aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci
diff options
context:
space:
mode:
authorBen Gardiner <bengardiner@nanometrics.ca>2010-12-09 16:51:04 -0500
committerKevin Hilman <khilman@deeprootsystems.com>2010-12-22 14:45:18 -0500
commit75929f5e2bcba7cc328fcf9a3d7ba7076946ac3a (patch)
tree7b54c518dc0e4e6987ff58ffab9a02cac2ebf28a /arch/arm/mach-davinci
parent22ca466847ad477d060baed84733c495bc6e81c8 (diff)
da850-evm: add UI Expander pushbuttons
This patch adds EV_KEYs for each of the 8 pushbuttons on the UI board via a gpio-key device. The expander is a tca6416; it controls the SEL_{A,B,C} lines which enable and disable the peripherals found on the UI board in addition to the 8 pushbuttons mentioned above. The reason the existing tca6416-keypad driver is not employed is because there was no aparent way to keep the gpio lines used as SEL_{A,B,C} registered while simultaneously registering the pushbuttons as a tca6416-keypad instance. Some experimentation with the polling interval was performed; we were searching for the largest polling interval that did not affect the feel of the responsiveness of the buttons. It is very subjective but 200ms seems to be a good value that accepts firm pushes but rejects very light ones. The key values assigned to the buttons were arbitrarily chosen to be F1-F8. Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca> Reviewed-by: Chris Cordahi <christophercordahi@nanometrics.ca> CC: Govindarajan, Sriramakrishnan <srk@ti.com> Reviewed-by: Sekhar Nori <nsekhar@ti.com> Signed-off-by: Sekhar Nori <nsekhar@ti.com> CC: Kevin Hilman <khilman@deeprootsystems.com> CC: Gabor Juhos <juhosg@openwrt.org> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm/mach-davinci')
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index fbdbd584cdf4..93bd43e93c45 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -17,8 +17,10 @@
17#include <linux/i2c.h> 17#include <linux/i2c.h>
18#include <linux/i2c/at24.h> 18#include <linux/i2c/at24.h>
19#include <linux/i2c/pca953x.h> 19#include <linux/i2c/pca953x.h>
20#include <linux/input.h>
20#include <linux/mfd/tps6507x.h> 21#include <linux/mfd/tps6507x.h>
21#include <linux/gpio.h> 22#include <linux/gpio.h>
23#include <linux/gpio_keys.h>
22#include <linux/platform_device.h> 24#include <linux/platform_device.h>
23#include <linux/mtd/mtd.h> 25#include <linux/mtd/mtd.h>
24#include <linux/mtd/nand.h> 26#include <linux/mtd/nand.h>
@@ -272,6 +274,87 @@ static inline void da850_evm_setup_emac_rmii(int rmii_sel)
272static inline void da850_evm_setup_emac_rmii(int rmii_sel) { } 274static inline void da850_evm_setup_emac_rmii(int rmii_sel) { }
273#endif 275#endif
274 276
277
278#define DA850_KEYS_DEBOUNCE_MS 10
279/*
280 * At 200ms polling interval it is possible to miss an
281 * event by tapping very lightly on the push button but most
282 * pushes do result in an event; longer intervals require the
283 * user to hold the button whereas shorter intervals require
284 * more CPU time for polling.
285 */
286#define DA850_GPIO_KEYS_POLL_MS 200
287
288enum da850_evm_ui_exp_pins {
289 DA850_EVM_UI_EXP_SEL_C = 5,
290 DA850_EVM_UI_EXP_SEL_B,
291 DA850_EVM_UI_EXP_SEL_A,
292 DA850_EVM_UI_EXP_PB8,
293 DA850_EVM_UI_EXP_PB7,
294 DA850_EVM_UI_EXP_PB6,
295 DA850_EVM_UI_EXP_PB5,
296 DA850_EVM_UI_EXP_PB4,
297 DA850_EVM_UI_EXP_PB3,
298 DA850_EVM_UI_EXP_PB2,
299 DA850_EVM_UI_EXP_PB1,
300};
301
302static const char const *da850_evm_ui_exp[] = {
303 [DA850_EVM_UI_EXP_SEL_C] = "sel_c",
304 [DA850_EVM_UI_EXP_SEL_B] = "sel_b",
305 [DA850_EVM_UI_EXP_SEL_A] = "sel_a",
306 [DA850_EVM_UI_EXP_PB8] = "pb8",
307 [DA850_EVM_UI_EXP_PB7] = "pb7",
308 [DA850_EVM_UI_EXP_PB6] = "pb6",
309 [DA850_EVM_UI_EXP_PB5] = "pb5",
310 [DA850_EVM_UI_EXP_PB4] = "pb4",
311 [DA850_EVM_UI_EXP_PB3] = "pb3",
312 [DA850_EVM_UI_EXP_PB2] = "pb2",
313 [DA850_EVM_UI_EXP_PB1] = "pb1",
314};
315
316#define DA850_N_UI_PB 8
317
318static struct gpio_keys_button da850_evm_ui_keys[] = {
319 [0 ... DA850_N_UI_PB - 1] = {
320 .type = EV_KEY,
321 .active_low = 1,
322 .wakeup = 0,
323 .debounce_interval = DA850_KEYS_DEBOUNCE_MS,
324 .code = -1, /* assigned at runtime */
325 .gpio = -1, /* assigned at runtime */
326 .desc = NULL, /* assigned at runtime */
327 },
328};
329
330static struct gpio_keys_platform_data da850_evm_ui_keys_pdata = {
331 .buttons = da850_evm_ui_keys,
332 .nbuttons = ARRAY_SIZE(da850_evm_ui_keys),
333 .poll_interval = DA850_GPIO_KEYS_POLL_MS,
334};
335
336static struct platform_device da850_evm_ui_keys_device = {
337 .name = "gpio-keys-polled",
338 .id = 0,
339 .dev = {
340 .platform_data = &da850_evm_ui_keys_pdata
341 },
342};
343
344static void da850_evm_ui_keys_init(unsigned gpio)
345{
346 int i;
347 struct gpio_keys_button *button;
348
349 for (i = 0; i < DA850_N_UI_PB; i++) {
350 button = &da850_evm_ui_keys[i];
351 button->code = KEY_F8 - i;
352 button->desc = (char *)
353 da850_evm_ui_exp[DA850_EVM_UI_EXP_PB8 + i];
354 button->gpio = gpio + DA850_EVM_UI_EXP_PB8 + i;
355 }
356}
357
275static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio, 358static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
276 unsigned ngpio, void *c) 359 unsigned ngpio, void *c)
277{ 360{
@@ -304,6 +387,13 @@ static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
304 gpio_direction_output(sel_b, 1); 387 gpio_direction_output(sel_b, 1);
305 gpio_direction_output(sel_c, 1); 388 gpio_direction_output(sel_c, 1);
306 389
390 da850_evm_ui_keys_init(gpio);
391 ret = platform_device_register(&da850_evm_ui_keys_device);
392 if (ret) {
393 pr_warning("Could not register UI GPIO expander push-buttons");
394 goto exp_setup_keys_fail;
395 }
396
307 ui_card_detected = 1; 397 ui_card_detected = 1;
308 pr_info("DA850/OMAP-L138 EVM UI card detected\n"); 398 pr_info("DA850/OMAP-L138 EVM UI card detected\n");
309 399
@@ -313,6 +403,8 @@ static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
313 403
314 return 0; 404 return 0;
315 405
406exp_setup_keys_fail:
407 gpio_free(sel_c);
316exp_setup_selc_fail: 408exp_setup_selc_fail:
317 gpio_free(sel_b); 409 gpio_free(sel_b);
318exp_setup_selb_fail: 410exp_setup_selb_fail:
@@ -324,6 +416,8 @@ exp_setup_sela_fail:
324static int da850_evm_ui_expander_teardown(struct i2c_client *client, 416static int da850_evm_ui_expander_teardown(struct i2c_client *client,
325 unsigned gpio, unsigned ngpio, void *c) 417 unsigned gpio, unsigned ngpio, void *c)
326{ 418{
419 platform_device_unregister(&da850_evm_ui_keys_device);
420
327 /* deselect all functionalities */ 421 /* deselect all functionalities */
328 gpio_set_value_cansleep(gpio + 5, 1); 422 gpio_set_value_cansleep(gpio + 5, 1);
329 gpio_set_value_cansleep(gpio + 6, 1); 423 gpio_set_value_cansleep(gpio + 6, 1);
@@ -340,6 +434,7 @@ static struct pca953x_platform_data da850_evm_ui_expander_info = {
340 .gpio_base = DAVINCI_N_GPIO, 434 .gpio_base = DAVINCI_N_GPIO,
341 .setup = da850_evm_ui_expander_setup, 435 .setup = da850_evm_ui_expander_setup,
342 .teardown = da850_evm_ui_expander_teardown, 436 .teardown = da850_evm_ui_expander_teardown,
437 .names = da850_evm_ui_exp,
343}; 438};
344 439
345static struct i2c_board_info __initdata da850_evm_i2c_devices[] = { 440static struct i2c_board_info __initdata da850_evm_i2c_devices[] = {