- Setting keyboard language
- WWAN Antenna type
- Auxmac
+ - Hardware damage detection capability
A compatibility table by model and feature is maintained on the web
site, http://ibm-acpi.sf.net/. I appreciate any success or failure
The exact semantics of the attributes may be found in
Documentation/ABI/testing/sysfs-class-power.
+Hardware damage detection capability
+------------------------------------
+
+sysfs attributes: hwdd_status
+
+Thinkpads are adding the ability to detect and report hardware damage.
+Add new sysfs interface to identify the damaged device status.
+Initial support is available for the USB-C replaceable connector.
+
+The command to check device damaged status is::
+
+ cat /sys/devices/platform/thinkpad_acpi/hwdd_status
+
+This value displays status of device damaged.
+
+- 0 = Not Damaged
+- 1 = Damaged
+
+The property is read-only. If feature is not supported then sysfs
+attribute is not created.
+
Multiple Commands, Module Parameters
------------------------------------
#include <linux/acpi.h>
#include <linux/backlight.h>
+#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/dmi.h>
.attrs = auxmac_attributes,
};
+/*************************************************************************
+ * HWDD subdriver, for the Lenovo Hardware Damage Detection feature.
+ */
+
+#define HWDD_GET_DMG_USBC 0x80000001
+#define HWDD_GET_CAP 0
+#define HWDD_NOT_SUPPORTED BIT(31)
+#define HWDD_SUPPORT_USBC BIT(0)
+
+#define PORT_STATUS GENMASK(7, 4)
+#define NUM_PORTS 4
+
+static bool hwdd_support_available;
+static bool ucdd_supported;
+
+static int hwdd_command(int command, int *output)
+{
+ acpi_handle hwdd_handle;
+
+ if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "HWDD", &hwdd_handle)))
+ return -ENODEV;
+
+ if (!acpi_evalf(hwdd_handle, output, NULL, "dd", command))
+ return -EIO;
+
+ return 0;
+}
+
+/* sysfs type-c damage detection capability */
+static ssize_t hwdd_status_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ unsigned int damage_status, port_status;
+ int err, i;
+
+ if (!ucdd_supported)
+ return -ENODEV;
+
+ /* Get USB TYPE-C damage status */
+ err = hwdd_command(HWDD_GET_DMG_USBC, &damage_status);
+ if (err)
+ return err;
+
+ port_status = FIELD_GET(PORT_STATUS, damage_status);
+ for (i = 0; i < NUM_PORTS; i++) {
+ if (!(damage_status & BIT(i)))
+ continue;
+ if (port_status & BIT(i))
+ return sysfs_emit(buf, "1\n");
+ }
+
+ return sysfs_emit(buf, "0\n");
+}
+static DEVICE_ATTR_RO(hwdd_status);
+
+static struct attribute *hwdd_attributes[] = {
+ &dev_attr_hwdd_status.attr,
+ NULL
+};
+
+static umode_t hwdd_attr_is_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+{
+ return hwdd_support_available ? attr->mode : 0;
+}
+
+static const struct attribute_group hwdd_attr_group = {
+ .is_visible = hwdd_attr_is_visible,
+ .attrs = hwdd_attributes,
+};
+
+static int tpacpi_hwdd_init(struct ibm_init_struct *iibm)
+{
+ int err, output;
+
+ /* Below command checks the HWDD damage capability */
+ err = hwdd_command(HWDD_GET_CAP, &output);
+ if (err)
+ return err;
+
+ if (!(output & HWDD_NOT_SUPPORTED))
+ return -ENODEV;
+
+ hwdd_support_available = true;
+
+ /*
+ * BIT(0) is assigned to check capability of damage detection is
+ * supported for USB Type-C port or not.
+ */
+ if (output & HWDD_SUPPORT_USBC)
+ ucdd_supported = true;
+
+ return err;
+}
+
+static struct ibm_struct hwdd_driver_data = {
+ .name = "hwdd",
+};
+
/* --------------------------------------------------------------------- */
static struct attribute *tpacpi_driver_attributes[] = {
&kbdlang_attr_group,
&dprc_attr_group,
&auxmac_attr_group,
+ &hwdd_attr_group,
NULL,
};
.init = auxmac_init,
.data = &auxmac_data,
},
+ {
+ .init = tpacpi_hwdd_init,
+ .data = &hwdd_driver_data,
+ },
};
static int __init set_ibm_param(const char *val, const struct kernel_param *kp)