root/sound/soc/codecs/rt5514-spi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rt5514_spi_copy_work
  2. rt5514_schedule_copy
  3. rt5514_spi_irq
  4. rt5514_spi_pcm_open
  5. rt5514_spi_hw_params
  6. rt5514_spi_hw_free
  7. rt5514_spi_pcm_pointer
  8. rt5514_spi_pcm_probe
  9. rt5514_spi_burst_read
  10. rt5514_spi_burst_write
  11. rt5514_spi_probe
  12. rt5514_suspend
  13. rt5514_resume

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * rt5514-spi.c  --  RT5514 SPI driver
   4  *
   5  * Copyright 2015 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/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>
  32 
  33 #include "rt5514-spi.h"
  34 
  35 #define DRV_NAME "rt5514-spi"
  36 
  37 static struct spi_device *rt5514_spi;
  38 
  39 struct rt5514_dsp {
  40         struct device *dev;
  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;
  46 };
  47 
  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,
  55         .periods_min            = 8,
  56         .periods_max            = 8,
  57         .channels_min           = 1,
  58         .channels_max           = 1,
  59         .buffer_bytes_max       = 0x20000,
  60 };
  61 
  62 static struct snd_soc_dai_driver rt5514_spi_dai = {
  63         .name = "rt5514-dsp-cpu-dai",
  64         .id = 0,
  65         .capture = {
  66                 .stream_name = "DSP Capture",
  67                 .channels_min = 1,
  68                 .channels_max = 1,
  69                 .rates = SNDRV_PCM_RATE_16000,
  70                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
  71         },
  72 };
  73 
  74 static void rt5514_spi_copy_work(struct work_struct *work)
  75 {
  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;
  81         u8 buf[8];
  82 
  83         mutex_lock(&rt5514_dsp->dma_lock);
  84         if (!rt5514_dsp->substream) {
  85                 dev_err(rt5514_dsp->dev, "No pcm substream\n");
  86                 goto done;
  87         }
  88 
  89         runtime = rt5514_dsp->substream->runtime;
  90         period_bytes = snd_pcm_lib_period_bytes(rt5514_dsp->substream);
  91         if (!period_bytes) {
  92                 schedule_delayed_work(&rt5514_dsp->copy_work, 5);
  93                 goto done;
  94         }
  95 
  96         if (rt5514_dsp->buf_size % period_bytes)
  97                 rt5514_dsp->buf_size = (rt5514_dsp->buf_size / period_bytes) *
  98                         period_bytes;
  99 
 100         if (rt5514_dsp->get_size >= rt5514_dsp->buf_size) {
 101                 rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP, (u8 *)&buf,
 102                         sizeof(buf));
 103                 cur_wp = buf[0] | buf[1] << 8 | buf[2] << 16 |
 104                                         buf[3] << 24;
 105 
 106                 if (cur_wp >= rt5514_dsp->buf_rp)
 107                         remain_data = (cur_wp - rt5514_dsp->buf_rp);
 108                 else
 109                         remain_data =
 110                                 (rt5514_dsp->buf_limit - rt5514_dsp->buf_rp) +
 111                                 (cur_wp - rt5514_dsp->buf_base);
 112 
 113                 if (remain_data < period_bytes) {
 114                         schedule_delayed_work(&rt5514_dsp->copy_work, 5);
 115                         goto done;
 116                 }
 117         }
 118 
 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,
 122                         period_bytes);
 123 
 124                 if (rt5514_dsp->buf_rp + period_bytes == rt5514_dsp->buf_limit)
 125                         rt5514_dsp->buf_rp = rt5514_dsp->buf_base;
 126                 else
 127                         rt5514_dsp->buf_rp += period_bytes;
 128         } else {
 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,
 132                         truncated_bytes);
 133 
 134                 rt5514_spi_burst_read(rt5514_dsp->buf_base,
 135                         runtime->dma_area + rt5514_dsp->dma_offset +
 136                         truncated_bytes, period_bytes - truncated_bytes);
 137 
 138                 rt5514_dsp->buf_rp = rt5514_dsp->buf_base + period_bytes -
 139                         truncated_bytes;
 140         }
 141 
 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;
 146 
 147         snd_pcm_period_elapsed(rt5514_dsp->substream);
 148 
 149         schedule_delayed_work(&rt5514_dsp->copy_work, 5);
 150 
 151 done:
 152         mutex_unlock(&rt5514_dsp->dma_lock);
 153 }
 154 
 155 static void rt5514_schedule_copy(struct rt5514_dsp *rt5514_dsp)
 156 {
 157         u8 buf[8];
 158 
 159         if (!rt5514_dsp->substream)
 160                 return;
 161 
 162         rt5514_dsp->get_size = 0;
 163 
 164         /**
 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.
 168          */
 169         rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE, (u8 *)&buf,
 170                 sizeof(buf));
 171         rt5514_dsp->buf_base = buf[0] | buf[1] << 8 | buf[2] << 16 |
 172                                 buf[3] << 24;
 173 
 174         rt5514_spi_burst_read(RT5514_BUFFER_VOICE_LIMIT, (u8 *)&buf,
 175                 sizeof(buf));
 176         rt5514_dsp->buf_limit = buf[0] | buf[1] << 8 | buf[2] << 16 |
 177                                 buf[3] << 24;
 178 
 179         rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP, (u8 *)&buf,
 180                 sizeof(buf));
 181         rt5514_dsp->buf_rp = buf[0] | buf[1] << 8 | buf[2] << 16 |
 182                                 buf[3] << 24;
 183 
 184         if (rt5514_dsp->buf_rp % 8)
 185                 rt5514_dsp->buf_rp = (rt5514_dsp->buf_rp / 8) * 8;
 186 
 187         rt5514_dsp->buf_size = rt5514_dsp->buf_limit - rt5514_dsp->buf_base;
 188 
 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);
 192 }
 193 
 194 static irqreturn_t rt5514_spi_irq(int irq, void *data)
 195 {
 196         struct rt5514_dsp *rt5514_dsp = data;
 197 
 198         rt5514_schedule_copy(rt5514_dsp);
 199 
 200         return IRQ_HANDLED;
 201 }
 202 
 203 /* PCM for streaming audio from the DSP buffer */
 204 static int rt5514_spi_pcm_open(struct snd_pcm_substream *substream)
 205 {
 206         snd_soc_set_runtime_hwparams(substream, &rt5514_spi_pcm_hardware);
 207 
 208         return 0;
 209 }
 210 
 211 static int rt5514_spi_hw_params(struct snd_pcm_substream *substream,
 212                                struct snd_pcm_hw_params *hw_params)
 213 {
 214         struct snd_soc_pcm_runtime *rtd = substream->private_data;
 215         struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
 216         struct rt5514_dsp *rt5514_dsp =
 217                 snd_soc_component_get_drvdata(component);
 218         int ret;
 219         u8 buf[8];
 220 
 221         mutex_lock(&rt5514_dsp->dma_lock);
 222         ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
 223                         params_buffer_bytes(hw_params));
 224         rt5514_dsp->substream = substream;
 225         rt5514_dsp->dma_offset = 0;
 226 
 227         /* Read IRQ status and schedule copy accordingly. */
 228         rt5514_spi_burst_read(RT5514_IRQ_CTRL, (u8 *)&buf, sizeof(buf));
 229         if (buf[0] & RT5514_IRQ_STATUS_BIT)
 230                 rt5514_schedule_copy(rt5514_dsp);
 231 
 232         mutex_unlock(&rt5514_dsp->dma_lock);
 233 
 234         return ret;
 235 }
 236 
 237 static int rt5514_spi_hw_free(struct snd_pcm_substream *substream)
 238 {
 239         struct snd_soc_pcm_runtime *rtd = substream->private_data;
 240         struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
 241         struct rt5514_dsp *rt5514_dsp =
 242                 snd_soc_component_get_drvdata(component);
 243 
 244         mutex_lock(&rt5514_dsp->dma_lock);
 245         rt5514_dsp->substream = NULL;
 246         mutex_unlock(&rt5514_dsp->dma_lock);
 247 
 248         cancel_delayed_work_sync(&rt5514_dsp->copy_work);
 249 
 250         return snd_pcm_lib_free_vmalloc_buffer(substream);
 251 }
 252 
 253 static snd_pcm_uframes_t rt5514_spi_pcm_pointer(
 254                 struct snd_pcm_substream *substream)
 255 {
 256         struct snd_pcm_runtime *runtime = substream->runtime;
 257         struct snd_soc_pcm_runtime *rtd = substream->private_data;
 258         struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
 259         struct rt5514_dsp *rt5514_dsp =
 260                 snd_soc_component_get_drvdata(component);
 261 
 262         return bytes_to_frames(runtime, rt5514_dsp->dma_offset);
 263 }
 264 
 265 static const struct snd_pcm_ops rt5514_spi_pcm_ops = {
 266         .open           = rt5514_spi_pcm_open,
 267         .hw_params      = rt5514_spi_hw_params,
 268         .hw_free        = rt5514_spi_hw_free,
 269         .pointer        = rt5514_spi_pcm_pointer,
 270         .page           = snd_pcm_lib_get_vmalloc_page,
 271 };
 272 
 273 static int rt5514_spi_pcm_probe(struct snd_soc_component *component)
 274 {
 275         struct rt5514_dsp *rt5514_dsp;
 276         int ret;
 277 
 278         rt5514_dsp = devm_kzalloc(component->dev, sizeof(*rt5514_dsp),
 279                         GFP_KERNEL);
 280         if (!rt5514_dsp)
 281                 return -ENOMEM;
 282 
 283         rt5514_dsp->dev = &rt5514_spi->dev;
 284         mutex_init(&rt5514_dsp->dma_lock);
 285         INIT_DELAYED_WORK(&rt5514_dsp->copy_work, rt5514_spi_copy_work);
 286         snd_soc_component_set_drvdata(component, rt5514_dsp);
 287 
 288         if (rt5514_spi->irq) {
 289                 ret = devm_request_threaded_irq(&rt5514_spi->dev,
 290                         rt5514_spi->irq, NULL, rt5514_spi_irq,
 291                         IRQF_TRIGGER_RISING | IRQF_ONESHOT, "rt5514-spi",
 292                         rt5514_dsp);
 293                 if (ret)
 294                         dev_err(&rt5514_spi->dev,
 295                                 "%s Failed to reguest IRQ: %d\n", __func__,
 296                                 ret);
 297                 else
 298                         device_init_wakeup(rt5514_dsp->dev, true);
 299         }
 300 
 301         return 0;
 302 }
 303 
 304 static const struct snd_soc_component_driver rt5514_spi_component = {
 305         .name  = DRV_NAME,
 306         .probe = rt5514_spi_pcm_probe,
 307         .ops = &rt5514_spi_pcm_ops,
 308 };
 309 
 310 /**
 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.
 315  *
 316  *
 317  * Returns true for success.
 318  */
 319 int rt5514_spi_burst_read(unsigned int addr, u8 *rxbuf, size_t len)
 320 {
 321         u8 spi_cmd = RT5514_SPI_CMD_BURST_READ;
 322         int status;
 323         u8 write_buf[8];
 324         unsigned int i, end, offset = 0;
 325 
 326         struct spi_message message;
 327         struct spi_transfer x[3];
 328 
 329         while (offset < len) {
 330                 if (offset + RT5514_SPI_BUF_LEN <= len)
 331                         end = RT5514_SPI_BUF_LEN;
 332                 else
 333                         end = len % RT5514_SPI_BUF_LEN;
 334 
 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;
 340 
 341                 spi_message_init(&message);
 342                 memset(x, 0, sizeof(x));
 343 
 344                 x[0].len = 5;
 345                 x[0].tx_buf = write_buf;
 346                 spi_message_add_tail(&x[0], &message);
 347 
 348                 x[1].len = 4;
 349                 x[1].tx_buf = write_buf;
 350                 spi_message_add_tail(&x[1], &message);
 351 
 352                 x[2].len = end;
 353                 x[2].rx_buf = rxbuf + offset;
 354                 spi_message_add_tail(&x[2], &message);
 355 
 356                 status = spi_sync(rt5514_spi, &message);
 357 
 358                 if (status)
 359                         return false;
 360 
 361                 offset += RT5514_SPI_BUF_LEN;
 362         }
 363 
 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];
 373 
 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];
 382         }
 383 
 384         return true;
 385 }
 386 EXPORT_SYMBOL_GPL(rt5514_spi_burst_read);
 387 
 388 /**
 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.
 393  *
 394  *
 395  * Returns true for success.
 396  */
 397 int rt5514_spi_burst_write(u32 addr, const u8 *txbuf, size_t len)
 398 {
 399         u8 spi_cmd = RT5514_SPI_CMD_BURST_WRITE;
 400         u8 *write_buf;
 401         unsigned int i, end, offset = 0;
 402 
 403         write_buf = kmalloc(RT5514_SPI_BUF_LEN + 6, GFP_KERNEL);
 404 
 405         if (write_buf == NULL)
 406                 return -ENOMEM;
 407 
 408         while (offset < len) {
 409                 if (offset + RT5514_SPI_BUF_LEN <= len)
 410                         end = RT5514_SPI_BUF_LEN;
 411                 else
 412                         end = len % RT5514_SPI_BUF_LEN;
 413 
 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;
 419 
 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];
 429                 }
 430 
 431                 write_buf[end + 5] = spi_cmd;
 432 
 433                 spi_write(rt5514_spi, write_buf, end + 6);
 434 
 435                 offset += RT5514_SPI_BUF_LEN;
 436         }
 437 
 438         kfree(write_buf);
 439 
 440         return 0;
 441 }
 442 EXPORT_SYMBOL_GPL(rt5514_spi_burst_write);
 443 
 444 static int rt5514_spi_probe(struct spi_device *spi)
 445 {
 446         int ret;
 447 
 448         rt5514_spi = spi;
 449 
 450         ret = devm_snd_soc_register_component(&spi->dev,
 451                                               &rt5514_spi_component,
 452                                               &rt5514_spi_dai, 1);
 453         if (ret < 0) {
 454                 dev_err(&spi->dev, "Failed to register component.\n");
 455                 return ret;
 456         }
 457 
 458         return 0;
 459 }
 460 
 461 static int __maybe_unused rt5514_suspend(struct device *dev)
 462 {
 463         int irq = to_spi_device(dev)->irq;
 464 
 465         if (device_may_wakeup(dev))
 466                 enable_irq_wake(irq);
 467 
 468         return 0;
 469 }
 470 
 471 static int __maybe_unused rt5514_resume(struct device *dev)
 472 {
 473         struct rt5514_dsp *rt5514_dsp = dev_get_drvdata(dev);
 474         int irq = to_spi_device(dev)->irq;
 475         u8 buf[8];
 476 
 477         if (device_may_wakeup(dev))
 478                 disable_irq_wake(irq);
 479 
 480         if (rt5514_dsp) {
 481                 if (rt5514_dsp->substream) {
 482                         rt5514_spi_burst_read(RT5514_IRQ_CTRL, (u8 *)&buf,
 483                                 sizeof(buf));
 484                         if (buf[0] & RT5514_IRQ_STATUS_BIT)
 485                                 rt5514_schedule_copy(rt5514_dsp);
 486                 }
 487         }
 488 
 489         return 0;
 490 }
 491 
 492 static const struct dev_pm_ops rt5514_pm_ops = {
 493         SET_SYSTEM_SLEEP_PM_OPS(rt5514_suspend, rt5514_resume)
 494 };
 495 
 496 static const struct of_device_id rt5514_of_match[] = {
 497         { .compatible = "realtek,rt5514", },
 498         {},
 499 };
 500 MODULE_DEVICE_TABLE(of, rt5514_of_match);
 501 
 502 static struct spi_driver rt5514_spi_driver = {
 503         .driver = {
 504                 .name = "rt5514",
 505                 .pm = &rt5514_pm_ops,
 506                 .of_match_table = of_match_ptr(rt5514_of_match),
 507         },
 508         .probe = rt5514_spi_probe,
 509 };
 510 module_spi_driver(rt5514_spi_driver);
 511 
 512 MODULE_DESCRIPTION("RT5514 SPI driver");
 513 MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
 514 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */