blob: 1a1a05d7cd4205deeb857bbfc6f5c85e6df0bc5b [file] [log] [blame]
Thomas Gleixner80503b22019-05-24 12:04:09 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Michael Hennerich88751dd2009-09-17 22:39:38 -07002/*
3 * File: drivers/input/keyboard/adp5588_keys.c
Michael Hennerich5a9003d2010-01-19 00:28:44 -08004 * Description: keypad driver for ADP5588 and ADP5587
5 * I2C QWERTY Keypad and IO Expander
Michael Hennerich88751dd2009-09-17 22:39:38 -07006 * Bugs: Enter bugs at http://blackfin.uclinux.org/
7 *
Michael Hennerich95716c02010-11-02 11:33:05 -07008 * Copyright (C) 2008-2010 Analog Devices Inc.
Michael Hennerich88751dd2009-09-17 22:39:38 -07009 */
10
Dmitry Torokhov2d115982022-05-31 14:05:22 -070011#include <linux/delay.h>
12#include <linux/errno.h>
13#include <linux/gpio/driver.h>
14#include <linux/i2c.h>
15#include <linux/input.h>
Michael Hennerich88751dd2009-09-17 22:39:38 -070016#include <linux/interrupt.h>
17#include <linux/irq.h>
Dmitry Torokhov2d115982022-05-31 14:05:22 -070018#include <linux/ktime.h>
19#include <linux/module.h>
Michael Hennerich88751dd2009-09-17 22:39:38 -070020#include <linux/platform_device.h>
Dmitry Torokhov2d115982022-05-31 14:05:22 -070021#include <linux/pm.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090022#include <linux/slab.h>
Dmitry Torokhov2d115982022-05-31 14:05:22 -070023#include <linux/timekeeping.h>
Michael Hennerich88751dd2009-09-17 22:39:38 -070024
Wolfram Sangc1a46342017-05-21 23:57:27 +020025#include <linux/platform_data/adp5588.h>
Michael Hennerich88751dd2009-09-17 22:39:38 -070026
Michael Hennerich88751dd2009-09-17 22:39:38 -070027/* Key Event Register xy */
28#define KEY_EV_PRESSED (1 << 7)
29#define KEY_EV_MASK (0x7F)
30
31#define KP_SEL(x) (0xFFFF >> (16 - x)) /* 2^x-1 */
32
33#define KEYP_MAX_EVENT 10
34
35/*
36 * Early pre 4.0 Silicon required to delay readout by at least 25ms,
37 * since the Event Counter Register updated 25ms after the interrupt
38 * asserted.
39 */
40#define WA_DELAYED_READOUT_REVID(rev) ((rev) < 4)
Dmitry Torokhov2d115982022-05-31 14:05:22 -070041#define WA_DELAYED_READOUT_TIME 25
Michael Hennerich88751dd2009-09-17 22:39:38 -070042
43struct adp5588_kpad {
44 struct i2c_client *client;
45 struct input_dev *input;
Dmitry Torokhov2d115982022-05-31 14:05:22 -070046 ktime_t irq_time;
Michael Hennerich88751dd2009-09-17 22:39:38 -070047 unsigned long delay;
48 unsigned short keycode[ADP5588_KEYMAPSIZE];
Xiaolong CHEN69a4af62010-06-24 19:10:40 -070049 const struct adp5588_gpi_map *gpimap;
50 unsigned short gpimapsize;
Xiaolong Chenba9f5072010-07-26 01:01:11 -070051#ifdef CONFIG_GPIOLIB
Michael Hennerich95716c02010-11-02 11:33:05 -070052 unsigned char gpiomap[ADP5588_MAXGPIO];
Xiaolong Chenba9f5072010-07-26 01:01:11 -070053 struct gpio_chip gc;
54 struct mutex gpio_lock; /* Protect cached dir, dat_out */
55 u8 dat_out[3];
56 u8 dir[3];
57#endif
Michael Hennerich88751dd2009-09-17 22:39:38 -070058};
59
60static int adp5588_read(struct i2c_client *client, u8 reg)
61{
62 int ret = i2c_smbus_read_byte_data(client, reg);
63
64 if (ret < 0)
65 dev_err(&client->dev, "Read Error\n");
66
67 return ret;
68}
69
70static int adp5588_write(struct i2c_client *client, u8 reg, u8 val)
71{
72 return i2c_smbus_write_byte_data(client, reg, val);
73}
74
Xiaolong Chenba9f5072010-07-26 01:01:11 -070075#ifdef CONFIG_GPIOLIB
76static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
77{
Linus Walleijd3baee32015-12-08 16:29:50 +010078 struct adp5588_kpad *kpad = gpiochip_get_data(chip);
Michael Hennerich95716c02010-11-02 11:33:05 -070079 unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
80 unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
Jean-Francois Dagenais910a9f52014-02-12 15:14:28 -080081 int val;
Xiaolong Chenba9f5072010-07-26 01:01:11 -070082
Jean-Francois Dagenais910a9f52014-02-12 15:14:28 -080083 mutex_lock(&kpad->gpio_lock);
84
85 if (kpad->dir[bank] & bit)
86 val = kpad->dat_out[bank];
87 else
88 val = adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank);
89
90 mutex_unlock(&kpad->gpio_lock);
91
92 return !!(val & bit);
Xiaolong Chenba9f5072010-07-26 01:01:11 -070093}
94
95static void adp5588_gpio_set_value(struct gpio_chip *chip,
96 unsigned off, int val)
97{
Linus Walleijd3baee32015-12-08 16:29:50 +010098 struct adp5588_kpad *kpad = gpiochip_get_data(chip);
Michael Hennerich95716c02010-11-02 11:33:05 -070099 unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
100 unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700101
102 mutex_lock(&kpad->gpio_lock);
103
104 if (val)
105 kpad->dat_out[bank] |= bit;
106 else
107 kpad->dat_out[bank] &= ~bit;
108
109 adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank,
110 kpad->dat_out[bank]);
111
112 mutex_unlock(&kpad->gpio_lock);
113}
114
115static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off)
116{
Linus Walleijd3baee32015-12-08 16:29:50 +0100117 struct adp5588_kpad *kpad = gpiochip_get_data(chip);
Michael Hennerich95716c02010-11-02 11:33:05 -0700118 unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
119 unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700120 int ret;
121
122 mutex_lock(&kpad->gpio_lock);
123
124 kpad->dir[bank] &= ~bit;
125 ret = adp5588_write(kpad->client, GPIO_DIR1 + bank, kpad->dir[bank]);
126
127 mutex_unlock(&kpad->gpio_lock);
128
129 return ret;
130}
131
132static int adp5588_gpio_direction_output(struct gpio_chip *chip,
133 unsigned off, int val)
134{
Linus Walleijd3baee32015-12-08 16:29:50 +0100135 struct adp5588_kpad *kpad = gpiochip_get_data(chip);
Michael Hennerich95716c02010-11-02 11:33:05 -0700136 unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
137 unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700138 int ret;
139
140 mutex_lock(&kpad->gpio_lock);
141
142 kpad->dir[bank] |= bit;
143
144 if (val)
145 kpad->dat_out[bank] |= bit;
146 else
147 kpad->dat_out[bank] &= ~bit;
148
149 ret = adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank,
150 kpad->dat_out[bank]);
151 ret |= adp5588_write(kpad->client, GPIO_DIR1 + bank,
152 kpad->dir[bank]);
153
154 mutex_unlock(&kpad->gpio_lock);
155
156 return ret;
157}
158
Bill Pemberton5298cc42012-11-23 21:38:25 -0800159static int adp5588_build_gpiomap(struct adp5588_kpad *kpad,
Dmitry Torokhov0d87c722010-08-02 18:33:26 -0700160 const struct adp5588_kpad_platform_data *pdata)
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700161{
Michael Hennerich95716c02010-11-02 11:33:05 -0700162 bool pin_used[ADP5588_MAXGPIO];
Dmitry Torokhov0d87c722010-08-02 18:33:26 -0700163 int n_unused = 0;
164 int i;
165
166 memset(pin_used, 0, sizeof(pin_used));
167
168 for (i = 0; i < pdata->rows; i++)
169 pin_used[i] = true;
170
171 for (i = 0; i < pdata->cols; i++)
172 pin_used[i + GPI_PIN_COL_BASE - GPI_PIN_BASE] = true;
173
174 for (i = 0; i < kpad->gpimapsize; i++)
175 pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true;
176
Michael Hennerich95716c02010-11-02 11:33:05 -0700177 for (i = 0; i < ADP5588_MAXGPIO; i++)
Dmitry Torokhov0d87c722010-08-02 18:33:26 -0700178 if (!pin_used[i])
179 kpad->gpiomap[n_unused++] = i;
180
181 return n_unused;
182}
183
Dmitry Torokhov45608822022-05-31 14:07:39 -0700184static void adp5588_gpio_do_teardown(void *_kpad)
185{
186 struct adp5588_kpad *kpad = _kpad;
187 struct device *dev = &kpad->client->dev;
188 const struct adp5588_kpad_platform_data *pdata = dev_get_platdata(dev);
189 const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
190 int error;
191
192 error = gpio_data->teardown(kpad->client,
193 kpad->gc.base, kpad->gc.ngpio,
194 gpio_data->context);
195 if (error)
196 dev_warn(&kpad->client->dev, "teardown failed %d\n", error);
197}
198
Bill Pemberton5298cc42012-11-23 21:38:25 -0800199static int adp5588_gpio_add(struct adp5588_kpad *kpad)
Dmitry Torokhov0d87c722010-08-02 18:33:26 -0700200{
201 struct device *dev = &kpad->client->dev;
Jingoo Hanc838cb32013-12-05 19:21:10 -0800202 const struct adp5588_kpad_platform_data *pdata = dev_get_platdata(dev);
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700203 const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
204 int i, error;
205
Dmitry Torokhov0d87c722010-08-02 18:33:26 -0700206 if (!gpio_data)
207 return 0;
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700208
Dmitry Torokhov0d87c722010-08-02 18:33:26 -0700209 kpad->gc.ngpio = adp5588_build_gpiomap(kpad, pdata);
210 if (kpad->gc.ngpio == 0) {
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700211 dev_info(dev, "No unused gpios left to export\n");
212 return 0;
213 }
214
215 kpad->gc.direction_input = adp5588_gpio_direction_input;
216 kpad->gc.direction_output = adp5588_gpio_direction_output;
217 kpad->gc.get = adp5588_gpio_get_value;
218 kpad->gc.set = adp5588_gpio_set_value;
219 kpad->gc.can_sleep = 1;
220
221 kpad->gc.base = gpio_data->gpio_start;
222 kpad->gc.label = kpad->client->name;
223 kpad->gc.owner = THIS_MODULE;
Jean-François Dagenaisd0a34572012-05-10 22:32:00 -0700224 kpad->gc.names = gpio_data->names;
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700225
226 mutex_init(&kpad->gpio_lock);
227
Dmitry Torokhov45608822022-05-31 14:07:39 -0700228 error = devm_gpiochip_add_data(dev, &kpad->gc, kpad);
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700229 if (error) {
Dmitry Torokhov45608822022-05-31 14:07:39 -0700230 dev_err(dev, "gpiochip_add failed: %d\n", error);
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700231 return error;
232 }
233
Michael Hennerich95716c02010-11-02 11:33:05 -0700234 for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700235 kpad->dat_out[i] = adp5588_read(kpad->client,
236 GPIO_DAT_OUT1 + i);
237 kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i);
238 }
239
240 if (gpio_data->setup) {
241 error = gpio_data->setup(kpad->client,
242 kpad->gc.base, kpad->gc.ngpio,
243 gpio_data->context);
244 if (error)
Dmitry Torokhov45608822022-05-31 14:07:39 -0700245 dev_warn(dev, "setup failed: %d\n", error);
246 }
247
248 if (gpio_data->teardown) {
249 error = devm_add_action(dev, adp5588_gpio_do_teardown, kpad);
250 if (error)
251 dev_warn(dev, "failed to schedule teardown: %d\n",
252 error);
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700253 }
254
255 return 0;
256}
257
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700258#else
Dmitry Torokhov0d87c722010-08-02 18:33:26 -0700259static inline int adp5588_gpio_add(struct adp5588_kpad *kpad)
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700260{
261 return 0;
262}
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700263#endif
264
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700265static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt)
266{
267 int i, j;
268
269 for (i = 0; i < ev_cnt; i++) {
270 int key = adp5588_read(kpad->client, Key_EVENTA + i);
271 int key_val = key & KEY_EV_MASK;
272
273 if (key_val >= GPI_PIN_BASE && key_val <= GPI_PIN_END) {
274 for (j = 0; j < kpad->gpimapsize; j++) {
275 if (key_val == kpad->gpimap[j].pin) {
276 input_report_switch(kpad->input,
277 kpad->gpimap[j].sw_evt,
278 key & KEY_EV_PRESSED);
279 break;
280 }
281 }
282 } else {
283 input_report_key(kpad->input,
284 kpad->keycode[key_val - 1],
285 key & KEY_EV_PRESSED);
286 }
287 }
288}
289
Dmitry Torokhov2d115982022-05-31 14:05:22 -0700290static irqreturn_t adp5588_hard_irq(int irq, void *handle)
Michael Hennerich88751dd2009-09-17 22:39:38 -0700291{
Dmitry Torokhov2d115982022-05-31 14:05:22 -0700292 struct adp5588_kpad *kpad = handle;
293
294 kpad->irq_time = ktime_get();
295
296 return IRQ_WAKE_THREAD;
297}
298
299static irqreturn_t adp5588_thread_irq(int irq, void *handle)
300{
301 struct adp5588_kpad *kpad = handle;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700302 struct i2c_client *client = kpad->client;
Dmitry Torokhov2d115982022-05-31 14:05:22 -0700303 ktime_t target_time, now;
304 unsigned long delay;
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700305 int status, ev_cnt;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700306
Dmitry Torokhov2d115982022-05-31 14:05:22 -0700307 /*
308 * Readout needs to wait for at least 25ms after the notification
309 * for REVID < 4.
310 */
311 if (kpad->delay) {
312 target_time = ktime_add_ms(kpad->irq_time, kpad->delay);
313 now = ktime_get();
314 if (ktime_before(now, target_time)) {
315 delay = ktime_to_us(ktime_sub(target_time, now));
316 usleep_range(delay, delay + 1000);
317 }
318 }
319
Michael Hennerich88751dd2009-09-17 22:39:38 -0700320 status = adp5588_read(client, INT_STAT);
321
Michael Hennerich95716c02010-11-02 11:33:05 -0700322 if (status & ADP5588_OVR_FLOW_INT) /* Unlikely and should never happen */
Michael Hennerich88751dd2009-09-17 22:39:38 -0700323 dev_err(&client->dev, "Event Overflow Error\n");
324
Michael Hennerich95716c02010-11-02 11:33:05 -0700325 if (status & ADP5588_KE_INT) {
326 ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & ADP5588_KEC;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700327 if (ev_cnt) {
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700328 adp5588_report_events(kpad, ev_cnt);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700329 input_sync(kpad->input);
330 }
331 }
Dmitry Torokhov2d115982022-05-31 14:05:22 -0700332
Michael Hennerich88751dd2009-09-17 22:39:38 -0700333 adp5588_write(client, INT_STAT, status); /* Status is W1C */
Michael Hennerich88751dd2009-09-17 22:39:38 -0700334
335 return IRQ_HANDLED;
336}
337
Bill Pemberton5298cc42012-11-23 21:38:25 -0800338static int adp5588_setup(struct i2c_client *client)
Michael Hennerich88751dd2009-09-17 22:39:38 -0700339{
Jingoo Hanc838cb32013-12-05 19:21:10 -0800340 const struct adp5588_kpad_platform_data *pdata =
341 dev_get_platdata(&client->dev);
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700342 const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700343 int i, ret;
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700344 unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700345
346 ret = adp5588_write(client, KP_GPIO1, KP_SEL(pdata->rows));
347 ret |= adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF);
348 ret |= adp5588_write(client, KP_GPIO3, KP_SEL(pdata->cols) >> 8);
349
350 if (pdata->en_keylock) {
351 ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1);
352 ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2);
Michael Hennerich95716c02010-11-02 11:33:05 -0700353 ret |= adp5588_write(client, KEY_LCK_EC_STAT, ADP5588_K_LCK_EN);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700354 }
355
356 for (i = 0; i < KEYP_MAX_EVENT; i++)
357 ret |= adp5588_read(client, Key_EVENTA);
358
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700359 for (i = 0; i < pdata->gpimapsize; i++) {
360 unsigned short pin = pdata->gpimap[i].pin;
361
362 if (pin <= GPI_PIN_ROW_END) {
363 evt_mode1 |= (1 << (pin - GPI_PIN_ROW_BASE));
364 } else {
365 evt_mode2 |= ((1 << (pin - GPI_PIN_COL_BASE)) & 0xFF);
366 evt_mode3 |= ((1 << (pin - GPI_PIN_COL_BASE)) >> 8);
367 }
368 }
369
370 if (pdata->gpimapsize) {
371 ret |= adp5588_write(client, GPI_EM1, evt_mode1);
372 ret |= adp5588_write(client, GPI_EM2, evt_mode2);
373 ret |= adp5588_write(client, GPI_EM3, evt_mode3);
374 }
375
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700376 if (gpio_data) {
Michael Hennerich95716c02010-11-02 11:33:05 -0700377 for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700378 int pull_mask = gpio_data->pullup_dis_mask;
379
380 ret |= adp5588_write(client, GPIO_PULL1 + i,
381 (pull_mask >> (8 * i)) & 0xFF);
382 }
383 }
384
Michael Hennerich95716c02010-11-02 11:33:05 -0700385 ret |= adp5588_write(client, INT_STAT,
386 ADP5588_CMP2_INT | ADP5588_CMP1_INT |
387 ADP5588_OVR_FLOW_INT | ADP5588_K_LCK_INT |
388 ADP5588_GPI_INT | ADP5588_KE_INT); /* Status is W1C */
Michael Hennerich88751dd2009-09-17 22:39:38 -0700389
Michael Hennerich95716c02010-11-02 11:33:05 -0700390 ret |= adp5588_write(client, CFG, ADP5588_INT_CFG |
391 ADP5588_OVR_FLOW_IEN |
392 ADP5588_KE_IEN);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700393
394 if (ret < 0) {
395 dev_err(&client->dev, "Write Error\n");
396 return ret;
397 }
398
399 return 0;
400}
401
Bill Pemberton5298cc42012-11-23 21:38:25 -0800402static void adp5588_report_switch_state(struct adp5588_kpad *kpad)
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700403{
404 int gpi_stat1 = adp5588_read(kpad->client, GPIO_DAT_STAT1);
405 int gpi_stat2 = adp5588_read(kpad->client, GPIO_DAT_STAT2);
406 int gpi_stat3 = adp5588_read(kpad->client, GPIO_DAT_STAT3);
407 int gpi_stat_tmp, pin_loc;
408 int i;
409
410 for (i = 0; i < kpad->gpimapsize; i++) {
411 unsigned short pin = kpad->gpimap[i].pin;
412
413 if (pin <= GPI_PIN_ROW_END) {
414 gpi_stat_tmp = gpi_stat1;
415 pin_loc = pin - GPI_PIN_ROW_BASE;
416 } else if ((pin - GPI_PIN_COL_BASE) < 8) {
417 gpi_stat_tmp = gpi_stat2;
418 pin_loc = pin - GPI_PIN_COL_BASE;
419 } else {
420 gpi_stat_tmp = gpi_stat3;
421 pin_loc = pin - GPI_PIN_COL_BASE - 8;
422 }
423
424 if (gpi_stat_tmp < 0) {
425 dev_err(&kpad->client->dev,
426 "Can't read GPIO_DAT_STAT switch %d default to OFF\n",
427 pin);
428 gpi_stat_tmp = 0;
429 }
430
431 input_report_switch(kpad->input,
432 kpad->gpimap[i].sw_evt,
433 !(gpi_stat_tmp & (1 << pin_loc)));
434 }
435
436 input_sync(kpad->input);
437}
438
439
Bill Pemberton5298cc42012-11-23 21:38:25 -0800440static int adp5588_probe(struct i2c_client *client,
441 const struct i2c_device_id *id)
Michael Hennerich88751dd2009-09-17 22:39:38 -0700442{
443 struct adp5588_kpad *kpad;
Jingoo Hanc838cb32013-12-05 19:21:10 -0800444 const struct adp5588_kpad_platform_data *pdata =
445 dev_get_platdata(&client->dev);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700446 struct input_dev *input;
447 unsigned int revid;
448 int ret, i;
449 int error;
450
451 if (!i2c_check_functionality(client->adapter,
452 I2C_FUNC_SMBUS_BYTE_DATA)) {
453 dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
454 return -EIO;
455 }
456
457 if (!pdata) {
458 dev_err(&client->dev, "no platform data?\n");
459 return -EINVAL;
460 }
461
462 if (!pdata->rows || !pdata->cols || !pdata->keymap) {
463 dev_err(&client->dev, "no rows, cols or keymap from pdata\n");
464 return -EINVAL;
465 }
466
467 if (pdata->keymapsize != ADP5588_KEYMAPSIZE) {
468 dev_err(&client->dev, "invalid keymapsize\n");
469 return -EINVAL;
470 }
471
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700472 if (!pdata->gpimap && pdata->gpimapsize) {
473 dev_err(&client->dev, "invalid gpimap from pdata\n");
474 return -EINVAL;
475 }
476
477 if (pdata->gpimapsize > ADP5588_GPIMAPSIZE_MAX) {
478 dev_err(&client->dev, "invalid gpimapsize\n");
479 return -EINVAL;
480 }
481
482 for (i = 0; i < pdata->gpimapsize; i++) {
483 unsigned short pin = pdata->gpimap[i].pin;
484
485 if (pin < GPI_PIN_BASE || pin > GPI_PIN_END) {
486 dev_err(&client->dev, "invalid gpi pin data\n");
487 return -EINVAL;
488 }
489
490 if (pin <= GPI_PIN_ROW_END) {
491 if (pin - GPI_PIN_ROW_BASE + 1 <= pdata->rows) {
492 dev_err(&client->dev, "invalid gpi row data\n");
493 return -EINVAL;
494 }
495 } else {
496 if (pin - GPI_PIN_COL_BASE + 1 <= pdata->cols) {
497 dev_err(&client->dev, "invalid gpi col data\n");
498 return -EINVAL;
499 }
500 }
501 }
502
Michael Hennerich88751dd2009-09-17 22:39:38 -0700503 if (!client->irq) {
504 dev_err(&client->dev, "no IRQ?\n");
505 return -EINVAL;
506 }
507
Dmitry Torokhov45608822022-05-31 14:07:39 -0700508 kpad = devm_kzalloc(&client->dev, sizeof(*kpad), GFP_KERNEL);
509 if (!kpad)
510 return -ENOMEM;
511
512 input = devm_input_allocate_device(&client->dev);
513 if (!input)
514 return -ENOMEM;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700515
516 kpad->client = client;
517 kpad->input = input;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700518
519 ret = adp5588_read(client, DEV_ID);
Dmitry Torokhov45608822022-05-31 14:07:39 -0700520 if (ret < 0)
521 return ret;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700522
523 revid = (u8) ret & ADP5588_DEVICE_ID_MASK;
524 if (WA_DELAYED_READOUT_REVID(revid))
Dmitry Torokhov2d115982022-05-31 14:05:22 -0700525 kpad->delay = msecs_to_jiffies(WA_DELAYED_READOUT_TIME);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700526
527 input->name = client->name;
528 input->phys = "adp5588-keys/input0";
Michael Hennerich88751dd2009-09-17 22:39:38 -0700529
530 input_set_drvdata(input, kpad);
531
532 input->id.bustype = BUS_I2C;
533 input->id.vendor = 0x0001;
534 input->id.product = 0x0001;
535 input->id.version = revid;
536
537 input->keycodesize = sizeof(kpad->keycode[0]);
538 input->keycodemax = pdata->keymapsize;
539 input->keycode = kpad->keycode;
540
541 memcpy(kpad->keycode, pdata->keymap,
542 pdata->keymapsize * input->keycodesize);
543
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700544 kpad->gpimap = pdata->gpimap;
545 kpad->gpimapsize = pdata->gpimapsize;
546
Michael Hennerich88751dd2009-09-17 22:39:38 -0700547 /* setup input device */
548 __set_bit(EV_KEY, input->evbit);
549
550 if (pdata->repeat)
551 __set_bit(EV_REP, input->evbit);
552
553 for (i = 0; i < input->keycodemax; i++)
Andrew Liue4cfb032013-11-23 10:06:36 -0800554 if (kpad->keycode[i] <= KEY_MAX)
555 __set_bit(kpad->keycode[i], input->keybit);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700556 __clear_bit(KEY_RESERVED, input->keybit);
557
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700558 if (kpad->gpimapsize)
559 __set_bit(EV_SW, input->evbit);
560 for (i = 0; i < kpad->gpimapsize; i++)
561 __set_bit(kpad->gpimap[i].sw_evt, input->swbit);
562
Michael Hennerich88751dd2009-09-17 22:39:38 -0700563 error = input_register_device(input);
564 if (error) {
Dmitry Torokhov45608822022-05-31 14:07:39 -0700565 dev_err(&client->dev, "unable to register input device: %d\n",
566 error);
567 return error;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700568 }
569
Dmitry Torokhov45608822022-05-31 14:07:39 -0700570 error = devm_request_threaded_irq(&client->dev, client->irq,
571 adp5588_hard_irq, adp5588_thread_irq,
572 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
573 client->dev.driver->name, kpad);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700574 if (error) {
Dmitry Torokhov45608822022-05-31 14:07:39 -0700575 dev_err(&client->dev, "failed to request irq %d: %d\n",
576 client->irq, error);
577 return error;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700578 }
579
580 error = adp5588_setup(client);
581 if (error)
Dmitry Torokhov45608822022-05-31 14:07:39 -0700582 return error;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700583
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700584 if (kpad->gpimapsize)
585 adp5588_report_switch_state(kpad);
586
Dmitry Torokhov0d87c722010-08-02 18:33:26 -0700587 error = adp5588_gpio_add(kpad);
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700588 if (error)
Dmitry Torokhov45608822022-05-31 14:07:39 -0700589 return error;
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700590
Michael Hennerich88751dd2009-09-17 22:39:38 -0700591 dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
592 return 0;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700593}
594
Bill Pembertone2619cf2012-11-23 21:50:47 -0800595static int adp5588_remove(struct i2c_client *client)
Michael Hennerich88751dd2009-09-17 22:39:38 -0700596{
Michael Hennerich88751dd2009-09-17 22:39:38 -0700597 adp5588_write(client, CFG, 0);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700598
Dmitry Torokhov45608822022-05-31 14:07:39 -0700599 /* all resources will be freed by devm */
Michael Hennerich88751dd2009-09-17 22:39:38 -0700600 return 0;
601}
602
Dmitry Torokhov6ec75b22022-05-31 14:06:01 -0700603static int __maybe_unused adp5588_suspend(struct device *dev)
Michael Hennerich88751dd2009-09-17 22:39:38 -0700604{
Dmitry Torokhov2d115982022-05-31 14:05:22 -0700605 struct i2c_client *client = to_i2c_client(dev);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700606
607 disable_irq(client->irq);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700608
Michael Hennerich88751dd2009-09-17 22:39:38 -0700609 return 0;
610}
611
Dmitry Torokhov6ec75b22022-05-31 14:06:01 -0700612static int __maybe_unused adp5588_resume(struct device *dev)
Michael Hennerich88751dd2009-09-17 22:39:38 -0700613{
Dmitry Torokhov2d115982022-05-31 14:05:22 -0700614 struct i2c_client *client = to_i2c_client(dev);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700615
Michael Hennerich88751dd2009-09-17 22:39:38 -0700616 enable_irq(client->irq);
617
618 return 0;
619}
620
Dmitry Torokhov6ec75b22022-05-31 14:06:01 -0700621static SIMPLE_DEV_PM_OPS(adp5588_dev_pm_ops, adp5588_suspend, adp5588_resume);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700622
623static const struct i2c_device_id adp5588_id[] = {
Michael Hennerichd5371552010-10-18 17:46:03 -0700624 { "adp5588-keys", 0 },
Michael Hennerich5a9003d2010-01-19 00:28:44 -0800625 { "adp5587-keys", 0 },
Michael Hennerich88751dd2009-09-17 22:39:38 -0700626 { }
627};
628MODULE_DEVICE_TABLE(i2c, adp5588_id);
629
630static struct i2c_driver adp5588_driver = {
631 .driver = {
632 .name = KBUILD_MODNAME,
Michael Hennerich88751dd2009-09-17 22:39:38 -0700633 .pm = &adp5588_dev_pm_ops,
Michael Hennerich88751dd2009-09-17 22:39:38 -0700634 },
635 .probe = adp5588_probe,
Bill Pemberton1cb0aa82012-11-23 21:27:39 -0800636 .remove = adp5588_remove,
Michael Hennerich88751dd2009-09-17 22:39:38 -0700637 .id_table = adp5588_id,
638};
639
Axel Lin1b92c1c2012-03-16 23:05:41 -0700640module_i2c_driver(adp5588_driver);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700641
642MODULE_LICENSE("GPL");
643MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
Michael Hennerich5a9003d2010-01-19 00:28:44 -0800644MODULE_DESCRIPTION("ADP5588/87 Keypad driver");