All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jyri Sarha <jsarha@ti.com>
To: Mark Brown <broonie@kernel.org>
Cc: linux-omap@vger.kernel.org, alsa-devel@alsa-project.org,
	devicetree@vger.kernel.org, bcousson@baylibre.com,
	peter.ujfalusi@ti.com, detheridge@ti.com
Subject: Re: [PATCH RFC 1/5] ASoC: tlv320aic31xx: Add basic codec driver implementation
Date: Tue, 4 Mar 2014 15:36:33 +0200	[thread overview]
Message-ID: <5315D6E1.3010008@ti.com> (raw)
In-Reply-To: <20140303063444.GR2411@sirena.org.uk>

On 03/03/2014 08:34 AM, Mark Brown wrote:
> On Wed, Feb 26, 2014 at 11:14:25AM +0200, Jyri Sarha wrote:
>> This commit adds a bare bones driver support for TLV320AIC31XX family
>> audio codecs. The driver adds basic stereo playback trough headphone
>> and speaker outputs and mono capture trough microphone inputs.
>
> Always CC maintainers on patches please.
>

Will do.

>> +static bool aic31xx_volatile(struct device *dev, unsigned int reg)
>> +{
>> +	if (aic31xx_precious(dev, reg) || aic31xx_real_volatile(dev, reg))
>> +		return true;
>> +
>> +	switch (reg) {
>> +	case AIC31XX_PAGECTL: /* regmap implementation requires this */
>> +	case AIC31XX_RESET: /* always clears after write */
>> +		return true;
>> +	}
>> +	return false;
>> +}
>
> This is more complex than you need, just write a standalone volatile
> function with some comments in it.
>

Replaced with straight forward aic31xx_volatile() and aic31xx_writable() 
functions.

>> +static const struct regmap_range_cfg aic31xx_ranges[] = {
>> +	{
>> +		.name = "codec-regmap",
>
> Make this meaningful or omit it.
>

Removed.

>> +#define AIC31XX_NUM_SUPPLIES	6
>> +static const char * const aic31xx_supply_names[] = {
>
> Use the define in the array size to help check everything lines up.
>

Done.

>> +static const char * const ldac_in_text[] = {
>> +	"off", "Left Data", "Right Data", "Mono"
>> +};
>
> Off not off - be consistent both internally and with the general style.
>

Done.

>> +static const struct snd_kcontrol_new aic311x_snd_controls[] = {
>> +	SOC_DOUBLE_R("SP Driver Playback Switch", AIC31XX_SPLGAIN,
>> +		     AIC31XX_SPRGAIN, 2, 1, 0),
>
> SP?
>

"SP" replaced with "Speaker", also in DAPM switches.

>> +	if (!strcmp(w->name, "DAC Left")) {
>> +		mask = AIC31XX_LDACPWRSTATUS_MASK;
>
> There's no overlap with the enable bits?  In general it would seem nicer
> to have a switch based on the register bits used for the enable rather
> than the tree of string comparisions but it's probably not that big a
> deal overall.
>

Not with bits, but with regs. I decided this structure would be easier 
to implement and understand than having a switch(w->reg) with nested 
switch(w->shift) cases. I replaced the string comparisons with a single 
switch case using a binary combination of w->reg and w->shift.

>> +		dev_err(w->codec->dev, "Unknown widget '%s' calling %s/n",
>> +			w->name, __func__);
>> +		return -1;		switch (w->shift) {
		case 7:
			mask = AIC31XX_LDACPWRSTATUS_MASK;

>
> Return real error codes.
>

Changed to -EINVAL.

>> +	if (event == SND_SOC_DAPM_POST_PMU)
>> +		return aic31xx_wait_bits(aic31xx, reg, mask, mask, 5000, 100);
>> +	else if (event == SND_SOC_DAPM_POST_PMD)
>> +		return aic31xx_wait_bits(aic31xx, reg, mask, 0, 5000, 100);
>
> switch.
>

Done.

>> +	SND_SOC_DAPM_DAC_E("DAC Right", "DAC Right Input",
>> +			   AIC31XX_DACSETUP, 6, 0, aic31xx_dapm_power_event,
>> +			   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
>
> Don't use stream names, use DAPM to route from the AIF to the widgets.
>

Renamed DAC stnames to "Left Playback" and "Right Playback".

>> +	switch (params_format(params)) {
>> +	case SNDRV_PCM_FORMAT_S16_LE:
>> +		break;
>
> params_width().
>

Done.

>> +			    AIC31XX_IFACE1_DATALEN_MASK,
>> +			    data);
>> +
>> +	return aic31xx_setup_pll(codec, params);
>
> This is going to mean that you have a symmetry constraint I think, if
> you try to set up different rates for playback and capture presumably
> things will break.  Setting symmetric_rates will tell applications about
> that.
>

Done.

>> +	case SND_SOC_DAIFMT_CBS_CFM:
>> +	case SND_SOC_DAIFMT_CBM_CFS:
>> +	case SND_SOC_DAIFMT_CBS_CFS:
>> +		dev_err(codec->dev, "Unsupported DAI master/slave interface\n");
>> +		return -EINVAL;
>> +	default:
>> +		dev_alert(codec->dev, "Invalid DAI master/slave interface\n");
>> +		return -EINVAL;
>
> Just have a default.
>

Done.

>> +	for (i = 0; aic31xx_divs[i].mclk != freq; i++)
>> +		if (i == ARRAY_SIZE(aic31xx_divs)) {
>> +			dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n",
>> +				__func__, freq);
>> +			return -EINVAL;
>> +		}
>
> Braces around the for () too please.
>

Done.

>> +static int aic31xx_set_power(struct snd_soc_codec *codec, int power)
>> +{
>> +	struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
>> +	int ret;
>> +
>> +	dev_dbg(codec->dev, "## %s: %d -> %d\n", __func__,
>> +		aic31xx->power, power);
>> +	if (aic31xx->power == power)
>> +		return 0;
>
> This looks like you need sensible refcounting somewhere?  Implementing
> this as the standard PM operations may be sensible.
>

Not really. This was just avoid power on sequence when bias level goes 
from SND_SOC_BIAS_PREPARE back to SND_SOC_BIAS_STANDBY. I'll change this 
to a "if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)" in set_bias_level 
like other codecs do.

>> +		if (gpio_is_valid(aic31xx->pdata.gpio_reset)) {
>> +			gpio_set_value(aic31xx->pdata.gpio_reset, 1);
>> +			udelay(100);
>> +		}
>> +		snd_soc_write(codec, AIC31XX_RESET, 0x01);
>> +		udelay(100);
>> +		regcache_cache_only(aic31xx->regmap, false);
>
> You should be coming out of cache only mode before you issue the reset
> write.  Is it not sensible to skip that if you have a physical reset
> line?
>
>> +		snd_soc_write(codec, AIC31XX_RESET, 0x01);
>> +		regcache_cache_only(aic31xx->regmap, true);
>> +
>> +		if (gpio_is_valid(aic31xx->pdata.gpio_reset))
>> +			gpio_set_value(aic31xx->pdata.gpio_reset, 0);
>
> Likewise here.  Also if you do reset the CODEC then the dance you did
> with the regulator notifiers becomes pointless - the goal with that is
> to avoid the need to resync the cache if the CODEC wasn't actually reset
> by a power cycle but since the CODEC is going to be explicitly reset
> before it's powered off there's no benefit.
>

I rewrote the bias-level/power logic a bit. It should now look more like 
the other codecs. I hope you like this version better.

>> +	switch (level) {
>> +	/* full On */
>> +	case SND_SOC_BIAS_ON:
>> +		/* All power is driven by DAPM system*/
>> +		break;
>> +	/* partial On */
>
> Coding style, please.
>

Removed the redundant badly indented comments.

Fixed also the Kconfig and Makefile ordering and added dt-include for 
micbias and changed the default to 2.0V. All are now squashed to a 
single patch.

In addition to addressing your comments I also added an internal ADC 
input and DAC output for codec to turn on at playback/capture start even 
if the alsamixers are not set correctly.

I'll mail the patches shortly.

Best regards,
Jyri

  reply	other threads:[~2014-03-04 13:36 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-26  9:14 [PATCH RFC 0/5] AM43xx-ePOS-EVM audio support with TLV320AIC31XX driver Jyri Sarha
2014-02-26  9:14 ` [PATCH RFC 1/5] ASoC: tlv320aic31xx: Add basic codec driver implementation Jyri Sarha
     [not found]   ` <73198e2f7aca0379abc596027d7d59ac250061c7.1393405575.git.jsarha-l0cyMroinI0@public.gmane.org>
2014-03-03  6:34     ` Mark Brown
2014-03-04 13:36       ` Jyri Sarha [this message]
2014-02-26  9:14 ` [PATCH RFC 2/5] ASoC: tlv320aic31xx: Add codec driver to Makefile and Kconfig Jyri Sarha
2014-02-27 14:11   ` Peter Ujfalusi
2014-03-03  5:09   ` Mark Brown
2014-02-26  9:14 ` [PATCH RFC 3/5] ASoC: tlv320aic31xx: Add DT binding document Jyri Sarha
2014-03-03  6:38   ` Mark Brown
2014-02-26  9:14 ` [PATCH RFC 4/5] ASoC: davinci-evm: Add AM43xx-EPOS-EVM audio support Jyri Sarha
2014-02-26  9:14 ` [PATCH RFC 5/5] ASoC: davinci: Add SND_AM43XX_SOC_EPOS_EVM build option Jyri Sarha

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5315D6E1.3010008@ti.com \
    --to=jsarha@ti.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=bcousson@baylibre.com \
    --cc=broonie@kernel.org \
    --cc=detheridge@ti.com \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=peter.ujfalusi@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.