0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/input.h>
0011 #include <linux/spi/spi.h>
0012 #include <linux/device.h>
0013 #include <linux/init.h>
0014 #include <linux/delay.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/irq.h>
0017 #include <linux/slab.h>
0018 #include <linux/sched.h>
0019 #include <linux/uaccess.h>
0020 #include <linux/regulator/consumer.h>
0021 #include <linux/pm_qos.h>
0022 #include <linux/sysfs.h>
0023 #include <linux/clk.h>
0024 #include <linux/firmware.h>
0025 #include <linux/acpi.h>
0026
0027 #include <sound/soc.h>
0028
0029 #include "rt5677.h"
0030 #include "rt5677-spi.h"
0031
0032 #define DRV_NAME "rt5677spi"
0033
0034 #define RT5677_SPI_BURST_LEN 240
0035 #define RT5677_SPI_HEADER 5
0036 #define RT5677_SPI_FREQ 6000000
0037
0038
0039
0040
0041
0042
0043
0044 #define RT5677_SPI_WRITE_BURST 0x5
0045 #define RT5677_SPI_READ_BURST 0x4
0046 #define RT5677_SPI_WRITE_32 0x3
0047 #define RT5677_SPI_READ_32 0x2
0048 #define RT5677_SPI_WRITE_16 0x1
0049 #define RT5677_SPI_READ_16 0x0
0050
0051 #define RT5677_BUF_BYTES_TOTAL 0x20000
0052 #define RT5677_MIC_BUF_ADDR 0x60030000
0053 #define RT5677_MODEL_ADDR 0x5FFC9800
0054 #define RT5677_MIC_BUF_BYTES ((u32)(RT5677_BUF_BYTES_TOTAL - \
0055 sizeof(u32)))
0056 #define RT5677_MIC_BUF_FIRST_READ_SIZE 0x10000
0057
0058 static struct spi_device *g_spi;
0059 static DEFINE_MUTEX(spi_mutex);
0060
0061 struct rt5677_dsp {
0062 struct device *dev;
0063 struct delayed_work copy_work;
0064 struct mutex dma_lock;
0065 struct snd_pcm_substream *substream;
0066 size_t dma_offset;
0067 size_t avail_bytes;
0068 u32 mic_read_offset;
0069 bool new_hotword;
0070 };
0071
0072 static const struct snd_pcm_hardware rt5677_spi_pcm_hardware = {
0073 .info = SNDRV_PCM_INFO_MMAP |
0074 SNDRV_PCM_INFO_MMAP_VALID |
0075 SNDRV_PCM_INFO_INTERLEAVED,
0076 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0077 .period_bytes_min = PAGE_SIZE,
0078 .period_bytes_max = RT5677_BUF_BYTES_TOTAL / 8,
0079 .periods_min = 8,
0080 .periods_max = 8,
0081 .channels_min = 1,
0082 .channels_max = 1,
0083 .buffer_bytes_max = RT5677_BUF_BYTES_TOTAL,
0084 };
0085
0086 static struct snd_soc_dai_driver rt5677_spi_dai = {
0087
0088
0089
0090
0091 .name = "rt5677-dsp-cpu-dai",
0092 .id = 0,
0093 .capture = {
0094 .stream_name = "DSP Capture",
0095 .channels_min = 1,
0096 .channels_max = 1,
0097 .rates = SNDRV_PCM_RATE_16000,
0098 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0099 },
0100 };
0101
0102
0103 static int rt5677_spi_pcm_open(
0104 struct snd_soc_component *component,
0105 struct snd_pcm_substream *substream)
0106 {
0107 snd_soc_set_runtime_hwparams(substream, &rt5677_spi_pcm_hardware);
0108 return 0;
0109 }
0110
0111 static int rt5677_spi_pcm_close(
0112 struct snd_soc_component *component,
0113 struct snd_pcm_substream *substream)
0114 {
0115 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0116 struct snd_soc_component *codec_component =
0117 snd_soc_rtdcom_lookup(rtd, "rt5677");
0118 struct rt5677_priv *rt5677 =
0119 snd_soc_component_get_drvdata(codec_component);
0120 struct rt5677_dsp *rt5677_dsp =
0121 snd_soc_component_get_drvdata(component);
0122
0123 cancel_delayed_work_sync(&rt5677_dsp->copy_work);
0124 rt5677->set_dsp_vad(codec_component, false);
0125 return 0;
0126 }
0127
0128 static int rt5677_spi_hw_params(
0129 struct snd_soc_component *component,
0130 struct snd_pcm_substream *substream,
0131 struct snd_pcm_hw_params *hw_params)
0132 {
0133 struct rt5677_dsp *rt5677_dsp =
0134 snd_soc_component_get_drvdata(component);
0135
0136 mutex_lock(&rt5677_dsp->dma_lock);
0137 rt5677_dsp->substream = substream;
0138 mutex_unlock(&rt5677_dsp->dma_lock);
0139
0140 return 0;
0141 }
0142
0143 static int rt5677_spi_hw_free(
0144 struct snd_soc_component *component,
0145 struct snd_pcm_substream *substream)
0146 {
0147 struct rt5677_dsp *rt5677_dsp =
0148 snd_soc_component_get_drvdata(component);
0149
0150 mutex_lock(&rt5677_dsp->dma_lock);
0151 rt5677_dsp->substream = NULL;
0152 mutex_unlock(&rt5677_dsp->dma_lock);
0153
0154 return 0;
0155 }
0156
0157 static int rt5677_spi_prepare(
0158 struct snd_soc_component *component,
0159 struct snd_pcm_substream *substream)
0160 {
0161 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0162 struct snd_soc_component *rt5677_component =
0163 snd_soc_rtdcom_lookup(rtd, "rt5677");
0164 struct rt5677_priv *rt5677 =
0165 snd_soc_component_get_drvdata(rt5677_component);
0166 struct rt5677_dsp *rt5677_dsp =
0167 snd_soc_component_get_drvdata(component);
0168
0169 rt5677->set_dsp_vad(rt5677_component, true);
0170 rt5677_dsp->dma_offset = 0;
0171 rt5677_dsp->avail_bytes = 0;
0172 return 0;
0173 }
0174
0175 static snd_pcm_uframes_t rt5677_spi_pcm_pointer(
0176 struct snd_soc_component *component,
0177 struct snd_pcm_substream *substream)
0178 {
0179 struct snd_pcm_runtime *runtime = substream->runtime;
0180 struct rt5677_dsp *rt5677_dsp =
0181 snd_soc_component_get_drvdata(component);
0182
0183 return bytes_to_frames(runtime, rt5677_dsp->dma_offset);
0184 }
0185
0186 static int rt5677_spi_mic_write_offset(u32 *mic_write_offset)
0187 {
0188 int ret;
0189
0190
0191
0192
0193 ret = rt5677_spi_read(RT5677_MIC_BUF_ADDR, mic_write_offset,
0194 sizeof(u32));
0195 if (ret)
0196 return ret;
0197
0198 *mic_write_offset = *mic_write_offset - sizeof(u32);
0199 return *mic_write_offset < RT5677_MIC_BUF_BYTES ? 0 : -EFAULT;
0200 }
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211 static int rt5677_spi_copy_block(struct rt5677_dsp *rt5677_dsp,
0212 u32 begin, u32 end)
0213 {
0214 struct snd_pcm_runtime *runtime = rt5677_dsp->substream->runtime;
0215 size_t bytes_per_frame = frames_to_bytes(runtime, 1);
0216 size_t first_chunk_len, second_chunk_len;
0217 int ret;
0218
0219 if (begin > end || runtime->dma_bytes < 2 * bytes_per_frame) {
0220 dev_err(rt5677_dsp->dev,
0221 "Invalid copy from (%u, %u), dma_area size %zu\n",
0222 begin, end, runtime->dma_bytes);
0223 return -EINVAL;
0224 }
0225
0226
0227 if (begin == end)
0228 return 0;
0229
0230
0231
0232
0233 if (end - begin > runtime->dma_bytes - bytes_per_frame)
0234 begin = end - (runtime->dma_bytes - bytes_per_frame);
0235
0236
0237 first_chunk_len = end - begin;
0238 second_chunk_len = 0;
0239 if (rt5677_dsp->dma_offset + first_chunk_len > runtime->dma_bytes) {
0240
0241 second_chunk_len = first_chunk_len;
0242 first_chunk_len = runtime->dma_bytes - rt5677_dsp->dma_offset;
0243 second_chunk_len -= first_chunk_len;
0244 }
0245
0246
0247 ret = rt5677_spi_read(RT5677_MIC_BUF_ADDR + sizeof(u32) + begin,
0248 runtime->dma_area + rt5677_dsp->dma_offset,
0249 first_chunk_len);
0250 if (ret)
0251 return ret;
0252 rt5677_dsp->dma_offset += first_chunk_len;
0253 if (rt5677_dsp->dma_offset == runtime->dma_bytes)
0254 rt5677_dsp->dma_offset = 0;
0255
0256
0257 if (second_chunk_len) {
0258 ret = rt5677_spi_read(RT5677_MIC_BUF_ADDR + sizeof(u32) +
0259 begin + first_chunk_len, runtime->dma_area,
0260 second_chunk_len);
0261 if (!ret)
0262 rt5677_dsp->dma_offset = second_chunk_len;
0263 }
0264 return ret;
0265 }
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275 static int rt5677_spi_copy(struct rt5677_dsp *rt5677_dsp, u32 amount)
0276 {
0277 int ret = 0;
0278 u32 target;
0279
0280 if (amount == 0)
0281 return ret;
0282
0283 target = rt5677_dsp->mic_read_offset + amount;
0284
0285 ret |= rt5677_spi_copy_block(rt5677_dsp, rt5677_dsp->mic_read_offset,
0286 min(target, RT5677_MIC_BUF_BYTES));
0287
0288 if (target >= RT5677_MIC_BUF_BYTES) {
0289
0290 target -= RT5677_MIC_BUF_BYTES;
0291 ret |= rt5677_spi_copy_block(rt5677_dsp, 0, target);
0292 }
0293
0294 if (!ret)
0295 rt5677_dsp->mic_read_offset = target;
0296 return ret;
0297 }
0298
0299
0300
0301
0302
0303 static void rt5677_spi_copy_work(struct work_struct *work)
0304 {
0305 struct rt5677_dsp *rt5677_dsp =
0306 container_of(work, struct rt5677_dsp, copy_work.work);
0307 struct snd_pcm_runtime *runtime;
0308 u32 mic_write_offset;
0309 size_t new_bytes, copy_bytes, period_bytes;
0310 unsigned int delay;
0311 int ret = 0;
0312
0313
0314 mutex_lock(&rt5677_dsp->dma_lock);
0315 if (!rt5677_dsp->substream) {
0316 dev_err(rt5677_dsp->dev, "No pcm substream\n");
0317 goto done;
0318 }
0319
0320 runtime = rt5677_dsp->substream->runtime;
0321
0322 if (rt5677_spi_mic_write_offset(&mic_write_offset)) {
0323 dev_err(rt5677_dsp->dev, "No mic_write_offset\n");
0324 goto done;
0325 }
0326
0327
0328
0329
0330
0331 if (rt5677_dsp->new_hotword) {
0332 rt5677_dsp->new_hotword = false;
0333
0334 if (mic_write_offset < RT5677_MIC_BUF_FIRST_READ_SIZE)
0335 rt5677_dsp->mic_read_offset = RT5677_MIC_BUF_BYTES -
0336 (RT5677_MIC_BUF_FIRST_READ_SIZE -
0337 mic_write_offset);
0338 else
0339 rt5677_dsp->mic_read_offset = mic_write_offset -
0340 RT5677_MIC_BUF_FIRST_READ_SIZE;
0341 }
0342
0343
0344 if (rt5677_dsp->mic_read_offset <= mic_write_offset)
0345 new_bytes = mic_write_offset - rt5677_dsp->mic_read_offset;
0346 else
0347 new_bytes = RT5677_MIC_BUF_BYTES + mic_write_offset
0348 - rt5677_dsp->mic_read_offset;
0349
0350
0351 period_bytes = snd_pcm_lib_period_bytes(rt5677_dsp->substream);
0352 while (new_bytes) {
0353 copy_bytes = min(new_bytes, period_bytes
0354 - rt5677_dsp->avail_bytes);
0355 ret = rt5677_spi_copy(rt5677_dsp, copy_bytes);
0356 if (ret) {
0357 dev_err(rt5677_dsp->dev, "Copy failed %d\n", ret);
0358 goto done;
0359 }
0360 rt5677_dsp->avail_bytes += copy_bytes;
0361 if (rt5677_dsp->avail_bytes >= period_bytes) {
0362 snd_pcm_period_elapsed(rt5677_dsp->substream);
0363 rt5677_dsp->avail_bytes = 0;
0364 }
0365 new_bytes -= copy_bytes;
0366 }
0367
0368 delay = bytes_to_frames(runtime, period_bytes) / (runtime->rate / 1000);
0369 schedule_delayed_work(&rt5677_dsp->copy_work, msecs_to_jiffies(delay));
0370 done:
0371 mutex_unlock(&rt5677_dsp->dma_lock);
0372 }
0373
0374 static int rt5677_spi_pcm_new(struct snd_soc_component *component,
0375 struct snd_soc_pcm_runtime *rtd)
0376 {
0377 snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_VMALLOC,
0378 NULL, 0, 0);
0379 return 0;
0380 }
0381
0382 static int rt5677_spi_pcm_probe(struct snd_soc_component *component)
0383 {
0384 struct rt5677_dsp *rt5677_dsp;
0385
0386 rt5677_dsp = devm_kzalloc(component->dev, sizeof(*rt5677_dsp),
0387 GFP_KERNEL);
0388 if (!rt5677_dsp)
0389 return -ENOMEM;
0390 rt5677_dsp->dev = &g_spi->dev;
0391 mutex_init(&rt5677_dsp->dma_lock);
0392 INIT_DELAYED_WORK(&rt5677_dsp->copy_work, rt5677_spi_copy_work);
0393
0394 snd_soc_component_set_drvdata(component, rt5677_dsp);
0395 return 0;
0396 }
0397
0398 static const struct snd_soc_component_driver rt5677_spi_dai_component = {
0399 .name = DRV_NAME,
0400 .probe = rt5677_spi_pcm_probe,
0401 .open = rt5677_spi_pcm_open,
0402 .close = rt5677_spi_pcm_close,
0403 .hw_params = rt5677_spi_hw_params,
0404 .hw_free = rt5677_spi_hw_free,
0405 .prepare = rt5677_spi_prepare,
0406 .pointer = rt5677_spi_pcm_pointer,
0407 .pcm_construct = rt5677_spi_pcm_new,
0408 };
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438 static u8 rt5677_spi_select_cmd(bool read, u32 align, u32 remain, u32 *len)
0439 {
0440 u8 cmd;
0441
0442 if (align == 4 || remain <= 4) {
0443 cmd = RT5677_SPI_READ_32;
0444 *len = 4;
0445 } else {
0446 cmd = RT5677_SPI_READ_BURST;
0447 *len = (((remain - 1) >> 3) + 1) << 3;
0448 *len = min_t(u32, *len, RT5677_SPI_BURST_LEN);
0449 }
0450 return read ? cmd : cmd + 1;
0451 }
0452
0453
0454
0455
0456 static void rt5677_spi_reverse(u8 *dst, u32 dstlen, const u8 *src, u32 srclen)
0457 {
0458 u32 w, i, si;
0459 u32 word_size = min_t(u32, dstlen, 8);
0460
0461 for (w = 0; w < dstlen; w += word_size) {
0462 for (i = 0; i < word_size && i + w < dstlen; i++) {
0463 si = w + word_size - i - 1;
0464 dst[w + i] = si < srclen ? src[si] : 0;
0465 }
0466 }
0467 }
0468
0469
0470 int rt5677_spi_read(u32 addr, void *rxbuf, size_t len)
0471 {
0472 u32 offset;
0473 int status = 0;
0474 struct spi_transfer t[2];
0475 struct spi_message m;
0476
0477 u8 header[RT5677_SPI_HEADER + 4];
0478 u8 body[RT5677_SPI_BURST_LEN];
0479 u8 spi_cmd;
0480 u8 *cb = rxbuf;
0481
0482 if (!g_spi)
0483 return -ENODEV;
0484
0485 if ((addr & 3) || (len & 3)) {
0486 dev_err(&g_spi->dev, "Bad read align 0x%x(%zu)\n", addr, len);
0487 return -EACCES;
0488 }
0489
0490 memset(t, 0, sizeof(t));
0491 t[0].tx_buf = header;
0492 t[0].len = sizeof(header);
0493 t[0].speed_hz = RT5677_SPI_FREQ;
0494 t[1].rx_buf = body;
0495 t[1].speed_hz = RT5677_SPI_FREQ;
0496 spi_message_init_with_transfers(&m, t, ARRAY_SIZE(t));
0497
0498 for (offset = 0; offset < len; offset += t[1].len) {
0499 spi_cmd = rt5677_spi_select_cmd(true, (addr + offset) & 7,
0500 len - offset, &t[1].len);
0501
0502
0503 header[0] = spi_cmd;
0504 header[1] = ((addr + offset) & 0xff000000) >> 24;
0505 header[2] = ((addr + offset) & 0x00ff0000) >> 16;
0506 header[3] = ((addr + offset) & 0x0000ff00) >> 8;
0507 header[4] = ((addr + offset) & 0x000000ff) >> 0;
0508
0509 mutex_lock(&spi_mutex);
0510 status |= spi_sync(g_spi, &m);
0511 mutex_unlock(&spi_mutex);
0512
0513
0514
0515 rt5677_spi_reverse(cb + offset, len - offset, body, t[1].len);
0516 }
0517 return status;
0518 }
0519 EXPORT_SYMBOL_GPL(rt5677_spi_read);
0520
0521
0522
0523
0524
0525 int rt5677_spi_write(u32 addr, const void *txbuf, size_t len)
0526 {
0527 u32 offset;
0528 int status = 0;
0529 struct spi_transfer t;
0530 struct spi_message m;
0531
0532 u8 buf[RT5677_SPI_HEADER + RT5677_SPI_BURST_LEN + 1];
0533 u8 *body = buf + RT5677_SPI_HEADER;
0534 u8 spi_cmd;
0535 const u8 *cb = txbuf;
0536
0537 if (!g_spi)
0538 return -ENODEV;
0539
0540 if (addr & 3) {
0541 dev_err(&g_spi->dev, "Bad write align 0x%x(%zu)\n", addr, len);
0542 return -EACCES;
0543 }
0544
0545 memset(&t, 0, sizeof(t));
0546 t.tx_buf = buf;
0547 t.speed_hz = RT5677_SPI_FREQ;
0548 spi_message_init_with_transfers(&m, &t, 1);
0549
0550 for (offset = 0; offset < len;) {
0551 spi_cmd = rt5677_spi_select_cmd(false, (addr + offset) & 7,
0552 len - offset, &t.len);
0553
0554
0555 buf[0] = spi_cmd;
0556 buf[1] = ((addr + offset) & 0xff000000) >> 24;
0557 buf[2] = ((addr + offset) & 0x00ff0000) >> 16;
0558 buf[3] = ((addr + offset) & 0x0000ff00) >> 8;
0559 buf[4] = ((addr + offset) & 0x000000ff) >> 0;
0560
0561
0562 rt5677_spi_reverse(body, t.len, cb + offset, len - offset);
0563 offset += t.len;
0564 t.len += RT5677_SPI_HEADER + 1;
0565
0566 mutex_lock(&spi_mutex);
0567 status |= spi_sync(g_spi, &m);
0568 mutex_unlock(&spi_mutex);
0569 }
0570 return status;
0571 }
0572 EXPORT_SYMBOL_GPL(rt5677_spi_write);
0573
0574 int rt5677_spi_write_firmware(u32 addr, const struct firmware *fw)
0575 {
0576 return rt5677_spi_write(addr, fw->data, fw->size);
0577 }
0578 EXPORT_SYMBOL_GPL(rt5677_spi_write_firmware);
0579
0580 void rt5677_spi_hotword_detected(void)
0581 {
0582 struct rt5677_dsp *rt5677_dsp;
0583
0584 if (!g_spi)
0585 return;
0586
0587 rt5677_dsp = dev_get_drvdata(&g_spi->dev);
0588 if (!rt5677_dsp) {
0589 dev_err(&g_spi->dev, "Can't get rt5677_dsp\n");
0590 return;
0591 }
0592
0593 mutex_lock(&rt5677_dsp->dma_lock);
0594 dev_info(rt5677_dsp->dev, "Hotword detected\n");
0595 rt5677_dsp->new_hotword = true;
0596 mutex_unlock(&rt5677_dsp->dma_lock);
0597
0598 schedule_delayed_work(&rt5677_dsp->copy_work, 0);
0599 }
0600 EXPORT_SYMBOL_GPL(rt5677_spi_hotword_detected);
0601
0602 static int rt5677_spi_probe(struct spi_device *spi)
0603 {
0604 int ret;
0605
0606 g_spi = spi;
0607
0608 ret = devm_snd_soc_register_component(&spi->dev,
0609 &rt5677_spi_dai_component,
0610 &rt5677_spi_dai, 1);
0611 if (ret < 0)
0612 dev_err(&spi->dev, "Failed to register component.\n");
0613
0614 return ret;
0615 }
0616
0617 #ifdef CONFIG_ACPI
0618 static const struct acpi_device_id rt5677_spi_acpi_id[] = {
0619 { "RT5677AA", 0 },
0620 { }
0621 };
0622 MODULE_DEVICE_TABLE(acpi, rt5677_spi_acpi_id);
0623 #endif
0624
0625 static struct spi_driver rt5677_spi_driver = {
0626 .driver = {
0627 .name = DRV_NAME,
0628 .acpi_match_table = ACPI_PTR(rt5677_spi_acpi_id),
0629 },
0630 .probe = rt5677_spi_probe,
0631 };
0632 module_spi_driver(rt5677_spi_driver);
0633
0634 MODULE_DESCRIPTION("ASoC RT5677 SPI driver");
0635 MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
0636 MODULE_LICENSE("GPL v2");