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_malloc_pages(subs, params_buffer_bytes(hw_params)); 93 } 94 95 /* 96 * pdacf_pcm_hw_free - hw_free callback for playback and capture 97 */ 98 static int pdacf_pcm_hw_free(struct snd_pcm_substream *subs) 99 { 100 return snd_pcm_lib_free_pages(subs); 101 } 102 103 /* 104 * pdacf_pcm_prepare - prepare callback for playback and capture 105 */ 106 static int pdacf_pcm_prepare(struct snd_pcm_substream *subs) 107 { 108 struct snd_pdacf *chip = snd_pcm_substream_chip(subs); 109 struct snd_pcm_runtime *runtime = subs->runtime; 110 u16 val, nval, aval; 111 112 if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE) 113 return -EBUSY; 114 115 chip->pcm_channels = runtime->channels; 116 117 chip->pcm_little = snd_pcm_format_little_endian(runtime->format) > 0; 118 #ifdef SNDRV_LITTLE_ENDIAN 119 chip->pcm_swab = snd_pcm_format_big_endian(runtime->format) > 0; 120 #else 121 chip->pcm_swab = chip->pcm_little; 122 #endif 123 124 if (snd_pcm_format_unsigned(runtime->format)) 125 chip->pcm_xor = 0x80008000; 126 127 if (pdacf_pcm_clear_sram(chip) < 0) 128 return -EIO; 129 130 val = nval = pdacf_reg_read(chip, PDAUDIOCF_REG_SCR); 131 nval &= ~(PDAUDIOCF_DATAFMT0|PDAUDIOCF_DATAFMT1); 132 switch (runtime->format) { 133 case SNDRV_PCM_FORMAT_S16_LE: 134 case SNDRV_PCM_FORMAT_S16_BE: 135 break; 136 default: /* 24-bit */ 137 nval |= PDAUDIOCF_DATAFMT0 | PDAUDIOCF_DATAFMT1; 138 break; 139 } 140 aval = 0; 141 chip->pcm_sample = 4; 142 switch (runtime->format) { 143 case SNDRV_PCM_FORMAT_S16_LE: 144 case SNDRV_PCM_FORMAT_S16_BE: 145 aval = AK4117_DIF_16R; 146 chip->pcm_frame = 2; 147 chip->pcm_sample = 2; 148 break; 149 case SNDRV_PCM_FORMAT_S24_3LE: 150 case SNDRV_PCM_FORMAT_S24_3BE: 151 chip->pcm_sample = 3; 152 /* fall through */ 153 default: /* 24-bit */ 154 aval = AK4117_DIF_24R; 155 chip->pcm_frame = 3; 156 chip->pcm_xor &= 0xffff0000; 157 break; 158 } 159 160 if (val != nval) { 161 snd_ak4117_reg_write(chip->ak4117, AK4117_REG_IO, AK4117_DIF2|AK4117_DIF1|AK4117_DIF0, aval); 162 pdacf_reg_write(chip, PDAUDIOCF_REG_SCR, nval); 163 } 164 165 val = pdacf_reg_read(chip, PDAUDIOCF_REG_IER); 166 val &= ~(PDAUDIOCF_IRQLVLEN1); 167 val |= PDAUDIOCF_IRQLVLEN0; 168 pdacf_reg_write(chip, PDAUDIOCF_REG_IER, val); 169 170 chip->pcm_size = runtime->buffer_size; 171 chip->pcm_period = runtime->period_size; 172 chip->pcm_area = runtime->dma_area; 173 174 return 0; 175 } 176 177 178 /* 179 * capture hw information 180 */ 181 182 static const struct snd_pcm_hardware pdacf_pcm_capture_hw = { 183 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 184 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | 185 SNDRV_PCM_INFO_MMAP_VALID | 186 SNDRV_PCM_INFO_BATCH), 187 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | 188 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | 189 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE, 190 .rates = SNDRV_PCM_RATE_32000 | 191 SNDRV_PCM_RATE_44100 | 192 SNDRV_PCM_RATE_48000 | 193 SNDRV_PCM_RATE_88200 | 194 SNDRV_PCM_RATE_96000 | 195 SNDRV_PCM_RATE_176400 | 196 SNDRV_PCM_RATE_192000, 197 .rate_min = 32000, 198 .rate_max = 192000, 199 .channels_min = 1, 200 .channels_max = 2, 201 .buffer_bytes_max = (512*1024), 202 .period_bytes_min = 8*1024, 203 .period_bytes_max = (64*1024), 204 .periods_min = 2, 205 .periods_max = 128, 206 .fifo_size = 0, 207 }; 208 209 210 /* 211 * pdacf_pcm_capture_open - open callback for capture 212 */ 213 static int pdacf_pcm_capture_open(struct snd_pcm_substream *subs) 214 { 215 struct snd_pcm_runtime *runtime = subs->runtime; 216 struct snd_pdacf *chip = snd_pcm_substream_chip(subs); 217 218 if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE) 219 return -EBUSY; 220 221 runtime->hw = pdacf_pcm_capture_hw; 222 runtime->private_data = chip; 223 chip->pcm_substream = subs; 224 225 return 0; 226 } 227 228 /* 229 * pdacf_pcm_capture_close - close callback for capture 230 */ 231 static int pdacf_pcm_capture_close(struct snd_pcm_substream *subs) 232 { 233 struct snd_pdacf *chip = snd_pcm_substream_chip(subs); 234 235 if (!chip) 236 return -EINVAL; 237 pdacf_reinit(chip, 0); 238 chip->pcm_substream = NULL; 239 return 0; 240 } 241 242 243 /* 244 * pdacf_pcm_capture_pointer - pointer callback for capture 245 */ 246 static snd_pcm_uframes_t pdacf_pcm_capture_pointer(struct snd_pcm_substream *subs) 247 { 248 struct snd_pdacf *chip = snd_pcm_substream_chip(subs); 249 return chip->pcm_hwptr; 250 } 251 252 /* 253 * operators for PCM capture 254 */ 255 static const struct snd_pcm_ops pdacf_pcm_capture_ops = { 256 .open = pdacf_pcm_capture_open, 257 .close = pdacf_pcm_capture_close, 258 .ioctl = snd_pcm_lib_ioctl, 259 .hw_params = pdacf_pcm_hw_params, 260 .hw_free = pdacf_pcm_hw_free, 261 .prepare = pdacf_pcm_prepare, 262 .trigger = pdacf_pcm_trigger, 263 .pointer = pdacf_pcm_capture_pointer, 264 }; 265 266 267 /* 268 * snd_pdacf_pcm_new - create and initialize a pcm 269 */ 270 int snd_pdacf_pcm_new(struct snd_pdacf *chip) 271 { 272 struct snd_pcm *pcm; 273 int err; 274 275 err = snd_pcm_new(chip->card, "PDAudioCF", 0, 0, 1, &pcm); 276 if (err < 0) 277 return err; 278 279 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pdacf_pcm_capture_ops); 280 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_VMALLOC, 281 snd_dma_continuous_data(GFP_KERNEL | GFP_DMA32), 282 0, 0); 283 284 pcm->private_data = chip; 285 pcm->info_flags = 0; 286 pcm->nonatomic = true; 287 strcpy(pcm->name, chip->card->shortname); 288 chip->pcm = pcm; 289 290 err = snd_ak4117_build(chip->ak4117, pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); 291 if (err < 0) 292 return err; 293 294 return 0; 295 } 296