blob: 2d213eb74e04e9addffb0e9256ad13aa192144cd [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>
Duncan Lauriea12fc812016-12-13 16:43:40 -08004#include <device/device.h>
Duncan Lauriea12fc812016-12-13 16:43:40 -08005#include <string.h>
6#include "chip.h"
Eric Lai18060d72019-04-24 14:21:04 +08007#include <gpio.h>
8#include <console/console.h>
Duncan Lauriea12fc812016-12-13 16:43:40 -08009
Julius Wernercd49cce2019-03-05 16:53:33 -080010#if CONFIG(HAVE_ACPI_TABLES)
Furquan Shaikh8220c4b2020-04-24 21:44:27 -070011static void i2c_hid_fill_dsm(const struct device *dev)
Duncan Lauriea12fc812016-12-13 16:43:40 -080012{
13 struct drivers_i2c_hid_config *config = dev->chip_info;
14 struct dsm_i2c_hid_config dsm_config = {
15 .hid_desc_reg_offset = config->hid_desc_reg_offset,
16 };
17
18 acpigen_write_dsm_i2c_hid(&dsm_config);
19}
20
Furquan Shaikh7536a392020-04-24 21:59:21 -070021static void i2c_hid_fill_ssdt_generator(const struct device *dev)
Duncan Lauriea12fc812016-12-13 16:43:40 -080022{
23 struct drivers_i2c_hid_config *config = dev->chip_info;
24 config->generic.cid = I2C_HID_CID;
25 i2c_generic_fill_ssdt(dev, &i2c_hid_fill_dsm, &config->generic);
26}
27
Aaron Durbinaa090cb2017-09-13 16:01:52 -060028static const char *i2c_hid_acpi_name(const struct device *dev)
Duncan Lauriea12fc812016-12-13 16:43:40 -080029{
30 static char name[5];
Matt DeVillier3d627812020-11-19 18:31:17 -060031 struct drivers_i2c_hid_config *config = dev->chip_info;
32 if (config->generic.name)
33 return config->generic.name;
34
Duncan Lauriea12fc812016-12-13 16:43:40 -080035 snprintf(name, sizeof(name), "H%03.3X", dev->path.i2c.device);
36 name[4] = '\0';
37 return name;
38}
39#endif
40
41static struct device_operations i2c_hid_ops = {
Nico Huber2f8ba692020-04-05 14:05:24 +020042 .read_resources = noop_read_resources,
43 .set_resources = noop_set_resources,
Julius Wernercd49cce2019-03-05 16:53:33 -080044#if CONFIG(HAVE_ACPI_TABLES)
Nico Huber68680dd2020-03-31 17:34:52 +020045 .acpi_name = i2c_hid_acpi_name,
46 .acpi_fill_ssdt = i2c_hid_fill_ssdt_generator,
Duncan Lauriea12fc812016-12-13 16:43:40 -080047#endif
48};
49
50static void i2c_hid_enable(struct device *dev)
51{
Naresh G Solanki69e9e712018-06-04 17:45:19 +053052 struct drivers_i2c_hid_config *config = dev->chip_info;
53
Eric Lai18060d72019-04-24 14:21:04 +080054 if (!config)
55 return;
56
57 /* Check if device is present by reading GPIO */
58 if (config->generic.device_present_gpio) {
59 int present = gpio_get(config->generic.device_present_gpio);
60 present ^= config->generic.device_present_gpio_invert;
61
62 printk(BIOS_INFO, "%s is %spresent\n",
63 dev->chip_ops->name, present ? "" : "not ");
64
65 if (!present) {
66 dev->enabled = 0;
67 return;
68 }
69 }
70
Duncan Lauriea12fc812016-12-13 16:43:40 -080071 dev->ops = &i2c_hid_ops;
Naresh G Solanki69e9e712018-06-04 17:45:19 +053072
73 if (config && config->generic.desc) {
74 dev->name = config->generic.desc;
75 }
Duncan Lauriea12fc812016-12-13 16:43:40 -080076}
77
78struct chip_operations drivers_i2c_hid_ops = {
79 CHIP_NAME("I2C HID Device")
Elyes HAOUAS2aa3b162018-11-27 17:02:10 +010080 .enable_dev = i2c_hid_enable
Duncan Lauriea12fc812016-12-13 16:43:40 -080081};