1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Driver for Sound Core PDAudioCF soundcards 4 * 5 * PCM part 6 * 7 * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz> 8 */ 9 10 #include <linux/delay.h> 11 #include <sound/core.h> 12 #include <sound/asoundef.h> 13 #include "pdaudiocf.h" 14 15 16 /* 17 * clear the SRAM contents 18 */ 19 static int pdacf_pcm_clear_sram(struct snd_pdacf *chip) 20 { 21 int max_loop = 64 * 1024; 22 23 while (inw(chip->port + PDAUDIOCF_REG_RDP) != inw(chip->port + PDAUDIOCF_REG_WDP)) { 24 if (max_loop-- < 0) 25 return -EIO; 26 inw(chip->port + PDAUDIOCF_REG_MD); 27 } 28 return 0; 29 } 30 31 /* 32 * pdacf_pcm_trigger - trigger callback for capture 33 */ 34 static int pdacf_pcm_trigger(struct snd_pcm_substream *subs, int cmd) 35 { 36 struct snd_pdacf *chip = snd_pcm_substream_chip(subs); 37 struct snd_pcm_runtime *runtime = subs->runtime; 38 int inc, ret = 0, rate; 39 unsigned short mask, val, tmp; 40 41 if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE) 42 return -EBUSY; 43 44 switch (cmd) { 45 case SNDRV_PCM_TRIGGER_START: 46 chip->pcm_hwptr = 0; 47 chip->pcm_tdone = 0; 48 /* fall thru */ 49 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 50 case SNDRV_PCM_TRIGGER_RESUME: 51 mask = 0; 52 val = PDAUDIOCF_RECORD; 53 inc = 1; 54 rate = snd_ak4117_check_rate_and_errors(chip->ak4117, AK4117_CHECK_NO_STAT|AK4117_CHECK_NO_RATE); 55 break; 56 case SNDRV_PCM_TRIGGER_STOP: 57 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 58 case SNDRV_PCM_TRIGGER_SUSPEND: 59 mask = PDAUDIOCF_RECORD; 60 val = 0; 61 inc = -1; 62 rate = 0; 63 break; 64 default: 65 return -EINVAL; 66 } 67 mutex_lock(&chip->reg_lock); 68 chip->pcm_running += inc; 69 tmp = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR); 70 if (chip->pcm_running) { 71 if ((chip->ak4117->rcs0 & AK4117_UNLCK) || runtime->rate != rate) { 72 chip->pcm_running -= inc; 73 ret = -EIO; 74 goto __end; 75 } 76 } 77 tmp &= ~mask; 78 tmp |= val; 79 pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, tmp); 80 __end: 81 mutex_unlock(&chip->reg_lock); 82 snd_ak4117_check_rate_and_errors(chip->ak4117, AK4117_CHECK_NO_RATE); 83 return ret; 84 } 85 86 /* 87 * pdacf_pcm_hw_params - hw_params callback for playback and capture 88 */ 89 static int pdacf_pcm_hw_params(struct snd_pcm_substream *subs, 90 struct snd_pcm_hw_params *hw_params) 91 { 92 return snd_pcm_lib_alloc_vmalloc_32_buffer 93 (subs, params_buffer_bytes(hw_params)); 94 } 95 96 /* 97 * pdacf_pcm_hw_free - hw_free callback for playback and capture 98 */ 99 static int pdacf_pcm_hw_free(struct snd_pcm_substream *subs) 100 { 101 return snd_pcm_lib_free_vmalloc_buffer(subs); 102 } 103 104 /* 105 * pdacf_pcm_prepare - prepare callback for playback and capture 106 */ 107 static int pdacf_pcm_prepare(struct snd_pcm_substream *subs) 108 { 109 struct snd_pdacf *chip = snd_pcm_substream_chip(subs); 110 struct snd_pcm_runtime *runtime = subs->runtime; 111 u16 val, nval, aval; 112 113 if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE) 114 return -EBUSY; 115 116 chip->pcm_channels = runtime->channels; 117 118 chip->pcm_little = snd_pcm_format_little_endian(runtime->format) > 0; 119 #ifdef SNDRV_LITTLE_ENDIAN 120 chip->pcm_swab = snd_pcm_format_big_endian(runtime->format) > 0; 121 #else 122 chip->pcm_swab = chip->pcm_little; 123 #endif 124 125 if (snd_pcm_format_unsigned(runtime->format)) 126 chip->pcm_xor = 0x80008000; 127 128 if (pdacf_pcm_clear_sram(chip) < 0) 129 return -EIO; 130 131 val = nval = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR); 132 nval &= ~(PDAUDIOCF_DATAFMT0|PDAUDIOCF_DATAFMT1); 133 switch (runtime->format) { 134 case SNDRV_PCM_FORMAT_S16_LE: 135 case SNDRV_PCM_FORMAT_S16_BE: 136 break; 137 default: /* 24-bit */ 138 nval |= PDAUDIOCF_DATAFMT0 | PDAUDIOCF_DATAFMT1; 139 break; 140 } 141 aval = 0; 142 chip->pcm_sample = 4; 143 switch (runtime->format) { 144 case SNDRV_PCM_FORMAT_S16_LE: 145 case SNDRV_PCM_FORMAT_S16_BE: 146 aval = AK4117_DIF_16R; 147 chip->pcm_frame = 2; 148 chip->pcm_sample = 2; 149 break; 150 case SNDRV_PCM_FORMAT_S24_3LE: 151 case SNDRV_PCM_FORMAT_S24_3BE: 152 chip->pcm_sample = 3; 153 /* fall through */ 154 default: /* 24-bit */ 155 aval = AK4117_DIF_24R; 156 chip->pcm_frame = 3; 157 chip->pcm_xor &= 0xffff0000; 158 break; 159 } 160 161 if (val != nval) { 162 snd_ak4117_reg_write(chip->ak4117, AK4117_REG_IO, AK4117_DIF2|AK4117_DIF1|AK4117_DIF0, aval); 163 pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, nval); 164 } 165 166 val = pdacf_reg_read(chip, PDAUDIOCF_REG_IER); 167 val &= ~(PDAUDIOCF_IRQLVLEN1); 168 val |= PDAUDIOCF_IRQLVLEN0; 169 pdacf_reg_write(chip, PDAUDIOCF_REG_IER, val); 170 171 chip->pcm_size = runtime->buffer_size; 172 chip->pcm_period = runtime->period_size; 173 chip->pcm_area = runtime->dma_area; 174 175 return 0; 176 } 177 178 179 /* 180 * capture hw information 181 */ 182 183 static const struct snd_pcm_hardware pdacf_pcm_capture_hw = { 184 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 185 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | 186 SNDRV_PCM_INFO_MMAP_VALID | 187 SNDRV_PCM_INFO_BATCH), 188 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | 189 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | 190 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE, 191 .rates = SNDRV_PCM_RATE_32000 | 192 SNDRV_PCM_RATE_44100 | 193 SNDRV_PCM_RATE_48000 | 194 SNDRV_PCM_RATE_88200 | 195 SNDRV_PCM_RATE_96000 | 196 SNDRV_PCM_RATE_176400 | 197 SNDRV_PCM_RATE_192000, 198 .rate_min = 32000, 199 .rate_max = 192000, 200 .channels_min = 1, 201 .channels_max = 2, 202 .buffer_bytes_max = (512*1024), 203 .period_bytes_min = 8*1024, 204 .period_bytes_max = (64*1024), 205 .periods_min = 2, 206 .periods_max = 128, 207 .fifo_size = 0, 208 }; 209 210 211 /* 212 * pdacf_pcm_capture_open - open callback for capture 213 */ 214 static int pdacf_pcm_capture_open(struct snd_pcm_substream *subs) 215 { 216 struct snd_pcm_runtime *runtime = subs->runtime; 217 struct snd_pdacf *chip = snd_pcm_substream_chip(subs); 218 219 if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE) 220 return -EBUSY; 221 222 runtime->hw = pdacf_pcm_capture_hw; 223 runtime->private_data = chip; 224 chip->pcm_substream = subs; 225 226 return 0; 227 } 228 229 /* 230 * pdacf_pcm_capture_close - close callback for capture 231 */ 232 static int pdacf_pcm_capture_close(struct snd_pcm_substream *subs) 233 { 234 struct snd_pdacf *chip = snd_pcm_substream_chip(subs); 235 236 if (!chip) 237 return -EINVAL; 238 pdacf_reinit(chip, 0); 239 chip->pcm_substream = NULL; 240 return 0; 241 } 242 243 244 /* 245 * pdacf_pcm_capture_pointer - pointer callback for capture 246 */ 247 static snd_pcm_uframes_t pdacf_pcm_capture_pointer(struct snd_pcm_substream *subs) 248 { 249 struct snd_pdacf *chip = snd_pcm_substream_chip(subs); 250 return chip->pcm_hwptr; 251 } 252 253 /* 254 * operators for PCM capture 255 */ 256 static const struct snd_pcm_ops pdacf_pcm_capture_ops = { 257 .open = pdacf_pcm_capture_open, 258 .close = pdacf_pcm_capture_close, 259 .ioctl = snd_pcm_lib_ioctl, 260 .hw_params = pdacf_pcm_hw_params, 261 .hw_free = pdacf_pcm_hw_free, 262 .prepare = pdacf_pcm_prepare, 263 .trigger = pdacf_pcm_trigger, 264 .pointer = pdacf_pcm_capture_pointer, 265 .page = snd_pcm_lib_get_vmalloc_page, 266 }; 267 268 269 /* 270 * snd_pdacf_pcm_new - create and initialize a pcm 271 */ 272 int snd_pdacf_pcm_new(struct snd_pdacf *chip) 273 { 274 struct snd_pcm *pcm; 275 int err; 276 277 err = snd_pcm_new(chip->card, "PDAudioCF", 0, 0, 1, &pcm); 278 if (err < 0) 279 return err; 280 281 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pdacf_pcm_capture_ops); 282 283 pcm->private_data = chip; 284 pcm->info_flags = 0; 285 pcm->nonatomic = true; 286 strcpy(pcm->name, chip->card->shortname); 287 chip->pcm = pcm; 288 289 err = snd_ak4117_build(chip->ak4117, pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); 290 if (err < 0) 291 return err; 292 293 return 0; 294 } 295