diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-03-28 13:03:58 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-03-28 13:03:58 +0200 |
commit | cdccfc8dc0bf62a1da327324a8d639139acc9279 (patch) | |
tree | dca7934b27d510c9c006558979ebc48e07a531cf /sound/pci | |
parent | b21a8ee67013372f439fbd1591e91d09de49bb9c (diff) | |
parent | c6b358748e19ce7e230b0926ac42696bc485a562 (diff) |
Merge branch 'fix/misc' into topic/misc
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/asihpi/asihpi.c | 137 | ||||
-rw-r--r-- | sound/pci/au88x0/au88x0.h | 4 | ||||
-rw-r--r-- | sound/pci/au88x0/au88x0_core.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 89 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 48 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 58 |
6 files changed, 239 insertions, 101 deletions
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 0ac1f98d91a1..f53a31e939c1 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -22,21 +22,6 @@ * for any purpose including commercial applications. */ -/* >0: print Hw params, timer vars. >1: print stream write/copy sizes */ -#define REALLY_VERBOSE_LOGGING 0 - -#if REALLY_VERBOSE_LOGGING -#define VPRINTK1 snd_printd -#else -#define VPRINTK1(...) -#endif - -#if REALLY_VERBOSE_LOGGING > 1 -#define VPRINTK2 snd_printd -#else -#define VPRINTK2(...) -#endif - #include "hpi_internal.h" #include "hpimsginit.h" #include "hpioctl.h" @@ -57,11 +42,25 @@ #include <sound/tlv.h> #include <sound/hwdep.h> - MODULE_LICENSE("GPL"); MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); +#if defined CONFIG_SND_DEBUG_VERBOSE +/** + * snd_printddd - very verbose debug printk + * @format: format string + * + * Works like snd_printk() for debugging purposes. + * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set. + * Must set snd module debug parameter to 3 to enable at runtime. + */ +#define snd_printddd(format, args...) \ + __snd_printk(3, __FILE__, __LINE__, format, ##args) +#else +#define snd_printddd(format, args...) do { } while (0) +#endif + static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; @@ -289,7 +288,6 @@ static u16 handle_error(u16 err, int line, char *filename) #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__) /***************************** GENERAL PCM ****************/ -#if REALLY_VERBOSE_LOGGING static void print_hwparams(struct snd_pcm_hw_params *p) { snd_printd("HWPARAMS \n"); @@ -304,9 +302,6 @@ static void print_hwparams(struct snd_pcm_hw_params *p) snd_printd("periods %d \n", params_periods(p)); snd_printd("buffer_size %d \n", params_buffer_size(p)); } -#else -#define print_hwparams(x) -#endif static snd_pcm_format_t hpi_to_alsa_formats[] = { -1, /* INVALID */ @@ -381,13 +376,13 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, "No local sampleclock, err %d\n", err); } - for (idx = 0; idx < 100; idx++) { - if (hpi_sample_clock_query_local_rate( - h_control, idx, &sample_rate)) { - if (!idx) - snd_printk(KERN_ERR - "Local rate query failed\n"); - + for (idx = -1; idx < 100; idx++) { + if (idx == -1) { + if (hpi_sample_clock_get_sample_rate(h_control, + &sample_rate)) + continue; + } else if (hpi_sample_clock_query_local_rate(h_control, + idx, &sample_rate)) { break; } @@ -440,8 +435,6 @@ static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi, } } - /* printk(KERN_INFO "Supported rates %X %d %d\n", - rates, rate_min, rate_max); */ pcmhw->rates = rates; pcmhw->rate_min = rate_min; pcmhw->rate_max = rate_max; @@ -466,7 +459,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, if (err) return err; - VPRINTK1(KERN_INFO "format %d, %d chans, %d_hz\n", + snd_printdd("format %d, %d chans, %d_hz\n", format, params_channels(params), params_rate(params)); @@ -489,13 +482,12 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, err = hpi_stream_host_buffer_attach(dpcm->h_stream, params_buffer_bytes(params), runtime->dma_addr); if (err == 0) { - VPRINTK1(KERN_INFO + snd_printdd( "stream_host_buffer_attach succeeded %u %lu\n", params_buffer_bytes(params), (unsigned long)runtime->dma_addr); } else { - snd_printd(KERN_INFO - "stream_host_buffer_attach error %d\n", + snd_printd("stream_host_buffer_attach error %d\n", err); return -ENOMEM; } @@ -504,7 +496,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, &dpcm->hpi_buffer_attached, NULL, NULL, NULL); - VPRINTK1(KERN_INFO "stream_host_buffer_attach status 0x%x\n", + snd_printdd("stream_host_buffer_attach status 0x%x\n", dpcm->hpi_buffer_attached); } bytes_per_sec = params_rate(params) * params_channels(params); @@ -517,7 +509,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, dpcm->bytes_per_sec = bytes_per_sec; dpcm->buffer_bytes = params_buffer_bytes(params); dpcm->period_bytes = params_period_bytes(params); - VPRINTK1(KERN_INFO "buffer_bytes=%d, period_bytes=%d, bps=%d\n", + snd_printdd("buffer_bytes=%d, period_bytes=%d, bps=%d\n", dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec); return 0; @@ -573,7 +565,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, struct snd_pcm_substream *s; u16 e; - VPRINTK1(KERN_INFO "%c%d trigger\n", + snd_printdd("%c%d trigger\n", SCHR(substream->stream), substream->number); switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -597,7 +589,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, * data?? */ unsigned int preload = ds->period_bytes * 1; - VPRINTK2(KERN_INFO "%d preload x%x\n", s->number, preload); + snd_printddd("%d preload x%x\n", s->number, preload); hpi_handle_error(hpi_outstream_write_buf( ds->h_stream, &runtime->dma_area[0], @@ -607,7 +599,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, } if (card->support_grouping) { - VPRINTK1(KERN_INFO "\t%c%d group\n", + snd_printdd("\t%c%d group\n", SCHR(s->stream), s->number); e = hpi_stream_group_add( @@ -622,7 +614,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, } else break; } - VPRINTK1(KERN_INFO "start\n"); + snd_printdd("start\n"); /* start the master stream */ snd_card_asihpi_pcm_timer_start(substream); if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || @@ -644,14 +636,14 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, s->runtime->status->state = SNDRV_PCM_STATE_SETUP; if (card->support_grouping) { - VPRINTK1(KERN_INFO "\t%c%d group\n", + snd_printdd("\t%c%d group\n", SCHR(s->stream), s->number); snd_pcm_trigger_done(s, substream); } else break; } - VPRINTK1(KERN_INFO "stop\n"); + snd_printdd("stop\n"); /* _prepare and _hwparams reset the stream */ hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); @@ -664,12 +656,12 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - VPRINTK1(KERN_INFO "pause release\n"); + snd_printdd("pause release\n"); hpi_handle_error(hpi_stream_start(dpcm->h_stream)); snd_card_asihpi_pcm_timer_start(substream); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - VPRINTK1(KERN_INFO "pause\n"); + snd_printdd("pause\n"); snd_card_asihpi_pcm_timer_stop(substream); hpi_handle_error(hpi_stream_stop(dpcm->h_stream)); break; @@ -741,7 +733,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) u16 state; u32 buffer_size, bytes_avail, samples_played, on_card_bytes; - VPRINTK1(KERN_INFO "%c%d snd_card_asihpi_timer_function\n", + snd_printdd("%c%d snd_card_asihpi_timer_function\n", SCHR(substream->stream), substream->number); /* find minimum newdata and buffer pos in group */ @@ -770,10 +762,10 @@ static void snd_card_asihpi_timer_function(unsigned long data) if ((bytes_avail == 0) && (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { hpi_handle_error(hpi_stream_start(ds->h_stream)); - VPRINTK1(KERN_INFO "P%d start\n", s->number); + snd_printdd("P%d start\n", s->number); } } else if (state == HPI_STATE_DRAINED) { - VPRINTK1(KERN_WARNING "P%d drained\n", + snd_printd(KERN_WARNING "P%d drained\n", s->number); /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); continue; */ @@ -794,13 +786,13 @@ static void snd_card_asihpi_timer_function(unsigned long data) newdata); } - VPRINTK1(KERN_INFO "PB timer hw_ptr x%04lX, appl_ptr x%04lX\n", + snd_printdd("hw_ptr x%04lX, appl_ptr x%04lX\n", (unsigned long)frames_to_bytes(runtime, runtime->status->hw_ptr), (unsigned long)frames_to_bytes(runtime, runtime->control->appl_ptr)); - VPRINTK1(KERN_INFO "%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," + snd_printdd("%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," " aux=x%04X space=x%04X\n", loops, SCHR(s->stream), s->number, state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail, @@ -822,7 +814,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) next_jiffies = max(next_jiffies, 1U); dpcm->timer.expires = jiffies + next_jiffies; - VPRINTK1(KERN_INFO "jif %d buf pos x%04X newdata x%04X xfer x%04X\n", + snd_printdd("jif %d buf pos x%04X newdata x%04X xfer x%04X\n", next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); snd_pcm_group_for_each_entry(s, substream) { @@ -837,7 +829,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) if (xfercount && (on_card_bytes <= ds->period_bytes)) { if (card->support_mmap) { if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { - VPRINTK2(KERN_INFO "P%d write x%04x\n", + snd_printddd("P%d write x%04x\n", s->number, ds->period_bytes); hpi_handle_error( @@ -848,7 +840,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) xfercount, &ds->format)); } else { - VPRINTK2(KERN_INFO "C%d read x%04x\n", + snd_printddd("C%d read x%04x\n", s->number, xfercount); hpi_handle_error( @@ -871,7 +863,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) { - /* snd_printd(KERN_INFO "Playback ioctl %d\n", cmd); */ + snd_printdd(KERN_INFO "Playback ioctl %d\n", cmd); return snd_pcm_lib_ioctl(substream, cmd, arg); } @@ -881,7 +873,7 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream * struct snd_pcm_runtime *runtime = substream->runtime; struct snd_card_asihpi_pcm *dpcm = runtime->private_data; - VPRINTK1(KERN_INFO "playback prepare %d\n", substream->number); + snd_printdd("playback prepare %d\n", substream->number); hpi_handle_error(hpi_outstream_reset(dpcm->h_stream)); dpcm->pcm_buf_host_rw_ofs = 0; @@ -898,7 +890,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream) snd_pcm_uframes_t ptr; ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); - /* VPRINTK2(KERN_INFO "playback_pointer=x%04lx\n", (unsigned long)ptr); */ + snd_printddd("playback_pointer=x%04lx\n", (unsigned long)ptr); return ptr; } @@ -1014,12 +1006,13 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, card->update_interval_frames); + snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, card->update_interval_frames * 2, UINT_MAX); snd_pcm_set_sync(substream); - VPRINTK1(KERN_INFO "playback open\n"); + snd_printdd("playback open\n"); return 0; } @@ -1030,7 +1023,7 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream) struct snd_card_asihpi_pcm *dpcm = runtime->private_data; hpi_handle_error(hpi_outstream_close(dpcm->h_stream)); - VPRINTK1(KERN_INFO "playback close\n"); + snd_printdd("playback close\n"); return 0; } @@ -1050,13 +1043,13 @@ static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream, if (copy_from_user(runtime->dma_area, src, len)) return -EFAULT; - VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n", + snd_printddd("playback copy%d %u bytes\n", substream->number, len); hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream, runtime->dma_area, len, &dpcm->format)); - dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len; + dpcm->pcm_buf_host_rw_ofs += len; return 0; } @@ -1066,16 +1059,11 @@ static int snd_card_asihpi_playback_silence(struct snd_pcm_substream * snd_pcm_uframes_t pos, snd_pcm_uframes_t count) { - unsigned int len; - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_card_asihpi_pcm *dpcm = runtime->private_data; - - len = frames_to_bytes(runtime, count); - VPRINTK1(KERN_INFO "playback silence %u bytes\n", len); - - memset(runtime->dma_area, 0, len); - hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream, - runtime->dma_area, len, &dpcm->format)); + /* Usually writes silence to DMA buffer, which should be overwritten + by real audio later. Our fifos cannot be overwritten, and are not + free-running DMAs. Silence is output on fifo underflow. + This callback is still required to allow the copy callback to be used. + */ return 0; } @@ -1110,7 +1098,7 @@ snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_card_asihpi_pcm *dpcm = runtime->private_data; - VPRINTK2(KERN_INFO "capture pointer %d=%d\n", + snd_printddd("capture pointer %d=%d\n", substream->number, dpcm->pcm_buf_dma_ofs); /* NOTE Unlike playback can't use actual samples_played for the capture position, because those samples aren't yet in @@ -1135,7 +1123,7 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream) dpcm->pcm_buf_dma_ofs = 0; dpcm->pcm_buf_elapsed_dma_ofs = 0; - VPRINTK1("Capture Prepare %d\n", substream->number); + snd_printdd("Capture Prepare %d\n", substream->number); return 0; } @@ -1198,7 +1186,7 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) if (dpcm == NULL) return -ENOMEM; - VPRINTK1("hpi_instream_open adapter %d stream %d\n", + snd_printdd("capture open adapter %d stream %d\n", card->adapter_index, substream->number); err = hpi_handle_error( @@ -1268,7 +1256,7 @@ static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream, len = frames_to_bytes(runtime, count); - VPRINTK2(KERN_INFO "capture copy%d %d bytes\n", substream->number, len); + snd_printddd("capture copy%d %d bytes\n", substream->number, len); hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream, runtime->dma_area, len)); @@ -2887,6 +2875,9 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, if (err) asihpi->update_interval_frames = 512; + if (!asihpi->support_mmap) + asihpi->update_interval_frames *= 2; + hpi_handle_error(hpi_instream_open(asihpi->adapter_index, 0, &h_stream)); @@ -2909,7 +2900,6 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, asihpi->support_mrx ); - err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams); if (err < 0) { snd_printk(KERN_ERR "pcm_new failed\n"); @@ -2944,6 +2934,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, sprintf(card->longname, "%s %i", card->shortname, asihpi->adapter_index); err = snd_card_register(card); + if (!err) { hpi_card->snd_card_asihpi = card; dev++; diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h index cf46bba563cf..ecb8f4daf408 100644 --- a/sound/pci/au88x0/au88x0.h +++ b/sound/pci/au88x0/au88x0.h @@ -211,7 +211,7 @@ static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma); //static void vortex_adbdma_stopfifo(vortex_t *vortex, int adbdma); static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma); static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma); -static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma); +static inline int vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma); static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma); #ifndef CHIP_AU8810 @@ -219,7 +219,7 @@ static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma); static void vortex_wtdma_stopfifo(vortex_t * vortex, int wtdma); static void vortex_wtdma_pausefifo(vortex_t * vortex, int wtdma); static void vortex_wtdma_resumefifo(vortex_t * vortex, int wtdma); -static int inline vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma); +static inline int vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma); #endif /* global stuff. */ diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index 16c0bdfbb164..489150380eac 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c @@ -1249,7 +1249,7 @@ static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) { } } -static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma) +static inline int vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma) { stream_t *dma = &vortex->dma_adb[adbdma]; int temp, page, delta; @@ -1506,7 +1506,7 @@ static int vortex_wtdma_getcursubuffer(vortex_t * vortex, int wtdma) POS_SHIFT) & POS_MASK); } #endif -static int inline vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma) +static inline int vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma) { stream_t *dma = &vortex->dma_wt[wtdma]; int temp; diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 734c6ee55d8a..2942d2a9ea10 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -4256,6 +4256,84 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec) } /* + * Precision R5500 + * 0x12 - HP/line-out + * 0x13 - speaker (mono) + * 0x15 - mic-in + */ + +static struct hda_verb ad1984a_precision_verbs[] = { + /* Unmute main output path */ + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */ + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */ + /* Analog mixer; mute as default */ + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, + /* Select mic as input */ + {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */ + /* Configure as mic */ + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ + /* HP unmute */ + {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + /* turn on EAPD */ + {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, + /* unsolicited event for pin-sense */ + {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, + { } /* end */ +}; + +static struct snd_kcontrol_new ad1984a_precision_mixers[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), + HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), + { } /* end */ +}; + + +/* mute internal speaker if HP is plugged */ +static void ad1984a_precision_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_jack_detect(codec, 0x12); + snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0, + HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); +} + + +/* unsolicited event for HP jack sensing */ +static void ad1984a_precision_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) != AD1884A_HP_EVENT) + return; + ad1984a_precision_automute(codec); +} + +/* initialize jack-sensing, too */ +static int ad1984a_precision_init(struct hda_codec *codec) +{ + ad198x_init(codec); + ad1984a_precision_automute(codec); + return 0; +} + + +/* * HP Touchsmart * port-A (0x11) - front hp-out * port-B (0x14) - unused @@ -4384,6 +4462,7 @@ enum { AD1884A_MOBILE, AD1884A_THINKPAD, AD1984A_TOUCHSMART, + AD1984A_PRECISION, AD1884A_MODELS }; @@ -4393,9 +4472,11 @@ static const char * const ad1884a_models[AD1884A_MODELS] = { [AD1884A_MOBILE] = "mobile", [AD1884A_THINKPAD] = "thinkpad", [AD1984A_TOUCHSMART] = "touchsmart", + [AD1984A_PRECISION] = "precision", }; static struct snd_pci_quirk ad1884a_cfg_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION), SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), @@ -4489,6 +4570,14 @@ static int patch_ad1884a(struct hda_codec *codec) codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; codec->patch_ops.init = ad1984a_thinkpad_init; break; + case AD1984A_PRECISION: + spec->mixers[0] = ad1984a_precision_mixers; + spec->init_verbs[spec->num_init_verbs++] = + ad1984a_precision_verbs; + spec->multiout.dig_out_nid = 0; + codec->patch_ops.unsol_event = ad1984a_precision_unsol_event; + codec->patch_ops.init = ad1984a_precision_init; + break; case AD1984A_TOUCHSMART: spec->mixers[0] = ad1984a_touchsmart_mixers; spec->init_verbs[0] = ad1984a_touchsmart_verbs; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 28f95d14ba6a..12c6f4508c54 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1290,7 +1290,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) case 0x10ec0883: case 0x10ec0885: case 0x10ec0887: - case 0x10ec0889: + /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ alc889_coef_init(codec); break; case 0x10ec0888: @@ -9863,7 +9863,6 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), - SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), @@ -10700,6 +10699,7 @@ enum { PINFIX_LENOVO_Y530, PINFIX_PB_M5210, PINFIX_ACER_ASPIRE_7736, + PINFIX_GIGABYTE_880GM, }; static const struct alc_fixup alc882_fixups[] = { @@ -10731,6 +10731,13 @@ static const struct alc_fixup alc882_fixups[] = { .type = ALC_FIXUP_SKU, .v.sku = ALC_FIXUP_SKU_IGNORE, }, + [PINFIX_GIGABYTE_880GM] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x14, 0x1114410 }, /* set as speaker */ + { } + } + }, }; static struct snd_pci_quirk alc882_fixup_tbl[] = { @@ -10738,6 +10745,7 @@ static struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), + SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", PINFIX_GIGABYTE_880GM), {} }; @@ -16008,9 +16016,12 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, return err; } else { const char *name = pfx; - if (!name) + int index = i; + if (!name) { name = chname[i]; - err = __alc861_create_out_sw(codec, name, nid, i, 3); + index = 0; + } + err = __alc861_create_out_sw(codec, name, nid, index, 3); if (err < 0) return err; } @@ -17161,16 +17172,19 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, return err; } else { const char *name = pfx; - if (!name) + int index = i; + if (!name) { name = chname[i]; + index = 0; + } err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, - name, i, + name, index, HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); if (err < 0) return err; err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, - name, i, + name, index, HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); if (err < 0) @@ -18768,8 +18782,6 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), - SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", - ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), @@ -19219,12 +19231,15 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, return err; } else { const char *name = pfx; - if (!name) + int index = i; + if (!name) { name = chname[i]; - err = __alc662_add_vol_ctl(spec, name, nid, i, 3); + index = 0; + } + err = __alc662_add_vol_ctl(spec, name, nid, index, 3); if (err < 0) return err; - err = __alc662_add_sw_ctl(spec, name, mix, i, 3); + err = __alc662_add_sw_ctl(spec, name, mix, index, 3); if (err < 0) return err; } @@ -19440,6 +19455,7 @@ enum { ALC662_FIXUP_IDEAPAD, ALC272_FIXUP_MARIO, ALC662_FIXUP_CZC_P10T, + ALC662_FIXUP_GIGABYTE, }; static const struct alc_fixup alc662_fixups[] = { @@ -19468,12 +19484,20 @@ static const struct alc_fixup alc662_fixups[] = { {} } }, + [ALC662_FIXUP_GIGABYTE] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x14, 0x1114410 }, /* set as speaker */ + { } + } + }, }; static struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), + SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", ALC662_FIXUP_GIGABYTE), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 63b0054200a8..1371b57c11e8 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -159,6 +159,7 @@ struct via_spec { #endif }; +static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec); static struct via_spec * via_new_spec(struct hda_codec *codec) { struct via_spec *spec; @@ -169,6 +170,10 @@ static struct via_spec * via_new_spec(struct hda_codec *codec) codec->spec = spec; spec->codec = codec; + spec->codec_type = get_codec_type(codec); + /* VT1708BCE & VT1708S are almost same */ + if (spec->codec_type == VT1708BCE) + spec->codec_type = VT1708S; return spec; } @@ -1101,6 +1106,7 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct via_spec *spec = codec->spec; unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + int ret; if (!spec->mux_nids[adc_idx]) return -EINVAL; @@ -1109,12 +1115,14 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0) snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - /* update jack power state */ - set_jack_power_state(codec); - return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, + ret = snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]); + /* update jack power state */ + set_jack_power_state(codec); + + return ret; } static int via_independent_hp_info(struct snd_kcontrol *kcontrol, @@ -1188,8 +1196,16 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, /* Get Independent Mode index of headphone pin widget */ spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel ? 1 : 0; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel); + if (spec->codec_type == VT1718S) + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0); + else + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_CONNECT_SEL, pinsel); + if (spec->codec_type == VT1812) + snd_hda_codec_write(codec, 0x35, 0, + AC_VERB_SET_CONNECT_SEL, pinsel); if (spec->multiout.hp_nid && spec->multiout.hp_nid != spec->multiout.dac_nids[HDA_FRONT]) snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid, @@ -1208,6 +1224,8 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, activate_ctl(codec, "Headphone Playback Switch", spec->hp_independent_mode); } + /* update jack power state */ + set_jack_power_state(codec); return 0; } @@ -1248,9 +1266,12 @@ static int via_hp_build(struct hda_codec *codec) break; } - nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS); - if (nums <= 1) - return 0; + if (spec->codec_type != VT1708) { + nums = snd_hda_get_connections(codec, nid, + conn, HDA_MAX_CONNECTIONS); + if (nums <= 1) + return 0; + } knew = via_clone_control(spec, &via_hp_mixer[0]); if (knew == NULL) @@ -1310,6 +1331,11 @@ static void mute_aa_path(struct hda_codec *codec, int mute) start_idx = 2; end_idx = 4; break; + case VT1718S: + nid_mixer = 0x21; + start_idx = 1; + end_idx = 3; + break; default: return; } @@ -2185,10 +2211,6 @@ static int via_init(struct hda_codec *codec) for (i = 0; i < spec->num_iverbs; i++) snd_hda_sequence_write(codec, spec->init_verbs[i]); - spec->codec_type = get_codec_type(codec); - if (spec->codec_type == VT1708BCE) - spec->codec_type = VT1708S; /* VT1708BCE & VT1708S are almost - same */ /* Lydia Add for EAPD enable */ if (!spec->dig_in_nid) { /* No Digital In connection */ if (spec->dig_in_pin) { @@ -2438,7 +2460,14 @@ static int vt_auto_create_analog_input_ctls(struct hda_codec *codec, else type_idx = 0; label = hda_get_autocfg_input_label(codec, cfg, i); - err = via_new_analog_input(spec, label, type_idx, idx, cap_nid); + if (spec->codec_type == VT1708S || + spec->codec_type == VT1702 || + spec->codec_type == VT1716S) + err = via_new_analog_input(spec, label, type_idx, + idx+1, cap_nid); + else + err = via_new_analog_input(spec, label, type_idx, + idx, cap_nid); if (err < 0) return err; snd_hda_add_imux_item(imux, label, idx, NULL); @@ -4147,6 +4176,11 @@ static int patch_vt1708S(struct hda_codec *codec) spec->stream_name_analog = "VT1708BCE Analog"; spec->stream_name_digital = "VT1708BCE Digital"; } + /* correct names for VT1818S */ + if (codec->vendor_id == 0x11060440) { + spec->stream_name_analog = "VT1818S Analog"; + spec->stream_name_digital = "VT1818S Digital"; + } return 0; } |