All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sebastian Reichel <sebastian.reichel@collabora.com>
To: Lee Jones <lee@kernel.org>
Cc: Heiko Stuebner <heiko@sntech.de>,
	Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>,
	Linus Walleij <linus.walleij@linaro.org>,
	Mark Brown <broonie@kernel.org>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Alexandre Belloni <alexandre.belloni@bootlin.com>,
	Alessandro Zummo <a.zummo@towertech.it>,
	linux-rockchip@lists.infradead.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, kernel@collabora.com
Subject: Re: [PATCHv5 07/10] mfd: rk8xx: add rk806 support
Date: Mon, 23 Jan 2023 15:33:21 +0100	[thread overview]
Message-ID: <20230123143321.lsddiol6bo2agfbk@mercury.elektranox.org> (raw)
In-Reply-To: <Y8rIadiDIEdXuM0Y@google.com>

[-- Attachment #1: Type: text/plain, Size: 13592 bytes --]

Hi,

On Fri, Jan 20, 2023 at 04:59:21PM +0000, Lee Jones wrote:
> On Mon, 09 Jan 2023, Sebastian Reichel wrote:
> 
> > Add support for SPI connected rk806, which is used by the RK3588
> > evaluation boards. The PMIC is advertised to support I2C and SPI,
> > but the evaluation boards all use SPI. Thus only SPI support is
> > added here.
> > 
> > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> > ---
> >  drivers/mfd/Kconfig       |  14 ++
> >  drivers/mfd/Makefile      |   1 +
> >  drivers/mfd/rk8xx-core.c  |  67 ++++++-
> >  drivers/mfd/rk8xx-spi.c   | 122 ++++++++++++
> >  include/linux/mfd/rk808.h | 409 ++++++++++++++++++++++++++++++++++++++
> >  5 files changed, 611 insertions(+), 2 deletions(-)
> >  create mode 100644 drivers/mfd/rk8xx-spi.c
> > 
> > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> > index 692e38283bda..13582ea5cb44 100644
> > --- a/drivers/mfd/Kconfig
> > +++ b/drivers/mfd/Kconfig
> > @@ -1222,6 +1222,20 @@ config MFD_RK8XX_I2C
> >  	  through I2C interface. The device supports multiple sub-devices
> >  	  including interrupts, RTC, LDO & DCDC regulators, and onkey.
> >  
> > +config MFD_RK8XX_SPI
> > +	tristate "Rockchip RK806 Power Management Chip"
> > +	depends on SPI && OF
> > +	select MFD_CORE
> > +	select REGMAP_SPI
> > +	select REGMAP_IRQ
> > +	select MFD_RK8XX
> > +	help
> > +	  If you say yes here you get support for the RK806 Power Management
> > +	  chip.
> > +	  This driver provides common support for accessing the device
> > +	  through an SPI interface. The device supports multiple sub-devices
> > +	  including interrupts, LDO & DCDC regulators, and power on-key.
> > +
> >  config MFD_RN5T618
> >  	tristate "Ricoh RN5T567/618 PMIC"
> >  	depends on I2C
> > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> > index f65ef1bd0810..a88f27cd837b 100644
> > --- a/drivers/mfd/Makefile
> > +++ b/drivers/mfd/Makefile
> > @@ -222,6 +222,7 @@ obj-$(CONFIG_MFD_NTXEC)		+= ntxec.o
> >  obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
> >  obj-$(CONFIG_MFD_RK8XX)		+= rk8xx-core.o
> >  obj-$(CONFIG_MFD_RK8XX_I2C)	+= rk8xx-i2c.o
> > +obj-$(CONFIG_MFD_RK8XX_SPI)	+= rk8xx-spi.o
> >  obj-$(CONFIG_MFD_RN5T618)	+= rn5t618.o
> >  obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
> >  obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
> > diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c
> > index c52f5fa1a4da..289f4c1f30c2 100644
> > --- a/drivers/mfd/rk8xx-core.c
> > +++ b/drivers/mfd/rk8xx-core.c
> > @@ -37,6 +37,11 @@ static const struct resource rk805_key_resources[] = {
> >  	DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
> >  };
> >  
> > +static struct resource rk806_pwrkey_resources[] = {
> > +	DEFINE_RES_IRQ(RK806_IRQ_PWRON_FALL),
> > +	DEFINE_RES_IRQ(RK806_IRQ_PWRON_RISE),
> > +};
> > +
> >  static const struct resource rk817_pwrkey_resources[] = {
> >  	DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
> >  	DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
> > @@ -64,6 +69,16 @@ static const struct mfd_cell rk805s[] = {
> >  	},
> >  };
> >  
> > +static const struct mfd_cell rk806s[] = {
> > +	{ .name = "rk805-pinctrl", },
> > +	{ .name = "rk808-regulator", },
> > +	{
> > +		.name = "rk805-pwrkey",
> > +		.num_resources = ARRAY_SIZE(rk806_pwrkey_resources),
> > +		.resources = &rk806_pwrkey_resources[0],
> 
> My OCD-sense is tingling.
> 
> Could you please add the resources *before* the num_resources please?
> 
> Also: '.resources = rk806_pwrkey_resources' is fine

Ack.

> 
> > +	},
> > +};
> > +
> >  static const struct mfd_cell rk808s[] = {
> >  	{ .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
> >  	{ .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
> > @@ -122,6 +137,12 @@ static const struct rk808_reg_data rk805_pre_init_reg[] = {
> >  	{RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
> >  };
> >  
> > +static const struct rk808_reg_data rk806_pre_init_reg[] = {
> > +	{ RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L },
> > +	{ RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN },
> > +	{ RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN },
> > +};
> > +
> >  static const struct rk808_reg_data rk808_pre_init_reg[] = {
> >  	{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_150MA },
> >  	{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_200MA },
> > @@ -272,6 +293,27 @@ static const struct regmap_irq rk805_irqs[] = {
> >  	},
> >  };
> >  
> > +static const struct regmap_irq rk806_irqs[] = {
> > +	/* INT_STS0 IRQs */
> > +	REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL),
> > +	REGMAP_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE),
> > +	REGMAP_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON),
> > +	REGMAP_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP),
> > +	REGMAP_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE),
> > +	REGMAP_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE),
> > +	REGMAP_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL),
> > +	REGMAP_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO),
> > +	/* INT_STS1 IRQs */
> > +	REGMAP_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0),
> > +	REGMAP_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1),
> > +	REGMAP_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2),
> > +	REGMAP_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR),
> > +	REGMAP_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO),
> > +	REGMAP_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO),
> > +	REGMAP_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO),
> > +	REGMAP_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT),
> > +};
> > +
> >  static const struct regmap_irq rk808_irqs[] = {
> >  	/* INT_STS */
> >  	[RK808_IRQ_VOUT_LO] = {
> > @@ -422,6 +464,18 @@ static struct regmap_irq_chip rk805_irq_chip = {
> >  	.init_ack_masked = true,
> >  };
> >  
> > +static struct regmap_irq_chip rk806_irq_chip = {
> > +	.name = "rk806",
> > +	.irqs = rk806_irqs,
> > +	.num_irqs = ARRAY_SIZE(rk806_irqs),
> > +	.num_regs = 2,
> > +	.irq_reg_stride = 2,
> > +	.mask_base = RK806_INT_MSK0,
> > +	.status_base = RK806_INT_STS0,
> > +	.ack_base = RK806_INT_STS0,
> > +	.init_ack_masked = true,
> > +};
> > +
> >  static const struct regmap_irq_chip rk808_irq_chip = {
> >  	.name = "rk808",
> >  	.irqs = rk808_irqs,
> > @@ -548,6 +602,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
> >  	struct rk808 *rk808;
> >  	const struct rk808_reg_data *pre_init_reg;
> >  	const struct mfd_cell *cells;
> > +	bool dual_support = false;
> >  	int nr_pre_init_regs;
> >  	int nr_cells;
> >  	int ret;
> > @@ -569,6 +624,14 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
> >  		cells = rk805s;
> >  		nr_cells = ARRAY_SIZE(rk805s);
> >  		break;
> > +	case RK806_ID:
> > +		rk808->regmap_irq_chip = &rk806_irq_chip;
> > +		pre_init_reg = rk806_pre_init_reg;
> > +		nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg);
> > +		cells = rk806s;
> > +		nr_cells = ARRAY_SIZE(rk806s);
> > +		dual_support = true;
> > +		break;
> >  	case RK808_ID:
> >  		rk808->regmap_irq_chip = &rk808_irq_chip;
> >  		pre_init_reg = rk808_pre_init_reg;
> > @@ -602,7 +665,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
> >  		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
> >  
> >  	ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
> > -				       IRQF_ONESHOT, -1,
> > +				       IRQF_ONESHOT | (dual_support ? IRQF_SHARED : 0), -1,
> 
> Why not 'dual_support = IRQF_SHARED', then | it regardless?

Ack

> 
> >  				       rk808->regmap_irq_chip, &rk808->irq_data);
> >  	if (ret)
> >  		return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
> > @@ -617,7 +680,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
> >  					     pre_init_reg[i].addr);
> >  	}
> >  
> > -	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
> > +	ret = devm_mfd_add_devices(dev, dual_support ? PLATFORM_DEVID_AUTO : PLATFORM_DEVID_NONE,
> 
> Any reason why you can't use AUTO all the time?

That would change device names (and thus sysfs paths) for already
supported devices. DEVID_AUTO appends a ".<number>" suffix compared
to DEVID_NONE.

> >  			      cells, nr_cells, NULL, 0,
> >  			      regmap_irq_get_domain(rk808->irq_data));
> >  	if (ret)
> > diff --git a/drivers/mfd/rk8xx-spi.c b/drivers/mfd/rk8xx-spi.c
> > new file mode 100644
> > index 000000000000..3fbcaaaa453a
> > --- /dev/null
> > +++ b/drivers/mfd/rk8xx-spi.c
> > @@ -0,0 +1,122 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Rockchip RK806 Core (SPI) driver
> > + *
> > + * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
> > + * Copyright (c) 2023 Collabora Ltd.
> > + *
> > + * Author: Xu Shengfei <xsf@rock-chips.com>
> > + * Author: Sebastian Reichel <sebastian.reichel@collabora.com>
> > + */
> > +
> > +#include <linux/interrupt.h>
> > +#include <linux/mfd/core.h>
> > +#include <linux/mfd/rk808.h>
> > +#include <linux/module.h>
> > +#include <linux/regmap.h>
> > +#include <linux/spi/spi.h>
> > +
> > +#define RK806_CMD		0
> > +#define RK806_REG_ADDR_L	1
> > +#define RK806_REG_ADDR_H	2
> > +
> > +static const struct regmap_range rk806_volatile_ranges[] = {
> > +	regmap_reg_range(RK806_POWER_EN0, RK806_POWER_EN5),
> > +	regmap_reg_range(RK806_DVS_START_CTRL, RK806_INT_MSK1),
> > +};
> > +
> > +static const struct regmap_access_table rk806_volatile_table = {
> > +	.yes_ranges = rk806_volatile_ranges,
> > +	.n_yes_ranges = ARRAY_SIZE(rk806_volatile_ranges),
> > +};
> > +
> > +static const struct regmap_config rk806_regmap_config_spi = {
> > +	.reg_bits = 8,
> > +	.val_bits = 8,
> > +	.cache_type = REGCACHE_RBTREE,
> > +	.volatile_table = &rk806_volatile_table,
> > +};
> > +
> > +static int rk806_spi_bus_write(void *context, const void *vdata, size_t count)
> > +{
> > +	struct device *dev = context;
> > +	struct spi_device *spi = to_spi_device(dev);
> > +	const char *data = vdata;
> > +	char buffer[3] = { 0 };
> > +	struct spi_transfer xfer[2] = { 0 };
> > +
> > +	buffer[RK806_CMD]	 = RK806_CMD_WRITE | (count - 2);
> 
> Comment or define please.
> 
> > +	buffer[RK806_REG_ADDR_L] = data[0];
> 
> As above.
> 
> > +	buffer[RK806_REG_ADDR_H] = RK806_REG_H;
> > +
> > +	xfer[0].tx_buf = buffer;
> > +	xfer[0].len = sizeof(buffer);
> > +	xfer[1].tx_buf = data+1;
> 
> And here.
> 
> > +	xfer[1].len = count-1;
> 
> Here too.

I don't follow. What part do you need comments/defines for? I did
add the RK806_CMD/RK806_REG_ADDR_L/RK806_REG_ADDR_H when you asked
for defines last times, so obviously you meant something else :)

> Nit: spaces around the '+' and '-' please.

Ack.

> > +	return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
> > +}
> > +
> > +static int rk806_spi_bus_read(void *context, const void *vreg, size_t reg_size,
> > +			      void *val, size_t val_size)
> > +{
> > +	struct device *dev = context;
> > +	struct spi_device *spi = to_spi_device(dev);
> > +	const char *reg = vreg;
> > +	char txbuf[3] = { 0 };
> > +
> > +	if (reg_size != sizeof(char) || val_size < 1)
> > +		return -EINVAL;
> > +
> > +	txbuf[RK806_CMD]	= RK806_CMD_READ | (val_size - 1);
> > +	txbuf[RK806_REG_ADDR_L]	= *reg;
> > +	txbuf[RK806_REG_ADDR_H]	= RK806_REG_H;
> 
> What's this for?  Isn't it already 0?

Yes. I guess I could remove the '= { 0 }' init considering I
explicitly do a full init of the buffer. OTOH the compiler will
optimize this anyways.

-- Sebastian

> > +	return spi_write_then_read(spi, txbuf, sizeof(txbuf), val, val_size);
> > +}
> > +
> > +static const struct regmap_bus rk806_regmap_bus_spi = {
> > +	.write = rk806_spi_bus_write,
> > +	.read = rk806_spi_bus_read,
> > +	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
> > +	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
> > +};
> > +
> > +static int rk8xx_spi_probe(struct spi_device *spi)
> > +{
> > +	struct regmap *regmap;
> > +
> > +	regmap = devm_regmap_init(&spi->dev, &rk806_regmap_bus_spi,
> > +				  &spi->dev, &rk806_regmap_config_spi);
> > +	if (IS_ERR(regmap))
> > +		return dev_err_probe(&spi->dev, PTR_ERR(regmap),
> > +				     "Failed to initialize register map\n");
> > +
> > +	return rk8xx_probe(&spi->dev, RK806_ID, spi->irq, regmap);
> > +}
> > +
> > +static const struct of_device_id rk8xx_spi_of_match[] = {
> > +	{ .compatible = "rockchip,rk806", },
> > +	{ }
> > +};
> > +MODULE_DEVICE_TABLE(of, rk8xx_spi_of_match);
> > +
> > +static const struct spi_device_id rk8xx_spi_id_table[] = {
> > +	{ "rk806", 0 },
> > +	{ }
> > +};
> > +MODULE_DEVICE_TABLE(spi, rk8xx_spi_id_table);
> > +
> > +static struct spi_driver rk8xx_spi_driver = {
> > +	.driver		= {
> > +		.name	= "rk8xx-spi",
> > +		.of_match_table = rk8xx_spi_of_match,
> > +	},
> > +	.probe		= rk8xx_spi_probe,
> > +	.id_table	= rk8xx_spi_id_table,
> > +};
> > +module_spi_driver(rk8xx_spi_driver);
> > +
> > +MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
> > +MODULE_DESCRIPTION("RK8xx SPI PMIC driver");
> > +MODULE_LICENSE("GPL v2");
> > diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
> 
> -- 
> Lee Jones [李琼斯]
> 
> -- 
> To unsubscribe, send mail to kernel-unsubscribe@lists.collabora.co.uk.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

WARNING: multiple messages have this Message-ID (diff)
From: Sebastian Reichel <sebastian.reichel@collabora.com>
To: Lee Jones <lee@kernel.org>
Cc: Heiko Stuebner <heiko@sntech.de>,
	Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
	Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>,
	Linus Walleij <linus.walleij@linaro.org>,
	Mark Brown <broonie@kernel.org>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Alexandre Belloni <alexandre.belloni@bootlin.com>,
	Alessandro Zummo <a.zummo@towertech.it>,
	linux-rockchip@lists.infradead.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, kernel@collabora.com
Subject: Re: [PATCHv5 07/10] mfd: rk8xx: add rk806 support
Date: Mon, 23 Jan 2023 15:33:21 +0100	[thread overview]
Message-ID: <20230123143321.lsddiol6bo2agfbk@mercury.elektranox.org> (raw)
In-Reply-To: <Y8rIadiDIEdXuM0Y@google.com>


[-- Attachment #1.1: Type: text/plain, Size: 13592 bytes --]

Hi,

On Fri, Jan 20, 2023 at 04:59:21PM +0000, Lee Jones wrote:
> On Mon, 09 Jan 2023, Sebastian Reichel wrote:
> 
> > Add support for SPI connected rk806, which is used by the RK3588
> > evaluation boards. The PMIC is advertised to support I2C and SPI,
> > but the evaluation boards all use SPI. Thus only SPI support is
> > added here.
> > 
> > Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
> > ---
> >  drivers/mfd/Kconfig       |  14 ++
> >  drivers/mfd/Makefile      |   1 +
> >  drivers/mfd/rk8xx-core.c  |  67 ++++++-
> >  drivers/mfd/rk8xx-spi.c   | 122 ++++++++++++
> >  include/linux/mfd/rk808.h | 409 ++++++++++++++++++++++++++++++++++++++
> >  5 files changed, 611 insertions(+), 2 deletions(-)
> >  create mode 100644 drivers/mfd/rk8xx-spi.c
> > 
> > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> > index 692e38283bda..13582ea5cb44 100644
> > --- a/drivers/mfd/Kconfig
> > +++ b/drivers/mfd/Kconfig
> > @@ -1222,6 +1222,20 @@ config MFD_RK8XX_I2C
> >  	  through I2C interface. The device supports multiple sub-devices
> >  	  including interrupts, RTC, LDO & DCDC regulators, and onkey.
> >  
> > +config MFD_RK8XX_SPI
> > +	tristate "Rockchip RK806 Power Management Chip"
> > +	depends on SPI && OF
> > +	select MFD_CORE
> > +	select REGMAP_SPI
> > +	select REGMAP_IRQ
> > +	select MFD_RK8XX
> > +	help
> > +	  If you say yes here you get support for the RK806 Power Management
> > +	  chip.
> > +	  This driver provides common support for accessing the device
> > +	  through an SPI interface. The device supports multiple sub-devices
> > +	  including interrupts, LDO & DCDC regulators, and power on-key.
> > +
> >  config MFD_RN5T618
> >  	tristate "Ricoh RN5T567/618 PMIC"
> >  	depends on I2C
> > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> > index f65ef1bd0810..a88f27cd837b 100644
> > --- a/drivers/mfd/Makefile
> > +++ b/drivers/mfd/Makefile
> > @@ -222,6 +222,7 @@ obj-$(CONFIG_MFD_NTXEC)		+= ntxec.o
> >  obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
> >  obj-$(CONFIG_MFD_RK8XX)		+= rk8xx-core.o
> >  obj-$(CONFIG_MFD_RK8XX_I2C)	+= rk8xx-i2c.o
> > +obj-$(CONFIG_MFD_RK8XX_SPI)	+= rk8xx-spi.o
> >  obj-$(CONFIG_MFD_RN5T618)	+= rn5t618.o
> >  obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
> >  obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
> > diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c
> > index c52f5fa1a4da..289f4c1f30c2 100644
> > --- a/drivers/mfd/rk8xx-core.c
> > +++ b/drivers/mfd/rk8xx-core.c
> > @@ -37,6 +37,11 @@ static const struct resource rk805_key_resources[] = {
> >  	DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL),
> >  };
> >  
> > +static struct resource rk806_pwrkey_resources[] = {
> > +	DEFINE_RES_IRQ(RK806_IRQ_PWRON_FALL),
> > +	DEFINE_RES_IRQ(RK806_IRQ_PWRON_RISE),
> > +};
> > +
> >  static const struct resource rk817_pwrkey_resources[] = {
> >  	DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE),
> >  	DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL),
> > @@ -64,6 +69,16 @@ static const struct mfd_cell rk805s[] = {
> >  	},
> >  };
> >  
> > +static const struct mfd_cell rk806s[] = {
> > +	{ .name = "rk805-pinctrl", },
> > +	{ .name = "rk808-regulator", },
> > +	{
> > +		.name = "rk805-pwrkey",
> > +		.num_resources = ARRAY_SIZE(rk806_pwrkey_resources),
> > +		.resources = &rk806_pwrkey_resources[0],
> 
> My OCD-sense is tingling.
> 
> Could you please add the resources *before* the num_resources please?
> 
> Also: '.resources = rk806_pwrkey_resources' is fine

Ack.

> 
> > +	},
> > +};
> > +
> >  static const struct mfd_cell rk808s[] = {
> >  	{ .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
> >  	{ .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
> > @@ -122,6 +137,12 @@ static const struct rk808_reg_data rk805_pre_init_reg[] = {
> >  	{RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
> >  };
> >  
> > +static const struct rk808_reg_data rk806_pre_init_reg[] = {
> > +	{ RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L },
> > +	{ RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN },
> > +	{ RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN },
> > +};
> > +
> >  static const struct rk808_reg_data rk808_pre_init_reg[] = {
> >  	{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_150MA },
> >  	{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK,  BUCK_ILMIN_200MA },
> > @@ -272,6 +293,27 @@ static const struct regmap_irq rk805_irqs[] = {
> >  	},
> >  };
> >  
> > +static const struct regmap_irq rk806_irqs[] = {
> > +	/* INT_STS0 IRQs */
> > +	REGMAP_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL),
> > +	REGMAP_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE),
> > +	REGMAP_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON),
> > +	REGMAP_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP),
> > +	REGMAP_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE),
> > +	REGMAP_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE),
> > +	REGMAP_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL),
> > +	REGMAP_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO),
> > +	/* INT_STS1 IRQs */
> > +	REGMAP_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0),
> > +	REGMAP_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1),
> > +	REGMAP_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2),
> > +	REGMAP_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR),
> > +	REGMAP_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO),
> > +	REGMAP_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO),
> > +	REGMAP_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO),
> > +	REGMAP_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT),
> > +};
> > +
> >  static const struct regmap_irq rk808_irqs[] = {
> >  	/* INT_STS */
> >  	[RK808_IRQ_VOUT_LO] = {
> > @@ -422,6 +464,18 @@ static struct regmap_irq_chip rk805_irq_chip = {
> >  	.init_ack_masked = true,
> >  };
> >  
> > +static struct regmap_irq_chip rk806_irq_chip = {
> > +	.name = "rk806",
> > +	.irqs = rk806_irqs,
> > +	.num_irqs = ARRAY_SIZE(rk806_irqs),
> > +	.num_regs = 2,
> > +	.irq_reg_stride = 2,
> > +	.mask_base = RK806_INT_MSK0,
> > +	.status_base = RK806_INT_STS0,
> > +	.ack_base = RK806_INT_STS0,
> > +	.init_ack_masked = true,
> > +};
> > +
> >  static const struct regmap_irq_chip rk808_irq_chip = {
> >  	.name = "rk808",
> >  	.irqs = rk808_irqs,
> > @@ -548,6 +602,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
> >  	struct rk808 *rk808;
> >  	const struct rk808_reg_data *pre_init_reg;
> >  	const struct mfd_cell *cells;
> > +	bool dual_support = false;
> >  	int nr_pre_init_regs;
> >  	int nr_cells;
> >  	int ret;
> > @@ -569,6 +624,14 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
> >  		cells = rk805s;
> >  		nr_cells = ARRAY_SIZE(rk805s);
> >  		break;
> > +	case RK806_ID:
> > +		rk808->regmap_irq_chip = &rk806_irq_chip;
> > +		pre_init_reg = rk806_pre_init_reg;
> > +		nr_pre_init_regs = ARRAY_SIZE(rk806_pre_init_reg);
> > +		cells = rk806s;
> > +		nr_cells = ARRAY_SIZE(rk806s);
> > +		dual_support = true;
> > +		break;
> >  	case RK808_ID:
> >  		rk808->regmap_irq_chip = &rk808_irq_chip;
> >  		pre_init_reg = rk808_pre_init_reg;
> > @@ -602,7 +665,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
> >  		return dev_err_probe(dev, -EINVAL, "No interrupt support, no core IRQ\n");
> >  
> >  	ret = devm_regmap_add_irq_chip(dev, rk808->regmap, irq,
> > -				       IRQF_ONESHOT, -1,
> > +				       IRQF_ONESHOT | (dual_support ? IRQF_SHARED : 0), -1,
> 
> Why not 'dual_support = IRQF_SHARED', then | it regardless?

Ack

> 
> >  				       rk808->regmap_irq_chip, &rk808->irq_data);
> >  	if (ret)
> >  		return dev_err_probe(dev, ret, "Failed to add irq_chip\n");
> > @@ -617,7 +680,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
> >  					     pre_init_reg[i].addr);
> >  	}
> >  
> > -	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
> > +	ret = devm_mfd_add_devices(dev, dual_support ? PLATFORM_DEVID_AUTO : PLATFORM_DEVID_NONE,
> 
> Any reason why you can't use AUTO all the time?

That would change device names (and thus sysfs paths) for already
supported devices. DEVID_AUTO appends a ".<number>" suffix compared
to DEVID_NONE.

> >  			      cells, nr_cells, NULL, 0,
> >  			      regmap_irq_get_domain(rk808->irq_data));
> >  	if (ret)
> > diff --git a/drivers/mfd/rk8xx-spi.c b/drivers/mfd/rk8xx-spi.c
> > new file mode 100644
> > index 000000000000..3fbcaaaa453a
> > --- /dev/null
> > +++ b/drivers/mfd/rk8xx-spi.c
> > @@ -0,0 +1,122 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Rockchip RK806 Core (SPI) driver
> > + *
> > + * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
> > + * Copyright (c) 2023 Collabora Ltd.
> > + *
> > + * Author: Xu Shengfei <xsf@rock-chips.com>
> > + * Author: Sebastian Reichel <sebastian.reichel@collabora.com>
> > + */
> > +
> > +#include <linux/interrupt.h>
> > +#include <linux/mfd/core.h>
> > +#include <linux/mfd/rk808.h>
> > +#include <linux/module.h>
> > +#include <linux/regmap.h>
> > +#include <linux/spi/spi.h>
> > +
> > +#define RK806_CMD		0
> > +#define RK806_REG_ADDR_L	1
> > +#define RK806_REG_ADDR_H	2
> > +
> > +static const struct regmap_range rk806_volatile_ranges[] = {
> > +	regmap_reg_range(RK806_POWER_EN0, RK806_POWER_EN5),
> > +	regmap_reg_range(RK806_DVS_START_CTRL, RK806_INT_MSK1),
> > +};
> > +
> > +static const struct regmap_access_table rk806_volatile_table = {
> > +	.yes_ranges = rk806_volatile_ranges,
> > +	.n_yes_ranges = ARRAY_SIZE(rk806_volatile_ranges),
> > +};
> > +
> > +static const struct regmap_config rk806_regmap_config_spi = {
> > +	.reg_bits = 8,
> > +	.val_bits = 8,
> > +	.cache_type = REGCACHE_RBTREE,
> > +	.volatile_table = &rk806_volatile_table,
> > +};
> > +
> > +static int rk806_spi_bus_write(void *context, const void *vdata, size_t count)
> > +{
> > +	struct device *dev = context;
> > +	struct spi_device *spi = to_spi_device(dev);
> > +	const char *data = vdata;
> > +	char buffer[3] = { 0 };
> > +	struct spi_transfer xfer[2] = { 0 };
> > +
> > +	buffer[RK806_CMD]	 = RK806_CMD_WRITE | (count - 2);
> 
> Comment or define please.
> 
> > +	buffer[RK806_REG_ADDR_L] = data[0];
> 
> As above.
> 
> > +	buffer[RK806_REG_ADDR_H] = RK806_REG_H;
> > +
> > +	xfer[0].tx_buf = buffer;
> > +	xfer[0].len = sizeof(buffer);
> > +	xfer[1].tx_buf = data+1;
> 
> And here.
> 
> > +	xfer[1].len = count-1;
> 
> Here too.

I don't follow. What part do you need comments/defines for? I did
add the RK806_CMD/RK806_REG_ADDR_L/RK806_REG_ADDR_H when you asked
for defines last times, so obviously you meant something else :)

> Nit: spaces around the '+' and '-' please.

Ack.

> > +	return spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
> > +}
> > +
> > +static int rk806_spi_bus_read(void *context, const void *vreg, size_t reg_size,
> > +			      void *val, size_t val_size)
> > +{
> > +	struct device *dev = context;
> > +	struct spi_device *spi = to_spi_device(dev);
> > +	const char *reg = vreg;
> > +	char txbuf[3] = { 0 };
> > +
> > +	if (reg_size != sizeof(char) || val_size < 1)
> > +		return -EINVAL;
> > +
> > +	txbuf[RK806_CMD]	= RK806_CMD_READ | (val_size - 1);
> > +	txbuf[RK806_REG_ADDR_L]	= *reg;
> > +	txbuf[RK806_REG_ADDR_H]	= RK806_REG_H;
> 
> What's this for?  Isn't it already 0?

Yes. I guess I could remove the '= { 0 }' init considering I
explicitly do a full init of the buffer. OTOH the compiler will
optimize this anyways.

-- Sebastian

> > +	return spi_write_then_read(spi, txbuf, sizeof(txbuf), val, val_size);
> > +}
> > +
> > +static const struct regmap_bus rk806_regmap_bus_spi = {
> > +	.write = rk806_spi_bus_write,
> > +	.read = rk806_spi_bus_read,
> > +	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
> > +	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
> > +};
> > +
> > +static int rk8xx_spi_probe(struct spi_device *spi)
> > +{
> > +	struct regmap *regmap;
> > +
> > +	regmap = devm_regmap_init(&spi->dev, &rk806_regmap_bus_spi,
> > +				  &spi->dev, &rk806_regmap_config_spi);
> > +	if (IS_ERR(regmap))
> > +		return dev_err_probe(&spi->dev, PTR_ERR(regmap),
> > +				     "Failed to initialize register map\n");
> > +
> > +	return rk8xx_probe(&spi->dev, RK806_ID, spi->irq, regmap);
> > +}
> > +
> > +static const struct of_device_id rk8xx_spi_of_match[] = {
> > +	{ .compatible = "rockchip,rk806", },
> > +	{ }
> > +};
> > +MODULE_DEVICE_TABLE(of, rk8xx_spi_of_match);
> > +
> > +static const struct spi_device_id rk8xx_spi_id_table[] = {
> > +	{ "rk806", 0 },
> > +	{ }
> > +};
> > +MODULE_DEVICE_TABLE(spi, rk8xx_spi_id_table);
> > +
> > +static struct spi_driver rk8xx_spi_driver = {
> > +	.driver		= {
> > +		.name	= "rk8xx-spi",
> > +		.of_match_table = rk8xx_spi_of_match,
> > +	},
> > +	.probe		= rk8xx_spi_probe,
> > +	.id_table	= rk8xx_spi_id_table,
> > +};
> > +module_spi_driver(rk8xx_spi_driver);
> > +
> > +MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>");
> > +MODULE_DESCRIPTION("RK8xx SPI PMIC driver");
> > +MODULE_LICENSE("GPL v2");
> > diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h
> 
> -- 
> Lee Jones [李琼斯]
> 
> -- 
> To unsubscribe, send mail to kernel-unsubscribe@lists.collabora.co.uk.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 170 bytes --]

_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

  reply	other threads:[~2023-01-23 14:33 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-09 17:27 [PATCHv5 00/10] Introduce RK806 Support Sebastian Reichel
2023-01-09 17:27 ` Sebastian Reichel
2023-01-09 17:27 ` [PATCHv5 01/10] clk: RK808: reduce 'struct rk808' usage Sebastian Reichel
2023-01-09 17:27   ` Sebastian Reichel
2023-01-09 17:27 ` [PATCHv5 02/10] mfd: rk808: convert to device managed resources Sebastian Reichel
2023-01-09 17:27   ` Sebastian Reichel
2023-01-09 17:27 ` [PATCHv5 03/10] mfd: rk808: use dev_err_probe Sebastian Reichel
2023-01-09 17:27   ` Sebastian Reichel
2023-01-09 17:27 ` [PATCHv5 04/10] mfd: rk808: replace 'struct i2c_client' with 'struct device' Sebastian Reichel
2023-01-09 17:27   ` Sebastian Reichel
2023-01-09 17:27 ` [PATCHv5 05/10] mfd: rk808: split into core and i2c Sebastian Reichel
2023-01-09 17:27   ` Sebastian Reichel
2023-01-20 16:28   ` Lee Jones
2023-01-20 16:28     ` Lee Jones
2023-01-09 17:27 ` [PATCHv5 06/10] dt-bindings: mfd: add rk806 binding Sebastian Reichel
2023-01-09 17:27   ` Sebastian Reichel
2023-01-13  0:10   ` Rob Herring
2023-01-13  0:10     ` Rob Herring
2023-01-09 17:27 ` [PATCHv5 07/10] mfd: rk8xx: add rk806 support Sebastian Reichel
2023-01-09 17:27   ` Sebastian Reichel
2023-01-20 16:59   ` Lee Jones
2023-01-20 16:59     ` Lee Jones
2023-01-23 14:33     ` Sebastian Reichel [this message]
2023-01-23 14:33       ` Sebastian Reichel
2023-01-23 15:27       ` Lee Jones
2023-01-23 15:27         ` Lee Jones
2023-01-09 17:27 ` [PATCHv5 08/10] pinctrl: rk805: add rk806 pinctrl support Sebastian Reichel
2023-01-09 17:27   ` Sebastian Reichel
2023-01-09 17:27 ` [PATCHv5 09/10] regulator: expose regulator_find_closest_bigger Sebastian Reichel
2023-01-09 17:27   ` Sebastian Reichel
2023-01-09 17:27 ` [PATCHv5 10/10] regulator: rk808: add rk806 support Sebastian Reichel
2023-01-09 17:27   ` Sebastian Reichel

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=20230123143321.lsddiol6bo2agfbk@mercury.elektranox.org \
    --to=sebastian.reichel@collabora.com \
    --cc=a.zummo@towertech.it \
    --cc=alexandre.belloni@bootlin.com \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=heiko@sntech.de \
    --cc=kernel@collabora.com \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=lee@kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=mturquette@baylibre.com \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.