Skip to content

Commit

Permalink
ASoC: TWL4030: Add VDL path support
Browse files Browse the repository at this point in the history
Add DAPMs for VDL(Voice Down Link) path. To support VDL path, we have
to change DAPMs of outputs(Earpiece, PreDrive Left/Right, Headset
Left/Right, Carkit Left/Right) from mux to mixer.

Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Acked-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Joonyoung Shim authored and Mark Brown committed Apr 23, 2009
1 parent 291ce18 commit 1a787e7
Showing 1 changed file with 126 additions and 130 deletions.
256 changes: 126 additions & 130 deletions sound/soc/codecs/twl4030.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,104 +321,60 @@ static void twl4030_power_down(struct snd_soc_codec *codec)
}

/* Earpiece */
static const char *twl4030_earpiece_texts[] =
{"Off", "DACL1", "DACL2", "DACR1"};

static const unsigned int twl4030_earpiece_values[] =
{0x0, 0x1, 0x2, 0x4};

static const struct soc_enum twl4030_earpiece_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_earpiece_texts),
twl4030_earpiece_texts,
twl4030_earpiece_values);

static const struct snd_kcontrol_new twl4030_dapm_earpiece_control =
SOC_DAPM_VALUE_ENUM("Route", twl4030_earpiece_enum);
static const struct snd_kcontrol_new twl4030_dapm_earpiece_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_EAR_CTL, 0, 1, 0),
SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_EAR_CTL, 1, 1, 0),
SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_EAR_CTL, 2, 1, 0),
SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_EAR_CTL, 3, 1, 0),
};

/* PreDrive Left */
static const char *twl4030_predrivel_texts[] =
{"Off", "DACL1", "DACL2", "DACR2"};

static const unsigned int twl4030_predrivel_values[] =
{0x0, 0x1, 0x2, 0x4};

static const struct soc_enum twl4030_predrivel_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_predrivel_texts),
twl4030_predrivel_texts,
twl4030_predrivel_values);

static const struct snd_kcontrol_new twl4030_dapm_predrivel_control =
SOC_DAPM_VALUE_ENUM("Route", twl4030_predrivel_enum);
static const struct snd_kcontrol_new twl4030_dapm_predrivel_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDL_CTL, 0, 1, 0),
SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PREDL_CTL, 1, 1, 0),
SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDL_CTL, 2, 1, 0),
SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDL_CTL, 3, 1, 0),
};

/* PreDrive Right */
static const char *twl4030_predriver_texts[] =
{"Off", "DACR1", "DACR2", "DACL2"};

static const unsigned int twl4030_predriver_values[] =
{0x0, 0x1, 0x2, 0x4};

static const struct soc_enum twl4030_predriver_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_predriver_texts),
twl4030_predriver_texts,
twl4030_predriver_values);

static const struct snd_kcontrol_new twl4030_dapm_predriver_control =
SOC_DAPM_VALUE_ENUM("Route", twl4030_predriver_enum);
static const struct snd_kcontrol_new twl4030_dapm_predriver_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDR_CTL, 0, 1, 0),
SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PREDR_CTL, 1, 1, 0),
SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDR_CTL, 2, 1, 0),
SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDR_CTL, 3, 1, 0),
};

/* Headset Left */
static const char *twl4030_hsol_texts[] =
{"Off", "DACL1", "DACL2"};

static const struct soc_enum twl4030_hsol_enum =
SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 1,
ARRAY_SIZE(twl4030_hsol_texts),
twl4030_hsol_texts);

static const struct snd_kcontrol_new twl4030_dapm_hsol_control =
SOC_DAPM_ENUM("Route", twl4030_hsol_enum);
static const struct snd_kcontrol_new twl4030_dapm_hsol_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 0, 1, 0),
SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_HS_SEL, 1, 1, 0),
SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_HS_SEL, 2, 1, 0),
};

/* Headset Right */
static const char *twl4030_hsor_texts[] =
{"Off", "DACR1", "DACR2"};

static const struct soc_enum twl4030_hsor_enum =
SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 4,
ARRAY_SIZE(twl4030_hsor_texts),
twl4030_hsor_texts);

static const struct snd_kcontrol_new twl4030_dapm_hsor_control =
SOC_DAPM_ENUM("Route", twl4030_hsor_enum);
static const struct snd_kcontrol_new twl4030_dapm_hsor_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 3, 1, 0),
SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_HS_SEL, 4, 1, 0),
SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_HS_SEL, 5, 1, 0),
};

/* Carkit Left */
static const char *twl4030_carkitl_texts[] =
{"Off", "DACL1", "DACL2"};

static const struct soc_enum twl4030_carkitl_enum =
SOC_ENUM_SINGLE(TWL4030_REG_PRECKL_CTL, 1,
ARRAY_SIZE(twl4030_carkitl_texts),
twl4030_carkitl_texts);

static const struct snd_kcontrol_new twl4030_dapm_carkitl_control =
SOC_DAPM_ENUM("Route", twl4030_carkitl_enum);
static const struct snd_kcontrol_new twl4030_dapm_carkitl_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKL_CTL, 0, 1, 0),
SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PRECKL_CTL, 1, 1, 0),
SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PRECKL_CTL, 2, 1, 0),
};

/* Carkit Right */
static const char *twl4030_carkitr_texts[] =
{"Off", "DACR1", "DACR2"};

static const struct soc_enum twl4030_carkitr_enum =
SOC_ENUM_SINGLE(TWL4030_REG_PRECKR_CTL, 1,
ARRAY_SIZE(twl4030_carkitr_texts),
twl4030_carkitr_texts);

static const struct snd_kcontrol_new twl4030_dapm_carkitr_control =
SOC_DAPM_ENUM("Route", twl4030_carkitr_enum);
static const struct snd_kcontrol_new twl4030_dapm_carkitr_controls[] = {
SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKR_CTL, 0, 1, 0),
SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PRECKR_CTL, 1, 1, 0),
SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PRECKR_CTL, 2, 1, 0),
};

/* Handsfree Left */
static const char *twl4030_handsfreel_texts[] =
{"Voice", "DACL1", "DACL2", "DACR2"};
{"Voice", "AudioL1", "AudioL2", "AudioR2"};

static const struct soc_enum twl4030_handsfreel_enum =
SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0,
Expand All @@ -430,7 +386,7 @@ SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);

/* Handsfree Right */
static const char *twl4030_handsfreer_texts[] =
{"Voice", "DACR1", "DACR2", "DACL2"};
{"Voice", "AudioR1", "AudioR2", "AudioL2"};

static const struct soc_enum twl4030_handsfreer_enum =
SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0,
Expand Down Expand Up @@ -828,6 +784,12 @@ static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1);
*/
static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0);

/*
* Voice Downlink GAIN volume control:
* from -37 to 12 dB in 1 dB steps (mute instead of -37 dB)
*/
static DECLARE_TLV_DB_SCALE(digital_voice_downlink_tlv, -3700, 100, 1);

/*
* Analog playback gain
* -24 dB to 12 dB in 2 dB steps
Expand Down Expand Up @@ -892,6 +854,16 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
1, 1, 0),

/* Common voice downlink gain controls */
SOC_SINGLE_TLV("DAC Voice Digital Downlink Volume",
TWL4030_REG_VRXPGA, 0, 0x31, 0, digital_voice_downlink_tlv),

SOC_SINGLE_TLV("DAC Voice Analog Downlink Volume",
TWL4030_REG_VDL_APGA_CTL, 3, 0x12, 1, analog_tlv),

SOC_SINGLE("DAC Voice Analog Downlink Switch",
TWL4030_REG_VDL_APGA_CTL, 1, 1, 0),

/* Separate output gain controls */
SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume",
TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
Expand Down Expand Up @@ -956,6 +928,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback",
SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback",
TWL4030_REG_AVDAC_CTL, 4, 0),

/* Analog PGAs */
SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL,
Expand All @@ -966,6 +940,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
0, 0, NULL, 0),
SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL,
0, 0, NULL, 0),
SND_SOC_DAPM_PGA("VDL_APGA", TWL4030_REG_VDL_APGA_CTL,
0, 0, NULL, 0),

/* Analog bypasses */
SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
Expand Down Expand Up @@ -998,26 +974,35 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL,
3, 0, NULL, 0),

/* Output MUX controls */
/* Output MIXER controls */
/* Earpiece */
SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_earpiece_control),
SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_earpiece_controls[0],
ARRAY_SIZE(twl4030_dapm_earpiece_controls)),
/* PreDrivL/R */
SND_SOC_DAPM_VALUE_MUX("PredriveL Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_predrivel_control),
SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_predriver_control),
SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_predrivel_controls[0],
ARRAY_SIZE(twl4030_dapm_predrivel_controls)),
SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_predriver_controls[0],
ARRAY_SIZE(twl4030_dapm_predriver_controls)),
/* HeadsetL/R */
SND_SOC_DAPM_MUX_E("HeadsetL Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_hsol_control, headsetl_event,
SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_hsor_control),
SND_SOC_DAPM_MIXER_E("HeadsetL Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_hsol_controls[0],
ARRAY_SIZE(twl4030_dapm_hsol_controls), headsetl_event,
SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER("HeadsetR Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_hsor_controls[0],
ARRAY_SIZE(twl4030_dapm_hsor_controls)),
/* CarkitL/R */
SND_SOC_DAPM_MUX("CarkitL Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_carkitl_control),
SND_SOC_DAPM_MUX("CarkitR Mux", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_carkitr_control),
SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_carkitl_controls[0],
ARRAY_SIZE(twl4030_dapm_carkitl_controls)),
SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0,
&twl4030_dapm_carkitr_controls[0],
ARRAY_SIZE(twl4030_dapm_carkitr_controls)),

/* Output MUX controls */
/* HandsfreeL/R */
SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0,
&twl4030_dapm_handsfreel_control, handsfree_event,
Expand Down Expand Up @@ -1082,50 +1067,61 @@ static const struct snd_soc_dapm_route intercon[] = {
{"ARXL2_APGA", NULL, "Analog L2 Playback Mixer"},
{"ARXR2_APGA", NULL, "Analog R2 Playback Mixer"},

{"VDL_APGA", NULL, "DAC Voice"},

/* Internal playback routings */
/* Earpiece */
{"Earpiece Mux", "DACL1", "ARXL1_APGA"},
{"Earpiece Mux", "DACL2", "ARXL2_APGA"},
{"Earpiece Mux", "DACR1", "ARXR1_APGA"},
{"Earpiece Mixer", "Voice", "VDL_APGA"},
{"Earpiece Mixer", "AudioL1", "ARXL1_APGA"},
{"Earpiece Mixer", "AudioL2", "ARXL2_APGA"},
{"Earpiece Mixer", "AudioR1", "ARXR1_APGA"},
/* PreDrivL */
{"PredriveL Mux", "DACL1", "ARXL1_APGA"},
{"PredriveL Mux", "DACL2", "ARXL2_APGA"},
{"PredriveL Mux", "DACR2", "ARXR2_APGA"},
{"PredriveL Mixer", "Voice", "VDL_APGA"},
{"PredriveL Mixer", "AudioL1", "ARXL1_APGA"},
{"PredriveL Mixer", "AudioL2", "ARXL2_APGA"},
{"PredriveL Mixer", "AudioR2", "ARXR2_APGA"},
/* PreDrivR */
{"PredriveR Mux", "DACR1", "ARXR1_APGA"},
{"PredriveR Mux", "DACR2", "ARXR2_APGA"},
{"PredriveR Mux", "DACL2", "ARXL2_APGA"},
{"PredriveR Mixer", "Voice", "VDL_APGA"},
{"PredriveR Mixer", "AudioR1", "ARXR1_APGA"},
{"PredriveR Mixer", "AudioR2", "ARXR2_APGA"},
{"PredriveR Mixer", "AudioL2", "ARXL2_APGA"},
/* HeadsetL */
{"HeadsetL Mux", "DACL1", "ARXL1_APGA"},
{"HeadsetL Mux", "DACL2", "ARXL2_APGA"},
{"HeadsetL Mixer", "Voice", "VDL_APGA"},
{"HeadsetL Mixer", "AudioL1", "ARXL1_APGA"},
{"HeadsetL Mixer", "AudioL2", "ARXL2_APGA"},
/* HeadsetR */
{"HeadsetR Mux", "DACR1", "ARXR1_APGA"},
{"HeadsetR Mux", "DACR2", "ARXR2_APGA"},
{"HeadsetR Mixer", "Voice", "VDL_APGA"},
{"HeadsetR Mixer", "AudioR1", "ARXR1_APGA"},
{"HeadsetR Mixer", "AudioR2", "ARXR2_APGA"},
/* CarkitL */
{"CarkitL Mux", "DACL1", "ARXL1_APGA"},
{"CarkitL Mux", "DACL2", "ARXL2_APGA"},
{"CarkitL Mixer", "Voice", "VDL_APGA"},
{"CarkitL Mixer", "AudioL1", "ARXL1_APGA"},
{"CarkitL Mixer", "AudioL2", "ARXL2_APGA"},
/* CarkitR */
{"CarkitR Mux", "DACR1", "ARXR1_APGA"},
{"CarkitR Mux", "DACR2", "ARXR2_APGA"},
{"CarkitR Mixer", "Voice", "VDL_APGA"},
{"CarkitR Mixer", "AudioR1", "ARXR1_APGA"},
{"CarkitR Mixer", "AudioR2", "ARXR2_APGA"},
/* HandsfreeL */
{"HandsfreeL Mux", "DACL1", "ARXL1_APGA"},
{"HandsfreeL Mux", "DACL2", "ARXL2_APGA"},
{"HandsfreeL Mux", "DACR2", "ARXR2_APGA"},
{"HandsfreeL Mux", "Voice", "VDL_APGA"},
{"HandsfreeL Mux", "AudioL1", "ARXL1_APGA"},
{"HandsfreeL Mux", "AudioL2", "ARXL2_APGA"},
{"HandsfreeL Mux", "AudioR2", "ARXR2_APGA"},
/* HandsfreeR */
{"HandsfreeR Mux", "DACR1", "ARXR1_APGA"},
{"HandsfreeR Mux", "DACR2", "ARXR2_APGA"},
{"HandsfreeR Mux", "DACL2", "ARXL2_APGA"},
{"HandsfreeR Mux", "Voice", "VDL_APGA"},
{"HandsfreeR Mux", "AudioR1", "ARXR1_APGA"},
{"HandsfreeR Mux", "AudioR2", "ARXR2_APGA"},
{"HandsfreeR Mux", "AudioL2", "ARXL2_APGA"},

/* outputs */
{"OUTL", NULL, "ARXL2_APGA"},
{"OUTR", NULL, "ARXR2_APGA"},
{"EARPIECE", NULL, "Earpiece Mux"},
{"PREDRIVEL", NULL, "PredriveL Mux"},
{"PREDRIVER", NULL, "PredriveR Mux"},
{"HSOL", NULL, "HeadsetL Mux"},
{"HSOR", NULL, "HeadsetR Mux"},
{"CARKITL", NULL, "CarkitL Mux"},
{"CARKITR", NULL, "CarkitR Mux"},
{"EARPIECE", NULL, "Earpiece Mixer"},
{"PREDRIVEL", NULL, "PredriveL Mixer"},
{"PREDRIVER", NULL, "PredriveR Mixer"},
{"HSOL", NULL, "HeadsetL Mixer"},
{"HSOR", NULL, "HeadsetR Mixer"},
{"CARKITL", NULL, "CarkitL Mixer"},
{"CARKITR", NULL, "CarkitR Mixer"},
{"HFL", NULL, "HandsfreeL Mux"},
{"HFR", NULL, "HandsfreeR Mux"},

Expand Down

0 comments on commit 1a787e7

Please sign in to comment.