1
2
3
4
5
6
7
8
9#include <linux/module.h>
10#include <linux/input.h>
11#include <linux/spi/spi.h>
12#include <linux/device.h>
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/interrupt.h>
16#include <linux/irq.h>
17#include <linux/slab.h>
18#include <linux/sched.h>
19#include <linux/uaccess.h>
20#include <linux/regulator/consumer.h>
21#include <linux/pm_qos.h>
22#include <linux/sysfs.h>
23#include <linux/clk.h>
24#include <linux/firmware.h>
25#include <linux/acpi.h>
26
27#include <sound/soc.h>
28
29#include "rt5677.h"
30#include "rt5677-spi.h"
31
32#define DRV_NAME "rt5677spi"
33
34#define RT5677_SPI_BURST_LEN 240
35#define RT5677_SPI_HEADER 5
36#define RT5677_SPI_FREQ 6000000
37
38
39
40
41
42
43
44#define RT5677_SPI_WRITE_BURST 0x5
45#define RT5677_SPI_READ_BURST 0x4
46#define RT5677_SPI_WRITE_32 0x3
47#define RT5677_SPI_READ_32 0x2
48#define RT5677_SPI_WRITE_16 0x1
49#define RT5677_SPI_READ_16 0x0
50
51#define RT5677_BUF_BYTES_TOTAL 0x20000
52#define RT5677_MIC_BUF_ADDR 0x60030000
53#define RT5677_MODEL_ADDR 0x5FFC9800
54#define RT5677_MIC_BUF_BYTES ((u32)(RT5677_BUF_BYTES_TOTAL - \
55 sizeof(u32)))
56#define RT5677_MIC_BUF_FIRST_READ_SIZE 0x10000
57
58static struct spi_device *g_spi;
59static DEFINE_MUTEX(spi_mutex);
60
61struct rt5677_dsp {
62 struct device *dev;
63 struct delayed_work copy_work;
64 struct mutex dma_lock;
65 struct snd_pcm_substream *substream;
66 size_t dma_offset;
67 size_t avail_bytes;
68 u32 mic_read_offset;
69 bool new_hotword;
70};
71
72static const struct snd_pcm_hardware rt5677_spi_pcm_hardware = {
73 .info = SNDRV_PCM_INFO_MMAP |
74 SNDRV_PCM_INFO_MMAP_VALID |
75 SNDRV_PCM_INFO_INTERLEAVED,
76 .formats = SNDRV_PCM_FMTBIT_S16_LE,
77 .period_bytes_min = PAGE_SIZE,
78 .period_bytes_max = RT5677_BUF_BYTES_TOTAL / 8,
79 .periods_min = 8,
80 .periods_max = 8,
81 .channels_min = 1,
82 .channels_max = 1,
83 .buffer_bytes_max = RT5677_BUF_BYTES_TOTAL,
84};
85
86static struct snd_soc_dai_driver rt5677_spi_dai = {
87
88
89
90
91 .name = "rt5677-dsp-cpu-dai",
92 .id = 0,
93 .capture = {
94 .stream_name = "DSP Capture",
95 .channels_min = 1,
96 .channels_max = 1,
97 .rates = SNDRV_PCM_RATE_16000,
98 .formats = SNDRV_PCM_FMTBIT_S16_LE,
99 },
100};
101
102
103static int rt5677_spi_pcm_open(
104 struct snd_soc_component *component,
105 struct snd_pcm_substream *substream)
106{
107 snd_soc_set_runtime_hwparams(substream, &rt5677_spi_pcm_hardware);
108 return 0;
109}
110
111static int rt5677_spi_pcm_close(
112 struct snd_soc_component *component,
113 struct snd_pcm_substream *substream)
114{
115 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
116 struct snd_soc_component *codec_component =
117 snd_soc_rtdcom_lookup(rtd, "rt5677");
118 struct rt5677_priv *rt5677 =
119 snd_soc_component_get_drvdata(codec_component);
120 struct rt5677_dsp *rt5677_dsp =
121 snd_soc_component_get_drvdata(component);
122
123 cancel_delayed_work_sync(&rt5677_dsp->copy_work);
124 rt5677->set_dsp_vad(codec_component, false);
125 return 0;
126}
127
128static int rt5677_spi_hw_params(
129 struct snd_soc_component *component,
130 struct snd_pcm_substream *substream,
131 struct snd_pcm_hw_params *hw_params)
132{
133 struct rt5677_dsp *rt5677_dsp =
134 snd_soc_component_get_drvdata(component);
135
136 mutex_lock(&rt5677_dsp->dma_lock);
137 rt5677_dsp->substream = substream;
138 mutex_unlock(&rt5677_dsp->dma_lock);
139
140 return 0;
141}
142
143static int rt5677_spi_hw_free(
144 struct snd_soc_component *component,
145 struct snd_pcm_substream *substream)
146{
147 struct rt5677_dsp *rt5677_dsp =
148 snd_soc_component_get_drvdata(component);
149
150 mutex_lock(&rt5677_dsp->dma_lock);
151 rt5677_dsp->substream = NULL;
152 mutex_unlock(&rt5677_dsp->dma_lock);
153
154 return 0;
155}
156
157static int rt5677_spi_prepare(
158 struct snd_soc_component *component,
159 struct snd_pcm_substream *substream)
160{
161 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
162 struct snd_soc_component *rt5677_component =
163 snd_soc_rtdcom_lookup(rtd, "rt5677");
164 struct rt5677_priv *rt5677 =
165 snd_soc_component_get_drvdata(rt5677_component);
166 struct rt5677_dsp *rt5677_dsp =
167 snd_soc_component_get_drvdata(component);
168
169 rt5677->set_dsp_vad(rt5677_component, true);
170 rt5677_dsp->dma_offset = 0;
171 rt5677_dsp->avail_bytes = 0;
172 return 0;
173}
174
175static snd_pcm_uframes_t rt5677_spi_pcm_pointer(
176 struct snd_soc_component *component,
177 struct snd_pcm_substream *substream)
178{
179 struct snd_pcm_runtime *runtime = substream->runtime;
180 struct rt5677_dsp *rt5677_dsp =
181 snd_soc_component_get_drvdata(component);
182
183 return bytes_to_frames(runtime, rt5677_dsp->dma_offset);
184}
185
186static int rt5677_spi_mic_write_offset(u32 *mic_write_offset)
187{
188 int ret;
189
190
191
192
193 ret = rt5677_spi_read(RT5677_MIC_BUF_ADDR, mic_write_offset,
194 sizeof(u32));
195 if (ret)
196 return ret;
197
198 *mic_write_offset = *mic_write_offset - sizeof(u32);
199 return *mic_write_offset < RT5677_MIC_BUF_BYTES ? 0 : -EFAULT;
200}
201
202
203
204
205
206
207
208
209
210
211static int rt5677_spi_copy_block(struct rt5677_dsp *rt5677_dsp,
212 u32 begin, u32 end)
213{
214 struct snd_pcm_runtime *runtime = rt5677_dsp->substream->runtime;
215 size_t bytes_per_frame = frames_to_bytes(runtime, 1);
216 size_t first_chunk_len, second_chunk_len;
217 int ret;
218
219 if (begin > end || runtime->dma_bytes < 2 * bytes_per_frame) {
220 dev_err(rt5677_dsp->dev,
221 "Invalid copy from (%u, %u), dma_area size %zu\n",
222 begin, end, runtime->dma_bytes);
223 return -EINVAL;
224 }
225
226
227 if (begin == end)
228 return 0;
229
230
231
232
233 if (end - begin > runtime->dma_bytes - bytes_per_frame)
234 begin = end - (runtime->dma_bytes - bytes_per_frame);
235
236
237 first_chunk_len = end - begin;
238 second_chunk_len = 0;
239 if (rt5677_dsp->dma_offset + first_chunk_len > runtime->dma_bytes) {
240
241 second_chunk_len = first_chunk_len;
242 first_chunk_len = runtime->dma_bytes - rt5677_dsp->dma_offset;
243 second_chunk_len -= first_chunk_len;
244 }
245
246
247 ret = rt5677_spi_read(RT5677_MIC_BUF_ADDR + sizeof(u32) + begin,
248 runtime->dma_area + rt5677_dsp->dma_offset,
249 first_chunk_len);
250 if (ret)
251 return ret;
252 rt5677_dsp->dma_offset += first_chunk_len;
253 if (rt5677_dsp->dma_offset == runtime->dma_bytes)
254 rt5677_dsp->dma_offset = 0;
255
256
257 if (second_chunk_len) {
258 ret = rt5677_spi_read(RT5677_MIC_BUF_ADDR + sizeof(u32) +
259 begin + first_chunk_len, runtime->dma_area,
260 second_chunk_len);
261 if (!ret)
262 rt5677_dsp->dma_offset = second_chunk_len;
263 }
264 return ret;
265}
266
267
268
269
270
271
272
273
274
275static int rt5677_spi_copy(struct rt5677_dsp *rt5677_dsp, u32 amount)
276{
277 int ret = 0;
278 u32 target;
279
280 if (amount == 0)
281 return ret;
282
283 target = rt5677_dsp->mic_read_offset + amount;
284
285 ret |= rt5677_spi_copy_block(rt5677_dsp, rt5677_dsp->mic_read_offset,
286 min(target, RT5677_MIC_BUF_BYTES));
287
288 if (target >= RT5677_MIC_BUF_BYTES) {
289
290 target -= RT5677_MIC_BUF_BYTES;
291 ret |= rt5677_spi_copy_block(rt5677_dsp, 0, target);
292 }
293
294 if (!ret)
295 rt5677_dsp->mic_read_offset = target;
296 return ret;
297}
298
299
300
301
302
303static void rt5677_spi_copy_work(struct work_struct *work)
304{
305 struct rt5677_dsp *rt5677_dsp =
306 container_of(work, struct rt5677_dsp, copy_work.work);
307 struct snd_pcm_runtime *runtime;
308 u32 mic_write_offset;
309 size_t new_bytes, copy_bytes, period_bytes;
310 unsigned int delay;
311 int ret = 0;
312
313
314 mutex_lock(&rt5677_dsp->dma_lock);
315 if (!rt5677_dsp->substream) {
316 dev_err(rt5677_dsp->dev, "No pcm substream\n");
317 goto done;
318 }
319
320 runtime = rt5677_dsp->substream->runtime;
321
322 if (rt5677_spi_mic_write_offset(&mic_write_offset)) {
323 dev_err(rt5677_dsp->dev, "No mic_write_offset\n");
324 goto done;
325 }
326
327
328
329
330
331 if (rt5677_dsp->new_hotword) {
332 rt5677_dsp->new_hotword = false;
333
334 if (mic_write_offset < RT5677_MIC_BUF_FIRST_READ_SIZE)
335 rt5677_dsp->mic_read_offset = RT5677_MIC_BUF_BYTES -
336 (RT5677_MIC_BUF_FIRST_READ_SIZE -
337 mic_write_offset);
338 else
339 rt5677_dsp->mic_read_offset = mic_write_offset -
340 RT5677_MIC_BUF_FIRST_READ_SIZE;
341 }
342
343
344 if (rt5677_dsp->mic_read_offset <= mic_write_offset)
345 new_bytes = mic_write_offset - rt5677_dsp->mic_read_offset;
346 else
347 new_bytes = RT5677_MIC_BUF_BYTES + mic_write_offset
348 - rt5677_dsp->mic_read_offset;
349
350
351 period_bytes = snd_pcm_lib_period_bytes(rt5677_dsp->substream);
352 while (new_bytes) {
353 copy_bytes = min(new_bytes, period_bytes
354 - rt5677_dsp->avail_bytes);
355 ret = rt5677_spi_copy(rt5677_dsp, copy_bytes);
356 if (ret) {
357 dev_err(rt5677_dsp->dev, "Copy failed %d\n", ret);
358 goto done;
359 }
360 rt5677_dsp->avail_bytes += copy_bytes;
361 if (rt5677_dsp->avail_bytes >= period_bytes) {
362 snd_pcm_period_elapsed(rt5677_dsp->substream);
363 rt5677_dsp->avail_bytes = 0;
364 }
365 new_bytes -= copy_bytes;
366 }
367
368 delay = bytes_to_frames(runtime, period_bytes) / (runtime->rate / 1000);
369 schedule_delayed_work(&rt5677_dsp->copy_work, msecs_to_jiffies(delay));
370done:
371 mutex_unlock(&rt5677_dsp->dma_lock);
372}
373
374static int rt5677_spi_pcm_new(struct snd_soc_component *component,
375 struct snd_soc_pcm_runtime *rtd)
376{
377 snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_VMALLOC,
378 NULL, 0, 0);
379 return 0;
380}
381
382static int rt5677_spi_pcm_probe(struct snd_soc_component *component)
383{
384 struct rt5677_dsp *rt5677_dsp;
385
386 rt5677_dsp = devm_kzalloc(component->dev, sizeof(*rt5677_dsp),
387 GFP_KERNEL);
388 if (!rt5677_dsp)
389 return -ENOMEM;
390 rt5677_dsp->dev = &g_spi->dev;
391 mutex_init(&rt5677_dsp->dma_lock);
392 INIT_DELAYED_WORK(&rt5677_dsp->copy_work, rt5677_spi_copy_work);
393
394 snd_soc_component_set_drvdata(component, rt5677_dsp);
395 return 0;
396}
397
398static const struct snd_soc_component_driver rt5677_spi_dai_component = {
399 .name = DRV_NAME,
400 .probe = rt5677_spi_pcm_probe,
401 .open = rt5677_spi_pcm_open,
402 .close = rt5677_spi_pcm_close,
403 .hw_params = rt5677_spi_hw_params,
404 .hw_free = rt5677_spi_hw_free,
405 .prepare = rt5677_spi_prepare,
406 .pointer = rt5677_spi_pcm_pointer,
407 .pcm_construct = rt5677_spi_pcm_new,
408};
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438static u8 rt5677_spi_select_cmd(bool read, u32 align, u32 remain, u32 *len)
439{
440 u8 cmd;
441
442 if (align == 4 || remain <= 4) {
443 cmd = RT5677_SPI_READ_32;
444 *len = 4;
445 } else {
446 cmd = RT5677_SPI_READ_BURST;
447 *len = (((remain - 1) >> 3) + 1) << 3;
448 *len = min_t(u32, *len, RT5677_SPI_BURST_LEN);
449 }
450 return read ? cmd : cmd + 1;
451}
452
453
454
455
456static void rt5677_spi_reverse(u8 *dst, u32 dstlen, const u8 *src, u32 srclen)
457{
458 u32 w, i, si;
459 u32 word_size = min_t(u32, dstlen, 8);
460
461 for (w = 0; w < dstlen; w += word_size) {
462 for (i = 0; i < word_size && i + w < dstlen; i++) {
463 si = w + word_size - i - 1;
464 dst[w + i] = si < srclen ? src[si] : 0;
465 }
466 }
467}
468
469
470int rt5677_spi_read(u32 addr, void *rxbuf, size_t len)
471{
472 u32 offset;
473 int status = 0;
474 struct spi_transfer t[2];
475 struct spi_message m;
476
477 u8 header[RT5677_SPI_HEADER + 4];
478 u8 body[RT5677_SPI_BURST_LEN];
479 u8 spi_cmd;
480 u8 *cb = rxbuf;
481
482 if (!g_spi)
483 return -ENODEV;
484
485 if ((addr & 3) || (len & 3)) {
486 dev_err(&g_spi->dev, "Bad read align 0x%x(%zu)\n", addr, len);
487 return -EACCES;
488 }
489
490 memset(t, 0, sizeof(t));
491 t[0].tx_buf = header;
492 t[0].len = sizeof(header);
493 t[0].speed_hz = RT5677_SPI_FREQ;
494 t[1].rx_buf = body;
495 t[1].speed_hz = RT5677_SPI_FREQ;
496 spi_message_init_with_transfers(&m, t, ARRAY_SIZE(t));
497
498 for (offset = 0; offset < len; offset += t[1].len) {
499 spi_cmd = rt5677_spi_select_cmd(true, (addr + offset) & 7,
500 len - offset, &t[1].len);
501
502
503 header[0] = spi_cmd;
504 header[1] = ((addr + offset) & 0xff000000) >> 24;
505 header[2] = ((addr + offset) & 0x00ff0000) >> 16;
506 header[3] = ((addr + offset) & 0x0000ff00) >> 8;
507 header[4] = ((addr + offset) & 0x000000ff) >> 0;
508
509 mutex_lock(&spi_mutex);
510 status |= spi_sync(g_spi, &m);
511 mutex_unlock(&spi_mutex);
512
513
514
515 rt5677_spi_reverse(cb + offset, len - offset, body, t[1].len);
516 }
517 return status;
518}
519EXPORT_SYMBOL_GPL(rt5677_spi_read);
520
521
522
523
524
525int rt5677_spi_write(u32 addr, const void *txbuf, size_t len)
526{
527 u32 offset;
528 int status = 0;
529 struct spi_transfer t;
530 struct spi_message m;
531
532 u8 buf[RT5677_SPI_HEADER + RT5677_SPI_BURST_LEN + 1];
533 u8 *body = buf + RT5677_SPI_HEADER;
534 u8 spi_cmd;
535 const u8 *cb = txbuf;
536
537 if (!g_spi)
538 return -ENODEV;
539
540 if (addr & 3) {
541 dev_err(&g_spi->dev, "Bad write align 0x%x(%zu)\n", addr, len);
542 return -EACCES;
543 }
544
545 memset(&t, 0, sizeof(t));
546 t.tx_buf = buf;
547 t.speed_hz = RT5677_SPI_FREQ;
548 spi_message_init_with_transfers(&m, &t, 1);
549
550 for (offset = 0; offset < len;) {
551 spi_cmd = rt5677_spi_select_cmd(false, (addr + offset) & 7,
552 len - offset, &t.len);
553
554
555 buf[0] = spi_cmd;
556 buf[1] = ((addr + offset) & 0xff000000) >> 24;
557 buf[2] = ((addr + offset) & 0x00ff0000) >> 16;
558 buf[3] = ((addr + offset) & 0x0000ff00) >> 8;
559 buf[4] = ((addr + offset) & 0x000000ff) >> 0;
560
561
562 rt5677_spi_reverse(body, t.len, cb + offset, len - offset);
563 offset += t.len;
564 t.len += RT5677_SPI_HEADER + 1;
565
566 mutex_lock(&spi_mutex);
567 status |= spi_sync(g_spi, &m);
568 mutex_unlock(&spi_mutex);
569 }
570 return status;
571}
572EXPORT_SYMBOL_GPL(rt5677_spi_write);
573
574int rt5677_spi_write_firmware(u32 addr, const struct firmware *fw)
575{
576 return rt5677_spi_write(addr, fw->data, fw->size);
577}
578EXPORT_SYMBOL_GPL(rt5677_spi_write_firmware);
579
580void rt5677_spi_hotword_detected(void)
581{
582 struct rt5677_dsp *rt5677_dsp;
583
584 if (!g_spi)
585 return;
586
587 rt5677_dsp = dev_get_drvdata(&g_spi->dev);
588 if (!rt5677_dsp) {
589 dev_err(&g_spi->dev, "Can't get rt5677_dsp\n");
590 return;
591 }
592
593 mutex_lock(&rt5677_dsp->dma_lock);
594 dev_info(rt5677_dsp->dev, "Hotword detected\n");
595 rt5677_dsp->new_hotword = true;
596 mutex_unlock(&rt5677_dsp->dma_lock);
597
598 schedule_delayed_work(&rt5677_dsp->copy_work, 0);
599}
600EXPORT_SYMBOL_GPL(rt5677_spi_hotword_detected);
601
602static int rt5677_spi_probe(struct spi_device *spi)
603{
604 int ret;
605
606 g_spi = spi;
607
608 ret = devm_snd_soc_register_component(&spi->dev,
609 &rt5677_spi_dai_component,
610 &rt5677_spi_dai, 1);
611 if (ret < 0)
612 dev_err(&spi->dev, "Failed to register component.\n");
613
614 return ret;
615}
616
617#ifdef CONFIG_ACPI
618static const struct acpi_device_id rt5677_spi_acpi_id[] = {
619 { "RT5677AA", 0 },
620 { }
621};
622MODULE_DEVICE_TABLE(acpi, rt5677_spi_acpi_id);
623#endif
624
625static struct spi_driver rt5677_spi_driver = {
626 .driver = {
627 .name = DRV_NAME,
628 .acpi_match_table = ACPI_PTR(rt5677_spi_acpi_id),
629 },
630 .probe = rt5677_spi_probe,
631};
632module_spi_driver(rt5677_spi_driver);
633
634MODULE_DESCRIPTION("ASoC RT5677 SPI driver");
635MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
636MODULE_LICENSE("GPL v2");
637