brintos

brintos / linux-shallow public Read only

0
0
Text · 22.0 KiB · b2a3fcf Raw
784 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * C-Media CMI8788 driver - PCM code4 *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			25621#define FIFO_BYTES_MULTICH		102422 23#define PERIOD_BYTES_MIN		6424 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 int115oxygen_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	else132		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	else246		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	else276		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	else332		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	else339		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	else553		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		else592			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		else598			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}784