1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2 // Copyright(c) 2015-17 Intel Corporation.
5 * MIPI Discovery And Configuration (DisCo) Specification for SoundWire
6 * specifies properties to be implemented for SoundWire Masters and Slaves.
7 * The DisCo spec doesn't mandate these properties. However, SDW bus cannot
8 * work without knowing these values.
10 * The helper functions read the Master and Slave properties. Implementers
11 * of Master or Slave drivers can use any of the below three mechanisms:
12 * a) Use these APIs here as .read_prop() callback for Master and Slave
13 * b) Implement own methods and set those as .read_prop(), but invoke
14 * APIs in this file for generic read and override the values with
15 * platform specific data
16 * c) Implement ones own methods which do not use anything provided
20 #include <linux/device.h>
21 #include <linux/property.h>
22 #include <linux/mod_devicetable.h>
23 #include <linux/soundwire/sdw.h>
27 * sdw_master_read_prop() - Read Master properties
28 * @bus: SDW bus instance
30 int sdw_master_read_prop(struct sdw_bus
*bus
)
32 struct sdw_master_prop
*prop
= &bus
->prop
;
33 struct fwnode_handle
*link
;
37 device_property_read_u32(bus
->dev
,
38 "mipi-sdw-sw-interface-revision", &prop
->revision
);
40 /* Find master handle */
41 snprintf(name
, sizeof(name
),
42 "mipi-sdw-master-%d-subproperties", bus
->link_id
);
44 link
= device_get_named_child_node(bus
->dev
, name
);
46 dev_err(bus
->dev
, "Master node %s not found\n", name
);
50 if (fwnode_property_read_bool(link
,
51 "mipi-sdw-clock-stop-mode0-supported") == true)
52 prop
->clk_stop_mode
= SDW_CLK_STOP_MODE0
;
54 if (fwnode_property_read_bool(link
,
55 "mipi-sdw-clock-stop-mode1-supported") == true)
56 prop
->clk_stop_mode
|= SDW_CLK_STOP_MODE1
;
58 fwnode_property_read_u32(link
,
59 "mipi-sdw-max-clock-frequency", &prop
->max_freq
);
61 nval
= fwnode_property_read_u32_array(link
,
62 "mipi-sdw-clock-frequencies-supported", NULL
, 0);
65 prop
->num_freq
= nval
;
66 prop
->freq
= devm_kcalloc(bus
->dev
, prop
->num_freq
,
67 sizeof(*prop
->freq
), GFP_KERNEL
);
71 fwnode_property_read_u32_array(link
,
72 "mipi-sdw-clock-frequencies-supported",
73 prop
->freq
, prop
->num_freq
);
77 * Check the frequencies supported. If FW doesn't provide max
78 * freq, then populate here by checking values.
80 if (!prop
->max_freq
&& prop
->freq
) {
81 prop
->max_freq
= prop
->freq
[0];
82 for (i
= 1; i
< prop
->num_freq
; i
++) {
83 if (prop
->freq
[i
] > prop
->max_freq
)
84 prop
->max_freq
= prop
->freq
[i
];
88 nval
= fwnode_property_read_u32_array(link
,
89 "mipi-sdw-supported-clock-gears", NULL
, 0);
92 prop
->num_clk_gears
= nval
;
93 prop
->clk_gears
= devm_kcalloc(bus
->dev
, prop
->num_clk_gears
,
94 sizeof(*prop
->clk_gears
), GFP_KERNEL
);
98 fwnode_property_read_u32_array(link
,
99 "mipi-sdw-supported-clock-gears",
100 prop
->clk_gears
, prop
->num_clk_gears
);
103 fwnode_property_read_u32(link
, "mipi-sdw-default-frame-rate",
104 &prop
->default_frame_rate
);
106 fwnode_property_read_u32(link
, "mipi-sdw-default-frame-row-size",
109 fwnode_property_read_u32(link
, "mipi-sdw-default-frame-col-size",
112 prop
->dynamic_frame
= fwnode_property_read_bool(link
,
113 "mipi-sdw-dynamic-frame-shape");
115 fwnode_property_read_u32(link
, "mipi-sdw-command-error-threshold",
116 &prop
->err_threshold
);
120 EXPORT_SYMBOL(sdw_master_read_prop
);
122 static int sdw_slave_read_dp0(struct sdw_slave
*slave
,
123 struct fwnode_handle
*port
, struct sdw_dp0_prop
*dp0
)
127 fwnode_property_read_u32(port
, "mipi-sdw-port-max-wordlength",
130 fwnode_property_read_u32(port
, "mipi-sdw-port-min-wordlength",
133 nval
= fwnode_property_read_u32_array(port
,
134 "mipi-sdw-port-wordlength-configs", NULL
, 0);
137 dp0
->num_words
= nval
;
138 dp0
->words
= devm_kcalloc(&slave
->dev
,
139 dp0
->num_words
, sizeof(*dp0
->words
),
144 fwnode_property_read_u32_array(port
,
145 "mipi-sdw-port-wordlength-configs",
146 dp0
->words
, dp0
->num_words
);
149 dp0
->flow_controlled
= fwnode_property_read_bool(
150 port
, "mipi-sdw-bra-flow-controlled");
152 dp0
->simple_ch_prep_sm
= fwnode_property_read_bool(
153 port
, "mipi-sdw-simplified-channel-prepare-sm");
155 dp0
->device_interrupts
= fwnode_property_read_bool(
156 port
, "mipi-sdw-imp-def-dp0-interrupts-supported");
161 static int sdw_slave_read_dpn(struct sdw_slave
*slave
,
162 struct sdw_dpn_prop
*dpn
, int count
, int ports
, char *type
)
164 struct fwnode_handle
*node
;
171 /* valid ports are 1 to 14 so apply mask */
172 addr
&= GENMASK(14, 1);
174 for_each_set_bit(bit
, &addr
, 32) {
175 snprintf(name
, sizeof(name
),
176 "mipi-sdw-dp-%d-%s-subproperties", bit
, type
);
180 node
= device_get_named_child_node(&slave
->dev
, name
);
182 dev_err(&slave
->dev
, "%s dpN not found\n", name
);
186 fwnode_property_read_u32(node
, "mipi-sdw-port-max-wordlength",
188 fwnode_property_read_u32(node
, "mipi-sdw-port-min-wordlength",
191 nval
= fwnode_property_read_u32_array(node
,
192 "mipi-sdw-port-wordlength-configs", NULL
, 0);
195 dpn
[i
].num_words
= nval
;
196 dpn
[i
].words
= devm_kcalloc(&slave
->dev
,
198 sizeof(*dpn
[i
].words
), GFP_KERNEL
);
202 fwnode_property_read_u32_array(node
,
203 "mipi-sdw-port-wordlength-configs",
204 dpn
[i
].words
, dpn
[i
].num_words
);
207 fwnode_property_read_u32(node
, "mipi-sdw-data-port-type",
210 fwnode_property_read_u32(node
,
211 "mipi-sdw-max-grouping-supported",
212 &dpn
[i
].max_grouping
);
214 dpn
[i
].simple_ch_prep_sm
= fwnode_property_read_bool(node
,
215 "mipi-sdw-simplified-channelprepare-sm");
217 fwnode_property_read_u32(node
,
218 "mipi-sdw-port-channelprepare-timeout",
219 &dpn
[i
].ch_prep_timeout
);
221 fwnode_property_read_u32(node
,
222 "mipi-sdw-imp-def-dpn-interrupts-supported",
223 &dpn
[i
].device_interrupts
);
225 fwnode_property_read_u32(node
, "mipi-sdw-min-channel-number",
228 fwnode_property_read_u32(node
, "mipi-sdw-max-channel-number",
231 nval
= fwnode_property_read_u32_array(node
,
232 "mipi-sdw-channel-number-list", NULL
, 0);
235 dpn
[i
].num_ch
= nval
;
236 dpn
[i
].ch
= devm_kcalloc(&slave
->dev
, dpn
[i
].num_ch
,
237 sizeof(*dpn
[i
].ch
), GFP_KERNEL
);
241 fwnode_property_read_u32_array(node
,
242 "mipi-sdw-channel-number-list",
243 dpn
[i
].ch
, dpn
[i
].num_ch
);
246 nval
= fwnode_property_read_u32_array(node
,
247 "mipi-sdw-channel-combination-list", NULL
, 0);
250 dpn
[i
].num_ch_combinations
= nval
;
251 dpn
[i
].ch_combinations
= devm_kcalloc(&slave
->dev
,
252 dpn
[i
].num_ch_combinations
,
253 sizeof(*dpn
[i
].ch_combinations
),
255 if (!dpn
[i
].ch_combinations
)
258 fwnode_property_read_u32_array(node
,
259 "mipi-sdw-channel-combination-list",
260 dpn
[i
].ch_combinations
,
261 dpn
[i
].num_ch_combinations
);
264 fwnode_property_read_u32(node
,
265 "mipi-sdw-modes-supported", &dpn
[i
].modes
);
267 fwnode_property_read_u32(node
, "mipi-sdw-max-async-buffer",
268 &dpn
[i
].max_async_buffer
);
270 dpn
[i
].block_pack_mode
= fwnode_property_read_bool(node
,
271 "mipi-sdw-block-packing-mode");
273 fwnode_property_read_u32(node
, "mipi-sdw-port-encoding-type",
274 &dpn
[i
].port_encoding
);
276 /* TODO: Read audio mode */
285 * sdw_slave_read_prop() - Read Slave properties
288 int sdw_slave_read_prop(struct sdw_slave
*slave
)
290 struct sdw_slave_prop
*prop
= &slave
->prop
;
291 struct device
*dev
= &slave
->dev
;
292 struct fwnode_handle
*port
;
293 int num_of_ports
, nval
, i
, dp0
= 0;
295 device_property_read_u32(dev
, "mipi-sdw-sw-interface-revision",
296 &prop
->mipi_revision
);
298 prop
->wake_capable
= device_property_read_bool(dev
,
299 "mipi-sdw-wake-up-unavailable");
300 prop
->wake_capable
= !prop
->wake_capable
;
302 prop
->test_mode_capable
= device_property_read_bool(dev
,
303 "mipi-sdw-test-mode-supported");
305 prop
->clk_stop_mode1
= false;
306 if (device_property_read_bool(dev
,
307 "mipi-sdw-clock-stop-mode1-supported"))
308 prop
->clk_stop_mode1
= true;
310 prop
->simple_clk_stop_capable
= device_property_read_bool(dev
,
311 "mipi-sdw-simplified-clockstopprepare-sm-supported");
313 device_property_read_u32(dev
, "mipi-sdw-clockstopprepare-timeout",
314 &prop
->clk_stop_timeout
);
316 device_property_read_u32(dev
, "mipi-sdw-slave-channelprepare-timeout",
317 &prop
->ch_prep_timeout
);
319 device_property_read_u32(dev
,
320 "mipi-sdw-clockstopprepare-hard-reset-behavior",
321 &prop
->reset_behave
);
323 prop
->high_PHY_capable
= device_property_read_bool(dev
,
324 "mipi-sdw-highPHY-capable");
326 prop
->paging_support
= device_property_read_bool(dev
,
327 "mipi-sdw-paging-support");
329 prop
->bank_delay_support
= device_property_read_bool(dev
,
330 "mipi-sdw-bank-delay-support");
332 device_property_read_u32(dev
,
333 "mipi-sdw-port15-read-behavior", &prop
->p15_behave
);
335 device_property_read_u32(dev
, "mipi-sdw-master-count",
336 &prop
->master_count
);
338 device_property_read_u32(dev
, "mipi-sdw-source-port-list",
339 &prop
->source_ports
);
341 device_property_read_u32(dev
, "mipi-sdw-sink-port-list",
344 /* Read dp0 properties */
345 port
= device_get_named_child_node(dev
, "mipi-sdw-dp-0-subproperties");
347 dev_dbg(dev
, "DP0 node not found!!\n");
350 prop
->dp0_prop
= devm_kzalloc(&slave
->dev
,
351 sizeof(*prop
->dp0_prop
), GFP_KERNEL
);
355 sdw_slave_read_dp0(slave
, port
, prop
->dp0_prop
);
360 * Based on each DPn port, get source and sink dpn properties.
361 * Also, some ports can operate as both source or sink.
364 /* Allocate memory for set bits in port lists */
365 nval
= hweight32(prop
->source_ports
);
366 prop
->src_dpn_prop
= devm_kcalloc(&slave
->dev
, nval
,
367 sizeof(*prop
->src_dpn_prop
), GFP_KERNEL
);
368 if (!prop
->src_dpn_prop
)
371 /* Read dpn properties for source port(s) */
372 sdw_slave_read_dpn(slave
, prop
->src_dpn_prop
, nval
,
373 prop
->source_ports
, "source");
375 nval
= hweight32(prop
->sink_ports
);
376 prop
->sink_dpn_prop
= devm_kcalloc(&slave
->dev
, nval
,
377 sizeof(*prop
->sink_dpn_prop
), GFP_KERNEL
);
378 if (!prop
->sink_dpn_prop
)
381 /* Read dpn properties for sink port(s) */
382 sdw_slave_read_dpn(slave
, prop
->sink_dpn_prop
, nval
,
383 prop
->sink_ports
, "sink");
385 /* some ports are bidirectional so check total ports by ORing */
386 nval
= prop
->source_ports
| prop
->sink_ports
;
387 num_of_ports
= hweight32(nval
) + dp0
; /* add DP0 */
389 /* Allocate port_ready based on num_of_ports */
390 slave
->port_ready
= devm_kcalloc(&slave
->dev
, num_of_ports
,
391 sizeof(*slave
->port_ready
), GFP_KERNEL
);
392 if (!slave
->port_ready
)
395 /* Initialize completion */
396 for (i
= 0; i
< num_of_ports
; i
++)
397 init_completion(&slave
->port_ready
[i
]);
401 EXPORT_SYMBOL(sdw_slave_read_prop
);