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(addr: &drvdata->dma_ch_bit_map, |
120 | size: v->rdma_channels); |
121 | |
122 | if (chan >= v->rdma_channels) |
123 | return -EBUSY; |
124 | } else { |
125 | chan = find_next_zero_bit(addr: &drvdata->dma_ch_bit_map, |
126 | size: v->wrdma_channel_start + |
127 | v->wrdma_channels, |
128 | offset: v->wrdma_channel_start); |
129 | |
130 | if (chan >= v->wrdma_channel_start + v->wrdma_channels) |
131 | return -EBUSY; |
132 | } |
133 | set_bit(nr: chan, addr: &drvdata->dma_ch_bit_map); |
134 | break; |
135 | case LPASS_DP_RX: |
136 | chan = find_first_zero_bit(addr: &drvdata->hdmi_dma_ch_bit_map, |
137 | size: v->hdmi_rdma_channels); |
138 | if (chan >= v->hdmi_rdma_channels) |
139 | return -EBUSY; |
140 | set_bit(nr: chan, addr: &drvdata->hdmi_dma_ch_bit_map); |
141 | break; |
142 | case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: |
143 | chan = find_first_zero_bit(addr: &drvdata->rxtx_dma_ch_bit_map, |
144 | size: 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(addr: &drvdata->rxtx_dma_ch_bit_map, |
150 | size: v->rxtx_wrdma_channel_start + |
151 | v->rxtx_wrdma_channels, |
152 | offset: v->rxtx_wrdma_channel_start); |
153 | if (chan >= v->rxtx_wrdma_channel_start + v->rxtx_wrdma_channels) |
154 | return -EBUSY; |
155 | set_bit(nr: chan, addr: &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(addr: &drvdata->va_dma_ch_bit_map, |
159 | size: v->va_wrdma_channel_start + |
160 | v->va_wrdma_channels, |
161 | offset: v->va_wrdma_channel_start); |
162 | if (chan >= v->va_wrdma_channel_start + v->va_wrdma_channels) |
163 | return -EBUSY; |
164 | set_bit(nr: chan, addr: &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(nr: chan, addr: &drvdata->dma_ch_bit_map); |
178 | break; |
179 | case LPASS_DP_RX: |
180 | clear_bit(nr: chan, addr: &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(nr: chan, addr: &drvdata->rxtx_dma_ch_bit_map); |
185 | break; |
186 | case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: |
187 | clear_bit(nr: chan, addr: &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, n: variant->num_clks, |
204 | size: 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, num_clks: drvdata->num_clks, 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(num_clks: drvdata->num_clks, 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(num_clks: drvdata->num_clks, 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(num_clks: drvdata->num_clks, 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(num_clks: drvdata->num_clks, 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 | |