1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <acpi/acpigen.h>
4 #include <acpi/acpi_device.h>
5 #include <acpi/acpi_soundwire.h>
6 #include <commonlib/helpers.h>
7 #include <device/device.h>
8 #include <device/soundwire.h>
11 #include "soundwire.h"
14 __weak
int soc_fill_soundwire_controller(struct intel_soundwire_controller
**controller
)
19 static bool link_enabled(const struct device
*dev
, unsigned int link
)
23 for (child
= dev
->downstream
->children
; child
; child
= child
->sibling
) {
24 if (child
->enabled
&& child
->path
.type
== DEVICE_PATH_GENERIC
&&
25 child
->path
.generic
.id
== link
)
31 static void intel_soundwire_link_prop_cb(struct acpi_dp
*dsd
, unsigned int id
,
32 const struct soundwire_controller
*controller
)
34 struct intel_soundwire_controller
*intel_controller
=
35 container_of(controller
, struct intel_soundwire_controller
, sdw
);
36 unsigned int quirk_mask
= intel_controller
->quirk_mask
;
38 /* Disable link if no are children enabled on this link device. */
39 if (!link_enabled(intel_controller
->dev
, id
))
40 quirk_mask
|= INTEL_SOUNDWIRE_QUIRK_BUS_DISABLE
;
42 acpi_dp_add_integer(dsd
, "intel-sdw-ip-clock", intel_controller
->ip_clock
);
43 acpi_dp_add_integer(dsd
, "intel-quirk-mask", quirk_mask
);
46 static void intel_soundwire_fill_ssdt(const struct device
*dev
)
49 struct intel_soundwire_controller
*controller
;
50 const char *scope
= acpi_device_scope(dev
);
55 if (soc_fill_soundwire_controller(&controller
) < 0 || !controller
)
58 /* Provide device pointer for link property callback function. */
59 controller
->dev
= dev
;
61 acpigen_write_scope(scope
);
62 acpigen_write_device(acpi_device_name(dev
));
63 acpigen_write_name_string("_DDN", dev
->chip_ops
->name
);
64 acpigen_write_name_integer("_ADR", controller
->acpi_address
);
65 acpigen_write_name_string("_CID", ACPI_HID_CONTAINER
);
67 acpigen_write_STA(acpi_device_status(dev
));
69 dsd
= acpi_dp_new_table("_DSD");
70 soundwire_gen_controller(dsd
, &controller
->sdw
, &intel_soundwire_link_prop_cb
);
73 acpigen_pop_len(); /* Device */
74 acpigen_pop_len(); /* Scope */
77 static const char *intel_soundwire_acpi_name(const struct device
*dev
)
82 static struct device_operations intel_soundwire_ops
= {
83 .read_resources
= noop_read_resources
,
84 .set_resources
= noop_set_resources
,
85 .acpi_name
= intel_soundwire_acpi_name
,
86 .acpi_fill_ssdt
= intel_soundwire_fill_ssdt
,
87 .scan_bus
= scan_static_bus
,
90 static void intel_soundwire_enable(struct device
*dev
)
92 dev
->ops
= &intel_soundwire_ops
;
95 struct chip_operations drivers_intel_soundwire_ops
= {
96 .name
= "Intel SoundWire Controller",
97 .enable_dev
= intel_soundwire_enable