1 // SPDX-License-Identifier: GPL-2.0-only
3 * Supports for the button array on the Surface tablets.
5 * (C) Copyright 2016 Red Hat, Inc
7 * Based on soc_button_array.c:
9 * {C} Copyright 2014 Intel Corporation
12 #include <linux/module.h>
13 #include <linux/input.h>
14 #include <linux/init.h>
15 #include <linux/kernel.h>
16 #include <linux/i2c.h>
17 #include <linux/slab.h>
18 #include <linux/acpi.h>
19 #include <linux/gpio/consumer.h>
20 #include <linux/gpio_keys.h>
21 #include <linux/gpio.h>
22 #include <linux/platform_device.h>
25 #define SURFACE_BUTTON_OBJ_NAME "TEV2"
26 #define MAX_NBUTTONS 4
29 * Some of the buttons like volume up/down are auto repeat, while others
30 * are not. To support both, we register two platform devices, and put
31 * buttons into them based on whether the key should be auto repeat.
33 #define BUTTON_TYPES 2
36 * Power button, Home button, Volume buttons support is supposed to
37 * be covered by drivers/input/misc/soc_button_array.c, which is implemented
38 * according to "Windows ACPI Design Guide for SoC Platforms".
39 * However surface 3 seems not to obey the specs, instead it uses
40 * device TEV2(MSHW0028) for declaring the GPIOs. The gpios are also slightly
41 * different in which the Home button is active high.
42 * Compared to surfacepro3_button.c which also handles MSHW0028, the Surface 3
43 * is a reduce platform and thus uses GPIOs, not ACPI events.
44 * We choose an I2C driver here because we need to access the resources
45 * declared under the device node, while surfacepro3_button.c only needs
46 * the ACPI companion node.
48 static const struct acpi_device_id surface3_acpi_match
[] = {
52 MODULE_DEVICE_TABLE(acpi
, surface3_acpi_match
);
54 struct surface3_button_info
{
57 unsigned int event_type
;
58 unsigned int event_code
;
64 struct surface3_button_data
{
65 struct platform_device
*children
[BUTTON_TYPES
];
69 * Get the Nth GPIO number from the ACPI object.
71 static int surface3_button_lookup_gpio(struct device
*dev
, int acpi_index
)
73 struct gpio_desc
*desc
;
76 desc
= gpiod_get_index(dev
, NULL
, acpi_index
, GPIOD_ASIS
);
80 gpio
= desc_to_gpio(desc
);
87 static struct platform_device
*
88 surface3_button_device_create(struct i2c_client
*client
,
89 const struct surface3_button_info
*button_info
,
92 const struct surface3_button_info
*info
;
93 struct platform_device
*pd
;
94 struct gpio_keys_button
*gpio_keys
;
95 struct gpio_keys_platform_data
*gpio_keys_pdata
;
100 gpio_keys_pdata
= devm_kzalloc(&client
->dev
,
101 sizeof(*gpio_keys_pdata
) +
102 sizeof(*gpio_keys
) * MAX_NBUTTONS
,
104 if (!gpio_keys_pdata
)
105 return ERR_PTR(-ENOMEM
);
107 gpio_keys
= (void *)(gpio_keys_pdata
+ 1);
109 for (info
= button_info
; info
->name
; info
++) {
110 if (info
->autorepeat
!= autorepeat
)
113 gpio
= surface3_button_lookup_gpio(&client
->dev
,
115 if (!gpio_is_valid(gpio
))
118 gpio_keys
[n_buttons
].type
= info
->event_type
;
119 gpio_keys
[n_buttons
].code
= info
->event_code
;
120 gpio_keys
[n_buttons
].gpio
= gpio
;
121 gpio_keys
[n_buttons
].active_low
= info
->active_low
;
122 gpio_keys
[n_buttons
].desc
= info
->name
;
123 gpio_keys
[n_buttons
].wakeup
= info
->wakeup
;
127 if (n_buttons
== 0) {
132 gpio_keys_pdata
->buttons
= gpio_keys
;
133 gpio_keys_pdata
->nbuttons
= n_buttons
;
134 gpio_keys_pdata
->rep
= autorepeat
;
136 pd
= platform_device_alloc("gpio-keys", PLATFORM_DEVID_AUTO
);
142 error
= platform_device_add_data(pd
, gpio_keys_pdata
,
143 sizeof(*gpio_keys_pdata
));
147 error
= platform_device_add(pd
);
154 platform_device_put(pd
);
156 devm_kfree(&client
->dev
, gpio_keys_pdata
);
157 return ERR_PTR(error
);
160 static int surface3_button_remove(struct i2c_client
*client
)
162 struct surface3_button_data
*priv
= i2c_get_clientdata(client
);
166 for (i
= 0; i
< BUTTON_TYPES
; i
++)
167 if (priv
->children
[i
])
168 platform_device_unregister(priv
->children
[i
]);
173 static struct surface3_button_info surface3_button_surface3
[] = {
174 { "power", 0, EV_KEY
, KEY_POWER
, false, true, true },
175 { "home", 1, EV_KEY
, KEY_LEFTMETA
, false, true, false },
176 { "volume_up", 2, EV_KEY
, KEY_VOLUMEUP
, true, false, true },
177 { "volume_down", 3, EV_KEY
, KEY_VOLUMEDOWN
, true, false, true },
181 static int surface3_button_probe(struct i2c_client
*client
,
182 const struct i2c_device_id
*id
)
184 struct device
*dev
= &client
->dev
;
185 struct surface3_button_data
*priv
;
186 struct platform_device
*pd
;
190 if (strncmp(acpi_device_bid(ACPI_COMPANION(&client
->dev
)),
191 SURFACE_BUTTON_OBJ_NAME
,
192 strlen(SURFACE_BUTTON_OBJ_NAME
)))
195 error
= gpiod_count(dev
, NULL
);
197 dev_dbg(dev
, "no GPIO attached, ignoring...\n");
201 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
205 i2c_set_clientdata(client
, priv
);
207 for (i
= 0; i
< BUTTON_TYPES
; i
++) {
208 pd
= surface3_button_device_create(client
,
209 surface3_button_surface3
,
213 if (error
!= -ENODEV
) {
214 surface3_button_remove(client
);
220 priv
->children
[i
] = pd
;
223 if (!priv
->children
[0] && !priv
->children
[1])
229 static const struct i2c_device_id surface3_id
[] = {
232 MODULE_DEVICE_TABLE(i2c
, surface3_id
);
234 static struct i2c_driver surface3_driver
= {
235 .probe
= surface3_button_probe
,
236 .remove
= surface3_button_remove
,
237 .id_table
= surface3_id
,
240 .acpi_match_table
= ACPI_PTR(surface3_acpi_match
),
243 module_i2c_driver(surface3_driver
);
245 MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
246 MODULE_DESCRIPTION("surface3 button array driver");
247 MODULE_LICENSE("GPL v2");