/*
 * C-Media CMI8788 driver - PCM code
 *
 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
 *
 *
 *  This driver is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License, version 2.
 *
 *  This driver is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this driver; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

#include <linux/pci.h>
#include <sound/control.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include "oxygen.h"

/* most DMA channels have a 16-bit counter for 32-bit words */
#define BUFFER_BYTES_MAX		((1 << 16) * 4)
/* the multichannel DMA channel has a 24-bit counter */
#define BUFFER_BYTES_MAX_MULTICH	((1 << 24) * 4)

#define PERIOD_BYTES_MIN		64

#define DEFAULT_BUFFER_BYTES		(BUFFER_BYTES_MAX / 2)
#define DEFAULT_BUFFER_BYTES_MULTICH	(1024 * 1024)

static const struct snd_pcm_hardware oxygen_stereo_hardware = {
	.info = SNDRV_PCM_INFO_MMAP |
		SNDRV_PCM_INFO_MMAP_VALID |
		SNDRV_PCM_INFO_INTERLEAVED |
		SNDRV_PCM_INFO_PAUSE |
		SNDRV_PCM_INFO_SYNC_START,
	.formats = SNDRV_PCM_FMTBIT_S16_LE |
		   SNDRV_PCM_FMTBIT_S32_LE,
	.rates = SNDRV_PCM_RATE_32000 |
		 SNDRV_PCM_RATE_44100 |
		 SNDRV_PCM_RATE_48000 |
		 SNDRV_PCM_RATE_64000 |
		 SNDRV_PCM_RATE_88200 |
		 SNDRV_PCM_RATE_96000 |
		 SNDRV_PCM_RATE_176400 |
		 SNDRV_PCM_RATE_192000,
	.rate_min = 32000,
	.rate_max = 192000,
	.channels_min = 2,
	.channels_max = 2,
	.buffer_bytes_max = BUFFER_BYTES_MAX,
	.period_bytes_min = PERIOD_BYTES_MIN,
	.period_bytes_max = BUFFER_BYTES_MAX,
	.periods_min = 1,
	.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
};
static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
	.info = SNDRV_PCM_INFO_MMAP |
		SNDRV_PCM_INFO_MMAP_VALID |
		SNDRV_PCM_INFO_INTERLEAVED |
		SNDRV_PCM_INFO_PAUSE |
		SNDRV_PCM_INFO_SYNC_START,
	.formats = SNDRV_PCM_FMTBIT_S16_LE |
		   SNDRV_PCM_FMTBIT_S32_LE,
	.rates = SNDRV_PCM_RATE_32000 |
		 SNDRV_PCM_RATE_44100 |
		 SNDRV_PCM_RATE_48000 |
		 SNDRV_PCM_RATE_64000 |
		 SNDRV_PCM_RATE_88200 |
		 SNDRV_PCM_RATE_96000 |
		 SNDRV_PCM_RATE_176400 |
		 SNDRV_PCM_RATE_192000,
	.rate_min = 32000,
	.rate_max = 192000,
	.channels_min = 2,
	.channels_max = 8,
	.buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH,
	.period_bytes_min = PERIOD_BYTES_MIN,
	.period_bytes_max = BUFFER_BYTES_MAX_MULTICH,
	.periods_min = 1,
	.periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN,
};
static const struct snd_pcm_hardware oxygen_ac97_hardware = {
	.info = SNDRV_PCM_INFO_MMAP |
		SNDRV_PCM_INFO_MMAP_VALID |
		SNDRV_PCM_INFO_INTERLEAVED |
		SNDRV_PCM_INFO_PAUSE |
		SNDRV_PCM_INFO_SYNC_START,
	.formats = SNDRV_PCM_FMTBIT_S16_LE,
	.rates = SNDRV_PCM_RATE_48000,
	.rate_min = 48000,
	.rate_max = 48000,
	.channels_min = 2,
	.channels_max = 2,
	.buffer_bytes_max = BUFFER_BYTES_MAX,
	.period_bytes_min = PERIOD_BYTES_MIN,
	.period_bytes_max = BUFFER_BYTES_MAX,
	.periods_min = 1,
	.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
};

static const struct snd_pcm_hardware *const oxygen_hardware[PCM_COUNT] = {
	[PCM_A] = &oxygen_stereo_hardware,
	[PCM_B] = &oxygen_stereo_hardware,
	[PCM_C] = &oxygen_stereo_hardware,
	[PCM_SPDIF] = &oxygen_stereo_hardware,
	[PCM_MULTICH] = &oxygen_multichannel_hardware,
	[PCM_AC97] = &oxygen_ac97_hardware,
};

static inline unsigned int
oxygen_substream_channel(struct snd_pcm_substream *substream)
{
	return (unsigned int)(uintptr_t)substream->runtime->private_data;
}

static int oxygen_open(struct snd_pcm_substream *substream,
		       unsigned int channel)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	int err;

	runtime->private_data = (void *)(uintptr_t)channel;
	if (channel == PCM_B && chip->has_ac97_1 &&
	    (chip->model.device_config & CAPTURE_2_FROM_AC97_1))
		runtime->hw = oxygen_ac97_hardware;
	else
		runtime->hw = *oxygen_hardware[channel];
	switch (channel) {
	case PCM_C:
		runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 |
				       SNDRV_PCM_RATE_64000);
		runtime->hw.rate_min = 44100;
		break;
	case PCM_MULTICH:
		runtime->hw.channels_max = chip->model.dac_channels;
		break;
	}
	if (chip->model.pcm_hardware_filter)
		chip->model.pcm_hardware_filter(channel, &runtime->hw);
	err = snd_pcm_hw_constraint_step(runtime, 0,
					 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
	if (err < 0)
		return err;
	err = snd_pcm_hw_constraint_step(runtime, 0,
					 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
	if (err < 0)
		return err;
	if (runtime->hw.formats & SNDRV_PCM_FMTBIT_S32_LE) {
		err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
		if (err < 0)
			return err;
	}
	if (runtime->hw.channels_max > 2) {
		err = snd_pcm_hw_constraint_step(runtime, 0,
						 SNDRV_PCM_HW_PARAM_CHANNELS,
						 2);
		if (err < 0)
			return err;
	}
	if (channel == PCM_MULTICH) {
		err = snd_pcm_hw_constraint_minmax
			(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 0, 8192000);
		if (err < 0)
			return err;
	}
	snd_pcm_set_sync(substream);
	chip->streams[channel] = substream;

	mutex_lock(&chip->mutex);
	chip->pcm_active |= 1 << channel;
	if (channel == PCM_SPDIF) {
		chip->spdif_pcm_bits = chip->spdif_bits;
		chip->controls[CONTROL_SPDIF_PCM]->vd[0].access &=
			~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
			       SNDRV_CTL_EVENT_MASK_INFO,
			       &chip->controls[CONTROL_SPDIF_PCM]->id);
	}
	mutex_unlock(&chip->mutex);

	return 0;
}

static int oxygen_rec_a_open(struct snd_pcm_substream *substream)
{
	return oxygen_open(substream, PCM_A);
}

static int oxygen_rec_b_open(struct snd_pcm_substream *substream)
{
	return oxygen_open(substream, PCM_B);
}

static int oxygen_rec_c_open(struct snd_pcm_substream *substream)
{
	return oxygen_open(substream, PCM_C);
}

static int oxygen_spdif_open(struct snd_pcm_substream *substream)
{
	return oxygen_open(substream, PCM_SPDIF);
}

static int oxygen_multich_open(struct snd_pcm_substream *substream)
{
	return oxygen_open(substream, PCM_MULTICH);
}

static int oxygen_ac97_open(struct snd_pcm_substream *substream)
{
	return oxygen_open(substream, PCM_AC97);
}

static int oxygen_close(struct snd_pcm_substream *substream)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	unsigned int channel = oxygen_substream_channel(substream);

	mutex_lock(&chip->mutex);
	chip->pcm_active &= ~(1 << channel);
	if (channel == PCM_SPDIF) {
		chip->controls[CONTROL_SPDIF_PCM]->vd[0].access |=
			SNDRV_CTL_ELEM_ACCESS_INACTIVE;
		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
			       SNDRV_CTL_EVENT_MASK_INFO,
			       &chip->controls[CONTROL_SPDIF_PCM]->id);
	}
	if (channel == PCM_SPDIF || channel == PCM_MULTICH)
		oxygen_update_spdif_source(chip);
	mutex_unlock(&chip->mutex);

	chip->streams[channel] = NULL;
	return 0;
}

static unsigned int oxygen_format(struct snd_pcm_hw_params *hw_params)
{
	if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
		return OXYGEN_FORMAT_24;
	else
		return OXYGEN_FORMAT_16;
}

static unsigned int oxygen_rate(struct snd_pcm_hw_params *hw_params)
{
	switch (params_rate(hw_params)) {
	case 32000:
		return OXYGEN_RATE_32000;
	case 44100:
		return OXYGEN_RATE_44100;
	default: /* 48000 */
		return OXYGEN_RATE_48000;
	case 64000:
		return OXYGEN_RATE_64000;
	case 88200:
		return OXYGEN_RATE_88200;
	case 96000:
		return OXYGEN_RATE_96000;
	case 176400:
		return OXYGEN_RATE_176400;
	case 192000:
		return OXYGEN_RATE_192000;
	}
}

unsigned int oxygen_default_i2s_mclk(struct oxygen *chip,
				     unsigned int channel,
				     struct snd_pcm_hw_params *hw_params)
{
	if (params_rate(hw_params) <= 96000)
		return OXYGEN_I2S_MCLK_256;
	else
		return OXYGEN_I2S_MCLK_128;
}
EXPORT_SYMBOL(oxygen_default_i2s_mclk);

static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params)
{
	if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
		return OXYGEN_I2S_BITS_24;
	else
		return OXYGEN_I2S_BITS_16;
}

static unsigned int oxygen_play_channels(struct snd_pcm_hw_params *hw_params)
{
	switch (params_channels(hw_params)) {
	default: /* 2 */
		return OXYGEN_PLAY_CHANNELS_2;
	case 4:
		return OXYGEN_PLAY_CHANNELS_4;
	case 6:
		return OXYGEN_PLAY_CHANNELS_6;
	case 8:
		return OXYGEN_PLAY_CHANNELS_8;
	}
}

static const unsigned int channel_base_registers[PCM_COUNT] = {
	[PCM_A] = OXYGEN_DMA_A_ADDRESS,
	[PCM_B] = OXYGEN_DMA_B_ADDRESS,
	[PCM_C] = OXYGEN_DMA_C_ADDRESS,
	[PCM_SPDIF] = OXYGEN_DMA_SPDIF_ADDRESS,
	[PCM_MULTICH] = OXYGEN_DMA_MULTICH_ADDRESS,
	[PCM_AC97] = OXYGEN_DMA_AC97_ADDRESS,
};

static int oxygen_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *hw_params)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	unsigned int channel = oxygen_substream_channel(substream);
	int err;

	err = snd_pcm_lib_malloc_pages(substream,
				       params_buffer_bytes(hw_params));
	if (err < 0)
		return err;

	oxygen_write32(chip, channel_base_registers[channel],
		       (u32)substream->runtime->dma_addr);
	if (channel == PCM_MULTICH) {
		oxygen_write32(chip, OXYGEN_DMA_MULTICH_COUNT,
			       params_buffer_bytes(hw_params) / 4 - 1);
		oxygen_write32(chip, OXYGEN_DMA_MULTICH_TCOUNT,
			       params_period_bytes(hw_params) / 4 - 1);
	} else {
		oxygen_write16(chip, channel_base_registers[channel] + 4,
			       params_buffer_bytes(hw_params) / 4 - 1);
		oxygen_write16(chip, channel_base_registers[channel] + 6,
			       params_period_bytes(hw_params) / 4 - 1);
	}
	return 0;
}

static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
				  struct snd_pcm_hw_params *hw_params)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	int err;

	err = oxygen_hw_params(substream, hw_params);
	if (err < 0)
		return err;

	spin_lock_irq(&chip->reg_lock);
	oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
			     oxygen_format(hw_params) << OXYGEN_REC_FORMAT_A_SHIFT,
			     OXYGEN_REC_FORMAT_A_MASK);
	oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
			      oxygen_rate(hw_params) |
			      chip->model.get_i2s_mclk(chip, PCM_A, hw_params) |
			      chip->model.adc_i2s_format |
			      oxygen_i2s_bits(hw_params),
			      OXYGEN_I2S_RATE_MASK |
			      OXYGEN_I2S_FORMAT_MASK |
			      OXYGEN_I2S_MCLK_MASK |
			      OXYGEN_I2S_BITS_MASK);
	spin_unlock_irq(&chip->reg_lock);

	mutex_lock(&chip->mutex);
	chip->model.set_adc_params(chip, hw_params);
	mutex_unlock(&chip->mutex);
	return 0;
}

static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
				  struct snd_pcm_hw_params *hw_params)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	int is_ac97;
	int err;

	err = oxygen_hw_params(substream, hw_params);
	if (err < 0)
		return err;

	is_ac97 = chip->has_ac97_1 &&
		(chip->model.device_config & CAPTURE_2_FROM_AC97_1);

	spin_lock_irq(&chip->reg_lock);
	oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
			     oxygen_format(hw_params) << OXYGEN_REC_FORMAT_B_SHIFT,
			     OXYGEN_REC_FORMAT_B_MASK);
	if (!is_ac97)
		oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
				      oxygen_rate(hw_params) |
				      chip->model.get_i2s_mclk(chip, PCM_B,
							       hw_params) |
				      chip->model.adc_i2s_format |
				      oxygen_i2s_bits(hw_params),
				      OXYGEN_I2S_RATE_MASK |
				      OXYGEN_I2S_FORMAT_MASK |
				      OXYGEN_I2S_MCLK_MASK |
				      OXYGEN_I2S_BITS_MASK);
	spin_unlock_irq(&chip->reg_lock);

	if (!is_ac97) {
		mutex_lock(&chip->mutex);
		chip->model.set_adc_params(chip, hw_params);
		mutex_unlock(&chip->mutex);
	}
	return 0;
}

static int oxygen_rec_c_hw_params(struct snd_pcm_substream *substream,
				  struct snd_pcm_hw_params *hw_params)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	int err;

	err = oxygen_hw_params(substream, hw_params);
	if (err < 0)
		return err;

	spin_lock_irq(&chip->reg_lock);
	oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
			     oxygen_format(hw_params) << OXYGEN_REC_FORMAT_C_SHIFT,
			     OXYGEN_REC_FORMAT_C_MASK);
	spin_unlock_irq(&chip->reg_lock);
	return 0;
}

static int oxygen_spdif_hw_params(struct snd_pcm_substream *substream,
				  struct snd_pcm_hw_params *hw_params)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	int err;

	err = oxygen_hw_params(substream, hw_params);
	if (err < 0)
		return err;

	mutex_lock(&chip->mutex);
	spin_lock_irq(&chip->reg_lock);
	oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
			    OXYGEN_SPDIF_OUT_ENABLE);
	oxygen_write8_masked(chip, OXYGEN_PLAY_FORMAT,
			     oxygen_format(hw_params) << OXYGEN_SPDIF_FORMAT_SHIFT,
			     OXYGEN_SPDIF_FORMAT_MASK);
	oxygen_write32_masked(chip, OXYGEN_SPDIF_CONTROL,
			      oxygen_rate(hw_params) << OXYGEN_SPDIF_OUT_RATE_SHIFT,
			      OXYGEN_SPDIF_OUT_RATE_MASK);
	oxygen_update_spdif_source(chip);
	spin_unlock_irq(&chip->reg_lock);
	mutex_unlock(&chip->mutex);
	return 0;
}

static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
				    struct snd_pcm_hw_params *hw_params)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	int err;

	err = oxygen_hw_params(substream, hw_params);
	if (err < 0)
		return err;

	mutex_lock(&chip->mutex);
	spin_lock_irq(&chip->reg_lock);
	oxygen_write8_masked(chip, OXYGEN_PLAY_CHANNELS,
			     oxygen_play_channels(hw_params),
			     OXYGEN_PLAY_CHANNELS_MASK);
	oxygen_write8_masked(chip, OXYGEN_PLAY_FORMAT,
			     oxygen_format(hw_params) << OXYGEN_MULTICH_FORMAT_SHIFT,
			     OXYGEN_MULTICH_FORMAT_MASK);
	oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
			      oxygen_rate(hw_params) |
			      chip->model.dac_i2s_format |
			      chip->model.get_i2s_mclk(chip, PCM_MULTICH,
						       hw_params) |
			      oxygen_i2s_bits(hw_params),
			      OXYGEN_I2S_RATE_MASK |
			      OXYGEN_I2S_FORMAT_MASK |
			      OXYGEN_I2S_MCLK_MASK |
			      OXYGEN_I2S_BITS_MASK);
	oxygen_update_spdif_source(chip);
	spin_unlock_irq(&chip->reg_lock);

	chip->model.set_dac_params(chip, hw_params);
	oxygen_update_dac_routing(chip);
	mutex_unlock(&chip->mutex);
	return 0;
}

static int oxygen_hw_free(struct snd_pcm_substream *substream)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	unsigned int channel = oxygen_substream_channel(substream);
	unsigned int channel_mask = 1 << channel;

	spin_lock_irq(&chip->reg_lock);
	chip->interrupt_mask &= ~channel_mask;
	oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);

	oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
	oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
	spin_unlock_irq(&chip->reg_lock);

	return snd_pcm_lib_free_pages(substream);
}

static int oxygen_spdif_hw_free(struct snd_pcm_substream *substream)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);

	spin_lock_irq(&chip->reg_lock);
	oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
			    OXYGEN_SPDIF_OUT_ENABLE);
	spin_unlock_irq(&chip->reg_lock);
	return oxygen_hw_free(substream);
}

static int oxygen_prepare(struct snd_pcm_substream *substream)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	unsigned int channel = oxygen_substream_channel(substream);
	unsigned int channel_mask = 1 << channel;

	spin_lock_irq(&chip->reg_lock);
	oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
	oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);

	chip->interrupt_mask |= channel_mask;
	oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
	spin_unlock_irq(&chip->reg_lock);
	return 0;
}

static int oxygen_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	struct snd_pcm_substream *s;
	unsigned int mask = 0;
	int pausing;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_SUSPEND:
		pausing = 0;
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		pausing = 1;
		break;
	default:
		return -EINVAL;
	}

	snd_pcm_group_for_each_entry(s, substream) {
		if (snd_pcm_substream_chip(s) == chip) {
			mask |= 1 << oxygen_substream_channel(s);
			snd_pcm_trigger_done(s, substream);
		}
	}

	spin_lock(&chip->reg_lock);
	if (!pausing) {
		if (cmd == SNDRV_PCM_TRIGGER_START)
			chip->pcm_running |= mask;
		else
			chip->pcm_running &= ~mask;
		oxygen_write8(chip, OXYGEN_DMA_STATUS, chip->pcm_running);
	} else {
		if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
			oxygen_set_bits8(chip, OXYGEN_DMA_PAUSE, mask);
		else
			oxygen_clear_bits8(chip, OXYGEN_DMA_PAUSE, mask);
	}
	spin_unlock(&chip->reg_lock);
	return 0;
}

static snd_pcm_uframes_t oxygen_pointer(struct snd_pcm_substream *substream)
{
	struct oxygen *chip = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	unsigned int channel = oxygen_substream_channel(substream);
	u32 curr_addr;

	/* no spinlock, this read should be atomic */
	curr_addr = oxygen_read32(chip, channel_base_registers[channel]);
	return bytes_to_frames(runtime, curr_addr - (u32)runtime->dma_addr);
}

static struct snd_pcm_ops oxygen_rec_a_ops = {
	.open      = oxygen_rec_a_open,
	.close     = oxygen_close,
	.ioctl     = snd_pcm_lib_ioctl,
	.hw_params = oxygen_rec_a_hw_params,
	.hw_free   = oxygen_hw_free,
	.prepare   = oxygen_prepare,
	.trigger   = oxygen_trigger,
	.pointer   = oxygen_pointer,
};

static struct snd_pcm_ops oxygen_rec_b_ops = {
	.open      = oxygen_rec_b_open,
	.close     = oxygen_close,
	.ioctl     = snd_pcm_lib_ioctl,
	.hw_params = oxygen_rec_b_hw_params,
	.hw_free   = oxygen_hw_free,
	.prepare   = oxygen_prepare,
	.trigger   = oxygen_trigger,
	.pointer   = oxygen_pointer,
};

static struct snd_pcm_ops oxygen_rec_c_ops = {
	.open      = oxygen_rec_c_open,
	.close     = oxygen_close,
	.ioctl     = snd_pcm_lib_ioctl,
	.hw_params = oxygen_rec_c_hw_params,
	.hw_free   = oxygen_hw_free,
	.prepare   = oxygen_prepare,
	.trigger   = oxygen_trigger,
	.pointer   = oxygen_pointer,
};

static struct snd_pcm_ops oxygen_spdif_ops = {
	.open      = oxygen_spdif_open,
	.close     = oxygen_close,
	.ioctl     = snd_pcm_lib_ioctl,
	.hw_params = oxygen_spdif_hw_params,
	.hw_free   = oxygen_spdif_hw_free,
	.prepare   = oxygen_prepare,
	.trigger   = oxygen_trigger,
	.pointer   = oxygen_pointer,
};

static struct snd_pcm_ops oxygen_multich_ops = {
	.open      = oxygen_multich_open,
	.close     = oxygen_close,
	.ioctl     = snd_pcm_lib_ioctl,
	.hw_params = oxygen_multich_hw_params,
	.hw_free   = oxygen_hw_free,
	.prepare   = oxygen_prepare,
	.trigger   = oxygen_trigger,
	.pointer   = oxygen_pointer,
};

static struct snd_pcm_ops oxygen_ac97_ops = {
	.open      = oxygen_ac97_open,
	.close     = oxygen_close,
	.ioctl     = snd_pcm_lib_ioctl,
	.hw_params = oxygen_hw_params,
	.hw_free   = oxygen_hw_free,
	.prepare   = oxygen_prepare,
	.trigger   = oxygen_trigger,
	.pointer   = oxygen_pointer,
};

static void oxygen_pcm_free(struct snd_pcm *pcm)
{
	snd_pcm_lib_preallocate_free_for_all(pcm);
}

int oxygen_pcm_init(struct oxygen *chip)
{
	struct snd_pcm *pcm;
	int outs, ins;
	int err;

	outs = !!(chip->model.device_config & PLAYBACK_0_TO_I2S);
	ins = !!(chip->model.device_config & (CAPTURE_0_FROM_I2S_1 |
					      CAPTURE_0_FROM_I2S_2));
	if (outs | ins) {
		err = snd_pcm_new(chip->card, "Multichannel",
				  0, outs, ins, &pcm);
		if (err < 0)
			return err;
		if (outs)
			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
					&oxygen_multich_ops);
		if (chip->model.device_config & CAPTURE_0_FROM_I2S_1)
			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
					&oxygen_rec_a_ops);
		else if (chip->model.device_config & CAPTURE_0_FROM_I2S_2)
			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
					&oxygen_rec_b_ops);
		pcm->private_data = chip;
		pcm->private_free = oxygen_pcm_free;
		strcpy(pcm->name, "Multichannel");
		if (outs)
			snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
						      SNDRV_DMA_TYPE_DEV,
						      snd_dma_pci_data(chip->pci),
						      DEFAULT_BUFFER_BYTES_MULTICH,
						      BUFFER_BYTES_MAX_MULTICH);
		if (ins)
			snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
						      SNDRV_DMA_TYPE_DEV,
						      snd_dma_pci_data(chip->pci),
						      DEFAULT_BUFFER_BYTES,
						      BUFFER_BYTES_MAX);
	}

	outs = !!(chip->model.device_config & PLAYBACK_1_TO_SPDIF);
	ins = !!(chip->model.device_config & CAPTURE_1_FROM_SPDIF);
	if (outs | ins) {
		err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm);
		if (err < 0)
			return err;
		if (outs)
			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
					&oxygen_spdif_ops);
		if (ins)
			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
					&oxygen_rec_c_ops);
		pcm->private_data = chip;
		pcm->private_free = oxygen_pcm_free;
		strcpy(pcm->name, "Digital");
		snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
						      snd_dma_pci_data(chip->pci),
						      DEFAULT_BUFFER_BYTES,
						      BUFFER_BYTES_MAX);
	}

	if (chip->has_ac97_1) {
		outs = !!(chip->model.device_config & PLAYBACK_2_TO_AC97_1);
		ins = !!(chip->model.device_config & CAPTURE_2_FROM_AC97_1);
	} else {
		outs = 0;
		ins = !!(chip->model.device_config & CAPTURE_2_FROM_I2S_2);
	}
	if (outs | ins) {
		err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2",
				  2, outs, ins, &pcm);
		if (err < 0)
			return err;
		if (outs) {
			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
					&oxygen_ac97_ops);
			oxygen_write8_masked(chip, OXYGEN_REC_ROUTING,
					     OXYGEN_REC_B_ROUTE_AC97_1,
					     OXYGEN_REC_B_ROUTE_MASK);
		}
		if (ins)
			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
					&oxygen_rec_b_ops);
		pcm->private_data = chip;
		pcm->private_free = oxygen_pcm_free;
		strcpy(pcm->name, outs ? "Front Panel" : "Analog 2");
		snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
						      snd_dma_pci_data(chip->pci),
						      DEFAULT_BUFFER_BYTES,
						      BUFFER_BYTES_MAX);
	}
	return 0;
}
