Loading Documentation/devicetree/bindings/sound/tlv320aic3x.txt +6 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,12 @@ Optional properties: - gpio-reset - gpio pin number used for codec reset - ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality - ai3x-micbias-vg - MicBias Voltage required. 1 - MICBIAS output is powered to 2.0V, 2 - MICBIAS output is powered to 2.5V, 3 - MICBIAS output is connected to AVDD, If this node is not mentioned or if the value is incorrect, then MicBias is powered down. Example: Loading include/sound/tlv320aic3x.h +10 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,13 @@ enum { AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15 }; enum aic3x_micbias_voltage { AIC3X_MICBIAS_OFF = 0, AIC3X_MICBIAS_2_0V = 1, AIC3X_MICBIAS_2_5V = 2, AIC3X_MICBIAS_AVDDV = 3, }; struct aic3x_setup_data { unsigned int gpio_func[2]; }; Loading @@ -53,6 +60,9 @@ struct aic3x_setup_data { struct aic3x_pdata { int gpio_reset; /* < 0 if not used */ struct aic3x_setup_data *setup; /* Selects the micbias voltage */ enum aic3x_micbias_voltage micbias_vg; }; #endif sound/soc/codecs/tlv320aic3x.c +77 −6 Original line number Diff line number Diff line Loading @@ -85,6 +85,9 @@ struct aic3x_priv { #define AIC3X_MODEL_33 1 #define AIC3X_MODEL_3007 2 u16 model; /* Selects the micbias voltage */ enum aic3x_micbias_voltage micbias_vg; }; /* Loading Loading @@ -195,6 +198,37 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, return ret; } /* * mic bias power on/off share the same register bits with * output voltage of mic bias. when power on mic bias, we * need reclaim it to voltage value. * 0x0 = Powered off * 0x1 = MICBIAS output is powered to 2.0V, * 0x2 = MICBIAS output is powered to 2.5V * 0x3 = MICBIAS output is connected to AVDD */ static int mic_bias_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); switch (event) { case SND_SOC_DAPM_POST_PMU: /* change mic bias voltage to user defined */ snd_soc_update_bits(codec, MICBIAS_CTRL, MICBIAS_LEVEL_MASK, aic3x->micbias_vg << MICBIAS_LEVEL_SHIFT); break; case SND_SOC_DAPM_PRE_PMD: snd_soc_update_bits(codec, MICBIAS_CTRL, MICBIAS_LEVEL_MASK, 0); break; } return 0; } static const char *aic3x_left_dac_mux[] = { "DAC_L1", "DAC_L3", "DAC_L2" }; static const char *aic3x_right_dac_mux[] = { "DAC_R1", "DAC_R3", "DAC_R2" }; static const char *aic3x_left_hpcom_mux[] = Loading Loading @@ -596,12 +630,9 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0), /* Mic Bias */ SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2V", MICBIAS_CTRL, 6, 3, 1, 0), SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2.5V", MICBIAS_CTRL, 6, 3, 2, 0), SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias AVDD", MICBIAS_CTRL, 6, 3, 3, 0), SND_SOC_DAPM_SUPPLY("Mic Bias", MICBIAS_CTRL, 6, 0, mic_bias_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), /* Output mixers */ SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0, Loading Loading @@ -1386,6 +1417,24 @@ static int aic3x_probe(struct snd_soc_codec *codec) if (aic3x->model == AIC3X_MODEL_3007) snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); /* set mic bias voltage */ switch (aic3x->micbias_vg) { case AIC3X_MICBIAS_2_0V: case AIC3X_MICBIAS_2_5V: case AIC3X_MICBIAS_AVDDV: snd_soc_update_bits(codec, MICBIAS_CTRL, MICBIAS_LEVEL_MASK, (aic3x->micbias_vg) << MICBIAS_LEVEL_SHIFT); break; case AIC3X_MICBIAS_OFF: /* * noting to do. target won't enter here. This is just to avoid * compile time warning "warning: enumeration value * 'AIC3X_MICBIAS_OFF' not handled in switch" */ break; } aic3x_add_widgets(codec); list_add(&aic3x->list, &reset_list); Loading Loading @@ -1461,6 +1510,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, struct aic3x_setup_data *ai3x_setup; struct device_node *np = i2c->dev.of_node; int ret; u32 value; aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL); if (aic3x == NULL) { Loading @@ -1474,6 +1524,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, if (pdata) { aic3x->gpio_reset = pdata->gpio_reset; aic3x->setup = pdata->setup; aic3x->micbias_vg = pdata->micbias_vg; } else if (np) { ai3x_setup = devm_kzalloc(&i2c->dev, sizeof(*ai3x_setup), GFP_KERNEL); Loading @@ -1493,6 +1544,26 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, aic3x->setup = ai3x_setup; } if (!of_property_read_u32(np, "ai3x-micbias-vg", &value)) { switch (value) { case 1 : aic3x->micbias_vg = AIC3X_MICBIAS_2_0V; break; case 2 : aic3x->micbias_vg = AIC3X_MICBIAS_2_5V; break; case 3 : aic3x->micbias_vg = AIC3X_MICBIAS_AVDDV; break; default : aic3x->micbias_vg = AIC3X_MICBIAS_OFF; dev_err(&i2c->dev, "Unsuitable MicBias voltage " "found in DT\n"); } } else { aic3x->micbias_vg = AIC3X_MICBIAS_OFF; } } else { aic3x->gpio_reset = -1; } Loading sound/soc/codecs/tlv320aic3x.h +4 −0 Original line number Diff line number Diff line Loading @@ -238,6 +238,10 @@ /* Default input volume */ #define DEFAULT_GAIN 0x20 /* MICBIAS Control Register */ #define MICBIAS_LEVEL_SHIFT (6) #define MICBIAS_LEVEL_MASK (3 << 6) /* headset detection / button API */ /* The AIC3x supports detection of stereo headsets (GND + left + right signal) Loading sound/soc/davinci/davinci-evm.c +3 −3 Original line number Diff line number Diff line Loading @@ -116,9 +116,9 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Line Out", NULL, "RLOUT"}, /* Mic connected to (MIC3L | MIC3R) */ {"MIC3L", NULL, "Mic Bias 2V"}, {"MIC3R", NULL, "Mic Bias 2V"}, {"Mic Bias 2V", NULL, "Mic Jack"}, {"MIC3L", NULL, "Mic Bias"}, {"MIC3R", NULL, "Mic Bias"}, {"Mic Bias", NULL, "Mic Jack"}, /* Line In connected to (LINE1L | LINE2L), (LINE1R | LINE2R) */ {"LINE1L", NULL, "Line In"}, Loading Loading
Documentation/devicetree/bindings/sound/tlv320aic3x.txt +6 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,12 @@ Optional properties: - gpio-reset - gpio pin number used for codec reset - ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality - ai3x-micbias-vg - MicBias Voltage required. 1 - MICBIAS output is powered to 2.0V, 2 - MICBIAS output is powered to 2.5V, 3 - MICBIAS output is connected to AVDD, If this node is not mentioned or if the value is incorrect, then MicBias is powered down. Example: Loading
include/sound/tlv320aic3x.h +10 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,13 @@ enum { AIC3X_GPIO2_FUNC_BUTTON_PRESS_IRQ = 15 }; enum aic3x_micbias_voltage { AIC3X_MICBIAS_OFF = 0, AIC3X_MICBIAS_2_0V = 1, AIC3X_MICBIAS_2_5V = 2, AIC3X_MICBIAS_AVDDV = 3, }; struct aic3x_setup_data { unsigned int gpio_func[2]; }; Loading @@ -53,6 +60,9 @@ struct aic3x_setup_data { struct aic3x_pdata { int gpio_reset; /* < 0 if not used */ struct aic3x_setup_data *setup; /* Selects the micbias voltage */ enum aic3x_micbias_voltage micbias_vg; }; #endif
sound/soc/codecs/tlv320aic3x.c +77 −6 Original line number Diff line number Diff line Loading @@ -85,6 +85,9 @@ struct aic3x_priv { #define AIC3X_MODEL_33 1 #define AIC3X_MODEL_3007 2 u16 model; /* Selects the micbias voltage */ enum aic3x_micbias_voltage micbias_vg; }; /* Loading Loading @@ -195,6 +198,37 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, return ret; } /* * mic bias power on/off share the same register bits with * output voltage of mic bias. when power on mic bias, we * need reclaim it to voltage value. * 0x0 = Powered off * 0x1 = MICBIAS output is powered to 2.0V, * 0x2 = MICBIAS output is powered to 2.5V * 0x3 = MICBIAS output is connected to AVDD */ static int mic_bias_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); switch (event) { case SND_SOC_DAPM_POST_PMU: /* change mic bias voltage to user defined */ snd_soc_update_bits(codec, MICBIAS_CTRL, MICBIAS_LEVEL_MASK, aic3x->micbias_vg << MICBIAS_LEVEL_SHIFT); break; case SND_SOC_DAPM_PRE_PMD: snd_soc_update_bits(codec, MICBIAS_CTRL, MICBIAS_LEVEL_MASK, 0); break; } return 0; } static const char *aic3x_left_dac_mux[] = { "DAC_L1", "DAC_L3", "DAC_L2" }; static const char *aic3x_right_dac_mux[] = { "DAC_R1", "DAC_R3", "DAC_R2" }; static const char *aic3x_left_hpcom_mux[] = Loading Loading @@ -596,12 +630,9 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0), /* Mic Bias */ SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2V", MICBIAS_CTRL, 6, 3, 1, 0), SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2.5V", MICBIAS_CTRL, 6, 3, 2, 0), SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias AVDD", MICBIAS_CTRL, 6, 3, 3, 0), SND_SOC_DAPM_SUPPLY("Mic Bias", MICBIAS_CTRL, 6, 0, mic_bias_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), /* Output mixers */ SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0, Loading Loading @@ -1386,6 +1417,24 @@ static int aic3x_probe(struct snd_soc_codec *codec) if (aic3x->model == AIC3X_MODEL_3007) snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); /* set mic bias voltage */ switch (aic3x->micbias_vg) { case AIC3X_MICBIAS_2_0V: case AIC3X_MICBIAS_2_5V: case AIC3X_MICBIAS_AVDDV: snd_soc_update_bits(codec, MICBIAS_CTRL, MICBIAS_LEVEL_MASK, (aic3x->micbias_vg) << MICBIAS_LEVEL_SHIFT); break; case AIC3X_MICBIAS_OFF: /* * noting to do. target won't enter here. This is just to avoid * compile time warning "warning: enumeration value * 'AIC3X_MICBIAS_OFF' not handled in switch" */ break; } aic3x_add_widgets(codec); list_add(&aic3x->list, &reset_list); Loading Loading @@ -1461,6 +1510,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, struct aic3x_setup_data *ai3x_setup; struct device_node *np = i2c->dev.of_node; int ret; u32 value; aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL); if (aic3x == NULL) { Loading @@ -1474,6 +1524,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, if (pdata) { aic3x->gpio_reset = pdata->gpio_reset; aic3x->setup = pdata->setup; aic3x->micbias_vg = pdata->micbias_vg; } else if (np) { ai3x_setup = devm_kzalloc(&i2c->dev, sizeof(*ai3x_setup), GFP_KERNEL); Loading @@ -1493,6 +1544,26 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, aic3x->setup = ai3x_setup; } if (!of_property_read_u32(np, "ai3x-micbias-vg", &value)) { switch (value) { case 1 : aic3x->micbias_vg = AIC3X_MICBIAS_2_0V; break; case 2 : aic3x->micbias_vg = AIC3X_MICBIAS_2_5V; break; case 3 : aic3x->micbias_vg = AIC3X_MICBIAS_AVDDV; break; default : aic3x->micbias_vg = AIC3X_MICBIAS_OFF; dev_err(&i2c->dev, "Unsuitable MicBias voltage " "found in DT\n"); } } else { aic3x->micbias_vg = AIC3X_MICBIAS_OFF; } } else { aic3x->gpio_reset = -1; } Loading
sound/soc/codecs/tlv320aic3x.h +4 −0 Original line number Diff line number Diff line Loading @@ -238,6 +238,10 @@ /* Default input volume */ #define DEFAULT_GAIN 0x20 /* MICBIAS Control Register */ #define MICBIAS_LEVEL_SHIFT (6) #define MICBIAS_LEVEL_MASK (3 << 6) /* headset detection / button API */ /* The AIC3x supports detection of stereo headsets (GND + left + right signal) Loading
sound/soc/davinci/davinci-evm.c +3 −3 Original line number Diff line number Diff line Loading @@ -116,9 +116,9 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Line Out", NULL, "RLOUT"}, /* Mic connected to (MIC3L | MIC3R) */ {"MIC3L", NULL, "Mic Bias 2V"}, {"MIC3R", NULL, "Mic Bias 2V"}, {"Mic Bias 2V", NULL, "Mic Jack"}, {"MIC3L", NULL, "Mic Bias"}, {"MIC3R", NULL, "Mic Bias"}, {"Mic Bias", NULL, "Mic Jack"}, /* Line In connected to (LINE1L | LINE2L), (LINE1R | LINE2R) */ {"LINE1L", NULL, "Line In"}, Loading