1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. 4 * 5 * lpass-sc7180.c -- ALSA SoC platform-machine driver for QTi LPASS 6 */ 7 8 #include <linux/module.h> 9 #include <sound/pcm.h> 10 #include <sound/soc.h> 11 #include <linux/pm.h> 12 13 #include <dt-bindings/sound/sc7180-lpass.h> 14 15 #include "lpass-lpaif-reg.h" 16 #include "lpass.h" 17 18 static struct snd_soc_dai_driver sc7280_lpass_cpu_dai_driver[] = { 19 { 20 .id = MI2S_PRIMARY, 21 .name = "Primary MI2S", 22 .playback = { 23 .stream_name = "Primary Playback", 24 .formats = SNDRV_PCM_FMTBIT_S16, 25 .rates = SNDRV_PCM_RATE_48000, 26 .rate_min = 48000, 27 .rate_max = 48000, 28 .channels_min = 2, 29 .channels_max = 2, 30 }, 31 .capture = { 32 .stream_name = "Primary Capture", 33 .formats = SNDRV_PCM_FMTBIT_S16 | 34 SNDRV_PCM_FMTBIT_S32, 35 .rates = SNDRV_PCM_RATE_48000, 36 .rate_min = 48000, 37 .rate_max = 48000, 38 .channels_min = 2, 39 .channels_max = 2, 40 }, 41 .ops = &asoc_qcom_lpass_cpu_dai_ops, 42 }, { 43 .id = MI2S_SECONDARY, 44 .name = "Secondary MI2S", 45 .playback = { 46 .stream_name = "Secondary MI2S Playback", 47 .formats = SNDRV_PCM_FMTBIT_S16, 48 .rates = SNDRV_PCM_RATE_48000, 49 .rate_min = 48000, 50 .rate_max = 48000, 51 .channels_min = 2, 52 .channels_max = 2, 53 }, 54 .ops = &asoc_qcom_lpass_cpu_dai_ops, 55 }, { 56 .id = LPASS_DP_RX, 57 .name = "Hdmi", 58 .playback = { 59 .stream_name = "DP Playback", 60 .formats = SNDRV_PCM_FMTBIT_S24, 61 .rates = SNDRV_PCM_RATE_48000, 62 .rate_min = 48000, 63 .rate_max = 48000, 64 .channels_min = 2, 65 .channels_max = 2, 66 }, 67 .ops = &asoc_qcom_lpass_hdmi_dai_ops, 68 }, { 69 .id = LPASS_CDC_DMA_RX0, 70 .name = "CDC DMA RX", 71 .playback = { 72 .stream_name = "WCD Playback", 73 .formats = SNDRV_PCM_FMTBIT_S16, 74 .rates = SNDRV_PCM_RATE_48000, 75 .rate_min = 48000, 76 .rate_max = 48000, 77 .channels_min = 2, 78 .channels_max = 2, 79 }, 80 .ops = &asoc_qcom_lpass_cdc_dma_dai_ops, 81 }, { 82 .id = LPASS_CDC_DMA_TX3, 83 .name = "CDC DMA TX", 84 .capture = { 85 .stream_name = "WCD Capture", 86 .formats = SNDRV_PCM_FMTBIT_S16, 87 .rates = SNDRV_PCM_RATE_48000, 88 .rate_min = 48000, 89 .rate_max = 48000, 90 .channels_min = 1, 91 .channels_max = 1, 92 }, 93 .ops = &asoc_qcom_lpass_cdc_dma_dai_ops, 94 }, { 95 .id = LPASS_CDC_DMA_VA_TX0, 96 .name = "CDC DMA VA", 97 .capture = { 98 .stream_name = "DMIC Capture", 99 .formats = SNDRV_PCM_FMTBIT_S16, 100 .rates = SNDRV_PCM_RATE_48000, 101 .rate_min = 48000, 102 .rate_max = 48000, 103 .channels_min = 2, 104 .channels_max = 4, 105 }, 106 .ops = &asoc_qcom_lpass_cdc_dma_dai_ops, 107 }, 108 }; 109 110 static int sc7280_lpass_alloc_dma_channel(struct lpass_data *drvdata, 111 int direction, unsigned int dai_id) 112 { 113 const struct lpass_variant *v = drvdata->variant; 114 int chan = 0; 115 116 switch (dai_id) { 117 case MI2S_PRIMARY ... MI2S_QUINARY: 118 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 119 chan = find_first_zero_bit(&drvdata->dma_ch_bit_map, 120 v->rdma_channels); 121 122 if (chan >= v->rdma_channels) 123 return -EBUSY; 124 } else { 125 chan = find_next_zero_bit(&drvdata->dma_ch_bit_map, 126 v->wrdma_channel_start + 127 v->wrdma_channels, 128 v->wrdma_channel_start); 129 130 if (chan >= v->wrdma_channel_start + v->wrdma_channels) 131 return -EBUSY; 132 } 133 set_bit(chan, &drvdata->dma_ch_bit_map); 134 break; 135 case LPASS_DP_RX: 136 chan = find_first_zero_bit(&drvdata->hdmi_dma_ch_bit_map, 137 v->hdmi_rdma_channels); 138 if (chan >= v->hdmi_rdma_channels) 139 return -EBUSY; 140 set_bit(chan, &drvdata->hdmi_dma_ch_bit_map); 141 break; 142 case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: 143 chan = find_first_zero_bit(&drvdata->rxtx_dma_ch_bit_map, 144 v->rxtx_rdma_channels); 145 if (chan >= v->rxtx_rdma_channels) 146 return -EBUSY; 147 break; 148 case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: 149 chan = find_next_zero_bit(&drvdata->rxtx_dma_ch_bit_map, 150 v->rxtx_wrdma_channel_start + 151 v->rxtx_wrdma_channels, 152 v->rxtx_wrdma_channel_start); 153 if (chan >= v->rxtx_wrdma_channel_start + v->rxtx_wrdma_channels) 154 return -EBUSY; 155 set_bit(chan, &drvdata->rxtx_dma_ch_bit_map); 156 break; 157 case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: 158 chan = find_next_zero_bit(&drvdata->va_dma_ch_bit_map, 159 v->va_wrdma_channel_start + 160 v->va_wrdma_channels, 161 v->va_wrdma_channel_start); 162 if (chan >= v->va_wrdma_channel_start + v->va_wrdma_channels) 163 return -EBUSY; 164 set_bit(chan, &drvdata->va_dma_ch_bit_map); 165 break; 166 default: 167 break; 168 } 169 170 return chan; 171 } 172 173 static int sc7280_lpass_free_dma_channel(struct lpass_data *drvdata, int chan, unsigned int dai_id) 174 { 175 switch (dai_id) { 176 case MI2S_PRIMARY ... MI2S_QUINARY: 177 clear_bit(chan, &drvdata->dma_ch_bit_map); 178 break; 179 case LPASS_DP_RX: 180 clear_bit(chan, &drvdata->hdmi_dma_ch_bit_map); 181 break; 182 case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: 183 case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: 184 clear_bit(chan, &drvdata->rxtx_dma_ch_bit_map); 185 break; 186 case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: 187 clear_bit(chan, &drvdata->va_dma_ch_bit_map); 188 break; 189 default: 190 break; 191 } 192 193 return 0; 194 } 195 196 static int sc7280_lpass_init(struct platform_device *pdev) 197 { 198 struct lpass_data *drvdata = platform_get_drvdata(pdev); 199 const struct lpass_variant *variant = drvdata->variant; 200 struct device *dev = &pdev->dev; 201 int ret, i; 202 203 drvdata->clks = devm_kcalloc(dev, variant->num_clks, 204 sizeof(*drvdata->clks), GFP_KERNEL); 205 if (!drvdata->clks) 206 return -ENOMEM; 207 208 drvdata->num_clks = variant->num_clks; 209 210 for (i = 0; i < drvdata->num_clks; i++) 211 drvdata->clks[i].id = variant->clk_name[i]; 212 213 ret = devm_clk_bulk_get(dev, drvdata->num_clks, drvdata->clks); 214 if (ret) { 215 dev_err(dev, "Failed to get clocks %d\n", ret); 216 return ret; 217 } 218 219 ret = clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks); 220 if (ret) { 221 dev_err(dev, "sc7280 clk_enable failed\n"); 222 return ret; 223 } 224 225 return 0; 226 } 227 228 static int sc7280_lpass_exit(struct platform_device *pdev) 229 { 230 struct lpass_data *drvdata = platform_get_drvdata(pdev); 231 232 clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks); 233 return 0; 234 } 235 236 static int __maybe_unused sc7280_lpass_dev_resume(struct device *dev) 237 { 238 struct lpass_data *drvdata = dev_get_drvdata(dev); 239 240 return clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks); 241 } 242 243 static int __maybe_unused sc7280_lpass_dev_suspend(struct device *dev) 244 { 245 struct lpass_data *drvdata = dev_get_drvdata(dev); 246 247 clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks); 248 return 0; 249 } 250 251 static const struct dev_pm_ops sc7280_lpass_pm_ops = { 252 SET_SYSTEM_SLEEP_PM_OPS(sc7280_lpass_dev_suspend, sc7280_lpass_dev_resume) 253 }; 254 255 static const struct lpass_variant sc7280_data = { 256 .i2sctrl_reg_base = 0x1000, 257 .i2sctrl_reg_stride = 0x1000, 258 .i2s_ports = 3, 259 .irq_reg_base = 0x9000, 260 .irq_reg_stride = 0x1000, 261 .irq_ports = 3, 262 .rdma_reg_base = 0xC000, 263 .rdma_reg_stride = 0x1000, 264 .rdma_channels = 5, 265 .rxtx_rdma_reg_base = 0xC000, 266 .rxtx_rdma_reg_stride = 0x1000, 267 .rxtx_rdma_channels = 8, 268 .hdmi_rdma_reg_base = 0x64000, 269 .hdmi_rdma_reg_stride = 0x1000, 270 .hdmi_rdma_channels = 4, 271 .dmactl_audif_start = 1, 272 .wrdma_reg_base = 0x18000, 273 .wrdma_reg_stride = 0x1000, 274 .wrdma_channel_start = 5, 275 .wrdma_channels = 4, 276 .rxtx_irq_reg_base = 0x9000, 277 .rxtx_irq_reg_stride = 0x1000, 278 .rxtx_irq_ports = 3, 279 .rxtx_wrdma_reg_base = 0x18000, 280 .rxtx_wrdma_reg_stride = 0x1000, 281 .rxtx_wrdma_channel_start = 5, 282 .rxtx_wrdma_channels = 6, 283 .va_wrdma_reg_base = 0x18000, 284 .va_wrdma_reg_stride = 0x1000, 285 .va_wrdma_channel_start = 5, 286 .va_wrdma_channels = 3, 287 .va_irq_reg_base = 0x9000, 288 .va_irq_reg_stride = 0x1000, 289 .va_irq_ports = 3, 290 291 .loopback = REG_FIELD_ID(0x1000, 17, 17, 3, 0x1000), 292 .spken = REG_FIELD_ID(0x1000, 16, 16, 3, 0x1000), 293 .spkmode = REG_FIELD_ID(0x1000, 11, 15, 3, 0x1000), 294 .spkmono = REG_FIELD_ID(0x1000, 10, 10, 3, 0x1000), 295 .micen = REG_FIELD_ID(0x1000, 9, 9, 3, 0x1000), 296 .micmode = REG_FIELD_ID(0x1000, 4, 8, 3, 0x1000), 297 .micmono = REG_FIELD_ID(0x1000, 3, 3, 3, 0x1000), 298 .wssrc = REG_FIELD_ID(0x1000, 2, 2, 3, 0x1000), 299 .bitwidth = REG_FIELD_ID(0x1000, 0, 1, 3, 0x1000), 300 301 .rdma_dyncclk = REG_FIELD_ID(0xC000, 21, 21, 5, 0x1000), 302 .rdma_bursten = REG_FIELD_ID(0xC000, 20, 20, 5, 0x1000), 303 .rdma_wpscnt = REG_FIELD_ID(0xC000, 16, 19, 5, 0x1000), 304 .rdma_intf = REG_FIELD_ID(0xC000, 12, 15, 5, 0x1000), 305 .rdma_fifowm = REG_FIELD_ID(0xC000, 1, 5, 5, 0x1000), 306 .rdma_enable = REG_FIELD_ID(0xC000, 0, 0, 5, 0x1000), 307 308 .wrdma_dyncclk = REG_FIELD_ID(0x18000, 22, 22, 4, 0x1000), 309 .wrdma_bursten = REG_FIELD_ID(0x18000, 21, 21, 4, 0x1000), 310 .wrdma_wpscnt = REG_FIELD_ID(0x18000, 17, 20, 4, 0x1000), 311 .wrdma_intf = REG_FIELD_ID(0x18000, 12, 16, 4, 0x1000), 312 .wrdma_fifowm = REG_FIELD_ID(0x18000, 1, 5, 4, 0x1000), 313 .wrdma_enable = REG_FIELD_ID(0x18000, 0, 0, 4, 0x1000), 314 315 .rxtx_rdma_enable = REG_FIELD_ID(0xC000, 0, 0, 7, 0x1000), 316 .rxtx_rdma_fifowm = REG_FIELD_ID(0xC000, 1, 11, 7, 0x1000), 317 .rxtx_rdma_intf = REG_FIELD_ID(0xC000, 12, 15, 7, 0x1000), 318 .rxtx_rdma_wpscnt = REG_FIELD_ID(0xC000, 16, 19, 7, 0x1000), 319 .rxtx_rdma_bursten = REG_FIELD_ID(0xC000, 20, 20, 7, 0x1000), 320 .rxtx_rdma_dyncclk = REG_FIELD_ID(0xC000, 21, 21, 7, 0x1000), 321 322 .rxtx_rdma_codec_ch = REG_FIELD_ID(0xC050, 0, 7, 7, 0x1000), 323 .rxtx_rdma_codec_intf = REG_FIELD_ID(0xC050, 16, 19, 7, 0x1000), 324 .rxtx_rdma_codec_fs_delay = REG_FIELD_ID(0xC050, 21, 24, 7, 0x1000), 325 .rxtx_rdma_codec_fs_sel = REG_FIELD_ID(0xC050, 25, 27, 7, 0x1000), 326 .rxtx_rdma_codec_pack = REG_FIELD_ID(0xC050, 29, 29, 5, 0x1000), 327 .rxtx_rdma_codec_enable = REG_FIELD_ID(0xC050, 30, 30, 7, 0x1000), 328 329 .rxtx_wrdma_enable = REG_FIELD_ID(0x18000, 0, 0, 5, 0x1000), 330 .rxtx_wrdma_fifowm = REG_FIELD_ID(0x18000, 1, 11, 5, 0x1000), 331 .rxtx_wrdma_intf = REG_FIELD_ID(0x18000, 12, 16, 5, 0x1000), 332 .rxtx_wrdma_wpscnt = REG_FIELD_ID(0x18000, 17, 20, 5, 0x1000), 333 .rxtx_wrdma_bursten = REG_FIELD_ID(0x18000, 21, 21, 5, 0x1000), 334 .rxtx_wrdma_dyncclk = REG_FIELD_ID(0x18000, 22, 22, 5, 0x1000), 335 336 .rxtx_wrdma_codec_ch = REG_FIELD_ID(0x18050, 0, 7, 5, 0x1000), 337 .rxtx_wrdma_codec_intf = REG_FIELD_ID(0x18050, 16, 19, 5, 0x1000), 338 .rxtx_wrdma_codec_fs_delay = REG_FIELD_ID(0x18050, 21, 24, 5, 0x1000), 339 .rxtx_wrdma_codec_fs_sel = REG_FIELD_ID(0x18050, 25, 27, 5, 0x1000), 340 .rxtx_wrdma_codec_pack = REG_FIELD_ID(0x18050, 29, 29, 5, 0x1000), 341 .rxtx_wrdma_codec_enable = REG_FIELD_ID(0x18050, 30, 30, 5, 0x1000), 342 343 .va_wrdma_enable = REG_FIELD_ID(0x18000, 0, 0, 5, 0x1000), 344 .va_wrdma_fifowm = REG_FIELD_ID(0x18000, 1, 11, 5, 0x1000), 345 .va_wrdma_intf = REG_FIELD_ID(0x18000, 12, 16, 5, 0x1000), 346 .va_wrdma_wpscnt = REG_FIELD_ID(0x18000, 17, 20, 5, 0x1000), 347 .va_wrdma_bursten = REG_FIELD_ID(0x18000, 21, 21, 5, 0x1000), 348 .va_wrdma_dyncclk = REG_FIELD_ID(0x18000, 22, 22, 5, 0x1000), 349 350 .va_wrdma_codec_ch = REG_FIELD_ID(0x18050, 0, 7, 5, 0x1000), 351 .va_wrdma_codec_intf = REG_FIELD_ID(0x18050, 16, 19, 5, 0x1000), 352 .va_wrdma_codec_fs_delay = REG_FIELD_ID(0x18050, 21, 24, 5, 0x1000), 353 .va_wrdma_codec_fs_sel = REG_FIELD_ID(0x18050, 25, 27, 5, 0x1000), 354 .va_wrdma_codec_pack = REG_FIELD_ID(0x18050, 29, 29, 5, 0x1000), 355 .va_wrdma_codec_enable = REG_FIELD_ID(0x18050, 30, 30, 5, 0x1000), 356 357 .hdmi_tx_ctl_addr = 0x1000, 358 .hdmi_legacy_addr = 0x1008, 359 .hdmi_vbit_addr = 0x610c0, 360 .hdmi_ch_lsb_addr = 0x61048, 361 .hdmi_ch_msb_addr = 0x6104c, 362 .ch_stride = 0x8, 363 .hdmi_parity_addr = 0x61034, 364 .hdmi_dmactl_addr = 0x61038, 365 .hdmi_dma_stride = 0x4, 366 .hdmi_DP_addr = 0x610c8, 367 .hdmi_sstream_addr = 0x6101c, 368 .hdmi_irq_reg_base = 0x63000, 369 .hdmi_irq_ports = 1, 370 371 .hdmi_rdma_dyncclk = REG_FIELD_ID(0x64000, 14, 14, 4, 0x1000), 372 .hdmi_rdma_bursten = REG_FIELD_ID(0x64000, 13, 13, 4, 0x1000), 373 .hdmi_rdma_burst8 = REG_FIELD_ID(0x64000, 15, 15, 4, 0x1000), 374 .hdmi_rdma_burst16 = REG_FIELD_ID(0x64000, 16, 16, 4, 0x1000), 375 .hdmi_rdma_dynburst = REG_FIELD_ID(0x64000, 18, 18, 4, 0x1000), 376 .hdmi_rdma_wpscnt = REG_FIELD_ID(0x64000, 10, 12, 4, 0x1000), 377 .hdmi_rdma_fifowm = REG_FIELD_ID(0x64000, 1, 5, 4, 0x1000), 378 .hdmi_rdma_enable = REG_FIELD_ID(0x64000, 0, 0, 4, 0x1000), 379 380 .sstream_en = REG_FIELD(0x6101c, 0, 0), 381 .dma_sel = REG_FIELD(0x6101c, 1, 2), 382 .auto_bbit_en = REG_FIELD(0x6101c, 3, 3), 383 .layout = REG_FIELD(0x6101c, 4, 4), 384 .layout_sp = REG_FIELD(0x6101c, 5, 8), 385 .set_sp_on_en = REG_FIELD(0x6101c, 10, 10), 386 .dp_audio = REG_FIELD(0x6101c, 11, 11), 387 .dp_staffing_en = REG_FIELD(0x6101c, 12, 12), 388 .dp_sp_b_hw_en = REG_FIELD(0x6101c, 13, 13), 389 390 .mute = REG_FIELD(0x610c8, 0, 0), 391 .as_sdp_cc = REG_FIELD(0x610c8, 1, 3), 392 .as_sdp_ct = REG_FIELD(0x610c8, 4, 7), 393 .aif_db4 = REG_FIELD(0x610c8, 8, 15), 394 .frequency = REG_FIELD(0x610c8, 16, 21), 395 .mst_index = REG_FIELD(0x610c8, 28, 29), 396 .dptx_index = REG_FIELD(0x610c8, 30, 31), 397 398 .soft_reset = REG_FIELD(0x1000, 31, 31), 399 .force_reset = REG_FIELD(0x1000, 30, 30), 400 401 .use_hw_chs = REG_FIELD(0x61038, 0, 0), 402 .use_hw_usr = REG_FIELD(0x61038, 1, 1), 403 .hw_chs_sel = REG_FIELD(0x61038, 2, 4), 404 .hw_usr_sel = REG_FIELD(0x61038, 5, 6), 405 406 .replace_vbit = REG_FIELD(0x610c0, 0, 0), 407 .vbit_stream = REG_FIELD(0x610c0, 1, 1), 408 409 .legacy_en = REG_FIELD(0x1008, 0, 0), 410 .calc_en = REG_FIELD(0x61034, 0, 0), 411 .lsb_bits = REG_FIELD(0x61048, 0, 31), 412 .msb_bits = REG_FIELD(0x6104c, 0, 31), 413 414 .clk_name = (const char*[]) { 415 "core_cc_sysnoc_mport_core" 416 }, 417 .num_clks = 1, 418 419 .dai_driver = sc7280_lpass_cpu_dai_driver, 420 .num_dai = ARRAY_SIZE(sc7280_lpass_cpu_dai_driver), 421 .dai_osr_clk_names = (const char *[]) { 422 "audio_cc_ext_mclk0", 423 "null" 424 }, 425 .dai_bit_clk_names = (const char *[]) { 426 "core_cc_ext_if0_ibit", 427 "core_cc_ext_if1_ibit" 428 }, 429 .init = sc7280_lpass_init, 430 .exit = sc7280_lpass_exit, 431 .alloc_dma_channel = sc7280_lpass_alloc_dma_channel, 432 .free_dma_channel = sc7280_lpass_free_dma_channel, 433 }; 434 435 static const struct of_device_id sc7280_lpass_cpu_device_id[] = { 436 {.compatible = "qcom,sc7280-lpass-cpu", .data = &sc7280_data}, 437 {} 438 }; 439 MODULE_DEVICE_TABLE(of, sc7280_lpass_cpu_device_id); 440 441 static struct platform_driver sc7280_lpass_cpu_platform_driver = { 442 .driver = { 443 .name = "sc7280-lpass-cpu", 444 .of_match_table = of_match_ptr(sc7280_lpass_cpu_device_id), 445 .pm = &sc7280_lpass_pm_ops, 446 }, 447 .probe = asoc_qcom_lpass_cpu_platform_probe, 448 .remove_new = asoc_qcom_lpass_cpu_platform_remove, 449 .shutdown = asoc_qcom_lpass_cpu_platform_shutdown, 450 }; 451 452 module_platform_driver(sc7280_lpass_cpu_platform_driver); 453 454 MODULE_DESCRIPTION("SC7280 LPASS CPU DRIVER"); 455 MODULE_LICENSE("GPL"); 456
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.