[alsa-devel] [PATCH] ALSA SOC driver for s3c24xx with uda1341

Kristoffer Ericson kristoffer.ericson at gmail.com
Mon Nov 10 18:58:00 CET 2008


On Mon, 10 Nov 2008 13:34:52 +0000
Mark Brown <broonie at sirena.org.uk> wrote:

> On Sat, Nov 08, 2008 at 08:43:55AM +0100, Christian Pellegrin wrote:
> 
> > This patch adds support for the UDA1341 codec and a sound card
> > definition for one of these UDAs connected to the s3c24xx. It is
> 
> First up, thanks for doing this work - it'd be good to see this merged
> into ASoC.
> 

I'm equally interested in this patch, seeing as I
got an hp jornada 7xx with uda1344 waiting.

Have you any plans on creating an 134x seeing as there
is very little difference between chipsets?

> > *heavily* based on the one made by Zoltan Devai but:
> 
> Ideally this should be submitted as multiple patches - at least one for
> the codec and one for the board, probably also one for the l3 interface.
> 
> > Generated on  20081108  against v2.6.27
> 
> Please generate patches against current git - the topic/asoc branch of:
> 
> 	git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git
> 
> In general, once the merge window is past it's best to submit patches
> against at least -rc1, submitting against the previous release makes it
> much more likely that your patch will be out of date as has happened
> here.
> 
> > +++ b/sound/soc/codecs/Kconfig
> > @@ -50,3 +50,6 @@ config SND_SOC_CS4270_VD33_ERRATA
> >  config SND_SOC_TLV320AIC3X
> >  	tristate
> >  	depends on I2C
> > +
> > +config SND_SOC_UDA1341
> > +	tristate
> 
> You should also add this to SND_SOC_ALL_CODECS.  There's a bunch of
> other things like this that have changed between 2.6.27 and the current
> code - for example, the bias level configuration.
> 
> > diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
> > index d7b97ab..cbace60 100644
> > --- a/sound/soc/codecs/Makefile
> > +++ b/sound/soc/codecs/Makefile
> > @@ -23,3 +23,4 @@ obj-$(CONFIG_SND_SOC_WM9712)	+= snd-soc-wm9712.o
> >  obj-$(CONFIG_SND_SOC_WM9713)	+= snd-soc-wm9713.o
> >  obj-$(CONFIG_SND_SOC_CS4270)	+= snd-soc-cs4270.o
> >  obj-$(CONFIG_SND_SOC_TLV320AIC3X)	+= snd-soc-tlv320aic3x.o
> > +obj-$(CONFIG_SND_SOC_UDA1341)	+= uda1341/
> 
> There doesn't seem to be much benefit to adding a subdirectory for two
> source files here.
> 
> > --- /dev/null
> > +++ b/sound/soc/codecs/uda1341/l3.c
> 
> > +/*#define L3_DEBUG 1*/
> > +#ifdef L3_DEBUG
> > +#define DBG(format, arg...) \
> > +	printk(KERN_DEBUG "L3: %s:" format "\n" , __func__, ## arg)
> > +#else
> > +#define DBG(format, arg...) do {} while (0)
> > +#endif
> 
> Please use the standard pr_debug() macro rather than defining custom
> ones.
> 
> > +#define setdat(adap, val)	(adap->setdat(adap, val))
> > +#define setclk(adap, val)	(adap->setclk(adap, val))
> > +#define setmode(adap, val)	(adap->setmode(adap, val))
> 
> These should be inline functions for type safety.
> 
> > +/*#define UDA1341_DEBUG 1*/
> > +#ifdef UDA1341_DEBUG
> > +#define DBG(format, arg...) \
> > +	printk(KERN_DEBUG "UDA1341: %s:" format "\n" , __func__, ## arg)
> > +#else
> > +#define DBG(format, arg...) do {} while (0)
> > +#endif
> 
> Please use the standard pr_debug() macro.
> 
> > +static int uda1341_write(struct snd_soc_codec *codec, unsigned int reg,
> > +	unsigned int value)
> > +{
> > +	int ret;
> > +	u8 addr;
> > +	u8 data = value;
> > +
> > +	DBG("reg: %02X, value:%02X", reg, value);
> > +
> > +	if (reg >= UDA1341_REGS_NUM) {
> > +		DBG("Unkown register: reg: %d", reg);
> > +		return -EINVAL;
> > +	}
> 
> That should probably print the error unconditionally.
> 
> > +static int uda1341_hw_params(struct snd_pcm_substream *substream,
> > +	struct snd_pcm_hw_params *params)
> > +{
> 
> > +	/* set SYSCLK / fs ratio */
> > +	switch (uda1341->sysclk / params_rate(params)) {
> 
> > +	default:
> > +		return -EINVAL;
> > +		break;
> > +	}
> 
> No need for the break here.  It's probably best to log an explicit error
> saying why the failure occurred - otherwise it'll be a bit obscure to
> users what's going on.  A similar comment applies to the other error
> cases.
> 
> > +static int uda1341_set_dai_sysclk(struct snd_soc_dai *codec_dai,
> > +				  int clk_id, unsigned int freq, int dir)
> > +{
> 
> > +	/* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
> > +	we'll error out on set_hw_params if it's not OK */
> 
> This implies rather more flexibility than actually exists - hw_params()
> requires an exact multiplier here.  You should probably add a note
> explaining that it's up to the machine driver to make sure that the rate
> is OK.
> 
> > +SOC_SINGLE("Channel 1 mixer gain", UDA1341_EA000, 0, 0x1F, 1),
> > +SOC_SINGLE("Channgel 2 mixer gain", UDA1341_EA001, 0, 0x1F, 1),
> 
> There's a typo here.  Also, this and many of the other control names
> don't fit in with the ALSA control name spec so won't be displayed
> correctly by applications.  For example, these should be "Volume" rather
> than "gain", and "switch" should be "Switch".  There's documentation of
> the standard
> names in:
> 
> 	Documentation/sound/alsa/ControlNames.txt
> 
> > +SOC_SINGLE("DAC Gain switch", UDA1341_STATUS1, 6, 1, 0),
> > +SOC_SINGLE("ADC Gain switch", UDA1341_STATUS1, 5, 1, 0),
> 
> What exactly do these controls do?  "Gain switch" sounds wrong - I'd not
> expect the gain to be a boolean.
> 
> > +static int uda1341_soc_suspend(struct platform_device *pdev,
> > +						pm_message_t state)
> > +{
> > +	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
> > +	struct snd_soc_codec *codec = socdev->codec;
> > +	struct uda1341_platform_data *pd;
> > +
> > +	uda1341_dapm_event(codec, SNDRV_CTL_POWER_D3cold);
> > +
> > +	pd = (struct uda1341_platform_data *) codec->control_data;
> > +	if (pd->power)
> > +		pd->power(0);
> 
> I'd expect that dapm_event() (which is now called set_bias_level())
> would be handling the power callback too.
> 
> > +struct snd_soc_codec_device soc_codec_dev_uda1341 = {
> > +	.probe =        uda1341_soc_probe,
> > +	.remove =       uda1341_soc_remove,
> > +#if defined(CONFIG_PM)
> > +	.suspend =      uda1341_soc_suspend,
> > +	.resume =       uda1341_soc_resume,
> > +#endif /* CONFIG_PM */
> 
> The standard idiom for this is to have an else defining the functions to
> NULL pointers above and then no ifdef here.
> 
> > +	void (*power) (int);
> 
> I'd really expect to see this being passed an argument specifying what
> it's interacting with.
> 
> > @@ -16,7 +16,7 @@ config SND_S3C2443_SOC_AC97
> >  	tristate
> >  	select AC97_BUS
> >  	select SND_SOC_AC97_BUS
> > -	
> > +
> >  config SND_S3C24XX_SOC_NEO1973_WM8753
> >  	tristate "SoC I2S Audio support for NEO1973 - WM8753"
> >  	depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01
> 
> Random whitespace change here...
> 
> > --- /dev/null
> > +++ b/sound/soc/s3c24xx/s3c24xx_uda1341.c
> 
> > +/*#define S3C24XX_UDA1341_DEBUG 1*/
> > +#ifdef S3C24XX_UDA1341_DEBUG
> > +#define DBG(x...) printk(KERN_DEBUG "s3c24xx-i2s: " x)
> > +#else
> > +#define DBG(x...)
> > +#endif
> 
> pr_debug().
> 
> > +static int s3c24xx_uda1341_hw_params(struct snd_pcm_substream *substream,
> > +                                       struct snd_pcm_hw_params *params)
> > +{
> 
> I can follow this function but it'd be nice to see more comments in
> here.  It looks like you could clarify it by iterating over a table of
> possible clock sources rather than writing each out in code.
> 
> It also looks like this should be imposing constraints which prevent the
> configuration of different rates for the DAC and ADC - several existing
> codec drivers like the wm8903 provide examples of doing this.
> 
> > +	ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, clk_source , clk,
> > +						SND_SOC_CLOCK_IN);
> > +	if (ret < 0)
> > +		return ret;
> 
> You want to run this through scripts/checkpatch.pl.
> 
> > +static void setdat(struct uda1341_platform_data *p, int v)
> > +{
> > +	s3c2410_gpio_setpin(s3c24xx_uda1341_l3_pins->l3_data, v > 0);
> > +	s3c2410_gpio_cfgpin(s3c24xx_uda1341_l3_pins->l3_data,
> > +			    S3C2410_GPIO_OUTPUT);
> > +}
> 
> Is there any reason for setting the pins to output mode each time?  It
> looks like you could just configure the mode once at startup and then
> only set the pin status here.
> 
> > +static void s3c24xx_uda1341_power(int en)
> > +{
> > +	if (s3c24xx_uda1341_l3_pins->power)
> > +		s3c24xx_uda1341_l3_pins->power(en);
> > +}
> 
> This feels like it ought to be initialised conditionally rather than
> having the check for the pin it.
> 
> > +	ret = platform_device_add(s3c24xx_uda1341_snd_device);
> 
> > +	xtal = clk_get(NULL, "xtal");
> > +	pclk = clk_get(NULL, "pclk");
> 
> This should be done in the init function for the device and should
> really check the return value in case it can't get the clock for some
> reason.  Ideally there'd be a dev there, but I'd need to check if the
> s3c24xx stuff does that.
> 
> -------------------------------------------------------------------
> List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
> FAQ:        http://www.arm.linux.org.uk/mailinglists/faq.php
> Etiquette:  http://www.arm.linux.org.uk/mailinglists/etiquette.php


-- 
Kristoffer Ericson <kristoffer.ericson at gmail.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
Url : http://mailman.alsa-project.org/pipermail/alsa-devel/attachments/20081110/51fbd9fa/attachment-0001.sig 


More information about the Alsa-devel mailing list