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/compiler.h> 17 #include <linux/device.h> 18 #include <linux/dma-mapping.h> 19 #include <linux/err.h> 20 #include <linux/export.h> 21 #include <linux/kernel.h> 22 #include <linux/module.h> 23 #include <linux/io.h> 24 #include <linux/platform_device.h> 25 #include <sound/memalloc.h> 26 #include <sound/pcm.h> 27 #include <sound/pcm_params.h> 28 #include <linux/regmap.h> 29 #include <sound/soc.h> 30 #include "lpass-lpaif-ipq806x.h" 31 #include "lpass.h" 32 33 #define LPASS_PLATFORM_BUFFER_SIZE (16 * 1024) 34 #define LPASS_PLATFORM_PERIODS 2 35 36 static struct snd_pcm_hardware lpass_platform_pcm_hardware = { 37 .info = SNDRV_PCM_INFO_MMAP | 38 SNDRV_PCM_INFO_MMAP_VALID | 39 SNDRV_PCM_INFO_INTERLEAVED | 40 SNDRV_PCM_INFO_PAUSE | 41 SNDRV_PCM_INFO_RESUME, 42 .formats = SNDRV_PCM_FMTBIT_S16 | 43 SNDRV_PCM_FMTBIT_S24 | 44 SNDRV_PCM_FMTBIT_S32, 45 .rates = SNDRV_PCM_RATE_8000_192000, 46 .rate_min = 8000, 47 .rate_max = 192000, 48 .channels_min = 1, 49 .channels_max = 8, 50 .buffer_bytes_max = LPASS_PLATFORM_BUFFER_SIZE, 51 .period_bytes_max = LPASS_PLATFORM_BUFFER_SIZE / 52 LPASS_PLATFORM_PERIODS, 53 .period_bytes_min = LPASS_PLATFORM_BUFFER_SIZE / 54 LPASS_PLATFORM_PERIODS, 55 .periods_min = LPASS_PLATFORM_PERIODS, 56 .periods_max = LPASS_PLATFORM_PERIODS, 57 .fifo_size = 0, 58 }; 59 60 static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream) 61 { 62 struct snd_pcm_runtime *runtime = substream->runtime; 63 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 64 int ret; 65 66 snd_soc_set_runtime_hwparams(substream, &lpass_platform_pcm_hardware); 67 68 runtime->dma_bytes = lpass_platform_pcm_hardware.buffer_bytes_max; 69 70 ret = snd_pcm_hw_constraint_integer(runtime, 71 SNDRV_PCM_HW_PARAM_PERIODS); 72 if (ret < 0) { 73 dev_err(soc_runtime->dev, "%s() setting constraints failed: %d\n", 74 __func__, ret); 75 return -EINVAL; 76 } 77 78 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 79 80 return 0; 81 } 82 83 static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream, 84 struct snd_pcm_hw_params *params) 85 { 86 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 87 struct lpass_data *drvdata = 88 snd_soc_platform_get_drvdata(soc_runtime->platform); 89 snd_pcm_format_t format = params_format(params); 90 unsigned int channels = params_channels(params); 91 unsigned int regval; 92 int bitwidth; 93 int ret; 94 95 bitwidth = snd_pcm_format_width(format); 96 if (bitwidth < 0) { 97 dev_err(soc_runtime->dev, "%s() invalid bit width given: %d\n", 98 __func__, bitwidth); 99 return bitwidth; 100 } 101 102 regval = LPAIF_RDMACTL_BURSTEN_INCR4 | 103 LPAIF_RDMACTL_AUDINTF_MI2S | 104 LPAIF_RDMACTL_FIFOWM_8; 105 106 switch (bitwidth) { 107 case 16: 108 switch (channels) { 109 case 1: 110 case 2: 111 regval |= LPAIF_RDMACTL_WPSCNT_ONE; 112 break; 113 case 4: 114 regval |= LPAIF_RDMACTL_WPSCNT_TWO; 115 break; 116 case 6: 117 regval |= LPAIF_RDMACTL_WPSCNT_THREE; 118 break; 119 case 8: 120 regval |= LPAIF_RDMACTL_WPSCNT_FOUR; 121 break; 122 default: 123 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n", 124 __func__, bitwidth, channels); 125 return -EINVAL; 126 } 127 break; 128 case 24: 129 case 32: 130 switch (channels) { 131 case 1: 132 regval |= LPAIF_RDMACTL_WPSCNT_ONE; 133 break; 134 case 2: 135 regval |= LPAIF_RDMACTL_WPSCNT_TWO; 136 break; 137 case 4: 138 regval |= LPAIF_RDMACTL_WPSCNT_FOUR; 139 break; 140 case 6: 141 regval |= LPAIF_RDMACTL_WPSCNT_SIX; 142 break; 143 case 8: 144 regval |= LPAIF_RDMACTL_WPSCNT_EIGHT; 145 break; 146 default: 147 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n", 148 __func__, bitwidth, channels); 149 return -EINVAL; 150 } 151 break; 152 default: 153 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n", 154 __func__, bitwidth, channels); 155 return -EINVAL; 156 } 157 158 ret = regmap_write(drvdata->lpaif_map, 159 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), regval); 160 if (ret) { 161 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", 162 __func__, ret); 163 return ret; 164 } 165 166 return 0; 167 } 168 169 static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream) 170 { 171 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 172 struct lpass_data *drvdata = 173 snd_soc_platform_get_drvdata(soc_runtime->platform); 174 int ret; 175 176 ret = regmap_write(drvdata->lpaif_map, 177 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), 0); 178 if (ret) 179 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", 180 __func__, ret); 181 182 return ret; 183 } 184 185 static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream) 186 { 187 struct snd_pcm_runtime *runtime = substream->runtime; 188 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 189 struct lpass_data *drvdata = 190 snd_soc_platform_get_drvdata(soc_runtime->platform); 191 int ret; 192 193 ret = regmap_write(drvdata->lpaif_map, 194 LPAIF_RDMABASE_REG(LPAIF_RDMA_CHAN_MI2S), 195 runtime->dma_addr); 196 if (ret) { 197 dev_err(soc_runtime->dev, "%s() error writing to rdmabase reg: %d\n", 198 __func__, ret); 199 return ret; 200 } 201 202 ret = regmap_write(drvdata->lpaif_map, 203 LPAIF_RDMABUFF_REG(LPAIF_RDMA_CHAN_MI2S), 204 (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1); 205 if (ret) { 206 dev_err(soc_runtime->dev, "%s() error writing to rdmabuff reg: %d\n", 207 __func__, ret); 208 return ret; 209 } 210 211 ret = regmap_write(drvdata->lpaif_map, 212 LPAIF_RDMAPER_REG(LPAIF_RDMA_CHAN_MI2S), 213 (snd_pcm_lib_period_bytes(substream) >> 2) - 1); 214 if (ret) { 215 dev_err(soc_runtime->dev, "%s() error writing to rdmaper reg: %d\n", 216 __func__, ret); 217 return ret; 218 } 219 220 ret = regmap_update_bits(drvdata->lpaif_map, 221 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), 222 LPAIF_RDMACTL_ENABLE_MASK, LPAIF_RDMACTL_ENABLE_ON); 223 if (ret) { 224 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", 225 __func__, ret); 226 return ret; 227 } 228 229 return 0; 230 } 231 232 static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream, 233 int cmd) 234 { 235 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 236 struct lpass_data *drvdata = 237 snd_soc_platform_get_drvdata(soc_runtime->platform); 238 int ret; 239 240 switch (cmd) { 241 case SNDRV_PCM_TRIGGER_START: 242 case SNDRV_PCM_TRIGGER_RESUME: 243 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 244 /* clear status before enabling interrupts */ 245 ret = regmap_write(drvdata->lpaif_map, 246 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST), 247 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S)); 248 if (ret) { 249 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n", 250 __func__, ret); 251 return ret; 252 } 253 254 ret = regmap_update_bits(drvdata->lpaif_map, 255 LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST), 256 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S), 257 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S)); 258 if (ret) { 259 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n", 260 __func__, ret); 261 return ret; 262 } 263 264 ret = regmap_update_bits(drvdata->lpaif_map, 265 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), 266 LPAIF_RDMACTL_ENABLE_MASK, 267 LPAIF_RDMACTL_ENABLE_ON); 268 if (ret) { 269 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", 270 __func__, ret); 271 return ret; 272 } 273 break; 274 case SNDRV_PCM_TRIGGER_STOP: 275 case SNDRV_PCM_TRIGGER_SUSPEND: 276 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 277 ret = regmap_update_bits(drvdata->lpaif_map, 278 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), 279 LPAIF_RDMACTL_ENABLE_MASK, 280 LPAIF_RDMACTL_ENABLE_OFF); 281 if (ret) { 282 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", 283 __func__, ret); 284 return ret; 285 } 286 287 ret = regmap_update_bits(drvdata->lpaif_map, 288 LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST), 289 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S), 0); 290 if (ret) { 291 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n", 292 __func__, ret); 293 return ret; 294 } 295 break; 296 } 297 298 return 0; 299 } 300 301 static snd_pcm_uframes_t lpass_platform_pcmops_pointer( 302 struct snd_pcm_substream *substream) 303 { 304 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 305 struct lpass_data *drvdata = 306 snd_soc_platform_get_drvdata(soc_runtime->platform); 307 unsigned int base_addr, curr_addr; 308 int ret; 309 310 ret = regmap_read(drvdata->lpaif_map, 311 LPAIF_RDMABASE_REG(LPAIF_RDMA_CHAN_MI2S), &base_addr); 312 if (ret) { 313 dev_err(soc_runtime->dev, "%s() error reading from rdmabase reg: %d\n", 314 __func__, ret); 315 return ret; 316 } 317 318 ret = regmap_read(drvdata->lpaif_map, 319 LPAIF_RDMACURR_REG(LPAIF_RDMA_CHAN_MI2S), &curr_addr); 320 if (ret) { 321 dev_err(soc_runtime->dev, "%s() error reading from rdmacurr reg: %d\n", 322 __func__, ret); 323 return ret; 324 } 325 326 return bytes_to_frames(substream->runtime, curr_addr - base_addr); 327 } 328 329 static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream, 330 struct vm_area_struct *vma) 331 { 332 struct snd_pcm_runtime *runtime = substream->runtime; 333 334 return dma_mmap_coherent(substream->pcm->card->dev, vma, 335 runtime->dma_area, runtime->dma_addr, 336 runtime->dma_bytes); 337 } 338 339 static struct snd_pcm_ops lpass_platform_pcm_ops = { 340 .open = lpass_platform_pcmops_open, 341 .ioctl = snd_pcm_lib_ioctl, 342 .hw_params = lpass_platform_pcmops_hw_params, 343 .hw_free = lpass_platform_pcmops_hw_free, 344 .prepare = lpass_platform_pcmops_prepare, 345 .trigger = lpass_platform_pcmops_trigger, 346 .pointer = lpass_platform_pcmops_pointer, 347 .mmap = lpass_platform_pcmops_mmap, 348 }; 349 350 static irqreturn_t lpass_platform_lpaif_irq(int irq, void *data) 351 { 352 struct snd_pcm_substream *substream = data; 353 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 354 struct lpass_data *drvdata = 355 snd_soc_platform_get_drvdata(soc_runtime->platform); 356 unsigned int interrupts; 357 irqreturn_t ret = IRQ_NONE; 358 int rv; 359 360 rv = regmap_read(drvdata->lpaif_map, 361 LPAIF_IRQSTAT_REG(LPAIF_IRQ_PORT_HOST), &interrupts); 362 if (rv) { 363 dev_err(soc_runtime->dev, "%s() error reading from irqstat reg: %d\n", 364 __func__, rv); 365 return IRQ_NONE; 366 } 367 interrupts &= LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S); 368 369 if (interrupts & LPAIF_IRQ_PER(LPAIF_RDMA_CHAN_MI2S)) { 370 rv = regmap_write(drvdata->lpaif_map, 371 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST), 372 LPAIF_IRQ_PER(LPAIF_RDMA_CHAN_MI2S)); 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(LPAIF_RDMA_CHAN_MI2S)) { 383 rv = regmap_write(drvdata->lpaif_map, 384 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST), 385 LPAIF_IRQ_XRUN(LPAIF_RDMA_CHAN_MI2S)); 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(LPAIF_RDMA_CHAN_MI2S)) { 397 rv = regmap_write(drvdata->lpaif_map, 398 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST), 399 LPAIF_IRQ_ERR(LPAIF_RDMA_CHAN_MI2S)); 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 int lpass_platform_alloc_buffer(struct snd_pcm_substream *substream, 414 struct snd_soc_pcm_runtime *soc_runtime) 415 { 416 struct snd_dma_buffer *buf = &substream->dma_buffer; 417 size_t size = lpass_platform_pcm_hardware.buffer_bytes_max; 418 419 buf->dev.type = SNDRV_DMA_TYPE_DEV; 420 buf->dev.dev = soc_runtime->dev; 421 buf->private_data = NULL; 422 buf->area = dma_alloc_coherent(soc_runtime->dev, size, &buf->addr, 423 GFP_KERNEL); 424 if (!buf->area) { 425 dev_err(soc_runtime->dev, "%s: Could not allocate DMA buffer\n", 426 __func__); 427 return -ENOMEM; 428 } 429 buf->bytes = size; 430 431 return 0; 432 } 433 434 static void lpass_platform_free_buffer(struct snd_pcm_substream *substream, 435 struct snd_soc_pcm_runtime *soc_runtime) 436 { 437 struct snd_dma_buffer *buf = &substream->dma_buffer; 438 439 if (buf->area) { 440 dma_free_coherent(soc_runtime->dev, buf->bytes, buf->area, 441 buf->addr); 442 } 443 buf->area = NULL; 444 } 445 446 static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime) 447 { 448 struct snd_pcm *pcm = soc_runtime->pcm; 449 struct snd_pcm_substream *substream = 450 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 451 struct lpass_data *drvdata = 452 snd_soc_platform_get_drvdata(soc_runtime->platform); 453 int ret; 454 455 soc_runtime->dev->coherent_dma_mask = DMA_BIT_MASK(32); 456 soc_runtime->dev->dma_mask = &soc_runtime->dev->coherent_dma_mask; 457 458 ret = lpass_platform_alloc_buffer(substream, soc_runtime); 459 if (ret) 460 return ret; 461 462 ret = devm_request_irq(soc_runtime->dev, drvdata->lpaif_irq, 463 lpass_platform_lpaif_irq, IRQF_TRIGGER_RISING, 464 "lpass-irq-lpaif", substream); 465 if (ret) { 466 dev_err(soc_runtime->dev, "%s() irq request failed: %d\n", 467 __func__, ret); 468 goto err_buf; 469 } 470 471 /* ensure audio hardware is disabled */ 472 ret = regmap_write(drvdata->lpaif_map, 473 LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST), 0); 474 if (ret) { 475 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n", 476 __func__, ret); 477 return ret; 478 } 479 ret = regmap_write(drvdata->lpaif_map, 480 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), 0); 481 if (ret) { 482 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n", 483 __func__, ret); 484 return ret; 485 } 486 487 return 0; 488 489 err_buf: 490 lpass_platform_free_buffer(substream, soc_runtime); 491 return ret; 492 } 493 494 static void lpass_platform_pcm_free(struct snd_pcm *pcm) 495 { 496 struct snd_pcm_substream *substream = 497 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 498 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; 499 500 lpass_platform_free_buffer(substream, soc_runtime); 501 } 502 503 static struct snd_soc_platform_driver lpass_platform_driver = { 504 .pcm_new = lpass_platform_pcm_new, 505 .pcm_free = lpass_platform_pcm_free, 506 .ops = &lpass_platform_pcm_ops, 507 }; 508 509 int asoc_qcom_lpass_platform_register(struct platform_device *pdev) 510 { 511 struct lpass_data *drvdata = platform_get_drvdata(pdev); 512 513 drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif"); 514 if (drvdata->lpaif_irq < 0) { 515 dev_err(&pdev->dev, "%s() error getting irq handle: %d\n", 516 __func__, drvdata->lpaif_irq); 517 return -ENODEV; 518 } 519 520 return devm_snd_soc_register_platform(&pdev->dev, 521 &lpass_platform_driver); 522 } 523 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_platform_register); 524 525 MODULE_DESCRIPTION("QTi LPASS Platform Driver"); 526 MODULE_LICENSE("GPL v2"); 527