[alsa-devel] ASoC: Hooking a TI CODEC to a i.MX27 MCU

Mark Brown broonie at opensource.wolfsonmicro.com
Thu Jun 3 13:14:56 CEST 2010


On Tue, Jun 01, 2010 at 09:32:38PM +1000, Stuart Longland wrote:

I know this isn't a proper submission but a few comments below.  This
looks like it'd be relatively easy to get submitted by stripping out a
lot of the commented out code and custom interfaces (like the DA7210
driver).

> The CODEC driver claims total control of the I2C device, and therefore
> makes it impossible to alter registers using i2c-tools.  However, as a
> work-around; I have provided read/write access to the registers via
> sysfs... we use the AIC3204 attached to I2C bus 0; the CODEC therefore
> lives under:

> 	/sys/bus/i2c/devices/0-0018

> There are two files:
> 	- regsel:	Takes or reports back the 16-bit register
> 			address in hexadecimal
> 	- regdata:	Reads or writes the value of the register

ASoC already provides register read/write access via debugfs as
standard, there's no need to implement this.

> struct aic3204_setup_data {
> 	unsigned int gpio_func[2];
> };

This would normally be platform data in a file in include/sound so it
can be set by the architecture code when the device is registered.

> /* TODO: PLL */
> /* #define ENABLE_PLL */

> /* SYSFS Interface -- we should move this to debugfs */
> static ssize_t aic3204_show_regsel(struct device *dev,
> 		struct device_attribute *attr, char *buf);
> static ssize_t aic3204_store_regsel(struct device *dev,
> 		struct device_attribute *attr, const char *buf, size_t count);
> static ssize_t aic3204_show_regdata(struct device *dev,
> 		struct device_attribute *attr, char *buf);
> static ssize_t aic3204_store_regdata(struct device *dev,
> 		struct device_attribute *attr, const char *buf, size_t count);
> static DEVICE_ATTR(regsel, S_IWUSR | S_IRUGO,
> 		aic3204_show_regsel, aic3204_store_regsel);
> static DEVICE_ATTR(regdata, S_IWUSR | S_IRUGO,
> 		aic3204_show_regdata, aic3204_store_regdata);

As I said above this is redundant and can be removed.

> #if 0
> 	printk( KERN_INFO "%s: pg %d reg %d[%04x] => %02x\n",
> 			__func__, reg >> 8, reg & 0xff, reg, value[0] );
> #endif

dev_dbg().

> }
> 
> /*
>  * Perform a read/modify/write cycle on a register.
>  *
>  * This is a shorthand function, it reads the specified register, masks out the
>  * bits in and_mask, applies bits in or_mask, then writes out the result to the
>  * register.
>  *
>  * It returns the modified value; or a negative error code.
>  */

There's a standard snd_soc_update_bits() function in ASoC.

> /*
>  * All input lines are connected when !0xf and disconnected with 0xf bit field,
>  * so we have to use specific dapm_put call for input mixer
>  */

Could you explain in more detial what this is doing?  I'm not
immediately seeing what this is doing but I suspect it might be a value
mux?

> #if 0

Just drop if 0ed sections.

> #define LDAC_ENUM	0
> #define RDAC_ENUM	1
> #define LHPCOM_ENUM	2
> #define RHPCOM_ENUM	3
> #define LINE1L_ENUM	4
> #define LINE1R_ENUM	5
> #define LINE2L_ENUM	6
> #define LINE2R_ENUM	7
> #define ADC_HPF_ENUM	8
> 
> static const struct soc_enum aic3204_enum[] = {
> 	SOC_ENUM_SINGLE(DAC_LINE_MUX, 6, 3, aic3204_left_dac_mux),

Use individually named variables rather than a table for legibility.

> 	/* Turn on ADC or DAC */
> 	if ( substream->stream == SNDRV_PCM_STREAM_PLAYBACK ) {
> 		aic3204_write(codec, AIC3204_DACS1,
> 				AIC3204_DACS1_LDAC_UP |
> 				AIC3204_DACS1_RDAC_UP |
> 				AIC3204_DACS1_LDACD_LEFT |
> 				AIC3204_DACS1_RDACD_RIGHT |
> 				AIC3204_DACS1_SOFT_DIS );

DAPM ought to be figuring this out for you...

> 	/* This all needs to be done elsewhere */

Yes.

> void aic3204_set_headset_detection(struct snd_soc_codec *codec, int detect,
> 				 int headset_debounce, int button_debounce)
> {
> #if 0

There's standard ASoC jack detection which this should integrate with.

> #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
> /*
>  * AIC3204 2 wire address can be up to 4 devices with device addresses
>  * 0x18, 0x19, 0x1A, 0x1B
>  */
> 
> /*
>  * If the i2c layer weren't so broken, we could pass this kind of data
>  * around
>  */
> static int aic3204_i2c_probe(struct i2c_client *i2c,
> 			   const struct i2c_device_id *id)

Use standard device model registration - the driver you were basing this
on has been converted now...


More information about the Alsa-devel mailing list