cobalt_btns.c (d0a0515fc30b55d4b09395d44762c5f41d6d02d5) | cobalt_btns.c (3d29cdff999c37b3876082278a8134a0642a02cd) |
---|---|
1/* 2 * Cobalt button interface driver. 3 * 4 * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 4 unchanged lines hidden (view full) --- 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20#include <linux/init.h> | 1/* 2 * Cobalt button interface driver. 3 * 4 * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 4 unchanged lines hidden (view full) --- 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20#include <linux/init.h> |
21#include <linux/input.h> | 21#include <linux/input-polldev.h> |
22#include <linux/ioport.h> 23#include <linux/module.h> 24#include <linux/platform_device.h> | 22#include <linux/ioport.h> 23#include <linux/module.h> 24#include <linux/platform_device.h> |
25#include <linux/jiffies.h> 26#include <linux/timer.h> | |
27 28#define BUTTONS_POLL_INTERVAL 30 /* msec */ 29#define BUTTONS_COUNT_THRESHOLD 3 30#define BUTTONS_STATUS_MASK 0xfe000000 31 32struct buttons_dev { | 25 26#define BUTTONS_POLL_INTERVAL 30 /* msec */ 27#define BUTTONS_COUNT_THRESHOLD 3 28#define BUTTONS_STATUS_MASK 0xfe000000 29 30struct buttons_dev { |
33 struct input_dev *input; | 31 struct input_polled_dev *poll_dev; |
34 void __iomem *reg; 35}; 36 37struct buttons_map { 38 uint32_t mask; 39 int keycode; 40 int count; 41}; 42 43static struct buttons_map buttons_map[] = { 44 { 0x02000000, KEY_RESTART, }, 45 { 0x04000000, KEY_LEFT, }, 46 { 0x08000000, KEY_UP, }, 47 { 0x10000000, KEY_DOWN, }, 48 { 0x20000000, KEY_RIGHT, }, 49 { 0x40000000, KEY_ENTER, }, 50 { 0x80000000, KEY_SELECT, }, 51}; 52 | 32 void __iomem *reg; 33}; 34 35struct buttons_map { 36 uint32_t mask; 37 int keycode; 38 int count; 39}; 40 41static struct buttons_map buttons_map[] = { 42 { 0x02000000, KEY_RESTART, }, 43 { 0x04000000, KEY_LEFT, }, 44 { 0x08000000, KEY_UP, }, 45 { 0x10000000, KEY_DOWN, }, 46 { 0x20000000, KEY_RIGHT, }, 47 { 0x40000000, KEY_ENTER, }, 48 { 0x80000000, KEY_SELECT, }, 49}; 50 |
53static struct timer_list buttons_timer; 54 55static void handle_buttons(unsigned long data) | 51static void handle_buttons(struct input_polled_dev *dev) |
56{ 57 struct buttons_map *button = buttons_map; | 52{ 53 struct buttons_map *button = buttons_map; |
58 struct buttons_dev *bdev; | 54 struct buttons_dev *bdev = dev->private; 55 struct input_dev *input = dev->input; |
59 uint32_t status; 60 int i; 61 | 56 uint32_t status; 57 int i; 58 |
62 bdev = (struct buttons_dev *)data; | |
63 status = readl(bdev->reg); 64 status = ~status & BUTTONS_STATUS_MASK; 65 66 for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { 67 if (status & button->mask) { 68 button->count++; 69 } else { 70 if (button->count >= BUTTONS_COUNT_THRESHOLD) { | 59 status = readl(bdev->reg); 60 status = ~status & BUTTONS_STATUS_MASK; 61 62 for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { 63 if (status & button->mask) { 64 button->count++; 65 } else { 66 if (button->count >= BUTTONS_COUNT_THRESHOLD) { |
71 input_report_key(bdev->input, button->keycode, 0); 72 input_sync(bdev->input); | 67 input_report_key(input, button->keycode, 0); 68 input_sync(input); |
73 } 74 button->count = 0; 75 } 76 77 if (button->count == BUTTONS_COUNT_THRESHOLD) { | 69 } 70 button->count = 0; 71 } 72 73 if (button->count == BUTTONS_COUNT_THRESHOLD) { |
78 input_report_key(bdev->input, button->keycode, 1); 79 input_sync(bdev->input); | 74 input_report_key(input, button->keycode, 1); 75 input_sync(input); |
80 } 81 82 button++; 83 } | 76 } 77 78 button++; 79 } |
84 85 mod_timer(&buttons_timer, jiffies + msecs_to_jiffies(BUTTONS_POLL_INTERVAL)); | |
86} 87 | 80} 81 |
88static int cobalt_buttons_open(struct input_dev *dev) 89{ 90 mod_timer(&buttons_timer, jiffies + msecs_to_jiffies(BUTTONS_POLL_INTERVAL)); 91 92 return 0; 93} 94 95static void cobalt_buttons_close(struct input_dev *dev) 96{ 97 del_timer_sync(&buttons_timer); 98} 99 | |
100static int __devinit cobalt_buttons_probe(struct platform_device *pdev) 101{ 102 struct buttons_dev *bdev; | 82static int __devinit cobalt_buttons_probe(struct platform_device *pdev) 83{ 84 struct buttons_dev *bdev; |
85 struct input_polled_dev *poll_dev; |
|
103 struct input_dev *input; 104 struct resource *res; 105 int error, i; 106 107 bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL); | 86 struct input_dev *input; 87 struct resource *res; 88 int error, i; 89 90 bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL); |
108 input = input_allocate_device(); 109 if (!bdev || !input) { | 91 poll_dev = input_allocate_polled_device(); 92 if (!bdev || !poll_dev) { |
110 error = -ENOMEM; 111 goto err_free_mem; 112 } 113 | 93 error = -ENOMEM; 94 goto err_free_mem; 95 } 96 |
97 poll_dev->private = bdev; 98 poll_dev->poll = handle_buttons; 99 poll_dev->poll_interval = BUTTONS_POLL_INTERVAL; 100 101 input = poll_dev->input; |
|
114 input->name = "Cobalt buttons"; 115 input->phys = "cobalt/input0"; 116 input->id.bustype = BUS_HOST; 117 input->cdev.dev = &pdev->dev; | 102 input->name = "Cobalt buttons"; 103 input->phys = "cobalt/input0"; 104 input->id.bustype = BUS_HOST; 105 input->cdev.dev = &pdev->dev; |
118 input->open = cobalt_buttons_open; 119 input->close = cobalt_buttons_close; | |
120 121 input->evbit[0] = BIT(EV_KEY); 122 for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { 123 set_bit(buttons_map[i].keycode, input->keybit); 124 buttons_map[i].count = 0; 125 } 126 127 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 128 if (!res) { 129 error = -EBUSY; 130 goto err_free_mem; 131 } 132 | 106 107 input->evbit[0] = BIT(EV_KEY); 108 for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { 109 set_bit(buttons_map[i].keycode, input->keybit); 110 buttons_map[i].count = 0; 111 } 112 113 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 114 if (!res) { 115 error = -EBUSY; 116 goto err_free_mem; 117 } 118 |
133 bdev->input = input; | 119 bdev->poll_dev = poll_dev; |
134 bdev->reg = ioremap(res->start, res->end - res->start + 1); 135 dev_set_drvdata(&pdev->dev, bdev); 136 | 120 bdev->reg = ioremap(res->start, res->end - res->start + 1); 121 dev_set_drvdata(&pdev->dev, bdev); 122 |
137 setup_timer(&buttons_timer, handle_buttons, (unsigned long)bdev); 138 139 error = input_register_device(input); | 123 error = input_register_polled_device(poll_dev); |
140 if (error) 141 goto err_iounmap; 142 143 return 0; 144 145 err_iounmap: 146 iounmap(bdev->reg); 147 err_free_mem: | 124 if (error) 125 goto err_iounmap; 126 127 return 0; 128 129 err_iounmap: 130 iounmap(bdev->reg); 131 err_free_mem: |
148 input_free_device(input); | 132 input_free_polled_device(poll_dev); |
149 kfree(bdev); 150 dev_set_drvdata(&pdev->dev, NULL); 151 return error; 152} 153 154static int __devexit cobalt_buttons_remove(struct platform_device *pdev) 155{ 156 struct device *dev = &pdev->dev; 157 struct buttons_dev *bdev = dev_get_drvdata(dev); 158 | 133 kfree(bdev); 134 dev_set_drvdata(&pdev->dev, NULL); 135 return error; 136} 137 138static int __devexit cobalt_buttons_remove(struct platform_device *pdev) 139{ 140 struct device *dev = &pdev->dev; 141 struct buttons_dev *bdev = dev_get_drvdata(dev); 142 |
159 input_unregister_device(bdev->input); | 143 input_unregister_polled_device(bdev->poll_dev); 144 input_free_polled_device(bdev->poll_dev); |
160 iounmap(bdev->reg); 161 kfree(bdev); 162 dev_set_drvdata(dev, NULL); 163 164 return 0; 165} 166 167static struct platform_driver cobalt_buttons_driver = { --- 20 unchanged lines hidden --- | 145 iounmap(bdev->reg); 146 kfree(bdev); 147 dev_set_drvdata(dev, NULL); 148 149 return 0; 150} 151 152static struct platform_driver cobalt_buttons_driver = { --- 20 unchanged lines hidden --- |