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