blob: 6e4169ebb916fee51a4064a6bd0f3c41a6ee3634 [file] [log] [blame]
Duncan Lauriea12fc812016-12-13 16:43:40 -08001/*
2 * This file is part of the coreboot project.
3 *
Duncan Lauriea12fc812016-12-13 16:43:40 -08004 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <arch/acpigen_dsm.h>
15#include <device/device.h>
16#include <stdint.h>
17#include <string.h>
18#include "chip.h"
Eric Lai18060d72019-04-24 14:21:04 +080019#include <gpio.h>
20#include <console/console.h>
Duncan Lauriea12fc812016-12-13 16:43:40 -080021
Julius Wernercd49cce2019-03-05 16:53:33 -080022#if CONFIG(HAVE_ACPI_TABLES)
Duncan Lauriea12fc812016-12-13 16:43:40 -080023static void i2c_hid_fill_dsm(struct device *dev)
24{
25 struct drivers_i2c_hid_config *config = dev->chip_info;
26 struct dsm_i2c_hid_config dsm_config = {
27 .hid_desc_reg_offset = config->hid_desc_reg_offset,
28 };
29
30 acpigen_write_dsm_i2c_hid(&dsm_config);
31}
32
33static void i2c_hid_fill_ssdt_generator(struct device *dev)
34{
35 struct drivers_i2c_hid_config *config = dev->chip_info;
36 config->generic.cid = I2C_HID_CID;
37 i2c_generic_fill_ssdt(dev, &i2c_hid_fill_dsm, &config->generic);
38}
39
Aaron Durbinaa090cb2017-09-13 16:01:52 -060040static const char *i2c_hid_acpi_name(const struct device *dev)
Duncan Lauriea12fc812016-12-13 16:43:40 -080041{
42 static char name[5];
43 snprintf(name, sizeof(name), "H%03.3X", dev->path.i2c.device);
44 name[4] = '\0';
45 return name;
46}
47#endif
48
49static struct device_operations i2c_hid_ops = {
Nico Huber68680dd2020-03-31 17:34:52 +020050 .read_resources = DEVICE_NOOP,
51 .set_resources = DEVICE_NOOP,
52 .enable_resources = DEVICE_NOOP,
Julius Wernercd49cce2019-03-05 16:53:33 -080053#if CONFIG(HAVE_ACPI_TABLES)
Nico Huber68680dd2020-03-31 17:34:52 +020054 .acpi_name = i2c_hid_acpi_name,
55 .acpi_fill_ssdt = i2c_hid_fill_ssdt_generator,
Duncan Lauriea12fc812016-12-13 16:43:40 -080056#endif
57};
58
59static void i2c_hid_enable(struct device *dev)
60{
Naresh G Solanki69e9e712018-06-04 17:45:19 +053061 struct drivers_i2c_hid_config *config = dev->chip_info;
62
Eric Lai18060d72019-04-24 14:21:04 +080063 if (!config)
64 return;
65
66 /* Check if device is present by reading GPIO */
67 if (config->generic.device_present_gpio) {
68 int present = gpio_get(config->generic.device_present_gpio);
69 present ^= config->generic.device_present_gpio_invert;
70
71 printk(BIOS_INFO, "%s is %spresent\n",
72 dev->chip_ops->name, present ? "" : "not ");
73
74 if (!present) {
75 dev->enabled = 0;
76 return;
77 }
78 }
79
Duncan Lauriea12fc812016-12-13 16:43:40 -080080 dev->ops = &i2c_hid_ops;
Naresh G Solanki69e9e712018-06-04 17:45:19 +053081
82 if (config && config->generic.desc) {
83 dev->name = config->generic.desc;
84 }
Duncan Lauriea12fc812016-12-13 16:43:40 -080085}
86
87struct chip_operations drivers_i2c_hid_ops = {
88 CHIP_NAME("I2C HID Device")
Elyes HAOUAS2aa3b162018-11-27 17:02:10 +010089 .enable_dev = i2c_hid_enable
Duncan Lauriea12fc812016-12-13 16:43:40 -080090};