arm: tegra: cardhu: support for PCA6416 gpio expander
[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 #include "board.h"
35 #include "board-cardhu.h"
36
37 #include "gpio-names.h"
38
39 #ifdef CONFIG_KEYBOARD_TEGRA
40 #ifdef CONFIG_INPUT_ALPS_GPIO_SCROLLWHEEL
41 #define CARDHU_ROW_COUNT        3
42 #define CARDHU_COL_COUNT        2
43 #else
44 #define CARDHU_ROW_COUNT        4
45 #define CARDHU_COL_COUNT        6
46 #endif
47
48 #ifdef CONFIG_INPUT_ALPS_GPIO_SCROLLWHEEL
49 static int plain_kbd_keycode[] = {
50         KEY_POWER,      KEY_RESERVED,
51         KEY_HOME,       KEY_BACK,
52         KEY_RESERVED,   KEY_RESERVED,
53 };
54 #else
55 static int plain_kbd_keycode[] = {
56         KEY_POWER,      KEY_RESERVED,   KEY_RESERVED,   KEY_RESERVED,
57                         KEY_RESERVED,   KEY_RESERVED,   KEY_RESERVED,
58         KEY_HOME,       KEY_BACK,       KEY_RESERVED,   KEY_RESERVED,
59                         KEY_RESERVED,   KEY_RESERVED,   KEY_RESERVED,
60         KEY_CAMERA,     KEY_CAMERA,     KEY_RESERVED,   KEY_RESERVED,
61                         KEY_RESERVED,   KEY_RESERVED,   KEY_RESERVED,
62         KEY_VOLUMEDOWN, KEY_VOLUMEUP,   KEY_RESERVED,   KEY_RESERVED,
63                         KEY_RESERVED,   KEY_RESERVED,   KEY_PAUSE,
64         KEY_END,        KEY_BACK,       KEY_RESERVED,   KEY_RESERVED,
65                         KEY_RESERVED,   KEY_PLAY,       KEY_PHONE,
66 };
67 #endif
68 static struct tegra_kbc_wake_key cardhu_wake_cfg[] = {
69         [0] = {
70                 .row = 0,
71                 .col = 0,
72         },
73 };
74
75 static struct tegra_kbc_platform_data cardhu_kbc_platform_data = {
76         .debounce_cnt = 20,
77         .repeat_cnt = 50 * 32,
78         .scan_timeout_cnt = 3000 * 32,
79         .plain_keycode = plain_kbd_keycode,
80         .fn_keycode = NULL,
81         .is_filter_keys = false,
82         .is_wake_on_any_key = false,
83         .wake_key_cnt = 1,
84         .wake_cfg = &cardhu_wake_cfg[0],
85 };
86
87 static struct resource cardhu_kbc_resources[] = {
88         [0] = {
89                 .start = TEGRA_KBC_BASE,
90                 .end   = TEGRA_KBC_BASE + TEGRA_KBC_SIZE - 1,
91                 .flags = IORESOURCE_MEM,
92         },
93         [1] = {
94                 .start = INT_KBC,
95                 .end   = INT_KBC,
96                 .flags = IORESOURCE_IRQ,
97         },
98 };
99
100
101 struct platform_device cardhu_kbc_device = {
102         .name = "tegra-kbc",
103         .id = -1,
104         .dev = {
105                 .platform_data = &cardhu_kbc_platform_data,
106         },
107         .resource = cardhu_kbc_resources,
108         .num_resources = ARRAY_SIZE(cardhu_kbc_resources),
109 };
110
111 int __init cardhu_kbc_init(void)
112 {
113         struct tegra_kbc_platform_data *data = &cardhu_kbc_platform_data;
114         int i;
115         struct board_info board_info;
116
117         tegra_get_board_info(&board_info);
118         if ((board_info.board_id == BOARD_E1198) ||
119                         (board_info.board_id == BOARD_E1291))
120                 return 0;
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 < CARDHU_ROW_COUNT; i++) {
129                 data->pin_cfg[i].num = i;
130                 data->pin_cfg[i].pin_type = kbc_pin_row;
131         }
132
133         for (i = 0; i < CARDHU_COL_COUNT; i++) {
134                 data->pin_cfg[i + CARDHU_ROW_COUNT].num = i;
135                 data->pin_cfg[i + CARDHU_ROW_COUNT].pin_type = kbc_pin_col;
136         }
137         platform_device_register(&cardhu_kbc_device);
138         return 0;
139 }
140 #else
141 int __init cardhu_kbc_init(void)
142 {
143 }
144 #endif
145
146 #ifdef CONFIG_INPUT_ALPS_GPIO_SCROLLWHEEL
147 #define GPIO_SCROLL(_pinaction, _gpio, _desc)           \
148 {                                                       \
149         .pinaction = GPIO_SCROLLWHEEL_PIN_##_pinaction, \
150         .gpio = TEGRA_GPIO_##_gpio,                     \
151         .desc = _desc,                                  \
152         .active_low = 1,                                \
153         .debounce_interval = 2,                         \
154 }
155
156 static struct gpio_scrollwheel_button scroll_keys[] = {
157         [0] = GPIO_SCROLL(ONOFF, PR3, "sw_onoff"),
158         [1] = GPIO_SCROLL(PRESS, PQ5, "sw_press"),
159         [2] = GPIO_SCROLL(ROT1, PQ3, "sw_rot1"),
160         [3] = GPIO_SCROLL(ROT2, PQ4, "sw_rot2"),
161 };
162
163 static struct gpio_scrollwheel_platform_data cardhu_scroll_platform_data = {
164         .buttons = scroll_keys,
165         .nbuttons = ARRAY_SIZE(scroll_keys),
166 };
167
168 static struct platform_device cardhu_scroll_device = {
169         .name   = "alps-gpio-scrollwheel",
170         .id     = 0,
171         .dev    = {
172                 .platform_data = &cardhu_scroll_platform_data,
173         },
174 };
175
176 int __init cardhu_scroll_init(void)
177 {
178         int i;
179         struct board_info board_info;
180
181         tegra_get_board_info(&board_info);
182         if ((board_info.board_id == BOARD_E1198) ||
183                 (board_info.board_id == BOARD_E1291))
184                 return 0;
185
186         pr_info("Registering alps scroll wheel\n");
187
188         /* Setting pins to gpio mode */
189         for (i = 0; i < ARRAY_SIZE(scroll_keys); i++)
190                 tegra_gpio_enable(scroll_keys[i].gpio);
191
192         platform_device_register(&cardhu_scroll_device);
193         return 0;
194 }
195 #else
196 int __init cardhu_scroll_init(void)
197 {
198         return 0;
199 }
200 #endif
201
202 #ifdef CONFIG_KEYBOARD_GPIO
203 #define GPIO_KEY(_id, _gpio, _iswake)           \
204         {                                       \
205                 .code = _id,                    \
206                 .gpio = TEGRA_GPIO_##_gpio,     \
207                 .active_low = 1,                \
208                 .desc = #_id,                   \
209                 .type = EV_KEY,                 \
210                 .wakeup = _iswake,              \
211                 .debounce_interval = 10,        \
212         }
213
214 static struct gpio_keys_button cardhu_keys[] = {
215         [0] = GPIO_KEY(KEY_HOME, PQ0, 0),
216         [1] = GPIO_KEY(KEY_BACK, PQ1, 0),
217         [2] = GPIO_KEY(KEY_MENU, PQ2, 0),
218         [3] = GPIO_KEY(KEY_SEARCH, PQ3, 0),
219         [4] = GPIO_KEY(KEY_VOLUMEUP, PR0, 0),
220         [5] = GPIO_KEY(KEY_VOLUMEDOWN, PR1, 0),
221         [6] = GPIO_KEY(KEY_POWER, PV0, 1),
222 };
223
224 static struct gpio_keys_platform_data cardhu_keys_platform_data = {
225         .buttons        = cardhu_keys,
226         .nbuttons       = ARRAY_SIZE(cardhu_keys),
227 };
228
229 static struct platform_device cardhu_keys_device = {
230         .name   = "gpio-keys",
231         .id     = 0,
232         .dev    = {
233                 .platform_data  = &cardhu_keys_platform_data,
234         },
235 };
236
237 int __init cardhu_keys_init(void)
238 {
239         int i;
240         int ret;
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                 return 0;
247
248         pr_info("Registering gpio keys\n");
249
250         /* Set KB_ROW2 to 0 for capcitive switch to be in scan mode */
251         if (board_info.board_id == BOARD_E1291) {
252                 ret = gpio_request(TEGRA_GPIO_PR2, "cap_sw_sl_scan");
253                 if (ret < 0) {
254                         pr_err("%s: gpio_request failed #%d\n",
255                                         __func__, TEGRA_GPIO_PR2);
256                         return ret;
257                 }
258                 ret = gpio_direction_output(TEGRA_GPIO_PR2, 0);
259                 if (ret < 0) {
260                         pr_err("%s: gpio_direction_output failed #%d\n",
261                                         __func__, TEGRA_GPIO_PR2);
262                         gpio_free(TEGRA_GPIO_PR2);
263                         return ret;
264                 }
265
266                 tegra_gpio_enable(TEGRA_GPIO_PR2);
267         }
268
269         /* Enable gpio mode for other pins */
270         for (i = 0; i < ARRAY_SIZE(cardhu_keys); i++)
271                 tegra_gpio_enable(cardhu_keys[i].gpio);
272
273         platform_device_register(&cardhu_keys_device);
274         return 0;
275 }
276 #else
277 int __init cardhu_keys_init(void)
278 {
279         return 0;
280 }
281 #endif