1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2 // Copyright(c) 2015-17 Intel Corporation.
5 * Soundwire Intel Master Driver
8 #include <linux/acpi.h>
9 #include <linux/delay.h>
10 #include <linux/interrupt.h>
11 #include <linux/platform_device.h>
12 #include <sound/pcm_params.h>
13 #include <sound/soc.h>
14 #include <linux/soundwire/sdw_registers.h>
15 #include <linux/soundwire/sdw.h>
16 #include <linux/soundwire/sdw_intel.h>
17 #include "cadence_master.h"
20 /* Intel SHIM Registers Definition */
21 #define SDW_SHIM_LCAP 0x0
22 #define SDW_SHIM_LCTL 0x4
23 #define SDW_SHIM_IPPTR 0x8
24 #define SDW_SHIM_SYNC 0xC
26 #define SDW_SHIM_CTLSCAP(x) (0x010 + 0x60 * x)
27 #define SDW_SHIM_CTLS0CM(x) (0x012 + 0x60 * x)
28 #define SDW_SHIM_CTLS1CM(x) (0x014 + 0x60 * x)
29 #define SDW_SHIM_CTLS2CM(x) (0x016 + 0x60 * x)
30 #define SDW_SHIM_CTLS3CM(x) (0x018 + 0x60 * x)
31 #define SDW_SHIM_PCMSCAP(x) (0x020 + 0x60 * x)
33 #define SDW_SHIM_PCMSYCHM(x, y) (0x022 + (0x60 * x) + (0x2 * y))
34 #define SDW_SHIM_PCMSYCHC(x, y) (0x042 + (0x60 * x) + (0x2 * y))
35 #define SDW_SHIM_PDMSCAP(x) (0x062 + 0x60 * x)
36 #define SDW_SHIM_IOCTL(x) (0x06C + 0x60 * x)
37 #define SDW_SHIM_CTMCTL(x) (0x06E + 0x60 * x)
39 #define SDW_SHIM_WAKEEN 0x190
40 #define SDW_SHIM_WAKESTS 0x192
42 #define SDW_SHIM_LCTL_SPA BIT(0)
43 #define SDW_SHIM_LCTL_CPA BIT(8)
45 #define SDW_SHIM_SYNC_SYNCPRD_VAL 0x176F
46 #define SDW_SHIM_SYNC_SYNCPRD GENMASK(14, 0)
47 #define SDW_SHIM_SYNC_SYNCCPU BIT(15)
48 #define SDW_SHIM_SYNC_CMDSYNC_MASK GENMASK(19, 16)
49 #define SDW_SHIM_SYNC_CMDSYNC BIT(16)
50 #define SDW_SHIM_SYNC_SYNCGO BIT(24)
52 #define SDW_SHIM_PCMSCAP_ISS GENMASK(3, 0)
53 #define SDW_SHIM_PCMSCAP_OSS GENMASK(7, 4)
54 #define SDW_SHIM_PCMSCAP_BSS GENMASK(12, 8)
56 #define SDW_SHIM_PCMSYCM_LCHN GENMASK(3, 0)
57 #define SDW_SHIM_PCMSYCM_HCHN GENMASK(7, 4)
58 #define SDW_SHIM_PCMSYCM_STREAM GENMASK(13, 8)
59 #define SDW_SHIM_PCMSYCM_DIR BIT(15)
61 #define SDW_SHIM_PDMSCAP_ISS GENMASK(3, 0)
62 #define SDW_SHIM_PDMSCAP_OSS GENMASK(7, 4)
63 #define SDW_SHIM_PDMSCAP_BSS GENMASK(12, 8)
64 #define SDW_SHIM_PDMSCAP_CPSS GENMASK(15, 13)
66 #define SDW_SHIM_IOCTL_MIF BIT(0)
67 #define SDW_SHIM_IOCTL_CO BIT(1)
68 #define SDW_SHIM_IOCTL_COE BIT(2)
69 #define SDW_SHIM_IOCTL_DO BIT(3)
70 #define SDW_SHIM_IOCTL_DOE BIT(4)
71 #define SDW_SHIM_IOCTL_BKE BIT(5)
72 #define SDW_SHIM_IOCTL_WPDD BIT(6)
73 #define SDW_SHIM_IOCTL_CIBD BIT(8)
74 #define SDW_SHIM_IOCTL_DIBD BIT(9)
76 #define SDW_SHIM_CTMCTL_DACTQE BIT(0)
77 #define SDW_SHIM_CTMCTL_DODS BIT(1)
78 #define SDW_SHIM_CTMCTL_DOAIS GENMASK(4, 3)
80 #define SDW_SHIM_WAKEEN_ENABLE BIT(0)
81 #define SDW_SHIM_WAKESTS_STATUS BIT(0)
83 /* Intel ALH Register definitions */
84 #define SDW_ALH_STRMZCFG(x) (0x000 + (0x4 * x))
86 #define SDW_ALH_STRMZCFG_DMAT_VAL 0x3
87 #define SDW_ALH_STRMZCFG_DMAT GENMASK(7, 0)
88 #define SDW_ALH_STRMZCFG_CHN GENMASK(19, 16)
99 struct sdw_intel_link_res
*res
;
102 #define cdns_to_intel(_cdns) container_of(_cdns, struct sdw_intel, cdns)
105 * Read, write helpers for HW registers
107 static inline int intel_readl(void __iomem
*base
, int offset
)
109 return readl(base
+ offset
);
112 static inline void intel_writel(void __iomem
*base
, int offset
, int value
)
114 writel(value
, base
+ offset
);
117 static inline u16
intel_readw(void __iomem
*base
, int offset
)
119 return readw(base
+ offset
);
122 static inline void intel_writew(void __iomem
*base
, int offset
, u16 value
)
124 writew(value
, base
+ offset
);
127 static int intel_clear_bit(void __iomem
*base
, int offset
, u32 value
, u32 mask
)
132 writel(value
, base
+ offset
);
134 reg_read
= readl(base
+ offset
);
135 if (!(reg_read
& mask
))
140 } while (timeout
!= 0);
145 static int intel_set_bit(void __iomem
*base
, int offset
, u32 value
, u32 mask
)
150 writel(value
, base
+ offset
);
152 reg_read
= readl(base
+ offset
);
158 } while (timeout
!= 0);
167 static int intel_link_power_up(struct sdw_intel
*sdw
)
169 unsigned int link_id
= sdw
->instance
;
170 void __iomem
*shim
= sdw
->res
->shim
;
171 int spa_mask
, cpa_mask
;
172 int link_control
, ret
;
174 /* Link power up sequence */
175 link_control
= intel_readl(shim
, SDW_SHIM_LCTL
);
176 spa_mask
= (SDW_SHIM_LCTL_SPA
<< link_id
);
177 cpa_mask
= (SDW_SHIM_LCTL_CPA
<< link_id
);
178 link_control
|= spa_mask
;
180 ret
= intel_set_bit(shim
, SDW_SHIM_LCTL
, link_control
, cpa_mask
);
184 sdw
->cdns
.link_up
= true;
188 static int intel_shim_init(struct sdw_intel
*sdw
)
190 void __iomem
*shim
= sdw
->res
->shim
;
191 unsigned int link_id
= sdw
->instance
;
193 u16 ioctl
= 0, act
= 0;
195 /* Initialize Shim */
196 ioctl
|= SDW_SHIM_IOCTL_BKE
;
197 intel_writew(shim
, SDW_SHIM_IOCTL(link_id
), ioctl
);
199 ioctl
|= SDW_SHIM_IOCTL_WPDD
;
200 intel_writew(shim
, SDW_SHIM_IOCTL(link_id
), ioctl
);
202 ioctl
|= SDW_SHIM_IOCTL_DO
;
203 intel_writew(shim
, SDW_SHIM_IOCTL(link_id
), ioctl
);
205 ioctl
|= SDW_SHIM_IOCTL_DOE
;
206 intel_writew(shim
, SDW_SHIM_IOCTL(link_id
), ioctl
);
208 /* Switch to MIP from Glue logic */
209 ioctl
= intel_readw(shim
, SDW_SHIM_IOCTL(link_id
));
211 ioctl
&= ~(SDW_SHIM_IOCTL_DOE
);
212 intel_writew(shim
, SDW_SHIM_IOCTL(link_id
), ioctl
);
214 ioctl
&= ~(SDW_SHIM_IOCTL_DO
);
215 intel_writew(shim
, SDW_SHIM_IOCTL(link_id
), ioctl
);
217 ioctl
|= (SDW_SHIM_IOCTL_MIF
);
218 intel_writew(shim
, SDW_SHIM_IOCTL(link_id
), ioctl
);
220 ioctl
&= ~(SDW_SHIM_IOCTL_BKE
);
221 ioctl
&= ~(SDW_SHIM_IOCTL_COE
);
223 intel_writew(shim
, SDW_SHIM_IOCTL(link_id
), ioctl
);
225 act
|= 0x1 << SDW_REG_SHIFT(SDW_SHIM_CTMCTL_DOAIS
);
226 act
|= SDW_SHIM_CTMCTL_DACTQE
;
227 act
|= SDW_SHIM_CTMCTL_DODS
;
228 intel_writew(shim
, SDW_SHIM_CTMCTL(link_id
), act
);
230 /* Now set SyncPRD period */
231 sync_reg
= intel_readl(shim
, SDW_SHIM_SYNC
);
232 sync_reg
|= (SDW_SHIM_SYNC_SYNCPRD_VAL
<<
233 SDW_REG_SHIFT(SDW_SHIM_SYNC_SYNCPRD
));
235 /* Set SyncCPU bit */
236 sync_reg
|= SDW_SHIM_SYNC_SYNCCPU
;
237 ret
= intel_clear_bit(shim
, SDW_SHIM_SYNC
, sync_reg
,
238 SDW_SHIM_SYNC_SYNCCPU
);
240 dev_err(sdw
->cdns
.dev
, "Failed to set sync period: %d", ret
);
248 static void intel_pdi_init(struct sdw_intel
*sdw
,
249 struct sdw_cdns_stream_config
*config
)
251 void __iomem
*shim
= sdw
->res
->shim
;
252 unsigned int link_id
= sdw
->instance
;
253 int pcm_cap
, pdm_cap
;
255 /* PCM Stream Capability */
256 pcm_cap
= intel_readw(shim
, SDW_SHIM_PCMSCAP(link_id
));
258 config
->pcm_bd
= (pcm_cap
& SDW_SHIM_PCMSCAP_BSS
) >>
259 SDW_REG_SHIFT(SDW_SHIM_PCMSCAP_BSS
);
260 config
->pcm_in
= (pcm_cap
& SDW_SHIM_PCMSCAP_ISS
) >>
261 SDW_REG_SHIFT(SDW_SHIM_PCMSCAP_ISS
);
262 config
->pcm_out
= (pcm_cap
& SDW_SHIM_PCMSCAP_OSS
) >>
263 SDW_REG_SHIFT(SDW_SHIM_PCMSCAP_OSS
);
265 /* PDM Stream Capability */
266 pdm_cap
= intel_readw(shim
, SDW_SHIM_PDMSCAP(link_id
));
268 config
->pdm_bd
= (pdm_cap
& SDW_SHIM_PDMSCAP_BSS
) >>
269 SDW_REG_SHIFT(SDW_SHIM_PDMSCAP_BSS
);
270 config
->pdm_in
= (pdm_cap
& SDW_SHIM_PDMSCAP_ISS
) >>
271 SDW_REG_SHIFT(SDW_SHIM_PDMSCAP_ISS
);
272 config
->pdm_out
= (pdm_cap
& SDW_SHIM_PDMSCAP_OSS
) >>
273 SDW_REG_SHIFT(SDW_SHIM_PDMSCAP_OSS
);
277 intel_pdi_get_ch_cap(struct sdw_intel
*sdw
, unsigned int pdi_num
, bool pcm
)
279 void __iomem
*shim
= sdw
->res
->shim
;
280 unsigned int link_id
= sdw
->instance
;
284 count
= intel_readw(shim
, SDW_SHIM_PCMSYCHC(link_id
, pdi_num
));
287 * WORKAROUND: on all existing Intel controllers, pdi
288 * number 2 reports channel count as 1 even though it
289 * supports 8 channels. Performing hardcoding for pdi
296 count
= intel_readw(shim
, SDW_SHIM_PDMSCAP(link_id
));
297 count
= ((count
& SDW_SHIM_PDMSCAP_CPSS
) >>
298 SDW_REG_SHIFT(SDW_SHIM_PDMSCAP_CPSS
));
301 /* zero based values for channel count in register */
307 static int intel_pdi_get_ch_update(struct sdw_intel
*sdw
,
308 struct sdw_cdns_pdi
*pdi
,
309 unsigned int num_pdi
,
310 unsigned int *num_ch
, bool pcm
)
314 for (i
= 0; i
< num_pdi
; i
++) {
315 pdi
->ch_count
= intel_pdi_get_ch_cap(sdw
, pdi
->num
, pcm
);
316 ch_count
+= pdi
->ch_count
;
324 static int intel_pdi_stream_ch_update(struct sdw_intel
*sdw
,
325 struct sdw_cdns_streams
*stream
, bool pcm
)
327 intel_pdi_get_ch_update(sdw
, stream
->bd
, stream
->num_bd
,
328 &stream
->num_ch_bd
, pcm
);
330 intel_pdi_get_ch_update(sdw
, stream
->in
, stream
->num_in
,
331 &stream
->num_ch_in
, pcm
);
333 intel_pdi_get_ch_update(sdw
, stream
->out
, stream
->num_out
,
334 &stream
->num_ch_out
, pcm
);
339 static int intel_pdi_ch_update(struct sdw_intel
*sdw
)
341 /* First update PCM streams followed by PDM streams */
342 intel_pdi_stream_ch_update(sdw
, &sdw
->cdns
.pcm
, true);
343 intel_pdi_stream_ch_update(sdw
, &sdw
->cdns
.pdm
, false);
349 intel_pdi_shim_configure(struct sdw_intel
*sdw
, struct sdw_cdns_pdi
*pdi
)
351 void __iomem
*shim
= sdw
->res
->shim
;
352 unsigned int link_id
= sdw
->instance
;
355 /* the Bulk and PCM streams are not contiguous */
356 pdi
->intel_alh_id
= (link_id
* 16) + pdi
->num
+ 3;
358 pdi
->intel_alh_id
+= 2;
361 * Program stream parameters to stream SHIM register
362 * This is applicable for PCM stream only.
364 if (pdi
->type
!= SDW_STREAM_PCM
)
367 if (pdi
->dir
== SDW_DATA_DIR_RX
)
368 pdi_conf
|= SDW_SHIM_PCMSYCM_DIR
;
370 pdi_conf
&= ~(SDW_SHIM_PCMSYCM_DIR
);
372 pdi_conf
|= (pdi
->intel_alh_id
<<
373 SDW_REG_SHIFT(SDW_SHIM_PCMSYCM_STREAM
));
374 pdi_conf
|= (pdi
->l_ch_num
<< SDW_REG_SHIFT(SDW_SHIM_PCMSYCM_LCHN
));
375 pdi_conf
|= (pdi
->h_ch_num
<< SDW_REG_SHIFT(SDW_SHIM_PCMSYCM_HCHN
));
377 intel_writew(shim
, SDW_SHIM_PCMSYCHM(link_id
, pdi
->num
), pdi_conf
);
381 intel_pdi_alh_configure(struct sdw_intel
*sdw
, struct sdw_cdns_pdi
*pdi
)
383 void __iomem
*alh
= sdw
->res
->alh
;
384 unsigned int link_id
= sdw
->instance
;
387 /* the Bulk and PCM streams are not contiguous */
388 pdi
->intel_alh_id
= (link_id
* 16) + pdi
->num
+ 3;
390 pdi
->intel_alh_id
+= 2;
392 /* Program Stream config ALH register */
393 conf
= intel_readl(alh
, SDW_ALH_STRMZCFG(pdi
->intel_alh_id
));
395 conf
|= (SDW_ALH_STRMZCFG_DMAT_VAL
<<
396 SDW_REG_SHIFT(SDW_ALH_STRMZCFG_DMAT
));
398 conf
|= ((pdi
->ch_count
- 1) <<
399 SDW_REG_SHIFT(SDW_ALH_STRMZCFG_CHN
));
401 intel_writel(alh
, SDW_ALH_STRMZCFG(pdi
->intel_alh_id
), conf
);
404 static int intel_config_stream(struct sdw_intel
*sdw
,
405 struct snd_pcm_substream
*substream
,
406 struct snd_soc_dai
*dai
,
407 struct snd_pcm_hw_params
*hw_params
, int link_id
)
409 if (sdw
->res
->ops
&& sdw
->res
->ops
->config_stream
)
410 return sdw
->res
->ops
->config_stream(sdw
->res
->arg
,
411 substream
, dai
, hw_params
, link_id
);
420 static struct sdw_cdns_port
*intel_alloc_port(struct sdw_intel
*sdw
,
421 u32 ch
, u32 dir
, bool pcm
)
423 struct sdw_cdns
*cdns
= &sdw
->cdns
;
424 struct sdw_cdns_port
*port
= NULL
;
427 for (i
= 0; i
< cdns
->num_ports
; i
++) {
428 if (cdns
->ports
[i
].assigned
== true)
431 port
= &cdns
->ports
[i
];
432 port
->assigned
= true;
433 port
->direction
= dir
;
439 dev_err(cdns
->dev
, "Unable to find a free port\n");
444 ret
= sdw_cdns_alloc_stream(cdns
, &cdns
->pcm
, port
, ch
, dir
);
448 intel_pdi_shim_configure(sdw
, port
->pdi
);
449 sdw_cdns_config_stream(cdns
, port
, ch
, dir
, port
->pdi
);
451 intel_pdi_alh_configure(sdw
, port
->pdi
);
454 ret
= sdw_cdns_alloc_stream(cdns
, &cdns
->pdm
, port
, ch
, dir
);
459 port
->assigned
= false;
466 static void intel_port_cleanup(struct sdw_cdns_dma_data
*dma
)
470 for (i
= 0; i
< dma
->nr_ports
; i
++) {
472 dma
->port
[i
]->pdi
->assigned
= false;
473 dma
->port
[i
]->pdi
= NULL
;
474 dma
->port
[i
]->assigned
= false;
480 static int intel_hw_params(struct snd_pcm_substream
*substream
,
481 struct snd_pcm_hw_params
*params
,
482 struct snd_soc_dai
*dai
)
484 struct sdw_cdns
*cdns
= snd_soc_dai_get_drvdata(dai
);
485 struct sdw_intel
*sdw
= cdns_to_intel(cdns
);
486 struct sdw_cdns_dma_data
*dma
;
487 struct sdw_stream_config sconfig
;
488 struct sdw_port_config
*pconfig
;
492 dma
= snd_soc_dai_get_dma_data(dai
, substream
);
496 ch
= params_channels(params
);
497 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
498 dir
= SDW_DATA_DIR_RX
;
500 dir
= SDW_DATA_DIR_TX
;
502 if (dma
->stream_type
== SDW_STREAM_PDM
) {
503 /* TODO: Check whether PDM decimator is already in use */
504 dma
->nr_ports
= sdw_cdns_get_stream(cdns
, &cdns
->pdm
, ch
, dir
);
507 dma
->nr_ports
= sdw_cdns_get_stream(cdns
, &cdns
->pcm
, ch
, dir
);
510 if (!dma
->nr_ports
) {
511 dev_err(dai
->dev
, "ports/resources not available");
515 dma
->port
= kcalloc(dma
->nr_ports
, sizeof(*dma
->port
), GFP_KERNEL
);
519 for (i
= 0; i
< dma
->nr_ports
; i
++) {
520 dma
->port
[i
] = intel_alloc_port(sdw
, ch
, dir
, pcm
);
527 /* Inform DSP about PDI stream number */
528 for (i
= 0; i
< dma
->nr_ports
; i
++) {
529 ret
= intel_config_stream(sdw
, substream
, dai
, params
,
530 dma
->port
[i
]->pdi
->intel_alh_id
);
535 sconfig
.direction
= dir
;
536 sconfig
.ch_count
= ch
;
537 sconfig
.frame_rate
= params_rate(params
);
538 sconfig
.type
= dma
->stream_type
;
540 if (dma
->stream_type
== SDW_STREAM_PDM
) {
541 sconfig
.frame_rate
*= 50;
544 sconfig
.bps
= snd_pcm_format_width(params_format(params
));
547 /* Port configuration */
548 pconfig
= kcalloc(dma
->nr_ports
, sizeof(*pconfig
), GFP_KERNEL
);
554 for (i
= 0; i
< dma
->nr_ports
; i
++) {
555 pconfig
[i
].num
= dma
->port
[i
]->num
;
556 pconfig
[i
].ch_mask
= (1 << ch
) - 1;
559 ret
= sdw_stream_add_master(&cdns
->bus
, &sconfig
,
560 pconfig
, dma
->nr_ports
, dma
->stream
);
562 dev_err(cdns
->dev
, "add master to stream failed:%d", ret
);
572 intel_port_cleanup(dma
);
578 intel_hw_free(struct snd_pcm_substream
*substream
, struct snd_soc_dai
*dai
)
580 struct sdw_cdns
*cdns
= snd_soc_dai_get_drvdata(dai
);
581 struct sdw_cdns_dma_data
*dma
;
584 dma
= snd_soc_dai_get_dma_data(dai
, substream
);
588 ret
= sdw_stream_remove_master(&cdns
->bus
, dma
->stream
);
590 dev_err(dai
->dev
, "remove master from stream %s failed: %d",
591 dma
->stream
->name
, ret
);
593 intel_port_cleanup(dma
);
598 static int intel_pcm_set_sdw_stream(struct snd_soc_dai
*dai
,
599 void *stream
, int direction
)
601 return cdns_set_sdw_stream(dai
, stream
, true, direction
);
604 static int intel_pdm_set_sdw_stream(struct snd_soc_dai
*dai
,
605 void *stream
, int direction
)
607 return cdns_set_sdw_stream(dai
, stream
, false, direction
);
610 static struct snd_soc_dai_ops intel_pcm_dai_ops
= {
611 .hw_params
= intel_hw_params
,
612 .hw_free
= intel_hw_free
,
613 .shutdown
= sdw_cdns_shutdown
,
614 .set_sdw_stream
= intel_pcm_set_sdw_stream
,
617 static struct snd_soc_dai_ops intel_pdm_dai_ops
= {
618 .hw_params
= intel_hw_params
,
619 .hw_free
= intel_hw_free
,
620 .shutdown
= sdw_cdns_shutdown
,
621 .set_sdw_stream
= intel_pdm_set_sdw_stream
,
624 static const struct snd_soc_component_driver dai_component
= {
628 static int intel_create_dai(struct sdw_cdns
*cdns
,
629 struct snd_soc_dai_driver
*dais
,
630 enum intel_pdi_type type
,
631 u32 num
, u32 off
, u32 max_ch
, bool pcm
)
638 /* TODO: Read supported rates/formats from hardware */
639 for (i
= off
; i
< (off
+ num
); i
++) {
640 dais
[i
].name
= kasprintf(GFP_KERNEL
, "SDW%d Pin%d",
645 if (type
== INTEL_PDI_BD
|| type
== INTEL_PDI_OUT
) {
646 dais
[i
].playback
.stream_name
= kasprintf(GFP_KERNEL
,
649 if (!dais
[i
].playback
.stream_name
) {
654 dais
[i
].playback
.channels_min
= 1;
655 dais
[i
].playback
.channels_max
= max_ch
;
656 dais
[i
].playback
.rates
= SNDRV_PCM_RATE_48000
;
657 dais
[i
].playback
.formats
= SNDRV_PCM_FMTBIT_S16_LE
;
660 if (type
== INTEL_PDI_BD
|| type
== INTEL_PDI_IN
) {
661 dais
[i
].capture
.stream_name
= kasprintf(GFP_KERNEL
,
664 if (!dais
[i
].capture
.stream_name
) {
666 kfree(dais
[i
].playback
.stream_name
);
670 dais
[i
].capture
.channels_min
= 1;
671 dais
[i
].capture
.channels_max
= max_ch
;
672 dais
[i
].capture
.rates
= SNDRV_PCM_RATE_48000
;
673 dais
[i
].capture
.formats
= SNDRV_PCM_FMTBIT_S16_LE
;
676 dais
[i
].id
= SDW_DAI_ID_RANGE_START
+ i
;
679 dais
[i
].ops
= &intel_pcm_dai_ops
;
681 dais
[i
].ops
= &intel_pdm_dai_ops
;
687 static int intel_register_dai(struct sdw_intel
*sdw
)
689 struct sdw_cdns
*cdns
= &sdw
->cdns
;
690 struct sdw_cdns_streams
*stream
;
691 struct snd_soc_dai_driver
*dais
;
692 int num_dai
, ret
, off
= 0;
694 /* DAIs are created based on total number of PDIs supported */
695 num_dai
= cdns
->pcm
.num_pdi
+ cdns
->pdm
.num_pdi
;
697 dais
= devm_kcalloc(cdns
->dev
, num_dai
, sizeof(*dais
), GFP_KERNEL
);
701 /* Create PCM DAIs */
704 ret
= intel_create_dai(cdns
, dais
, INTEL_PDI_IN
,
705 stream
->num_in
, off
, stream
->num_ch_in
, true);
709 off
+= cdns
->pcm
.num_in
;
710 ret
= intel_create_dai(cdns
, dais
, INTEL_PDI_OUT
,
711 cdns
->pcm
.num_out
, off
, stream
->num_ch_out
, true);
715 off
+= cdns
->pcm
.num_out
;
716 ret
= intel_create_dai(cdns
, dais
, INTEL_PDI_BD
,
717 cdns
->pcm
.num_bd
, off
, stream
->num_ch_bd
, true);
721 /* Create PDM DAIs */
723 off
+= cdns
->pcm
.num_bd
;
724 ret
= intel_create_dai(cdns
, dais
, INTEL_PDI_IN
,
725 cdns
->pdm
.num_in
, off
, stream
->num_ch_in
, false);
729 off
+= cdns
->pdm
.num_in
;
730 ret
= intel_create_dai(cdns
, dais
, INTEL_PDI_OUT
,
731 cdns
->pdm
.num_out
, off
, stream
->num_ch_out
, false);
735 off
+= cdns
->pdm
.num_bd
;
736 ret
= intel_create_dai(cdns
, dais
, INTEL_PDI_BD
,
737 cdns
->pdm
.num_bd
, off
, stream
->num_ch_bd
, false);
741 return snd_soc_register_component(cdns
->dev
, &dai_component
,
745 static int intel_prop_read(struct sdw_bus
*bus
)
747 /* Initialize with default handler to read all DisCo properties */
748 sdw_master_read_prop(bus
);
750 /* BIOS is not giving some values correctly. So, lets override them */
751 bus
->prop
.num_freq
= 1;
752 bus
->prop
.freq
= devm_kcalloc(bus
->dev
, sizeof(*bus
->prop
.freq
),
753 bus
->prop
.num_freq
, GFP_KERNEL
);
757 bus
->prop
.freq
[0] = bus
->prop
.max_freq
;
758 bus
->prop
.err_threshold
= 5;
763 static struct sdw_master_ops sdw_intel_ops
= {
764 .read_prop
= sdw_master_read_prop
,
765 .xfer_msg
= cdns_xfer_msg
,
766 .xfer_msg_defer
= cdns_xfer_msg_defer
,
767 .reset_page_addr
= cdns_reset_page_addr
,
768 .set_bus_conf
= cdns_bus_conf
,
774 static int intel_probe(struct platform_device
*pdev
)
776 struct sdw_cdns_stream_config config
;
777 struct sdw_intel
*sdw
;
780 sdw
= devm_kzalloc(&pdev
->dev
, sizeof(*sdw
), GFP_KERNEL
);
784 sdw
->instance
= pdev
->id
;
785 sdw
->res
= dev_get_platdata(&pdev
->dev
);
786 sdw
->cdns
.dev
= &pdev
->dev
;
787 sdw
->cdns
.registers
= sdw
->res
->registers
;
788 sdw
->cdns
.instance
= sdw
->instance
;
789 sdw
->cdns
.msg_count
= 0;
790 sdw
->cdns
.bus
.dev
= &pdev
->dev
;
791 sdw
->cdns
.bus
.link_id
= pdev
->id
;
793 sdw_cdns_probe(&sdw
->cdns
);
795 /* Set property read ops */
796 sdw_intel_ops
.read_prop
= intel_prop_read
;
797 sdw
->cdns
.bus
.ops
= &sdw_intel_ops
;
799 sdw_intel_ops
.read_prop
= intel_prop_read
;
800 sdw
->cdns
.bus
.ops
= &sdw_intel_ops
;
802 platform_set_drvdata(pdev
, sdw
);
804 ret
= sdw_add_bus_master(&sdw
->cdns
.bus
);
806 dev_err(&pdev
->dev
, "sdw_add_bus_master fail: %d\n", ret
);
810 /* Initialize shim and controller */
811 intel_link_power_up(sdw
);
812 intel_shim_init(sdw
);
814 ret
= sdw_cdns_init(&sdw
->cdns
);
818 ret
= sdw_cdns_enable_interrupt(&sdw
->cdns
);
820 /* Read the PDI config and initialize cadence PDI */
821 intel_pdi_init(sdw
, &config
);
822 ret
= sdw_cdns_pdi_init(&sdw
->cdns
, config
);
826 intel_pdi_ch_update(sdw
);
829 ret
= request_threaded_irq(sdw
->res
->irq
, sdw_cdns_irq
,
830 sdw_cdns_thread
, IRQF_SHARED
, KBUILD_MODNAME
,
833 dev_err(sdw
->cdns
.dev
, "unable to grab IRQ %d, disabling device\n",
839 ret
= intel_register_dai(sdw
);
841 dev_err(sdw
->cdns
.dev
, "DAI registration failed: %d", ret
);
842 snd_soc_unregister_component(sdw
->cdns
.dev
);
849 free_irq(sdw
->res
->irq
, sdw
);
851 sdw_delete_bus_master(&sdw
->cdns
.bus
);
856 static int intel_remove(struct platform_device
*pdev
)
858 struct sdw_intel
*sdw
;
860 sdw
= platform_get_drvdata(pdev
);
862 free_irq(sdw
->res
->irq
, sdw
);
863 snd_soc_unregister_component(sdw
->cdns
.dev
);
864 sdw_delete_bus_master(&sdw
->cdns
.bus
);
869 static struct platform_driver sdw_intel_drv
= {
870 .probe
= intel_probe
,
871 .remove
= intel_remove
,
878 module_platform_driver(sdw_intel_drv
);
880 MODULE_LICENSE("Dual BSD/GPL");
881 MODULE_ALIAS("platform:int-sdw");
882 MODULE_DESCRIPTION("Intel Soundwire Master Driver");