1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright(c) 2017-2019 Intel Corporation.
4 #include <linux/device.h>
5 #include <linux/debugfs.h>
6 #include <linux/mod_devicetable.h>
7 #include <linux/slab.h>
8 #include <linux/soundwire/sdw.h>
9 #include <linux/soundwire/sdw_registers.h>
12 static struct dentry
*sdw_debugfs_root
;
14 void sdw_bus_debugfs_init(struct sdw_bus
*bus
)
18 if (!sdw_debugfs_root
)
21 /* create the debugfs master-N */
22 snprintf(name
, sizeof(name
), "master-%d", bus
->link_id
);
23 bus
->debugfs
= debugfs_create_dir(name
, sdw_debugfs_root
);
26 void sdw_bus_debugfs_exit(struct sdw_bus
*bus
)
28 debugfs_remove_recursive(bus
->debugfs
);
31 #define RD_BUF (3 * PAGE_SIZE)
33 static ssize_t
sdw_sprintf(struct sdw_slave
*slave
,
34 char *buf
, size_t pos
, unsigned int reg
)
38 value
= sdw_read(slave
, reg
);
41 return scnprintf(buf
+ pos
, RD_BUF
- pos
, "%3x\tXX\n", reg
);
43 return scnprintf(buf
+ pos
, RD_BUF
- pos
,
44 "%3x\t%2x\n", reg
, value
);
47 static int sdw_slave_reg_show(struct seq_file
*s_file
, void *data
)
49 struct sdw_slave
*slave
= s_file
->private;
54 buf
= kzalloc(RD_BUF
, GFP_KERNEL
);
58 ret
= scnprintf(buf
, RD_BUF
, "Register Value\n");
60 /* DP0 non-banked registers */
61 ret
+= scnprintf(buf
+ ret
, RD_BUF
- ret
, "\nDP0\n");
62 for (i
= SDW_DP0_INT
; i
<= SDW_DP0_PREPARECTRL
; i
++)
63 ret
+= sdw_sprintf(slave
, buf
, ret
, i
);
65 /* DP0 Bank 0 registers */
66 ret
+= scnprintf(buf
+ ret
, RD_BUF
- ret
, "Bank0\n");
67 ret
+= sdw_sprintf(slave
, buf
, ret
, SDW_DP0_CHANNELEN
);
68 for (i
= SDW_DP0_SAMPLECTRL1
; i
<= SDW_DP0_LANECTRL
; i
++)
69 ret
+= sdw_sprintf(slave
, buf
, ret
, i
);
71 /* DP0 Bank 1 registers */
72 ret
+= scnprintf(buf
+ ret
, RD_BUF
- ret
, "Bank1\n");
73 ret
+= sdw_sprintf(slave
, buf
, ret
,
74 SDW_DP0_CHANNELEN
+ SDW_BANK1_OFFSET
);
75 for (i
= SDW_DP0_SAMPLECTRL1
+ SDW_BANK1_OFFSET
;
76 i
<= SDW_DP0_LANECTRL
+ SDW_BANK1_OFFSET
; i
++)
77 ret
+= sdw_sprintf(slave
, buf
, ret
, i
);
80 ret
+= scnprintf(buf
+ ret
, RD_BUF
- ret
, "\nSCP\n");
81 for (i
= SDW_SCP_INT1
; i
<= SDW_SCP_BANKDELAY
; i
++)
82 ret
+= sdw_sprintf(slave
, buf
, ret
, i
);
83 for (i
= SDW_SCP_DEVID_0
; i
<= SDW_SCP_DEVID_5
; i
++)
84 ret
+= sdw_sprintf(slave
, buf
, ret
, i
);
87 * SCP Bank 0/1 registers are read-only and cannot be
88 * retrieved from the Slave. The Master typically keeps track
89 * of the current frame size so the information can be found
93 /* DP1..14 registers */
94 for (i
= 1; SDW_VALID_PORT_RANGE(i
); i
++) {
97 ret
+= scnprintf(buf
+ ret
, RD_BUF
- ret
, "\nDP%d\n", i
);
98 for (j
= SDW_DPN_INT(i
); j
<= SDW_DPN_PREPARECTRL(i
); j
++)
99 ret
+= sdw_sprintf(slave
, buf
, ret
, j
);
101 /* DPi Bank0 registers */
102 ret
+= scnprintf(buf
+ ret
, RD_BUF
- ret
, "Bank0\n");
103 for (j
= SDW_DPN_CHANNELEN_B0(i
);
104 j
<= SDW_DPN_LANECTRL_B0(i
); j
++)
105 ret
+= sdw_sprintf(slave
, buf
, ret
, j
);
107 /* DPi Bank1 registers */
108 ret
+= scnprintf(buf
+ ret
, RD_BUF
- ret
, "Bank1\n");
109 for (j
= SDW_DPN_CHANNELEN_B1(i
);
110 j
<= SDW_DPN_LANECTRL_B1(i
); j
++)
111 ret
+= sdw_sprintf(slave
, buf
, ret
, j
);
114 seq_printf(s_file
, "%s", buf
);
119 DEFINE_SHOW_ATTRIBUTE(sdw_slave_reg
);
121 void sdw_slave_debugfs_init(struct sdw_slave
*slave
)
123 struct dentry
*master
;
127 master
= slave
->bus
->debugfs
;
129 /* create the debugfs slave-name */
130 snprintf(name
, sizeof(name
), "%s", dev_name(&slave
->dev
));
131 d
= debugfs_create_dir(name
, master
);
133 debugfs_create_file("registers", 0400, d
, slave
, &sdw_slave_reg_fops
);
138 void sdw_slave_debugfs_exit(struct sdw_slave
*slave
)
140 debugfs_remove_recursive(slave
->debugfs
);
143 void sdw_debugfs_init(void)
145 sdw_debugfs_root
= debugfs_create_dir("soundwire", NULL
);
148 void sdw_debugfs_exit(void)
150 debugfs_remove_recursive(sdw_debugfs_root
);