static int lola_dest_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct lola *chip = snd_kcontrol_chip(kcontrol); unsigned int src_ofs = kcontrol->private_value & 0xff; unsigned int src_num = (kcontrol->private_value >> 8) & 0xff; unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff; unsigned int dst, mask; unsigned short gains[MAX_STREAM_COUNT]; int i, num; mask = 0; num = 0; for (i = 0; i < src_num; i++) { unsigned short val = ucontrol->value.integer.value[i]; if (val) { gains[num++] = val - 1; mask |= 1 << i; } } mask <<= src_ofs; dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs; return lola_mixer_set_dest_gains(chip, dst, mask, gains); }
static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int left_reg = kcontrol->private_value & 0xff; int right_reg = (kcontrol->private_value >> 8) & 0xff; int shift_left = (kcontrol->private_value >> 16) & 0x07; int shift_right = (kcontrol->private_value >> 19) & 0x07; int mask = (kcontrol->private_value >> 24) & 0xff; int invert = (kcontrol->private_value >> 22) & 1; int change; unsigned short val1, val2; val1 = ucontrol->value.integer.value[0] & mask; val2 = ucontrol->value.integer.value[1] & mask; if (invert) { val1 = mask - val1; val2 = mask - val2; } val1 <<= shift_left; val2 <<= shift_right; spin_lock_irqsave(&chip->reg_lock, flags); if (left_reg != right_reg) { val1 = (chip->eimage[CS4236_REG(left_reg)] & ~(mask << shift_left)) | val1; val2 = (chip->eimage[CS4236_REG(right_reg)] & ~(mask << shift_right)) | val2; change = val1 != chip->eimage[CS4236_REG(left_reg)] || val2 != chip->eimage[CS4236_REG(right_reg)]; snd_cs4236_ext_out(chip, left_reg, val1); snd_cs4236_ext_out(chip, right_reg, val2); } else { val1 = (chip->eimage[CS4236_REG(left_reg)] & ~((mask << shift_left) | (mask << shift_right))) | val1 | val2; change = val1 != chip->eimage[CS4236_REG(left_reg)]; snd_cs4236_ext_out(chip, left_reg, val1); } spin_unlock_irqrestore(&chip->reg_lock, flags); return change; }
static int ak4xxx_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); int chip = AK_GET_CHIP(kcontrol->private_value); int addr = AK_GET_ADDR(kcontrol->private_value); int shift = AK_GET_SHIFT(kcontrol->private_value); int invert = AK_GET_INVERT(kcontrol->private_value); long flag = ucontrol->value.integer.value[0]; unsigned char val, oval; int change; if (invert) flag = ! flag; oval = snd_akm4xxx_get(ak, chip, addr); if (flag) val = oval | (1<<shift); else val = oval & ~(1<<shift); change = (oval != val); if (change) snd_akm4xxx_write(ak, chip, addr, val); return change; }
static int lola_dest_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct lola *chip = snd_kcontrol_chip(kcontrol); unsigned int src_ofs = kcontrol->private_value & 0xff; unsigned int src_num = (kcontrol->private_value >> 8) & 0xff; unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff; unsigned int dst, mask, i; dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs; mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]); for (i = 0; i < src_num; i++) { unsigned int src = src_ofs + i; unsigned short val; if (!(chip->mixer.src_mask & (1 << src))) return -EINVAL; if (mask & (1 << dst)) val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1; else val = 0; ucontrol->value.integer.value[i] = val; } return 0; }
static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static const char *texts[5] = { "Line", "Digital", "Digi+SRC", "Mic", "Line+Mic" }; int i; struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); i = 2; /* no SRC, no Mic available */ if (chip->mgr->board_has_aes1) { i = 3; /* SRC available */ if (chip->mgr->board_has_mic) i = 5; /* Mic and MicroMix available */ } uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = i; if (uinfo->value.enumerated.item > (i-1)) uinfo->value.enumerated.item = i-1; strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); return 0; }
static int put_ak_reg(struct snd_kcontrol *kcontrol, int addr, unsigned char nval) { struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol); unsigned int mask = AK_GET_MASK(kcontrol->private_value); int chip = AK_GET_CHIP(kcontrol->private_value); if (snd_akm4xxx_get_vol(ak, chip, addr) == nval) return 0; snd_akm4xxx_set_vol(ak, chip, addr, nval); if (AK_GET_VOL_CVT(kcontrol->private_value) && nval < 128) nval = vol_cvt_datt[nval]; if (AK_GET_IPGA(kcontrol->private_value) && nval >= 128) nval++; /* need to correct + 1 since both 127 and 128 are 0dB */ if (AK_GET_INVERT(kcontrol->private_value)) nval = mask - nval; if (AK_GET_NEEDSMSB(kcontrol->private_value)) nval |= 0x80; /* printk(KERN_DEBUG "DEBUG - AK writing reg: chip %x addr %x, nval %x\n", chip, addr, nval); */ snd_akm4xxx_write(ak, chip, addr, nval); return 1; }
static int set_lineout_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm1811_machine_priv *wm1811 = snd_soc_card_get_drvdata(codec->card); lineout_mode = ucontrol->value.integer.value[0]; if (lineout_mode) { wm8994_vmid_mode(codec, WM8994_VMID_FORCE); if (wm1811->lineout_switch_f) wm1811->lineout_switch_f(1); } else { if (wm1811->lineout_switch_f) wm1811->lineout_switch_f(0); wm8994_vmid_mode(codec, WM8994_VMID_NORMAL); } dev_info(codec->dev, "set lineout mode : %s\n", lineout_mode_text[lineout_mode]); return 0; }
static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); int changed = 0; int i; down(&chip->mgr->mixer_mutex); for (i = 0; i < 2; i++) { if (chip->monitoring_active[i] != ucontrol->value.integer.value[i]) { chip->monitoring_active[i] = ucontrol->value.integer.value[i]; changed |= (1<<i); /* mask 0x01 and 0x02 */ } } if(changed & 0x01) /* update left monitoring volume and mute */ pcxhr_update_audio_pipe_level(chip, 0, 0); if(changed & 0x02) /* update right monitoring volume and mute */ pcxhr_update_audio_pipe_level(chip, 0, 1); up(&chip->mgr->mixer_mutex); return (changed != 0); }
static int control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); int pos = kcontrol->private_value; if (pos & CNT_INTVAL) { dev->control_state[pos & ~CNT_INTVAL] = ucontrol->value.integer.value[0]; snd_usb_caiaq_send_command(dev, EP1_CMD_DIMM_LEDS, dev->control_state, sizeof(dev->control_state)); } else { if (ucontrol->value.integer.value[0]) dev->control_state[pos / 8] |= 1 << (pos % 8); else dev->control_state[pos / 8] &= ~(1 << (pos % 8)); snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, dev->control_state, sizeof(dev->control_state)); } return 1; }
static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_wss *chip = snd_kcontrol_chip(kcontrol); unsigned long flags; int change; unsigned short enable, val; enable = ucontrol->value.integer.value[0] & 1; mutex_lock(&chip->mce_mutex); snd_wss_mce_up(chip); spin_lock_irqsave(&chip->reg_lock, flags); val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x0e) | (0<<2) | (enable << 1); change = val != chip->image[CS4231_ALT_FEATURE_1]; snd_wss_out(chip, CS4231_ALT_FEATURE_1, val); val = snd_cs4236_ctrl_in(chip, 4) | 0xc0; snd_cs4236_ctrl_out(chip, 4, val); udelay(100); val &= ~0x40; snd_cs4236_ctrl_out(chip, 4, val); spin_unlock_irqrestore(&chip->reg_lock, flags); snd_wss_mce_down(chip); mutex_unlock(&chip->mce_mutex); #if 0 printk(KERN_DEBUG "set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, " "C5 = 0x%x, C6 = 0x%x, C8 = 0x%x\n", snd_wss_in(chip, CS4231_ALT_FEATURE_1), snd_cs4236_ctrl_in(chip, 3), snd_cs4236_ctrl_in(chip, 4), snd_cs4236_ctrl_in(chip, 5), snd_cs4236_ctrl_in(chip, 6), snd_cs4236_ctrl_in(chip, 8)); #endif return change; }
static int snd_cs8427_qsubcode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol); unsigned char reg = CS8427_REG_QSUBCODE; int err; snd_i2c_lock(device->bus); if ((err = snd_i2c_sendbytes(device, ®, 1)) != 1) { snd_printk(KERN_ERR "unable to send register 0x%x byte " "to CS8427\n", reg); snd_i2c_unlock(device->bus); return err < 0 ? err : -EIO; } err = snd_i2c_readbytes(device, ucontrol->value.bytes.data, 10); if (err != 10) { snd_printk(KERN_ERR "unable to read Q-subcode bytes " "from CS8427\n"); snd_i2c_unlock(device->bus); return err < 0 ? err : -EIO; } snd_i2c_unlock(device->bus); return 0; }
static int max98505_adc_en_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct max98505_priv *max98505 = snd_soc_codec_get_drvdata(codec); struct max98505_pdata *pdata = max98505->pdata; int sel = (int)ucontrol->value.integer.value[0]; if (sel) regmap_update_bits(max98505->regmap, MAX98505_R036_BLOCK_ENABLE, MAX98505_ADC_VIMON_EN_MASK, MAX98505_ADC_VIMON_EN_MASK); else regmap_update_bits(max98505->regmap, MAX98505_R036_BLOCK_ENABLE, MAX98505_ADC_VIMON_EN_MASK, 0); pdata->vstep.adc_status = !!sel; #ifdef CONFIG_SND_SOC_MAXIM_DSM maxdsm_update_feature_en_adc(!!sel); #endif /* CONFIG_SND_SOC_MAXIM_DSM */ return 0; }
static int snd_tea6330t_put_master_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct tea6330t *tea = snd_kcontrol_chip(kcontrol); int change, err; unsigned char bytes[3]; unsigned char oval1, oval2, val1, val2; val1 = ucontrol->value.integer.value[0] & 1; val2 = ucontrol->value.integer.value[1] & 1; snd_i2c_lock(tea->bus); oval1 = tea->regs[TEA6330T_SADDR_VOLUME_LEFT] == 0 ? 0 : 1; oval2 = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] == 0 ? 0 : 1; change = val1 != oval1 || val2 != oval2; tea->regs[TEA6330T_SADDR_VOLUME_LEFT] = val1 ? tea->mleft : 0; tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] = val2 ? tea->mright : 0; bytes[0] = TEA6330T_SADDR_VOLUME_LEFT; bytes[1] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT]; bytes[2] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT]; if ((err = snd_i2c_sendbytes(tea->device, bytes, 3)) < 0) change = err; snd_i2c_unlock(tea->bus); return change; }
static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int i; int changed = 0; int mixin; unsigned char vol; vortex_t *vortex = snd_kcontrol_chip(kcontrol); int subdev = kcontrol->id.subdevice; struct pcm_vol *p = &vortex->pcm_vol[subdev]; int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2); for (i = 0; i < max_chn; i++) { if (p->vol[i] != ucontrol->value.integer.value[i]) { p->vol[i] = ucontrol->value.integer.value[i]; if (p->active) { switch (vortex->dma_adb[p->dma].nr_ch) { case 1: mixin = p->mixin[0]; break; case 2: default: mixin = p->mixin[(i < 2) ? i : (i - 2)]; break; case 4: mixin = p->mixin[i]; break; } vol = p->vol[i]; vortex_mix_setinputvolumebyte(vortex, vortex->mixplayb[i], mixin, vol); } changed = 1; } } return changed; }
static int mv88fx_snd_spdif_stream_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct mv88fx_snd_chip *chip = snd_kcontrol_chip(kcontrol); int i, change = 0, word; unsigned int val; struct mv88fx_snd_stream *pbstream = &chip->stream[SNDRV_PCM_STREAM_PLAYBACK]; int port = chip->port; mv88fx_snd_debug(""); val = 0; port = port; spin_lock_irq(&chip->reg_lock); for (word = 0; word < 4; word++) { for (i = 0; i < 4; i++) { chip->stream[SNDRV_PCM_STREAM_PLAYBACK]. spdif_status[word] |= ucontrol->value.iec958.status[word + i] << (i * 8); } mv88fx_snd_writel(chip->base, MV_AUDIO_SPDIF_PLAY_CH_STATUS_LEFT_REG(port, word), pbstream->spdif_status[word]); mv88fx_snd_writel(chip->base, MV_AUDIO_SPDIF_PLAY_CH_STATUS_RIGHT_REG(port, word), pbstream->spdif_status[word]); } if (pbstream->spdif_status[0] & IEC958_AES0_NONAUDIO) chip->pcm_mode = NON_PCM; spin_unlock_irq(&chip->reg_lock); return change; }
static int hsw_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); struct sst_hsw *hsw = pdata->hsw; u32 volume; if (ucontrol->value.integer.value[0] == ucontrol->value.integer.value[1]) { volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); sst_hsw_mixer_set_volume(hsw, 0, 2, volume); } else { volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); sst_hsw_mixer_set_volume(hsw, 0, 0, volume); volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[1]); sst_hsw_mixer_set_volume(hsw, 0, 1, volume); } return 0; }
static int vx_audio_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct vx_core *chip = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = chip->audio_source_target; return 0; }
static bool ctl_has_mute(struct snd_kcontrol *kcontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); return query_amp_caps(codec, get_amp_nid(kcontrol), get_amp_direction(kcontrol)) & AC_AMPCAP_MUTE; }
static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); unsigned long fe_id = kcontrol->private_value; struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) snd_soc_platform_get_drvdata(platform); struct msm_compr_audio_effects *audio_effects = NULL; struct snd_compr_stream *cstream = NULL; struct msm_compr_audio *prtd = NULL; long *values = &(ucontrol->value.integer.value[0]); int effects_module; pr_debug("%s\n", __func__); if (fe_id >= MSM_FRONTEND_DAI_MAX) { pr_err("%s Received out of bounds fe_id %lu\n", __func__, fe_id); return -EINVAL; } cstream = pdata->cstream[fe_id]; audio_effects = pdata->audio_effects[fe_id]; if (!cstream || !audio_effects) { pr_err("%s: stream or effects inactive\n", __func__); return -EINVAL; } prtd = cstream->runtime->private_data; if (!prtd) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } effects_module = *values++; switch (effects_module) { case VIRTUALIZER_MODULE: pr_debug("%s: VIRTUALIZER_MODULE\n", __func__); msm_audio_effects_virtualizer_handler(prtd->audio_client, &(audio_effects->virtualizer), values); break; case REVERB_MODULE: pr_debug("%s: REVERB_MODULE\n", __func__); msm_audio_effects_reverb_handler(prtd->audio_client, &(audio_effects->reverb), values); break; case BASS_BOOST_MODULE: pr_debug("%s: BASS_BOOST_MODULE\n", __func__); msm_audio_effects_bass_boost_handler(prtd->audio_client, &(audio_effects->bass_boost), values); break; case EQ_MODULE: pr_debug("%s: EQ_MODULE\n", __func__); msm_audio_effects_popless_eq_handler(prtd->audio_client, &(audio_effects->equalizer), values); break; default: pr_err("%s Invalid effects config module\n", __func__); return -EINVAL; } return 0; }
/* * snd_ubi32_cs4384_put_volume */ static int snd_ubi32_cs4384_put_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct ubi32_snd_priv *priv = snd_kcontrol_chip(kcontrol); struct i2c_client *client = (struct i2c_client *)priv->client; struct snd_ubi32_cs4384_priv *cs4384_priv; unsigned int id = (unsigned int)kcontrol->private_value; int ch = snd_ubi32_cs4384_ch_ofs[id]; unsigned long flags; unsigned char send[3]; int nch; int ret = -EINVAL; if (id >= SND_UBI32_CS4384_LAST_ID) { return -EINVAL; } cs4384_priv = snd_ubi32_priv_get_drv(priv); spin_lock_irqsave(&cs4384_priv->lock, flags); send[0] = 0; switch (id) { case SND_UBI32_CS4384_REAR_ID: send[0] = 0x06; /* * Fall through */ case SND_UBI32_CS4384_SURROUND_ID: send[0] += 0x03; /* * Fall through */ case SND_UBI32_CS4384_FRONT_ID: send[0] += 0x8B; nch = 2; send[1] = 255 - (ucontrol->value.integer.value[0] & 0xFF); send[2] = 255 - (ucontrol->value.integer.value[1] & 0xFF); cs4384_priv->volume[ch++] = send[1]; cs4384_priv->volume[ch] = send[2]; break; case SND_UBI32_CS4384_LFE_ID: send[0] = 0x81; /* * Fall through */ case SND_UBI32_CS4384_CENTER_ID: send[0] += 0x11; nch = 1; send[1] = 255 - (ucontrol->value.integer.value[0] & 0xFF); cs4384_priv->volume[ch] = send[1]; break; default: spin_unlock_irqrestore(&cs4384_priv->lock, flags); goto done; } /* * Send the volume to the chip */ nch++; ret = i2c_master_send(client, send, nch); if (ret != nch) { snd_printk(KERN_ERR "Failed to set volume on CS4384\n"); } done: spin_unlock_irqrestore(&cs4384_priv->lock, flags); return ret; }
static int tegra_aic326x_call_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct tegra_aic326x *machine = snd_kcontrol_chip(kcontrol); int is_call_mode_new = ucontrol->value.integer.value[0]; #ifdef CONFIG_ARCH_TEGRA_2x_SOC int codec_dap_id, codec_dap_sel, bb_dap_id, bb_dap_sel; #else /*assumes tegra3*/ int codec_index; unsigned int i; #endif if (machine->is_call_mode == is_call_mode_new) return 0; #ifdef CONFIG_ARCH_TEGRA_2x_SOC bb_dap_id = TEGRA20_DAS_DAP_ID_3; bb_dap_sel = TEGRA20_DAS_DAP_SEL_DAP3; if (machine->is_device_bt) { codec_dap_id = TEGRA20_DAS_DAP_ID_4; codec_dap_sel = TEGRA20_DAS_DAP_SEL_DAP4; } else { codec_dap_id = TEGRA20_DAS_DAP_ID_2; codec_dap_sel = TEGRA20_DAS_DAP_SEL_DAP2; } #else /*assumes tegra3*/ if (machine->is_device_bt) codec_index = BT_SCO; else codec_index = HIFI_CODEC; #endif if (is_call_mode_new) { #ifdef CONFIG_ARCH_TEGRA_2x_SOC tegra20_das_set_tristate(codec_dap_id, 1); tegra20_das_set_tristate(bb_dap_id, 1); tegra20_das_connect_dap_to_dap(codec_dap_id, bb_dap_sel, 0, 0, 0); tegra20_das_connect_dap_to_dap(bb_dap_id, codec_dap_sel, 1, 0, 0); tegra20_das_set_tristate(codec_dap_id, 0); tegra20_das_set_tristate(bb_dap_id, 0); #else /*assumes tegra3*/ if (machine->codec_info[codec_index].rate == 0 || machine->codec_info[codec_index].channels == 0) return -EINVAL; for (i = 0; i < machine->pcard->num_links; i++) machine->pcard->dai_link[i].ignore_suspend = 1; tegra30_make_voice_call_connections( &machine->codec_info[codec_index], &machine->codec_info[BASEBAND]); #endif } else { #ifdef CONFIG_ARCH_TEGRA_2x_SOC tegra20_das_set_tristate(codec_dap_id, 1); tegra20_das_set_tristate(bb_dap_id, 1); tegra20_das_connect_dap_to_dap(bb_dap_id, bb_dap_sel, 0, 0, 0); tegra20_das_connect_dap_to_dap(codec_dap_id, codec_dap_sel, 0, 0, 0); tegra20_das_set_tristate(codec_dap_id, 0); tegra20_das_set_tristate(bb_dap_id, 0); #else /*assumes tegra3*/ tegra30_break_voice_call_connections( &machine->codec_info[codec_index], &machine->codec_info[BASEBAND]); for (i = 0; i < machine->pcard->num_links; i++) machine->pcard->dai_link[i].ignore_suspend = 0; #endif } machine->is_call_mode = is_call_mode_new; g_is_call_mode = machine->is_call_mode; return 1; }
static int phase28_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8; return 0; }
static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct snd_soc_dapm_context *dapm = &codec->dapm; struct soc_enum *control = (struct soc_enum *)kcontrol->private_value; unsigned short pins; int pin, changed = 0; /* Refuse any mode changes if we are not able to control the codec. */ if (!codec->hw_write) return -EUNATCH; if (ucontrol->value.enumerated.item[0] >= control->max) return -EINVAL; mutex_lock(&codec->mutex); /* Translate selection to bitmap */ pins = ams_delta_audio_mode_pins[ucontrol->value.enumerated.item[0]]; /* Setup pins after corresponding bits if changed */ pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE)); if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) { changed = 1; if (pin) snd_soc_dapm_enable_pin(dapm, "Mouthpiece"); else snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); } pin = !!(pins & (1 << AMS_DELTA_EARPIECE)); if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) { changed = 1; if (pin) snd_soc_dapm_enable_pin(dapm, "Earpiece"); else snd_soc_dapm_disable_pin(dapm, "Earpiece"); } pin = !!(pins & (1 << AMS_DELTA_MICROPHONE)); if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) { changed = 1; if (pin) snd_soc_dapm_enable_pin(dapm, "Microphone"); else snd_soc_dapm_disable_pin(dapm, "Microphone"); } pin = !!(pins & (1 << AMS_DELTA_SPEAKER)); if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) { changed = 1; if (pin) snd_soc_dapm_enable_pin(dapm, "Speaker"); else snd_soc_dapm_disable_pin(dapm, "Speaker"); } pin = !!(pins & (1 << AMS_DELTA_AGC)); if (pin != ams_delta_audio_agc) { ams_delta_audio_agc = pin; changed = 1; if (pin) snd_soc_dapm_enable_pin(dapm, "AGCIN"); else snd_soc_dapm_disable_pin(dapm, "AGCIN"); } if (changed) snd_soc_dapm_sync(dapm); mutex_unlock(&codec->mutex); return changed; }
static int vx_clock_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct vx_core *chip = snd_kcontrol_chip(kcontrol); ucontrol->value.enumerated.item[0] = chip->clock_mode; return 0; }
static int s5m8751_set_scenario_endpoints(struct tt_scenario_context *c) { struct snd_kcontrol *kcontrol = (struct snd_kcontrol *) c->data; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); /* check whether the new scenario is already active, if so, don't set it again as this has been seen to result in non wanted register changes e.g. setting scenario TT_SCENARIO_ASR twice result in non ASR scenario registers being set. */ if (c->tt_current_scenario == c->tt_scenario) return 0; /* scenario routing switching */ switch(c->tt_scenario) { default: case TT_SCENARIO_AUDIO_INIT: /* enable mic bias (not if we use mic pre-amp) */ s5m8751_mic_bias_enable(codec); case TT_SCENARIO_AUDIO_OFF: c->tt_volume = 0; snd_soc_update_bits(codec, S5M8751_AMP_MUTE, S5M8751_AMP_MUTE_SPK_S2D_MASK | \ S5M8751_AMP_MUTE_LHP_MASK | S5M8751_AMP_MUTE_RHP_MASK | \ S5M8751_AMP_MUTE_LLINE_MASK | S5M8751_AMP_MUTE_RLINE_MASK, (0 << S5M8751_AMP_MUTE_SPK_S2D_SHIFT) | \ (0 << S5M8751_AMP_MUTE_LHP_SHIFT) | (0 << S5M8751_AMP_MUTE_RHP_SHIFT) | \ (0 << S5M8751_AMP_MUTE_LLINE_SHIFT) | (0 << S5M8751_AMP_MUTE_RLINE_SHIFT)); snd_soc_update_bits(codec, S5M8751_AMP_EN, S5M8751_AMP_EN_SPK_MASK | \ S5M8751_AMP_EN_LHP_MASK | S5M8751_AMP_EN_RHP_MASK | \ S5M8751_AMP_EN_LLINE_MASK | S5M8751_AMP_EN_RLINE_MASK, (0 << S5M8751_AMP_EN_SPK_SHIFT) | \ (0 << S5M8751_AMP_EN_LHP_SHIFT) | (0 << S5M8751_AMP_EN_RHP_SHIFT) | \ (0 << S5M8751_AMP_EN_LLINE_SHIFT) | (0 << S5M8751_AMP_EN_RLINE_SHIFT)); switch(c->tt_current_scenario) { case TT_SCENARIO_VR: s5m8751_alc_disable(codec); case TT_SCENARIO_NOISE: case TT_SCENARIO_ASR: s5m8751_mic_disable(codec); break; case TT_SCENARIO_HF_SPEAKER: s5m8751_mic_disable(codec); case TT_SCENARIO_SPEAKER: snd_soc_dapm_disable_pin(codec, "Speaker"); break; case TT_SCENARIO_LINEOUT: snd_soc_dapm_disable_pin(codec, "Headphones"); break; case TT_SCENARIO_FM: snd_soc_dapm_disable_pin(codec, "Headphones"); break; case TT_SCENARIO_HF_LINEOUT: case TT_SCENARIO_HF_FM: s5m8751_mic_disable(codec); snd_soc_dapm_disable_pin(codec, "Headphones"); break; case TT_SCENARIO_iPod: s5m8751_line_in_disable(codec); s5m8751_mic_bias_enable(codec); break; case TT_SCENARIO_iPod_SPEAKER: s5m8751_line_in_disable(codec); s5m8751_mic_bias_enable(codec); snd_soc_dapm_disable_pin(codec, "Speaker"); break; case TT_SCENARIO_iPod_LINEOUT: case TT_SCENARIO_iPod_FM: s5m8751_line_in_disable(codec); s5m8751_mic_bias_enable(codec); snd_soc_dapm_disable_pin(codec, "Headphones"); break; default: snd_soc_dapm_disable_pin(codec, "Headphones"); snd_soc_dapm_disable_pin(codec, "Speaker"); break; } break; case TT_SCENARIO_ASR: break; case TT_SCENARIO_VR: break; case TT_SCENARIO_NOISE: break; case TT_SCENARIO_iPod: break; case TT_SCENARIO_SPEAKER: snd_soc_dapm_enable_pin(codec, "Speaker"); break; case TT_SCENARIO_LINEOUT: snd_soc_dapm_enable_pin(codec, "Headphones"); break; case TT_SCENARIO_FM: snd_soc_dapm_enable_pin(codec, "Headphones"); break; case TT_SCENARIO_iPod_SPEAKER: snd_soc_dapm_enable_pin(codec, "Speaker"); break; case TT_SCENARIO_iPod_LINEOUT: case TT_SCENARIO_iPod_FM: snd_soc_dapm_enable_pin(codec, "Headphones"); break; case TT_SCENARIO_HF_SPEAKER: snd_soc_dapm_enable_pin(codec, "Speaker"); break; case TT_SCENARIO_HF_LINEOUT: case TT_SCENARIO_HF_FM: snd_soc_dapm_enable_pin(codec, "Headphones"); break; } c->tt_current_scenario = c->tt_scenario; snd_soc_dapm_sync(codec); switch(c->tt_scenario) { case TT_SCENARIO_LINEOUT: case TT_SCENARIO_iPod_LINEOUT: case TT_SCENARIO_FM: case TT_SCENARIO_iPod_FM: snd_soc_update_bits(codec, S5M8751_DA_PDB1, S5M8751_DA_PDB1_MASK, S5M8751_PDB_REF | S5M8751_PDB_DACL | S5M8751_PDB_DACR | \ S5M8751_PDB_MR | S5M8751_PDB_ML); snd_soc_update_bits(codec, S5M8751_DA_AMIX1, S5M8751_DA_AMIX1_MASK, S5M8751_RDAC_MR | S5M8751_LDAC_ML); snd_soc_update_bits(codec, S5M8751_DA_AMIX2, S5M8751_DA_AMIX2_MASK, 0); snd_soc_update_bits(codec, S5M8751_AMP_EN, S5M8751_AMP_EN_LLINE_MASK | S5M8751_AMP_EN_RLINE_MASK, 1 << S5M8751_AMP_EN_LLINE_SHIFT | 1 << S5M8751_AMP_EN_RLINE_SHIFT); snd_soc_update_bits(codec, S5M8751_AMP_MUTE, S5M8751_AMP_MUTE_LLINE_MASK | S5M8751_AMP_MUTE_RLINE_MASK, 1 << S5M8751_AMP_MUTE_LLINE_SHIFT | 1 << S5M8751_AMP_MUTE_RLINE_SHIFT); break; default: case TT_SCENARIO_AUDIO_INIT: case TT_SCENARIO_AUDIO_OFF: break; case TT_SCENARIO_SPEAKER: case TT_SCENARIO_iPod_SPEAKER: case TT_SCENARIO_HF_SPEAKER: snd_soc_update_bits(codec, S5M8751_DA_PDB1, S5M8751_DA_PDB1_MASK, S5M8751_PDB_REF | S5M8751_PDB_DACL | S5M8751_PDB_DACR | \ S5M8751_PDB_MM); snd_soc_update_bits(codec, S5M8751_DA_AMIX1, S5M8751_DA_AMIX1_MASK, S5M8751_RDAC_MM | S5M8751_LDAC_MM); snd_soc_update_bits(codec, S5M8751_DA_AMIX2, S5M8751_DA_AMIX2_MASK, 0); snd_soc_update_bits(codec, S5M8751_AMP_EN, S5M8751_AMP_EN_SPK_MASK, 1 << S5M8751_AMP_EN_SPK_SHIFT); snd_soc_update_bits(codec, S5M8751_AMP_MUTE, S5M8751_AMP_MUTE_SPK_S2D_MASK, 1 << S5M8751_AMP_MUTE_SPK_S2D_SHIFT); break; } snd_soc_dapm_sync(codec); return 1; }
static int adc3101_set_scenario_endpoints(struct tt_scenario_context *c) { struct snd_kcontrol *kcontrol = (struct snd_kcontrol *) c->data; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); /* check whether the new scenario is already active, if so, don't set it again as this has been seen to result in non wanted register changes e.g. setting scenario TT_SCENARIO_ASR twice result in non ASR scenario registers being set. */ if (c->tt_current_scenario == c->tt_scenario) return 0; /* scenario routing switching */ switch(c->tt_scenario) { default: case TT_SCENARIO_AUDIO_INIT: /* enable mic bias (not if we use mic pre-amp) */ adc3101_mic_bias_enable(codec); case TT_SCENARIO_AUDIO_OFF: c->tt_volume = 0; switch(c->tt_current_scenario) { case TT_SCENARIO_VR: adc3101_alc_disable(codec); case TT_SCENARIO_NOISE: case TT_SCENARIO_ASR: case TT_SCENARIO_HF_LINEOUT: case TT_SCENARIO_HF_FM: case TT_SCENARIO_HF_SPEAKER: adc3101_mic_disable(codec); break; case TT_SCENARIO_SPEAKER: case TT_SCENARIO_LINEOUT: case TT_SCENARIO_FM: break; adc3101_mic_disable(codec); break; case TT_SCENARIO_iPod: adc3101_line_in_disable(codec); adc3101_mic_bias_enable(codec); break; case TT_SCENARIO_iPod_SPEAKER: adc3101_line_in_disable(codec); adc3101_mic_bias_enable(codec); break; case TT_SCENARIO_iPod_LINEOUT: case TT_SCENARIO_iPod_FM: adc3101_line_in_disable(codec); adc3101_mic_bias_enable(codec); break; default: snd_soc_dapm_disable_pin(codec, "MicIn"); break; } break; case TT_SCENARIO_ASR: adc3101_mic_enable(codec, 25, 1); break; case TT_SCENARIO_VR: adc3101_mic_enable(codec, 25, 1); break; case TT_SCENARIO_NOISE: adc3101_mic_enable(codec, 15, 1); break; case TT_SCENARIO_iPod: adc3101_line_in_enable(codec); break; case TT_SCENARIO_SPEAKER: break; case TT_SCENARIO_LINEOUT: break; case TT_SCENARIO_FM: break; case TT_SCENARIO_iPod_SPEAKER: adc3101_line_in_enable(codec); break; case TT_SCENARIO_iPod_LINEOUT: case TT_SCENARIO_iPod_FM: adc3101_line_in_enable(codec); break; case TT_SCENARIO_HF_SPEAKER: adc3101_mic_enable(codec, 13, 1); break; case TT_SCENARIO_HF_LINEOUT: case TT_SCENARIO_HF_FM: adc3101_mic_enable(codec, 13, 1); break; } c->tt_current_scenario = c->tt_scenario; snd_soc_dapm_sync(codec); switch(c->tt_scenario) { case TT_SCENARIO_LINEOUT: case TT_SCENARIO_iPod_LINEOUT: case TT_SCENARIO_FM: case TT_SCENARIO_iPod_FM: break; default: case TT_SCENARIO_AUDIO_INIT: case TT_SCENARIO_AUDIO_OFF: break; case TT_SCENARIO_SPEAKER: case TT_SCENARIO_iPod_SPEAKER: case TT_SCENARIO_HF_SPEAKER: break; } return 1; }
static int phase28_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf; return 0; }
static int afe_sinegen_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct mt_pcm_routing_priv *priv = snd_soc_component_get_drvdata(component); if (priv->afe_sinegen_type == ucontrol->value.integer.value[0]) { pr_debug("%s dummy operation for %u", __func__, priv->afe_sinegen_type); return 0; } if (priv->afe_sinegen_type != AFE_SGEN_OFF) mt_afe_disable_sinegen_hw(); switch (ucontrol->value.integer.value[0]) { case AFE_SGEN_I0I1: mt_afe_enable_sinegen_hw(INTER_CONN_I00, MT_AFE_MEMIF_DIRECTION_INPUT); break; case AFE_SGEN_I2: mt_afe_enable_sinegen_hw(INTER_CONN_I02, MT_AFE_MEMIF_DIRECTION_INPUT); break; case AFE_SGEN_I3I4: mt_afe_enable_sinegen_hw(INTER_CONN_I03, MT_AFE_MEMIF_DIRECTION_INPUT); break; case AFE_SGEN_I5I6: mt_afe_enable_sinegen_hw(INTER_CONN_I05, MT_AFE_MEMIF_DIRECTION_INPUT); break; case AFE_SGEN_I7I8: mt_afe_enable_sinegen_hw(INTER_CONN_I07, MT_AFE_MEMIF_DIRECTION_INPUT); break; case AFE_SGEN_I9: mt_afe_enable_sinegen_hw(INTER_CONN_I09, MT_AFE_MEMIF_DIRECTION_INPUT); break; case AFE_SGEN_I10I11: mt_afe_enable_sinegen_hw(INTER_CONN_I10, MT_AFE_MEMIF_DIRECTION_INPUT); break; case AFE_SGEN_I12I13: mt_afe_enable_sinegen_hw(INTER_CONN_I12, MT_AFE_MEMIF_DIRECTION_INPUT); break; case AFE_SGEN_I15I16: mt_afe_enable_sinegen_hw(INTER_CONN_I15, MT_AFE_MEMIF_DIRECTION_INPUT); break; case AFE_SGEN_I17I18: mt_afe_enable_sinegen_hw(INTER_CONN_I17, MT_AFE_MEMIF_DIRECTION_INPUT); break; case AFE_SGEN_I19I20: mt_afe_enable_sinegen_hw(INTER_CONN_I19, MT_AFE_MEMIF_DIRECTION_INPUT); break; case AFE_SGEN_O0O1: mt_afe_enable_sinegen_hw(INTER_CONN_O01, MT_AFE_MEMIF_DIRECTION_OUTPUT); break; case AFE_SGEN_O2: mt_afe_enable_sinegen_hw(INTER_CONN_O02, MT_AFE_MEMIF_DIRECTION_OUTPUT); break; case AFE_SGEN_O3O4: mt_afe_enable_sinegen_hw(INTER_CONN_O03, MT_AFE_MEMIF_DIRECTION_OUTPUT); break; case AFE_SGEN_O5O6: mt_afe_enable_sinegen_hw(INTER_CONN_O05, MT_AFE_MEMIF_DIRECTION_OUTPUT); break; case AFE_SGEN_O7O8: mt_afe_enable_sinegen_hw(INTER_CONN_O07, MT_AFE_MEMIF_DIRECTION_OUTPUT); break; case AFE_SGEN_O9O10: mt_afe_enable_sinegen_hw(INTER_CONN_O09, MT_AFE_MEMIF_DIRECTION_OUTPUT); break; case AFE_SGEN_O11: mt_afe_enable_sinegen_hw(INTER_CONN_O11, MT_AFE_MEMIF_DIRECTION_OUTPUT); break; case AFE_SGEN_O12: mt_afe_enable_sinegen_hw(INTER_CONN_O12, MT_AFE_MEMIF_DIRECTION_OUTPUT); break; case AFE_SGEN_O13O14: mt_afe_enable_sinegen_hw(INTER_CONN_O13, MT_AFE_MEMIF_DIRECTION_OUTPUT); break; case AFE_SGEN_O15O16: mt_afe_enable_sinegen_hw(INTER_CONN_O15, MT_AFE_MEMIF_DIRECTION_OUTPUT); break; case AFE_SGEN_O19O20: mt_afe_enable_sinegen_hw(INTER_CONN_O19, MT_AFE_MEMIF_DIRECTION_OUTPUT); break; case AFE_SGEN_O21O22: mt_afe_enable_sinegen_hw(INTER_CONN_O21, MT_AFE_MEMIF_DIRECTION_OUTPUT); break; case AFE_SGEN_I14: case AFE_SGEN_I21I22: case AFE_SGEN_O17O18: case AFE_SGEN_O23O24: /* not supported */ break; default: mt_afe_disable_sinegen_hw(); break; } priv->afe_sinegen_type = ucontrol->value.integer.value[0]; return 0; }
/* * input MUX */ static int cmi_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct cmi_spec *spec = codec->spec; return snd_hda_input_mux_info(spec->input_mux, uinfo); }
static int ap_loopback_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct mt_pcm_routing_priv *priv = snd_soc_component_get_drvdata(component); uint32_t sample_rate = 48000; long set_value = ucontrol->value.integer.value[0]; if (priv->ap_loopback_type == set_value) { pr_debug("%s dummy operation for %u", __func__, priv->ap_loopback_type); return 0; } if (priv->ap_loopback_type != AP_LOOPBACK_NONE) { if (priv->ap_loopback_type == AP_LOOPBACK_AMIC_TO_I2S0 || priv->ap_loopback_type == AP_LOOPBACK_HEADSET_MIC_TO_I2S0) { mt_afe_disable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_OUT_2); if (!mt_afe_get_memory_path_state(MT_AFE_DIGITAL_BLOCK_I2S_OUT_2)) mt_afe_disable_2nd_i2s_out(); mt_afe_disable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_IN_2); if (!mt_afe_get_memory_path_state(MT_AFE_DIGITAL_BLOCK_I2S_IN_2)) mt_afe_disable_2nd_i2s_in(); mt_afe_disable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_IN_ADC); if (mt_afe_get_memory_path_state(MT_AFE_DIGITAL_BLOCK_I2S_IN_ADC) == false) mt_afe_disable_i2s_adc(); mt_afe_set_connection(INTER_DISCONNECT, INTER_CONN_I03, INTER_CONN_O00); mt_afe_set_connection(INTER_DISCONNECT, INTER_CONN_I04, INTER_CONN_O01); } else { mt_afe_disable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_OUT_DAC); if (!mt_afe_get_memory_path_state(MT_AFE_DIGITAL_BLOCK_I2S_OUT_DAC)) mt_afe_disable_i2s_dac(); mt_afe_disable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_IN_ADC); if (mt_afe_get_memory_path_state(MT_AFE_DIGITAL_BLOCK_I2S_IN_ADC) == false) mt_afe_disable_i2s_adc(); mt_afe_set_connection(INTER_DISCONNECT, INTER_CONN_I03, INTER_CONN_O03); mt_afe_set_connection(INTER_DISCONNECT, INTER_CONN_I03, INTER_CONN_O04); } mt_afe_enable_afe(false); mt_afe_adc_clk_off(); mt_afe_dac_clk_off(); mt_afe_main_clk_off(); } if (set_value == AP_LOOPBACK_AMIC_TO_SPK || set_value == AP_LOOPBACK_AMIC_TO_HP || set_value == AP_LOOPBACK_DMIC_TO_SPK || set_value == AP_LOOPBACK_DMIC_TO_HP || set_value == AP_LOOPBACK_HEADSET_MIC_TO_SPK || set_value == AP_LOOPBACK_HEADSET_MIC_TO_HP) { if (set_value == AP_LOOPBACK_DMIC_TO_SPK || set_value == AP_LOOPBACK_DMIC_TO_HP) { sample_rate = 32000; } mt_afe_main_clk_on(); mt_afe_dac_clk_on(); mt_afe_adc_clk_on(); mt_afe_set_connection(INTER_CONNECT, INTER_CONN_I03, INTER_CONN_O03); mt_afe_set_connection(INTER_CONNECT, INTER_CONN_I04, INTER_CONN_O04); mt_afe_set_out_conn_format(MT_AFE_CONN_OUTPUT_16BIT, INTER_CONN_O03); mt_afe_set_out_conn_format(MT_AFE_CONN_OUTPUT_16BIT, INTER_CONN_O04); /* configure uplink */ mt_afe_set_i2s_adc_in(sample_rate); if (mt_afe_get_memory_path_state(MT_AFE_DIGITAL_BLOCK_I2S_IN_ADC) == false) { mt_afe_enable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_IN_ADC); mt_afe_enable_i2s_adc(); } else { mt_afe_enable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_IN_ADC); } /* configure downlink */ if (mt_afe_get_memory_path_state(MT_AFE_DIGITAL_BLOCK_I2S_OUT_DAC) == false) { mt_afe_enable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_OUT_DAC); mt_afe_set_i2s_dac_out(sample_rate); mt_afe_enable_i2s_dac(); } else { mt_afe_enable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_OUT_DAC); } mt_afe_enable_afe(true); } else if (set_value == AP_LOOPBACK_AMIC_TO_I2S0 || set_value == AP_LOOPBACK_HEADSET_MIC_TO_I2S0) { mt_afe_main_clk_on(); mt_afe_dac_clk_on(); mt_afe_adc_clk_on(); mt_afe_set_connection(INTER_CONNECT, INTER_CONN_I03, INTER_CONN_O00); mt_afe_set_connection(INTER_CONNECT, INTER_CONN_I04, INTER_CONN_O01); mt_afe_set_out_conn_format(MT_AFE_CONN_OUTPUT_16BIT, INTER_CONN_O00); mt_afe_set_out_conn_format(MT_AFE_CONN_OUTPUT_16BIT, INTER_CONN_O01); /* configure uplink */ mt_afe_set_i2s_adc_in(sample_rate); if (mt_afe_get_memory_path_state(MT_AFE_DIGITAL_BLOCK_I2S_IN_ADC) == false) { mt_afe_enable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_IN_ADC); mt_afe_enable_i2s_adc(); } else { mt_afe_enable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_IN_ADC); } /* configure downlink */ /* i2s0 soft reset begin */ mt_afe_set_reg(AUDIO_TOP_CON1, 0x2, 0x2); if (mt_afe_get_memory_path_state(MT_AFE_DIGITAL_BLOCK_I2S_IN_2)) { mt_afe_enable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_IN_2); mt_afe_disable_2nd_i2s_in(); } else { mt_afe_enable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_IN_2); } mt_afe_set_sample_rate(MT_AFE_DIGITAL_BLOCK_MEM_I2S, sample_rate); mt_afe_set_2nd_i2s_in(MT_AFE_I2S_WLEN_16BITS, MT_AFE_I2S_SRC_MASTER_MODE, MT_AFE_BCK_INV_NO_INVERSE, MT_AFE_NORMAL_CLOCK); mt_afe_enable_2nd_i2s_in(); if (mt_afe_get_memory_path_state(MT_AFE_DIGITAL_BLOCK_I2S_OUT_2)) { mt_afe_enable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_OUT_2); mt_afe_disable_2nd_i2s_out(); } else { mt_afe_enable_memory_path(MT_AFE_DIGITAL_BLOCK_I2S_OUT_2); } mt_afe_set_2nd_i2s_out(sample_rate, MT_AFE_NORMAL_CLOCK); mt_afe_enable_2nd_i2s_out(); /* i2s0 soft reset end */ udelay(1); mt_afe_set_reg(AUDIO_TOP_CON1, 0x0, 0x2); mt_afe_enable_afe(true); } priv->ap_loopback_type = ucontrol->value.integer.value[0]; return 0; }