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