666850368e2862115b63d25e5074677acb038652
[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/mfd/tps6591x.h>
29 #include <linux/interrupt_keys.h>
30 #include <linux/gpio_scrollwheel.h>
31
32 #include <mach/irqs.h>
33 #include <mach/io.h>
34 #include <mach/iomap.h>
35 #include <mach/kbc.h>
36 #include "board.h"
37 #include "board-cardhu.h"
38
39 #include "gpio-names.h"
40
41 #define CARDHU_ROW_COUNT        4
42 #define CARDHU_COL_COUNT        2
43 #define CARDHU_PM269_ROW_COUNT  2
44 #define CARDHU_PM269_COL_COUNT  4
45
46 #if 0
47 static int plain_kbd_keycode[] = {
48         KEY_POWER,      KEY_RESERVED,
49         KEY_HOME,       KEY_BACK,
50         KEY_CAMERA,     KEY_CAMERA,
51         KEY_VOLUMEDOWN, KEY_VOLUMEUP
52 };
53
54 static int plain_kbd_keycode_pm269[] = {
55         KEY_POWER,      KEY_RESERVED,
56         KEY_VOLUMEUP,   KEY_VOLUMEDOWN,
57         KEY_HOME,       KEY_MENU,
58         KEY_BACK,       KEY_SEARCH
59 };
60
61 static struct tegra_kbc_wake_key cardhu_wake_cfg[] = {
62         [0] = {
63                 .row = 0,
64                 .col = 0,
65         },
66 };
67
68 static struct tegra_kbc_platform_data cardhu_kbc_platform_data = {
69         .debounce_cnt = 20,
70         .repeat_cnt = 50 * 32,
71         .scan_timeout_cnt = 3000 * 32,
72         .plain_keycode = plain_kbd_keycode,
73         .fn_keycode = NULL,
74         .is_filter_keys = false,
75         .is_wake_on_any_key = false,
76         .wake_key_cnt = 1,
77         .wake_cfg = &cardhu_wake_cfg[0],
78 };
79
80 static struct resource cardhu_kbc_resources[] = {
81         [0] = {
82                 .start = TEGRA_KBC_BASE,
83                 .end   = TEGRA_KBC_BASE + TEGRA_KBC_SIZE - 1,
84                 .flags = IORESOURCE_MEM,
85         },
86         [1] = {
87                 .start = INT_KBC,
88                 .end   = INT_KBC,
89                 .flags = IORESOURCE_IRQ,
90         },
91 };
92
93 struct platform_device cardhu_kbc_device = {
94         .name = "tegra-kbc",
95         .id = -1,
96         .dev = {
97                 .platform_data = &cardhu_kbc_platform_data,
98         },
99         .resource = cardhu_kbc_resources,
100         .num_resources = ARRAY_SIZE(cardhu_kbc_resources),
101 };
102
103 int __init cardhu_kbc_init(void)
104 {
105         struct tegra_kbc_platform_data *data = &cardhu_kbc_platform_data;
106         int i;
107         struct board_info board_info;
108         int row_count = CARDHU_ROW_COUNT, col_count = CARDHU_COL_COUNT;
109
110         tegra_get_board_info(&board_info);
111
112         if ((board_info.board_id == BOARD_E1198) ||
113                         (board_info.board_id == BOARD_E1291))
114                 return 0;
115
116         if ((board_info.board_id == BOARD_PM269) ||
117                 (board_info.board_id == BOARD_PM305)) {
118                 cardhu_kbc_platform_data.plain_keycode = plain_kbd_keycode_pm269;
119                 row_count = CARDHU_PM269_ROW_COUNT;
120                 col_count = CARDHU_PM269_COL_COUNT;
121         }
122
123         pr_info("Registering tegra-kbc\n");
124          /* Setup the pin configuration information. */
125         for (i = 0; i < KBC_MAX_GPIO; i++) {
126                 data->pin_cfg[i].num = 0;
127                 data->pin_cfg[i].pin_type = kbc_pin_unused;
128         }
129         for (i = 0; i < row_count; i++) {
130                 data->pin_cfg[i].num = i;
131                 data->pin_cfg[i].pin_type = kbc_pin_row;
132         }
133         for (i = 0; i < col_count; i++) {
134                 data->pin_cfg[i + row_count].num = i;
135                 data->pin_cfg[i + row_count].pin_type = kbc_pin_col;
136         }
137
138         platform_device_register(&cardhu_kbc_device);
139
140         return 0;
141 }
142 #else
143 int __init cardhu_kbc_init(void)
144 {
145         return 0;
146 }
147 #endif
148
149 int __init cardhu_scroll_init(void)
150 {
151         return 0;
152 }
153
154 #define GPIO_KEY(_id, _gpio, _iswake)           \
155         {                                       \
156                 .code = _id,                    \
157                 .gpio = TEGRA_GPIO_##_gpio,     \
158                 .active_low = 1,                \
159                 .desc = #_id,                   \
160                 .type = EV_KEY,                 \
161                 .wakeup = _iswake,              \
162                 .debounce_interval = 10,        \
163         }
164
165 static struct gpio_keys_button cardhu_keys_e1198[] = {
166         [0] = GPIO_KEY(KEY_HOME, PQ0, 0),
167         [1] = GPIO_KEY(KEY_BACK, PQ1, 0),
168         [2] = GPIO_KEY(KEY_MENU, PQ2, 0),
169         [3] = GPIO_KEY(KEY_SEARCH, PQ3, 0),
170         [4] = GPIO_KEY(KEY_VOLUMEUP, PR0, 0),
171         [5] = GPIO_KEY(KEY_VOLUMEDOWN, PR1, 0),
172         [6] = GPIO_KEY(KEY_POWER, PV0, 1),
173 };
174
175 static struct gpio_keys_platform_data cardhu_keys_e1198_platform_data = {
176         .buttons        = cardhu_keys_e1198,
177         .nbuttons       = ARRAY_SIZE(cardhu_keys_e1198),
178 };
179
180 static struct platform_device cardhu_keys_e1198_device = {
181         .name   = "gpio-keys",
182         .id     = 0,
183         .dev    = {
184                 .platform_data  = &cardhu_keys_e1198_platform_data,
185         },
186 };
187
188 static struct gpio_keys_button cardhu_keys_e1291[] = {
189         [0] = GPIO_KEY(KEY_MENU, PR0, 0),
190         [1] = GPIO_KEY(KEY_BACK, PR1, 0),
191         [2] = GPIO_KEY(KEY_HOME, PR2, 0),
192         [3] = GPIO_KEY(KEY_SEARCH, PQ3, 0),
193         [4] = GPIO_KEY(KEY_VOLUMEUP, PQ0, 0),
194         [5] = GPIO_KEY(KEY_VOLUMEDOWN, PQ1, 0),
195 };
196
197 static struct gpio_keys_platform_data cardhu_keys_e1291_platform_data = {
198         .buttons        = cardhu_keys_e1291,
199         .nbuttons       = ARRAY_SIZE(cardhu_keys_e1291),
200 };
201
202 static struct platform_device cardhu_keys_e1291_device = {
203         .name   = "gpio-keys",
204         .id     = 0,
205         .dev    = {
206                 .platform_data  = &cardhu_keys_e1291_platform_data,
207         },
208 };
209
210 #define INT_KEY(_id, _irq, _iswake, _deb_int)   \
211         {                                       \
212                 .code = _id,                    \
213                 .irq = _irq,                    \
214                 .active_low = 1,                \
215                 .desc = #_id,                   \
216                 .type = EV_KEY,                 \
217                 .wakeup = _iswake,              \
218                 .debounce_interval = _deb_int,  \
219         }
220 static struct interrupt_keys_button cardhu_int_keys[] = {
221         [0] = INT_KEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 0, 100),
222         [1] = INT_KEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON_LP, 0, 8000),
223 };
224
225 static struct interrupt_keys_platform_data cardhu_int_keys_pdata = {
226         .int_buttons    = cardhu_int_keys,
227         .nbuttons       = ARRAY_SIZE(cardhu_int_keys),
228 };
229
230 static struct platform_device cardhu_int_keys_device = {
231         .name   = "interrupt-keys",
232         .id     = 0,
233         .dev    = {
234                 .platform_data  = &cardhu_int_keys_pdata,
235         },
236 };
237
238 int __init cardhu_keys_init(void)
239 {
240         int i;
241         struct board_info board_info;
242
243         tegra_get_board_info(&board_info);
244         if (!((board_info.board_id == BOARD_E1198) ||
245                 (board_info.board_id == BOARD_E1291) ||
246                 (board_info.board_id == BOARD_PM305) ||
247                 (board_info.board_id == BOARD_PM269)))
248                 return 0;
249
250         pr_info("Registering gpio keys\n");
251
252         if (board_info.board_id == BOARD_E1291) {
253                 /* Enable gpio mode for other pins */
254                 for (i = 0; i < ARRAY_SIZE(cardhu_keys_e1291); i++)
255                         tegra_gpio_enable(cardhu_keys_e1291[i].gpio);
256
257                 platform_device_register(&cardhu_keys_e1291_device);
258         } else if (board_info.board_id == BOARD_E1198) {
259                 /* For E1198 */
260                 for (i = 0; i < ARRAY_SIZE(cardhu_keys_e1198); i++)
261                         tegra_gpio_enable(cardhu_keys_e1198[i].gpio);
262
263                 platform_device_register(&cardhu_keys_e1198_device);
264         }
265
266         /* Register on-key through pmu interrupt */
267         if ((board_info.board_id == BOARD_E1291) ||
268                 (board_info.board_id == BOARD_PM305) ||
269                 (board_info.board_id == BOARD_PM269))
270                 platform_device_register(&cardhu_int_keys_device);
271         return 0;
272 }