Loading Documentation/devicetree/bindings/input/gpio-keys-polled.txt 0 → 100644 +38 −0 Original line number Diff line number Diff line Device-Tree bindings for input/gpio_keys_polled.c keyboard driver Required properties: - compatible = "gpio-keys-polled"; - poll-interval: Poll interval time in milliseconds Optional properties: - autorepeat: Boolean, Enable auto repeat feature of Linux input subsystem. Each button (key) is represented as a sub-node of "gpio-keys-polled": Subnode properties: - gpios: OF device-tree gpio specification. - label: Descriptive name of the key. - linux,code: Keycode to emit. Optional subnode-properties: - linux,input-type: Specify event type this button/key generates. If not specified defaults to <1> == EV_KEY. - debounce-interval: Debouncing interval time in milliseconds. If not specified defaults to 5. - gpio-key,wakeup: Boolean, button can wake-up the system. Example nodes: gpio_keys_polled { compatible = "gpio-keys-polled"; #address-cells = <1>; #size-cells = <0>; poll-interval = <100>; autorepeat; button@21 { label = "GPIO Key UP"; linux,code = <103>; gpios = <&gpio1 0 1>; }; ... Documentation/devicetree/bindings/input/rotary-encoder.txt 0 → 100644 +36 −0 Original line number Diff line number Diff line Rotary encoder DT bindings Required properties: - gpios: a spec for two GPIOs to be used Optional properties: - linux,axis: the input subsystem axis to map to this rotary encoder. Defaults to 0 (ABS_X / REL_X) - rotary-encoder,steps: Number of steps in a full turnaround of the encoder. Only relevant for absolute axis. Defaults to 24 which is a typical value for such devices. - rotary-encoder,relative-axis: register a relative axis rather than an absolute one. Relative axis will only generate +1/-1 events on the input device, hence no steps need to be passed. - rotary-encoder,rollover: Automatic rollove when the rotary value becomes greater than the specified steps or smaller than 0. For absolute axis only. - rotary-encoder,half-period: Makes the driver work on half-period mode. See Documentation/input/rotary-encoder.txt for more information. Example: rotary@0 { compatible = "rotary-encoder"; gpios = <&gpio 19 1>, <&gpio 20 0>; /* GPIO19 is inverted */ linux,axis = <0>; /* REL_X */ rotary-encoder,relative-axis; }; rotary@1 { compatible = "rotary-encoder"; gpios = <&gpio 21 0>, <&gpio 22 0>; linux,axis = <1>; /* ABS_Y */ rotary-encoder,steps = <24>; rotary-encoder,rollover; }; drivers/input/ff-memless.c +8 −6 Original line number Diff line number Diff line Loading @@ -74,8 +74,10 @@ static const struct ff_envelope *get_envelope(const struct ff_effect *effect) switch (effect->type) { case FF_PERIODIC: return &effect->u.periodic.envelope; case FF_CONSTANT: return &effect->u.constant.envelope; default: return &empty_envelope; } Loading drivers/input/input.c +26 −17 Original line number Diff line number Diff line Loading @@ -844,18 +844,10 @@ int input_set_keycode(struct input_dev *dev, } EXPORT_SYMBOL(input_set_keycode); #define MATCH_BIT(bit, max) \ for (i = 0; i < BITS_TO_LONGS(max); i++) \ if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \ break; \ if (i != BITS_TO_LONGS(max)) \ continue; static const struct input_device_id *input_match_device(struct input_handler *handler, struct input_dev *dev) { const struct input_device_id *id; int i; for (id = handler->id_table; id->flags || id->driver_info; id++) { Loading @@ -875,15 +867,32 @@ static const struct input_device_id *input_match_device(struct input_handler *ha if (id->version != dev->id.version) continue; MATCH_BIT(evbit, EV_MAX); MATCH_BIT(keybit, KEY_MAX); MATCH_BIT(relbit, REL_MAX); MATCH_BIT(absbit, ABS_MAX); MATCH_BIT(mscbit, MSC_MAX); MATCH_BIT(ledbit, LED_MAX); MATCH_BIT(sndbit, SND_MAX); MATCH_BIT(ffbit, FF_MAX); MATCH_BIT(swbit, SW_MAX); if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX)) continue; if (!bitmap_subset(id->keybit, dev->keybit, KEY_MAX)) continue; if (!bitmap_subset(id->relbit, dev->relbit, REL_MAX)) continue; if (!bitmap_subset(id->absbit, dev->absbit, ABS_MAX)) continue; if (!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX)) continue; if (!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX)) continue; if (!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX)) continue; if (!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX)) continue; if (!bitmap_subset(id->swbit, dev->swbit, SW_MAX)) continue; if (!handler->match || handler->match(handler, dev)) return id; Loading drivers/input/keyboard/gpio_keys.c +88 −81 Original line number Diff line number Diff line Loading @@ -43,11 +43,9 @@ struct gpio_button_data { }; struct gpio_keys_drvdata { const struct gpio_keys_platform_data *pdata; struct input_dev *input; struct mutex disable_lock; unsigned int n_buttons; int (*enable)(struct device *dev); void (*disable)(struct device *dev); struct gpio_button_data data[0]; }; Loading Loading @@ -171,7 +169,7 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata, if (!bits) return -ENOMEM; for (i = 0; i < ddata->n_buttons; i++) { for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; if (bdata->button->type != type) Loading Loading @@ -219,7 +217,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, goto out; /* First validate */ for (i = 0; i < ddata->n_buttons; i++) { for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; if (bdata->button->type != type) Loading @@ -234,7 +232,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, mutex_lock(&ddata->disable_lock); for (i = 0; i < ddata->n_buttons; i++) { for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; if (bdata->button->type != type) Loading Loading @@ -346,6 +344,9 @@ static void gpio_keys_gpio_work_func(struct work_struct *work) container_of(work, struct gpio_button_data, work); gpio_keys_gpio_report_event(bdata); if (bdata->button->wakeup) pm_relax(bdata->input->dev.parent); } static void gpio_keys_gpio_timer(unsigned long _data) Loading @@ -361,6 +362,8 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) BUG_ON(irq != bdata->irq); if (bdata->button->wakeup) pm_stay_awake(bdata->input->dev.parent); if (bdata->timer_debounce) mod_timer(&bdata->timer, jiffies + msecs_to_jiffies(bdata->timer_debounce)); Loading Loading @@ -397,6 +400,9 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) spin_lock_irqsave(&bdata->lock, flags); if (!bdata->key_pressed) { if (bdata->button->wakeup) pm_wakeup_event(bdata->input->dev.parent, 0); input_event(input, EV_KEY, button->code, 1); input_sync(input); Loading Loading @@ -523,56 +529,64 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev, static int gpio_keys_open(struct input_dev *input) { struct gpio_keys_drvdata *ddata = input_get_drvdata(input); const struct gpio_keys_platform_data *pdata = ddata->pdata; return ddata->enable ? ddata->enable(input->dev.parent) : 0; return pdata->enable ? pdata->enable(input->dev.parent) : 0; } static void gpio_keys_close(struct input_dev *input) { struct gpio_keys_drvdata *ddata = input_get_drvdata(input); const struct gpio_keys_platform_data *pdata = ddata->pdata; if (ddata->disable) ddata->disable(input->dev.parent); if (pdata->disable) pdata->disable(input->dev.parent); } /* * Handlers for alternative sources of platform_data */ #ifdef CONFIG_OF /* * Translate OpenFirmware node properties into platform_data */ static int gpio_keys_get_devtree_pdata(struct device *dev, struct gpio_keys_platform_data *pdata) static struct gpio_keys_platform_data * __devinit gpio_keys_get_devtree_pdata(struct device *dev) { struct device_node *node, *pp; struct gpio_keys_platform_data *pdata; struct gpio_keys_button *button; int error; int nbuttons; int i; struct gpio_keys_button *buttons; u32 reg; node = dev->of_node; if (node == NULL) return -ENODEV; memset(pdata, 0, sizeof *pdata); if (!node) { error = -ENODEV; goto err_out; } pdata->rep = !!of_get_property(node, "autorepeat", NULL); nbuttons = of_get_child_count(node); if (nbuttons == 0) { error = -ENODEV; goto err_out; } /* First count the subnodes */ pp = NULL; while ((pp = of_get_next_child(node, pp))) pdata->nbuttons++; pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button), GFP_KERNEL); if (!pdata) { error = -ENOMEM; goto err_out; } if (pdata->nbuttons == 0) return -ENODEV; pdata->buttons = (struct gpio_keys_button *)(pdata + 1); pdata->nbuttons = nbuttons; buttons = kzalloc(pdata->nbuttons * (sizeof *buttons), GFP_KERNEL); if (!buttons) return -ENOMEM; pdata->rep = !!of_get_property(node, "autorepeat", NULL); pp = NULL; i = 0; while ((pp = of_get_next_child(node, pp))) { for_each_child_of_node(node, pp) { enum of_gpio_flags flags; if (!of_find_property(pp, "gpios", NULL)) { Loading @@ -580,39 +594,42 @@ static int gpio_keys_get_devtree_pdata(struct device *dev, dev_warn(dev, "Found button without gpios\n"); continue; } buttons[i].gpio = of_get_gpio_flags(pp, 0, &flags); buttons[i].active_low = flags & OF_GPIO_ACTIVE_LOW; if (of_property_read_u32(pp, "linux,code", ®)) { dev_err(dev, "Button without keycode: 0x%x\n", buttons[i].gpio); goto out_fail; } buttons[i].code = reg; button = &pdata->buttons[i++]; buttons[i].desc = of_get_property(pp, "label", NULL); button->gpio = of_get_gpio_flags(pp, 0, &flags); button->active_low = flags & OF_GPIO_ACTIVE_LOW; if (of_property_read_u32(pp, "linux,input-type", ®) == 0) buttons[i].type = reg; else buttons[i].type = EV_KEY; if (of_property_read_u32(pp, "linux,code", &button->code)) { dev_err(dev, "Button without keycode: 0x%x\n", button->gpio); error = -EINVAL; goto err_free_pdata; } buttons[i].wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); button->desc = of_get_property(pp, "label", NULL); if (of_property_read_u32(pp, "debounce-interval", ®) == 0) buttons[i].debounce_interval = reg; else buttons[i].debounce_interval = 5; if (of_property_read_u32(pp, "linux,input-type", &button->type)) button->type = EV_KEY; button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); i++; if (of_property_read_u32(pp, "debounce-interval", &button->debounce_interval)) button->debounce_interval = 5; } pdata->buttons = buttons; if (pdata->nbuttons == 0) { error = -EINVAL; goto err_free_pdata; } return 0; return pdata; out_fail: kfree(buttons); return -ENODEV; err_free_pdata: kfree(pdata); err_out: return ERR_PTR(error); } static struct of_device_id gpio_keys_of_match[] = { Loading @@ -623,14 +640,12 @@ MODULE_DEVICE_TABLE(of, gpio_keys_of_match); #else static int gpio_keys_get_devtree_pdata(struct device *dev, struct gpio_keys_platform_data *altp) static inline struct gpio_keys_platform_data * gpio_keys_get_devtree_pdata(struct device *dev) { return -ENODEV; return ERR_PTR(-ENODEV); } #define gpio_keys_of_match NULL #endif static void gpio_remove_key(struct gpio_button_data *bdata) Loading @@ -645,19 +660,17 @@ static void gpio_remove_key(struct gpio_button_data *bdata) static int __devinit gpio_keys_probe(struct platform_device *pdev) { const struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; struct gpio_keys_drvdata *ddata; struct device *dev = &pdev->dev; struct gpio_keys_platform_data alt_pdata; const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); struct gpio_keys_drvdata *ddata; struct input_dev *input; int i, error; int wakeup = 0; if (!pdata) { error = gpio_keys_get_devtree_pdata(dev, &alt_pdata); if (error) return error; pdata = &alt_pdata; pdata = gpio_keys_get_devtree_pdata(dev); if (IS_ERR(pdata)) return PTR_ERR(pdata); } ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + Loading @@ -670,10 +683,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) goto fail1; } ddata->pdata = pdata; ddata->input = input; ddata->n_buttons = pdata->nbuttons; ddata->enable = pdata->enable; ddata->disable = pdata->disable; mutex_init(&ddata->disable_lock); platform_set_drvdata(pdev, ddata); Loading Loading @@ -742,9 +753,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) fail1: input_free_device(input); kfree(ddata); /* If we have no platform_data, we allocated buttons dynamically. */ if (!pdev->dev.platform_data) kfree(pdata->buttons); /* If we have no platform data, we allocated pdata dynamically. */ if (!dev_get_platdata(&pdev->dev)) kfree(pdata); return error; } Loading @@ -759,18 +770,14 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); for (i = 0; i < ddata->n_buttons; i++) for (i = 0; i < ddata->pdata->nbuttons; i++) gpio_remove_key(&ddata->data[i]); input_unregister_device(input); /* * If we had no platform_data, we allocated buttons dynamically, and * must free them here. ddata->data[0].button is the pointer to the * beginning of the allocated array. */ if (!pdev->dev.platform_data) kfree(ddata->data[0].button); /* If we have no platform data, we allocated pdata dynamically. */ if (!dev_get_platdata(&pdev->dev)) kfree(ddata->pdata); kfree(ddata); Loading @@ -784,7 +791,7 @@ static int gpio_keys_suspend(struct device *dev) int i; if (device_may_wakeup(dev)) { for (i = 0; i < ddata->n_buttons; i++) { for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; if (bdata->button->wakeup) enable_irq_wake(bdata->irq); Loading @@ -799,7 +806,7 @@ static int gpio_keys_resume(struct device *dev) struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); int i; for (i = 0; i < ddata->n_buttons; i++) { for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; if (bdata->button->wakeup && device_may_wakeup(dev)) disable_irq_wake(bdata->irq); Loading @@ -822,7 +829,7 @@ static struct platform_driver gpio_keys_device_driver = { .name = "gpio-keys", .owner = THIS_MODULE, .pm = &gpio_keys_pm_ops, .of_match_table = gpio_keys_of_match, .of_match_table = of_match_ptr(gpio_keys_of_match), } }; Loading Loading
Documentation/devicetree/bindings/input/gpio-keys-polled.txt 0 → 100644 +38 −0 Original line number Diff line number Diff line Device-Tree bindings for input/gpio_keys_polled.c keyboard driver Required properties: - compatible = "gpio-keys-polled"; - poll-interval: Poll interval time in milliseconds Optional properties: - autorepeat: Boolean, Enable auto repeat feature of Linux input subsystem. Each button (key) is represented as a sub-node of "gpio-keys-polled": Subnode properties: - gpios: OF device-tree gpio specification. - label: Descriptive name of the key. - linux,code: Keycode to emit. Optional subnode-properties: - linux,input-type: Specify event type this button/key generates. If not specified defaults to <1> == EV_KEY. - debounce-interval: Debouncing interval time in milliseconds. If not specified defaults to 5. - gpio-key,wakeup: Boolean, button can wake-up the system. Example nodes: gpio_keys_polled { compatible = "gpio-keys-polled"; #address-cells = <1>; #size-cells = <0>; poll-interval = <100>; autorepeat; button@21 { label = "GPIO Key UP"; linux,code = <103>; gpios = <&gpio1 0 1>; }; ...
Documentation/devicetree/bindings/input/rotary-encoder.txt 0 → 100644 +36 −0 Original line number Diff line number Diff line Rotary encoder DT bindings Required properties: - gpios: a spec for two GPIOs to be used Optional properties: - linux,axis: the input subsystem axis to map to this rotary encoder. Defaults to 0 (ABS_X / REL_X) - rotary-encoder,steps: Number of steps in a full turnaround of the encoder. Only relevant for absolute axis. Defaults to 24 which is a typical value for such devices. - rotary-encoder,relative-axis: register a relative axis rather than an absolute one. Relative axis will only generate +1/-1 events on the input device, hence no steps need to be passed. - rotary-encoder,rollover: Automatic rollove when the rotary value becomes greater than the specified steps or smaller than 0. For absolute axis only. - rotary-encoder,half-period: Makes the driver work on half-period mode. See Documentation/input/rotary-encoder.txt for more information. Example: rotary@0 { compatible = "rotary-encoder"; gpios = <&gpio 19 1>, <&gpio 20 0>; /* GPIO19 is inverted */ linux,axis = <0>; /* REL_X */ rotary-encoder,relative-axis; }; rotary@1 { compatible = "rotary-encoder"; gpios = <&gpio 21 0>, <&gpio 22 0>; linux,axis = <1>; /* ABS_Y */ rotary-encoder,steps = <24>; rotary-encoder,rollover; };
drivers/input/ff-memless.c +8 −6 Original line number Diff line number Diff line Loading @@ -74,8 +74,10 @@ static const struct ff_envelope *get_envelope(const struct ff_effect *effect) switch (effect->type) { case FF_PERIODIC: return &effect->u.periodic.envelope; case FF_CONSTANT: return &effect->u.constant.envelope; default: return &empty_envelope; } Loading
drivers/input/input.c +26 −17 Original line number Diff line number Diff line Loading @@ -844,18 +844,10 @@ int input_set_keycode(struct input_dev *dev, } EXPORT_SYMBOL(input_set_keycode); #define MATCH_BIT(bit, max) \ for (i = 0; i < BITS_TO_LONGS(max); i++) \ if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \ break; \ if (i != BITS_TO_LONGS(max)) \ continue; static const struct input_device_id *input_match_device(struct input_handler *handler, struct input_dev *dev) { const struct input_device_id *id; int i; for (id = handler->id_table; id->flags || id->driver_info; id++) { Loading @@ -875,15 +867,32 @@ static const struct input_device_id *input_match_device(struct input_handler *ha if (id->version != dev->id.version) continue; MATCH_BIT(evbit, EV_MAX); MATCH_BIT(keybit, KEY_MAX); MATCH_BIT(relbit, REL_MAX); MATCH_BIT(absbit, ABS_MAX); MATCH_BIT(mscbit, MSC_MAX); MATCH_BIT(ledbit, LED_MAX); MATCH_BIT(sndbit, SND_MAX); MATCH_BIT(ffbit, FF_MAX); MATCH_BIT(swbit, SW_MAX); if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX)) continue; if (!bitmap_subset(id->keybit, dev->keybit, KEY_MAX)) continue; if (!bitmap_subset(id->relbit, dev->relbit, REL_MAX)) continue; if (!bitmap_subset(id->absbit, dev->absbit, ABS_MAX)) continue; if (!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX)) continue; if (!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX)) continue; if (!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX)) continue; if (!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX)) continue; if (!bitmap_subset(id->swbit, dev->swbit, SW_MAX)) continue; if (!handler->match || handler->match(handler, dev)) return id; Loading
drivers/input/keyboard/gpio_keys.c +88 −81 Original line number Diff line number Diff line Loading @@ -43,11 +43,9 @@ struct gpio_button_data { }; struct gpio_keys_drvdata { const struct gpio_keys_platform_data *pdata; struct input_dev *input; struct mutex disable_lock; unsigned int n_buttons; int (*enable)(struct device *dev); void (*disable)(struct device *dev); struct gpio_button_data data[0]; }; Loading Loading @@ -171,7 +169,7 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata, if (!bits) return -ENOMEM; for (i = 0; i < ddata->n_buttons; i++) { for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; if (bdata->button->type != type) Loading Loading @@ -219,7 +217,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, goto out; /* First validate */ for (i = 0; i < ddata->n_buttons; i++) { for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; if (bdata->button->type != type) Loading @@ -234,7 +232,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata, mutex_lock(&ddata->disable_lock); for (i = 0; i < ddata->n_buttons; i++) { for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; if (bdata->button->type != type) Loading Loading @@ -346,6 +344,9 @@ static void gpio_keys_gpio_work_func(struct work_struct *work) container_of(work, struct gpio_button_data, work); gpio_keys_gpio_report_event(bdata); if (bdata->button->wakeup) pm_relax(bdata->input->dev.parent); } static void gpio_keys_gpio_timer(unsigned long _data) Loading @@ -361,6 +362,8 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) BUG_ON(irq != bdata->irq); if (bdata->button->wakeup) pm_stay_awake(bdata->input->dev.parent); if (bdata->timer_debounce) mod_timer(&bdata->timer, jiffies + msecs_to_jiffies(bdata->timer_debounce)); Loading Loading @@ -397,6 +400,9 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) spin_lock_irqsave(&bdata->lock, flags); if (!bdata->key_pressed) { if (bdata->button->wakeup) pm_wakeup_event(bdata->input->dev.parent, 0); input_event(input, EV_KEY, button->code, 1); input_sync(input); Loading Loading @@ -523,56 +529,64 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev, static int gpio_keys_open(struct input_dev *input) { struct gpio_keys_drvdata *ddata = input_get_drvdata(input); const struct gpio_keys_platform_data *pdata = ddata->pdata; return ddata->enable ? ddata->enable(input->dev.parent) : 0; return pdata->enable ? pdata->enable(input->dev.parent) : 0; } static void gpio_keys_close(struct input_dev *input) { struct gpio_keys_drvdata *ddata = input_get_drvdata(input); const struct gpio_keys_platform_data *pdata = ddata->pdata; if (ddata->disable) ddata->disable(input->dev.parent); if (pdata->disable) pdata->disable(input->dev.parent); } /* * Handlers for alternative sources of platform_data */ #ifdef CONFIG_OF /* * Translate OpenFirmware node properties into platform_data */ static int gpio_keys_get_devtree_pdata(struct device *dev, struct gpio_keys_platform_data *pdata) static struct gpio_keys_platform_data * __devinit gpio_keys_get_devtree_pdata(struct device *dev) { struct device_node *node, *pp; struct gpio_keys_platform_data *pdata; struct gpio_keys_button *button; int error; int nbuttons; int i; struct gpio_keys_button *buttons; u32 reg; node = dev->of_node; if (node == NULL) return -ENODEV; memset(pdata, 0, sizeof *pdata); if (!node) { error = -ENODEV; goto err_out; } pdata->rep = !!of_get_property(node, "autorepeat", NULL); nbuttons = of_get_child_count(node); if (nbuttons == 0) { error = -ENODEV; goto err_out; } /* First count the subnodes */ pp = NULL; while ((pp = of_get_next_child(node, pp))) pdata->nbuttons++; pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button), GFP_KERNEL); if (!pdata) { error = -ENOMEM; goto err_out; } if (pdata->nbuttons == 0) return -ENODEV; pdata->buttons = (struct gpio_keys_button *)(pdata + 1); pdata->nbuttons = nbuttons; buttons = kzalloc(pdata->nbuttons * (sizeof *buttons), GFP_KERNEL); if (!buttons) return -ENOMEM; pdata->rep = !!of_get_property(node, "autorepeat", NULL); pp = NULL; i = 0; while ((pp = of_get_next_child(node, pp))) { for_each_child_of_node(node, pp) { enum of_gpio_flags flags; if (!of_find_property(pp, "gpios", NULL)) { Loading @@ -580,39 +594,42 @@ static int gpio_keys_get_devtree_pdata(struct device *dev, dev_warn(dev, "Found button without gpios\n"); continue; } buttons[i].gpio = of_get_gpio_flags(pp, 0, &flags); buttons[i].active_low = flags & OF_GPIO_ACTIVE_LOW; if (of_property_read_u32(pp, "linux,code", ®)) { dev_err(dev, "Button without keycode: 0x%x\n", buttons[i].gpio); goto out_fail; } buttons[i].code = reg; button = &pdata->buttons[i++]; buttons[i].desc = of_get_property(pp, "label", NULL); button->gpio = of_get_gpio_flags(pp, 0, &flags); button->active_low = flags & OF_GPIO_ACTIVE_LOW; if (of_property_read_u32(pp, "linux,input-type", ®) == 0) buttons[i].type = reg; else buttons[i].type = EV_KEY; if (of_property_read_u32(pp, "linux,code", &button->code)) { dev_err(dev, "Button without keycode: 0x%x\n", button->gpio); error = -EINVAL; goto err_free_pdata; } buttons[i].wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); button->desc = of_get_property(pp, "label", NULL); if (of_property_read_u32(pp, "debounce-interval", ®) == 0) buttons[i].debounce_interval = reg; else buttons[i].debounce_interval = 5; if (of_property_read_u32(pp, "linux,input-type", &button->type)) button->type = EV_KEY; button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); i++; if (of_property_read_u32(pp, "debounce-interval", &button->debounce_interval)) button->debounce_interval = 5; } pdata->buttons = buttons; if (pdata->nbuttons == 0) { error = -EINVAL; goto err_free_pdata; } return 0; return pdata; out_fail: kfree(buttons); return -ENODEV; err_free_pdata: kfree(pdata); err_out: return ERR_PTR(error); } static struct of_device_id gpio_keys_of_match[] = { Loading @@ -623,14 +640,12 @@ MODULE_DEVICE_TABLE(of, gpio_keys_of_match); #else static int gpio_keys_get_devtree_pdata(struct device *dev, struct gpio_keys_platform_data *altp) static inline struct gpio_keys_platform_data * gpio_keys_get_devtree_pdata(struct device *dev) { return -ENODEV; return ERR_PTR(-ENODEV); } #define gpio_keys_of_match NULL #endif static void gpio_remove_key(struct gpio_button_data *bdata) Loading @@ -645,19 +660,17 @@ static void gpio_remove_key(struct gpio_button_data *bdata) static int __devinit gpio_keys_probe(struct platform_device *pdev) { const struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; struct gpio_keys_drvdata *ddata; struct device *dev = &pdev->dev; struct gpio_keys_platform_data alt_pdata; const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); struct gpio_keys_drvdata *ddata; struct input_dev *input; int i, error; int wakeup = 0; if (!pdata) { error = gpio_keys_get_devtree_pdata(dev, &alt_pdata); if (error) return error; pdata = &alt_pdata; pdata = gpio_keys_get_devtree_pdata(dev); if (IS_ERR(pdata)) return PTR_ERR(pdata); } ddata = kzalloc(sizeof(struct gpio_keys_drvdata) + Loading @@ -670,10 +683,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) goto fail1; } ddata->pdata = pdata; ddata->input = input; ddata->n_buttons = pdata->nbuttons; ddata->enable = pdata->enable; ddata->disable = pdata->disable; mutex_init(&ddata->disable_lock); platform_set_drvdata(pdev, ddata); Loading Loading @@ -742,9 +753,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) fail1: input_free_device(input); kfree(ddata); /* If we have no platform_data, we allocated buttons dynamically. */ if (!pdev->dev.platform_data) kfree(pdata->buttons); /* If we have no platform data, we allocated pdata dynamically. */ if (!dev_get_platdata(&pdev->dev)) kfree(pdata); return error; } Loading @@ -759,18 +770,14 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); for (i = 0; i < ddata->n_buttons; i++) for (i = 0; i < ddata->pdata->nbuttons; i++) gpio_remove_key(&ddata->data[i]); input_unregister_device(input); /* * If we had no platform_data, we allocated buttons dynamically, and * must free them here. ddata->data[0].button is the pointer to the * beginning of the allocated array. */ if (!pdev->dev.platform_data) kfree(ddata->data[0].button); /* If we have no platform data, we allocated pdata dynamically. */ if (!dev_get_platdata(&pdev->dev)) kfree(ddata->pdata); kfree(ddata); Loading @@ -784,7 +791,7 @@ static int gpio_keys_suspend(struct device *dev) int i; if (device_may_wakeup(dev)) { for (i = 0; i < ddata->n_buttons; i++) { for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; if (bdata->button->wakeup) enable_irq_wake(bdata->irq); Loading @@ -799,7 +806,7 @@ static int gpio_keys_resume(struct device *dev) struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev); int i; for (i = 0; i < ddata->n_buttons; i++) { for (i = 0; i < ddata->pdata->nbuttons; i++) { struct gpio_button_data *bdata = &ddata->data[i]; if (bdata->button->wakeup && device_may_wakeup(dev)) disable_irq_wake(bdata->irq); Loading @@ -822,7 +829,7 @@ static struct platform_driver gpio_keys_device_driver = { .name = "gpio-keys", .owner = THIS_MODULE, .pm = &gpio_keys_pm_ops, .of_match_table = gpio_keys_of_match, .of_match_table = of_match_ptr(gpio_keys_of_match), } }; Loading