diff options
Diffstat (limited to 'drivers/input/keyboard/adp5589-keys.c')
-rw-r--r-- | drivers/input/keyboard/adp5589-keys.c | 609 |
1 files changed, 482 insertions, 127 deletions
diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c index c7708263051b..02b5d53031bf 100644 --- a/drivers/input/keyboard/adp5589-keys.c +++ b/drivers/input/keyboard/adp5589-keys.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Description: keypad driver for ADP5589 | 2 | * Description: keypad driver for ADP5589, ADP5585 |
3 | * I2C QWERTY Keypad and IO Expander | 3 | * I2C QWERTY Keypad and IO Expander |
4 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 4 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ |
5 | * | 5 | * |
@@ -22,35 +22,165 @@ | |||
22 | 22 | ||
23 | #include <linux/input/adp5589.h> | 23 | #include <linux/input/adp5589.h> |
24 | 24 | ||
25 | /* ADP5589/ADP5585 Common Registers */ | ||
26 | #define ADP5589_5_ID 0x00 | ||
27 | #define ADP5589_5_INT_STATUS 0x01 | ||
28 | #define ADP5589_5_STATUS 0x02 | ||
29 | #define ADP5589_5_FIFO_1 0x03 | ||
30 | #define ADP5589_5_FIFO_2 0x04 | ||
31 | #define ADP5589_5_FIFO_3 0x05 | ||
32 | #define ADP5589_5_FIFO_4 0x06 | ||
33 | #define ADP5589_5_FIFO_5 0x07 | ||
34 | #define ADP5589_5_FIFO_6 0x08 | ||
35 | #define ADP5589_5_FIFO_7 0x09 | ||
36 | #define ADP5589_5_FIFO_8 0x0A | ||
37 | #define ADP5589_5_FIFO_9 0x0B | ||
38 | #define ADP5589_5_FIFO_10 0x0C | ||
39 | #define ADP5589_5_FIFO_11 0x0D | ||
40 | #define ADP5589_5_FIFO_12 0x0E | ||
41 | #define ADP5589_5_FIFO_13 0x0F | ||
42 | #define ADP5589_5_FIFO_14 0x10 | ||
43 | #define ADP5589_5_FIFO_15 0x11 | ||
44 | #define ADP5589_5_FIFO_16 0x12 | ||
45 | #define ADP5589_5_GPI_INT_STAT_A 0x13 | ||
46 | #define ADP5589_5_GPI_INT_STAT_B 0x14 | ||
47 | |||
48 | /* ADP5589 Registers */ | ||
49 | #define ADP5589_GPI_INT_STAT_C 0x15 | ||
50 | #define ADP5589_GPI_STATUS_A 0x16 | ||
51 | #define ADP5589_GPI_STATUS_B 0x17 | ||
52 | #define ADP5589_GPI_STATUS_C 0x18 | ||
53 | #define ADP5589_RPULL_CONFIG_A 0x19 | ||
54 | #define ADP5589_RPULL_CONFIG_B 0x1A | ||
55 | #define ADP5589_RPULL_CONFIG_C 0x1B | ||
56 | #define ADP5589_RPULL_CONFIG_D 0x1C | ||
57 | #define ADP5589_RPULL_CONFIG_E 0x1D | ||
58 | #define ADP5589_GPI_INT_LEVEL_A 0x1E | ||
59 | #define ADP5589_GPI_INT_LEVEL_B 0x1F | ||
60 | #define ADP5589_GPI_INT_LEVEL_C 0x20 | ||
61 | #define ADP5589_GPI_EVENT_EN_A 0x21 | ||
62 | #define ADP5589_GPI_EVENT_EN_B 0x22 | ||
63 | #define ADP5589_GPI_EVENT_EN_C 0x23 | ||
64 | #define ADP5589_GPI_INTERRUPT_EN_A 0x24 | ||
65 | #define ADP5589_GPI_INTERRUPT_EN_B 0x25 | ||
66 | #define ADP5589_GPI_INTERRUPT_EN_C 0x26 | ||
67 | #define ADP5589_DEBOUNCE_DIS_A 0x27 | ||
68 | #define ADP5589_DEBOUNCE_DIS_B 0x28 | ||
69 | #define ADP5589_DEBOUNCE_DIS_C 0x29 | ||
70 | #define ADP5589_GPO_DATA_OUT_A 0x2A | ||
71 | #define ADP5589_GPO_DATA_OUT_B 0x2B | ||
72 | #define ADP5589_GPO_DATA_OUT_C 0x2C | ||
73 | #define ADP5589_GPO_OUT_MODE_A 0x2D | ||
74 | #define ADP5589_GPO_OUT_MODE_B 0x2E | ||
75 | #define ADP5589_GPO_OUT_MODE_C 0x2F | ||
76 | #define ADP5589_GPIO_DIRECTION_A 0x30 | ||
77 | #define ADP5589_GPIO_DIRECTION_B 0x31 | ||
78 | #define ADP5589_GPIO_DIRECTION_C 0x32 | ||
79 | #define ADP5589_UNLOCK1 0x33 | ||
80 | #define ADP5589_UNLOCK2 0x34 | ||
81 | #define ADP5589_EXT_LOCK_EVENT 0x35 | ||
82 | #define ADP5589_UNLOCK_TIMERS 0x36 | ||
83 | #define ADP5589_LOCK_CFG 0x37 | ||
84 | #define ADP5589_RESET1_EVENT_A 0x38 | ||
85 | #define ADP5589_RESET1_EVENT_B 0x39 | ||
86 | #define ADP5589_RESET1_EVENT_C 0x3A | ||
87 | #define ADP5589_RESET2_EVENT_A 0x3B | ||
88 | #define ADP5589_RESET2_EVENT_B 0x3C | ||
89 | #define ADP5589_RESET_CFG 0x3D | ||
90 | #define ADP5589_PWM_OFFT_LOW 0x3E | ||
91 | #define ADP5589_PWM_OFFT_HIGH 0x3F | ||
92 | #define ADP5589_PWM_ONT_LOW 0x40 | ||
93 | #define ADP5589_PWM_ONT_HIGH 0x41 | ||
94 | #define ADP5589_PWM_CFG 0x42 | ||
95 | #define ADP5589_CLOCK_DIV_CFG 0x43 | ||
96 | #define ADP5589_LOGIC_1_CFG 0x44 | ||
97 | #define ADP5589_LOGIC_2_CFG 0x45 | ||
98 | #define ADP5589_LOGIC_FF_CFG 0x46 | ||
99 | #define ADP5589_LOGIC_INT_EVENT_EN 0x47 | ||
100 | #define ADP5589_POLL_PTIME_CFG 0x48 | ||
101 | #define ADP5589_PIN_CONFIG_A 0x49 | ||
102 | #define ADP5589_PIN_CONFIG_B 0x4A | ||
103 | #define ADP5589_PIN_CONFIG_C 0x4B | ||
104 | #define ADP5589_PIN_CONFIG_D 0x4C | ||
105 | #define ADP5589_GENERAL_CFG 0x4D | ||
106 | #define ADP5589_INT_EN 0x4E | ||
107 | |||
108 | /* ADP5585 Registers */ | ||
109 | #define ADP5585_GPI_STATUS_A 0x15 | ||
110 | #define ADP5585_GPI_STATUS_B 0x16 | ||
111 | #define ADP5585_RPULL_CONFIG_A 0x17 | ||
112 | #define ADP5585_RPULL_CONFIG_B 0x18 | ||
113 | #define ADP5585_RPULL_CONFIG_C 0x19 | ||
114 | #define ADP5585_RPULL_CONFIG_D 0x1A | ||
115 | #define ADP5585_GPI_INT_LEVEL_A 0x1B | ||
116 | #define ADP5585_GPI_INT_LEVEL_B 0x1C | ||
117 | #define ADP5585_GPI_EVENT_EN_A 0x1D | ||
118 | #define ADP5585_GPI_EVENT_EN_B 0x1E | ||
119 | #define ADP5585_GPI_INTERRUPT_EN_A 0x1F | ||
120 | #define ADP5585_GPI_INTERRUPT_EN_B 0x20 | ||
121 | #define ADP5585_DEBOUNCE_DIS_A 0x21 | ||
122 | #define ADP5585_DEBOUNCE_DIS_B 0x22 | ||
123 | #define ADP5585_GPO_DATA_OUT_A 0x23 | ||
124 | #define ADP5585_GPO_DATA_OUT_B 0x24 | ||
125 | #define ADP5585_GPO_OUT_MODE_A 0x25 | ||
126 | #define ADP5585_GPO_OUT_MODE_B 0x26 | ||
127 | #define ADP5585_GPIO_DIRECTION_A 0x27 | ||
128 | #define ADP5585_GPIO_DIRECTION_B 0x28 | ||
129 | #define ADP5585_RESET1_EVENT_A 0x29 | ||
130 | #define ADP5585_RESET1_EVENT_B 0x2A | ||
131 | #define ADP5585_RESET1_EVENT_C 0x2B | ||
132 | #define ADP5585_RESET2_EVENT_A 0x2C | ||
133 | #define ADP5585_RESET2_EVENT_B 0x2D | ||
134 | #define ADP5585_RESET_CFG 0x2E | ||
135 | #define ADP5585_PWM_OFFT_LOW 0x2F | ||
136 | #define ADP5585_PWM_OFFT_HIGH 0x30 | ||
137 | #define ADP5585_PWM_ONT_LOW 0x31 | ||
138 | #define ADP5585_PWM_ONT_HIGH 0x32 | ||
139 | #define ADP5585_PWM_CFG 0x33 | ||
140 | #define ADP5585_LOGIC_CFG 0x34 | ||
141 | #define ADP5585_LOGIC_FF_CFG 0x35 | ||
142 | #define ADP5585_LOGIC_INT_EVENT_EN 0x36 | ||
143 | #define ADP5585_POLL_PTIME_CFG 0x37 | ||
144 | #define ADP5585_PIN_CONFIG_A 0x38 | ||
145 | #define ADP5585_PIN_CONFIG_B 0x39 | ||
146 | #define ADP5585_PIN_CONFIG_D 0x3A | ||
147 | #define ADP5585_GENERAL_CFG 0x3B | ||
148 | #define ADP5585_INT_EN 0x3C | ||
149 | |||
150 | /* ID Register */ | ||
151 | #define ADP5589_5_DEVICE_ID_MASK 0xF | ||
152 | #define ADP5589_5_MAN_ID_MASK 0xF | ||
153 | #define ADP5589_5_MAN_ID_SHIFT 4 | ||
154 | #define ADP5589_5_MAN_ID 0x02 | ||
155 | |||
25 | /* GENERAL_CFG Register */ | 156 | /* GENERAL_CFG Register */ |
26 | #define OSC_EN (1 << 7) | 157 | #define OSC_EN (1 << 7) |
27 | #define CORE_CLK(x) (((x) & 0x3) << 5) | 158 | #define CORE_CLK(x) (((x) & 0x3) << 5) |
28 | #define LCK_TRK_LOGIC (1 << 4) | 159 | #define LCK_TRK_LOGIC (1 << 4) /* ADP5589 only */ |
29 | #define LCK_TRK_GPI (1 << 3) | 160 | #define LCK_TRK_GPI (1 << 3) /* ADP5589 only */ |
30 | #define INT_CFG (1 << 1) | 161 | #define INT_CFG (1 << 1) |
31 | #define RST_CFG (1 << 0) | 162 | #define RST_CFG (1 << 0) |
32 | 163 | ||
33 | /* INT_EN Register */ | 164 | /* INT_EN Register */ |
34 | #define LOGIC2_IEN (1 << 5) | 165 | #define LOGIC2_IEN (1 << 5) /* ADP5589 only */ |
35 | #define LOGIC1_IEN (1 << 4) | 166 | #define LOGIC1_IEN (1 << 4) |
36 | #define LOCK_IEN (1 << 3) | 167 | #define LOCK_IEN (1 << 3) /* ADP5589 only */ |
37 | #define OVRFLOW_IEN (1 << 2) | 168 | #define OVRFLOW_IEN (1 << 2) |
38 | #define GPI_IEN (1 << 1) | 169 | #define GPI_IEN (1 << 1) |
39 | #define EVENT_IEN (1 << 0) | 170 | #define EVENT_IEN (1 << 0) |
40 | 171 | ||
41 | /* Interrupt Status Register */ | 172 | /* Interrupt Status Register */ |
42 | #define LOGIC2_INT (1 << 5) | 173 | #define LOGIC2_INT (1 << 5) /* ADP5589 only */ |
43 | #define LOGIC1_INT (1 << 4) | 174 | #define LOGIC1_INT (1 << 4) |
44 | #define LOCK_INT (1 << 3) | 175 | #define LOCK_INT (1 << 3) /* ADP5589 only */ |
45 | #define OVRFLOW_INT (1 << 2) | 176 | #define OVRFLOW_INT (1 << 2) |
46 | #define GPI_INT (1 << 1) | 177 | #define GPI_INT (1 << 1) |
47 | #define EVENT_INT (1 << 0) | 178 | #define EVENT_INT (1 << 0) |
48 | 179 | ||
49 | /* STATUS Register */ | 180 | /* STATUS Register */ |
50 | 181 | #define LOGIC2_STAT (1 << 7) /* ADP5589 only */ | |
51 | #define LOGIC2_STAT (1 << 7) | ||
52 | #define LOGIC1_STAT (1 << 6) | 182 | #define LOGIC1_STAT (1 << 6) |
53 | #define LOCK_STAT (1 << 5) | 183 | #define LOCK_STAT (1 << 5) /* ADP5589 only */ |
54 | #define KEC 0xF | 184 | #define KEC 0xF |
55 | 185 | ||
56 | /* PIN_CONFIG_D Register */ | 186 | /* PIN_CONFIG_D Register */ |
@@ -61,27 +191,54 @@ | |||
61 | #define LOCK_EN (1 << 0) | 191 | #define LOCK_EN (1 << 0) |
62 | 192 | ||
63 | #define PTIME_MASK 0x3 | 193 | #define PTIME_MASK 0x3 |
64 | #define LTIME_MASK 0x3 | 194 | #define LTIME_MASK 0x3 /* ADP5589 only */ |
65 | 195 | ||
66 | /* Key Event Register xy */ | 196 | /* Key Event Register xy */ |
67 | #define KEY_EV_PRESSED (1 << 7) | 197 | #define KEY_EV_PRESSED (1 << 7) |
68 | #define KEY_EV_MASK (0x7F) | 198 | #define KEY_EV_MASK (0x7F) |
69 | 199 | ||
70 | #define KEYP_MAX_EVENT 16 | 200 | #define KEYP_MAX_EVENT 16 |
201 | #define ADP5589_MAXGPIO 19 | ||
202 | #define ADP5585_MAXGPIO 11 /* 10 on the ADP5585-01, 11 on ADP5585-02 */ | ||
71 | 203 | ||
72 | #define MAXGPIO 19 | 204 | enum { |
73 | #define ADP_BANK(offs) ((offs) >> 3) | 205 | ADP5589, |
74 | #define ADP_BIT(offs) (1u << ((offs) & 0x7)) | 206 | ADP5585_01, |
207 | ADP5585_02 | ||
208 | }; | ||
209 | |||
210 | struct adp_constants { | ||
211 | u8 maxgpio; | ||
212 | u8 keymapsize; | ||
213 | u8 gpi_pin_row_base; | ||
214 | u8 gpi_pin_row_end; | ||
215 | u8 gpi_pin_col_base; | ||
216 | u8 gpi_pin_base; | ||
217 | u8 gpi_pin_end; | ||
218 | u8 gpimapsize_max; | ||
219 | u8 max_row_num; | ||
220 | u8 max_col_num; | ||
221 | u8 row_mask; | ||
222 | u8 col_mask; | ||
223 | u8 col_shift; | ||
224 | u8 c4_extend_cfg; | ||
225 | u8 (*bank) (u8 offset); | ||
226 | u8 (*bit) (u8 offset); | ||
227 | u8 (*reg) (u8 reg); | ||
228 | }; | ||
75 | 229 | ||
76 | struct adp5589_kpad { | 230 | struct adp5589_kpad { |
77 | struct i2c_client *client; | 231 | struct i2c_client *client; |
78 | struct input_dev *input; | 232 | struct input_dev *input; |
233 | const struct adp_constants *var; | ||
79 | unsigned short keycode[ADP5589_KEYMAPSIZE]; | 234 | unsigned short keycode[ADP5589_KEYMAPSIZE]; |
80 | const struct adp5589_gpi_map *gpimap; | 235 | const struct adp5589_gpi_map *gpimap; |
81 | unsigned short gpimapsize; | 236 | unsigned short gpimapsize; |
82 | unsigned extend_cfg; | 237 | unsigned extend_cfg; |
238 | bool is_adp5585; | ||
239 | bool adp5585_support_row5; | ||
83 | #ifdef CONFIG_GPIOLIB | 240 | #ifdef CONFIG_GPIOLIB |
84 | unsigned char gpiomap[MAXGPIO]; | 241 | unsigned char gpiomap[ADP5589_MAXGPIO]; |
85 | bool export_gpio; | 242 | bool export_gpio; |
86 | struct gpio_chip gc; | 243 | struct gpio_chip gc; |
87 | struct mutex gpio_lock; /* Protect cached dir, dat_out */ | 244 | struct mutex gpio_lock; /* Protect cached dir, dat_out */ |
@@ -90,6 +247,129 @@ struct adp5589_kpad { | |||
90 | #endif | 247 | #endif |
91 | }; | 248 | }; |
92 | 249 | ||
250 | /* | ||
251 | * ADP5589 / ADP5585 derivative / variant handling | ||
252 | */ | ||
253 | |||
254 | |||
255 | /* ADP5589 */ | ||
256 | |||
257 | static unsigned char adp5589_bank(unsigned char offset) | ||
258 | { | ||
259 | return offset >> 3; | ||
260 | } | ||
261 | |||
262 | static unsigned char adp5589_bit(unsigned char offset) | ||
263 | { | ||
264 | return 1u << (offset & 0x7); | ||
265 | } | ||
266 | |||
267 | static unsigned char adp5589_reg(unsigned char reg) | ||
268 | { | ||
269 | return reg; | ||
270 | } | ||
271 | |||
272 | static const struct adp_constants const_adp5589 = { | ||
273 | .maxgpio = ADP5589_MAXGPIO, | ||
274 | .keymapsize = ADP5589_KEYMAPSIZE, | ||
275 | .gpi_pin_row_base = ADP5589_GPI_PIN_ROW_BASE, | ||
276 | .gpi_pin_row_end = ADP5589_GPI_PIN_ROW_END, | ||
277 | .gpi_pin_col_base = ADP5589_GPI_PIN_COL_BASE, | ||
278 | .gpi_pin_base = ADP5589_GPI_PIN_BASE, | ||
279 | .gpi_pin_end = ADP5589_GPI_PIN_END, | ||
280 | .gpimapsize_max = ADP5589_GPIMAPSIZE_MAX, | ||
281 | .c4_extend_cfg = 12, | ||
282 | .max_row_num = ADP5589_MAX_ROW_NUM, | ||
283 | .max_col_num = ADP5589_MAX_COL_NUM, | ||
284 | .row_mask = ADP5589_ROW_MASK, | ||
285 | .col_mask = ADP5589_COL_MASK, | ||
286 | .col_shift = ADP5589_COL_SHIFT, | ||
287 | .bank = adp5589_bank, | ||
288 | .bit = adp5589_bit, | ||
289 | .reg = adp5589_reg, | ||
290 | }; | ||
291 | |||
292 | /* ADP5585 */ | ||
293 | |||
294 | static unsigned char adp5585_bank(unsigned char offset) | ||
295 | { | ||
296 | return offset > ADP5585_MAX_ROW_NUM; | ||
297 | } | ||
298 | |||
299 | static unsigned char adp5585_bit(unsigned char offset) | ||
300 | { | ||
301 | return (offset > ADP5585_MAX_ROW_NUM) ? | ||
302 | 1u << (offset - ADP5585_COL_SHIFT) : 1u << offset; | ||
303 | } | ||
304 | |||
305 | static const unsigned char adp5585_reg_lut[] = { | ||
306 | [ADP5589_GPI_STATUS_A] = ADP5585_GPI_STATUS_A, | ||
307 | [ADP5589_GPI_STATUS_B] = ADP5585_GPI_STATUS_B, | ||
308 | [ADP5589_RPULL_CONFIG_A] = ADP5585_RPULL_CONFIG_A, | ||
309 | [ADP5589_RPULL_CONFIG_B] = ADP5585_RPULL_CONFIG_B, | ||
310 | [ADP5589_RPULL_CONFIG_C] = ADP5585_RPULL_CONFIG_C, | ||
311 | [ADP5589_RPULL_CONFIG_D] = ADP5585_RPULL_CONFIG_D, | ||
312 | [ADP5589_GPI_INT_LEVEL_A] = ADP5585_GPI_INT_LEVEL_A, | ||
313 | [ADP5589_GPI_INT_LEVEL_B] = ADP5585_GPI_INT_LEVEL_B, | ||
314 | [ADP5589_GPI_EVENT_EN_A] = ADP5585_GPI_EVENT_EN_A, | ||
315 | [ADP5589_GPI_EVENT_EN_B] = ADP5585_GPI_EVENT_EN_B, | ||
316 | [ADP5589_GPI_INTERRUPT_EN_A] = ADP5585_GPI_INTERRUPT_EN_A, | ||
317 | [ADP5589_GPI_INTERRUPT_EN_B] = ADP5585_GPI_INTERRUPT_EN_B, | ||
318 | [ADP5589_DEBOUNCE_DIS_A] = ADP5585_DEBOUNCE_DIS_A, | ||
319 | [ADP5589_DEBOUNCE_DIS_B] = ADP5585_DEBOUNCE_DIS_B, | ||
320 | [ADP5589_GPO_DATA_OUT_A] = ADP5585_GPO_DATA_OUT_A, | ||
321 | [ADP5589_GPO_DATA_OUT_B] = ADP5585_GPO_DATA_OUT_B, | ||
322 | [ADP5589_GPO_OUT_MODE_A] = ADP5585_GPO_OUT_MODE_A, | ||
323 | [ADP5589_GPO_OUT_MODE_B] = ADP5585_GPO_OUT_MODE_B, | ||
324 | [ADP5589_GPIO_DIRECTION_A] = ADP5585_GPIO_DIRECTION_A, | ||
325 | [ADP5589_GPIO_DIRECTION_B] = ADP5585_GPIO_DIRECTION_B, | ||
326 | [ADP5589_RESET1_EVENT_A] = ADP5585_RESET1_EVENT_A, | ||
327 | [ADP5589_RESET1_EVENT_B] = ADP5585_RESET1_EVENT_B, | ||
328 | [ADP5589_RESET1_EVENT_C] = ADP5585_RESET1_EVENT_C, | ||
329 | [ADP5589_RESET2_EVENT_A] = ADP5585_RESET2_EVENT_A, | ||
330 | [ADP5589_RESET2_EVENT_B] = ADP5585_RESET2_EVENT_B, | ||
331 | [ADP5589_RESET_CFG] = ADP5585_RESET_CFG, | ||
332 | [ADP5589_PWM_OFFT_LOW] = ADP5585_PWM_OFFT_LOW, | ||
333 | [ADP5589_PWM_OFFT_HIGH] = ADP5585_PWM_OFFT_HIGH, | ||
334 | [ADP5589_PWM_ONT_LOW] = ADP5585_PWM_ONT_LOW, | ||
335 | [ADP5589_PWM_ONT_HIGH] = ADP5585_PWM_ONT_HIGH, | ||
336 | [ADP5589_PWM_CFG] = ADP5585_PWM_CFG, | ||
337 | [ADP5589_LOGIC_1_CFG] = ADP5585_LOGIC_CFG, | ||
338 | [ADP5589_LOGIC_FF_CFG] = ADP5585_LOGIC_FF_CFG, | ||
339 | [ADP5589_LOGIC_INT_EVENT_EN] = ADP5585_LOGIC_INT_EVENT_EN, | ||
340 | [ADP5589_POLL_PTIME_CFG] = ADP5585_POLL_PTIME_CFG, | ||
341 | [ADP5589_PIN_CONFIG_A] = ADP5585_PIN_CONFIG_A, | ||
342 | [ADP5589_PIN_CONFIG_B] = ADP5585_PIN_CONFIG_B, | ||
343 | [ADP5589_PIN_CONFIG_D] = ADP5585_PIN_CONFIG_D, | ||
344 | [ADP5589_GENERAL_CFG] = ADP5585_GENERAL_CFG, | ||
345 | [ADP5589_INT_EN] = ADP5585_INT_EN, | ||
346 | }; | ||
347 | |||
348 | static unsigned char adp5585_reg(unsigned char reg) | ||
349 | { | ||
350 | return adp5585_reg_lut[reg]; | ||
351 | } | ||
352 | |||
353 | static const struct adp_constants const_adp5585 = { | ||
354 | .maxgpio = ADP5585_MAXGPIO, | ||
355 | .keymapsize = ADP5585_KEYMAPSIZE, | ||
356 | .gpi_pin_row_base = ADP5585_GPI_PIN_ROW_BASE, | ||
357 | .gpi_pin_row_end = ADP5585_GPI_PIN_ROW_END, | ||
358 | .gpi_pin_col_base = ADP5585_GPI_PIN_COL_BASE, | ||
359 | .gpi_pin_base = ADP5585_GPI_PIN_BASE, | ||
360 | .gpi_pin_end = ADP5585_GPI_PIN_END, | ||
361 | .gpimapsize_max = ADP5585_GPIMAPSIZE_MAX, | ||
362 | .c4_extend_cfg = 10, | ||
363 | .max_row_num = ADP5585_MAX_ROW_NUM, | ||
364 | .max_col_num = ADP5585_MAX_COL_NUM, | ||
365 | .row_mask = ADP5585_ROW_MASK, | ||
366 | .col_mask = ADP5585_COL_MASK, | ||
367 | .col_shift = ADP5585_COL_SHIFT, | ||
368 | .bank = adp5585_bank, | ||
369 | .bit = adp5585_bit, | ||
370 | .reg = adp5585_reg, | ||
371 | }; | ||
372 | |||
93 | static int adp5589_read(struct i2c_client *client, u8 reg) | 373 | static int adp5589_read(struct i2c_client *client, u8 reg) |
94 | { | 374 | { |
95 | int ret = i2c_smbus_read_byte_data(client, reg); | 375 | int ret = i2c_smbus_read_byte_data(client, reg); |
@@ -109,19 +389,20 @@ static int adp5589_write(struct i2c_client *client, u8 reg, u8 val) | |||
109 | static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off) | 389 | static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off) |
110 | { | 390 | { |
111 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | 391 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); |
112 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | 392 | unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); |
113 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | 393 | unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); |
114 | 394 | ||
115 | return !!(adp5589_read(kpad->client, ADP5589_GPI_STATUS_A + bank) & | 395 | return !!(adp5589_read(kpad->client, |
116 | bit); | 396 | kpad->var->reg(ADP5589_GPI_STATUS_A) + bank) & |
397 | bit); | ||
117 | } | 398 | } |
118 | 399 | ||
119 | static void adp5589_gpio_set_value(struct gpio_chip *chip, | 400 | static void adp5589_gpio_set_value(struct gpio_chip *chip, |
120 | unsigned off, int val) | 401 | unsigned off, int val) |
121 | { | 402 | { |
122 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | 403 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); |
123 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | 404 | unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); |
124 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | 405 | unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); |
125 | 406 | ||
126 | mutex_lock(&kpad->gpio_lock); | 407 | mutex_lock(&kpad->gpio_lock); |
127 | 408 | ||
@@ -130,8 +411,8 @@ static void adp5589_gpio_set_value(struct gpio_chip *chip, | |||
130 | else | 411 | else |
131 | kpad->dat_out[bank] &= ~bit; | 412 | kpad->dat_out[bank] &= ~bit; |
132 | 413 | ||
133 | adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank, | 414 | adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A) + |
134 | kpad->dat_out[bank]); | 415 | bank, kpad->dat_out[bank]); |
135 | 416 | ||
136 | mutex_unlock(&kpad->gpio_lock); | 417 | mutex_unlock(&kpad->gpio_lock); |
137 | } | 418 | } |
@@ -139,14 +420,15 @@ static void adp5589_gpio_set_value(struct gpio_chip *chip, | |||
139 | static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off) | 420 | static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off) |
140 | { | 421 | { |
141 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | 422 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); |
142 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | 423 | unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); |
143 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | 424 | unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); |
144 | int ret; | 425 | int ret; |
145 | 426 | ||
146 | mutex_lock(&kpad->gpio_lock); | 427 | mutex_lock(&kpad->gpio_lock); |
147 | 428 | ||
148 | kpad->dir[bank] &= ~bit; | 429 | kpad->dir[bank] &= ~bit; |
149 | ret = adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank, | 430 | ret = adp5589_write(kpad->client, |
431 | kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank, | ||
150 | kpad->dir[bank]); | 432 | kpad->dir[bank]); |
151 | 433 | ||
152 | mutex_unlock(&kpad->gpio_lock); | 434 | mutex_unlock(&kpad->gpio_lock); |
@@ -158,8 +440,8 @@ static int adp5589_gpio_direction_output(struct gpio_chip *chip, | |||
158 | unsigned off, int val) | 440 | unsigned off, int val) |
159 | { | 441 | { |
160 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); | 442 | struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc); |
161 | unsigned int bank = ADP_BANK(kpad->gpiomap[off]); | 443 | unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); |
162 | unsigned int bit = ADP_BIT(kpad->gpiomap[off]); | 444 | unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); |
163 | int ret; | 445 | int ret; |
164 | 446 | ||
165 | mutex_lock(&kpad->gpio_lock); | 447 | mutex_lock(&kpad->gpio_lock); |
@@ -171,9 +453,10 @@ static int adp5589_gpio_direction_output(struct gpio_chip *chip, | |||
171 | else | 453 | else |
172 | kpad->dat_out[bank] &= ~bit; | 454 | kpad->dat_out[bank] &= ~bit; |
173 | 455 | ||
174 | ret = adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank, | 456 | ret = adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A) |
175 | kpad->dat_out[bank]); | 457 | + bank, kpad->dat_out[bank]); |
176 | ret |= adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank, | 458 | ret |= adp5589_write(kpad->client, |
459 | kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank, | ||
177 | kpad->dir[bank]); | 460 | kpad->dir[bank]); |
178 | 461 | ||
179 | mutex_unlock(&kpad->gpio_lock); | 462 | mutex_unlock(&kpad->gpio_lock); |
@@ -184,26 +467,29 @@ static int adp5589_gpio_direction_output(struct gpio_chip *chip, | |||
184 | static int __devinit adp5589_build_gpiomap(struct adp5589_kpad *kpad, | 467 | static int __devinit adp5589_build_gpiomap(struct adp5589_kpad *kpad, |
185 | const struct adp5589_kpad_platform_data *pdata) | 468 | const struct adp5589_kpad_platform_data *pdata) |
186 | { | 469 | { |
187 | bool pin_used[MAXGPIO]; | 470 | bool pin_used[ADP5589_MAXGPIO]; |
188 | int n_unused = 0; | 471 | int n_unused = 0; |
189 | int i; | 472 | int i; |
190 | 473 | ||
191 | memset(pin_used, false, sizeof(pin_used)); | 474 | memset(pin_used, false, sizeof(pin_used)); |
192 | 475 | ||
193 | for (i = 0; i < MAXGPIO; i++) | 476 | for (i = 0; i < kpad->var->maxgpio; i++) |
194 | if (pdata->keypad_en_mask & (1 << i)) | 477 | if (pdata->keypad_en_mask & (1 << i)) |
195 | pin_used[i] = true; | 478 | pin_used[i] = true; |
196 | 479 | ||
197 | for (i = 0; i < kpad->gpimapsize; i++) | 480 | for (i = 0; i < kpad->gpimapsize; i++) |
198 | pin_used[kpad->gpimap[i].pin - ADP5589_GPI_PIN_BASE] = true; | 481 | pin_used[kpad->gpimap[i].pin - kpad->var->gpi_pin_base] = true; |
199 | 482 | ||
200 | if (kpad->extend_cfg & R4_EXTEND_CFG) | 483 | if (kpad->extend_cfg & R4_EXTEND_CFG) |
201 | pin_used[4] = true; | 484 | pin_used[4] = true; |
202 | 485 | ||
203 | if (kpad->extend_cfg & C4_EXTEND_CFG) | 486 | if (kpad->extend_cfg & C4_EXTEND_CFG) |
204 | pin_used[12] = true; | 487 | pin_used[kpad->var->c4_extend_cfg] = true; |
488 | |||
489 | if (!kpad->adp5585_support_row5) | ||
490 | pin_used[5] = true; | ||
205 | 491 | ||
206 | for (i = 0; i < MAXGPIO; i++) | 492 | for (i = 0; i < kpad->var->maxgpio; i++) |
207 | if (!pin_used[i]) | 493 | if (!pin_used[i]) |
208 | kpad->gpiomap[n_unused++] = i; | 494 | kpad->gpiomap[n_unused++] = i; |
209 | 495 | ||
@@ -246,11 +532,11 @@ static int __devinit adp5589_gpio_add(struct adp5589_kpad *kpad) | |||
246 | return error; | 532 | return error; |
247 | } | 533 | } |
248 | 534 | ||
249 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) { | 535 | for (i = 0; i <= kpad->var->bank(kpad->var->maxgpio); i++) { |
250 | kpad->dat_out[i] = adp5589_read(kpad->client, | 536 | kpad->dat_out[i] = adp5589_read(kpad->client, kpad->var->reg( |
251 | ADP5589_GPO_DATA_OUT_A + i); | 537 | ADP5589_GPO_DATA_OUT_A) + i); |
252 | kpad->dir[i] = adp5589_read(kpad->client, | 538 | kpad->dir[i] = adp5589_read(kpad->client, kpad->var->reg( |
253 | ADP5589_GPIO_DIRECTION_A + i); | 539 | ADP5589_GPIO_DIRECTION_A) + i); |
254 | } | 540 | } |
255 | 541 | ||
256 | if (gpio_data->setup) { | 542 | if (gpio_data->setup) { |
@@ -317,11 +603,11 @@ static void adp5589_report_events(struct adp5589_kpad *kpad, int ev_cnt) | |||
317 | int i; | 603 | int i; |
318 | 604 | ||
319 | for (i = 0; i < ev_cnt; i++) { | 605 | for (i = 0; i < ev_cnt; i++) { |
320 | int key = adp5589_read(kpad->client, ADP5589_FIFO_1 + i); | 606 | int key = adp5589_read(kpad->client, ADP5589_5_FIFO_1 + i); |
321 | int key_val = key & KEY_EV_MASK; | 607 | int key_val = key & KEY_EV_MASK; |
322 | 608 | ||
323 | if (key_val >= ADP5589_GPI_PIN_BASE && | 609 | if (key_val >= kpad->var->gpi_pin_base && |
324 | key_val <= ADP5589_GPI_PIN_END) { | 610 | key_val <= kpad->var->gpi_pin_end) { |
325 | adp5589_report_switches(kpad, key, key_val); | 611 | adp5589_report_switches(kpad, key, key_val); |
326 | } else { | 612 | } else { |
327 | input_report_key(kpad->input, | 613 | input_report_key(kpad->input, |
@@ -337,29 +623,30 @@ static irqreturn_t adp5589_irq(int irq, void *handle) | |||
337 | struct i2c_client *client = kpad->client; | 623 | struct i2c_client *client = kpad->client; |
338 | int status, ev_cnt; | 624 | int status, ev_cnt; |
339 | 625 | ||
340 | status = adp5589_read(client, ADP5589_INT_STATUS); | 626 | status = adp5589_read(client, ADP5589_5_INT_STATUS); |
341 | 627 | ||
342 | if (status & OVRFLOW_INT) /* Unlikely and should never happen */ | 628 | if (status & OVRFLOW_INT) /* Unlikely and should never happen */ |
343 | dev_err(&client->dev, "Event Overflow Error\n"); | 629 | dev_err(&client->dev, "Event Overflow Error\n"); |
344 | 630 | ||
345 | if (status & EVENT_INT) { | 631 | if (status & EVENT_INT) { |
346 | ev_cnt = adp5589_read(client, ADP5589_STATUS) & KEC; | 632 | ev_cnt = adp5589_read(client, ADP5589_5_STATUS) & KEC; |
347 | if (ev_cnt) { | 633 | if (ev_cnt) { |
348 | adp5589_report_events(kpad, ev_cnt); | 634 | adp5589_report_events(kpad, ev_cnt); |
349 | input_sync(kpad->input); | 635 | input_sync(kpad->input); |
350 | } | 636 | } |
351 | } | 637 | } |
352 | 638 | ||
353 | adp5589_write(client, ADP5589_INT_STATUS, status); /* Status is W1C */ | 639 | adp5589_write(client, ADP5589_5_INT_STATUS, status); /* Status is W1C */ |
354 | 640 | ||
355 | return IRQ_HANDLED; | 641 | return IRQ_HANDLED; |
356 | } | 642 | } |
357 | 643 | ||
358 | static int __devinit adp5589_get_evcode(struct adp5589_kpad *kpad, unsigned short key) | 644 | static int __devinit adp5589_get_evcode(struct adp5589_kpad *kpad, |
645 | unsigned short key) | ||
359 | { | 646 | { |
360 | int i; | 647 | int i; |
361 | 648 | ||
362 | for (i = 0; i < ADP5589_KEYMAPSIZE; i++) | 649 | for (i = 0; i < kpad->var->keymapsize; i++) |
363 | if (key == kpad->keycode[i]) | 650 | if (key == kpad->keycode[i]) |
364 | return (i + 1) | KEY_EV_PRESSED; | 651 | return (i + 1) | KEY_EV_PRESSED; |
365 | 652 | ||
@@ -372,19 +659,23 @@ static int __devinit adp5589_setup(struct adp5589_kpad *kpad) | |||
372 | { | 659 | { |
373 | struct i2c_client *client = kpad->client; | 660 | struct i2c_client *client = kpad->client; |
374 | const struct adp5589_kpad_platform_data *pdata = | 661 | const struct adp5589_kpad_platform_data *pdata = |
375 | client->dev.platform_data; | 662 | client->dev.platform_data; |
376 | int i, ret; | 663 | u8 (*reg) (u8) = kpad->var->reg; |
377 | unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0; | 664 | unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0; |
378 | unsigned char pull_mask = 0; | 665 | unsigned char pull_mask = 0; |
666 | int i, ret; | ||
667 | |||
668 | ret = adp5589_write(client, reg(ADP5589_PIN_CONFIG_A), | ||
669 | pdata->keypad_en_mask & kpad->var->row_mask); | ||
670 | ret |= adp5589_write(client, reg(ADP5589_PIN_CONFIG_B), | ||
671 | (pdata->keypad_en_mask >> kpad->var->col_shift) & | ||
672 | kpad->var->col_mask); | ||
379 | 673 | ||
380 | ret = adp5589_write(client, ADP5589_PIN_CONFIG_A, | 674 | if (!kpad->is_adp5585) |
381 | pdata->keypad_en_mask & 0xFF); | 675 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_C, |
382 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_B, | 676 | (pdata->keypad_en_mask >> 16) & 0xFF); |
383 | (pdata->keypad_en_mask >> 8) & 0xFF); | ||
384 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_C, | ||
385 | (pdata->keypad_en_mask >> 16) & 0xFF); | ||
386 | 677 | ||
387 | if (pdata->en_keylock) { | 678 | if (!kpad->is_adp5585 && pdata->en_keylock) { |
388 | ret |= adp5589_write(client, ADP5589_UNLOCK1, | 679 | ret |= adp5589_write(client, ADP5589_UNLOCK1, |
389 | pdata->unlock_key1); | 680 | pdata->unlock_key1); |
390 | ret |= adp5589_write(client, ADP5589_UNLOCK2, | 681 | ret |= adp5589_write(client, ADP5589_UNLOCK2, |
@@ -395,96 +686,130 @@ static int __devinit adp5589_setup(struct adp5589_kpad *kpad) | |||
395 | } | 686 | } |
396 | 687 | ||
397 | for (i = 0; i < KEYP_MAX_EVENT; i++) | 688 | for (i = 0; i < KEYP_MAX_EVENT; i++) |
398 | ret |= adp5589_read(client, ADP5589_FIFO_1 + i); | 689 | ret |= adp5589_read(client, ADP5589_5_FIFO_1 + i); |
399 | 690 | ||
400 | for (i = 0; i < pdata->gpimapsize; i++) { | 691 | for (i = 0; i < pdata->gpimapsize; i++) { |
401 | unsigned short pin = pdata->gpimap[i].pin; | 692 | unsigned short pin = pdata->gpimap[i].pin; |
402 | 693 | ||
403 | if (pin <= ADP5589_GPI_PIN_ROW_END) { | 694 | if (pin <= kpad->var->gpi_pin_row_end) { |
404 | evt_mode1 |= (1 << (pin - ADP5589_GPI_PIN_ROW_BASE)); | 695 | evt_mode1 |= (1 << (pin - kpad->var->gpi_pin_row_base)); |
405 | } else { | 696 | } else { |
406 | evt_mode2 |= | 697 | evt_mode2 |= |
407 | ((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) & 0xFF); | 698 | ((1 << (pin - kpad->var->gpi_pin_col_base)) & 0xFF); |
408 | evt_mode3 |= | 699 | if (!kpad->is_adp5585) |
409 | ((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) >> 8); | 700 | evt_mode3 |= ((1 << (pin - |
701 | kpad->var->gpi_pin_col_base)) >> 8); | ||
410 | } | 702 | } |
411 | } | 703 | } |
412 | 704 | ||
413 | if (pdata->gpimapsize) { | 705 | if (pdata->gpimapsize) { |
414 | ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_A, evt_mode1); | 706 | ret |= adp5589_write(client, reg(ADP5589_GPI_EVENT_EN_A), |
415 | ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_B, evt_mode2); | 707 | evt_mode1); |
416 | ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_C, evt_mode3); | 708 | ret |= adp5589_write(client, reg(ADP5589_GPI_EVENT_EN_B), |
709 | evt_mode2); | ||
710 | if (!kpad->is_adp5585) | ||
711 | ret |= adp5589_write(client, | ||
712 | reg(ADP5589_GPI_EVENT_EN_C), | ||
713 | evt_mode3); | ||
417 | } | 714 | } |
418 | 715 | ||
419 | if (pdata->pull_dis_mask & pdata->pullup_en_100k & | 716 | if (pdata->pull_dis_mask & pdata->pullup_en_100k & |
420 | pdata->pullup_en_300k & pdata->pulldown_en_300k) | 717 | pdata->pullup_en_300k & pdata->pulldown_en_300k) |
421 | dev_warn(&client->dev, "Conflicting pull resistor config\n"); | 718 | dev_warn(&client->dev, "Conflicting pull resistor config\n"); |
422 | 719 | ||
423 | for (i = 0; i < MAXGPIO; i++) { | 720 | for (i = 0; i <= kpad->var->max_row_num; i++) { |
424 | unsigned val = 0; | 721 | unsigned val = 0, bit = (1 << i); |
722 | if (pdata->pullup_en_300k & bit) | ||
723 | val = 0; | ||
724 | else if (pdata->pulldown_en_300k & bit) | ||
725 | val = 1; | ||
726 | else if (pdata->pullup_en_100k & bit) | ||
727 | val = 2; | ||
728 | else if (pdata->pull_dis_mask & bit) | ||
729 | val = 3; | ||
730 | |||
731 | pull_mask |= val << (2 * (i & 0x3)); | ||
732 | |||
733 | if (i == 3 || i == kpad->var->max_row_num) { | ||
734 | ret |= adp5589_write(client, reg(ADP5585_RPULL_CONFIG_A) | ||
735 | + (i >> 2), pull_mask); | ||
736 | pull_mask = 0; | ||
737 | } | ||
738 | } | ||
425 | 739 | ||
426 | if (pdata->pullup_en_300k & (1 << i)) | 740 | for (i = 0; i <= kpad->var->max_col_num; i++) { |
741 | unsigned val = 0, bit = 1 << (i + kpad->var->col_shift); | ||
742 | if (pdata->pullup_en_300k & bit) | ||
427 | val = 0; | 743 | val = 0; |
428 | else if (pdata->pulldown_en_300k & (1 << i)) | 744 | else if (pdata->pulldown_en_300k & bit) |
429 | val = 1; | 745 | val = 1; |
430 | else if (pdata->pullup_en_100k & (1 << i)) | 746 | else if (pdata->pullup_en_100k & bit) |
431 | val = 2; | 747 | val = 2; |
432 | else if (pdata->pull_dis_mask & (1 << i)) | 748 | else if (pdata->pull_dis_mask & bit) |
433 | val = 3; | 749 | val = 3; |
434 | 750 | ||
435 | pull_mask |= val << (2 * (i & 0x3)); | 751 | pull_mask |= val << (2 * (i & 0x3)); |
436 | 752 | ||
437 | if ((i & 0x3) == 0x3 || i == MAXGPIO - 1) { | 753 | if (i == 3 || i == kpad->var->max_col_num) { |
438 | ret |= adp5589_write(client, | 754 | ret |= adp5589_write(client, |
439 | ADP5589_RPULL_CONFIG_A + (i >> 2), | 755 | reg(ADP5585_RPULL_CONFIG_C) + |
440 | pull_mask); | 756 | (i >> 2), pull_mask); |
441 | pull_mask = 0; | 757 | pull_mask = 0; |
442 | } | 758 | } |
443 | } | 759 | } |
444 | 760 | ||
445 | if (pdata->reset1_key_1 && pdata->reset1_key_2 && pdata->reset1_key_3) { | 761 | if (pdata->reset1_key_1 && pdata->reset1_key_2 && pdata->reset1_key_3) { |
446 | ret |= adp5589_write(client, ADP5589_RESET1_EVENT_A, | 762 | ret |= adp5589_write(client, reg(ADP5589_RESET1_EVENT_A), |
447 | adp5589_get_evcode(kpad, | 763 | adp5589_get_evcode(kpad, |
448 | pdata->reset1_key_1)); | 764 | pdata->reset1_key_1)); |
449 | ret |= adp5589_write(client, ADP5589_RESET1_EVENT_B, | 765 | ret |= adp5589_write(client, reg(ADP5589_RESET1_EVENT_B), |
450 | adp5589_get_evcode(kpad, | 766 | adp5589_get_evcode(kpad, |
451 | pdata->reset1_key_2)); | 767 | pdata->reset1_key_2)); |
452 | ret |= adp5589_write(client, ADP5589_RESET1_EVENT_C, | 768 | ret |= adp5589_write(client, reg(ADP5589_RESET1_EVENT_C), |
453 | adp5589_get_evcode(kpad, | 769 | adp5589_get_evcode(kpad, |
454 | pdata->reset1_key_3)); | 770 | pdata->reset1_key_3)); |
455 | kpad->extend_cfg |= R4_EXTEND_CFG; | 771 | kpad->extend_cfg |= R4_EXTEND_CFG; |
456 | } | 772 | } |
457 | 773 | ||
458 | if (pdata->reset2_key_1 && pdata->reset2_key_2) { | 774 | if (pdata->reset2_key_1 && pdata->reset2_key_2) { |
459 | ret |= adp5589_write(client, ADP5589_RESET2_EVENT_A, | 775 | ret |= adp5589_write(client, reg(ADP5589_RESET2_EVENT_A), |
460 | adp5589_get_evcode(kpad, | 776 | adp5589_get_evcode(kpad, |
461 | pdata->reset2_key_1)); | 777 | pdata->reset2_key_1)); |
462 | ret |= adp5589_write(client, ADP5589_RESET2_EVENT_B, | 778 | ret |= adp5589_write(client, reg(ADP5589_RESET2_EVENT_B), |
463 | adp5589_get_evcode(kpad, | 779 | adp5589_get_evcode(kpad, |
464 | pdata->reset2_key_2)); | 780 | pdata->reset2_key_2)); |
465 | kpad->extend_cfg |= C4_EXTEND_CFG; | 781 | kpad->extend_cfg |= C4_EXTEND_CFG; |
466 | } | 782 | } |
467 | 783 | ||
468 | if (kpad->extend_cfg) { | 784 | if (kpad->extend_cfg) { |
469 | ret |= adp5589_write(client, ADP5589_RESET_CFG, | 785 | ret |= adp5589_write(client, reg(ADP5589_RESET_CFG), |
470 | pdata->reset_cfg); | 786 | pdata->reset_cfg); |
471 | ret |= adp5589_write(client, ADP5589_PIN_CONFIG_D, | 787 | ret |= adp5589_write(client, reg(ADP5589_PIN_CONFIG_D), |
472 | kpad->extend_cfg); | 788 | kpad->extend_cfg); |
473 | } | 789 | } |
474 | 790 | ||
475 | for (i = 0; i <= ADP_BANK(MAXGPIO); i++) | 791 | ret |= adp5589_write(client, reg(ADP5589_DEBOUNCE_DIS_A), |
476 | ret |= adp5589_write(client, ADP5589_DEBOUNCE_DIS_A + i, | 792 | pdata->debounce_dis_mask & kpad->var->row_mask); |
477 | pdata->debounce_dis_mask >> (i * 8)); | ||
478 | 793 | ||
479 | ret |= adp5589_write(client, ADP5589_POLL_PTIME_CFG, | 794 | ret |= adp5589_write(client, reg(ADP5589_DEBOUNCE_DIS_B), |
795 | (pdata->debounce_dis_mask >> kpad->var->col_shift) | ||
796 | & kpad->var->col_mask); | ||
797 | |||
798 | if (!kpad->is_adp5585) | ||
799 | ret |= adp5589_write(client, reg(ADP5589_DEBOUNCE_DIS_C), | ||
800 | (pdata->debounce_dis_mask >> 16) & 0xFF); | ||
801 | |||
802 | ret |= adp5589_write(client, reg(ADP5589_POLL_PTIME_CFG), | ||
480 | pdata->scan_cycle_time & PTIME_MASK); | 803 | pdata->scan_cycle_time & PTIME_MASK); |
481 | ret |= adp5589_write(client, ADP5589_INT_STATUS, LOGIC2_INT | | 804 | ret |= adp5589_write(client, ADP5589_5_INT_STATUS, |
482 | LOGIC1_INT | OVRFLOW_INT | LOCK_INT | | 805 | (kpad->is_adp5585 ? 0 : LOGIC2_INT) | |
806 | LOGIC1_INT | OVRFLOW_INT | | ||
807 | (kpad->is_adp5585 ? 0 : LOCK_INT) | | ||
483 | GPI_INT | EVENT_INT); /* Status is W1C */ | 808 | GPI_INT | EVENT_INT); /* Status is W1C */ |
484 | 809 | ||
485 | ret |= adp5589_write(client, ADP5589_GENERAL_CFG, | 810 | ret |= adp5589_write(client, reg(ADP5589_GENERAL_CFG), |
486 | INT_CFG | OSC_EN | CORE_CLK(3)); | 811 | INT_CFG | OSC_EN | CORE_CLK(3)); |
487 | ret |= adp5589_write(client, ADP5589_INT_EN, | 812 | ret |= adp5589_write(client, reg(ADP5589_INT_EN), |
488 | OVRFLOW_IEN | GPI_IEN | EVENT_IEN); | 813 | OVRFLOW_IEN | GPI_IEN | EVENT_IEN); |
489 | 814 | ||
490 | if (ret < 0) { | 815 | if (ret < 0) { |
@@ -497,30 +822,33 @@ static int __devinit adp5589_setup(struct adp5589_kpad *kpad) | |||
497 | 822 | ||
498 | static void __devinit adp5589_report_switch_state(struct adp5589_kpad *kpad) | 823 | static void __devinit adp5589_report_switch_state(struct adp5589_kpad *kpad) |
499 | { | 824 | { |
500 | int gpi_stat1 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_A); | ||
501 | int gpi_stat2 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_B); | ||
502 | int gpi_stat3 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_C); | ||
503 | int gpi_stat_tmp, pin_loc; | 825 | int gpi_stat_tmp, pin_loc; |
504 | int i; | 826 | int i; |
827 | int gpi_stat1 = adp5589_read(kpad->client, | ||
828 | kpad->var->reg(ADP5589_GPI_STATUS_A)); | ||
829 | int gpi_stat2 = adp5589_read(kpad->client, | ||
830 | kpad->var->reg(ADP5589_GPI_STATUS_B)); | ||
831 | int gpi_stat3 = !kpad->is_adp5585 ? | ||
832 | adp5589_read(kpad->client, ADP5589_GPI_STATUS_C) : 0; | ||
505 | 833 | ||
506 | for (i = 0; i < kpad->gpimapsize; i++) { | 834 | for (i = 0; i < kpad->gpimapsize; i++) { |
507 | unsigned short pin = kpad->gpimap[i].pin; | 835 | unsigned short pin = kpad->gpimap[i].pin; |
508 | 836 | ||
509 | if (pin <= ADP5589_GPI_PIN_ROW_END) { | 837 | if (pin <= kpad->var->gpi_pin_row_end) { |
510 | gpi_stat_tmp = gpi_stat1; | 838 | gpi_stat_tmp = gpi_stat1; |
511 | pin_loc = pin - ADP5589_GPI_PIN_ROW_BASE; | 839 | pin_loc = pin - kpad->var->gpi_pin_row_base; |
512 | } else if ((pin - ADP5589_GPI_PIN_COL_BASE) < 8) { | 840 | } else if ((pin - kpad->var->gpi_pin_col_base) < 8) { |
513 | gpi_stat_tmp = gpi_stat2; | 841 | gpi_stat_tmp = gpi_stat2; |
514 | pin_loc = pin - ADP5589_GPI_PIN_COL_BASE; | 842 | pin_loc = pin - kpad->var->gpi_pin_col_base; |
515 | } else { | 843 | } else { |
516 | gpi_stat_tmp = gpi_stat3; | 844 | gpi_stat_tmp = gpi_stat3; |
517 | pin_loc = pin - ADP5589_GPI_PIN_COL_BASE - 8; | 845 | pin_loc = pin - kpad->var->gpi_pin_col_base - 8; |
518 | } | 846 | } |
519 | 847 | ||
520 | if (gpi_stat_tmp < 0) { | 848 | if (gpi_stat_tmp < 0) { |
521 | dev_err(&kpad->client->dev, | 849 | dev_err(&kpad->client->dev, |
522 | "Can't read GPIO_DAT_STAT switch" | 850 | "Can't read GPIO_DAT_STAT switch %d, default to OFF\n", |
523 | " %d default to OFF\n", pin); | 851 | pin); |
524 | gpi_stat_tmp = 0; | 852 | gpi_stat_tmp = 0; |
525 | } | 853 | } |
526 | 854 | ||
@@ -536,7 +864,8 @@ static int __devinit adp5589_probe(struct i2c_client *client, | |||
536 | const struct i2c_device_id *id) | 864 | const struct i2c_device_id *id) |
537 | { | 865 | { |
538 | struct adp5589_kpad *kpad; | 866 | struct adp5589_kpad *kpad; |
539 | const struct adp5589_kpad_platform_data *pdata; | 867 | const struct adp5589_kpad_platform_data *pdata = |
868 | client->dev.platform_data; | ||
540 | struct input_dev *input; | 869 | struct input_dev *input; |
541 | unsigned int revid; | 870 | unsigned int revid; |
542 | int ret, i; | 871 | int ret, i; |
@@ -548,56 +877,79 @@ static int __devinit adp5589_probe(struct i2c_client *client, | |||
548 | return -EIO; | 877 | return -EIO; |
549 | } | 878 | } |
550 | 879 | ||
551 | pdata = client->dev.platform_data; | ||
552 | if (!pdata) { | 880 | if (!pdata) { |
553 | dev_err(&client->dev, "no platform data?\n"); | 881 | dev_err(&client->dev, "no platform data?\n"); |
554 | return -EINVAL; | 882 | return -EINVAL; |
555 | } | 883 | } |
556 | 884 | ||
557 | if (!((pdata->keypad_en_mask & 0xFF) && | 885 | kpad = kzalloc(sizeof(*kpad), GFP_KERNEL); |
558 | (pdata->keypad_en_mask >> 8)) || !pdata->keymap) { | 886 | if (!kpad) |
887 | return -ENOMEM; | ||
888 | |||
889 | switch (id->driver_data) { | ||
890 | case ADP5585_02: | ||
891 | kpad->adp5585_support_row5 = true; | ||
892 | case ADP5585_01: | ||
893 | kpad->is_adp5585 = true; | ||
894 | kpad->var = &const_adp5585; | ||
895 | break; | ||
896 | case ADP5589: | ||
897 | kpad->var = &const_adp5589; | ||
898 | break; | ||
899 | } | ||
900 | |||
901 | if (!((pdata->keypad_en_mask & kpad->var->row_mask) && | ||
902 | (pdata->keypad_en_mask >> kpad->var->col_shift)) || | ||
903 | !pdata->keymap) { | ||
559 | dev_err(&client->dev, "no rows, cols or keymap from pdata\n"); | 904 | dev_err(&client->dev, "no rows, cols or keymap from pdata\n"); |
560 | return -EINVAL; | 905 | error = -EINVAL; |
906 | goto err_free_mem; | ||
561 | } | 907 | } |
562 | 908 | ||
563 | if (pdata->keymapsize != ADP5589_KEYMAPSIZE) { | 909 | if (pdata->keymapsize != kpad->var->keymapsize) { |
564 | dev_err(&client->dev, "invalid keymapsize\n"); | 910 | dev_err(&client->dev, "invalid keymapsize\n"); |
565 | return -EINVAL; | 911 | error = -EINVAL; |
912 | goto err_free_mem; | ||
566 | } | 913 | } |
567 | 914 | ||
568 | if (!pdata->gpimap && pdata->gpimapsize) { | 915 | if (!pdata->gpimap && pdata->gpimapsize) { |
569 | dev_err(&client->dev, "invalid gpimap from pdata\n"); | 916 | dev_err(&client->dev, "invalid gpimap from pdata\n"); |
570 | return -EINVAL; | 917 | error = -EINVAL; |
918 | goto err_free_mem; | ||
571 | } | 919 | } |
572 | 920 | ||
573 | if (pdata->gpimapsize > ADP5589_GPIMAPSIZE_MAX) { | 921 | if (pdata->gpimapsize > kpad->var->gpimapsize_max) { |
574 | dev_err(&client->dev, "invalid gpimapsize\n"); | 922 | dev_err(&client->dev, "invalid gpimapsize\n"); |
575 | return -EINVAL; | 923 | error = -EINVAL; |
924 | goto err_free_mem; | ||
576 | } | 925 | } |
577 | 926 | ||
578 | for (i = 0; i < pdata->gpimapsize; i++) { | 927 | for (i = 0; i < pdata->gpimapsize; i++) { |
579 | unsigned short pin = pdata->gpimap[i].pin; | 928 | unsigned short pin = pdata->gpimap[i].pin; |
580 | 929 | ||
581 | if (pin < ADP5589_GPI_PIN_BASE || pin > ADP5589_GPI_PIN_END) { | 930 | if (pin < kpad->var->gpi_pin_base || |
931 | pin > kpad->var->gpi_pin_end) { | ||
582 | dev_err(&client->dev, "invalid gpi pin data\n"); | 932 | dev_err(&client->dev, "invalid gpi pin data\n"); |
583 | return -EINVAL; | 933 | error = -EINVAL; |
934 | goto err_free_mem; | ||
584 | } | 935 | } |
585 | 936 | ||
586 | if ((1 << (pin - ADP5589_GPI_PIN_ROW_BASE)) & | 937 | if ((1 << (pin - kpad->var->gpi_pin_row_base)) & |
587 | pdata->keypad_en_mask) { | 938 | pdata->keypad_en_mask) { |
588 | dev_err(&client->dev, "invalid gpi row/col data\n"); | 939 | dev_err(&client->dev, "invalid gpi row/col data\n"); |
589 | return -EINVAL; | 940 | error = -EINVAL; |
941 | goto err_free_mem; | ||
590 | } | 942 | } |
591 | } | 943 | } |
592 | 944 | ||
593 | if (!client->irq) { | 945 | if (!client->irq) { |
594 | dev_err(&client->dev, "no IRQ?\n"); | 946 | dev_err(&client->dev, "no IRQ?\n"); |
595 | return -EINVAL; | 947 | error = -EINVAL; |
948 | goto err_free_mem; | ||
596 | } | 949 | } |
597 | 950 | ||
598 | kpad = kzalloc(sizeof(*kpad), GFP_KERNEL); | ||
599 | input = input_allocate_device(); | 951 | input = input_allocate_device(); |
600 | if (!kpad || !input) { | 952 | if (!input) { |
601 | error = -ENOMEM; | 953 | error = -ENOMEM; |
602 | goto err_free_mem; | 954 | goto err_free_mem; |
603 | } | 955 | } |
@@ -605,13 +957,13 @@ static int __devinit adp5589_probe(struct i2c_client *client, | |||
605 | kpad->client = client; | 957 | kpad->client = client; |
606 | kpad->input = input; | 958 | kpad->input = input; |
607 | 959 | ||
608 | ret = adp5589_read(client, ADP5589_ID); | 960 | ret = adp5589_read(client, ADP5589_5_ID); |
609 | if (ret < 0) { | 961 | if (ret < 0) { |
610 | error = ret; | 962 | error = ret; |
611 | goto err_free_mem; | 963 | goto err_free_input; |
612 | } | 964 | } |
613 | 965 | ||
614 | revid = (u8) ret & ADP5589_DEVICE_ID_MASK; | 966 | revid = (u8) ret & ADP5589_5_DEVICE_ID_MASK; |
615 | 967 | ||
616 | input->name = client->name; | 968 | input->name = client->name; |
617 | input->phys = "adp5589-keys/input0"; | 969 | input->phys = "adp5589-keys/input0"; |
@@ -652,7 +1004,7 @@ static int __devinit adp5589_probe(struct i2c_client *client, | |||
652 | error = input_register_device(input); | 1004 | error = input_register_device(input); |
653 | if (error) { | 1005 | if (error) { |
654 | dev_err(&client->dev, "unable to register input device\n"); | 1006 | dev_err(&client->dev, "unable to register input device\n"); |
655 | goto err_free_mem; | 1007 | goto err_free_input; |
656 | } | 1008 | } |
657 | 1009 | ||
658 | error = request_threaded_irq(client->irq, NULL, adp5589_irq, | 1010 | error = request_threaded_irq(client->irq, NULL, adp5589_irq, |
@@ -685,8 +1037,9 @@ err_free_irq: | |||
685 | err_unreg_dev: | 1037 | err_unreg_dev: |
686 | input_unregister_device(input); | 1038 | input_unregister_device(input); |
687 | input = NULL; | 1039 | input = NULL; |
688 | err_free_mem: | 1040 | err_free_input: |
689 | input_free_device(input); | 1041 | input_free_device(input); |
1042 | err_free_mem: | ||
690 | kfree(kpad); | 1043 | kfree(kpad); |
691 | 1044 | ||
692 | return error; | 1045 | return error; |
@@ -696,7 +1049,7 @@ static int __devexit adp5589_remove(struct i2c_client *client) | |||
696 | { | 1049 | { |
697 | struct adp5589_kpad *kpad = i2c_get_clientdata(client); | 1050 | struct adp5589_kpad *kpad = i2c_get_clientdata(client); |
698 | 1051 | ||
699 | adp5589_write(client, ADP5589_GENERAL_CFG, 0); | 1052 | adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0); |
700 | free_irq(client->irq, kpad); | 1053 | free_irq(client->irq, kpad); |
701 | input_unregister_device(kpad->input); | 1054 | input_unregister_device(kpad->input); |
702 | adp5589_gpio_remove(kpad); | 1055 | adp5589_gpio_remove(kpad); |
@@ -736,7 +1089,9 @@ static int adp5589_resume(struct device *dev) | |||
736 | static SIMPLE_DEV_PM_OPS(adp5589_dev_pm_ops, adp5589_suspend, adp5589_resume); | 1089 | static SIMPLE_DEV_PM_OPS(adp5589_dev_pm_ops, adp5589_suspend, adp5589_resume); |
737 | 1090 | ||
738 | static const struct i2c_device_id adp5589_id[] = { | 1091 | static const struct i2c_device_id adp5589_id[] = { |
739 | {"adp5589-keys", 0}, | 1092 | {"adp5589-keys", ADP5589}, |
1093 | {"adp5585-keys", ADP5585_01}, | ||
1094 | {"adp5585-02-keys", ADP5585_02}, /* Adds ROW5 to ADP5585 */ | ||
740 | {} | 1095 | {} |
741 | }; | 1096 | }; |
742 | 1097 | ||
@@ -767,4 +1122,4 @@ module_exit(adp5589_exit); | |||
767 | 1122 | ||
768 | MODULE_LICENSE("GPL"); | 1123 | MODULE_LICENSE("GPL"); |
769 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); | 1124 | MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
770 | MODULE_DESCRIPTION("ADP5589 Keypad driver"); | 1125 | MODULE_DESCRIPTION("ADP5589/ADP5585 Keypad driver"); |