Fixed and tested hwdep device and documentation about it.
authormnzaki <mnzaki@gmail.com>
Sat, 11 Sep 2010 13:45:37 +0000 (16:45 +0300)
committermnzaki <mnzaki@gmail.com>
Sat, 11 Sep 2010 13:45:37 +0000 (16:45 +0300)
Now it actually works, and the documentation is accurate. Also
very close to removing the warning at the top.

kernel-2.6.28/Documentation/sound/alsa/soc/tlv320aic3x.txt
kernel-2.6.28/sound/soc/codecs/tlv320aic3x.c

index ec748f2..c82cb3b 100644 (file)
@@ -1,3 +1,6 @@
+WARNING: THINGS DESCRIBED BELOW ARE NOT YET IN THE REPOS. THEY WILL BE, 
+VERY SOON.
+
 The TLV320AIC3X is a powerful four channel low power audio codec family.
 More information is available at:
     http://focus.ti.com/docs/prod/folders/print/tlv320aic34.html
 The TLV320AIC3X is a powerful four channel low power audio codec family.
 More information is available at:
     http://focus.ti.com/docs/prod/folders/print/tlv320aic34.html
@@ -22,38 +25,51 @@ The IIR Filter consists of 2 cascaded biquads. The formula is:
  /                                \  /                                \
 |    (N0 + 2*N1*z^-1 + N2*z^-2)    ||    (N3 + 2*N4*z^-1 + N5*z^-2)    |
 |  ------------------------------  ||  ------------------------------  |
  /                                \  /                                \
 |    (N0 + 2*N1*z^-1 + N2*z^-2)    ||    (N3 + 2*N4*z^-1 + N5*z^-2)    |
 |  ------------------------------  ||  ------------------------------  |
- \ (32768 - 2*D1*z^-1 - D2*z^-2)  /  \ (32768 - 2*D4*z^-1 - D5*z^-2)  /
+|  (32768 - 2*D1*z^-1 - D2*z^-2)   ||   (32768 - 2*D4*z^-1 - D5*z^-2)  |
+\                                 /  \                                /
 
 The filter can be controlled through an alsa hwdep device, via 
 
 The filter can be controlled through an alsa hwdep device, via 
-libalsa. A short example follows, note that the data struct must be
-passed *EXACTLY* as shown:
+libasound. A short example follows, note that the data struct must be
+passed *EXACTLY* as shown. Remember to link against libasound:
+gcc myapp.c -lasound -o myapp
 
 
+-------------------------------EXAMPLE----------------------------------
 #include <stdint.h>
 #include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <alsa/asoundlib.h>
 #include <alsa/hwdep.h>
 
 #include <alsa/hwdep.h>
 
-struct _iirfilter_data {
+struct iirfilter_data {
     int16_t N0, N1, N2, D1, D2;
     int16_t N3, N4, N5, D4, D5;
     int16_t N0, N1, N2, D1, D2;
     int16_t N3, N4, N5, D4, D5;
-} iirfilter_data;
+};
 
 
-/* Initialize */
-snd_hwdep *hwdep;
+int main() {
+    int ret;
+    snd_hwdep_t *hwdep;
+    struct iirfilter_data data = {
+           .N0 = 27619, .N1 = -27034, .N2 = 26461, .D1 = 32131, .D2 = -31506,
+        .N3 = 27619, .N4 = -27034, .N5 = 26461, .D4 = 32131, .D5 = -31506
+    };
 
 
-snd_hwdep_open(&hwdep, "IIR Filter", "w");
+/* Initialize */
+    ret = snd_hwdep_open(&hwdep, "hw:0,0", SND_HWDEP_OPEN_DUPLEX);
+    if(ret != 0) exit(1);
 
 /* To write: */
 
 /* To write: */
-iirfilter_data = {
-       .N0 = 27619, .N1 = -27034, .N2 = 26461, .D1 = 32131, .D2 = -31506,
-    .N3 = 27619, .N4 = -27034, .N5 = 26461, .D4 = 32131, .D5 = -31506
-};
-
-snd_hwdep_write(hwdep, (void*)iirfilter_data, sizeof(iirfilter_data));
+    snd_hwdep_write(hwdep, (void*)&data, sizeof(data));
 
 /* To read: */
 
 /* To read: */
-snd_hwdep_read(hwdep, (void*)iirfilter_data, sizeof(iirfilter_data));
+    snd_hwdep_read(hwdep, (void*)&data, sizeof(data));
 
 /* To enable/disable filtering: */
 
 /* To enable/disable filtering: */
-int arg = 1; /* 1 = enable, 0 = disable */
-snd_hwdep_ioctl(hwdep, 1, &arg);
+    int arg = 1; /* 1 = enable, 0 = disable */
+    snd_hwdep_ioctl(hwdep, 1, &arg);
+    return 0;
+}
+------------------------------------------------------------------------
+
 
 
 
 
index 20747a6..22e432a 100644 (file)
@@ -184,14 +184,15 @@ static int aic3x_write(struct snd_soc_codec *codec,
 {
        static char curpage = -1;
        u8 data[2], page = 0;
 {
        static char curpage = -1;
        u8 data[2], page = 0;
-    printk("MNZ: aic3x_write(reg = %i, val = %x), curpage = %i\n",
-    reg, value, curpage);
+
        /*mutex_lock(&codec->mutex);*/
        
        if (reg > 127){
                reg -= 128;
                page = 1;
        }
        /*mutex_lock(&codec->mutex);*/
        
        if (reg > 127){
                reg -= 128;
                page = 1;
        }
+    printk("MNZ: aic3x_write(reg = %i, val = 0x%x, page = %i)\n",
+    reg, value, page);
        if(reg && curpage != page){
                data[0] = 0;
                data[1] = page;
        if(reg && curpage != page){
                data[0] = 0;
                data[1] = page;
@@ -201,7 +202,6 @@ static int aic3x_write(struct snd_soc_codec *codec,
                } else {
                        curpage = page;
                }
                } else {
                        curpage = page;
                }
-        printk("MNZ: aic3x_write(), switched to page%i\n", curpage);
        }
 
 
        }
 
 
@@ -375,7 +375,7 @@ static const char *aic3x_linein_mode_mux[] = { "single-ended", "differential" };
 static const char *aic3x_adc_hpf[] =
     { "Disabled", "0.0045xFs", "0.0125xFs", "0.025xFs" };
 static const char *aic3x_dac_filt[] =
 static const char *aic3x_adc_hpf[] =
     { "Disabled", "0.0045xFs", "0.0125xFs", "0.025xFs" };
 static const char *aic3x_dac_filt[] =
-       { "Off", "On", "Custom" };
+       { "Off", "Bass/Treble", "Custom" };
 
 #define LDAC_ENUM      0
 #define RDAC_ENUM      1
 
 #define LDAC_ENUM      0
 #define RDAC_ENUM      1
@@ -495,7 +495,6 @@ static int aic3x_dacfilter_set_state(struct snd_soc_codec *codec,
                int state)
 {
        struct aic3x_priv *aic3x = codec->private_data;
                int state)
 {
        struct aic3x_priv *aic3x = codec->private_data;
-       printk("MNZ: dacfilter_set_state(state = %i)\n", state);
 
        if(aic3x->dacfilter.state == state) return 0;
        
 
        if(aic3x->dacfilter.state == state) return 0;
        
@@ -514,6 +513,12 @@ static int aic3x_dacfilter_set_state(struct snd_soc_codec *codec,
 
 /* DAC Filter hwdep device callbacks */
 
 
 /* DAC Filter hwdep device callbacks */
 
+static int snd_hwdep_dacfilter_open_aic3x(struct snd_hwdep *hw,
+       struct file *file)
+{
+       return 0;
+}
+
 static int snd_hwdep_dacfilter_ioctl_aic3x(struct snd_hwdep *hw,
        struct file *file, unsigned int cmd, unsigned long arg)
 {
 static int snd_hwdep_dacfilter_ioctl_aic3x(struct snd_hwdep *hw,
        struct file *file, unsigned int cmd, unsigned long arg)
 {
@@ -555,7 +560,6 @@ static int snd_soc_get_dacfilter_aic3x(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
        struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-printk("MNZ: get_dacfilter getting state: %i\n",((struct aic3x_priv*)codec->private_data)->dacfilter.state );  
        ucontrol->value.enumerated.item[0] = 
                ((struct aic3x_priv*)codec->private_data)->dacfilter.state;
        return 0;
        ucontrol->value.enumerated.item[0] = 
                ((struct aic3x_priv*)codec->private_data)->dacfilter.state;
        return 0;
@@ -565,7 +569,6 @@ static int snd_soc_put_dacfilter_aic3x(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
        struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-       printk("MNZ: put_dacfilter setting to %i\n", ucontrol->value.enumerated.item[0]);
        if (ucontrol->value.enumerated.item[0] > 2)
                return -EINVAL;
        aic3x_dacfilter_set_state(codec, ucontrol->value.enumerated.item[0]);
        if (ucontrol->value.enumerated.item[0] > 2)
                return -EINVAL;
        aic3x_dacfilter_set_state(codec, ucontrol->value.enumerated.item[0]);
@@ -1506,6 +1509,8 @@ static int aic3x_init(struct snd_soc_device *socdev)
 {
        struct snd_soc_codec *codec = socdev->codec;
        struct aic3x_setup_data *setup = socdev->codec_data;
 {
        struct snd_soc_codec *codec = socdev->codec;
        struct aic3x_setup_data *setup = socdev->codec_data;
+       struct snd_hwdep *hwdep;
+    char hwdepid[] = "IIR Filter";
        int reg, ret = 0;
 
        codec->name = "tlv320aic3x";
        int reg, ret = 0;
 
        codec->name = "tlv320aic3x";
@@ -1602,7 +1607,19 @@ static int aic3x_init(struct snd_soc_device *socdev)
 
        aic3x_add_controls(codec);
        aic3x_add_widgets(codec);
 
        aic3x_add_controls(codec);
        aic3x_add_widgets(codec);
+
+       if(snd_hwdep_new(codec->card, hwdepid, 0, &hwdep) == 0){
+               hwdep->private_data = codec;
+               sprintf(hwdep->name, hwdepid);
+               hwdep->ops.open = snd_hwdep_dacfilter_open_aic3x;
+               hwdep->ops.ioctl = snd_hwdep_dacfilter_ioctl_aic3x;
+               hwdep->ops.read = snd_hwdep_dacfilter_read_aic3x;
+               hwdep->ops.write = snd_hwdep_dacfilter_write_aic3x;
+               ((struct aic3x_priv*)codec->private_data)->hwdep = hwdep;
+       }
+
        ret = snd_soc_register_card(socdev);
        ret = snd_soc_register_card(socdev);
+
        if (ret < 0) {
                printk(KERN_ERR "aic3x: failed to register card\n");
                goto card_err;
        if (ret < 0) {
                printk(KERN_ERR "aic3x: failed to register card\n");
                goto card_err;
@@ -1726,7 +1743,6 @@ static int aic3x_probe(struct platform_device *pdev)
        struct aic3x_setup_data *setup;
        struct snd_soc_codec *codec;
        struct aic3x_priv *aic3x;
        struct aic3x_setup_data *setup;
        struct snd_soc_codec *codec;
        struct aic3x_priv *aic3x;
-       struct snd_hwdep *hwdep;
        int ret = 0;
 
        printk(KERN_INFO "AIC3X Audio Codec %s\n", AIC3X_VERSION);
        int ret = 0;
 
        printk(KERN_INFO "AIC3X Audio Codec %s\n", AIC3X_VERSION);
@@ -1761,15 +1777,6 @@ static int aic3x_probe(struct platform_device *pdev)
        /* Add other interfaces here */
 #endif
 
        /* Add other interfaces here */
 #endif
 
-       if(snd_hwdep_new(codec->card, "IIR Filter", 0, &hwdep) == 0){
-               printk("MNZ: hwdep initialized\n");
-        hwdep->private_data = codec;
-               hwdep->ops.ioctl = snd_hwdep_dacfilter_ioctl_aic3x;
-               hwdep->ops.read = snd_hwdep_dacfilter_read_aic3x;
-               hwdep->ops.write = snd_hwdep_dacfilter_write_aic3x;
-               aic3x->hwdep = hwdep;
-       }
-       
        if (ret != 0) {
                kfree(codec->private_data);
                kfree(codec);
        if (ret != 0) {
                kfree(codec->private_data);
                kfree(codec);