ARM: tegra: cardhu: Allow LP0->LP3 using PM269 GPIO power button without KBC
[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                 cardhu_kbc_platform_data.plain_keycode = plain_kbd_keycode_pm269;
118                 row_count = CARDHU_PM269_ROW_COUNT;
119                 col_count = CARDHU_PM269_COL_COUNT;
120         }
121
122         pr_info("Registering tegra-kbc\n");
123          /* Setup the pin configuration information. */
124         for (i = 0; i < KBC_MAX_GPIO; i++) {
125                 data->pin_cfg[i].num = 0;
126                 data->pin_cfg[i].pin_type = kbc_pin_unused;
127         }
128         for (i = 0; i < row_count; i++) {
129                 data->pin_cfg[i].num = i;
130                 data->pin_cfg[i].pin_type = kbc_pin_row;
131         }
132         for (i = 0; i < col_count; i++) {
133                 data->pin_cfg[i + row_count].num = i;
134                 data->pin_cfg[i + row_count].pin_type = kbc_pin_col;
135         }
136
137         platform_device_register(&cardhu_kbc_device);
138
139         return 0;
140 }
141 #else
142 int __init cardhu_kbc_init(void)
143 {
144         return 0;
145 }
146 #endif
147
148 int __init cardhu_scroll_init(void)
149 {
150         return 0;
151 }
152
153 #define GPIO_KEY(_id, _gpio, _iswake)           \
154         {                                       \
155                 .code = _id,                    \
156                 .gpio = TEGRA_GPIO_##_gpio,     \
157                 .active_low = 1,                \
158                 .desc = #_id,                   \
159                 .type = EV_KEY,                 \
160                 .wakeup = _iswake,              \
161                 .debounce_interval = 10,        \
162         }
163
164 static struct gpio_keys_button cardhu_keys_e1198[] = {
165         [0] = GPIO_KEY(KEY_HOME, PQ0, 0),
166         [1] = GPIO_KEY(KEY_BACK, PQ1, 0),
167         [2] = GPIO_KEY(KEY_MENU, PQ2, 0),
168         [3] = GPIO_KEY(KEY_SEARCH, PQ3, 0),
169         [4] = GPIO_KEY(KEY_VOLUMEUP, PR0, 0),
170         [5] = GPIO_KEY(KEY_VOLUMEDOWN, PR1, 0),
171         [6] = GPIO_KEY(KEY_POWER, PV0, 1),
172 };
173
174 static struct gpio_keys_platform_data cardhu_keys_e1198_platform_data = {
175         .buttons        = cardhu_keys_e1198,
176         .nbuttons       = ARRAY_SIZE(cardhu_keys_e1198),
177 };
178
179 static struct platform_device cardhu_keys_e1198_device = {
180         .name   = "gpio-keys",
181         .id     = 0,
182         .dev    = {
183                 .platform_data  = &cardhu_keys_e1198_platform_data,
184         },
185 };
186
187 static struct gpio_keys_button cardhu_keys_e1291[] = {
188         [0] = GPIO_KEY(KEY_POWER, PR0, 0),
189         [1] = GPIO_KEY(KEY_BACK, PR1, 0),
190         [2] = GPIO_KEY(KEY_HOME, PR2, 0),
191         [3] = GPIO_KEY(KEY_SEARCH, PQ3, 0),
192         [4] = GPIO_KEY(KEY_VOLUMEUP, PQ0, 0),
193         [5] = GPIO_KEY(KEY_VOLUMEDOWN, PQ1, 0),
194 };
195
196 static struct gpio_keys_platform_data cardhu_keys_e1291_platform_data = {
197         .buttons        = cardhu_keys_e1291,
198         .nbuttons       = ARRAY_SIZE(cardhu_keys_e1291),
199 };
200
201 static struct platform_device cardhu_keys_e1291_device = {
202         .name   = "gpio-keys",
203         .id     = 0,
204         .dev    = {
205                 .platform_data  = &cardhu_keys_e1291_platform_data,
206         },
207 };
208
209 #define INT_KEY(_id, _irq, _iswake, _deb_int)   \
210         {                                       \
211                 .code = _id,                    \
212                 .irq = _irq,                    \
213                 .active_low = 1,                \
214                 .desc = #_id,                   \
215                 .type = EV_KEY,                 \
216                 .wakeup = _iswake,              \
217                 .debounce_interval = _deb_int,  \
218         }
219 static struct interrupt_keys_button cardhu_int_keys_e1291[] = {
220         [0] = INT_KEY(KEY_MENU, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 0, 100),
221         [1] = INT_KEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON_LP, 0, 8000),
222 };
223
224 static struct interrupt_keys_platform_data cardhu_int_keys_e1291_pdata = {
225         .int_buttons    = cardhu_int_keys_e1291,
226         .nbuttons       = ARRAY_SIZE(cardhu_int_keys_e1291),
227 };
228
229 static struct platform_device cardhu_int_keys_e1291_device = {
230         .name   = "interrupt-keys",
231         .id     = 0,
232         .dev    = {
233                 .platform_data  = &cardhu_int_keys_e1291_pdata,
234         },
235 };
236
237 static struct interrupt_keys_button cardhu_int_keys_pm269[] = {
238         [0] = INT_KEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 0, 100),
239         [1] = INT_KEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON_LP, 0, 8000),
240 };
241
242 static struct interrupt_keys_platform_data cardhu_int_keys_pm269_pdata = {
243         .int_buttons    = cardhu_int_keys_pm269,
244         .nbuttons       = ARRAY_SIZE(cardhu_int_keys_pm269),
245 };
246
247 static struct platform_device cardhu_int_keys_pm269_device = {
248         .name   = "interrupt-keys",
249         .id     = 0,
250         .dev    = {
251                 .platform_data  = &cardhu_int_keys_pm269_pdata,
252         },
253 };
254
255 int __init cardhu_keys_init(void)
256 {
257         int i;
258         struct board_info board_info;
259
260         tegra_get_board_info(&board_info);
261         if (!((board_info.board_id == BOARD_E1198) ||
262                 (board_info.board_id == BOARD_E1291) ||
263                 (board_info.board_id == BOARD_PM269)))
264                 return 0;
265
266         pr_info("Registering gpio keys\n");
267
268         if (board_info.board_id == BOARD_E1291) {
269                 /* Enable gpio mode for other pins */
270                 for (i = 0; i < ARRAY_SIZE(cardhu_keys_e1291); i++)
271                         tegra_gpio_enable(cardhu_keys_e1291[i].gpio);
272
273                 platform_device_register(&cardhu_keys_e1291_device);
274                 platform_device_register(&cardhu_int_keys_e1291_device);
275         } else if (board_info.board_id == BOARD_PM269) {
276                 platform_device_register(&cardhu_int_keys_pm269_device);
277         } else {
278                 /* For E1198 */
279                 for (i = 0; i < ARRAY_SIZE(cardhu_keys_e1198); i++)
280                         tegra_gpio_enable(cardhu_keys_e1198[i].gpio);
281
282                 platform_device_register(&cardhu_keys_e1198_device);
283         }
284         return 0;
285 }