diff options
Diffstat (limited to 'sound/pci')
62 files changed, 1357 insertions, 1269 deletions
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 1ef7cdf1d3e8..f4459d1a9d67 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -2941,19 +2941,3 @@ int snd_ac97_tune_hardware(struct snd_ac97 *ac97, } EXPORT_SYMBOL(snd_ac97_tune_hardware); - -/* - * INIT part - */ - -static int __init alsa_ac97_init(void) -{ - return 0; -} - -static void __exit alsa_ac97_exit(void) -{ -} - -module_init(alsa_ac97_init) -module_exit(alsa_ac97_exit) diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 39547e32e584..9f569379b77e 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -1484,12 +1484,9 @@ static struct snd_pcm_hardware snd_ali_capture = static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime) { struct snd_ali_voice *pvoice = runtime->private_data; - struct snd_ali *codec; - if (pvoice) { - codec = pvoice->codec; + if (pvoice) snd_ali_free_voice(pvoice->codec, pvoice); - } } static int snd_ali_open(struct snd_pcm_substream *substream, int rec, diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 64e0961f93ba..a31fe1550903 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -311,27 +311,29 @@ static void print_hwparams(struct snd_pcm_substream *substream, snd_pcm_format_width(params_format(p)) / 8); } +#define INVALID_FORMAT (__force snd_pcm_format_t)(-1) + static snd_pcm_format_t hpi_to_alsa_formats[] = { - -1, /* INVALID */ + INVALID_FORMAT, /* INVALID */ SNDRV_PCM_FORMAT_U8, /* HPI_FORMAT_PCM8_UNSIGNED 1 */ SNDRV_PCM_FORMAT_S16, /* HPI_FORMAT_PCM16_SIGNED 2 */ - -1, /* HPI_FORMAT_MPEG_L1 3 */ + INVALID_FORMAT, /* HPI_FORMAT_MPEG_L1 3 */ SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L2 4 */ SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L3 5 */ - -1, /* HPI_FORMAT_DOLBY_AC2 6 */ - -1, /* HPI_FORMAT_DOLBY_AC3 7 */ + INVALID_FORMAT, /* HPI_FORMAT_DOLBY_AC2 6 */ + INVALID_FORMAT, /* HPI_FORMAT_DOLBY_AC3 7 */ SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN 8 */ - -1, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */ - -1, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */ + INVALID_FORMAT, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */ + INVALID_FORMAT, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */ SNDRV_PCM_FORMAT_S32, /* HPI_FORMAT_PCM32_SIGNED 11 */ - -1, /* HPI_FORMAT_RAW_BITSTREAM 12 */ - -1, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */ + INVALID_FORMAT, /* HPI_FORMAT_RAW_BITSTREAM 12 */ + INVALID_FORMAT, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */ SNDRV_PCM_FORMAT_FLOAT, /* HPI_FORMAT_PCM32_FLOAT 14 */ #if 1 /* ALSA can't handle 3 byte sample size together with power-of-2 * constraint on buffer_bytes, so disable this format */ - -1 + INVALID_FORMAT #else /* SNDRV_PCM_FORMAT_S24_3LE */ /* HPI_FORMAT_PCM24_SIGNED 15 */ #endif @@ -1023,7 +1025,7 @@ static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi, format, sample_rate, 128000, 0); if (!err) err = hpi_outstream_query_format(h_stream, &hpi_format); - if (!err && (hpi_to_alsa_formats[format] != -1)) + if (!err && (hpi_to_alsa_formats[format] != INVALID_FORMAT)) formats |= pcm_format_to_bits(hpi_to_alsa_formats[format]); } return formats; @@ -1205,7 +1207,7 @@ static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi, format, sample_rate, 128000, 0); if (!err) err = hpi_instream_query_format(h_stream, &hpi_format); - if (!err && (hpi_to_alsa_formats[format] != -1)) + if (!err && (hpi_to_alsa_formats[format] != INVALID_FORMAT)) formats |= pcm_format_to_bits(hpi_to_alsa_formats[format]); } return formats; diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 8d5abfa4e24b..2864698436a5 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c @@ -635,7 +635,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, { struct hpi_message hm; struct hpi_response hr; - u32 max_streams; HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n"); memset(&hm, 0, sizeof(hm)); @@ -660,10 +659,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, pao->type = hr.u.ax.info.adapter_type; pao->index = hr.u.ax.info.adapter_index; - max_streams = - hr.u.ax.info.num_outstreams + - hr.u.ax.info.num_instreams; - HPI_DEBUG_LOG(VERBOSE, "got adapter info type %x index %d serial %d\n", hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index, diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 7ae63d452bba..a1e4944dcfe8 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -207,10 +207,10 @@ struct atiixp; */ struct atiixp_dma_desc { - u32 addr; /* DMA buffer address */ + __le32 addr; /* DMA buffer address */ u16 status; /* status bits */ u16 size; /* size of the packet in dwords */ - u32 next; /* address of the next packet descriptor */ + __le32 next; /* address of the next packet descriptor */ }; /* diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index a586635664e0..dc1de860cedf 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c @@ -183,10 +183,10 @@ struct atiixp_modem; */ struct atiixp_dma_desc { - u32 addr; /* DMA buffer address */ + __le32 addr; /* DMA buffer address */ u16 status; /* status bits */ u16 size; /* size of the packet in dwords */ - u32 next; /* address of the next packet descriptor */ + __le32 next; /* address of the next packet descriptor */ }; /* diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h index bcc648bf6478..e3e31f07d766 100644 --- a/sound/pci/au88x0/au88x0.h +++ b/sound/pci/au88x0/au88x0.h @@ -241,7 +241,7 @@ static int vortex_core_init(vortex_t * card); static int vortex_core_shutdown(vortex_t * card); static void vortex_enable_int(vortex_t * card); static irqreturn_t vortex_interrupt(int irq, void *dev_id); -static int vortex_alsafmt_aspfmt(int alsafmt, vortex_t *v); +static int vortex_alsafmt_aspfmt(snd_pcm_format_t alsafmt, vortex_t *v); /* Connection stuff. */ static void vortex_connect_default(vortex_t * vortex, int en); diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index 4083c8b01619..2e5b460a847c 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c @@ -2770,7 +2770,7 @@ static int vortex_core_shutdown(vortex_t * vortex) /* Alsa support. */ -static int vortex_alsafmt_aspfmt(int alsafmt, vortex_t *v) +static int vortex_alsafmt_aspfmt(snd_pcm_format_t alsafmt, vortex_t *v) { int fmt; diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index d8ade8771a32..ba971042f871 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -228,14 +228,14 @@ static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substrea unsigned int periods, unsigned int period_bytes) { unsigned int i, offset; - u32 *risc; + __le32 *risc; if (chip->dma_risc.area == NULL) { if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), PAGE_ALIGN(MAX_RISC_SIZE), &chip->dma_risc) < 0) return -ENOMEM; } - risc = (u32 *)chip->dma_risc.area; + risc = (__le32 *)chip->dma_risc.area; offset = 0; *risc++ = cpu_to_le32(RISC_SYNC | RISC_SYNC_FM1); *risc++ = cpu_to_le32(0); diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c index abb01ce66983..8d0a3d357345 100644 --- a/sound/pci/cs46xx/dsp_spos_scb_lib.c +++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c @@ -73,13 +73,10 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry, { struct proc_scb_info * scb_info = entry->private_data; struct dsp_scb_descriptor * scb = scb_info->scb_desc; - struct dsp_spos_instance * ins; struct snd_cs46xx *chip = scb_info->chip; int j,col; void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET; - ins = chip->dsp_spos_instance; - mutex_lock(&chip->spos_mutex); snd_iprintf(buffer,"%04x %s:\n",scb->address,scb->scb_name); diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c index de409cda50aa..4590086d9cd8 100644 --- a/sound/pci/cs5535audio/cs5535audio.c +++ b/sound/pci/cs5535audio/cs5535audio.c @@ -192,8 +192,6 @@ static void process_bm0_irq(struct cs5535audio *cs5535au) bm_stat = cs_readb(cs5535au, ACC_BM0_STATUS); spin_unlock(&cs5535au->reg_lock); if (bm_stat & EOP) { - struct cs5535audio_dma *dma; - dma = cs5535au->playback_substream->runtime->private_data; snd_pcm_period_elapsed(cs5535au->playback_substream); } else { dev_err(cs5535au->card->dev, @@ -208,11 +206,8 @@ static void process_bm1_irq(struct cs5535audio *cs5535au) spin_lock(&cs5535au->reg_lock); bm_stat = cs_readb(cs5535au, ACC_BM1_STATUS); spin_unlock(&cs5535au->reg_lock); - if (bm_stat & EOP) { - struct cs5535audio_dma *dma; - dma = cs5535au->capture_substream->runtime->private_data; + if (bm_stat & EOP) snd_pcm_period_elapsed(cs5535au->capture_substream); - } } static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id) diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h index f4fcdf93f3c8..d84620a0c26c 100644 --- a/sound/pci/cs5535audio/cs5535audio.h +++ b/sound/pci/cs5535audio/cs5535audio.h @@ -67,9 +67,9 @@ struct cs5535audio_dma_ops { }; struct cs5535audio_dma_desc { - u32 addr; - u16 size; - u16 ctlreserved; + __le32 addr; + __le16 size; + __le16 ctlreserved; }; struct cs5535audio_dma { diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c index ee7065f6e162..326caec854e1 100644 --- a/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/sound/pci/cs5535audio/cs5535audio_pcm.c @@ -158,8 +158,8 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au, lastdesc->addr = cpu_to_le32((u32) dma->desc_buf.addr); lastdesc->size = 0; lastdesc->ctlreserved = cpu_to_le16(PRD_JMP); - jmpprd_addr = cpu_to_le32(lastdesc->addr + - (sizeof(struct cs5535audio_dma_desc)*periods)); + jmpprd_addr = (u32)dma->desc_buf.addr + + sizeof(struct cs5535audio_dma_desc) * periods; dma->substream = substream; dma->period_bytes = period_bytes; diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 8e6eb9d7984b..6a051a1c3724 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -1319,7 +1319,7 @@ static int hw_pll_init(struct hw *hw, unsigned int rsr) break; hw_write_20kx(hw, PLLCTL, pllctl); - mdelay(40); + msleep(40); } if (i >= 3) { dev_alert(hw->card->dev, "PLL initialization failed!!!\n"); @@ -1407,7 +1407,7 @@ static int hw_reset_dac(struct hw *hw) /* To be effective, need to reset the DAC twice. */ for (i = 0; i < 2; i++) { /* set gpio */ - mdelay(100); + msleep(100); gpioorg = (u16)hw_read_20kx(hw, GPIO); gpioorg &= 0xfffd; hw_write_20kx(hw, GPIO, gpioorg); @@ -2030,7 +2030,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info) hw_write_20kx(hw, GIE, 0); /* Reset all SRC pending interrupts */ hw_write_20kx(hw, SRCIP, 0); - mdelay(30); + msleep(30); /* Detect the card ID and configure GPIO accordingly. */ switch (hw->model) { diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index b866d6b2c923..3c966fafc754 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c @@ -1316,12 +1316,12 @@ static int hw_pll_init(struct hw *hw, unsigned int rsr) set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 4 : 147 - 4); set_field(&pllctl, PLLCTL_RD, 48000 == rsr ? 1 - 1 : 10 - 1); hw_write_20kx(hw, PLL_CTL, pllctl); - mdelay(40); + msleep(40); pllctl = hw_read_20kx(hw, PLL_CTL); set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 2 : 147 - 2); hw_write_20kx(hw, PLL_CTL, pllctl); - mdelay(40); + msleep(40); for (i = 0; i < 1000; i++) { pllstat = hw_read_20kx(hw, PLL_STAT); @@ -1584,7 +1584,7 @@ static void hw_dac_stop(struct hw *hw) data = hw_read_20kx(hw, GPIO_DATA); data &= 0xFFFFFFFD; hw_write_20kx(hw, GPIO_DATA, data); - mdelay(10); + usleep_range(10000, 11000); } static void hw_dac_start(struct hw *hw) @@ -1593,7 +1593,7 @@ static void hw_dac_start(struct hw *hw) data = hw_read_20kx(hw, GPIO_DATA); data |= 0x2; hw_write_20kx(hw, GPIO_DATA, data); - mdelay(50); + msleep(50); } static void hw_dac_reset(struct hw *hw) @@ -1864,11 +1864,11 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info) hw_write_20kx(hw, GPIO_DATA, data); } - mdelay(10); + usleep_range(10000, 11000); /* Return the ADC to normal operation. */ data |= (0x1 << 15); hw_write_20kx(hw, GPIO_DATA, data); - mdelay(50); + msleep(50); /* I2C write to register offset 0x0B to set ADC LRCLK polarity */ /* invert bit, interface format to I2S, word length to 24-bit, */ diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c index db710d0a609f..4777d50fbbf8 100644 --- a/sound/pci/ctxfi/ctmixer.c +++ b/sound/pci/ctxfi/ctmixer.c @@ -938,17 +938,18 @@ static int ct_mixer_topology_build(struct ct_mixer *mixer) struct sum *sum; struct amixer *amix_d, *amix_s; enum CT_AMIXER_CTL i, j; + enum CT_SUM_CTL k; /* Build topology from destination to source */ /* Set up Master mixer */ - for (i = AMIXER_MASTER_F, j = SUM_IN_F; - i <= AMIXER_MASTER_S; i++, j++) { + for (i = AMIXER_MASTER_F, k = SUM_IN_F; + i <= AMIXER_MASTER_S; i++, k++) { amix_d = mixer->amixers[i*CHN_NUM]; - sum = mixer->sums[j*CHN_NUM]; + sum = mixer->sums[k*CHN_NUM]; amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL); amix_d = mixer->amixers[i*CHN_NUM+1]; - sum = mixer->sums[j*CHN_NUM+1]; + sum = mixer->sums[k*CHN_NUM+1]; amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL); } @@ -972,12 +973,12 @@ static int ct_mixer_topology_build(struct ct_mixer *mixer) amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL); /* Set up PCM-in mixer */ - for (i = AMIXER_PCM_F, j = SUM_IN_F; i <= AMIXER_PCM_S; i++, j++) { + for (i = AMIXER_PCM_F, k = SUM_IN_F; i <= AMIXER_PCM_S; i++, k++) { amix_d = mixer->amixers[i*CHN_NUM]; - sum = mixer->sums[j*CHN_NUM]; + sum = mixer->sums[k*CHN_NUM]; amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); amix_d = mixer->amixers[i*CHN_NUM+1]; - sum = mixer->sums[j*CHN_NUM+1]; + sum = mixer->sums[k*CHN_NUM+1]; amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum); } diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 358ef7dcf410..907cf1a46712 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -713,6 +713,7 @@ static int pcm_prepare(struct snd_pcm_substream *substream) break; case SNDRV_PCM_FORMAT_S32_BE: format.data_are_bigendian = 1; + /* fall through */ case SNDRV_PCM_FORMAT_S32_LE: format.bits_per_sample = 32; break; @@ -764,6 +765,7 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) pipe->last_counter = 0; pipe->position = 0; *pipe->dma_counter = 0; + /* fall through */ case PIPE_STATE_PAUSED: pipe->state = PIPE_STATE_STARTED; break; diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h index 44b390a667d5..be4d0489394a 100644 --- a/sound/pci/echoaudio/echoaudio.h +++ b/sound/pci/echoaudio/echoaudio.h @@ -294,7 +294,7 @@ struct audiopipe { - volatile u32 *dma_counter; /* Commpage register that contains + volatile __le32 *dma_counter; /* Commpage register that contains * the current dma position * (lower 32 bits only) */ diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c index 22c786b8a889..cc3c79387194 100644 --- a/sound/pci/echoaudio/echoaudio_3g.c +++ b/sound/pci/echoaudio/echoaudio_3g.c @@ -73,19 +73,21 @@ register. write_control_reg sends the new control register value to the DSP. */ static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, char force) { + __le32 ctl_reg, frq_reg; + if (wait_handshake(chip)) return -EIO; dev_dbg(chip->card->dev, "WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq); - ctl = cpu_to_le32(ctl); - frq = cpu_to_le32(frq); + ctl_reg = cpu_to_le32(ctl); + frq_reg = cpu_to_le32(frq); - if (ctl != chip->comm_page->control_register || - frq != chip->comm_page->e3g_frq_register || force) { - chip->comm_page->e3g_frq_register = frq; - chip->comm_page->control_register = ctl; + if (ctl_reg != chip->comm_page->control_register || + frq_reg != chip->comm_page->e3g_frq_register || force) { + chip->comm_page->e3g_frq_register = frq_reg; + chip->comm_page->control_register = ctl_reg; clear_handshake(chip); return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); } diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c index 15aae2fad8e4..b181752b8481 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.c +++ b/sound/pci/echoaudio/echoaudio_dsp.c @@ -679,7 +679,7 @@ static int restore_dsp_rettings(struct echoaudio *chip) /* Gina20/Darla20 only. Should be harmless for other cards. */ chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF; chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF; - chip->comm_page->handshake = 0xffffffff; + chip->comm_page->handshake = cpu_to_le32(0xffffffff); /* Restore output busses */ for (i = 0; i < num_busses_out(chip); i++) { @@ -989,7 +989,7 @@ static int init_dsp_comm_page(struct echoaudio *chip) /* Init the comm page */ chip->comm_page->comm_size = cpu_to_le32(sizeof(struct comm_page)); - chip->comm_page->handshake = 0xffffffff; + chip->comm_page->handshake = cpu_to_le32(0xffffffff); chip->comm_page->midi_out_free_count = cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE); chip->comm_page->sample_rate = cpu_to_le32(44100); @@ -1087,7 +1087,7 @@ static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe, /* The counter register is where the DSP writes the 32 bit DMA position for a pipe. The DSP is constantly updating this value as it moves data. The DMA counter is in units of bytes, not samples. */ - pipe->dma_counter = &chip->comm_page->position[pipe_index]; + pipe->dma_counter = (__le32 *)&chip->comm_page->position[pipe_index]; *pipe->dma_counter = 0; return pipe_index; } diff --git a/sound/pci/echoaudio/echoaudio_dsp.h b/sound/pci/echoaudio/echoaudio_dsp.h index cb7d75a0a503..aa9129519795 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.h +++ b/sound/pci/echoaudio/echoaudio_dsp.h @@ -627,8 +627,8 @@ sg_entry struct is read by the DSP, so all values must be little-endian. */ #define MAX_SGLIST_ENTRIES 512 struct sg_entry { - u32 addr; - u32 size; + __le32 addr; + __le32 size; }; @@ -643,18 +643,18 @@ struct sg_entry { ****************************************************************************/ struct comm_page { /* Base Length*/ - u32 comm_size; /* size of this object 0x000 4 */ - u32 flags; /* See Appendix A below 0x004 4 */ - u32 unused; /* Unused entry 0x008 4 */ - u32 sample_rate; /* Card sample rate in Hz 0x00c 4 */ - u32 handshake; /* DSP command handshake 0x010 4 */ - u32 cmd_start; /* Chs. to start mask 0x014 4 */ - u32 cmd_stop; /* Chs. to stop mask 0x018 4 */ - u32 cmd_reset; /* Chs. to reset mask 0x01c 4 */ - u16 audio_format[DSP_MAXPIPES]; /* Chs. audio format 0x020 32*2 */ + __le32 comm_size; /* size of this object 0x000 4 */ + __le32 flags; /* See Appendix A below 0x004 4 */ + __le32 unused; /* Unused entry 0x008 4 */ + __le32 sample_rate; /* Card sample rate in Hz 0x00c 4 */ + __le32 handshake; /* DSP command handshake 0x010 4 */ + __le32 cmd_start; /* Chs. to start mask 0x014 4 */ + __le32 cmd_stop; /* Chs. to stop mask 0x018 4 */ + __le32 cmd_reset; /* Chs. to reset mask 0x01c 4 */ + __le16 audio_format[DSP_MAXPIPES]; /* Chs. audio format 0x020 32*2 */ struct sg_entry sglist_addr[DSP_MAXPIPES]; /* Chs. Physical sglist addrs 0x060 32*8 */ - u32 position[DSP_MAXPIPES]; + __le32 position[DSP_MAXPIPES]; /* Positions for ea. ch. 0x160 32*4 */ s8 vu_meter[DSP_MAXPIPES]; /* VU meters 0x1e0 32*1 */ @@ -666,28 +666,28 @@ struct comm_page { /* Base Length*/ /* Input gain 0x230 16*1 */ s8 monitors[MONITOR_ARRAY_SIZE]; /* Monitor map 0x240 0x180 */ - u32 play_coeff[MAX_PLAY_TAPS]; + __le32 play_coeff[MAX_PLAY_TAPS]; /* Gina/Darla play filters - obsolete 0x3c0 168*4 */ - u32 rec_coeff[MAX_REC_TAPS]; + __le32 rec_coeff[MAX_REC_TAPS]; /* Gina/Darla record filters - obsolete 0x660 192*4 */ - u16 midi_input[MIDI_IN_BUFFER_SIZE]; + __le16 midi_input[MIDI_IN_BUFFER_SIZE]; /* MIDI input data transfer buffer 0x960 256*2 */ u8 gd_clock_state; /* Chg Gina/Darla clock state 0xb60 1 */ u8 gd_spdif_status; /* Chg. Gina/Darla S/PDIF state 0xb61 1 */ u8 gd_resampler_state; /* Should always be 3 0xb62 1 */ u8 filler2; /* 0xb63 1 */ - u32 nominal_level_mask; /* -10 level enable mask 0xb64 4 */ - u16 input_clock; /* Chg. Input clock state 0xb68 2 */ - u16 output_clock; /* Chg. Output clock state 0xb6a 2 */ - u32 status_clocks; /* Current Input clock state 0xb6c 4 */ - u32 ext_box_status; /* External box status 0xb70 4 */ - u32 cmd_add_buffer; /* Pipes to add (obsolete) 0xb74 4 */ - u32 midi_out_free_count; + __le32 nominal_level_mask; /* -10 level enable mask 0xb64 4 */ + __le16 input_clock; /* Chg. Input clock state 0xb68 2 */ + __le16 output_clock; /* Chg. Output clock state 0xb6a 2 */ + __le32 status_clocks; /* Current Input clock state 0xb6c 4 */ + __le32 ext_box_status; /* External box status 0xb70 4 */ + __le32 cmd_add_buffer; /* Pipes to add (obsolete) 0xb74 4 */ + __le32 midi_out_free_count; /* # of bytes free in MIDI output FIFO 0xb78 4 */ - u32 unused2; /* Cyclic pipes 0xb7c 4 */ - u32 control_register; + __le32 unused2; /* Cyclic pipes 0xb7c 4 */ + __le32 control_register; /* Mona, Gina24, Layla24, 3G ctrl reg 0xb80 4 */ - u32 e3g_frq_register; /* 3G frequency register 0xb84 4 */ + __le32 e3g_frq_register; /* 3G frequency register 0xb84 4 */ u8 filler[24]; /* filler 0xb88 24*1 */ s8 vmixer[VMIXER_ARRAY_SIZE]; /* Vmixer levels 0xba0 64*1 */ diff --git a/sound/pci/echoaudio/echoaudio_gml.c b/sound/pci/echoaudio/echoaudio_gml.c index 834b39e97db7..eea6fe530ab4 100644 --- a/sound/pci/echoaudio/echoaudio_gml.c +++ b/sound/pci/echoaudio/echoaudio_gml.c @@ -63,6 +63,8 @@ the control register. write_control_reg sends the new control register value to the DSP. */ static int write_control_reg(struct echoaudio *chip, u32 value, char force) { + __le32 reg_value; + /* Handle the digital input auto-mute */ if (chip->digital_in_automute) value |= GML_DIGITAL_IN_AUTO_MUTE; @@ -72,11 +74,11 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force) dev_dbg(chip->card->dev, "write_control_reg: 0x%x\n", value); /* Write the control register */ - value = cpu_to_le32(value); - if (value != chip->comm_page->control_register || force) { + reg_value = cpu_to_le32(value); + if (reg_value != chip->comm_page->control_register || force) { if (wait_handshake(chip)) return -EIO; - chip->comm_page->control_register = value; + chip->comm_page->control_register = reg_value; clear_handshake(chip); return send_vector(chip, DSP_VC_WRITE_CONTROL_REG); } diff --git a/sound/pci/emu10k1/emu10k1_patch.c b/sound/pci/emu10k1/emu10k1_patch.c index 0e069aeab86d..c32eb7053715 100644 --- a/sound/pci/emu10k1/emu10k1_patch.c +++ b/sound/pci/emu10k1/emu10k1_patch.c @@ -70,11 +70,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, loopend = sampleend; /* be sure loop points start < end */ - if (sp->v.loopstart >= sp->v.loopend) { - int tmp = sp->v.loopstart; - sp->v.loopstart = sp->v.loopend; - sp->v.loopend = tmp; - } + if (sp->v.loopstart >= sp->v.loopend) + swap(sp->v.loopstart, sp->v.loopend); /* compute true data size to be loaded */ truesize = sp->v.size + BLANK_HEAD_SIZE; diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index de2ecbe95d6c..90713741c2dc 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -526,7 +526,7 @@ static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu, if (!test_bit(gpr, icode->gpr_valid)) continue; if (in_kernel) - val = *(u32 *)&icode->gpr_map[gpr]; + val = *(__force u32 *)&icode->gpr_map[gpr]; else if (get_user(val, &icode->gpr_map[gpr])) return -EFAULT; snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val); @@ -560,8 +560,8 @@ static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu, if (!test_bit(tram, icode->tram_valid)) continue; if (in_kernel) { - val = *(u32 *)&icode->tram_data_map[tram]; - addr = *(u32 *)&icode->tram_addr_map[tram]; + val = *(__force u32 *)&icode->tram_data_map[tram]; + addr = *(__force u32 *)&icode->tram_addr_map[tram]; } else { if (get_user(val, &icode->tram_data_map[tram]) || get_user(addr, &icode->tram_addr_map[tram])) @@ -611,8 +611,8 @@ static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu, if (!test_bit(pc / 2, icode->code_valid)) continue; if (in_kernel) { - lo = *(u32 *)&icode->code[pc + 0]; - hi = *(u32 *)&icode->code[pc + 1]; + lo = *(__force u32 *)&icode->code[pc + 0]; + hi = *(__force u32 *)&icode->code[pc + 1]; } else { if (get_user(lo, &icode->code[pc + 0]) || get_user(hi, &icode->code[pc + 1])) @@ -666,7 +666,7 @@ static unsigned int *copy_tlv(const unsigned int __user *_tlv, bool in_kernel) if (!_tlv) return NULL; if (in_kernel) - memcpy(data, (void *)_tlv, sizeof(data)); + memcpy(data, (__force void *)_tlv, sizeof(data)); else if (copy_from_user(data, _tlv, sizeof(data))) return NULL; if (data[1] >= MAX_TLV_SIZE) @@ -676,7 +676,7 @@ static unsigned int *copy_tlv(const unsigned int __user *_tlv, bool in_kernel) return NULL; memcpy(tlv, data, sizeof(data)); if (in_kernel) { - memcpy(tlv + 2, (void *)(_tlv + 2), data[1]); + memcpy(tlv + 2, (__force void *)(_tlv + 2), data[1]); } else if (copy_from_user(tlv + 2, _tlv + 2, data[1])) { kfree(tlv); return NULL; @@ -693,7 +693,7 @@ static int copy_gctl(struct snd_emu10k1 *emu, if (emu->support_tlv) { if (in_kernel) - memcpy(gctl, (void *)&_gctl[idx], sizeof(*gctl)); + memcpy(gctl, (__force void *)&_gctl[idx], sizeof(*gctl)); else if (copy_from_user(gctl, &_gctl[idx], sizeof(*gctl))) return -EFAULT; return 0; @@ -701,7 +701,7 @@ static int copy_gctl(struct snd_emu10k1 *emu, octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl; if (in_kernel) - memcpy(gctl, (void *)&octl[idx], sizeof(*octl)); + memcpy(gctl, (__force void *)&octl[idx], sizeof(*octl)); else if (copy_from_user(gctl, &octl[idx], sizeof(*octl))) return -EFAULT; gctl->tlv = NULL; @@ -735,7 +735,7 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, for (i = 0, _id = icode->gpr_del_controls; i < icode->gpr_del_control_count; i++, _id++) { if (in_kernel) - id = *(struct snd_ctl_elem_id *)_id; + id = *(__force struct snd_ctl_elem_id *)_id; else if (copy_from_user(&id, _id, sizeof(id))) return -EFAULT; if (snd_emu10k1_look_for_ctl(emu, &id) == NULL) @@ -833,7 +833,7 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, knew.device = gctl->id.device; knew.subdevice = gctl->id.subdevice; knew.info = snd_emu10k1_gpr_ctl_info; - knew.tlv.p = copy_tlv(gctl->tlv, in_kernel); + knew.tlv.p = copy_tlv((__force const unsigned int __user *)gctl->tlv, in_kernel); if (knew.tlv.p) knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ; @@ -897,7 +897,7 @@ static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu, for (i = 0, _id = icode->gpr_del_controls; i < icode->gpr_del_control_count; i++, _id++) { if (in_kernel) - id = *(struct snd_ctl_elem_id *)_id; + id = *(__force struct snd_ctl_elem_id *)_id; else if (copy_from_user(&id, _id, sizeof(id))) return -EFAULT; down_write(&card->controls_rwsem); diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 69f9b100bd24..9f2b6097f486 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -290,7 +290,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, struct snd_pcm_runtime *runtime = substream->runtime; unsigned int silent_page, tmp; int voice, stereo, w_16; - unsigned char attn, send_amount[8]; + unsigned char send_amount[8]; unsigned char send_routing[8]; unsigned long flags; unsigned int pitch_target; @@ -313,7 +313,6 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu, /* volume parameters */ if (extra) { - attn = 0; memset(send_routing, 0, sizeof(send_routing)); send_routing[0] = 0; send_routing[1] = 1; @@ -779,7 +778,7 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_START: snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra); /* do we need this? */ snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[0]); - /* follow thru */ + /* fall through */ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE) @@ -929,7 +928,7 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream, } snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra); - /* follow thru */ + /* fall through */ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL); diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 39f79a6b5283..727eb3da1fda 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -2392,7 +2392,7 @@ static int snd_audiopci_probe(struct pci_dev *pci, static int dev; struct snd_card *card; struct ensoniq *ensoniq; - int err, pcm_devs[2]; + int err; if (dev >= SNDRV_CARDS) return -ENODEV; @@ -2412,7 +2412,6 @@ static int snd_audiopci_probe(struct pci_dev *pci, } card->private_data = ensoniq; - pcm_devs[0] = 0; pcm_devs[1] = 1; #ifdef CHIP1370 if ((err = snd_ensoniq_1370_mixer(ensoniq)) < 0) { snd_card_free(card); diff --git a/sound/pci/hda/dell_wmi_helper.c b/sound/pci/hda/dell_wmi_helper.c index 1b48a8c19d28..bbd6c87a4ed6 100644 --- a/sound/pci/hda/dell_wmi_helper.c +++ b/sound/pci/hda/dell_wmi_helper.c @@ -6,111 +6,18 @@ #if IS_ENABLED(CONFIG_DELL_LAPTOP) #include <linux/dell-led.h> -enum { - MICMUTE_LED_ON, - MICMUTE_LED_OFF, - MICMUTE_LED_FOLLOW_CAPTURE, - MICMUTE_LED_FOLLOW_MUTE, -}; - -static int dell_led_mode = MICMUTE_LED_FOLLOW_MUTE; -static int dell_capture; -static int dell_led_value; static int (*dell_micmute_led_set_func)(int); -static void (*dell_old_cap_hook)(struct hda_codec *, - struct snd_kcontrol *, - struct snd_ctl_elem_value *); - -static void call_micmute_led_update(void) -{ - int val; - - switch (dell_led_mode) { - case MICMUTE_LED_ON: - val = 1; - break; - case MICMUTE_LED_OFF: - val = 0; - break; - case MICMUTE_LED_FOLLOW_CAPTURE: - val = dell_capture; - break; - case MICMUTE_LED_FOLLOW_MUTE: - default: - val = !dell_capture; - break; - } - - if (val == dell_led_value) - return; - dell_led_value = val; - dell_micmute_led_set_func(dell_led_value); -} - -static void update_dell_wmi_micmute_led(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - if (dell_old_cap_hook) - dell_old_cap_hook(codec, kcontrol, ucontrol); - - if (!ucontrol || !dell_micmute_led_set_func) - return; - if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) { - /* TODO: How do I verify if it's a mono or stereo here? */ - dell_capture = (ucontrol->value.integer.value[0] || - ucontrol->value.integer.value[1]); - call_micmute_led_update(); - } -} -static int dell_mic_mute_led_mode_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) +static void dell_micmute_update(struct hda_codec *codec) { - static const char * const texts[] = { - "On", "Off", "Follow Capture", "Follow Mute", - }; - - return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); -} + struct hda_gen_spec *spec = codec->spec; -static int dell_mic_mute_led_mode_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = dell_led_mode; - return 0; + dell_micmute_led_set_func(spec->micmute_led.led_value); } -static int dell_mic_mute_led_mode_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - unsigned int mode; - - mode = ucontrol->value.enumerated.item[0]; - if (mode > MICMUTE_LED_FOLLOW_MUTE) - mode = MICMUTE_LED_FOLLOW_MUTE; - if (mode == dell_led_mode) - return 0; - dell_led_mode = mode; - call_micmute_led_update(); - return 1; -} - -static const struct snd_kcontrol_new dell_mic_mute_mode_ctls[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic Mute-LED Mode", - .info = dell_mic_mute_led_mode_info, - .get = dell_mic_mute_led_mode_get, - .put = dell_mic_mute_led_mode_put, - }, - {} -}; - static void alc_fixup_dell_wmi(struct hda_codec *codec, const struct hda_fixup *fix, int action) { - struct alc_spec *spec = codec->spec; bool removefunc = false; if (action == HDA_FIXUP_ACT_PROBE) { @@ -121,25 +28,14 @@ static void alc_fixup_dell_wmi(struct hda_codec *codec, return; } - removefunc = true; - if (dell_micmute_led_set_func(false) >= 0) { - dell_led_value = 0; - if (spec->gen.num_adc_nids > 1 && !spec->gen.dyn_adc_switch) - codec_dbg(codec, "Skipping micmute LED control due to several ADCs"); - else { - dell_old_cap_hook = spec->gen.cap_sync_hook; - spec->gen.cap_sync_hook = update_dell_wmi_micmute_led; - removefunc = false; - add_mixer(spec, dell_mic_mute_mode_ctls); - } - } - + removefunc = (dell_micmute_led_set_func(false) < 0) || + (snd_hda_gen_add_micmute_led(codec, + dell_micmute_update) < 0); } if (dell_micmute_led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) { symbol_put(dell_micmute_led_set); dell_micmute_led_set_func = NULL; - dell_old_cap_hook = NULL; } } diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 20a171ac4bb2..0a5085537034 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -37,15 +37,8 @@ #include "hda_jack.h" #include <sound/hda_hwdep.h> -#ifdef CONFIG_PM -#define codec_in_pm(codec) atomic_read(&(codec)->core.in_pm) -#define hda_codec_is_power_on(codec) \ - (!pm_runtime_suspended(hda_codec_dev(codec))) -#else -#define codec_in_pm(codec) 0 -#define hda_codec_is_power_on(codec) 1 -#endif - +#define codec_in_pm(codec) snd_hdac_is_in_pm(&codec->core) +#define hda_codec_is_power_on(codec) snd_hdac_is_power_on(&codec->core) #define codec_has_epss(codec) \ ((codec)->core.power_caps & AC_PWRST_EPSS) #define codec_has_clkstop(codec) \ @@ -858,6 +851,39 @@ static void snd_hda_codec_dev_release(struct device *dev) kfree(codec); } +#define DEV_NAME_LEN 31 + +static int snd_hda_codec_device_init(struct hda_bus *bus, struct snd_card *card, + unsigned int codec_addr, struct hda_codec **codecp) +{ + char name[DEV_NAME_LEN]; + struct hda_codec *codec; + int err; + + dev_dbg(card->dev, "%s: entry\n", __func__); + + if (snd_BUG_ON(!bus)) + return -EINVAL; + if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS)) + return -EINVAL; + + codec = kzalloc(sizeof(*codec), GFP_KERNEL); + if (!codec) + return -ENOMEM; + + sprintf(name, "hdaudioC%dD%d", card->number, codec_addr); + err = snd_hdac_device_init(&codec->core, &bus->core, name, codec_addr); + if (err < 0) { + kfree(codec); + return err; + } + + codec->core.type = HDA_DEV_LEGACY; + *codecp = codec; + + return err; +} + /** * snd_hda_codec_new - create a HDA codec * @bus: the bus to assign @@ -869,7 +895,19 @@ static void snd_hda_codec_dev_release(struct device *dev) int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, unsigned int codec_addr, struct hda_codec **codecp) { - struct hda_codec *codec; + int ret; + + ret = snd_hda_codec_device_init(bus, card, codec_addr, codecp); + if (ret < 0) + return ret; + + return snd_hda_codec_device_new(bus, card, codec_addr, *codecp); +} +EXPORT_SYMBOL_GPL(snd_hda_codec_new); + +int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, + unsigned int codec_addr, struct hda_codec *codec) +{ char component[31]; hda_nid_t fg; int err; @@ -879,25 +917,14 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, .dev_free = snd_hda_codec_dev_free, }; + dev_dbg(card->dev, "%s: entry\n", __func__); + if (snd_BUG_ON(!bus)) return -EINVAL; if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS)) return -EINVAL; - codec = kzalloc(sizeof(*codec), GFP_KERNEL); - if (!codec) - return -ENOMEM; - - sprintf(component, "hdaudioC%dD%d", card->number, codec_addr); - err = snd_hdac_device_init(&codec->core, &bus->core, component, - codec_addr); - if (err < 0) { - kfree(codec); - return err; - } - codec->core.dev.release = snd_hda_codec_dev_release; - codec->core.type = HDA_DEV_LEGACY; codec->core.exec_verb = codec_exec_verb; codec->bus = bus; @@ -957,15 +984,13 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, if (err < 0) goto error; - if (codecp) - *codecp = codec; return 0; error: put_device(hda_codec_dev(codec)); return err; } -EXPORT_SYMBOL_GPL(snd_hda_codec_new); +EXPORT_SYMBOL_GPL(snd_hda_codec_device_new); /** * snd_hda_codec_update_widgets - Refresh widget caps and pin defaults @@ -2846,14 +2871,13 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec) { unsigned int state; - atomic_inc(&codec->core.in_pm); - + snd_hdac_enter_pm(&codec->core); if (codec->patch_ops.suspend) codec->patch_ops.suspend(codec); hda_cleanup_all_streams(codec); state = hda_set_power_state(codec, AC_PWRST_D3); update_power_acct(codec, true); - atomic_dec(&codec->core.in_pm); + snd_hdac_leave_pm(&codec->core); return state; } @@ -2862,8 +2886,7 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec) */ static void hda_call_codec_resume(struct hda_codec *codec) { - atomic_inc(&codec->core.in_pm); - + snd_hdac_enter_pm(&codec->core); if (codec->core.regmap) regcache_mark_dirty(codec->core.regmap); @@ -2886,7 +2909,7 @@ static void hda_call_codec_resume(struct hda_codec *codec) hda_jackpoll_work(&codec->jackpoll_work.work); else snd_hda_jack_report_sync(codec); - atomic_dec(&codec->core.in_pm); + snd_hdac_leave_pm(&codec->core); } static int hda_codec_runtime_suspend(struct device *dev) @@ -2992,6 +3015,7 @@ int snd_hda_codec_build_controls(struct hda_codec *codec) sync_power_up_states(codec); return 0; } +EXPORT_SYMBOL_GPL(snd_hda_codec_build_controls); /* * PCM stuff @@ -3197,6 +3221,7 @@ int snd_hda_codec_parse_pcms(struct hda_codec *codec) return 0; } +EXPORT_SYMBOL_GPL(snd_hda_codec_parse_pcms); /* assign all PCMs of the given codec */ int snd_hda_codec_build_pcms(struct hda_codec *codec) @@ -3252,8 +3277,8 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, for (; knew->name; knew++) { struct snd_kcontrol *kctl; int addr = 0, idx = 0; - if (knew->iface == -1) /* skip this codec private value */ - continue; + if (knew->iface == (__force snd_ctl_elem_iface_t)-1) + continue; /* skip this codec private value */ for (;;) { kctl = snd_ctl_new1(knew, codec); if (!kctl) @@ -3843,7 +3868,7 @@ EXPORT_SYMBOL_GPL(snd_hda_correct_pin_ctl); * This function is a helper to set a pin ctl value more safely. * It corrects the pin ctl value via snd_hda_correct_pin_ctl(), stores the * value in pin target array via snd_hda_codec_set_pin_target(), then - * actually writes the value via either snd_hda_codec_update_cache() or + * actually writes the value via either snd_hda_codec_write_cache() or * snd_hda_codec_write() depending on @cached flag. */ int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, @@ -3852,7 +3877,7 @@ int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, val = snd_hda_correct_pin_ctl(codec, pin, val); snd_hda_codec_set_pin_target(codec, pin, val); if (cached) - return snd_hda_codec_update_cache(codec, pin, 0, + return snd_hda_codec_write_cache(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); else return snd_hda_codec_write(codec, pin, 0, diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index a8b1b31f161c..0d98bb9068b1 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -84,6 +84,7 @@ struct hda_bus { */ typedef int (*hda_codec_patch_t)(struct hda_codec *); +#define HDA_CODEC_ID_SKIP_PROBE 0x00000001 #define HDA_CODEC_ID_GENERIC_HDMI 0x00000101 #define HDA_CODEC_ID_GENERIC 0x00000201 @@ -308,6 +309,8 @@ struct hda_codec { */ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card, unsigned int codec_addr, struct hda_codec **codecp); +int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, + unsigned int codec_addr, struct hda_codec *codec); int snd_hda_codec_configure(struct hda_codec *codec); int snd_hda_codec_update_widgets(struct hda_codec *codec); @@ -382,9 +385,6 @@ snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, return snd_hdac_regmap_write(&codec->core, nid, verb, parm); } -#define snd_hda_codec_update_cache(codec, nid, flags, verb, parm) \ - snd_hda_codec_write_cache(codec, nid, flags, verb, parm) - /* the struct for codec->pin_configs */ struct hda_pincfg { hda_nid_t nid; diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index db773e219aaa..579984ecdec3 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -209,7 +209,7 @@ static void parse_user_hints(struct hda_codec *codec) */ #define update_pin_ctl(codec, pin, val) \ - snd_hda_codec_update_cache(codec, pin, 0, \ + snd_hda_codec_write_cache(codec, pin, 0, \ AC_VERB_SET_PIN_WIDGET_CONTROL, val) /* restore the pinctl based on the cached value */ @@ -898,7 +898,7 @@ void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path, hda_nid_t nid = path->path[i]; if (enable && path->multi[i]) - snd_hda_codec_update_cache(codec, nid, 0, + snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, path->idx[i]); if (has_amp_in(codec, path, i)) @@ -930,7 +930,7 @@ static void set_pin_eapd(struct hda_codec *codec, hda_nid_t pin, bool enable) return; if (codec->inv_eapd) enable = !enable; - snd_hda_codec_update_cache(codec, pin, 0, + snd_hda_codec_write_cache(codec, pin, 0, AC_VERB_SET_EAPD_BTLENABLE, enable ? 0x02 : 0x00); } @@ -3900,6 +3900,142 @@ static int parse_mic_boost(struct hda_codec *codec) } /* + * mic mute LED hook helpers + */ +enum { + MICMUTE_LED_ON, + MICMUTE_LED_OFF, + MICMUTE_LED_FOLLOW_CAPTURE, + MICMUTE_LED_FOLLOW_MUTE, +}; + +static void call_micmute_led_update(struct hda_codec *codec) +{ + struct hda_gen_spec *spec = codec->spec; + unsigned int val; + + switch (spec->micmute_led.led_mode) { + case MICMUTE_LED_ON: + val = 1; + break; + case MICMUTE_LED_OFF: + val = 0; + break; + case MICMUTE_LED_FOLLOW_CAPTURE: + val = !!spec->micmute_led.capture; + break; + case MICMUTE_LED_FOLLOW_MUTE: + default: + val = !spec->micmute_led.capture; + break; + } + + if (val == spec->micmute_led.led_value) + return; + spec->micmute_led.led_value = val; + if (spec->micmute_led.update) + spec->micmute_led.update(codec); +} + +static void update_micmute_led(struct hda_codec *codec, + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_gen_spec *spec = codec->spec; + unsigned int mask; + + if (spec->micmute_led.old_hook) + spec->micmute_led.old_hook(codec, kcontrol, ucontrol); + + if (!ucontrol) + return; + mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + if (!strcmp("Capture Switch", ucontrol->id.name)) { + /* TODO: How do I verify if it's a mono or stereo here? */ + if (ucontrol->value.integer.value[0] || + ucontrol->value.integer.value[1]) + spec->micmute_led.capture |= mask; + else + spec->micmute_led.capture &= ~mask; + call_micmute_led_update(codec); + } +} + +static int micmute_led_mode_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static const char * const texts[] = { + "On", "Off", "Follow Capture", "Follow Mute", + }; + + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); +} + +static int micmute_led_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct hda_gen_spec *spec = codec->spec; + + ucontrol->value.enumerated.item[0] = spec->micmute_led.led_mode; + return 0; +} + +static int micmute_led_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct hda_gen_spec *spec = codec->spec; + unsigned int mode; + + mode = ucontrol->value.enumerated.item[0]; + if (mode > MICMUTE_LED_FOLLOW_MUTE) + mode = MICMUTE_LED_FOLLOW_MUTE; + if (mode == spec->micmute_led.led_mode) + return 0; + spec->micmute_led.led_mode = mode; + call_micmute_led_update(codec); + return 1; +} + +static const struct snd_kcontrol_new micmute_led_mode_ctl = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic Mute-LED Mode", + .info = micmute_led_mode_info, + .get = micmute_led_mode_get, + .put = micmute_led_mode_put, +}; + +/** + * snd_hda_gen_add_micmute_led - helper for setting up mic mute LED hook + * @codec: the HDA codec + * @hook: the callback for updating LED + * + * Called from the codec drivers for offering the mic mute LED controls. + * When established, it sets up cap_sync_hook and triggers the callback at + * each time when the capture mixer switch changes. The callback is supposed + * to update the LED accordingly. + * + * Returns 0 if the hook is established or a negative error code. + */ +int snd_hda_gen_add_micmute_led(struct hda_codec *codec, + void (*hook)(struct hda_codec *)) +{ + struct hda_gen_spec *spec = codec->spec; + + spec->micmute_led.led_mode = MICMUTE_LED_FOLLOW_MUTE; + spec->micmute_led.capture = 0; + spec->micmute_led.led_value = 0; + spec->micmute_led.old_hook = spec->cap_sync_hook; + spec->micmute_led.update = hook; + spec->cap_sync_hook = update_micmute_led; + if (!snd_hda_gen_add_kctl(spec, NULL, &micmute_led_mode_ctl)) + return -ENOMEM; + return 0; +} +EXPORT_SYMBOL_GPL(snd_hda_gen_add_micmute_led); + +/* * parse digital I/Os and set up NIDs in BIOS auto-parse mode */ static void parse_digital(struct hda_codec *codec) @@ -5837,7 +5973,7 @@ static void clear_unsol_on_unused_pins(struct hda_codec *codec) hda_nid_t nid = pin->nid; if (is_jack_detectable(codec, nid) && !snd_hda_jack_tbl_get(codec, nid)) - snd_hda_codec_update_cache(codec, nid, 0, + snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_UNSOLICITED_ENABLE, 0); } } diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 61772317de46..10123664fa61 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -86,6 +86,16 @@ struct badness_table { extern const struct badness_table hda_main_out_badness; extern const struct badness_table hda_extra_out_badness; +struct hda_micmute_hook { + unsigned int led_mode; + unsigned int capture; + unsigned int led_value; + void (*update)(struct hda_codec *codec); + void (*old_hook)(struct hda_codec *codec, + struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +}; + struct hda_gen_spec { char stream_name_analog[32]; /* analog PCM stream */ const struct hda_pcm_stream *stream_analog_playback; @@ -276,6 +286,9 @@ struct hda_gen_spec { struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); + /* mic mute LED hook; called via cap_sync_hook */ + struct hda_micmute_hook micmute_led; + /* PCM hooks */ void (*pcm_playback_hook)(struct hda_pcm_stream *hinfo, struct hda_codec *codec, @@ -342,4 +355,7 @@ unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on); int snd_hda_gen_fix_pin_power(struct hda_codec *codec, hda_nid_t pin); +int snd_hda_gen_add_micmute_led(struct hda_codec *codec, + void (*hook)(struct hda_codec *)); + #endif /* __SOUND_HDA_GENERIC_H */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1ae1850b3bfd..1b2ce304152a 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1319,15 +1319,16 @@ static const struct vga_switcheroo_client_ops azx_vs_ops = { static int register_vga_switcheroo(struct azx *chip) { struct hda_intel *hda = container_of(chip, struct hda_intel, chip); + struct pci_dev *p; int err; if (!hda->use_vga_switcheroo) return 0; - /* FIXME: currently only handling DIS controller - * is there any machine with two switchable HDMI audio controllers? - */ - err = vga_switcheroo_register_audio_client(chip->pci, &azx_vs_ops, - VGA_SWITCHEROO_DIS); + + p = get_bound_vga(chip->pci); + err = vga_switcheroo_register_audio_client(chip->pci, &azx_vs_ops, p); + pci_dev_put(p); + if (err < 0) return err; hda->vga_switcheroo_registered = 1; @@ -1429,7 +1430,7 @@ static struct pci_dev *get_bound_vga(struct pci_dev *pci) p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus), pci->bus->number, 0); if (p) { - if ((p->class >> 8) == PCI_CLASS_DISPLAY_VGA) + if ((p->class >> 16) == PCI_BASE_CLASS_DISPLAY) return p; pci_dev_put(p); } @@ -2207,7 +2208,7 @@ out_free: */ static struct snd_pci_quirk power_save_blacklist[] = { /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ - SND_PCI_QUIRK(0x1849, 0x0c0c, "Asrock B85M-ITX", 0), + SND_PCI_QUIRK(0x1849, 0xc892, "Asrock B85M-ITX", 0), /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ SND_PCI_QUIRK(0x1849, 0x7662, "Asrock H81M-HDS", 0), /* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */ @@ -2535,7 +2536,8 @@ static const struct pci_device_id azx_ids[] = { .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, /* AMD Raven */ { PCI_DEVICE(0x1022, 0x15e3), - .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, + .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB | + AZX_DCAPS_PM_RUNTIME }, /* ATI HDMI */ { PCI_DEVICE(0x1002, 0x0002), .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS }, diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 757857313426..fd476fb40e1b 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -148,7 +148,7 @@ static void ad_vmaster_eapd_hook(void *private_data, int enabled) return; if (codec->inv_eapd) enabled = !enabled; - snd_hda_codec_update_cache(codec, spec->eapd_nid, 0, + snd_hda_codec_write_cache(codec, spec->eapd_nid, 0, AC_VERB_SET_EAPD_BTLENABLE, enabled ? 0x02 : 0x00); } @@ -991,7 +991,7 @@ static void ad1884_vmaster_hp_gpio_hook(void *private_data, int enabled) if (spec->eapd_nid) ad_vmaster_eapd_hook(private_data, enabled); - snd_hda_codec_update_cache(codec, 0x01, 0, + snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, enabled ? 0x00 : 0x02); } diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 321e95c409c1..0166a3d7cd55 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -897,7 +897,7 @@ struct ca0132_spec { const struct hda_verb *base_init_verbs; const struct hda_verb *base_exit_verbs; const struct hda_verb *chip_init_verbs; - const struct hda_verb *sbz_init_verbs; + const struct hda_verb *desktop_init_verbs; struct hda_verb *spec_init_verbs; struct auto_pin_cfg autocfg; @@ -965,9 +965,11 @@ struct ca0132_spec { long cur_ctl_vals[TUNING_CTLS_COUNT]; #endif /* - * Sound Blaster Z PCI region 2 iomem, used for input and output - * switching, and other unknown commands. + * The Recon3D, Sound Blaster Z, Sound Blaster ZxR, and Sound Blaster + * AE-5 all use PCI region 2 to toggle GPIO and other currently unknown + * things. */ + bool use_pci_mmio; void __iomem *mem_base; /* @@ -994,6 +996,7 @@ enum { QUIRK_ALIENWARE_M17XR4, QUIRK_SBZ, QUIRK_R3DI, + QUIRK_R3D, }; static const struct hda_pintbl alienware_pincfgs[] = { @@ -1025,6 +1028,21 @@ static const struct hda_pintbl sbz_pincfgs[] = { {} }; +/* Recon3D pin configs taken from Windows Driver */ +static const struct hda_pintbl r3d_pincfgs[] = { + { 0x0b, 0x01014110 }, /* Port G -- Lineout FRONT L/R */ + { 0x0c, 0x014510f0 }, /* SPDIF Out 1 */ + { 0x0d, 0x014510f0 }, /* Digital Out */ + { 0x0e, 0x01c520f0 }, /* SPDIF In */ + { 0x0f, 0x0221401f }, /* Port A -- BackPanel HP */ + { 0x10, 0x01016011 }, /* Port D -- Center/LFE or FP Hp */ + { 0x11, 0x01011014 }, /* Port B -- LineMicIn2 / Rear L/R */ + { 0x12, 0x02a090f0 }, /* Port C -- LineIn1 */ + { 0x13, 0x908700f0 }, /* What U Hear In*/ + { 0x18, 0x50d000f0 }, /* N/A */ + {} +}; + /* Recon3D integrated pin configs taken from Windows Driver */ static const struct hda_pintbl r3di_pincfgs[] = { { 0x0b, 0x01014110 }, /* Port G -- Lineout FRONT L/R */ @@ -1050,6 +1068,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = { SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI), SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI), SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI), + SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D), {} }; @@ -3073,6 +3092,24 @@ static bool dspload_wait_loaded(struct hda_codec *codec) */ /* + * For cards with PCI-E region2 (Sound Blaster Z/ZxR, Recon3D, and AE-5) + * the mmio address 0x320 is used to set GPIO pins. The format for the data + * The first eight bits are just the number of the pin. So far, I've only seen + * this number go to 7. + */ +static void ca0132_mmio_gpio_set(struct hda_codec *codec, unsigned int gpio_pin, + bool enable) +{ + struct ca0132_spec *spec = codec->spec; + unsigned short gpio_data; + + gpio_data = gpio_pin & 0xF; + gpio_data |= ((enable << 8) & 0x100); + + writew(gpio_data, spec->mem_base + 0x320); +} + +/* * Sets up the GPIO pins so that they are discoverable. If this isn't done, * the card shows as having no GPIO pins. */ @@ -3947,15 +3984,19 @@ static int ca0132_alt_select_out(struct hda_codec *codec) /*speaker out config*/ switch (spec->quirk) { case QUIRK_SBZ: - writew(0x0007, spec->mem_base + 0x320); - writew(0x0104, spec->mem_base + 0x320); - writew(0x0101, spec->mem_base + 0x320); + ca0132_mmio_gpio_set(codec, 7, false); + ca0132_mmio_gpio_set(codec, 4, true); + ca0132_mmio_gpio_set(codec, 1, true); chipio_set_control_param(codec, 0x0D, 0x18); break; case QUIRK_R3DI: chipio_set_control_param(codec, 0x0D, 0x24); r3di_gpio_out_set(codec, R3DI_LINE_OUT); break; + case QUIRK_R3D: + chipio_set_control_param(codec, 0x0D, 0x24); + ca0132_mmio_gpio_set(codec, 1, true); + break; } /* disable headphone node */ @@ -3983,15 +4024,19 @@ static int ca0132_alt_select_out(struct hda_codec *codec) /* Headphone out config*/ switch (spec->quirk) { case QUIRK_SBZ: - writew(0x0107, spec->mem_base + 0x320); - writew(0x0104, spec->mem_base + 0x320); - writew(0x0001, spec->mem_base + 0x320); + ca0132_mmio_gpio_set(codec, 7, true); + ca0132_mmio_gpio_set(codec, 4, true); + ca0132_mmio_gpio_set(codec, 1, false); chipio_set_control_param(codec, 0x0D, 0x12); break; case QUIRK_R3DI: chipio_set_control_param(codec, 0x0D, 0x21); r3di_gpio_out_set(codec, R3DI_HEADPHONE_OUT); break; + case QUIRK_R3D: + chipio_set_control_param(codec, 0x0D, 0x21); + ca0132_mmio_gpio_set(codec, 0x1, false); + break; } snd_hda_codec_write(codec, spec->out_pins[0], 0, @@ -4025,15 +4070,19 @@ static int ca0132_alt_select_out(struct hda_codec *codec) /* Surround out config*/ switch (spec->quirk) { case QUIRK_SBZ: - writew(0x0007, spec->mem_base + 0x320); - writew(0x0104, spec->mem_base + 0x320); - writew(0x0101, spec->mem_base + 0x320); + ca0132_mmio_gpio_set(codec, 7, false); + ca0132_mmio_gpio_set(codec, 4, true); + ca0132_mmio_gpio_set(codec, 1, true); chipio_set_control_param(codec, 0x0D, 0x18); break; case QUIRK_R3DI: chipio_set_control_param(codec, 0x0D, 0x24); r3di_gpio_out_set(codec, R3DI_LINE_OUT); break; + case QUIRK_R3D: + ca0132_mmio_gpio_set(codec, 1, true); + chipio_set_control_param(codec, 0x0D, 0x24); + break; } /* enable line out node */ pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0, @@ -4291,7 +4340,8 @@ static int ca0132_alt_select_in(struct hda_codec *codec) case REAR_MIC: switch (spec->quirk) { case QUIRK_SBZ: - writew(0x0000, spec->mem_base + 0x320); + case QUIRK_R3D: + ca0132_mmio_gpio_set(codec, 0, false); tmp = FLOAT_THREE; break; case QUIRK_R3DI: @@ -4323,7 +4373,8 @@ static int ca0132_alt_select_in(struct hda_codec *codec) ca0132_mic_boost_set(codec, 0); switch (spec->quirk) { case QUIRK_SBZ: - writew(0x0000, spec->mem_base + 0x320); + case QUIRK_R3D: + ca0132_mmio_gpio_set(codec, 0, false); break; case QUIRK_R3DI: r3di_gpio_mic_set(codec, R3DI_REAR_MIC); @@ -4349,8 +4400,9 @@ static int ca0132_alt_select_in(struct hda_codec *codec) case FRONT_MIC: switch (spec->quirk) { case QUIRK_SBZ: - writew(0x0100, spec->mem_base + 0x320); - writew(0x0005, spec->mem_base + 0x320); + case QUIRK_R3D: + ca0132_mmio_gpio_set(codec, 0, true); + ca0132_mmio_gpio_set(codec, 5, false); tmp = FLOAT_THREE; break; case QUIRK_R3DI: @@ -5516,8 +5568,7 @@ static int ca0132_alt_add_effect_slider(struct hda_codec *codec, hda_nid_t nid, sprintf(namestr, "FX: %s %s Volume", pfx, dirstr[dir]); - knew.tlv.c = 0; - knew.tlv.p = 0; + knew.tlv.c = NULL; switch (nid) { case XBASS_XOVER: @@ -5729,11 +5780,11 @@ static const struct snd_kcontrol_new ca0132_mixer[] = { }; /* - * SBZ specific control mixer. Removes auto-detect for mic, and adds surround - * controls. Also sets both the Front Playback and Capture Volume controls to - * alt so they set the DSP's decibel level. + * Desktop specific control mixer. Removes auto-detect for mic, and adds + * surround controls. Also sets both the Front Playback and Capture Volume + * controls to alt so they set the DSP's decibel level. */ -static const struct snd_kcontrol_new sbz_mixer[] = { +static const struct snd_kcontrol_new desktop_mixer[] = { CA0132_ALT_CODEC_VOL("Front Playback Volume", 0x02, HDA_OUTPUT), CA0132_CODEC_MUTE("Front Playback Switch", VNID_SPK, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x04, 0, HDA_OUTPUT), @@ -5804,8 +5855,8 @@ static int ca0132_build_controls(struct hda_codec *codec) */ num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT; for (i = 0; i < num_fx; i++) { - /* SBZ breaks if Echo Cancellation is used */ - if (spec->quirk == QUIRK_SBZ) { + /* SBZ and R3D break if Echo Cancellation is used. */ + if (spec->quirk == QUIRK_SBZ || spec->quirk == QUIRK_R3D) { if (i == (ECHO_CANCELLATION - IN_EFFECT_START_NID + OUT_EFFECTS_COUNT)) continue; @@ -6187,10 +6238,10 @@ static void ca0132_refresh_widget_caps(struct hda_codec *codec) } /* - * Recon3Di r3di_setup_defaults sub functions. + * Recon3D r3d_setup_defaults sub functions. */ -static void r3di_dsp_scp_startup(struct hda_codec *codec) +static void r3d_dsp_scp_startup(struct hda_codec *codec) { unsigned int tmp; @@ -6211,7 +6262,7 @@ static void r3di_dsp_scp_startup(struct hda_codec *codec) } -static void r3di_dsp_initial_mic_setup(struct hda_codec *codec) +static void r3d_dsp_initial_mic_setup(struct hda_codec *codec) { unsigned int tmp; @@ -6421,10 +6472,10 @@ static void ca0132_setup_defaults(struct hda_codec *codec) } /* - * Setup default parameters for Recon3Di DSP. + * Setup default parameters for Recon3D/Recon3Di DSP. */ -static void r3di_setup_defaults(struct hda_codec *codec) +static void r3d_setup_defaults(struct hda_codec *codec) { struct ca0132_spec *spec = codec->spec; unsigned int tmp; @@ -6434,9 +6485,9 @@ static void r3di_setup_defaults(struct hda_codec *codec) if (spec->dsp_state != DSP_DOWNLOADED) return; - r3di_dsp_scp_startup(codec); + r3d_dsp_scp_startup(codec); - r3di_dsp_initial_mic_setup(codec); + r3d_dsp_initial_mic_setup(codec); /*remove DSP headroom*/ tmp = FLOAT_ZERO; @@ -6450,7 +6501,8 @@ static void r3di_setup_defaults(struct hda_codec *codec) /* Set speaker source? */ dspio_set_uint_param(codec, 0x32, 0x00, tmp); - r3di_gpio_dsp_status_set(codec, R3DI_DSP_DOWNLOADED); + if (spec->quirk == QUIRK_R3DI) + r3di_gpio_dsp_status_set(codec, R3DI_DSP_DOWNLOADED); /* Setup effect defaults */ num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1; @@ -6462,7 +6514,6 @@ static void r3di_setup_defaults(struct hda_codec *codec) ca0132_effects[idx].def_vals[i]); } } - } /* @@ -6727,7 +6778,12 @@ static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb) static void amic_callback(struct hda_codec *codec, struct hda_jack_callback *cb) { - ca0132_select_mic(codec); + struct ca0132_spec *spec = codec->spec; + + if (spec->use_alt_functions) + ca0132_alt_select_in(codec); + else + ca0132_select_mic(codec); } static void ca0132_init_unsol(struct hda_codec *codec) @@ -6798,8 +6854,8 @@ static struct hda_verb ca0132_init_verbs0[] = { {} }; -/* Extra init verbs for SBZ */ -static struct hda_verb sbz_init_verbs[] = { +/* Extra init verbs for desktop cards. */ +static struct hda_verb ca0132_init_verbs1[] = { {0x15, 0x70D, 0x20}, {0x15, 0x70E, 0x19}, {0x15, 0x707, 0x00}, @@ -6891,16 +6947,12 @@ static void sbz_region2_exit(struct hda_codec *codec) writeb(0x0, spec->mem_base + 0x100); for (i = 0; i < 8; i++) writeb(0xb3, spec->mem_base + 0x304); - /* - * I believe these are GPIO, with the right most hex digit being the - * gpio pin, and the second digit being on or off. We see this more in - * the input/output select functions. - */ - writew(0x0000, spec->mem_base + 0x320); - writew(0x0001, spec->mem_base + 0x320); - writew(0x0104, spec->mem_base + 0x320); - writew(0x0005, spec->mem_base + 0x320); - writew(0x0007, spec->mem_base + 0x320); + + ca0132_mmio_gpio_set(codec, 0, false); + ca0132_mmio_gpio_set(codec, 1, false); + ca0132_mmio_gpio_set(codec, 4, true); + ca0132_mmio_gpio_set(codec, 5, false); + ca0132_mmio_gpio_set(codec, 7, false); } static void sbz_set_pin_ctl_default(struct hda_codec *codec) @@ -6916,7 +6968,7 @@ static void sbz_set_pin_ctl_default(struct hda_codec *codec) AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00); } -static void sbz_clear_unsolicited(struct hda_codec *codec) +static void ca0132_clear_unsolicited(struct hda_codec *codec) { hda_nid_t pins[7] = {0x0B, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13}; unsigned int i; @@ -6969,21 +7021,22 @@ static void sbz_exit_chip(struct hda_codec *codec) chipio_set_control_param(codec, 0x0D, 0x24); - sbz_clear_unsolicited(codec); + ca0132_clear_unsolicited(codec); sbz_set_pin_ctl_default(codec); snd_hda_codec_write(codec, 0x0B, 0, AC_VERB_SET_EAPD_BTLENABLE, 0x00); - if (dspload_is_loaded(codec)) - dsp_reset(codec); - - snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, - VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x00); - sbz_region2_exit(codec); } +static void r3d_exit_chip(struct hda_codec *codec) +{ + ca0132_clear_unsolicited(codec); + snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00); + snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x5b); +} + static void ca0132_exit_chip(struct hda_codec *codec) { /* put any chip cleanup stuffs here. */ @@ -7098,9 +7151,27 @@ static void sbz_pre_dsp_setup(struct hda_codec *codec) AC_VERB_SET_PIN_WIDGET_CONTROL, 0x44); } -/* - * Extra commands that don't really fit anywhere else. - */ +static void r3d_pre_dsp_setup(struct hda_codec *codec) +{ + + snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xfc); + snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xfd); + snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xfe); + snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xff); + + chipio_write(codec, 0x18b0a4, 0x000000c2); + + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x1E); + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x1C); + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_8051_DATA_WRITE, 0x5B); + + snd_hda_codec_write(codec, 0x11, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x44); +} + static void r3di_pre_dsp_setup(struct hda_codec *codec) { chipio_write(codec, 0x18b0a4, 0x000000c2); @@ -7125,13 +7196,12 @@ static void r3di_pre_dsp_setup(struct hda_codec *codec) AC_VERB_SET_PIN_WIDGET_CONTROL, 0x04); } - /* * These are sent before the DSP is downloaded. Not sure * what they do, or if they're necessary. Could possibly * be removed. Figure they're better to leave in. */ -static void sbz_region2_startup(struct hda_codec *codec) +static void ca0132_mmio_init(struct hda_codec *codec) { struct ca0132_spec *spec = codec->spec; @@ -7171,7 +7241,7 @@ static void ca0132_alt_init(struct hda_codec *codec) ca0132_gpio_init(codec); sbz_pre_dsp_setup(codec); snd_hda_sequence_write(codec, spec->chip_init_verbs); - snd_hda_sequence_write(codec, spec->sbz_init_verbs); + snd_hda_sequence_write(codec, spec->desktop_init_verbs); break; case QUIRK_R3DI: codec_dbg(codec, "R3DI alt_init"); @@ -7182,6 +7252,11 @@ static void ca0132_alt_init(struct hda_codec *codec) snd_hda_sequence_write(codec, spec->chip_init_verbs); snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x6FF, 0xC4); break; + case QUIRK_R3D: + r3d_pre_dsp_setup(codec); + snd_hda_sequence_write(codec, spec->chip_init_verbs); + snd_hda_sequence_write(codec, spec->desktop_init_verbs); + break; } } @@ -7218,8 +7293,8 @@ static int ca0132_init(struct hda_codec *codec) spec->dsp_state = DSP_DOWNLOAD_INIT; spec->curr_chip_addx = INVALID_CHIP_ADDRESS; - if (spec->quirk == QUIRK_SBZ) - sbz_region2_startup(codec); + if (spec->use_pci_mmio) + ca0132_mmio_init(codec); snd_hda_power_up_pm(codec); @@ -7236,14 +7311,13 @@ static int ca0132_init(struct hda_codec *codec) ca0132_refresh_widget_caps(codec); - if (spec->quirk == QUIRK_SBZ) - writew(0x0107, spec->mem_base + 0x320); - switch (spec->quirk) { case QUIRK_R3DI: - r3di_setup_defaults(codec); + case QUIRK_R3D: + r3d_setup_defaults(codec); break; case QUIRK_SBZ: + sbz_setup_defaults(codec); break; default: ca0132_setup_defaults(codec); @@ -7274,20 +7348,12 @@ static int ca0132_init(struct hda_codec *codec) ca0132_gpio_setup(codec); snd_hda_sequence_write(codec, spec->spec_init_verbs); - switch (spec->quirk) { - case QUIRK_SBZ: - sbz_setup_defaults(codec); - ca0132_alt_select_out(codec); - ca0132_alt_select_in(codec); - break; - case QUIRK_R3DI: + if (spec->use_alt_functions) { ca0132_alt_select_out(codec); ca0132_alt_select_in(codec); - break; - default: + } else { ca0132_select_out(codec); ca0132_select_mic(codec); - break; } snd_hda_jack_report_sync(codec); @@ -7316,16 +7382,17 @@ static void ca0132_free(struct hda_codec *codec) case QUIRK_SBZ: sbz_exit_chip(codec); break; + case QUIRK_R3D: + r3d_exit_chip(codec); + break; case QUIRK_R3DI: r3di_gpio_shutdown(codec); - snd_hda_sequence_write(codec, spec->base_exit_verbs); - ca0132_exit_chip(codec); - break; - default: - snd_hda_sequence_write(codec, spec->base_exit_verbs); - ca0132_exit_chip(codec); break; } + + snd_hda_sequence_write(codec, spec->base_exit_verbs); + ca0132_exit_chip(codec); + snd_hda_power_down(codec); if (spec->mem_base) iounmap(spec->mem_base); @@ -7386,8 +7453,15 @@ static void ca0132_config(struct hda_codec *codec) spec->unsol_tag_amic1 = 0x11; break; case QUIRK_SBZ: - codec_dbg(codec, "%s: QUIRK_SBZ applied.\n", __func__); - snd_hda_apply_pincfgs(codec, sbz_pincfgs); + case QUIRK_R3D: + if (spec->quirk == QUIRK_SBZ) { + codec_dbg(codec, "%s: QUIRK_SBZ applied.\n", __func__); + snd_hda_apply_pincfgs(codec, sbz_pincfgs); + } + if (spec->quirk == QUIRK_R3D) { + codec_dbg(codec, "%s: QUIRK_R3D applied.\n", __func__); + snd_hda_apply_pincfgs(codec, r3d_pincfgs); + } spec->num_outputs = 2; spec->out_pins[0] = 0x0B; /* Line out */ @@ -7473,8 +7547,8 @@ static int ca0132_prepare_verbs(struct hda_codec *codec) struct ca0132_spec *spec = codec->spec; spec->chip_init_verbs = ca0132_init_verbs0; - if (spec->quirk == QUIRK_SBZ) - spec->sbz_init_verbs = sbz_init_verbs; + if (spec->quirk == QUIRK_SBZ || spec->quirk == QUIRK_R3D) + spec->desktop_init_verbs = ca0132_init_verbs1; spec->spec_init_verbs = kcalloc(NUM_SPEC_VERBS, sizeof(struct hda_verb), GFP_KERNEL); @@ -7530,25 +7604,19 @@ static int patch_ca0132(struct hda_codec *codec) else spec->quirk = QUIRK_NONE; - /* Setup BAR Region 2 for Sound Blaster Z */ - if (spec->quirk == QUIRK_SBZ) { - spec->mem_base = pci_iomap(codec->bus->pci, 2, 0xC20); - if (spec->mem_base == NULL) { - codec_warn(codec, "pci_iomap failed!"); - codec_info(codec, "perhaps this is not an SBZ?"); - spec->quirk = QUIRK_NONE; - } - } - spec->dsp_state = DSP_DOWNLOAD_INIT; spec->num_mixers = 1; /* Set which mixers each quirk uses. */ switch (spec->quirk) { case QUIRK_SBZ: - spec->mixers[0] = sbz_mixer; + spec->mixers[0] = desktop_mixer; snd_hda_codec_set_name(codec, "Sound Blaster Z"); break; + case QUIRK_R3D: + spec->mixers[0] = desktop_mixer; + snd_hda_codec_set_name(codec, "Recon3D"); + break; case QUIRK_R3DI: spec->mixers[0] = r3di_mixer; snd_hda_codec_set_name(codec, "Recon3Di"); @@ -7558,19 +7626,34 @@ static int patch_ca0132(struct hda_codec *codec) break; } - /* Setup whether or not to use alt functions/controls */ + /* Setup whether or not to use alt functions/controls/pci_mmio */ switch (spec->quirk) { case QUIRK_SBZ: + case QUIRK_R3D: + spec->use_alt_controls = true; + spec->use_alt_functions = true; + spec->use_pci_mmio = true; + break; case QUIRK_R3DI: spec->use_alt_controls = true; spec->use_alt_functions = true; + spec->use_pci_mmio = false; break; default: spec->use_alt_controls = false; spec->use_alt_functions = false; + spec->use_pci_mmio = false; break; } + if (spec->use_pci_mmio) { + spec->mem_base = pci_iomap(codec->bus->pci, 2, 0xC20); + if (spec->mem_base == NULL) { + codec_warn(codec, "pci_iomap failed! Setting quirk to QUIRK_NONE."); + spec->quirk = QUIRK_NONE; + } + } + spec->base_init_verbs = ca0132_base_init_verbs; spec->base_exit_verbs = ca0132_base_exit_verbs; diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index d6e079f4ec09..a7f91be45194 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -1096,25 +1096,6 @@ static int cs421x_init(struct hda_codec *codec) return 0; } -static int cs421x_build_controls(struct hda_codec *codec) -{ - struct cs_spec *spec = codec->spec; - int err; - - err = snd_hda_gen_build_controls(codec); - if (err < 0) - return err; - - if (spec->gen.autocfg.speaker_outs && - spec->vendor_nid == CS4210_VENDOR_NID) { - err = snd_hda_ctl_add(codec, 0, - snd_ctl_new1(&cs421x_speaker_boost_ctl, codec)); - if (err < 0) - return err; - } - return 0; -} - static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac) { unsigned int caps; @@ -1144,6 +1125,14 @@ static int cs421x_parse_auto_config(struct hda_codec *codec) return err; parse_cs421x_digital(codec); + + if (spec->gen.autocfg.speaker_outs && + spec->vendor_nid == CS4210_VENDOR_NID) { + if (!snd_hda_gen_add_kctl(&spec->gen, NULL, + &cs421x_speaker_boost_ctl)) + return -ENOMEM; + } + return 0; } @@ -1175,7 +1164,7 @@ static int cs421x_suspend(struct hda_codec *codec) #endif static const struct hda_codec_ops cs421x_patch_ops = { - .build_controls = cs421x_build_controls, + .build_controls = snd_hda_gen_build_controls, .build_pcms = snd_hda_gen_build_pcms, .init = cs421x_init, .free = cs_free, diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index f641c20095f7..cfd4e4f97f8f 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -37,8 +37,6 @@ struct conexant_spec { struct hda_gen_spec gen; - unsigned int beep_amp; - /* extra EAPD pins */ unsigned int num_eapds; hda_nid_t eapds[4]; @@ -62,65 +60,48 @@ struct conexant_spec { #ifdef CONFIG_SND_HDA_INPUT_BEEP -static inline void set_beep_amp(struct conexant_spec *spec, hda_nid_t nid, - int idx, int dir) -{ - spec->gen.beep_nid = nid; - spec->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir); -} -/* additional beep mixers; the actual parameters are overwritten at build */ +/* additional beep mixers; private_value will be overwritten */ static const struct snd_kcontrol_new cxt_beep_mixer[] = { HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), - { } /* end */ }; -/* create beep controls if needed */ -static int add_beep_ctls(struct hda_codec *codec) +static int set_beep_amp(struct conexant_spec *spec, hda_nid_t nid, + int idx, int dir) { - struct conexant_spec *spec = codec->spec; - int err; + struct snd_kcontrol_new *knew; + unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir); + int i; - if (spec->beep_amp) { - const struct snd_kcontrol_new *knew; - for (knew = cxt_beep_mixer; knew->name; knew++) { - struct snd_kcontrol *kctl; - kctl = snd_ctl_new1(knew, codec); - if (!kctl) - return -ENOMEM; - kctl->private_value = spec->beep_amp; - err = snd_hda_ctl_add(codec, 0, kctl); - if (err < 0) - return err; - } + spec->gen.beep_nid = nid; + for (i = 0; i < ARRAY_SIZE(cxt_beep_mixer); i++) { + knew = snd_hda_gen_add_kctl(&spec->gen, NULL, + &cxt_beep_mixer[i]); + if (!knew) + return -ENOMEM; + knew->private_value = beep_amp; } return 0; } -#else -#define set_beep_amp(spec, nid, idx, dir) /* NOP */ -#define add_beep_ctls(codec) 0 -#endif - -/* - * Automatic parser for CX20641 & co - */ -#ifdef CONFIG_SND_HDA_INPUT_BEEP -static void cx_auto_parse_beep(struct hda_codec *codec) +static int cx_auto_parse_beep(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; hda_nid_t nid; for_each_hda_codec_node(nid, codec) - if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) { - set_beep_amp(spec, nid, 0, HDA_OUTPUT); - break; - } + if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) + return set_beep_amp(spec, nid, 0, HDA_OUTPUT); + return 0; } #else -#define cx_auto_parse_beep(codec) +#define cx_auto_parse_beep(codec) 0 #endif +/* + * Automatic parser for CX20641 & co + */ + /* parse EAPDs */ static void cx_auto_parse_eapd(struct hda_codec *codec) { @@ -179,21 +160,6 @@ static void cx_auto_vmaster_hook_mute_led(void *private_data, int enabled) enabled ? 0x00 : 0x02); } -static int cx_auto_build_controls(struct hda_codec *codec) -{ - int err; - - err = snd_hda_gen_build_controls(codec); - if (err < 0) - return err; - - err = add_beep_ctls(codec); - if (err < 0) - return err; - - return 0; -} - static int cx_auto_init(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; @@ -211,6 +177,7 @@ static void cx_auto_reboot_notify(struct hda_codec *codec) struct conexant_spec *spec = codec->spec; switch (codec->core.vendor_id) { + case 0x14f12008: /* CX8200 */ case 0x14f150f2: /* CX20722 */ case 0x14f150f4: /* CX20724 */ break; @@ -218,13 +185,14 @@ static void cx_auto_reboot_notify(struct hda_codec *codec) return; } - /* Turn the CX20722 codec into D3 to avoid spurious noises + /* Turn the problematic codec into D3 to avoid spurious noises from the internal speaker during (and after) reboot */ cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, false); snd_hda_codec_set_power_to_all(codec, codec->core.afg, AC_PWRST_D3); snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + msleep(10); } static void cx_auto_free(struct hda_codec *codec) @@ -234,7 +202,7 @@ static void cx_auto_free(struct hda_codec *codec) } static const struct hda_codec_ops cx_auto_patch_ops = { - .build_controls = cx_auto_build_controls, + .build_controls = snd_hda_gen_build_controls, .build_pcms = snd_hda_gen_build_pcms, .init = cx_auto_init, .reboot_notify = cx_auto_reboot_notify, @@ -343,6 +311,7 @@ static void cxt_fixup_headphone_mic(struct hda_codec *codec, snd_hdac_regmap_add_vendor_verb(&codec->core, 0x410); break; case HDA_FIXUP_ACT_PROBE: + WARN_ON(spec->gen.cap_sync_hook); spec->gen.cap_sync_hook = cxt_update_headset_mode_hook; spec->gen.automute_hook = cxt_update_headset_mode; break; @@ -374,7 +343,7 @@ static void cxt_fixup_headset_mic(struct hda_codec *codec, * control. */ #define update_mic_pin(codec, nid, val) \ - snd_hda_codec_update_cache(codec, nid, 0, \ + snd_hda_codec_write_cache(codec, nid, 0, \ AC_VERB_SET_PIN_WIDGET_CONTROL, val) static const struct hda_input_mux olpc_xo_dc_bias = { @@ -695,16 +664,12 @@ static void cxt_fixup_gpio_mute_hook(void *private_data, int enabled) } /* turn on/off mic-mute LED via GPIO per capture hook */ -static void cxt_fixup_gpio_mic_mute_hook(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static void cxt_gpio_micmute_update(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; - if (ucontrol) - cxt_update_gpio_led(codec, spec->gpio_mic_led_mask, - ucontrol->value.integer.value[0] || - ucontrol->value.integer.value[1]); + cxt_update_gpio_led(codec, spec->gpio_mic_led_mask, + spec->gen.micmute_led.led_value); } @@ -721,11 +686,11 @@ static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, if (action == HDA_FIXUP_ACT_PRE_PROBE) { spec->gen.vmaster_mute.hook = cxt_fixup_gpio_mute_hook; - spec->gen.cap_sync_hook = cxt_fixup_gpio_mic_mute_hook; spec->gpio_led = 0; spec->mute_led_polarity = 0; spec->gpio_mute_led_mask = 0x01; spec->gpio_mic_led_mask = 0x02; + snd_hda_gen_add_micmute_led(codec, cxt_gpio_micmute_update); } snd_hda_add_verbs(codec, gpio_init); if (spec->gpio_led) @@ -1037,7 +1002,6 @@ static int patch_conexant_auto(struct hda_codec *codec) codec->spec = spec; codec->patch_ops = cx_auto_patch_ops; - cx_auto_parse_beep(codec); cx_auto_parse_eapd(codec); spec->gen.own_eapd_ctl = 1; if (spec->dynamic_eapd) @@ -1097,6 +1061,10 @@ static int patch_conexant_auto(struct hda_codec *codec) if (err < 0) goto error; + err = cx_auto_parse_beep(codec); + if (err < 0) + goto error; + /* Some laptops with Conexant chips show stalls in S3 resume, * which falls into the single-cmd mode. * Better to make reset, then. diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 8a49415aebac..cb587dce67a9 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -177,13 +177,13 @@ struct hdmi_spec { /* i915/powerwell (Haswell+/Valleyview+) specific */ bool use_acomp_notifier; /* use i915 eld_notify callback for hotplug */ - struct i915_audio_component_audio_ops i915_audio_ops; + struct drm_audio_component_audio_ops drm_audio_ops; struct hdac_chmap chmap; hda_nid_t vendor_nid; }; -#ifdef CONFIG_SND_HDA_I915 +#ifdef CONFIG_SND_HDA_COMPONENT static inline bool codec_has_acomp(struct hda_codec *codec) { struct hdmi_spec *spec = codec->spec; @@ -339,13 +339,13 @@ static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol, if (!per_pin) { /* no pin is bound to the pcm */ uinfo->count = 0; - mutex_unlock(&spec->pcm_lock); - return 0; + goto unlock; } eld = &per_pin->sink_eld; uinfo->count = eld->eld_valid ? eld->eld_size : 0; - mutex_unlock(&spec->pcm_lock); + unlock: + mutex_unlock(&spec->pcm_lock); return 0; } @@ -357,6 +357,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, struct hdmi_spec_per_pin *per_pin; struct hdmi_eld *eld; int pcm_idx; + int err = 0; pcm_idx = kcontrol->private_value; mutex_lock(&spec->pcm_lock); @@ -365,16 +366,15 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, /* no pin is bound to the pcm */ memset(ucontrol->value.bytes.data, 0, ARRAY_SIZE(ucontrol->value.bytes.data)); - mutex_unlock(&spec->pcm_lock); - return 0; + goto unlock; } - eld = &per_pin->sink_eld; + eld = &per_pin->sink_eld; if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) || eld->eld_size > ELD_MAX_SIZE) { - mutex_unlock(&spec->pcm_lock); snd_BUG(); - return -EINVAL; + err = -EINVAL; + goto unlock; } memset(ucontrol->value.bytes.data, 0, @@ -382,9 +382,10 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, if (eld->eld_valid) memcpy(ucontrol->value.bytes.data, eld->eld_buffer, eld->eld_size); - mutex_unlock(&spec->pcm_lock); - return 0; + unlock: + mutex_unlock(&spec->pcm_lock); + return err; } static const struct snd_kcontrol_new eld_bytes_ctl = { @@ -1209,8 +1210,8 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, pin_idx = hinfo_to_pin_index(codec, hinfo); if (!spec->dyn_pcm_assign) { if (snd_BUG_ON(pin_idx < 0)) { - mutex_unlock(&spec->pcm_lock); - return -EINVAL; + err = -EINVAL; + goto unlock; } } else { /* no pin is assigned to the PCM @@ -1218,16 +1219,13 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, */ if (pin_idx < 0) { err = hdmi_pcm_open_no_pin(hinfo, codec, substream); - mutex_unlock(&spec->pcm_lock); - return err; + goto unlock; } } err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx); - if (err < 0) { - mutex_unlock(&spec->pcm_lock); - return err; - } + if (err < 0) + goto unlock; per_cvt = get_cvt(spec, cvt_idx); /* Claim converter */ @@ -1264,12 +1262,11 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, per_cvt->assigned = 0; hinfo->nid = 0; snd_hda_spdif_ctls_unassign(codec, pcm_idx); - mutex_unlock(&spec->pcm_lock); - return -ENODEV; + err = -ENODEV; + goto unlock; } } - mutex_unlock(&spec->pcm_lock); /* Store the updated parameters */ runtime->hw.channels_min = hinfo->channels_min; runtime->hw.channels_max = hinfo->channels_max; @@ -1278,7 +1275,9 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2); - return 0; + unlock: + mutex_unlock(&spec->pcm_lock); + return err; } /* @@ -1867,7 +1866,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, struct snd_pcm_runtime *runtime = substream->runtime; bool non_pcm; int pinctl; - int err; + int err = 0; mutex_lock(&spec->pcm_lock); pin_idx = hinfo_to_pin_index(codec, hinfo); @@ -1879,13 +1878,12 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, pin_cvt_fixup(codec, NULL, cvt_nid); snd_hda_codec_setup_stream(codec, cvt_nid, stream_tag, 0, format); - mutex_unlock(&spec->pcm_lock); - return 0; + goto unlock; } if (snd_BUG_ON(pin_idx < 0)) { - mutex_unlock(&spec->pcm_lock); - return -EINVAL; + err = -EINVAL; + goto unlock; } per_pin = get_pin(spec, pin_idx); pin_nid = per_pin->pin_nid; @@ -1924,6 +1922,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, /* snd_hda_set_dev_select() has been called before */ err = spec->ops.setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); + unlock: mutex_unlock(&spec->pcm_lock); return err; } @@ -1945,6 +1944,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, struct hdmi_spec_per_cvt *per_cvt; struct hdmi_spec_per_pin *per_pin; int pinctl; + int err = 0; if (hinfo->nid) { pcm_idx = hinfo_to_pcm_index(codec, hinfo); @@ -1963,14 +1963,12 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, snd_hda_spdif_ctls_unassign(codec, pcm_idx); clear_bit(pcm_idx, &spec->pcm_in_use); pin_idx = hinfo_to_pin_index(codec, hinfo); - if (spec->dyn_pcm_assign && pin_idx < 0) { - mutex_unlock(&spec->pcm_lock); - return 0; - } + if (spec->dyn_pcm_assign && pin_idx < 0) + goto unlock; if (snd_BUG_ON(pin_idx < 0)) { - mutex_unlock(&spec->pcm_lock); - return -EINVAL; + err = -EINVAL; + goto unlock; } per_pin = get_pin(spec, pin_idx); @@ -1989,10 +1987,11 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, per_pin->setup = false; per_pin->channels = 0; mutex_unlock(&per_pin->lock); + unlock: mutex_unlock(&spec->pcm_lock); } - return 0; + return err; } static const struct hda_pcm_ops generic_ops = { @@ -2288,7 +2287,7 @@ static void generic_hdmi_free(struct hda_codec *codec) int pin_idx, pcm_idx; if (codec_has_acomp(codec)) - snd_hdac_i915_register_notifier(NULL); + snd_hdac_acomp_register_notifier(&codec->bus->core, NULL); for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); @@ -2471,6 +2470,38 @@ static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg, snd_hda_codec_set_power_to_all(codec, fg, power_state); } +/* There is a fixed mapping between audio pin node and display port. + * on SNB, IVY, HSW, BSW, SKL, BXT, KBL: + * Pin Widget 5 - PORT B (port = 1 in i915 driver) + * Pin Widget 6 - PORT C (port = 2 in i915 driver) + * Pin Widget 7 - PORT D (port = 3 in i915 driver) + * + * on VLV, ILK: + * Pin Widget 4 - PORT B (port = 1 in i915 driver) + * Pin Widget 5 - PORT C (port = 2 in i915 driver) + * Pin Widget 6 - PORT D (port = 3 in i915 driver) + */ +static int intel_base_nid(struct hda_codec *codec) +{ + switch (codec->core.vendor_id) { + case 0x80860054: /* ILK */ + case 0x80862804: /* ILK */ + case 0x80862882: /* VLV */ + return 4; + default: + return 5; + } +} + +static int intel_pin2port(void *audio_ptr, int pin_nid) +{ + int base_nid = intel_base_nid(audio_ptr); + + if (WARN_ON(pin_nid < base_nid || pin_nid >= base_nid + 3)) + return -1; + return pin_nid - base_nid + 1; /* intel port is 1-based */ +} + static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe) { struct hda_codec *codec = audio_ptr; @@ -2481,16 +2512,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe) if (port < 1 || port > 3) return; - switch (codec->core.vendor_id) { - case 0x80860054: /* ILK */ - case 0x80862804: /* ILK */ - case 0x80862882: /* VLV */ - pin_nid = port + 0x03; - break; - default: - pin_nid = port + 0x04; - break; - } + pin_nid = port + intel_base_nid(codec) - 1; /* intel port is 1-based */ /* skip notification during system suspend (but not in runtime PM); * the state will be updated at resume @@ -2498,7 +2520,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe) if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0) return; /* ditto during suspend/resume process itself */ - if (atomic_read(&(codec)->core.in_pm)) + if (snd_hdac_is_in_pm(&codec->core)) return; snd_hdac_i915_set_bclk(&codec->bus->core); @@ -2511,14 +2533,16 @@ static void register_i915_notifier(struct hda_codec *codec) struct hdmi_spec *spec = codec->spec; spec->use_acomp_notifier = true; - spec->i915_audio_ops.audio_ptr = codec; + spec->drm_audio_ops.audio_ptr = codec; /* intel_audio_codec_enable() or intel_audio_codec_disable() * will call pin_eld_notify with using audio_ptr pointer * We need make sure audio_ptr is really setup */ wmb(); - spec->i915_audio_ops.pin_eld_notify = intel_pin_eld_notify; - snd_hdac_i915_register_notifier(&spec->i915_audio_ops); + spec->drm_audio_ops.pin2port = intel_pin2port; + spec->drm_audio_ops.pin_eld_notify = intel_pin_eld_notify; + snd_hdac_acomp_register_notifier(&codec->bus->core, + &spec->drm_audio_ops); } /* setup_stream ops override for HSW+ */ @@ -2551,6 +2575,8 @@ static int alloc_intel_hdmi(struct hda_codec *codec) /* requires i915 binding */ if (!codec->bus->core.audio_component) { codec_info(codec, "No i915 binding for Intel HDMI/DP codec\n"); + /* set probe_id here to prevent generic fallback binding */ + codec->probe_id = HDA_CODEC_ID_SKIP_PROBE; return -ENODEV; } diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f6af3e1c2b93..b20974ef1e13 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -43,11 +43,9 @@ /* extra amp-initialization sequence types */ enum { + ALC_INIT_UNDEFINED, ALC_INIT_NONE, ALC_INIT_DEFAULT, - ALC_INIT_GPIO1, - ALC_INIT_GPIO2, - ALC_INIT_GPIO3, }; enum { @@ -85,19 +83,20 @@ struct alc_spec { struct hda_gen_spec gen; /* must be at head */ /* codec parameterization */ - const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ - unsigned int num_mixers; - unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ - struct alc_customize_define cdefine; unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ + /* GPIO bits */ + unsigned int gpio_mask; + unsigned int gpio_dir; + unsigned int gpio_data; + bool gpio_write_delay; /* add a delay before writing gpio_data */ + /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */ int mute_led_polarity; hda_nid_t mute_led_nid; hda_nid_t cap_mute_led_nid; - unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ unsigned int gpio_mute_led_mask; unsigned int gpio_mic_led_mask; @@ -205,41 +204,87 @@ static void alc_process_coef_fw(struct hda_codec *codec, } /* - * Append the given mixer and verb elements for the later use - * The mixer array is referred in build_controls(), and init_verbs are - * called in init(). + * GPIO setup tables, used in initialization */ -static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) + +/* Enable GPIO mask and set output */ +static void alc_setup_gpio(struct hda_codec *codec, unsigned int mask) +{ + struct alc_spec *spec = codec->spec; + + spec->gpio_mask |= mask; + spec->gpio_dir |= mask; + spec->gpio_data |= mask; +} + +static void alc_write_gpio_data(struct hda_codec *codec) { - if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) + struct alc_spec *spec = codec->spec; + + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, + spec->gpio_data); +} + +static void alc_update_gpio_data(struct hda_codec *codec, unsigned int mask, + bool on) +{ + struct alc_spec *spec = codec->spec; + unsigned int oldval = spec->gpio_data; + + if (on) + spec->gpio_data |= mask; + else + spec->gpio_data &= ~mask; + if (oldval != spec->gpio_data) + alc_write_gpio_data(codec); +} + +static void alc_write_gpio(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + + if (!spec->gpio_mask) return; - spec->mixers[spec->num_mixers++] = mix; + + snd_hda_codec_write(codec, codec->core.afg, 0, + AC_VERB_SET_GPIO_MASK, spec->gpio_mask); + snd_hda_codec_write(codec, codec->core.afg, 0, + AC_VERB_SET_GPIO_DIRECTION, spec->gpio_dir); + if (spec->gpio_write_delay) + msleep(1); + alc_write_gpio_data(codec); } -/* - * GPIO setup tables, used in initialization - */ -/* Enable GPIO mask and set output */ -static const struct hda_verb alc_gpio1_init_verbs[] = { - {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, - { } -}; +static void alc_fixup_gpio(struct hda_codec *codec, int action, + unsigned int mask) +{ + if (action == HDA_FIXUP_ACT_PRE_PROBE) + alc_setup_gpio(codec, mask); +} -static const struct hda_verb alc_gpio2_init_verbs[] = { - {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, - { } -}; +static void alc_fixup_gpio1(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + alc_fixup_gpio(codec, action, 0x01); +} -static const struct hda_verb alc_gpio3_init_verbs[] = { - {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, - { } -}; +static void alc_fixup_gpio2(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + alc_fixup_gpio(codec, action, 0x02); +} + +static void alc_fixup_gpio3(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + alc_fixup_gpio(codec, action, 0x03); +} + +static void alc_fixup_gpio4(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + alc_fixup_gpio(codec, action, 0x04); +} /* * Fix hardware PLL issue @@ -447,16 +492,8 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) { alc_fill_eapd_coef(codec); alc_auto_setup_eapd(codec, true); + alc_write_gpio(codec); switch (type) { - case ALC_INIT_GPIO1: - snd_hda_sequence_write(codec, alc_gpio1_init_verbs); - break; - case ALC_INIT_GPIO2: - snd_hda_sequence_write(codec, alc_gpio2_init_verbs); - break; - case ALC_INIT_GPIO3: - snd_hda_sequence_write(codec, alc_gpio3_init_verbs); - break; case ALC_INIT_DEFAULT: switch (codec->core.vendor_id) { case 0x10ec0260: @@ -656,20 +693,22 @@ do_sku: * 7~6 : Reserved */ tmp = (ass & 0x38) >> 3; /* external Amp control */ - switch (tmp) { - case 1: - spec->init_amp = ALC_INIT_GPIO1; - break; - case 3: - spec->init_amp = ALC_INIT_GPIO2; - break; - case 7: - spec->init_amp = ALC_INIT_GPIO3; - break; - case 5: - default: - spec->init_amp = ALC_INIT_DEFAULT; - break; + if (spec->init_amp == ALC_INIT_UNDEFINED) { + switch (tmp) { + case 1: + alc_setup_gpio(codec, 0x01); + break; + case 3: + alc_setup_gpio(codec, 0x02); + break; + case 7: + alc_setup_gpio(codec, 0x03); + break; + case 5: + default: + spec->init_amp = ALC_INIT_DEFAULT; + break; + } } /* is laptop or Desktop and enable the function "Mute internal speaker @@ -722,47 +761,14 @@ static void alc_fixup_inv_dmic(struct hda_codec *codec, } -#ifdef CONFIG_SND_HDA_INPUT_BEEP -/* additional beep mixers; the actual parameters are overwritten at build */ -static const struct snd_kcontrol_new alc_beep_mixer[] = { - HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), - HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), - { } /* end */ -}; -#endif - static int alc_build_controls(struct hda_codec *codec) { - struct alc_spec *spec = codec->spec; - int i, err; + int err; err = snd_hda_gen_build_controls(codec); if (err < 0) return err; - for (i = 0; i < spec->num_mixers; i++) { - err = snd_hda_add_new_ctls(codec, spec->mixers[i]); - if (err < 0) - return err; - } - -#ifdef CONFIG_SND_HDA_INPUT_BEEP - /* create beep controls if needed */ - if (spec->beep_amp) { - const struct snd_kcontrol_new *knew; - for (knew = alc_beep_mixer; knew->name; knew++) { - struct snd_kcontrol *kctl; - kctl = snd_ctl_new1(knew, codec); - if (!kctl) - return -ENOMEM; - kctl->private_value = spec->beep_amp; - err = snd_hda_ctl_add(codec, 0, kctl); - if (err < 0) - return err; - } - } -#endif - snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD); return 0; } @@ -973,8 +979,30 @@ static int alc_codec_rename_from_preset(struct hda_codec *codec) * Digital-beep handlers */ #ifdef CONFIG_SND_HDA_INPUT_BEEP -#define set_beep_amp(spec, nid, idx, dir) \ - ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) + +/* additional beep mixers; private_value will be overwritten */ +static const struct snd_kcontrol_new alc_beep_mixer[] = { + HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), + HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), +}; + +/* set up and create beep controls */ +static int set_beep_amp(struct alc_spec *spec, hda_nid_t nid, + int idx, int dir) +{ + struct snd_kcontrol_new *knew; + unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir); + int i; + + for (i = 0; i < ARRAY_SIZE(alc_beep_mixer); i++) { + knew = snd_hda_gen_add_kctl(&spec->gen, NULL, + &alc_beep_mixer[i]); + if (!knew) + return -ENOMEM; + knew->private_value = beep_amp; + } + return 0; +} static const struct snd_pci_quirk beep_white_list[] = { SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1), @@ -999,7 +1027,7 @@ static inline int has_cdefine_beep(struct hda_codec *codec) return spec->cdefine.enable_pcbeep; } #else -#define set_beep_amp(spec, nid, idx, dir) /* NOP */ +#define set_beep_amp(spec, nid, idx, dir) 0 #define has_cdefine_beep(codec) 0 #endif @@ -1104,12 +1132,12 @@ static void alc880_fixup_vol_knob(struct hda_codec *codec, static const struct hda_fixup alc880_fixups[] = { [ALC880_FIXUP_GPIO1] = { - .type = HDA_FIXUP_VERBS, - .v.verbs = alc_gpio1_init_verbs, + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_gpio1, }, [ALC880_FIXUP_GPIO2] = { - .type = HDA_FIXUP_VERBS, - .v.verbs = alc_gpio2_init_verbs, + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_gpio2, }, [ALC880_FIXUP_MEDION_RIM] = { .type = HDA_FIXUP_VERBS, @@ -1501,8 +1529,11 @@ static int patch_alc880(struct hda_codec *codec) if (err < 0) goto error; - if (!spec->gen.no_analog) - set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); + if (!spec->gen.no_analog) { + err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); + if (err < 0) + goto error; + } snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); @@ -1544,8 +1575,8 @@ enum { static void alc260_gpio1_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, - spec->gen.hp_jack_present); + + alc_update_gpio_data(codec, 0x01, spec->gen.hp_jack_present); } static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, @@ -1562,7 +1593,7 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ snd_hda_jack_detect_enable_callback(codec, 0x0f, snd_hda_gen_hp_automute); - snd_hda_add_verbs(codec, alc_gpio1_init_verbs); + alc_setup_gpio(codec, 0x01); } } @@ -1589,8 +1620,6 @@ static void alc260_fixup_kn1(struct hda_codec *codec, switch (action) { case HDA_FIXUP_ACT_PRE_PROBE: snd_hda_apply_pincfgs(codec, pincfgs); - break; - case HDA_FIXUP_ACT_PROBE: spec->init_amp = ALC_INIT_NONE; break; } @@ -1600,7 +1629,7 @@ static void alc260_fixup_fsc_s7020(struct hda_codec *codec, const struct hda_fixup *fix, int action) { struct alc_spec *spec = codec->spec; - if (action == HDA_FIXUP_ACT_PROBE) + if (action == HDA_FIXUP_ACT_PRE_PROBE) spec->init_amp = ALC_INIT_NONE; } @@ -1638,8 +1667,8 @@ static const struct hda_fixup alc260_fixups[] = { }, }, [ALC260_FIXUP_GPIO1] = { - .type = HDA_FIXUP_VERBS, - .v.verbs = alc_gpio1_init_verbs, + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_gpio1, }, [ALC260_FIXUP_GPIO1_TOGGLE] = { .type = HDA_FIXUP_FUNC, @@ -1751,8 +1780,11 @@ static int patch_alc260(struct hda_codec *codec) if (err < 0) goto error; - if (!spec->gen.no_analog) - set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); + if (!spec->gen.no_analog) { + err = set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); + if (err < 0) + goto error; + } snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); @@ -1824,47 +1856,14 @@ static void alc889_fixup_coef(struct hda_codec *codec, alc_update_coef_idx(codec, 7, 0, 0x2030); } -/* toggle speaker-output according to the hp-jack state */ -static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) -{ - unsigned int gpiostate, gpiomask, gpiodir; - - gpiostate = snd_hda_codec_read(codec, codec->core.afg, 0, - AC_VERB_GET_GPIO_DATA, 0); - - if (!muted) - gpiostate |= (1 << pin); - else - gpiostate &= ~(1 << pin); - - gpiomask = snd_hda_codec_read(codec, codec->core.afg, 0, - AC_VERB_GET_GPIO_MASK, 0); - gpiomask |= (1 << pin); - - gpiodir = snd_hda_codec_read(codec, codec->core.afg, 0, - AC_VERB_GET_GPIO_DIRECTION, 0); - gpiodir |= (1 << pin); - - - snd_hda_codec_write(codec, codec->core.afg, 0, - AC_VERB_SET_GPIO_MASK, gpiomask); - snd_hda_codec_write(codec, codec->core.afg, 0, - AC_VERB_SET_GPIO_DIRECTION, gpiodir); - - msleep(1); - - snd_hda_codec_write(codec, codec->core.afg, 0, - AC_VERB_SET_GPIO_DATA, gpiostate); -} - /* set up GPIO at initialization */ static void alc885_fixup_macpro_gpio(struct hda_codec *codec, const struct hda_fixup *fix, int action) { - if (action != HDA_FIXUP_ACT_INIT) - return; - alc882_gpio_mute(codec, 0, 0); - alc882_gpio_mute(codec, 1, 0); + struct alc_spec *spec = codec->spec; + + spec->gpio_write_delay = true; + alc_fixup_gpio3(codec, fix, action); } /* Fix the connection of some pins for ALC889: @@ -2143,20 +2142,20 @@ static const struct hda_fixup alc882_fixups[] = { } }, [ALC882_FIXUP_GPIO1] = { - .type = HDA_FIXUP_VERBS, - .v.verbs = alc_gpio1_init_verbs, + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_gpio1, }, [ALC882_FIXUP_GPIO2] = { - .type = HDA_FIXUP_VERBS, - .v.verbs = alc_gpio2_init_verbs, + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_gpio2, }, [ALC882_FIXUP_GPIO3] = { - .type = HDA_FIXUP_VERBS, - .v.verbs = alc_gpio3_init_verbs, + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_gpio3, }, [ALC882_FIXUP_ASUS_W2JC] = { - .type = HDA_FIXUP_VERBS, - .v.verbs = alc_gpio1_init_verbs, + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_gpio1, .chained = true, .chain_id = ALC882_FIXUP_EAPD, }, @@ -2376,12 +2375,37 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { }; static const struct hda_model_fixup alc882_fixup_models[] = { + {.id = ALC882_FIXUP_ABIT_AW9D_MAX, .name = "abit-aw9d"}, + {.id = ALC882_FIXUP_LENOVO_Y530, .name = "lenovo-y530"}, + {.id = ALC882_FIXUP_ACER_ASPIRE_7736, .name = "acer-aspire-7736"}, + {.id = ALC882_FIXUP_ASUS_W90V, .name = "asus-w90v"}, + {.id = ALC889_FIXUP_CD, .name = "cd"}, + {.id = ALC889_FIXUP_FRONT_HP_NO_PRESENCE, .name = "no-front-hp"}, + {.id = ALC889_FIXUP_VAIO_TT, .name = "vaio-tt"}, + {.id = ALC888_FIXUP_EEE1601, .name = "eee1601"}, + {.id = ALC882_FIXUP_EAPD, .name = "alc882-eapd"}, + {.id = ALC883_FIXUP_EAPD, .name = "alc883-eapd"}, + {.id = ALC882_FIXUP_GPIO1, .name = "gpio1"}, + {.id = ALC882_FIXUP_GPIO2, .name = "gpio2"}, + {.id = ALC882_FIXUP_GPIO3, .name = "gpio3"}, + {.id = ALC889_FIXUP_COEF, .name = "alc889-coef"}, + {.id = ALC882_FIXUP_ASUS_W2JC, .name = "asus-w2jc"}, {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, + {.id = ALC885_FIXUP_MACPRO_GPIO, .name = "macpro-gpio"}, + {.id = ALC889_FIXUP_DAC_ROUTE, .name = "dac-route"}, + {.id = ALC889_FIXUP_MBP_VREF, .name = "mbp-vref"}, + {.id = ALC889_FIXUP_IMAC91_VREF, .name = "imac91-vref"}, + {.id = ALC889_FIXUP_MBA11_VREF, .name = "mba11-vref"}, + {.id = ALC889_FIXUP_MBA21_VREF, .name = "mba21-vref"}, + {.id = ALC889_FIXUP_MP11_VREF, .name = "mp11-vref"}, + {.id = ALC889_FIXUP_MP41_VREF, .name = "mp41-vref"}, {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"}, {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"}, + {.id = ALC887_FIXUP_ASUS_BASS, .name = "asus-bass"}, {.id = ALC1220_FIXUP_GB_DUAL_CODECS, .name = "dual-codecs"}, + {.id = ALC1220_FIXUP_CLEVO_P950, .name = "clevo-p950"}, {} }; @@ -2435,8 +2459,11 @@ static int patch_alc882(struct hda_codec *codec) if (err < 0) goto error; - if (!spec->gen.no_analog && spec->gen.beep_nid) - set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); + if (!spec->gen.no_analog && spec->gen.beep_nid) { + err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); + if (err < 0) + goto error; + } snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); @@ -2557,6 +2584,14 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { static const struct hda_model_fixup alc262_fixup_models[] = { {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, + {.id = ALC262_FIXUP_FSC_H270, .name = "fsc-h270"}, + {.id = ALC262_FIXUP_FSC_S7110, .name = "fsc-s7110"}, + {.id = ALC262_FIXUP_HP_Z200, .name = "hp-z200"}, + {.id = ALC262_FIXUP_TYAN, .name = "tyan"}, + {.id = ALC262_FIXUP_LENOVO_3000, .name = "lenovo-3000"}, + {.id = ALC262_FIXUP_BENQ, .name = "benq"}, + {.id = ALC262_FIXUP_BENQ_T31, .name = "benq-t31"}, + {.id = ALC262_FIXUP_INTEL_BAYLEYBAY, .name = "bayleybay"}, {} }; @@ -2598,8 +2633,11 @@ static int patch_alc262(struct hda_codec *codec) if (err < 0) goto error; - if (!spec->gen.no_analog && spec->gen.beep_nid) - set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); + if (!spec->gen.no_analog && spec->gen.beep_nid) { + err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); + if (err < 0) + goto error; + } snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); @@ -2645,7 +2683,6 @@ static const struct snd_kcontrol_new alc268_beep_mixer[] = { .put = alc268_beep_switch_put, .private_value = HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT) }, - { } }; /* set PCBEEP vol = 0, mute connections */ @@ -2686,6 +2723,7 @@ static const struct hda_fixup alc268_fixups[] = { static const struct hda_model_fixup alc268_fixup_models[] = { {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, + {.id = ALC268_FIXUP_SPDIF, .name = "spdif"}, {} }; @@ -2713,7 +2751,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) static int patch_alc268(struct hda_codec *codec) { struct alc_spec *spec; - int err; + int i, err; /* ALC268 has no aa-loopback mixer */ err = alc_alloc_spec(codec, 0); @@ -2735,7 +2773,13 @@ static int patch_alc268(struct hda_codec *codec) if (err > 0 && !spec->gen.no_analog && spec->gen.autocfg.speaker_pins[0] != 0x1d) { - add_mixer(spec, alc268_beep_mixer); + for (i = 0; i < ARRAY_SIZE(alc268_beep_mixer); i++) { + if (!snd_hda_gen_add_kctl(&spec->gen, NULL, + &alc268_beep_mixer[i])) { + err = -ENOMEM; + goto error; + } + } snd_hda_add_verbs(codec, alc268_beep_init_verbs); if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) /* override the amp caps for beep generator */ @@ -3454,9 +3498,8 @@ static int alc269_resume(struct hda_codec *codec) * suspend, and won't restore the data after resume, so we restore it * in the driver. */ - if (spec->gpio_led) - snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, - spec->gpio_led); + if (spec->gpio_data) + alc_write_gpio_data(codec); if (spec->has_alc5505_dsp) alc5505_dsp_resume(codec); @@ -3696,18 +3739,10 @@ static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask, bool enabled) { struct alc_spec *spec = codec->spec; - unsigned int oldval = spec->gpio_led; if (spec->mute_led_polarity) enabled = !enabled; - - if (enabled) - spec->gpio_led &= ~mask; - else - spec->gpio_led |= mask; - if (spec->gpio_led != oldval) - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, - spec->gpio_led); + alc_update_gpio_data(codec, mask, !enabled); /* muted -> LED on */ } /* turn on/off mute LED via GPIO per vmaster hook */ @@ -3720,104 +3755,79 @@ static void alc_fixup_gpio_mute_hook(void *private_data, int enabled) } /* turn on/off mic-mute LED via GPIO per capture hook */ -static void alc_fixup_gpio_mic_mute_hook(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static void alc_gpio_micmute_update(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - if (ucontrol) - alc_update_gpio_led(codec, spec->gpio_mic_led_mask, - ucontrol->value.integer.value[0] || - ucontrol->value.integer.value[1]); + alc_update_gpio_led(codec, spec->gpio_mic_led_mask, + spec->gen.micmute_led.led_value); } -static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, - const struct hda_fixup *fix, int action) +/* setup mute and mic-mute GPIO bits, add hooks appropriately */ +static void alc_fixup_hp_gpio_led(struct hda_codec *codec, + int action, + unsigned int mute_mask, + unsigned int micmute_mask) { struct alc_spec *spec = codec->spec; - static const struct hda_verb gpio_init[] = { - { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, - { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, - {} - }; - if (action == HDA_FIXUP_ACT_PRE_PROBE) { + alc_fixup_gpio(codec, action, mute_mask | micmute_mask); + + if (action != HDA_FIXUP_ACT_PRE_PROBE) + return; + if (mute_mask) { + spec->gpio_mute_led_mask = mute_mask; spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; - spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; - spec->gpio_led = 0; - spec->mute_led_polarity = 0; - spec->gpio_mute_led_mask = 0x08; - spec->gpio_mic_led_mask = 0x10; - snd_hda_add_verbs(codec, gpio_init); + } + if (micmute_mask) { + spec->gpio_mic_led_mask = micmute_mask; + snd_hda_gen_add_micmute_led(codec, alc_gpio_micmute_update); } } -static void alc286_fixup_hp_gpio_led(struct hda_codec *codec, +static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, const struct hda_fixup *fix, int action) { - struct alc_spec *spec = codec->spec; - static const struct hda_verb gpio_init[] = { - { 0x01, AC_VERB_SET_GPIO_MASK, 0x22 }, - { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x22 }, - {} - }; + alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10); +} - if (action == HDA_FIXUP_ACT_PRE_PROBE) { - spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; - spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; - spec->gpio_led = 0; - spec->mute_led_polarity = 0; - spec->gpio_mute_led_mask = 0x02; - spec->gpio_mic_led_mask = 0x20; - snd_hda_add_verbs(codec, gpio_init); - } +static void alc286_fixup_hp_gpio_led(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + alc_fixup_hp_gpio_led(codec, action, 0x02, 0x20); } /* turn on/off mic-mute LED per capture hook */ -static void alc269_fixup_hp_cap_mic_mute_hook(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static void alc_cap_micmute_update(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int pinval, enable, disable; + unsigned int pinval; + if (!spec->cap_mute_led_nid) + return; pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid); pinval &= ~AC_PINCTL_VREFEN; - enable = pinval | AC_PINCTL_VREF_80; - disable = pinval | AC_PINCTL_VREF_HIZ; - - if (!ucontrol) - return; - - if (ucontrol->value.integer.value[0] || - ucontrol->value.integer.value[1]) - pinval = disable; + if (spec->gen.micmute_led.led_value) + pinval |= AC_PINCTL_VREF_80; else - pinval = enable; - - if (spec->cap_mute_led_nid) - snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval); + pinval |= AC_PINCTL_VREF_HIZ; + snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval); } static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec, const struct hda_fixup *fix, int action) { struct alc_spec *spec = codec->spec; - static const struct hda_verb gpio_init[] = { - { 0x01, AC_VERB_SET_GPIO_MASK, 0x08 }, - { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x08 }, - {} - }; + alc_fixup_hp_gpio_led(codec, action, 0x08, 0); if (action == HDA_FIXUP_ACT_PRE_PROBE) { - spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; - spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; - spec->gpio_led = 0; - spec->mute_led_polarity = 0; - spec->gpio_mute_led_mask = 0x08; + /* Like hp_gpio_mic1_led, but also needs GPIO4 low to + * enable headphone amp + */ + spec->gpio_mask |= 0x10; + spec->gpio_dir |= 0x10; spec->cap_mute_led_nid = 0x18; - snd_hda_add_verbs(codec, gpio_init); + snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update); codec->power_filter = led_power_filter; } } @@ -3825,22 +3835,12 @@ static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec, static void alc280_fixup_hp_gpio4(struct hda_codec *codec, const struct hda_fixup *fix, int action) { - /* Like hp_gpio_mic1_led, but also needs GPIO4 low to enable headphone amp */ struct alc_spec *spec = codec->spec; - static const struct hda_verb gpio_init[] = { - { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, - { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, - {} - }; + alc_fixup_hp_gpio_led(codec, action, 0x08, 0); if (action == HDA_FIXUP_ACT_PRE_PROBE) { - spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; - spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; - spec->gpio_led = 0; - spec->mute_led_polarity = 0; - spec->gpio_mute_led_mask = 0x08; spec->cap_mute_led_nid = 0x18; - snd_hda_add_verbs(codec, gpio_init); + snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update); codec->power_filter = led_power_filter; } } @@ -3890,38 +3890,29 @@ static int alc_register_micmute_input_device(struct hda_codec *codec) return 0; } +/* GPIO1 = set according to SKU external amp + * GPIO2 = mic mute hotkey + * GPIO3 = mute LED + * GPIO4 = mic mute LED + */ static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec, const struct hda_fixup *fix, int action) { - /* GPIO1 = set according to SKU external amp - GPIO2 = mic mute hotkey - GPIO3 = mute LED - GPIO4 = mic mute LED */ - static const struct hda_verb gpio_init[] = { - { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e }, - { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a }, - { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 }, - {} - }; - struct alc_spec *spec = codec->spec; + alc_fixup_hp_gpio_led(codec, action, 0x08, 0x10); if (action == HDA_FIXUP_ACT_PRE_PROBE) { + spec->init_amp = ALC_INIT_DEFAULT; if (alc_register_micmute_input_device(codec) != 0) return; - snd_hda_add_verbs(codec, gpio_init); + spec->gpio_mask |= 0x06; + spec->gpio_dir |= 0x02; + spec->gpio_data |= 0x02; snd_hda_codec_write_cache(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04); snd_hda_jack_detect_enable_callback(codec, codec->core.afg, gpio2_mic_hotkey_event); - - spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; - spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; - spec->gpio_led = 0; - spec->mute_led_polarity = 0; - spec->gpio_mute_led_mask = 0x08; - spec->gpio_mic_led_mask = 0x10; return; } @@ -3929,40 +3920,28 @@ static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec, return; switch (action) { - case HDA_FIXUP_ACT_PROBE: - spec->init_amp = ALC_INIT_DEFAULT; - break; case HDA_FIXUP_ACT_FREE: input_unregister_device(spec->kb_dev); spec->kb_dev = NULL; } } +/* Line2 = mic mute hotkey + * GPIO2 = mic mute LED + */ static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec, const struct hda_fixup *fix, int action) { - /* Line2 = mic mute hotkey - GPIO2 = mic mute LED */ - static const struct hda_verb gpio_init[] = { - { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 }, - { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 }, - {} - }; - struct alc_spec *spec = codec->spec; + alc_fixup_hp_gpio_led(codec, action, 0, 0x04); if (action == HDA_FIXUP_ACT_PRE_PROBE) { + spec->init_amp = ALC_INIT_DEFAULT; if (alc_register_micmute_input_device(codec) != 0) return; - snd_hda_add_verbs(codec, gpio_init); snd_hda_jack_detect_enable_callback(codec, 0x1b, gpio2_mic_hotkey_event); - - spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook; - spec->gpio_led = 0; - spec->mute_led_polarity = 0; - spec->gpio_mic_led_mask = 0x04; return; } @@ -3970,9 +3949,6 @@ static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec, return; switch (action) { - case HDA_FIXUP_ACT_PROBE: - spec->init_amp = ALC_INIT_DEFAULT; - break; case HDA_FIXUP_ACT_FREE: input_unregister_device(spec->kb_dev); spec->kb_dev = NULL; @@ -3988,14 +3964,10 @@ static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, { struct alc_spec *spec = codec->spec; + alc269_fixup_hp_mute_led_micx(codec, fix, action, 0x1a); if (action == HDA_FIXUP_ACT_PRE_PROBE) { - spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; - spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook; - spec->mute_led_polarity = 0; - spec->mute_led_nid = 0x1a; spec->cap_mute_led_nid = 0x18; - spec->gen.vmaster_mute_enum = 1; - codec->power_filter = led_power_filter; + snd_hda_gen_add_micmute_led(codec, alc_cap_micmute_update); } } @@ -4843,6 +4815,7 @@ static void alc_probe_headset_mode(struct hda_codec *codec) spec->headphone_mic_pin = cfg->inputs[i].pin; } + WARN_ON(spec->gen.cap_sync_hook); spec->gen.cap_sync_hook = alc_update_headset_mode_hook; spec->gen.automute_hook = alc_update_headset_mode; spec->gen.hp_automute_hook = alc_update_headset_jack_cb; @@ -4934,13 +4907,10 @@ static void alc288_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_callback *jack) { struct alc_spec *spec = codec->spec; - int present; alc_update_headset_jack_cb(codec, jack); /* Headset Mic enable or disable, only for Dell Dino */ - present = spec->gen.hp_jack_present ? 0x40 : 0; - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, - present); + alc_update_gpio_data(codec, 0x40, spec->gen.hp_jack_present); } static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec, @@ -4949,6 +4919,9 @@ static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec, alc_fixup_headset_mode(codec, fix, action); if (action == HDA_FIXUP_ACT_PROBE) { struct alc_spec *spec = codec->spec; + /* toggled via hp_automute_hook */ + spec->gpio_mask |= 0x40; + spec->gpio_dir |= 0x40; spec->gen.hp_automute_hook = alc288_update_headset_jack_cb; } } @@ -4969,7 +4942,7 @@ static void alc_no_shutup(struct hda_codec *codec) static void alc_fixup_no_shutup(struct hda_codec *codec, const struct hda_fixup *fix, int action) { - if (action == HDA_FIXUP_ACT_PROBE) { + if (action == HDA_FIXUP_ACT_PRE_PROBE) { struct alc_spec *spec = codec->spec; spec->shutup = alc_no_shutup; } @@ -5051,10 +5024,9 @@ static void alc_fixup_dell_xps13(struct hda_codec *codec, * it causes a click noise at start up */ snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ); + spec->shutup = alc_shutup_dell_xps13; break; case HDA_FIXUP_ACT_PROBE: - spec->shutup = alc_shutup_dell_xps13; - /* Make the internal mic the default input source. */ for (i = 0; i < imux->num_items; i++) { if (spec->gen.imux_pins[i] == 0x12) { @@ -5231,13 +5203,6 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec, const struct hda_fixup *fix, int action) { struct alc_spec *spec = codec->spec; - /* TX300 needs to set up GPIO2 for the speaker amp */ - static const struct hda_verb gpio2_verbs[] = { - { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 }, - { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 }, - { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 }, - {} - }; static const struct hda_pintbl dock_pins[] = { { 0x1b, 0x21114000 }, /* dock speaker pin */ {} @@ -5245,13 +5210,18 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec, switch (action) { case HDA_FIXUP_ACT_PRE_PROBE: - snd_hda_add_verbs(codec, gpio2_verbs); + spec->init_amp = ALC_INIT_DEFAULT; + /* TX300 needs to set up GPIO2 for the speaker amp */ + alc_setup_gpio(codec, 0x04); snd_hda_apply_pincfgs(codec, dock_pins); spec->gen.auto_mute_via_amp = 1; spec->gen.automute_hook = asus_tx300_automute; snd_hda_jack_detect_enable_callback(codec, 0x1b, snd_hda_gen_hp_automute); break; + case HDA_FIXUP_ACT_PROBE: + spec->init_amp = ALC_INIT_DEFAULT; + break; case HDA_FIXUP_ACT_BUILD: /* this is a bit tricky; give more sane names for the main * (tablet) speaker and the dock speaker, respectively @@ -5325,30 +5295,26 @@ static void alc280_fixup_hp_9480m(struct hda_codec *codec, int action) { struct alc_spec *spec = codec->spec; - static const struct hda_verb gpio_init[] = { - { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, - { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, - {} - }; + alc_fixup_hp_gpio_led(codec, action, 0x08, 0); if (action == HDA_FIXUP_ACT_PRE_PROBE) { - /* Set the hooks to turn the headphone amp on/off - * as needed - */ - spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; + /* amp at GPIO4; toggled via alc280_hp_gpio4_automute_hook() */ + spec->gpio_mask |= 0x10; + spec->gpio_dir |= 0x10; spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook; + } +} - /* The GPIOs are currently off */ - spec->gpio_led = 0; - - /* GPIO3 is connected to the output mute LED, - * high is on, low is off - */ - spec->mute_led_polarity = 0; - spec->gpio_mute_led_mask = 0x08; +static void alc275_fixup_gpio4_off(struct hda_codec *codec, + const struct hda_fixup *fix, + int action) +{ + struct alc_spec *spec = codec->spec; - /* Initialize GPIO configuration */ - snd_hda_add_verbs(codec, gpio_init); + if (action == HDA_FIXUP_ACT_PRE_PROBE) { + spec->gpio_mask |= 0x04; + spec->gpio_dir |= 0x04; + /* set data bit low */ } } @@ -5492,7 +5458,6 @@ enum { ALC280_FIXUP_HP_9480M, ALC288_FIXUP_DELL_HEADSET_MODE, ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, - ALC288_FIXUP_DELL_XPS_13_GPIO6, ALC288_FIXUP_DELL_XPS_13, ALC288_FIXUP_DISABLE_AAMIX, ALC292_FIXUP_DELL_E7X, @@ -5540,13 +5505,8 @@ static const struct hda_fixup alc269_fixups[] = { } }, [ALC275_FIXUP_SONY_VAIO_GPIO2] = { - .type = HDA_FIXUP_VERBS, - .v.verbs = (const struct hda_verb[]) { - {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, - { } - }, + .type = HDA_FIXUP_FUNC, + .v.func = alc275_fixup_gpio4_off, .chained = true, .chain_id = ALC269_FIXUP_SONY_VAIO }, @@ -6113,22 +6073,11 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE }, - [ALC288_FIXUP_DELL_XPS_13_GPIO6] = { - .type = HDA_FIXUP_VERBS, - .v.verbs = (const struct hda_verb[]) { - {0x01, AC_VERB_SET_GPIO_MASK, 0x40}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x40}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, - { } - }, - .chained = true, - .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE - }, [ALC288_FIXUP_DISABLE_AAMIX] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_disable_aamix, .chained = true, - .chain_id = ALC288_FIXUP_DELL_XPS_13_GPIO6 + .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE }, [ALC288_FIXUP_DELL_XPS_13] = { .type = HDA_FIXUP_FUNC, @@ -6291,14 +6240,9 @@ static const struct hda_fixup alc269_fixups[] = { .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE }, [ALC256_FIXUP_ASUS_AIO_GPIO2] = { - .type = HDA_FIXUP_VERBS, - .v.verbs = (const struct hda_verb[]) { - /* Set up GPIO2 for the speaker amp */ - { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 }, - { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 }, - { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 }, - {} - }, + .type = HDA_FIXUP_FUNC, + /* Set up GPIO2 for the speaker amp */ + .v.func = alc_fixup_gpio4, }, [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = { .type = HDA_FIXUP_PINS, @@ -6530,6 +6474,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360), SND_PCI_QUIRK(0x103c, 0x82bf, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x82c0, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), @@ -6713,13 +6658,95 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic1-led"}, {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, + {.id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, .name = "dell-headset3"}, + {.id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, .name = "dell-headset4"}, {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"}, {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"}, {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"}, {.id = ALC292_FIXUP_TPT440, .name = "tpt440"}, {.id = ALC292_FIXUP_TPT460, .name = "tpt460"}, + {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"}, {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"}, {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"}, + {.id = ALC269_FIXUP_SONY_VAIO, .name = "vaio"}, + {.id = ALC269_FIXUP_DELL_M101Z, .name = "dell-m101z"}, + {.id = ALC269_FIXUP_ASUS_G73JW, .name = "asus-g73jw"}, + {.id = ALC269_FIXUP_LENOVO_EAPD, .name = "lenovo-eapd"}, + {.id = ALC275_FIXUP_SONY_HWEQ, .name = "sony-hweq"}, + {.id = ALC269_FIXUP_PCM_44K, .name = "pcm44k"}, + {.id = ALC269_FIXUP_LIFEBOOK, .name = "lifebook"}, + {.id = ALC269_FIXUP_LIFEBOOK_EXTMIC, .name = "lifebook-extmic"}, + {.id = ALC269_FIXUP_LIFEBOOK_HP_PIN, .name = "lifebook-hp-pin"}, + {.id = ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC, .name = "lifebook-u7x7"}, + {.id = ALC269VB_FIXUP_AMIC, .name = "alc269vb-amic"}, + {.id = ALC269VB_FIXUP_DMIC, .name = "alc269vb-dmic"}, + {.id = ALC269_FIXUP_HP_MUTE_LED_MIC1, .name = "hp-mute-led-mic1"}, + {.id = ALC269_FIXUP_HP_MUTE_LED_MIC2, .name = "hp-mute-led-mic2"}, + {.id = ALC269_FIXUP_HP_MUTE_LED_MIC3, .name = "hp-mute-led-mic3"}, + {.id = ALC269_FIXUP_HP_GPIO_MIC1_LED, .name = "hp-gpio-mic1"}, + {.id = ALC269_FIXUP_HP_LINE1_MIC1_LED, .name = "hp-line1-mic1"}, + {.id = ALC269_FIXUP_NO_SHUTUP, .name = "noshutup"}, + {.id = ALC286_FIXUP_SONY_MIC_NO_PRESENCE, .name = "sony-nomic"}, + {.id = ALC269_FIXUP_ASPIRE_HEADSET_MIC, .name = "aspire-headset-mic"}, + {.id = ALC269_FIXUP_ASUS_X101, .name = "asus-x101"}, + {.id = ALC271_FIXUP_HP_GATE_MIC_JACK, .name = "acer-ao7xx"}, + {.id = ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, .name = "acer-aspire-e1"}, + {.id = ALC269_FIXUP_ACER_AC700, .name = "acer-ac700"}, + {.id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST, .name = "limit-mic-boost"}, + {.id = ALC269VB_FIXUP_ASUS_ZENBOOK, .name = "asus-zenbook"}, + {.id = ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, .name = "asus-zenbook-ux31a"}, + {.id = ALC269VB_FIXUP_ORDISSIMO_EVE2, .name = "ordissimo"}, + {.id = ALC282_FIXUP_ASUS_TX300, .name = "asus-tx300"}, + {.id = ALC283_FIXUP_INT_MIC, .name = "alc283-int-mic"}, + {.id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, .name = "mono-speakers"}, + {.id = ALC290_FIXUP_SUBWOOFER_HSJACK, .name = "alc290-subwoofer"}, + {.id = ALC269_FIXUP_THINKPAD_ACPI, .name = "thinkpad"}, + {.id = ALC269_FIXUP_DMIC_THINKPAD_ACPI, .name = "dmic-thinkpad"}, + {.id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE, .name = "alc255-acer"}, + {.id = ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc255-asus"}, + {.id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"}, + {.id = ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "alc255-dell2"}, + {.id = ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc293-dell1"}, + {.id = ALC283_FIXUP_HEADSET_MIC, .name = "alc283-headset"}, + {.id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED, .name = "alc255-dell-mute"}, + {.id = ALC282_FIXUP_ASPIRE_V5_PINS, .name = "aspire-v5"}, + {.id = ALC280_FIXUP_HP_GPIO4, .name = "hp-gpio4"}, + {.id = ALC286_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, + {.id = ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY, .name = "hp-gpio2-hotkey"}, + {.id = ALC280_FIXUP_HP_DOCK_PINS, .name = "hp-dock-pins"}, + {.id = ALC269_FIXUP_HP_DOCK_GPIO_MIC1_LED, .name = "hp-dock-gpio-mic"}, + {.id = ALC280_FIXUP_HP_9480M, .name = "hp-9480m"}, + {.id = ALC288_FIXUP_DELL_HEADSET_MODE, .name = "alc288-dell-headset"}, + {.id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc288-dell1"}, + {.id = ALC288_FIXUP_DELL_XPS_13, .name = "alc288-dell-xps13"}, + {.id = ALC292_FIXUP_DELL_E7X, .name = "dell-e7x"}, + {.id = ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, .name = "alc293-dell"}, + {.id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc298-dell1"}, + {.id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, .name = "alc298-dell-aio"}, + {.id = ALC275_FIXUP_DELL_XPS, .name = "alc275-dell-xps"}, + {.id = ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, .name = "alc256-dell-xps13"}, + {.id = ALC293_FIXUP_LENOVO_SPK_NOISE, .name = "lenovo-spk-noise"}, + {.id = ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, .name = "lenovo-hotkey"}, + {.id = ALC255_FIXUP_DELL_SPK_NOISE, .name = "dell-spk-noise"}, + {.id = ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "alc255-dell1"}, + {.id = ALC295_FIXUP_DISABLE_DAC3, .name = "alc295-disable-dac3"}, + {.id = ALC280_FIXUP_HP_HEADSET_MIC, .name = "alc280-hp-headset"}, + {.id = ALC221_FIXUP_HP_FRONT_MIC, .name = "alc221-hp-mic"}, + {.id = ALC298_FIXUP_SPK_VOLUME, .name = "alc298-spk-volume"}, + {.id = ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, .name = "dell-inspiron-7559"}, + {.id = ALC269_FIXUP_ATIV_BOOK_8, .name = "ativ-book"}, + {.id = ALC221_FIXUP_HP_MIC_NO_PRESENCE, .name = "alc221-hp-mic"}, + {.id = ALC256_FIXUP_ASUS_HEADSET_MODE, .name = "alc256-asus-headset"}, + {.id = ALC256_FIXUP_ASUS_MIC, .name = "alc256-asus-mic"}, + {.id = ALC256_FIXUP_ASUS_AIO_GPIO2, .name = "alc256-asus-aio"}, + {.id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, .name = "alc233-asus"}, + {.id = ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, .name = "alc233-eapd"}, + {.id = ALC294_FIXUP_LENOVO_MIC_LOCATION, .name = "alc294-lenovo-mic"}, + {.id = ALC225_FIXUP_DELL_WYSE_MIC_NO_PRESENCE, .name = "alc225-wyse"}, + {.id = ALC274_FIXUP_DELL_AIO_LINEOUT_VERB, .name = "alc274-dell-aio"}, + {.id = ALC255_FIXUP_DUMMY_LINEOUT_VERB, .name = "alc255-dummy-lineout"}, + {.id = ALC255_FIXUP_DELL_HEADSET_MIC, .name = "alc255-dell-headset"}, + {.id = ALC295_FIXUP_HP_X360, .name = "alc295-hp-x360"}, {} }; #define ALC225_STANDARD_PINS \ @@ -6983,7 +7010,7 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x12, 0x90a60130}, {0x19, 0x03a11020}, {0x21, 0x0321101f}), - SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL_XPS_13_GPIO6, + SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, {0x12, 0x90a60120}, {0x14, 0x90170110}, {0x21, 0x0321101f}), @@ -7140,18 +7167,6 @@ static int patch_alc269(struct hda_codec *codec) spec->shutup = alc_default_shutup; spec->init_hook = alc_default_init; - snd_hda_pick_fixup(codec, alc269_fixup_models, - alc269_fixup_tbl, alc269_fixups); - snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups); - snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl, - alc269_fixups); - snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); - - alc_auto_parse_customize_define(codec); - - if (has_cdefine_beep(codec)) - spec->gen.beep_nid = 0x01; - switch (codec->core.vendor_id) { case 0x10ec0269: spec->codec_variant = ALC269_TYPE_ALC269VA; @@ -7271,13 +7286,28 @@ static int patch_alc269(struct hda_codec *codec) spec->init_hook = alc5505_dsp_init; } + snd_hda_pick_fixup(codec, alc269_fixup_models, + alc269_fixup_tbl, alc269_fixups); + snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups); + snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl, + alc269_fixups); + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); + + alc_auto_parse_customize_define(codec); + + if (has_cdefine_beep(codec)) + spec->gen.beep_nid = 0x01; + /* automatic parse from the BIOS config */ err = alc269_parse_auto_config(codec); if (err < 0) goto error; - if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) - set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT); + if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid) { + err = set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT); + if (err < 0) + goto error; + } snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); @@ -7406,8 +7436,11 @@ static int patch_alc861(struct hda_codec *codec) if (err < 0) goto error; - if (!spec->gen.no_analog) - set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); + if (!spec->gen.no_analog) { + err = set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); + if (err < 0) + goto error; + } snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); @@ -7447,16 +7480,21 @@ static void alc861vd_fixup_dallas(struct hda_codec *codec, } } +/* reset GPIO1 */ +static void alc660vd_fixup_asus_gpio1(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + + if (action == HDA_FIXUP_ACT_PRE_PROBE) + spec->gpio_mask |= 0x02; + alc_fixup_gpio(codec, action, 0x01); +} + static const struct hda_fixup alc861vd_fixups[] = { [ALC660VD_FIX_ASUS_GPIO1] = { - .type = HDA_FIXUP_VERBS, - .v.verbs = (const struct hda_verb[]) { - /* reset GPIO1 */ - {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, - { } - } + .type = HDA_FIXUP_FUNC, + .v.func = alc660vd_fixup_asus_gpio1, }, [ALC861VD_FIX_DALLAS] = { .type = HDA_FIXUP_FUNC, @@ -7495,8 +7533,11 @@ static int patch_alc861vd(struct hda_codec *codec) if (err < 0) goto error; - if (!spec->gen.no_analog) - set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); + if (!spec->gen.no_analog) { + err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); + if (err < 0) + goto error; + } snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); @@ -7577,7 +7618,7 @@ static unsigned int gpio_led_power_filter(struct hda_codec *codec, unsigned int power_state) { struct alc_spec *spec = codec->spec; - if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_led) + if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_data) return AC_PWRST_D0; return power_state; } @@ -7586,18 +7627,10 @@ static void alc662_fixup_led_gpio1(struct hda_codec *codec, const struct hda_fixup *fix, int action) { struct alc_spec *spec = codec->spec; - static const struct hda_verb gpio_init[] = { - { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 }, - { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 }, - {} - }; + alc_fixup_hp_gpio_led(codec, action, 0x01, 0); if (action == HDA_FIXUP_ACT_PRE_PROBE) { - spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook; - spec->gpio_led = 0; spec->mute_led_polarity = 1; - spec->gpio_mute_led_mask = 0x01; - snd_hda_add_verbs(codec, gpio_init); codec->power_filter = gpio_led_power_filter; } } @@ -8110,7 +8143,10 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { }; static const struct hda_model_fixup alc662_fixup_models[] = { + {.id = ALC662_FIXUP_ASPIRE, .name = "aspire"}, + {.id = ALC662_FIXUP_IDEAPAD, .name = "ideapad"}, {.id = ALC272_FIXUP_MARIO, .name = "mario"}, + {.id = ALC662_FIXUP_HP_RP5800, .name = "hp-rp5800"}, {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"}, @@ -8119,8 +8155,23 @@ static const struct hda_model_fixup alc662_fixup_models[] = { {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, + {.id = ALC662_FIXUP_ZOTAC_Z68, .name = "zotac-z68"}, {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, + {.id = ALC662_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc662-headset-multi"}, {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, + {.id = ALC662_FIXUP_HEADSET_MODE, .name = "alc662-headset"}, + {.id = ALC668_FIXUP_HEADSET_MODE, .name = "alc668-headset"}, + {.id = ALC662_FIXUP_BASS_16, .name = "bass16"}, + {.id = ALC662_FIXUP_BASS_1A, .name = "bass1a"}, + {.id = ALC668_FIXUP_AUTO_MUTE, .name = "automute"}, + {.id = ALC668_FIXUP_DELL_XPS13, .name = "dell-xps13"}, + {.id = ALC662_FIXUP_ASUS_Nx50, .name = "asus-nx50"}, + {.id = ALC668_FIXUP_ASUS_Nx51, .name = "asus-nx51"}, + {.id = ALC891_FIXUP_HEADSET_MODE, .name = "alc891-headset"}, + {.id = ALC891_FIXUP_DELL_MIC_NO_PRESENCE, .name = "alc891-headset-multi"}, + {.id = ALC662_FIXUP_ACER_VERITON, .name = "acer-veriton"}, + {.id = ALC892_FIXUP_ASROCK_MOBO, .name = "asrock-mobo"}, + {.id = ALC662_FIXUP_USI_HEADSET_MODE, .name = "usi-headset"}, {.id = ALC662_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"}, {} }; @@ -8214,18 +8265,20 @@ static int patch_alc662(struct hda_codec *codec) if (!spec->gen.no_analog && spec->gen.beep_nid) { switch (codec->core.vendor_id) { case 0x10ec0662: - set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); + err = set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); break; case 0x10ec0272: case 0x10ec0663: case 0x10ec0665: case 0x10ec0668: - set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); + err = set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); break; case 0x10ec0273: - set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); + err = set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); break; } + if (err < 0) + goto error; } snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 63d15b545b33..046705b4691a 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -332,33 +332,15 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, } /* hook for controlling mic-mute LED GPIO */ -static void stac_capture_led_hook(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static void stac_capture_led_update(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; - unsigned int mask; - bool cur_mute, prev_mute; - if (!kcontrol || !ucontrol) - return; - - mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); - prev_mute = !spec->mic_enabled; - if (ucontrol->value.integer.value[0] || - ucontrol->value.integer.value[1]) - spec->mic_enabled |= mask; + if (spec->gen.micmute_led.led_value) + spec->gpio_data |= spec->mic_mute_led_gpio; else - spec->mic_enabled &= ~mask; - cur_mute = !spec->mic_enabled; - if (cur_mute != prev_mute) { - if (cur_mute) - spec->gpio_data |= spec->mic_mute_led_gpio; - else - spec->gpio_data &= ~spec->mic_mute_led_gpio; - stac_gpio_set(codec, spec->gpio_mask, - spec->gpio_dir, spec->gpio_data); - } + spec->gpio_data &= ~spec->mic_mute_led_gpio; + stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); } static int stac_vrefout_set(struct hda_codec *codec, @@ -4656,8 +4638,7 @@ static void stac_setup_gpio(struct hda_codec *codec) spec->gpio_dir |= spec->mic_mute_led_gpio; spec->mic_enabled = 0; spec->gpio_data |= spec->mic_mute_led_gpio; - - spec->gen.cap_sync_hook = stac_capture_led_hook; + snd_hda_gen_add_micmute_led(codec, stac_capture_led_update); } } diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index fc30d1e8aa76..6b9617aee0e6 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -90,13 +90,6 @@ enum VIA_HDA_CODEC { struct via_spec { struct hda_gen_spec gen; - /* codec parameterization */ - const struct snd_kcontrol_new *mixers[6]; - unsigned int num_mixers; - - const struct hda_verb *init_verbs[5]; - unsigned int num_iverbs; - /* HP mode source */ unsigned int dmic_enabled; enum VIA_HDA_CODEC codec_type; @@ -107,8 +100,6 @@ struct via_spec { /* work to check hp jack state */ int hp_work_active; int vt1708_jack_detect; - - unsigned int beep_amp; }; static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec); @@ -262,69 +253,51 @@ static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol, return 1; } -static const struct snd_kcontrol_new via_pin_power_ctl_enum[] = { - { +static const struct snd_kcontrol_new via_pin_power_ctl_enum = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Dynamic Power-Control", .info = via_pin_power_ctl_info, .get = via_pin_power_ctl_get, .put = via_pin_power_ctl_put, - }, - {} /* terminator */ }; #ifdef CONFIG_SND_HDA_INPUT_BEEP -static inline void set_beep_amp(struct via_spec *spec, hda_nid_t nid, - int idx, int dir) -{ - spec->gen.beep_nid = nid; - spec->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir); -} - /* additional beep mixers; the actual parameters are overwritten at build */ -static const struct snd_kcontrol_new cxt_beep_mixer[] = { +static const struct snd_kcontrol_new via_beep_mixer[] = { HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), - { } /* end */ }; -/* create beep controls if needed */ -static int add_beep_ctls(struct hda_codec *codec) +static int set_beep_amp(struct via_spec *spec, hda_nid_t nid, + int idx, int dir) { - struct via_spec *spec = codec->spec; - int err; + struct snd_kcontrol_new *knew; + unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir); + int i; - if (spec->beep_amp) { - const struct snd_kcontrol_new *knew; - for (knew = cxt_beep_mixer; knew->name; knew++) { - struct snd_kcontrol *kctl; - kctl = snd_ctl_new1(knew, codec); - if (!kctl) - return -ENOMEM; - kctl->private_value = spec->beep_amp; - err = snd_hda_ctl_add(codec, 0, kctl); - if (err < 0) - return err; - } + spec->gen.beep_nid = nid; + for (i = 0; i < ARRAY_SIZE(via_beep_mixer); i++) { + knew = snd_hda_gen_add_kctl(&spec->gen, NULL, + &via_beep_mixer[i]); + if (!knew) + return -ENOMEM; + knew->private_value = beep_amp; } return 0; } -static void auto_parse_beep(struct hda_codec *codec) +static int auto_parse_beep(struct hda_codec *codec) { struct via_spec *spec = codec->spec; hda_nid_t nid; for_each_hda_codec_node(nid, codec) - if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) { - set_beep_amp(spec, nid, 0, HDA_OUTPUT); - break; - } + if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) + return set_beep_amp(spec, nid, 0, HDA_OUTPUT); + return 0; } #else -#define set_beep_amp(spec, nid, idx, dir) /* NOP */ -#define add_beep_ctls(codec) 0 -#define auto_parse_beep(codec) +#define auto_parse_beep(codec) 0 #endif /* check AA path's mute status */ @@ -403,30 +376,6 @@ static void analog_low_current_mode(struct hda_codec *codec) return __analog_low_current_mode(codec, false); } -static int via_build_controls(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - int err, i; - - err = snd_hda_gen_build_controls(codec); - if (err < 0) - return err; - - err = add_beep_ctls(codec); - if (err < 0) - return err; - - spec->mixers[spec->num_mixers++] = via_pin_power_ctl_enum; - - for (i = 0; i < spec->num_mixers; i++) { - err = snd_hda_add_new_ctls(codec, spec->mixers[i]); - if (err < 0) - return err; - } - - return 0; -} - static void via_playback_pcm_hook(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream, @@ -481,7 +430,7 @@ static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid) static int via_init(struct hda_codec *codec); static const struct hda_codec_ops via_patch_ops = { - .build_controls = via_build_controls, + .build_controls = snd_hda_gen_build_controls, .build_pcms = snd_hda_gen_build_pcms, .init = via_init, .free = via_free, @@ -545,16 +494,13 @@ static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol, return 1; } -static const struct snd_kcontrol_new vt1708_jack_detect_ctl[] = { - { +static const struct snd_kcontrol_new vt1708_jack_detect_ctl = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Jack Detect", .count = 1, .info = snd_ctl_boolean_mono_info, .get = vt1708_jack_detect_get, .put = vt1708_jack_detect_put, - }, - {} /* terminator */ }; static const struct badness_table via_main_out_badness = { @@ -586,12 +532,17 @@ static int via_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; - auto_parse_beep(codec); - err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); if (err < 0) return err; + err = auto_parse_beep(codec); + if (err < 0) + return err; + + if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &via_pin_power_ctl_enum)) + return -ENOMEM; + /* disable widget PM at start for compatibility */ codec->power_save_node = 0; spec->gen.power_down_unused = 0; @@ -600,12 +551,6 @@ static int via_parse_auto_config(struct hda_codec *codec) static int via_init(struct hda_codec *codec) { - struct via_spec *spec = codec->spec; - int i; - - for (i = 0; i < spec->num_iverbs; i++) - snd_hda_sequence_write(codec, spec->init_verbs[i]); - /* init power states */ __analog_low_current_mode(codec, true); @@ -623,7 +568,7 @@ static int vt1708_build_controls(struct hda_codec *codec) int err; int old_interval = codec->jackpoll_interval; codec->jackpoll_interval = msecs_to_jiffies(100); - err = via_build_controls(codec); + err = snd_hda_gen_build_controls(codec); codec->jackpoll_interval = old_interval; return err; } @@ -684,22 +629,29 @@ static int patch_vt1708(struct hda_codec *codec) vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID); vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID); + err = snd_hda_add_verbs(codec, vt1708_init_verbs); + if (err < 0) + goto error; + /* automatic parse from the BIOS config */ err = via_parse_auto_config(codec); - if (err < 0) { - via_free(codec); - return err; - } + if (err < 0) + goto error; /* add jack detect on/off control */ - spec->mixers[spec->num_mixers++] = vt1708_jack_detect_ctl; - - spec->init_verbs[spec->num_iverbs++] = vt1708_init_verbs; + if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &vt1708_jack_detect_ctl)) { + err = -ENOMEM; + goto error; + } /* clear jackpoll_interval again; it's set dynamically */ codec->jackpoll_interval = 0; return 0; + + error: + via_free(codec); + return err; } static int patch_vt1709(struct hda_codec *codec) @@ -715,12 +667,14 @@ static int patch_vt1709(struct hda_codec *codec) spec->gen.mixer_nid = 0x18; err = via_parse_auto_config(codec); - if (err < 0) { - via_free(codec); - return err; - } + if (err < 0) + goto error; return 0; + + error: + via_free(codec); + return err; } static int patch_vt1708S(struct hda_codec *codec); @@ -741,12 +695,14 @@ static int patch_vt1708B(struct hda_codec *codec) /* automatic parse from the BIOS config */ err = via_parse_auto_config(codec); - if (err < 0) { - via_free(codec); - return err; - } + if (err < 0) + goto error; return 0; + + error: + via_free(codec); + return err; } /* Patch for VT1708S */ @@ -791,16 +747,20 @@ static int patch_vt1708S(struct hda_codec *codec) if (codec->core.vendor_id == 0x11064397) snd_hda_codec_set_name(codec, "VT1705"); + err = snd_hda_add_verbs(codec, vt1708S_init_verbs); + if (err < 0) + goto error; + /* automatic parse from the BIOS config */ err = via_parse_auto_config(codec); - if (err < 0) { - via_free(codec); - return err; - } - - spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs; + if (err < 0) + goto error; return 0; + + error: + via_free(codec); + return err; } /* Patch for VT1702 */ @@ -832,16 +792,20 @@ static int patch_vt1702(struct hda_codec *codec) (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) | (1 << AC_AMPCAP_MUTE_SHIFT)); + err = snd_hda_add_verbs(codec, vt1702_init_verbs); + if (err < 0) + goto error; + /* automatic parse from the BIOS config */ err = via_parse_auto_config(codec); - if (err < 0) { - via_free(codec); - return err; - } - - spec->init_verbs[spec->num_iverbs++] = vt1702_init_verbs; + if (err < 0) + goto error; return 0; + + error: + via_free(codec); + return err; } /* Patch for VT1718S */ @@ -904,16 +868,20 @@ static int patch_vt1718S(struct hda_codec *codec) override_mic_boost(codec, 0x29, 0, 3, 40); add_secret_dac_path(codec); + err = snd_hda_add_verbs(codec, vt1718S_init_verbs); + if (err < 0) + goto error; + /* automatic parse from the BIOS config */ err = via_parse_auto_config(codec); - if (err < 0) { - via_free(codec); - return err; - } - - spec->init_verbs[spec->num_iverbs++] = vt1718S_init_verbs; + if (err < 0) + goto error; return 0; + + error: + via_free(codec); + return err; } /* Patch for VT1716S */ @@ -955,9 +923,9 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol, return 1; } -static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = { - HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT), - { +static const struct snd_kcontrol_new vt1716s_dmic_mixer_vol = + HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT); +static const struct snd_kcontrol_new vt1716s_dmic_mixer_sw = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Digital Mic Capture Switch", .subdevice = HDA_SUBDEV_NID_FLAG | 0x26, @@ -965,16 +933,12 @@ static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = { .info = vt1716s_dmic_info, .get = vt1716s_dmic_get, .put = vt1716s_dmic_put, - }, - {} /* end */ }; /* mono-out mixer elements */ -static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = { - HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT), - { } /* end */ -}; +static const struct snd_kcontrol_new vt1716S_mono_out_mixer = + HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT); static const struct hda_verb vt1716S_init_verbs[] = { /* Enable Boost Volume backdoor */ @@ -1000,19 +964,27 @@ static int patch_vt1716S(struct hda_codec *codec) override_mic_boost(codec, 0x1a, 0, 3, 40); override_mic_boost(codec, 0x1e, 0, 3, 40); + err = snd_hda_add_verbs(codec, vt1716S_init_verbs); + if (err < 0) + goto error; + /* automatic parse from the BIOS config */ err = via_parse_auto_config(codec); - if (err < 0) { - via_free(codec); - return err; - } - - spec->init_verbs[spec->num_iverbs++] = vt1716S_init_verbs; + if (err < 0) + goto error; - spec->mixers[spec->num_mixers++] = vt1716s_dmic_mixer; - spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer; + if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &vt1716s_dmic_mixer_vol) || + !snd_hda_gen_add_kctl(&spec->gen, NULL, &vt1716s_dmic_mixer_sw) || + !snd_hda_gen_add_kctl(&spec->gen, NULL, &vt1716S_mono_out_mixer)) { + err = -ENOMEM; + goto error; + } return 0; + + error: + via_free(codec); + return err; } /* for vt2002P */ @@ -1107,19 +1079,23 @@ static int patch_vt2002P(struct hda_codec *codec) snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups); snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); - /* automatic parse from the BIOS config */ - err = via_parse_auto_config(codec); - if (err < 0) { - via_free(codec); - return err; - } - if (spec->codec_type == VT1802) - spec->init_verbs[spec->num_iverbs++] = vt1802_init_verbs; + err = snd_hda_add_verbs(codec, vt1802_init_verbs); else - spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs; + err = snd_hda_add_verbs(codec, vt2002P_init_verbs); + if (err < 0) + goto error; + + /* automatic parse from the BIOS config */ + err = via_parse_auto_config(codec); + if (err < 0) + goto error; return 0; + + error: + via_free(codec); + return err; } /* for vt1812 */ @@ -1148,16 +1124,20 @@ static int patch_vt1812(struct hda_codec *codec) override_mic_boost(codec, 0x29, 0, 3, 40); add_secret_dac_path(codec); + err = snd_hda_add_verbs(codec, vt1812_init_verbs); + if (err < 0) + goto error; + /* automatic parse from the BIOS config */ err = via_parse_auto_config(codec); - if (err < 0) { - via_free(codec); - return err; - } - - spec->init_verbs[spec->num_iverbs++] = vt1812_init_verbs; + if (err < 0) + goto error; return 0; + + error: + via_free(codec); + return err; } /* patch for vt3476 */ @@ -1185,16 +1165,20 @@ static int patch_vt3476(struct hda_codec *codec) spec->gen.mixer_nid = 0x3f; add_secret_dac_path(codec); + err = snd_hda_add_verbs(codec, vt3476_init_verbs); + if (err < 0) + goto error; + /* automatic parse from the BIOS config */ err = via_parse_auto_config(codec); - if (err < 0) { - via_free(codec); - return err; - } - - spec->init_verbs[spec->num_iverbs++] = vt3476_init_verbs; + if (err < 0) + goto error; return 0; + + error: + via_free(codec); + return err; } /* diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c index 65bb3ac6af4c..97f49b751e6e 100644 --- a/sound/pci/hda/thinkpad_helper.c +++ b/sound/pci/hda/thinkpad_helper.c @@ -27,17 +27,11 @@ static void update_tpacpi_mute_led(void *private_data, int enabled) led_set_func(TPACPI_LED_MUTE, !enabled); } -static void update_tpacpi_micmute_led(struct hda_codec *codec, - struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static void update_tpacpi_micmute(struct hda_codec *codec) { - if (!ucontrol || !led_set_func) - return; - if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) { - /* TODO: How do I verify if it's a mono or stereo here? */ - bool val = ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]; - led_set_func(TPACPI_LED_MICMUTE, !val); - } + struct hda_gen_spec *spec = codec->spec; + + led_set_func(TPACPI_LED_MICMUTE, spec->micmute_led.led_value); } static void hda_fixup_thinkpad_acpi(struct hda_codec *codec, @@ -63,15 +57,10 @@ static void hda_fixup_thinkpad_acpi(struct hda_codec *codec, spec->vmaster_mute.hook = update_tpacpi_mute_led; removefunc = false; } - if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) { - if (spec->num_adc_nids > 1 && !spec->dyn_adc_switch) - codec_dbg(codec, - "Skipping micmute LED control due to several ADCs"); - else { - spec->cap_sync_hook = update_tpacpi_micmute_led; - removefunc = false; - } - } + if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0 && + snd_hda_gen_add_micmute_led(codec, + update_tpacpi_micmute) > 0) + removefunc = false; } if (led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) { diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c index 179ef7a5f0d1..a553897a4c4f 100644 --- a/sound/pci/ice1712/ak4xxx.c +++ b/sound/pci/ice1712/ak4xxx.c @@ -179,18 +179,6 @@ int snd_ice1712_akm4xxx_build_controls(struct snd_ice1712 *ice) return 0; } -static int __init alsa_ice1712_akm4xxx_module_init(void) -{ - return 0; -} - -static void __exit alsa_ice1712_akm4xxx_module_exit(void) -{ -} - -module_init(alsa_ice1712_akm4xxx_module_init) -module_exit(alsa_ice1712_akm4xxx_module_exit) - EXPORT_SYMBOL(snd_ice1712_akm4xxx_init); EXPORT_SYMBOL(snd_ice1712_akm4xxx_free); EXPORT_SYMBOL(snd_ice1712_akm4xxx_build_controls); diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c index d7366ade5a25..c97b5528e4b8 100644 --- a/sound/pci/ice1712/prodigy_hifi.c +++ b/sound/pci/ice1712/prodigy_hifi.c @@ -314,26 +314,7 @@ static struct snd_kcontrol_new prodigy_hd2_controls[] = { /* --------------- */ -/* - * Logarithmic volume values for WM87*6 - * Computed as 20 * Log10(255 / x) - */ -static const unsigned char wm_vol[256] = { - 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23, - 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, - 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, - 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 -}; - -#define WM_VOL_MAX (sizeof(wm_vol) - 1) +#define WM_VOL_MAX 255 #define WM_VOL_MUTE 0x8000 diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 4c24346340f4..5ee468d1aefe 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -351,7 +351,7 @@ enum { struct ichdev { unsigned int ichd; /* ich device number */ unsigned long reg_offset; /* offset to bmaddr */ - u32 *bdbar; /* CPU address (32bit) */ + __le32 *bdbar; /* CPU address (32bit) */ unsigned int bdbar_addr; /* PCI bus address (32bit) */ struct snd_pcm_substream *substream; unsigned int physbuf; /* physical address (32bit) */ @@ -677,7 +677,7 @@ static void snd_intel8x0_ali_codec_write(struct snd_ac97 *ac97, unsigned short r static void snd_intel8x0_setup_periods(struct intel8x0 *chip, struct ichdev *ichdev) { int idx; - u32 *bdbar = ichdev->bdbar; + __le32 *bdbar = ichdev->bdbar; unsigned long port = ichdev->reg_offset; iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr); @@ -3143,7 +3143,7 @@ static int snd_intel8x0_create(struct snd_card *card, int_sta_masks = 0; for (i = 0; i < chip->bdbars_count; i++) { ichdev = &chip->ichd[i]; - ichdev->bdbar = ((u32 *)chip->bdbars.area) + + ichdev->bdbar = ((__le32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2); ichdev->bdbar_addr = chip->bdbars.addr + (i * sizeof(u32) * ICH_MAX_FRAGS * 2); diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index 3a4769a97d29..943a726b1c1b 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c @@ -168,7 +168,7 @@ enum { ALID_MDMIN, ALID_MDMOUT, ALID_MDMLAST = ALID_MDMOUT }; struct ichdev { unsigned int ichd; /* ich device number */ unsigned long reg_offset; /* offset to bmaddr */ - u32 *bdbar; /* CPU address (32bit) */ + __le32 *bdbar; /* CPU address (32bit) */ unsigned int bdbar_addr; /* PCI bus address (32bit) */ struct snd_pcm_substream *substream; unsigned int physbuf; /* physical address (32bit) */ @@ -395,7 +395,7 @@ static unsigned short snd_intel8x0m_codec_read(struct snd_ac97 *ac97, static void snd_intel8x0m_setup_periods(struct intel8x0m *chip, struct ichdev *ichdev) { int idx; - u32 *bdbar = ichdev->bdbar; + __le32 *bdbar = ichdev->bdbar; unsigned long port = ichdev->reg_offset; iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr); @@ -1217,7 +1217,7 @@ static int snd_intel8x0m_create(struct snd_card *card, int_sta_masks = 0; for (i = 0; i < chip->bdbars_count; i++) { ichdev = &chip->ichd[i]; - ichdev->bdbar = ((u32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2); + ichdev->bdbar = ((__le32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2); ichdev->bdbar_addr = chip->bdbars.addr + (i * sizeof(u32) * ICH_MAX_FRAGS * 2); int_sta_masks |= ichdev->int_sta_mask; } diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 4206ba44d8bb..4e189a93f475 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -1326,7 +1326,7 @@ static int snd_korg1212_copy_to(struct snd_pcm_substream *substream, } #endif if (in_kernel) - memcpy((void *)dst, src, size); + memcpy((__force void *)dst, src, size); else if (copy_to_user(dst, src, size)) return -EFAULT; src++; @@ -1365,7 +1365,7 @@ static int snd_korg1212_copy_from(struct snd_pcm_substream *substream, } #endif if (in_kernel) - memcpy((void *)dst, src, size); + memcpy(dst, (__force void *)src, size); else if (copy_from_user(dst, src, size)) return -EFAULT; dst++; diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c index 9ff600084973..254f24366892 100644 --- a/sound/pci/lola/lola.c +++ b/sound/pci/lola/lola.c @@ -369,9 +369,9 @@ static int setup_corb_rirb(struct lola *chip) return err; chip->corb.addr = chip->rb.addr; - chip->corb.buf = (u32 *)chip->rb.area; + chip->corb.buf = (__le32 *)chip->rb.area; chip->rirb.addr = chip->rb.addr + 2048; - chip->rirb.buf = (u32 *)(chip->rb.area + 2048); + chip->rirb.buf = (__le32 *)(chip->rb.area + 2048); /* disable ringbuffer DMAs */ lola_writeb(chip, BAR0, RIRBCTL, 0); diff --git a/sound/pci/lola/lola.h b/sound/pci/lola/lola.h index f0b100059efd..bd852fed8bb6 100644 --- a/sound/pci/lola/lola.h +++ b/sound/pci/lola/lola.h @@ -220,7 +220,7 @@ struct lola_bar { /* CORB/RIRB */ struct lola_rb { - u32 *buf; /* CORB/RIRB buffer, 8 byte per each entry */ + __le32 *buf; /* CORB/RIRB buffer, 8 byte per each entry */ dma_addr_t addr; /* physical address of CORB/RIRB buffer */ unsigned short rp, wp; /* read/write pointers */ int cmds; /* number of pending requests */ @@ -275,7 +275,7 @@ struct lola_mixer_array { struct lola_mixer_widget { unsigned int nid; unsigned int caps; - struct lola_mixer_array __user *array; + struct lola_mixer_array __iomem *array; struct lola_mixer_array *array_saved; unsigned int src_stream_outs; unsigned int src_phys_ins; diff --git a/sound/pci/lola/lola_pcm.c b/sound/pci/lola/lola_pcm.c index 310b26a756c9..e70276c3ea20 100644 --- a/sound/pci/lola/lola_pcm.c +++ b/sound/pci/lola/lola_pcm.c @@ -316,10 +316,10 @@ static int lola_pcm_hw_free(struct snd_pcm_substream *substream) * set up a BDL entry */ static int setup_bdle(struct snd_pcm_substream *substream, - struct lola_stream *str, u32 **bdlp, + struct lola_stream *str, __le32 **bdlp, int ofs, int size) { - u32 *bdl = *bdlp; + __le32 *bdl = *bdlp; while (size > 0) { dma_addr_t addr; @@ -355,14 +355,14 @@ static int lola_setup_periods(struct lola *chip, struct lola_pcm *pcm, struct snd_pcm_substream *substream, struct lola_stream *str) { - u32 *bdl; + __le32 *bdl; int i, ofs, periods, period_bytes; period_bytes = str->period_bytes; periods = str->bufsize / period_bytes; /* program the initial BDL entries */ - bdl = (u32 *)(pcm->bdl.area + LOLA_BDL_ENTRY_SIZE * str->index); + bdl = (__le32 *)(pcm->bdl.area + LOLA_BDL_ENTRY_SIZE * str->index); ofs = 0; str->frags = 0; for (i = 0; i < periods; i++) { diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 224e942f556d..62962178a9d7 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -2103,7 +2103,7 @@ static const u16 minisrc_lpf[MINISRC_LPF_LEN] = { static void snd_m3_assp_init(struct snd_m3 *chip) { unsigned int i; - const u16 *data; + const __le16 *data; /* zero kernel data */ for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++) @@ -2121,7 +2121,7 @@ static void snd_m3_assp_init(struct snd_m3 *chip) KDATA_DMA_XFER0); /* write kernel into code memory.. */ - data = (const u16 *)chip->assp_kernel_image->data; + data = (const __le16 *)chip->assp_kernel_image->data; for (i = 0 ; i * 2 < chip->assp_kernel_image->size; i++) { snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, REV_B_CODE_MEMORY_BEGIN + i, @@ -2134,7 +2134,7 @@ static void snd_m3_assp_init(struct snd_m3 *chip) * drop it there. It seems that the minisrc doesn't * need vectors, so we won't bother with them.. */ - data = (const u16 *)chip->assp_minisrc_image->data; + data = (const __le16 *)chip->assp_minisrc_image->data; for (i = 0; i * 2 < chip->assp_minisrc_image->size; i++) { snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, 0x400 + i, le16_to_cpu(data[i])); diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index a74f1ad7e7b8..9cd297a42f24 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -182,6 +182,7 @@ static int mixart_set_clock(struct mixart_mgr *mgr, case PIPE_RUNNING: if(rate != 0) break; + /* fall through */ default: if(rate == 0) return 0; /* nothing to do */ diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c index 8bf2ce32d4a8..71776bfe0485 100644 --- a/sound/pci/mixart/mixart_core.c +++ b/sound/pci/mixart/mixart_core.c @@ -107,7 +107,7 @@ static int get_msg(struct mixart_mgr *mgr, struct mixart_msg *resp, #ifndef __BIG_ENDIAN size /= 4; /* u32 size */ for(i=0; i < size; i++) { - ((u32*)resp->data)[i] = be32_to_cpu(((u32*)resp->data)[i]); + ((u32*)resp->data)[i] = be32_to_cpu(((__be32*)resp->data)[i]); } #endif @@ -519,7 +519,7 @@ irqreturn_t snd_mixart_threaded_irq(int irq, void *dev_id) /* Traces are text: the swapped msg_data has to be swapped back ! */ int i; for(i=0; i<(resp.size/4); i++) { - (mixart_msg_data)[i] = cpu_to_be32((mixart_msg_data)[i]); + ((__be32*)mixart_msg_data)[i] = cpu_to_be32((mixart_msg_data)[i]); } #endif ((char*)mixart_msg_data)[resp.size - 1] = 0; @@ -540,7 +540,7 @@ irqreturn_t snd_mixart_threaded_irq(int irq, void *dev_id) dev_err(&mgr->pci->dev, "canceled notification %x !\n", msg); } - /* no break, continue ! */ + /* fall through */ case MSG_TYPE_ANSWER: /* answer or notification to a message we are waiting for*/ mutex_lock(&mgr->msg_lock); diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c index 5bfd3ac80db5..bc92758de82c 100644 --- a/sound/pci/mixart/mixart_hwdep.c +++ b/sound/pci/mixart/mixart_hwdep.c @@ -73,30 +73,30 @@ static int mixart_wait_nice_for_register_value(struct mixart_mgr *mgr, */ struct snd_mixart_elf32_ehdr { u8 e_ident[16]; - u16 e_type; - u16 e_machine; - u32 e_version; - u32 e_entry; - u32 e_phoff; - u32 e_shoff; - u32 e_flags; - u16 e_ehsize; - u16 e_phentsize; - u16 e_phnum; - u16 e_shentsize; - u16 e_shnum; - u16 e_shstrndx; + __be16 e_type; + __be16 e_machine; + __be32 e_version; + __be32 e_entry; + __be32 e_phoff; + __be32 e_shoff; + __be32 e_flags; + __be16 e_ehsize; + __be16 e_phentsize; + __be16 e_phnum; + __be16 e_shentsize; + __be16 e_shnum; + __be16 e_shstrndx; }; struct snd_mixart_elf32_phdr { - u32 p_type; - u32 p_offset; - u32 p_vaddr; - u32 p_paddr; - u32 p_filesz; - u32 p_memsz; - u32 p_flags; - u32 p_align; + __be32 p_type; + __be32 p_offset; + __be32 p_vaddr; + __be32 p_paddr; + __be32 p_filesz; + __be32 p_memsz; + __be32 p_flags; + __be32 p_align; }; static int mixart_load_elf(struct mixart_mgr *mgr, const struct firmware *dsp ) diff --git a/sound/pci/mixart/mixart_hwdep.h b/sound/pci/mixart/mixart_hwdep.h index 812e288ef2e7..2794cd385b8e 100644 --- a/sound/pci/mixart/mixart_hwdep.h +++ b/sound/pci/mixart/mixart_hwdep.h @@ -26,19 +26,19 @@ #include <sound/hwdep.h> #ifndef readl_be -#define readl_be(x) be32_to_cpu(__raw_readl(x)) +#define readl_be(x) be32_to_cpu((__force __be32)__raw_readl(x)) #endif #ifndef writel_be -#define writel_be(data,addr) __raw_writel(cpu_to_be32(data),addr) +#define writel_be(data,addr) __raw_writel((__force u32)cpu_to_be32(data),addr) #endif #ifndef readl_le -#define readl_le(x) le32_to_cpu(__raw_readl(x)) +#define readl_le(x) le32_to_cpu((__force __le32)__raw_readl(x)) #endif #ifndef writel_le -#define writel_le(data,addr) __raw_writel(cpu_to_le32(data),addr) +#define writel_le(data,addr) __raw_writel((__force u32)cpu_to_le32(data),addr) #endif #define MIXART_MEM(mgr,x) ((mgr)->mem[0].virt + (x)) diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index 44f3b48d47b1..23017e3bc76c 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -470,10 +470,10 @@ struct snd_riptide { }; struct sgd { /* scatter gather desriptor */ - u32 dwNextLink; - u32 dwSegPtrPhys; - u32 dwSegLen; - u32 dwStat_Ctl; + __le32 dwNextLink; + __le32 dwSegPtrPhys; + __le32 dwSegLen; + __le32 dwStat_Ctl; }; struct pcmhw { /* pcm descriptor */ @@ -1017,7 +1017,7 @@ getsamplerate(struct cmdif *cif, unsigned char *intdec, unsigned int *rate) static int setsampleformat(struct cmdif *cif, unsigned char mixer, unsigned char id, - unsigned char channels, unsigned char format) + unsigned char channels, snd_pcm_format_t format) { unsigned char w, ch, sig, order; diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 7fbdb703bfcd..7218f38b59db 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c @@ -1433,14 +1433,12 @@ static int snd_sonicvibes_midi(struct sonicvibes *sonic, { struct snd_mpu401 * mpu = rmidi->private_data; struct snd_card *card = sonic->card; - struct snd_rawmidi_str *dir; unsigned int idx; int err; mpu->private_data = sonic; mpu->open_input = snd_sonicvibes_midi_input_open; mpu->close_input = snd_sonicvibes_midi_input_close; - dir = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]; for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_midi_controls); idx++) if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_sonicvibes_midi_controls[idx], sonic))) < 0) return err; diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c index cedf13b64803..2f18b1cdc2cd 100644 --- a/sound/pci/trident/trident.c +++ b/sound/pci/trident/trident.c @@ -123,7 +123,7 @@ static int snd_trident_probe(struct pci_dev *pci, } else { strcpy(card->shortname, "Trident "); } - strcat(card->shortname, card->driver); + strcat(card->shortname, str); sprintf(card->longname, "%s PCI Audio at 0x%lx, irq %d", card->shortname, trident->port, trident->irq); diff --git a/sound/pci/trident/trident.h b/sound/pci/trident/trident.h index 9624e5937719..2d62c1921255 100644 --- a/sound/pci/trident/trident.h +++ b/sound/pci/trident/trident.h @@ -264,7 +264,7 @@ struct snd_trident_memblk_arg { }; struct snd_trident_tlb { - unsigned int * entries; /* 16k-aligned TLB table */ + __le32 *entries; /* 16k-aligned TLB table */ dma_addr_t entries_dmaaddr; /* 16k-aligned PCI address to TLB table */ unsigned long * shadow_entries; /* shadow entries with virtual addresses */ struct snd_dma_buffer buffer; diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 49c64fae3466..5523e193d556 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -3359,7 +3359,7 @@ static int snd_trident_tlb_alloc(struct snd_trident *trident) dev_err(trident->card->dev, "unable to allocate TLB buffer\n"); return -ENOMEM; } - trident->tlb.entries = (unsigned int*)ALIGN((unsigned long)trident->tlb.buffer.area, SNDRV_TRIDENT_MAX_PAGES * 4); + trident->tlb.entries = (__le32 *)ALIGN((unsigned long)trident->tlb.buffer.area, SNDRV_TRIDENT_MAX_PAGES * 4); trident->tlb.entries_dmaaddr = ALIGN(trident->tlb.buffer.addr, SNDRV_TRIDENT_MAX_PAGES * 4); /* allocate shadow TLB page table (virtual addresses) */ trident->tlb.shadow_entries = diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c index d4298af6d3ee..c0d0bf44f365 100644 --- a/sound/pci/vx222/vx222_ops.c +++ b/sound/pci/vx222/vx222_ops.c @@ -275,7 +275,7 @@ static void vx2_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime, length >>= 2; /* in 32bit words */ /* Transfer using pseudo-dma. */ for (; length > 0; length--) { - outl(cpu_to_le32(*addr), port); + outl(*addr, port); addr++; } addr = (u32 *)runtime->dma_area; @@ -285,7 +285,7 @@ static void vx2_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime, count >>= 2; /* in 32bit words */ /* Transfer using pseudo-dma. */ for (; count > 0; count--) { - outl(cpu_to_le32(*addr), port); + outl(*addr, port); addr++; } @@ -313,7 +313,7 @@ static void vx2_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime, length >>= 2; /* in 32bit words */ /* Transfer using pseudo-dma. */ for (; length > 0; length--) - *addr++ = le32_to_cpu(inl(port)); + *addr++ = inl(port); addr = (u32 *)runtime->dma_area; pipe->hw_ptr = 0; } @@ -321,7 +321,7 @@ static void vx2_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime, count >>= 2; /* in 32bit words */ /* Transfer using pseudo-dma. */ for (; count > 0; count--) - *addr++ = le32_to_cpu(inl(port)); + *addr++ = inl(port); vx2_release_pseudo_dma(chip); } diff --git a/sound/pci/ymfpci/ymfpci.h b/sound/pci/ymfpci/ymfpci.h index aa9bb065f385..e2fa7e360d79 100644 --- a/sound/pci/ymfpci/ymfpci.h +++ b/sound/pci/ymfpci/ymfpci.h @@ -185,50 +185,50 @@ */ struct snd_ymfpci_playback_bank { - u32 format; - u32 loop_default; - u32 base; /* 32-bit address */ - u32 loop_start; /* 32-bit offset */ - u32 loop_end; /* 32-bit offset */ - u32 loop_frac; /* 8-bit fraction - loop_start */ - u32 delta_end; /* pitch delta end */ - u32 lpfK_end; - u32 eg_gain_end; - u32 left_gain_end; - u32 right_gain_end; - u32 eff1_gain_end; - u32 eff2_gain_end; - u32 eff3_gain_end; - u32 lpfQ; - u32 status; - u32 num_of_frames; - u32 loop_count; - u32 start; - u32 start_frac; - u32 delta; - u32 lpfK; - u32 eg_gain; - u32 left_gain; - u32 right_gain; - u32 eff1_gain; - u32 eff2_gain; - u32 eff3_gain; - u32 lpfD1; - u32 lpfD2; + __le32 format; + __le32 loop_default; + __le32 base; /* 32-bit address */ + __le32 loop_start; /* 32-bit offset */ + __le32 loop_end; /* 32-bit offset */ + __le32 loop_frac; /* 8-bit fraction - loop_start */ + __le32 delta_end; /* pitch delta end */ + __le32 lpfK_end; + __le32 eg_gain_end; + __le32 left_gain_end; + __le32 right_gain_end; + __le32 eff1_gain_end; + __le32 eff2_gain_end; + __le32 eff3_gain_end; + __le32 lpfQ; + __le32 status; + __le32 num_of_frames; + __le32 loop_count; + __le32 start; + __le32 start_frac; + __le32 delta; + __le32 lpfK; + __le32 eg_gain; + __le32 left_gain; + __le32 right_gain; + __le32 eff1_gain; + __le32 eff2_gain; + __le32 eff3_gain; + __le32 lpfD1; + __le32 lpfD2; }; struct snd_ymfpci_capture_bank { - u32 base; /* 32-bit address */ - u32 loop_end; /* 32-bit offset */ - u32 start; /* 32-bit offset */ - u32 num_of_loops; /* counter */ + __le32 base; /* 32-bit address */ + __le32 loop_end; /* 32-bit offset */ + __le32 start; /* 32-bit offset */ + __le32 num_of_loops; /* counter */ }; struct snd_ymfpci_effect_bank { - u32 base; /* 32-bit address */ - u32 loop_end; /* 32-bit offset */ - u32 start; /* 32-bit offset */ - u32 temp; + __le32 base; /* 32-bit address */ + __le32 loop_end; /* 32-bit offset */ + __le32 start; /* 32-bit offset */ + __le32 temp; }; struct snd_ymfpci_pcm; @@ -316,7 +316,7 @@ struct snd_ymfpci { dma_addr_t work_base_addr; struct snd_dma_buffer ac3_tmp_base; - u32 *ctrl_playback; + __le32 *ctrl_playback; struct snd_ymfpci_playback_bank *bank_playback[YDSXG_PLAYBACK_VOICES][2]; struct snd_ymfpci_capture_bank *bank_capture[YDSXG_CAPTURE_VOICES][2]; struct snd_ymfpci_effect_bank *bank_effect[YDSXG_EFFECT_VOICES][2]; diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 6f81396aadc9..a4926fb03991 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -336,7 +336,7 @@ static void snd_ymfpci_pcm_interrupt(struct snd_ymfpci *chip, struct snd_ymfpci_ unsigned int subs = ypcm->substream->number; unsigned int next_bank = 1 - chip->active_bank; struct snd_ymfpci_playback_bank *bank; - u32 volume; + __le32 volume; bank = &voice->bank[next_bank]; volume = cpu_to_le32(chip->pcm_mixer[subs].left << 15); @@ -505,7 +505,7 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int u32 lpfK = snd_ymfpci_calc_lpfK(runtime->rate); struct snd_ymfpci_playback_bank *bank; unsigned int nbank; - u32 vol_left, vol_right; + __le32 vol_left, vol_right; u8 use_left, use_right; unsigned long flags; @@ -2135,7 +2135,7 @@ static int snd_ymfpci_memalloc(struct snd_ymfpci *chip) chip->bank_base_playback = ptr; chip->bank_base_playback_addr = ptr_addr; - chip->ctrl_playback = (u32 *)ptr; + chip->ctrl_playback = (__le32 *)ptr; chip->ctrl_playback[0] = cpu_to_le32(YDSXG_PLAYBACK_VOICES); ptr += ALIGN(playback_ctrl_size, 0x100); ptr_addr += ALIGN(playback_ctrl_size, 0x100); |