/*
 * i2sbus driver -- pcm routines
 *
 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
 *
 * GPL v2, can be found in COPYING.
 */

#include <asm/io.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <asm/macio.h>
#include <linux/pci.h>
#include <linux/module.h>
#include "../soundbus.h"
#include "i2sbus.h"

static inline void get_pcm_info(struct i2sbus_dev *i2sdev, int in,
				struct pcm_info **pi, struct pcm_info **other)
{
	if (in) {
		if (pi)
			*pi = &i2sdev->in;
		if (other)
			*other = &i2sdev->out;
	} else {
		if (pi)
			*pi = &i2sdev->out;
		if (other)
			*other = &i2sdev->in;
	}
}

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 * mclk) == 0) {
		if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_18MHz / (rate * mclk), out)) {
			*out |= I2S_SF_CLOCK_SOURCE_18MHz;
			return 0;
		}
	}
	if (I2S_CLOCK_SPEED_45MHz % (rate * mclk) == 0) {
		if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_45MHz / (rate * mclk), out)) {
			*out |= I2S_SF_CLOCK_SOURCE_45MHz;
			return 0;
		}
	}
	if (I2S_CLOCK_SPEED_49MHz % (rate * mclk) == 0) {
		if (!i2s_sf_mclkdiv(I2S_CLOCK_SPEED_49MHz / (rate * mclk), out)) {
			*out |= I2S_SF_CLOCK_SOURCE_49MHz;
			return 0;
		}
	}
	return -1;
}

#define CHECK_RATE(rate)						\
	do { if (rates & SNDRV_PCM_RATE_ ##rate) {			\
		int dummy;						\
		if (clock_and_divisors(sysclock_factor,			\
				       bus_factor, rate, &dummy))	\
			rates &= ~SNDRV_PCM_RATE_ ##rate;		\
	} } while (0)

static int i2sbus_pcm_open(struct i2sbus_dev *i2sdev, int in)
{
	struct pcm_info *pi, *other;
	struct soundbus_dev *sdev;
	int masks_inited = 0, err;
	struct codec_info_item *cii, *rev;
	struct snd_pcm_hardware *hw;
	u64 formats = 0;
	unsigned int rates = 0;
	struct transfer_info v;
	int result = 0;
	int bus_factor = 0, sysclock_factor = 0;
	int found_this;

	mutex_lock(&i2sdev->lock);

	get_pcm_info(i2sdev, in, &pi, &other);

	hw = &pi->substream->runtime->hw;
	sdev = &i2sdev->sound;

	if (pi->active) {
		/* alsa messed up */
		result = -EBUSY;
		goto out_unlock;
	}

	/* we now need to assign the hw */
	list_for_each_entry(cii, &sdev->codec_list, list) {
		struct transfer_info *ti = cii->codec->transfers;
		bus_factor = cii->codec->bus_factor;
		sysclock_factor = cii->codec->sysclock_factor;
		while (ti->formats && ti->rates) {
			v = *ti;
			if (ti->transfer_in == in
			    && cii->codec->usable(cii, ti, &v)) {
				if (masks_inited) {
					formats &= v.formats;
					rates &= v.rates;
				} else {
					formats = v.formats;
					rates = v.rates;
					masks_inited = 1;
				}
			}
			ti++;
		}
	}
	if (!masks_inited || !bus_factor || !sysclock_factor) {
		result = -ENODEV;
		goto out_unlock;
	}
	/* bus dependent stuff */
	hw->info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
		   SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME |
		   SNDRV_PCM_INFO_JOINT_DUPLEX;

	CHECK_RATE(5512);
	CHECK_RATE(8000);
	CHECK_RATE(11025);
	CHECK_RATE(16000);
	CHECK_RATE(22050);
	CHECK_RATE(32000);
	CHECK_RATE(44100);
	CHECK_RATE(48000);
	CHECK_RATE(64000);
	CHECK_RATE(88200);
	CHECK_RATE(96000);
	CHECK_RATE(176400);
	CHECK_RATE(192000);
	hw->rates = rates;

	/* well. the codec might want 24 bits only, and we'll
	 * ever only transfer 24 bits, but they are top-aligned!
	 * So for alsa, we claim that we're doing full 32 bit
	 * while in reality we'll ignore the lower 8 bits of
	 * that when doing playback (they're transferred as 0
	 * as far as I know, no codecs we have are 32-bit capable
	 * so I can't really test) and when doing recording we'll
	 * always have those lower 8 bits recorded as 0 */
	if (formats & SNDRV_PCM_FMTBIT_S24_BE)
		formats |= SNDRV_PCM_FMTBIT_S32_BE;
	if (formats & SNDRV_PCM_FMTBIT_U24_BE)
		formats |= SNDRV_PCM_FMTBIT_U32_BE;
	/* now mask off what we can support. I suppose we could
	 * also support S24_3LE and some similar formats, but I
	 * doubt there's a codec that would be able to use that,
	 * so we don't support it here. */
	hw->formats = formats & (SNDRV_PCM_FMTBIT_S16_BE |
				 SNDRV_PCM_FMTBIT_U16_BE |
				 SNDRV_PCM_FMTBIT_S32_BE |
				 SNDRV_PCM_FMTBIT_U32_BE);

	/* we need to set the highest and lowest rate possible.
	 * These are the highest and lowest rates alsa can
	 * support properly in its bitfield.
	 * Below, we'll use that to restrict to the rate
	 * currently in use (if any). */
	hw->rate_min = 5512;
	hw->rate_max = 192000;
	/* if the other stream is active, then we can only
	 * support what it is currently using.
	 * FIXME: I lied. This comment is wrong. We can support
	 * anything that works with the same serial format, ie.
	 * when recording 24 bit sound we can well play 16 bit
	 * sound at the same time iff using the same transfer mode.
	 */
	if (other->active) {
		/* FIXME: is this guaranteed by the alsa api? */
		hw->formats &= (1ULL << i2sdev->format);
		/* see above, restrict rates to the one we already have */
		hw->rate_min = i2sdev->rate;
		hw->rate_max = i2sdev->rate;
	}

	hw->channels_min = 2;
	hw->channels_max = 2;
	/* these are somewhat arbitrary */
	hw->buffer_bytes_max = 131072;
	hw->period_bytes_min = 256;
	hw->period_bytes_max = 16384;
	hw->periods_min = 3;
	hw->periods_max = MAX_DBDMA_COMMANDS;
	err = snd_pcm_hw_constraint_integer(pi->substream->runtime,
					    SNDRV_PCM_HW_PARAM_PERIODS);
	if (err < 0) {
		result = err;
		goto out_unlock;
	}
	list_for_each_entry(cii, &sdev->codec_list, list) {
		if (cii->codec->open) {
			err = cii->codec->open(cii, pi->substream);
			if (err) {
				result = err;
				/* unwind */
				found_this = 0;
				list_for_each_entry_reverse(rev,
				    &sdev->codec_list, list) {
					if (found_this && rev->codec->close) {
						rev->codec->close(rev,
								pi->substream);
					}
					if (rev == cii)
						found_this = 1;
				}
				goto out_unlock;
			}
		}
	}

 out_unlock:
	mutex_unlock(&i2sdev->lock);
	return result;
}

#undef CHECK_RATE

static int i2sbus_pcm_close(struct i2sbus_dev *i2sdev, int in)
{
	struct codec_info_item *cii;
	struct pcm_info *pi;
	int err = 0, tmp;

	mutex_lock(&i2sdev->lock);

	get_pcm_info(i2sdev, in, &pi, NULL);

	list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
		if (cii->codec->close) {
			tmp = cii->codec->close(cii, pi->substream);
			if (tmp)
				err = tmp;
		}
	}

	pi->substream = NULL;
	pi->active = 0;
	mutex_unlock(&i2sdev->lock);
	return err;
}

static void i2sbus_wait_for_stop(struct i2sbus_dev *i2sdev,
				 struct pcm_info *pi)
{
	unsigned long flags;
	struct completion done;
	long timeout;

	spin_lock_irqsave(&i2sdev->low_lock, flags);
	if (pi->dbdma_ring.stopping) {
		init_completion(&done);
		pi->stop_completion = &done;
		spin_unlock_irqrestore(&i2sdev->low_lock, flags);
		timeout = wait_for_completion_timeout(&done, HZ);
		spin_lock_irqsave(&i2sdev->low_lock, flags);
		pi->stop_completion = NULL;
		if (timeout == 0) {
			/* timeout expired, stop dbdma forcefully */
			printk(KERN_ERR "i2sbus_wait_for_stop: timed out\n");
			/* make sure RUN, PAUSE and S0 bits are cleared */
			out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);
			pi->dbdma_ring.stopping = 0;
			timeout = 10;
			while (in_le32(&pi->dbdma->status) & ACTIVE) {
				if (--timeout <= 0)
					break;
				udelay(1);
			}
		}
	}
	spin_unlock_irqrestore(&i2sdev->low_lock, flags);
}

#ifdef CONFIG_PM
void i2sbus_wait_for_stop_both(struct i2sbus_dev *i2sdev)
{
	struct pcm_info *pi;

	get_pcm_info(i2sdev, 0, &pi, NULL);
	i2sbus_wait_for_stop(i2sdev, pi);
	get_pcm_info(i2sdev, 1, &pi, NULL);
	i2sbus_wait_for_stop(i2sdev, pi);
}
#endif

static int i2sbus_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params)
{
	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
}

static inline int i2sbus_hw_free(struct snd_pcm_substream *substream, int in)
{
	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
	struct pcm_info *pi;

	get_pcm_info(i2sdev, in, &pi, NULL);
	if (pi->dbdma_ring.stopping)
		i2sbus_wait_for_stop(i2sdev, pi);
	snd_pcm_lib_free_pages(substream);
	return 0;
}

static int i2sbus_playback_hw_free(struct snd_pcm_substream *substream)
{
	return i2sbus_hw_free(substream, 0);
}

static int i2sbus_record_hw_free(struct snd_pcm_substream *substream)
{
	return i2sbus_hw_free(substream, 1);
}

static int i2sbus_pcm_prepare(struct i2sbus_dev *i2sdev, int in)
{
	/* whee. Hard work now. The user has selected a bitrate
	 * and bit format, so now we have to program our
	 * I2S controller appropriately. */
	struct snd_pcm_runtime *runtime;
	struct dbdma_cmd *command;
	int i, periodsize, nperiods;
	dma_addr_t offset;
	struct bus_info bi;
	struct codec_info_item *cii;
	int sfr = 0;		/* serial format register */
	int dws = 0;		/* data word sizes reg */
	int input_16bit;
	struct pcm_info *pi, *other;
	int cnt;
	int result = 0;
	unsigned int cmd, stopaddr;

	mutex_lock(&i2sdev->lock);

	get_pcm_info(i2sdev, in, &pi, &other);

	if (pi->dbdma_ring.running) {
		result = -EBUSY;
		goto out_unlock;
	}
	if (pi->dbdma_ring.stopping)
		i2sbus_wait_for_stop(i2sdev, pi);

	if (!pi->substream || !pi->substream->runtime) {
		result = -EINVAL;
		goto out_unlock;
	}

	runtime = pi->substream->runtime;
	pi->active = 1;
	if (other->active &&
	    ((i2sdev->format != runtime->format)
	     || (i2sdev->rate != runtime->rate))) {
		result = -EINVAL;
		goto out_unlock;
	}

	i2sdev->format = runtime->format;
	i2sdev->rate = runtime->rate;

	periodsize = snd_pcm_lib_period_bytes(pi->substream);
	nperiods = pi->substream->runtime->periods;
	pi->current_period = 0;

	/* generate dbdma command ring first */
	command = pi->dbdma_ring.cmds;
	memset(command, 0, (nperiods + 2) * sizeof(struct dbdma_cmd));

	/* commands to DMA to/from the ring */
	/*
	 * For input, we need to do a graceful stop; if we abort
	 * the DMA, we end up with leftover bytes that corrupt
	 * the next recording.  To do this we set the S0 status
	 * bit and wait for the DMA controller to stop.  Each
	 * command has a branch condition to
	 * make it branch to a stop command if S0 is set.
	 * On input we also need to wait for the S7 bit to be
	 * set before turning off the DMA controller.
	 * In fact we do the graceful stop for output as well.
	 */
	offset = runtime->dma_addr;
	cmd = (in? INPUT_MORE: OUTPUT_MORE) | BR_IFSET | INTR_ALWAYS;
	stopaddr = pi->dbdma_ring.bus_cmd_start +
		(nperiods + 1) * sizeof(struct dbdma_cmd);
	for (i = 0; i < nperiods; i++, command++, offset += periodsize) {
		command->command = cpu_to_le16(cmd);
		command->cmd_dep = cpu_to_le32(stopaddr);
		command->phy_addr = cpu_to_le32(offset);
		command->req_count = cpu_to_le16(periodsize);
	}

	/* branch back to beginning of ring */
	command->command = cpu_to_le16(DBDMA_NOP | BR_ALWAYS);
	command->cmd_dep = cpu_to_le32(pi->dbdma_ring.bus_cmd_start);
	command++;

	/* set stop command */
	command->command = cpu_to_le16(DBDMA_STOP);

	/* ok, let's set the serial format and stuff */
	switch (runtime->format) {
	/* 16 bit formats */
	case SNDRV_PCM_FORMAT_S16_BE:
	case SNDRV_PCM_FORMAT_U16_BE:
		/* FIXME: if we add different bus factors we need to
		 * do more here!! */
		bi.bus_factor = 0;
		list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
			bi.bus_factor = cii->codec->bus_factor;
			break;
		}
		if (!bi.bus_factor) {
			result = -ENODEV;
			goto out_unlock;
		}
		input_16bit = 1;
		break;
	case SNDRV_PCM_FORMAT_S32_BE:
	case SNDRV_PCM_FORMAT_U32_BE:
		/* force 64x bus speed, otherwise the data cannot be
		 * transferred quickly enough! */
		bi.bus_factor = 64;
		input_16bit = 0;
		break;
	default:
		result = -EINVAL;
		goto out_unlock;
	}
	/* we assume all sysclocks are the same! */
	list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
		bi.sysclock_factor = cii->codec->sysclock_factor;
		break;
	}

	if (clock_and_divisors(bi.sysclock_factor,
			       bi.bus_factor,
			       runtime->rate,
			       &sfr) < 0) {
		result = -EINVAL;
		goto out_unlock;
	}
	switch (bi.bus_factor) {
	case 32:
		sfr |= I2S_SF_SERIAL_FORMAT_I2S_32X;
		break;
	case 64:
		sfr |= I2S_SF_SERIAL_FORMAT_I2S_64X;
		break;
	}
	/* FIXME: THIS ASSUMES MASTER ALL THE TIME */
	sfr |= I2S_SF_SCLK_MASTER;

	list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
		int err = 0;
		if (cii->codec->prepare)
			err = cii->codec->prepare(cii, &bi, pi->substream);
		if (err) {
			result = err;
			goto out_unlock;
		}
	}
	/* codecs are fine with it, so set our clocks */
	if (input_16bit)
		dws =	(2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
			(2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
			I2S_DWS_DATA_IN_16BIT | I2S_DWS_DATA_OUT_16BIT;
	else
		dws =	(2 << I2S_DWS_NUM_CHANNELS_IN_SHIFT) |
			(2 << I2S_DWS_NUM_CHANNELS_OUT_SHIFT) |
			I2S_DWS_DATA_IN_24BIT | I2S_DWS_DATA_OUT_24BIT;

	/* early exit if already programmed correctly */
	/* not locking these is fine since we touch them only in this function */
	if (in_le32(&i2sdev->intfregs->serial_format) == sfr
	 && in_le32(&i2sdev->intfregs->data_word_sizes) == dws)
		goto out_unlock;

	/* let's notify the codecs about clocks going away.
	 * For now we only do mastering on the i2s cell... */
	list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
		if (cii->codec->switch_clock)
			cii->codec->switch_clock(cii, CLOCK_SWITCH_PREPARE_SLAVE);

	i2sbus_control_enable(i2sdev->control, i2sdev);
	i2sbus_control_cell(i2sdev->control, i2sdev, 1);

	out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);

	i2sbus_control_clock(i2sdev->control, i2sdev, 0);

	msleep(1);

	/* wait for clock stopped. This can apparently take a while... */
	cnt = 100;
	while (cnt-- &&
	    !(in_le32(&i2sdev->intfregs->intr_ctl) & I2S_PENDING_CLOCKS_STOPPED)) {
		msleep(5);
	}
	out_le32(&i2sdev->intfregs->intr_ctl, I2S_PENDING_CLOCKS_STOPPED);

	/* not locking these is fine since we touch them only in this function */
	out_le32(&i2sdev->intfregs->serial_format, sfr);
	out_le32(&i2sdev->intfregs->data_word_sizes, dws);

        i2sbus_control_enable(i2sdev->control, i2sdev);
        i2sbus_control_cell(i2sdev->control, i2sdev, 1);
        i2sbus_control_clock(i2sdev->control, i2sdev, 1);
	msleep(1);

	list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
		if (cii->codec->switch_clock)
			cii->codec->switch_clock(cii, CLOCK_SWITCH_SLAVE);

 out_unlock:
	mutex_unlock(&i2sdev->lock);
	return result;
}

#ifdef CONFIG_PM
void i2sbus_pcm_prepare_both(struct i2sbus_dev *i2sdev)
{
	i2sbus_pcm_prepare(i2sdev, 0);
	i2sbus_pcm_prepare(i2sdev, 1);
}
#endif

static int i2sbus_pcm_trigger(struct i2sbus_dev *i2sdev, int in, int cmd)
{
	struct codec_info_item *cii;
	struct pcm_info *pi;
	int result = 0;
	unsigned long flags;

	spin_lock_irqsave(&i2sdev->low_lock, flags);

	get_pcm_info(i2sdev, in, &pi, NULL);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
		if (pi->dbdma_ring.running) {
			result = -EALREADY;
			goto out_unlock;
		}
		list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
			if (cii->codec->start)
				cii->codec->start(cii, pi->substream);
		pi->dbdma_ring.running = 1;

		if (pi->dbdma_ring.stopping) {
			/* Clear the S0 bit, then see if we stopped yet */
			out_le32(&pi->dbdma->control, 1 << 16);
			if (in_le32(&pi->dbdma->status) & ACTIVE) {
				/* possible race here? */
				udelay(10);
				if (in_le32(&pi->dbdma->status) & ACTIVE) {
					pi->dbdma_ring.stopping = 0;
					goto out_unlock; /* keep running */
				}
			}
		}

		/* make sure RUN, PAUSE and S0 bits are cleared */
		out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);

		/* set branch condition select register */
		out_le32(&pi->dbdma->br_sel, (1 << 16) | 1);

		/* write dma command buffer address to the dbdma chip */
		out_le32(&pi->dbdma->cmdptr, pi->dbdma_ring.bus_cmd_start);

		/* initialize the frame count and current period */
		pi->current_period = 0;
		pi->frame_count = in_le32(&i2sdev->intfregs->frame_count);

		/* set the DMA controller running */
		out_le32(&pi->dbdma->control, (RUN << 16) | RUN);

		/* off you go! */
		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
		if (!pi->dbdma_ring.running) {
			result = -EALREADY;
			goto out_unlock;
		}
		pi->dbdma_ring.running = 0;

		/* Set the S0 bit to make the DMA branch to the stop cmd */
		out_le32(&pi->dbdma->control, (1 << 16) | 1);
		pi->dbdma_ring.stopping = 1;

		list_for_each_entry(cii, &i2sdev->sound.codec_list, list)
			if (cii->codec->stop)
				cii->codec->stop(cii, pi->substream);
		break;
	default:
		result = -EINVAL;
		goto out_unlock;
	}

 out_unlock:
	spin_unlock_irqrestore(&i2sdev->low_lock, flags);
	return result;
}

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;

	if (fc >= pi->substream->runtime->buffer_size)
		fc %= pi->substream->runtime->buffer_size;
	return fc;
}

static inline void handle_interrupt(struct i2sbus_dev *i2sdev, int in)
{
	struct pcm_info *pi;
	u32 fc, nframes;
	u32 status;
	int timeout, i;
	int dma_stopped = 0;
	struct snd_pcm_runtime *runtime;

	spin_lock(&i2sdev->low_lock);
	get_pcm_info(i2sdev, in, &pi, NULL);
	if (!pi->dbdma_ring.running && !pi->dbdma_ring.stopping)
		goto out_unlock;

	i = pi->current_period;
	runtime = pi->substream->runtime;
	while (pi->dbdma_ring.cmds[i].xfer_status) {
		if (le16_to_cpu(pi->dbdma_ring.cmds[i].xfer_status) & BT)
			/*
			 * BT is the branch taken bit.  If it took a branch
			 * it is because we set the S0 bit to make it
			 * branch to the stop command.
			 */
			dma_stopped = 1;
		pi->dbdma_ring.cmds[i].xfer_status = 0;

		if (++i >= runtime->periods) {
			i = 0;
			pi->frame_count += runtime->buffer_size;
		}
		pi->current_period = i;

		/*
		 * Check the frame count.  The DMA tends to get a bit
		 * ahead of the frame counter, which confuses the core.
		 */
		fc = in_le32(&i2sdev->intfregs->frame_count);
		nframes = i * runtime->period_size;
		if (fc < pi->frame_count + nframes)
			pi->frame_count = fc - nframes;
	}

	if (dma_stopped) {
		timeout = 1000;
		for (;;) {
			status = in_le32(&pi->dbdma->status);
			if (!(status & ACTIVE) && (!in || (status & 0x80)))
				break;
			if (--timeout <= 0) {
				printk(KERN_ERR "i2sbus: timed out "
				       "waiting for DMA to stop!\n");
				break;
			}
			udelay(1);
		}

		/* Turn off DMA controller, clear S0 bit */
		out_le32(&pi->dbdma->control, (RUN | PAUSE | 1) << 16);

		pi->dbdma_ring.stopping = 0;
		if (pi->stop_completion)
			complete(pi->stop_completion);
	}

	if (!pi->dbdma_ring.running)
		goto out_unlock;
	spin_unlock(&i2sdev->low_lock);
	/* may call _trigger again, hence needs to be unlocked */
	snd_pcm_period_elapsed(pi->substream);
	return;

 out_unlock:
	spin_unlock(&i2sdev->low_lock);
}

irqreturn_t i2sbus_tx_intr(int irq, void *devid)
{
	handle_interrupt((struct i2sbus_dev *)devid, 0);
	return IRQ_HANDLED;
}

irqreturn_t i2sbus_rx_intr(int irq, void *devid)
{
	handle_interrupt((struct i2sbus_dev *)devid, 1);
	return IRQ_HANDLED;
}

static int i2sbus_playback_open(struct snd_pcm_substream *substream)
{
	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);

	if (!i2sdev)
		return -EINVAL;
	i2sdev->out.substream = substream;
	return i2sbus_pcm_open(i2sdev, 0);
}

static int i2sbus_playback_close(struct snd_pcm_substream *substream)
{
	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
	int err;

	if (!i2sdev)
		return -EINVAL;
	if (i2sdev->out.substream != substream)
		return -EINVAL;
	err = i2sbus_pcm_close(i2sdev, 0);
	if (!err)
		i2sdev->out.substream = NULL;
	return err;
}

static int i2sbus_playback_prepare(struct snd_pcm_substream *substream)
{
	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);

	if (!i2sdev)
		return -EINVAL;
	if (i2sdev->out.substream != substream)
		return -EINVAL;
	return i2sbus_pcm_prepare(i2sdev, 0);
}

static int i2sbus_playback_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);

	if (!i2sdev)
		return -EINVAL;
	if (i2sdev->out.substream != substream)
		return -EINVAL;
	return i2sbus_pcm_trigger(i2sdev, 0, cmd);
}

static snd_pcm_uframes_t i2sbus_playback_pointer(struct snd_pcm_substream
						 *substream)
{
	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);

	if (!i2sdev)
		return -EINVAL;
	if (i2sdev->out.substream != substream)
		return 0;
	return i2sbus_pcm_pointer(i2sdev, 0);
}

static struct snd_pcm_ops i2sbus_playback_ops = {
	.open =		i2sbus_playback_open,
	.close =	i2sbus_playback_close,
	.ioctl =	snd_pcm_lib_ioctl,
	.hw_params =	i2sbus_hw_params,
	.hw_free =	i2sbus_playback_hw_free,
	.prepare =	i2sbus_playback_prepare,
	.trigger =	i2sbus_playback_trigger,
	.pointer =	i2sbus_playback_pointer,
};

static int i2sbus_record_open(struct snd_pcm_substream *substream)
{
	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);

	if (!i2sdev)
		return -EINVAL;
	i2sdev->in.substream = substream;
	return i2sbus_pcm_open(i2sdev, 1);
}

static int i2sbus_record_close(struct snd_pcm_substream *substream)
{
	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);
	int err;

	if (!i2sdev)
		return -EINVAL;
	if (i2sdev->in.substream != substream)
		return -EINVAL;
	err = i2sbus_pcm_close(i2sdev, 1);
	if (!err)
		i2sdev->in.substream = NULL;
	return err;
}

static int i2sbus_record_prepare(struct snd_pcm_substream *substream)
{
	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);

	if (!i2sdev)
		return -EINVAL;
	if (i2sdev->in.substream != substream)
		return -EINVAL;
	return i2sbus_pcm_prepare(i2sdev, 1);
}

static int i2sbus_record_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);

	if (!i2sdev)
		return -EINVAL;
	if (i2sdev->in.substream != substream)
		return -EINVAL;
	return i2sbus_pcm_trigger(i2sdev, 1, cmd);
}

static snd_pcm_uframes_t i2sbus_record_pointer(struct snd_pcm_substream
					       *substream)
{
	struct i2sbus_dev *i2sdev = snd_pcm_substream_chip(substream);

	if (!i2sdev)
		return -EINVAL;
	if (i2sdev->in.substream != substream)
		return 0;
	return i2sbus_pcm_pointer(i2sdev, 1);
}

static struct snd_pcm_ops i2sbus_record_ops = {
	.open =		i2sbus_record_open,
	.close =	i2sbus_record_close,
	.ioctl =	snd_pcm_lib_ioctl,
	.hw_params =	i2sbus_hw_params,
	.hw_free =	i2sbus_record_hw_free,
	.prepare =	i2sbus_record_prepare,
	.trigger =	i2sbus_record_trigger,
	.pointer =	i2sbus_record_pointer,
};

static void i2sbus_private_free(struct snd_pcm *pcm)
{
	struct i2sbus_dev *i2sdev = snd_pcm_chip(pcm);
	struct codec_info_item *p, *tmp;

	i2sdev->sound.pcm = NULL;
	i2sdev->out.created = 0;
	i2sdev->in.created = 0;
	list_for_each_entry_safe(p, tmp, &i2sdev->sound.codec_list, list) {
		printk(KERN_ERR "i2sbus: a codec didn't unregister!\n");
		list_del(&p->list);
		module_put(p->codec->owner);
		kfree(p);
	}
	soundbus_dev_put(&i2sdev->sound);
	module_put(THIS_MODULE);
}

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");
		return -EINVAL;
	}

	list_for_each_entry(cii, &dev->codec_list, list) {
		if (cii->codec_data == data)
			return -EALREADY;
	}

	if (!ci->transfers || !ci->transfers->formats
	    || !ci->transfers->rates || !ci->usable)
		return -EINVAL;

	/* we currently code the i2s transfer on the clock, and support only
	 * 32 and 64 */
	if (ci->bus_factor != 32 && ci->bus_factor != 64)
		return -EINVAL;

	/* If you want to fix this, you need to keep track of what transport infos
	 * are to be used, which codecs they belong to, and then fix all the
	 * sysclock/busclock stuff above to depend on which is usable */
	list_for_each_entry(cii, &dev->codec_list, list) {
		if (cii->codec->sysclock_factor != ci->sysclock_factor) {
			printk(KERN_DEBUG
			       "cannot yet handle multiple different sysclocks!\n");
			return -EINVAL;
		}
		if (cii->codec->bus_factor != ci->bus_factor) {
			printk(KERN_DEBUG
			       "cannot yet handle multiple different bus clocks!\n");
			return -EINVAL;
		}
	}

	tmp = ci->transfers;
	while (tmp->formats && tmp->rates) {
		if (tmp->transfer_in)
			in = 1;
		else
			out = 1;
		tmp++;
	}

	cii = kzalloc(sizeof(struct codec_info_item), GFP_KERNEL);
	if (!cii) {
		printk(KERN_DEBUG "i2sbus: failed to allocate cii\n");
		return -ENOMEM;
	}

	/* use the private data to point to the codec info */
	cii->sdev = soundbus_dev_get(dev);
	cii->codec = ci;
	cii->codec_data = data;

	if (!cii->sdev) {
		printk(KERN_DEBUG
		       "i2sbus: failed to get soundbus dev reference\n");
		err = -ENODEV;
		goto out_free_cii;
	}

	if (!try_module_get(THIS_MODULE)) {
		printk(KERN_DEBUG "i2sbus: failed to get module reference!\n");
		err = -EBUSY;
		goto out_put_sdev;
	}

	if (!try_module_get(ci->owner)) {
		printk(KERN_DEBUG
		       "i2sbus: failed to get module reference to codec owner!\n");
		err = -EBUSY;
		goto out_put_this_module;
	}

	if (!dev->pcm) {
		err = snd_pcm_new(card, dev->pcmname, dev->pcmid, 0, 0,
				  &dev->pcm);
		if (err) {
			printk(KERN_DEBUG "i2sbus: failed to create pcm\n");
			goto out_put_ci_module;
		}
		dev->pcm->dev = &dev->ofdev.dev;
	}

	/* ALSA yet again sucks.
	 * If it is ever fixed, remove this line. See below. */
	out = in = 1;

	if (!i2sdev->out.created && out) {
		if (dev->pcm->card != card) {
			/* eh? */
			printk(KERN_ERR
			       "Can't attach same bus to different cards!\n");
			err = -EINVAL;
			goto out_put_ci_module;
		}
		err = snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, 1);
		if (err)
			goto out_put_ci_module;
		snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK,
				&i2sbus_playback_ops);
		i2sdev->out.created = 1;
	}

	if (!i2sdev->in.created && in) {
		if (dev->pcm->card != card) {
			printk(KERN_ERR
			       "Can't attach same bus to different cards!\n");
			err = -EINVAL;
			goto out_put_ci_module;
		}
		err = snd_pcm_new_stream(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, 1);
		if (err)
			goto out_put_ci_module;
		snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE,
				&i2sbus_record_ops);
		i2sdev->in.created = 1;
	}

	/* so we have to register the pcm after adding any substream
	 * to it because alsa doesn't create the devices for the
	 * substreams when we add them later.
	 * Therefore, force in and out on both busses (above) and
	 * register the pcm now instead of just after creating it.
	 */
	err = snd_device_register(card, dev->pcm);
	if (err) {
		printk(KERN_ERR "i2sbus: error registering new pcm\n");
		goto out_put_ci_module;
	}
	/* no errors any more, so let's add this to our list */
	list_add(&cii->list, &dev->codec_list);

	dev->pcm->private_data = i2sdev;
	dev->pcm->private_free = i2sbus_private_free;

	/* well, we really should support scatter/gather DMA */
	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);

	return 0;
 out_put_ci_module:
	module_put(ci->owner);
 out_put_this_module:
	module_put(THIS_MODULE);
 out_put_sdev:
	soundbus_dev_put(dev);
 out_free_cii:
	kfree(cii);
	return err;
}

void i2sbus_detach_codec(struct soundbus_dev *dev, void *data)
{
	struct codec_info_item *cii = NULL, *i;

	list_for_each_entry(i, &dev->codec_list, list) {
		if (i->codec_data == data) {
			cii = i;
			break;
		}
	}
	if (cii) {
		list_del(&cii->list);
		module_put(cii->codec->owner);
		kfree(cii);
	}
	/* no more codecs, but still a pcm? */
	if (list_empty(&dev->codec_list) && dev->pcm) {
		/* the actual cleanup is done by the callback above! */
		snd_device_free(dev->pcm->card, dev->pcm);
	}
}
