FILE
rz-ssi.c
File preview with syntax highlighting.
linux-6.19.14/sound/soc/renesas/rz-ssi.c
1// SPDX-License-Identifier: GPL-2.0 2// 3// Renesas RZ/G2L ASoC Serial Sound Interface (SSIF-2) Driver 4// 5// Copyright (C) 2021 Renesas Electronics Corp. 6// Copyright (C) 2019 Chris Brandt. 7// 8 9#include <linux/clk.h> 10#include <linux/dmaengine.h> 11#include <linux/io.h> 12#include <linux/iopoll.h> 13#include <linux/module.h> 14#include <linux/pm_runtime.h> 15#include <linux/reset.h> 16#include <sound/pcm_params.h> 17#include <sound/soc.h> 18 19/* REGISTER OFFSET */ 20#define SSICR 0x000 21#define SSISR 0x004 22#define SSIFCR 0x010 23#define SSIFSR 0x014 24#define SSIFTDR 0x018 25#define SSIFRDR 0x01c 26#define SSIOFR 0x020 27#define SSISCR 0x024 28 29/* SSI REGISTER BITS */ 30#define SSICR_DWL(x) (((x) & 0x7) << 19) 31#define SSICR_SWL(x) (((x) & 0x7) << 16) 32 33#define SSICR_CKS BIT(30) 34#define SSICR_TUIEN BIT(29) 35#define SSICR_TOIEN BIT(28) 36#define SSICR_RUIEN BIT(27) 37#define SSICR_ROIEN BIT(26) 38#define SSICR_MST BIT(14) 39#define SSICR_BCKP BIT(13) 40#define SSICR_LRCKP BIT(12) 41#define SSICR_CKDV(x) (((x) & 0xf) << 4) 42#define SSICR_TEN BIT(1) 43#define SSICR_REN BIT(0) 44 45#define SSISR_TUIRQ BIT(29) 46#define SSISR_TOIRQ BIT(28) 47#define SSISR_RUIRQ BIT(27) 48#define SSISR_ROIRQ BIT(26) 49#define SSISR_IIRQ BIT(25) 50 51#define SSIFCR_AUCKE BIT(31) 52#define SSIFCR_SSIRST BIT(16) 53#define SSIFCR_TIE BIT(3) 54#define SSIFCR_RIE BIT(2) 55#define SSIFCR_TFRST BIT(1) 56#define SSIFCR_RFRST BIT(0) 57#define SSIFCR_FIFO_RST (SSIFCR_TFRST | SSIFCR_RFRST) 58 59#define SSIFSR_TDC_MASK 0x3f 60#define SSIFSR_TDC_SHIFT 24 61#define SSIFSR_RDC_MASK 0x3f 62#define SSIFSR_RDC_SHIFT 8 63 64#define SSIFSR_TDE BIT(16) 65#define SSIFSR_RDF BIT(0) 66 67#define SSIOFR_LRCONT BIT(8) 68 69#define SSISCR_TDES(x) (((x) & 0x1f) << 8) 70#define SSISCR_RDFS(x) (((x) & 0x1f) << 0) 71 72/* Pre allocated buffers sizes */ 73#define PREALLOC_BUFFER (SZ_32K) 74#define PREALLOC_BUFFER_MAX (SZ_32K) 75 76#define SSI_RATES SNDRV_PCM_RATE_8000_48000 /* 8k-48kHz */ 77#define SSI_FMTS SNDRV_PCM_FMTBIT_S16_LE 78#define SSI_CHAN_MIN 2 79#define SSI_CHAN_MAX 2 80#define SSI_FIFO_DEPTH 32 81 82struct rz_ssi_priv; 83 84struct rz_ssi_stream { 85 struct rz_ssi_priv *priv; 86 struct snd_pcm_substream *substream; 87 int fifo_sample_size; /* sample capacity of SSI FIFO */ 88 int dma_buffer_pos; /* The address for the next DMA descriptor */ 89 int completed_dma_buf_pos; /* The address of the last completed DMA descriptor. */ 90 int period_counter; /* for keeping track of periods transferred */ 91 int buffer_pos; /* current frame position in the buffer */ 92 int running; /* 0=stopped, 1=running */ 93 94 int uerr_num; 95 int oerr_num; 96 97 struct dma_chan *dma_ch; 98 99 int (*transfer)(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm); 100}; 101 102struct rz_ssi_priv { 103 void __iomem *base; 104 struct reset_control *rstc; 105 struct device *dev; 106 struct clk *sfr_clk; 107 struct clk *clk; 108 109 phys_addr_t phys; 110 int irq_int; 111 int irq_tx; 112 int irq_rx; 113 int irq_rt; 114 115 spinlock_t lock; 116 117 /* 118 * The SSI supports full-duplex transmission and reception. 119 * However, if an error occurs, channel reset (both transmission 120 * and reception reset) is required. 121 * So it is better to use as half-duplex (playing and recording 122 * should be done on separate channels). 123 */ 124 struct rz_ssi_stream playback; 125 struct rz_ssi_stream capture; 126 127 /* clock */ 128 unsigned long audio_mck; 129 unsigned long audio_clk_1; 130 unsigned long audio_clk_2; 131 132 bool lrckp_fsync_fall; /* LR clock polarity (SSICR.LRCKP) */ 133 bool bckp_rise; /* Bit clock polarity (SSICR.BCKP) */ 134 bool dma_rt; 135 136 struct { 137 bool tx_active; 138 bool rx_active; 139 bool one_stream_triggered; 140 } dup; 141 142 /* Full duplex communication support */ 143 struct { 144 unsigned int rate; 145 unsigned int channels; 146 unsigned int sample_width; 147 unsigned int sample_bits; 148 } hw_params_cache; 149}; 150 151static void rz_ssi_dma_complete(void *data); 152 153static void rz_ssi_reg_writel(struct rz_ssi_priv *priv, uint reg, u32 data) 154{ 155 writel(data, (priv->base + reg)); 156} 157 158static u32 rz_ssi_reg_readl(struct rz_ssi_priv *priv, uint reg) 159{ 160 return readl(priv->base + reg); 161} 162 163static void rz_ssi_reg_mask_setl(struct rz_ssi_priv *priv, uint reg, 164 u32 bclr, u32 bset) 165{ 166 u32 val; 167 168 val = readl(priv->base + reg); 169 val = (val & ~bclr) | bset; 170 writel(val, (priv->base + reg)); 171} 172 173static inline bool rz_ssi_stream_is_play(struct snd_pcm_substream *substream) 174{ 175 return substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 176} 177 178static inline struct rz_ssi_stream * 179rz_ssi_stream_get(struct rz_ssi_priv *ssi, struct snd_pcm_substream *substream) 180{ 181 struct rz_ssi_stream *stream = &ssi->playback; 182 183 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) 184 stream = &ssi->capture; 185 186 return stream; 187} 188 189static inline bool rz_ssi_is_dma_enabled(struct rz_ssi_priv *ssi) 190{ 191 return (ssi->playback.dma_ch && (ssi->dma_rt || ssi->capture.dma_ch)); 192} 193 194static void rz_ssi_set_substream(struct rz_ssi_stream *strm, 195 struct snd_pcm_substream *substream) 196{ 197 struct rz_ssi_priv *ssi = strm->priv; 198 199 guard(spinlock_irqsave)(&ssi->lock); 200 201 strm->substream = substream; 202} 203 204static bool rz_ssi_stream_is_valid(struct rz_ssi_priv *ssi, 205 struct rz_ssi_stream *strm) 206{ 207 guard(spinlock_irqsave)(&ssi->lock); 208 209 return strm->substream && strm->substream->runtime; 210} 211 212static inline bool rz_ssi_is_stream_running(struct rz_ssi_stream *strm) 213{ 214 return strm->substream && strm->running; 215} 216 217static void rz_ssi_stream_init(struct rz_ssi_stream *strm, 218 struct snd_pcm_substream *substream) 219{ 220 rz_ssi_set_substream(strm, substream); 221 strm->dma_buffer_pos = 0; 222 strm->completed_dma_buf_pos = 0; 223 strm->period_counter = 0; 224 strm->buffer_pos = 0; 225 226 strm->oerr_num = 0; 227 strm->uerr_num = 0; 228 strm->running = 0; 229 230 /* fifo init */ 231 strm->fifo_sample_size = SSI_FIFO_DEPTH; 232} 233 234static void rz_ssi_stream_quit(struct rz_ssi_priv *ssi, 235 struct rz_ssi_stream *strm) 236{ 237 struct device *dev = ssi->dev; 238 239 rz_ssi_set_substream(strm, NULL); 240 241 if (strm->oerr_num > 0) 242 dev_info(dev, "overrun = %d\n", strm->oerr_num); 243 244 if (strm->uerr_num > 0) 245 dev_info(dev, "underrun = %d\n", strm->uerr_num); 246} 247 248static int rz_ssi_clk_setup(struct rz_ssi_priv *ssi, unsigned int rate, 249 unsigned int channels) 250{ 251 static u8 ckdv[] = { 1, 2, 4, 8, 16, 32, 64, 128, 6, 12, 24, 48, 96 }; 252 unsigned int channel_bits = 32; /* System Word Length */ 253 unsigned long bclk_rate = rate * channels * channel_bits; 254 unsigned int div; 255 unsigned int i; 256 u32 ssicr = 0; 257 u32 clk_ckdv; 258 259 /* Clear AUCKE so we can set MST */ 260 rz_ssi_reg_writel(ssi, SSIFCR, 0); 261 262 /* Continue to output LRCK pin even when idle */ 263 rz_ssi_reg_writel(ssi, SSIOFR, SSIOFR_LRCONT); 264 if (ssi->audio_clk_1 && ssi->audio_clk_2) { 265 if (ssi->audio_clk_1 % bclk_rate) 266 ssi->audio_mck = ssi->audio_clk_2; 267 else 268 ssi->audio_mck = ssi->audio_clk_1; 269 } 270 271 /* Clock setting */ 272 ssicr |= SSICR_MST; 273 if (ssi->audio_mck == ssi->audio_clk_1) 274 ssicr |= SSICR_CKS; 275 if (ssi->bckp_rise) 276 ssicr |= SSICR_BCKP; 277 if (ssi->lrckp_fsync_fall) 278 ssicr |= SSICR_LRCKP; 279 280 /* Determine the clock divider */ 281 clk_ckdv = 0; 282 div = ssi->audio_mck / bclk_rate; 283 /* try to find an match */ 284 for (i = 0; i < ARRAY_SIZE(ckdv); i++) { 285 if (ckdv[i] == div) { 286 clk_ckdv = i; 287 break; 288 } 289 } 290 291 if (i == ARRAY_SIZE(ckdv)) { 292 dev_err(ssi->dev, "Rate not divisible by audio clock source\n"); 293 return -EINVAL; 294 } 295 296 /* 297 * DWL: Data Word Length = 16 bits 298 * SWL: System Word Length = 32 bits 299 */ 300 ssicr |= SSICR_CKDV(clk_ckdv); 301 ssicr |= SSICR_DWL(1) | SSICR_SWL(3); 302 rz_ssi_reg_writel(ssi, SSICR, ssicr); 303 rz_ssi_reg_writel(ssi, SSIFCR, SSIFCR_AUCKE | SSIFCR_FIFO_RST); 304 305 return 0; 306} 307 308static void rz_ssi_set_idle(struct rz_ssi_priv *ssi) 309{ 310 u32 tmp; 311 int ret; 312 313 /* Disable irqs */ 314 rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TUIEN | SSICR_TOIEN | 315 SSICR_RUIEN | SSICR_ROIEN, 0); 316 rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_TIE | SSIFCR_RIE, 0); 317 318 /* Clear all error flags */ 319 rz_ssi_reg_mask_setl(ssi, SSISR, 320 (SSISR_TOIRQ | SSISR_TUIRQ | SSISR_ROIRQ | 321 SSISR_RUIRQ), 0); 322 323 /* Wait for idle */ 324 ret = readl_poll_timeout_atomic(ssi->base + SSISR, tmp, (tmp & SSISR_IIRQ), 1, 100); 325 if (ret) 326 dev_warn_ratelimited(ssi->dev, "timeout waiting for SSI idle\n"); 327 328 /* Hold FIFOs in reset */ 329 rz_ssi_reg_mask_setl(ssi, SSIFCR, 0, SSIFCR_FIFO_RST); 330} 331 332static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) 333{ 334 bool is_play = rz_ssi_stream_is_play(strm->substream); 335 bool is_full_duplex; 336 u32 ssicr, ssifcr; 337 338 is_full_duplex = ssi->dup.tx_active && ssi->dup.rx_active; 339 ssicr = rz_ssi_reg_readl(ssi, SSICR); 340 ssifcr = rz_ssi_reg_readl(ssi, SSIFCR); 341 if (!is_full_duplex) { 342 ssifcr &= ~0xF; 343 } else if (ssi->dup.one_stream_triggered) { 344 rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TEN | SSICR_REN, 0); 345 rz_ssi_set_idle(ssi); 346 ssifcr &= ~SSIFCR_FIFO_RST; 347 } 348 349 /* FIFO interrupt thresholds */ 350 if (rz_ssi_is_dma_enabled(ssi)) 351 rz_ssi_reg_writel(ssi, SSISCR, 0); 352 else 353 rz_ssi_reg_writel(ssi, SSISCR, 354 SSISCR_TDES(strm->fifo_sample_size / 2 - 1) | 355 SSISCR_RDFS(0)); 356 357 /* enable IRQ */ 358 if (is_play) { 359 ssicr |= SSICR_TUIEN | SSICR_TOIEN; 360 ssifcr |= SSIFCR_TIE; 361 if (!is_full_duplex) 362 ssifcr |= SSIFCR_RFRST; 363 } else { 364 ssicr |= SSICR_RUIEN | SSICR_ROIEN; 365 ssifcr |= SSIFCR_RIE; 366 if (!is_full_duplex) 367 ssifcr |= SSIFCR_TFRST; 368 } 369 370 rz_ssi_reg_writel(ssi, SSICR, ssicr); 371 rz_ssi_reg_writel(ssi, SSIFCR, ssifcr); 372 373 /* Clear all error flags */ 374 rz_ssi_reg_mask_setl(ssi, SSISR, 375 (SSISR_TOIRQ | SSISR_TUIRQ | SSISR_ROIRQ | 376 SSISR_RUIRQ), 0); 377 378 strm->running = 1; 379 if (!is_full_duplex) { 380 ssicr |= is_play ? SSICR_TEN : SSICR_REN; 381 rz_ssi_reg_writel(ssi, SSICR, ssicr); 382 } else if (ssi->dup.one_stream_triggered) { 383 ssicr |= SSICR_TEN | SSICR_REN; 384 rz_ssi_reg_writel(ssi, SSICR, ssicr); 385 ssi->dup.one_stream_triggered = false; 386 } else { 387 ssi->dup.one_stream_triggered = true; 388 } 389 390 return 0; 391} 392 393static int rz_ssi_swreset(struct rz_ssi_priv *ssi) 394{ 395 u32 tmp; 396 397 rz_ssi_reg_mask_setl(ssi, SSIFCR, 0, SSIFCR_SSIRST); 398 rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, 0); 399 return readl_poll_timeout_atomic(ssi->base + SSIFCR, tmp, !(tmp & SSIFCR_SSIRST), 1, 5); 400} 401 402static int rz_ssi_stop(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) 403{ 404 strm->running = 0; 405 406 if (rz_ssi_is_stream_running(&ssi->playback) || 407 rz_ssi_is_stream_running(&ssi->capture)) 408 return 0; 409 410 /* Disable TX/RX */ 411 rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TEN | SSICR_REN, 0); 412 413 /* Cancel all remaining DMA transactions */ 414 if (rz_ssi_is_dma_enabled(ssi)) { 415 if (ssi->playback.dma_ch) 416 dmaengine_terminate_async(ssi->playback.dma_ch); 417 if (ssi->capture.dma_ch) 418 dmaengine_terminate_async(ssi->capture.dma_ch); 419 } 420 421 rz_ssi_set_idle(ssi); 422 423 return 0; 424} 425 426static void rz_ssi_pointer_update(struct rz_ssi_stream *strm, int frames) 427{ 428 struct snd_pcm_substream *substream = strm->substream; 429 struct snd_pcm_runtime *runtime; 430 int current_period; 431 432 if (!strm->running || !substream || !substream->runtime) 433 return; 434 435 runtime = substream->runtime; 436 strm->buffer_pos += frames; 437 WARN_ON(strm->buffer_pos > runtime->buffer_size); 438 439 /* ring buffer */ 440 if (strm->buffer_pos == runtime->buffer_size) 441 strm->buffer_pos = 0; 442 443 current_period = strm->buffer_pos / runtime->period_size; 444 if (strm->period_counter != current_period) { 445 snd_pcm_period_elapsed(strm->substream); 446 strm->period_counter = current_period; 447 } 448 449 strm->completed_dma_buf_pos += runtime->period_size; 450 if (strm->completed_dma_buf_pos >= runtime->buffer_size) 451 strm->completed_dma_buf_pos = 0; 452} 453 454static int rz_ssi_pio_recv(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) 455{ 456 struct snd_pcm_substream *substream = strm->substream; 457 struct snd_pcm_runtime *runtime; 458 u16 *buf; 459 int fifo_samples; 460 int frames_left; 461 int samples; 462 int i; 463 464 if (!rz_ssi_stream_is_valid(ssi, strm)) 465 return -EINVAL; 466 467 runtime = substream->runtime; 468 469 do { 470 /* frames left in this period */ 471 frames_left = runtime->period_size - 472 (strm->buffer_pos % runtime->period_size); 473 if (!frames_left) 474 frames_left = runtime->period_size; 475 476 /* Samples in RX FIFO */ 477 fifo_samples = (rz_ssi_reg_readl(ssi, SSIFSR) >> 478 SSIFSR_RDC_SHIFT) & SSIFSR_RDC_MASK; 479 480 /* Only read full frames at a time */ 481 samples = 0; 482 while (frames_left && (fifo_samples >= runtime->channels)) { 483 samples += runtime->channels; 484 fifo_samples -= runtime->channels; 485 frames_left--; 486 } 487 488 /* not enough samples yet */ 489 if (!samples) 490 break; 491 492 /* calculate new buffer index */ 493 buf = (u16 *)runtime->dma_area; 494 buf += strm->buffer_pos * runtime->channels; 495 496 /* Note, only supports 16-bit samples */ 497 for (i = 0; i < samples; i++) 498 *buf++ = (u16)(rz_ssi_reg_readl(ssi, SSIFRDR) >> 16); 499 500 rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0); 501 rz_ssi_pointer_update(strm, samples / runtime->channels); 502 } while (!frames_left && fifo_samples >= runtime->channels); 503 504 return 0; 505} 506 507static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) 508{ 509 struct snd_pcm_substream *substream = strm->substream; 510 struct snd_pcm_runtime *runtime = substream->runtime; 511 int sample_space; 512 int samples = 0; 513 int frames_left; 514 int i; 515 u32 ssifsr; 516 u16 *buf; 517 518 if (!rz_ssi_stream_is_valid(ssi, strm)) 519 return -EINVAL; 520 521 /* frames left in this period */ 522 frames_left = runtime->period_size - (strm->buffer_pos % 523 runtime->period_size); 524 if (frames_left == 0) 525 frames_left = runtime->period_size; 526 527 sample_space = strm->fifo_sample_size; 528 ssifsr = rz_ssi_reg_readl(ssi, SSIFSR); 529 sample_space -= (ssifsr >> SSIFSR_TDC_SHIFT) & SSIFSR_TDC_MASK; 530 if (sample_space < 0) 531 return -EINVAL; 532 533 /* Only add full frames at a time */ 534 while (frames_left && (sample_space >= runtime->channels)) { 535 samples += runtime->channels; 536 sample_space -= runtime->channels; 537 frames_left--; 538 } 539 540 /* no space to send anything right now */ 541 if (samples == 0) 542 return 0; 543 544 /* calculate new buffer index */ 545 buf = (u16 *)(runtime->dma_area); 546 buf += strm->buffer_pos * runtime->channels; 547 548 /* Note, only supports 16-bit samples */ 549 for (i = 0; i < samples; i++) 550 rz_ssi_reg_writel(ssi, SSIFTDR, ((u32)(*buf++) << 16)); 551 552 rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_TDE, 0); 553 rz_ssi_pointer_update(strm, samples / runtime->channels); 554 555 return 0; 556} 557 558static irqreturn_t rz_ssi_interrupt(int irq, void *data) 559{ 560 struct rz_ssi_stream *strm_playback = NULL; 561 struct rz_ssi_stream *strm_capture = NULL; 562 struct rz_ssi_priv *ssi = data; 563 u32 ssisr = rz_ssi_reg_readl(ssi, SSISR); 564 565 if (ssi->playback.substream) 566 strm_playback = &ssi->playback; 567 if (ssi->capture.substream) 568 strm_capture = &ssi->capture; 569 570 if (!strm_playback && !strm_capture) 571 return IRQ_HANDLED; /* Left over TX/RX interrupt */ 572 573 if (irq == ssi->irq_int) { /* error or idle */ 574 bool is_stopped = false; 575 int i, count; 576 577 if (rz_ssi_is_dma_enabled(ssi)) 578 count = 4; 579 else 580 count = 1; 581 582 if (ssisr & (SSISR_RUIRQ | SSISR_ROIRQ | SSISR_TUIRQ | SSISR_TOIRQ)) 583 is_stopped = true; 584 585 if (ssi->capture.substream && is_stopped) { 586 if (ssisr & SSISR_RUIRQ) 587 strm_capture->uerr_num++; 588 if (ssisr & SSISR_ROIRQ) 589 strm_capture->oerr_num++; 590 591 rz_ssi_stop(ssi, strm_capture); 592 } 593 594 if (ssi->playback.substream && is_stopped) { 595 if (ssisr & SSISR_TUIRQ) 596 strm_playback->uerr_num++; 597 if (ssisr & SSISR_TOIRQ) 598 strm_playback->oerr_num++; 599 600 rz_ssi_stop(ssi, strm_playback); 601 } 602 603 /* Clear all flags */ 604 rz_ssi_reg_mask_setl(ssi, SSISR, SSISR_TOIRQ | SSISR_TUIRQ | 605 SSISR_ROIRQ | SSISR_RUIRQ, 0); 606 607 /* Add/remove more data */ 608 if (ssi->capture.substream && is_stopped) { 609 for (i = 0; i < count; i++) 610 strm_capture->transfer(ssi, strm_capture); 611 } 612 613 if (ssi->playback.substream && is_stopped) { 614 for (i = 0; i < count; i++) 615 strm_playback->transfer(ssi, strm_playback); 616 } 617 618 /* Resume */ 619 if (ssi->playback.substream && is_stopped) 620 rz_ssi_start(ssi, &ssi->playback); 621 if (ssi->capture.substream && is_stopped) 622 rz_ssi_start(ssi, &ssi->capture); 623 } 624 625 if (!rz_ssi_is_stream_running(&ssi->playback) && 626 !rz_ssi_is_stream_running(&ssi->capture)) 627 return IRQ_HANDLED; 628 629 /* tx data empty */ 630 if (irq == ssi->irq_tx && rz_ssi_is_stream_running(&ssi->playback)) 631 strm_playback->transfer(ssi, &ssi->playback); 632 633 /* rx data full */ 634 if (irq == ssi->irq_rx && rz_ssi_is_stream_running(&ssi->capture)) { 635 strm_capture->transfer(ssi, &ssi->capture); 636 rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0); 637 } 638 639 if (irq == ssi->irq_rt) { 640 if (ssi->playback.substream) { 641 strm_playback->transfer(ssi, &ssi->playback); 642 } else { 643 strm_capture->transfer(ssi, &ssi->capture); 644 rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0); 645 } 646 } 647 648 return IRQ_HANDLED; 649} 650 651static int rz_ssi_dma_slave_config(struct rz_ssi_priv *ssi, 652 struct dma_chan *dma_ch, bool is_play) 653{ 654 struct dma_slave_config cfg; 655 656 memset(&cfg, 0, sizeof(cfg)); 657 658 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; 659 cfg.dst_addr = ssi->phys + SSIFTDR; 660 cfg.src_addr = ssi->phys + SSIFRDR; 661 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 662 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; 663 664 return dmaengine_slave_config(dma_ch, &cfg); 665} 666 667static int rz_ssi_dma_transfer(struct rz_ssi_priv *ssi, 668 struct rz_ssi_stream *strm) 669{ 670 struct snd_pcm_substream *substream = strm->substream; 671 struct dma_async_tx_descriptor *desc; 672 struct snd_pcm_runtime *runtime; 673 enum dma_transfer_direction dir; 674 u32 dma_paddr, dma_size; 675 int amount; 676 677 if (!rz_ssi_stream_is_valid(ssi, strm)) 678 return -EINVAL; 679 680 runtime = substream->runtime; 681 if (runtime->state == SNDRV_PCM_STATE_DRAINING) 682 /* 683 * Stream is ending, so do not queue up any more DMA 684 * transfers otherwise we play partial sound clips 685 * because we can't shut off the DMA quick enough. 686 */ 687 return 0; 688 689 dir = rz_ssi_stream_is_play(substream) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; 690 691 /* Always transfer 1 period */ 692 amount = runtime->period_size; 693 694 /* DMA physical address and size */ 695 dma_paddr = runtime->dma_addr + frames_to_bytes(runtime, 696 strm->dma_buffer_pos); 697 dma_size = frames_to_bytes(runtime, amount); 698 desc = dmaengine_prep_slave_single(strm->dma_ch, dma_paddr, dma_size, 699 dir, 700 DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 701 if (!desc) { 702 dev_err(ssi->dev, "dmaengine_prep_slave_single() fail\n"); 703 return -ENOMEM; 704 } 705 706 desc->callback = rz_ssi_dma_complete; 707 desc->callback_param = strm; 708 709 if (dmaengine_submit(desc) < 0) { 710 dev_err(ssi->dev, "dmaengine_submit() fail\n"); 711 return -EIO; 712 } 713 714 /* Update DMA pointer */ 715 strm->dma_buffer_pos += amount; 716 if (strm->dma_buffer_pos >= runtime->buffer_size) 717 strm->dma_buffer_pos = 0; 718 719 /* Start DMA */ 720 dma_async_issue_pending(strm->dma_ch); 721 722 return 0; 723} 724 725static void rz_ssi_dma_complete(void *data) 726{ 727 struct rz_ssi_stream *strm = (struct rz_ssi_stream *)data; 728 729 if (!strm->running || !strm->substream || !strm->substream->runtime) 730 return; 731 732 /* Note that next DMA transaction has probably already started */ 733 rz_ssi_pointer_update(strm, strm->substream->runtime->period_size); 734 735 /* Queue up another DMA transaction */ 736 rz_ssi_dma_transfer(strm->priv, strm); 737} 738 739static void rz_ssi_release_dma_channels(struct rz_ssi_priv *ssi) 740{ 741 if (ssi->playback.dma_ch) { 742 dma_release_channel(ssi->playback.dma_ch); 743 ssi->playback.dma_ch = NULL; 744 if (ssi->dma_rt) 745 ssi->dma_rt = false; 746 } 747 748 if (ssi->capture.dma_ch) { 749 dma_release_channel(ssi->capture.dma_ch); 750 ssi->capture.dma_ch = NULL; 751 } 752} 753 754static int rz_ssi_dma_request(struct rz_ssi_priv *ssi, struct device *dev) 755{ 756 ssi->playback.dma_ch = dma_request_chan(dev, "tx"); 757 if (IS_ERR(ssi->playback.dma_ch)) 758 ssi->playback.dma_ch = NULL; 759 760 ssi->capture.dma_ch = dma_request_chan(dev, "rx"); 761 if (IS_ERR(ssi->capture.dma_ch)) 762 ssi->capture.dma_ch = NULL; 763 764 if (!ssi->playback.dma_ch && !ssi->capture.dma_ch) { 765 ssi->playback.dma_ch = dma_request_chan(dev, "rt"); 766 if (IS_ERR(ssi->playback.dma_ch)) { 767 ssi->playback.dma_ch = NULL; 768 goto no_dma; 769 } 770 771 ssi->dma_rt = true; 772 } 773 774 if (!rz_ssi_is_dma_enabled(ssi)) 775 goto no_dma; 776 777 if (ssi->playback.dma_ch && 778 (rz_ssi_dma_slave_config(ssi, ssi->playback.dma_ch, true) < 0)) 779 goto no_dma; 780 781 if (ssi->capture.dma_ch && 782 (rz_ssi_dma_slave_config(ssi, ssi->capture.dma_ch, false) < 0)) 783 goto no_dma; 784 785 return 0; 786 787no_dma: 788 rz_ssi_release_dma_channels(ssi); 789 790 return -ENODEV; 791} 792 793static int rz_ssi_trigger_resume(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) 794{ 795 struct snd_pcm_substream *substream = strm->substream; 796 struct snd_pcm_runtime *runtime = substream->runtime; 797 int ret; 798 799 strm->dma_buffer_pos = strm->completed_dma_buf_pos + runtime->period_size; 800 801 if (rz_ssi_is_stream_running(&ssi->playback) || 802 rz_ssi_is_stream_running(&ssi->capture)) 803 return 0; 804 805 ret = rz_ssi_swreset(ssi); 806 if (ret) 807 return ret; 808 809 return rz_ssi_clk_setup(ssi, ssi->hw_params_cache.rate, 810 ssi->hw_params_cache.channels); 811} 812 813static int rz_ssi_dai_trigger(struct snd_pcm_substream *substream, int cmd, 814 struct snd_soc_dai *dai) 815{ 816 struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); 817 struct rz_ssi_stream *strm = rz_ssi_stream_get(ssi, substream); 818 int ret = 0, i, num_transfer = 1; 819 820 switch (cmd) { 821 case SNDRV_PCM_TRIGGER_RESUME: 822 ret = rz_ssi_trigger_resume(ssi, strm); 823 if (ret) 824 return ret; 825 826 fallthrough; 827 828 case SNDRV_PCM_TRIGGER_START: 829 if (cmd == SNDRV_PCM_TRIGGER_START) 830 rz_ssi_stream_init(strm, substream); 831 832 if (ssi->dma_rt) { 833 bool is_playback; 834 835 is_playback = rz_ssi_stream_is_play(substream); 836 ret = rz_ssi_dma_slave_config(ssi, ssi->playback.dma_ch, 837 is_playback); 838 /* Fallback to pio */ 839 if (ret < 0) { 840 ssi->playback.transfer = rz_ssi_pio_send; 841 ssi->capture.transfer = rz_ssi_pio_recv; 842 rz_ssi_release_dma_channels(ssi); 843 } 844 } 845 846 /* For DMA, queue up multiple DMA descriptors */ 847 if (rz_ssi_is_dma_enabled(ssi)) 848 num_transfer = 4; 849 850 for (i = 0; i < num_transfer; i++) { 851 ret = strm->transfer(ssi, strm); 852 if (ret) 853 goto done; 854 } 855 856 ret = rz_ssi_start(ssi, strm); 857 break; 858 859 case SNDRV_PCM_TRIGGER_SUSPEND: 860 rz_ssi_stop(ssi, strm); 861 break; 862 863 case SNDRV_PCM_TRIGGER_STOP: 864 rz_ssi_stop(ssi, strm); 865 rz_ssi_stream_quit(ssi, strm); 866 break; 867 } 868 869done: 870 return ret; 871} 872 873static int rz_ssi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 874{ 875 struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); 876 877 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { 878 case SND_SOC_DAIFMT_BP_FP: 879 break; 880 default: 881 dev_err(ssi->dev, "Codec should be clk and frame consumer\n"); 882 return -EINVAL; 883 } 884 885 /* 886 * set clock polarity 887 * 888 * "normal" BCLK = Signal is available at rising edge of BCLK 889 * "normal" FSYNC = (I2S) Left ch starts with falling FSYNC edge 890 */ 891 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 892 case SND_SOC_DAIFMT_NB_NF: 893 ssi->bckp_rise = false; 894 ssi->lrckp_fsync_fall = false; 895 break; 896 case SND_SOC_DAIFMT_NB_IF: 897 ssi->bckp_rise = false; 898 ssi->lrckp_fsync_fall = true; 899 break; 900 case SND_SOC_DAIFMT_IB_NF: 901 ssi->bckp_rise = true; 902 ssi->lrckp_fsync_fall = false; 903 break; 904 case SND_SOC_DAIFMT_IB_IF: 905 ssi->bckp_rise = true; 906 ssi->lrckp_fsync_fall = true; 907 break; 908 default: 909 return -EINVAL; 910 } 911 912 /* only i2s support */ 913 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 914 case SND_SOC_DAIFMT_I2S: 915 break; 916 default: 917 dev_err(ssi->dev, "Only I2S mode is supported.\n"); 918 return -EINVAL; 919 } 920 921 return 0; 922} 923 924static int rz_ssi_startup(struct snd_pcm_substream *substream, 925 struct snd_soc_dai *dai) 926{ 927 struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); 928 929 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 930 ssi->dup.tx_active = true; 931 else 932 ssi->dup.rx_active = true; 933 934 return 0; 935} 936 937static void rz_ssi_shutdown(struct snd_pcm_substream *substream, 938 struct snd_soc_dai *dai) 939{ 940 struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); 941 942 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 943 ssi->dup.tx_active = false; 944 else 945 ssi->dup.rx_active = false; 946} 947 948static bool rz_ssi_is_valid_hw_params(struct rz_ssi_priv *ssi, unsigned int rate, 949 unsigned int channels, 950 unsigned int sample_width, 951 unsigned int sample_bits) 952{ 953 if (ssi->hw_params_cache.rate != rate || 954 ssi->hw_params_cache.channels != channels || 955 ssi->hw_params_cache.sample_width != sample_width || 956 ssi->hw_params_cache.sample_bits != sample_bits) 957 return false; 958 959 return true; 960} 961 962static void rz_ssi_cache_hw_params(struct rz_ssi_priv *ssi, unsigned int rate, 963 unsigned int channels, 964 unsigned int sample_width, 965 unsigned int sample_bits) 966{ 967 ssi->hw_params_cache.rate = rate; 968 ssi->hw_params_cache.channels = channels; 969 ssi->hw_params_cache.sample_width = sample_width; 970 ssi->hw_params_cache.sample_bits = sample_bits; 971} 972 973static int rz_ssi_dai_hw_params(struct snd_pcm_substream *substream, 974 struct snd_pcm_hw_params *params, 975 struct snd_soc_dai *dai) 976{ 977 struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); 978 unsigned int sample_bits = hw_param_interval(params, 979 SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min; 980 unsigned int sample_width = params_width(params); 981 unsigned int channels = params_channels(params); 982 unsigned int rate = params_rate(params); 983 int ret; 984 985 if (sample_bits != 16) { 986 dev_err(ssi->dev, "Unsupported sample width: %d\n", 987 sample_bits); 988 return -EINVAL; 989 } 990 991 if (channels != 2) { 992 dev_err(ssi->dev, "Number of channels not matched: %d\n", 993 channels); 994 return -EINVAL; 995 } 996 997 if (rz_ssi_is_stream_running(&ssi->playback) || 998 rz_ssi_is_stream_running(&ssi->capture)) { 999 if (rz_ssi_is_valid_hw_params(ssi, rate, channels, sample_width, sample_bits)) 1000 return 0; 1001 1002 dev_err(ssi->dev, "Full duplex needs same HW params\n"); 1003 return -EINVAL; 1004 } 1005 1006 rz_ssi_cache_hw_params(ssi, rate, channels, sample_width, sample_bits); 1007 1008 ret = rz_ssi_swreset(ssi); 1009 if (ret) 1010 return ret; 1011 1012 return rz_ssi_clk_setup(ssi, rate, channels); 1013} 1014 1015static const struct snd_soc_dai_ops rz_ssi_dai_ops = { 1016 .startup = rz_ssi_startup, 1017 .shutdown = rz_ssi_shutdown, 1018 .trigger = rz_ssi_dai_trigger, 1019 .set_fmt = rz_ssi_dai_set_fmt, 1020 .hw_params = rz_ssi_dai_hw_params, 1021}; 1022 1023static const struct snd_pcm_hardware rz_ssi_pcm_hardware = { 1024 .info = SNDRV_PCM_INFO_INTERLEAVED | 1025 SNDRV_PCM_INFO_MMAP | 1026 SNDRV_PCM_INFO_MMAP_VALID | 1027 SNDRV_PCM_INFO_RESUME, 1028 .buffer_bytes_max = PREALLOC_BUFFER, 1029 .period_bytes_min = 32, 1030 .period_bytes_max = 8192, 1031 .channels_min = SSI_CHAN_MIN, 1032 .channels_max = SSI_CHAN_MAX, 1033 .periods_min = 1, 1034 .periods_max = 32, 1035 .fifo_size = 32 * 2, 1036}; 1037 1038static int rz_ssi_pcm_open(struct snd_soc_component *component, 1039 struct snd_pcm_substream *substream) 1040{ 1041 snd_soc_set_runtime_hwparams(substream, &rz_ssi_pcm_hardware); 1042 1043 return snd_pcm_hw_constraint_integer(substream->runtime, 1044 SNDRV_PCM_HW_PARAM_PERIODS); 1045} 1046 1047static snd_pcm_uframes_t rz_ssi_pcm_pointer(struct snd_soc_component *component, 1048 struct snd_pcm_substream *substream) 1049{ 1050 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 1051 struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0); 1052 struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); 1053 struct rz_ssi_stream *strm = rz_ssi_stream_get(ssi, substream); 1054 1055 return strm->buffer_pos; 1056} 1057 1058static int rz_ssi_pcm_new(struct snd_soc_component *component, 1059 struct snd_soc_pcm_runtime *rtd) 1060{ 1061 snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, 1062 rtd->card->snd_card->dev, 1063 PREALLOC_BUFFER, PREALLOC_BUFFER_MAX); 1064 return 0; 1065} 1066 1067static struct snd_soc_dai_driver rz_ssi_soc_dai[] = { 1068 { 1069 .name = "rz-ssi-dai", 1070 .playback = { 1071 .rates = SSI_RATES, 1072 .formats = SSI_FMTS, 1073 .channels_min = SSI_CHAN_MIN, 1074 .channels_max = SSI_CHAN_MAX, 1075 }, 1076 .capture = { 1077 .rates = SSI_RATES, 1078 .formats = SSI_FMTS, 1079 .channels_min = SSI_CHAN_MIN, 1080 .channels_max = SSI_CHAN_MAX, 1081 }, 1082 .ops = &rz_ssi_dai_ops, 1083 }, 1084}; 1085 1086static const struct snd_soc_component_driver rz_ssi_soc_component = { 1087 .name = "rz-ssi", 1088 .open = rz_ssi_pcm_open, 1089 .pointer = rz_ssi_pcm_pointer, 1090 .pcm_construct = rz_ssi_pcm_new, 1091 .legacy_dai_naming = 1, 1092}; 1093 1094static int rz_ssi_probe(struct platform_device *pdev) 1095{ 1096 struct device *dev = &pdev->dev; 1097 struct rz_ssi_priv *ssi; 1098 struct clk *audio_clk; 1099 struct resource *res; 1100 int ret; 1101 1102 ssi = devm_kzalloc(dev, sizeof(*ssi), GFP_KERNEL); 1103 if (!ssi) 1104 return -ENOMEM; 1105 1106 ssi->dev = dev; 1107 ssi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 1108 if (IS_ERR(ssi->base)) 1109 return PTR_ERR(ssi->base); 1110 1111 ssi->phys = res->start; 1112 ssi->clk = devm_clk_get(dev, "ssi"); 1113 if (IS_ERR(ssi->clk)) 1114 return PTR_ERR(ssi->clk); 1115 1116 ssi->sfr_clk = devm_clk_get(dev, "ssi_sfr"); 1117 if (IS_ERR(ssi->sfr_clk)) 1118 return PTR_ERR(ssi->sfr_clk); 1119 1120 audio_clk = devm_clk_get(dev, "audio_clk1"); 1121 if (IS_ERR(audio_clk)) 1122 return dev_err_probe(&pdev->dev, PTR_ERR(audio_clk), 1123 "no audio clk1"); 1124 1125 ssi->audio_clk_1 = clk_get_rate(audio_clk); 1126 audio_clk = devm_clk_get(dev, "audio_clk2"); 1127 if (IS_ERR(audio_clk)) 1128 return dev_err_probe(&pdev->dev, PTR_ERR(audio_clk), 1129 "no audio clk2"); 1130 1131 ssi->audio_clk_2 = clk_get_rate(audio_clk); 1132 if (!(ssi->audio_clk_1 || ssi->audio_clk_2)) 1133 return dev_err_probe(&pdev->dev, -EINVAL, 1134 "no audio clk1 or audio clk2"); 1135 1136 ssi->audio_mck = ssi->audio_clk_1 ? ssi->audio_clk_1 : ssi->audio_clk_2; 1137 1138 /* Detect DMA support */ 1139 ret = rz_ssi_dma_request(ssi, dev); 1140 if (ret < 0) { 1141 dev_warn(dev, "DMA not available, using PIO\n"); 1142 ssi->playback.transfer = rz_ssi_pio_send; 1143 ssi->capture.transfer = rz_ssi_pio_recv; 1144 } else { 1145 dev_info(dev, "DMA enabled"); 1146 ssi->playback.transfer = rz_ssi_dma_transfer; 1147 ssi->capture.transfer = rz_ssi_dma_transfer; 1148 } 1149 1150 ssi->playback.priv = ssi; 1151 ssi->capture.priv = ssi; 1152 1153 spin_lock_init(&ssi->lock); 1154 dev_set_drvdata(dev, ssi); 1155 1156 /* Error Interrupt */ 1157 ssi->irq_int = platform_get_irq_byname(pdev, "int_req"); 1158 if (ssi->irq_int < 0) { 1159 ret = ssi->irq_int; 1160 goto err_release_dma_chs; 1161 } 1162 1163 ret = devm_request_irq(dev, ssi->irq_int, &rz_ssi_interrupt, 1164 0, dev_name(dev), ssi); 1165 if (ret < 0) { 1166 dev_err_probe(dev, ret, "irq request error (int_req)\n"); 1167 goto err_release_dma_chs; 1168 } 1169 1170 if (!rz_ssi_is_dma_enabled(ssi)) { 1171 /* Tx and Rx interrupts (pio only) */ 1172 ssi->irq_tx = platform_get_irq_byname(pdev, "dma_tx"); 1173 ssi->irq_rx = platform_get_irq_byname(pdev, "dma_rx"); 1174 if (ssi->irq_tx == -ENXIO && ssi->irq_rx == -ENXIO) { 1175 ssi->irq_rt = platform_get_irq_byname(pdev, "dma_rt"); 1176 if (ssi->irq_rt < 0) 1177 return ssi->irq_rt; 1178 1179 ret = devm_request_irq(dev, ssi->irq_rt, 1180 &rz_ssi_interrupt, 0, 1181 dev_name(dev), ssi); 1182 if (ret < 0) 1183 return dev_err_probe(dev, ret, 1184 "irq request error (dma_rt)\n"); 1185 } else { 1186 if (ssi->irq_tx < 0) 1187 return ssi->irq_tx; 1188 1189 if (ssi->irq_rx < 0) 1190 return ssi->irq_rx; 1191 1192 ret = devm_request_irq(dev, ssi->irq_tx, 1193 &rz_ssi_interrupt, 0, 1194 dev_name(dev), ssi); 1195 if (ret < 0) 1196 return dev_err_probe(dev, ret, 1197 "irq request error (dma_tx)\n"); 1198 1199 ret = devm_request_irq(dev, ssi->irq_rx, 1200 &rz_ssi_interrupt, 0, 1201 dev_name(dev), ssi); 1202 if (ret < 0) 1203 return dev_err_probe(dev, ret, 1204 "irq request error (dma_rx)\n"); 1205 } 1206 } 1207 1208 ssi->rstc = devm_reset_control_get_exclusive(dev, NULL); 1209 if (IS_ERR(ssi->rstc)) { 1210 ret = PTR_ERR(ssi->rstc); 1211 goto err_release_dma_chs; 1212 } 1213 1214 /* Default 0 for power saving. Can be overridden via sysfs. */ 1215 pm_runtime_set_autosuspend_delay(dev, 0); 1216 pm_runtime_use_autosuspend(dev); 1217 ret = devm_pm_runtime_enable(dev); 1218 if (ret < 0) { 1219 dev_err(dev, "Failed to enable runtime PM!\n"); 1220 goto err_release_dma_chs; 1221 } 1222 1223 ret = devm_snd_soc_register_component(dev, &rz_ssi_soc_component, 1224 rz_ssi_soc_dai, 1225 ARRAY_SIZE(rz_ssi_soc_dai)); 1226 if (ret < 0) { 1227 dev_err(dev, "failed to register snd component\n"); 1228 goto err_release_dma_chs; 1229 } 1230 1231 return 0; 1232 1233err_release_dma_chs: 1234 rz_ssi_release_dma_channels(ssi); 1235 1236 return ret; 1237} 1238 1239static void rz_ssi_remove(struct platform_device *pdev) 1240{ 1241 struct rz_ssi_priv *ssi = dev_get_drvdata(&pdev->dev); 1242 1243 rz_ssi_release_dma_channels(ssi); 1244 1245 reset_control_assert(ssi->rstc); 1246} 1247 1248static const struct of_device_id rz_ssi_of_match[] = { 1249 { .compatible = "renesas,rz-ssi", }, 1250 {/* Sentinel */}, 1251}; 1252MODULE_DEVICE_TABLE(of, rz_ssi_of_match); 1253 1254static int rz_ssi_runtime_suspend(struct device *dev) 1255{ 1256 struct rz_ssi_priv *ssi = dev_get_drvdata(dev); 1257 1258 return reset_control_assert(ssi->rstc); 1259} 1260 1261static int rz_ssi_runtime_resume(struct device *dev) 1262{ 1263 struct rz_ssi_priv *ssi = dev_get_drvdata(dev); 1264 1265 return reset_control_deassert(ssi->rstc); 1266} 1267 1268static const struct dev_pm_ops rz_ssi_pm_ops = { 1269 RUNTIME_PM_OPS(rz_ssi_runtime_suspend, rz_ssi_runtime_resume, NULL) 1270 NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) 1271}; 1272 1273static struct platform_driver rz_ssi_driver = { 1274 .driver = { 1275 .name = "rz-ssi-pcm-audio", 1276 .of_match_table = rz_ssi_of_match, 1277 .pm = pm_ptr(&rz_ssi_pm_ops), 1278 }, 1279 .probe = rz_ssi_probe, 1280 .remove = rz_ssi_remove, 1281}; 1282 1283module_platform_driver(rz_ssi_driver); 1284 1285MODULE_LICENSE("GPL v2"); 1286MODULE_DESCRIPTION("Renesas RZ/G2L ASoC Serial Sound Interface Driver"); 1287MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
~/
Read-only file preview.