1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Socionext UniPhier AIO Compress Audio driver. 4 // 5 // Copyright (c) 2017-2018 Socionext Inc. 6 7 #include <linux/bitfield.h> 8 #include <linux/circ_buf.h> 9 #include <linux/dma-mapping.h> 10 #include <linux/errno.h> 11 #include <linux/kernel.h> 12 #include <linux/module.h> 13 #include <sound/core.h> 14 #include <sound/pcm.h> 15 #include <sound/soc.h> 16 17 #include "aio.h" 18 19 static int uniphier_aio_compr_prepare(struct snd_soc_component *component, 20 struct snd_compr_stream *cstream); 21 static int uniphier_aio_compr_hw_free(struct snd_soc_component *component, 22 struct snd_compr_stream *cstream); 23 24 static int uniphier_aio_comprdma_new(struct snd_soc_pcm_runtime *rtd) 25 { 26 struct snd_compr *compr = rtd->compr; 27 struct device *dev = compr->card->dev; 28 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 29 struct uniphier_aio_sub *sub = &aio->sub[compr->direction]; 30 size_t size = AUD_RING_SIZE; 31 int dma_dir = DMA_FROM_DEVICE, ret; 32 33 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(33)); 34 if (ret) 35 return ret; 36 37 sub->compr_area = kzalloc(size, GFP_KERNEL); 38 if (!sub->compr_area) 39 return -ENOMEM; 40 41 if (sub->swm->dir == PORT_DIR_OUTPUT) 42 dma_dir = DMA_TO_DEVICE; 43 44 sub->compr_addr = dma_map_single(dev, sub->compr_area, size, dma_dir); 45 if (dma_mapping_error(dev, sub->compr_addr)) { 46 kfree(sub->compr_area); 47 sub->compr_area = NULL; 48 49 return -ENOMEM; 50 } 51 52 sub->compr_bytes = size; 53 54 return 0; 55 } 56 57 static int uniphier_aio_comprdma_free(struct snd_soc_pcm_runtime *rtd) 58 { 59 struct snd_compr *compr = rtd->compr; 60 struct device *dev = compr->card->dev; 61 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 62 struct uniphier_aio_sub *sub = &aio->sub[compr->direction]; 63 int dma_dir = DMA_FROM_DEVICE; 64 65 if (sub->swm->dir == PORT_DIR_OUTPUT) 66 dma_dir = DMA_TO_DEVICE; 67 68 dma_unmap_single(dev, sub->compr_addr, sub->compr_bytes, dma_dir); 69 kfree(sub->compr_area); 70 sub->compr_area = NULL; 71 72 return 0; 73 } 74 75 static int uniphier_aio_compr_open(struct snd_soc_component *component, 76 struct snd_compr_stream *cstream) 77 { 78 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 79 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 80 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 81 int ret; 82 83 if (sub->cstream) 84 return -EBUSY; 85 86 sub->cstream = cstream; 87 sub->pass_through = 1; 88 sub->use_mmap = false; 89 90 ret = uniphier_aio_comprdma_new(rtd); 91 if (ret) 92 return ret; 93 94 ret = aio_init(sub); 95 if (ret) 96 return ret; 97 98 return 0; 99 } 100 101 static int uniphier_aio_compr_free(struct snd_soc_component *component, 102 struct snd_compr_stream *cstream) 103 { 104 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 105 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 106 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 107 int ret; 108 109 ret = uniphier_aio_compr_hw_free(component, cstream); 110 if (ret) 111 return ret; 112 ret = uniphier_aio_comprdma_free(rtd); 113 if (ret) 114 return ret; 115 116 sub->cstream = NULL; 117 118 return 0; 119 } 120 121 static int uniphier_aio_compr_get_params(struct snd_soc_component *component, 122 struct snd_compr_stream *cstream, 123 struct snd_codec *params) 124 { 125 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 126 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 127 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 128 129 *params = sub->cparams.codec; 130 131 return 0; 132 } 133 134 static int uniphier_aio_compr_set_params(struct snd_soc_component *component, 135 struct snd_compr_stream *cstream, 136 struct snd_compr_params *params) 137 { 138 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 139 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 140 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 141 struct device *dev = &aio->chip->pdev->dev; 142 int ret; 143 144 if (params->codec.id != SND_AUDIOCODEC_IEC61937) { 145 dev_err(dev, "Codec ID is not supported(%d)\n", 146 params->codec.id); 147 return -EINVAL; 148 } 149 if (params->codec.profile != SND_AUDIOPROFILE_IEC61937_SPDIF) { 150 dev_err(dev, "Codec profile is not supported(%d)\n", 151 params->codec.profile); 152 return -EINVAL; 153 } 154 155 /* IEC frame type will be changed after received valid data */ 156 sub->iec_pc = IEC61937_PC_AAC; 157 158 sub->cparams = *params; 159 sub->setting = 1; 160 161 aio_port_reset(sub); 162 aio_src_reset(sub); 163 164 ret = uniphier_aio_compr_prepare(component, cstream); 165 if (ret) 166 return ret; 167 168 return 0; 169 } 170 171 static int uniphier_aio_compr_hw_free(struct snd_soc_component *component, 172 struct snd_compr_stream *cstream) 173 { 174 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 175 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 176 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 177 178 sub->setting = 0; 179 180 return 0; 181 } 182 183 static int uniphier_aio_compr_prepare(struct snd_soc_component *component, 184 struct snd_compr_stream *cstream) 185 { 186 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 187 struct snd_compr_runtime *runtime = cstream->runtime; 188 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 189 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 190 int bytes = runtime->fragment_size; 191 unsigned long flags; 192 int ret; 193 194 ret = aiodma_ch_set_param(sub); 195 if (ret) 196 return ret; 197 198 spin_lock_irqsave(&sub->lock, flags); 199 ret = aiodma_rb_set_buffer(sub, sub->compr_addr, 200 sub->compr_addr + sub->compr_bytes, 201 bytes); 202 spin_unlock_irqrestore(&sub->lock, flags); 203 if (ret) 204 return ret; 205 206 ret = aio_port_set_param(sub, sub->pass_through, &sub->params); 207 if (ret) 208 return ret; 209 ret = aio_oport_set_stream_type(sub, sub->iec_pc); 210 if (ret) 211 return ret; 212 aio_port_set_enable(sub, 1); 213 214 ret = aio_if_set_param(sub, sub->pass_through); 215 if (ret) 216 return ret; 217 218 return 0; 219 } 220 221 static int uniphier_aio_compr_trigger(struct snd_soc_component *component, 222 struct snd_compr_stream *cstream, 223 int cmd) 224 { 225 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 226 struct snd_compr_runtime *runtime = cstream->runtime; 227 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 228 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 229 struct device *dev = &aio->chip->pdev->dev; 230 int bytes = runtime->fragment_size, ret = 0; 231 unsigned long flags; 232 233 spin_lock_irqsave(&sub->lock, flags); 234 switch (cmd) { 235 case SNDRV_PCM_TRIGGER_START: 236 aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes); 237 aiodma_ch_set_enable(sub, 1); 238 sub->running = 1; 239 240 break; 241 case SNDRV_PCM_TRIGGER_STOP: 242 sub->running = 0; 243 aiodma_ch_set_enable(sub, 0); 244 245 break; 246 default: 247 dev_warn(dev, "Unknown trigger(%d)\n", cmd); 248 ret = -EINVAL; 249 } 250 spin_unlock_irqrestore(&sub->lock, flags); 251 252 return ret; 253 } 254 255 static int uniphier_aio_compr_pointer(struct snd_soc_component *component, 256 struct snd_compr_stream *cstream, 257 struct snd_compr_tstamp *tstamp) 258 { 259 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 260 struct snd_compr_runtime *runtime = cstream->runtime; 261 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 262 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 263 int bytes = runtime->fragment_size; 264 unsigned long flags; 265 u32 pos; 266 267 spin_lock_irqsave(&sub->lock, flags); 268 269 aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes); 270 271 if (sub->swm->dir == PORT_DIR_OUTPUT) { 272 pos = sub->rd_offs; 273 /* Size of AIO output format is double of IEC61937 */ 274 tstamp->copied_total = sub->rd_total / 2; 275 } else { 276 pos = sub->wr_offs; 277 tstamp->copied_total = sub->rd_total; 278 } 279 tstamp->byte_offset = pos; 280 281 spin_unlock_irqrestore(&sub->lock, flags); 282 283 return 0; 284 } 285 286 static int aio_compr_send_to_hw(struct uniphier_aio_sub *sub, 287 char __user *buf, size_t dstsize) 288 { 289 u32 __user *srcbuf = (u32 __user *)buf; 290 u32 *dstbuf = (u32 *)(sub->compr_area + sub->wr_offs); 291 int src = 0, dst = 0, ret; 292 u32 frm, frm_a, frm_b; 293 294 while (dstsize > 0) { 295 ret = get_user(frm, srcbuf + src); 296 if (ret) 297 return ret; 298 src++; 299 300 frm_a = frm & 0xffff; 301 frm_b = (frm >> 16) & 0xffff; 302 303 if (frm == IEC61937_HEADER_SIGN) { 304 frm_a |= 0x01000000; 305 306 /* Next data is Pc and Pd */ 307 sub->iec_header = true; 308 } else { 309 u16 pc = be16_to_cpu((__be16)frm_a); 310 311 if (sub->iec_header && sub->iec_pc != pc) { 312 /* Force overwrite IEC frame type */ 313 sub->iec_pc = pc; 314 ret = aio_oport_set_stream_type(sub, pc); 315 if (ret) 316 return ret; 317 } 318 sub->iec_header = false; 319 } 320 dstbuf[dst++] = frm_a; 321 dstbuf[dst++] = frm_b; 322 323 dstsize -= sizeof(u32) * 2; 324 } 325 326 return 0; 327 } 328 329 static int uniphier_aio_compr_copy(struct snd_soc_component *component, 330 struct snd_compr_stream *cstream, 331 char __user *buf, size_t count) 332 { 333 struct snd_soc_pcm_runtime *rtd = cstream->private_data; 334 struct snd_compr_runtime *runtime = cstream->runtime; 335 struct device *carddev = rtd->compr->card->dev; 336 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0)); 337 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction]; 338 size_t cnt = min_t(size_t, count, aio_rb_space_to_end(sub) / 2); 339 int bytes = runtime->fragment_size; 340 unsigned long flags; 341 size_t s; 342 int ret; 343 344 if (cnt < sizeof(u32)) 345 return 0; 346 347 if (sub->swm->dir == PORT_DIR_OUTPUT) { 348 dma_addr_t dmapos = sub->compr_addr + sub->wr_offs; 349 350 /* Size of AIO output format is double of IEC61937 */ 351 s = cnt * 2; 352 353 dma_sync_single_for_cpu(carddev, dmapos, s, DMA_TO_DEVICE); 354 ret = aio_compr_send_to_hw(sub, buf, s); 355 dma_sync_single_for_device(carddev, dmapos, s, DMA_TO_DEVICE); 356 } else { 357 dma_addr_t dmapos = sub->compr_addr + sub->rd_offs; 358 359 s = cnt; 360 361 dma_sync_single_for_cpu(carddev, dmapos, s, DMA_FROM_DEVICE); 362 ret = copy_to_user(buf, sub->compr_area + sub->rd_offs, s); 363 dma_sync_single_for_device(carddev, dmapos, s, DMA_FROM_DEVICE); 364 } 365 if (ret) 366 return -EFAULT; 367 368 spin_lock_irqsave(&sub->lock, flags); 369 370 sub->threshold = 2 * bytes; 371 aiodma_rb_set_threshold(sub, sub->compr_bytes, 2 * bytes); 372 373 if (sub->swm->dir == PORT_DIR_OUTPUT) { 374 sub->wr_offs += s; 375 if (sub->wr_offs >= sub->compr_bytes) 376 sub->wr_offs -= sub->compr_bytes; 377 } else { 378 sub->rd_offs += s; 379 if (sub->rd_offs >= sub->compr_bytes) 380 sub->rd_offs -= sub->compr_bytes; 381 } 382 aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes); 383 384 spin_unlock_irqrestore(&sub->lock, flags); 385 386 return cnt; 387 } 388 389 static int uniphier_aio_compr_get_caps(struct snd_soc_component *component, 390 struct snd_compr_stream *cstream, 391 struct snd_compr_caps *caps) 392 { 393 caps->num_codecs = 1; 394 caps->min_fragment_size = AUD_MIN_FRAGMENT_SIZE; 395 caps->max_fragment_size = AUD_MAX_FRAGMENT_SIZE; 396 caps->min_fragments = AUD_MIN_FRAGMENT; 397 caps->max_fragments = AUD_MAX_FRAGMENT; 398 caps->codecs[0] = SND_AUDIOCODEC_IEC61937; 399 400 return 0; 401 } 402 403 static const struct snd_compr_codec_caps caps_iec = { 404 .num_descriptors = 1, 405 .descriptor[0].max_ch = 8, 406 .descriptor[0].num_sample_rates = 0, 407 .descriptor[0].num_bitrates = 0, 408 .descriptor[0].profiles = SND_AUDIOPROFILE_IEC61937_SPDIF, 409 .descriptor[0].modes = SND_AUDIOMODE_IEC_AC3 | 410 SND_AUDIOMODE_IEC_MPEG1 | 411 SND_AUDIOMODE_IEC_MP3 | 412 SND_AUDIOMODE_IEC_DTS, 413 .descriptor[0].formats = 0, 414 }; 415 416 static int uniphier_aio_compr_get_codec_caps(struct snd_soc_component *component, 417 struct snd_compr_stream *stream, 418 struct snd_compr_codec_caps *codec) 419 { 420 if (codec->codec == SND_AUDIOCODEC_IEC61937) 421 *codec = caps_iec; 422 else 423 return -EINVAL; 424 425 return 0; 426 } 427 428 const struct snd_compress_ops uniphier_aio_compress_ops = { 429 .open = uniphier_aio_compr_open, 430 .free = uniphier_aio_compr_free, 431 .get_params = uniphier_aio_compr_get_params, 432 .set_params = uniphier_aio_compr_set_params, 433 .trigger = uniphier_aio_compr_trigger, 434 .pointer = uniphier_aio_compr_pointer, 435 .copy = uniphier_aio_compr_copy, 436 .get_caps = uniphier_aio_compr_get_caps, 437 .get_codec_caps = uniphier_aio_compr_get_codec_caps, 438 }; 439