1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2 // Copyright(c) 2015-17 Intel Corporation.
4 #include <linux/acpi.h>
6 #include <linux/soundwire/sdw.h>
7 #include <linux/soundwire/sdw_type.h>
8 #include <sound/sdca.h>
10 #include "sysfs_local.h"
12 static void sdw_slave_release(struct device
*dev
)
14 struct sdw_slave
*slave
= dev_to_sdw_dev(dev
);
16 mutex_destroy(&slave
->sdw_dev_lock
);
20 const struct device_type sdw_slave_type
= {
22 .release
= sdw_slave_release
,
23 .uevent
= sdw_slave_uevent
,
26 int sdw_slave_add(struct sdw_bus
*bus
,
27 struct sdw_slave_id
*id
, struct fwnode_handle
*fwnode
)
29 struct sdw_slave
*slave
;
33 slave
= kzalloc(sizeof(*slave
), GFP_KERNEL
);
37 /* Initialize data structure */
38 memcpy(&slave
->id
, id
, sizeof(*id
));
39 slave
->dev
.parent
= bus
->dev
;
40 slave
->dev
.fwnode
= fwnode
;
42 if (id
->unique_id
== SDW_IGNORED_UNIQUE_ID
) {
43 /* name shall be sdw:ctrl:link:mfg:part:class */
44 dev_set_name(&slave
->dev
, "sdw:%01x:%01x:%04x:%04x:%02x",
45 bus
->controller_id
, bus
->link_id
, id
->mfg_id
, id
->part_id
,
48 /* name shall be sdw:ctrl:link:mfg:part:class:unique */
49 dev_set_name(&slave
->dev
, "sdw:%01x:%01x:%04x:%04x:%02x:%01x",
50 bus
->controller_id
, bus
->link_id
, id
->mfg_id
, id
->part_id
,
51 id
->class_id
, id
->unique_id
);
54 slave
->dev
.bus
= &sdw_bus_type
;
55 slave
->dev
.of_node
= of_node_get(to_of_node(fwnode
));
56 slave
->dev
.type
= &sdw_slave_type
;
57 slave
->dev
.groups
= sdw_slave_status_attr_groups
;
59 slave
->status
= SDW_SLAVE_UNATTACHED
;
60 init_completion(&slave
->enumeration_complete
);
61 init_completion(&slave
->initialization_complete
);
63 slave
->probed
= false;
64 slave
->first_interrupt_done
= false;
65 mutex_init(&slave
->sdw_dev_lock
);
67 for (i
= 0; i
< SDW_MAX_PORTS
; i
++)
68 init_completion(&slave
->port_ready
[i
]);
70 mutex_lock(&bus
->bus_lock
);
71 list_add_tail(&slave
->node
, &bus
->slaves
);
72 mutex_unlock(&bus
->bus_lock
);
75 * The Soundwire driver probe may optionally register SDCA
76 * sub-devices, one per Function. This means the information
77 * on the SDCA revision and the number/type of Functions need
78 * to be extracted from platform firmware before the SoundWire
79 * driver probe, and as a consequence before the SoundWire
80 * device_register() below.
82 sdca_lookup_interface_revision(slave
);
83 sdca_lookup_functions(slave
);
85 ret
= device_register(&slave
->dev
);
87 dev_err(bus
->dev
, "Failed to add slave: ret %d\n", ret
);
90 * On err, don't free but drop ref as this will be freed
91 * when release method is invoked.
93 mutex_lock(&bus
->bus_lock
);
94 list_del(&slave
->node
);
95 mutex_unlock(&bus
->bus_lock
);
96 put_device(&slave
->dev
);
100 sdw_slave_debugfs_init(slave
);
104 EXPORT_SYMBOL(sdw_slave_add
);
106 #if IS_ENABLED(CONFIG_ACPI)
108 static bool find_slave(struct sdw_bus
*bus
,
109 struct acpi_device
*adev
,
110 struct sdw_slave_id
*id
)
112 unsigned int link_id
;
116 ret
= acpi_get_local_u64_address(adev
->handle
, &addr
);
120 if (bus
->ops
->override_adr
)
121 addr
= bus
->ops
->override_adr(bus
, addr
);
126 /* Extract link id from ADR, Bit 51 to 48 (included) */
127 link_id
= SDW_DISCO_LINK_ID(addr
);
129 /* Check for link_id match */
130 if (link_id
!= bus
->link_id
)
133 sdw_extract_slave_id(bus
, addr
, id
);
138 struct sdw_acpi_child_walk_data
{
140 struct acpi_device
*adev
;
141 struct sdw_slave_id id
;
142 bool ignore_unique_id
;
145 static int sdw_acpi_check_duplicate(struct acpi_device
*adev
, void *data
)
147 struct sdw_acpi_child_walk_data
*cwd
= data
;
148 struct sdw_bus
*bus
= cwd
->bus
;
149 struct sdw_slave_id id
;
151 if (adev
== cwd
->adev
)
154 if (!find_slave(bus
, adev
, &id
))
157 if (cwd
->id
.sdw_version
!= id
.sdw_version
|| cwd
->id
.mfg_id
!= id
.mfg_id
||
158 cwd
->id
.part_id
!= id
.part_id
|| cwd
->id
.class_id
!= id
.class_id
)
161 if (cwd
->id
.unique_id
!= id
.unique_id
) {
163 "Valid unique IDs 0x%x 0x%x for Slave mfg_id 0x%04x, part_id 0x%04x\n",
164 cwd
->id
.unique_id
, id
.unique_id
, cwd
->id
.mfg_id
,
166 cwd
->ignore_unique_id
= false;
171 "Invalid unique IDs 0x%x 0x%x for Slave mfg_id 0x%04x, part_id 0x%04x\n",
172 cwd
->id
.unique_id
, id
.unique_id
, cwd
->id
.mfg_id
, cwd
->id
.part_id
);
176 static int sdw_acpi_find_one(struct acpi_device
*adev
, void *data
)
178 struct sdw_bus
*bus
= data
;
179 struct sdw_acpi_child_walk_data cwd
= {
182 .ignore_unique_id
= true,
186 if (!find_slave(bus
, adev
, &cwd
.id
))
189 /* Brute-force O(N^2) search for duplicates. */
190 ret
= acpi_dev_for_each_child(ACPI_COMPANION(bus
->dev
),
191 sdw_acpi_check_duplicate
, &cwd
);
195 if (cwd
.ignore_unique_id
)
196 cwd
.id
.unique_id
= SDW_IGNORED_UNIQUE_ID
;
198 /* Ignore errors and continue. */
199 sdw_slave_add(bus
, &cwd
.id
, acpi_fwnode_handle(adev
));
204 * sdw_acpi_find_slaves() - Find Slave devices in Master ACPI node
205 * @bus: SDW bus instance
207 * Scans Master ACPI node for SDW child Slave devices and registers it.
209 int sdw_acpi_find_slaves(struct sdw_bus
*bus
)
211 struct acpi_device
*parent
;
213 parent
= ACPI_COMPANION(bus
->dev
);
215 dev_err(bus
->dev
, "Can't find parent for acpi bind\n");
219 return acpi_dev_for_each_child(parent
, sdw_acpi_find_one
, bus
);
225 * sdw_of_find_slaves() - Find Slave devices in master device tree node
226 * @bus: SDW bus instance
228 * Scans Master DT node for SDW child Slave devices and registers it.
230 int sdw_of_find_slaves(struct sdw_bus
*bus
)
232 struct device
*dev
= bus
->dev
;
233 struct device_node
*node
;
235 for_each_child_of_node(bus
->dev
->of_node
, node
) {
236 int link_id
, ret
, len
;
237 unsigned int sdw_version
;
238 const char *compat
= NULL
;
239 struct sdw_slave_id id
;
242 compat
= of_get_property(node
, "compatible", NULL
);
246 ret
= sscanf(compat
, "sdw%01x%04hx%04hx%02hhx", &sdw_version
,
247 &id
.mfg_id
, &id
.part_id
, &id
.class_id
);
250 dev_err(dev
, "Invalid compatible string found %s\n",
255 addr
= of_get_property(node
, "reg", &len
);
256 if (!addr
|| (len
< 2 * sizeof(u32
))) {
257 dev_err(dev
, "Invalid Link and Instance ID\n");
261 link_id
= be32_to_cpup(addr
++);
262 id
.unique_id
= be32_to_cpup(addr
);
263 id
.sdw_version
= sdw_version
;
265 /* Check for link_id match */
266 if (link_id
!= bus
->link_id
)
269 sdw_slave_add(bus
, &id
, of_fwnode_handle(node
));
275 MODULE_IMPORT_NS("SND_SOC_SDCA");