1/* 2 * siu_pcm.c - ALSA driver for Renesas SH7343, SH7722 SIU peripheral. 3 * 4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> 5 * Copyright (C) 2006 Carlos Munoz <carlos@kenati.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 as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21#include <linux/delay.h> 22#include <linux/dma-mapping.h> 23#include <linux/dmaengine.h> 24#include <linux/interrupt.h> 25#include <linux/module.h> 26#include <linux/platform_device.h> 27 28#include <sound/control.h> 29#include <sound/core.h> 30#include <sound/pcm.h> 31#include <sound/pcm_params.h> 32#include <sound/soc-dai.h> 33 34#include <asm/siu.h> 35 36#include "siu.h" 37 38#define GET_MAX_PERIODS(buf_bytes, period_bytes) \ 39 ((buf_bytes) / (period_bytes)) 40#define PERIOD_OFFSET(buf_addr, period_num, period_bytes) \ 41 ((buf_addr) + ((period_num) * (period_bytes))) 42 43#define RWF_STM_RD 0x01 /* Read in progress */ 44#define RWF_STM_WT 0x02 /* Write in progress */ 45 46struct siu_port *siu_ports[SIU_PORT_NUM]; 47 48/* transfersize is number of u32 dma transfers per period */ 49static int siu_pcm_stmwrite_stop(struct siu_port *port_info) 50{ 51 struct siu_info *info = siu_i2s_dai.private_data; 52 u32 __iomem *base = info->reg; 53 struct siu_stream *siu_stream = &port_info->playback; 54 u32 stfifo; 55 56 if (!siu_stream->rw_flg) 57 return -EPERM; 58 59 /* output FIFO disable */ 60 stfifo = siu_read32(base + SIU_STFIFO); 61 siu_write32(base + SIU_STFIFO, stfifo & ~0x0c180c18); 62 pr_debug("%s: STFIFO %x -> %x\n", __func__, 63 stfifo, stfifo & ~0x0c180c18); 64 65 /* during stmwrite clear */ 66 siu_stream->rw_flg = 0; 67 68 return 0; 69} 70 71static int siu_pcm_stmwrite_start(struct siu_port *port_info) 72{ 73 struct siu_stream *siu_stream = &port_info->playback; 74 75 if (siu_stream->rw_flg) 76 return -EPERM; 77 78 /* Current period in buffer */ 79 port_info->playback.cur_period = 0; 80 81 /* during stmwrite flag set */ 82 siu_stream->rw_flg = RWF_STM_WT; 83 84 /* DMA transfer start */ 85 tasklet_schedule(&siu_stream->tasklet); 86 87 return 0; 88} 89 90static void siu_dma_tx_complete(void *arg) 91{ 92 struct siu_stream *siu_stream = arg; 93 94 if (!siu_stream->rw_flg) 95 return; 96 97 /* Update completed period count */ 98 if (++siu_stream->cur_period >= 99 GET_MAX_PERIODS(siu_stream->buf_bytes, 100 siu_stream->period_bytes)) 101 siu_stream->cur_period = 0; 102 103 pr_debug("%s: done period #%d (%u/%u bytes), cookie %d\n", 104 __func__, siu_stream->cur_period, 105 siu_stream->cur_period * siu_stream->period_bytes, 106 siu_stream->buf_bytes, siu_stream->cookie); 107 108 tasklet_schedule(&siu_stream->tasklet); 109 110 /* Notify alsa: a period is done */ 111 snd_pcm_period_elapsed(siu_stream->substream); 112} 113 114static int siu_pcm_wr_set(struct siu_port *port_info, 115 dma_addr_t buff, u32 size) 116{ 117 struct siu_info *info = siu_i2s_dai.private_data; 118 u32 __iomem *base = info->reg; 119 struct siu_stream *siu_stream = &port_info->playback; 120 struct snd_pcm_substream *substream = siu_stream->substream; 121 struct device *dev = substream->pcm->card->dev; 122 struct dma_async_tx_descriptor *desc; 123 dma_cookie_t cookie; 124 struct scatterlist sg; 125 u32 stfifo; 126 127 sg_init_table(&sg, 1); 128 sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)), 129 size, offset_in_page(buff)); 130 sg_dma_address(&sg) = buff; 131 132 desc = siu_stream->chan->device->device_prep_slave_sg(siu_stream->chan, 133 &sg, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 134 if (!desc) { 135 dev_err(dev, "Failed to allocate a dma descriptor\n"); 136 return -ENOMEM; 137 } 138 139 desc->callback = siu_dma_tx_complete; 140 desc->callback_param = siu_stream; 141 cookie = desc->tx_submit(desc); 142 if (cookie < 0) { 143 dev_err(dev, "Failed to submit a dma transfer\n"); 144 return cookie; 145 } 146 147 siu_stream->tx_desc = desc; 148 siu_stream->cookie = cookie; 149 150 dma_async_issue_pending(siu_stream->chan); 151 152 /* only output FIFO enable */ 153 stfifo = siu_read32(base + SIU_STFIFO); 154 siu_write32(base + SIU_STFIFO, stfifo | (port_info->stfifo & 0x0c180c18)); 155 dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__, 156 stfifo, stfifo | (port_info->stfifo & 0x0c180c18)); 157 158 return 0; 159} 160 161static int siu_pcm_rd_set(struct siu_port *port_info, 162 dma_addr_t buff, size_t size) 163{ 164 struct siu_info *info = siu_i2s_dai.private_data; 165 u32 __iomem *base = info->reg; 166 struct siu_stream *siu_stream = &port_info->capture; 167 struct snd_pcm_substream *substream = siu_stream->substream; 168 struct device *dev = substream->pcm->card->dev; 169 struct dma_async_tx_descriptor *desc; 170 dma_cookie_t cookie; 171 struct scatterlist sg; 172 u32 stfifo; 173 174 dev_dbg(dev, "%s: %u@%llx\n", __func__, size, (unsigned long long)buff); 175 176 sg_init_table(&sg, 1); 177 sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)), 178 size, offset_in_page(buff)); 179 sg_dma_address(&sg) = buff; 180 181 desc = siu_stream->chan->device->device_prep_slave_sg(siu_stream->chan, 182 &sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 183 if (!desc) { 184 dev_err(dev, "Failed to allocate dma descriptor\n"); 185 return -ENOMEM; 186 } 187 188 desc->callback = siu_dma_tx_complete; 189 desc->callback_param = siu_stream; 190 cookie = desc->tx_submit(desc); 191 if (cookie < 0) { 192 dev_err(dev, "Failed to submit dma descriptor\n"); 193 return cookie; 194 } 195 196 siu_stream->tx_desc = desc; 197 siu_stream->cookie = cookie; 198 199 dma_async_issue_pending(siu_stream->chan); 200 201 /* only input FIFO enable */ 202 stfifo = siu_read32(base + SIU_STFIFO); 203 siu_write32(base + SIU_STFIFO, siu_read32(base + SIU_STFIFO) | 204 (port_info->stfifo & 0x13071307)); 205 dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__, 206 stfifo, stfifo | (port_info->stfifo & 0x13071307)); 207 208 return 0; 209} 210 211static void siu_io_tasklet(unsigned long data) 212{ 213 struct siu_stream *siu_stream = (struct siu_stream *)data; 214 struct snd_pcm_substream *substream = siu_stream->substream; 215 struct device *dev = substream->pcm->card->dev; 216 struct snd_pcm_runtime *rt = substream->runtime; 217 struct siu_port *port_info = siu_port_info(substream); 218 219 dev_dbg(dev, "%s: flags %x\n", __func__, siu_stream->rw_flg); 220 221 if (!siu_stream->rw_flg) { 222 dev_dbg(dev, "%s: stream inactive\n", __func__); 223 return; 224 } 225 226 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 227 dma_addr_t buff; 228 size_t count; 229 u8 *virt; 230 231 buff = (dma_addr_t)PERIOD_OFFSET(rt->dma_addr, 232 siu_stream->cur_period, 233 siu_stream->period_bytes); 234 virt = PERIOD_OFFSET(rt->dma_area, 235 siu_stream->cur_period, 236 siu_stream->period_bytes); 237 count = siu_stream->period_bytes; 238 239 /* DMA transfer start */ 240 siu_pcm_rd_set(port_info, buff, count); 241 } else { 242 siu_pcm_wr_set(port_info, 243 (dma_addr_t)PERIOD_OFFSET(rt->dma_addr, 244 siu_stream->cur_period, 245 siu_stream->period_bytes), 246 siu_stream->period_bytes); 247 } 248} 249 250/* Capture */ 251static int siu_pcm_stmread_start(struct siu_port *port_info) 252{ 253 struct siu_stream *siu_stream = &port_info->capture; 254 255 if (siu_stream->xfer_cnt > 0x1000000) 256 return -EINVAL; 257 if (siu_stream->rw_flg) 258 return -EPERM; 259 260 /* Current period in buffer */ 261 siu_stream->cur_period = 0; 262 263 /* during stmread flag set */ 264 siu_stream->rw_flg = RWF_STM_RD; 265 266 tasklet_schedule(&siu_stream->tasklet); 267 268 return 0; 269} 270 271static int siu_pcm_stmread_stop(struct siu_port *port_info) 272{ 273 struct siu_info *info = siu_i2s_dai.private_data; 274 u32 __iomem *base = info->reg; 275 struct siu_stream *siu_stream = &port_info->capture; 276 struct device *dev = siu_stream->substream->pcm->card->dev; 277 u32 stfifo; 278 279 if (!siu_stream->rw_flg) 280 return -EPERM; 281 282 /* input FIFO disable */ 283 stfifo = siu_read32(base + SIU_STFIFO); 284 siu_write32(base + SIU_STFIFO, stfifo & ~0x13071307); 285 dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__, 286 stfifo, stfifo & ~0x13071307); 287 288 /* during stmread flag clear */ 289 siu_stream->rw_flg = 0; 290 291 return 0; 292} 293 294static int siu_pcm_hw_params(struct snd_pcm_substream *ss, 295 struct snd_pcm_hw_params *hw_params) 296{ 297 struct siu_info *info = siu_i2s_dai.private_data; 298 struct device *dev = ss->pcm->card->dev; 299 int ret; 300 301 dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id); 302 303 ret = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params)); 304 if (ret < 0) 305 dev_err(dev, "snd_pcm_lib_malloc_pages() failed\n"); 306 307 return ret; 308} 309 310static int siu_pcm_hw_free(struct snd_pcm_substream *ss) 311{ 312 struct siu_info *info = siu_i2s_dai.private_data; 313 struct siu_port *port_info = siu_port_info(ss); 314 struct device *dev = ss->pcm->card->dev; 315 struct siu_stream *siu_stream; 316 317 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) 318 siu_stream = &port_info->playback; 319 else 320 siu_stream = &port_info->capture; 321 322 dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id); 323 324 return snd_pcm_lib_free_pages(ss); 325} 326 327static bool filter(struct dma_chan *chan, void *slave) 328{ 329 struct sh_dmae_slave *param = slave; 330 331 pr_debug("%s: slave ID %d\n", __func__, param->slave_id); 332 333 if (unlikely(param->dma_dev != chan->device->dev)) 334 return false; 335 336 chan->private = param; 337 return true; 338} 339 340static int siu_pcm_open(struct snd_pcm_substream *ss) 341{ 342 /* Playback / Capture */ 343 struct siu_info *info = siu_i2s_dai.private_data; 344 struct siu_port *port_info = siu_port_info(ss); 345 struct siu_stream *siu_stream; 346 u32 port = info->port_id; 347 struct siu_platform *pdata = siu_i2s_dai.dev->platform_data; 348 struct device *dev = ss->pcm->card->dev; 349 dma_cap_mask_t mask; 350 struct sh_dmae_slave *param; 351 352 dma_cap_zero(mask); 353 dma_cap_set(DMA_SLAVE, mask); 354 355 dev_dbg(dev, "%s, port=%d@%p\n", __func__, port, port_info); 356 357 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) { 358 siu_stream = &port_info->playback; 359 param = &siu_stream->param; 360 param->slave_id = port ? pdata->dma_slave_tx_b : 361 pdata->dma_slave_tx_a; 362 } else { 363 siu_stream = &port_info->capture; 364 param = &siu_stream->param; 365 param->slave_id = port ? pdata->dma_slave_rx_b : 366 pdata->dma_slave_rx_a; 367 } 368 369 param->dma_dev = pdata->dma_dev; 370 /* Get DMA channel */ 371 siu_stream->chan = dma_request_channel(mask, filter, param); 372 if (!siu_stream->chan) { 373 dev_err(dev, "DMA channel allocation failed!\n"); 374 return -EBUSY; 375 } 376 377 siu_stream->substream = ss; 378 379 return 0; 380} 381 382static int siu_pcm_close(struct snd_pcm_substream *ss) 383{ 384 struct siu_info *info = siu_i2s_dai.private_data; 385 struct device *dev = ss->pcm->card->dev; 386 struct siu_port *port_info = siu_port_info(ss); 387 struct siu_stream *siu_stream; 388 389 dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id); 390 391 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) 392 siu_stream = &port_info->playback; 393 else 394 siu_stream = &port_info->capture; 395 396 dma_release_channel(siu_stream->chan); 397 siu_stream->chan = NULL; 398 399 siu_stream->substream = NULL; 400 401 return 0; 402} 403 404static int siu_pcm_prepare(struct snd_pcm_substream *ss) 405{ 406 struct siu_info *info = siu_i2s_dai.private_data; 407 struct siu_port *port_info = siu_port_info(ss); 408 struct device *dev = ss->pcm->card->dev; 409 struct snd_pcm_runtime *rt = ss->runtime; 410 struct siu_stream *siu_stream; 411 snd_pcm_sframes_t xfer_cnt; 412 413 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) 414 siu_stream = &port_info->playback; 415 else 416 siu_stream = &port_info->capture; 417 418 rt = siu_stream->substream->runtime; 419 420 siu_stream->buf_bytes = snd_pcm_lib_buffer_bytes(ss); 421 siu_stream->period_bytes = snd_pcm_lib_period_bytes(ss); 422 423 dev_dbg(dev, "%s: port=%d, %d channels, period=%u bytes\n", __func__, 424 info->port_id, rt->channels, siu_stream->period_bytes); 425 426 /* We only support buffers that are multiples of the period */ 427 if (siu_stream->buf_bytes % siu_stream->period_bytes) { 428 dev_err(dev, "%s() - buffer=%d not multiple of period=%d\n", 429 __func__, siu_stream->buf_bytes, 430 siu_stream->period_bytes); 431 return -EINVAL; 432 } 433 434 xfer_cnt = bytes_to_frames(rt, siu_stream->period_bytes); 435 if (!xfer_cnt || xfer_cnt > 0x1000000) 436 return -EINVAL; 437 438 siu_stream->format = rt->format; 439 siu_stream->xfer_cnt = xfer_cnt; 440 441 dev_dbg(dev, "port=%d buf=%lx buf_bytes=%d period_bytes=%d " 442 "format=%d channels=%d xfer_cnt=%d\n", info->port_id, 443 (unsigned long)rt->dma_addr, siu_stream->buf_bytes, 444 siu_stream->period_bytes, 445 siu_stream->format, rt->channels, (int)xfer_cnt); 446 447 return 0; 448} 449 450static int siu_pcm_trigger(struct snd_pcm_substream *ss, int cmd) 451{ 452 struct siu_info *info = siu_i2s_dai.private_data; 453 struct device *dev = ss->pcm->card->dev; 454 struct siu_port *port_info = siu_port_info(ss); 455 int ret; 456 457 dev_dbg(dev, "%s: port=%d@%p, cmd=%d\n", __func__, 458 info->port_id, port_info, cmd); 459 460 switch (cmd) { 461 case SNDRV_PCM_TRIGGER_START: 462 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) 463 ret = siu_pcm_stmwrite_start(port_info); 464 else 465 ret = siu_pcm_stmread_start(port_info); 466 467 if (ret < 0) 468 dev_warn(dev, "%s: start failed on port=%d\n", 469 __func__, info->port_id); 470 471 break; 472 case SNDRV_PCM_TRIGGER_STOP: 473 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) 474 siu_pcm_stmwrite_stop(port_info); 475 else 476 siu_pcm_stmread_stop(port_info); 477 ret = 0; 478 479 break; 480 default: 481 dev_err(dev, "%s() unsupported cmd=%d\n", __func__, cmd); 482 ret = -EINVAL; 483 } 484 485 return ret; 486} 487 488/* 489 * So far only resolution of one period is supported, subject to extending the 490 * dmangine API 491 */ 492static snd_pcm_uframes_t siu_pcm_pointer_dma(struct snd_pcm_substream *ss) 493{ 494 struct device *dev = ss->pcm->card->dev; 495 struct siu_info *info = siu_i2s_dai.private_data; 496 u32 __iomem *base = info->reg; 497 struct siu_port *port_info = siu_port_info(ss); 498 struct snd_pcm_runtime *rt = ss->runtime; 499 size_t ptr; 500 struct siu_stream *siu_stream; 501 502 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) 503 siu_stream = &port_info->playback; 504 else 505 siu_stream = &port_info->capture; 506 507 /* 508 * ptr is the offset into the buffer where the dma is currently at. We 509 * check if the dma buffer has just wrapped. 510 */ 511 ptr = PERIOD_OFFSET(rt->dma_addr, 512 siu_stream->cur_period, 513 siu_stream->period_bytes) - rt->dma_addr; 514 515 dev_dbg(dev, 516 "%s: port=%d, events %x, FSTS %x, xferred %u/%u, cookie %d\n", 517 __func__, info->port_id, siu_read32(base + SIU_EVNTC), 518 siu_read32(base + SIU_SBFSTS), ptr, siu_stream->buf_bytes, 519 siu_stream->cookie); 520 521 if (ptr >= siu_stream->buf_bytes) 522 ptr = 0; 523 524 return bytes_to_frames(ss->runtime, ptr); 525} 526 527static int siu_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, 528 struct snd_pcm *pcm) 529{ 530 /* card->dev == socdev->dev, see snd_soc_new_pcms() */ 531 struct siu_info *info = siu_i2s_dai.private_data; 532 struct platform_device *pdev = to_platform_device(card->dev); 533 int ret; 534 int i; 535 536 /* pdev->id selects between SIUA and SIUB */ 537 if (pdev->id < 0 || pdev->id >= SIU_PORT_NUM) 538 return -EINVAL; 539 540 info->port_id = pdev->id; 541 542 /* 543 * While the siu has 2 ports, only one port can be on at a time (only 1 544 * SPB). So far all the boards using the siu had only one of the ports 545 * wired to a codec. To simplify things, we only register one port with 546 * alsa. In case both ports are needed, it should be changed here 547 */ 548 for (i = pdev->id; i < pdev->id + 1; i++) { 549 struct siu_port **port_info = &siu_ports[i]; 550 551 ret = siu_init_port(i, port_info, card); 552 if (ret < 0) 553 return ret; 554 555 ret = snd_pcm_lib_preallocate_pages_for_all(pcm, 556 SNDRV_DMA_TYPE_DEV, NULL, 557 SIU_BUFFER_BYTES_MAX, SIU_BUFFER_BYTES_MAX); 558 if (ret < 0) { 559 dev_err(card->dev, 560 "snd_pcm_lib_preallocate_pages_for_all() err=%d", 561 ret); 562 goto fail; 563 } 564 565 (*port_info)->pcm = pcm; 566 567 /* IO tasklets */ 568 tasklet_init(&(*port_info)->playback.tasklet, siu_io_tasklet, 569 (unsigned long)&(*port_info)->playback); 570 tasklet_init(&(*port_info)->capture.tasklet, siu_io_tasklet, 571 (unsigned long)&(*port_info)->capture); 572 } 573 574 dev_info(card->dev, "SuperH SIU driver initialized.\n"); 575 return 0; 576 577fail: 578 siu_free_port(siu_ports[pdev->id]); 579 dev_err(card->dev, "SIU: failed to initialize.\n"); 580 return ret; 581} 582 583static void siu_pcm_free(struct snd_pcm *pcm) 584{ 585 struct platform_device *pdev = to_platform_device(pcm->card->dev); 586 struct siu_port *port_info = siu_ports[pdev->id]; 587 588 tasklet_kill(&port_info->capture.tasklet); 589 tasklet_kill(&port_info->playback.tasklet); 590 591 siu_free_port(port_info); 592 snd_pcm_lib_preallocate_free_for_all(pcm); 593 594 dev_dbg(pcm->card->dev, "%s\n", __func__); 595} 596 597static struct snd_pcm_ops siu_pcm_ops = { 598 .open = siu_pcm_open, 599 .close = siu_pcm_close, 600 .ioctl = snd_pcm_lib_ioctl, 601 .hw_params = siu_pcm_hw_params, 602 .hw_free = siu_pcm_hw_free, 603 .prepare = siu_pcm_prepare, 604 .trigger = siu_pcm_trigger, 605 .pointer = siu_pcm_pointer_dma, 606}; 607 608struct snd_soc_platform siu_platform = { 609 .name = "siu-audio", 610 .pcm_ops = &siu_pcm_ops, 611 .pcm_new = siu_pcm_new, 612 .pcm_free = siu_pcm_free, 613}; 614EXPORT_SYMBOL_GPL(siu_platform); 615