1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <acpi/acpigen_dsm.h>
4 #include <acpi/acpi_device.h>
6 #include <device/device.h>
11 #include <console/console.h>
13 #if CONFIG(HAVE_ACPI_TABLES)
14 static void i2c_hid_fill_dsm(const struct device
*dev
)
16 struct drivers_i2c_hid_config
*config
= dev
->chip_info
;
17 struct dsm_i2c_hid_config dsm_config
= {
18 .hid_desc_reg_offset
= config
->hid_desc_reg_offset
,
21 acpigen_write_dsm_i2c_hid(&dsm_config
);
24 static void i2c_hid_fill_ssdt_generator(const struct device
*dev
)
26 struct drivers_i2c_hid_config
*config
= dev
->chip_info
;
27 config
->generic
.cid
= I2C_HID_CID
;
28 i2c_generic_fill_ssdt(dev
, &i2c_hid_fill_dsm
, &config
->generic
);
31 static const char *i2c_hid_acpi_name(const struct device
*dev
)
34 struct drivers_i2c_hid_config
*config
= dev
->chip_info
;
35 if (config
->generic
.name
)
36 return config
->generic
.name
;
38 snprintf(name
, sizeof(name
), "H%03.3X", dev
->path
.i2c
.device
);
44 static struct device_operations i2c_hid_ops
= {
45 .read_resources
= noop_read_resources
,
46 .set_resources
= noop_set_resources
,
47 #if CONFIG(HAVE_ACPI_TABLES)
48 .acpi_name
= i2c_hid_acpi_name
,
49 .acpi_fill_ssdt
= i2c_hid_fill_ssdt_generator
,
53 static void i2c_hid_enable(struct device
*dev
)
55 struct drivers_i2c_hid_config
*config
= dev
->chip_info
;
60 /* Check if device is present by reading GPIO */
61 if (config
->generic
.device_present_gpio
) {
62 int present
= gpio_get(config
->generic
.device_present_gpio
);
63 present
^= config
->generic
.device_present_gpio_invert
;
65 printk(BIOS_INFO
, "%s is %spresent\n",
66 dev
->chip_ops
->name
, present
? "" : "not ");
75 * Ensure that I2C HID devices use level triggered interrupts as per ACPI
76 * I2C HID requirement. Check interrupt and GPIO interrupt.
78 if ((!config
->generic
.irq_gpio
.pin_count
&&
79 config
->generic
.irq
.mode
!= ACPI_IRQ_LEVEL_TRIGGERED
) ||
80 (config
->generic
.irq_gpio
.pin_count
&&
81 config
->generic
.irq_gpio
.irq
.mode
!= ACPI_IRQ_LEVEL_TRIGGERED
)) {
82 printk(BIOS_ERR
, "%s IRQ is not level triggered.\n", config
->generic
.hid
);
86 dev
->ops
= &i2c_hid_ops
;
88 if (config
&& config
->generic
.desc
) {
89 dev
->name
= config
->generic
.desc
;
93 struct chip_operations drivers_i2c_hid_ops
= {
94 .name
= "I2C HID Device",
95 .enable_dev
= i2c_hid_enable