1 // SPDX-License-Identifier: GPL-2.0-only
3 * rt5514-spi.c -- RT5514 SPI driver
5 * Copyright 2015 Realtek Semiconductor Corp.
6 * Author: Oder Chiou <oder_chiou@realtek.com>
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/gpio.h>
19 #include <linux/sched.h>
20 #include <linux/uaccess.h>
21 #include <linux/regulator/consumer.h>
22 #include <linux/pm_qos.h>
23 #include <linux/sysfs.h>
24 #include <linux/clk.h>
25 #include <sound/core.h>
26 #include <sound/pcm.h>
27 #include <sound/pcm_params.h>
28 #include <sound/soc.h>
29 #include <sound/soc-dapm.h>
30 #include <sound/initval.h>
31 #include <sound/tlv.h>
33 #include "rt5514-spi.h"
35 #define DRV_NAME "rt5514-spi"
37 static struct spi_device
*rt5514_spi
;
41 struct delayed_work copy_work
;
42 struct mutex dma_lock
;
43 struct snd_pcm_substream
*substream
;
44 unsigned int buf_base
, buf_limit
, buf_rp
;
45 size_t buf_size
, get_size
, dma_offset
;
48 static const struct snd_pcm_hardware rt5514_spi_pcm_hardware
= {
49 .info
= SNDRV_PCM_INFO_MMAP
|
50 SNDRV_PCM_INFO_MMAP_VALID
|
51 SNDRV_PCM_INFO_INTERLEAVED
,
52 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
53 .period_bytes_min
= PAGE_SIZE
,
54 .period_bytes_max
= 0x20000 / 8,
59 .buffer_bytes_max
= 0x20000,
62 static struct snd_soc_dai_driver rt5514_spi_dai
= {
63 .name
= "rt5514-dsp-cpu-dai",
66 .stream_name
= "DSP Capture",
69 .rates
= SNDRV_PCM_RATE_16000
,
70 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
74 static void rt5514_spi_copy_work(struct work_struct
*work
)
76 struct rt5514_dsp
*rt5514_dsp
=
77 container_of(work
, struct rt5514_dsp
, copy_work
.work
);
78 struct snd_pcm_runtime
*runtime
;
79 size_t period_bytes
, truncated_bytes
= 0;
80 unsigned int cur_wp
, remain_data
;
83 mutex_lock(&rt5514_dsp
->dma_lock
);
84 if (!rt5514_dsp
->substream
) {
85 dev_err(rt5514_dsp
->dev
, "No pcm substream\n");
89 runtime
= rt5514_dsp
->substream
->runtime
;
90 period_bytes
= snd_pcm_lib_period_bytes(rt5514_dsp
->substream
);
92 schedule_delayed_work(&rt5514_dsp
->copy_work
, 5);
96 if (rt5514_dsp
->buf_size
% period_bytes
)
97 rt5514_dsp
->buf_size
= (rt5514_dsp
->buf_size
/ period_bytes
) *
100 if (rt5514_dsp
->get_size
>= rt5514_dsp
->buf_size
) {
101 rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP
, (u8
*)&buf
,
103 cur_wp
= buf
[0] | buf
[1] << 8 | buf
[2] << 16 |
106 if (cur_wp
>= rt5514_dsp
->buf_rp
)
107 remain_data
= (cur_wp
- rt5514_dsp
->buf_rp
);
110 (rt5514_dsp
->buf_limit
- rt5514_dsp
->buf_rp
) +
111 (cur_wp
- rt5514_dsp
->buf_base
);
113 if (remain_data
< period_bytes
) {
114 schedule_delayed_work(&rt5514_dsp
->copy_work
, 5);
119 if (rt5514_dsp
->buf_rp
+ period_bytes
<= rt5514_dsp
->buf_limit
) {
120 rt5514_spi_burst_read(rt5514_dsp
->buf_rp
,
121 runtime
->dma_area
+ rt5514_dsp
->dma_offset
,
124 if (rt5514_dsp
->buf_rp
+ period_bytes
== rt5514_dsp
->buf_limit
)
125 rt5514_dsp
->buf_rp
= rt5514_dsp
->buf_base
;
127 rt5514_dsp
->buf_rp
+= period_bytes
;
129 truncated_bytes
= rt5514_dsp
->buf_limit
- rt5514_dsp
->buf_rp
;
130 rt5514_spi_burst_read(rt5514_dsp
->buf_rp
,
131 runtime
->dma_area
+ rt5514_dsp
->dma_offset
,
134 rt5514_spi_burst_read(rt5514_dsp
->buf_base
,
135 runtime
->dma_area
+ rt5514_dsp
->dma_offset
+
136 truncated_bytes
, period_bytes
- truncated_bytes
);
138 rt5514_dsp
->buf_rp
= rt5514_dsp
->buf_base
+ period_bytes
-
142 rt5514_dsp
->get_size
+= period_bytes
;
143 rt5514_dsp
->dma_offset
+= period_bytes
;
144 if (rt5514_dsp
->dma_offset
>= runtime
->dma_bytes
)
145 rt5514_dsp
->dma_offset
= 0;
147 snd_pcm_period_elapsed(rt5514_dsp
->substream
);
149 schedule_delayed_work(&rt5514_dsp
->copy_work
, 5);
152 mutex_unlock(&rt5514_dsp
->dma_lock
);
155 static void rt5514_schedule_copy(struct rt5514_dsp
*rt5514_dsp
)
159 if (!rt5514_dsp
->substream
)
162 rt5514_dsp
->get_size
= 0;
165 * The address area x1800XXXX is the register address, and it cannot
166 * support spi burst read perfectly. So we use the spi burst read
167 * individually to make sure the data correctly.
169 rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE
, (u8
*)&buf
,
171 rt5514_dsp
->buf_base
= buf
[0] | buf
[1] << 8 | buf
[2] << 16 |
174 rt5514_spi_burst_read(RT5514_BUFFER_VOICE_LIMIT
, (u8
*)&buf
,
176 rt5514_dsp
->buf_limit
= buf
[0] | buf
[1] << 8 | buf
[2] << 16 |
179 rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP
, (u8
*)&buf
,
181 rt5514_dsp
->buf_rp
= buf
[0] | buf
[1] << 8 | buf
[2] << 16 |
184 if (rt5514_dsp
->buf_rp
% 8)
185 rt5514_dsp
->buf_rp
= (rt5514_dsp
->buf_rp
/ 8) * 8;
187 rt5514_dsp
->buf_size
= rt5514_dsp
->buf_limit
- rt5514_dsp
->buf_base
;
189 if (rt5514_dsp
->buf_base
&& rt5514_dsp
->buf_limit
&&
190 rt5514_dsp
->buf_rp
&& rt5514_dsp
->buf_size
)
191 schedule_delayed_work(&rt5514_dsp
->copy_work
, 0);
194 static irqreturn_t
rt5514_spi_irq(int irq
, void *data
)
196 struct rt5514_dsp
*rt5514_dsp
= data
;
198 rt5514_schedule_copy(rt5514_dsp
);
203 /* PCM for streaming audio from the DSP buffer */
204 static int rt5514_spi_pcm_open(struct snd_soc_component
*component
,
205 struct snd_pcm_substream
*substream
)
207 snd_soc_set_runtime_hwparams(substream
, &rt5514_spi_pcm_hardware
);
212 static int rt5514_spi_hw_params(struct snd_soc_component
*component
,
213 struct snd_pcm_substream
*substream
,
214 struct snd_pcm_hw_params
*hw_params
)
216 struct rt5514_dsp
*rt5514_dsp
=
217 snd_soc_component_get_drvdata(component
);
220 mutex_lock(&rt5514_dsp
->dma_lock
);
221 rt5514_dsp
->substream
= substream
;
222 rt5514_dsp
->dma_offset
= 0;
224 /* Read IRQ status and schedule copy accordingly. */
225 rt5514_spi_burst_read(RT5514_IRQ_CTRL
, (u8
*)&buf
, sizeof(buf
));
226 if (buf
[0] & RT5514_IRQ_STATUS_BIT
)
227 rt5514_schedule_copy(rt5514_dsp
);
229 mutex_unlock(&rt5514_dsp
->dma_lock
);
234 static int rt5514_spi_hw_free(struct snd_soc_component
*component
,
235 struct snd_pcm_substream
*substream
)
237 struct rt5514_dsp
*rt5514_dsp
=
238 snd_soc_component_get_drvdata(component
);
240 mutex_lock(&rt5514_dsp
->dma_lock
);
241 rt5514_dsp
->substream
= NULL
;
242 mutex_unlock(&rt5514_dsp
->dma_lock
);
244 cancel_delayed_work_sync(&rt5514_dsp
->copy_work
);
249 static snd_pcm_uframes_t
rt5514_spi_pcm_pointer(
250 struct snd_soc_component
*component
,
251 struct snd_pcm_substream
*substream
)
253 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
254 struct rt5514_dsp
*rt5514_dsp
=
255 snd_soc_component_get_drvdata(component
);
257 return bytes_to_frames(runtime
, rt5514_dsp
->dma_offset
);
261 static int rt5514_spi_pcm_probe(struct snd_soc_component
*component
)
263 struct rt5514_dsp
*rt5514_dsp
;
266 rt5514_dsp
= devm_kzalloc(component
->dev
, sizeof(*rt5514_dsp
),
271 rt5514_dsp
->dev
= &rt5514_spi
->dev
;
272 mutex_init(&rt5514_dsp
->dma_lock
);
273 INIT_DELAYED_WORK(&rt5514_dsp
->copy_work
, rt5514_spi_copy_work
);
274 snd_soc_component_set_drvdata(component
, rt5514_dsp
);
276 if (rt5514_spi
->irq
) {
277 ret
= devm_request_threaded_irq(&rt5514_spi
->dev
,
278 rt5514_spi
->irq
, NULL
, rt5514_spi_irq
,
279 IRQF_TRIGGER_RISING
| IRQF_ONESHOT
, "rt5514-spi",
282 dev_err(&rt5514_spi
->dev
,
283 "%s Failed to reguest IRQ: %d\n", __func__
,
286 device_init_wakeup(rt5514_dsp
->dev
, true);
292 static int rt5514_spi_pcm_new(struct snd_soc_component
*component
,
293 struct snd_soc_pcm_runtime
*rtd
)
295 snd_pcm_set_managed_buffer_all(rtd
->pcm
, SNDRV_DMA_TYPE_VMALLOC
,
300 static const struct snd_soc_component_driver rt5514_spi_component
= {
302 .probe
= rt5514_spi_pcm_probe
,
303 .open
= rt5514_spi_pcm_open
,
304 .hw_params
= rt5514_spi_hw_params
,
305 .hw_free
= rt5514_spi_hw_free
,
306 .pointer
= rt5514_spi_pcm_pointer
,
307 .pcm_construct
= rt5514_spi_pcm_new
,
311 * rt5514_spi_burst_read - Read data from SPI by rt5514 address.
312 * @addr: Start address.
313 * @rxbuf: Data Buffer for reading.
314 * @len: Data length, it must be a multiple of 8.
317 * Returns true for success.
319 int rt5514_spi_burst_read(unsigned int addr
, u8
*rxbuf
, size_t len
)
321 u8 spi_cmd
= RT5514_SPI_CMD_BURST_READ
;
324 unsigned int i
, end
, offset
= 0;
326 struct spi_message message
;
327 struct spi_transfer x
[3];
329 while (offset
< len
) {
330 if (offset
+ RT5514_SPI_BUF_LEN
<= len
)
331 end
= RT5514_SPI_BUF_LEN
;
333 end
= len
% RT5514_SPI_BUF_LEN
;
335 write_buf
[0] = spi_cmd
;
336 write_buf
[1] = ((addr
+ offset
) & 0xff000000) >> 24;
337 write_buf
[2] = ((addr
+ offset
) & 0x00ff0000) >> 16;
338 write_buf
[3] = ((addr
+ offset
) & 0x0000ff00) >> 8;
339 write_buf
[4] = ((addr
+ offset
) & 0x000000ff) >> 0;
341 spi_message_init(&message
);
342 memset(x
, 0, sizeof(x
));
345 x
[0].tx_buf
= write_buf
;
346 spi_message_add_tail(&x
[0], &message
);
349 x
[1].tx_buf
= write_buf
;
350 spi_message_add_tail(&x
[1], &message
);
353 x
[2].rx_buf
= rxbuf
+ offset
;
354 spi_message_add_tail(&x
[2], &message
);
356 status
= spi_sync(rt5514_spi
, &message
);
361 offset
+= RT5514_SPI_BUF_LEN
;
364 for (i
= 0; i
< len
; i
+= 8) {
365 write_buf
[0] = rxbuf
[i
+ 0];
366 write_buf
[1] = rxbuf
[i
+ 1];
367 write_buf
[2] = rxbuf
[i
+ 2];
368 write_buf
[3] = rxbuf
[i
+ 3];
369 write_buf
[4] = rxbuf
[i
+ 4];
370 write_buf
[5] = rxbuf
[i
+ 5];
371 write_buf
[6] = rxbuf
[i
+ 6];
372 write_buf
[7] = rxbuf
[i
+ 7];
374 rxbuf
[i
+ 0] = write_buf
[7];
375 rxbuf
[i
+ 1] = write_buf
[6];
376 rxbuf
[i
+ 2] = write_buf
[5];
377 rxbuf
[i
+ 3] = write_buf
[4];
378 rxbuf
[i
+ 4] = write_buf
[3];
379 rxbuf
[i
+ 5] = write_buf
[2];
380 rxbuf
[i
+ 6] = write_buf
[1];
381 rxbuf
[i
+ 7] = write_buf
[0];
386 EXPORT_SYMBOL_GPL(rt5514_spi_burst_read
);
389 * rt5514_spi_burst_write - Write data to SPI by rt5514 address.
390 * @addr: Start address.
391 * @txbuf: Data Buffer for writng.
392 * @len: Data length, it must be a multiple of 8.
395 * Returns true for success.
397 int rt5514_spi_burst_write(u32 addr
, const u8
*txbuf
, size_t len
)
399 u8 spi_cmd
= RT5514_SPI_CMD_BURST_WRITE
;
401 unsigned int i
, end
, offset
= 0;
403 write_buf
= kmalloc(RT5514_SPI_BUF_LEN
+ 6, GFP_KERNEL
);
405 if (write_buf
== NULL
)
408 while (offset
< len
) {
409 if (offset
+ RT5514_SPI_BUF_LEN
<= len
)
410 end
= RT5514_SPI_BUF_LEN
;
412 end
= len
% RT5514_SPI_BUF_LEN
;
414 write_buf
[0] = spi_cmd
;
415 write_buf
[1] = ((addr
+ offset
) & 0xff000000) >> 24;
416 write_buf
[2] = ((addr
+ offset
) & 0x00ff0000) >> 16;
417 write_buf
[3] = ((addr
+ offset
) & 0x0000ff00) >> 8;
418 write_buf
[4] = ((addr
+ offset
) & 0x000000ff) >> 0;
420 for (i
= 0; i
< end
; i
+= 8) {
421 write_buf
[i
+ 12] = txbuf
[offset
+ i
+ 0];
422 write_buf
[i
+ 11] = txbuf
[offset
+ i
+ 1];
423 write_buf
[i
+ 10] = txbuf
[offset
+ i
+ 2];
424 write_buf
[i
+ 9] = txbuf
[offset
+ i
+ 3];
425 write_buf
[i
+ 8] = txbuf
[offset
+ i
+ 4];
426 write_buf
[i
+ 7] = txbuf
[offset
+ i
+ 5];
427 write_buf
[i
+ 6] = txbuf
[offset
+ i
+ 6];
428 write_buf
[i
+ 5] = txbuf
[offset
+ i
+ 7];
431 write_buf
[end
+ 5] = spi_cmd
;
433 spi_write(rt5514_spi
, write_buf
, end
+ 6);
435 offset
+= RT5514_SPI_BUF_LEN
;
442 EXPORT_SYMBOL_GPL(rt5514_spi_burst_write
);
444 static int rt5514_spi_probe(struct spi_device
*spi
)
450 ret
= devm_snd_soc_register_component(&spi
->dev
,
451 &rt5514_spi_component
,
454 dev_err(&spi
->dev
, "Failed to register component.\n");
461 static int __maybe_unused
rt5514_suspend(struct device
*dev
)
463 int irq
= to_spi_device(dev
)->irq
;
465 if (device_may_wakeup(dev
))
466 enable_irq_wake(irq
);
471 static int __maybe_unused
rt5514_resume(struct device
*dev
)
473 struct rt5514_dsp
*rt5514_dsp
= dev_get_drvdata(dev
);
474 int irq
= to_spi_device(dev
)->irq
;
477 if (device_may_wakeup(dev
))
478 disable_irq_wake(irq
);
481 if (rt5514_dsp
->substream
) {
482 rt5514_spi_burst_read(RT5514_IRQ_CTRL
, (u8
*)&buf
,
484 if (buf
[0] & RT5514_IRQ_STATUS_BIT
)
485 rt5514_schedule_copy(rt5514_dsp
);
492 static const struct dev_pm_ops rt5514_pm_ops
= {
493 SET_SYSTEM_SLEEP_PM_OPS(rt5514_suspend
, rt5514_resume
)
496 static const struct of_device_id rt5514_of_match
[] = {
497 { .compatible
= "realtek,rt5514", },
500 MODULE_DEVICE_TABLE(of
, rt5514_of_match
);
502 static struct spi_driver rt5514_spi_driver
= {
505 .pm
= &rt5514_pm_ops
,
506 .of_match_table
= of_match_ptr(rt5514_of_match
),
508 .probe
= rt5514_spi_probe
,
510 module_spi_driver(rt5514_spi_driver
);
512 MODULE_DESCRIPTION("RT5514 SPI driver");
513 MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
514 MODULE_LICENSE("GPL v2");