Skip to content

Commit bd113a1

Browse files
nunojsalag-linaro
authored andcommitted
mfd: adp5585: Add support for input devices
The ADP558x family supports a built in keypad matrix decoder which can be added as an Input device. In order to both support the Input and the GPIO device, we need to create a bitmap of the supported pins and track their usage since they can either be used as GPIOs (GPIs) or as part of the keymap. We also need to mark special pins busy in case some features are being used (ex: pwm or reset events). Signed-off-by: Nuno Sá <nuno.sa@analog.com> Link: https://lore.kernel.org/r/20250701-dev-adp5589-fw-v7-14-b1fcfe9e9826@analog.com Signed-off-by: Lee Jones <lee@kernel.org>
1 parent 333812d commit bd113a1

2 files changed

Lines changed: 41 additions & 0 deletions

File tree

drivers/mfd/adp5585.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,20 @@
2222
enum {
2323
ADP5585_DEV_GPIO,
2424
ADP5585_DEV_PWM,
25+
ADP5585_DEV_INPUT,
2526
ADP5585_DEV_MAX
2627
};
2728

2829
static const struct mfd_cell adp5585_devs[ADP5585_DEV_MAX] = {
2930
MFD_CELL_NAME("adp5585-gpio"),
3031
MFD_CELL_NAME("adp5585-pwm"),
32+
MFD_CELL_NAME("adp5585-keys"),
3133
};
3234

3335
static const struct mfd_cell adp5589_devs[] = {
3436
MFD_CELL_NAME("adp5589-gpio"),
3537
MFD_CELL_NAME("adp5589-pwm"),
38+
MFD_CELL_NAME("adp5589-keys"),
3639
};
3740

3841
static const struct regmap_range adp5585_volatile_ranges[] = {
@@ -172,6 +175,7 @@ static const struct adp5585_regs adp5585_regs = {
172175
.reset_cfg = ADP5585_RESET_CFG,
173176
.reset1_event_a = ADP5585_RESET1_EVENT_A,
174177
.reset2_event_a = ADP5585_RESET2_EVENT_A,
178+
.pin_cfg_a = ADP5585_PIN_CONFIG_A,
175179
};
176180

177181
static const struct adp5585_regs adp5589_regs = {
@@ -182,6 +186,7 @@ static const struct adp5585_regs adp5589_regs = {
182186
.reset_cfg = ADP5589_RESET_CFG,
183187
.reset1_event_a = ADP5589_RESET1_EVENT_A,
184188
.reset2_event_a = ADP5589_RESET2_EVENT_A,
189+
.pin_cfg_a = ADP5589_PIN_CONFIG_A,
185190
};
186191

187192
static int adp5585_validate_event(const struct adp5585_dev *adp5585, unsigned int ev)
@@ -239,6 +244,8 @@ static struct regmap_config *adp5585_fill_variant_config(struct adp5585_dev *adp
239244
case ADP5585_04:
240245
adp5585->id = ADP5585_MAN_ID_VALUE;
241246
adp5585->regs = &adp5585_regs;
247+
adp5585->n_pins = ADP5585_PIN_MAX;
248+
adp5585->reset2_out = ADP5585_RESET2_OUT;
242249
if (adp5585->variant == ADP5585_01)
243250
adp5585->has_pin6 = true;
244251
regmap_config = devm_kmemdup(adp5585->dev, &adp5585_regmap_config_template,
@@ -251,6 +258,8 @@ static struct regmap_config *adp5585_fill_variant_config(struct adp5585_dev *adp
251258
adp5585->regs = &adp5589_regs;
252259
adp5585->has_unlock = true;
253260
adp5585->has_pin6 = true;
261+
adp5585->n_pins = ADP5589_PIN_MAX;
262+
adp5585->reset2_out = ADP5589_RESET2_OUT;
254263
regmap_config = devm_kmemdup(adp5585->dev, &adp5589_regmap_config_template,
255264
sizeof(*regmap_config), GFP_KERNEL);
256265
break;
@@ -439,6 +448,8 @@ static int adp5585_add_devices(const struct adp5585_dev *adp5585)
439448
cells = adp5589_devs;
440449

441450
if (device_property_present(dev, "#pwm-cells")) {
451+
/* Make sure the PWM output pin is not used by the GPIO or INPUT devices */
452+
__set_bit(ADP5585_PWM_OUT, adp5585->pin_usage);
442453
ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO,
443454
&cells[ADP5585_DEV_PWM], 1, NULL, 0, NULL);
444455
if (ret)
@@ -452,6 +463,13 @@ static int adp5585_add_devices(const struct adp5585_dev *adp5585)
452463
return dev_err_probe(dev, ret, "Failed to add GPIO device\n");
453464
}
454465

466+
if (device_property_present(adp5585->dev, "adi,keypad-pins")) {
467+
ret = devm_mfd_add_devices(adp5585->dev, PLATFORM_DEVID_AUTO,
468+
&cells[ADP5585_DEV_INPUT], 1, NULL, 0, NULL);
469+
if (ret)
470+
return dev_err_probe(dev, ret, "Failed to add input device\n");
471+
}
472+
455473
return 0;
456474
}
457475

@@ -518,6 +536,10 @@ static int adp5585_setup(struct adp5585_dev *adp5585)
518536
unsigned int reg_val = 0, i;
519537
int ret;
520538

539+
/* If pin_6 (ROW5/GPI6) is not available, make sure to mark it as "busy" */
540+
if (!adp5585->has_pin6)
541+
__set_bit(ADP5585_ROW5, adp5585->pin_usage);
542+
521543
/* Configure the device with reset and unlock events */
522544
for (i = 0; i < adp5585->nkeys_unlock; i++) {
523545
ret = regmap_write(adp5585->regmap, ADP5589_UNLOCK1 + i,
@@ -542,13 +564,18 @@ static int adp5585_setup(struct adp5585_dev *adp5585)
542564
adp5585->reset1_keys[i] | ADP5585_RESET_EV_PRESS);
543565
if (ret)
544566
return ret;
567+
568+
/* Mark that pin as not usable for the INPUT and GPIO devices. */
569+
__set_bit(ADP5585_RESET1_OUT, adp5585->pin_usage);
545570
}
546571

547572
for (i = 0; i < adp5585->nkeys_reset2; i++) {
548573
ret = regmap_write(adp5585->regmap, regs->reset2_event_a + i,
549574
adp5585->reset2_keys[i] | ADP5585_RESET_EV_PRESS);
550575
if (ret)
551576
return ret;
577+
578+
__set_bit(adp5585->reset2_out, adp5585->pin_usage);
552579
}
553580

554581
if (adp5585->nkeys_reset1 || adp5585->nkeys_reset2) {
@@ -697,6 +724,10 @@ static int adp5585_i2c_probe(struct i2c_client *i2c)
697724
return dev_err_probe(&i2c->dev, -ENODEV,
698725
"Invalid device ID 0x%02x\n", id);
699726

727+
adp5585->pin_usage = devm_bitmap_zalloc(&i2c->dev, adp5585->n_pins, GFP_KERNEL);
728+
if (!adp5585->pin_usage)
729+
return -ENOMEM;
730+
700731
ret = adp5585_parse_fw(adp5585);
701732
if (ret)
702733
return ret;

include/linux/mfd/adp5585.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@
126126
#define ADP5585_GPI_EVENT_END 47
127127
#define ADP5585_ROW5_KEY_EVENT_START 1
128128
#define ADP5585_ROW5_KEY_EVENT_END 30
129+
#define ADP5585_PWM_OUT 3
130+
#define ADP5585_RESET1_OUT 4
131+
#define ADP5585_RESET2_OUT 9
132+
#define ADP5585_ROW5 5
129133

130134
/* ADP5589 */
131135
#define ADP5589_MAN_ID_VALUE 0x10
@@ -154,6 +158,7 @@
154158
#define ADP5589_PWM_ONT_LOW 0x40
155159
#define ADP5589_PWM_CFG 0x42
156160
#define ADP5589_POLL_PTIME_CFG 0x48
161+
#define ADP5589_PIN_CONFIG_A 0x49
157162
#define ADP5589_PIN_CONFIG_D 0x4C
158163
#define ADP5589_GENERAL_CFG 0x4d
159164
#define ADP5589_INT_EN 0x4e
@@ -165,6 +170,7 @@
165170
#define ADP5589_GPI_EVENT_START 97
166171
#define ADP5589_GPI_EVENT_END 115
167172
#define ADP5589_UNLOCK_WILDCARD 127
173+
#define ADP5589_RESET2_OUT 12
168174

169175
struct regmap;
170176

@@ -188,13 +194,17 @@ struct adp5585_regs {
188194
unsigned int reset_cfg;
189195
unsigned int reset1_event_a;
190196
unsigned int reset2_event_a;
197+
unsigned int pin_cfg_a;
191198
};
192199

193200
struct adp5585_dev {
194201
struct device *dev;
195202
struct regmap *regmap;
196203
const struct adp5585_regs *regs;
197204
struct blocking_notifier_head event_notifier;
205+
unsigned long *pin_usage;
206+
unsigned int n_pins;
207+
unsigned int reset2_out;
198208
enum adp5585_variant variant;
199209
unsigned int id;
200210
bool has_unlock;

0 commit comments

Comments
 (0)