[arm] tegra:cardhu: Configuration for all possible keypads
[linux-2.6.git] / arch / arm / mach-tegra / board-cardhu-kbc.c
1 /*
2  * arch/arm/mach-tegra/board-cardhu-kbc.c
3  * Keys configuration for Nvidia tegra3 cardhu platform.
4  *
5  * Copyright (C) 2011 NVIDIA, Inc.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
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., 59 Temple Place, Suite 330, Boston, MA
19  * 02111-1307, USA
20  */
21
22 #include <linux/kernel.h>
23 #include <linux/platform_device.h>
24 #include <linux/input.h>
25 #include <linux/device.h>
26 #include <linux/gpio.h>
27 #include <linux/gpio_keys.h>
28 #include <linux/gpio_scrollwheel.h>
29
30 #include <mach/irqs.h>
31 #include <mach/io.h>
32 #include <mach/iomap.h>
33 #include <mach/kbc.h>
34
35 #include "gpio-names.h"
36
37 #ifdef CONFIG_KEYBOARD_TEGRA
38 #ifdef CONFIG_INPUT_ALPS_GPIO_SCROLLWHEEL
39 #define CARDHU_ROW_COUNT        3
40 #define CARDHU_COL_COUNT        2
41 #else
42 #define CARDHU_ROW_COUNT        4
43 #define CARDHU_COL_COUNT        6
44 #endif
45
46 #ifdef CONFIG_INPUT_ALPS_GPIO_SCROLLWHEEL
47 static int plain_kbd_keycode[] = {
48         KEY_POWER,      KEY_RESERVED,
49         KEY_HOME,       KEY_BACK,
50         KEY_RESERVED,   KEY_RESERVED,
51 };
52 #else
53 static int plain_kbd_keycode[] = {
54         KEY_POWER,      KEY_RESERVED,   KEY_RESERVED,   KEY_RESERVED,
55                         KEY_RESERVED,   KEY_RESERVED,   KEY_RESERVED,
56         KEY_HOME,       KEY_BACK,       KEY_RESERVED,   KEY_RESERVED,
57                         KEY_RESERVED,   KEY_RESERVED,   KEY_RESERVED,
58         KEY_CAMERA,     KEY_CAMERA,     KEY_RESERVED,   KEY_RESERVED,
59                         KEY_RESERVED,   KEY_RESERVED,   KEY_RESERVED,
60         KEY_VOLUMEDOWN, KEY_VOLUMEUP,   KEY_RESERVED,   KEY_RESERVED,
61                         KEY_RESERVED,   KEY_RESERVED,   KEY_PAUSE,
62         KEY_END,        KEY_BACK,       KEY_RESERVED,   KEY_RESERVED,
63                         KEY_RESERVED,   KEY_PLAY,       KEY_PHONE,
64 };
65 #endif
66 static struct tegra_kbc_wake_key cardhu_wake_cfg[] = {
67         [0] = {
68                 .row = 0,
69                 .col = 0,
70         },
71 };
72
73 static struct tegra_kbc_platform_data cardhu_kbc_platform_data = {
74         .debounce_cnt = 20,
75         .repeat_cnt = 50 * 32,
76         .scan_timeout_cnt = 3000 * 32,
77         .plain_keycode = plain_kbd_keycode,
78         .fn_keycode = NULL,
79         .is_filter_keys = false,
80         .is_wake_on_any_key = false,
81         .wake_key_cnt = 1,
82         .wake_cfg = &cardhu_wake_cfg[0],
83 };
84
85 static struct resource cardhu_kbc_resources[] = {
86         [0] = {
87                 .start = TEGRA_KBC_BASE,
88                 .end   = TEGRA_KBC_BASE + TEGRA_KBC_SIZE - 1,
89                 .flags = IORESOURCE_MEM,
90         },
91         [1] = {
92                 .start = INT_KBC,
93                 .end   = INT_KBC,
94                 .flags = IORESOURCE_IRQ,
95         },
96 };
97
98
99 struct platform_device cardhu_kbc_device = {
100         .name = "tegra-kbc",
101         .id = -1,
102         .dev = {
103                 .platform_data = &cardhu_kbc_platform_data,
104         },
105         .resource = cardhu_kbc_resources,
106         .num_resources = ARRAY_SIZE(cardhu_kbc_resources),
107 };
108
109 int __init cardhu_kbc_init(void)
110 {
111         struct tegra_kbc_platform_data *data = &cardhu_kbc_platform_data;
112         int i;
113
114         pr_info("KBC: cardhu_kbc_init\n");
115
116          /* Setup the pin configuration information. */
117         for (i = 0; i < KBC_MAX_GPIO; i++) {
118                 data->pin_cfg[i].num = 0;
119                 data->pin_cfg[i].pin_type = kbc_pin_unused;
120         }
121         for (i = 0; i < CARDHU_ROW_COUNT; i++) {
122                 data->pin_cfg[i].num = i;
123                 data->pin_cfg[i].pin_type = kbc_pin_row;
124         }
125
126         for (i = 0; i < CARDHU_COL_COUNT; i++) {
127                 data->pin_cfg[i + CARDHU_ROW_COUNT].num = i;
128                 data->pin_cfg[i + CARDHU_ROW_COUNT].pin_type = kbc_pin_col;
129         }
130         platform_device_register(&cardhu_kbc_device);
131         return 0;
132 }
133 #else
134 int __init cardhu_kbc_init(void)
135 {
136 }
137 #endif
138
139 #ifdef CONFIG_INPUT_ALPS_GPIO_SCROLLWHEEL
140 #define GPIO_SCROLL(_pinaction, _gpio, _desc)           \
141 {                                                       \
142         .pinaction = GPIO_SCROLLWHEEL_PIN_##_pinaction, \
143         .gpio = TEGRA_GPIO_##_gpio,                     \
144         .desc = _desc,                                  \
145         .active_low = 1,                                \
146         .debounce_interval = 2,                         \
147 }
148
149 static struct gpio_scrollwheel_button scroll_keys[] = {
150         [0] = GPIO_SCROLL(ONOFF, PR3, "sw_onoff"),
151         [1] = GPIO_SCROLL(PRESS, PQ5, "sw_press"),
152         [2] = GPIO_SCROLL(ROT1, PQ3, "sw_rot1"),
153         [3] = GPIO_SCROLL(ROT2, PQ4, "sw_rot2"),
154 };
155
156 static struct gpio_scrollwheel_platform_data cardhu_scroll_platform_data = {
157         .buttons = scroll_keys,
158         .nbuttons = ARRAY_SIZE(scroll_keys),
159 };
160
161 static struct platform_device cardhu_scroll_device = {
162         .name   = "alps-gpio-scrollwheel",
163         .id     = 0,
164         .dev    = {
165                 .platform_data = &cardhu_scroll_platform_data,
166         },
167 };
168
169 int __init cardhu_scroll_init(void)
170 {
171         int i;
172         /* Setting pins to gpio mode */
173         for (i = 0; i < ARRAY_SIZE(scroll_keys); i++)
174                 tegra_gpio_enable(scroll_keys[i].gpio);
175
176         platform_device_register(&cardhu_scroll_device);
177         return 0;
178 }
179 #else
180 int __init cardhu_scroll_init(void)
181 {
182         return 0;
183 }
184 #endif
185
186 #ifdef CONFIG_KEYBOARD_GPIO
187 #define GPIO_KEY(_id, _gpio, _iswake)           \
188         {                                       \
189                 .code = _id,                    \
190                 .gpio = TEGRA_GPIO_##_gpio,     \
191                 .active_low = 1,                \
192                 .desc = #_id,                   \
193                 .type = EV_KEY,                 \
194                 .wakeup = _iswake,              \
195                 .debounce_interval = 10,        \
196         }
197
198 static struct gpio_keys_button cardhu_keys[] = {
199         [0] = GPIO_KEY(KEY_HOME, PQ0, 0),
200         [1] = GPIO_KEY(KEY_MENU, PQ1, 0),
201         [2] = GPIO_KEY(KEY_SEARCH, PQ2, 0),
202         [3] = GPIO_KEY(KEY_BACK, PQ3, 0),
203         [4] = GPIO_KEY(KEY_VOLUMEUP, PR0, 0),
204         [5] = GPIO_KEY(KEY_VOLUMEDOWN, PR1, 0),
205         [6] = GPIO_KEY(KEY_POWER, PV0, 1),
206 };
207
208 static struct gpio_keys_platform_data cardhu_keys_platform_data = {
209         .buttons        = cardhu_keys,
210         .nbuttons       = ARRAY_SIZE(cardhu_keys),
211 };
212
213 static struct platform_device cardhu_keys_device = {
214         .name   = "gpio-keys",
215         .id     = 0,
216         .dev    = {
217                 .platform_data  = &cardhu_keys_platform_data,
218         },
219 };
220
221 int __init cardhu_keys_init(void)
222 {
223         int i;
224         int ret;
225
226         /* Set KB_ROW2 to 0 for capcitive switch to be in scan mode */
227         ret = gpio_request(TEGRA_GPIO_PR2, "cap_sw_sl_scan");
228         if (ret < 0) {
229                 pr_err("%s: gpio_request failed #%d\n",
230                                         __func__, TEGRA_GPIO_PR2);
231                 return ret;
232         }
233         ret = gpio_direction_output(TEGRA_GPIO_PR2, 0);
234         if (ret < 0) {
235                 pr_err("%s: gpio_direction_output failed #%d\n",
236                                         __func__, TEGRA_GPIO_PR2);
237                 gpio_free(TEGRA_GPIO_PR2);
238                 return ret;
239         }
240
241         tegra_gpio_enable(TEGRA_GPIO_PR2);
242
243         /* Enable gpio mode for other pins */
244         for (i = 0; i < ARRAY_SIZE(cardhu_keys); i++)
245                 tegra_gpio_enable(cardhu_keys[i].gpio);
246
247         platform_device_register(&cardhu_keys_device);
248         return 0;
249 }
250 #else
251 int __init cardhu_keys_init(void)
252 {
253         return 0;
254 }
255 #endif