2 * Supports for the button array on the Surface tablets.
4 * (C) Copyright 2016 Red Hat, Inc
6 * Based on soc_button_array.c:
8 * {C} Copyright 2014 Intel Corporation
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; version 2
16 #include <linux/module.h>
17 #include <linux/input.h>
18 #include <linux/init.h>
19 #include <linux/kernel.h>
20 #include <linux/i2c.h>
21 #include <linux/slab.h>
22 #include <linux/acpi.h>
23 #include <linux/gpio/consumer.h>
24 #include <linux/gpio_keys.h>
25 #include <linux/gpio.h>
26 #include <linux/platform_device.h>
29 #define SURFACE_BUTTON_OBJ_NAME "TEV2"
30 #define MAX_NBUTTONS 4
33 * Some of the buttons like volume up/down are auto repeat, while others
34 * are not. To support both, we register two platform devices, and put
35 * buttons into them based on whether the key should be auto repeat.
37 #define BUTTON_TYPES 2
40 * Power button, Home button, Volume buttons support is supposed to
41 * be covered by drivers/input/misc/soc_button_array.c, which is implemented
42 * according to "Windows ACPI Design Guide for SoC Platforms".
43 * However surface 3 seems not to obey the specs, instead it uses
44 * device TEV2(MSHW0028) for declaring the GPIOs. The gpios are also slightly
45 * different in which the Home button is active high.
46 * Compared to surfacepro3_button.c which also handles MSHW0028, the Surface 3
47 * is a reduce platform and thus uses GPIOs, not ACPI events.
48 * We choose an I2C driver here because we need to access the resources
49 * declared under the device node, while surfacepro3_button.c only needs
50 * the ACPI companion node.
52 static const struct acpi_device_id surface3_acpi_match
[] = {
56 MODULE_DEVICE_TABLE(acpi
, surface3_acpi_match
);
58 struct surface3_button_info
{
61 unsigned int event_type
;
62 unsigned int event_code
;
68 struct surface3_button_data
{
69 struct platform_device
*children
[BUTTON_TYPES
];
73 * Get the Nth GPIO number from the ACPI object.
75 static int surface3_button_lookup_gpio(struct device
*dev
, int acpi_index
)
77 struct gpio_desc
*desc
;
80 desc
= gpiod_get_index(dev
, NULL
, acpi_index
, GPIOD_ASIS
);
84 gpio
= desc_to_gpio(desc
);
91 static struct platform_device
*
92 surface3_button_device_create(struct i2c_client
*client
,
93 const struct surface3_button_info
*button_info
,
96 const struct surface3_button_info
*info
;
97 struct platform_device
*pd
;
98 struct gpio_keys_button
*gpio_keys
;
99 struct gpio_keys_platform_data
*gpio_keys_pdata
;
104 gpio_keys_pdata
= devm_kzalloc(&client
->dev
,
105 sizeof(*gpio_keys_pdata
) +
106 sizeof(*gpio_keys
) * MAX_NBUTTONS
,
108 if (!gpio_keys_pdata
)
109 return ERR_PTR(-ENOMEM
);
111 gpio_keys
= (void *)(gpio_keys_pdata
+ 1);
113 for (info
= button_info
; info
->name
; info
++) {
114 if (info
->autorepeat
!= autorepeat
)
117 gpio
= surface3_button_lookup_gpio(&client
->dev
,
119 if (!gpio_is_valid(gpio
))
122 gpio_keys
[n_buttons
].type
= info
->event_type
;
123 gpio_keys
[n_buttons
].code
= info
->event_code
;
124 gpio_keys
[n_buttons
].gpio
= gpio
;
125 gpio_keys
[n_buttons
].active_low
= info
->active_low
;
126 gpio_keys
[n_buttons
].desc
= info
->name
;
127 gpio_keys
[n_buttons
].wakeup
= info
->wakeup
;
131 if (n_buttons
== 0) {
136 gpio_keys_pdata
->buttons
= gpio_keys
;
137 gpio_keys_pdata
->nbuttons
= n_buttons
;
138 gpio_keys_pdata
->rep
= autorepeat
;
140 pd
= platform_device_alloc("gpio-keys", PLATFORM_DEVID_AUTO
);
146 error
= platform_device_add_data(pd
, gpio_keys_pdata
,
147 sizeof(*gpio_keys_pdata
));
151 error
= platform_device_add(pd
);
158 platform_device_put(pd
);
160 devm_kfree(&client
->dev
, gpio_keys_pdata
);
161 return ERR_PTR(error
);
164 static int surface3_button_remove(struct i2c_client
*client
)
166 struct surface3_button_data
*priv
= i2c_get_clientdata(client
);
170 for (i
= 0; i
< BUTTON_TYPES
; i
++)
171 if (priv
->children
[i
])
172 platform_device_unregister(priv
->children
[i
]);
177 static struct surface3_button_info surface3_button_surface3
[] = {
178 { "power", 0, EV_KEY
, KEY_POWER
, false, true, true },
179 { "home", 1, EV_KEY
, KEY_LEFTMETA
, false, true, false },
180 { "volume_up", 2, EV_KEY
, KEY_VOLUMEUP
, true, false, true },
181 { "volume_down", 3, EV_KEY
, KEY_VOLUMEDOWN
, true, false, true },
185 static int surface3_button_probe(struct i2c_client
*client
,
186 const struct i2c_device_id
*id
)
188 struct device
*dev
= &client
->dev
;
189 struct surface3_button_data
*priv
;
190 struct platform_device
*pd
;
194 if (strncmp(acpi_device_bid(ACPI_COMPANION(&client
->dev
)),
195 SURFACE_BUTTON_OBJ_NAME
,
196 strlen(SURFACE_BUTTON_OBJ_NAME
)))
199 error
= gpiod_count(dev
, NULL
);
201 dev_dbg(dev
, "no GPIO attached, ignoring...\n");
205 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
209 i2c_set_clientdata(client
, priv
);
211 for (i
= 0; i
< BUTTON_TYPES
; i
++) {
212 pd
= surface3_button_device_create(client
,
213 surface3_button_surface3
,
217 if (error
!= -ENODEV
) {
218 surface3_button_remove(client
);
224 priv
->children
[i
] = pd
;
227 if (!priv
->children
[0] && !priv
->children
[1])
233 static const struct i2c_device_id surface3_id
[] = {
236 MODULE_DEVICE_TABLE(i2c
, surface3_id
);
238 static struct i2c_driver surface3_driver
= {
239 .probe
= surface3_button_probe
,
240 .remove
= surface3_button_remove
,
241 .id_table
= surface3_id
,
244 .acpi_match_table
= ACPI_PTR(surface3_acpi_match
),
247 module_i2c_driver(surface3_driver
);
249 MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
250 MODULE_DESCRIPTION("surface3 button array driver");
251 MODULE_LICENSE("GPL v2");