All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: Johannes Berg <johannes@sipsolutions.net>
Cc: linuxppc-dev@ozlabs.org, alsa-devel@alsa-project.org
Subject: Re: [RFC 4/8] snd-aoa: add i2sbus
Date: Fri, 02 Jun 2006 16:23:21 +0200	[thread overview]
Message-ID: <s5hr7274ox2.wl%tiwai@suse.de> (raw)
In-Reply-To: <20060601115847.420788000@sipsolutions.net>

At Thu, 01 Jun 2006 13:58:48 +0200,
Johannes Berg wrote:
> 
> --- /dev/null
> +++ b/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c
> +static int clock_and_divisors(int mclk, int sclk, int rate, int *out)
> +{
> +	/* sclk must be derived from mclk! */
> +	if (mclk % sclk)
> +		return -1;
> +	/* derive sclk register value */
> +	if (i2s_sf_sclkdiv(mclk / sclk, out))
> +		return -1;
> +
> +	if (I2S_CLOCK_SPEED_18MHz % rate == 0) {
> +		if ((I2S_CLOCK_SPEED_18MHz / rate) % mclk == 0) {

Equivalent with "I2S_CLOCK_SPEED_18MHZ % (rate * mclk) == 0" ?

> +static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
> +{
(snip)
> +	list_for_each_entry(cii, &sdev->codec_list, list) {
> +		if (cii->codec->open) {
> +			err = cii->codec->open(cii, pi->substream);
> +			if (err) {
> +				result = err;
> +				goto out_unlock;

What happens if the first code is opened but fail the secondary?
No need to close the first?

> +static snd_pcm_uframes_t i2sbus_pcm_pointer(struct i2sbus_dev *i2sdev, int in)
> +{
> +	struct pcm_info *pi;
> +	u32 fc;
> +
> +	get_pcm_info(i2sdev, in, &pi, NULL);
> +
> +	fc = in_le32(&i2sdev->intfregs->frame_count);
> +	fc = fc - pi->frame_count;
> +
> +	return (bytes_to_frames(pi->substream->runtime,
> +			       pi->current_period *
> +			       snd_pcm_lib_period_bytes(pi->substream)) + fc) % pi->substream->runtime->buffer_size;
> +}
> +
> +static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in)
> +{
> +	struct pcm_info *pi;
> +	u32 fc;
> +	u32 delta;
> +
> +	spin_lock(&i2sdev->low_lock);
> +	get_pcm_info(i2sdev, in, &pi, NULL);
> +	if (!pi->substream) {
> +		printk(KERN_INFO "i2sbus: got %s irq while not active!\n",
> +		       in ? "rx" : "tx");
> +		goto out_unlock;
> +	}
> +
> +	fc = in_le32(&i2sdev->intfregs->frame_count);
> +	/* a counter overflow does not change the calculation. */
> +	delta = fc - pi->frame_count;
> +
> +	/* update current_period */
> +	while (delta >= pi->substream->runtime->period_size) {
> +		pi->current_period++;
> +		delta = delta - pi->substream->runtime->period_size;
> +	}
> +
> +	if (unlikely(delta)) {
> +		/* Some interrupt came late, so check the dbdma.
> +		 * This special case exists to syncronize the frame_count with the
> +		 * dbdma transfers, but is hit every once in a while. */
> +		int period;
> +
> +		period = (in_le32(&pi->dbdma->cmdptr) - pi->dbdma_ring.bus_cmd_start) / sizeof(struct dbdma_cmd);
> +		pi->current_period = pi->current_period % pi->substream->runtime->periods;
> +
> +		while (pi->current_period != period) {
> +			pi->current_period = (pi->current_period + 1) % pi->substream->runtime->periods;
> +			/* Set delta to zero, as the frame_count value is too high (otherwise the code path
> +			 * will not be executed).
> +			 * This is to correct the fact that the frame_count is too low at the beginning
> +			 * due to the dbdma's buffer. */
> +			delta = 0;

Too long lines...

> +/* FIXME: this function needs an error handling strategy with labels */
> +int
> +i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
> +		    struct codec_info *ci, void *data)
> +{
> +	int err, in = 0, out = 0;
> +	struct transfer_info *tmp;
> +	struct i2sbus_dev *i2sdev = soundbus_dev_to_i2sbus_dev(dev);
> +	struct codec_info_item *cii;
> +
> +	if (!dev->pcmname || dev->pcmid == -1) {
> +		printk(KERN_ERR "i2sbus: pcm name and id must be set!\n");

No error return?

> +	/* well, we really should support scatter/gather DMA */
> +	/* FIXME FIXME FIXME: If this fails, we BUG() when the alsa layer
> +	 * later tries to allocate memory. Apparently we should be setting
> +	 * some device pointer for that ...
> +	 */
> +	snd_pcm_lib_preallocate_pages_for_all(
> +		dev->pcm, SNDRV_DMA_TYPE_DEV,
> +		snd_dma_pci_data(macio_get_pci_dev(i2sdev->macio)),
> +		64 * 1024, 64 * 1024);

Is the comment true?  Yes, you have to set the device pointer via
snd_pcm_lib_preallocate*().  But it must be OK even if preallocate
fails.

> --- /dev/null
> +++ b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
> +static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
> +				       struct dbdma_command_mem *r,
> +				       int numcmds)
> +{
> +	/* one more for rounding */
> +	r->size = (numcmds+1) * sizeof(struct dbdma_cmd);
> +	/* We use the PCI APIs for now until the generic one gets fixed
> +	 * enough or until we get some macio-specific versions
> +	 */
> +	r->space = pci_alloc_consistent(macio_get_pci_dev(i2sdev->macio),
> +					r->size,
> +					&r->bus_addr);

Better to use dma_alloc_coherent().  pci_alloc_consistent() implies
GFP_ATOMIC.

> +static irqreturn_t i2sbus_bus_intr(int irq, void *devid, struct pt_regs *regs)
> +{
> +	struct i2sbus_dev *dev = devid;
> +	u32 intreg;
> +
> +	spin_lock(&dev->low_lock);
> +	intreg = in_le32(&dev->intfregs->intr_ctl);
> +
> +	printk(KERN_INFO "i2sbus: interrupt, intr reg is 0x%x!\n", intreg);

Should this be really always printed?


Takashi

WARNING: multiple messages have this Message-ID (diff)
From: Takashi Iwai <tiwai@suse.de>
To: Johannes Berg <johannes@sipsolutions.net>
Cc: linuxppc-dev@ozlabs.org, alsa-devel@alsa-project.org
Subject: Re: [Alsa-devel] [RFC 4/8] snd-aoa: add i2sbus
Date: Fri, 02 Jun 2006 16:23:21 +0200	[thread overview]
Message-ID: <s5hr7274ox2.wl%tiwai@suse.de> (raw)
In-Reply-To: <20060601115847.420788000@sipsolutions.net>

At Thu, 01 Jun 2006 13:58:48 +0200,
Johannes Berg wrote:
> 
> --- /dev/null
> +++ b/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c
> +static int clock_and_divisors(int mclk, int sclk, int rate, int *out)
> +{
> +	/* sclk must be derived from mclk! */
> +	if (mclk % sclk)
> +		return -1;
> +	/* derive sclk register value */
> +	if (i2s_sf_sclkdiv(mclk / sclk, out))
> +		return -1;
> +
> +	if (I2S_CLOCK_SPEED_18MHz % rate == 0) {
> +		if ((I2S_CLOCK_SPEED_18MHz / rate) % mclk == 0) {

Equivalent with "I2S_CLOCK_SPEED_18MHZ % (rate * mclk) == 0" ?

> +static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
> +{
(snip)
> +	list_for_each_entry(cii, &sdev->codec_list, list) {
> +		if (cii->codec->open) {
> +			err = cii->codec->open(cii, pi->substream);
> +			if (err) {
> +				result = err;
> +				goto out_unlock;

What happens if the first code is opened but fail the secondary?
No need to close the first?

> +static snd_pcm_uframes_t i2sbus_pcm_pointer(struct i2sbus_dev *i2sdev, int in)
> +{
> +	struct pcm_info *pi;
> +	u32 fc;
> +
> +	get_pcm_info(i2sdev, in, &pi, NULL);
> +
> +	fc = in_le32(&i2sdev->intfregs->frame_count);
> +	fc = fc - pi->frame_count;
> +
> +	return (bytes_to_frames(pi->substream->runtime,
> +			       pi->current_period *
> +			       snd_pcm_lib_period_bytes(pi->substream)) + fc) % pi->substream->runtime->buffer_size;
> +}
> +
> +static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in)
> +{
> +	struct pcm_info *pi;
> +	u32 fc;
> +	u32 delta;
> +
> +	spin_lock(&i2sdev->low_lock);
> +	get_pcm_info(i2sdev, in, &pi, NULL);
> +	if (!pi->substream) {
> +		printk(KERN_INFO "i2sbus: got %s irq while not active!\n",
> +		       in ? "rx" : "tx");
> +		goto out_unlock;
> +	}
> +
> +	fc = in_le32(&i2sdev->intfregs->frame_count);
> +	/* a counter overflow does not change the calculation. */
> +	delta = fc - pi->frame_count;
> +
> +	/* update current_period */
> +	while (delta >= pi->substream->runtime->period_size) {
> +		pi->current_period++;
> +		delta = delta - pi->substream->runtime->period_size;
> +	}
> +
> +	if (unlikely(delta)) {
> +		/* Some interrupt came late, so check the dbdma.
> +		 * This special case exists to syncronize the frame_count with the
> +		 * dbdma transfers, but is hit every once in a while. */
> +		int period;
> +
> +		period = (in_le32(&pi->dbdma->cmdptr) - pi->dbdma_ring.bus_cmd_start) / sizeof(struct dbdma_cmd);
> +		pi->current_period = pi->current_period % pi->substream->runtime->periods;
> +
> +		while (pi->current_period != period) {
> +			pi->current_period = (pi->current_period + 1) % pi->substream->runtime->periods;
> +			/* Set delta to zero, as the frame_count value is too high (otherwise the code path
> +			 * will not be executed).
> +			 * This is to correct the fact that the frame_count is too low at the beginning
> +			 * due to the dbdma's buffer. */
> +			delta = 0;

Too long lines...

> +/* FIXME: this function needs an error handling strategy with labels */
> +int
> +i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card,
> +		    struct codec_info *ci, void *data)
> +{
> +	int err, in = 0, out = 0;
> +	struct transfer_info *tmp;
> +	struct i2sbus_dev *i2sdev = soundbus_dev_to_i2sbus_dev(dev);
> +	struct codec_info_item *cii;
> +
> +	if (!dev->pcmname || dev->pcmid == -1) {
> +		printk(KERN_ERR "i2sbus: pcm name and id must be set!\n");

No error return?

> +	/* well, we really should support scatter/gather DMA */
> +	/* FIXME FIXME FIXME: If this fails, we BUG() when the alsa layer
> +	 * later tries to allocate memory. Apparently we should be setting
> +	 * some device pointer for that ...
> +	 */
> +	snd_pcm_lib_preallocate_pages_for_all(
> +		dev->pcm, SNDRV_DMA_TYPE_DEV,
> +		snd_dma_pci_data(macio_get_pci_dev(i2sdev->macio)),
> +		64 * 1024, 64 * 1024);

Is the comment true?  Yes, you have to set the device pointer via
snd_pcm_lib_preallocate*().  But it must be OK even if preallocate
fails.

> --- /dev/null
> +++ b/sound/aoa/soundbus/i2sbus/i2sbus-core.c
> +static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
> +				       struct dbdma_command_mem *r,
> +				       int numcmds)
> +{
> +	/* one more for rounding */
> +	r->size = (numcmds+1) * sizeof(struct dbdma_cmd);
> +	/* We use the PCI APIs for now until the generic one gets fixed
> +	 * enough or until we get some macio-specific versions
> +	 */
> +	r->space = pci_alloc_consistent(macio_get_pci_dev(i2sdev->macio),
> +					r->size,
> +					&r->bus_addr);

Better to use dma_alloc_coherent().  pci_alloc_consistent() implies
GFP_ATOMIC.

> +static irqreturn_t i2sbus_bus_intr(int irq, void *devid, struct pt_regs *regs)
> +{
> +	struct i2sbus_dev *dev = devid;
> +	u32 intreg;
> +
> +	spin_lock(&dev->low_lock);
> +	intreg = in_le32(&dev->intfregs->intr_ctl);
> +
> +	printk(KERN_INFO "i2sbus: interrupt, intr reg is 0x%x!\n", intreg);

Should this be really always printed?


Takashi

  reply	other threads:[~2006-06-02 14:23 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-06-01 11:58 [RFC 0/8] snd-aoa: add snd-aoa Johannes Berg
2006-06-01 11:58 ` [RFC 1/8] snd-aoa: add aoa header files Johannes Berg
2006-06-01 11:58   ` Johannes Berg
2006-06-01 11:58 ` [RFC 2/8] snd-aoa: add aoa core Johannes Berg
2006-06-01 11:58   ` Johannes Berg
2006-06-02 13:42   ` Takashi Iwai
2006-06-02 13:42     ` [Alsa-devel] " Takashi Iwai
2006-06-02 13:46     ` Johannes Berg
2006-06-02 13:46       ` [Alsa-devel] " Johannes Berg
2006-06-01 11:58 ` [RFC 3/8] snd-aoa: add soundbus Johannes Berg
2006-06-01 11:58   ` Johannes Berg
2006-06-02 13:53   ` Takashi Iwai
2006-06-02 13:53     ` [Alsa-devel] " Takashi Iwai
2006-06-02 14:07     ` Johannes Berg
2006-06-02 14:07     ` [Alsa-devel] " Johannes Berg
2006-06-02 14:21       ` Takashi Iwai
2006-06-02 14:21         ` [Alsa-devel] " Takashi Iwai
2006-06-02 14:41         ` Andreas Schwab
2006-06-02 14:41           ` [Alsa-devel] " Andreas Schwab
2006-06-02 14:44           ` Johannes Berg
2006-06-02 14:44             ` [Alsa-devel] " Johannes Berg
2006-06-02 14:45           ` Takashi Iwai
2006-06-02 14:45             ` [Alsa-devel] " Takashi Iwai
2006-06-01 11:58 ` [RFC 4/8] snd-aoa: add i2sbus Johannes Berg
2006-06-01 11:58   ` Johannes Berg
2006-06-02 14:23   ` Takashi Iwai [this message]
2006-06-02 14:23     ` [Alsa-devel] " Takashi Iwai
2006-06-06 11:17     ` Johannes Berg
2006-06-06 11:17     ` [Alsa-devel] " Johannes Berg
2006-06-06 14:00       ` Takashi Iwai
2006-06-06 14:00       ` [Alsa-devel] " Takashi Iwai
2006-06-07 11:40         ` Johannes Berg
2006-06-07 11:40           ` [Alsa-devel] " Johannes Berg
2006-06-07 12:41           ` Takashi Iwai
2006-06-07 12:41             ` [Alsa-devel] " Takashi Iwai
2006-06-07 12:45             ` Johannes Berg
2006-06-07 12:45               ` [Alsa-devel] " Johannes Berg
2006-06-07 12:49               ` Takashi Iwai
2006-06-07 12:49                 ` [Alsa-devel] " Takashi Iwai
2006-06-07 12:52                 ` Johannes Berg
2006-06-07 12:52                   ` [Alsa-devel] " Johannes Berg
2006-06-07 12:58                   ` Takashi Iwai
2006-06-07 12:58                   ` [Alsa-devel] " Takashi Iwai
2006-06-07 13:01                     ` Johannes Berg
2006-06-07 13:01                       ` [Alsa-devel] " Johannes Berg
2006-06-01 11:58 ` [RFC 5/8] snd-aoa: add codecs Johannes Berg
2006-06-01 11:58   ` Johannes Berg
2006-06-02 14:31   ` Takashi Iwai
2006-06-02 14:31     ` [Alsa-devel] " Takashi Iwai
2006-06-06 11:36     ` Johannes Berg
2006-06-06 11:36     ` [Alsa-devel] " Johannes Berg
2006-06-01 11:58 ` [RFC 6/8] snd-aoa: add layout-id fabric Johannes Berg
2006-06-01 11:58   ` Johannes Berg
2006-06-01 11:58 ` [RFC 7/8] snd-aoa: add Kconfig and Makefile Johannes Berg
2006-06-01 11:58   ` Johannes Berg
2006-06-01 11:58 ` [RFC 8/8] snd-aoa: wire up aoa in sound/ Johannes Berg
2006-06-01 11:58   ` Johannes Berg
2006-06-02 14:43 ` [RFC 0/8] snd-aoa: add snd-aoa Takashi Iwai
2006-06-02 14:43   ` [Alsa-devel] " Takashi Iwai
2006-06-02 14:56   ` Johannes Berg
2006-06-02 14:56     ` [Alsa-devel] " Johannes Berg
2006-06-02 15:23     ` Takashi Iwai
2006-06-02 15:23     ` Takashi Iwai

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=s5hr7274ox2.wl%tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=johannes@sipsolutions.net \
    --cc=linuxppc-dev@ozlabs.org \
    /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.