Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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