devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Nuno Sá" <noname.nuno@gmail.com>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>, nuno.sa@analog.com
Cc: linux-gpio@vger.kernel.org, linux-pwm@vger.kernel.org,
	devicetree@vger.kernel.org, linux-input@vger.kernel.org,
	"Lee Jones" <lee@kernel.org>, "Rob Herring" <robh@kernel.org>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
	"Conor Dooley" <conor+dt@kernel.org>,
	"Uwe Kleine-König" <ukleinek@kernel.org>,
	"Linus Walleij" <linus.walleij@linaro.org>,
	"Bartosz Golaszewski" <brgl@bgdev.pl>,
	"Dmitry Torokhov" <dmitry.torokhov@gmail.com>,
	"Liu Ying" <victor.liu@nxp.com>
Subject: Re: [PATCH v2 12/17] Input: adp5585: Add Analog Devices ADP5585/89 support
Date: Mon, 21 Apr 2025 13:33:23 +0100	[thread overview]
Message-ID: <f6896ba5c4bc0596db5950220ef956b629df7b04.camel@gmail.com> (raw)
In-Reply-To: <20250421093515.GI29968@pendragon.ideasonboard.com>

On Mon, 2025-04-21 at 12:35 +0300, Laurent Pinchart wrote:
> Hi Nuno,
> 
> Thank you for the patch.
> 
> On Tue, Apr 15, 2025 at 03:49:28PM +0100, Nuno Sá via B4 Relay wrote:
> > From: Nuno Sá <nuno.sa@analog.com>
> > 
> > The ADP5585 is a 10/11 input/output port expander with a built in keypad
> > matrix decoder, programmable logic, reset generator, and PWM generator.
> > This driver supports the keyboard function using the platform device
> > registered by the core MFD driver.
> > 
> > The ADP5589 has 19 pins and also features an unlock function.
> > 
> > Signed-off-by: Nuno Sá <nuno.sa@analog.com>
> > ---
> >  MAINTAINERS                           |   1 +
> >  drivers/input/keyboard/Kconfig        |  11 ++
> >  drivers/input/keyboard/Makefile       |   1 +
> >  drivers/input/keyboard/adp5585-keys.c | 221
> > ++++++++++++++++++++++++++++++++++
> >  4 files changed, 234 insertions(+)
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index
> > b5acf50fc6af4322dec0dad2169b46c6a1903e3c..48bd39a1a96d9c57145cf2560eec542484
> > 27fc89 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -549,6 +549,7 @@ L:	linux-pwm@vger.kernel.org
> >  S:	Maintained
> >  F:	Documentation/devicetree/bindings/*/adi,adp5585*.yaml
> >  F:	drivers/gpio/gpio-adp5585.c
> > +F:	drivers/input/adp5585-keys.c
> >  F:	drivers/mfd/adp5585.c
> >  F:	drivers/pwm/pwm-adp5585.c
> >  F:	include/linux/mfd/adp5585.h
> > diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> > index
> > 721ab69e84ac6586f4f19102890a15ca3fcf1910..322da0957067db77c7f66ab26a181d39c2
> > c1d513 100644
> > --- a/drivers/input/keyboard/Kconfig
> > +++ b/drivers/input/keyboard/Kconfig
> > @@ -37,6 +37,17 @@ config KEYBOARD_ADP5520
> >  	  To compile this driver as a module, choose M here: the module
> > will
> >  	  be called adp5520-keys.
> >  
> > +config KEYBOARD_ADP5585
> > +	tristate "ADP5585 and similar  I2C QWERTY Keypad and IO Expanders"
> > +	depends on MFD_ADP5585
> > +	select INPUT_MATRIXKMAP
> > +	help
> > +	  This option enables support for the KEYMAP function found in the
> > Analog
> > +	  Devices ADP5585 and similar devices.
> > +
> > +	  To compile this driver as a module, choose M here: the
> > +	  module will be called adp5585-keys.
> > +
> >  config KEYBOARD_ADP5588
> >  	tristate "ADP5588/87 I2C QWERTY Keypad and IO Expander"
> >  	depends on I2C
> > diff --git a/drivers/input/keyboard/Makefile
> > b/drivers/input/keyboard/Makefile
> > index
> > 1e0721c3070968a6339a42f65a95af48364f6897..f00ec003a59aa28577ae164c0539cc5aff
> > 9579fc 100644
> > --- a/drivers/input/keyboard/Makefile
> > +++ b/drivers/input/keyboard/Makefile
> > @@ -7,6 +7,7 @@
> >  
> >  obj-$(CONFIG_KEYBOARD_ADC)		+= adc-keys.o
> >  obj-$(CONFIG_KEYBOARD_ADP5520)		+= adp5520-keys.o
> > +obj-$(CONFIG_KEYBOARD_ADP5585)		+= adp5585-keys.o
> >  obj-$(CONFIG_KEYBOARD_ADP5588)		+= adp5588-keys.o
> >  obj-$(CONFIG_KEYBOARD_ADP5589)		+= adp5589-keys.o
> >  obj-$(CONFIG_KEYBOARD_AMIGA)		+= amikbd.o
> > diff --git a/drivers/input/keyboard/adp5585-keys.c
> > b/drivers/input/keyboard/adp5585-keys.c
> > new file mode 100644
> > index
> > 0000000000000000000000000000000000000000..93961a9e822f8b10b1bca526b9486eed4a
> > d7f8f7
> > --- /dev/null
> > +++ b/drivers/input/keyboard/adp5585-keys.c
> > @@ -0,0 +1,221 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Analog Devices ADP5585 Keys driver
> > + *
> > + * Copyright (C) 2025 Analog Devices, Inc.
> > + */
> > +
> > +#include <linux/bitmap.h>
> > +#include <linux/device.h>
> > +#include <linux/find.h>
> > +#include <linux/input.h>
> > +#include <linux/input/matrix_keypad.h>
> > +#include <linux/mfd/adp5585.h>
> > +#include <linux/module.h>
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/property.h>
> > +#include <linux/regmap.h>
> > +#include <linux/types.h>
> > +
> > +/* As needed for the matrix parsing code */
> > +#define ADP5589_MAX_KEYMAPSIZE		123
> > +
> > +struct adp5585_kpad {
> > +	struct input_dev *input;
> > +	unsigned short keycode[ADP5589_MAX_KEYMAPSIZE];
> > +	struct device *dev;
> > +	int row_shift;
> > +	u8 max_rows;
> > +	u8 max_cols;
> > +};
> > +
> > +static int adp5585_keys_parse_fw(const struct adp5585_dev *adp5585,
> > +				 struct adp5585_kpad *kpad)
> > +{
> > +	unsigned long row_map, col_map;
> > +	struct device *dev = kpad->dev;
> > +	u32 cols = 0, rows = 0;
> > +	int ret;
> > +
> > +	row_map = bitmap_read(adp5585->keypad, 0, kpad->max_rows);
> > +	col_map = bitmap_read(adp5585->keypad, kpad->max_rows, kpad-
> > >max_cols);
> > +	/*
> > +	 * Note that given that we get a mask (and the HW allows it), we
> > +	 * can have holes in our keypad (eg: row0, row1 and row7 enabled).
> > +	 * However, for the matrix parsing functions we need to pass the
> > +	 * number of rows/cols as the maximum row/col used plus 1. This
> > +	 * pretty much means we will also have holes in our SW keypad.
> > +	 */
> > +	if (!bitmap_empty(&row_map, kpad->max_rows))
> > +		rows = find_last_bit(&row_map, kpad->max_rows) + 1;
> > +	if (!bitmap_empty(&col_map, kpad->max_cols))
> > +		cols = find_last_bit(&col_map, kpad->max_cols) + 1;
> > +
> > +	if (!rows && !cols)
> > +		return dev_err_probe(dev, -EINVAL,
> > +				     "No rows or columns defined for the
> > keypad\n");
> > +
> > +	if (cols && !rows)
> > +		return dev_err_probe(dev, -EINVAL,
> > +				     "Cannot have columns with no
> > rows!\n");
> > +
> > +	if (rows && !cols)
> > +		return dev_err_probe(dev, -EINVAL,
> > +				     "Cannot have rows with no
> > columns!\n");
> > +
> > +	ret = matrix_keypad_build_keymap(NULL, NULL, rows, cols,
> > +					 kpad->keycode, kpad->input);
> > +	if (ret)
> > +		return ret;
> > +
> > +	kpad->row_shift = get_count_order(cols);
> > +
> > +	if (device_property_present(kpad->dev, "autorepeat"))
> > +		__set_bit(EV_REP, kpad->input->evbit);
> > +
> > +	return 0;
> > +}
> > +
> > +static int adp5585_keys_setup(const struct adp5585_dev *adp5585,
> > +			      struct adp5585_kpad *kpad)
> > +{
> > +	unsigned long keys_bits, start = 0, nbits = kpad->max_rows;
> > +	const struct adp5585_regs *regs = adp5585->info->regs;
> > +	unsigned int i = 0, max_cols = kpad->max_cols;
> > +	int ret;
> > +
> > +	/*
> > +	 * Take care as the below assumes max_rows is always less or equal
> > than
> > +	 * 8 which is true for the supported devices. If we happen to add
> > +	 * another device we need to make sure this still holds true.
> > Although
> > +	 * adding a new device is very unlikely.
> > +	 */
> > +	do {
> > +		keys_bits = bitmap_read(adp5585->keypad, start, nbits);
> > +		if (keys_bits) {
> > +			ret = regmap_write(adp5585->regmap, regs->pin_cfg_a
> > + i,
> > +					   keys_bits);
> > +			if (ret)
> > +				return ret;
> > +		}
> > +
> > +		start += nbits;
> > +		if (max_cols > 8) {
> > +			nbits = 8;
> > +			max_cols -= nbits;
> > +		} else {
> > +			nbits = max_cols;
> > +		}
> > +
> > +		i++;
> > +	} while (start < kpad->max_rows + kpad->max_cols);
> > +
> > +	return 0;
> > +}
> > +
> > +static void adp5585_keys_ev_handle(struct device *dev, unsigned int key,
> > +				   bool key_press)
> > +{
> > +	struct adp5585_kpad *kpad = dev_get_drvdata(dev);
> > +	unsigned int row, col, code;
> > +
> > +	row = (key - 1) / (kpad->max_cols);
> > +	col = (key - 1) % (kpad->max_cols);
> > +	code = MATRIX_SCAN_CODE(row, col, kpad->row_shift);
> > +
> > +	dev_dbg_ratelimited(kpad->dev, "report key(%d) r(%d) c(%d)
> > code(%d)\n",
> > +			    key, row, col, kpad->keycode[code]);
> > +
> > +	input_report_key(kpad->input, kpad->keycode[code], key_press);
> > +	input_sync(kpad->input);
> > +}
> > +
> > +static void adp5585_keys_ev_handle_clean(void *adp5585)
> > +{
> > +	adp5585_keys_ev_handle_set(adp5585, NULL, NULL);
> > +}
> > +
> > +static int adp5585_keys_probe(struct platform_device *pdev)
> > +{
> > +	struct adp5585_dev *adp5585 = dev_get_drvdata(pdev->dev.parent);
> > +	struct device *dev = &pdev->dev;
> > +	struct adp5585_kpad *kpad;
> > +	unsigned int revid;
> > +	const char *phys;
> > +	int ret;
> > +
> > +	kpad = devm_kzalloc(dev, sizeof(*kpad), GFP_KERNEL);
> > +	if (!kpad)
> > +		return -ENOMEM;
> > +
> > +	if (!adp5585->irq)
> > +		return dev_err_probe(dev, -EINVAL,
> > +				     "IRQ is mandatory for the keypad\n");
> 
> This causes the following messages to be printed in the kernel log on a
> platform where the keypad feature is not declared in DT:
> 
> [   11.625591] adp5585-keys adp5585-keys.1.auto: error -EINVAL: IRQ is
> mandatory for the keypad
> [   11.625637] adp5585-keys adp5585-keys.1.auto: probe with driver adp5585-
> keys failed with error -22
> 
> The MFD driver should detect which features are declared, and only
> register the corresponding MFD cells.

Oh right, the above does not look right!

- Nuno Sá
> 
> > +
> > +	kpad->dev = dev;
> > +	kpad->max_cols = adp5585->info->max_cols;
> > +	kpad->max_rows = adp5585->info->max_rows;
> > +
> > +	kpad->input = devm_input_allocate_device(dev);
> > +	if (!kpad->input)
> > +		return -ENOMEM;
> > +
> > +	ret = regmap_read(adp5585->regmap, ADP5585_ID, &revid);
> > +	if (ret)
> > +		return dev_err_probe(dev, ret, "Failed to read device
> > ID\n");
> > +
> > +	phys = devm_kasprintf(dev, GFP_KERNEL, "%s/input0", pdev->name);
> > +	if (!phys)
> > +		return -ENOMEM;
> > +
> > +	kpad->input->name = pdev->name;
> > +	kpad->input->phys = phys;
> > +	kpad->input->dev.parent = dev;
> > +
> > +	input_set_drvdata(kpad->input, kpad);
> > +
> > +	kpad->input->id.bustype = BUS_I2C;
> > +	kpad->input->id.vendor = 0x0001;
> > +	kpad->input->id.product = 0x0001;
> > +	kpad->input->id.version = revid & ADP5585_REV_ID_MASK;
> > +
> > +	device_set_of_node_from_dev(dev, dev->parent);
> > +
> > +	ret = adp5585_keys_parse_fw(adp5585, kpad);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = adp5585_keys_setup(adp5585, kpad);
> > +	if (ret)
> > +		return ret;
> > +
> > +	platform_set_drvdata(pdev, kpad);
> > +	adp5585_keys_ev_handle_set(adp5585, adp5585_keys_ev_handle, dev);
> > +	ret = devm_add_action_or_reset(dev, adp5585_keys_ev_handle_clean,
> > +				       adp5585);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return input_register_device(kpad->input);
> > +}
> > +
> > +static const struct platform_device_id adp5585_keys_id_table[] = {
> > +	{ "adp5585-keys" },
> > +	{ "adp5589-keys" },
> > +	{ }
> > +};
> > +MODULE_DEVICE_TABLE(platform, adp5585_keys_id_table);
> > +
> > +static struct platform_driver adp5585_keys_driver = {
> > +	.driver	= {
> > +		.name = "adp5585-keys",
> > +	},
> > +	.probe = adp5585_keys_probe,
> > +	.id_table = adp5585_keys_id_table,
> > +};
> > +module_platform_driver(adp5585_keys_driver);
> > +
> > +MODULE_AUTHOR("Nuno Sá <nuno.sa@analog.com>");
> > +MODULE_DESCRIPTION("ADP5585 Keys Driver");
> > +MODULE_LICENSE("GPL");

  reply	other threads:[~2025-04-21 12:33 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-15 14:49 [PATCH v2 00/17] mfd: adp5585: support keymap events and drop legacy Input driver Nuno Sá via B4 Relay
2025-04-15 14:49 ` [PATCH v2 01/17] dt-bindings: mfd: adp5585: ease on the required properties Nuno Sá via B4 Relay
2025-04-21  8:56   ` Laurent Pinchart
2025-04-21 12:12     ` Nuno Sá
2025-04-21 12:29       ` Laurent Pinchart
2025-04-21 12:45         ` Nuno Sá
2025-04-21 18:57   ` Rob Herring (Arm)
2025-04-15 14:49 ` [PATCH v2 02/17] mfd: adp5585: enable oscilator during probe Nuno Sá via B4 Relay
2025-04-21  8:57   ` Laurent Pinchart
2025-04-21 12:14     ` Nuno Sá
2025-04-21 22:03       ` Laurent Pinchart
2025-04-22  7:50         ` Nuno Sá
2025-04-15 14:49 ` [PATCH v2 03/17] pwm: adp5585: don't control OSC_EN in the pwm driver Nuno Sá via B4 Relay
2025-04-15 14:49 ` [PATCH v2 04/17] mfd: adp5585: make use of MFD_CELL_NAME() Nuno Sá via B4 Relay
2025-04-21  9:03   ` Laurent Pinchart
2025-04-24 15:55   ` Lee Jones
2025-04-15 14:49 ` [PATCH v2 05/17] dt-bindings: mfd: adp5585: document adp5589 I/O expander Nuno Sá via B4 Relay
2025-04-21  9:07   ` Laurent Pinchart
2025-04-21 18:59   ` Rob Herring (Arm)
2025-04-15 14:49 ` [PATCH v2 06/17] mfd: adp5585: add support for adp5589 Nuno Sá via B4 Relay
2025-04-21  9:15   ` Laurent Pinchart
2025-04-21 12:21     ` Nuno Sá
2025-04-21 22:06       ` Laurent Pinchart
2025-04-22  7:51         ` Nuno Sá
2025-04-24 16:01         ` Lee Jones
2025-04-24 16:18   ` Lee Jones
2025-04-24 16:30     ` Laurent Pinchart
2025-04-24 16:38       ` Lee Jones
2025-04-24 19:39         ` Laurent Pinchart
2025-04-25  7:58           ` Lee Jones
2025-04-25  9:13             ` Laurent Pinchart
2025-04-25  9:23               ` Lee Jones
2025-04-28  9:24               ` Nuno Sá
2025-04-15 14:49 ` [PATCH v2 07/17] gpio: adp5585: add support for the ad5589 expander Nuno Sá via B4 Relay
2025-04-17 12:27   ` Bartosz Golaszewski
2025-04-21  9:23   ` Laurent Pinchart
2025-04-21 12:22     ` Nuno Sá
2025-04-15 14:49 ` [PATCH v2 08/17] pwm: adp5585: add support for adp5589 Nuno Sá via B4 Relay
2025-04-15 14:49 ` [PATCH v2 09/17] dt-bindings: mfd: adp5585: add properties for input events Nuno Sá via B4 Relay
2025-04-21  9:28   ` Laurent Pinchart
2025-04-21 12:24     ` Nuno Sá
2025-04-29 15:03   ` Rob Herring (Arm)
2025-04-15 14:49 ` [PATCH v2 10/17] mfd: adp5585: add support for key events Nuno Sá via B4 Relay
2025-04-21  9:33   ` Laurent Pinchart
2025-04-21 12:32     ` Nuno Sá
2025-04-21 22:13       ` Laurent Pinchart
2025-04-24 16:07     ` Lee Jones
2025-04-24 16:24       ` Laurent Pinchart
2025-04-24 16:28         ` Lee Jones
2025-04-15 14:49 ` [PATCH v2 11/17] gpio: adp5585: support gpi events Nuno Sá via B4 Relay
2025-04-17 12:28   ` Bartosz Golaszewski
2025-04-15 14:49 ` [PATCH v2 12/17] Input: adp5585: Add Analog Devices ADP5585/89 support Nuno Sá via B4 Relay
2025-04-19  2:44   ` Dmitry Torokhov
2025-04-21  9:35   ` Laurent Pinchart
2025-04-21 12:33     ` Nuno Sá [this message]
2025-04-15 14:49 ` [PATCH v2 13/17] Input: adp5589: remove the driver Nuno Sá via B4 Relay
2025-04-19  2:45   ` Dmitry Torokhov
2025-04-21  9:40   ` Laurent Pinchart
2025-04-21 12:34     ` Nuno Sá
2025-04-15 14:49 ` [PATCH v2 14/17] mfd: adp5585: support getting vdd regulator Nuno Sá via B4 Relay
2025-04-21  9:48   ` Laurent Pinchart
2025-04-21 12:38     ` Nuno Sá
2025-04-21 22:09       ` Laurent Pinchart
2025-04-22  8:12         ` Nuno Sá
2025-04-15 14:49 ` [PATCH v2 15/17] dt-bindings: mfd: adp5585: document reset gpio Nuno Sá via B4 Relay
2025-04-21  9:36   ` Laurent Pinchart
2025-04-15 14:49 ` [PATCH v2 16/17] mfd: adp5585: add support for a reset pin Nuno Sá via B4 Relay
2025-04-21  9:46   ` Laurent Pinchart
2025-04-21 12:42     ` Nuno Sá
2025-04-21 22:10       ` Laurent Pinchart
2025-04-15 14:49 ` [PATCH v2 17/17] pwm: adp5585: make sure to include mod_devicetable.h Nuno Sá via B4 Relay
2025-04-21  9:50   ` Laurent Pinchart
2025-04-15 15:56 ` [PATCH v2 00/17] mfd: adp5585: support keymap events and drop legacy Input driver Laurent Pinchart
2025-04-21 10:08   ` Laurent Pinchart
2025-04-16  9:02 ` Liu Ying
2025-04-16 10:03   ` Nuno Sá
2025-05-01 12:00 ` Lee Jones
2025-05-01 14:09   ` Laurent Pinchart
2025-05-02  7:13     ` Lee Jones
2025-05-02  7:35       ` Nuno Sá
2025-05-02  8:30         ` Lee Jones

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f6896ba5c4bc0596db5950220ef956b629df7b04.camel@gmail.com \
    --to=noname.nuno@gmail.com \
    --cc=brgl@bgdev.pl \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=krzk+dt@kernel.org \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=lee@kernel.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-pwm@vger.kernel.org \
    --cc=nuno.sa@analog.com \
    --cc=robh@kernel.org \
    --cc=ukleinek@kernel.org \
    --cc=victor.liu@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).