All of lore.kernel.org
 help / color / mirror / Atom feed
* twl4030 asoc kcontrols and widgets
@ 2008-11-20  9:38 naveen krishna ch
  2008-11-20 10:52 ` Mark Brown
  2008-11-20 14:02 ` Peter Ujfalusi
  0 siblings, 2 replies; 13+ messages in thread
From: naveen krishna ch @ 2008-11-20  9:38 UTC (permalink / raw)
  To: alsa-devel

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 :)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: twl4030 asoc kcontrols and widgets
  2008-11-20  9:38 twl4030 asoc kcontrols and widgets naveen krishna ch
@ 2008-11-20 10:52 ` Mark Brown
  2008-11-20 14:02 ` Peter Ujfalusi
  1 sibling, 0 replies; 13+ messages in thread
From: Mark Brown @ 2008-11-20 10:52 UTC (permalink / raw)
  To: naveen krishna ch; +Cc: alsa-devel, Steve Sakoman

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.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: TWL4030 asoc kcontrols and widgets
       [not found] <ef0d8a250811200202o5852dabct8c5b135b86141f67@mail.gmail.com>
@ 2008-11-20 10:55 ` Felipe Balbi
  2008-11-20 17:32   ` Tony Lindgren
  0 siblings, 1 reply; 13+ messages in thread
From: Felipe Balbi @ 2008-11-20 10:55 UTC (permalink / raw)
  To: naveen krishna ch; +Cc: linux-omap-open-source, linux-omap, Tony Lindgren

This list has been moved to linux-omap@vger.kernel.org

Please, keep that in Cc, also for ASoC development, send it also to the
proper alsa mailing list alsa-devel@alsa-project.org

Tony, I think you should apply this patch in mainline tree:

diff --git a/MAINTAINERS b/MAINTAINERS
index 8dae455..54c8e90 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4010,6 +4010,13 @@ P:       Alex Dubov
 M:     oakad@yahoo.com
 S:     Maintained

+TI OMAP
+P:     Tony Lindgren
+M:     tony@atomide.com
+L:     linux-omap@vger.kernel.org
+T:     git kernel.org:/pub/scm/linux/tmlind/linux-omap-2.6.git
+S:     Maintained
+
 TI OMAP MMC INTERFACE DRIVER
 P:     Carlos Aguiar, Anderson Briglia and Syed Khasim
 M:     linux-omap@vger.kernel.org


On Thu, Nov 20, 2008 at 12:02 PM, naveen krishna ch
<naveenkrishna.ch@gmail.com> wrote:
> Hi All
>
> 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..
>
> Thanks and Regards,
>
> (: Naveen Krishna Ch :)
> _______________________________________________
> Linux-omap-open-source mailing list
> Linux-omap-open-source@linux.omap.com
> http://linux.omap.com/mailman/listinfo/linux-omap-open-source
>



-- 
Best Regards,

Felipe Balbi
felipebalbi@users.sourceforge.net

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: twl4030 asoc kcontrols and widgets
  2008-11-20  9:38 twl4030 asoc kcontrols and widgets naveen krishna ch
  2008-11-20 10:52 ` Mark Brown
@ 2008-11-20 14:02 ` Peter Ujfalusi
  2008-11-20 14:14   ` Mark Brown
  2008-11-20 14:17   ` naveen krishna ch
  1 sibling, 2 replies; 13+ messages in thread
From: Peter Ujfalusi @ 2008-11-20 14:02 UTC (permalink / raw)
  To: alsa-devel; +Cc: ext naveen krishna ch, Steve Sakoman

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?

-- 
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
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: twl4030 asoc kcontrols and widgets
  2008-11-20 14:02 ` Peter Ujfalusi
@ 2008-11-20 14:14   ` Mark Brown
  2008-11-20 15:39     ` Steve Sakoman
  2008-11-20 14:17   ` naveen krishna ch
  1 sibling, 1 reply; 13+ messages in thread
From: Mark Brown @ 2008-11-20 14:14 UTC (permalink / raw)
  To: Peter Ujfalusi; +Cc: ext naveen krishna ch, alsa-devel, Steve Sakoman

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.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: twl4030 asoc kcontrols and widgets
  2008-11-20 14:02 ` Peter Ujfalusi
  2008-11-20 14:14   ` Mark Brown
@ 2008-11-20 14:17   ` naveen krishna ch
  1 sibling, 0 replies; 13+ messages in thread
From: naveen krishna ch @ 2008-11-20 14:17 UTC (permalink / raw)
  To: Peter Ujfalusi; +Cc: alsa-devel, Steve Sakoman

On Thu, Nov 20, 2008 at 7:32 PM, Peter Ujfalusi <peter.ujfalusi@nokia.com>wrote:

> 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
> >
>



-- 
Thanks,
keep smiling...
keep winning...

(: Naveen Krishna Ch :)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: twl4030 asoc kcontrols and widgets
  2008-11-20 14:14   ` Mark Brown
@ 2008-11-20 15:39     ` Steve Sakoman
  2008-11-21  9:49       ` Peter Ujfalusi
  0 siblings, 1 reply; 13+ messages in thread
From: Steve Sakoman @ 2008-11-20 15:39 UTC (permalink / raw)
  To: Mark Brown
  Cc: ext naveen krishna ch, alsa-devel, Peter Ujfalusi, Steve Sakoman

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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: TWL4030 asoc kcontrols and widgets
  2008-11-20 10:55 ` TWL4030 asoc kcontrols and widgets Felipe Balbi
@ 2008-11-20 17:32   ` Tony Lindgren
  2008-11-20 17:42     ` Felipe Balbi
  0 siblings, 1 reply; 13+ messages in thread
From: Tony Lindgren @ 2008-11-20 17:32 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: naveen krishna ch, linux-omap-open-source, linux-omap

* Felipe Balbi <felipebalbi@users.sourceforge.net> [081120 02:55]:
> This list has been moved to linux-omap@vger.kernel.org
> 
> Please, keep that in Cc, also for ASoC development, send it also to the
> proper alsa mailing list alsa-devel@alsa-project.org
> 
> Tony, I think you should apply this patch in mainline tree:
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8dae455..54c8e90 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4010,6 +4010,13 @@ P:       Alex Dubov
>  M:     oakad@yahoo.com
>  S:     Maintained
> 
> +TI OMAP
> +P:     Tony Lindgren
> +M:     tony@atomide.com
> +L:     linux-omap@vger.kernel.org
> +T:     git kernel.org:/pub/scm/linux/tmlind/linux-omap-2.6.git
> +S:     Maintained
> +
>  TI OMAP MMC INTERFACE DRIVER
>  P:     Carlos Aguiar, Anderson Briglia and Syed Khasim
>  M:     linux-omap@vger.kernel.org


Yeah sure. Let's also add maintainers for omap subsystems that have
maintainers while we're at it.

Tony


> 
> 
> On Thu, Nov 20, 2008 at 12:02 PM, naveen krishna ch
> <naveenkrishna.ch@gmail.com> wrote:
> > Hi All
> >
> > 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..
> >
> > Thanks and Regards,
> >
> > (: Naveen Krishna Ch :)
> > _______________________________________________
> > Linux-omap-open-source mailing list
> > Linux-omap-open-source@linux.omap.com
> > http://linux.omap.com/mailman/listinfo/linux-omap-open-source
> >
> 
> 
> 
> -- 
> Best Regards,
> 
> Felipe Balbi
> felipebalbi@users.sourceforge.net

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: TWL4030 asoc kcontrols and widgets
  2008-11-20 17:32   ` Tony Lindgren
@ 2008-11-20 17:42     ` Felipe Balbi
  2008-11-20 18:56       ` (non-hs)mmc vs lockdep David Brownell
  0 siblings, 1 reply; 13+ messages in thread
From: Felipe Balbi @ 2008-11-20 17:42 UTC (permalink / raw)
  To: ext Tony Lindgren
  Cc: Felipe Balbi, naveen krishna ch, linux-omap-open-source,
	linux-omap

On Thu, Nov 20, 2008 at 09:32:07AM -0800, Tony Lindgren wrote:
> * Felipe Balbi <felipebalbi@users.sourceforge.net> [081120 02:55]:
> > This list has been moved to linux-omap@vger.kernel.org
> > 
> > Please, keep that in Cc, also for ASoC development, send it also to the
> > proper alsa mailing list alsa-devel@alsa-project.org
> > 
> > Tony, I think you should apply this patch in mainline tree:
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 8dae455..54c8e90 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -4010,6 +4010,13 @@ P:       Alex Dubov
> >  M:     oakad@yahoo.com
> >  S:     Maintained
> > 
> > +TI OMAP
> > +P:     Tony Lindgren
> > +M:     tony@atomide.com
> > +L:     linux-omap@vger.kernel.org
> > +T:     git kernel.org:/pub/scm/linux/tmlind/linux-omap-2.6.git
> > +S:     Maintained
> > +
> >  TI OMAP MMC INTERFACE DRIVER
> >  P:     Carlos Aguiar, Anderson Briglia and Syed Khasim
> >  M:     linux-omap@vger.kernel.org
> 
> 
> Yeah sure. Let's also add maintainers for omap subsystems that have
> maintainers while we're at it.

sounds good. At least mmc is already there.

-- 
balbi

^ permalink raw reply	[flat|nested] 13+ messages in thread

* (non-hs)mmc vs lockdep
  2008-11-20 17:42     ` Felipe Balbi
@ 2008-11-20 18:56       ` David Brownell
  2008-11-20 19:10         ` Felipe Balbi
  0 siblings, 1 reply; 13+ messages in thread
From: David Brownell @ 2008-11-20 18:56 UTC (permalink / raw)
  To: linux-omap

On Thursday 20 November 2008, Felipe Balbi wrote:
> > >  TI OMAP MMC INTERFACE DRIVER
> > >  P:     Carlos Aguiar, Anderson Briglia and Syed Khasim
> > >  M:     linux-omap@vger.kernel.org
> > 
> > 
> > Yeah sure. Let's also add maintainers for omap subsystems that have
> > maintainers while we're at it.
> 
> sounds good. At least mmc is already there.

So, who's going to fix the bug with the non-highspeed MMC controller
driver whereby it breaks with LOCKDEP enabled?

The "BUG_ON(irqs_disabled());" in mmc_omap_start_request() triggers,
since something inside the latest ARM MM code assumes it's never called
with IRQs blocked ... a regression was introduced at some point.  The
same failure is seen in some other MMC controller drivers.

- Dave


--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: (non-hs)mmc vs lockdep
  2008-11-20 18:56       ` (non-hs)mmc vs lockdep David Brownell
@ 2008-11-20 19:10         ` Felipe Balbi
  0 siblings, 0 replies; 13+ messages in thread
From: Felipe Balbi @ 2008-11-20 19:10 UTC (permalink / raw)
  To: David Brownell; +Cc: linux-omap

On Thu, Nov 20, 2008 at 10:56:28AM -0800, David Brownell wrote:
> On Thursday 20 November 2008, Felipe Balbi wrote:
> > > >  TI OMAP MMC INTERFACE DRIVER
> > > >  P:     Carlos Aguiar, Anderson Briglia and Syed Khasim
> > > >  M:     linux-omap@vger.kernel.org
> > > 
> > > 
> > > Yeah sure. Let's also add maintainers for omap subsystems that have
> > > maintainers while we're at it.
> > 
> > sounds good. At least mmc is already there.
> 
> So, who's going to fix the bug with the non-highspeed MMC controller
> driver whereby it breaks with LOCKDEP enabled?
> 
> The "BUG_ON(irqs_disabled());" in mmc_omap_start_request() triggers,
> since something inside the latest ARM MM code assumes it's never called
> with IRQs blocked ... a regression was introduced at some point.  The
> same failure is seen in some other MMC controller drivers.

Well, I haven't seen patches from none of the three maintainers for
quite a while. Maybe someone at TI could take over the driver(s) ??

-- 
balbi
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: twl4030 asoc kcontrols and widgets
  2008-11-20 15:39     ` Steve Sakoman
@ 2008-11-21  9:49       ` Peter Ujfalusi
  2008-11-21 15:49         ` Mark Brown
  0 siblings, 1 reply; 13+ messages in thread
From: Peter Ujfalusi @ 2008-11-21  9:49 UTC (permalink / raw)
  To: ext Steve Sakoman
  Cc: ext naveen krishna ch, alsa-devel, Mark Brown, Steve Sakoman

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?

-- 
Péter

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: twl4030 asoc kcontrols and widgets
  2008-11-21  9:49       ` Peter Ujfalusi
@ 2008-11-21 15:49         ` Mark Brown
  0 siblings, 0 replies; 13+ messages in thread
From: Mark Brown @ 2008-11-21 15:49 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: ext Steve Sakoman, ext naveen krishna ch, alsa-devel,
	Steve Sakoman

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.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2008-11-21 15:49 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <ef0d8a250811200202o5852dabct8c5b135b86141f67@mail.gmail.com>
2008-11-20 10:55 ` TWL4030 asoc kcontrols and widgets Felipe Balbi
2008-11-20 17:32   ` Tony Lindgren
2008-11-20 17:42     ` Felipe Balbi
2008-11-20 18:56       ` (non-hs)mmc vs lockdep David Brownell
2008-11-20 19:10         ` Felipe Balbi
2008-11-20  9:38 twl4030 asoc kcontrols and widgets naveen krishna ch
2008-11-20 10:52 ` Mark Brown
2008-11-20 14:02 ` Peter Ujfalusi
2008-11-20 14:14   ` Mark Brown
2008-11-20 15:39     ` Steve Sakoman
2008-11-21  9:49       ` Peter Ujfalusi
2008-11-21 15:49         ` Mark Brown
2008-11-20 14:17   ` naveen krishna ch

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.