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
));
286 count
= intel_readw(shim
, SDW_SHIM_PDMSCAP(link_id
));
287 count
= ((count
& SDW_SHIM_PDMSCAP_CPSS
) >>
288 SDW_REG_SHIFT(SDW_SHIM_PDMSCAP_CPSS
));
291 /* zero based values for channel count in register */
297 static int intel_pdi_get_ch_update(struct sdw_intel
*sdw
,
298 struct sdw_cdns_pdi
*pdi
,
299 unsigned int num_pdi
,
300 unsigned int *num_ch
, bool pcm
)
304 for (i
= 0; i
< num_pdi
; i
++) {
305 pdi
->ch_count
= intel_pdi_get_ch_cap(sdw
, pdi
->num
, pcm
);
306 ch_count
+= pdi
->ch_count
;
314 static int intel_pdi_stream_ch_update(struct sdw_intel
*sdw
,
315 struct sdw_cdns_streams
*stream
, bool pcm
)
317 intel_pdi_get_ch_update(sdw
, stream
->bd
, stream
->num_bd
,
318 &stream
->num_ch_bd
, pcm
);
320 intel_pdi_get_ch_update(sdw
, stream
->in
, stream
->num_in
,
321 &stream
->num_ch_in
, pcm
);
323 intel_pdi_get_ch_update(sdw
, stream
->out
, stream
->num_out
,
324 &stream
->num_ch_out
, pcm
);
329 static int intel_pdi_ch_update(struct sdw_intel
*sdw
)
331 /* First update PCM streams followed by PDM streams */
332 intel_pdi_stream_ch_update(sdw
, &sdw
->cdns
.pcm
, true);
333 intel_pdi_stream_ch_update(sdw
, &sdw
->cdns
.pdm
, false);
339 intel_pdi_shim_configure(struct sdw_intel
*sdw
, struct sdw_cdns_pdi
*pdi
)
341 void __iomem
*shim
= sdw
->res
->shim
;
342 unsigned int link_id
= sdw
->instance
;
345 pdi
->intel_alh_id
= (link_id
* 16) + pdi
->num
+ 5;
348 * Program stream parameters to stream SHIM register
349 * This is applicable for PCM stream only.
351 if (pdi
->type
!= SDW_STREAM_PCM
)
354 if (pdi
->dir
== SDW_DATA_DIR_RX
)
355 pdi_conf
|= SDW_SHIM_PCMSYCM_DIR
;
357 pdi_conf
&= ~(SDW_SHIM_PCMSYCM_DIR
);
359 pdi_conf
|= (pdi
->intel_alh_id
<<
360 SDW_REG_SHIFT(SDW_SHIM_PCMSYCM_STREAM
));
361 pdi_conf
|= (pdi
->l_ch_num
<< SDW_REG_SHIFT(SDW_SHIM_PCMSYCM_LCHN
));
362 pdi_conf
|= (pdi
->h_ch_num
<< SDW_REG_SHIFT(SDW_SHIM_PCMSYCM_HCHN
));
364 intel_writew(shim
, SDW_SHIM_PCMSYCHM(link_id
, pdi
->num
), pdi_conf
);
368 intel_pdi_alh_configure(struct sdw_intel
*sdw
, struct sdw_cdns_pdi
*pdi
)
370 void __iomem
*alh
= sdw
->res
->alh
;
371 unsigned int link_id
= sdw
->instance
;
374 pdi
->intel_alh_id
= (link_id
* 16) + pdi
->num
+ 5;
376 /* Program Stream config ALH register */
377 conf
= intel_readl(alh
, SDW_ALH_STRMZCFG(pdi
->intel_alh_id
));
379 conf
|= (SDW_ALH_STRMZCFG_DMAT_VAL
<<
380 SDW_REG_SHIFT(SDW_ALH_STRMZCFG_DMAT
));
382 conf
|= ((pdi
->ch_count
- 1) <<
383 SDW_REG_SHIFT(SDW_ALH_STRMZCFG_CHN
));
385 intel_writel(alh
, SDW_ALH_STRMZCFG(pdi
->intel_alh_id
), conf
);
388 static int intel_config_stream(struct sdw_intel
*sdw
,
389 struct snd_pcm_substream
*substream
,
390 struct snd_soc_dai
*dai
,
391 struct snd_pcm_hw_params
*hw_params
, int link_id
)
393 if (sdw
->res
->ops
&& sdw
->res
->ops
->config_stream
)
394 return sdw
->res
->ops
->config_stream(sdw
->res
->arg
,
395 substream
, dai
, hw_params
, link_id
);
404 static struct sdw_cdns_port
*intel_alloc_port(struct sdw_intel
*sdw
,
405 u32 ch
, u32 dir
, bool pcm
)
407 struct sdw_cdns
*cdns
= &sdw
->cdns
;
408 struct sdw_cdns_port
*port
= NULL
;
411 for (i
= 0; i
< cdns
->num_ports
; i
++) {
412 if (cdns
->ports
[i
].assigned
== true)
415 port
= &cdns
->ports
[i
];
416 port
->assigned
= true;
417 port
->direction
= dir
;
423 dev_err(cdns
->dev
, "Unable to find a free port\n");
428 ret
= sdw_cdns_alloc_stream(cdns
, &cdns
->pcm
, port
, ch
, dir
);
432 intel_pdi_shim_configure(sdw
, port
->pdi
);
433 sdw_cdns_config_stream(cdns
, port
, ch
, dir
, port
->pdi
);
435 intel_pdi_alh_configure(sdw
, port
->pdi
);
438 ret
= sdw_cdns_alloc_stream(cdns
, &cdns
->pdm
, port
, ch
, dir
);
443 port
->assigned
= false;
450 static void intel_port_cleanup(struct sdw_cdns_dma_data
*dma
)
454 for (i
= 0; i
< dma
->nr_ports
; i
++) {
456 dma
->port
[i
]->pdi
->assigned
= false;
457 dma
->port
[i
]->pdi
= NULL
;
458 dma
->port
[i
]->assigned
= false;
464 static int intel_hw_params(struct snd_pcm_substream
*substream
,
465 struct snd_pcm_hw_params
*params
,
466 struct snd_soc_dai
*dai
)
468 struct sdw_cdns
*cdns
= snd_soc_dai_get_drvdata(dai
);
469 struct sdw_intel
*sdw
= cdns_to_intel(cdns
);
470 struct sdw_cdns_dma_data
*dma
;
471 struct sdw_stream_config sconfig
;
472 struct sdw_port_config
*pconfig
;
476 dma
= snd_soc_dai_get_dma_data(dai
, substream
);
480 ch
= params_channels(params
);
481 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
482 dir
= SDW_DATA_DIR_RX
;
484 dir
= SDW_DATA_DIR_TX
;
486 if (dma
->stream_type
== SDW_STREAM_PDM
) {
487 /* TODO: Check whether PDM decimator is already in use */
488 dma
->nr_ports
= sdw_cdns_get_stream(cdns
, &cdns
->pdm
, ch
, dir
);
491 dma
->nr_ports
= sdw_cdns_get_stream(cdns
, &cdns
->pcm
, ch
, dir
);
494 if (!dma
->nr_ports
) {
495 dev_err(dai
->dev
, "ports/resources not available");
499 dma
->port
= kcalloc(dma
->nr_ports
, sizeof(*dma
->port
), GFP_KERNEL
);
503 for (i
= 0; i
< dma
->nr_ports
; i
++) {
504 dma
->port
[i
] = intel_alloc_port(sdw
, ch
, dir
, pcm
);
511 /* Inform DSP about PDI stream number */
512 for (i
= 0; i
< dma
->nr_ports
; i
++) {
513 ret
= intel_config_stream(sdw
, substream
, dai
, params
,
514 dma
->port
[i
]->pdi
->intel_alh_id
);
519 sconfig
.direction
= dir
;
520 sconfig
.ch_count
= ch
;
521 sconfig
.frame_rate
= params_rate(params
);
522 sconfig
.type
= dma
->stream_type
;
524 if (dma
->stream_type
== SDW_STREAM_PDM
) {
525 sconfig
.frame_rate
*= 50;
528 sconfig
.bps
= snd_pcm_format_width(params_format(params
));
531 /* Port configuration */
532 pconfig
= kcalloc(dma
->nr_ports
, sizeof(*pconfig
), GFP_KERNEL
);
538 for (i
= 0; i
< dma
->nr_ports
; i
++) {
539 pconfig
[i
].num
= dma
->port
[i
]->num
;
540 pconfig
[i
].ch_mask
= (1 << ch
) - 1;
543 ret
= sdw_stream_add_master(&cdns
->bus
, &sconfig
,
544 pconfig
, dma
->nr_ports
, dma
->stream
);
546 dev_err(cdns
->dev
, "add master to stream failed:%d", ret
);
556 intel_port_cleanup(dma
);
562 intel_hw_free(struct snd_pcm_substream
*substream
, struct snd_soc_dai
*dai
)
564 struct sdw_cdns
*cdns
= snd_soc_dai_get_drvdata(dai
);
565 struct sdw_cdns_dma_data
*dma
;
568 dma
= snd_soc_dai_get_dma_data(dai
, substream
);
572 ret
= sdw_stream_remove_master(&cdns
->bus
, dma
->stream
);
574 dev_err(dai
->dev
, "remove master from stream %s failed: %d",
575 dma
->stream
->name
, ret
);
577 intel_port_cleanup(dma
);
582 static int intel_pcm_set_sdw_stream(struct snd_soc_dai
*dai
,
583 void *stream
, int direction
)
585 return cdns_set_sdw_stream(dai
, stream
, true, direction
);
588 static int intel_pdm_set_sdw_stream(struct snd_soc_dai
*dai
,
589 void *stream
, int direction
)
591 return cdns_set_sdw_stream(dai
, stream
, false, direction
);
594 static struct snd_soc_dai_ops intel_pcm_dai_ops
= {
595 .hw_params
= intel_hw_params
,
596 .hw_free
= intel_hw_free
,
597 .shutdown
= sdw_cdns_shutdown
,
598 .set_sdw_stream
= intel_pcm_set_sdw_stream
,
601 static struct snd_soc_dai_ops intel_pdm_dai_ops
= {
602 .hw_params
= intel_hw_params
,
603 .hw_free
= intel_hw_free
,
604 .shutdown
= sdw_cdns_shutdown
,
605 .set_sdw_stream
= intel_pdm_set_sdw_stream
,
608 static const struct snd_soc_component_driver dai_component
= {
612 static int intel_create_dai(struct sdw_cdns
*cdns
,
613 struct snd_soc_dai_driver
*dais
,
614 enum intel_pdi_type type
,
615 u32 num
, u32 off
, u32 max_ch
, bool pcm
)
622 /* TODO: Read supported rates/formats from hardware */
623 for (i
= off
; i
< (off
+ num
); i
++) {
624 dais
[i
].name
= kasprintf(GFP_KERNEL
, "SDW%d Pin%d",
629 if (type
== INTEL_PDI_BD
|| type
== INTEL_PDI_OUT
) {
630 dais
[i
].playback
.stream_name
= kasprintf(GFP_KERNEL
,
633 if (!dais
[i
].playback
.stream_name
) {
638 dais
[i
].playback
.channels_min
= 1;
639 dais
[i
].playback
.channels_max
= max_ch
;
640 dais
[i
].playback
.rates
= SNDRV_PCM_RATE_48000
;
641 dais
[i
].playback
.formats
= SNDRV_PCM_FMTBIT_S16_LE
;
644 if (type
== INTEL_PDI_BD
|| type
== INTEL_PDI_IN
) {
645 dais
[i
].capture
.stream_name
= kasprintf(GFP_KERNEL
,
648 if (!dais
[i
].capture
.stream_name
) {
650 kfree(dais
[i
].playback
.stream_name
);
654 dais
[i
].playback
.channels_min
= 1;
655 dais
[i
].playback
.channels_max
= max_ch
;
656 dais
[i
].capture
.rates
= SNDRV_PCM_RATE_48000
;
657 dais
[i
].capture
.formats
= SNDRV_PCM_FMTBIT_S16_LE
;
660 dais
[i
].id
= SDW_DAI_ID_RANGE_START
+ i
;
663 dais
[i
].ops
= &intel_pcm_dai_ops
;
665 dais
[i
].ops
= &intel_pdm_dai_ops
;
671 static int intel_register_dai(struct sdw_intel
*sdw
)
673 struct sdw_cdns
*cdns
= &sdw
->cdns
;
674 struct sdw_cdns_streams
*stream
;
675 struct snd_soc_dai_driver
*dais
;
676 int num_dai
, ret
, off
= 0;
678 /* DAIs are created based on total number of PDIs supported */
679 num_dai
= cdns
->pcm
.num_pdi
+ cdns
->pdm
.num_pdi
;
681 dais
= devm_kcalloc(cdns
->dev
, num_dai
, sizeof(*dais
), GFP_KERNEL
);
685 /* Create PCM DAIs */
688 ret
= intel_create_dai(cdns
, dais
, INTEL_PDI_IN
,
689 stream
->num_in
, off
, stream
->num_ch_in
, true);
693 off
+= cdns
->pcm
.num_in
;
694 ret
= intel_create_dai(cdns
, dais
, INTEL_PDI_OUT
,
695 cdns
->pcm
.num_out
, off
, stream
->num_ch_out
, true);
699 off
+= cdns
->pcm
.num_out
;
700 ret
= intel_create_dai(cdns
, dais
, INTEL_PDI_BD
,
701 cdns
->pcm
.num_bd
, off
, stream
->num_ch_bd
, true);
705 /* Create PDM DAIs */
707 off
+= cdns
->pcm
.num_bd
;
708 ret
= intel_create_dai(cdns
, dais
, INTEL_PDI_IN
,
709 cdns
->pdm
.num_in
, off
, stream
->num_ch_in
, false);
713 off
+= cdns
->pdm
.num_in
;
714 ret
= intel_create_dai(cdns
, dais
, INTEL_PDI_OUT
,
715 cdns
->pdm
.num_out
, off
, stream
->num_ch_out
, false);
719 off
+= cdns
->pdm
.num_bd
;
720 ret
= intel_create_dai(cdns
, dais
, INTEL_PDI_BD
,
721 cdns
->pdm
.num_bd
, off
, stream
->num_ch_bd
, false);
725 return snd_soc_register_component(cdns
->dev
, &dai_component
,
729 static int intel_prop_read(struct sdw_bus
*bus
)
731 /* Initialize with default handler to read all DisCo properties */
732 sdw_master_read_prop(bus
);
734 /* BIOS is not giving some values correctly. So, lets override them */
735 bus
->prop
.num_freq
= 1;
736 bus
->prop
.freq
= devm_kcalloc(bus
->dev
, sizeof(*bus
->prop
.freq
),
737 bus
->prop
.num_freq
, GFP_KERNEL
);
741 bus
->prop
.freq
[0] = bus
->prop
.max_freq
;
742 bus
->prop
.err_threshold
= 5;
747 static struct sdw_master_ops sdw_intel_ops
= {
748 .read_prop
= sdw_master_read_prop
,
749 .xfer_msg
= cdns_xfer_msg
,
750 .xfer_msg_defer
= cdns_xfer_msg_defer
,
751 .reset_page_addr
= cdns_reset_page_addr
,
752 .set_bus_conf
= cdns_bus_conf
,
758 static int intel_probe(struct platform_device
*pdev
)
760 struct sdw_cdns_stream_config config
;
761 struct sdw_intel
*sdw
;
764 sdw
= devm_kzalloc(&pdev
->dev
, sizeof(*sdw
), GFP_KERNEL
);
768 sdw
->instance
= pdev
->id
;
769 sdw
->res
= dev_get_platdata(&pdev
->dev
);
770 sdw
->cdns
.dev
= &pdev
->dev
;
771 sdw
->cdns
.registers
= sdw
->res
->registers
;
772 sdw
->cdns
.instance
= sdw
->instance
;
773 sdw
->cdns
.msg_count
= 0;
774 sdw
->cdns
.bus
.dev
= &pdev
->dev
;
775 sdw
->cdns
.bus
.link_id
= pdev
->id
;
777 sdw_cdns_probe(&sdw
->cdns
);
779 /* Set property read ops */
780 sdw_intel_ops
.read_prop
= intel_prop_read
;
781 sdw
->cdns
.bus
.ops
= &sdw_intel_ops
;
783 sdw_intel_ops
.read_prop
= intel_prop_read
;
784 sdw
->cdns
.bus
.ops
= &sdw_intel_ops
;
786 platform_set_drvdata(pdev
, sdw
);
788 ret
= sdw_add_bus_master(&sdw
->cdns
.bus
);
790 dev_err(&pdev
->dev
, "sdw_add_bus_master fail: %d\n", ret
);
794 /* Initialize shim and controller */
795 intel_link_power_up(sdw
);
796 intel_shim_init(sdw
);
798 ret
= sdw_cdns_init(&sdw
->cdns
);
802 ret
= sdw_cdns_enable_interrupt(&sdw
->cdns
);
804 /* Read the PDI config and initialize cadence PDI */
805 intel_pdi_init(sdw
, &config
);
806 ret
= sdw_cdns_pdi_init(&sdw
->cdns
, config
);
810 intel_pdi_ch_update(sdw
);
813 ret
= request_threaded_irq(sdw
->res
->irq
, sdw_cdns_irq
,
814 sdw_cdns_thread
, IRQF_SHARED
, KBUILD_MODNAME
,
817 dev_err(sdw
->cdns
.dev
, "unable to grab IRQ %d, disabling device\n",
823 ret
= intel_register_dai(sdw
);
825 dev_err(sdw
->cdns
.dev
, "DAI registration failed: %d", ret
);
826 snd_soc_unregister_component(sdw
->cdns
.dev
);
833 free_irq(sdw
->res
->irq
, sdw
);
835 sdw_delete_bus_master(&sdw
->cdns
.bus
);
840 static int intel_remove(struct platform_device
*pdev
)
842 struct sdw_intel
*sdw
;
844 sdw
= platform_get_drvdata(pdev
);
846 free_irq(sdw
->res
->irq
, sdw
);
847 snd_soc_unregister_component(sdw
->cdns
.dev
);
848 sdw_delete_bus_master(&sdw
->cdns
.bus
);
853 static struct platform_driver sdw_intel_drv
= {
854 .probe
= intel_probe
,
855 .remove
= intel_remove
,
862 module_platform_driver(sdw_intel_drv
);
864 MODULE_LICENSE("Dual BSD/GPL");
865 MODULE_ALIAS("platform:int-sdw");
866 MODULE_DESCRIPTION("Intel Soundwire Master Driver");