@@ -200,14 +200,17 @@ struct adp5588_kpad {
u8 pull_dis[3];
};
-static int adp5588_read(struct i2c_client *client, u8 reg)
+static int adp5588_read(struct i2c_client *client, u8 reg, u8 *val)
{
int ret = i2c_smbus_read_byte_data(client, reg);
- if (ret < 0)
+ if (ret < 0) {
dev_err(&client->dev, "Read Error\n");
+ return ret;
+ }
- return ret;
+ *val = ret;
+ return 0;
}
static int adp5588_write(struct i2c_client *client, u8 reg, u8 val)
@@ -220,14 +223,17 @@ static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned int off)
struct adp5588_kpad *kpad = gpiochip_get_data(chip);
unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
- int val;
+ int error;
+ u8 val;
guard(mutex)(&kpad->gpio_lock);
if (kpad->dir[bank] & bit)
- val = kpad->dat_out[bank];
- else
- val = adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank);
+ return !!(kpad->dat_out[bank] & bit);
+
+ error = adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank, &val);
+ if (error)
+ return error;
return !!(val & bit);
}
@@ -453,10 +459,20 @@ static int adp5588_gpio_add(struct adp5588_kpad *kpad)
}
for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
- kpad->dat_out[i] = adp5588_read(kpad->client,
- GPIO_DAT_OUT1 + i);
- kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i);
- kpad->pull_dis[i] = adp5588_read(kpad->client, GPIO_PULL1 + i);
+ error = adp5588_read(kpad->client,
+ GPIO_DAT_OUT1 + i, &kpad->dat_out[i]);
+ if (error)
+ return error;
+
+ error = adp5588_read(kpad->client, GPIO_DIR1 + i,
+ &kpad->dir[i]);
+ if (error)
+ return error;
+
+ error = adp5588_read(kpad->client, GPIO_PULL1 + i,
+ &kpad->pull_dis[i]);
+ if (error)
+ return error;
}
return 0;
@@ -519,9 +535,15 @@ static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt)
int i;
for (i = 0; i < ev_cnt; i++) {
- int key = adp5588_read(kpad->client, KEY_EVENTA + i);
- int key_val = key & KEY_EV_MASK;
- int key_press = key & KEY_EV_PRESSED;
+ u8 key, key_val, key_press;
+ int error;
+
+ error = adp5588_read(kpad->client, KEY_EVENTA + i, &key);
+ if (error)
+ return;
+
+ key_val = key & KEY_EV_MASK;
+ key_press = key & KEY_EV_PRESSED;
if (key_val >= GPI_PIN_BASE && key_val <= GPI_PIN_END) {
/* gpio line used as IRQ source */
@@ -556,7 +578,8 @@ static irqreturn_t adp5588_thread_irq(int irq, void *handle)
struct i2c_client *client = kpad->client;
ktime_t target_time, now;
unsigned long delay;
- int status, ev_cnt;
+ u8 status, ev_cnt;
+ int error;
/*
* Readout needs to wait for at least 25ms after the notification
@@ -571,19 +594,23 @@ static irqreturn_t adp5588_thread_irq(int irq, void *handle)
}
}
- status = adp5588_read(client, INT_STAT);
+ error = adp5588_read(client, INT_STAT, &status);
+ if (error)
+ return IRQ_HANDLED;
if (status & ADP5588_OVR_FLOW_INT) /* Unlikely and should never happen */
dev_err(&client->dev, "Event Overflow Error\n");
if (status & ADP5588_KE_INT) {
- ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & ADP5588_KEC;
- if (ev_cnt) {
- adp5588_report_events(kpad, ev_cnt);
- input_sync(kpad->input);
- }
+ error = adp5588_read(client, KEY_LCK_EC_STAT, &ev_cnt);
+ if (error || !(ev_cnt & ADP5588_KEC))
+ goto out_irq;
+
+ adp5588_report_events(kpad, ev_cnt & ADP5588_KEC);
+ input_sync(kpad->input);
}
+out_irq:
adp5588_write(client, INT_STAT, status); /* Status is W1C */
return IRQ_HANDLED;
@@ -593,6 +620,7 @@ static int adp5588_setup(struct adp5588_kpad *kpad)
{
struct i2c_client *client = kpad->client;
int i, ret;
+ u8 dummy;
ret = adp5588_write(client, KP_GPIO1, KP_SEL(kpad->rows));
if (ret)
@@ -619,8 +647,8 @@ static int adp5588_setup(struct adp5588_kpad *kpad)
}
for (i = 0; i < KEYP_MAX_EVENT; i++) {
- ret = adp5588_read(client, KEY_EVENTA);
- if (ret < 0)
+ ret = adp5588_read(client, KEY_EVENTA, &dummy);
+ if (ret)
return ret;
}
@@ -724,8 +752,8 @@ static int adp5588_probe(struct i2c_client *client)
struct input_dev *input;
struct gpio_desc *gpio;
unsigned int revid;
- int ret;
int error;
+ u8 id;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -762,11 +790,11 @@ static int adp5588_probe(struct i2c_client *client)
fsleep(60);
}
- ret = adp5588_read(client, DEV_ID);
- if (ret < 0)
- return ret;
+ error = adp5588_read(client, DEV_ID, &id);
+ if (error)
+ return error;
- revid = ret & ADP5588_DEVICE_ID_MASK;
+ revid = id & ADP5588_DEVICE_ID_MASK;
if (WA_DELAYED_READOUT_REVID(revid))
kpad->delay = msecs_to_jiffies(WA_DELAYED_READOUT_TIME);