178a56aabSPhil Blundell /* 278a56aabSPhil Blundell * Driver for keys on GPIO lines capable of generating interrupts. 378a56aabSPhil Blundell * 478a56aabSPhil Blundell * Copyright 2005 Phil Blundell 578a56aabSPhil Blundell * 678a56aabSPhil Blundell * This program is free software; you can redistribute it and/or modify 778a56aabSPhil Blundell * it under the terms of the GNU General Public License version 2 as 878a56aabSPhil Blundell * published by the Free Software Foundation. 978a56aabSPhil Blundell */ 1078a56aabSPhil Blundell 1178a56aabSPhil Blundell #include <linux/module.h> 1278a56aabSPhil Blundell 1378a56aabSPhil Blundell #include <linux/init.h> 1478a56aabSPhil Blundell #include <linux/fs.h> 1578a56aabSPhil Blundell #include <linux/interrupt.h> 1678a56aabSPhil Blundell #include <linux/irq.h> 1778a56aabSPhil Blundell #include <linux/sched.h> 1878a56aabSPhil Blundell #include <linux/pm.h> 1978a56aabSPhil Blundell #include <linux/sysctl.h> 2078a56aabSPhil Blundell #include <linux/proc_fs.h> 2178a56aabSPhil Blundell #include <linux/delay.h> 2278a56aabSPhil Blundell #include <linux/platform_device.h> 2378a56aabSPhil Blundell #include <linux/input.h> 2449015beeSDavid Brownell #include <linux/gpio_keys.h> 25da0d03feSJani Nikula #include <linux/workqueue.h> 26111bc59cSBen Dooks #include <linux/gpio.h> 2778a56aabSPhil Blundell 28a33466e3SDmitry Baryshkov struct gpio_button_data { 29a33466e3SDmitry Baryshkov struct gpio_keys_button *button; 30a33466e3SDmitry Baryshkov struct input_dev *input; 31ca865a77SJani Nikula struct timer_list timer; 32da0d03feSJani Nikula struct work_struct work; 33*9e3af04fSMika Westerberg bool disabled; 34a33466e3SDmitry Baryshkov }; 35a33466e3SDmitry Baryshkov 36a33466e3SDmitry Baryshkov struct gpio_keys_drvdata { 37a33466e3SDmitry Baryshkov struct input_dev *input; 38*9e3af04fSMika Westerberg struct mutex disable_lock; 39*9e3af04fSMika Westerberg unsigned int n_buttons; 40a33466e3SDmitry Baryshkov struct gpio_button_data data[0]; 41a33466e3SDmitry Baryshkov }; 42a33466e3SDmitry Baryshkov 43*9e3af04fSMika Westerberg /* 44*9e3af04fSMika Westerberg * SYSFS interface for enabling/disabling keys and switches: 45*9e3af04fSMika Westerberg * 46*9e3af04fSMika Westerberg * There are 4 attributes under /sys/devices/platform/gpio-keys/ 47*9e3af04fSMika Westerberg * keys [ro] - bitmap of keys (EV_KEY) which can be 48*9e3af04fSMika Westerberg * disabled 49*9e3af04fSMika Westerberg * switches [ro] - bitmap of switches (EV_SW) which can be 50*9e3af04fSMika Westerberg * disabled 51*9e3af04fSMika Westerberg * disabled_keys [rw] - bitmap of keys currently disabled 52*9e3af04fSMika Westerberg * disabled_switches [rw] - bitmap of switches currently disabled 53*9e3af04fSMika Westerberg * 54*9e3af04fSMika Westerberg * Userland can change these values and hence disable event generation 55*9e3af04fSMika Westerberg * for each key (or switch). Disabling a key means its interrupt line 56*9e3af04fSMika Westerberg * is disabled. 57*9e3af04fSMika Westerberg * 58*9e3af04fSMika Westerberg * For example, if we have following switches set up as gpio-keys: 59*9e3af04fSMika Westerberg * SW_DOCK = 5 60*9e3af04fSMika Westerberg * SW_CAMERA_LENS_COVER = 9 61*9e3af04fSMika Westerberg * SW_KEYPAD_SLIDE = 10 62*9e3af04fSMika Westerberg * SW_FRONT_PROXIMITY = 11 63*9e3af04fSMika Westerberg * This is read from switches: 64*9e3af04fSMika Westerberg * 11-9,5 65*9e3af04fSMika Westerberg * Next we want to disable proximity (11) and dock (5), we write: 66*9e3af04fSMika Westerberg * 11,5 67*9e3af04fSMika Westerberg * to file disabled_switches. Now proximity and dock IRQs are disabled. 68*9e3af04fSMika Westerberg * This can be verified by reading the file disabled_switches: 69*9e3af04fSMika Westerberg * 11,5 70*9e3af04fSMika Westerberg * If we now want to enable proximity (11) switch we write: 71*9e3af04fSMika Westerberg * 5 72*9e3af04fSMika Westerberg * to disabled_switches. 73*9e3af04fSMika Westerberg * 74*9e3af04fSMika Westerberg * We can disable only those keys which don't allow sharing the irq. 75*9e3af04fSMika Westerberg */ 76*9e3af04fSMika Westerberg 77*9e3af04fSMika Westerberg /** 78*9e3af04fSMika Westerberg * get_n_events_by_type() - returns maximum number of events per @type 79*9e3af04fSMika Westerberg * @type: type of button (%EV_KEY, %EV_SW) 80*9e3af04fSMika Westerberg * 81*9e3af04fSMika Westerberg * Return value of this function can be used to allocate bitmap 82*9e3af04fSMika Westerberg * large enough to hold all bits for given type. 83*9e3af04fSMika Westerberg */ 84*9e3af04fSMika Westerberg static inline int get_n_events_by_type(int type) 85*9e3af04fSMika Westerberg { 86*9e3af04fSMika Westerberg BUG_ON(type != EV_SW && type != EV_KEY); 87*9e3af04fSMika Westerberg 88*9e3af04fSMika Westerberg return (type == EV_KEY) ? KEY_CNT : SW_CNT; 89*9e3af04fSMika Westerberg } 90*9e3af04fSMika Westerberg 91*9e3af04fSMika Westerberg /** 92*9e3af04fSMika Westerberg * gpio_keys_disable_button() - disables given GPIO button 93*9e3af04fSMika Westerberg * @bdata: button data for button to be disabled 94*9e3af04fSMika Westerberg * 95*9e3af04fSMika Westerberg * Disables button pointed by @bdata. This is done by masking 96*9e3af04fSMika Westerberg * IRQ line. After this function is called, button won't generate 97*9e3af04fSMika Westerberg * input events anymore. Note that one can only disable buttons 98*9e3af04fSMika Westerberg * that don't share IRQs. 99*9e3af04fSMika Westerberg * 100*9e3af04fSMika Westerberg * Make sure that @bdata->disable_lock is locked when entering 101*9e3af04fSMika Westerberg * this function to avoid races when concurrent threads are 102*9e3af04fSMika Westerberg * disabling buttons at the same time. 103*9e3af04fSMika Westerberg */ 104*9e3af04fSMika Westerberg static void gpio_keys_disable_button(struct gpio_button_data *bdata) 105*9e3af04fSMika Westerberg { 106*9e3af04fSMika Westerberg if (!bdata->disabled) { 107*9e3af04fSMika Westerberg /* 108*9e3af04fSMika Westerberg * Disable IRQ and possible debouncing timer. 109*9e3af04fSMika Westerberg */ 110*9e3af04fSMika Westerberg disable_irq(gpio_to_irq(bdata->button->gpio)); 111*9e3af04fSMika Westerberg if (bdata->button->debounce_interval) 112*9e3af04fSMika Westerberg del_timer_sync(&bdata->timer); 113*9e3af04fSMika Westerberg 114*9e3af04fSMika Westerberg bdata->disabled = true; 115*9e3af04fSMika Westerberg } 116*9e3af04fSMika Westerberg } 117*9e3af04fSMika Westerberg 118*9e3af04fSMika Westerberg /** 119*9e3af04fSMika Westerberg * gpio_keys_enable_button() - enables given GPIO button 120*9e3af04fSMika Westerberg * @bdata: button data for button to be disabled 121*9e3af04fSMika Westerberg * 122*9e3af04fSMika Westerberg * Enables given button pointed by @bdata. 123*9e3af04fSMika Westerberg * 124*9e3af04fSMika Westerberg * Make sure that @bdata->disable_lock is locked when entering 125*9e3af04fSMika Westerberg * this function to avoid races with concurrent threads trying 126*9e3af04fSMika Westerberg * to enable the same button at the same time. 127*9e3af04fSMika Westerberg */ 128*9e3af04fSMika Westerberg static void gpio_keys_enable_button(struct gpio_button_data *bdata) 129*9e3af04fSMika Westerberg { 130*9e3af04fSMika Westerberg if (bdata->disabled) { 131*9e3af04fSMika Westerberg enable_irq(gpio_to_irq(bdata->button->gpio)); 132*9e3af04fSMika Westerberg bdata->disabled = false; 133*9e3af04fSMika Westerberg } 134*9e3af04fSMika Westerberg } 135*9e3af04fSMika Westerberg 136*9e3af04fSMika Westerberg /** 137*9e3af04fSMika Westerberg * gpio_keys_attr_show_helper() - fill in stringified bitmap of buttons 138*9e3af04fSMika Westerberg * @ddata: pointer to drvdata 139*9e3af04fSMika Westerberg * @buf: buffer where stringified bitmap is written 140*9e3af04fSMika Westerberg * @type: button type (%EV_KEY, %EV_SW) 141*9e3af04fSMika Westerberg * @only_disabled: does caller want only those buttons that are 142*9e3af04fSMika Westerberg * currently disabled or all buttons that can be 143*9e3af04fSMika Westerberg * disabled 144*9e3af04fSMika Westerberg * 145*9e3af04fSMika Westerberg * This function writes buttons that can be disabled to @buf. If 146*9e3af04fSMika Westerberg * @only_disabled is true, then @buf contains only those buttons 147*9e3af04fSMika Westerberg * that are currently disabled. Returns 0 on success or negative 148*9e3af04fSMika Westerberg * errno on failure. 149*9e3af04fSMika Westerberg */ 150*9e3af04fSMika Westerberg static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata, 151*9e3af04fSMika Westerberg char *buf, unsigned int type, 152*9e3af04fSMika Westerberg bool only_disabled) 153*9e3af04fSMika Westerberg { 154*9e3af04fSMika Westerberg int n_events = get_n_events_by_type(type); 155*9e3af04fSMika Westerberg unsigned long *bits; 156*9e3af04fSMika Westerberg ssize_t ret; 157*9e3af04fSMika Westerberg int i; 158*9e3af04fSMika Westerberg 159*9e3af04fSMika Westerberg bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); 160*9e3af04fSMika Westerberg if (!bits) 161*9e3af04fSMika Westerberg return -ENOMEM; 162*9e3af04fSMika Westerberg 163*9e3af04fSMika Westerberg for (i = 0; i < ddata->n_buttons; i++) { 164*9e3af04fSMika Westerberg struct gpio_button_data *bdata = &ddata->data[i]; 165*9e3af04fSMika Westerberg 166*9e3af04fSMika Westerberg if (bdata->button->type != type) 167*9e3af04fSMika Westerberg continue; 168*9e3af04fSMika Westerberg 169*9e3af04fSMika Westerberg if (only_disabled && !bdata->disabled) 170*9e3af04fSMika Westerberg continue; 171*9e3af04fSMika Westerberg 172*9e3af04fSMika Westerberg __set_bit(bdata->button->code, bits); 173*9e3af04fSMika Westerberg } 174*9e3af04fSMika Westerberg 175*9e3af04fSMika Westerberg ret = bitmap_scnlistprintf(buf, PAGE_SIZE - 2, bits, n_events); 176*9e3af04fSMika Westerberg buf[ret++] = '\n'; 177*9e3af04fSMika Westerberg buf[ret] = '\0'; 178*9e3af04fSMika Westerberg 179*9e3af04fSMika Westerberg kfree(bits); 180*9e3af04fSMika Westerberg 181*9e3af04fSMika Westerberg return ret; 182*9e3af04fSMika Westerberg } 183*9e3af04fSMika Westerberg 184*9e3af04fSMika Westerberg /** 185*9e3af04fSMika Westerberg * gpio_keys_attr_store_helper() - enable/disable buttons based on given bitmap 186*9e3af04fSMika Westerberg * @ddata: pointer to drvdata 187*9e3af04fSMika Westerberg * @buf: buffer from userspace that contains stringified bitmap 188*9e3af04fSMika Westerberg * @type: button type (%EV_KEY, %EV_SW) 189*9e3af04fSMika Westerberg * 190*9e3af04fSMika Westerberg * This function parses stringified bitmap from @buf and disables/enables 191*9e3af04fSMika Westerberg * GPIO buttons accordinly. Returns 0 on success and negative error 192*9e3af04fSMika Westerberg * on failure. 193*9e3af04fSMika Westerberg */ 194*9e3af04fSMika Westerberg static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, 195*9e3af04fSMika Westerberg const char *buf, unsigned int type) 196*9e3af04fSMika Westerberg { 197*9e3af04fSMika Westerberg int n_events = get_n_events_by_type(type); 198*9e3af04fSMika Westerberg unsigned long *bits; 199*9e3af04fSMika Westerberg ssize_t error; 200*9e3af04fSMika Westerberg int i; 201*9e3af04fSMika Westerberg 202*9e3af04fSMika Westerberg bits = kcalloc(BITS_TO_LONGS(n_events), sizeof(*bits), GFP_KERNEL); 203*9e3af04fSMika Westerberg if (!bits) 204*9e3af04fSMika Westerberg return -ENOMEM; 205*9e3af04fSMika Westerberg 206*9e3af04fSMika Westerberg error = bitmap_parselist(buf, bits, n_events); 207*9e3af04fSMika Westerberg if (error) 208*9e3af04fSMika Westerberg goto out; 209*9e3af04fSMika Westerberg 210*9e3af04fSMika Westerberg /* First validate */ 211*9e3af04fSMika Westerberg for (i = 0; i < ddata->n_buttons; i++) { 212*9e3af04fSMika Westerberg struct gpio_button_data *bdata = &ddata->data[i]; 213*9e3af04fSMika Westerberg 214*9e3af04fSMika Westerberg if (bdata->button->type != type) 215*9e3af04fSMika Westerberg continue; 216*9e3af04fSMika Westerberg 217*9e3af04fSMika Westerberg if (test_bit(bdata->button->code, bits) && 218*9e3af04fSMika Westerberg !bdata->button->can_disable) { 219*9e3af04fSMika Westerberg error = -EINVAL; 220*9e3af04fSMika Westerberg goto out; 221*9e3af04fSMika Westerberg } 222*9e3af04fSMika Westerberg } 223*9e3af04fSMika Westerberg 224*9e3af04fSMika Westerberg mutex_lock(&ddata->disable_lock); 225*9e3af04fSMika Westerberg 226*9e3af04fSMika Westerberg for (i = 0; i < ddata->n_buttons; i++) { 227*9e3af04fSMika Westerberg struct gpio_button_data *bdata = &ddata->data[i]; 228*9e3af04fSMika Westerberg 229*9e3af04fSMika Westerberg if (bdata->button->type != type) 230*9e3af04fSMika Westerberg continue; 231*9e3af04fSMika Westerberg 232*9e3af04fSMika Westerberg if (test_bit(bdata->button->code, bits)) 233*9e3af04fSMika Westerberg gpio_keys_disable_button(bdata); 234*9e3af04fSMika Westerberg else 235*9e3af04fSMika Westerberg gpio_keys_enable_button(bdata); 236*9e3af04fSMika Westerberg } 237*9e3af04fSMika Westerberg 238*9e3af04fSMika Westerberg mutex_unlock(&ddata->disable_lock); 239*9e3af04fSMika Westerberg 240*9e3af04fSMika Westerberg out: 241*9e3af04fSMika Westerberg kfree(bits); 242*9e3af04fSMika Westerberg return error; 243*9e3af04fSMika Westerberg } 244*9e3af04fSMika Westerberg 245*9e3af04fSMika Westerberg #define ATTR_SHOW_FN(name, type, only_disabled) \ 246*9e3af04fSMika Westerberg static ssize_t gpio_keys_show_##name(struct device *dev, \ 247*9e3af04fSMika Westerberg struct device_attribute *attr, \ 248*9e3af04fSMika Westerberg char *buf) \ 249*9e3af04fSMika Westerberg { \ 250*9e3af04fSMika Westerberg struct platform_device *pdev = to_platform_device(dev); \ 251*9e3af04fSMika Westerberg struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ 252*9e3af04fSMika Westerberg \ 253*9e3af04fSMika Westerberg return gpio_keys_attr_show_helper(ddata, buf, \ 254*9e3af04fSMika Westerberg type, only_disabled); \ 255*9e3af04fSMika Westerberg } 256*9e3af04fSMika Westerberg 257*9e3af04fSMika Westerberg ATTR_SHOW_FN(keys, EV_KEY, false); 258*9e3af04fSMika Westerberg ATTR_SHOW_FN(switches, EV_SW, false); 259*9e3af04fSMika Westerberg ATTR_SHOW_FN(disabled_keys, EV_KEY, true); 260*9e3af04fSMika Westerberg ATTR_SHOW_FN(disabled_switches, EV_SW, true); 261*9e3af04fSMika Westerberg 262*9e3af04fSMika Westerberg /* 263*9e3af04fSMika Westerberg * ATTRIBUTES: 264*9e3af04fSMika Westerberg * 265*9e3af04fSMika Westerberg * /sys/devices/platform/gpio-keys/keys [ro] 266*9e3af04fSMika Westerberg * /sys/devices/platform/gpio-keys/switches [ro] 267*9e3af04fSMika Westerberg */ 268*9e3af04fSMika Westerberg static DEVICE_ATTR(keys, S_IRUGO, gpio_keys_show_keys, NULL); 269*9e3af04fSMika Westerberg static DEVICE_ATTR(switches, S_IRUGO, gpio_keys_show_switches, NULL); 270*9e3af04fSMika Westerberg 271*9e3af04fSMika Westerberg #define ATTR_STORE_FN(name, type) \ 272*9e3af04fSMika Westerberg static ssize_t gpio_keys_store_##name(struct device *dev, \ 273*9e3af04fSMika Westerberg struct device_attribute *attr, \ 274*9e3af04fSMika Westerberg const char *buf, \ 275*9e3af04fSMika Westerberg size_t count) \ 276*9e3af04fSMika Westerberg { \ 277*9e3af04fSMika Westerberg struct platform_device *pdev = to_platform_device(dev); \ 278*9e3af04fSMika Westerberg struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); \ 279*9e3af04fSMika Westerberg ssize_t error; \ 280*9e3af04fSMika Westerberg \ 281*9e3af04fSMika Westerberg error = gpio_keys_attr_store_helper(ddata, buf, type); \ 282*9e3af04fSMika Westerberg if (error) \ 283*9e3af04fSMika Westerberg return error; \ 284*9e3af04fSMika Westerberg \ 285*9e3af04fSMika Westerberg return count; \ 286*9e3af04fSMika Westerberg } 287*9e3af04fSMika Westerberg 288*9e3af04fSMika Westerberg ATTR_STORE_FN(disabled_keys, EV_KEY); 289*9e3af04fSMika Westerberg ATTR_STORE_FN(disabled_switches, EV_SW); 290*9e3af04fSMika Westerberg 291*9e3af04fSMika Westerberg /* 292*9e3af04fSMika Westerberg * ATTRIBUTES: 293*9e3af04fSMika Westerberg * 294*9e3af04fSMika Westerberg * /sys/devices/platform/gpio-keys/disabled_keys [rw] 295*9e3af04fSMika Westerberg * /sys/devices/platform/gpio-keys/disables_switches [rw] 296*9e3af04fSMika Westerberg */ 297*9e3af04fSMika Westerberg static DEVICE_ATTR(disabled_keys, S_IWUSR | S_IRUGO, 298*9e3af04fSMika Westerberg gpio_keys_show_disabled_keys, 299*9e3af04fSMika Westerberg gpio_keys_store_disabled_keys); 300*9e3af04fSMika Westerberg static DEVICE_ATTR(disabled_switches, S_IWUSR | S_IRUGO, 301*9e3af04fSMika Westerberg gpio_keys_show_disabled_switches, 302*9e3af04fSMika Westerberg gpio_keys_store_disabled_switches); 303*9e3af04fSMika Westerberg 304*9e3af04fSMika Westerberg static struct attribute *gpio_keys_attrs[] = { 305*9e3af04fSMika Westerberg &dev_attr_keys.attr, 306*9e3af04fSMika Westerberg &dev_attr_switches.attr, 307*9e3af04fSMika Westerberg &dev_attr_disabled_keys.attr, 308*9e3af04fSMika Westerberg &dev_attr_disabled_switches.attr, 309*9e3af04fSMika Westerberg NULL, 310*9e3af04fSMika Westerberg }; 311*9e3af04fSMika Westerberg 312*9e3af04fSMika Westerberg static struct attribute_group gpio_keys_attr_group = { 313*9e3af04fSMika Westerberg .attrs = gpio_keys_attrs, 314*9e3af04fSMika Westerberg }; 315*9e3af04fSMika Westerberg 3166ee88d71SDaniel Mack static void gpio_keys_report_event(struct gpio_button_data *bdata) 31778a56aabSPhil Blundell { 318ce25d7e9SUwe Kleine-König struct gpio_keys_button *button = bdata->button; 319ce25d7e9SUwe Kleine-König struct input_dev *input = bdata->input; 32084767d00SRoman Moravcik unsigned int type = button->type ?: EV_KEY; 321a33466e3SDmitry Baryshkov int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low; 32284767d00SRoman Moravcik 32384767d00SRoman Moravcik input_event(input, type, button->code, !!state); 32478a56aabSPhil Blundell input_sync(input); 325a33466e3SDmitry Baryshkov } 326a33466e3SDmitry Baryshkov 3276ee88d71SDaniel Mack static void gpio_keys_work_func(struct work_struct *work) 3286ee88d71SDaniel Mack { 3296ee88d71SDaniel Mack struct gpio_button_data *bdata = 3306ee88d71SDaniel Mack container_of(work, struct gpio_button_data, work); 3316ee88d71SDaniel Mack 3326ee88d71SDaniel Mack gpio_keys_report_event(bdata); 3336ee88d71SDaniel Mack } 3346ee88d71SDaniel Mack 335da0d03feSJani Nikula static void gpio_keys_timer(unsigned long _data) 336ca865a77SJani Nikula { 337ca865a77SJani Nikula struct gpio_button_data *data = (struct gpio_button_data *)_data; 338ca865a77SJani Nikula 339da0d03feSJani Nikula schedule_work(&data->work); 340ca865a77SJani Nikula } 341ca865a77SJani Nikula 342a33466e3SDmitry Baryshkov static irqreturn_t gpio_keys_isr(int irq, void *dev_id) 343a33466e3SDmitry Baryshkov { 34457ffe9d5SUwe Kleine-König struct gpio_button_data *bdata = dev_id; 34557ffe9d5SUwe Kleine-König struct gpio_keys_button *button = bdata->button; 346a33466e3SDmitry Baryshkov 34757ffe9d5SUwe Kleine-König BUG_ON(irq != gpio_to_irq(button->gpio)); 348a33466e3SDmitry Baryshkov 349ca865a77SJani Nikula if (button->debounce_interval) 350ca865a77SJani Nikula mod_timer(&bdata->timer, 351ca865a77SJani Nikula jiffies + msecs_to_jiffies(button->debounce_interval)); 352ca865a77SJani Nikula else 353da0d03feSJani Nikula schedule_work(&bdata->work); 354a33466e3SDmitry Baryshkov 3551164ec1aSDavid Brownell return IRQ_HANDLED; 35678a56aabSPhil Blundell } 35778a56aabSPhil Blundell 358*9e3af04fSMika Westerberg static int __devinit gpio_keys_setup_key(struct platform_device *pdev, 359bc8f1eafSBen Dooks struct gpio_button_data *bdata, 360bc8f1eafSBen Dooks struct gpio_keys_button *button) 361bc8f1eafSBen Dooks { 362bc8f1eafSBen Dooks char *desc = button->desc ? button->desc : "gpio_keys"; 363*9e3af04fSMika Westerberg struct device *dev = &pdev->dev; 364*9e3af04fSMika Westerberg unsigned long irqflags; 365bc8f1eafSBen Dooks int irq, error; 366bc8f1eafSBen Dooks 367bc8f1eafSBen Dooks setup_timer(&bdata->timer, gpio_keys_timer, (unsigned long)bdata); 3686ee88d71SDaniel Mack INIT_WORK(&bdata->work, gpio_keys_work_func); 369bc8f1eafSBen Dooks 370bc8f1eafSBen Dooks error = gpio_request(button->gpio, desc); 371bc8f1eafSBen Dooks if (error < 0) { 372bc8f1eafSBen Dooks dev_err(dev, "failed to request GPIO %d, error %d\n", 373bc8f1eafSBen Dooks button->gpio, error); 374bc8f1eafSBen Dooks goto fail2; 375bc8f1eafSBen Dooks } 376bc8f1eafSBen Dooks 377bc8f1eafSBen Dooks error = gpio_direction_input(button->gpio); 378bc8f1eafSBen Dooks if (error < 0) { 379bc8f1eafSBen Dooks dev_err(dev, "failed to configure" 380bc8f1eafSBen Dooks " direction for GPIO %d, error %d\n", 381bc8f1eafSBen Dooks button->gpio, error); 382bc8f1eafSBen Dooks goto fail3; 383bc8f1eafSBen Dooks } 384bc8f1eafSBen Dooks 385bc8f1eafSBen Dooks irq = gpio_to_irq(button->gpio); 386bc8f1eafSBen Dooks if (irq < 0) { 387bc8f1eafSBen Dooks error = irq; 388bc8f1eafSBen Dooks dev_err(dev, "Unable to get irq number for GPIO %d, error %d\n", 389bc8f1eafSBen Dooks button->gpio, error); 390bc8f1eafSBen Dooks goto fail3; 391bc8f1eafSBen Dooks } 392bc8f1eafSBen Dooks 393*9e3af04fSMika Westerberg irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; 394*9e3af04fSMika Westerberg /* 395*9e3af04fSMika Westerberg * If platform has specified that the button can be disabled, 396*9e3af04fSMika Westerberg * we don't want it to share the interrupt line. 397*9e3af04fSMika Westerberg */ 398*9e3af04fSMika Westerberg if (!button->can_disable) 399*9e3af04fSMika Westerberg irqflags |= IRQF_SHARED; 400*9e3af04fSMika Westerberg 401*9e3af04fSMika Westerberg error = request_irq(irq, gpio_keys_isr, irqflags, desc, bdata); 402bc8f1eafSBen Dooks if (error) { 403bc8f1eafSBen Dooks dev_err(dev, "Unable to claim irq %d; error %d\n", 404bc8f1eafSBen Dooks irq, error); 405bc8f1eafSBen Dooks goto fail3; 406bc8f1eafSBen Dooks } 407bc8f1eafSBen Dooks 408bc8f1eafSBen Dooks return 0; 409bc8f1eafSBen Dooks 410bc8f1eafSBen Dooks fail3: 411bc8f1eafSBen Dooks gpio_free(button->gpio); 412bc8f1eafSBen Dooks fail2: 413bc8f1eafSBen Dooks return error; 414bc8f1eafSBen Dooks } 415bc8f1eafSBen Dooks 41678a56aabSPhil Blundell static int __devinit gpio_keys_probe(struct platform_device *pdev) 41778a56aabSPhil Blundell { 41878a56aabSPhil Blundell struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 419a33466e3SDmitry Baryshkov struct gpio_keys_drvdata *ddata; 420db19fd8bSBen Dooks struct device *dev = &pdev->dev; 42178a56aabSPhil Blundell struct input_dev *input; 42278a56aabSPhil Blundell int i, error; 423e15b0213SAnti Sullin int wakeup = 0; 42478a56aabSPhil Blundell 425a33466e3SDmitry Baryshkov ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + 426a33466e3SDmitry Baryshkov pdata->nbuttons * sizeof(struct gpio_button_data), 427a33466e3SDmitry Baryshkov GFP_KERNEL); 42878a56aabSPhil Blundell input = input_allocate_device(); 429a33466e3SDmitry Baryshkov if (!ddata || !input) { 430db19fd8bSBen Dooks dev_err(dev, "failed to allocate state\n"); 431a33466e3SDmitry Baryshkov error = -ENOMEM; 432a33466e3SDmitry Baryshkov goto fail1; 433a33466e3SDmitry Baryshkov } 43478a56aabSPhil Blundell 435*9e3af04fSMika Westerberg ddata->input = input; 436*9e3af04fSMika Westerberg ddata->n_buttons = pdata->nbuttons; 437*9e3af04fSMika Westerberg mutex_init(&ddata->disable_lock); 438*9e3af04fSMika Westerberg 439a33466e3SDmitry Baryshkov platform_set_drvdata(pdev, ddata); 44078a56aabSPhil Blundell 44178a56aabSPhil Blundell input->name = pdev->name; 44278a56aabSPhil Blundell input->phys = "gpio-keys/input0"; 443469ba4dfSDmitry Torokhov input->dev.parent = &pdev->dev; 44478a56aabSPhil Blundell 44578a56aabSPhil Blundell input->id.bustype = BUS_HOST; 44678a56aabSPhil Blundell input->id.vendor = 0x0001; 44778a56aabSPhil Blundell input->id.product = 0x0001; 44878a56aabSPhil Blundell input->id.version = 0x0100; 44978a56aabSPhil Blundell 450b67b4b11SDominic Curran /* Enable auto repeat feature of Linux input subsystem */ 451b67b4b11SDominic Curran if (pdata->rep) 452b67b4b11SDominic Curran __set_bit(EV_REP, input->evbit); 453b67b4b11SDominic Curran 45478a56aabSPhil Blundell for (i = 0; i < pdata->nbuttons; i++) { 45584767d00SRoman Moravcik struct gpio_keys_button *button = &pdata->buttons[i]; 456a33466e3SDmitry Baryshkov struct gpio_button_data *bdata = &ddata->data[i]; 45784767d00SRoman Moravcik unsigned int type = button->type ?: EV_KEY; 45878a56aabSPhil Blundell 459a33466e3SDmitry Baryshkov bdata->input = input; 46074dd4393SUwe Kleine-König bdata->button = button; 461a33466e3SDmitry Baryshkov 462*9e3af04fSMika Westerberg error = gpio_keys_setup_key(pdev, bdata, button); 463bc8f1eafSBen Dooks if (error) 464a33466e3SDmitry Baryshkov goto fail2; 46584767d00SRoman Moravcik 466e15b0213SAnti Sullin if (button->wakeup) 467e15b0213SAnti Sullin wakeup = 1; 468e15b0213SAnti Sullin 46984767d00SRoman Moravcik input_set_capability(input, type, button->code); 47078a56aabSPhil Blundell } 47178a56aabSPhil Blundell 472*9e3af04fSMika Westerberg error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group); 473*9e3af04fSMika Westerberg if (error) { 474*9e3af04fSMika Westerberg dev_err(dev, "Unable to export keys/switches, error: %d\n", 475*9e3af04fSMika Westerberg error); 476*9e3af04fSMika Westerberg goto fail2; 477*9e3af04fSMika Westerberg } 478*9e3af04fSMika Westerberg 47978a56aabSPhil Blundell error = input_register_device(input); 48078a56aabSPhil Blundell if (error) { 481*9e3af04fSMika Westerberg dev_err(dev, "Unable to register input device, error: %d\n", 482*9e3af04fSMika Westerberg error); 483*9e3af04fSMika Westerberg goto fail3; 48478a56aabSPhil Blundell } 48578a56aabSPhil Blundell 4866ee88d71SDaniel Mack /* get current state of buttons */ 4876ee88d71SDaniel Mack for (i = 0; i < pdata->nbuttons; i++) 4886ee88d71SDaniel Mack gpio_keys_report_event(&ddata->data[i]); 4896ee88d71SDaniel Mack input_sync(input); 4906ee88d71SDaniel Mack 491e15b0213SAnti Sullin device_init_wakeup(&pdev->dev, wakeup); 492e15b0213SAnti Sullin 49378a56aabSPhil Blundell return 0; 49478a56aabSPhil Blundell 495*9e3af04fSMika Westerberg fail3: 496*9e3af04fSMika Westerberg sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); 497a33466e3SDmitry Baryshkov fail2: 4986a2e3911SHerbert Valerio Riedel while (--i >= 0) { 49957ffe9d5SUwe Kleine-König free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); 500ca865a77SJani Nikula if (pdata->buttons[i].debounce_interval) 501ca865a77SJani Nikula del_timer_sync(&ddata->data[i].timer); 502da0d03feSJani Nikula cancel_work_sync(&ddata->data[i].work); 5036a2e3911SHerbert Valerio Riedel gpio_free(pdata->buttons[i].gpio); 5046a2e3911SHerbert Valerio Riedel } 50578a56aabSPhil Blundell 506006df302SAnti Sullin platform_set_drvdata(pdev, NULL); 507a33466e3SDmitry Baryshkov fail1: 50878a56aabSPhil Blundell input_free_device(input); 509a33466e3SDmitry Baryshkov kfree(ddata); 51078a56aabSPhil Blundell 51178a56aabSPhil Blundell return error; 51278a56aabSPhil Blundell } 51378a56aabSPhil Blundell 51478a56aabSPhil Blundell static int __devexit gpio_keys_remove(struct platform_device *pdev) 51578a56aabSPhil Blundell { 51678a56aabSPhil Blundell struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 517a33466e3SDmitry Baryshkov struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); 518a33466e3SDmitry Baryshkov struct input_dev *input = ddata->input; 51978a56aabSPhil Blundell int i; 52078a56aabSPhil Blundell 521*9e3af04fSMika Westerberg sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group); 522*9e3af04fSMika Westerberg 523e15b0213SAnti Sullin device_init_wakeup(&pdev->dev, 0); 524e15b0213SAnti Sullin 52578a56aabSPhil Blundell for (i = 0; i < pdata->nbuttons; i++) { 5260d98f6bbSPhilipp Zabel int irq = gpio_to_irq(pdata->buttons[i].gpio); 52757ffe9d5SUwe Kleine-König free_irq(irq, &ddata->data[i]); 528ca865a77SJani Nikula if (pdata->buttons[i].debounce_interval) 529ca865a77SJani Nikula del_timer_sync(&ddata->data[i].timer); 530da0d03feSJani Nikula cancel_work_sync(&ddata->data[i].work); 5316a2e3911SHerbert Valerio Riedel gpio_free(pdata->buttons[i].gpio); 53278a56aabSPhil Blundell } 53378a56aabSPhil Blundell 53478a56aabSPhil Blundell input_unregister_device(input); 53578a56aabSPhil Blundell 53678a56aabSPhil Blundell return 0; 53778a56aabSPhil Blundell } 53878a56aabSPhil Blundell 539e15b0213SAnti Sullin 540e15b0213SAnti Sullin #ifdef CONFIG_PM 541ae78e0e0SMike Rapoport static int gpio_keys_suspend(struct device *dev) 542e15b0213SAnti Sullin { 543ae78e0e0SMike Rapoport struct platform_device *pdev = to_platform_device(dev); 544e15b0213SAnti Sullin struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 545e15b0213SAnti Sullin int i; 546e15b0213SAnti Sullin 547e15b0213SAnti Sullin if (device_may_wakeup(&pdev->dev)) { 548e15b0213SAnti Sullin for (i = 0; i < pdata->nbuttons; i++) { 549e15b0213SAnti Sullin struct gpio_keys_button *button = &pdata->buttons[i]; 550e15b0213SAnti Sullin if (button->wakeup) { 551e15b0213SAnti Sullin int irq = gpio_to_irq(button->gpio); 552e15b0213SAnti Sullin enable_irq_wake(irq); 553e15b0213SAnti Sullin } 554e15b0213SAnti Sullin } 555e15b0213SAnti Sullin } 556e15b0213SAnti Sullin 557e15b0213SAnti Sullin return 0; 558e15b0213SAnti Sullin } 559e15b0213SAnti Sullin 560ae78e0e0SMike Rapoport static int gpio_keys_resume(struct device *dev) 561e15b0213SAnti Sullin { 562ae78e0e0SMike Rapoport struct platform_device *pdev = to_platform_device(dev); 5636ee88d71SDaniel Mack struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev); 564e15b0213SAnti Sullin struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; 565e15b0213SAnti Sullin int i; 566e15b0213SAnti Sullin 567e15b0213SAnti Sullin for (i = 0; i < pdata->nbuttons; i++) { 5686ee88d71SDaniel Mack 569e15b0213SAnti Sullin struct gpio_keys_button *button = &pdata->buttons[i]; 5706ee88d71SDaniel Mack if (button->wakeup && device_may_wakeup(&pdev->dev)) { 571e15b0213SAnti Sullin int irq = gpio_to_irq(button->gpio); 572e15b0213SAnti Sullin disable_irq_wake(irq); 573e15b0213SAnti Sullin } 5746ee88d71SDaniel Mack 5756ee88d71SDaniel Mack gpio_keys_report_event(&ddata->data[i]); 576e15b0213SAnti Sullin } 5776ee88d71SDaniel Mack input_sync(ddata->input); 578e15b0213SAnti Sullin 579e15b0213SAnti Sullin return 0; 580e15b0213SAnti Sullin } 581ae78e0e0SMike Rapoport 582ae78e0e0SMike Rapoport static const struct dev_pm_ops gpio_keys_pm_ops = { 583ae78e0e0SMike Rapoport .suspend = gpio_keys_suspend, 584ae78e0e0SMike Rapoport .resume = gpio_keys_resume, 585ae78e0e0SMike Rapoport }; 586e15b0213SAnti Sullin #endif 587e15b0213SAnti Sullin 5889b07044cSUwe Kleine-König static struct platform_driver gpio_keys_device_driver = { 58978a56aabSPhil Blundell .probe = gpio_keys_probe, 59078a56aabSPhil Blundell .remove = __devexit_p(gpio_keys_remove), 59178a56aabSPhil Blundell .driver = { 59278a56aabSPhil Blundell .name = "gpio-keys", 593d7b5247bSKay Sievers .owner = THIS_MODULE, 594ae78e0e0SMike Rapoport #ifdef CONFIG_PM 595ae78e0e0SMike Rapoport .pm = &gpio_keys_pm_ops, 596ae78e0e0SMike Rapoport #endif 59778a56aabSPhil Blundell } 59878a56aabSPhil Blundell }; 59978a56aabSPhil Blundell 60078a56aabSPhil Blundell static int __init gpio_keys_init(void) 60178a56aabSPhil Blundell { 60278a56aabSPhil Blundell return platform_driver_register(&gpio_keys_device_driver); 60378a56aabSPhil Blundell } 60478a56aabSPhil Blundell 60578a56aabSPhil Blundell static void __exit gpio_keys_exit(void) 60678a56aabSPhil Blundell { 60778a56aabSPhil Blundell platform_driver_unregister(&gpio_keys_device_driver); 60878a56aabSPhil Blundell } 60978a56aabSPhil Blundell 61078a56aabSPhil Blundell module_init(gpio_keys_init); 61178a56aabSPhil Blundell module_exit(gpio_keys_exit); 61278a56aabSPhil Blundell 61378a56aabSPhil Blundell MODULE_LICENSE("GPL"); 61478a56aabSPhil Blundell MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>"); 61578a56aabSPhil Blundell MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs"); 616d7b5247bSKay Sievers MODULE_ALIAS("platform:gpio-keys"); 617