178a56aabSPhil Blundell /* 278a56aabSPhil Blundell * Driver for keys on GPIO lines capable of generating interrupts. 378a56aabSPhil Blundell * 478a56aabSPhil Blundell * Copyright 2005 Phil Blundell 5fd05d089SDavid Jander * Copyright 2010, 2011 David Jander <david@protonic.nl> 678a56aabSPhil Blundell * 778a56aabSPhil Blundell * This program is free software; you can redistribute it and/or modify 878a56aabSPhil Blundell * it under the terms of the GNU General Public License version 2 as 978a56aabSPhil Blundell * published by the Free Software Foundation. 1078a56aabSPhil Blundell */ 1178a56aabSPhil Blundell 1278a56aabSPhil Blundell #include <linux/module.h> 1378a56aabSPhil Blundell 1478a56aabSPhil Blundell #include <linux/init.h> 1578a56aabSPhil Blundell #include <linux/fs.h> 1678a56aabSPhil Blundell #include <linux/interrupt.h> 1778a56aabSPhil Blundell #include <linux/irq.h> 1878a56aabSPhil Blundell #include <linux/sched.h> 1978a56aabSPhil Blundell #include <linux/pm.h> 205a0e3ad6STejun Heo #include <linux/slab.h> 2178a56aabSPhil Blundell #include <linux/sysctl.h> 2278a56aabSPhil Blundell #include <linux/proc_fs.h> 2378a56aabSPhil Blundell #include <linux/delay.h> 2478a56aabSPhil Blundell #include <linux/platform_device.h> 2578a56aabSPhil Blundell #include <linux/input.h> 2649015beeSDavid Brownell #include <linux/gpio_keys.h> 27da0d03feSJani Nikula #include <linux/workqueue.h> 28111bc59cSBen Dooks #include <linux/gpio.h> 29fd05d089SDavid Jander #include <linux/of_platform.h> 30fd05d089SDavid Jander #include <linux/of_gpio.h> 3178a56aabSPhil Blundell 32a33466e3SDmitry Baryshkov struct gpio_button_data { 33d9080921SDmitry Torokhov const struct gpio_keys_button *button; 34a33466e3SDmitry Baryshkov struct input_dev *input; 35ca865a77SJani Nikula struct timer_list timer; 36da0d03feSJani Nikula struct work_struct work; 3728ed684fSGrazvydas Ignotas int timer_debounce; /* in msecs */ 389e3af04fSMika Westerberg bool disabled; 39a33466e3SDmitry Baryshkov }; 40a33466e3SDmitry Baryshkov 41a33466e3SDmitry Baryshkov struct gpio_keys_drvdata { 42a33466e3SDmitry Baryshkov struct input_dev *input; 439e3af04fSMika Westerberg struct mutex disable_lock; 449e3af04fSMika Westerberg unsigned int n_buttons; 45173bdd74SShubhrajyoti D int (*enable)(struct device *dev); 46173bdd74SShubhrajyoti D void (*disable)(struct device *dev); 47a33466e3SDmitry Baryshkov struct gpio_button_data data[0]; 48a33466e3SDmitry Baryshkov }; 49a33466e3SDmitry Baryshkov 509e3af04fSMika Westerberg /* 519e3af04fSMika Westerberg * SYSFS interface for enabling/disabling keys and switches: 529e3af04fSMika Westerberg * 539e3af04fSMika Westerberg * There are 4 attributes under /sys/devices/platform/gpio-keys/ 549e3af04fSMika Westerberg * keys [ro] - bitmap of keys (EV_KEY) which can be 559e3af04fSMika Westerberg * disabled 569e3af04fSMika Westerberg * switches [ro] - bitmap of switches (EV_SW) which can be 579e3af04fSMika Westerberg * disabled 589e3af04fSMika Westerberg * disabled_keys [rw] - bitmap of keys currently disabled 599e3af04fSMika Westerberg * disabled_switches [rw] - bitmap of switches currently disabled 609e3af04fSMika Westerberg * 619e3af04fSMika Westerberg * Userland can change these values and hence disable event generation 629e3af04fSMika Westerberg * for each key (or switch). Disabling a key means its interrupt line 639e3af04fSMika Westerberg * is disabled. 649e3af04fSMika Westerberg * 659e3af04fSMika Westerberg * For example, if we have following switches set up as gpio-keys: 669e3af04fSMika Westerberg * SW_DOCK = 5 679e3af04fSMika Westerberg * SW_CAMERA_LENS_COVER = 9 689e3af04fSMika Westerberg * SW_KEYPAD_SLIDE = 10 699e3af04fSMika Westerberg * SW_FRONT_PROXIMITY = 11 709e3af04fSMika Westerberg * This is read from switches: 719e3af04fSMika Westerberg * 11-9,5 729e3af04fSMika Westerberg * Next we want to disable proximity (11) and dock (5), we write: 739e3af04fSMika Westerberg * 11,5 749e3af04fSMika Westerberg * to file disabled_switches. Now proximity and dock IRQs are disabled. 759e3af04fSMika Westerberg * This can be verified by reading the file disabled_switches: 769e3af04fSMika Westerberg * 11,5 779e3af04fSMika Westerberg * If we now want to enable proximity (11) switch we write: 789e3af04fSMika Westerberg * 5 799e3af04fSMika Westerberg * to disabled_switches. 809e3af04fSMika Westerberg * 819e3af04fSMika Westerberg * We can disable only those keys which don't allow sharing the irq. 829e3af04fSMika Westerberg */ 839e3af04fSMika Westerberg 849e3af04fSMika Westerberg /** 859e3af04fSMika Westerberg * get_n_events_by_type() - returns maximum number of events per @type 869e3af04fSMika Westerberg * @type: type of button (%EV_KEY, %EV_SW) 879e3af04fSMika Westerberg * 889e3af04fSMika Westerberg * Return value of this function can be used to allocate bitmap 899e3af04fSMika Westerberg * large enough to hold all bits for given type. 909e3af04fSMika Westerberg */ 919e3af04fSMika Westerberg static inline int get_n_events_by_type(int type) 929e3af04fSMika Westerberg { 939e3af04fSMika Westerberg BUG_ON(type != EV_SW && type != EV_KEY); 949e3af04fSMika Westerberg 959e3af04fSMika Westerberg return (type == EV_KEY) ? KEY_CNT : SW_CNT; 969e3af04fSMika Westerberg } 979e3af04fSMika Westerberg 989e3af04fSMika Westerberg /** 999e3af04fSMika Westerberg * gpio_keys_disable_button() - disables given GPIO button 1009e3af04fSMika Westerberg * @bdata: button data for button to be disabled 1019e3af04fSMika Westerberg * 1029e3af04fSMika Westerberg * Disables button pointed by @bdata. This is done by masking 1039e3af04fSMika Westerberg * IRQ line. After this function is called, button won't generate 1049e3af04fSMika Westerberg * input events anymore. Note that one can only disable buttons 1059e3af04fSMika Westerberg * that don't share IRQs. 1069e3af04fSMika Westerberg * 1079e3af04fSMika Westerberg * Make sure that @bdata->disable_lock is locked when entering 1089e3af04fSMika Westerberg * this function to avoid races when concurrent threads are 1099e3af04fSMika Westerberg * disabling buttons at the same time. 1109e3af04fSMika Westerberg */ 1119e3af04fSMika Westerberg static void gpio_keys_disable_button(struct gpio_button_data *bdata) 1129e3af04fSMika Westerberg { 1139e3af04fSMika Westerberg if (!bdata->disabled) { 1149e3af04fSMika Westerberg /* 1159e3af04fSMika Westerberg * Disable IRQ and possible debouncing timer. 1169e3af04fSMika Westerberg */ 1179e3af04fSMika Westerberg disable_irq(gpio_to_irq(bdata->button->gpio)); 11828ed684fSGrazvydas Ignotas if (bdata->timer_debounce) 1199e3af04fSMika Westerberg del_timer_sync(&bdata->timer); 1209e3af04fSMika Westerberg 1219e3af04fSMika Westerberg bdata->disabled = true; 1229e3af04fSMika Westerberg } 1239e3af04fSMika Westerberg } 1249e3af04fSMika Westerberg 1259e3af04fSMika Westerberg /** 1269e3af04fSMika Westerberg * gpio_keys_enable_button() - enables given GPIO button 1279e3af04fSMika Westerberg * @bdata: button data for button to be disabled 1289e3af04fSMika Westerberg * 1299e3af04fSMika Westerberg * Enables given button pointed by @bdata. 1309e3af04fSMika Westerberg * 1319e3af04fSMika Westerberg * Make sure that @bdata->disable_lock is locked when entering 1329e3af04fSMika Westerberg * this function to avoid races with concurrent threads trying 1339e3af04fSMika Westerberg * to enable the same button at the same time. 1349e3af04fSMika Westerberg */ 1359e3af04fSMika Westerberg static void gpio_keys_enable_button(struct gpio_button_data *bdata) 1369e3af04fSMika Westerberg { 1379e3af04fSMika Westerberg if (bdata->disabled) { 1389e3af04fSMika Westerberg enable_irq(gpio_to_irq(bdata->button->gpio)); 1399e3af04fSMika Westerberg bdata->disabled = false; 1409e3af04fSMika Westerberg } 1419e3af04fSMika Westerberg } 1429e3af04fSMika Westerberg 1439e3af04fSMika Westerberg /** 1449e3af04fSMika Westerberg * gpio_keys_attr_show_helper() - fill in stringified bitmap of buttons 1459e3af04fSMika Westerberg * @ddata: pointer to drvdata 1469e3af04fSMika Westerberg * @buf: buffer where stringified bitmap is written 1479e3af04fSMika Westerberg * @type: button type (%EV_KEY, %EV_SW) 1489e3af04fSMika Westerberg * @only_disabled: does caller want only those buttons that are 1499e3af04fSMika Westerberg * currently disabled or all buttons that can be 1509e3af04fSMika Westerberg * disabled 1519e3af04fSMika Westerberg * 1529e3af04fSMika Westerberg * This function writes buttons that can be disabled to @buf. If 1539e3af04fSMika Westerberg * @only_disabled is true, then @buf contains only those buttons 1549e3af04fSMika Westerberg * that are currently disabled. Returns 0 on success or negative 1559e3af04fSMika Westerberg * errno on failure. 1569e3af04fSMika Westerberg */ 1579e3af04fSMika Westerberg static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata, 1589e3af04fSMika Westerberg char *buf, unsigned int type, 1599e3af04fSMika Westerberg bool only_disabled) 1609e3af04fSMika Westerberg { 1619e3af04fSMika Westerberg int n_events = get_n_events_by_type(type); 1629e3af04fSMika Westerberg unsigned long *bits; 1639e3af04fSMika Westerberg ssize_t ret; 1649e3af04fSMika Westerberg int i; 1659e3af04fSMika Westerberg 1669e3af04fSMika Westerberg bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); 1679e3af04fSMika Westerberg if (!bits) 1689e3af04fSMika Westerberg return -ENOMEM; 1699e3af04fSMika Westerberg 1709e3af04fSMika Westerberg for (i = 0; i < ddata->n_buttons; i++) { 1719e3af04fSMika Westerberg struct gpio_button_data *bdata = &ddata->data[i]; 1729e3af04fSMika Westerberg 1739e3af04fSMika Westerberg if (bdata->button->type != type) 1749e3af04fSMika Westerberg continue; 1759e3af04fSMika Westerberg 1769e3af04fSMika Westerberg if (only_disabled && !bdata->disabled) 1779e3af04fSMika Westerberg continue; 1789e3af04fSMika Westerberg 1799e3af04fSMika Westerberg __set_bit(bdata->button->code, bits); 1809e3af04fSMika Westerberg } 1819e3af04fSMika Westerberg 1829e3af04fSMika Westerberg ret = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, bits, n_events); 1839e3af04fSMika Westerberg buf[ret++] = '\n'; 1849e3af04fSMika Westerberg buf[ret] = '\0'; 1859e3af04fSMika Westerberg 1869e3af04fSMika Westerberg kfree(bits); 1879e3af04fSMika Westerberg 1889e3af04fSMika Westerberg return ret; 1899e3af04fSMika Westerberg } 1909e3af04fSMika Westerberg 1919e3af04fSMika Westerberg /** 1929e3af04fSMika Westerberg * gpio_keys_attr_store_helper() - enable/disable buttons based on given bitmap 1939e3af04fSMika Westerberg * @ddata: pointer to drvdata 1949e3af04fSMika Westerberg * @buf: buffer from userspace that contains stringified bitmap 1959e3af04fSMika Westerberg * @type: button type (%EV_KEY, %EV_SW) 1969e3af04fSMika Westerberg * 1979e3af04fSMika Westerberg * This function parses stringified bitmap from @buf and disables/enables 198*a16ca239SDmitry Torokhov * GPIO buttons accordingly. Returns 0 on success and negative error 1999e3af04fSMika Westerberg * on failure. 2009e3af04fSMika Westerberg */ 2019e3af04fSMika Westerberg static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, 2029e3af04fSMika Westerberg const char *buf, unsigned int type) 2039e3af04fSMika Westerberg { 2049e3af04fSMika Westerberg int n_events = get_n_events_by_type(type); 2059e3af04fSMika Westerberg unsigned long *bits; 2069e3af04fSMika Westerberg ssize_t error; 2079e3af04fSMika Westerberg int i; 2089e3af04fSMika Westerberg 2099e3af04fSMika Westerberg bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); 2109e3af04fSMika Westerberg if (!bits) 2119e3af04fSMika Westerberg return -ENOMEM; 2129e3af04fSMika Westerberg 2139e3af04fSMika Westerberg error = bitmap_parselist(buf, bits, n_events); 2149e3af04fSMika Westerberg if (error) 2159e3af04fSMika Westerberg goto out; 2169e3af04fSMika Westerberg 2179e3af04fSMika Westerberg /* First validate */ 2189e3af04fSMika Westerberg for (i = 0; i < ddata->n_buttons; i++) { 2199e3af04fSMika Westerberg struct gpio_button_data *bdata = &ddata->data[i]; 2209e3af04fSMika Westerberg 2219e3af04fSMika Westerberg if (bdata->button->type != type) 2229e3af04fSMika Westerberg continue; 2239e3af04fSMika Westerberg 2249e3af04fSMika Westerberg if (test_bit(bdata->button->code, bits) && 2259e3af04fSMika Westerberg !bdata->button->can_disable) { 2269e3af04fSMika Westerberg error = -EINVAL; 2279e3af04fSMika Westerberg goto out; 2289e3af04fSMika Westerberg } 2299e3af04fSMika Westerberg } 2309e3af04fSMika Westerberg 2319e3af04fSMika Westerberg mutex_lock(&ddata->disable_lock); 2329e3af04fSMika Westerberg 2339e3af04fSMika Westerberg for (i = 0; i < ddata->n_buttons; i++) { 2349e3af04fSMika Westerberg struct gpio_button_data *bdata = &ddata->data[i]; 2359e3af04fSMika Westerberg 2369e3af04fSMika Westerberg if (bdata->button->type != type) 2379e3af04fSMika Westerberg continue; 2389e3af04fSMika Westerberg 2399e3af04fSMika Westerberg if (test_bit(bdata->button->code, bits)) 2409e3af04fSMika Westerberg gpio_keys_disable_button(bdata); 2419e3af04fSMika Westerberg else 2429e3af04fSMika Westerberg gpio_keys_enable_button(bdata); 2439e3af04fSMika Westerberg } 2449e3af04fSMika Westerberg 2459e3af04fSMika Westerberg mutex_unlock(&ddata->disable_lock); 2469e3af04fSMika Westerberg 2479e3af04fSMika Westerberg out: 2489e3af04fSMika Westerberg kfree(bits); 2499e3af04fSMika Westerberg return error; 2509e3af04fSMika Westerberg } 2519e3af04fSMika Westerberg 2529e3af04fSMika Westerberg #define ATTR_SHOW_FN(name, type, only_disabled) \ 2539e3af04fSMika Westerberg static ssize_t gpio_keys_show_##name(struct device *dev, \ 2549e3af04fSMika Westerberg struct device_attribute *attr, \ 2559e3af04fSMika Westerberg char *buf) \ 2569e3af04fSMika Westerberg { \ 2579e3af04fSMika Westerberg struct platform_device *pdev = to_platform_device(dev); \ 2589e3af04fSMika Westerberg struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ 2599e3af04fSMika Westerberg \ 2609e3af04fSMika Westerberg return gpio_keys_attr_show_helper(ddata, buf, \ 2619e3af04fSMika Westerberg type, only_disabled); \ 2629e3af04fSMika Westerberg } 2639e3af04fSMika Westerberg 2649e3af04fSMika Westerberg ATTR_SHOW_FN(keys, EV_KEY, false); 2659e3af04fSMika Westerberg ATTR_SHOW_FN(switches, EV_SW, false); 2669e3af04fSMika Westerberg ATTR_SHOW_FN(disabled_keys, EV_KEY, true); 2679e3af04fSMika Westerberg ATTR_SHOW_FN(disabled_switches, EV_SW, true); 2689e3af04fSMika Westerberg 2699e3af04fSMika Westerberg /* 2709e3af04fSMika Westerberg * ATTRIBUTES: 2719e3af04fSMika Westerberg * 2729e3af04fSMika Westerberg * /sys/devices/platform/gpio-keys/keys [ro] 2739e3af04fSMika Westerberg * /sys/devices/platform/gpio-keys/switches [ro] 2749e3af04fSMika Westerberg */ 2759e3af04fSMika Westerberg static DEVICE_ATTR(keys, S_IRUGO, gpio_keys_show_keys, NULL); 2769e3af04fSMika Westerberg static DEVICE_ATTR(switches, S_IRUGO, gpio_keys_show_switches, NULL); 2779e3af04fSMika Westerberg 2789e3af04fSMika Westerberg #define ATTR_STORE_FN(name, type) \ 2799e3af04fSMika Westerberg static ssize_t gpio_keys_store_##name(struct device *dev, \ 2809e3af04fSMika Westerberg struct device_attribute *attr, \ 2819e3af04fSMika Westerberg const char *buf, \ 2829e3af04fSMika Westerberg size_t count) \ 2839e3af04fSMika Westerberg { \ 2849e3af04fSMika Westerberg struct platform_device *pdev = to_platform_device(dev); \ 2859e3af04fSMika Westerberg struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ 2869e3af04fSMika Westerberg ssize_t error; \ 2879e3af04fSMika Westerberg \ 2889e3af04fSMika Westerberg error = gpio_keys_attr_store_helper(ddata, buf, type); \ 2899e3af04fSMika Westerberg if (error) \ 2909e3af04fSMika Westerberg return error; \ 2919e3af04fSMika Westerberg \ 2929e3af04fSMika Westerberg return count; \ 2939e3af04fSMika Westerberg } 2949e3af04fSMika Westerberg 2959e3af04fSMika Westerberg ATTR_STORE_FN(disabled_keys, EV_KEY); 2969e3af04fSMika Westerberg ATTR_STORE_FN(disabled_switches, EV_SW); 2979e3af04fSMika Westerberg 2989e3af04fSMika Westerberg /* 2999e3af04fSMika Westerberg * ATTRIBUTES: 3009e3af04fSMika Westerberg * 3019e3af04fSMika Westerberg * /sys/devices/platform/gpio-keys/disabled_keys [rw] 3029e3af04fSMika Westerberg * /sys/devices/platform/gpio-keys/disables_switches [rw] 3039e3af04fSMika Westerberg */ 3049e3af04fSMika Westerberg static DEVICE_ATTR(disabled_keys, S_IWUSR | S_IRUGO, 3059e3af04fSMika Westerberg gpio_keys_show_disabled_keys, 3069e3af04fSMika Westerberg gpio_keys_store_disabled_keys); 3079e3af04fSMika Westerberg static DEVICE_ATTR(disabled_switches, S_IWUSR | S_IRUGO, 3089e3af04fSMika Westerberg gpio_keys_show_disabled_switches, 3099e3af04fSMika Westerberg gpio_keys_store_disabled_switches); 3109e3af04fSMika Westerberg 3119e3af04fSMika Westerberg static struct attribute *gpio_keys_attrs[] = { 3129e3af04fSMika Westerberg &dev_attr_keys.attr, 3139e3af04fSMika Westerberg &dev_attr_switches.attr, 3149e3af04fSMika Westerberg &dev_attr_disabled_keys.attr, 3159e3af04fSMika Westerberg &dev_attr_disabled_switches.attr, 3169e3af04fSMika Westerberg NULL, 3179e3af04fSMika Westerberg }; 3189e3af04fSMika Westerberg 3199e3af04fSMika Westerberg static struct attribute_group gpio_keys_attr_group = { 3209e3af04fSMika Westerberg .attrs = gpio_keys_attrs, 3219e3af04fSMika Westerberg }; 3229e3af04fSMika Westerberg 3236ee88d71SDaniel Mack static void gpio_keys_report_event(struct gpio_button_data *bdata) 32478a56aabSPhil Blundell { 325d9080921SDmitry Torokhov const struct gpio_keys_button *button = bdata->button; 326ce25d7e9SUwe Kleine-König struct input_dev *input = bdata->input; 32784767d00SRoman Moravcik unsigned int type = button->type ?: EV_KEY; 32894a8cab8SPhilippe Langlais int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0) ^ button->active_low; 32984767d00SRoman Moravcik 33092a47674SAlexander Stein if (type == EV_ABS) { 33192a47674SAlexander Stein if (state) 33292a47674SAlexander Stein input_event(input, type, button->code, button->value); 33392a47674SAlexander Stein } else { 33484767d00SRoman Moravcik input_event(input, type, button->code, !!state); 33592a47674SAlexander Stein } 33678a56aabSPhil Blundell input_sync(input); 337a33466e3SDmitry Baryshkov } 338a33466e3SDmitry Baryshkov 3396ee88d71SDaniel Mack static void gpio_keys_work_func(struct work_struct *work) 3406ee88d71SDaniel Mack { 3416ee88d71SDaniel Mack struct gpio_button_data *bdata = 3426ee88d71SDaniel Mack container_of(work, struct gpio_button_data, work); 3436ee88d71SDaniel Mack 3446ee88d71SDaniel Mack gpio_keys_report_event(bdata); 3456ee88d71SDaniel Mack } 3466ee88d71SDaniel Mack 347da0d03feSJani Nikula static void gpio_keys_timer(unsigned long _data) 348ca865a77SJani Nikula { 349ca865a77SJani Nikula struct gpio_button_data *data = (struct gpio_button_data *)_data; 350ca865a77SJani Nikula 351da0d03feSJani Nikula schedule_work(&data->work); 352ca865a77SJani Nikula } 353ca865a77SJani Nikula 354a33466e3SDmitry Baryshkov static irqreturn_t gpio_keys_isr(int irq, void *dev_id) 355a33466e3SDmitry Baryshkov { 35657ffe9d5SUwe Kleine-König struct gpio_button_data *bdata = dev_id; 357d9080921SDmitry Torokhov const struct gpio_keys_button *button = bdata->button; 358a33466e3SDmitry Baryshkov 35957ffe9d5SUwe Kleine-König BUG_ON(irq != gpio_to_irq(button->gpio)); 360a33466e3SDmitry Baryshkov 36128ed684fSGrazvydas Ignotas if (bdata->timer_debounce) 362ca865a77SJani Nikula mod_timer(&bdata->timer, 36328ed684fSGrazvydas Ignotas jiffies + msecs_to_jiffies(bdata->timer_debounce)); 364ca865a77SJani Nikula else 365da0d03feSJani Nikula schedule_work(&bdata->work); 366a33466e3SDmitry Baryshkov 3671164ec1aSDavid Brownell return IRQ_HANDLED; 36878a56aabSPhil Blundell } 36978a56aabSPhil Blundell 3709e3af04fSMika Westerberg static int __devinit gpio_keys_setup_key(struct platform_device *pdev, 371d9080921SDmitry Torokhov struct input_dev *input, 372bc8f1eafSBen Dooks struct gpio_button_data *bdata, 373d9080921SDmitry Torokhov const struct gpio_keys_button *button) 374bc8f1eafSBen Dooks { 37592a47674SAlexander Stein const char *desc = button->desc ? button->desc : "gpio_keys"; 3769e3af04fSMika Westerberg struct device *dev = &pdev->dev; 3779e3af04fSMika Westerberg unsigned long irqflags; 378bc8f1eafSBen Dooks int irq, error; 379bc8f1eafSBen Dooks 380bc8f1eafSBen Dooks setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); 3816ee88d71SDaniel Mack INIT_WORK(&bdata->work, gpio_keys_work_func); 382d9080921SDmitry Torokhov bdata->input = input; 383d9080921SDmitry Torokhov bdata->button = button; 384bc8f1eafSBen Dooks 385bc8f1eafSBen Dooks error = gpio_request(button->gpio, desc); 386bc8f1eafSBen Dooks if (error < 0) { 387bc8f1eafSBen Dooks dev_err(dev, "failed to request GPIO %d, error %d\n", 388bc8f1eafSBen Dooks button->gpio, error); 389bc8f1eafSBen Dooks goto fail2; 390bc8f1eafSBen Dooks } 391bc8f1eafSBen Dooks 392bc8f1eafSBen Dooks error = gpio_direction_input(button->gpio); 393bc8f1eafSBen Dooks if (error < 0) { 394bc8f1eafSBen Dooks dev_err(dev, "failed to configure" 395bc8f1eafSBen Dooks " direction for GPIO %d, error %d\n", 396bc8f1eafSBen Dooks button->gpio, error); 397bc8f1eafSBen Dooks goto fail3; 398bc8f1eafSBen Dooks } 399bc8f1eafSBen Dooks 40028ed684fSGrazvydas Ignotas if (button->debounce_interval) { 40128ed684fSGrazvydas Ignotas error = gpio_set_debounce(button->gpio, 40228ed684fSGrazvydas Ignotas button->debounce_interval * 1000); 40328ed684fSGrazvydas Ignotas /* use timer if gpiolib doesn't provide debounce */ 40428ed684fSGrazvydas Ignotas if (error < 0) 40528ed684fSGrazvydas Ignotas bdata->timer_debounce = button->debounce_interval; 40628ed684fSGrazvydas Ignotas } 40728ed684fSGrazvydas Ignotas 408bc8f1eafSBen Dooks irq = gpio_to_irq(button->gpio); 409bc8f1eafSBen Dooks if (irq < 0) { 410bc8f1eafSBen Dooks error = irq; 411bc8f1eafSBen Dooks dev_err(dev, "Unable to get irq number for GPIO %d, error %d\n", 412bc8f1eafSBen Dooks button->gpio, error); 413bc8f1eafSBen Dooks goto fail3; 414bc8f1eafSBen Dooks } 415bc8f1eafSBen Dooks 4169e3af04fSMika Westerberg irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; 4179e3af04fSMika Westerberg /* 4189e3af04fSMika Westerberg * If platform has specified that the button can be disabled, 4199e3af04fSMika Westerberg * we don't want it to share the interrupt line. 4209e3af04fSMika Westerberg */ 4219e3af04fSMika Westerberg if (!button->can_disable) 4229e3af04fSMika Westerberg irqflags |= IRQF_SHARED; 4239e3af04fSMika Westerberg 4246709c9a5SDavid Jander error = request_any_context_irq(irq, gpio_keys_isr, irqflags, desc, bdata); 42594a8cab8SPhilippe Langlais if (error < 0) { 426bc8f1eafSBen Dooks dev_err(dev, "Unable to claim irq %d; error %d\n", 427bc8f1eafSBen Dooks irq, error); 428bc8f1eafSBen Dooks goto fail3; 429bc8f1eafSBen Dooks } 430bc8f1eafSBen Dooks 431d9080921SDmitry Torokhov input_set_capability(input, button->type ?: EV_KEY, button->code); 432bc8f1eafSBen Dooks return 0; 433bc8f1eafSBen Dooks 434bc8f1eafSBen Dooks fail3: 435bc8f1eafSBen Dooks gpio_free(button->gpio); 436bc8f1eafSBen Dooks fail2: 437bc8f1eafSBen Dooks return error; 438bc8f1eafSBen Dooks } 439bc8f1eafSBen Dooks 440173bdd74SShubhrajyoti D static int gpio_keys_open(struct input_dev *input) 441173bdd74SShubhrajyoti D { 442173bdd74SShubhrajyoti D struct gpio_keys_drvdata *ddata = input_get_drvdata(input); 443173bdd74SShubhrajyoti D 444173bdd74SShubhrajyoti D return ddata->enable ? ddata->enable(input->dev.parent) : 0; 445173bdd74SShubhrajyoti D } 446173bdd74SShubhrajyoti D 447173bdd74SShubhrajyoti D static void gpio_keys_close(struct input_dev *input) 448173bdd74SShubhrajyoti D { 449173bdd74SShubhrajyoti D struct gpio_keys_drvdata *ddata = input_get_drvdata(input); 450173bdd74SShubhrajyoti D 451173bdd74SShubhrajyoti D if (ddata->disable) 452173bdd74SShubhrajyoti D ddata->disable(input->dev.parent); 453173bdd74SShubhrajyoti D } 454173bdd74SShubhrajyoti D 455fd05d089SDavid Jander /* 456fd05d089SDavid Jander * Handlers for alternative sources of platform_data 457fd05d089SDavid Jander */ 458fd05d089SDavid Jander #ifdef CONFIG_OF 459fd05d089SDavid Jander /* 460fd05d089SDavid Jander * Translate OpenFirmware node properties into platform_data 461fd05d089SDavid Jander */ 462fd05d089SDavid Jander static int gpio_keys_get_devtree_pdata(struct device *dev, 463fd05d089SDavid Jander struct gpio_keys_platform_data *pdata) 464fd05d089SDavid Jander { 465fd05d089SDavid Jander struct device_node *node, *pp; 466fd05d089SDavid Jander int i; 467fd05d089SDavid Jander struct gpio_keys_button *buttons; 468cca84699STobias Klauser u32 reg; 469fd05d089SDavid Jander 470fd05d089SDavid Jander node = dev->of_node; 471fd05d089SDavid Jander if (node == NULL) 472fd05d089SDavid Jander return -ENODEV; 473fd05d089SDavid Jander 474fd05d089SDavid Jander memset(pdata, 0, sizeof *pdata); 475fd05d089SDavid Jander 476cca84699STobias Klauser pdata->rep = !!of_get_property(node, "autorepeat", NULL); 477fd05d089SDavid Jander 478fd05d089SDavid Jander /* First count the subnodes */ 479fd05d089SDavid Jander pdata->nbuttons = 0; 480fd05d089SDavid Jander pp = NULL; 481fd05d089SDavid Jander while ((pp = of_get_next_child(node, pp))) 482fd05d089SDavid Jander pdata->nbuttons++; 483fd05d089SDavid Jander 484fd05d089SDavid Jander if (pdata->nbuttons == 0) 485fd05d089SDavid Jander return -ENODEV; 486fd05d089SDavid Jander 487fd05d089SDavid Jander buttons = kzalloc(pdata->nbuttons * (sizeof *buttons), GFP_KERNEL); 488fd05d089SDavid Jander if (!buttons) 4891f4bb066STobias Klauser return -ENOMEM; 490fd05d089SDavid Jander 491fd05d089SDavid Jander pp = NULL; 492fd05d089SDavid Jander i = 0; 493fd05d089SDavid Jander while ((pp = of_get_next_child(node, pp))) { 494fd05d089SDavid Jander enum of_gpio_flags flags; 495fd05d089SDavid Jander 496fd05d089SDavid Jander if (!of_find_property(pp, "gpios", NULL)) { 497fd05d089SDavid Jander pdata->nbuttons--; 498fd05d089SDavid Jander dev_warn(dev, "Found button without gpios\n"); 499fd05d089SDavid Jander continue; 500fd05d089SDavid Jander } 501fd05d089SDavid Jander buttons[i].gpio = of_get_gpio_flags(pp, 0, &flags); 502fd05d089SDavid Jander buttons[i].active_low = flags & OF_GPIO_ACTIVE_LOW; 503fd05d089SDavid Jander 504cca84699STobias Klauser if (of_property_read_u32(pp, "linux,code", ®)) { 505fd05d089SDavid Jander dev_err(dev, "Button without keycode: 0x%x\n", buttons[i].gpio); 506fd05d089SDavid Jander goto out_fail; 507fd05d089SDavid Jander } 508cca84699STobias Klauser buttons[i].code = reg; 509fd05d089SDavid Jander 510cca84699STobias Klauser buttons[i].desc = of_get_property(pp, "label", NULL); 511fd05d089SDavid Jander 512cca84699STobias Klauser if (of_property_read_u32(pp, "linux,input-type", ®) == 0) 513cca84699STobias Klauser buttons[i].type = reg; 514cca84699STobias Klauser else 515cca84699STobias Klauser buttons[i].type = EV_KEY; 516fd05d089SDavid Jander 517fd05d089SDavid Jander buttons[i].wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); 518fd05d089SDavid Jander 519cca84699STobias Klauser if (of_property_read_u32(pp, "debounce-interval", ®) == 0) 520cca84699STobias Klauser buttons[i].debounce_interval = reg; 521cca84699STobias Klauser else 522cca84699STobias Klauser buttons[i].debounce_interval = 5; 523fd05d089SDavid Jander 524fd05d089SDavid Jander i++; 525fd05d089SDavid Jander } 526fd05d089SDavid Jander 527fd05d089SDavid Jander pdata->buttons = buttons; 528fd05d089SDavid Jander 529fd05d089SDavid Jander return 0; 530fd05d089SDavid Jander 531fd05d089SDavid Jander out_fail: 532fd05d089SDavid Jander kfree(buttons); 533fd05d089SDavid Jander return -ENODEV; 534fd05d089SDavid Jander } 535fd05d089SDavid Jander 536fd05d089SDavid Jander static struct of_device_id gpio_keys_of_match[] = { 537fd05d089SDavid Jander { .compatible = "gpio-keys", }, 538fd05d089SDavid Jander { }, 539fd05d089SDavid Jander }; 540fd05d089SDavid Jander MODULE_DEVICE_TABLE(of, gpio_keys_of_match); 541fd05d089SDavid Jander 542fd05d089SDavid Jander #else 543fd05d089SDavid Jander 544fd05d089SDavid Jander static int gpio_keys_get_devtree_pdata(struct device *dev, 545fd05d089SDavid Jander struct gpio_keys_platform_data *altp) 546fd05d089SDavid Jander { 547fd05d089SDavid Jander return -ENODEV; 548fd05d089SDavid Jander } 549fd05d089SDavid Jander 550fd05d089SDavid Jander #define gpio_keys_of_match NULL 551fd05d089SDavid Jander 552fd05d089SDavid Jander #endif 553fd05d089SDavid Jander 554*a16ca239SDmitry Torokhov static void gpio_remove_key(struct gpio_button_data *bdata) 555*a16ca239SDmitry Torokhov { 556*a16ca239SDmitry Torokhov free_irq(gpio_to_irq(bdata->button->gpio), bdata); 557*a16ca239SDmitry Torokhov if (bdata->timer_debounce) 558*a16ca239SDmitry Torokhov del_timer_sync(&bdata->timer); 559*a16ca239SDmitry Torokhov cancel_work_sync(&bdata->work); 560*a16ca239SDmitry Torokhov gpio_free(bdata->button->gpio); 561*a16ca239SDmitry Torokhov } 562*a16ca239SDmitry Torokhov 56378a56aabSPhil Blundell static int __devinit gpio_keys_probe(struct platform_device *pdev) 56478a56aabSPhil Blundell { 565d9080921SDmitry Torokhov const struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 566a33466e3SDmitry Baryshkov struct gpio_keys_drvdata *ddata; 567db19fd8bSBen Dooks struct device *dev = &pdev->dev; 568fd05d089SDavid Jander struct gpio_keys_platform_data alt_pdata; 56978a56aabSPhil Blundell struct input_dev *input; 57078a56aabSPhil Blundell int i, error; 571e15b0213SAnti Sullin int wakeup = 0; 57278a56aabSPhil Blundell 573fd05d089SDavid Jander if (!pdata) { 574fd05d089SDavid Jander error = gpio_keys_get_devtree_pdata(dev, &alt_pdata); 575fd05d089SDavid Jander if (error) 576fd05d089SDavid Jander return error; 577fd05d089SDavid Jander pdata = &alt_pdata; 578fd05d089SDavid Jander } 579fd05d089SDavid Jander 580a33466e3SDmitry Baryshkov ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + 581a33466e3SDmitry Baryshkov pdata->nbuttons * sizeof(struct gpio_button_data), 582a33466e3SDmitry Baryshkov GFP_KERNEL); 58378a56aabSPhil Blundell input = input_allocate_device(); 584a33466e3SDmitry Baryshkov if (!ddata || !input) { 585db19fd8bSBen Dooks dev_err(dev, "failed to allocate state\n"); 586a33466e3SDmitry Baryshkov error = -ENOMEM; 587a33466e3SDmitry Baryshkov goto fail1; 588a33466e3SDmitry Baryshkov } 58978a56aabSPhil Blundell 5909e3af04fSMika Westerberg ddata->input = input; 5919e3af04fSMika Westerberg ddata->n_buttons = pdata->nbuttons; 592173bdd74SShubhrajyoti D ddata->enable = pdata->enable; 593173bdd74SShubhrajyoti D ddata->disable = pdata->disable; 5949e3af04fSMika Westerberg mutex_init(&ddata->disable_lock); 5959e3af04fSMika Westerberg 596a33466e3SDmitry Baryshkov platform_set_drvdata(pdev, ddata); 597173bdd74SShubhrajyoti D input_set_drvdata(input, ddata); 59878a56aabSPhil Blundell 59946711277SAlexander Stein input->name = pdata->name ? : pdev->name; 60078a56aabSPhil Blundell input->phys = "gpio-keys/input0"; 601469ba4dfSDmitry Torokhov input->dev.parent = &pdev->dev; 602173bdd74SShubhrajyoti D input->open = gpio_keys_open; 603173bdd74SShubhrajyoti D input->close = gpio_keys_close; 60478a56aabSPhil Blundell 60578a56aabSPhil Blundell input->id.bustype = BUS_HOST; 60678a56aabSPhil Blundell input->id.vendor = 0x0001; 60778a56aabSPhil Blundell input->id.product = 0x0001; 60878a56aabSPhil Blundell input->id.version = 0x0100; 60978a56aabSPhil Blundell 610b67b4b11SDominic Curran /* Enable auto repeat feature of Linux input subsystem */ 611b67b4b11SDominic Curran if (pdata->rep) 612b67b4b11SDominic Curran __set_bit(EV_REP, input->evbit); 613b67b4b11SDominic Curran 61478a56aabSPhil Blundell for (i = 0; i < pdata->nbuttons; i++) { 615d9080921SDmitry Torokhov const struct gpio_keys_button *button = &pdata->buttons[i]; 616a33466e3SDmitry Baryshkov struct gpio_button_data *bdata = &ddata->data[i]; 61778a56aabSPhil Blundell 618d9080921SDmitry Torokhov error = gpio_keys_setup_key(pdev, input, bdata, button); 619bc8f1eafSBen Dooks if (error) 620a33466e3SDmitry Baryshkov goto fail2; 62184767d00SRoman Moravcik 622e15b0213SAnti Sullin if (button->wakeup) 623e15b0213SAnti Sullin wakeup = 1; 62478a56aabSPhil Blundell } 62578a56aabSPhil Blundell 6269e3af04fSMika Westerberg error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group); 6279e3af04fSMika Westerberg if (error) { 6289e3af04fSMika Westerberg dev_err(dev, "Unable to export keys/switches, error: %d\n", 6299e3af04fSMika Westerberg error); 6309e3af04fSMika Westerberg goto fail2; 6319e3af04fSMika Westerberg } 6329e3af04fSMika Westerberg 63378a56aabSPhil Blundell error = input_register_device(input); 63478a56aabSPhil Blundell if (error) { 6359e3af04fSMika Westerberg dev_err(dev, "Unable to register input device, error: %d\n", 6369e3af04fSMika Westerberg error); 6379e3af04fSMika Westerberg goto fail3; 63878a56aabSPhil Blundell } 63978a56aabSPhil Blundell 6406ee88d71SDaniel Mack /* get current state of buttons */ 6416ee88d71SDaniel Mack for (i = 0; i < pdata->nbuttons; i++) 6426ee88d71SDaniel Mack gpio_keys_report_event(&ddata->data[i]); 6436ee88d71SDaniel Mack input_sync(input); 6446ee88d71SDaniel Mack 645e15b0213SAnti Sullin device_init_wakeup(&pdev->dev, wakeup); 646e15b0213SAnti Sullin 64778a56aabSPhil Blundell return 0; 64878a56aabSPhil Blundell 6499e3af04fSMika Westerberg fail3: 6509e3af04fSMika Westerberg sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); 651a33466e3SDmitry Baryshkov fail2: 652*a16ca239SDmitry Torokhov while (--i >= 0) 653*a16ca239SDmitry Torokhov gpio_remove_key(&ddata->data[i]); 65478a56aabSPhil Blundell 655006df302SAnti Sullin platform_set_drvdata(pdev, NULL); 656a33466e3SDmitry Baryshkov fail1: 65778a56aabSPhil Blundell input_free_device(input); 658a33466e3SDmitry Baryshkov kfree(ddata); 659fd05d089SDavid Jander /* If we have no platform_data, we allocated buttons dynamically. */ 660fd05d089SDavid Jander if (!pdev->dev.platform_data) 661fd05d089SDavid Jander kfree(pdata->buttons); 66278a56aabSPhil Blundell 66378a56aabSPhil Blundell return error; 66478a56aabSPhil Blundell } 66578a56aabSPhil Blundell 66678a56aabSPhil Blundell static int __devexit gpio_keys_remove(struct platform_device *pdev) 66778a56aabSPhil Blundell { 668a33466e3SDmitry Baryshkov struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); 669a33466e3SDmitry Baryshkov struct input_dev *input = ddata->input; 67078a56aabSPhil Blundell int i; 67178a56aabSPhil Blundell 6729e3af04fSMika Westerberg sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); 6739e3af04fSMika Westerberg 674e15b0213SAnti Sullin device_init_wakeup(&pdev->dev, 0); 675e15b0213SAnti Sullin 676*a16ca239SDmitry Torokhov for (i = 0; i < ddata->n_buttons; i++) 677*a16ca239SDmitry Torokhov gpio_remove_key(&ddata->data[i]); 67878a56aabSPhil Blundell 67978a56aabSPhil Blundell input_unregister_device(input); 680fd05d089SDavid Jander 681fd05d089SDavid Jander /* 682fd05d089SDavid Jander * If we had no platform_data, we allocated buttons dynamically, and 683fd05d089SDavid Jander * must free them here. ddata->data[0].button is the pointer to the 684fd05d089SDavid Jander * beginning of the allocated array. 685fd05d089SDavid Jander */ 686fd05d089SDavid Jander if (!pdev->dev.platform_data) 687fd05d089SDavid Jander kfree(ddata->data[0].button); 688fd05d089SDavid Jander 68916382079SAxel Lin kfree(ddata); 69078a56aabSPhil Blundell 69178a56aabSPhil Blundell return 0; 69278a56aabSPhil Blundell } 69378a56aabSPhil Blundell 694bdda8216SDmitry Torokhov #ifdef CONFIG_PM_SLEEP 695ae78e0e0SMike Rapoport static int gpio_keys_suspend(struct device *dev) 696e15b0213SAnti Sullin { 697fd05d089SDavid Jander struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); 698d9080921SDmitry Torokhov const struct gpio_keys_button *button; 699e15b0213SAnti Sullin int i; 700e15b0213SAnti Sullin 701fd05d089SDavid Jander if (device_may_wakeup(dev)) { 702fd05d089SDavid Jander for (i = 0; i < ddata->n_buttons; i++) { 703d9080921SDmitry Torokhov button = ddata->data[i].button; 704e15b0213SAnti Sullin if (button->wakeup) { 705e15b0213SAnti Sullin int irq = gpio_to_irq(button->gpio); 706e15b0213SAnti Sullin enable_irq_wake(irq); 707e15b0213SAnti Sullin } 708e15b0213SAnti Sullin } 709e15b0213SAnti Sullin } 710e15b0213SAnti Sullin 711e15b0213SAnti Sullin return 0; 712e15b0213SAnti Sullin } 713e15b0213SAnti Sullin 714ae78e0e0SMike Rapoport static int gpio_keys_resume(struct device *dev) 715e15b0213SAnti Sullin { 716fd05d089SDavid Jander struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); 717d9080921SDmitry Torokhov const struct gpio_keys_button *button; 718e15b0213SAnti Sullin int i; 719e15b0213SAnti Sullin 720fd05d089SDavid Jander for (i = 0; i < ddata->n_buttons; i++) { 721d9080921SDmitry Torokhov button = ddata->data[i].button; 722fd05d089SDavid Jander if (button->wakeup && device_may_wakeup(dev)) { 723e15b0213SAnti Sullin int irq = gpio_to_irq(button->gpio); 724e15b0213SAnti Sullin disable_irq_wake(irq); 725e15b0213SAnti Sullin } 7266ee88d71SDaniel Mack 7276ee88d71SDaniel Mack gpio_keys_report_event(&ddata->data[i]); 728e15b0213SAnti Sullin } 7296ee88d71SDaniel Mack input_sync(ddata->input); 730e15b0213SAnti Sullin 731e15b0213SAnti Sullin return 0; 732e15b0213SAnti Sullin } 733e15b0213SAnti Sullin #endif 734e15b0213SAnti Sullin 735bdda8216SDmitry Torokhov static SIMPLE_DEV_PM_OPS(gpio_keys_pm_ops, gpio_keys_suspend, gpio_keys_resume); 736bdda8216SDmitry Torokhov 7379b07044cSUwe Kleine-König static struct platform_driver gpio_keys_device_driver = { 73878a56aabSPhil Blundell .probe = gpio_keys_probe, 73978a56aabSPhil Blundell .remove = __devexit_p(gpio_keys_remove), 74078a56aabSPhil Blundell .driver = { 74178a56aabSPhil Blundell .name = "gpio-keys", 742d7b5247bSKay Sievers .owner = THIS_MODULE, 743ae78e0e0SMike Rapoport .pm = &gpio_keys_pm_ops, 744fd05d089SDavid Jander .of_match_table = gpio_keys_of_match, 74578a56aabSPhil Blundell } 74678a56aabSPhil Blundell }; 74778a56aabSPhil Blundell 74878a56aabSPhil Blundell static int __init gpio_keys_init(void) 74978a56aabSPhil Blundell { 75078a56aabSPhil Blundell return platform_driver_register(&gpio_keys_device_driver); 75178a56aabSPhil Blundell } 75278a56aabSPhil Blundell 75378a56aabSPhil Blundell static void __exit gpio_keys_exit(void) 75478a56aabSPhil Blundell { 75578a56aabSPhil Blundell platform_driver_unregister(&gpio_keys_device_driver); 75678a56aabSPhil Blundell } 75778a56aabSPhil Blundell 758b2330205SDavid Jander late_initcall(gpio_keys_init); 75978a56aabSPhil Blundell module_exit(gpio_keys_exit); 76078a56aabSPhil Blundell 76178a56aabSPhil Blundell MODULE_LICENSE("GPL"); 76278a56aabSPhil Blundell MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>"); 7637e2ecdf4SDavid Jander MODULE_DESCRIPTION("Keyboard driver for GPIOs"); 764d7b5247bSKay Sievers MODULE_ALIAS("platform:gpio-keys"); 765