git: c0c7847d4950 - stable/13 - iichid(4): Add support for ASUS C300 chromebook.

From: Vladimir Kondratyev <wulf_at_FreeBSD.org>
Date: Sat, 24 Dec 2022 08:36:59 UTC
The branch stable/13 has been updated by wulf:

URL: https://cgit.FreeBSD.org/src/commit/?id=c0c7847d4950f7d379e6421fe418e459e8997bc4

commit c0c7847d4950f7d379e6421fe418e459e8997bc4
Author:     Vladimir Kondratyev <wulf@FreeBSD.org>
AuthorDate: 2022-03-02 23:35:23 +0000
Commit:     Vladimir Kondratyev <wulf@FreeBSD.org>
CommitDate: 2022-12-24 08:33:26 +0000

    iichid(4): Add support for ASUS C300 chromebook.
    
    Some chromebooks e.g. ASUS C300 have no valid _CID and _DSM ACPI
    objects required for device identification and HID descriptor address
    detection. Add quirk to allow required data to be hardcoded in to
    driver.
    
    (cherry picked from commit 34e051c45cfc25f74dbfaa42e0dee45d670fecd3)
---
 sys/dev/iicbus/iichid.c | 47 +++++++++++++++++++++++++++++++----------------
 1 file changed, 31 insertions(+), 16 deletions(-)

diff --git a/sys/dev/iicbus/iichid.c b/sys/dev/iicbus/iichid.c
index a8b5c930be19..bb8945245a2e 100644
--- a/sys/dev/iicbus/iichid.c
+++ b/sys/dev/iicbus/iichid.c
@@ -130,10 +130,18 @@ struct i2c_hid_desc {
 	uint32_t reserved;
 } __packed;
 
-static char *iichid_ids[] = {
-	"PNP0C50",
-	"ACPI0C50",
-	NULL
+#define	IICHID_REG_NONE	-1
+#define	IICHID_REG_ACPI	(UINT16_MAX + 1)
+#define	IICHID_REG_ELAN	0x0001
+
+static const struct iichid_id {
+	char *id;
+	int reg;
+} iichid_ids[] = {
+	{ "ELAN0000",	IICHID_REG_ELAN },
+	{ "PNP0C50",	IICHID_REG_ACPI },
+	{ "ACPI0C50",	IICHID_REG_ACPI },
+	{ NULL,		0 },
 };
 
 enum iichid_powerstate_how {
@@ -197,18 +205,21 @@ static int	iichid_reset_callout(struct iichid_softc *);
 static void	iichid_teardown_callout(struct iichid_softc *);
 #endif
 
-static __inline bool
+static inline int
 acpi_is_iichid(ACPI_HANDLE handle)
 {
-	char	**ids;
+	const struct iichid_id *ids;
 	UINT32	sta;
+	int reg;
 
-	for (ids = iichid_ids; *ids != NULL; ids++) {
-		if (acpi_MatchHid(handle, *ids))
+	for (ids = iichid_ids; ids->id != NULL; ids++) {
+		if (acpi_MatchHid(handle, ids->id)) {
+			reg = ids->reg;
 			break;
+		}
 	}
-	if (*ids == NULL)
-		return (false);
+	if (ids->id == NULL)
+		return (IICHID_REG_NONE);
 
 	/*
 	 * If no _STA method or if it failed, then assume that
@@ -216,9 +227,9 @@ acpi_is_iichid(ACPI_HANDLE handle)
 	 */
 	if (ACPI_FAILURE(acpi_GetInteger(handle, "_STA", &sta)) ||
 	    ACPI_DEVICE_PRESENT(sta))
-		return (true);
+		return (reg);
 
-	return (false);
+	return (IICHID_REG_NONE);
 }
 
 static ACPI_STATUS
@@ -1007,7 +1018,7 @@ iichid_probe(device_t dev)
 	ACPI_HANDLE handle;
 	char buf[80];
 	uint16_t config_reg;
-	int error;
+	int error, reg;
 
 	sc = device_get_softc(dev);
 	sc->dev = dev;
@@ -1028,11 +1039,15 @@ iichid_probe(device_t dev)
 	if (handle == NULL)
 		return (ENXIO);
 
-	if (!acpi_is_iichid(handle))
+	reg = acpi_is_iichid(handle);
+	if (reg == IICHID_REG_NONE)
 		return (ENXIO);
 
-	if (ACPI_FAILURE(iichid_get_config_reg(handle, &config_reg)))
-		return (ENXIO);
+	if (reg == IICHID_REG_ACPI) {
+		if (ACPI_FAILURE(iichid_get_config_reg(handle, &config_reg)))
+			return (ENXIO);
+	} else
+		config_reg = (uint16_t)reg;
 
 	DPRINTF(sc, "  IICbus addr       : 0x%02X\n", sc->addr >> 1);
 	DPRINTF(sc, "  HID descriptor reg: 0x%02X\n", config_reg);