0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/acpi.h>
0009 #include <linux/bits.h>
0010 #include <linux/bitfield.h>
0011 #include <linux/device.h>
0012 #include <linux/errno.h>
0013 #include <linux/export.h>
0014 #include <linux/fwnode.h>
0015 #include <linux/module.h>
0016 #include <linux/soundwire/sdw_intel.h>
0017 #include <linux/string.h>
0018
0019 #define SDW_LINK_TYPE 4
0020 #define SDW_MAX_LINKS 4
0021
0022 static int ctrl_link_mask;
0023 module_param_named(sdw_link_mask, ctrl_link_mask, int, 0444);
0024 MODULE_PARM_DESC(sdw_link_mask, "Intel link mask (one bit per link)");
0025
0026 static bool is_link_enabled(struct fwnode_handle *fw_node, int i)
0027 {
0028 struct fwnode_handle *link;
0029 char name[32];
0030 u32 quirk_mask = 0;
0031
0032
0033 snprintf(name, sizeof(name),
0034 "mipi-sdw-link-%d-subproperties", i);
0035
0036 link = fwnode_get_named_child_node(fw_node, name);
0037 if (!link)
0038 return false;
0039
0040 fwnode_property_read_u32(link,
0041 "intel-quirk-mask",
0042 &quirk_mask);
0043
0044 if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
0045 return false;
0046
0047 return true;
0048 }
0049
0050 static int
0051 sdw_intel_scan_controller(struct sdw_intel_acpi_info *info)
0052 {
0053 struct acpi_device *adev = acpi_fetch_acpi_dev(info->handle);
0054 int ret, i;
0055 u8 count;
0056
0057 if (!adev)
0058 return -EINVAL;
0059
0060
0061 count = 0;
0062 ret = fwnode_property_read_u8_array(acpi_fwnode_handle(adev),
0063 "mipi-sdw-master-count", &count, 1);
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 if (ret) {
0078 dev_err(&adev->dev,
0079 "Failed to read mipi-sdw-master-count: %d\n", ret);
0080 return -EINVAL;
0081 }
0082
0083
0084 if (count > SDW_MAX_LINKS) {
0085 dev_err(&adev->dev, "Link count %d exceeds max %d\n",
0086 count, SDW_MAX_LINKS);
0087 return -EINVAL;
0088 }
0089
0090 if (!count) {
0091 dev_warn(&adev->dev, "No SoundWire links detected\n");
0092 return -EINVAL;
0093 }
0094 dev_dbg(&adev->dev, "ACPI reports %d SDW Link devices\n", count);
0095
0096 info->count = count;
0097 info->link_mask = 0;
0098
0099 for (i = 0; i < count; i++) {
0100 if (ctrl_link_mask && !(ctrl_link_mask & BIT(i))) {
0101 dev_dbg(&adev->dev,
0102 "Link %d masked, will not be enabled\n", i);
0103 continue;
0104 }
0105
0106 if (!is_link_enabled(acpi_fwnode_handle(adev), i)) {
0107 dev_dbg(&adev->dev,
0108 "Link %d not selected in firmware\n", i);
0109 continue;
0110 }
0111
0112 info->link_mask |= BIT(i);
0113 }
0114
0115 return 0;
0116 }
0117
0118 static acpi_status sdw_intel_acpi_cb(acpi_handle handle, u32 level,
0119 void *cdata, void **return_value)
0120 {
0121 struct sdw_intel_acpi_info *info = cdata;
0122 acpi_status status;
0123 u64 adr;
0124
0125 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
0126 if (ACPI_FAILURE(status))
0127 return AE_OK;
0128
0129 if (!acpi_fetch_acpi_dev(handle)) {
0130 pr_err("%s: Couldn't find ACPI handle\n", __func__);
0131 return AE_NOT_FOUND;
0132 }
0133
0134
0135
0136
0137
0138
0139
0140
0141 if (FIELD_GET(GENMASK(31, 28), adr) != SDW_LINK_TYPE)
0142 return AE_OK;
0143
0144
0145 info->handle = handle;
0146
0147
0148 return AE_CTRL_TERMINATE;
0149 }
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161 int sdw_intel_acpi_scan(acpi_handle *parent_handle,
0162 struct sdw_intel_acpi_info *info)
0163 {
0164 acpi_status status;
0165
0166 info->handle = NULL;
0167
0168
0169
0170
0171
0172
0173 status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
0174 parent_handle, 2,
0175 sdw_intel_acpi_cb,
0176 NULL, info, NULL);
0177 if (ACPI_FAILURE(status) || info->handle == NULL)
0178 return -ENODEV;
0179
0180 return sdw_intel_scan_controller(info);
0181 }
0182 EXPORT_SYMBOL_NS(sdw_intel_acpi_scan, SND_INTEL_SOUNDWIRE_ACPI);
0183
0184 MODULE_LICENSE("Dual BSD/GPL");
0185 MODULE_DESCRIPTION("Intel Soundwire ACPI helpers");