xref: /openbmc/linux/sound/soc/codecs/rt5514-spi.c (revision 293d5b43)
1 /*
2  * rt5514-spi.c  --  RT5514 SPI driver
3  *
4  * Copyright 2015 Realtek Semiconductor Corp.
5  * Author: Oder Chiou <oder_chiou@realtek.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 
12 #include <linux/module.h>
13 #include <linux/input.h>
14 #include <linux/spi/spi.h>
15 #include <linux/device.h>
16 #include <linux/init.h>
17 #include <linux/delay.h>
18 #include <linux/interrupt.h>
19 #include <linux/irq.h>
20 #include <linux/slab.h>
21 #include <linux/gpio.h>
22 #include <linux/sched.h>
23 #include <linux/kthread.h>
24 #include <linux/uaccess.h>
25 #include <linux/miscdevice.h>
26 #include <linux/regulator/consumer.h>
27 #include <linux/pm_qos.h>
28 #include <linux/sysfs.h>
29 #include <linux/clk.h>
30 #include <sound/core.h>
31 #include <sound/pcm.h>
32 #include <sound/pcm_params.h>
33 #include <sound/soc.h>
34 #include <sound/soc-dapm.h>
35 #include <sound/initval.h>
36 #include <sound/tlv.h>
37 
38 #include "rt5514-spi.h"
39 
40 static struct spi_device *rt5514_spi;
41 
42 struct rt5514_dsp {
43 	struct device *dev;
44 	struct delayed_work copy_work;
45 	struct mutex dma_lock;
46 	struct snd_pcm_substream *substream;
47 	unsigned int buf_base, buf_limit, buf_rp;
48 	size_t buf_size;
49 	size_t dma_offset;
50 	size_t dsp_offset;
51 };
52 
53 static const struct snd_pcm_hardware rt5514_spi_pcm_hardware = {
54 	.info			= SNDRV_PCM_INFO_MMAP |
55 				  SNDRV_PCM_INFO_MMAP_VALID |
56 				  SNDRV_PCM_INFO_INTERLEAVED,
57 	.formats		= SNDRV_PCM_FMTBIT_S16_LE,
58 	.period_bytes_min	= PAGE_SIZE,
59 	.period_bytes_max	= 0x20000 / 8,
60 	.periods_min		= 8,
61 	.periods_max		= 8,
62 	.channels_min		= 1,
63 	.channels_max		= 1,
64 	.buffer_bytes_max	= 0x20000,
65 };
66 
67 static struct snd_soc_dai_driver rt5514_spi_dai = {
68 	.name = "rt5514-dsp-cpu-dai",
69 	.id = 0,
70 	.capture = {
71 		.stream_name = "DSP Capture",
72 		.channels_min = 1,
73 		.channels_max = 1,
74 		.rates = SNDRV_PCM_RATE_16000,
75 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
76 	},
77 };
78 
79 static void rt5514_spi_copy_work(struct work_struct *work)
80 {
81 	struct rt5514_dsp *rt5514_dsp =
82 		container_of(work, struct rt5514_dsp, copy_work.work);
83 	struct snd_pcm_runtime *runtime;
84 	size_t period_bytes, truncated_bytes = 0;
85 
86 	mutex_lock(&rt5514_dsp->dma_lock);
87 	if (!rt5514_dsp->substream) {
88 		dev_err(rt5514_dsp->dev, "No pcm substream\n");
89 		goto done;
90 	}
91 
92 	runtime = rt5514_dsp->substream->runtime;
93 	period_bytes = snd_pcm_lib_period_bytes(rt5514_dsp->substream);
94 
95 	if (rt5514_dsp->buf_size - rt5514_dsp->dsp_offset <  period_bytes)
96 		period_bytes = rt5514_dsp->buf_size - rt5514_dsp->dsp_offset;
97 
98 	if (rt5514_dsp->buf_rp + period_bytes <= rt5514_dsp->buf_limit) {
99 		rt5514_spi_burst_read(rt5514_dsp->buf_rp,
100 			runtime->dma_area + rt5514_dsp->dma_offset,
101 			period_bytes);
102 
103 		if (rt5514_dsp->buf_rp + period_bytes == rt5514_dsp->buf_limit)
104 			rt5514_dsp->buf_rp = rt5514_dsp->buf_base;
105 		else
106 			rt5514_dsp->buf_rp += period_bytes;
107 	} else {
108 		truncated_bytes = rt5514_dsp->buf_limit - rt5514_dsp->buf_rp;
109 		rt5514_spi_burst_read(rt5514_dsp->buf_rp,
110 			runtime->dma_area + rt5514_dsp->dma_offset,
111 			truncated_bytes);
112 
113 		rt5514_spi_burst_read(rt5514_dsp->buf_base,
114 			runtime->dma_area + rt5514_dsp->dma_offset +
115 			truncated_bytes, period_bytes - truncated_bytes);
116 
117 			rt5514_dsp->buf_rp = rt5514_dsp->buf_base +
118 				period_bytes - truncated_bytes;
119 	}
120 
121 	rt5514_dsp->dma_offset += period_bytes;
122 	if (rt5514_dsp->dma_offset >= runtime->dma_bytes)
123 		rt5514_dsp->dma_offset = 0;
124 
125 	rt5514_dsp->dsp_offset += period_bytes;
126 
127 	snd_pcm_period_elapsed(rt5514_dsp->substream);
128 
129 	if (rt5514_dsp->dsp_offset < rt5514_dsp->buf_size)
130 		schedule_delayed_work(&rt5514_dsp->copy_work, 5);
131 done:
132 	mutex_unlock(&rt5514_dsp->dma_lock);
133 }
134 
135 /* PCM for streaming audio from the DSP buffer */
136 static int rt5514_spi_pcm_open(struct snd_pcm_substream *substream)
137 {
138 	snd_soc_set_runtime_hwparams(substream, &rt5514_spi_pcm_hardware);
139 
140 	return 0;
141 }
142 
143 static int rt5514_spi_hw_params(struct snd_pcm_substream *substream,
144 			       struct snd_pcm_hw_params *hw_params)
145 {
146 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
147 	struct rt5514_dsp *rt5514_dsp =
148 			snd_soc_platform_get_drvdata(rtd->platform);
149 	int ret;
150 
151 	mutex_lock(&rt5514_dsp->dma_lock);
152 	ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
153 			params_buffer_bytes(hw_params));
154 	rt5514_dsp->substream = substream;
155 	mutex_unlock(&rt5514_dsp->dma_lock);
156 
157 	return ret;
158 }
159 
160 static int rt5514_spi_hw_free(struct snd_pcm_substream *substream)
161 {
162 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
163 	struct rt5514_dsp *rt5514_dsp =
164 			snd_soc_platform_get_drvdata(rtd->platform);
165 
166 	mutex_lock(&rt5514_dsp->dma_lock);
167 	rt5514_dsp->substream = NULL;
168 	mutex_unlock(&rt5514_dsp->dma_lock);
169 
170 	cancel_delayed_work_sync(&rt5514_dsp->copy_work);
171 
172 	return snd_pcm_lib_free_vmalloc_buffer(substream);
173 }
174 
175 static int rt5514_spi_prepare(struct snd_pcm_substream *substream)
176 {
177 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
178 	struct rt5514_dsp *rt5514_dsp =
179 			snd_soc_platform_get_drvdata(rtd->platform);
180 	u8 buf[8];
181 
182 	rt5514_dsp->dma_offset = 0;
183 	rt5514_dsp->dsp_offset = 0;
184 
185 	/**
186 	 * The address area x1800XXXX is the register address, and it cannot
187 	 * support spi burst read perfectly. So we use the spi burst read
188 	 * individually to make sure the data correctly.
189 	*/
190 	rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE, (u8 *)&buf,
191 		sizeof(buf));
192 	rt5514_dsp->buf_base = buf[0] | buf[1] << 8 | buf[2] << 16 |
193 				buf[3] << 24;
194 
195 	rt5514_spi_burst_read(RT5514_BUFFER_VOICE_LIMIT, (u8 *)&buf,
196 		sizeof(buf));
197 	rt5514_dsp->buf_limit = buf[0] | buf[1] << 8 | buf[2] << 16 |
198 				buf[3] << 24;
199 
200 	rt5514_spi_burst_read(RT5514_BUFFER_VOICE_RP, (u8 *)&buf,
201 		sizeof(buf));
202 	rt5514_dsp->buf_rp = buf[0] | buf[1] << 8 | buf[2] << 16 |
203 				buf[3] << 24;
204 
205 	rt5514_spi_burst_read(RT5514_BUFFER_VOICE_SIZE, (u8 *)&buf,
206 		sizeof(buf));
207 	rt5514_dsp->buf_size = buf[0] | buf[1] << 8 | buf[2] << 16 |
208 				buf[3] << 24;
209 
210 	return 0;
211 }
212 
213 static int rt5514_spi_trigger(struct snd_pcm_substream *substream, int cmd)
214 {
215 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
216 	struct rt5514_dsp *rt5514_dsp =
217 			snd_soc_platform_get_drvdata(rtd->platform);
218 
219 	if (cmd == SNDRV_PCM_TRIGGER_START) {
220 		if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit &&
221 			rt5514_dsp->buf_rp && rt5514_dsp->buf_size)
222 			schedule_delayed_work(&rt5514_dsp->copy_work, 0);
223 	}
224 
225 	return 0;
226 }
227 
228 static snd_pcm_uframes_t rt5514_spi_pcm_pointer(
229 		struct snd_pcm_substream *substream)
230 {
231 	struct snd_pcm_runtime *runtime = substream->runtime;
232 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
233 	struct rt5514_dsp *rt5514_dsp =
234 		snd_soc_platform_get_drvdata(rtd->platform);
235 
236 	return bytes_to_frames(runtime, rt5514_dsp->dma_offset);
237 }
238 
239 static struct snd_pcm_ops rt5514_spi_pcm_ops = {
240 	.open		= rt5514_spi_pcm_open,
241 	.hw_params	= rt5514_spi_hw_params,
242 	.hw_free	= rt5514_spi_hw_free,
243 	.trigger	= rt5514_spi_trigger,
244 	.prepare	= rt5514_spi_prepare,
245 	.pointer	= rt5514_spi_pcm_pointer,
246 	.mmap		= snd_pcm_lib_mmap_vmalloc,
247 	.page		= snd_pcm_lib_get_vmalloc_page,
248 };
249 
250 static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform)
251 {
252 	struct rt5514_dsp *rt5514_dsp;
253 
254 	rt5514_dsp = devm_kzalloc(platform->dev, sizeof(*rt5514_dsp),
255 			GFP_KERNEL);
256 
257 	rt5514_dsp->dev = &rt5514_spi->dev;
258 	mutex_init(&rt5514_dsp->dma_lock);
259 	INIT_DELAYED_WORK(&rt5514_dsp->copy_work, rt5514_spi_copy_work);
260 	snd_soc_platform_set_drvdata(platform, rt5514_dsp);
261 
262 	return 0;
263 }
264 
265 static struct snd_soc_platform_driver rt5514_spi_platform = {
266 	.probe = rt5514_spi_pcm_probe,
267 	.ops = &rt5514_spi_pcm_ops,
268 };
269 
270 static const struct snd_soc_component_driver rt5514_spi_dai_component = {
271 	.name		= "rt5514-spi-dai",
272 };
273 
274 /**
275  * rt5514_spi_burst_read - Read data from SPI by rt5514 address.
276  * @addr: Start address.
277  * @rxbuf: Data Buffer for reading.
278  * @len: Data length, it must be a multiple of 8.
279  *
280  *
281  * Returns true for success.
282  */
283 int rt5514_spi_burst_read(unsigned int addr, u8 *rxbuf, size_t len)
284 {
285 	u8 spi_cmd = RT5514_SPI_CMD_BURST_READ;
286 	int status;
287 	u8 write_buf[8];
288 	unsigned int i, end, offset = 0;
289 
290 	struct spi_message message;
291 	struct spi_transfer x[3];
292 
293 	while (offset < len) {
294 		if (offset + RT5514_SPI_BUF_LEN <= len)
295 			end = RT5514_SPI_BUF_LEN;
296 		else
297 			end = len % RT5514_SPI_BUF_LEN;
298 
299 		write_buf[0] = spi_cmd;
300 		write_buf[1] = ((addr + offset) & 0xff000000) >> 24;
301 		write_buf[2] = ((addr + offset) & 0x00ff0000) >> 16;
302 		write_buf[3] = ((addr + offset) & 0x0000ff00) >> 8;
303 		write_buf[4] = ((addr + offset) & 0x000000ff) >> 0;
304 
305 		spi_message_init(&message);
306 		memset(x, 0, sizeof(x));
307 
308 		x[0].len = 5;
309 		x[0].tx_buf = write_buf;
310 		spi_message_add_tail(&x[0], &message);
311 
312 		x[1].len = 4;
313 		x[1].tx_buf = write_buf;
314 		spi_message_add_tail(&x[1], &message);
315 
316 		x[2].len = end;
317 		x[2].rx_buf = rxbuf + offset;
318 		spi_message_add_tail(&x[2], &message);
319 
320 		status = spi_sync(rt5514_spi, &message);
321 
322 		if (status)
323 			return false;
324 
325 		offset += RT5514_SPI_BUF_LEN;
326 	}
327 
328 	for (i = 0; i < len; i += 8) {
329 		write_buf[0] = rxbuf[i + 0];
330 		write_buf[1] = rxbuf[i + 1];
331 		write_buf[2] = rxbuf[i + 2];
332 		write_buf[3] = rxbuf[i + 3];
333 		write_buf[4] = rxbuf[i + 4];
334 		write_buf[5] = rxbuf[i + 5];
335 		write_buf[6] = rxbuf[i + 6];
336 		write_buf[7] = rxbuf[i + 7];
337 
338 		rxbuf[i + 0] = write_buf[7];
339 		rxbuf[i + 1] = write_buf[6];
340 		rxbuf[i + 2] = write_buf[5];
341 		rxbuf[i + 3] = write_buf[4];
342 		rxbuf[i + 4] = write_buf[3];
343 		rxbuf[i + 5] = write_buf[2];
344 		rxbuf[i + 6] = write_buf[1];
345 		rxbuf[i + 7] = write_buf[0];
346 	}
347 
348 	return true;
349 }
350 
351 /**
352  * rt5514_spi_burst_write - Write data to SPI by rt5514 address.
353  * @addr: Start address.
354  * @txbuf: Data Buffer for writng.
355  * @len: Data length, it must be a multiple of 8.
356  *
357  *
358  * Returns true for success.
359  */
360 int rt5514_spi_burst_write(u32 addr, const u8 *txbuf, size_t len)
361 {
362 	u8 spi_cmd = RT5514_SPI_CMD_BURST_WRITE;
363 	u8 *write_buf;
364 	unsigned int i, end, offset = 0;
365 
366 	write_buf = kmalloc(RT5514_SPI_BUF_LEN + 6, GFP_KERNEL);
367 
368 	if (write_buf == NULL)
369 		return -ENOMEM;
370 
371 	while (offset < len) {
372 		if (offset + RT5514_SPI_BUF_LEN <= len)
373 			end = RT5514_SPI_BUF_LEN;
374 		else
375 			end = len % RT5514_SPI_BUF_LEN;
376 
377 		write_buf[0] = spi_cmd;
378 		write_buf[1] = ((addr + offset) & 0xff000000) >> 24;
379 		write_buf[2] = ((addr + offset) & 0x00ff0000) >> 16;
380 		write_buf[3] = ((addr + offset) & 0x0000ff00) >> 8;
381 		write_buf[4] = ((addr + offset) & 0x000000ff) >> 0;
382 
383 		for (i = 0; i < end; i += 8) {
384 			write_buf[i + 12] = txbuf[offset + i + 0];
385 			write_buf[i + 11] = txbuf[offset + i + 1];
386 			write_buf[i + 10] = txbuf[offset + i + 2];
387 			write_buf[i +  9] = txbuf[offset + i + 3];
388 			write_buf[i +  8] = txbuf[offset + i + 4];
389 			write_buf[i +  7] = txbuf[offset + i + 5];
390 			write_buf[i +  6] = txbuf[offset + i + 6];
391 			write_buf[i +  5] = txbuf[offset + i + 7];
392 		}
393 
394 		write_buf[end + 5] = spi_cmd;
395 
396 		spi_write(rt5514_spi, write_buf, end + 6);
397 
398 		offset += RT5514_SPI_BUF_LEN;
399 	}
400 
401 	kfree(write_buf);
402 
403 	return 0;
404 }
405 EXPORT_SYMBOL_GPL(rt5514_spi_burst_write);
406 
407 static int rt5514_spi_probe(struct spi_device *spi)
408 {
409 	int ret;
410 
411 	rt5514_spi = spi;
412 
413 	ret = devm_snd_soc_register_platform(&spi->dev, &rt5514_spi_platform);
414 	if (ret < 0) {
415 		dev_err(&spi->dev, "Failed to register platform.\n");
416 		return ret;
417 	}
418 
419 	ret = devm_snd_soc_register_component(&spi->dev,
420 					      &rt5514_spi_dai_component,
421 					      &rt5514_spi_dai, 1);
422 	if (ret < 0) {
423 		dev_err(&spi->dev, "Failed to register component.\n");
424 		return ret;
425 	}
426 
427 	return 0;
428 }
429 
430 static const struct of_device_id rt5514_of_match[] = {
431 	{ .compatible = "realtek,rt5514", },
432 	{},
433 };
434 MODULE_DEVICE_TABLE(of, rt5514_of_match);
435 
436 static struct spi_driver rt5514_spi_driver = {
437 	.driver = {
438 		.name = "rt5514",
439 		.of_match_table = of_match_ptr(rt5514_of_match),
440 	},
441 	.probe = rt5514_spi_probe,
442 };
443 module_spi_driver(rt5514_spi_driver);
444 
445 MODULE_DESCRIPTION("RT5514 SPI driver");
446 MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
447 MODULE_LICENSE("GPL v2");
448