1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
5 * lpass-sc7180.c -- ALSA SoC platform-machine driver for QTi LPASS
8 #include <linux/module.h>
10 #include <sound/soc.h>
13 #include <dt-bindings/sound/sc7180-lpass.h>
15 #include "lpass-lpaif-reg.h"
18 static struct snd_soc_dai_driver sc7280_lpass_cpu_dai_driver
[] = {
21 .name
= "Primary MI2S",
23 .stream_name
= "Primary Playback",
24 .formats
= SNDRV_PCM_FMTBIT_S16
,
25 .rates
= SNDRV_PCM_RATE_48000
,
32 .stream_name
= "Primary Capture",
33 .formats
= SNDRV_PCM_FMTBIT_S16
|
35 .rates
= SNDRV_PCM_RATE_48000
,
41 .ops
= &asoc_qcom_lpass_cpu_dai_ops
,
44 .name
= "Secondary MI2S",
46 .stream_name
= "Secondary MI2S Playback",
47 .formats
= SNDRV_PCM_FMTBIT_S16
,
48 .rates
= SNDRV_PCM_RATE_48000
,
54 .ops
= &asoc_qcom_lpass_cpu_dai_ops
,
59 .stream_name
= "DP Playback",
60 .formats
= SNDRV_PCM_FMTBIT_S24
,
61 .rates
= SNDRV_PCM_RATE_48000
,
67 .ops
= &asoc_qcom_lpass_hdmi_dai_ops
,
69 .id
= LPASS_CDC_DMA_RX0
,
72 .stream_name
= "WCD Playback",
73 .formats
= SNDRV_PCM_FMTBIT_S16
,
74 .rates
= SNDRV_PCM_RATE_48000
,
80 .ops
= &asoc_qcom_lpass_cdc_dma_dai_ops
,
82 .id
= LPASS_CDC_DMA_TX3
,
85 .stream_name
= "WCD Capture",
86 .formats
= SNDRV_PCM_FMTBIT_S16
,
87 .rates
= SNDRV_PCM_RATE_48000
,
93 .ops
= &asoc_qcom_lpass_cdc_dma_dai_ops
,
95 .id
= LPASS_CDC_DMA_VA_TX0
,
98 .stream_name
= "DMIC Capture",
99 .formats
= SNDRV_PCM_FMTBIT_S16
,
100 .rates
= SNDRV_PCM_RATE_48000
,
106 .ops
= &asoc_qcom_lpass_cdc_dma_dai_ops
,
110 static int sc7280_lpass_alloc_dma_channel(struct lpass_data
*drvdata
,
111 int direction
, unsigned int dai_id
)
113 const struct lpass_variant
*v
= drvdata
->variant
;
117 case MI2S_PRIMARY
... MI2S_QUINARY
:
118 if (direction
== SNDRV_PCM_STREAM_PLAYBACK
) {
119 chan
= find_first_zero_bit(&drvdata
->dma_ch_bit_map
,
122 if (chan
>= v
->rdma_channels
)
125 chan
= find_next_zero_bit(&drvdata
->dma_ch_bit_map
,
126 v
->wrdma_channel_start
+
128 v
->wrdma_channel_start
);
130 if (chan
>= v
->wrdma_channel_start
+ v
->wrdma_channels
)
133 set_bit(chan
, &drvdata
->dma_ch_bit_map
);
136 chan
= find_first_zero_bit(&drvdata
->hdmi_dma_ch_bit_map
,
137 v
->hdmi_rdma_channels
);
138 if (chan
>= v
->hdmi_rdma_channels
)
140 set_bit(chan
, &drvdata
->hdmi_dma_ch_bit_map
);
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
)
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
)
155 set_bit(chan
, &drvdata
->rxtx_dma_ch_bit_map
);
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
)
164 set_bit(chan
, &drvdata
->va_dma_ch_bit_map
);
173 static int sc7280_lpass_free_dma_channel(struct lpass_data
*drvdata
, int chan
, unsigned int dai_id
)
176 case MI2S_PRIMARY
... MI2S_QUINARY
:
177 clear_bit(chan
, &drvdata
->dma_ch_bit_map
);
180 clear_bit(chan
, &drvdata
->hdmi_dma_ch_bit_map
);
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
);
186 case LPASS_CDC_DMA_VA_TX0
... LPASS_CDC_DMA_VA_TX8
:
187 clear_bit(chan
, &drvdata
->va_dma_ch_bit_map
);
196 static int sc7280_lpass_init(struct platform_device
*pdev
)
198 struct lpass_data
*drvdata
= platform_get_drvdata(pdev
);
199 const struct lpass_variant
*variant
= drvdata
->variant
;
200 struct device
*dev
= &pdev
->dev
;
203 drvdata
->clks
= devm_kcalloc(dev
, variant
->num_clks
,
204 sizeof(*drvdata
->clks
), GFP_KERNEL
);
208 drvdata
->num_clks
= variant
->num_clks
;
210 for (i
= 0; i
< drvdata
->num_clks
; i
++)
211 drvdata
->clks
[i
].id
= variant
->clk_name
[i
];
213 ret
= devm_clk_bulk_get(dev
, drvdata
->num_clks
, drvdata
->clks
);
215 dev_err(dev
, "Failed to get clocks %d\n", ret
);
219 ret
= clk_bulk_prepare_enable(drvdata
->num_clks
, drvdata
->clks
);
221 dev_err(dev
, "sc7280 clk_enable failed\n");
228 static int sc7280_lpass_exit(struct platform_device
*pdev
)
230 struct lpass_data
*drvdata
= platform_get_drvdata(pdev
);
232 clk_bulk_disable_unprepare(drvdata
->num_clks
, drvdata
->clks
);
236 static int __maybe_unused
sc7280_lpass_dev_resume(struct device
*dev
)
238 struct lpass_data
*drvdata
= dev_get_drvdata(dev
);
240 return clk_bulk_prepare_enable(drvdata
->num_clks
, drvdata
->clks
);
243 static int __maybe_unused
sc7280_lpass_dev_suspend(struct device
*dev
)
245 struct lpass_data
*drvdata
= dev_get_drvdata(dev
);
247 clk_bulk_disable_unprepare(drvdata
->num_clks
, drvdata
->clks
);
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
)
255 static const struct lpass_variant sc7280_data
= {
256 .i2sctrl_reg_base
= 0x1000,
257 .i2sctrl_reg_stride
= 0x1000,
259 .irq_reg_base
= 0x9000,
260 .irq_reg_stride
= 0x1000,
262 .rdma_reg_base
= 0xC000,
263 .rdma_reg_stride
= 0x1000,
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,
276 .rxtx_irq_reg_base
= 0x9000,
277 .rxtx_irq_reg_stride
= 0x1000,
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,
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),
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),
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),
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),
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),
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),
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),
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),
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),
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,
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,
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),
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),
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),
398 .soft_reset
= REG_FIELD(0x1000, 31, 31),
399 .force_reset
= REG_FIELD(0x1000, 30, 30),
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),
406 .replace_vbit
= REG_FIELD(0x610c0, 0, 0),
407 .vbit_stream
= REG_FIELD(0x610c0, 1, 1),
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),
414 .clk_name
= (const char*[]) {
415 "core_cc_sysnoc_mport_core"
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",
425 .dai_bit_clk_names
= (const char *[]) {
426 "core_cc_ext_if0_ibit",
427 "core_cc_ext_if1_ibit"
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
,
435 static const struct of_device_id sc7280_lpass_cpu_device_id
[] = {
436 {.compatible
= "qcom,sc7280-lpass-cpu", .data
= &sc7280_data
},
439 MODULE_DEVICE_TABLE(of
, sc7280_lpass_cpu_device_id
);
441 static struct platform_driver sc7280_lpass_cpu_platform_driver
= {
443 .name
= "sc7280-lpass-cpu",
444 .of_match_table
= of_match_ptr(sc7280_lpass_cpu_device_id
),
445 .pm
= &sc7280_lpass_pm_ops
,
447 .probe
= asoc_qcom_lpass_cpu_platform_probe
,
448 .remove
= asoc_qcom_lpass_cpu_platform_remove
,
449 .shutdown
= asoc_qcom_lpass_cpu_platform_shutdown
,
452 module_platform_driver(sc7280_lpass_cpu_platform_driver
);
454 MODULE_DESCRIPTION("SC7280 LPASS CPU DRIVER");
455 MODULE_LICENSE("GPL");