]> Git Repo - linux.git/blob - drivers/soundwire/cadence_master.c
ARM: dts: imx7s: Enable SNVS power key according to board design
[linux.git] / drivers / soundwire / cadence_master.c
1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2 // Copyright(c) 2015-17 Intel Corporation.
3
4 /*
5  * Cadence SoundWire Master module
6  * Used by Master driver
7  */
8
9 #include <linux/delay.h>
10 #include <linux/device.h>
11 #include <linux/interrupt.h>
12 #include <linux/module.h>
13 #include <linux/mod_devicetable.h>
14 #include <linux/soundwire/sdw_registers.h>
15 #include <linux/soundwire/sdw.h>
16 #include <sound/pcm_params.h>
17 #include <sound/soc.h>
18 #include "bus.h"
19 #include "cadence_master.h"
20
21 #define CDNS_MCP_CONFIG                         0x0
22
23 #define CDNS_MCP_CONFIG_MCMD_RETRY              GENMASK(27, 24)
24 #define CDNS_MCP_CONFIG_MPREQ_DELAY             GENMASK(20, 16)
25 #define CDNS_MCP_CONFIG_MMASTER                 BIT(7)
26 #define CDNS_MCP_CONFIG_BUS_REL                 BIT(6)
27 #define CDNS_MCP_CONFIG_SNIFFER                 BIT(5)
28 #define CDNS_MCP_CONFIG_SSPMOD                  BIT(4)
29 #define CDNS_MCP_CONFIG_CMD                     BIT(3)
30 #define CDNS_MCP_CONFIG_OP                      GENMASK(2, 0)
31 #define CDNS_MCP_CONFIG_OP_NORMAL               0
32
33 #define CDNS_MCP_CONTROL                        0x4
34
35 #define CDNS_MCP_CONTROL_RST_DELAY              GENMASK(10, 8)
36 #define CDNS_MCP_CONTROL_CMD_RST                BIT(7)
37 #define CDNS_MCP_CONTROL_SOFT_RST               BIT(6)
38 #define CDNS_MCP_CONTROL_SW_RST                 BIT(5)
39 #define CDNS_MCP_CONTROL_HW_RST                 BIT(4)
40 #define CDNS_MCP_CONTROL_CLK_PAUSE              BIT(3)
41 #define CDNS_MCP_CONTROL_CLK_STOP_CLR           BIT(2)
42 #define CDNS_MCP_CONTROL_CMD_ACCEPT             BIT(1)
43 #define CDNS_MCP_CONTROL_BLOCK_WAKEUP           BIT(0)
44
45 #define CDNS_MCP_CMDCTRL                        0x8
46 #define CDNS_MCP_SSPSTAT                        0xC
47 #define CDNS_MCP_FRAME_SHAPE                    0x10
48 #define CDNS_MCP_FRAME_SHAPE_INIT               0x14
49
50 #define CDNS_MCP_CONFIG_UPDATE                  0x18
51 #define CDNS_MCP_CONFIG_UPDATE_BIT              BIT(0)
52
53 #define CDNS_MCP_PHYCTRL                        0x1C
54 #define CDNS_MCP_SSP_CTRL0                      0x20
55 #define CDNS_MCP_SSP_CTRL1                      0x28
56 #define CDNS_MCP_CLK_CTRL0                      0x30
57 #define CDNS_MCP_CLK_CTRL1                      0x38
58
59 #define CDNS_MCP_STAT                           0x40
60
61 #define CDNS_MCP_STAT_ACTIVE_BANK               BIT(20)
62 #define CDNS_MCP_STAT_CLK_STOP                  BIT(16)
63
64 #define CDNS_MCP_INTSTAT                        0x44
65 #define CDNS_MCP_INTMASK                        0x48
66
67 #define CDNS_MCP_INT_IRQ                        BIT(31)
68 #define CDNS_MCP_INT_WAKEUP                     BIT(16)
69 #define CDNS_MCP_INT_SLAVE_RSVD                 BIT(15)
70 #define CDNS_MCP_INT_SLAVE_ALERT                BIT(14)
71 #define CDNS_MCP_INT_SLAVE_ATTACH               BIT(13)
72 #define CDNS_MCP_INT_SLAVE_NATTACH              BIT(12)
73 #define CDNS_MCP_INT_SLAVE_MASK                 GENMASK(15, 12)
74 #define CDNS_MCP_INT_DPINT                      BIT(11)
75 #define CDNS_MCP_INT_CTRL_CLASH                 BIT(10)
76 #define CDNS_MCP_INT_DATA_CLASH                 BIT(9)
77 #define CDNS_MCP_INT_CMD_ERR                    BIT(7)
78 #define CDNS_MCP_INT_RX_WL                      BIT(2)
79 #define CDNS_MCP_INT_TXE                        BIT(1)
80
81 #define CDNS_MCP_INTSET                         0x4C
82
83 #define CDNS_SDW_SLAVE_STAT                     0x50
84 #define CDNS_MCP_SLAVE_STAT_MASK                BIT(1, 0)
85
86 #define CDNS_MCP_SLAVE_INTSTAT0                 0x54
87 #define CDNS_MCP_SLAVE_INTSTAT1                 0x58
88 #define CDNS_MCP_SLAVE_INTSTAT_NPRESENT         BIT(0)
89 #define CDNS_MCP_SLAVE_INTSTAT_ATTACHED         BIT(1)
90 #define CDNS_MCP_SLAVE_INTSTAT_ALERT            BIT(2)
91 #define CDNS_MCP_SLAVE_INTSTAT_RESERVED         BIT(3)
92 #define CDNS_MCP_SLAVE_STATUS_BITS              GENMASK(3, 0)
93 #define CDNS_MCP_SLAVE_STATUS_NUM               4
94
95 #define CDNS_MCP_SLAVE_INTMASK0                 0x5C
96 #define CDNS_MCP_SLAVE_INTMASK1                 0x60
97
98 #define CDNS_MCP_SLAVE_INTMASK0_MASK            GENMASK(30, 0)
99 #define CDNS_MCP_SLAVE_INTMASK1_MASK            GENMASK(16, 0)
100
101 #define CDNS_MCP_PORT_INTSTAT                   0x64
102 #define CDNS_MCP_PDI_STAT                       0x6C
103
104 #define CDNS_MCP_FIFOLEVEL                      0x78
105 #define CDNS_MCP_FIFOSTAT                       0x7C
106 #define CDNS_MCP_RX_FIFO_AVAIL                  GENMASK(5, 0)
107
108 #define CDNS_MCP_CMD_BASE                       0x80
109 #define CDNS_MCP_RESP_BASE                      0x80
110 #define CDNS_MCP_CMD_LEN                        0x20
111 #define CDNS_MCP_CMD_WORD_LEN                   0x4
112
113 #define CDNS_MCP_CMD_SSP_TAG                    BIT(31)
114 #define CDNS_MCP_CMD_COMMAND                    GENMASK(30, 28)
115 #define CDNS_MCP_CMD_DEV_ADDR                   GENMASK(27, 24)
116 #define CDNS_MCP_CMD_REG_ADDR_H                 GENMASK(23, 16)
117 #define CDNS_MCP_CMD_REG_ADDR_L                 GENMASK(15, 8)
118 #define CDNS_MCP_CMD_REG_DATA                   GENMASK(7, 0)
119
120 #define CDNS_MCP_CMD_READ                       2
121 #define CDNS_MCP_CMD_WRITE                      3
122
123 #define CDNS_MCP_RESP_RDATA                     GENMASK(15, 8)
124 #define CDNS_MCP_RESP_ACK                       BIT(0)
125 #define CDNS_MCP_RESP_NACK                      BIT(1)
126
127 #define CDNS_DP_SIZE                            128
128
129 #define CDNS_DPN_B0_CONFIG(n)                   (0x100 + CDNS_DP_SIZE * (n))
130 #define CDNS_DPN_B0_CH_EN(n)                    (0x104 + CDNS_DP_SIZE * (n))
131 #define CDNS_DPN_B0_SAMPLE_CTRL(n)              (0x108 + CDNS_DP_SIZE * (n))
132 #define CDNS_DPN_B0_OFFSET_CTRL(n)              (0x10C + CDNS_DP_SIZE * (n))
133 #define CDNS_DPN_B0_HCTRL(n)                    (0x110 + CDNS_DP_SIZE * (n))
134 #define CDNS_DPN_B0_ASYNC_CTRL(n)               (0x114 + CDNS_DP_SIZE * (n))
135
136 #define CDNS_DPN_B1_CONFIG(n)                   (0x118 + CDNS_DP_SIZE * (n))
137 #define CDNS_DPN_B1_CH_EN(n)                    (0x11C + CDNS_DP_SIZE * (n))
138 #define CDNS_DPN_B1_SAMPLE_CTRL(n)              (0x120 + CDNS_DP_SIZE * (n))
139 #define CDNS_DPN_B1_OFFSET_CTRL(n)              (0x124 + CDNS_DP_SIZE * (n))
140 #define CDNS_DPN_B1_HCTRL(n)                    (0x128 + CDNS_DP_SIZE * (n))
141 #define CDNS_DPN_B1_ASYNC_CTRL(n)               (0x12C + CDNS_DP_SIZE * (n))
142
143 #define CDNS_DPN_CONFIG_BPM                     BIT(18)
144 #define CDNS_DPN_CONFIG_BGC                     GENMASK(17, 16)
145 #define CDNS_DPN_CONFIG_WL                      GENMASK(12, 8)
146 #define CDNS_DPN_CONFIG_PORT_DAT                GENMASK(3, 2)
147 #define CDNS_DPN_CONFIG_PORT_FLOW               GENMASK(1, 0)
148
149 #define CDNS_DPN_SAMPLE_CTRL_SI                 GENMASK(15, 0)
150
151 #define CDNS_DPN_OFFSET_CTRL_1                  GENMASK(7, 0)
152 #define CDNS_DPN_OFFSET_CTRL_2                  GENMASK(15, 8)
153
154 #define CDNS_DPN_HCTRL_HSTOP                    GENMASK(3, 0)
155 #define CDNS_DPN_HCTRL_HSTART                   GENMASK(7, 4)
156 #define CDNS_DPN_HCTRL_LCTRL                    GENMASK(10, 8)
157
158 #define CDNS_PORTCTRL                           0x130
159 #define CDNS_PORTCTRL_DIRN                      BIT(7)
160 #define CDNS_PORTCTRL_BANK_INVERT               BIT(8)
161
162 #define CDNS_PORT_OFFSET                        0x80
163
164 #define CDNS_PDI_CONFIG(n)                      (0x1100 + (n) * 16)
165
166 #define CDNS_PDI_CONFIG_SOFT_RESET              BIT(24)
167 #define CDNS_PDI_CONFIG_CHANNEL                 GENMASK(15, 8)
168 #define CDNS_PDI_CONFIG_PORT                    GENMASK(4, 0)
169
170 /* Driver defaults */
171
172 #define CDNS_DEFAULT_CLK_DIVIDER                0
173 #define CDNS_DEFAULT_FRAME_SHAPE                0x30
174 #define CDNS_DEFAULT_SSP_INTERVAL               0x18
175 #define CDNS_TX_TIMEOUT                         2000
176
177 #define CDNS_PCM_PDI_OFFSET                     0x2
178 #define CDNS_PDM_PDI_OFFSET                     0x6
179
180 #define CDNS_SCP_RX_FIFOLEVEL                   0x2
181
182 /*
183  * register accessor helpers
184  */
185 static inline u32 cdns_readl(struct sdw_cdns *cdns, int offset)
186 {
187         return readl(cdns->registers + offset);
188 }
189
190 static inline void cdns_writel(struct sdw_cdns *cdns, int offset, u32 value)
191 {
192         writel(value, cdns->registers + offset);
193 }
194
195 static inline void cdns_updatel(struct sdw_cdns *cdns,
196                                 int offset, u32 mask, u32 val)
197 {
198         u32 tmp;
199
200         tmp = cdns_readl(cdns, offset);
201         tmp = (tmp & ~mask) | val;
202         cdns_writel(cdns, offset, tmp);
203 }
204
205 static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
206 {
207         int timeout = 10;
208         u32 reg_read;
209
210         writel(value, cdns->registers + offset);
211
212         /* Wait for bit to be self cleared */
213         do {
214                 reg_read = readl(cdns->registers + offset);
215                 if ((reg_read & value) == 0)
216                         return 0;
217
218                 timeout--;
219                 udelay(50);
220         } while (timeout != 0);
221
222         return -EAGAIN;
223 }
224
225 /*
226  * IO Calls
227  */
228 static enum sdw_command_response
229 cdns_fill_msg_resp(struct sdw_cdns *cdns,
230                    struct sdw_msg *msg, int count, int offset)
231 {
232         int nack = 0, no_ack = 0;
233         int i;
234
235         /* check message response */
236         for (i = 0; i < count; i++) {
237                 if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
238                         no_ack = 1;
239                         dev_dbg(cdns->dev, "Msg Ack not received\n");
240                         if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
241                                 nack = 1;
242                                 dev_err(cdns->dev, "Msg NACK received\n");
243                         }
244                 }
245         }
246
247         if (nack) {
248                 dev_err(cdns->dev, "Msg NACKed for Slave %d\n", msg->dev_num);
249                 return SDW_CMD_FAIL;
250         } else if (no_ack) {
251                 dev_dbg(cdns->dev, "Msg ignored for Slave %d\n", msg->dev_num);
252                 return SDW_CMD_IGNORED;
253         }
254
255         /* fill response */
256         for (i = 0; i < count; i++)
257                 msg->buf[i + offset] = cdns->response_buf[i] >>
258                                 SDW_REG_SHIFT(CDNS_MCP_RESP_RDATA);
259
260         return SDW_CMD_OK;
261 }
262
263 static enum sdw_command_response
264 _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,
265                int offset, int count, bool defer)
266 {
267         unsigned long time;
268         u32 base, i, data;
269         u16 addr;
270
271         /* Program the watermark level for RX FIFO */
272         if (cdns->msg_count != count) {
273                 cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, count);
274                 cdns->msg_count = count;
275         }
276
277         base = CDNS_MCP_CMD_BASE;
278         addr = msg->addr;
279
280         for (i = 0; i < count; i++) {
281                 data = msg->dev_num << SDW_REG_SHIFT(CDNS_MCP_CMD_DEV_ADDR);
282                 data |= cmd << SDW_REG_SHIFT(CDNS_MCP_CMD_COMMAND);
283                 data |= addr++  << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L);
284
285                 if (msg->flags == SDW_MSG_FLAG_WRITE)
286                         data |= msg->buf[i + offset];
287
288                 data |= msg->ssp_sync << SDW_REG_SHIFT(CDNS_MCP_CMD_SSP_TAG);
289                 cdns_writel(cdns, base, data);
290                 base += CDNS_MCP_CMD_WORD_LEN;
291         }
292
293         if (defer)
294                 return SDW_CMD_OK;
295
296         /* wait for timeout or response */
297         time = wait_for_completion_timeout(&cdns->tx_complete,
298                                            msecs_to_jiffies(CDNS_TX_TIMEOUT));
299         if (!time) {
300                 dev_err(cdns->dev, "IO transfer timed out\n");
301                 msg->len = 0;
302                 return SDW_CMD_TIMEOUT;
303         }
304
305         return cdns_fill_msg_resp(cdns, msg, count, offset);
306 }
307
308 static enum sdw_command_response
309 cdns_program_scp_addr(struct sdw_cdns *cdns, struct sdw_msg *msg)
310 {
311         int nack = 0, no_ack = 0;
312         unsigned long time;
313         u32 data[2], base;
314         int i;
315
316         /* Program the watermark level for RX FIFO */
317         if (cdns->msg_count != CDNS_SCP_RX_FIFOLEVEL) {
318                 cdns_writel(cdns, CDNS_MCP_FIFOLEVEL, CDNS_SCP_RX_FIFOLEVEL);
319                 cdns->msg_count = CDNS_SCP_RX_FIFOLEVEL;
320         }
321
322         data[0] = msg->dev_num << SDW_REG_SHIFT(CDNS_MCP_CMD_DEV_ADDR);
323         data[0] |= 0x3 << SDW_REG_SHIFT(CDNS_MCP_CMD_COMMAND);
324         data[1] = data[0];
325
326         data[0] |= SDW_SCP_ADDRPAGE1 << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L);
327         data[1] |= SDW_SCP_ADDRPAGE2 << SDW_REG_SHIFT(CDNS_MCP_CMD_REG_ADDR_L);
328
329         data[0] |= msg->addr_page1;
330         data[1] |= msg->addr_page2;
331
332         base = CDNS_MCP_CMD_BASE;
333         cdns_writel(cdns, base, data[0]);
334         base += CDNS_MCP_CMD_WORD_LEN;
335         cdns_writel(cdns, base, data[1]);
336
337         time = wait_for_completion_timeout(&cdns->tx_complete,
338                                            msecs_to_jiffies(CDNS_TX_TIMEOUT));
339         if (!time) {
340                 dev_err(cdns->dev, "SCP Msg trf timed out\n");
341                 msg->len = 0;
342                 return SDW_CMD_TIMEOUT;
343         }
344
345         /* check response the writes */
346         for (i = 0; i < 2; i++) {
347                 if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) {
348                         no_ack = 1;
349                         dev_err(cdns->dev, "Program SCP Ack not received\n");
350                         if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) {
351                                 nack = 1;
352                                 dev_err(cdns->dev, "Program SCP NACK received\n");
353                         }
354                 }
355         }
356
357         /* For NACK, NO ack, don't return err if we are in Broadcast mode */
358         if (nack) {
359                 dev_err(cdns->dev,
360                         "SCP_addrpage NACKed for Slave %d\n", msg->dev_num);
361                 return SDW_CMD_FAIL;
362         } else if (no_ack) {
363                 dev_dbg(cdns->dev,
364                         "SCP_addrpage ignored for Slave %d\n", msg->dev_num);
365                 return SDW_CMD_IGNORED;
366         }
367
368         return SDW_CMD_OK;
369 }
370
371 static int cdns_prep_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int *cmd)
372 {
373         int ret;
374
375         if (msg->page) {
376                 ret = cdns_program_scp_addr(cdns, msg);
377                 if (ret) {
378                         msg->len = 0;
379                         return ret;
380                 }
381         }
382
383         switch (msg->flags) {
384         case SDW_MSG_FLAG_READ:
385                 *cmd = CDNS_MCP_CMD_READ;
386                 break;
387
388         case SDW_MSG_FLAG_WRITE:
389                 *cmd = CDNS_MCP_CMD_WRITE;
390                 break;
391
392         default:
393                 dev_err(cdns->dev, "Invalid msg cmd: %d\n", msg->flags);
394                 return -EINVAL;
395         }
396
397         return 0;
398 }
399
400 enum sdw_command_response
401 cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg)
402 {
403         struct sdw_cdns *cdns = bus_to_cdns(bus);
404         int cmd = 0, ret, i;
405
406         ret = cdns_prep_msg(cdns, msg, &cmd);
407         if (ret)
408                 return SDW_CMD_FAIL_OTHER;
409
410         for (i = 0; i < msg->len / CDNS_MCP_CMD_LEN; i++) {
411                 ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
412                                      CDNS_MCP_CMD_LEN, false);
413                 if (ret < 0)
414                         goto exit;
415         }
416
417         if (!(msg->len % CDNS_MCP_CMD_LEN))
418                 goto exit;
419
420         ret = _cdns_xfer_msg(cdns, msg, cmd, i * CDNS_MCP_CMD_LEN,
421                              msg->len % CDNS_MCP_CMD_LEN, false);
422
423 exit:
424         return ret;
425 }
426 EXPORT_SYMBOL(cdns_xfer_msg);
427
428 enum sdw_command_response
429 cdns_xfer_msg_defer(struct sdw_bus *bus,
430                     struct sdw_msg *msg, struct sdw_defer *defer)
431 {
432         struct sdw_cdns *cdns = bus_to_cdns(bus);
433         int cmd = 0, ret;
434
435         /* for defer only 1 message is supported */
436         if (msg->len > 1)
437                 return -ENOTSUPP;
438
439         ret = cdns_prep_msg(cdns, msg, &cmd);
440         if (ret)
441                 return SDW_CMD_FAIL_OTHER;
442
443         cdns->defer = defer;
444         cdns->defer->length = msg->len;
445
446         return _cdns_xfer_msg(cdns, msg, cmd, 0, msg->len, true);
447 }
448 EXPORT_SYMBOL(cdns_xfer_msg_defer);
449
450 enum sdw_command_response
451 cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num)
452 {
453         struct sdw_cdns *cdns = bus_to_cdns(bus);
454         struct sdw_msg msg;
455
456         /* Create dummy message with valid device number */
457         memset(&msg, 0, sizeof(msg));
458         msg.dev_num = dev_num;
459
460         return cdns_program_scp_addr(cdns, &msg);
461 }
462 EXPORT_SYMBOL(cdns_reset_page_addr);
463
464 /*
465  * IRQ handling
466  */
467
468 static void cdns_read_response(struct sdw_cdns *cdns)
469 {
470         u32 num_resp, cmd_base;
471         int i;
472
473         num_resp = cdns_readl(cdns, CDNS_MCP_FIFOSTAT);
474         num_resp &= CDNS_MCP_RX_FIFO_AVAIL;
475
476         cmd_base = CDNS_MCP_CMD_BASE;
477
478         for (i = 0; i < num_resp; i++) {
479                 cdns->response_buf[i] = cdns_readl(cdns, cmd_base);
480                 cmd_base += CDNS_MCP_CMD_WORD_LEN;
481         }
482 }
483
484 static int cdns_update_slave_status(struct sdw_cdns *cdns,
485                                     u32 slave0, u32 slave1)
486 {
487         enum sdw_slave_status status[SDW_MAX_DEVICES + 1];
488         bool is_slave = false;
489         u64 slave, mask;
490         int i, set_status;
491
492         /* combine the two status */
493         slave = ((u64)slave1 << 32) | slave0;
494         memset(status, 0, sizeof(status));
495
496         for (i = 0; i <= SDW_MAX_DEVICES; i++) {
497                 mask = (slave >> (i * CDNS_MCP_SLAVE_STATUS_NUM)) &
498                                 CDNS_MCP_SLAVE_STATUS_BITS;
499                 if (!mask)
500                         continue;
501
502                 is_slave = true;
503                 set_status = 0;
504
505                 if (mask & CDNS_MCP_SLAVE_INTSTAT_RESERVED) {
506                         status[i] = SDW_SLAVE_RESERVED;
507                         set_status++;
508                 }
509
510                 if (mask & CDNS_MCP_SLAVE_INTSTAT_ATTACHED) {
511                         status[i] = SDW_SLAVE_ATTACHED;
512                         set_status++;
513                 }
514
515                 if (mask & CDNS_MCP_SLAVE_INTSTAT_ALERT) {
516                         status[i] = SDW_SLAVE_ALERT;
517                         set_status++;
518                 }
519
520                 if (mask & CDNS_MCP_SLAVE_INTSTAT_NPRESENT) {
521                         status[i] = SDW_SLAVE_UNATTACHED;
522                         set_status++;
523                 }
524
525                 /* first check if Slave reported multiple status */
526                 if (set_status > 1) {
527                         dev_warn(cdns->dev,
528                                  "Slave reported multiple Status: %d\n",
529                                  status[i]);
530                         /*
531                          * TODO: we need to reread the status here by
532                          * issuing a PING cmd
533                          */
534                 }
535         }
536
537         if (is_slave)
538                 return sdw_handle_slave_status(&cdns->bus, status);
539
540         return 0;
541 }
542
543 /**
544  * sdw_cdns_irq() - Cadence interrupt handler
545  * @irq: irq number
546  * @dev_id: irq context
547  */
548 irqreturn_t sdw_cdns_irq(int irq, void *dev_id)
549 {
550         struct sdw_cdns *cdns = dev_id;
551         u32 int_status;
552         int ret = IRQ_HANDLED;
553
554         /* Check if the link is up */
555         if (!cdns->link_up)
556                 return IRQ_NONE;
557
558         int_status = cdns_readl(cdns, CDNS_MCP_INTSTAT);
559
560         if (!(int_status & CDNS_MCP_INT_IRQ))
561                 return IRQ_NONE;
562
563         if (int_status & CDNS_MCP_INT_RX_WL) {
564                 cdns_read_response(cdns);
565
566                 if (cdns->defer) {
567                         cdns_fill_msg_resp(cdns, cdns->defer->msg,
568                                            cdns->defer->length, 0);
569                         complete(&cdns->defer->complete);
570                         cdns->defer = NULL;
571                 } else {
572                         complete(&cdns->tx_complete);
573                 }
574         }
575
576         if (int_status & CDNS_MCP_INT_CTRL_CLASH) {
577                 /* Slave is driving bit slot during control word */
578                 dev_err_ratelimited(cdns->dev, "Bus clash for control word\n");
579                 int_status |= CDNS_MCP_INT_CTRL_CLASH;
580         }
581
582         if (int_status & CDNS_MCP_INT_DATA_CLASH) {
583                 /*
584                  * Multiple slaves trying to drive bit slot, or issue with
585                  * ownership of data bits or Slave gone bonkers
586                  */
587                 dev_err_ratelimited(cdns->dev, "Bus clash for data word\n");
588                 int_status |= CDNS_MCP_INT_DATA_CLASH;
589         }
590
591         if (int_status & CDNS_MCP_INT_SLAVE_MASK) {
592                 /* Mask the Slave interrupt and wake thread */
593                 cdns_updatel(cdns, CDNS_MCP_INTMASK,
594                              CDNS_MCP_INT_SLAVE_MASK, 0);
595
596                 int_status &= ~CDNS_MCP_INT_SLAVE_MASK;
597                 ret = IRQ_WAKE_THREAD;
598         }
599
600         cdns_writel(cdns, CDNS_MCP_INTSTAT, int_status);
601         return ret;
602 }
603 EXPORT_SYMBOL(sdw_cdns_irq);
604
605 /**
606  * sdw_cdns_thread() - Cadence irq thread handler
607  * @irq: irq number
608  * @dev_id: irq context
609  */
610 irqreturn_t sdw_cdns_thread(int irq, void *dev_id)
611 {
612         struct sdw_cdns *cdns = dev_id;
613         u32 slave0, slave1;
614
615         dev_dbg(cdns->dev, "Slave status change\n");
616
617         slave0 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT0);
618         slave1 = cdns_readl(cdns, CDNS_MCP_SLAVE_INTSTAT1);
619
620         cdns_update_slave_status(cdns, slave0, slave1);
621         cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT0, slave0);
622         cdns_writel(cdns, CDNS_MCP_SLAVE_INTSTAT1, slave1);
623
624         /* clear and unmask Slave interrupt now */
625         cdns_writel(cdns, CDNS_MCP_INTSTAT, CDNS_MCP_INT_SLAVE_MASK);
626         cdns_updatel(cdns, CDNS_MCP_INTMASK,
627                      CDNS_MCP_INT_SLAVE_MASK, CDNS_MCP_INT_SLAVE_MASK);
628
629         return IRQ_HANDLED;
630 }
631 EXPORT_SYMBOL(sdw_cdns_thread);
632
633 /*
634  * init routines
635  */
636 static int _cdns_enable_interrupt(struct sdw_cdns *cdns)
637 {
638         u32 mask;
639
640         cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK0,
641                     CDNS_MCP_SLAVE_INTMASK0_MASK);
642         cdns_writel(cdns, CDNS_MCP_SLAVE_INTMASK1,
643                     CDNS_MCP_SLAVE_INTMASK1_MASK);
644
645         mask = CDNS_MCP_INT_SLAVE_RSVD | CDNS_MCP_INT_SLAVE_ALERT |
646                 CDNS_MCP_INT_SLAVE_ATTACH | CDNS_MCP_INT_SLAVE_NATTACH |
647                 CDNS_MCP_INT_CTRL_CLASH | CDNS_MCP_INT_DATA_CLASH |
648                 CDNS_MCP_INT_RX_WL | CDNS_MCP_INT_IRQ | CDNS_MCP_INT_DPINT;
649
650         cdns_writel(cdns, CDNS_MCP_INTMASK, mask);
651
652         return 0;
653 }
654
655 /**
656  * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config
657  * @cdns: Cadence instance
658  */
659 int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns)
660 {
661         int ret;
662
663         _cdns_enable_interrupt(cdns);
664         ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
665                              CDNS_MCP_CONFIG_UPDATE_BIT);
666         if (ret < 0)
667                 dev_err(cdns->dev, "Config update timedout\n");
668
669         return ret;
670 }
671 EXPORT_SYMBOL(sdw_cdns_enable_interrupt);
672
673 static int cdns_allocate_pdi(struct sdw_cdns *cdns,
674                              struct sdw_cdns_pdi **stream,
675                              u32 num, u32 pdi_offset)
676 {
677         struct sdw_cdns_pdi *pdi;
678         int i;
679
680         if (!num)
681                 return 0;
682
683         pdi = devm_kcalloc(cdns->dev, num, sizeof(*pdi), GFP_KERNEL);
684         if (!pdi)
685                 return -ENOMEM;
686
687         for (i = 0; i < num; i++) {
688                 pdi[i].num = i + pdi_offset;
689                 pdi[i].assigned = false;
690         }
691
692         *stream = pdi;
693         return 0;
694 }
695
696 /**
697  * sdw_cdns_pdi_init() - PDI initialization routine
698  *
699  * @cdns: Cadence instance
700  * @config: Stream configurations
701  */
702 int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
703                       struct sdw_cdns_stream_config config)
704 {
705         struct sdw_cdns_streams *stream;
706         int offset, i, ret;
707
708         cdns->pcm.num_bd = config.pcm_bd;
709         cdns->pcm.num_in = config.pcm_in;
710         cdns->pcm.num_out = config.pcm_out;
711         cdns->pdm.num_bd = config.pdm_bd;
712         cdns->pdm.num_in = config.pdm_in;
713         cdns->pdm.num_out = config.pdm_out;
714
715         /* Allocate PDIs for PCMs */
716         stream = &cdns->pcm;
717
718         /* First two PDIs are reserved for bulk transfers */
719         stream->num_bd -= CDNS_PCM_PDI_OFFSET;
720         offset = CDNS_PCM_PDI_OFFSET;
721
722         ret = cdns_allocate_pdi(cdns, &stream->bd,
723                                 stream->num_bd, offset);
724         if (ret)
725                 return ret;
726
727         offset += stream->num_bd;
728
729         ret = cdns_allocate_pdi(cdns, &stream->in,
730                                 stream->num_in, offset);
731         if (ret)
732                 return ret;
733
734         offset += stream->num_in;
735
736         ret = cdns_allocate_pdi(cdns, &stream->out,
737                                 stream->num_out, offset);
738         if (ret)
739                 return ret;
740
741         /* Update total number of PCM PDIs */
742         stream->num_pdi = stream->num_bd + stream->num_in + stream->num_out;
743         cdns->num_ports = stream->num_pdi;
744
745         /* Allocate PDIs for PDMs */
746         stream = &cdns->pdm;
747         offset = CDNS_PDM_PDI_OFFSET;
748         ret = cdns_allocate_pdi(cdns, &stream->bd,
749                                 stream->num_bd, offset);
750         if (ret)
751                 return ret;
752
753         offset += stream->num_bd;
754
755         ret = cdns_allocate_pdi(cdns, &stream->in,
756                                 stream->num_in, offset);
757         if (ret)
758                 return ret;
759
760         offset += stream->num_in;
761
762         ret = cdns_allocate_pdi(cdns, &stream->out,
763                                 stream->num_out, offset);
764         if (ret)
765                 return ret;
766
767         /* Update total number of PDM PDIs */
768         stream->num_pdi = stream->num_bd + stream->num_in + stream->num_out;
769         cdns->num_ports += stream->num_pdi;
770
771         cdns->ports = devm_kcalloc(cdns->dev, cdns->num_ports,
772                                    sizeof(*cdns->ports), GFP_KERNEL);
773         if (!cdns->ports) {
774                 ret = -ENOMEM;
775                 return ret;
776         }
777
778         for (i = 0; i < cdns->num_ports; i++) {
779                 cdns->ports[i].assigned = false;
780                 cdns->ports[i].num = i + 1; /* Port 0 reserved for bulk */
781         }
782
783         return 0;
784 }
785 EXPORT_SYMBOL(sdw_cdns_pdi_init);
786
787 /**
788  * sdw_cdns_init() - Cadence initialization
789  * @cdns: Cadence instance
790  */
791 int sdw_cdns_init(struct sdw_cdns *cdns)
792 {
793         u32 val;
794         int ret;
795
796         /* Exit clock stop */
797         ret = cdns_clear_bit(cdns, CDNS_MCP_CONTROL,
798                              CDNS_MCP_CONTROL_CLK_STOP_CLR);
799         if (ret < 0) {
800                 dev_err(cdns->dev, "Couldn't exit from clock stop\n");
801                 return ret;
802         }
803
804         /* Set clock divider */
805         val = cdns_readl(cdns, CDNS_MCP_CLK_CTRL0);
806         val |= CDNS_DEFAULT_CLK_DIVIDER;
807         cdns_writel(cdns, CDNS_MCP_CLK_CTRL0, val);
808
809         /* Set the default frame shape */
810         cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, CDNS_DEFAULT_FRAME_SHAPE);
811
812         /* Set SSP interval to default value */
813         cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL);
814         cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, CDNS_DEFAULT_SSP_INTERVAL);
815
816         /* Set cmd accept mode */
817         cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT,
818                      CDNS_MCP_CONTROL_CMD_ACCEPT);
819
820         /* Configure mcp config */
821         val = cdns_readl(cdns, CDNS_MCP_CONFIG);
822
823         /* Set Max cmd retry to 15 */
824         val |= CDNS_MCP_CONFIG_MCMD_RETRY;
825
826         /* Set frame delay between PREQ and ping frame to 15 frames */
827         val |= 0xF << SDW_REG_SHIFT(CDNS_MCP_CONFIG_MPREQ_DELAY);
828
829         /* Disable auto bus release */
830         val &= ~CDNS_MCP_CONFIG_BUS_REL;
831
832         /* Disable sniffer mode */
833         val &= ~CDNS_MCP_CONFIG_SNIFFER;
834
835         /* Set cmd mode for Tx and Rx cmds */
836         val &= ~CDNS_MCP_CONFIG_CMD;
837
838         /* Set operation to normal */
839         val &= ~CDNS_MCP_CONFIG_OP;
840         val |= CDNS_MCP_CONFIG_OP_NORMAL;
841
842         cdns_writel(cdns, CDNS_MCP_CONFIG, val);
843
844         return 0;
845 }
846 EXPORT_SYMBOL(sdw_cdns_init);
847
848 int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params)
849 {
850         struct sdw_cdns *cdns = bus_to_cdns(bus);
851         int mcp_clkctrl_off, mcp_clkctrl;
852         int divider;
853
854         if (!params->curr_dr_freq) {
855                 dev_err(cdns->dev, "NULL curr_dr_freq\n");
856                 return -EINVAL;
857         }
858
859         divider = (params->max_dr_freq / params->curr_dr_freq) - 1;
860
861         if (params->next_bank)
862                 mcp_clkctrl_off = CDNS_MCP_CLK_CTRL1;
863         else
864                 mcp_clkctrl_off = CDNS_MCP_CLK_CTRL0;
865
866         mcp_clkctrl = cdns_readl(cdns, mcp_clkctrl_off);
867         mcp_clkctrl |= divider;
868         cdns_writel(cdns, mcp_clkctrl_off, mcp_clkctrl);
869
870         return 0;
871 }
872 EXPORT_SYMBOL(cdns_bus_conf);
873
874 static int cdns_port_params(struct sdw_bus *bus,
875                             struct sdw_port_params *p_params, unsigned int bank)
876 {
877         struct sdw_cdns *cdns = bus_to_cdns(bus);
878         int dpn_config = 0, dpn_config_off;
879
880         if (bank)
881                 dpn_config_off = CDNS_DPN_B1_CONFIG(p_params->num);
882         else
883                 dpn_config_off = CDNS_DPN_B0_CONFIG(p_params->num);
884
885         dpn_config = cdns_readl(cdns, dpn_config_off);
886
887         dpn_config |= ((p_params->bps - 1) <<
888                                 SDW_REG_SHIFT(CDNS_DPN_CONFIG_WL));
889         dpn_config |= (p_params->flow_mode <<
890                                 SDW_REG_SHIFT(CDNS_DPN_CONFIG_PORT_FLOW));
891         dpn_config |= (p_params->data_mode <<
892                                 SDW_REG_SHIFT(CDNS_DPN_CONFIG_PORT_DAT));
893
894         cdns_writel(cdns, dpn_config_off, dpn_config);
895
896         return 0;
897 }
898
899 static int cdns_transport_params(struct sdw_bus *bus,
900                                  struct sdw_transport_params *t_params,
901                                  enum sdw_reg_bank bank)
902 {
903         struct sdw_cdns *cdns = bus_to_cdns(bus);
904         int dpn_offsetctrl = 0, dpn_offsetctrl_off;
905         int dpn_config = 0, dpn_config_off;
906         int dpn_hctrl = 0, dpn_hctrl_off;
907         int num = t_params->port_num;
908         int dpn_samplectrl_off;
909
910         /*
911          * Note: Only full data port is supported on the Master side for
912          * both PCM and PDM ports.
913          */
914
915         if (bank) {
916                 dpn_config_off = CDNS_DPN_B1_CONFIG(num);
917                 dpn_samplectrl_off = CDNS_DPN_B1_SAMPLE_CTRL(num);
918                 dpn_hctrl_off = CDNS_DPN_B1_HCTRL(num);
919                 dpn_offsetctrl_off = CDNS_DPN_B1_OFFSET_CTRL(num);
920         } else {
921                 dpn_config_off = CDNS_DPN_B0_CONFIG(num);
922                 dpn_samplectrl_off = CDNS_DPN_B0_SAMPLE_CTRL(num);
923                 dpn_hctrl_off = CDNS_DPN_B0_HCTRL(num);
924                 dpn_offsetctrl_off = CDNS_DPN_B0_OFFSET_CTRL(num);
925         }
926
927         dpn_config = cdns_readl(cdns, dpn_config_off);
928
929         dpn_config |= (t_params->blk_grp_ctrl <<
930                                 SDW_REG_SHIFT(CDNS_DPN_CONFIG_BGC));
931         dpn_config |= (t_params->blk_pkg_mode <<
932                                 SDW_REG_SHIFT(CDNS_DPN_CONFIG_BPM));
933         cdns_writel(cdns, dpn_config_off, dpn_config);
934
935         dpn_offsetctrl |= (t_params->offset1 <<
936                                 SDW_REG_SHIFT(CDNS_DPN_OFFSET_CTRL_1));
937         dpn_offsetctrl |= (t_params->offset2 <<
938                                 SDW_REG_SHIFT(CDNS_DPN_OFFSET_CTRL_2));
939         cdns_writel(cdns, dpn_offsetctrl_off,  dpn_offsetctrl);
940
941         dpn_hctrl |= (t_params->hstart <<
942                                 SDW_REG_SHIFT(CDNS_DPN_HCTRL_HSTART));
943         dpn_hctrl |= (t_params->hstop << SDW_REG_SHIFT(CDNS_DPN_HCTRL_HSTOP));
944         dpn_hctrl |= (t_params->lane_ctrl <<
945                                 SDW_REG_SHIFT(CDNS_DPN_HCTRL_LCTRL));
946
947         cdns_writel(cdns, dpn_hctrl_off, dpn_hctrl);
948         cdns_writel(cdns, dpn_samplectrl_off, (t_params->sample_interval - 1));
949
950         return 0;
951 }
952
953 static int cdns_port_enable(struct sdw_bus *bus,
954                             struct sdw_enable_ch *enable_ch, unsigned int bank)
955 {
956         struct sdw_cdns *cdns = bus_to_cdns(bus);
957         int dpn_chnen_off, ch_mask;
958
959         if (bank)
960                 dpn_chnen_off = CDNS_DPN_B1_CH_EN(enable_ch->port_num);
961         else
962                 dpn_chnen_off = CDNS_DPN_B0_CH_EN(enable_ch->port_num);
963
964         ch_mask = enable_ch->ch_mask * enable_ch->enable;
965         cdns_writel(cdns, dpn_chnen_off, ch_mask);
966
967         return 0;
968 }
969
970 static const struct sdw_master_port_ops cdns_port_ops = {
971         .dpn_set_port_params = cdns_port_params,
972         .dpn_set_port_transport_params = cdns_transport_params,
973         .dpn_port_enable_ch = cdns_port_enable,
974 };
975
976 /**
977  * sdw_cdns_probe() - Cadence probe routine
978  * @cdns: Cadence instance
979  */
980 int sdw_cdns_probe(struct sdw_cdns *cdns)
981 {
982         init_completion(&cdns->tx_complete);
983         cdns->bus.port_ops = &cdns_port_ops;
984
985         return 0;
986 }
987 EXPORT_SYMBOL(sdw_cdns_probe);
988
989 int cdns_set_sdw_stream(struct snd_soc_dai *dai,
990                         void *stream, bool pcm, int direction)
991 {
992         struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
993         struct sdw_cdns_dma_data *dma;
994
995         dma = kzalloc(sizeof(*dma), GFP_KERNEL);
996         if (!dma)
997                 return -ENOMEM;
998
999         if (pcm)
1000                 dma->stream_type = SDW_STREAM_PCM;
1001         else
1002                 dma->stream_type = SDW_STREAM_PDM;
1003
1004         dma->bus = &cdns->bus;
1005         dma->link_id = cdns->instance;
1006
1007         dma->stream = stream;
1008
1009         if (direction == SNDRV_PCM_STREAM_PLAYBACK)
1010                 dai->playback_dma_data = dma;
1011         else
1012                 dai->capture_dma_data = dma;
1013
1014         return 0;
1015 }
1016 EXPORT_SYMBOL(cdns_set_sdw_stream);
1017
1018 /**
1019  * cdns_find_pdi() - Find a free PDI
1020  *
1021  * @cdns: Cadence instance
1022  * @num: Number of PDIs
1023  * @pdi: PDI instances
1024  *
1025  * Find and return a free PDI for a given PDI array
1026  */
1027 static struct sdw_cdns_pdi *cdns_find_pdi(struct sdw_cdns *cdns,
1028                                           unsigned int num,
1029                                           struct sdw_cdns_pdi *pdi)
1030 {
1031         int i;
1032
1033         for (i = 0; i < num; i++) {
1034                 if (pdi[i].assigned)
1035                         continue;
1036                 pdi[i].assigned = true;
1037                 return &pdi[i];
1038         }
1039
1040         return NULL;
1041 }
1042
1043 /**
1044  * sdw_cdns_config_stream: Configure a stream
1045  *
1046  * @cdns: Cadence instance
1047  * @port: Cadence data port
1048  * @ch: Channel count
1049  * @dir: Data direction
1050  * @pdi: PDI to be used
1051  */
1052 void sdw_cdns_config_stream(struct sdw_cdns *cdns,
1053                             struct sdw_cdns_port *port,
1054                             u32 ch, u32 dir, struct sdw_cdns_pdi *pdi)
1055 {
1056         u32 offset, val = 0;
1057
1058         if (dir == SDW_DATA_DIR_RX)
1059                 val = CDNS_PORTCTRL_DIRN;
1060
1061         offset = CDNS_PORTCTRL + port->num * CDNS_PORT_OFFSET;
1062         cdns_updatel(cdns, offset, CDNS_PORTCTRL_DIRN, val);
1063
1064         val = port->num;
1065         val |= ((1 << ch) - 1) << SDW_REG_SHIFT(CDNS_PDI_CONFIG_CHANNEL);
1066         cdns_writel(cdns, CDNS_PDI_CONFIG(pdi->num), val);
1067 }
1068 EXPORT_SYMBOL(sdw_cdns_config_stream);
1069
1070 /**
1071  * cdns_get_num_pdi() - Get number of PDIs required
1072  *
1073  * @cdns: Cadence instance
1074  * @pdi: PDI to be used
1075  * @num: Number of PDIs
1076  * @ch_count: Channel count
1077  */
1078 static int cdns_get_num_pdi(struct sdw_cdns *cdns,
1079                             struct sdw_cdns_pdi *pdi,
1080                             unsigned int num, u32 ch_count)
1081 {
1082         int i, pdis = 0;
1083
1084         for (i = 0; i < num; i++) {
1085                 if (pdi[i].assigned)
1086                         continue;
1087
1088                 if (pdi[i].ch_count < ch_count)
1089                         ch_count -= pdi[i].ch_count;
1090                 else
1091                         ch_count = 0;
1092
1093                 pdis++;
1094
1095                 if (!ch_count)
1096                         break;
1097         }
1098
1099         if (ch_count)
1100                 return 0;
1101
1102         return pdis;
1103 }
1104
1105 /**
1106  * sdw_cdns_get_stream() - Get stream information
1107  *
1108  * @cdns: Cadence instance
1109  * @stream: Stream to be allocated
1110  * @ch: Channel count
1111  * @dir: Data direction
1112  */
1113 int sdw_cdns_get_stream(struct sdw_cdns *cdns,
1114                         struct sdw_cdns_streams *stream,
1115                         u32 ch, u32 dir)
1116 {
1117         int pdis = 0;
1118
1119         if (dir == SDW_DATA_DIR_RX)
1120                 pdis = cdns_get_num_pdi(cdns, stream->in, stream->num_in, ch);
1121         else
1122                 pdis = cdns_get_num_pdi(cdns, stream->out, stream->num_out, ch);
1123
1124         /* check if we found PDI, else find in bi-directional */
1125         if (!pdis)
1126                 pdis = cdns_get_num_pdi(cdns, stream->bd, stream->num_bd, ch);
1127
1128         return pdis;
1129 }
1130 EXPORT_SYMBOL(sdw_cdns_get_stream);
1131
1132 /**
1133  * sdw_cdns_alloc_stream() - Allocate a stream
1134  *
1135  * @cdns: Cadence instance
1136  * @stream: Stream to be allocated
1137  * @port: Cadence data port
1138  * @ch: Channel count
1139  * @dir: Data direction
1140  */
1141 int sdw_cdns_alloc_stream(struct sdw_cdns *cdns,
1142                           struct sdw_cdns_streams *stream,
1143                           struct sdw_cdns_port *port, u32 ch, u32 dir)
1144 {
1145         struct sdw_cdns_pdi *pdi = NULL;
1146
1147         if (dir == SDW_DATA_DIR_RX)
1148                 pdi = cdns_find_pdi(cdns, stream->num_in, stream->in);
1149         else
1150                 pdi = cdns_find_pdi(cdns, stream->num_out, stream->out);
1151
1152         /* check if we found a PDI, else find in bi-directional */
1153         if (!pdi)
1154                 pdi = cdns_find_pdi(cdns, stream->num_bd, stream->bd);
1155
1156         if (!pdi)
1157                 return -EIO;
1158
1159         port->pdi = pdi;
1160         pdi->l_ch_num = 0;
1161         pdi->h_ch_num = ch - 1;
1162         pdi->dir = dir;
1163         pdi->ch_count = ch;
1164
1165         return 0;
1166 }
1167 EXPORT_SYMBOL(sdw_cdns_alloc_stream);
1168
1169 void sdw_cdns_shutdown(struct snd_pcm_substream *substream,
1170                        struct snd_soc_dai *dai)
1171 {
1172         struct sdw_cdns_dma_data *dma;
1173
1174         dma = snd_soc_dai_get_dma_data(dai, substream);
1175         if (!dma)
1176                 return;
1177
1178         snd_soc_dai_set_dma_data(dai, substream, NULL);
1179         kfree(dma);
1180 }
1181 EXPORT_SYMBOL(sdw_cdns_shutdown);
1182
1183 MODULE_LICENSE("Dual BSD/GPL");
1184 MODULE_DESCRIPTION("Cadence Soundwire Library");
This page took 0.097838 seconds and 4 git commands to generate.