Skip to content

Commit 27b730e

Browse files
author
Jiri Kosina
committed
Merge branch 'for-5.12/i2c-hid' into for-linus
- ACPI and OF support made more generic / decoupled. From Douglas Anderson - support for Goodix devices from Douglas Anderson
2 parents d631007 + c1ed18c commit 27b730e

11 files changed

Lines changed: 578 additions & 262 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/input/goodix,gt7375p.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Goodix GT7375P touchscreen
8+
9+
maintainers:
10+
- Douglas Anderson <dianders@chromium.org>
11+
12+
description:
13+
Supports the Goodix GT7375P touchscreen.
14+
This touchscreen uses the i2c-hid protocol but has some non-standard
15+
power sequencing required.
16+
17+
properties:
18+
compatible:
19+
items:
20+
- const: goodix,gt7375p
21+
22+
reg:
23+
enum:
24+
- 0x5d
25+
- 0x14
26+
27+
interrupts:
28+
maxItems: 1
29+
30+
reset-gpios:
31+
true
32+
33+
vdd-supply:
34+
description: The 3.3V supply to the touchscreen.
35+
36+
required:
37+
- compatible
38+
- reg
39+
- interrupts
40+
- reset-gpios
41+
- vdd-supply
42+
43+
additionalProperties: false
44+
45+
examples:
46+
- |
47+
#include <dt-bindings/clock/qcom,rpmh.h>
48+
#include <dt-bindings/gpio/gpio.h>
49+
#include <dt-bindings/interrupt-controller/irq.h>
50+
51+
i2c {
52+
#address-cells = <1>;
53+
#size-cells = <0>;
54+
55+
ap_ts: touchscreen@5d {
56+
compatible = "goodix,gt7375p";
57+
reg = <0x5d>;
58+
59+
interrupt-parent = <&tlmm>;
60+
interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
61+
62+
reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>;
63+
vdd-supply = <&pp3300_ts>;
64+
};
65+
};

arch/arm64/configs/defconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,8 @@ CONFIG_SND_SOC_WM8904=m
749749
CONFIG_SND_SOC_WSA881X=m
750750
CONFIG_SND_SIMPLE_CARD=m
751751
CONFIG_SND_AUDIO_GRAPH_CARD=m
752-
CONFIG_I2C_HID=m
752+
CONFIG_I2C_HID_ACPI=m
753+
CONFIG_I2C_HID_OF=m
753754
CONFIG_USB_CONN_GPIO=m
754755
CONFIG_USB=y
755756
CONFIG_USB_OTG=y

drivers/hid/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ obj-$(CONFIG_USB_HID) += usbhid/
138138
obj-$(CONFIG_USB_MOUSE) += usbhid/
139139
obj-$(CONFIG_USB_KBD) += usbhid/
140140

141-
obj-$(CONFIG_I2C_HID) += i2c-hid/
141+
obj-$(CONFIG_I2C_HID_CORE) += i2c-hid/
142142

143143
obj-$(CONFIG_INTEL_ISH_HID) += intel-ish-hid/
144144
obj-$(INTEL_ISH_FIRMWARE_DOWNLOADER) += intel-ish-hid/

drivers/hid/i2c-hid/Kconfig

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,55 @@
22
menu "I2C HID support"
33
depends on I2C
44

5-
config I2C_HID
6-
tristate "HID over I2C transport layer"
5+
config I2C_HID_ACPI
6+
tristate "HID over I2C transport layer ACPI driver"
77
default n
8-
depends on I2C && INPUT
9-
select HID
8+
depends on I2C && INPUT && ACPI
9+
help
10+
Say Y here if you use a keyboard, a touchpad, a touchscreen, or any
11+
other HID based devices which is connected to your computer via I2C.
12+
This driver supports ACPI-based systems.
13+
14+
If unsure, say N.
15+
16+
This support is also available as a module. If so, the module
17+
will be called i2c-hid-acpi. It will also build/depend on the
18+
module i2c-hid.
19+
20+
config I2C_HID_OF
21+
tristate "HID over I2C transport layer Open Firmware driver"
22+
default n
23+
depends on I2C && INPUT && OF
1024
help
1125
Say Y here if you use a keyboard, a touchpad, a touchscreen, or any
1226
other HID based devices which is connected to your computer via I2C.
27+
This driver supports Open Firmware (Device Tree)-based systems.
1328

1429
If unsure, say N.
1530

1631
This support is also available as a module. If so, the module
17-
will be called i2c-hid.
32+
will be called i2c-hid-of. It will also build/depend on the
33+
module i2c-hid.
34+
35+
config I2C_HID_OF_GOODIX
36+
tristate "Driver for Goodix hid-i2c based devices on OF systems"
37+
default n
38+
depends on I2C && INPUT && OF
39+
help
40+
Say Y here if you want support for Goodix i2c devices that use
41+
the i2c-hid protocol on Open Firmware (Device Tree)-based
42+
systems.
43+
44+
If unsure, say N.
45+
46+
This support is also available as a module. If so, the module
47+
will be called i2c-hid-of-goodix. It will also build/depend on
48+
the module i2c-hid.
1849

1950
endmenu
51+
52+
config I2C_HID_CORE
53+
tristate
54+
default y if I2C_HID_ACPI=y || I2C_HID_OF=y || I2C_HID_OF_GOODIX=y
55+
default m if I2C_HID_ACPI=m || I2C_HID_OF=m || I2C_HID_OF_GOODIX=m
56+
select HID

drivers/hid/i2c-hid/Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
# Makefile for the I2C input drivers
44
#
55

6-
obj-$(CONFIG_I2C_HID) += i2c-hid.o
6+
obj-$(CONFIG_I2C_HID_CORE) += i2c-hid.o
77

88
i2c-hid-objs = i2c-hid-core.o
99
i2c-hid-$(CONFIG_DMI) += i2c-hid-dmi-quirks.o
10+
11+
obj-$(CONFIG_I2C_HID_ACPI) += i2c-hid-acpi.o
12+
obj-$(CONFIG_I2C_HID_OF) += i2c-hid-of.o
13+
obj-$(CONFIG_I2C_HID_OF_GOODIX) += i2c-hid-of-goodix.o

drivers/hid/i2c-hid/i2c-hid-acpi.c

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* HID over I2C ACPI Subclass
3+
*
4+
* Copyright (c) 2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
5+
* Copyright (c) 2012 Ecole Nationale de l'Aviation Civile, France
6+
* Copyright (c) 2012 Red Hat, Inc
7+
*
8+
* This code was forked out of the core code, which was partly based on
9+
* "USB HID support for Linux":
10+
*
11+
* Copyright (c) 1999 Andreas Gal
12+
* Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
13+
* Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
14+
* Copyright (c) 2007-2008 Oliver Neukum
15+
* Copyright (c) 2006-2010 Jiri Kosina
16+
*
17+
* This file is subject to the terms and conditions of the GNU General Public
18+
* License. See the file COPYING in the main directory of this archive for
19+
* more details.
20+
*/
21+
22+
#include <linux/acpi.h>
23+
#include <linux/device.h>
24+
#include <linux/i2c.h>
25+
#include <linux/kernel.h>
26+
#include <linux/module.h>
27+
#include <linux/pm.h>
28+
29+
#include "i2c-hid.h"
30+
31+
struct i2c_hid_acpi {
32+
struct i2chid_ops ops;
33+
struct i2c_client *client;
34+
};
35+
36+
static const struct acpi_device_id i2c_hid_acpi_blacklist[] = {
37+
/*
38+
* The CHPN0001 ACPI device, which is used to describe the Chipone
39+
* ICN8505 controller, has a _CID of PNP0C50 but is not HID compatible.
40+
*/
41+
{"CHPN0001", 0 },
42+
{ },
43+
};
44+
45+
static int i2c_hid_acpi_get_descriptor(struct i2c_client *client)
46+
{
47+
static guid_t i2c_hid_guid =
48+
GUID_INIT(0x3CDFF6F7, 0x4267, 0x4555,
49+
0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE);
50+
union acpi_object *obj;
51+
struct acpi_device *adev;
52+
acpi_handle handle;
53+
u16 hid_descriptor_address;
54+
55+
handle = ACPI_HANDLE(&client->dev);
56+
if (!handle || acpi_bus_get_device(handle, &adev)) {
57+
dev_err(&client->dev, "Error could not get ACPI device\n");
58+
return -ENODEV;
59+
}
60+
61+
if (acpi_match_device_ids(adev, i2c_hid_acpi_blacklist) == 0)
62+
return -ENODEV;
63+
64+
obj = acpi_evaluate_dsm_typed(handle, &i2c_hid_guid, 1, 1, NULL,
65+
ACPI_TYPE_INTEGER);
66+
if (!obj) {
67+
dev_err(&client->dev, "Error _DSM call to get HID descriptor address failed\n");
68+
return -ENODEV;
69+
}
70+
71+
hid_descriptor_address = obj->integer.value;
72+
ACPI_FREE(obj);
73+
74+
return hid_descriptor_address;
75+
}
76+
77+
static void i2c_hid_acpi_shutdown_tail(struct i2chid_ops *ops)
78+
{
79+
struct i2c_hid_acpi *ihid_acpi =
80+
container_of(ops, struct i2c_hid_acpi, ops);
81+
struct device *dev = &ihid_acpi->client->dev;
82+
acpi_device_set_power(ACPI_COMPANION(dev), ACPI_STATE_D3_COLD);
83+
}
84+
85+
static int i2c_hid_acpi_probe(struct i2c_client *client,
86+
const struct i2c_device_id *dev_id)
87+
{
88+
struct device *dev = &client->dev;
89+
struct i2c_hid_acpi *ihid_acpi;
90+
struct acpi_device *adev;
91+
u16 hid_descriptor_address;
92+
int ret;
93+
94+
ihid_acpi = devm_kzalloc(&client->dev, sizeof(*ihid_acpi), GFP_KERNEL);
95+
if (!ihid_acpi)
96+
return -ENOMEM;
97+
98+
ihid_acpi->client = client;
99+
ihid_acpi->ops.shutdown_tail = i2c_hid_acpi_shutdown_tail;
100+
101+
ret = i2c_hid_acpi_get_descriptor(client);
102+
if (ret < 0)
103+
return ret;
104+
hid_descriptor_address = ret;
105+
106+
adev = ACPI_COMPANION(dev);
107+
if (adev)
108+
acpi_device_fix_up_power(adev);
109+
110+
if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) {
111+
device_set_wakeup_capable(dev, true);
112+
device_set_wakeup_enable(dev, false);
113+
}
114+
115+
return i2c_hid_core_probe(client, &ihid_acpi->ops,
116+
hid_descriptor_address);
117+
}
118+
119+
static const struct acpi_device_id i2c_hid_acpi_match[] = {
120+
{"ACPI0C50", 0 },
121+
{"PNP0C50", 0 },
122+
{ },
123+
};
124+
MODULE_DEVICE_TABLE(acpi, i2c_hid_acpi_match);
125+
126+
static struct i2c_driver i2c_hid_acpi_driver = {
127+
.driver = {
128+
.name = "i2c_hid_acpi",
129+
.pm = &i2c_hid_core_pm,
130+
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
131+
.acpi_match_table = ACPI_PTR(i2c_hid_acpi_match),
132+
},
133+
134+
.probe = i2c_hid_acpi_probe,
135+
.remove = i2c_hid_core_remove,
136+
.shutdown = i2c_hid_core_shutdown,
137+
};
138+
139+
module_i2c_driver(i2c_hid_acpi_driver);
140+
141+
MODULE_DESCRIPTION("HID over I2C ACPI driver");
142+
MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
143+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)