blob: c91b04a922ff4bd8d976ad875e6a68eabd08932e [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Duncan Lauriea12fc812016-12-13 16:43:40 -08002
Furquan Shaikh76cedd22020-05-02 10:24:23 -07003#include <acpi/acpigen_dsm.h>
Karthikeyan Ramasubramaniana7e67882021-02-09 10:07:47 -07004#include <acpi/acpi_device.h>
5#include <assert.h>
Duncan Lauriea12fc812016-12-13 16:43:40 -08006#include <device/device.h>
Elyes Haouasbdd03c22024-05-27 11:20:07 +02007#include <stdio.h>
Elyes Haouas08375b52024-05-27 11:36:52 +02008
Duncan Lauriea12fc812016-12-13 16:43:40 -08009#include "chip.h"
Eric Lai18060d72019-04-24 14:21:04 +080010#include <gpio.h>
11#include <console/console.h>
Duncan Lauriea12fc812016-12-13 16:43:40 -080012
Julius Wernercd49cce2019-03-05 16:53:33 -080013#if CONFIG(HAVE_ACPI_TABLES)
Furquan Shaikh8220c4b2020-04-24 21:44:27 -070014static void i2c_hid_fill_dsm(const struct device *dev)
Duncan Lauriea12fc812016-12-13 16:43:40 -080015{
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,
19 };
20
21 acpigen_write_dsm_i2c_hid(&dsm_config);
22}
23
Furquan Shaikh7536a392020-04-24 21:59:21 -070024static void i2c_hid_fill_ssdt_generator(const struct device *dev)
Duncan Lauriea12fc812016-12-13 16:43:40 -080025{
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);
29}
30
Aaron Durbinaa090cb2017-09-13 16:01:52 -060031static const char *i2c_hid_acpi_name(const struct device *dev)
Duncan Lauriea12fc812016-12-13 16:43:40 -080032{
33 static char name[5];
Matt DeVillier3d627812020-11-19 18:31:17 -060034 struct drivers_i2c_hid_config *config = dev->chip_info;
35 if (config->generic.name)
36 return config->generic.name;
37
Duncan Lauriea12fc812016-12-13 16:43:40 -080038 snprintf(name, sizeof(name), "H%03.3X", dev->path.i2c.device);
39 name[4] = '\0';
40 return name;
41}
42#endif
43
44static struct device_operations i2c_hid_ops = {
Nico Huber2f8ba692020-04-05 14:05:24 +020045 .read_resources = noop_read_resources,
46 .set_resources = noop_set_resources,
Julius Wernercd49cce2019-03-05 16:53:33 -080047#if CONFIG(HAVE_ACPI_TABLES)
Nico Huber68680dd2020-03-31 17:34:52 +020048 .acpi_name = i2c_hid_acpi_name,
49 .acpi_fill_ssdt = i2c_hid_fill_ssdt_generator,
Duncan Lauriea12fc812016-12-13 16:43:40 -080050#endif
51};
52
53static void i2c_hid_enable(struct device *dev)
54{
Naresh G Solanki69e9e712018-06-04 17:45:19 +053055 struct drivers_i2c_hid_config *config = dev->chip_info;
56
Eric Lai18060d72019-04-24 14:21:04 +080057 if (!config)
58 return;
59
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;
64
65 printk(BIOS_INFO, "%s is %spresent\n",
66 dev->chip_ops->name, present ? "" : "not ");
67
68 if (!present) {
69 dev->enabled = 0;
70 return;
71 }
72 }
73
Karthikeyan Ramasubramaniana7e67882021-02-09 10:07:47 -070074 /*
75 * Ensure that I2C HID devices use level triggered interrupts as per ACPI
76 * I2C HID requirement. Check interrupt and GPIO interrupt.
77 */
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);
83 BUG();
84 }
85
Duncan Lauriea12fc812016-12-13 16:43:40 -080086 dev->ops = &i2c_hid_ops;
Naresh G Solanki69e9e712018-06-04 17:45:19 +053087
88 if (config && config->generic.desc) {
89 dev->name = config->generic.desc;
90 }
Duncan Lauriea12fc812016-12-13 16:43:40 -080091}
92
93struct chip_operations drivers_i2c_hid_ops = {
Nicholas Sudsgaardbfb11be2024-01-30 09:53:46 +090094 .name = "I2C HID Device",
Elyes HAOUAS2aa3b162018-11-27 17:02:10 +010095 .enable_dev = i2c_hid_enable
Duncan Lauriea12fc812016-12-13 16:43:40 -080096};