blob: 66409f8cec9167b867d8e288ef75a258ac538f51 [file] [log] [blame]
Meng Wang43bbb872018-12-10 12:32:05 +08001// SPDX-License-Identifier: GPL-2.0-only
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08002/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303 */
4
5#include <linux/irq.h>
6#include <linux/kernel.h>
7#include <linux/init.h>
8#include <linux/slab.h>
9#include <linux/io.h>
10#include <linux/interrupt.h>
11#include <linux/platform_device.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053012#include <linux/delay.h>
13#include <linux/kthread.h>
14#include <linux/clk.h>
15#include <linux/pm_runtime.h>
16#include <linux/of.h>
17#include <linux/debugfs.h>
18#include <linux/uaccess.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053019#include <soc/soundwire.h>
20#include <soc/swr-wcd.h>
Vignesh Kulothungan9ca8dc32018-05-09 17:41:11 -070021#include <dsp/msm-audio-event-notify.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053022#include "swrm_registers.h"
23#include "swr-wcd-ctrl.h"
24
25#define SWR_BROADCAST_CMD_ID 0x0F
26#define SWR_AUTO_SUSPEND_DELAY 3 /* delay in sec */
27#define SWR_DEV_ID_MASK 0xFFFFFFFF
28#define SWR_REG_VAL_PACK(data, dev, id, reg) \
29 ((reg) | ((id) << 16) | ((dev) << 20) | ((data) << 24))
30
31/* pm runtime auto suspend timer in msecs */
32static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000;
33module_param(auto_suspend_timer, int, 0664);
34MODULE_PARM_DESC(auto_suspend_timer, "timer for auto suspend");
35
36static u8 mstr_ports[] = {100, 101, 102, 103, 104, 105, 106, 107};
37static u8 mstr_port_type[] = {SWR_DAC_PORT, SWR_COMP_PORT, SWR_BOOST_PORT,
38 SWR_DAC_PORT, SWR_COMP_PORT, SWR_BOOST_PORT,
39 SWR_VISENSE_PORT, SWR_VISENSE_PORT};
40
41struct usecase uc[] = {
42 {0, 0, 0}, /* UC0: no ports */
43 {1, 1, 2400}, /* UC1: Spkr */
44 {1, 4, 600}, /* UC2: Compander */
45 {1, 2, 300}, /* UC3: Smart Boost */
46 {1, 2, 1200}, /* UC4: VI Sense */
47 {4, 9, 4500}, /* UC5: Spkr + Comp + SB + VI */
48 {8, 18, 9000}, /* UC6: 2*(Spkr + Comp + SB + VI) */
49 {2, 2, 4800}, /* UC7: 2*Spkr */
50 {2, 5, 3000}, /* UC8: Spkr + Comp */
51 {4, 10, 6000}, /* UC9: 2*(Spkr + Comp) */
52 {3, 7, 3300}, /* UC10: Spkr + Comp + SB */
53 {6, 14, 6600}, /* UC11: 2*(Spkr + Comp + SB) */
54 {2, 3, 2700}, /* UC12: Spkr + SB */
55 {4, 6, 5400}, /* UC13: 2*(Spkr + SB) */
56 {3, 5, 3900}, /* UC14: Spkr + SB + VI */
57 {6, 10, 7800}, /* UC15: 2*(Spkr + SB + VI) */
58 {2, 3, 3600}, /* UC16: Spkr + VI */
59 {4, 6, 7200}, /* UC17: 2*(Spkr + VI) */
60 {3, 7, 4200}, /* UC18: Spkr + Comp + VI */
61 {6, 14, 8400}, /* UC19: 2*(Spkr + Comp + VI) */
62};
63#define MAX_USECASE ARRAY_SIZE(uc)
64
65struct port_params pp[MAX_USECASE][SWR_MSTR_PORT_LEN] = {
66 /* UC 0 */
67 {
68 {0, 0, 0},
69 },
70 /* UC 1 */
71 {
72 {7, 1, 0},
73 },
74 /* UC 2 */
75 {
76 {31, 2, 0},
77 },
78 /* UC 3 */
79 {
80 {63, 12, 31},
81 },
82 /* UC 4 */
83 {
84 {15, 7, 0},
85 },
86 /* UC 5 */
87 {
88 {7, 1, 0},
89 {31, 2, 0},
90 {63, 12, 31},
91 {15, 7, 0},
92 },
93 /* UC 6 */
94 {
95 {7, 1, 0},
96 {31, 2, 0},
97 {63, 12, 31},
98 {15, 7, 0},
99 {7, 6, 0},
100 {31, 18, 0},
101 {63, 13, 31},
102 {15, 10, 0},
103 },
104 /* UC 7 */
105 {
106 {7, 1, 0},
107 {7, 6, 0},
108
109 },
110 /* UC 8 */
111 {
112 {7, 1, 0},
113 {31, 2, 0},
114 },
115 /* UC 9 */
116 {
117 {7, 1, 0},
118 {31, 2, 0},
119 {7, 6, 0},
120 {31, 18, 0},
121 },
122 /* UC 10 */
123 {
124 {7, 1, 0},
125 {31, 2, 0},
126 {63, 12, 31},
127 },
128 /* UC 11 */
129 {
130 {7, 1, 0},
131 {31, 2, 0},
132 {63, 12, 31},
133 {7, 6, 0},
134 {31, 18, 0},
135 {63, 13, 31},
136 },
137 /* UC 12 */
138 {
139 {7, 1, 0},
140 {63, 12, 31},
141 },
142 /* UC 13 */
143 {
144 {7, 1, 0},
145 {63, 12, 31},
146 {7, 6, 0},
147 {63, 13, 31},
148 },
149 /* UC 14 */
150 {
151 {7, 1, 0},
152 {63, 12, 31},
153 {15, 7, 0},
154 },
155 /* UC 15 */
156 {
157 {7, 1, 0},
158 {63, 12, 31},
159 {15, 7, 0},
160 {7, 6, 0},
161 {63, 13, 31},
162 {15, 10, 0},
163 },
164 /* UC 16 */
165 {
166 {7, 1, 0},
167 {15, 7, 0},
168 },
169 /* UC 17 */
170 {
171 {7, 1, 0},
172 {15, 7, 0},
173 {7, 6, 0},
174 {15, 10, 0},
175 },
176 /* UC 18 */
177 {
178 {7, 1, 0},
179 {31, 2, 0},
180 {15, 7, 0},
181 },
182 /* UC 19 */
183 {
184 {7, 1, 0},
185 {31, 2, 0},
186 {15, 7, 0},
187 {7, 6, 0},
188 {31, 18, 0},
189 {15, 10, 0},
190 },
191};
192
193enum {
194 SWR_NOT_PRESENT, /* Device is detached/not present on the bus */
195 SWR_ATTACHED_OK, /* Device is attached */
196 SWR_ALERT, /* Device alters master for any interrupts */
197 SWR_RESERVED, /* Reserved */
198};
199
200#define SWRM_MAX_PORT_REG 40
201#define SWRM_MAX_INIT_REG 8
202
203#define SWR_MSTR_MAX_REG_ADDR 0x1740
204#define SWR_MSTR_START_REG_ADDR 0x00
205#define SWR_MSTR_MAX_BUF_LEN 32
206#define BYTES_PER_LINE 12
207#define SWR_MSTR_RD_BUF_LEN 8
208#define SWR_MSTR_WR_BUF_LEN 32
209
210static void swrm_copy_data_port_config(struct swr_master *master,
211 u8 inactive_bank);
212static struct swr_mstr_ctrl *dbgswrm;
213static struct dentry *debugfs_swrm_dent;
214static struct dentry *debugfs_peek;
215static struct dentry *debugfs_poke;
216static struct dentry *debugfs_reg_dump;
217static unsigned int read_data;
218
219
220static bool swrm_is_msm_variant(int val)
221{
222 return (val == SWRM_VERSION_1_3);
223}
224
225static int swrm_debug_open(struct inode *inode, struct file *file)
226{
227 file->private_data = inode->i_private;
228 return 0;
229}
230
231static int get_parameters(char *buf, u32 *param1, int num_of_par)
232{
233 char *token;
234 int base, cnt;
235
236 token = strsep(&buf, " ");
237 for (cnt = 0; cnt < num_of_par; cnt++) {
238 if (token) {
239 if ((token[1] == 'x') || (token[1] == 'X'))
240 base = 16;
241 else
242 base = 10;
243
244 if (kstrtou32(token, base, &param1[cnt]) != 0)
245 return -EINVAL;
246
247 token = strsep(&buf, " ");
248 } else
249 return -EINVAL;
250 }
251 return 0;
252}
253
254static ssize_t swrm_reg_show(char __user *ubuf, size_t count,
255 loff_t *ppos)
256{
257 int i, reg_val, len;
258 ssize_t total = 0;
259 char tmp_buf[SWR_MSTR_MAX_BUF_LEN];
260
261 if (!ubuf || !ppos)
262 return 0;
263
264 for (i = (((int) *ppos / BYTES_PER_LINE) + SWR_MSTR_START_REG_ADDR);
265 i <= SWR_MSTR_MAX_REG_ADDR; i += 4) {
266 reg_val = dbgswrm->read(dbgswrm->handle, i);
267 len = snprintf(tmp_buf, 25, "0x%.3x: 0x%.2x\n", i, reg_val);
Aditya Bavanari8aacfcf2019-06-21 15:56:39 +0530268 if (len < 0) {
269 pr_err("%s: fail to fill the buffer\n", __func__);
270 total = -EFAULT;
271 goto copy_err;
272 }
273
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530274 if ((total + len) >= count - 1)
275 break;
276 if (copy_to_user((ubuf + total), tmp_buf, len)) {
277 pr_err("%s: fail to copy reg dump\n", __func__);
278 total = -EFAULT;
279 goto copy_err;
280 }
281 *ppos += len;
282 total += len;
283 }
284
285copy_err:
286 return total;
287}
288
289static ssize_t swrm_debug_read(struct file *file, char __user *ubuf,
290 size_t count, loff_t *ppos)
291{
292 char lbuf[SWR_MSTR_RD_BUF_LEN];
293 char *access_str;
294 ssize_t ret_cnt;
295
296 if (!count || !file || !ppos || !ubuf)
297 return -EINVAL;
298
299 access_str = file->private_data;
300 if (*ppos < 0)
301 return -EINVAL;
302
303 if (!strcmp(access_str, "swrm_peek")) {
304 snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data);
305 ret_cnt = simple_read_from_buffer(ubuf, count, ppos, lbuf,
306 strnlen(lbuf, 7));
307 } else if (!strcmp(access_str, "swrm_reg_dump")) {
308 ret_cnt = swrm_reg_show(ubuf, count, ppos);
309 } else {
310 pr_err("%s: %s not permitted to read\n", __func__, access_str);
311 ret_cnt = -EPERM;
312 }
313 return ret_cnt;
314}
315
316static ssize_t swrm_debug_write(struct file *filp,
317 const char __user *ubuf, size_t cnt, loff_t *ppos)
318{
319 char lbuf[SWR_MSTR_WR_BUF_LEN];
320 int rc;
321 u32 param[5];
322 char *access_str;
323
324 if (!filp || !ppos || !ubuf)
325 return -EINVAL;
326
327 access_str = filp->private_data;
328 if (cnt > sizeof(lbuf) - 1)
329 return -EINVAL;
330
331 rc = copy_from_user(lbuf, ubuf, cnt);
332 if (rc)
333 return -EFAULT;
334
335 lbuf[cnt] = '\0';
336 if (!strcmp(access_str, "swrm_poke")) {
337 /* write */
338 rc = get_parameters(lbuf, param, 2);
339 if ((param[0] <= SWR_MSTR_MAX_REG_ADDR) &&
340 (param[1] <= 0xFFFFFFFF) &&
341 (rc == 0))
342 rc = dbgswrm->write(dbgswrm->handle, param[0],
343 param[1]);
344 else
345 rc = -EINVAL;
346 } else if (!strcmp(access_str, "swrm_peek")) {
347 /* read */
348 rc = get_parameters(lbuf, param, 1);
349 if ((param[0] <= SWR_MSTR_MAX_REG_ADDR) && (rc == 0))
350 read_data = dbgswrm->read(dbgswrm->handle, param[0]);
351 else
352 rc = -EINVAL;
353 }
354 if (rc == 0)
355 rc = cnt;
356 else
357 pr_err("%s: rc = %d\n", __func__, rc);
358
359 return rc;
360}
361
362static const struct file_operations swrm_debug_ops = {
363 .open = swrm_debug_open,
364 .write = swrm_debug_write,
365 .read = swrm_debug_read,
366};
367
368static int swrm_set_ch_map(struct swr_mstr_ctrl *swrm, void *data)
369{
370 struct swr_mstr_port *pinfo = (struct swr_mstr_port *)data;
371
372 swrm->mstr_port = kzalloc(sizeof(struct swr_mstr_port), GFP_KERNEL);
373 if (swrm->mstr_port == NULL)
374 return -ENOMEM;
375 swrm->mstr_port->num_port = pinfo->num_port;
376 swrm->mstr_port->port = kzalloc((pinfo->num_port * sizeof(u8)),
377 GFP_KERNEL);
378 if (!swrm->mstr_port->port) {
379 kfree(swrm->mstr_port);
380 swrm->mstr_port = NULL;
381 return -ENOMEM;
382 }
383 memcpy(swrm->mstr_port->port, pinfo->port, pinfo->num_port);
384 return 0;
385}
386
387static bool swrm_is_port_en(struct swr_master *mstr)
388{
389 return !!(mstr->num_port);
390}
391
392static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable)
393{
394 if (!swrm->clk || !swrm->handle)
395 return -EINVAL;
396
397 if (enable) {
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +0530398 swrm->clk_ref_count++;
399 if (swrm->clk_ref_count == 1) {
400 swrm->clk(swrm->handle, true);
401 swrm->state = SWR_MSTR_UP;
402 }
403 } else if (--swrm->clk_ref_count == 0) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530404 swrm->clk(swrm->handle, false);
405 swrm->state = SWR_MSTR_DOWN;
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +0530406 } else if (swrm->clk_ref_count < 0) {
407 pr_err("%s: swrm clk count mismatch\n", __func__);
408 swrm->clk_ref_count = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530409 }
410 return 0;
411}
412
413static int swrm_get_port_config(struct swr_master *master)
414{
415 u32 ch_rate = 0;
416 u32 num_ch = 0;
417 int i, uc_idx;
418 u32 portcount = 0;
419
420 for (i = 0; i < SWR_MSTR_PORT_LEN; i++) {
421 if (master->port[i].port_en) {
422 ch_rate += master->port[i].ch_rate;
423 num_ch += master->port[i].num_ch;
424 portcount++;
425 }
426 }
427 for (i = 0; i < ARRAY_SIZE(uc); i++) {
428 if ((uc[i].num_port == portcount) &&
429 (uc[i].num_ch == num_ch) &&
430 (uc[i].chrate == ch_rate)) {
431 uc_idx = i;
432 break;
433 }
434 }
435
436 if (i >= ARRAY_SIZE(uc)) {
437 dev_err(&master->dev,
438 "%s: usecase port:%d, num_ch:%d, chrate:%d not found\n",
439 __func__, master->num_port, num_ch, ch_rate);
440 return -EINVAL;
441 }
442 for (i = 0; i < SWR_MSTR_PORT_LEN; i++) {
443 if (master->port[i].port_en) {
444 master->port[i].sinterval = pp[uc_idx][i].si;
445 master->port[i].offset1 = pp[uc_idx][i].off1;
446 master->port[i].offset2 = pp[uc_idx][i].off2;
447 }
448 }
449 return 0;
450}
451
452static int swrm_get_master_port(u8 *mstr_port_id, u8 slv_port_id)
453{
454 int i;
455
456 for (i = 0; i < SWR_MSTR_PORT_LEN; i++) {
457 if (mstr_ports[i] == slv_port_id) {
458 *mstr_port_id = i;
459 return 0;
460 }
461 }
462 return -EINVAL;
463}
464
465static u32 swrm_get_packed_reg_val(u8 *cmd_id, u8 cmd_data,
466 u8 dev_addr, u16 reg_addr)
467{
468 u32 val;
469 u8 id = *cmd_id;
470
471 if (id != SWR_BROADCAST_CMD_ID) {
472 if (id < 14)
473 id += 1;
474 else
475 id = 0;
476 *cmd_id = id;
477 }
478 val = SWR_REG_VAL_PACK(cmd_data, dev_addr, id, reg_addr);
479
480 return val;
481}
482
483static int swrm_cmd_fifo_rd_cmd(struct swr_mstr_ctrl *swrm, int *cmd_data,
484 u8 dev_addr, u8 cmd_id, u16 reg_addr,
485 u32 len)
486{
487 u32 val;
488 int ret = 0;
489
490 val = swrm_get_packed_reg_val(&swrm->rcmd_id, len, dev_addr, reg_addr);
491 ret = swrm->write(swrm->handle, SWRM_CMD_FIFO_RD_CMD, val);
492 if (ret < 0) {
493 dev_err(swrm->dev, "%s: reg 0x%x write failed, err:%d\n",
494 __func__, val, ret);
495 goto err;
496 }
497 *cmd_data = swrm->read(swrm->handle, SWRM_CMD_FIFO_RD_FIFO_ADDR);
498 dev_dbg(swrm->dev,
499 "%s: reg: 0x%x, cmd_id: 0x%x, dev_id: 0x%x, cmd_data: 0x%x\n",
500 __func__, reg_addr, cmd_id, dev_addr, *cmd_data);
501err:
502 return ret;
503}
504
505static int swrm_cmd_fifo_wr_cmd(struct swr_mstr_ctrl *swrm, u8 cmd_data,
506 u8 dev_addr, u8 cmd_id, u16 reg_addr)
507{
508 u32 val;
509 int ret = 0;
510
511 if (!cmd_id)
512 val = swrm_get_packed_reg_val(&swrm->wcmd_id, cmd_data,
513 dev_addr, reg_addr);
514 else
515 val = swrm_get_packed_reg_val(&cmd_id, cmd_data,
516 dev_addr, reg_addr);
517
518 dev_dbg(swrm->dev,
519 "%s: reg: 0x%x, cmd_id: 0x%x, dev_id: 0x%x, cmd_data: 0x%x\n",
520 __func__, reg_addr, cmd_id, dev_addr, cmd_data);
521 ret = swrm->write(swrm->handle, SWRM_CMD_FIFO_WR_CMD, val);
522 if (ret < 0) {
523 dev_err(swrm->dev, "%s: reg 0x%x write failed, err:%d\n",
524 __func__, val, ret);
525 goto err;
526 }
527 if (cmd_id == 0xF) {
528 /*
529 * sleep for 10ms for MSM soundwire variant to allow broadcast
530 * command to complete.
531 */
532 if (swrm_is_msm_variant(swrm->version))
533 usleep_range(10000, 10100);
534 else
535 wait_for_completion_timeout(&swrm->broadcast,
536 (2 * HZ/10));
537 }
538err:
539 return ret;
540}
541
542static int swrm_read(struct swr_master *master, u8 dev_num, u16 reg_addr,
543 void *buf, u32 len)
544{
545 struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
546 int ret = 0;
547 int val;
548 u8 *reg_val = (u8 *)buf;
549
550 if (!swrm) {
551 dev_err(&master->dev, "%s: swrm is NULL\n", __func__);
552 return -EINVAL;
553 }
554
555 if (dev_num)
556 ret = swrm_cmd_fifo_rd_cmd(swrm, &val, dev_num, 0, reg_addr,
557 len);
558 else
559 val = swrm->read(swrm->handle, reg_addr);
560
561 if (!ret)
562 *reg_val = (u8)val;
563
564 pm_runtime_mark_last_busy(&swrm->pdev->dev);
565
566 return ret;
567}
568
569static int swrm_write(struct swr_master *master, u8 dev_num, u16 reg_addr,
570 const void *buf)
571{
572 struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
573 int ret = 0;
574 u8 reg_val = *(u8 *)buf;
575
576 if (!swrm) {
577 dev_err(&master->dev, "%s: swrm is NULL\n", __func__);
578 return -EINVAL;
579 }
580
581 if (dev_num)
582 ret = swrm_cmd_fifo_wr_cmd(swrm, reg_val, dev_num, 0, reg_addr);
583 else
584 ret = swrm->write(swrm->handle, reg_addr, reg_val);
585
586 pm_runtime_mark_last_busy(&swrm->pdev->dev);
587
588 return ret;
589}
590
591static int swrm_bulk_write(struct swr_master *master, u8 dev_num, void *reg,
592 const void *buf, size_t len)
593{
594 struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
595 int ret = 0;
596 int i;
597 u32 *val;
598 u32 *swr_fifo_reg;
599
600 if (!swrm || !swrm->handle) {
601 dev_err(&master->dev, "%s: swrm is NULL\n", __func__);
602 return -EINVAL;
603 }
604 if (len <= 0)
605 return -EINVAL;
606
607 if (dev_num) {
608 swr_fifo_reg = kcalloc(len, sizeof(u32), GFP_KERNEL);
609 if (!swr_fifo_reg) {
610 ret = -ENOMEM;
611 goto err;
612 }
613 val = kcalloc(len, sizeof(u32), GFP_KERNEL);
614 if (!val) {
615 ret = -ENOMEM;
616 goto mem_fail;
617 }
618
619 for (i = 0; i < len; i++) {
620 val[i] = swrm_get_packed_reg_val(&swrm->wcmd_id,
621 ((u8 *)buf)[i],
622 dev_num,
623 ((u16 *)reg)[i]);
624 swr_fifo_reg[i] = SWRM_CMD_FIFO_WR_CMD;
625 }
626 ret = swrm->bulk_write(swrm->handle, swr_fifo_reg, val, len);
627 if (ret) {
628 dev_err(&master->dev, "%s: bulk write failed\n",
629 __func__);
630 ret = -EINVAL;
631 }
632 } else {
633 dev_err(&master->dev,
634 "%s: No support of Bulk write for master regs\n",
635 __func__);
636 ret = -EINVAL;
637 goto err;
638 }
639 kfree(val);
640mem_fail:
641 kfree(swr_fifo_reg);
642err:
643 pm_runtime_mark_last_busy(&swrm->pdev->dev);
644 return ret;
645}
646
647static u8 get_inactive_bank_num(struct swr_mstr_ctrl *swrm)
648{
649 return (swrm->read(swrm->handle, SWRM_MCP_STATUS) &
650 SWRM_MCP_STATUS_BANK_NUM_MASK) ? 0 : 1;
651}
652
653static void enable_bank_switch(struct swr_mstr_ctrl *swrm, u8 bank,
654 u8 row, u8 col)
655{
Laxminath Kasam62cd1972018-11-27 18:12:11 +0530656 /* apply div2 setting for inactive bank before bank switch */
657 swrm_cmd_fifo_wr_cmd(swrm, 0x01, 0xF, 0x00,
658 SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(bank));
659
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530660 swrm_cmd_fifo_wr_cmd(swrm, ((row << 3) | col), 0xF, 0xF,
661 SWRS_SCP_FRAME_CTRL_BANK(bank));
662}
663
664static struct swr_port_info *swrm_get_port(struct swr_master *master,
665 u8 port_id)
666{
667 int i;
668 struct swr_port_info *port = NULL;
669
670 for (i = 0; i < SWR_MSTR_PORT_LEN; i++) {
671 port = &master->port[i];
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530672 if (port->slave_port_id == port_id) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530673 dev_dbg(&master->dev, "%s: port_id: %d, index: %d\n",
674 __func__, port_id, i);
675 return port;
676 }
677 }
678
679 return NULL;
680}
681
682static struct swr_port_info *swrm_get_avail_port(struct swr_master *master)
683{
684 int i;
685 struct swr_port_info *port = NULL;
686
687 for (i = 0; i < SWR_MSTR_PORT_LEN; i++) {
688 port = &master->port[i];
689 if (port->port_en)
690 continue;
691
692 dev_dbg(&master->dev, "%s: port_id: %d, index: %d\n",
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530693 __func__, port->slave_port_id, i);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530694 return port;
695 }
696
697 return NULL;
698}
699
700static struct swr_port_info *swrm_get_enabled_port(struct swr_master *master,
701 u8 port_id)
702{
703 int i;
704 struct swr_port_info *port = NULL;
705
706 for (i = 0; i < SWR_MSTR_PORT_LEN; i++) {
707 port = &master->port[i];
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530708 if ((port->slave_port_id == port_id) && (port->port_en == true))
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530709 break;
710 }
711 if (i == SWR_MSTR_PORT_LEN)
712 port = NULL;
713 return port;
714}
715
716static bool swrm_remove_from_group(struct swr_master *master)
717{
718 struct swr_device *swr_dev;
719 struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
720 bool is_removed = false;
721
722 if (!swrm)
723 goto end;
724
725 mutex_lock(&swrm->mlock);
726 if ((swrm->num_rx_chs > 1) &&
727 (swrm->num_rx_chs == swrm->num_cfg_devs)) {
728 list_for_each_entry(swr_dev, &master->devices,
729 dev_list) {
730 swr_dev->group_id = SWR_GROUP_NONE;
731 master->gr_sid = 0;
732 }
733 is_removed = true;
734 }
735 mutex_unlock(&swrm->mlock);
736
737end:
738 return is_removed;
739}
740
741static void swrm_cleanup_disabled_data_ports(struct swr_master *master,
742 u8 bank)
743{
744 u32 value;
745 struct swr_port_info *port;
746 int i;
747 int port_type;
748 struct swrm_mports *mport, *mport_next = NULL;
749 int port_disable_cnt = 0;
750 struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
751
752 if (!swrm) {
753 pr_err("%s: swrm is null\n", __func__);
754 return;
755 }
756
757 dev_dbg(swrm->dev, "%s: master num_port: %d\n", __func__,
758 master->num_port);
759
760 mport = list_first_entry_or_null(&swrm->mport_list,
761 struct swrm_mports,
762 list);
763 if (!mport) {
764 dev_err(swrm->dev, "%s: list is empty\n", __func__);
765 return;
766 }
767
768 for (i = 0; i < master->num_port; i++) {
769 port = swrm_get_port(master, mstr_ports[mport->id]);
770 if (!port || port->ch_en)
771 goto inc_loop;
772
773 port_disable_cnt++;
774 port_type = mstr_port_type[mport->id];
775 value = ((port->ch_en)
776 << SWRM_DP_PORT_CTRL_EN_CHAN_SHFT);
777 value |= ((port->offset2)
778 << SWRM_DP_PORT_CTRL_OFFSET2_SHFT);
779 value |= ((port->offset1)
780 << SWRM_DP_PORT_CTRL_OFFSET1_SHFT);
781 value |= port->sinterval;
782
783 swrm->write(swrm->handle,
784 SWRM_DP_PORT_CTRL_BANK((mport->id+1), bank),
785 value);
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530786 swrm_cmd_fifo_wr_cmd(swrm, 0x00, port->dev_num, 0x00,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530787 SWRS_DP_CHANNEL_ENABLE_BANK(port_type, bank));
788
789 dev_dbg(swrm->dev, "%s: mport :%d, reg: 0x%x, val: 0x%x\n",
790 __func__, mport->id,
791 (SWRM_DP_PORT_CTRL_BANK((mport->id+1), bank)), value);
792
793inc_loop:
794 mport_next = list_next_entry(mport, list);
795 if (port && !port->ch_en) {
796 list_del(&mport->list);
797 kfree(mport);
798 }
799 if (!mport_next) {
800 dev_err(swrm->dev, "%s: end of list\n", __func__);
801 break;
802 }
803 mport = mport_next;
804 }
805 master->num_port -= port_disable_cnt;
806
807 dev_dbg(swrm->dev, "%s:disable ports: %d, active ports (rem): %d\n",
808 __func__, port_disable_cnt, master->num_port);
809}
810
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530811static int swrm_slvdev_datapath_control(struct swr_master *master,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530812 bool enable)
813{
814 u8 bank;
815 u32 value, n_col;
816 struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
817 int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK |
818 SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK |
819 SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_BMSK);
820 u8 inactive_bank;
821
822 if (!swrm) {
823 pr_err("%s: swrm is null\n", __func__);
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530824 return 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530825 }
826
827 bank = get_inactive_bank_num(swrm);
828
829 dev_dbg(swrm->dev, "%s: enable: %d, cfg_devs: %d\n",
830 __func__, enable, swrm->num_cfg_devs);
831
832 if (enable) {
833 /* set Row = 48 and col = 16 */
834 n_col = SWR_MAX_COL;
835 } else {
836 /*
837 * Do not change to 48x2 if number of channels configured
838 * as stereo and if disable datapath is called for the
839 * first slave device
840 */
841 if (swrm->num_cfg_devs > 0)
842 n_col = SWR_MAX_COL;
843 else
844 n_col = SWR_MIN_COL;
845
846 /*
847 * All ports are already disabled, no need to perform
848 * bank-switch and copy operation. This case can arise
849 * when speaker channels are enabled in stereo mode with
850 * BROADCAST and disabled in GROUP_NONE
851 */
852 if (master->num_port == 0)
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530853 return 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530854 }
855
856 value = swrm->read(swrm->handle, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank));
857 value &= (~mask);
858 value |= ((0 << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
859 (n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
860 (0 << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
861 swrm->write(swrm->handle, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
862
863 dev_dbg(swrm->dev, "%s: regaddr: 0x%x, value: 0x%x\n", __func__,
864 SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
865
866 enable_bank_switch(swrm, bank, SWR_MAX_ROW, n_col);
867
868 inactive_bank = bank ? 0 : 1;
869 if (enable)
870 swrm_copy_data_port_config(master, inactive_bank);
871 else
872 swrm_cleanup_disabled_data_ports(master, inactive_bank);
873
874 if (!swrm_is_port_en(master)) {
875 dev_dbg(&master->dev, "%s: pm_runtime auto suspend triggered\n",
876 __func__);
877 pm_runtime_mark_last_busy(&swrm->pdev->dev);
878 pm_runtime_put_autosuspend(&swrm->pdev->dev);
879 }
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530880 return 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530881}
882
883static void swrm_apply_port_config(struct swr_master *master)
884{
885 u8 bank;
886 struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
887
888 if (!swrm) {
889 pr_err("%s: Invalid handle to swr controller\n",
890 __func__);
891 return;
892 }
893
894 bank = get_inactive_bank_num(swrm);
895 dev_dbg(swrm->dev, "%s: enter bank: %d master_ports: %d\n",
896 __func__, bank, master->num_port);
897
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530898 swrm_copy_data_port_config(master, bank);
899}
900
901static void swrm_copy_data_port_config(struct swr_master *master, u8 bank)
902{
903 u32 value;
904 struct swr_port_info *port;
905 int i;
906 int port_type;
907 struct swrm_mports *mport;
908 u32 reg[SWRM_MAX_PORT_REG];
909 u32 val[SWRM_MAX_PORT_REG];
910 int len = 0;
911 struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
912
913 if (!swrm) {
914 pr_err("%s: swrm is null\n", __func__);
915 return;
916 }
917
918 dev_dbg(swrm->dev, "%s: master num_port: %d\n", __func__,
919 master->num_port);
920
921 mport = list_first_entry_or_null(&swrm->mport_list,
922 struct swrm_mports,
923 list);
924 if (!mport) {
925 dev_err(swrm->dev, "%s: list is empty\n", __func__);
926 return;
927 }
928 for (i = 0; i < master->num_port; i++) {
929
930 port = swrm_get_enabled_port(master, mstr_ports[mport->id]);
931 if (!port)
932 continue;
933 port_type = mstr_port_type[mport->id];
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530934 if (!port->dev_num || (port->dev_num > master->num_dev)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530935 dev_dbg(swrm->dev, "%s: invalid device id = %d\n",
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530936 __func__, port->dev_num);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530937 continue;
938 }
939 value = ((port->ch_en)
940 << SWRM_DP_PORT_CTRL_EN_CHAN_SHFT);
941 value |= ((port->offset2)
942 << SWRM_DP_PORT_CTRL_OFFSET2_SHFT);
943 value |= ((port->offset1)
944 << SWRM_DP_PORT_CTRL_OFFSET1_SHFT);
945 value |= port->sinterval;
946
947 reg[len] = SWRM_DP_PORT_CTRL_BANK((mport->id+1), bank);
948 val[len++] = value;
949
950 dev_dbg(swrm->dev, "%s: mport :%d, reg: 0x%x, val: 0x%x\n",
951 __func__, mport->id,
952 (SWRM_DP_PORT_CTRL_BANK((mport->id+1), bank)), value);
953
954 reg[len] = SWRM_CMD_FIFO_WR_CMD;
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530955 val[len++] = SWR_REG_VAL_PACK(port->ch_en, port->dev_num, 0x00,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530956 SWRS_DP_CHANNEL_ENABLE_BANK(port_type, bank));
957
958 reg[len] = SWRM_CMD_FIFO_WR_CMD;
959 val[len++] = SWR_REG_VAL_PACK(port->sinterval,
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530960 port->dev_num, 0x00,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530961 SWRS_DP_SAMPLE_CONTROL_1_BANK(port_type, bank));
962
963 reg[len] = SWRM_CMD_FIFO_WR_CMD;
964 val[len++] = SWR_REG_VAL_PACK(port->offset1,
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530965 port->dev_num, 0x00,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530966 SWRS_DP_OFFSET_CONTROL_1_BANK(port_type, bank));
967
968 if (port_type != 0) {
969 reg[len] = SWRM_CMD_FIFO_WR_CMD;
970 val[len++] = SWR_REG_VAL_PACK(port->offset2,
Ramprasad Katkame38aed42018-03-07 16:26:49 +0530971 port->dev_num, 0x00,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530972 SWRS_DP_OFFSET_CONTROL_2_BANK(port_type,
973 bank));
974 }
975 mport = list_next_entry(mport, list);
976 if (!mport) {
977 dev_err(swrm->dev, "%s: end of list\n", __func__);
978 break;
979 }
980 }
981 swrm->bulk_write(swrm->handle, reg, val, len);
982}
983
984static int swrm_connect_port(struct swr_master *master,
985 struct swr_params *portinfo)
986{
987 int i;
988 struct swr_port_info *port;
989 int ret = 0;
990 struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
991 struct swrm_mports *mport;
992 struct list_head *ptr, *next;
993
994 dev_dbg(&master->dev, "%s: enter\n", __func__);
995 if (!portinfo)
996 return -EINVAL;
997
998 if (!swrm) {
999 dev_err(&master->dev,
1000 "%s: Invalid handle to swr controller\n",
1001 __func__);
1002 return -EINVAL;
1003 }
1004
1005 mutex_lock(&swrm->mlock);
1006 if (!swrm_is_port_en(master))
1007 pm_runtime_get_sync(&swrm->pdev->dev);
1008
1009 for (i = 0; i < portinfo->num_port; i++) {
1010 mport = kzalloc(sizeof(struct swrm_mports), GFP_KERNEL);
1011 if (!mport) {
1012 ret = -ENOMEM;
1013 goto mem_fail;
1014 }
1015 ret = swrm_get_master_port(&mport->id,
1016 portinfo->port_id[i]);
1017 if (ret < 0) {
1018 dev_err(&master->dev,
1019 "%s: mstr portid for slv port %d not found\n",
1020 __func__, portinfo->port_id[i]);
1021 goto port_fail;
1022 }
1023 port = swrm_get_avail_port(master);
1024 if (!port) {
1025 dev_err(&master->dev,
1026 "%s: avail ports not found!\n", __func__);
1027 goto port_fail;
1028 }
1029 list_add(&mport->list, &swrm->mport_list);
Ramprasad Katkame38aed42018-03-07 16:26:49 +05301030 port->dev_num = portinfo->dev_num;
1031 port->slave_port_id = portinfo->port_id[i];
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301032 port->num_ch = portinfo->num_ch[i];
1033 port->ch_rate = portinfo->ch_rate[i];
1034 port->ch_en = portinfo->ch_en[i];
1035 port->port_en = true;
1036 dev_dbg(&master->dev,
1037 "%s: mstr port %d, slv port %d ch_rate %d num_ch %d\n",
Ramprasad Katkame38aed42018-03-07 16:26:49 +05301038 __func__, mport->id, port->slave_port_id, port->ch_rate,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301039 port->num_ch);
1040 }
1041 master->num_port += portinfo->num_port;
1042 if (master->num_port >= SWR_MSTR_PORT_LEN)
1043 master->num_port = SWR_MSTR_PORT_LEN;
1044
1045 swrm_get_port_config(master);
1046 swr_port_response(master, portinfo->tid);
1047 swrm->num_cfg_devs += 1;
1048 dev_dbg(&master->dev, "%s: cfg_devs: %d, rx_chs: %d\n",
1049 __func__, swrm->num_cfg_devs, swrm->num_rx_chs);
1050 if (swrm->num_rx_chs > 1) {
1051 if (swrm->num_rx_chs == swrm->num_cfg_devs)
1052 swrm_apply_port_config(master);
1053 } else {
1054 swrm_apply_port_config(master);
1055 }
1056 mutex_unlock(&swrm->mlock);
1057 return 0;
1058
1059port_fail:
1060 kfree(mport);
1061mem_fail:
1062 list_for_each_safe(ptr, next, &swrm->mport_list) {
1063 mport = list_entry(ptr, struct swrm_mports, list);
1064 for (i = 0; i < portinfo->num_port; i++) {
1065 if (portinfo->port_id[i] == mstr_ports[mport->id]) {
1066 port = swrm_get_port(master,
1067 portinfo->port_id[i]);
1068 if (port)
1069 port->ch_en = false;
1070 list_del(&mport->list);
1071 kfree(mport);
1072 break;
1073 }
1074 }
1075 }
1076 mutex_unlock(&swrm->mlock);
1077 return ret;
1078}
1079
1080static int swrm_disconnect_port(struct swr_master *master,
1081 struct swr_params *portinfo)
1082{
1083 int i;
1084 struct swr_port_info *port;
1085 u8 bank;
1086 u32 value;
1087 int ret = 0;
1088 u8 mport_id = 0;
1089 int port_type = 0;
1090 struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
1091
1092 if (!swrm) {
1093 dev_err(&master->dev,
1094 "%s: Invalid handle to swr controller\n",
1095 __func__);
1096 return -EINVAL;
1097 }
1098
1099 if (!portinfo) {
1100 dev_err(&master->dev, "%s: portinfo is NULL\n", __func__);
1101 return -EINVAL;
1102 }
1103 mutex_lock(&swrm->mlock);
1104 bank = get_inactive_bank_num(swrm);
1105 for (i = 0; i < portinfo->num_port; i++) {
1106 ret = swrm_get_master_port(&mport_id,
1107 portinfo->port_id[i]);
1108 if (ret < 0) {
1109 dev_err(&master->dev,
1110 "%s: mstr portid for slv port %d not found\n",
1111 __func__, portinfo->port_id[i]);
1112 mutex_unlock(&swrm->mlock);
1113 return -EINVAL;
1114 }
1115 port = swrm_get_enabled_port(master, portinfo->port_id[i]);
1116 if (!port) {
1117 dev_dbg(&master->dev, "%s: port %d already disabled\n",
1118 __func__, portinfo->port_id[i]);
1119 continue;
1120 }
1121 port_type = mstr_port_type[mport_id];
Ramprasad Katkame38aed42018-03-07 16:26:49 +05301122 port->dev_num = portinfo->dev_num;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301123 port->port_en = false;
1124 port->ch_en = 0;
1125 value = port->ch_en << SWRM_DP_PORT_CTRL_EN_CHAN_SHFT;
1126 value |= (port->offset2 << SWRM_DP_PORT_CTRL_OFFSET2_SHFT);
1127 value |= (port->offset1 << SWRM_DP_PORT_CTRL_OFFSET1_SHFT);
1128 value |= port->sinterval;
1129
1130
1131 swrm->write(swrm->handle,
1132 SWRM_DP_PORT_CTRL_BANK((mport_id+1), bank),
1133 value);
Ramprasad Katkame38aed42018-03-07 16:26:49 +05301134 swrm_cmd_fifo_wr_cmd(swrm, 0x00, port->dev_num, 0x00,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301135 SWRS_DP_CHANNEL_ENABLE_BANK(port_type, bank));
1136 }
1137
1138 swr_port_response(master, portinfo->tid);
1139 swrm->num_cfg_devs -= 1;
1140 dev_dbg(&master->dev, "%s: cfg_devs: %d, rx_chs: %d, active ports: %d\n",
1141 __func__, swrm->num_cfg_devs, swrm->num_rx_chs,
1142 master->num_port);
1143 mutex_unlock(&swrm->mlock);
1144
1145 return 0;
1146}
1147
1148static int swrm_check_slave_change_status(struct swr_mstr_ctrl *swrm,
1149 int status, u8 *devnum)
1150{
1151 int i;
1152 int new_sts = status;
1153 int ret = SWR_NOT_PRESENT;
1154
1155 if (status != swrm->slave_status) {
1156 for (i = 0; i < (swrm->master.num_dev + 1); i++) {
1157 if ((status & SWRM_MCP_SLV_STATUS_MASK) !=
1158 (swrm->slave_status & SWRM_MCP_SLV_STATUS_MASK)) {
1159 ret = (status & SWRM_MCP_SLV_STATUS_MASK);
1160 *devnum = i;
1161 break;
1162 }
1163 status >>= 2;
1164 swrm->slave_status >>= 2;
1165 }
1166 swrm->slave_status = new_sts;
1167 }
1168 return ret;
1169}
1170
1171static irqreturn_t swr_mstr_interrupt(int irq, void *dev)
1172{
1173 struct swr_mstr_ctrl *swrm = dev;
1174 u32 value, intr_sts;
1175 int status, chg_sts, i;
1176 u8 devnum = 0;
1177 int ret = IRQ_HANDLED;
1178
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +05301179 mutex_lock(&swrm->reslock);
1180 swrm_clk_request(swrm, true);
1181 mutex_unlock(&swrm->reslock);
1182
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301183 intr_sts = swrm->read(swrm->handle, SWRM_INTERRUPT_STATUS);
1184 intr_sts &= SWRM_INTERRUPT_STATUS_RMSK;
1185 for (i = 0; i < SWRM_INTERRUPT_MAX; i++) {
1186 value = intr_sts & (1 << i);
1187 if (!value)
1188 continue;
1189
1190 swrm->write(swrm->handle, SWRM_INTERRUPT_CLEAR, value);
1191 switch (value) {
1192 case SWRM_INTERRUPT_STATUS_SLAVE_PEND_IRQ:
1193 dev_dbg(swrm->dev, "SWR slave pend irq\n");
1194 break;
1195 case SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED:
1196 dev_dbg(swrm->dev, "SWR new slave attached\n");
1197 break;
1198 case SWRM_INTERRUPT_STATUS_CHANGE_ENUM_SLAVE_STATUS:
1199 status = swrm->read(swrm->handle, SWRM_MCP_SLV_STATUS);
1200 if (status == swrm->slave_status) {
1201 dev_dbg(swrm->dev,
1202 "%s: No change in slave status: %d\n",
1203 __func__, status);
1204 break;
1205 }
1206 chg_sts = swrm_check_slave_change_status(swrm, status,
1207 &devnum);
1208 switch (chg_sts) {
1209 case SWR_NOT_PRESENT:
1210 dev_dbg(swrm->dev, "device %d got detached\n",
1211 devnum);
1212 break;
1213 case SWR_ATTACHED_OK:
1214 dev_dbg(swrm->dev, "device %d got attached\n",
1215 devnum);
1216 break;
1217 case SWR_ALERT:
1218 dev_dbg(swrm->dev,
1219 "device %d has pending interrupt\n",
1220 devnum);
1221 break;
1222 }
1223 break;
1224 case SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET:
1225 dev_err_ratelimited(swrm->dev, "SWR bus clash detected\n");
1226 break;
1227 case SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW:
1228 dev_dbg(swrm->dev, "SWR read FIFO overflow\n");
1229 break;
1230 case SWRM_INTERRUPT_STATUS_RD_FIFO_UNDERFLOW:
1231 dev_dbg(swrm->dev, "SWR read FIFO underflow\n");
1232 break;
1233 case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW:
1234 dev_dbg(swrm->dev, "SWR write FIFO overflow\n");
1235 break;
1236 case SWRM_INTERRUPT_STATUS_CMD_ERROR:
1237 value = swrm->read(swrm->handle, SWRM_CMD_FIFO_STATUS);
1238 dev_err_ratelimited(swrm->dev,
1239 "SWR CMD error, fifo status 0x%x, flushing fifo\n",
1240 value);
1241 swrm->write(swrm->handle, SWRM_CMD_FIFO_CMD, 0x1);
1242 break;
1243 case SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION:
1244 dev_dbg(swrm->dev, "SWR Port collision detected\n");
1245 break;
1246 case SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH:
1247 dev_dbg(swrm->dev, "SWR read enable valid mismatch\n");
1248 break;
1249 case SWRM_INTERRUPT_STATUS_SPECIAL_CMD_ID_FINISHED:
1250 complete(&swrm->broadcast);
1251 dev_dbg(swrm->dev, "SWR cmd id finished\n");
1252 break;
1253 case SWRM_INTERRUPT_STATUS_NEW_SLAVE_AUTO_ENUM_FINISHED:
1254 break;
1255 case SWRM_INTERRUPT_STATUS_AUTO_ENUM_FAILED:
1256 break;
1257 case SWRM_INTERRUPT_STATUS_AUTO_ENUM_TABLE_IS_FULL:
1258 break;
1259 case SWRM_INTERRUPT_STATUS_BUS_RESET_FINISHED:
1260 complete(&swrm->reset);
1261 break;
1262 case SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED:
1263 break;
1264 default:
1265 dev_err_ratelimited(swrm->dev, "SWR unknown interrupt\n");
1266 ret = IRQ_NONE;
1267 break;
1268 }
1269 }
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +05301270
1271 mutex_lock(&swrm->reslock);
1272 swrm_clk_request(swrm, false);
1273 mutex_unlock(&swrm->reslock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301274 return ret;
1275}
1276
1277static int swrm_get_device_status(struct swr_mstr_ctrl *swrm, u8 devnum)
1278{
1279 u32 val;
1280
1281 swrm->slave_status = swrm->read(swrm->handle, SWRM_MCP_SLV_STATUS);
1282 val = (swrm->slave_status >> (devnum * 2));
1283 val &= SWRM_MCP_SLV_STATUS_MASK;
1284 return val;
1285}
1286
1287static int swrm_get_logical_dev_num(struct swr_master *mstr, u64 dev_id,
1288 u8 *dev_num)
1289{
1290 int i;
1291 u64 id = 0;
1292 int ret = -EINVAL;
1293 struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(mstr);
Vidyakumar Athota39a430c2018-01-22 15:44:58 -08001294 struct swr_device *swr_dev;
Laxminath Kasam55c95512018-02-26 20:31:02 +05301295 u32 num_dev = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301296
1297 if (!swrm) {
1298 pr_err("%s: Invalid handle to swr controller\n",
1299 __func__);
1300 return ret;
1301 }
Laxminath Kasam55c95512018-02-26 20:31:02 +05301302 if (swrm->num_dev)
1303 num_dev = swrm->num_dev;
1304 else
1305 num_dev = mstr->num_dev;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301306
1307 pm_runtime_get_sync(&swrm->pdev->dev);
Laxminath Kasam55c95512018-02-26 20:31:02 +05301308 for (i = 1; i < (num_dev + 1); i++) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301309 id = ((u64)(swrm->read(swrm->handle,
1310 SWRM_ENUMERATOR_SLAVE_DEV_ID_2(i))) << 32);
1311 id |= swrm->read(swrm->handle,
1312 SWRM_ENUMERATOR_SLAVE_DEV_ID_1(i));
Vidyakumar Athota39a430c2018-01-22 15:44:58 -08001313 /*
1314 * As pm_runtime_get_sync() brings all slaves out of reset
1315 * update logical device number for all slaves.
1316 */
1317 list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
1318 if (swr_dev->addr == (id & SWR_DEV_ID_MASK)) {
1319 u32 status = swrm_get_device_status(swrm, i);
1320
1321 if ((status == 0x01) || (status == 0x02)) {
1322 swr_dev->dev_num = i;
1323 if ((id & SWR_DEV_ID_MASK) == dev_id) {
1324 *dev_num = i;
1325 ret = 0;
1326 }
1327 dev_dbg(swrm->dev, "%s: devnum %d is assigned for dev addr %lx\n",
1328 __func__, i, swr_dev->addr);
1329 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301330 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301331 }
1332 }
Vidyakumar Athota39a430c2018-01-22 15:44:58 -08001333 if (ret)
1334 dev_err(swrm->dev, "%s: device 0x%llx is not ready\n",
1335 __func__, dev_id);
1336
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301337 pm_runtime_mark_last_busy(&swrm->pdev->dev);
1338 pm_runtime_put_autosuspend(&swrm->pdev->dev);
1339 return ret;
1340}
1341static int swrm_master_init(struct swr_mstr_ctrl *swrm)
1342{
1343 int ret = 0;
1344 u32 val;
1345 u8 row_ctrl = SWR_MAX_ROW;
1346 u8 col_ctrl = SWR_MIN_COL;
1347 u8 ssp_period = 1;
1348 u8 retry_cmd_num = 3;
1349 u32 reg[SWRM_MAX_INIT_REG];
1350 u32 value[SWRM_MAX_INIT_REG];
1351 int len = 0;
1352
1353 /* Clear Rows and Cols */
1354 val = ((row_ctrl << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
1355 (col_ctrl << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
1356 (ssp_period << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
1357
1358 reg[len] = SWRM_MCP_FRAME_CTRL_BANK_ADDR(0);
1359 value[len++] = val;
1360
1361 /* Set Auto enumeration flag */
1362 reg[len] = SWRM_ENUMERATOR_CFG_ADDR;
1363 value[len++] = 1;
1364
1365 /* Mask soundwire interrupts */
1366 reg[len] = SWRM_INTERRUPT_MASK_ADDR;
1367 value[len++] = 0x1FFFD;
1368
1369 /* Configure No pings */
1370 val = swrm->read(swrm->handle, SWRM_MCP_CFG_ADDR);
1371 val &= ~SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_BMSK;
1372 val |= (0x1f << SWRM_MCP_CFG_MAX_NUM_OF_CMD_NO_PINGS_SHFT);
1373 reg[len] = SWRM_MCP_CFG_ADDR;
1374 value[len++] = val;
1375
1376 /* Configure number of retries of a read/write cmd */
1377 val = (retry_cmd_num << SWRM_CMD_FIFO_CFG_NUM_OF_CMD_RETRY_SHFT);
1378 reg[len] = SWRM_CMD_FIFO_CFG_ADDR;
1379 value[len++] = val;
1380
1381 /* Set IRQ to PULSE */
1382 reg[len] = SWRM_COMP_CFG_ADDR;
1383 value[len++] = 0x02;
1384
1385 reg[len] = SWRM_COMP_CFG_ADDR;
1386 value[len++] = 0x03;
1387
1388 reg[len] = SWRM_INTERRUPT_CLEAR;
1389 value[len++] = 0x08;
1390
1391 swrm->bulk_write(swrm->handle, reg, value, len);
1392
1393 return ret;
1394}
1395
Vignesh Kulothungan9ca8dc32018-05-09 17:41:11 -07001396static int swrm_event_notify(struct notifier_block *self,
1397 unsigned long action, void *data)
1398{
1399 struct swr_mstr_ctrl *swrm = container_of(self, struct swr_mstr_ctrl,
1400 event_notifier);
1401 if (!swrm || !swrm->pdev) {
1402 pr_err("%s: swrm or pdev is NULL\n", __func__);
1403 return -EINVAL;
1404 }
1405 if (action != MSM_AUD_DC_EVENT) {
1406 dev_err(&swrm->pdev->dev, "%s: invalid event type: %lu\n", __func__, action);
1407 return -EINVAL;
1408 }
1409
1410 schedule_work(&(swrm->dc_presence_work));
1411
1412 return 0;
1413}
1414
1415static void swrm_notify_work_fn(struct work_struct *work)
1416{
1417 struct swr_mstr_ctrl *swrm = container_of(work, struct swr_mstr_ctrl,
1418 dc_presence_work);
1419 swrm_wcd_notify(swrm->pdev, SWR_DEVICE_DOWN, NULL);
1420}
1421
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301422static int swrm_probe(struct platform_device *pdev)
1423{
1424 struct swr_mstr_ctrl *swrm;
1425 struct swr_ctrl_platform_data *pdata;
1426 int ret;
1427
1428 /* Allocate soundwire master driver structure */
1429 swrm = kzalloc(sizeof(struct swr_mstr_ctrl), GFP_KERNEL);
1430 if (!swrm) {
1431 ret = -ENOMEM;
1432 goto err_memory_fail;
1433 }
1434 swrm->dev = &pdev->dev;
1435 swrm->pdev = pdev;
1436 platform_set_drvdata(pdev, swrm);
1437 swr_set_ctrl_data(&swrm->master, swrm);
1438 pdata = dev_get_platdata(&pdev->dev);
1439 if (!pdata) {
1440 dev_err(&pdev->dev, "%s: pdata from parent is NULL\n",
1441 __func__);
1442 ret = -EINVAL;
1443 goto err_pdata_fail;
1444 }
1445 swrm->handle = (void *)pdata->handle;
1446 if (!swrm->handle) {
1447 dev_err(&pdev->dev, "%s: swrm->handle is NULL\n",
1448 __func__);
1449 ret = -EINVAL;
1450 goto err_pdata_fail;
1451 }
1452 swrm->read = pdata->read;
1453 if (!swrm->read) {
1454 dev_err(&pdev->dev, "%s: swrm->read is NULL\n",
1455 __func__);
1456 ret = -EINVAL;
1457 goto err_pdata_fail;
1458 }
1459 swrm->write = pdata->write;
1460 if (!swrm->write) {
1461 dev_err(&pdev->dev, "%s: swrm->write is NULL\n",
1462 __func__);
1463 ret = -EINVAL;
1464 goto err_pdata_fail;
1465 }
1466 swrm->bulk_write = pdata->bulk_write;
1467 if (!swrm->bulk_write) {
1468 dev_err(&pdev->dev, "%s: swrm->bulk_write is NULL\n",
1469 __func__);
1470 ret = -EINVAL;
1471 goto err_pdata_fail;
1472 }
1473 swrm->clk = pdata->clk;
1474 if (!swrm->clk) {
1475 dev_err(&pdev->dev, "%s: swrm->clk is NULL\n",
1476 __func__);
1477 ret = -EINVAL;
1478 goto err_pdata_fail;
1479 }
1480 swrm->reg_irq = pdata->reg_irq;
1481 if (!swrm->reg_irq) {
1482 dev_err(&pdev->dev, "%s: swrm->reg_irq is NULL\n",
1483 __func__);
1484 ret = -EINVAL;
1485 goto err_pdata_fail;
1486 }
1487 swrm->master.read = swrm_read;
1488 swrm->master.write = swrm_write;
1489 swrm->master.bulk_write = swrm_bulk_write;
1490 swrm->master.get_logical_dev_num = swrm_get_logical_dev_num;
1491 swrm->master.connect_port = swrm_connect_port;
1492 swrm->master.disconnect_port = swrm_disconnect_port;
1493 swrm->master.slvdev_datapath_control = swrm_slvdev_datapath_control;
1494 swrm->master.remove_from_group = swrm_remove_from_group;
1495 swrm->master.dev.parent = &pdev->dev;
1496 swrm->master.dev.of_node = pdev->dev.of_node;
1497 swrm->master.num_port = 0;
1498 swrm->num_enum_slaves = 0;
1499 swrm->rcmd_id = 0;
1500 swrm->wcmd_id = 0;
1501 swrm->slave_status = 0;
1502 swrm->num_rx_chs = 0;
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +05301503 swrm->clk_ref_count = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301504 swrm->state = SWR_MSTR_RESUME;
1505 init_completion(&swrm->reset);
1506 init_completion(&swrm->broadcast);
1507 mutex_init(&swrm->mlock);
1508 INIT_LIST_HEAD(&swrm->mport_list);
1509 mutex_init(&swrm->reslock);
Xiaojun Sangf7dd63a2017-12-19 16:56:24 +08001510 mutex_init(&swrm->force_down_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301511
Laxminath Kasam55c95512018-02-26 20:31:02 +05301512 ret = of_property_read_u32(swrm->dev->of_node, "qcom,swr-num-dev",
1513 &swrm->num_dev);
1514 if (ret)
1515 dev_dbg(&pdev->dev, "%s: Looking up %s property failed\n",
1516 __func__, "qcom,swr-num-dev");
1517 else {
1518 if (swrm->num_dev > SWR_MAX_SLAVE_DEVICES) {
1519 dev_err(&pdev->dev, "%s: num_dev %d > max limit %d\n",
1520 __func__, swrm->num_dev, SWR_MAX_SLAVE_DEVICES);
1521 ret = -EINVAL;
1522 goto err_pdata_fail;
1523 }
1524 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301525 ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm,
1526 SWR_IRQ_REGISTER);
1527 if (ret) {
1528 dev_err(&pdev->dev, "%s: IRQ register failed ret %d\n",
1529 __func__, ret);
1530 goto err_irq_fail;
1531 }
1532
1533 ret = swr_register_master(&swrm->master);
1534 if (ret) {
1535 dev_err(&pdev->dev, "%s: error adding swr master\n", __func__);
1536 goto err_mstr_fail;
1537 }
1538
1539 /* Add devices registered with board-info as the
1540 * controller will be up now
1541 */
1542 swr_master_add_boarddevices(&swrm->master);
1543 mutex_lock(&swrm->mlock);
1544 swrm_clk_request(swrm, true);
1545 ret = swrm_master_init(swrm);
1546 if (ret < 0) {
1547 dev_err(&pdev->dev,
1548 "%s: Error in master Initializaiton, err %d\n",
1549 __func__, ret);
1550 mutex_unlock(&swrm->mlock);
1551 goto err_mstr_fail;
1552 }
1553 swrm->version = swrm->read(swrm->handle, SWRM_COMP_HW_VERSION);
1554
1555 mutex_unlock(&swrm->mlock);
1556
1557 if (pdev->dev.of_node)
1558 of_register_swr_devices(&swrm->master);
1559
1560 dbgswrm = swrm;
1561 debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0);
1562 if (!IS_ERR(debugfs_swrm_dent)) {
1563 debugfs_peek = debugfs_create_file("swrm_peek",
1564 S_IFREG | 0444, debugfs_swrm_dent,
1565 (void *) "swrm_peek", &swrm_debug_ops);
1566
1567 debugfs_poke = debugfs_create_file("swrm_poke",
1568 S_IFREG | 0444, debugfs_swrm_dent,
1569 (void *) "swrm_poke", &swrm_debug_ops);
1570
1571 debugfs_reg_dump = debugfs_create_file("swrm_reg_dump",
1572 S_IFREG | 0444, debugfs_swrm_dent,
1573 (void *) "swrm_reg_dump",
1574 &swrm_debug_ops);
1575 }
1576 pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer);
1577 pm_runtime_use_autosuspend(&pdev->dev);
1578 pm_runtime_set_active(&pdev->dev);
1579 pm_runtime_enable(&pdev->dev);
1580 pm_runtime_mark_last_busy(&pdev->dev);
1581
Vignesh Kulothungan9ca8dc32018-05-09 17:41:11 -07001582 INIT_WORK(&swrm->dc_presence_work, swrm_notify_work_fn);
1583 swrm->event_notifier.notifier_call = swrm_event_notify;
1584 msm_aud_evt_register_client(&swrm->event_notifier);
1585
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301586 return 0;
1587err_mstr_fail:
1588 swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
1589 swrm, SWR_IRQ_FREE);
1590err_irq_fail:
Xiaojun Sangf7dd63a2017-12-19 16:56:24 +08001591 mutex_destroy(&swrm->mlock);
1592 mutex_destroy(&swrm->reslock);
1593 mutex_destroy(&swrm->force_down_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301594err_pdata_fail:
1595 kfree(swrm);
1596err_memory_fail:
1597 return ret;
1598}
1599
1600static int swrm_remove(struct platform_device *pdev)
1601{
1602 struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
1603
Laxminath Kasam30ad7512017-11-28 12:40:22 +05301604 if (swrm->reg_irq)
1605 swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
1606 swrm, SWR_IRQ_FREE);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301607 if (swrm->mstr_port) {
1608 kfree(swrm->mstr_port->port);
1609 swrm->mstr_port->port = NULL;
1610 kfree(swrm->mstr_port);
1611 swrm->mstr_port = NULL;
1612 }
1613 pm_runtime_disable(&pdev->dev);
1614 pm_runtime_set_suspended(&pdev->dev);
1615 swr_unregister_master(&swrm->master);
Vignesh Kulothungan9ca8dc32018-05-09 17:41:11 -07001616 msm_aud_evt_unregister_client(&swrm->event_notifier);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301617 mutex_destroy(&swrm->mlock);
1618 mutex_destroy(&swrm->reslock);
Xiaojun Sangf7dd63a2017-12-19 16:56:24 +08001619 mutex_destroy(&swrm->force_down_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301620 kfree(swrm);
1621 return 0;
1622}
1623
1624static int swrm_clk_pause(struct swr_mstr_ctrl *swrm)
1625{
1626 u32 val;
1627
1628 dev_dbg(swrm->dev, "%s: state: %d\n", __func__, swrm->state);
1629 swrm->write(swrm->handle, SWRM_INTERRUPT_MASK_ADDR, 0x1FDFD);
1630 val = swrm->read(swrm->handle, SWRM_MCP_CFG_ADDR);
1631 val |= SWRM_MCP_CFG_BUS_CLK_PAUSE_BMSK;
1632 swrm->write(swrm->handle, SWRM_MCP_CFG_ADDR, val);
1633 swrm->state = SWR_MSTR_PAUSE;
1634
1635 return 0;
1636}
1637
1638#ifdef CONFIG_PM
1639static int swrm_runtime_resume(struct device *dev)
1640{
1641 struct platform_device *pdev = to_platform_device(dev);
1642 struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
1643 int ret = 0;
1644 struct swr_master *mstr = &swrm->master;
1645 struct swr_device *swr_dev;
1646
1647 dev_dbg(dev, "%s: pm_runtime: resume, state:%d\n",
1648 __func__, swrm->state);
1649 mutex_lock(&swrm->reslock);
1650 if ((swrm->state == SWR_MSTR_PAUSE) ||
1651 (swrm->state == SWR_MSTR_DOWN)) {
1652 if (swrm->state == SWR_MSTR_DOWN) {
1653 if (swrm_clk_request(swrm, true))
1654 goto exit;
1655 }
1656 list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
1657 ret = swr_device_up(swr_dev);
1658 if (ret) {
1659 dev_err(dev,
1660 "%s: failed to wakeup swr dev %d\n",
1661 __func__, swr_dev->dev_num);
1662 swrm_clk_request(swrm, false);
1663 goto exit;
1664 }
1665 }
1666 swrm->write(swrm->handle, SWRM_COMP_SW_RESET, 0x01);
1667 swrm->write(swrm->handle, SWRM_COMP_SW_RESET, 0x01);
1668 swrm_master_init(swrm);
1669 }
1670exit:
1671 pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer);
1672 mutex_unlock(&swrm->reslock);
1673 return ret;
1674}
1675
1676static int swrm_runtime_suspend(struct device *dev)
1677{
1678 struct platform_device *pdev = to_platform_device(dev);
1679 struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
1680 int ret = 0;
1681 struct swr_master *mstr = &swrm->master;
1682 struct swr_device *swr_dev;
Xiaojun Sangf7dd63a2017-12-19 16:56:24 +08001683 int current_state = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301684
1685 dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n",
1686 __func__, swrm->state);
1687 mutex_lock(&swrm->reslock);
Xiaojun Sangf7dd63a2017-12-19 16:56:24 +08001688 mutex_lock(&swrm->force_down_lock);
1689 current_state = swrm->state;
1690 mutex_unlock(&swrm->force_down_lock);
1691 if ((current_state == SWR_MSTR_RESUME) ||
1692 (current_state == SWR_MSTR_UP) ||
1693 (current_state == SWR_MSTR_SSR)) {
1694
1695 if ((current_state != SWR_MSTR_SSR) &&
1696 swrm_is_port_en(&swrm->master)) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301697 dev_dbg(dev, "%s ports are enabled\n", __func__);
1698 ret = -EBUSY;
1699 goto exit;
1700 }
1701 swrm_clk_pause(swrm);
1702 swrm->write(swrm->handle, SWRM_COMP_CFG_ADDR, 0x00);
1703 list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
1704 ret = swr_device_down(swr_dev);
1705 if (ret) {
1706 dev_err(dev,
1707 "%s: failed to shutdown swr dev %d\n",
1708 __func__, swr_dev->dev_num);
1709 goto exit;
1710 }
1711 }
1712 swrm_clk_request(swrm, false);
1713 }
1714exit:
1715 mutex_unlock(&swrm->reslock);
1716 return ret;
1717}
1718#endif /* CONFIG_PM */
1719
1720static int swrm_device_down(struct device *dev)
1721{
1722 struct platform_device *pdev = to_platform_device(dev);
1723 struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
1724 int ret = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301725
1726 dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state);
Xiaojun Sangf7dd63a2017-12-19 16:56:24 +08001727
1728 mutex_lock(&swrm->force_down_lock);
1729 swrm->state = SWR_MSTR_SSR;
1730 mutex_unlock(&swrm->force_down_lock);
1731 /* Use pm runtime function to tear down */
1732 ret = pm_runtime_put_sync_suspend(dev);
1733 pm_runtime_get_noresume(dev);
1734
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301735 return ret;
1736}
1737
1738/**
1739 * swrm_wcd_notify - parent device can notify to soundwire master through
1740 * this function
1741 * @pdev: pointer to platform device structure
1742 * @id: command id from parent to the soundwire master
1743 * @data: data from parent device to soundwire master
1744 */
1745int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
1746{
1747 struct swr_mstr_ctrl *swrm;
1748 int ret = 0;
1749 struct swr_master *mstr;
1750 struct swr_device *swr_dev;
1751
1752 if (!pdev) {
1753 pr_err("%s: pdev is NULL\n", __func__);
1754 return -EINVAL;
1755 }
1756 swrm = platform_get_drvdata(pdev);
1757 if (!swrm) {
1758 dev_err(&pdev->dev, "%s: swrm is NULL\n", __func__);
1759 return -EINVAL;
1760 }
1761 mstr = &swrm->master;
1762
1763 switch (id) {
1764 case SWR_CH_MAP:
1765 if (!data) {
1766 dev_err(swrm->dev, "%s: data is NULL\n", __func__);
1767 ret = -EINVAL;
1768 } else {
1769 ret = swrm_set_ch_map(swrm, data);
1770 }
1771 break;
1772 case SWR_DEVICE_DOWN:
1773 dev_dbg(swrm->dev, "%s: swr master down called\n", __func__);
1774 mutex_lock(&swrm->mlock);
1775 if ((swrm->state == SWR_MSTR_PAUSE) ||
1776 (swrm->state == SWR_MSTR_DOWN))
1777 dev_dbg(swrm->dev, "%s: SWR master is already Down: %d\n",
1778 __func__, swrm->state);
1779 else
1780 swrm_device_down(&pdev->dev);
1781 mutex_unlock(&swrm->mlock);
1782 break;
1783 case SWR_DEVICE_UP:
1784 dev_dbg(swrm->dev, "%s: swr master up called\n", __func__);
1785 mutex_lock(&swrm->mlock);
1786 mutex_lock(&swrm->reslock);
1787 if ((swrm->state == SWR_MSTR_RESUME) ||
1788 (swrm->state == SWR_MSTR_UP)) {
1789 dev_dbg(swrm->dev, "%s: SWR master is already UP: %d\n",
1790 __func__, swrm->state);
Laxminath Kasam3fda0752018-07-31 19:27:44 +05301791 list_for_each_entry(swr_dev, &mstr->devices, dev_list)
1792 swr_reset_device(swr_dev);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301793 } else {
1794 pm_runtime_mark_last_busy(&pdev->dev);
1795 mutex_unlock(&swrm->reslock);
1796 pm_runtime_get_sync(&pdev->dev);
1797 mutex_lock(&swrm->reslock);
1798 list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
1799 ret = swr_reset_device(swr_dev);
1800 if (ret) {
1801 dev_err(swrm->dev,
1802 "%s: failed to reset swr device %d\n",
1803 __func__, swr_dev->dev_num);
1804 swrm_clk_request(swrm, false);
1805 }
1806 }
1807 pm_runtime_mark_last_busy(&pdev->dev);
1808 pm_runtime_put_autosuspend(&pdev->dev);
1809 }
1810 mutex_unlock(&swrm->reslock);
1811 mutex_unlock(&swrm->mlock);
1812 break;
1813 case SWR_SET_NUM_RX_CH:
1814 if (!data) {
1815 dev_err(swrm->dev, "%s: data is NULL\n", __func__);
1816 ret = -EINVAL;
1817 } else {
1818 mutex_lock(&swrm->mlock);
1819 swrm->num_rx_chs = *(int *)data;
1820 if ((swrm->num_rx_chs > 1) && !swrm->num_cfg_devs) {
1821 list_for_each_entry(swr_dev, &mstr->devices,
1822 dev_list) {
1823 ret = swr_set_device_group(swr_dev,
1824 SWR_BROADCAST);
1825 if (ret)
1826 dev_err(swrm->dev,
1827 "%s: set num ch failed\n",
1828 __func__);
1829 }
1830 } else {
1831 list_for_each_entry(swr_dev, &mstr->devices,
1832 dev_list) {
1833 ret = swr_set_device_group(swr_dev,
1834 SWR_GROUP_NONE);
1835 if (ret)
1836 dev_err(swrm->dev,
1837 "%s: set num ch failed\n",
1838 __func__);
1839 }
1840 }
1841 mutex_unlock(&swrm->mlock);
1842 }
1843 break;
1844 default:
1845 dev_err(swrm->dev, "%s: swr master unknown id %d\n",
1846 __func__, id);
1847 break;
1848 }
1849 return ret;
1850}
1851EXPORT_SYMBOL(swrm_wcd_notify);
1852
1853#ifdef CONFIG_PM_SLEEP
1854static int swrm_suspend(struct device *dev)
1855{
1856 int ret = -EBUSY;
1857 struct platform_device *pdev = to_platform_device(dev);
1858 struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
1859
1860 dev_dbg(dev, "%s: system suspend, state: %d\n", __func__, swrm->state);
1861 if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
1862 ret = swrm_runtime_suspend(dev);
1863 if (!ret) {
1864 /*
1865 * Synchronize runtime-pm and system-pm states:
1866 * At this point, we are already suspended. If
1867 * runtime-pm still thinks its active, then
1868 * make sure its status is in sync with HW
1869 * status. The three below calls let the
1870 * runtime-pm know that we are suspended
1871 * already without re-invoking the suspend
1872 * callback
1873 */
1874 pm_runtime_disable(dev);
1875 pm_runtime_set_suspended(dev);
1876 pm_runtime_enable(dev);
1877 }
1878 }
1879 if (ret == -EBUSY) {
1880 /*
1881 * There is a possibility that some audio stream is active
1882 * during suspend. We dont want to return suspend failure in
1883 * that case so that display and relevant components can still
1884 * go to suspend.
1885 * If there is some other error, then it should be passed-on
1886 * to system level suspend
1887 */
1888 ret = 0;
1889 }
1890 return ret;
1891}
1892
1893static int swrm_resume(struct device *dev)
1894{
1895 int ret = 0;
1896 struct platform_device *pdev = to_platform_device(dev);
1897 struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
1898
1899 dev_dbg(dev, "%s: system resume, state: %d\n", __func__, swrm->state);
1900 if (!pm_runtime_enabled(dev) || !pm_runtime_suspend(dev)) {
1901 ret = swrm_runtime_resume(dev);
1902 if (!ret) {
1903 pm_runtime_mark_last_busy(dev);
1904 pm_request_autosuspend(dev);
1905 }
1906 }
1907 return ret;
1908}
1909#endif /* CONFIG_PM_SLEEP */
1910
1911static const struct dev_pm_ops swrm_dev_pm_ops = {
1912 SET_SYSTEM_SLEEP_PM_OPS(
1913 swrm_suspend,
1914 swrm_resume
1915 )
1916 SET_RUNTIME_PM_OPS(
1917 swrm_runtime_suspend,
1918 swrm_runtime_resume,
1919 NULL
1920 )
1921};
1922
1923static const struct of_device_id swrm_dt_match[] = {
1924 {
1925 .compatible = "qcom,swr-wcd",
1926 },
1927 {}
1928};
1929
1930static struct platform_driver swr_mstr_driver = {
1931 .probe = swrm_probe,
1932 .remove = swrm_remove,
1933 .driver = {
1934 .name = SWR_WCD_NAME,
1935 .owner = THIS_MODULE,
1936 .pm = &swrm_dev_pm_ops,
1937 .of_match_table = swrm_dt_match,
Xiaojun Sang53cd13a2018-06-29 15:14:37 +08001938 .suppress_bind_attrs = true,
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301939 },
1940};
1941
1942static int __init swrm_init(void)
1943{
1944 return platform_driver_register(&swr_mstr_driver);
1945}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05301946module_init(swrm_init);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301947
1948static void __exit swrm_exit(void)
1949{
1950 platform_driver_unregister(&swr_mstr_driver);
1951}
1952module_exit(swrm_exit);
1953
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301954MODULE_LICENSE("GPL v2");
1955MODULE_DESCRIPTION("WCD SoundWire Controller");
1956MODULE_ALIAS("platform:swr-wcd");