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",
41 /* Find master handle */
42 snprintf(name
, sizeof(name
),
43 "mipi-sdw-link-%d-subproperties", bus
->link_id
);
45 link
= device_get_named_child_node(bus
->dev
, name
);
47 dev_err(bus
->dev
, "Master node %s not found\n", name
);
51 if (fwnode_property_read_bool(link
,
52 "mipi-sdw-clock-stop-mode0-supported"))
53 prop
->clk_stop_modes
|= BIT(SDW_CLK_STOP_MODE0
);
55 if (fwnode_property_read_bool(link
,
56 "mipi-sdw-clock-stop-mode1-supported"))
57 prop
->clk_stop_modes
|= BIT(SDW_CLK_STOP_MODE1
);
59 fwnode_property_read_u32(link
,
60 "mipi-sdw-max-clock-frequency",
63 nval
= fwnode_property_count_u32(link
, "mipi-sdw-clock-frequencies-supported");
65 prop
->num_clk_freq
= nval
;
66 prop
->clk_freq
= devm_kcalloc(bus
->dev
, prop
->num_clk_freq
,
67 sizeof(*prop
->clk_freq
),
72 fwnode_property_read_u32_array(link
,
73 "mipi-sdw-clock-frequencies-supported",
74 prop
->clk_freq
, prop
->num_clk_freq
);
78 * Check the frequencies supported. If FW doesn't provide max
79 * freq, then populate here by checking values.
81 if (!prop
->max_clk_freq
&& prop
->clk_freq
) {
82 prop
->max_clk_freq
= prop
->clk_freq
[0];
83 for (i
= 1; i
< prop
->num_clk_freq
; i
++) {
84 if (prop
->clk_freq
[i
] > prop
->max_clk_freq
)
85 prop
->max_clk_freq
= prop
->clk_freq
[i
];
89 nval
= fwnode_property_count_u32(link
, "mipi-sdw-supported-clock-gears");
91 prop
->num_clk_gears
= nval
;
92 prop
->clk_gears
= devm_kcalloc(bus
->dev
, prop
->num_clk_gears
,
93 sizeof(*prop
->clk_gears
),
98 fwnode_property_read_u32_array(link
,
99 "mipi-sdw-supported-clock-gears",
101 prop
->num_clk_gears
);
104 fwnode_property_read_u32(link
, "mipi-sdw-default-frame-rate",
105 &prop
->default_frame_rate
);
107 fwnode_property_read_u32(link
, "mipi-sdw-default-frame-row-size",
110 fwnode_property_read_u32(link
, "mipi-sdw-default-frame-col-size",
113 prop
->dynamic_frame
= fwnode_property_read_bool(link
,
114 "mipi-sdw-dynamic-frame-shape");
116 fwnode_property_read_u32(link
, "mipi-sdw-command-error-threshold",
117 &prop
->err_threshold
);
121 EXPORT_SYMBOL(sdw_master_read_prop
);
123 static int sdw_slave_read_dp0(struct sdw_slave
*slave
,
124 struct fwnode_handle
*port
,
125 struct sdw_dp0_prop
*dp0
)
129 fwnode_property_read_u32(port
, "mipi-sdw-port-max-wordlength",
132 fwnode_property_read_u32(port
, "mipi-sdw-port-min-wordlength",
135 nval
= fwnode_property_count_u32(port
, "mipi-sdw-port-wordlength-configs");
138 dp0
->num_words
= nval
;
139 dp0
->words
= devm_kcalloc(&slave
->dev
,
140 dp0
->num_words
, sizeof(*dp0
->words
),
145 fwnode_property_read_u32_array(port
,
146 "mipi-sdw-port-wordlength-configs",
147 dp0
->words
, dp0
->num_words
);
150 dp0
->BRA_flow_controlled
= fwnode_property_read_bool(port
,
151 "mipi-sdw-bra-flow-controlled");
153 dp0
->simple_ch_prep_sm
= fwnode_property_read_bool(port
,
154 "mipi-sdw-simplified-channel-prepare-sm");
156 dp0
->imp_def_interrupts
= fwnode_property_read_bool(port
,
157 "mipi-sdw-imp-def-dp0-interrupts-supported");
162 static int sdw_slave_read_dpn(struct sdw_slave
*slave
,
163 struct sdw_dpn_prop
*dpn
, int count
, int ports
,
166 struct fwnode_handle
*node
;
173 /* valid ports are 1 to 14 so apply mask */
174 addr
&= GENMASK(14, 1);
176 for_each_set_bit(bit
, &addr
, 32) {
177 snprintf(name
, sizeof(name
),
178 "mipi-sdw-dp-%d-%s-subproperties", bit
, type
);
182 node
= device_get_named_child_node(&slave
->dev
, name
);
184 dev_err(&slave
->dev
, "%s dpN not found\n", name
);
188 fwnode_property_read_u32(node
, "mipi-sdw-port-max-wordlength",
190 fwnode_property_read_u32(node
, "mipi-sdw-port-min-wordlength",
193 nval
= fwnode_property_count_u32(node
, "mipi-sdw-port-wordlength-configs");
195 dpn
[i
].num_words
= nval
;
196 dpn
[i
].words
= devm_kcalloc(&slave
->dev
,
198 sizeof(*dpn
[i
].words
),
203 fwnode_property_read_u32_array(node
,
204 "mipi-sdw-port-wordlength-configs",
205 dpn
[i
].words
, dpn
[i
].num_words
);
208 fwnode_property_read_u32(node
, "mipi-sdw-data-port-type",
211 fwnode_property_read_u32(node
,
212 "mipi-sdw-max-grouping-supported",
213 &dpn
[i
].max_grouping
);
215 dpn
[i
].simple_ch_prep_sm
= fwnode_property_read_bool(node
,
216 "mipi-sdw-simplified-channelprepare-sm");
218 fwnode_property_read_u32(node
,
219 "mipi-sdw-port-channelprepare-timeout",
220 &dpn
[i
].ch_prep_timeout
);
222 fwnode_property_read_u32(node
,
223 "mipi-sdw-imp-def-dpn-interrupts-supported",
224 &dpn
[i
].imp_def_interrupts
);
226 fwnode_property_read_u32(node
, "mipi-sdw-min-channel-number",
229 fwnode_property_read_u32(node
, "mipi-sdw-max-channel-number",
232 nval
= fwnode_property_count_u32(node
, "mipi-sdw-channel-number-list");
234 dpn
[i
].num_ch
= nval
;
235 dpn
[i
].ch
= devm_kcalloc(&slave
->dev
, dpn
[i
].num_ch
,
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_count_u32(node
, "mipi-sdw-channel-combination-list");
248 dpn
[i
].num_ch_combinations
= nval
;
249 dpn
[i
].ch_combinations
= devm_kcalloc(&slave
->dev
,
250 dpn
[i
].num_ch_combinations
,
251 sizeof(*dpn
[i
].ch_combinations
),
253 if (!dpn
[i
].ch_combinations
)
256 fwnode_property_read_u32_array(node
,
257 "mipi-sdw-channel-combination-list",
258 dpn
[i
].ch_combinations
,
259 dpn
[i
].num_ch_combinations
);
262 fwnode_property_read_u32(node
,
263 "mipi-sdw-modes-supported", &dpn
[i
].modes
);
265 fwnode_property_read_u32(node
, "mipi-sdw-max-async-buffer",
266 &dpn
[i
].max_async_buffer
);
268 dpn
[i
].block_pack_mode
= fwnode_property_read_bool(node
,
269 "mipi-sdw-block-packing-mode");
271 fwnode_property_read_u32(node
, "mipi-sdw-port-encoding-type",
272 &dpn
[i
].port_encoding
);
274 /* TODO: Read audio mode */
283 * sdw_slave_read_prop() - Read Slave properties
286 int sdw_slave_read_prop(struct sdw_slave
*slave
)
288 struct sdw_slave_prop
*prop
= &slave
->prop
;
289 struct device
*dev
= &slave
->dev
;
290 struct fwnode_handle
*port
;
291 int num_of_ports
, nval
, i
, dp0
= 0;
293 device_property_read_u32(dev
, "mipi-sdw-sw-interface-revision",
294 &prop
->mipi_revision
);
296 prop
->wake_capable
= device_property_read_bool(dev
,
297 "mipi-sdw-wake-up-unavailable");
298 prop
->wake_capable
= !prop
->wake_capable
;
300 prop
->test_mode_capable
= device_property_read_bool(dev
,
301 "mipi-sdw-test-mode-supported");
303 prop
->clk_stop_mode1
= false;
304 if (device_property_read_bool(dev
,
305 "mipi-sdw-clock-stop-mode1-supported"))
306 prop
->clk_stop_mode1
= true;
308 prop
->simple_clk_stop_capable
= device_property_read_bool(dev
,
309 "mipi-sdw-simplified-clockstopprepare-sm-supported");
311 device_property_read_u32(dev
, "mipi-sdw-clockstopprepare-timeout",
312 &prop
->clk_stop_timeout
);
314 device_property_read_u32(dev
, "mipi-sdw-slave-channelprepare-timeout",
315 &prop
->ch_prep_timeout
);
317 device_property_read_u32(dev
,
318 "mipi-sdw-clockstopprepare-hard-reset-behavior",
319 &prop
->reset_behave
);
321 prop
->high_PHY_capable
= device_property_read_bool(dev
,
322 "mipi-sdw-highPHY-capable");
324 prop
->paging_support
= device_property_read_bool(dev
,
325 "mipi-sdw-paging-support");
327 prop
->bank_delay_support
= device_property_read_bool(dev
,
328 "mipi-sdw-bank-delay-support");
330 device_property_read_u32(dev
,
331 "mipi-sdw-port15-read-behavior", &prop
->p15_behave
);
333 device_property_read_u32(dev
, "mipi-sdw-master-count",
334 &prop
->master_count
);
336 device_property_read_u32(dev
, "mipi-sdw-source-port-list",
337 &prop
->source_ports
);
339 device_property_read_u32(dev
, "mipi-sdw-sink-port-list",
342 /* Read dp0 properties */
343 port
= device_get_named_child_node(dev
, "mipi-sdw-dp-0-subproperties");
345 dev_dbg(dev
, "DP0 node not found!!\n");
347 prop
->dp0_prop
= devm_kzalloc(&slave
->dev
,
348 sizeof(*prop
->dp0_prop
),
353 sdw_slave_read_dp0(slave
, port
, prop
->dp0_prop
);
358 * Based on each DPn port, get source and sink dpn properties.
359 * Also, some ports can operate as both source or sink.
362 /* Allocate memory for set bits in port lists */
363 nval
= hweight32(prop
->source_ports
);
364 prop
->src_dpn_prop
= devm_kcalloc(&slave
->dev
, nval
,
365 sizeof(*prop
->src_dpn_prop
),
367 if (!prop
->src_dpn_prop
)
370 /* Read dpn properties for source port(s) */
371 sdw_slave_read_dpn(slave
, prop
->src_dpn_prop
, nval
,
372 prop
->source_ports
, "source");
374 nval
= hweight32(prop
->sink_ports
);
375 prop
->sink_dpn_prop
= devm_kcalloc(&slave
->dev
, nval
,
376 sizeof(*prop
->sink_dpn_prop
),
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
),
393 if (!slave
->port_ready
)
396 /* Initialize completion */
397 for (i
= 0; i
< num_of_ports
; i
++)
398 init_completion(&slave
->port_ready
[i
]);
402 EXPORT_SYMBOL(sdw_slave_read_prop
);