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-cpu.c -- ALSA SoC CPU DAI driver for QTi LPASS 14 */ 15 16 #include <linux/clk.h> 17 #include <linux/kernel.h> 18 #include <linux/module.h> 19 #include <linux/of.h> 20 #include <linux/of_device.h> 21 #include <linux/platform_device.h> 22 #include <sound/pcm.h> 23 #include <sound/pcm_params.h> 24 #include <linux/regmap.h> 25 #include <sound/soc.h> 26 #include <sound/soc-dai.h> 27 #include "lpass-lpaif-reg.h" 28 #include "lpass.h" 29 30 static int lpass_cpu_daiops_set_sysclk(struct snd_soc_dai *dai, int clk_id, 31 unsigned int freq, int dir) 32 { 33 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); 34 int ret; 35 36 if (IS_ERR(drvdata->mi2s_osr_clk[dai->driver->id])) 37 return 0; 38 39 ret = clk_set_rate(drvdata->mi2s_osr_clk[dai->driver->id], freq); 40 if (ret) 41 dev_err(dai->dev, "%s() error setting mi2s osrclk to %u: %d\n", 42 __func__, freq, ret); 43 44 return ret; 45 } 46 47 static int lpass_cpu_daiops_startup(struct snd_pcm_substream *substream, 48 struct snd_soc_dai *dai) 49 { 50 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); 51 int ret; 52 53 if (!IS_ERR(drvdata->mi2s_osr_clk[dai->driver->id])) { 54 ret = clk_prepare_enable( 55 drvdata->mi2s_osr_clk[dai->driver->id]); 56 if (ret) { 57 dev_err(dai->dev, "%s() error in enabling mi2s osr clk: %d\n", 58 __func__, ret); 59 return ret; 60 } 61 } 62 63 ret = clk_prepare_enable(drvdata->mi2s_bit_clk[dai->driver->id]); 64 if (ret) { 65 dev_err(dai->dev, "%s() error in enabling mi2s bit clk: %d\n", 66 __func__, ret); 67 if (!IS_ERR(drvdata->mi2s_osr_clk[dai->driver->id])) 68 clk_disable_unprepare( 69 drvdata->mi2s_osr_clk[dai->driver->id]); 70 return ret; 71 } 72 73 return 0; 74 } 75 76 static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream, 77 struct snd_soc_dai *dai) 78 { 79 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); 80 81 clk_disable_unprepare(drvdata->mi2s_bit_clk[dai->driver->id]); 82 83 if (!IS_ERR(drvdata->mi2s_osr_clk[dai->driver->id])) 84 clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]); 85 } 86 87 static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream, 88 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 89 { 90 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); 91 snd_pcm_format_t format = params_format(params); 92 unsigned int channels = params_channels(params); 93 unsigned int rate = params_rate(params); 94 unsigned int regval; 95 int bitwidth, ret; 96 97 bitwidth = snd_pcm_format_width(format); 98 if (bitwidth < 0) { 99 dev_err(dai->dev, "%s() invalid bit width given: %d\n", 100 __func__, bitwidth); 101 return bitwidth; 102 } 103 104 regval = LPAIF_I2SCTL_LOOPBACK_DISABLE | 105 LPAIF_I2SCTL_WSSRC_INTERNAL; 106 107 switch (bitwidth) { 108 case 16: 109 regval |= LPAIF_I2SCTL_BITWIDTH_16; 110 break; 111 case 24: 112 regval |= LPAIF_I2SCTL_BITWIDTH_24; 113 break; 114 case 32: 115 regval |= LPAIF_I2SCTL_BITWIDTH_32; 116 break; 117 default: 118 dev_err(dai->dev, "%s() invalid bitwidth given: %d\n", 119 __func__, bitwidth); 120 return -EINVAL; 121 } 122 123 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 124 switch (channels) { 125 case 1: 126 regval |= LPAIF_I2SCTL_SPKMODE_SD0; 127 regval |= LPAIF_I2SCTL_SPKMONO_MONO; 128 break; 129 case 2: 130 regval |= LPAIF_I2SCTL_SPKMODE_SD0; 131 regval |= LPAIF_I2SCTL_SPKMONO_STEREO; 132 break; 133 case 4: 134 regval |= LPAIF_I2SCTL_SPKMODE_QUAD01; 135 regval |= LPAIF_I2SCTL_SPKMONO_STEREO; 136 break; 137 case 6: 138 regval |= LPAIF_I2SCTL_SPKMODE_6CH; 139 regval |= LPAIF_I2SCTL_SPKMONO_STEREO; 140 break; 141 case 8: 142 regval |= LPAIF_I2SCTL_SPKMODE_8CH; 143 regval |= LPAIF_I2SCTL_SPKMONO_STEREO; 144 break; 145 default: 146 dev_err(dai->dev, "%s() invalid channels given: %u\n", 147 __func__, channels); 148 return -EINVAL; 149 } 150 } else { 151 switch (channels) { 152 case 1: 153 regval |= LPAIF_I2SCTL_MICMODE_SD0; 154 regval |= LPAIF_I2SCTL_MICMONO_MONO; 155 break; 156 case 2: 157 regval |= LPAIF_I2SCTL_MICMODE_SD0; 158 regval |= LPAIF_I2SCTL_MICMONO_STEREO; 159 break; 160 case 4: 161 regval |= LPAIF_I2SCTL_MICMODE_QUAD01; 162 regval |= LPAIF_I2SCTL_MICMONO_STEREO; 163 break; 164 case 6: 165 regval |= LPAIF_I2SCTL_MICMODE_6CH; 166 regval |= LPAIF_I2SCTL_MICMONO_STEREO; 167 break; 168 case 8: 169 regval |= LPAIF_I2SCTL_MICMODE_8CH; 170 regval |= LPAIF_I2SCTL_MICMONO_STEREO; 171 break; 172 default: 173 dev_err(dai->dev, "%s() invalid channels given: %u\n", 174 __func__, channels); 175 return -EINVAL; 176 } 177 } 178 179 ret = regmap_write(drvdata->lpaif_map, 180 LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id), 181 regval); 182 if (ret) { 183 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", 184 __func__, ret); 185 return ret; 186 } 187 188 ret = clk_set_rate(drvdata->mi2s_bit_clk[dai->driver->id], 189 rate * bitwidth * 2); 190 if (ret) { 191 dev_err(dai->dev, "%s() error setting mi2s bitclk to %u: %d\n", 192 __func__, rate * bitwidth * 2, ret); 193 return ret; 194 } 195 196 return 0; 197 } 198 199 static int lpass_cpu_daiops_hw_free(struct snd_pcm_substream *substream, 200 struct snd_soc_dai *dai) 201 { 202 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); 203 int ret; 204 205 ret = regmap_write(drvdata->lpaif_map, 206 LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id), 207 0); 208 if (ret) 209 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", 210 __func__, ret); 211 212 return ret; 213 } 214 215 static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream, 216 struct snd_soc_dai *dai) 217 { 218 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); 219 int ret; 220 unsigned int val, mask; 221 222 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 223 val = LPAIF_I2SCTL_SPKEN_ENABLE; 224 mask = LPAIF_I2SCTL_SPKEN_MASK; 225 } else { 226 val = LPAIF_I2SCTL_MICEN_ENABLE; 227 mask = LPAIF_I2SCTL_MICEN_MASK; 228 } 229 230 ret = regmap_update_bits(drvdata->lpaif_map, 231 LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id), 232 mask, val); 233 if (ret) 234 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", 235 __func__, ret); 236 237 return ret; 238 } 239 240 static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream, 241 int cmd, struct snd_soc_dai *dai) 242 { 243 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); 244 int ret = -EINVAL; 245 unsigned int val, mask; 246 247 switch (cmd) { 248 case SNDRV_PCM_TRIGGER_START: 249 case SNDRV_PCM_TRIGGER_RESUME: 250 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 251 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 252 val = LPAIF_I2SCTL_SPKEN_ENABLE; 253 mask = LPAIF_I2SCTL_SPKEN_MASK; 254 } else { 255 val = LPAIF_I2SCTL_MICEN_ENABLE; 256 mask = LPAIF_I2SCTL_MICEN_MASK; 257 } 258 259 ret = regmap_update_bits(drvdata->lpaif_map, 260 LPAIF_I2SCTL_REG(drvdata->variant, 261 dai->driver->id), 262 mask, val); 263 if (ret) 264 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", 265 __func__, ret); 266 break; 267 case SNDRV_PCM_TRIGGER_STOP: 268 case SNDRV_PCM_TRIGGER_SUSPEND: 269 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 270 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 271 val = LPAIF_I2SCTL_SPKEN_DISABLE; 272 mask = LPAIF_I2SCTL_SPKEN_MASK; 273 } else { 274 val = LPAIF_I2SCTL_MICEN_DISABLE; 275 mask = LPAIF_I2SCTL_MICEN_MASK; 276 } 277 278 ret = regmap_update_bits(drvdata->lpaif_map, 279 LPAIF_I2SCTL_REG(drvdata->variant, 280 dai->driver->id), 281 mask, val); 282 if (ret) 283 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", 284 __func__, ret); 285 break; 286 } 287 288 return ret; 289 } 290 291 const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops = { 292 .set_sysclk = lpass_cpu_daiops_set_sysclk, 293 .startup = lpass_cpu_daiops_startup, 294 .shutdown = lpass_cpu_daiops_shutdown, 295 .hw_params = lpass_cpu_daiops_hw_params, 296 .hw_free = lpass_cpu_daiops_hw_free, 297 .prepare = lpass_cpu_daiops_prepare, 298 .trigger = lpass_cpu_daiops_trigger, 299 }; 300 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops); 301 302 int asoc_qcom_lpass_cpu_dai_probe(struct snd_soc_dai *dai) 303 { 304 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai); 305 int ret; 306 307 /* ensure audio hardware is disabled */ 308 ret = regmap_write(drvdata->lpaif_map, 309 LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id), 0); 310 if (ret) 311 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n", 312 __func__, ret); 313 314 return ret; 315 } 316 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_probe); 317 318 static const struct snd_soc_component_driver lpass_cpu_comp_driver = { 319 .name = "lpass-cpu", 320 }; 321 322 static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg) 323 { 324 struct lpass_data *drvdata = dev_get_drvdata(dev); 325 struct lpass_variant *v = drvdata->variant; 326 int i; 327 328 for (i = 0; i < v->i2s_ports; ++i) 329 if (reg == LPAIF_I2SCTL_REG(v, i)) 330 return true; 331 332 for (i = 0; i < v->irq_ports; ++i) { 333 if (reg == LPAIF_IRQEN_REG(v, i)) 334 return true; 335 if (reg == LPAIF_IRQCLEAR_REG(v, i)) 336 return true; 337 } 338 339 for (i = 0; i < v->rdma_channels; ++i) { 340 if (reg == LPAIF_RDMACTL_REG(v, i)) 341 return true; 342 if (reg == LPAIF_RDMABASE_REG(v, i)) 343 return true; 344 if (reg == LPAIF_RDMABUFF_REG(v, i)) 345 return true; 346 if (reg == LPAIF_RDMAPER_REG(v, i)) 347 return true; 348 } 349 350 for (i = 0; i < v->wrdma_channels; ++i) { 351 if (reg == LPAIF_WRDMACTL_REG(v, i + v->wrdma_channel_start)) 352 return true; 353 if (reg == LPAIF_WRDMABASE_REG(v, i + v->wrdma_channel_start)) 354 return true; 355 if (reg == LPAIF_WRDMABUFF_REG(v, i + v->wrdma_channel_start)) 356 return true; 357 if (reg == LPAIF_WRDMAPER_REG(v, i + v->wrdma_channel_start)) 358 return true; 359 } 360 361 return false; 362 } 363 364 static bool lpass_cpu_regmap_readable(struct device *dev, unsigned int reg) 365 { 366 struct lpass_data *drvdata = dev_get_drvdata(dev); 367 struct lpass_variant *v = drvdata->variant; 368 int i; 369 370 for (i = 0; i < v->i2s_ports; ++i) 371 if (reg == LPAIF_I2SCTL_REG(v, i)) 372 return true; 373 374 for (i = 0; i < v->irq_ports; ++i) { 375 if (reg == LPAIF_IRQEN_REG(v, i)) 376 return true; 377 if (reg == LPAIF_IRQSTAT_REG(v, i)) 378 return true; 379 } 380 381 for (i = 0; i < v->rdma_channels; ++i) { 382 if (reg == LPAIF_RDMACTL_REG(v, i)) 383 return true; 384 if (reg == LPAIF_RDMABASE_REG(v, i)) 385 return true; 386 if (reg == LPAIF_RDMABUFF_REG(v, i)) 387 return true; 388 if (reg == LPAIF_RDMACURR_REG(v, i)) 389 return true; 390 if (reg == LPAIF_RDMAPER_REG(v, i)) 391 return true; 392 } 393 394 for (i = 0; i < v->wrdma_channels; ++i) { 395 if (reg == LPAIF_WRDMACTL_REG(v, i + v->wrdma_channel_start)) 396 return true; 397 if (reg == LPAIF_WRDMABASE_REG(v, i + v->wrdma_channel_start)) 398 return true; 399 if (reg == LPAIF_WRDMABUFF_REG(v, i + v->wrdma_channel_start)) 400 return true; 401 if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start)) 402 return true; 403 if (reg == LPAIF_WRDMAPER_REG(v, i + v->wrdma_channel_start)) 404 return true; 405 } 406 407 return false; 408 } 409 410 static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg) 411 { 412 struct lpass_data *drvdata = dev_get_drvdata(dev); 413 struct lpass_variant *v = drvdata->variant; 414 int i; 415 416 for (i = 0; i < v->irq_ports; ++i) 417 if (reg == LPAIF_IRQSTAT_REG(v, i)) 418 return true; 419 420 for (i = 0; i < v->rdma_channels; ++i) 421 if (reg == LPAIF_RDMACURR_REG(v, i)) 422 return true; 423 424 for (i = 0; i < v->wrdma_channels; ++i) 425 if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start)) 426 return true; 427 428 return false; 429 } 430 431 static struct regmap_config lpass_cpu_regmap_config = { 432 .reg_bits = 32, 433 .reg_stride = 4, 434 .val_bits = 32, 435 .writeable_reg = lpass_cpu_regmap_writeable, 436 .readable_reg = lpass_cpu_regmap_readable, 437 .volatile_reg = lpass_cpu_regmap_volatile, 438 .cache_type = REGCACHE_FLAT, 439 }; 440 441 int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) 442 { 443 struct lpass_data *drvdata; 444 struct device_node *dsp_of_node; 445 struct resource *res; 446 struct lpass_variant *variant; 447 struct device *dev = &pdev->dev; 448 const struct of_device_id *match; 449 char clk_name[16]; 450 int ret, i, dai_id; 451 452 dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0); 453 if (dsp_of_node) { 454 dev_err(&pdev->dev, "%s() DSP exists and holds audio resources\n", 455 __func__); 456 return -EBUSY; 457 } 458 459 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct lpass_data), 460 GFP_KERNEL); 461 if (!drvdata) 462 return -ENOMEM; 463 platform_set_drvdata(pdev, drvdata); 464 465 match = of_match_device(dev->driver->of_match_table, dev); 466 if (!match || !match->data) 467 return -EINVAL; 468 469 drvdata->variant = (struct lpass_variant *)match->data; 470 variant = drvdata->variant; 471 472 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-lpaif"); 473 474 drvdata->lpaif = devm_ioremap_resource(&pdev->dev, res); 475 if (IS_ERR((void const __force *)drvdata->lpaif)) { 476 dev_err(&pdev->dev, "%s() error mapping reg resource: %ld\n", 477 __func__, 478 PTR_ERR((void const __force *)drvdata->lpaif)); 479 return PTR_ERR((void const __force *)drvdata->lpaif); 480 } 481 482 lpass_cpu_regmap_config.max_register = LPAIF_WRDMAPER_REG(variant, 483 variant->wrdma_channels + 484 variant->wrdma_channel_start); 485 486 drvdata->lpaif_map = devm_regmap_init_mmio(&pdev->dev, drvdata->lpaif, 487 &lpass_cpu_regmap_config); 488 if (IS_ERR(drvdata->lpaif_map)) { 489 dev_err(&pdev->dev, "%s() error initializing regmap: %ld\n", 490 __func__, PTR_ERR(drvdata->lpaif_map)); 491 return PTR_ERR(drvdata->lpaif_map); 492 } 493 494 if (variant->init) 495 variant->init(pdev); 496 497 for (i = 0; i < variant->num_dai; i++) { 498 dai_id = variant->dai_driver[i].id; 499 if (variant->num_dai > 1) 500 sprintf(clk_name, "mi2s-osr-clk%d", i); 501 else 502 sprintf(clk_name, "mi2s-osr-clk"); 503 504 drvdata->mi2s_osr_clk[dai_id] = devm_clk_get(&pdev->dev, 505 clk_name); 506 if (IS_ERR(drvdata->mi2s_osr_clk[dai_id])) { 507 dev_warn(&pdev->dev, 508 "%s() error getting mi2s-osr-clk: %ld\n", 509 __func__, 510 PTR_ERR(drvdata->mi2s_osr_clk[dai_id])); 511 } 512 513 if (variant->num_dai > 1) 514 sprintf(clk_name, "mi2s-bit-clk%d", i); 515 else 516 sprintf(clk_name, "mi2s-bit-clk"); 517 518 drvdata->mi2s_bit_clk[dai_id] = devm_clk_get(&pdev->dev, 519 clk_name); 520 if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) { 521 dev_err(&pdev->dev, 522 "%s() error getting mi2s-bit-clk: %ld\n", 523 __func__, 524 PTR_ERR(drvdata->mi2s_bit_clk[dai_id])); 525 return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]); 526 } 527 } 528 529 drvdata->ahbix_clk = devm_clk_get(&pdev->dev, "ahbix-clk"); 530 if (IS_ERR(drvdata->ahbix_clk)) { 531 dev_err(&pdev->dev, "%s() error getting ahbix-clk: %ld\n", 532 __func__, PTR_ERR(drvdata->ahbix_clk)); 533 return PTR_ERR(drvdata->ahbix_clk); 534 } 535 536 ret = clk_set_rate(drvdata->ahbix_clk, LPASS_AHBIX_CLOCK_FREQUENCY); 537 if (ret) { 538 dev_err(&pdev->dev, "%s() error setting rate on ahbix_clk: %d\n", 539 __func__, ret); 540 return ret; 541 } 542 dev_dbg(&pdev->dev, "%s() set ahbix_clk rate to %lu\n", __func__, 543 clk_get_rate(drvdata->ahbix_clk)); 544 545 ret = clk_prepare_enable(drvdata->ahbix_clk); 546 if (ret) { 547 dev_err(&pdev->dev, "%s() error enabling ahbix_clk: %d\n", 548 __func__, ret); 549 return ret; 550 } 551 552 ret = devm_snd_soc_register_component(&pdev->dev, 553 &lpass_cpu_comp_driver, 554 variant->dai_driver, 555 variant->num_dai); 556 if (ret) { 557 dev_err(&pdev->dev, "%s() error registering cpu driver: %d\n", 558 __func__, ret); 559 goto err_clk; 560 } 561 562 ret = asoc_qcom_lpass_platform_register(pdev); 563 if (ret) { 564 dev_err(&pdev->dev, "%s() error registering platform driver: %d\n", 565 __func__, ret); 566 goto err_clk; 567 } 568 569 return 0; 570 571 err_clk: 572 clk_disable_unprepare(drvdata->ahbix_clk); 573 return ret; 574 } 575 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_probe); 576 577 int asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev) 578 { 579 struct lpass_data *drvdata = platform_get_drvdata(pdev); 580 581 if (drvdata->variant->exit) 582 drvdata->variant->exit(pdev); 583 584 clk_disable_unprepare(drvdata->ahbix_clk); 585 586 return 0; 587 } 588 EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_platform_remove); 589 590 MODULE_DESCRIPTION("QTi LPASS CPU Driver"); 591 MODULE_LICENSE("GPL v2"); 592