[alsa-devel] twl4030 asoc kcontrols and widgets
Hi Alsa devel,
I have been working on TWL4030 codec driver for ALSA SOC. I have taken sound/soc/codec/twl4030.c as reference from main line
This Patch adds some kcontrols, widgets and interconnection map for some of the TWL4030 ASOC codec I was building it for a custom board as it was for OVERO
Suggestions on the DAPM part of the driver would be helpful
Thanks in advance.
The patch is as follows.
--- twl4030.c 2008-11-19 12:04:32.000000000 +0530 +++ /home/chnaveen/Desktop/twl4030.c 2008-11-21 15:08:06.000000000 +0530 @@ -16,7 +16,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA - * + * Modified by : Naveen Krishna Ch + * Added Kcontrols for OMAP3 WaterlooBoard + * Dated : 28th october 2008 */
#include <linux/module.h> @@ -29,24 +31,27 @@ #include <linux/i2c/twl4030.h> #include <sound/core.h> #include <sound/pcm.h> +#include <sound/jack.h> #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/soc-dapm.h> #include <sound/initval.h> - +#include <asm/arch/twl4030.h> #include "twl4030.h"
+static int twl4030_jack_func; + /* * twl4030 register cache & default register settings */ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { 0x00, /* this register not used */ - 0x93, /* REG_CODEC_MODE (0x1) */ + 0x03, /* REG_CODEC_MODE (0x1) */ 0xc3, /* REG_OPTION (0x2) */ 0x00, /* REG_UNKNOWN (0x3) */ 0x00, /* REG_MICBIAS_CTL (0x4) */ - 0x24, /* REG_ANAMICL (0x5) */ - 0x04, /* REG_ANAMICR (0x6) */ + 0xb0, /* REG_ANAMICL (0x5) */ + 0x10, /* REG_ANAMICR (0x6) */ 0x0a, /* REG_AVADC_CTL (0x7) */ 0x00, /* REG_ADCMICSEL (0x8) */ 0x00, /* REG_DIGMIXING (0x9) */ @@ -67,22 +72,22 @@ 0x00, /* REG_ARX2VTXPGA (0x18) */ 0x00, /* REG_ARXL1_APGA_CTL (0x19) */ 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */ - 0x4b, /* REG_ARXL2_APGA_CTL (0x1B) */ - 0x4b, /* REG_ARXR2_APGA_CTL (0x1C) */ + 0x2b, /* REG_ARXL2_APGA_CTL (0x1B) */ + 0x2b, /* REG_ARXR2_APGA_CTL (0x1C) */ 0x00, /* REG_ATX2ARXPGA (0x1D) */ 0x00, /* REG_BT_IF (0x1E) */ 0x00, /* REG_BTPGA (0x1F) */ 0x00, /* REG_BTSTPGA (0x20) */ - 0x00, /* REG_EAR_CTL (0x21) */ - 0x24, /* REG_HS_SEL (0x22) */ - 0x0a, /* REG_HS_GAIN_SET (0x23) */ - 0x00, /* REG_HS_POPN_SET (0x24) */ - 0x00, /* REG_PREDL_CTL (0x25) */ - 0x00, /* REG_PREDR_CTL (0x26) */ - 0x00, /* REG_PRECKL_CTL (0x27) */ - 0x00, /* REG_PRECKR_CTL (0x28) */ - 0x00, /* REG_HFL_CTL (0x29) */ - 0x00, /* REG_HFR_CTL (0x2A) */ + 0x20, /* REG_EAR_CTL (0x21) */ + 0x00, /* REG_HS_SEL (0x22) */ + 0x05, /* REG_HS_GAIN_SET (0x23) */ + 0x42, /* REG_HS_POPN_SET (0x24) */ + 0x20, /* REG_PREDL_CTL (0x25) */ + 0x20, /* REG_PREDR_CTL (0x26) */ + 0x20, /* REG_PRECKL_CTL (0x27) */ + 0x20, /* REG_PRECKR_CTL (0x28) */ + 0x1f, /* REG_HFL_CTL (0x29) */ + 0x1f, /* REG_HFR_CTL (0x2A) */ 0x00, /* REG_ALC_CTL (0x2B) */ 0x00, /* REG_ALC_SET1 (0x2C) */ 0x00, /* REG_ALC_SET2 (0x2D) */ @@ -112,9 +117,40 @@ 0x00, /* REG_VIBRA_CTL (0x45) */ 0x00, /* REG_VIBRA_SET (0x46) */ 0x00, /* REG_VIBRA_PWM_SET (0x47) */ - 0x00, /* REG_ANAMIC_GAIN (0x48) */ + 0x24, /* REG_ANAMIC_GAIN (0x48) */ 0x00, /* REG_MISC_SET_2 (0x49) */ }; +static void twl4030_ext_control(struct snd_soc_codec *codec) +{ + if (twl4030_jack_func) + snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + else + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + + snd_soc_dapm_sync(codec); +} + +static int twl4030_get_jack(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = twl4030_jack_func; + + return 0; +} + +static int twl4030_set_jack(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + + if (twl4030_jack_func == ucontrol->value.integer.value[0]) + return 0; + + twl4030_jack_func = ucontrol->value.integer.value[0]; + twl4030_ext_control(codec); + + return 1; +}
/* * read twl4030 register cache @@ -188,14 +224,83 @@ twl4030_write(codec, i, twl4030_reg[i]);
} +static const char *jack_function[] = {"Off", "Headphone"}; + +static const struct soc_enum twl4030_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(jack_function), jack_function), +}; +
static const struct snd_kcontrol_new twl4030_snd_controls[] = { - SOC_DOUBLE_R("Master Playback Volume", - TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA, - 0, 127, 0), - SOC_DOUBLE_R("Capture Volume", - TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA, - 0, 127, 0), + + /* Master Playback Volume Controls */ + SOC_DOUBLE_R("Master PLayback Course Gain ctrl", + TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA, + 6, 3, 0), + SOC_DOUBLE_R("Master Playback Fine Gain ctrl", + TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA, + 0, 63, 0), + + /* Playback Speaker volume controls */ + SOC_DOUBLE_R("Speaker R2+L2 Volume ctrls", + TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL, + 3, 17, 0), + + /* Capture Gain controls */ + SOC_DOUBLE_R("Master Capture Gain ctrl", + TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA, + 0, 31, 0), + /* Loop gain controls*/ + SOC_DOUBLE("Loop Gain ctrl", TWL4030_REG_ATX2ARXPGA, + 3 , 0, 7, 0), + + SOC_DOUBLE("Main +Sub mic capture gain ctrl", + TWL4030_REG_ANAMIC_GAIN, 3 , 0, 5, 0), + + SOC_DOUBLE_R("External Speaker Volume control", + TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL, + 4, 3, 0), + + SOC_DOUBLE_R("Pre Car kit Volume control", + TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL, + 4, 3, 0), + + SOC_SINGLE("DACL2", TWL4030_REG_AVDAC_CTL, 3, 1, 0), + SOC_SINGLE("DACR2", TWL4030_REG_AVDAC_CTL, 2, 1, 0), + + SOC_ENUM_EXT("Jack Function", twl4030_enum[0], + twl4030_get_jack, twl4030_set_jack), +}; + +/* Right PGA Mixer control switches */ +static const struct snd_kcontrol_new twl4030_right_pga_mixer_controls[] = { + SOC_DAPM_SINGLE("HS Mic switch", TWL4030_REG_ANAMICL, 1, 1, 0), + SOC_DAPM_SINGLE("Aux/FM right switch", TWL4030_REG_ANAMICR, 2, 1, 0), + SOC_DAPM_SINGLE("Sub Mic switch", TWL4030_REG_ANAMICR, 0, 1, 0), +}; + +/* Left PGA Mixer control switches */ +static const struct snd_kcontrol_new twl4030_left_pga_mixer_controls[] = { + SOC_DAPM_SINGLE("HS Mic switch", TWL4030_REG_ANAMICL, 1, 1, 0), + SOC_DAPM_SINGLE("Aux/FM left switch", TWL4030_REG_ANAMICL, 2, 1, 0), + SOC_DAPM_SINGLE("Main Mic switch", TWL4030_REG_ANAMICL, 0, 1, 0), +}; + +/* Right DACR2 Mixer */ +static const struct snd_kcontrol_new twl4030_dacr2_mixer_controls[] = { + SOC_DAPM_SINGLE("Headset-R switch", TWL4030_REG_HS_SEL, 5, 1, 0), + SOC_DAPM_SINGLE("Handsfree-R switch", TWL4030_REG_HFR_CTL, 5, 1, 0), + SOC_DAPM_SINGLE("PRECK-R switch", TWL4030_REG_PRECKR_CTL, 2, 1, 0), + SOC_DAPM_DOUBLE("E class-D amp-R switch", TWL4030_REG_PREDR_CTL, 3, 2, 1, 0, 0), +}; + +/* Left DACL2 Mixer */ +static const struct snd_kcontrol_new twl4030_dacl2_mixer_controls[] = { + SOC_DAPM_SINGLE("Headset-L switch", TWL4030_REG_HS_SEL, 2, 1, 0), + SOC_DAPM_SINGLE("Handsfree-L switch", TWL4030_REG_HFL_CTL, 5, 1, 0), + SOC_DAPM_SINGLE("Ear peice switch", TWL4030_REG_EAR_CTL, 2, 1, 0), + SOC_DAPM_SINGLE("PRECK-L switch", TWL4030_REG_PRECKL_CTL, 2, 1, 0), + SOC_DAPM_DOUBLE("E class-D amp-L switch", TWL4031_REG_PREDL_CTL, 3, 2, 1, 0, 0), };
/* add non dapm controls */ @@ -215,27 +320,96 @@ }
static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { - SND_SOC_DAPM_INPUT("INL"), - SND_SOC_DAPM_INPUT("INR"), - - SND_SOC_DAPM_OUTPUT("OUTL"), - SND_SOC_DAPM_OUTPUT("OUTR"), - - SND_SOC_DAPM_DAC("DACL", "Left Playback", SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_DAC("DACR", "Right Playback", SND_SOC_NOPM, 0, 0), - - SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_HP("Headphone Jack", NULL), + + /* Left ADC for capture */ + SND_SOC_DAPM_ADC("ADCL", "Left Capture ADC", TWL4030_REG_AVADC_CTL, 3, 0), + + /* dapm widget (path domain) for left PGA mixer */ + SND_SOC_DAPM_MIXER("LINEIN-L", SND_SOC_NOPM, 0, 0, + &twl4030_left_pga_mixer_controls[0], + ARRAY_SIZE(twl4030_left_pga_mixer_controls)), + + /* Right ADC for capture*/ + SND_SOC_DAPM_ADC("ADCR", "Right Capture ADC", TWL4030_REG_AVADC_CTL, 1, 0), + + /* dapm widget (path domain) for right PGA mixer */ + SND_SOC_DAPM_MIXER("LINEIN-R", SND_SOC_NOPM, 0, 0, + &twl4030_right_pga_mixer_controls[0], + ARRAY_SIZE(twl4030_right_pga_mixer_controls)), + + /* dapm widget (path domain) for left DACL2 Mixer */ + + SND_SOC_DAPM_MIXER("DACL2 Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dacl2_mixer_controls[0], + ARRAY_SIZE(twl4030_dacl2_mixer_controls)), + + /* dapm widget (path domain) for DACR2 Mixer */ + SND_SOC_DAPM_MIXER("DACR2 Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dacr2_mixer_controls[0], + ARRAY_SIZE(twl4030_dacr2_mixer_controls)), + + /* Inputs Left*/ + SND_SOC_DAPM_INPUT("HSMIC"), + SND_SOC_DAPM_INPUT("Aux/fm left"), + SND_SOC_DAPM_INPUT("Main mic"), + + /* Inputs Right*/ + SND_SOC_DAPM_INPUT("HSMIC"), + SND_SOC_DAPM_INPUT("Aux/fm right"), + SND_SOC_DAPM_INPUT("Sub mic"), + + /* Outputs Left*/ + SND_SOC_DAPM_OUTPUT("HSOL"), + SND_SOC_DAPM_OUTPUT("IHF_LEFT"), + SND_SOC_DAPM_OUTPUT("EAR"), + SND_SOC_DAPM_OUTPUT("E class-D L"), + SND_SOC_DAPM_OUTPUT("PRECK-L"); + + /* Outputs Right */ + SND_SOC_DAPM_OUTPUT("HSOR"), + SND_SOC_DAPM_OUTPUT("IHF_RIGHT"), + SND_SOC_DAPM_OUTPUT("E class-D R"), + SND_SOC_DAPM_OUTPUT("PRECK-R"); };
static const struct snd_soc_dapm_route intercon[] = { - /* outputs */ - {"OUTL", NULL, "DACL"}, - {"OUTR", NULL, "DACR"}, - - /* inputs */ - {"ADCL", NULL, "INL"}, - {"ADCR", NULL, "INR"}, + + /* ******** Left input ******** */ + {"LINEIN-L", "HS Mic switch", "HSMIC"}, + {"LINEIN-L", "Aux/FM left switch", "Aux/fm left"}, + {"LINEIN-L", "Main Mic switch", "Main mic"}, + + {"ADCL", NULL, "LINEIN-L"}, + + + /* ******** Right Input ******** */ + {"LINEIN-R", "HS Mic switch", "HSMIC"}, + {"LINEIN-R", "Aux/FM right switch", "Aux/fm right"}, + {"LINEIN-R", "Sub Mic switch", "Sub mic"}, + + {"ADCR", NULL, "LINEIN-R"}, + + /* ******** Left Output ******** */ + //{"DACL2", NULL, "DACL2 Mixer"}, + + {"DACL2 Mixer", "Headset-L switch", "HSOL"}, + {"DACL2 Mixer", "Handsfree-L switch", "IHF_LEFT"}, + {"DACL2 Mixer", "Ear peice switch", "EAR"}, + {"DACL2 Mixer", "PRECK-L switch", "PRECK-L"}, + {"DACL2 Mixer","E class-D amp-L switch","E class-D L"}, + + {"Headphone Jack",NULL, "HSOL"}, + /* ******** Right Output ******** */ + //{"DACR2", NULL, "DACR2 Mixer"}, + + {"DACR2 Mixer", "Headset-R switch","HSOR"}, + {"DACR2 Mixer", "Handsfree-R switch","IHF_RIGHT"}, + {"DACR2 Mixer", "PRECK-R switch", "PRECK-R"}, + {"DACR2 Mixer","E class-D amp-R switch","E class-D R"}, + + {"Headphone Jack",NULL, "HSOR"}, };
static int twl4030_add_widgets(struct snd_soc_codec *codec) @@ -280,7 +454,7 @@ /* toggle CODECPDZ as per TRM */ twl4030_clear_codecpdz(codec); twl4030_set_codecpdz(codec); - + /* program anti-pop with bias ramp delay */ popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); popn &= TWL4030_RAMP_DELAY; @@ -384,6 +558,9 @@ case 48000: mode |= TWL4030_APLL_RATE_48000; break; + case 96000: + mode |= TWL4030_APLL_RATE_96000; + break; default: printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n", params_rate(params)); @@ -434,6 +611,7 @@ u8 infreq;
switch (freq) { + case 19200000: infreq = TWL4030_APLL_INFREQ_19200KHZ; break; @@ -504,20 +682,24 @@ return 0; }
-#define TWL4030_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) +#define TWL4030_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \ + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) + #define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
struct snd_soc_dai twl4030_dai = { .name = "twl4030", .playback = { .stream_name = "Playback", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = TWL4030_RATES, .formats = TWL4030_FORMATS,}, .capture = { .stream_name = "Capture", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = TWL4030_RATES, .formats = TWL4030_FORMATS,}, @@ -616,13 +798,14 @@
codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); if (codec == NULL) - return -ENOMEM; - + return -ENOMEM; + socdev->codec = codec; mutex_init(&codec->mutex); INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); - + + twl4030_socdev = socdev; twl4030_init(socdev);
Patch ends..
I need suggestions on the DAPM part of the driver.
Thanks and Regards,
(: Naveen Krishna Ch :)
On Thu, Nov 20, 2008 at 03:08:33PM +0530, naveen krishna ch wrote:
I have been working on TWL4030 codec driver for ALSA SOC. I have taken sound/soc/codec/twl4030.c as reference from main line
CCing Steve Sakoman who wrote the driver.
This Patch adds some kcontrols, widgets and interconnection map for some of the TWL4030 ASOC codec
It's doing a bit more than that... This should be split up into several patches, each making a single logical change: for example, the change to the register defaults could be split out since they are (presumably) something that applies in general. Splitting things up like this makes it easier to review your patches since it makes the purpose of each individual code change much clearer and easier to verify.
Please see Documentation/SubmittingPatches for details on how to format patches for submission.
Suggestions on the DAPM part of the driver would be helpful
Aside from the control name and formatting issues identified below it looks mostly reasonable, though I've not looked at how well it corresponds to the codec at all. My main concern is that the driver has non-DAPM power management provided by twl4030_power_up() and friends - how does your driver interact with this? I would expect to see something dealing with that, for pops and clicks if nothing else.
Some more specific comments:
--- twl4030.c 2008-11-19 12:04:32.000000000 +0530 +++ /home/chnaveen/Desktop/twl4030.c 2008-11-21 15:08:06.000000000 +0530 @@ -16,7 +16,9 @@
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- 02110-1301 USA
- Modified by : Naveen Krishna Ch
- Added Kcontrols for OMAP3 WaterlooBoard
*/
- Dated : 28th october 2008
Don't add in-code changelogs, git keeps track of the history of files.
/*
- twl4030 register cache & default register settings
*/ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { 0x00, /* this register not used */
- 0x93, /* REG_CODEC_MODE (0x1) */
- 0x03, /* REG_CODEC_MODE (0x1) */ 0xc3, /* REG_OPTION (0x2) */
...
- 0x00, /* REG_ANAMIC_GAIN (0x48) */
- 0x24, /* REG_ANAMIC_GAIN (0x48) */ 0x00, /* REG_MISC_SET_2 (0x49) */
This whole hunk should be splittable out from the rest of the code. I'd also like to see some discussion about what's being changed and why - is it just that the register defaults are incorrect?
}; +static void twl4030_ext_control(struct snd_soc_codec *codec) +{
There should be a blank line between the register defaults and the start of the function - this is a problem in several parts of your patch.
if (twl4030_jack_func)
snd_soc_dapm_enable_pin(codec, "Headphone Jack");
else
snd_soc_dapm_disable_pin(codec, "Headphone Jack");
snd_soc_dapm_sync(codec);
+}
The jack handling code you have added should not be part of the TWL4030 driver, it should be part of the machine driver for the board. Any jacks will depend on the particular board - some boards may not wire up the headphone output at all.
static const struct snd_kcontrol_new twl4030_snd_controls[] = {
- SOC_DOUBLE_R("Master Playback Volume",
TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
0, 127, 0),
- SOC_DOUBLE_R("Capture Volume",
TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA,
0, 127, 0),
- /* Master Playback Volume Controls */
- SOC_DOUBLE_R("Master PLayback Course Gain ctrl",
TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
6, 3, 0),
- SOC_DOUBLE_R("Master Playback Fine Gain ctrl",
TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
0, 63, 0),
These and your other control names should conform to the ALSA control names standard - see Documentation/sound/alsa/ControlNames.txt. For gain controls the last word should be Volume.
- /* Loop gain controls*/
SOC_DOUBLE("Loop Gain ctrl", TWL4030_REG_ATX2ARXPGA,
3 , 0, 7, 0),
SOC_DOUBLE("Main +Sub mic capture gain ctrl",
TWL4030_REG_ANAMIC_GAIN, 3 , 0, 5, 0),
SOC_DOUBLE_R("External Speaker Volume control",
TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
4, 3, 0),
- SOC_DOUBLE_R("Pre Car kit Volume control",
TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL,
4, 3, 0),
Your indentation appears to be done rather inconsistently.
+/* Right PGA Mixer control switches */ +static const struct snd_kcontrol_new twl4030_right_pga_mixer_controls[] = {
SOC_DAPM_SINGLE("HS Mic switch", TWL4030_REG_ANAMICL, 1, 1, 0),
SOC_DAPM_SINGLE("Aux/FM right switch", TWL4030_REG_ANAMICR, 2, 1,
0),
SOC_DAPM_SINGLE("Sub Mic switch", TWL4030_REG_ANAMICR, 0, 1, 0),
+};
Should be "Switch" not "switch".
static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
- SND_SOC_DAPM_INPUT("INL"),
- SND_SOC_DAPM_INPUT("INR"),
- SND_SOC_DAPM_OUTPUT("OUTL"),
- SND_SOC_DAPM_OUTPUT("OUTR"),
Why have these been changed?
- /* Right ADC for capture*/
SND_SOC_DAPM_ADC("ADCR", "Right Capture ADC",
TWL4030_REG_AVADC_CTL, 1, 0),
It looks like your MUA has word wrapped your patch here. This will make it impossible to apply. You might find it's easier to use something like git-send-email to send the patches if you can't see how to turn off word wrapping in your MUA.
SND_SOC_DAPM_INPUT("HSMIC"),
SND_SOC_DAPM_INPUT("Aux/fm left"),
SND_SOC_DAPM_INPUT("Main mic"),
The normal thing here is to use the pin names specified in the datasheet rather than plain text descriptions - this avoids any confusion when people are connecting these up in machine drivers.
/* ******** Right Output ******** */
//{"DACR2", NULL, "DACR2 Mixer"},
Remove code rather than leaving it commented out.
@@ -280,7 +454,7 @@ /* toggle CODECPDZ as per TRM */ twl4030_clear_codecpdz(codec); twl4030_set_codecpdz(codec);
- /* program anti-pop with bias ramp delay */ popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); popn &= TWL4030_RAMP_DELAY;
Random indentation change here - you've got a few of those, please remove them.
@@ -384,6 +558,9 @@ case 48000: mode |= TWL4030_APLL_RATE_48000; break;
- case 96000:
mode |= TWL4030_APLL_RATE_96000;
break;
This should be split out into a separate patch.
@@ -504,20 +682,24 @@ return 0; }
-#define TWL4030_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) +#define TWL4030_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \
SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
This definitely won't apply to the current driver. Also I suspect you just want SNDRV_PCM_RATE_8000_96000 here.
Hello,
I have been also working on the twl4030 codec driver for some time now. Altrough my patchset is not yet ready, but I'd like to be heard early enough: My plan is to add _all_ (ok, almost all) the features we can get with TWLx030... So instead of having 'only' one possible route from DACl2/DACR2, I have implemented in a reverse order: For all outputs (HSOL/R, PreDriveL/R, HFL/R IHFL/R, EAR) one can select from where the audio is routed. For example: PreDriveL can output audio from Voice, DACL1, DACL2, DACR2 PreDriveR can output audio from Voice, DACR1, DACR2, DACL2 HSOL can output audio from Voice, DACL1, DACL2 HSOR can output audio from Voice, DACR1, DACR2 and the list goes on... With this mode one can enable whatever combination of routing he/she needs from TWL.
Since these channels are really 'independent' inside of TWL, making the routing/mixing flexible (you might say extremely flexible) could make sense.
CCing: Steve Sakoman who actually wrote the driver - could cc Mark Brown as well, but it seams that he is reading alsa-devel quite frequently ;)
What do you think?
On Thu, Nov 20, 2008 at 04:02:43PM +0200, Peter Ujfalusi wrote:
My plan is to add _all_ (ok, almost all) the features we can get with TWLx030... So instead of having 'only' one possible route from DACl2/DACR2, I have implemented in a reverse order:
...
With this mode one can enable whatever combination of routing he/she needs from TWL.
Since these channels are really 'independent' inside of TWL, making the routing/mixing flexible (you might say extremely flexible) could make sense.
This is good - an ASoC codec driver should expose as much functionality of the codec as possible and let user space configure it at runtime. See for example the WM8900 or WM8990 drivers for examples of codecs with fairly complex audio routing.
CCing: Steve Sakoman who actually wrote the driver - could cc Mark Brown as well, but it seams that he is reading alsa-devel quite frequently ;)
It's still useful to keep people in CCs - it's not so bad with alsa-devel but it does help to ensure that things don't get missed on high volume mailing lists.
On Thu, Nov 20, 2008 at 6:14 AM, Mark Brown broonie@sirena.org.uk wrote:
On Thu, Nov 20, 2008 at 04:02:43PM +0200, Peter Ujfalusi wrote:
My plan is to add _all_ (ok, almost all) the features we can get with TWLx030... So instead of having 'only' one possible route from DACl2/DACR2, I have implemented in a reverse order:
...
With this mode one can enable whatever combination of routing he/she needs from TWL.
Since these channels are really 'independent' inside of TWL, making the routing/mixing flexible (you might say extremely flexible) could make sense.
This is good - an ASoC codec driver should expose as much functionality of the codec as possible and let user space configure it at runtime. See for example the WM8900 or WM8990 drivers for examples of codecs with fairly complex audio routing.
Agreed! This is a really good thing to do.
Had I not been under a lot of time pressure when doing the original version of the driver I would have taken this approach myself.
I'm glad to see that you are tackling this. Peter, you should post your patches for comment. Might help speed things along if we get more folks looking and contributing.
Steve
Hi,
Sorry about the delayed reply...
On Thursday 20 November 2008 17:39:14 ext Steve Sakoman wrote:
Agreed! This is a really good thing to do.
Had I not been under a lot of time pressure when doing the original version of the driver I would have taken this approach myself.
I'm glad to see that you are tackling this. Peter, you should post your patches for comment. Might help speed things along if we get more folks looking and contributing.
Steve
I'm planing to send patches as soon as possible. I have been working with the twl4030 codec for about a week now, so the thing that I have is far from what it should be at the end... I can explain in short what I have at the moment and what is missing: - Playback route controls for: - PreDriveL (Off, Voice, DACL1, DACL2, DACR2) - PreDriveR (Off, Voice, DACR1, DACR2, DACL2) - HeadsetL (Off, Voice, DACL1, DACL2) - HeadsetR (Off, Voice, DACR1, DACR2) - CarkitL (Off, Voice, DACL1, DACL2) # or PRECKT_Right - CarkitR (Off, Voice, DACR1, DACR2) # or PRECKT_Left - HandsfreeL (Voice, DACL1, DACL2, DACR2) # or IHFL or Class-DL # (depends which text I take) - HandsfreeR (Voice, DACR1, DACR2, DACL2) # or IHFR or Class-DR # (depends which text I take)
Volume/Gain controls: - FGAIN in DAC2 (mute, -62 - 0 dB, in 1 dB steps) - CGAIN in DAC2 (0 - 12 dB, in 6 dB steps) - PreDrive(L and R, not separate) playback gain, or volume control (mute, -6, 0, 6 dB) - Headset(L and R, not separate) playback gain, or volume control (mute, -6, 0, 6 dB) - Carkit(L and R, not separate) playback gain, or volume control (mute, -6, 0, 6 dB)
All of the above are added to the twl4030_snd_controls at this point of time.
The twl4030_reg has been set to disable all outputs by default, it is up to the user to enable the needed outputs.
SND_SOC_DAPM_INPUT() and SND_SOC_DAPM_OUTPUT() definitions for all physical inputs, outputs. I have not yet started with the correct dapm_route for the TWL, it is going to be quite a mess. At the moment outputs are connected to DACL/R2, for example: {"PREDRIVL", NULL, "DACL2"}
So in the playback side what you can do already: You can select the routing individually for all outputs (except the Earpiece, hmm I forgot about it).
The capture path is kind of untouched, it is in the to-do list, it does works with the DIGIMIC0 for me.
Three sets of get/put function for dealing with TWL's specially crafted registers (Routing selections, Gain controls).
What needs to be done: Lot's of things... Clean up? snd_soc_dapm_route, snd_soc_dapm_widget things (I need an A3 paper for that). Capture controls and corresponding dapm_route, dapm_widgets
So this is my current status, are you still interested to see these things? What else should I add before I send the patch?
On Fri, Nov 21, 2008 at 11:49:03AM +0200, Peter Ujfalusi wrote:
So this is my current status, are you still interested to see these things? What else should I add before I send the patch?
If you're going to submit this stuff please send a series of incremental patches - it makes things easier to review. Since there seem to be a few people working on this it's probably worth pushing stuff out as people have it rather than waiting for everything to be complete and coordinating through the ALSA tree.
On Thu, Nov 20, 2008 at 7:32 PM, Peter Ujfalusi peter.ujfalusi@nokia.comwrote:
Hello,
I have been also working on the twl4030 codec driver for some time now. Altrough my patchset is not yet ready, but I'd like to be heard early enough: My plan is to add _all_ (ok, almost all) the features we can get with TWLx030... So instead of having 'only' one possible route from DACl2/DACR2, I have implemented in a reverse order: For all outputs (HSOL/R, PreDriveL/R, HFL/R IHFL/R, EAR) one can select from where the audio is routed. For example: PreDriveL can output audio from Voice, DACL1, DACL2, DACR2 PreDriveR can output audio from Voice, DACR1, DACR2, DACL2 HSOL can output audio from Voice, DACL1, DACL2 HSOR can output audio from Voice, DACR1, DACR2 and the list goes on... With this mode one can enable whatever combination of routing he/she needs from TWL.
Since these channels are really 'independent' inside of TWL, making the routing/mixing flexible (you might say extremely flexible) could make sense.
CCing: Steve Sakoman who actually wrote the driver - could cc Mark Brown as well, but it seams that he is reading alsa-devel quite frequently ;)
What do you think?
Great job. In my case being a custom board the other paths (DACL1 and Voice) and Pre car kit are not configured.
Routing that way would get full CODEC into use and using DAPM events then would really give their best.
-- Péter
On Thursday 20 November 2008 11:38:33 ext naveen krishna ch wrote:
Hi Alsa devel,
I have been working on TWL4030 codec driver for ALSA SOC. I have taken sound/soc/codec/twl4030.c as reference from main line
This Patch adds some kcontrols, widgets and interconnection map for some
of
the TWL4030 ASOC codec I was building it for a custom board as it was for OVERO
Suggestions on the DAPM part of the driver would be helpful
Thanks in advance.
The patch is as follows. I need suggestions on the DAPM part of the driver.
Thanks and Regards,
(: Naveen Krishna Ch :) _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
participants (4)
-
Mark Brown
-
naveen krishna ch
-
Peter Ujfalusi
-
Steve Sakoman