cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

oxygen_pcm.c (22477B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * C-Media CMI8788 driver - PCM code
      4 *
      5 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
      6 */
      7
      8#include <linux/pci.h>
      9#include <sound/control.h>
     10#include <sound/core.h>
     11#include <sound/pcm.h>
     12#include <sound/pcm_params.h>
     13#include "oxygen.h"
     14
     15/* most DMA channels have a 16-bit counter for 32-bit words */
     16#define BUFFER_BYTES_MAX		((1 << 16) * 4)
     17/* the multichannel DMA channel has a 24-bit counter */
     18#define BUFFER_BYTES_MAX_MULTICH	((1 << 24) * 4)
     19
     20#define FIFO_BYTES			256
     21#define FIFO_BYTES_MULTICH		1024
     22
     23#define PERIOD_BYTES_MIN		64
     24
     25#define DEFAULT_BUFFER_BYTES		(BUFFER_BYTES_MAX / 2)
     26#define DEFAULT_BUFFER_BYTES_MULTICH	(1024 * 1024)
     27
     28static const struct snd_pcm_hardware oxygen_stereo_hardware = {
     29	.info = SNDRV_PCM_INFO_MMAP |
     30		SNDRV_PCM_INFO_MMAP_VALID |
     31		SNDRV_PCM_INFO_INTERLEAVED |
     32		SNDRV_PCM_INFO_PAUSE |
     33		SNDRV_PCM_INFO_SYNC_START |
     34		SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
     35	.formats = SNDRV_PCM_FMTBIT_S16_LE |
     36		   SNDRV_PCM_FMTBIT_S32_LE,
     37	.rates = SNDRV_PCM_RATE_32000 |
     38		 SNDRV_PCM_RATE_44100 |
     39		 SNDRV_PCM_RATE_48000 |
     40		 SNDRV_PCM_RATE_64000 |
     41		 SNDRV_PCM_RATE_88200 |
     42		 SNDRV_PCM_RATE_96000 |
     43		 SNDRV_PCM_RATE_176400 |
     44		 SNDRV_PCM_RATE_192000,
     45	.rate_min = 32000,
     46	.rate_max = 192000,
     47	.channels_min = 2,
     48	.channels_max = 2,
     49	.buffer_bytes_max = BUFFER_BYTES_MAX,
     50	.period_bytes_min = PERIOD_BYTES_MIN,
     51	.period_bytes_max = BUFFER_BYTES_MAX,
     52	.periods_min = 1,
     53	.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
     54	.fifo_size = FIFO_BYTES,
     55};
     56static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
     57	.info = SNDRV_PCM_INFO_MMAP |
     58		SNDRV_PCM_INFO_MMAP_VALID |
     59		SNDRV_PCM_INFO_INTERLEAVED |
     60		SNDRV_PCM_INFO_PAUSE |
     61		SNDRV_PCM_INFO_SYNC_START |
     62		SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
     63	.formats = SNDRV_PCM_FMTBIT_S16_LE |
     64		   SNDRV_PCM_FMTBIT_S32_LE,
     65	.rates = SNDRV_PCM_RATE_32000 |
     66		 SNDRV_PCM_RATE_44100 |
     67		 SNDRV_PCM_RATE_48000 |
     68		 SNDRV_PCM_RATE_64000 |
     69		 SNDRV_PCM_RATE_88200 |
     70		 SNDRV_PCM_RATE_96000 |
     71		 SNDRV_PCM_RATE_176400 |
     72		 SNDRV_PCM_RATE_192000,
     73	.rate_min = 32000,
     74	.rate_max = 192000,
     75	.channels_min = 2,
     76	.channels_max = 8,
     77	.buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH,
     78	.period_bytes_min = PERIOD_BYTES_MIN,
     79	.period_bytes_max = BUFFER_BYTES_MAX_MULTICH,
     80	.periods_min = 1,
     81	.periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN,
     82	.fifo_size = FIFO_BYTES_MULTICH,
     83};
     84static const struct snd_pcm_hardware oxygen_ac97_hardware = {
     85	.info = SNDRV_PCM_INFO_MMAP |
     86		SNDRV_PCM_INFO_MMAP_VALID |
     87		SNDRV_PCM_INFO_INTERLEAVED |
     88		SNDRV_PCM_INFO_PAUSE |
     89		SNDRV_PCM_INFO_SYNC_START |
     90		SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
     91	.formats = SNDRV_PCM_FMTBIT_S16_LE,
     92	.rates = SNDRV_PCM_RATE_48000,
     93	.rate_min = 48000,
     94	.rate_max = 48000,
     95	.channels_min = 2,
     96	.channels_max = 2,
     97	.buffer_bytes_max = BUFFER_BYTES_MAX,
     98	.period_bytes_min = PERIOD_BYTES_MIN,
     99	.period_bytes_max = BUFFER_BYTES_MAX,
    100	.periods_min = 1,
    101	.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
    102	.fifo_size = FIFO_BYTES,
    103};
    104
    105static const struct snd_pcm_hardware *const oxygen_hardware[PCM_COUNT] = {
    106	[PCM_A] = &oxygen_stereo_hardware,
    107	[PCM_B] = &oxygen_stereo_hardware,
    108	[PCM_C] = &oxygen_stereo_hardware,
    109	[PCM_SPDIF] = &oxygen_stereo_hardware,
    110	[PCM_MULTICH] = &oxygen_multichannel_hardware,
    111	[PCM_AC97] = &oxygen_ac97_hardware,
    112};
    113
    114static inline unsigned int
    115oxygen_substream_channel(struct snd_pcm_substream *substream)
    116{
    117	return (unsigned int)(uintptr_t)substream->runtime->private_data;
    118}
    119
    120static int oxygen_open(struct snd_pcm_substream *substream,
    121		       unsigned int channel)
    122{
    123	struct oxygen *chip = snd_pcm_substream_chip(substream);
    124	struct snd_pcm_runtime *runtime = substream->runtime;
    125	int err;
    126
    127	runtime->private_data = (void *)(uintptr_t)channel;
    128	if (channel == PCM_B && chip->has_ac97_1 &&
    129	    (chip->model.device_config & CAPTURE_2_FROM_AC97_1))
    130		runtime->hw = oxygen_ac97_hardware;
    131	else
    132		runtime->hw = *oxygen_hardware[channel];
    133	switch (channel) {
    134	case PCM_C:
    135		if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) {
    136			runtime->hw.rates &= ~(SNDRV_PCM_RATE_32000 |
    137					       SNDRV_PCM_RATE_64000);
    138			runtime->hw.rate_min = 44100;
    139		}
    140		fallthrough;
    141	case PCM_A:
    142	case PCM_B:
    143		runtime->hw.fifo_size = 0;
    144		break;
    145	case PCM_MULTICH:
    146		runtime->hw.channels_max = chip->model.dac_channels_pcm;
    147		break;
    148	}
    149	if (chip->model.pcm_hardware_filter)
    150		chip->model.pcm_hardware_filter(channel, &runtime->hw);
    151	err = snd_pcm_hw_constraint_step(runtime, 0,
    152					 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
    153	if (err < 0)
    154		return err;
    155	err = snd_pcm_hw_constraint_step(runtime, 0,
    156					 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
    157	if (err < 0)
    158		return err;
    159	if (runtime->hw.formats & SNDRV_PCM_FMTBIT_S32_LE) {
    160		err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
    161		if (err < 0)
    162			return err;
    163	}
    164	if (runtime->hw.channels_max > 2) {
    165		err = snd_pcm_hw_constraint_step(runtime, 0,
    166						 SNDRV_PCM_HW_PARAM_CHANNELS,
    167						 2);
    168		if (err < 0)
    169			return err;
    170	}
    171	snd_pcm_set_sync(substream);
    172	chip->streams[channel] = substream;
    173
    174	mutex_lock(&chip->mutex);
    175	chip->pcm_active |= 1 << channel;
    176	if (channel == PCM_SPDIF) {
    177		chip->spdif_pcm_bits = chip->spdif_bits;
    178		chip->controls[CONTROL_SPDIF_PCM]->vd[0].access &=
    179			~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
    180		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
    181			       SNDRV_CTL_EVENT_MASK_INFO,
    182			       &chip->controls[CONTROL_SPDIF_PCM]->id);
    183	}
    184	mutex_unlock(&chip->mutex);
    185
    186	return 0;
    187}
    188
    189static int oxygen_rec_a_open(struct snd_pcm_substream *substream)
    190{
    191	return oxygen_open(substream, PCM_A);
    192}
    193
    194static int oxygen_rec_b_open(struct snd_pcm_substream *substream)
    195{
    196	return oxygen_open(substream, PCM_B);
    197}
    198
    199static int oxygen_rec_c_open(struct snd_pcm_substream *substream)
    200{
    201	return oxygen_open(substream, PCM_C);
    202}
    203
    204static int oxygen_spdif_open(struct snd_pcm_substream *substream)
    205{
    206	return oxygen_open(substream, PCM_SPDIF);
    207}
    208
    209static int oxygen_multich_open(struct snd_pcm_substream *substream)
    210{
    211	return oxygen_open(substream, PCM_MULTICH);
    212}
    213
    214static int oxygen_ac97_open(struct snd_pcm_substream *substream)
    215{
    216	return oxygen_open(substream, PCM_AC97);
    217}
    218
    219static int oxygen_close(struct snd_pcm_substream *substream)
    220{
    221	struct oxygen *chip = snd_pcm_substream_chip(substream);
    222	unsigned int channel = oxygen_substream_channel(substream);
    223
    224	mutex_lock(&chip->mutex);
    225	chip->pcm_active &= ~(1 << channel);
    226	if (channel == PCM_SPDIF) {
    227		chip->controls[CONTROL_SPDIF_PCM]->vd[0].access |=
    228			SNDRV_CTL_ELEM_ACCESS_INACTIVE;
    229		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |
    230			       SNDRV_CTL_EVENT_MASK_INFO,
    231			       &chip->controls[CONTROL_SPDIF_PCM]->id);
    232	}
    233	if (channel == PCM_SPDIF || channel == PCM_MULTICH)
    234		oxygen_update_spdif_source(chip);
    235	mutex_unlock(&chip->mutex);
    236
    237	chip->streams[channel] = NULL;
    238	return 0;
    239}
    240
    241static unsigned int oxygen_format(struct snd_pcm_hw_params *hw_params)
    242{
    243	if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
    244		return OXYGEN_FORMAT_24;
    245	else
    246		return OXYGEN_FORMAT_16;
    247}
    248
    249static unsigned int oxygen_rate(struct snd_pcm_hw_params *hw_params)
    250{
    251	switch (params_rate(hw_params)) {
    252	case 32000:
    253		return OXYGEN_RATE_32000;
    254	case 44100:
    255		return OXYGEN_RATE_44100;
    256	default: /* 48000 */
    257		return OXYGEN_RATE_48000;
    258	case 64000:
    259		return OXYGEN_RATE_64000;
    260	case 88200:
    261		return OXYGEN_RATE_88200;
    262	case 96000:
    263		return OXYGEN_RATE_96000;
    264	case 176400:
    265		return OXYGEN_RATE_176400;
    266	case 192000:
    267		return OXYGEN_RATE_192000;
    268	}
    269}
    270
    271static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params)
    272{
    273	if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
    274		return OXYGEN_I2S_BITS_24;
    275	else
    276		return OXYGEN_I2S_BITS_16;
    277}
    278
    279static unsigned int oxygen_play_channels(struct snd_pcm_hw_params *hw_params)
    280{
    281	switch (params_channels(hw_params)) {
    282	default: /* 2 */
    283		return OXYGEN_PLAY_CHANNELS_2;
    284	case 4:
    285		return OXYGEN_PLAY_CHANNELS_4;
    286	case 6:
    287		return OXYGEN_PLAY_CHANNELS_6;
    288	case 8:
    289		return OXYGEN_PLAY_CHANNELS_8;
    290	}
    291}
    292
    293static const unsigned int channel_base_registers[PCM_COUNT] = {
    294	[PCM_A] = OXYGEN_DMA_A_ADDRESS,
    295	[PCM_B] = OXYGEN_DMA_B_ADDRESS,
    296	[PCM_C] = OXYGEN_DMA_C_ADDRESS,
    297	[PCM_SPDIF] = OXYGEN_DMA_SPDIF_ADDRESS,
    298	[PCM_MULTICH] = OXYGEN_DMA_MULTICH_ADDRESS,
    299	[PCM_AC97] = OXYGEN_DMA_AC97_ADDRESS,
    300};
    301
    302static int oxygen_hw_params(struct snd_pcm_substream *substream,
    303			    struct snd_pcm_hw_params *hw_params)
    304{
    305	struct oxygen *chip = snd_pcm_substream_chip(substream);
    306	unsigned int channel = oxygen_substream_channel(substream);
    307
    308	oxygen_write32(chip, channel_base_registers[channel],
    309		       (u32)substream->runtime->dma_addr);
    310	if (channel == PCM_MULTICH) {
    311		oxygen_write32(chip, OXYGEN_DMA_MULTICH_COUNT,
    312			       params_buffer_bytes(hw_params) / 4 - 1);
    313		oxygen_write32(chip, OXYGEN_DMA_MULTICH_TCOUNT,
    314			       params_period_bytes(hw_params) / 4 - 1);
    315	} else {
    316		oxygen_write16(chip, channel_base_registers[channel] + 4,
    317			       params_buffer_bytes(hw_params) / 4 - 1);
    318		oxygen_write16(chip, channel_base_registers[channel] + 6,
    319			       params_period_bytes(hw_params) / 4 - 1);
    320	}
    321	return 0;
    322}
    323
    324static u16 get_mclk(struct oxygen *chip, unsigned int channel,
    325		    struct snd_pcm_hw_params *params)
    326{
    327	unsigned int mclks, shift;
    328
    329	if (channel == PCM_MULTICH)
    330		mclks = chip->model.dac_mclks;
    331	else
    332		mclks = chip->model.adc_mclks;
    333
    334	if (params_rate(params) <= 48000)
    335		shift = 0;
    336	else if (params_rate(params) <= 96000)
    337		shift = 2;
    338	else
    339		shift = 4;
    340
    341	return OXYGEN_I2S_MCLK(mclks >> shift);
    342}
    343
    344static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
    345				  struct snd_pcm_hw_params *hw_params)
    346{
    347	struct oxygen *chip = snd_pcm_substream_chip(substream);
    348	int err;
    349
    350	err = oxygen_hw_params(substream, hw_params);
    351	if (err < 0)
    352		return err;
    353
    354	spin_lock_irq(&chip->reg_lock);
    355	oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
    356			     oxygen_format(hw_params) << OXYGEN_REC_FORMAT_A_SHIFT,
    357			     OXYGEN_REC_FORMAT_A_MASK);
    358	oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
    359			      oxygen_rate(hw_params) |
    360			      chip->model.adc_i2s_format |
    361			      get_mclk(chip, PCM_A, hw_params) |
    362			      oxygen_i2s_bits(hw_params),
    363			      OXYGEN_I2S_RATE_MASK |
    364			      OXYGEN_I2S_FORMAT_MASK |
    365			      OXYGEN_I2S_MCLK_MASK |
    366			      OXYGEN_I2S_BITS_MASK);
    367	spin_unlock_irq(&chip->reg_lock);
    368
    369	mutex_lock(&chip->mutex);
    370	chip->model.set_adc_params(chip, hw_params);
    371	mutex_unlock(&chip->mutex);
    372	return 0;
    373}
    374
    375static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
    376				  struct snd_pcm_hw_params *hw_params)
    377{
    378	struct oxygen *chip = snd_pcm_substream_chip(substream);
    379	int is_ac97;
    380	int err;
    381
    382	err = oxygen_hw_params(substream, hw_params);
    383	if (err < 0)
    384		return err;
    385
    386	is_ac97 = chip->has_ac97_1 &&
    387		(chip->model.device_config & CAPTURE_2_FROM_AC97_1);
    388
    389	spin_lock_irq(&chip->reg_lock);
    390	oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
    391			     oxygen_format(hw_params) << OXYGEN_REC_FORMAT_B_SHIFT,
    392			     OXYGEN_REC_FORMAT_B_MASK);
    393	if (!is_ac97)
    394		oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
    395				      oxygen_rate(hw_params) |
    396				      chip->model.adc_i2s_format |
    397				      get_mclk(chip, PCM_B, hw_params) |
    398				      oxygen_i2s_bits(hw_params),
    399				      OXYGEN_I2S_RATE_MASK |
    400				      OXYGEN_I2S_FORMAT_MASK |
    401				      OXYGEN_I2S_MCLK_MASK |
    402				      OXYGEN_I2S_BITS_MASK);
    403	spin_unlock_irq(&chip->reg_lock);
    404
    405	if (!is_ac97) {
    406		mutex_lock(&chip->mutex);
    407		chip->model.set_adc_params(chip, hw_params);
    408		mutex_unlock(&chip->mutex);
    409	}
    410	return 0;
    411}
    412
    413static int oxygen_rec_c_hw_params(struct snd_pcm_substream *substream,
    414				  struct snd_pcm_hw_params *hw_params)
    415{
    416	struct oxygen *chip = snd_pcm_substream_chip(substream);
    417	bool is_spdif;
    418	int err;
    419
    420	err = oxygen_hw_params(substream, hw_params);
    421	if (err < 0)
    422		return err;
    423
    424	is_spdif = chip->model.device_config & CAPTURE_1_FROM_SPDIF;
    425
    426	spin_lock_irq(&chip->reg_lock);
    427	oxygen_write8_masked(chip, OXYGEN_REC_FORMAT,
    428			     oxygen_format(hw_params) << OXYGEN_REC_FORMAT_C_SHIFT,
    429			     OXYGEN_REC_FORMAT_C_MASK);
    430	if (!is_spdif)
    431		oxygen_write16_masked(chip, OXYGEN_I2S_C_FORMAT,
    432				      oxygen_rate(hw_params) |
    433				      chip->model.adc_i2s_format |
    434				      get_mclk(chip, PCM_B, hw_params) |
    435				      oxygen_i2s_bits(hw_params),
    436				      OXYGEN_I2S_RATE_MASK |
    437				      OXYGEN_I2S_FORMAT_MASK |
    438				      OXYGEN_I2S_MCLK_MASK |
    439				      OXYGEN_I2S_BITS_MASK);
    440	spin_unlock_irq(&chip->reg_lock);
    441
    442	if (!is_spdif) {
    443		mutex_lock(&chip->mutex);
    444		chip->model.set_adc_params(chip, hw_params);
    445		mutex_unlock(&chip->mutex);
    446	}
    447	return 0;
    448}
    449
    450static int oxygen_spdif_hw_params(struct snd_pcm_substream *substream,
    451				  struct snd_pcm_hw_params *hw_params)
    452{
    453	struct oxygen *chip = snd_pcm_substream_chip(substream);
    454	int err;
    455
    456	err = oxygen_hw_params(substream, hw_params);
    457	if (err < 0)
    458		return err;
    459
    460	mutex_lock(&chip->mutex);
    461	spin_lock_irq(&chip->reg_lock);
    462	oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
    463			    OXYGEN_SPDIF_OUT_ENABLE);
    464	oxygen_write8_masked(chip, OXYGEN_PLAY_FORMAT,
    465			     oxygen_format(hw_params) << OXYGEN_SPDIF_FORMAT_SHIFT,
    466			     OXYGEN_SPDIF_FORMAT_MASK);
    467	oxygen_write32_masked(chip, OXYGEN_SPDIF_CONTROL,
    468			      oxygen_rate(hw_params) << OXYGEN_SPDIF_OUT_RATE_SHIFT,
    469			      OXYGEN_SPDIF_OUT_RATE_MASK);
    470	oxygen_update_spdif_source(chip);
    471	spin_unlock_irq(&chip->reg_lock);
    472	mutex_unlock(&chip->mutex);
    473	return 0;
    474}
    475
    476static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
    477				    struct snd_pcm_hw_params *hw_params)
    478{
    479	struct oxygen *chip = snd_pcm_substream_chip(substream);
    480	int err;
    481
    482	err = oxygen_hw_params(substream, hw_params);
    483	if (err < 0)
    484		return err;
    485
    486	mutex_lock(&chip->mutex);
    487	spin_lock_irq(&chip->reg_lock);
    488	oxygen_write8_masked(chip, OXYGEN_PLAY_CHANNELS,
    489			     oxygen_play_channels(hw_params),
    490			     OXYGEN_PLAY_CHANNELS_MASK);
    491	oxygen_write8_masked(chip, OXYGEN_PLAY_FORMAT,
    492			     oxygen_format(hw_params) << OXYGEN_MULTICH_FORMAT_SHIFT,
    493			     OXYGEN_MULTICH_FORMAT_MASK);
    494	oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
    495			      oxygen_rate(hw_params) |
    496			      chip->model.dac_i2s_format |
    497			      get_mclk(chip, PCM_MULTICH, hw_params) |
    498			      oxygen_i2s_bits(hw_params),
    499			      OXYGEN_I2S_RATE_MASK |
    500			      OXYGEN_I2S_FORMAT_MASK |
    501			      OXYGEN_I2S_MCLK_MASK |
    502			      OXYGEN_I2S_BITS_MASK);
    503	oxygen_update_spdif_source(chip);
    504	spin_unlock_irq(&chip->reg_lock);
    505
    506	chip->model.set_dac_params(chip, hw_params);
    507	oxygen_update_dac_routing(chip);
    508	mutex_unlock(&chip->mutex);
    509	return 0;
    510}
    511
    512static int oxygen_hw_free(struct snd_pcm_substream *substream)
    513{
    514	struct oxygen *chip = snd_pcm_substream_chip(substream);
    515	unsigned int channel = oxygen_substream_channel(substream);
    516	unsigned int channel_mask = 1 << channel;
    517
    518	spin_lock_irq(&chip->reg_lock);
    519	chip->interrupt_mask &= ~channel_mask;
    520	oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
    521
    522	oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
    523	oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
    524	spin_unlock_irq(&chip->reg_lock);
    525
    526	return 0;
    527}
    528
    529static int oxygen_spdif_hw_free(struct snd_pcm_substream *substream)
    530{
    531	struct oxygen *chip = snd_pcm_substream_chip(substream);
    532
    533	spin_lock_irq(&chip->reg_lock);
    534	oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
    535			    OXYGEN_SPDIF_OUT_ENABLE);
    536	spin_unlock_irq(&chip->reg_lock);
    537	return oxygen_hw_free(substream);
    538}
    539
    540static int oxygen_prepare(struct snd_pcm_substream *substream)
    541{
    542	struct oxygen *chip = snd_pcm_substream_chip(substream);
    543	unsigned int channel = oxygen_substream_channel(substream);
    544	unsigned int channel_mask = 1 << channel;
    545
    546	spin_lock_irq(&chip->reg_lock);
    547	oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
    548	oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
    549
    550	if (substream->runtime->no_period_wakeup)
    551		chip->interrupt_mask &= ~channel_mask;
    552	else
    553		chip->interrupt_mask |= channel_mask;
    554	oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
    555	spin_unlock_irq(&chip->reg_lock);
    556	return 0;
    557}
    558
    559static int oxygen_trigger(struct snd_pcm_substream *substream, int cmd)
    560{
    561	struct oxygen *chip = snd_pcm_substream_chip(substream);
    562	struct snd_pcm_substream *s;
    563	unsigned int mask = 0;
    564	int pausing;
    565
    566	switch (cmd) {
    567	case SNDRV_PCM_TRIGGER_STOP:
    568	case SNDRV_PCM_TRIGGER_START:
    569	case SNDRV_PCM_TRIGGER_SUSPEND:
    570		pausing = 0;
    571		break;
    572	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
    573	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
    574		pausing = 1;
    575		break;
    576	default:
    577		return -EINVAL;
    578	}
    579
    580	snd_pcm_group_for_each_entry(s, substream) {
    581		if (snd_pcm_substream_chip(s) == chip) {
    582			mask |= 1 << oxygen_substream_channel(s);
    583			snd_pcm_trigger_done(s, substream);
    584		}
    585	}
    586
    587	spin_lock(&chip->reg_lock);
    588	if (!pausing) {
    589		if (cmd == SNDRV_PCM_TRIGGER_START)
    590			chip->pcm_running |= mask;
    591		else
    592			chip->pcm_running &= ~mask;
    593		oxygen_write8(chip, OXYGEN_DMA_STATUS, chip->pcm_running);
    594	} else {
    595		if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
    596			oxygen_set_bits8(chip, OXYGEN_DMA_PAUSE, mask);
    597		else
    598			oxygen_clear_bits8(chip, OXYGEN_DMA_PAUSE, mask);
    599	}
    600	spin_unlock(&chip->reg_lock);
    601	return 0;
    602}
    603
    604static snd_pcm_uframes_t oxygen_pointer(struct snd_pcm_substream *substream)
    605{
    606	struct oxygen *chip = snd_pcm_substream_chip(substream);
    607	struct snd_pcm_runtime *runtime = substream->runtime;
    608	unsigned int channel = oxygen_substream_channel(substream);
    609	u32 curr_addr;
    610
    611	/* no spinlock, this read should be atomic */
    612	curr_addr = oxygen_read32(chip, channel_base_registers[channel]);
    613	return bytes_to_frames(runtime, curr_addr - (u32)runtime->dma_addr);
    614}
    615
    616static const struct snd_pcm_ops oxygen_rec_a_ops = {
    617	.open      = oxygen_rec_a_open,
    618	.close     = oxygen_close,
    619	.hw_params = oxygen_rec_a_hw_params,
    620	.hw_free   = oxygen_hw_free,
    621	.prepare   = oxygen_prepare,
    622	.trigger   = oxygen_trigger,
    623	.pointer   = oxygen_pointer,
    624};
    625
    626static const struct snd_pcm_ops oxygen_rec_b_ops = {
    627	.open      = oxygen_rec_b_open,
    628	.close     = oxygen_close,
    629	.hw_params = oxygen_rec_b_hw_params,
    630	.hw_free   = oxygen_hw_free,
    631	.prepare   = oxygen_prepare,
    632	.trigger   = oxygen_trigger,
    633	.pointer   = oxygen_pointer,
    634};
    635
    636static const struct snd_pcm_ops oxygen_rec_c_ops = {
    637	.open      = oxygen_rec_c_open,
    638	.close     = oxygen_close,
    639	.hw_params = oxygen_rec_c_hw_params,
    640	.hw_free   = oxygen_hw_free,
    641	.prepare   = oxygen_prepare,
    642	.trigger   = oxygen_trigger,
    643	.pointer   = oxygen_pointer,
    644};
    645
    646static const struct snd_pcm_ops oxygen_spdif_ops = {
    647	.open      = oxygen_spdif_open,
    648	.close     = oxygen_close,
    649	.hw_params = oxygen_spdif_hw_params,
    650	.hw_free   = oxygen_spdif_hw_free,
    651	.prepare   = oxygen_prepare,
    652	.trigger   = oxygen_trigger,
    653	.pointer   = oxygen_pointer,
    654};
    655
    656static const struct snd_pcm_ops oxygen_multich_ops = {
    657	.open      = oxygen_multich_open,
    658	.close     = oxygen_close,
    659	.hw_params = oxygen_multich_hw_params,
    660	.hw_free   = oxygen_hw_free,
    661	.prepare   = oxygen_prepare,
    662	.trigger   = oxygen_trigger,
    663	.pointer   = oxygen_pointer,
    664};
    665
    666static const struct snd_pcm_ops oxygen_ac97_ops = {
    667	.open      = oxygen_ac97_open,
    668	.close     = oxygen_close,
    669	.hw_params = oxygen_hw_params,
    670	.hw_free   = oxygen_hw_free,
    671	.prepare   = oxygen_prepare,
    672	.trigger   = oxygen_trigger,
    673	.pointer   = oxygen_pointer,
    674};
    675
    676int oxygen_pcm_init(struct oxygen *chip)
    677{
    678	struct snd_pcm *pcm;
    679	int outs, ins;
    680	int err;
    681
    682	outs = !!(chip->model.device_config & PLAYBACK_0_TO_I2S);
    683	ins = !!(chip->model.device_config & (CAPTURE_0_FROM_I2S_1 |
    684					      CAPTURE_0_FROM_I2S_2));
    685	if (outs | ins) {
    686		err = snd_pcm_new(chip->card, "Multichannel",
    687				  0, outs, ins, &pcm);
    688		if (err < 0)
    689			return err;
    690		if (outs)
    691			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
    692					&oxygen_multich_ops);
    693		if (chip->model.device_config & CAPTURE_0_FROM_I2S_1)
    694			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
    695					&oxygen_rec_a_ops);
    696		else if (chip->model.device_config & CAPTURE_0_FROM_I2S_2)
    697			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
    698					&oxygen_rec_b_ops);
    699		pcm->private_data = chip;
    700		strcpy(pcm->name, "Multichannel");
    701		if (outs)
    702			snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
    703						   SNDRV_DMA_TYPE_DEV,
    704						   &chip->pci->dev,
    705						   DEFAULT_BUFFER_BYTES_MULTICH,
    706						   BUFFER_BYTES_MAX_MULTICH);
    707		if (ins)
    708			snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
    709						   SNDRV_DMA_TYPE_DEV,
    710						   &chip->pci->dev,
    711						   DEFAULT_BUFFER_BYTES,
    712						   BUFFER_BYTES_MAX);
    713	}
    714
    715	outs = !!(chip->model.device_config & PLAYBACK_1_TO_SPDIF);
    716	ins = !!(chip->model.device_config & CAPTURE_1_FROM_SPDIF);
    717	if (outs | ins) {
    718		err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm);
    719		if (err < 0)
    720			return err;
    721		if (outs)
    722			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
    723					&oxygen_spdif_ops);
    724		if (ins)
    725			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
    726					&oxygen_rec_c_ops);
    727		pcm->private_data = chip;
    728		strcpy(pcm->name, "Digital");
    729		snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
    730					       &chip->pci->dev,
    731					       DEFAULT_BUFFER_BYTES,
    732					       BUFFER_BYTES_MAX);
    733	}
    734
    735	if (chip->has_ac97_1) {
    736		outs = !!(chip->model.device_config & PLAYBACK_2_TO_AC97_1);
    737		ins = !!(chip->model.device_config & CAPTURE_2_FROM_AC97_1);
    738	} else {
    739		outs = 0;
    740		ins = !!(chip->model.device_config & CAPTURE_2_FROM_I2S_2);
    741	}
    742	if (outs | ins) {
    743		err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2",
    744				  2, outs, ins, &pcm);
    745		if (err < 0)
    746			return err;
    747		if (outs) {
    748			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
    749					&oxygen_ac97_ops);
    750			oxygen_write8_masked(chip, OXYGEN_REC_ROUTING,
    751					     OXYGEN_REC_B_ROUTE_AC97_1,
    752					     OXYGEN_REC_B_ROUTE_MASK);
    753		}
    754		if (ins)
    755			snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
    756					&oxygen_rec_b_ops);
    757		pcm->private_data = chip;
    758		strcpy(pcm->name, outs ? "Front Panel" : "Analog 2");
    759		snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
    760					       &chip->pci->dev,
    761					       DEFAULT_BUFFER_BYTES,
    762					       BUFFER_BYTES_MAX);
    763	}
    764
    765	ins = !!(chip->model.device_config & CAPTURE_3_FROM_I2S_3);
    766	if (ins) {
    767		err = snd_pcm_new(chip->card, "Analog3", 3, 0, ins, &pcm);
    768		if (err < 0)
    769			return err;
    770		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
    771				&oxygen_rec_c_ops);
    772		oxygen_write8_masked(chip, OXYGEN_REC_ROUTING,
    773				     OXYGEN_REC_C_ROUTE_I2S_ADC_3,
    774				     OXYGEN_REC_C_ROUTE_MASK);
    775		pcm->private_data = chip;
    776		strcpy(pcm->name, "Analog 3");
    777		snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
    778					       &chip->pci->dev,
    779					       DEFAULT_BUFFER_BYTES,
    780					       BUFFER_BYTES_MAX);
    781	}
    782	return 0;
    783}