^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) * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * @File ctpcm.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * @Brief
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This file contains the definition of the pcm device functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * @Author Liu Chun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * @Date Apr 2 2008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "ctpcm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "cttimer.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* Hardware descriptions for playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static const struct snd_pcm_hardware ct_pcm_playback_hw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) .info = (SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) SNDRV_PCM_INFO_MMAP_VALID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) SNDRV_PCM_INFO_PAUSE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) .formats = (SNDRV_PCM_FMTBIT_U8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) SNDRV_PCM_FMTBIT_S16_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) SNDRV_PCM_FMTBIT_S24_3LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) SNDRV_PCM_FMTBIT_S32_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) SNDRV_PCM_FMTBIT_FLOAT_LE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .rates = (SNDRV_PCM_RATE_CONTINUOUS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) SNDRV_PCM_RATE_8000_192000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) .rate_min = 8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) .rate_max = 192000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .buffer_bytes_max = (128*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .period_bytes_min = (64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .period_bytes_max = (128*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .periods_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .periods_max = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .fifo_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static const struct snd_pcm_hardware ct_spdif_passthru_playback_hw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .info = (SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) SNDRV_PCM_INFO_MMAP_VALID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) SNDRV_PCM_INFO_PAUSE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .formats = SNDRV_PCM_FMTBIT_S16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .rates = (SNDRV_PCM_RATE_48000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) SNDRV_PCM_RATE_44100 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) SNDRV_PCM_RATE_32000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .rate_min = 32000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .buffer_bytes_max = (128*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .period_bytes_min = (64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .period_bytes_max = (128*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .periods_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .periods_max = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .fifo_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* Hardware descriptions for capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static const struct snd_pcm_hardware ct_pcm_capture_hw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .info = (SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) SNDRV_PCM_INFO_PAUSE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) SNDRV_PCM_INFO_MMAP_VALID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .formats = (SNDRV_PCM_FMTBIT_U8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) SNDRV_PCM_FMTBIT_S16_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) SNDRV_PCM_FMTBIT_S24_3LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) SNDRV_PCM_FMTBIT_S32_LE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) SNDRV_PCM_FMTBIT_FLOAT_LE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .rates = (SNDRV_PCM_RATE_CONTINUOUS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) SNDRV_PCM_RATE_8000_96000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .rate_min = 8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .rate_max = 96000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .buffer_bytes_max = (128*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .period_bytes_min = (384),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .period_bytes_max = (64*1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .periods_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .periods_max = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .fifo_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static void ct_atc_pcm_interrupt(struct ct_atc_pcm *atc_pcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct ct_atc_pcm *apcm = atc_pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (!apcm->substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) snd_pcm_period_elapsed(apcm->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void ct_atc_pcm_free_substream(struct snd_pcm_runtime *runtime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct ct_atc_pcm *apcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct ct_atc *atc = snd_pcm_substream_chip(apcm->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) atc->pcm_release_resources(atc, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) ct_timer_instance_free(apcm->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) kfree(apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) runtime->private_data = NULL;
^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) /* pcm playback operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static int ct_pcm_playback_open(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) struct ct_atc *atc = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct ct_atc_pcm *apcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (!apcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) apcm->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) apcm->interrupt = ct_atc_pcm_interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (IEC958 == substream->pcm->device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) runtime->hw = ct_spdif_passthru_playback_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) atc->spdif_out_passthru(atc, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) runtime->hw = ct_pcm_playback_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (FRONT == substream->pcm->device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) runtime->hw.channels_max = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) err = snd_pcm_hw_constraint_integer(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) SNDRV_PCM_HW_PARAM_PERIODS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) goto free_pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) err = snd_pcm_hw_constraint_minmax(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 1024, UINT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) goto free_pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) apcm->timer = ct_timer_instance_new(atc->timer, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (!apcm->timer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) goto free_pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) runtime->private_data = apcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) runtime->private_free = ct_atc_pcm_free_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) free_pcm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) kfree(apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int ct_pcm_playback_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct ct_atc *atc = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* TODO: Notify mixer inactive. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (IEC958 == substream->pcm->device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) atc->spdif_out_passthru(atc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* The ct_atc_pcm object will be freed by runtime->private_free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static int ct_pcm_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct ct_atc *atc = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct ct_atc_pcm *apcm = substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* clear previous resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) atc->pcm_release_resources(atc, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static int ct_pcm_hw_free(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct ct_atc *atc = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct ct_atc_pcm *apcm = substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* clear previous resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) atc->pcm_release_resources(atc, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static int ct_pcm_playback_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct ct_atc *atc = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct ct_atc_pcm *apcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (IEC958 == substream->pcm->device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) err = atc->spdif_passthru_playback_prepare(atc, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) err = atc->pcm_playback_prepare(atc, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) dev_err(atc->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) "Preparing pcm playback failed!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return 0;
^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
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ct_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct ct_atc *atc = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct ct_atc_pcm *apcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) atc->pcm_playback_start(atc, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) atc->pcm_playback_stop(atc, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) break;
^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) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static snd_pcm_uframes_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ct_pcm_playback_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) unsigned long position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct ct_atc *atc = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct ct_atc_pcm *apcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* Read out playback position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) position = atc->pcm_playback_position(atc, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) position = bytes_to_frames(runtime, position);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (position >= runtime->buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) position = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* pcm capture operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct ct_atc *atc = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct ct_atc_pcm *apcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (!apcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) apcm->started = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) apcm->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) apcm->interrupt = ct_atc_pcm_interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) runtime->hw = ct_pcm_capture_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) runtime->hw.rate_max = atc->rsr * atc->msr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) err = snd_pcm_hw_constraint_integer(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) SNDRV_PCM_HW_PARAM_PERIODS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) goto free_pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) err = snd_pcm_hw_constraint_minmax(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 1024, UINT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) goto free_pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) apcm->timer = ct_timer_instance_new(atc->timer, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (!apcm->timer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) goto free_pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) runtime->private_data = apcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) runtime->private_free = ct_atc_pcm_free_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) free_pcm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) kfree(apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static int ct_pcm_capture_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* The ct_atc_pcm object will be freed by runtime->private_free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* TODO: Notify mixer inactive. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static int ct_pcm_capture_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct ct_atc *atc = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct ct_atc_pcm *apcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) err = atc->pcm_capture_prepare(atc, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dev_err(atc->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) "Preparing pcm capture failed!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ct_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct ct_atc *atc = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct ct_atc_pcm *apcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) atc->pcm_capture_start(atc, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) atc->pcm_capture_stop(atc, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) atc->pcm_capture_stop(atc, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static snd_pcm_uframes_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ct_pcm_capture_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) unsigned long position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct ct_atc *atc = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct ct_atc_pcm *apcm = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* Read out playback position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) position = atc->pcm_capture_position(atc, apcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) position = bytes_to_frames(runtime, position);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (position >= runtime->buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) position = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* PCM operators for playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static const struct snd_pcm_ops ct_pcm_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .open = ct_pcm_playback_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .close = ct_pcm_playback_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .hw_params = ct_pcm_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .hw_free = ct_pcm_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .prepare = ct_pcm_playback_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .trigger = ct_pcm_playback_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) .pointer = ct_pcm_playback_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* PCM operators for capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static const struct snd_pcm_ops ct_pcm_capture_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) .open = ct_pcm_capture_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) .close = ct_pcm_capture_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .hw_params = ct_pcm_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .hw_free = ct_pcm_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) .prepare = ct_pcm_capture_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) .trigger = ct_pcm_capture_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .pointer = ct_pcm_capture_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static const struct snd_pcm_chmap_elem surround_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) { .channels = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .map = { SNDRV_CHMAP_MONO } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) { .channels = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static const struct snd_pcm_chmap_elem clfe_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) { .channels = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .map = { SNDRV_CHMAP_MONO } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) { .channels = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) .map = { SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static const struct snd_pcm_chmap_elem side_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) { .channels = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) .map = { SNDRV_CHMAP_MONO } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) { .channels = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .map = { SNDRV_CHMAP_SL, SNDRV_CHMAP_SR } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* Create ALSA pcm device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) int ct_alsa_pcm_create(struct ct_atc *atc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) enum CTALSADEVS device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) const char *device_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) const struct snd_pcm_chmap_elem *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) int chs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) int playback_count, capture_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) playback_count = (IEC958 == device) ? 1 : 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) capture_count = (FRONT == device) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) err = snd_pcm_new(atc->card, "ctxfi", device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) playback_count, capture_count, &pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dev_err(atc->card->dev, "snd_pcm_new failed!! Err=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) pcm->private_data = atc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) pcm->info_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) strlcpy(pcm->name, device_name, sizeof(pcm->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ct_pcm_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (FRONT == device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) snd_pcm_set_ops(pcm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) SNDRV_PCM_STREAM_CAPTURE, &ct_pcm_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) &atc->pci->dev, 128*1024, 128*1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) chs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) switch (device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) case FRONT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) chs = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) map = snd_pcm_std_chmaps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) case SURROUND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) map = surround_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) case CLFE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) map = clfe_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) case SIDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) map = side_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) map = snd_pcm_std_chmaps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, chs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) atc->pcms[device] = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }