[PATCH 03/13] Input: adp5589-keys: add chip_info structure

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add a more natural chip_info structure and add it to the i2c id table
driver data so that we do not need an enum a switch() to get the
specific bits of each device.

Signed-off-by: Nuno Sa <nuno.sa@xxxxxxxxxx>
---
 drivers/input/keyboard/adp5589-keys.c | 181 ++++++++++++++++++----------------
 1 file changed, 95 insertions(+), 86 deletions(-)

diff --git a/drivers/input/keyboard/adp5589-keys.c b/drivers/input/keyboard/adp5589-keys.c
index 922d3ab998f3a5dfbaf277f10eb19e5cd1b35415..eaa5440d4f9e14352409dd880cd254354612bf3e 100644
--- a/drivers/input/keyboard/adp5589-keys.c
+++ b/drivers/input/keyboard/adp5589-keys.c
@@ -228,16 +228,20 @@ struct adp_constants {
 	u8 (*reg) (u8 reg);
 };
 
+struct adp5589_info {
+	const struct adp_constants *var;
+	bool support_row5;
+	bool is_adp5585;
+};
+
 struct adp5589_kpad {
 	struct i2c_client *client;
 	struct input_dev *input;
-	const struct adp_constants *var;
+	const struct adp5589_info *info;
 	unsigned short keycode[ADP5589_KEYMAPSIZE];
 	const struct adp5589_gpi_map *gpimap;
 	unsigned short gpimapsize;
 	unsigned extend_cfg;
-	bool is_adp5585;
-	bool support_row5;
 #ifdef CONFIG_GPIOLIB
 	unsigned char gpiomap[ADP5589_MAXGPIO];
 	struct gpio_chip gc;
@@ -389,8 +393,8 @@ static int adp5589_write(struct i2c_client *client, u8 reg, u8 val)
 static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off)
 {
 	struct adp5589_kpad *kpad = gpiochip_get_data(chip);
-	unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
-	unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
+	unsigned int bank = kpad->info->var->bank(kpad->gpiomap[off]);
+	unsigned int bit = kpad->info->var->bit(kpad->gpiomap[off]);
 	int val;
 
 	mutex_lock(&kpad->gpio_lock);
@@ -398,7 +402,7 @@ static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off)
 		val = kpad->dat_out[bank];
 	else
 		val = adp5589_read(kpad->client,
-				   kpad->var->reg(ADP5589_GPI_STATUS_A) + bank);
+				   kpad->info->var->reg(ADP5589_GPI_STATUS_A) + bank);
 	mutex_unlock(&kpad->gpio_lock);
 
 	return !!(val & bit);
@@ -408,8 +412,8 @@ static void adp5589_gpio_set_value(struct gpio_chip *chip,
 				   unsigned off, int val)
 {
 	struct adp5589_kpad *kpad = gpiochip_get_data(chip);
-	unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
-	unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
+	unsigned int bank = kpad->info->var->bank(kpad->gpiomap[off]);
+	unsigned int bit = kpad->info->var->bit(kpad->gpiomap[off]);
 
 	mutex_lock(&kpad->gpio_lock);
 
@@ -418,7 +422,7 @@ static void adp5589_gpio_set_value(struct gpio_chip *chip,
 	else
 		kpad->dat_out[bank] &= ~bit;
 
-	adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A) +
+	adp5589_write(kpad->client, kpad->info->var->reg(ADP5589_GPO_DATA_OUT_A) +
 		      bank, kpad->dat_out[bank]);
 
 	mutex_unlock(&kpad->gpio_lock);
@@ -427,15 +431,15 @@ static void adp5589_gpio_set_value(struct gpio_chip *chip,
 static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off)
 {
 	struct adp5589_kpad *kpad = gpiochip_get_data(chip);
-	unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
-	unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
+	unsigned int bank = kpad->info->var->bank(kpad->gpiomap[off]);
+	unsigned int bit = kpad->info->var->bit(kpad->gpiomap[off]);
 	int ret;
 
 	mutex_lock(&kpad->gpio_lock);
 
 	kpad->dir[bank] &= ~bit;
 	ret = adp5589_write(kpad->client,
-			    kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
+			    kpad->info->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
 			    kpad->dir[bank]);
 
 	mutex_unlock(&kpad->gpio_lock);
@@ -447,8 +451,8 @@ static int adp5589_gpio_direction_output(struct gpio_chip *chip,
 					 unsigned off, int val)
 {
 	struct adp5589_kpad *kpad = gpiochip_get_data(chip);
-	unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
-	unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
+	unsigned int bank = kpad->info->var->bank(kpad->gpiomap[off]);
+	unsigned int bit = kpad->info->var->bit(kpad->gpiomap[off]);
 	int ret;
 
 	mutex_lock(&kpad->gpio_lock);
@@ -460,10 +464,10 @@ static int adp5589_gpio_direction_output(struct gpio_chip *chip,
 	else
 		kpad->dat_out[bank] &= ~bit;
 
-	ret = adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A)
+	ret = adp5589_write(kpad->client, kpad->info->var->reg(ADP5589_GPO_DATA_OUT_A)
 			    + bank, kpad->dat_out[bank]);
 	ret |= adp5589_write(kpad->client,
-			     kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
+			     kpad->info->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
 			     kpad->dir[bank]);
 
 	mutex_unlock(&kpad->gpio_lock);
@@ -480,23 +484,23 @@ static int adp5589_build_gpiomap(struct adp5589_kpad *kpad,
 
 	memset(pin_used, false, sizeof(pin_used));
 
-	for (i = 0; i < kpad->var->maxgpio; i++)
+	for (i = 0; i < kpad->info->var->maxgpio; i++)
 		if (pdata->keypad_en_mask & BIT(i))
 			pin_used[i] = true;
 
 	for (i = 0; i < kpad->gpimapsize; i++)
-		pin_used[kpad->gpimap[i].pin - kpad->var->gpi_pin_base] = true;
+		pin_used[kpad->gpimap[i].pin - kpad->info->var->gpi_pin_base] = true;
 
 	if (kpad->extend_cfg & R4_EXTEND_CFG)
 		pin_used[4] = true;
 
 	if (kpad->extend_cfg & C4_EXTEND_CFG)
-		pin_used[kpad->var->c4_extend_cfg] = true;
+		pin_used[kpad->info->var->c4_extend_cfg] = true;
 
-	if (!kpad->support_row5)
+	if (!kpad->info->support_row5)
 		pin_used[5] = true;
 
-	for (i = 0; i < kpad->var->maxgpio; i++)
+	for (i = 0; i < kpad->info->var->maxgpio; i++)
 		if (!pin_used[i])
 			kpad->gpiomap[n_unused++] = i;
 
@@ -536,11 +540,11 @@ static int adp5589_gpio_add(struct adp5589_kpad *kpad)
 	if (error)
 		return error;
 
-	for (i = 0; i <= kpad->var->bank(kpad->var->maxgpio); i++) {
-		kpad->dat_out[i] = adp5589_read(kpad->client, kpad->var->reg(
-						ADP5589_GPO_DATA_OUT_A) + i);
-		kpad->dir[i] = adp5589_read(kpad->client, kpad->var->reg(
-					    ADP5589_GPIO_DIRECTION_A) + i);
+	for (i = 0; i <= kpad->info->var->bank(kpad->info->var->maxgpio); i++) {
+		kpad->dat_out[i] = adp5589_read(kpad->client,
+						kpad->info->var->reg(ADP5589_GPO_DATA_OUT_A) + i);
+		kpad->dir[i] = adp5589_read(kpad->client,
+					    kpad->info->var->reg(ADP5589_GPIO_DIRECTION_A) + i);
 	}
 
 	return 0;
@@ -575,8 +579,8 @@ static void adp5589_report_events(struct adp5589_kpad *kpad, int ev_cnt)
 		int key = adp5589_read(kpad->client, ADP5589_5_FIFO_1 + i);
 		int key_val = key & KEY_EV_MASK;
 
-		if (key_val >= kpad->var->gpi_pin_base &&
-		    key_val <= kpad->var->gpi_pin_end) {
+		if (key_val >= kpad->info->var->gpi_pin_base &&
+		    key_val <= kpad->info->var->gpi_pin_end) {
 			adp5589_report_switches(kpad, key, key_val);
 		} else {
 			input_report_key(kpad->input,
@@ -614,7 +618,7 @@ static int adp5589_get_evcode(struct adp5589_kpad *kpad, unsigned short key)
 {
 	int i;
 
-	for (i = 0; i < kpad->var->keymapsize; i++)
+	for (i = 0; i < kpad->info->var->keymapsize; i++)
 		if (key == kpad->keycode[i])
 			return (i + 1) | KEY_EV_PRESSED;
 
@@ -628,22 +632,22 @@ static int adp5589_setup(struct adp5589_kpad *kpad)
 	struct i2c_client *client = kpad->client;
 	const struct adp5589_kpad_platform_data *pdata =
 		dev_get_platdata(&client->dev);
-	u8 (*reg) (u8) = kpad->var->reg;
+	u8 (*reg)(u8) = kpad->info->var->reg;
 	unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0;
 	unsigned char pull_mask = 0;
 	int i, ret;
 
 	ret = adp5589_write(client, reg(ADP5589_PIN_CONFIG_A),
-			    pdata->keypad_en_mask & kpad->var->row_mask);
+			    pdata->keypad_en_mask & kpad->info->var->row_mask);
 	ret |= adp5589_write(client, reg(ADP5589_PIN_CONFIG_B),
-			     (pdata->keypad_en_mask >> kpad->var->col_shift) &
-			     kpad->var->col_mask);
+			     (pdata->keypad_en_mask >> kpad->info->var->col_shift) &
+			     kpad->info->var->col_mask);
 
-	if (!kpad->is_adp5585)
+	if (!kpad->info->is_adp5585)
 		ret |= adp5589_write(client, ADP5589_PIN_CONFIG_C,
 				     (pdata->keypad_en_mask >> 16) & 0xFF);
 
-	if (!kpad->is_adp5585 && pdata->en_keylock) {
+	if (!kpad->info->is_adp5585 && pdata->en_keylock) {
 		ret |= adp5589_write(client, ADP5589_UNLOCK1,
 				     pdata->unlock_key1);
 		ret |= adp5589_write(client, ADP5589_UNLOCK2,
@@ -659,14 +663,14 @@ static int adp5589_setup(struct adp5589_kpad *kpad)
 	for (i = 0; i < pdata->gpimapsize; i++) {
 		unsigned short pin = pdata->gpimap[i].pin;
 
-		if (pin <= kpad->var->gpi_pin_row_end) {
-			evt_mode1 |= BIT(pin - kpad->var->gpi_pin_row_base);
+		if (pin <= kpad->info->var->gpi_pin_row_end) {
+			evt_mode1 |= BIT(pin - kpad->info->var->gpi_pin_row_base);
 		} else {
 			evt_mode2 |=
-			    BIT(pin - kpad->var->gpi_pin_col_base) & 0xFF;
-			if (!kpad->is_adp5585)
+			    BIT(pin - kpad->info->var->gpi_pin_col_base) & 0xFF;
+			if (!kpad->info->is_adp5585)
 				evt_mode3 |=
-				    BIT(pin - kpad->var->gpi_pin_col_base) >> 8;
+				    BIT(pin - kpad->info->var->gpi_pin_col_base) >> 8;
 		}
 	}
 
@@ -675,7 +679,7 @@ static int adp5589_setup(struct adp5589_kpad *kpad)
 				     evt_mode1);
 		ret |= adp5589_write(client, reg(ADP5589_GPI_EVENT_EN_B),
 				     evt_mode2);
-		if (!kpad->is_adp5585)
+		if (!kpad->info->is_adp5585)
 			ret |= adp5589_write(client,
 					     reg(ADP5589_GPI_EVENT_EN_C),
 					     evt_mode3);
@@ -685,7 +689,7 @@ static int adp5589_setup(struct adp5589_kpad *kpad)
 		pdata->pullup_en_300k & pdata->pulldown_en_300k)
 		dev_warn(&client->dev, "Conflicting pull resistor config\n");
 
-	for (i = 0; i <= kpad->var->max_row_num; i++) {
+	for (i = 0; i <= kpad->info->var->max_row_num; i++) {
 		unsigned int val = 0, bit = BIT(i);
 		if (pdata->pullup_en_300k & bit)
 			val = 0;
@@ -698,15 +702,15 @@ static int adp5589_setup(struct adp5589_kpad *kpad)
 
 		pull_mask |= val << (2 * (i & 0x3));
 
-		if (i % 4 == 3 || i == kpad->var->max_row_num) {
+		if (i % 4 == 3 || i == kpad->info->var->max_row_num) {
 			ret |= adp5589_write(client, reg(ADP5585_RPULL_CONFIG_A)
 					     + (i >> 2), pull_mask);
 			pull_mask = 0;
 		}
 	}
 
-	for (i = 0; i <= kpad->var->max_col_num; i++) {
-		unsigned int val = 0, bit = BIT(i + kpad->var->col_shift);
+	for (i = 0; i <= kpad->info->var->max_col_num; i++) {
+		unsigned int val = 0, bit = BIT(i + kpad->info->var->col_shift);
 		if (pdata->pullup_en_300k & bit)
 			val = 0;
 		else if (pdata->pulldown_en_300k & bit)
@@ -718,7 +722,7 @@ static int adp5589_setup(struct adp5589_kpad *kpad)
 
 		pull_mask |= val << (2 * (i & 0x3));
 
-		if (i % 4 == 3 || i == kpad->var->max_col_num) {
+		if (i % 4 == 3 || i == kpad->info->var->max_col_num) {
 			ret |= adp5589_write(client,
 					     reg(ADP5585_RPULL_CONFIG_C) +
 					     (i >> 2), pull_mask);
@@ -757,22 +761,22 @@ static int adp5589_setup(struct adp5589_kpad *kpad)
 	}
 
 	ret |= adp5589_write(client, reg(ADP5589_DEBOUNCE_DIS_A),
-			    pdata->debounce_dis_mask & kpad->var->row_mask);
+			    pdata->debounce_dis_mask & kpad->info->var->row_mask);
 
 	ret |= adp5589_write(client, reg(ADP5589_DEBOUNCE_DIS_B),
-			     (pdata->debounce_dis_mask >> kpad->var->col_shift)
-			     & kpad->var->col_mask);
+			     (pdata->debounce_dis_mask >> kpad->info->var->col_shift)
+			     & kpad->info->var->col_mask);
 
-	if (!kpad->is_adp5585)
+	if (!kpad->info->is_adp5585)
 		ret |= adp5589_write(client, reg(ADP5589_DEBOUNCE_DIS_C),
 				     (pdata->debounce_dis_mask >> 16) & 0xFF);
 
 	ret |= adp5589_write(client, reg(ADP5589_POLL_PTIME_CFG),
 			     pdata->scan_cycle_time & PTIME_MASK);
 	ret |= adp5589_write(client, ADP5589_5_INT_STATUS,
-			     (kpad->is_adp5585 ? 0 : LOGIC2_INT) |
+			     (kpad->info->is_adp5585 ? 0 : LOGIC2_INT) |
 			     LOGIC1_INT | OVRFLOW_INT |
-			     (kpad->is_adp5585 ? 0 : LOCK_INT) |
+			     (kpad->info->is_adp5585 ? 0 : LOCK_INT) |
 			     GPI_INT | EVENT_INT);	/* Status is W1C */
 
 	ret |= adp5589_write(client, reg(ADP5589_GENERAL_CFG),
@@ -793,24 +797,24 @@ static void adp5589_report_switch_state(struct adp5589_kpad *kpad)
 	int gpi_stat_tmp, pin_loc;
 	int i;
 	int gpi_stat1 = adp5589_read(kpad->client,
-				     kpad->var->reg(ADP5589_GPI_STATUS_A));
+				     kpad->info->var->reg(ADP5589_GPI_STATUS_A));
 	int gpi_stat2 = adp5589_read(kpad->client,
-				     kpad->var->reg(ADP5589_GPI_STATUS_B));
-	int gpi_stat3 = !kpad->is_adp5585 ?
+				     kpad->info->var->reg(ADP5589_GPI_STATUS_B));
+	int gpi_stat3 = !kpad->info->is_adp5585 ?
 			adp5589_read(kpad->client, ADP5589_GPI_STATUS_C) : 0;
 
 	for (i = 0; i < kpad->gpimapsize; i++) {
 		unsigned short pin = kpad->gpimap[i].pin;
 
-		if (pin <= kpad->var->gpi_pin_row_end) {
+		if (pin <= kpad->info->var->gpi_pin_row_end) {
 			gpi_stat_tmp = gpi_stat1;
-			pin_loc = pin - kpad->var->gpi_pin_row_base;
-		} else if ((pin - kpad->var->gpi_pin_col_base) < 8) {
+			pin_loc = pin - kpad->info->var->gpi_pin_row_base;
+		} else if ((pin - kpad->info->var->gpi_pin_col_base) < 8) {
 			gpi_stat_tmp = gpi_stat2;
-			pin_loc = pin - kpad->var->gpi_pin_col_base;
+			pin_loc = pin - kpad->info->var->gpi_pin_col_base;
 		} else {
 			gpi_stat_tmp = gpi_stat3;
-			pin_loc = pin - kpad->var->gpi_pin_col_base - 8;
+			pin_loc = pin - kpad->info->var->gpi_pin_col_base - 8;
 		}
 
 		if (gpi_stat_tmp < 0) {
@@ -837,14 +841,13 @@ static int adp5589_keypad_add(struct adp5589_kpad *kpad, unsigned int revid)
 	unsigned int i;
 	int error;
 
-	if (!((pdata->keypad_en_mask & kpad->var->row_mask) &&
-			(pdata->keypad_en_mask >> kpad->var->col_shift)) ||
-			!pdata->keymap) {
+	if (!((pdata->keypad_en_mask & kpad->info->var->row_mask) &&
+	      (pdata->keypad_en_mask >> kpad->info->var->col_shift)) || !pdata->keymap) {
 		dev_err(&client->dev, "no rows, cols or keymap from pdata\n");
 		return -EINVAL;
 	}
 
-	if (pdata->keymapsize != kpad->var->keymapsize) {
+	if (pdata->keymapsize != kpad->info->var->keymapsize) {
 		dev_err(&client->dev, "invalid keymapsize\n");
 		return -EINVAL;
 	}
@@ -854,7 +857,7 @@ static int adp5589_keypad_add(struct adp5589_kpad *kpad, unsigned int revid)
 		return -EINVAL;
 	}
 
-	if (pdata->gpimapsize > kpad->var->gpimapsize_max) {
+	if (pdata->gpimapsize > kpad->info->var->gpimapsize_max) {
 		dev_err(&client->dev, "invalid gpimapsize\n");
 		return -EINVAL;
 	}
@@ -862,13 +865,13 @@ static int adp5589_keypad_add(struct adp5589_kpad *kpad, unsigned int revid)
 	for (i = 0; i < pdata->gpimapsize; i++) {
 		unsigned short pin = pdata->gpimap[i].pin;
 
-		if (pin < kpad->var->gpi_pin_base ||
-				pin > kpad->var->gpi_pin_end) {
+		if (pin < kpad->info->var->gpi_pin_base ||
+		    pin > kpad->info->var->gpi_pin_end) {
 			dev_err(&client->dev, "invalid gpi pin data\n");
 			return -EINVAL;
 		}
 
-		if (BIT(pin - kpad->var->gpi_pin_row_base) &
+		if (BIT(pin - kpad->info->var->gpi_pin_row_base) &
 				pdata->keypad_en_mask) {
 			dev_err(&client->dev, "invalid gpi row/col data\n");
 			return -EINVAL;
@@ -945,12 +948,28 @@ static void adp5589_clear_config(void *data)
 {
 	struct adp5589_kpad *kpad = data;
 
-	adp5589_write(kpad->client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
+	adp5589_write(kpad->client, kpad->info->var->reg(ADP5589_GENERAL_CFG),
+		      0);
 }
 
+static const struct adp5589_info adp5589_info = {
+	.var = &const_adp5589,
+	.support_row5 = true,
+};
+
+static const struct adp5589_info adp5585_info = {
+	.var = &const_adp5585,
+	.is_adp5585 = true,
+};
+
+static const struct adp5589_info adp5585_2_info = {
+	.var = &const_adp5585,
+	.is_adp5585 = true,
+	.support_row5 = true,
+};
+
 static int adp5589_probe(struct i2c_client *client)
 {
-	const struct i2c_device_id *id = i2c_client_get_device_id(client);
 	struct adp5589_kpad *kpad;
 	const struct adp5589_kpad_platform_data *pdata =
 		dev_get_platdata(&client->dev);
@@ -974,19 +993,9 @@ static int adp5589_probe(struct i2c_client *client)
 
 	kpad->client = client;
 
-	switch (id->driver_data) {
-	case ADP5585_02:
-		kpad->support_row5 = true;
-		fallthrough;
-	case ADP5585_01:
-		kpad->is_adp5585 = true;
-		kpad->var = &const_adp5585;
-		break;
-	case ADP5589:
-		kpad->support_row5 = true;
-		kpad->var = &const_adp5589;
-		break;
-	}
+	kpad->info = i2c_get_match_data(client);
+	if (!kpad->info)
+		return -ENODEV;
 
 	error = devm_add_action_or_reset(&client->dev, adp5589_clear_config,
 					 kpad);
@@ -1045,9 +1054,9 @@ static int adp5589_resume(struct device *dev)
 static DEFINE_SIMPLE_DEV_PM_OPS(adp5589_dev_pm_ops, adp5589_suspend, adp5589_resume);
 
 static const struct i2c_device_id adp5589_id[] = {
-	{"adp5589-keys", ADP5589},
-	{"adp5585-keys", ADP5585_01},
-	{"adp5585-02-keys", ADP5585_02}, /* Adds ROW5 to ADP5585 */
+	{"adp5589-keys", (kernel_ulong_t)&adp5589_info},
+	{"adp5585-keys", (kernel_ulong_t)&adp5585_info},
+	{"adp5585-02-keys", (kernel_ulong_t)&adp5585_2_info}, /* Adds ROW5 to ADP5585 */
 	{}
 };
 

-- 
2.46.1





[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux