From: mnzaki Date: Sat, 11 Sep 2010 13:45:37 +0000 (+0300) Subject: Fixed and tested hwdep device and documentation about it. X-Git-Url: http://git.maemo.org/git/?p=aic34-eq;a=commitdiff_plain;h=b5b52432c643decdd96e02b009c150d309cb741e Fixed and tested hwdep device and documentation about it. Now it actually works, and the documentation is accurate. Also very close to removing the warning at the top. --- diff --git a/kernel-2.6.28/Documentation/sound/alsa/soc/tlv320aic3x.txt b/kernel-2.6.28/Documentation/sound/alsa/soc/tlv320aic3x.txt index ec748f2..c82cb3b 100644 --- a/kernel-2.6.28/Documentation/sound/alsa/soc/tlv320aic3x.txt +++ b/kernel-2.6.28/Documentation/sound/alsa/soc/tlv320aic3x.txt @@ -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 @@ -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) | | ------------------------------ || ------------------------------ | - \ (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 -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 +#include +#include +#include +#include #include -struct _iirfilter_data { +struct iirfilter_data { 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: */ -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: */ -snd_hwdep_read(hwdep, (void*)iirfilter_data, sizeof(iirfilter_data)); + snd_hwdep_read(hwdep, (void*)&data, sizeof(data)); /* 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; +} +------------------------------------------------------------------------ + diff --git a/kernel-2.6.28/sound/soc/codecs/tlv320aic3x.c b/kernel-2.6.28/sound/soc/codecs/tlv320aic3x.c index 20747a6..22e432a 100644 --- a/kernel-2.6.28/sound/soc/codecs/tlv320aic3x.c +++ b/kernel-2.6.28/sound/soc/codecs/tlv320aic3x.c @@ -184,14 +184,15 @@ static int aic3x_write(struct snd_soc_codec *codec, { 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; } + 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; @@ -201,7 +202,6 @@ static int aic3x_write(struct snd_soc_codec *codec, } 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[] = - { "Off", "On", "Custom" }; + { "Off", "Bass/Treble", "Custom" }; #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; - printk("MNZ: dacfilter_set_state(state = %i)\n", state); 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 */ +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) { @@ -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); -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; @@ -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); - 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]); @@ -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_hwdep *hwdep; + char hwdepid[] = "IIR Filter"; 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); + + 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); + 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 snd_hwdep *hwdep; 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 - 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);