diff options
Diffstat (limited to 'arch/arm/mach-tegra/board-cardhu-kbc.c')
-rw-r--r-- | arch/arm/mach-tegra/board-cardhu-kbc.c | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-cardhu-kbc.c b/arch/arm/mach-tegra/board-cardhu-kbc.c new file mode 100644 index 00000000000..3bf0a3b864f --- /dev/null +++ b/arch/arm/mach-tegra/board-cardhu-kbc.c | |||
@@ -0,0 +1,299 @@ | |||
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/mfd/max77663-core.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 | #include "devices.h" | ||
41 | |||
42 | #define CARDHU_PM269_ROW_COUNT 2 | ||
43 | #define CARDHU_PM269_COL_COUNT 4 | ||
44 | |||
45 | static const u32 kbd_keymap[] = { | ||
46 | KEY(0, 0, KEY_POWER), | ||
47 | KEY(0, 1, KEY_RESERVED), | ||
48 | KEY(0, 2, KEY_VOLUMEUP), | ||
49 | KEY(0, 3, KEY_VOLUMEDOWN), | ||
50 | |||
51 | KEY(1, 0, KEY_HOME), | ||
52 | KEY(1, 1, KEY_MENU), | ||
53 | KEY(1, 2, KEY_BACK), | ||
54 | KEY(1, 3, KEY_SEARCH), | ||
55 | }; | ||
56 | static const struct matrix_keymap_data keymap_data = { | ||
57 | .keymap = kbd_keymap, | ||
58 | .keymap_size = ARRAY_SIZE(kbd_keymap), | ||
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 * 32, /* 20ms debounce time */ | ||
70 | .repeat_cnt = 1, | ||
71 | .scan_count = 30, | ||
72 | .wakeup = true, | ||
73 | .keymap_data = &keymap_data, | ||
74 | .wake_cnt = 1, | ||
75 | .wake_cfg = &cardhu_wake_cfg[0], | ||
76 | #ifdef CONFIG_ANDROID | ||
77 | .disable_ev_rep = true, | ||
78 | #endif | ||
79 | }; | ||
80 | |||
81 | int __init cardhu_kbc_init(void) | ||
82 | { | ||
83 | struct tegra_kbc_platform_data *data = &cardhu_kbc_platform_data; | ||
84 | int i; | ||
85 | struct board_info board_info; | ||
86 | |||
87 | tegra_get_board_info(&board_info); | ||
88 | if ((board_info.board_id == BOARD_E1198) || | ||
89 | (board_info.board_id == BOARD_E1291)) | ||
90 | return 0; | ||
91 | |||
92 | pr_info("Registering tegra-kbc\n"); | ||
93 | tegra_kbc_device.dev.platform_data = &cardhu_kbc_platform_data; | ||
94 | |||
95 | for (i = 0; i < CARDHU_PM269_ROW_COUNT; i++) { | ||
96 | data->pin_cfg[i].num = i; | ||
97 | data->pin_cfg[i].is_row = true; | ||
98 | data->pin_cfg[i].en = true; | ||
99 | } | ||
100 | for (i = 0; i < CARDHU_PM269_COL_COUNT; i++) { | ||
101 | data->pin_cfg[i + KBC_PIN_GPIO_16].num = i; | ||
102 | data->pin_cfg[i + KBC_PIN_GPIO_16].en = true; | ||
103 | } | ||
104 | |||
105 | platform_device_register(&tegra_kbc_device); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | int __init cardhu_scroll_init(void) | ||
110 | { | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | #define GPIO_KEY(_id, _gpio, _iswake) \ | ||
115 | { \ | ||
116 | .code = _id, \ | ||
117 | .gpio = TEGRA_GPIO_##_gpio, \ | ||
118 | .active_low = 1, \ | ||
119 | .desc = #_id, \ | ||
120 | .type = EV_KEY, \ | ||
121 | .wakeup = _iswake, \ | ||
122 | .debounce_interval = 10, \ | ||
123 | } | ||
124 | |||
125 | #define GPIO_IKEY(_id, _irq, _iswake, _deb) \ | ||
126 | { \ | ||
127 | .code = _id, \ | ||
128 | .gpio = -1, \ | ||
129 | .irq = _irq, \ | ||
130 | .desc = #_id, \ | ||
131 | .type = EV_KEY, \ | ||
132 | .wakeup = _iswake, \ | ||
133 | .debounce_interval = _deb, \ | ||
134 | } | ||
135 | |||
136 | static struct gpio_keys_button cardhu_keys_e1198[] = { | ||
137 | [0] = GPIO_KEY(KEY_HOME, PQ0, 0), | ||
138 | [1] = GPIO_KEY(KEY_BACK, PQ1, 0), | ||
139 | [2] = GPIO_KEY(KEY_MENU, PQ2, 0), | ||
140 | [3] = GPIO_KEY(KEY_SEARCH, PQ3, 0), | ||
141 | [4] = GPIO_KEY(KEY_VOLUMEUP, PR0, 0), | ||
142 | [5] = GPIO_KEY(KEY_VOLUMEDOWN, PR1, 0), | ||
143 | [6] = GPIO_KEY(KEY_POWER, PV0, 1), | ||
144 | [7] = GPIO_IKEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 1, 100), | ||
145 | }; | ||
146 | |||
147 | static struct gpio_keys_platform_data cardhu_keys_e1198_pdata = { | ||
148 | .buttons = cardhu_keys_e1198, | ||
149 | .nbuttons = ARRAY_SIZE(cardhu_keys_e1198), | ||
150 | }; | ||
151 | |||
152 | static struct platform_device cardhu_keys_e1198_device = { | ||
153 | .name = "gpio-keys", | ||
154 | .id = 0, | ||
155 | .dev = { | ||
156 | .platform_data = &cardhu_keys_e1198_pdata, | ||
157 | }, | ||
158 | }; | ||
159 | |||
160 | static struct gpio_keys_button cardhu_keys_e1291[] = { | ||
161 | [0] = GPIO_KEY(KEY_VOLUMEDOWN, PR0, 0), | ||
162 | [1] = GPIO_KEY(KEY_VOLUMEUP, PR1, 0), | ||
163 | [2] = GPIO_KEY(KEY_HOME, PR2, 0), | ||
164 | [3] = GPIO_KEY(KEY_SEARCH, PQ3, 0), | ||
165 | [4] = GPIO_KEY(KEY_BACK, PQ0, 0), | ||
166 | [5] = GPIO_KEY(KEY_MENU, PQ1, 0), | ||
167 | [6] = GPIO_IKEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 1, 100), | ||
168 | }; | ||
169 | |||
170 | static struct gpio_keys_button cardhu_keys_e1291_a04[] = { | ||
171 | [0] = GPIO_KEY(KEY_VOLUMEDOWN, PR0, 0), | ||
172 | [1] = GPIO_KEY(KEY_VOLUMEUP, PR1, 0), | ||
173 | [2] = GPIO_KEY(KEY_HOME, PQ2, 0), | ||
174 | [3] = GPIO_KEY(KEY_SEARCH, PQ3, 0), | ||
175 | [4] = GPIO_KEY(KEY_BACK, PQ0, 0), | ||
176 | [5] = GPIO_KEY(KEY_MENU, PQ1, 0), | ||
177 | [6] = GPIO_IKEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 1, 100), | ||
178 | }; | ||
179 | |||
180 | static struct gpio_keys_platform_data cardhu_keys_e1291_pdata = { | ||
181 | .buttons = cardhu_keys_e1291, | ||
182 | .nbuttons = ARRAY_SIZE(cardhu_keys_e1291), | ||
183 | }; | ||
184 | |||
185 | static struct platform_device cardhu_keys_e1291_device = { | ||
186 | .name = "gpio-keys", | ||
187 | .id = 0, | ||
188 | .dev = { | ||
189 | .platform_data = &cardhu_keys_e1291_pdata, | ||
190 | }, | ||
191 | }; | ||
192 | |||
193 | static struct gpio_keys_button cardhu_int_keys[] = { | ||
194 | [0] = GPIO_IKEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 1, 100), | ||
195 | }; | ||
196 | |||
197 | static struct gpio_keys_button cardhu_pm298_int_keys[] = { | ||
198 | [0] = GPIO_IKEY(KEY_POWER, MAX77663_IRQ_BASE + MAX77663_IRQ_ONOFF_EN0_FALLING, 1, 100), | ||
199 | [1] = GPIO_IKEY(KEY_POWER, MAX77663_IRQ_BASE + MAX77663_IRQ_ONOFF_EN0_1SEC, 1, 3000), | ||
200 | }; | ||
201 | |||
202 | static struct gpio_keys_button cardhu_pm299_int_keys[] = { | ||
203 | [0] = GPIO_IKEY(KEY_POWER, RICOH583_IRQ_BASE + RICOH583_IRQ_ONKEY, 1, 100), | ||
204 | }; | ||
205 | |||
206 | static struct gpio_keys_platform_data cardhu_int_keys_pdata = { | ||
207 | .buttons = cardhu_int_keys, | ||
208 | .nbuttons = ARRAY_SIZE(cardhu_int_keys), | ||
209 | }; | ||
210 | |||
211 | static struct platform_device cardhu_int_keys_device = { | ||
212 | .name = "gpio-keys", | ||
213 | .id = 0, | ||
214 | .dev = { | ||
215 | .platform_data = &cardhu_int_keys_pdata, | ||
216 | }, | ||
217 | }; | ||
218 | |||
219 | int __init cardhu_keys_init(void) | ||
220 | { | ||
221 | int i; | ||
222 | struct board_info board_info; | ||
223 | struct board_info pmu_board_info; | ||
224 | int gpio_nr; | ||
225 | |||
226 | tegra_get_board_info(&board_info); | ||
227 | if (!((board_info.board_id == BOARD_E1198) || | ||
228 | (board_info.board_id == BOARD_E1291) || | ||
229 | (board_info.board_id == BOARD_E1186) || | ||
230 | (board_info.board_id == BOARD_E1257) || | ||
231 | (board_info.board_id == BOARD_PM305) || | ||
232 | (board_info.board_id == BOARD_PM311) || | ||
233 | (board_info.board_id == BOARD_PM269))) | ||
234 | return 0; | ||
235 | |||
236 | pr_info("Registering gpio keys\n"); | ||
237 | |||
238 | if (board_info.board_id == BOARD_E1291) { | ||
239 | if (board_info.fab >= BOARD_FAB_A04) { | ||
240 | cardhu_keys_e1291_pdata.buttons = | ||
241 | cardhu_keys_e1291_a04; | ||
242 | cardhu_keys_e1291_pdata.nbuttons = | ||
243 | ARRAY_SIZE(cardhu_keys_e1291_a04); | ||
244 | } | ||
245 | |||
246 | /* Enable gpio mode for other pins */ | ||
247 | for (i = 0; i < cardhu_keys_e1291_pdata.nbuttons; i++) { | ||
248 | gpio_nr = cardhu_keys_e1291_pdata.buttons[i].gpio; | ||
249 | if (gpio_nr < 0) { | ||
250 | if (get_tegra_image_type() == rck_image) | ||
251 | cardhu_keys_e1291_pdata.buttons[i].code | ||
252 | = KEY_ENTER; | ||
253 | } else { | ||
254 | tegra_gpio_enable(gpio_nr); | ||
255 | } | ||
256 | } | ||
257 | |||
258 | platform_device_register(&cardhu_keys_e1291_device); | ||
259 | } else if (board_info.board_id == BOARD_E1198) { | ||
260 | /* For E1198 */ | ||
261 | for (i = 0; i < ARRAY_SIZE(cardhu_keys_e1198); i++) { | ||
262 | gpio_nr = cardhu_keys_e1198[i].gpio; | ||
263 | if (gpio_nr < 0) { | ||
264 | if (get_tegra_image_type() == rck_image) | ||
265 | cardhu_keys_e1198[i].code = KEY_ENTER; | ||
266 | } else { | ||
267 | tegra_gpio_enable(gpio_nr); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | platform_device_register(&cardhu_keys_e1198_device); | ||
272 | } | ||
273 | |||
274 | /* Register on-key through pmu interrupt */ | ||
275 | tegra_get_pmu_board_info(&pmu_board_info); | ||
276 | |||
277 | if (pmu_board_info.board_id == BOARD_PMU_PM298) { | ||
278 | cardhu_int_keys_pdata.buttons = cardhu_pm298_int_keys; | ||
279 | cardhu_int_keys_pdata.nbuttons = | ||
280 | ARRAY_SIZE(cardhu_pm298_int_keys); | ||
281 | } | ||
282 | |||
283 | if (pmu_board_info.board_id == BOARD_PMU_PM299) { | ||
284 | cardhu_int_keys_pdata.buttons = cardhu_pm299_int_keys; | ||
285 | cardhu_int_keys_pdata.nbuttons = | ||
286 | ARRAY_SIZE(cardhu_pm299_int_keys); | ||
287 | } | ||
288 | |||
289 | if ((board_info.board_id == BOARD_E1257) || | ||
290 | (board_info.board_id == BOARD_E1186) || | ||
291 | (board_info.board_id == BOARD_PM305) || | ||
292 | (board_info.board_id == BOARD_PM311) || | ||
293 | (board_info.board_id == BOARD_PM269)) { | ||
294 | if (get_tegra_image_type() == rck_image) | ||
295 | cardhu_int_keys[0].code = KEY_ENTER; | ||
296 | platform_device_register(&cardhu_int_keys_device); | ||
297 | } | ||
298 | return 0; | ||
299 | } | ||