0001
0002
0003
0004
0005
0006
0007 #include <linux/bitfield.h>
0008 #include <linux/circ_buf.h>
0009 #include <linux/dma-mapping.h>
0010 #include <linux/errno.h>
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <sound/core.h>
0014 #include <sound/pcm.h>
0015 #include <sound/soc.h>
0016
0017 #include "aio.h"
0018
0019 static int uniphier_aio_compr_prepare(struct snd_soc_component *component,
0020 struct snd_compr_stream *cstream);
0021 static int uniphier_aio_compr_hw_free(struct snd_soc_component *component,
0022 struct snd_compr_stream *cstream);
0023
0024 static int uniphier_aio_comprdma_new(struct snd_soc_pcm_runtime *rtd)
0025 {
0026 struct snd_compr *compr = rtd->compr;
0027 struct device *dev = compr->card->dev;
0028 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0));
0029 struct uniphier_aio_sub *sub = &aio->sub[compr->direction];
0030 size_t size = AUD_RING_SIZE;
0031 int dma_dir = DMA_FROM_DEVICE, ret;
0032
0033 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(33));
0034 if (ret)
0035 return ret;
0036
0037 sub->compr_area = kzalloc(size, GFP_KERNEL);
0038 if (!sub->compr_area)
0039 return -ENOMEM;
0040
0041 if (sub->swm->dir == PORT_DIR_OUTPUT)
0042 dma_dir = DMA_TO_DEVICE;
0043
0044 sub->compr_addr = dma_map_single(dev, sub->compr_area, size, dma_dir);
0045 if (dma_mapping_error(dev, sub->compr_addr)) {
0046 kfree(sub->compr_area);
0047 sub->compr_area = NULL;
0048
0049 return -ENOMEM;
0050 }
0051
0052 sub->compr_bytes = size;
0053
0054 return 0;
0055 }
0056
0057 static int uniphier_aio_comprdma_free(struct snd_soc_pcm_runtime *rtd)
0058 {
0059 struct snd_compr *compr = rtd->compr;
0060 struct device *dev = compr->card->dev;
0061 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0));
0062 struct uniphier_aio_sub *sub = &aio->sub[compr->direction];
0063 int dma_dir = DMA_FROM_DEVICE;
0064
0065 if (sub->swm->dir == PORT_DIR_OUTPUT)
0066 dma_dir = DMA_TO_DEVICE;
0067
0068 dma_unmap_single(dev, sub->compr_addr, sub->compr_bytes, dma_dir);
0069 kfree(sub->compr_area);
0070 sub->compr_area = NULL;
0071
0072 return 0;
0073 }
0074
0075 static int uniphier_aio_compr_open(struct snd_soc_component *component,
0076 struct snd_compr_stream *cstream)
0077 {
0078 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0079 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0));
0080 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
0081 int ret;
0082
0083 if (sub->cstream)
0084 return -EBUSY;
0085
0086 sub->cstream = cstream;
0087 sub->pass_through = 1;
0088 sub->use_mmap = false;
0089
0090 ret = uniphier_aio_comprdma_new(rtd);
0091 if (ret)
0092 return ret;
0093
0094 ret = aio_init(sub);
0095 if (ret)
0096 return ret;
0097
0098 return 0;
0099 }
0100
0101 static int uniphier_aio_compr_free(struct snd_soc_component *component,
0102 struct snd_compr_stream *cstream)
0103 {
0104 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0105 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0));
0106 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
0107 int ret;
0108
0109 ret = uniphier_aio_compr_hw_free(component, cstream);
0110 if (ret)
0111 return ret;
0112 ret = uniphier_aio_comprdma_free(rtd);
0113 if (ret)
0114 return ret;
0115
0116 sub->cstream = NULL;
0117
0118 return 0;
0119 }
0120
0121 static int uniphier_aio_compr_get_params(struct snd_soc_component *component,
0122 struct snd_compr_stream *cstream,
0123 struct snd_codec *params)
0124 {
0125 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0126 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0));
0127 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
0128
0129 *params = sub->cparams.codec;
0130
0131 return 0;
0132 }
0133
0134 static int uniphier_aio_compr_set_params(struct snd_soc_component *component,
0135 struct snd_compr_stream *cstream,
0136 struct snd_compr_params *params)
0137 {
0138 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0139 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0));
0140 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
0141 struct device *dev = &aio->chip->pdev->dev;
0142
0143 if (params->codec.id != SND_AUDIOCODEC_IEC61937) {
0144 dev_err(dev, "Codec ID is not supported(%d)\n",
0145 params->codec.id);
0146 return -EINVAL;
0147 }
0148 if (params->codec.profile != SND_AUDIOPROFILE_IEC61937_SPDIF) {
0149 dev_err(dev, "Codec profile is not supported(%d)\n",
0150 params->codec.profile);
0151 return -EINVAL;
0152 }
0153
0154
0155 sub->iec_pc = IEC61937_PC_AAC;
0156
0157 sub->cparams = *params;
0158 sub->setting = 1;
0159
0160 aio_port_reset(sub);
0161 aio_src_reset(sub);
0162
0163 return uniphier_aio_compr_prepare(component, cstream);
0164 }
0165
0166 static int uniphier_aio_compr_hw_free(struct snd_soc_component *component,
0167 struct snd_compr_stream *cstream)
0168 {
0169 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0170 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0));
0171 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
0172
0173 sub->setting = 0;
0174
0175 return 0;
0176 }
0177
0178 static int uniphier_aio_compr_prepare(struct snd_soc_component *component,
0179 struct snd_compr_stream *cstream)
0180 {
0181 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0182 struct snd_compr_runtime *runtime = cstream->runtime;
0183 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0));
0184 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
0185 int bytes = runtime->fragment_size;
0186 unsigned long flags;
0187 int ret;
0188
0189 ret = aiodma_ch_set_param(sub);
0190 if (ret)
0191 return ret;
0192
0193 spin_lock_irqsave(&sub->lock, flags);
0194 ret = aiodma_rb_set_buffer(sub, sub->compr_addr,
0195 sub->compr_addr + sub->compr_bytes,
0196 bytes);
0197 spin_unlock_irqrestore(&sub->lock, flags);
0198 if (ret)
0199 return ret;
0200
0201 ret = aio_port_set_param(sub, sub->pass_through, &sub->params);
0202 if (ret)
0203 return ret;
0204 ret = aio_oport_set_stream_type(sub, sub->iec_pc);
0205 if (ret)
0206 return ret;
0207 aio_port_set_enable(sub, 1);
0208
0209 ret = aio_if_set_param(sub, sub->pass_through);
0210 if (ret)
0211 return ret;
0212
0213 return 0;
0214 }
0215
0216 static int uniphier_aio_compr_trigger(struct snd_soc_component *component,
0217 struct snd_compr_stream *cstream,
0218 int cmd)
0219 {
0220 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0221 struct snd_compr_runtime *runtime = cstream->runtime;
0222 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0));
0223 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
0224 struct device *dev = &aio->chip->pdev->dev;
0225 int bytes = runtime->fragment_size, ret = 0;
0226 unsigned long flags;
0227
0228 spin_lock_irqsave(&sub->lock, flags);
0229 switch (cmd) {
0230 case SNDRV_PCM_TRIGGER_START:
0231 aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
0232 aiodma_ch_set_enable(sub, 1);
0233 sub->running = 1;
0234
0235 break;
0236 case SNDRV_PCM_TRIGGER_STOP:
0237 sub->running = 0;
0238 aiodma_ch_set_enable(sub, 0);
0239
0240 break;
0241 default:
0242 dev_warn(dev, "Unknown trigger(%d)\n", cmd);
0243 ret = -EINVAL;
0244 }
0245 spin_unlock_irqrestore(&sub->lock, flags);
0246
0247 return ret;
0248 }
0249
0250 static int uniphier_aio_compr_pointer(struct snd_soc_component *component,
0251 struct snd_compr_stream *cstream,
0252 struct snd_compr_tstamp *tstamp)
0253 {
0254 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0255 struct snd_compr_runtime *runtime = cstream->runtime;
0256 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0));
0257 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
0258 int bytes = runtime->fragment_size;
0259 unsigned long flags;
0260 u32 pos;
0261
0262 spin_lock_irqsave(&sub->lock, flags);
0263
0264 aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
0265
0266 if (sub->swm->dir == PORT_DIR_OUTPUT) {
0267 pos = sub->rd_offs;
0268
0269 tstamp->copied_total = sub->rd_total / 2;
0270 } else {
0271 pos = sub->wr_offs;
0272 tstamp->copied_total = sub->rd_total;
0273 }
0274 tstamp->byte_offset = pos;
0275
0276 spin_unlock_irqrestore(&sub->lock, flags);
0277
0278 return 0;
0279 }
0280
0281 static int aio_compr_send_to_hw(struct uniphier_aio_sub *sub,
0282 char __user *buf, size_t dstsize)
0283 {
0284 u32 __user *srcbuf = (u32 __user *)buf;
0285 u32 *dstbuf = (u32 *)(sub->compr_area + sub->wr_offs);
0286 int src = 0, dst = 0, ret;
0287 u32 frm, frm_a, frm_b;
0288
0289 while (dstsize > 0) {
0290 ret = get_user(frm, srcbuf + src);
0291 if (ret)
0292 return ret;
0293 src++;
0294
0295 frm_a = frm & 0xffff;
0296 frm_b = (frm >> 16) & 0xffff;
0297
0298 if (frm == IEC61937_HEADER_SIGN) {
0299 frm_a |= 0x01000000;
0300
0301
0302 sub->iec_header = true;
0303 } else {
0304 u16 pc = be16_to_cpu((__be16)frm_a);
0305
0306 if (sub->iec_header && sub->iec_pc != pc) {
0307
0308 sub->iec_pc = pc;
0309 ret = aio_oport_set_stream_type(sub, pc);
0310 if (ret)
0311 return ret;
0312 }
0313 sub->iec_header = false;
0314 }
0315 dstbuf[dst++] = frm_a;
0316 dstbuf[dst++] = frm_b;
0317
0318 dstsize -= sizeof(u32) * 2;
0319 }
0320
0321 return 0;
0322 }
0323
0324 static int uniphier_aio_compr_copy(struct snd_soc_component *component,
0325 struct snd_compr_stream *cstream,
0326 char __user *buf, size_t count)
0327 {
0328 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
0329 struct snd_compr_runtime *runtime = cstream->runtime;
0330 struct device *carddev = rtd->compr->card->dev;
0331 struct uniphier_aio *aio = uniphier_priv(asoc_rtd_to_cpu(rtd, 0));
0332 struct uniphier_aio_sub *sub = &aio->sub[cstream->direction];
0333 size_t cnt = min_t(size_t, count, aio_rb_space_to_end(sub) / 2);
0334 int bytes = runtime->fragment_size;
0335 unsigned long flags;
0336 size_t s;
0337 int ret;
0338
0339 if (cnt < sizeof(u32))
0340 return 0;
0341
0342 if (sub->swm->dir == PORT_DIR_OUTPUT) {
0343 dma_addr_t dmapos = sub->compr_addr + sub->wr_offs;
0344
0345
0346 s = cnt * 2;
0347
0348 dma_sync_single_for_cpu(carddev, dmapos, s, DMA_TO_DEVICE);
0349 ret = aio_compr_send_to_hw(sub, buf, s);
0350 dma_sync_single_for_device(carddev, dmapos, s, DMA_TO_DEVICE);
0351 } else {
0352 dma_addr_t dmapos = sub->compr_addr + sub->rd_offs;
0353
0354 s = cnt;
0355
0356 dma_sync_single_for_cpu(carddev, dmapos, s, DMA_FROM_DEVICE);
0357 ret = copy_to_user(buf, sub->compr_area + sub->rd_offs, s);
0358 dma_sync_single_for_device(carddev, dmapos, s, DMA_FROM_DEVICE);
0359 }
0360 if (ret)
0361 return -EFAULT;
0362
0363 spin_lock_irqsave(&sub->lock, flags);
0364
0365 sub->threshold = 2 * bytes;
0366 aiodma_rb_set_threshold(sub, sub->compr_bytes, 2 * bytes);
0367
0368 if (sub->swm->dir == PORT_DIR_OUTPUT) {
0369 sub->wr_offs += s;
0370 if (sub->wr_offs >= sub->compr_bytes)
0371 sub->wr_offs -= sub->compr_bytes;
0372 } else {
0373 sub->rd_offs += s;
0374 if (sub->rd_offs >= sub->compr_bytes)
0375 sub->rd_offs -= sub->compr_bytes;
0376 }
0377 aiodma_rb_sync(sub, sub->compr_addr, sub->compr_bytes, bytes);
0378
0379 spin_unlock_irqrestore(&sub->lock, flags);
0380
0381 return cnt;
0382 }
0383
0384 static int uniphier_aio_compr_get_caps(struct snd_soc_component *component,
0385 struct snd_compr_stream *cstream,
0386 struct snd_compr_caps *caps)
0387 {
0388 caps->num_codecs = 1;
0389 caps->min_fragment_size = AUD_MIN_FRAGMENT_SIZE;
0390 caps->max_fragment_size = AUD_MAX_FRAGMENT_SIZE;
0391 caps->min_fragments = AUD_MIN_FRAGMENT;
0392 caps->max_fragments = AUD_MAX_FRAGMENT;
0393 caps->codecs[0] = SND_AUDIOCODEC_IEC61937;
0394
0395 return 0;
0396 }
0397
0398 static const struct snd_compr_codec_caps caps_iec = {
0399 .num_descriptors = 1,
0400 .descriptor[0].max_ch = 8,
0401 .descriptor[0].num_sample_rates = 0,
0402 .descriptor[0].num_bitrates = 0,
0403 .descriptor[0].profiles = SND_AUDIOPROFILE_IEC61937_SPDIF,
0404 .descriptor[0].modes = SND_AUDIOMODE_IEC_AC3 |
0405 SND_AUDIOMODE_IEC_MPEG1 |
0406 SND_AUDIOMODE_IEC_MP3 |
0407 SND_AUDIOMODE_IEC_DTS,
0408 .descriptor[0].formats = 0,
0409 };
0410
0411 static int uniphier_aio_compr_get_codec_caps(struct snd_soc_component *component,
0412 struct snd_compr_stream *stream,
0413 struct snd_compr_codec_caps *codec)
0414 {
0415 if (codec->codec == SND_AUDIOCODEC_IEC61937)
0416 *codec = caps_iec;
0417 else
0418 return -EINVAL;
0419
0420 return 0;
0421 }
0422
0423 const struct snd_compress_ops uniphier_aio_compress_ops = {
0424 .open = uniphier_aio_compr_open,
0425 .free = uniphier_aio_compr_free,
0426 .get_params = uniphier_aio_compr_get_params,
0427 .set_params = uniphier_aio_compr_set_params,
0428 .trigger = uniphier_aio_compr_trigger,
0429 .pointer = uniphier_aio_compr_pointer,
0430 .copy = uniphier_aio_compr_copy,
0431 .get_caps = uniphier_aio_compr_get_caps,
0432 .get_codec_caps = uniphier_aio_compr_get_codec_caps,
0433 };