arm: tegra: tegratab: KEY_UNKNOWN as default wakeup_key
[linux-2.6.git] / arch / arm / mach-tegra / board-tegratab-kbc.c
1 /*
2  * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/platform_device.h>
19 #include <linux/input.h>
20 #include <mach/io.h>
21 #include <linux/io.h>
22 #include <mach/iomap.h>
23 #include <mach/kbc.h>
24 #include <linux/gpio.h>
25 #include <linux/gpio_keys.h>
26 #include <linux/mfd/palmas.h>
27 #include "wakeups-t11x.h"
28
29 #include "tegra-board-id.h"
30 #include "board.h"
31 #include "board-tegratab.h"
32 #include "devices.h"
33
34 #define GPIO_KEY(_id, _gpio, _iswake)           \
35         {                                       \
36                 .code = _id,                    \
37                 .gpio = TEGRA_GPIO_##_gpio,     \
38                 .active_low = 1,                \
39                 .desc = #_id,                   \
40                 .type = EV_KEY,                 \
41                 .wakeup = _iswake,              \
42                 .debounce_interval = 30,        \
43         }
44
45 #define GPIO_SW(_id, _gpio, _active_low, _iswake)   \
46         {                                           \
47                 .code = _id,                        \
48                 .gpio = TEGRA_GPIO_##_gpio,         \
49                 .irq = -1,                          \
50                 .type = EV_SW,                      \
51                 .desc = #_id,                       \
52                 .active_low = _active_low,          \
53                 .wakeup = _iswake,                  \
54                 .debounce_interval = 0,             \
55         }
56
57 static struct gpio_keys_button tegratab_e1569_keys[] = {
58         [0] = GPIO_KEY(KEY_POWER, PQ0, 1),
59         [1] = GPIO_KEY(KEY_VOLUMEUP, PR2, 0),
60         [2] = GPIO_KEY(KEY_VOLUMEDOWN, PR1, 0),
61 };
62
63 static struct gpio_keys_button tegratab_p1640_keys[] = {
64         [0] = GPIO_KEY(KEY_POWER, PQ0, 1),
65         [1] = GPIO_KEY(KEY_VOLUMEUP, PR2, 0),
66         [2] = GPIO_KEY(KEY_VOLUMEDOWN, PQ2, 0),
67         [3] = GPIO_SW(SW_LID, PC7, 1, 1),
68         [4] = GPIO_SW(SW_TABLET_MODE, PQ1, 0, 0),
69 };
70
71 static struct gpio_keys_button tegratab_p1640_a01_keys[] = {
72         [0] = GPIO_KEY(KEY_POWER, PQ0, 1),
73         [1] = GPIO_KEY(KEY_VOLUMEUP, PR2, 0),
74         [2] = GPIO_KEY(KEY_VOLUMEDOWN, PQ2, 0),
75         [3] = GPIO_SW(SW_LID, PC7, 1, 1),
76         [4] = GPIO_SW(SW_TABLET_MODE, PO5, 0, 1),
77 };
78
79 static int tegratab_wakeup_key(void)
80 {
81         int wakeup_key;
82         u64 status = readl(IO_ADDRESS(TEGRA_PMC_BASE) + PMC_WAKE_STATUS)
83                 | (u64)readl(IO_ADDRESS(TEGRA_PMC_BASE)
84                 + PMC_WAKE2_STATUS) << 32;
85         if (status & ((u64)1 << TEGRA_WAKE_GPIO_PQ0))
86                 wakeup_key = KEY_POWER;
87         else if (status & ((u64)1 << TEGRA_WAKE_GPIO_PC7))
88                 wakeup_key = SW_LID;
89         else if (status & ((u64)1 << TEGRA_WAKE_GPIO_PO5))
90                 wakeup_key = SW_TABLET_MODE;
91         else
92                 wakeup_key = KEY_UNKNOWN;
93
94         return wakeup_key;
95 }
96
97 static struct gpio_keys_platform_data tegratab_keys_pdata = {
98         .buttons        = tegratab_e1569_keys,
99         .nbuttons       = ARRAY_SIZE(tegratab_e1569_keys),
100         .wakeup_key     = tegratab_wakeup_key,
101 };
102
103 static struct platform_device tegratab_keys_device = {
104         .name   = "gpio-keys",
105         .id     = 0,
106         .dev    = {
107                 .platform_data  = &tegratab_keys_pdata,
108         },
109 };
110
111 int __init tegratab_kbc_init(void)
112 {
113         struct board_info board_info;
114
115         tegra_get_board_info(&board_info);
116
117         if (board_info.board_id == BOARD_P1640) {
118                 if (board_info.fab == BOARD_FAB_A00) {
119                         tegratab_keys_pdata.buttons = tegratab_p1640_keys;
120                         tegratab_keys_pdata.nbuttons =
121                            ARRAY_SIZE(tegratab_p1640_keys);
122                 } else {
123                         tegratab_keys_pdata.buttons = tegratab_p1640_a01_keys;
124                         tegratab_keys_pdata.nbuttons =
125                            ARRAY_SIZE(tegratab_p1640_a01_keys);
126                 }
127         }
128
129         platform_device_register(&tegratab_keys_device);
130
131         return 0;
132 }
133