Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 120274
b: refs/heads/master
c: 5920b45
h: refs/heads/master
v: v3
  • Loading branch information
Grazvydas Ignotas authored and Mark Brown committed Dec 3, 2008
1 parent 3a8c1fe commit 828a1f9
Show file tree
Hide file tree
Showing 3 changed files with 191 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 87689d567a45f80416feea0a2aa6d3a2a6b8963a
refs/heads/master: 5920b45303291057fef827f5bdafe04001c1bbae
177 changes: 174 additions & 3 deletions trunk/sound/soc/codecs/twl4030.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
0xc3, /* REG_OPTION (0x2) */
0x00, /* REG_UNKNOWN (0x3) */
0x00, /* REG_MICBIAS_CTL (0x4) */
0x24, /* REG_ANAMICL (0x5) */
0x04, /* REG_ANAMICR (0x6) */
0x0a, /* REG_AVADC_CTL (0x7) */
0x20, /* REG_ANAMICL (0x5) */
0x00, /* REG_ANAMICR (0x6) */
0x00, /* REG_AVADC_CTL (0x7) */
0x00, /* REG_ADCMICSEL (0x8) */
0x00, /* REG_DIGMIXING (0x9) */
0x0c, /* REG_ATXL1PGA (0xA) */
Expand Down Expand Up @@ -347,6 +347,162 @@ static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
return err;
}

static int twl4030_get_left_input(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = kcontrol->private_data;
u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
int result = 0;

/* one bit must be set a time */
reg &= TWL4030_CKMIC_EN | TWL4030_AUXL_EN | TWL4030_HSMIC_EN
| TWL4030_MAINMIC_EN;
if (reg != 0) {
result++;
while ((reg & 1) == 0) {
result++;
reg >>= 1;
}
}

ucontrol->value.integer.value[0] = result;
return 0;
}

static int twl4030_put_left_input(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = kcontrol->private_data;
int value = ucontrol->value.integer.value[0];
u8 anamicl, micbias, avadc_ctl;

anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
anamicl &= ~(TWL4030_CKMIC_EN | TWL4030_AUXL_EN | TWL4030_HSMIC_EN
| TWL4030_MAINMIC_EN);
micbias = twl4030_read_reg_cache(codec, TWL4030_REG_MICBIAS_CTL);
micbias &= ~(TWL4030_HSMICBIAS_EN | TWL4030_MICBIAS1_EN);
avadc_ctl = twl4030_read_reg_cache(codec, TWL4030_REG_AVADC_CTL);

switch (value) {
case 1:
anamicl |= TWL4030_MAINMIC_EN;
micbias |= TWL4030_MICBIAS1_EN;
break;
case 2:
anamicl |= TWL4030_HSMIC_EN;
micbias |= TWL4030_HSMICBIAS_EN;
break;
case 3:
anamicl |= TWL4030_AUXL_EN;
break;
case 4:
anamicl |= TWL4030_CKMIC_EN;
break;
default:
break;
}

/* If some input is selected, enable amp and ADC */
if (value != 0) {
anamicl |= TWL4030_MICAMPL_EN;
avadc_ctl |= TWL4030_ADCL_EN;
} else {
anamicl &= ~TWL4030_MICAMPL_EN;
avadc_ctl &= ~TWL4030_ADCL_EN;
}

twl4030_write(codec, TWL4030_REG_ANAMICL, anamicl);
twl4030_write(codec, TWL4030_REG_MICBIAS_CTL, micbias);
twl4030_write(codec, TWL4030_REG_AVADC_CTL, avadc_ctl);

return 1;
}

static int twl4030_get_right_input(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = kcontrol->private_data;
u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICR);
int value = 0;

reg &= TWL4030_SUBMIC_EN|TWL4030_AUXR_EN;
switch (reg) {
case TWL4030_SUBMIC_EN:
value = 1;
break;
case TWL4030_AUXR_EN:
value = 2;
break;
default:
break;
}

ucontrol->value.integer.value[0] = value;
return 0;
}

static int twl4030_put_right_input(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = kcontrol->private_data;
int value = ucontrol->value.integer.value[0];
u8 anamicr, micbias, avadc_ctl;

anamicr = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICR);
anamicr &= ~(TWL4030_SUBMIC_EN|TWL4030_AUXR_EN);
micbias = twl4030_read_reg_cache(codec, TWL4030_REG_MICBIAS_CTL);
micbias &= ~TWL4030_MICBIAS2_EN;
avadc_ctl = twl4030_read_reg_cache(codec, TWL4030_REG_AVADC_CTL);

switch (value) {
case 1:
anamicr |= TWL4030_SUBMIC_EN;
micbias |= TWL4030_MICBIAS2_EN;
break;
case 2:
anamicr |= TWL4030_AUXR_EN;
break;
default:
break;
}

if (value != 0) {
anamicr |= TWL4030_MICAMPR_EN;
avadc_ctl |= TWL4030_ADCR_EN;
} else {
anamicr &= ~TWL4030_MICAMPR_EN;
avadc_ctl &= ~TWL4030_ADCR_EN;
}

twl4030_write(codec, TWL4030_REG_ANAMICR, anamicr);
twl4030_write(codec, TWL4030_REG_MICBIAS_CTL, micbias);
twl4030_write(codec, TWL4030_REG_AVADC_CTL, avadc_ctl);

return 1;
}

static const char *twl4030_left_in_sel[] = {
"None",
"Main Mic",
"Headset Mic",
"Line In",
"Carkit Mic",
};

static const char *twl4030_right_in_sel[] = {
"None",
"Sub Mic",
"Line In",
};

static const struct soc_enum twl4030_left_input_mux =
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl4030_left_in_sel),
twl4030_left_in_sel);

static const struct soc_enum twl4030_right_input_mux =
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl4030_right_in_sel),
twl4030_right_in_sel);

/*
* FGAIN volume control:
* from -62 to 0 dB in 1 dB steps (mute instead of -63 dB)
Expand Down Expand Up @@ -378,6 +534,12 @@ static DECLARE_TLV_DB_SCALE(output_tvl, -1200, 600, 1);
*/
static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);

/*
* Gain control for input amplifiers
* 0 dB to 30 dB in 6 dB steps
*/
static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);

static const struct snd_kcontrol_new twl4030_snd_controls[] = {
/* Common playback gain controls */
SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
Expand Down Expand Up @@ -420,6 +582,15 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
SOC_DOUBLE_R_TLV("Capture Volume",
TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA,
0, 0x1f, 0, digital_capture_tlv),

SOC_DOUBLE_TLV("Input Boost Volume", TWL4030_REG_ANAMIC_GAIN,
0, 3, 5, 0, input_gain_tlv),

/* Input source controls */
SOC_ENUM_EXT("Left Input Source", twl4030_left_input_mux,
twl4030_get_left_input, twl4030_put_left_input),
SOC_ENUM_EXT("Right Input Source", twl4030_right_input_mux,
twl4030_get_right_input, twl4030_put_right_input),
};

/* add non dapm controls */
Expand Down
16 changes: 16 additions & 0 deletions trunk/sound/soc/codecs/twl4030.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,16 @@
#define TWL4030_CODECPDZ 0x02
#define TWL4030_OPT_MODE 0x01

/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */

#define TWL4030_MICBIAS2_CTL 0x40
#define TWL4030_MICBIAS1_CTL 0x20
#define TWL4030_HSMICBIAS_EN 0x04
#define TWL4030_MICBIAS2_EN 0x02
#define TWL4030_MICBIAS1_EN 0x01

/* ANAMICL (0x05) Fields */

#define TWL4030_CNCL_OFFSET_START 0x80
#define TWL4030_OFFSET_CNCL_SEL 0x60
#define TWL4030_OFFSET_CNCL_SEL_ARX1 0x00
Expand All @@ -127,10 +136,17 @@
#define TWL4030_MAINMIC_EN 0x01

/* ANAMICR (0x06) Fields */

#define TWL4030_MICAMPR_EN 0x10
#define TWL4030_AUXR_EN 0x04
#define TWL4030_SUBMIC_EN 0x01

/* AVADC_CTL (0x07) Fields */

#define TWL4030_ADCL_EN 0x08
#define TWL4030_AVADC_CLK_PRIORITY 0x04
#define TWL4030_ADCR_EN 0x02

/* AUDIO_IF (0x0E) Fields */

#define TWL4030_AIF_SLAVE_EN 0x80
Expand Down

0 comments on commit 828a1f9

Please sign in to comment.