devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mark Brown <broonie@kernel.org>
To: Max Filippov <jcmvbkbc@gmail.com>
Cc: Mark Rutland <mark.rutland@arm.com>,
	devicetree@vger.kernel.org, alsa-devel@alsa-project.org,
	Pawel Moll <pawel.moll@arm.com>,
	linux-xtensa@linux-xtensa.org, Takashi Iwai <tiwai@suse.de>,
	Ian Campbell <ijc+devicetree@hellion.org.uk>,
	Liam Girdwood <lgirdwood@gmail.com>,
	linux-kernel@vger.kernel.org, Rob Herring <robh+dt@kernel.org>,
	Kumar Gala <galak@codeaurora.org>,
	Grant Likely <grant.likely@linaro.org>
Subject: Re: [PATCH] ASoC: add xtensa xtfpga I2S interface and platform
Date: Mon, 27 Oct 2014 19:32:29 +0000	[thread overview]
Message-ID: <20141027193229.GE18557@sirena.org.uk> (raw)
In-Reply-To: <1414436825-19416-1-git-send-email-jcmvbkbc@gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 4956 bytes --]

On Mon, Oct 27, 2014 at 10:07:05PM +0300, Max Filippov wrote:

> +config SND_SOC_XTENSA_XTFPGA
> +	tristate "SoC Audio for xtensa xtfpga"
> +	depends on XTENSA_PLATFORM_XTFPGA
> +	select SND_SOC_XTFPGA_I2S
> +	select SND_SOC_TLV320AIC23_SPI
> +	select SND_SIMPLE_CARD

I've only got this far in the file and have to leave now so I'll look
properly at the actual code later but the above shouldn't have the CODEC
or card driver selected, if the I2S driver is well written it should be
usable independently of either.

> +++ b/sound/soc/xtensa/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_SND_SOC_XTFPGA_I2S) += xtfpga-i2s.o

Please follow the style for all other ASoC drivers and name the module
snd-soc-foo.

> +static void xtfpga_i2s_push_tx(struct xtfpga_i2s *i2s)
> +{
> +	struct snd_pcm_substream *tx_substream;
> +	struct snd_pcm_runtime *runtime;
> +
> +	rcu_read_lock();
> +	tx_substream = rcu_dereference(i2s->tx_substream);
> +	runtime = tx_substream->runtime;
> +#define xtfpga_i2s_tx_loop(i2s, runtime, channels, sample_bits) \
> +	do { \
> +		const u##sample_bits (*p)[channels] = \
> +			(void *)runtime->dma_area; \
> +		for (; i2s->tx_fifo_sz < i2s->tx_fifo_high; \
> +		     i2s->tx_fifo_sz += 2) { \
> +			iowrite32(p[i2s->tx_ptr][0], \
> +				  i2s->regs + XTFPGA_I2S_CHAN0_DATA); \
> +			iowrite32(p[i2s->tx_ptr][channels - 1], \
> +				  i2s->regs + XTFPGA_I2S_CHAN0_DATA); \
> +			if (++i2s->tx_ptr >= runtime->buffer_size) \
> +				i2s->tx_ptr = 0; \
> +		} \
> +	} while (0)
> +
> +	switch (runtime->sample_bits | (runtime->channels << 8)) {
> +	case 0x110:
> +		xtfpga_i2s_tx_loop(i2s, runtime, 1, 16);
> +		break;

This really needs some rework to be legible.  I'd suggest making your
macro an inline function and either replacing these magic numbers in the
switch statement with defines or just writing the code clearly and
letting the compiler figure it out.

Some documentation explaining what your RCU usage is all about would
also be good...  I'm not clear why it's being used, none of the FIQ
drivers do this and I can't entirely figure out what we're defending
against other than the tasklet which we should be stopping anyway and
why what we're doing is safe.

I would also expect to see the data transfer and I2S bits more split
out, presumably this IP can actually be used in designs with a DMA
controller and one would expect that for practical systems this would be
the common case?

> +	if (int_status & XTFPGA_I2S_INT_UNDERRUN) {
> +		i2s->tx_fifo_sz = 0;
> +		regmap_update_bits(i2s->regmap, XTFPGA_I2S_CONFIG,
> +				   XTFPGA_I2S_CONFIG_INT_ENABLE |
> +				   XTFPGA_I2S_CONFIG_TX_ENABLE, 0);
> +	} else {
> +		i2s->tx_fifo_sz = i2s->tx_fifo_low;
> +		regmap_update_bits(i2s->regmap, XTFPGA_I2S_CONFIG,
> +				   XTFPGA_I2S_CONFIG_INT_ENABLE, 0);
> +	}

We're trying to implement a NAPI style thing here?

> +	if (tx_active) {
> +		if (i2s->tx_fifo_high < 256)
> +			xtfpga_i2s_refill_fifo(i2s);
> +		else
> +			tasklet_hi_schedule(&i2s->refill_fifo);

How does the interrupt handler avoid getting into a fight with the
tasklet if the interrupt line is shared?

> +static int xtfpga_i2s_hw_params(struct snd_pcm_substream *substream,
> +				   struct snd_pcm_hw_params *params,
> +				   struct snd_soc_dai *dai)
> +{
> +	struct xtfpga_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> +	unsigned srate = params_rate(params);
> +	unsigned channels = params_channels(params);
> +	unsigned period_size = params_period_size(params);
> +	unsigned sample_size = snd_pcm_format_width(params_format(params));
> +	unsigned freq, ratio, level;
> +	int err;
> +
> +	switch (params_format(params)) {
> +	case SNDRV_PCM_FORMAT_S16_LE:
> +	case SNDRV_PCM_FORMAT_S32_LE:
> +		break;

This looks buggy, we're accepting two different formats but not storing
anything or telling the hardware - especially concerning given that this
is a master only driver.

> +	regmap_update_bits(i2s->regmap, XTFPGA_I2S_CONFIG,
> +			   XTFPGA_I2S_CONFIG_RES_MASK,
> +			   sample_size << XTFPGA_I2S_CONFIG_RES_BASE);
> +
> +	if (i2s->clk_enabled) {
> +		clk_disable_unprepare(i2s->clk);
> +		i2s->clk_enabled = false;
> +	}
> +	freq = 256 * srate;
> +	err = clk_set_rate(i2s->clk, freq);
> +	if (err < 0)
> +		return err;
> +
> +	err = clk_prepare_enable(i2s->clk);
> +	if (err < 0)
> +		return err;
> +	i2s->clk_enabled = true;

This stuff with the clock seems complicated, why not just leave it
disabled when not in use and take advantage of the reference counting
the core already has?

> +	ratio = (freq - srate * sample_size * 8) /
> +		(srate * sample_size * 4);

What ratio exactly?  This needs more brackets in the first line and a
comment explaining what it's calculating.

> +	i2s->tx_fifo_low = XTFPGA_I2S_FIFO_SIZE / 2;
> +	for (level = 1;
> +	     /* period_size * 2: FIFO always gets 2 samples per frame */
> +	     i2s->tx_fifo_low / 2 >= period_size * 2;
> +	     ++level)
> +		i2s->tx_fifo_low /= 2;

This can't come out with a bad value?

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



  reply	other threads:[~2014-10-27 19:32 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-27 19:07 [PATCH] ASoC: add xtensa xtfpga I2S interface and platform Max Filippov
2014-10-27 19:32 ` Mark Brown [this message]
2014-10-27 20:38   ` Max Filippov
2014-10-28 15:42     ` Mark Brown
2014-10-28 17:00       ` Max Filippov
2014-10-28 17:38         ` Mark Brown
2014-10-28 18:11           ` Max Filippov
2014-10-28 21:34             ` Mark Brown
2014-10-29 14:19               ` Max Filippov
2014-10-29 14:23           ` Max Filippov
2014-10-29 21:02             ` Mark Brown
2014-10-29 21:10               ` Max Filippov
2014-10-29 21:16                 ` Mark Brown
2014-10-28 15:58 ` [alsa-devel] " Lars-Peter Clausen
     [not found]   ` <544FBD20.5000604-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
2014-10-28 16:04     ` Mark Brown
2014-10-28 16:39       ` Lars-Peter Clausen
2014-10-28 16:47         ` Takashi Iwai
2014-10-28 17:06         ` Mark Brown
2014-10-28 17:16   ` Max Filippov

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=20141027193229.GE18557@sirena.org.uk \
    --to=broonie@kernel.org \
    --cc=alsa-devel@alsa-project.org \
    --cc=devicetree@vger.kernel.org \
    --cc=galak@codeaurora.org \
    --cc=grant.likely@linaro.org \
    --cc=ijc+devicetree@hellion.org.uk \
    --cc=jcmvbkbc@gmail.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-xtensa@linux-xtensa.org \
    --cc=mark.rutland@arm.com \
    --cc=pawel.moll@arm.com \
    --cc=robh+dt@kernel.org \
    --cc=tiwai@suse.de \
    /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).