638 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * rt5677-spi.c -- RT5677 ALSA SoC audio codec driver4 *5 * Copyright 2013 Realtek Semiconductor Corp.6 * Author: Oder Chiou <oder_chiou@realtek.com>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 24035#define RT5677_SPI_HEADER 536#define RT5677_SPI_FREQ 600000037 38/* The AddressPhase and DataPhase of SPI commands are MSB first on the wire.39 * DataPhase word size of 16-bit commands is 2 bytes.40 * DataPhase word size of 32-bit commands is 4 bytes.41 * DataPhase word size of burst commands is 8 bytes.42 * The DSP CPU is little-endian.43 */44#define RT5677_SPI_WRITE_BURST 0x545#define RT5677_SPI_READ_BURST 0x446#define RT5677_SPI_WRITE_32 0x347#define RT5677_SPI_READ_32 0x248#define RT5677_SPI_WRITE_16 0x149#define RT5677_SPI_READ_16 0x050 51#define RT5677_BUF_BYTES_TOTAL 0x2000052#define RT5677_MIC_BUF_ADDR 0x6003000053#define RT5677_MODEL_ADDR 0x5FFC980054#define RT5677_MIC_BUF_BYTES ((u32)(RT5677_BUF_BYTES_TOTAL - \55 sizeof(u32)))56#define RT5677_MIC_BUF_FIRST_READ_SIZE 0x1000057 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; /* zero-based offset into runtime->dma_area */67 size_t avail_bytes; /* number of new bytes since last period */68 u32 mic_read_offset; /* zero-based offset into DSP's mic buffer */69 bool new_hotword; /* a new hotword is fired */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 /* The DAI name "rt5677-dsp-cpu-dai" is not used. The actual DAI name88 * registered with ASoC is the name of the device "spi-RT5677AA:00",89 * because we only have one DAI. See snd_soc_register_dais().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/* PCM for streaming audio from the DSP buffer */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 = snd_soc_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 = snd_soc_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 /* Grab the first 4 bytes that hold the write pointer on the190 * dsp, and check to make sure that it points somewhere inside the191 * buffer.192 */193 ret = rt5677_spi_read(RT5677_MIC_BUF_ADDR, mic_write_offset,194 sizeof(u32));195 if (ret)196 return ret;197 /* Adjust the offset so that it's zero-based */198 *mic_write_offset = *mic_write_offset - sizeof(u32);199 return *mic_write_offset < RT5677_MIC_BUF_BYTES ? 0 : -EFAULT;200}201 202/*203 * Copy one contiguous block of audio samples from the DSP mic buffer to the204 * dma_area of the pcm runtime. The receiving buffer may wrap around.205 * @begin: start offset of the block to copy, in bytes.206 * @end: offset of the first byte after the block to copy, must be greater207 * than or equal to begin.208 *209 * Return: Zero if successful, or a negative error code on failure.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 /* The block to copy is empty */227 if (begin == end)228 return 0;229 230 /* If the incoming chunk is too big for the receiving buffer, only the231 * last "receiving buffer size - one frame" bytes are copied.232 */233 if (end - begin > runtime->dma_bytes - bytes_per_frame)234 begin = end - (runtime->dma_bytes - bytes_per_frame);235 236 /* May need to split to two chunks, calculate the size of each */237 first_chunk_len = end - begin;238 second_chunk_len = 0;239 if (rt5677_dsp->dma_offset + first_chunk_len > runtime->dma_bytes) {240 /* Receiving buffer wrapped around */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 /* Copy first chunk */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 /* Copy second chunk */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 * Copy a given amount of audio samples from the DSP mic buffer starting at269 * mic_read_offset, to the dma_area of the pcm runtime. The source buffer may270 * wrap around. mic_read_offset is updated after successful copy.271 * @amount: amount of samples to copy, in bytes.272 *273 * Return: Zero if successful, or a negative error code on failure.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 /* Copy the first chunk in DSP's mic buffer */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 /* Wrap around, copy the second chunk */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 * A delayed work that streams audio samples from the DSP mic buffer to the301 * dma_area of the pcm runtime via SPI.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 /* Ensure runtime->dma_area buffer does not go away while copying. */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 /* If this is the first time that we've asked for streaming data after328 * a hotword is fired, we should start reading from the previous 2329 * seconds of audio from wherever the mic_write_offset is currently.330 */331 if (rt5677_dsp->new_hotword) {332 rt5677_dsp->new_hotword = false;333 /* See if buffer wraparound happens */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 else339 rt5677_dsp->mic_read_offset = mic_write_offset -340 RT5677_MIC_BUF_FIRST_READ_SIZE;341 }342 343 /* Calculate the amount of new samples in bytes */344 if (rt5677_dsp->mic_read_offset <= mic_write_offset)345 new_bytes = mic_write_offset - rt5677_dsp->mic_read_offset;346 else347 new_bytes = RT5677_MIC_BUF_BYTES + mic_write_offset348 - rt5677_dsp->mic_read_offset;349 350 /* Copy all new samples from DSP mic buffer, one period at a time */351 period_bytes = snd_pcm_lib_period_bytes(rt5677_dsp->substream);352 while (new_bytes) {353 copy_bytes = min(new_bytes, period_bytes354 - 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 .legacy_dai_naming = 1,409};410 411/* Select a suitable transfer command for the next transfer to ensure412 * the transfer address is always naturally aligned while minimizing413 * the total number of transfers required.414 *415 * 3 transfer commands are available:416 * RT5677_SPI_READ/WRITE_16: Transfer 2 bytes417 * RT5677_SPI_READ/WRITE_32: Transfer 4 bytes418 * RT5677_SPI_READ/WRITE_BURST: Transfer any multiples of 8 bytes419 *420 * Note:421 * 16 Bit writes and reads are restricted to the address range422 * 0x18020000 ~ 0x18021000423 *424 * For example, reading 256 bytes at 0x60030004 uses the following commands:425 * 0x60030004 RT5677_SPI_READ_32 4 bytes426 * 0x60030008 RT5677_SPI_READ_BURST 240 bytes427 * 0x600300F8 RT5677_SPI_READ_BURST 8 bytes428 * 0x60030100 RT5677_SPI_READ_32 4 bytes429 *430 * Input:431 * @read: true for read commands; false for write commands432 * @align: alignment of the next transfer address433 * @remain: number of bytes remaining to transfer434 *435 * Output:436 * @len: number of bytes to transfer with the selected command437 * Returns the selected command438 */439static u8 rt5677_spi_select_cmd(bool read, u32 align, u32 remain, u32 *len)440{441 u8 cmd;442 443 if (align == 4 || remain <= 4) {444 cmd = RT5677_SPI_READ_32;445 *len = 4;446 } else {447 cmd = RT5677_SPI_READ_BURST;448 *len = (((remain - 1) >> 3) + 1) << 3;449 *len = min_t(u32, *len, RT5677_SPI_BURST_LEN);450 }451 return read ? cmd : cmd + 1;452}453 454/* Copy dstlen bytes from src to dst, while reversing byte order for each word.455 * If srclen < dstlen, zeros are padded.456 */457static void rt5677_spi_reverse(u8 *dst, u32 dstlen, const u8 *src, u32 srclen)458{459 u32 w, i, si;460 u32 word_size = min_t(u32, dstlen, 8);461 462 for (w = 0; w < dstlen; w += word_size) {463 for (i = 0; i < word_size && i + w < dstlen; i++) {464 si = w + word_size - i - 1;465 dst[w + i] = si < srclen ? src[si] : 0;466 }467 }468}469 470/* Read DSP address space using SPI. addr and len have to be 4-byte aligned. */471int rt5677_spi_read(u32 addr, void *rxbuf, size_t len)472{473 u32 offset;474 int status = 0;475 struct spi_transfer t[2];476 struct spi_message m;477 /* +4 bytes is for the DummyPhase following the AddressPhase */478 u8 header[RT5677_SPI_HEADER + 4];479 u8 body[RT5677_SPI_BURST_LEN];480 u8 spi_cmd;481 u8 *cb = rxbuf;482 483 if (!g_spi)484 return -ENODEV;485 486 if ((addr & 3) || (len & 3)) {487 dev_err(&g_spi->dev, "Bad read align 0x%x(%zu)\n", addr, len);488 return -EACCES;489 }490 491 memset(t, 0, sizeof(t));492 t[0].tx_buf = header;493 t[0].len = sizeof(header);494 t[0].speed_hz = RT5677_SPI_FREQ;495 t[1].rx_buf = body;496 t[1].speed_hz = RT5677_SPI_FREQ;497 spi_message_init_with_transfers(&m, t, ARRAY_SIZE(t));498 499 for (offset = 0; offset < len; offset += t[1].len) {500 spi_cmd = rt5677_spi_select_cmd(true, (addr + offset) & 7,501 len - offset, &t[1].len);502 503 /* Construct SPI message header */504 header[0] = spi_cmd;505 header[1] = ((addr + offset) & 0xff000000) >> 24;506 header[2] = ((addr + offset) & 0x00ff0000) >> 16;507 header[3] = ((addr + offset) & 0x0000ff00) >> 8;508 header[4] = ((addr + offset) & 0x000000ff) >> 0;509 510 mutex_lock(&spi_mutex);511 status |= spi_sync(g_spi, &m);512 mutex_unlock(&spi_mutex);513 514 515 /* Copy data back to caller buffer */516 rt5677_spi_reverse(cb + offset, len - offset, body, t[1].len);517 }518 return status;519}520EXPORT_SYMBOL_GPL(rt5677_spi_read);521 522/* Write DSP address space using SPI. addr has to be 4-byte aligned.523 * If len is not 4-byte aligned, then extra zeros are written at the end524 * as padding.525 */526int rt5677_spi_write(u32 addr, const void *txbuf, size_t len)527{528 u32 offset;529 int status = 0;530 struct spi_transfer t;531 struct spi_message m;532 /* +1 byte is for the DummyPhase following the DataPhase */533 u8 buf[RT5677_SPI_HEADER + RT5677_SPI_BURST_LEN + 1];534 u8 *body = buf + RT5677_SPI_HEADER;535 u8 spi_cmd;536 const u8 *cb = txbuf;537 538 if (!g_spi)539 return -ENODEV;540 541 if (addr & 3) {542 dev_err(&g_spi->dev, "Bad write align 0x%x(%zu)\n", addr, len);543 return -EACCES;544 }545 546 memset(&t, 0, sizeof(t));547 t.tx_buf = buf;548 t.speed_hz = RT5677_SPI_FREQ;549 spi_message_init_with_transfers(&m, &t, 1);550 551 for (offset = 0; offset < len;) {552 spi_cmd = rt5677_spi_select_cmd(false, (addr + offset) & 7,553 len - offset, &t.len);554 555 /* Construct SPI message header */556 buf[0] = spi_cmd;557 buf[1] = ((addr + offset) & 0xff000000) >> 24;558 buf[2] = ((addr + offset) & 0x00ff0000) >> 16;559 buf[3] = ((addr + offset) & 0x0000ff00) >> 8;560 buf[4] = ((addr + offset) & 0x000000ff) >> 0;561 562 /* Fetch data from caller buffer */563 rt5677_spi_reverse(body, t.len, cb + offset, len - offset);564 offset += t.len;565 t.len += RT5677_SPI_HEADER + 1;566 567 mutex_lock(&spi_mutex);568 status |= spi_sync(g_spi, &m);569 mutex_unlock(&spi_mutex);570 }571 return status;572}573EXPORT_SYMBOL_GPL(rt5677_spi_write);574 575int rt5677_spi_write_firmware(u32 addr, const struct firmware *fw)576{577 return rt5677_spi_write(addr, fw->data, fw->size);578}579EXPORT_SYMBOL_GPL(rt5677_spi_write_firmware);580 581void rt5677_spi_hotword_detected(void)582{583 struct rt5677_dsp *rt5677_dsp;584 585 if (!g_spi)586 return;587 588 rt5677_dsp = dev_get_drvdata(&g_spi->dev);589 if (!rt5677_dsp) {590 dev_err(&g_spi->dev, "Can't get rt5677_dsp\n");591 return;592 }593 594 mutex_lock(&rt5677_dsp->dma_lock);595 dev_info(rt5677_dsp->dev, "Hotword detected\n");596 rt5677_dsp->new_hotword = true;597 mutex_unlock(&rt5677_dsp->dma_lock);598 599 schedule_delayed_work(&rt5677_dsp->copy_work, 0);600}601EXPORT_SYMBOL_GPL(rt5677_spi_hotword_detected);602 603static int rt5677_spi_probe(struct spi_device *spi)604{605 int ret;606 607 g_spi = spi;608 609 ret = devm_snd_soc_register_component(&spi->dev,610 &rt5677_spi_dai_component,611 &rt5677_spi_dai, 1);612 if (ret < 0)613 dev_err(&spi->dev, "Failed to register component.\n");614 615 return ret;616}617 618#ifdef CONFIG_ACPI619static const struct acpi_device_id rt5677_spi_acpi_id[] = {620 { "RT5677AA", 0 },621 { }622};623MODULE_DEVICE_TABLE(acpi, rt5677_spi_acpi_id);624#endif625 626static struct spi_driver rt5677_spi_driver = {627 .driver = {628 .name = DRV_NAME,629 .acpi_match_table = ACPI_PTR(rt5677_spi_acpi_id),630 },631 .probe = rt5677_spi_probe,632};633module_spi_driver(rt5677_spi_driver);634 635MODULE_DESCRIPTION("ASoC RT5677 SPI driver");636MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");637MODULE_LICENSE("GPL v2");638