^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) }