1 /* 2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 and 6 * only version 2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * lpass-platform.c -- ALSA SoC platform driver for QTi LPASS 14 */ 15 16 #include <linux/dma-mapping.h> 17 #include <linux/export.h> 18 #include <linux/kernel.h> 19 #include <linux/module.h> 20 #include <linux/platform_device.h> 21 #include <sound/pcm_params.h> 22 #include <linux/regmap.h> 23 #include <sound/soc.h> 24 #include "lpass-lpaif-reg.h" 25 #include "lpass.h" 26 27 struct lpass_pcm_data { 28 int rdma_ch; 29 int i2s_port; 30 }; 31 32 #define LPASS_PLATFORM_BUFFER_SIZE (16 * 1024) 33 #define LPASS_PLATFORM_PERIODS 2 34 35 static struct snd_pcm_hardware lpass_platform_pcm_hardware = { 36 .info = SNDRV_PCM_INFO_MMAP | 37 SNDRV_PCM_INFO_MMAP_VALID | 38 SNDRV_PCM_INFO_INTERLEAVED | 39 SNDRV_PCM_INFO_PAUSE | 40 SNDRV_PCM_INFO_RESUME, 41 .formats = SNDRV_PCM_FMTBIT_S16 | 42 SNDRV_PCM_FMTBIT_S24 | 43 SNDRV_PCM_FMTBIT_S32, 44 .rates = SNDRV_PCM_RATE_8000_192000, 45 .rate_min = 8000, 46 .rate_max = 192000, 47 .channels_min = 1, 48 .channels_max = 8, 49 .buffer_bytes_max = LPASS_PLATFORM_BUFFER_SIZE, 50 .period_bytes_max = LPASS_PLATFORM_BUFFER_SIZE / 51 LPASS_PLATFORM_PERIODS, 52 .period_bytes_min = LPASS_PLATFORM_BUFFER_SIZE / 53 LPASS_PLATFORM_PERIODS, 54 .periods_min = LPASS_PLATFORM_PERIODS, 55 .periods_max = LPASS_PLATFORM_PERIODS, 56 .fifo_size = 0, 57 }; 58 59 static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream) 60 { 61 struct snd_pcm_runtime *runtime = substream->runtime; 62 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 63 int ret; 64 65 snd_soc_set_runtime_hwparams(substream, &lpass_platform_pcm_hardware); 66 67 runtime->dma_bytes = lpass_platform_pcm_hardware.buffer_bytes_max; 68 69 ret = snd_pcm_hw_constraint_integer(runtime, 70 SNDRV_PCM_HW_PARAM_PERIODS); 71 if (ret < 0) { 72 dev_err(soc_runtime->dev, "%s() setting constraints failed: %d\n", 73 __func__, ret); 74 return -EINVAL; 75 } 76 77 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 78 79 return 0; 80 } 81 82 static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream, 83 struct snd_pcm_hw_params *params) 84 { 85 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 86 struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); 87 struct lpass_data *drvdata = 88 snd_soc_platform_get_drvdata(soc_runtime->platform); 89 struct lpass_variant *v = drvdata->variant; 90 snd_pcm_format_t format = params_format(params); 91 unsigned int channels = params_channels(params); 92 unsigned int regval; 93 int bitwidth; 94 int ret, rdma_port = pcm_data->i2s_port + v->rdmactl_audif_start; 95 96 bitwidth = snd_pcm_format_width(format); 97 if (bitwidth < 0) { 98 dev_err(soc_runtime->dev, "%s() invalid bit width given: %d\n", 99 __func__, bitwidth); 100 return bitwidth; 101 } 102 103 regval = LPAIF_RDMACTL_BURSTEN_INCR4 | 104 LPAIF_RDMACTL_AUDINTF(rdma_port) | 105 LPAIF_RDMACTL_FIFOWM_8; 106 107 switch (bitwidth) { 108 case 16: 109 switch (channels) { 110 case 1: 111 case 2: 112 regval |= LPAIF_RDMACTL_WPSCNT_ONE; 113 break; 114 case 4: 115 regval |= LPAIF_RDMACTL_WPSCNT_TWO; 116 break; 117 case 6: 118 regval |= LPAIF_RDMACTL_WPSCNT_THREE; 119 break; 120 case 8: 121 regval |= LPAIF_RDMACTL_WPSCNT_FOUR; 122 break; 123 default: 124 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n", 125 __func__, bitwidth, channels); 126 return -EINVAL; 127 } 128 break; 129 case 24: 130 case 32: 131 switch (channels) { 132 case 1: 133 regval |= LPAIF_RDMACTL_WPSCNT_ONE; 134 break; 135 case 2: 136 regval |= LPAIF_RDMACTL_WPSCNT_TWO; 137 break; 138 case 4: 139 regval |= LPAIF_RDMACTL_WPSCNT_FOUR; 140 break; 141 case 6: 142 regval |= LPAIF_RDMACTL_WPSCNT_SIX; 143 break; 144 case 8: 145 regval |= LPAIF_RDMACTL_WPSCNT_EIGHT; 146 break; 147 default: 148 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n", 149 __func__, bitwidth, channels); 150 return -EINVAL; 151 } 152 break; 153 default: 154 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n", 155 __func__, bitwidth, channels); 156 return -EINVAL; 157 } 158 159 ret = regmap_write(drvdata->lpaif_map, 160 LPAIF_RDMACTL_REG(v, pcm_data->rdma_ch), regval); 161 if (ret) { 162 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", 163 __func__, ret); 164 return ret; 165 } 166 167 return 0; 168 } 169 170 static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream) 171 { 172 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 173 struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); 174 struct lpass_data *drvdata = 175 snd_soc_platform_get_drvdata(soc_runtime->platform); 176 struct lpass_variant *v = drvdata->variant; 177 int ret; 178 179 ret = regmap_write(drvdata->lpaif_map, 180 LPAIF_RDMACTL_REG(v, pcm_data->rdma_ch), 0); 181 if (ret) 182 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", 183 __func__, ret); 184 185 return ret; 186 } 187 188 static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream) 189 { 190 struct snd_pcm_runtime *runtime = substream->runtime; 191 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 192 struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); 193 struct lpass_data *drvdata = 194 snd_soc_platform_get_drvdata(soc_runtime->platform); 195 struct lpass_variant *v = drvdata->variant; 196 int ret, ch = pcm_data->rdma_ch; 197 198 ret = regmap_write(drvdata->lpaif_map, 199 LPAIF_RDMABASE_REG(v, ch), 200 runtime->dma_addr); 201 if (ret) { 202 dev_err(soc_runtime->dev, "%s() error writing to rdmabase reg: %d\n", 203 __func__, ret); 204 return ret; 205 } 206 207 ret = regmap_write(drvdata->lpaif_map, 208 LPAIF_RDMABUFF_REG(v, ch), 209 (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1); 210 if (ret) { 211 dev_err(soc_runtime->dev, "%s() error writing to rdmabuff reg: %d\n", 212 __func__, ret); 213 return ret; 214 } 215 216 ret = regmap_write(drvdata->lpaif_map, 217 LPAIF_RDMAPER_REG(v, ch), 218 (snd_pcm_lib_period_bytes(substream) >> 2) - 1); 219 if (ret) { 220 dev_err(soc_runtime->dev, "%s() error writing to rdmaper reg: %d\n", 221 __func__, ret); 222 return ret; 223 } 224 225 ret = regmap_update_bits(drvdata->lpaif_map, 226 LPAIF_RDMACTL_REG(v, ch), 227 LPAIF_RDMACTL_ENABLE_MASK, LPAIF_RDMACTL_ENABLE_ON); 228 if (ret) { 229 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", 230 __func__, ret); 231 return ret; 232 } 233 234 return 0; 235 } 236 237 static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream, 238 int cmd) 239 { 240 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 241 struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); 242 struct lpass_data *drvdata = 243 snd_soc_platform_get_drvdata(soc_runtime->platform); 244 struct lpass_variant *v = drvdata->variant; 245 int ret, ch = pcm_data->rdma_ch; 246 247 switch (cmd) { 248 case SNDRV_PCM_TRIGGER_START: 249 case SNDRV_PCM_TRIGGER_RESUME: 250 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 251 /* clear status before enabling interrupts */ 252 ret = regmap_write(drvdata->lpaif_map, 253 LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST), 254 LPAIF_IRQ_ALL(ch)); 255 if (ret) { 256 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n", 257 __func__, ret); 258 return ret; 259 } 260 261 ret = regmap_update_bits(drvdata->lpaif_map, 262 LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST), 263 LPAIF_IRQ_ALL(ch), 264 LPAIF_IRQ_ALL(ch)); 265 if (ret) { 266 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n", 267 __func__, ret); 268 return ret; 269 } 270 271 ret = regmap_update_bits(drvdata->lpaif_map, 272 LPAIF_RDMACTL_REG(v, ch), 273 LPAIF_RDMACTL_ENABLE_MASK, 274 LPAIF_RDMACTL_ENABLE_ON); 275 if (ret) { 276 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", 277 __func__, ret); 278 return ret; 279 } 280 break; 281 case SNDRV_PCM_TRIGGER_STOP: 282 case SNDRV_PCM_TRIGGER_SUSPEND: 283 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 284 ret = regmap_update_bits(drvdata->lpaif_map, 285 LPAIF_RDMACTL_REG(v, ch), 286 LPAIF_RDMACTL_ENABLE_MASK, 287 LPAIF_RDMACTL_ENABLE_OFF); 288 if (ret) { 289 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", 290 __func__, ret); 291 return ret; 292 } 293 294 ret = regmap_update_bits(drvdata->lpaif_map, 295 LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST), 296 LPAIF_IRQ_ALL(ch), 0); 297 if (ret) { 298 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n", 299 __func__, ret); 300 return ret; 301 } 302 break; 303 } 304 305 return 0; 306 } 307 308 static snd_pcm_uframes_t lpass_platform_pcmops_pointer( 309 struct snd_pcm_substream *substream) 310 { 311 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 312 struct lpass_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(soc_runtime); 313 struct lpass_data *drvdata = 314 snd_soc_platform_get_drvdata(soc_runtime->platform); 315 struct lpass_variant *v = drvdata->variant; 316 unsigned int base_addr, curr_addr; 317 int ret, ch = pcm_data->rdma_ch; 318 319 ret = regmap_read(drvdata->lpaif_map, 320 LPAIF_RDMABASE_REG(v, ch), &base_addr); 321 if (ret) { 322 dev_err(soc_runtime->dev, "%s() error reading from rdmabase reg: %d\n", 323 __func__, ret); 324 return ret; 325 } 326 327 ret = regmap_read(drvdata->lpaif_map, 328 LPAIF_RDMACURR_REG(v, ch), &curr_addr); 329 if (ret) { 330 dev_err(soc_runtime->dev, "%s() error reading from rdmacurr reg: %d\n", 331 __func__, ret); 332 return ret; 333 } 334 335 return bytes_to_frames(substream->runtime, curr_addr - base_addr); 336 } 337 338 static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream, 339 struct vm_area_struct *vma) 340 { 341 struct snd_pcm_runtime *runtime = substream->runtime; 342 343 return dma_mmap_coherent(substream->pcm->card->dev, vma, 344 runtime->dma_area, runtime->dma_addr, 345 runtime->dma_bytes); 346 } 347 348 static struct snd_pcm_ops lpass_platform_pcm_ops = { 349 .open = lpass_platform_pcmops_open, 350 .ioctl = snd_pcm_lib_ioctl, 351 .hw_params = lpass_platform_pcmops_hw_params, 352 .hw_free = lpass_platform_pcmops_hw_free, 353 .prepare = lpass_platform_pcmops_prepare, 354 .trigger = lpass_platform_pcmops_trigger, 355 .pointer = lpass_platform_pcmops_pointer, 356 .mmap = lpass_platform_pcmops_mmap, 357 }; 358 359 static irqreturn_t lpass_dma_interrupt_handler( 360 struct snd_pcm_substream *substream, 361 struct lpass_data *drvdata, 362 int chan, u32 interrupts) 363 { 364 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 365 struct lpass_variant *v = drvdata->variant; 366 irqreturn_t ret = IRQ_NONE; 367 int rv; 368 369 if (interrupts & LPAIF_IRQ_PER(chan)) { 370 rv = regmap_write(drvdata->lpaif_map, 371 LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST), 372 LPAIF_IRQ_PER(chan)); 373 if (rv) { 374 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n", 375 __func__, rv); 376 return IRQ_NONE; 377 } 378 snd_pcm_period_elapsed(substream); 379 ret = IRQ_HANDLED; 380 } 381 382 if (interrupts & LPAIF_IRQ_XRUN(chan)) { 383 rv = regmap_write(drvdata->lpaif_map, 384 LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST), 385 LPAIF_IRQ_XRUN(chan)); 386 if (rv) { 387 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n", 388 __func__, rv); 389 return IRQ_NONE; 390 } 391 dev_warn(soc_runtime->dev, "%s() xrun warning\n", __func__); 392 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); 393 ret = IRQ_HANDLED; 394 } 395 396 if (interrupts & LPAIF_IRQ_ERR(chan)) { 397 rv = regmap_write(drvdata->lpaif_map, 398 LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST), 399 LPAIF_IRQ_ERR(chan)); 400 if (rv) { 401 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n", 402 __func__, rv); 403 return IRQ_NONE; 404 } 405 dev_err(soc_runtime->dev, "%s() bus access error\n", __func__); 406 snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); 407 ret = IRQ_HANDLED; 408 } 409 410 return ret; 411 } 412 413 static irqreturn_t lpass_platform_lpaif_irq(int irq, void *data) 414 { 415 struct lpass_data *drvdata = data; 416 struct lpass_variant *v = drvdata->variant; 417 unsigned int irqs; 418 int rv, chan; 419 420 rv = regmap_read(drvdata->lpaif_map, 421 LPAIF_IRQSTAT_REG(v, LPAIF_IRQ_PORT_HOST), &irqs); 422 if (rv) { 423 pr_err("%s() error reading from irqstat reg: %d\n", 424 __func__, rv); 425 return IRQ_NONE; 426 } 427 428 /* Handle per channel interrupts */ 429 for (chan = 0; chan < LPASS_MAX_DMA_CHANNELS; chan++) { 430 if (irqs & LPAIF_IRQ_ALL(chan) && drvdata->substream[chan]) { 431 rv = lpass_dma_interrupt_handler( 432 drvdata->substream[chan], 433 drvdata, chan, irqs); 434 if (rv != IRQ_HANDLED) 435 return rv; 436 } 437 } 438 439 return IRQ_HANDLED; 440 } 441 442 static int lpass_platform_alloc_buffer(struct snd_pcm_substream *substream, 443 struct snd_soc_pcm_runtime *soc_runtime) 444 { 445 struct snd_dma_buffer *buf = &substream->dma_buffer; 446 size_t size = lpass_platform_pcm_hardware.buffer_bytes_max; 447 448 buf->dev.type = SNDRV_DMA_TYPE_DEV; 449 buf->dev.dev = soc_runtime->dev; 450 buf->private_data = NULL; 451 buf->area = dma_alloc_coherent(soc_runtime->dev, size, &buf->addr, 452 GFP_KERNEL); 453 if (!buf->area) { 454 dev_err(soc_runtime->dev, "%s: Could not allocate DMA buffer\n", 455 __func__); 456 return -ENOMEM; 457 } 458 buf->bytes = size; 459 460 return 0; 461 } 462 463 static void lpass_platform_free_buffer(struct snd_pcm_substream *substream, 464 struct snd_soc_pcm_runtime *soc_runtime) 465 { 466 struct snd_dma_buffer *buf = &substream->dma_buffer; 467 468 if (buf->area) { 469 dma_free_coherent(soc_runtime->dev, buf->bytes, buf->area, 470 buf->addr); 471 } 472 buf->area = NULL; 473 } 474 475 static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime) 476 { 477 struct snd_pcm *pcm = soc_runtime->pcm; 478 struct snd_pcm_substream *substream = 479 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 480 struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai; 481 struct lpass_data *drvdata = 482 snd_soc_platform_get_drvdata(soc_runtime->platform); 483 struct lpass_variant *v = drvdata->variant; 484 int ret; 485 struct lpass_pcm_data *data; 486 487 data = devm_kzalloc(soc_runtime->dev, sizeof(*data), GFP_KERNEL); 488 if (!data) 489 return -ENOMEM; 490 491 if (v->alloc_dma_channel) 492 data->rdma_ch = v->alloc_dma_channel(drvdata); 493 494 if (IS_ERR_VALUE(data->rdma_ch)) 495 return data->rdma_ch; 496 497 drvdata->substream[data->rdma_ch] = substream; 498 data->i2s_port = cpu_dai->driver->id; 499 500 snd_soc_pcm_set_drvdata(soc_runtime, data); 501 502 soc_runtime->dev->coherent_dma_mask = DMA_BIT_MASK(32); 503 soc_runtime->dev->dma_mask = &soc_runtime->dev->coherent_dma_mask; 504 505 ret = lpass_platform_alloc_buffer(substream, soc_runtime); 506 if (ret) 507 return ret; 508 509 ret = regmap_write(drvdata->lpaif_map, 510 LPAIF_RDMACTL_REG(v, data->rdma_ch), 0); 511 if (ret) { 512 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", 513 __func__, ret); 514 goto err_buf; 515 } 516 517 return 0; 518 519 err_buf: 520 lpass_platform_free_buffer(substream, soc_runtime); 521 return ret; 522 } 523 524 static void lpass_platform_pcm_free(struct snd_pcm *pcm) 525 { 526 struct snd_pcm_substream *substream = 527 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 528 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 529 struct lpass_data *drvdata = 530 snd_soc_platform_get_drvdata(soc_runtime->platform); 531 struct lpass_pcm_data *data = snd_soc_pcm_get_drvdata(soc_runtime); 532 struct lpass_variant *v = drvdata->variant; 533 534 drvdata->substream[data->rdma_ch] = NULL; 535 536 if (v->free_dma_channel) 537 v->free_dma_channel(drvdata, data->rdma_ch); 538 539 lpass_platform_free_buffer(substream, soc_runtime); 540 } 541 542 static struct snd_soc_platform_driver lpass_platform_driver = { 543 .pcm_new = lpass_platform_pcm_new, 544 .pcm_free = lpass_platform_pcm_free, 545 .ops = &lpass_platform_pcm_ops, 546 }; 547 548 int asoc_qcom_lpass_platform_register(struct platform_device *pdev) 549 { 550 struct lpass_data *drvdata = platform_get_drvdata(pdev); 551 struct lpass_variant *v = drvdata->variant; 552 int ret; 553 554 drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif"); 555 if (drvdata->lpaif_irq < 0) { 556 dev_err(&pdev->dev, "%s() error getting irq handle: %d\n", 557 __func__, drvdata->lpaif_irq); 558 return -ENODEV; 559 } 560 561 /* ensure audio hardware is disabled */ 562 ret = regmap_write(drvdata->lpaif_map, 563 LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST), 0); 564 if (ret) { 565 dev_err(&pdev->dev, "%s() error writing to irqen reg: %d\n", 566 __func__, ret); 567 return ret; 568 } 569 570 ret = devm_request_irq(&pdev->dev, drvdata->lpaif_irq, 571 lpass_platform_lpaif_irq, IRQF_TRIGGER_RISING, 572 "lpass-irq-lpaif", drvdata); 573 if (ret) { 574 dev_err(&pdev->dev, "%s() irq request failed: %d\n", 575 __func__, ret); 576 return ret; 577 } 578 579 580 return devm_snd_soc_register_platform(&pdev->dev, 581 &lpass_platform_driver); 582 } 583 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_platform_register); 584 585 MODULE_DESCRIPTION("QTi LPASS Platform Driver"); 586 MODULE_LICENSE("GPL v2"); 587