1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright(c) 2015-2020 Intel Corporation.
3
4 #include <linux/device.h>
5 #include <linux/slab.h>
6 #include <linux/sysfs.h>
7 #include <linux/soundwire/sdw.h>
8 #include <linux/soundwire/sdw_type.h>
9 #include "bus.h"
10 #include "sysfs_local.h"
11
12 /*
13 * Slave sysfs
14 */
15
16 /*
17 * The sysfs for Slave reflects the MIPI description as given
18 * in the MIPI DisCo spec.
19 * status and device_number come directly from the MIPI SoundWire
20 * 1.x specification.
21 *
22 * Base file is device
23 * |---- status
24 * |---- device_number
25 * |---- modalias
26 * |---- dev-properties
27 * |---- mipi_revision
28 * |---- wake_capable
29 * |---- test_mode_capable
30 * |---- clk_stop_mode1
31 * |---- simple_clk_stop_capable
32 * |---- clk_stop_timeout
33 * |---- ch_prep_timeout
34 * |---- reset_behave
35 * |---- high_PHY_capable
36 * |---- paging_support
37 * |---- bank_delay_support
38 * |---- p15_behave
39 * |---- master_count
40 * |---- source_ports
41 * |---- sink_ports
42 * |---- dp0
43 * |---- max_word
44 * |---- min_word
45 * |---- words
46 * |---- BRA_flow_controlled
47 * |---- simple_ch_prep_sm
48 * |---- imp_def_interrupts
49 * |---- dpN_<sink/src>
50 * |---- max_word
51 * |---- min_word
52 * |---- words
53 * |---- type
54 * |---- max_grouping
55 * |---- simple_ch_prep_sm
56 * |---- ch_prep_timeout
57 * |---- imp_def_interrupts
58 * |---- min_ch
59 * |---- max_ch
60 * |---- channels
61 * |---- ch_combinations
62 * |---- max_async_buffer
63 * |---- block_pack_mode
64 * |---- port_encoding
65 *
66 */
67
68 #define sdw_slave_attr(field, format_string) \
69 static ssize_t field##_show(struct device *dev, \
70 struct device_attribute *attr, \
71 char *buf) \
72 { \
73 struct sdw_slave *slave = dev_to_sdw_dev(dev); \
74 return sprintf(buf, format_string, slave->prop.field); \
75 } \
76 static DEVICE_ATTR_RO(field)
77
78 sdw_slave_attr(mipi_revision, "0x%x\n");
79 sdw_slave_attr(wake_capable, "%d\n");
80 sdw_slave_attr(test_mode_capable, "%d\n");
81 sdw_slave_attr(clk_stop_mode1, "%d\n");
82 sdw_slave_attr(simple_clk_stop_capable, "%d\n");
83 sdw_slave_attr(clk_stop_timeout, "%d\n");
84 sdw_slave_attr(ch_prep_timeout, "%d\n");
85 sdw_slave_attr(reset_behave, "%d\n");
86 sdw_slave_attr(high_PHY_capable, "%d\n");
87 sdw_slave_attr(paging_support, "%d\n");
88 sdw_slave_attr(bank_delay_support, "%d\n");
89 sdw_slave_attr(p15_behave, "%d\n");
90 sdw_slave_attr(master_count, "%d\n");
91 sdw_slave_attr(source_ports, "0x%x\n");
92 sdw_slave_attr(sink_ports, "0x%x\n");
93
modalias_show(struct device * dev,struct device_attribute * attr,char * buf)94 static ssize_t modalias_show(struct device *dev,
95 struct device_attribute *attr, char *buf)
96 {
97 struct sdw_slave *slave = dev_to_sdw_dev(dev);
98
99 return sdw_slave_modalias(slave, buf, 256);
100 }
101 static DEVICE_ATTR_RO(modalias);
102
103 static struct attribute *slave_attrs[] = {
104 &dev_attr_modalias.attr,
105 NULL,
106 };
107
108 static const struct attribute_group slave_attr_group = {
109 .attrs = slave_attrs,
110 };
111
112 static struct attribute *slave_dev_attrs[] = {
113 &dev_attr_mipi_revision.attr,
114 &dev_attr_wake_capable.attr,
115 &dev_attr_test_mode_capable.attr,
116 &dev_attr_clk_stop_mode1.attr,
117 &dev_attr_simple_clk_stop_capable.attr,
118 &dev_attr_clk_stop_timeout.attr,
119 &dev_attr_ch_prep_timeout.attr,
120 &dev_attr_reset_behave.attr,
121 &dev_attr_high_PHY_capable.attr,
122 &dev_attr_paging_support.attr,
123 &dev_attr_bank_delay_support.attr,
124 &dev_attr_p15_behave.attr,
125 &dev_attr_master_count.attr,
126 &dev_attr_source_ports.attr,
127 &dev_attr_sink_ports.attr,
128 NULL,
129 };
130
131 static const struct attribute_group sdw_slave_dev_attr_group = {
132 .attrs = slave_dev_attrs,
133 .name = "dev-properties",
134 };
135
136 /*
137 * DP0 sysfs
138 */
139
140 #define sdw_dp0_attr(field, format_string) \
141 static ssize_t field##_show(struct device *dev, \
142 struct device_attribute *attr, \
143 char *buf) \
144 { \
145 struct sdw_slave *slave = dev_to_sdw_dev(dev); \
146 return sprintf(buf, format_string, slave->prop.dp0_prop->field);\
147 } \
148 static DEVICE_ATTR_RO(field)
149
150 sdw_dp0_attr(max_word, "%d\n");
151 sdw_dp0_attr(min_word, "%d\n");
152 sdw_dp0_attr(BRA_flow_controlled, "%d\n");
153 sdw_dp0_attr(simple_ch_prep_sm, "%d\n");
154 sdw_dp0_attr(imp_def_interrupts, "0x%x\n");
155
words_show(struct device * dev,struct device_attribute * attr,char * buf)156 static ssize_t words_show(struct device *dev,
157 struct device_attribute *attr, char *buf)
158 {
159 struct sdw_slave *slave = dev_to_sdw_dev(dev);
160 ssize_t size = 0;
161 int i;
162
163 for (i = 0; i < slave->prop.dp0_prop->num_words; i++)
164 size += sprintf(buf + size, "%d ",
165 slave->prop.dp0_prop->words[i]);
166 size += sprintf(buf + size, "\n");
167
168 return size;
169 }
170 static DEVICE_ATTR_RO(words);
171
172 static struct attribute *dp0_attrs[] = {
173 &dev_attr_max_word.attr,
174 &dev_attr_min_word.attr,
175 &dev_attr_words.attr,
176 &dev_attr_BRA_flow_controlled.attr,
177 &dev_attr_simple_ch_prep_sm.attr,
178 &dev_attr_imp_def_interrupts.attr,
179 NULL,
180 };
181
dp0_attr_visible(struct kobject * kobj,struct attribute * attr,int n)182 static umode_t dp0_attr_visible(struct kobject *kobj, struct attribute *attr,
183 int n)
184 {
185 struct sdw_slave *slave = dev_to_sdw_dev(kobj_to_dev(kobj));
186
187 if (slave->prop.dp0_prop)
188 return attr->mode;
189 return 0;
190 }
191
dp0_group_visible(struct kobject * kobj)192 static bool dp0_group_visible(struct kobject *kobj)
193 {
194 struct sdw_slave *slave = dev_to_sdw_dev(kobj_to_dev(kobj));
195
196 if (slave->prop.dp0_prop)
197 return true;
198 return false;
199 }
200 DEFINE_SYSFS_GROUP_VISIBLE(dp0);
201
202 static const struct attribute_group dp0_group = {
203 .attrs = dp0_attrs,
204 .is_visible = SYSFS_GROUP_VISIBLE(dp0),
205 .name = "dp0",
206 };
207
208 const struct attribute_group *sdw_attr_groups[] = {
209 &slave_attr_group,
210 &sdw_slave_dev_attr_group,
211 &dp0_group,
212 NULL,
213 };
214
215 /*
216 * the status is shown in capital letters for UNATTACHED and RESERVED
217 * on purpose, to highlight users to the fact that these status values
218 * are not expected.
219 */
220 static const char *const slave_status[] = {
221 [SDW_SLAVE_UNATTACHED] = "UNATTACHED",
222 [SDW_SLAVE_ATTACHED] = "Attached",
223 [SDW_SLAVE_ALERT] = "Alert",
224 [SDW_SLAVE_RESERVED] = "RESERVED",
225 };
226
status_show(struct device * dev,struct device_attribute * attr,char * buf)227 static ssize_t status_show(struct device *dev,
228 struct device_attribute *attr, char *buf)
229 {
230 struct sdw_slave *slave = dev_to_sdw_dev(dev);
231
232 return sprintf(buf, "%s\n", slave_status[slave->status]);
233 }
234 static DEVICE_ATTR_RO(status);
235
device_number_show(struct device * dev,struct device_attribute * attr,char * buf)236 static ssize_t device_number_show(struct device *dev,
237 struct device_attribute *attr, char *buf)
238 {
239 struct sdw_slave *slave = dev_to_sdw_dev(dev);
240
241 if (slave->status == SDW_SLAVE_UNATTACHED)
242 return sprintf(buf, "%s", "N/A");
243 else
244 return sprintf(buf, "%d", slave->dev_num);
245 }
246 static DEVICE_ATTR_RO(device_number);
247
248 static struct attribute *slave_status_attrs[] = {
249 &dev_attr_status.attr,
250 &dev_attr_device_number.attr,
251 NULL,
252 };
253
254 /*
255 * we don't use ATTRIBUTES_GROUP here since the group is used in a
256 * separate file and can't be handled as a static.
257 */
258 static const struct attribute_group sdw_slave_status_attr_group = {
259 .attrs = slave_status_attrs,
260 };
261
262 const struct attribute_group *sdw_slave_status_attr_groups[] = {
263 &sdw_slave_status_attr_group,
264 NULL
265 };
266