linux-omap.vger.kernel.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).