[PATCH 2/2] regulator: rpi-panel-v2: Add regulator for 7" Raspberry Pi 720x1280

Geert Uytterhoeven geert at linux-m68k.org
Wed Jun 11 02:55:08 PDT 2025


CC pwm

On Wed, 11 Jun 2025 at 10:19, Marek Vasut
<marek.vasut+renesas at mailbox.org> wrote:
> From: Dave Stevenson <dave.stevenson at raspberrypi.com>
>
> Add regulator for the 7" Raspberry Pi 720x1280 DSI panel based on ili9881.
> This is the Raspberry Pi DSI Panel V2. The newer Raspberry Pi 5" and 7"
> panels have a slightly different register map to the original one. Add a
> new driver for this "regulator" chip, this time by exposing two GPIOs and
> one PWM controller, both of which can be consumed by panel driver and
> pwm-backlight respectively.
>
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> Signed-off-by: Marek Vasut <marek.vasut+renesas at mailbox.org>
> ---
> Loosely based on:
> https://github.com/raspberrypi/linux 3c07b87e877e ("regulator: Add a regulator for the new LCD panels")]
> https://github.com/raspberrypi/linux 68c59b9e6275 ("regulator: rpi_panel_v2: Add remove and shutdown hooks")]
> ---
> Cc: Broadcom internal kernel review list <bcm-kernel-feedback-list at broadcom.com>
> Cc: Conor Dooley <conor+dt at kernel.org>
> Cc: Dave Stevenson <dave.stevenson at raspberrypi.com>
> Cc: Florian Fainelli <florian.fainelli at broadcom.com>
> Cc: Krzysztof Kozlowski <krzk+dt at kernel.org>
> Cc: Liam Girdwood <lgirdwood at gmail.com>
> Cc: Mark Brown <broonie at kernel.org>
> Cc: Rob Herring <robh at kernel.org>
> Cc: devicetree at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-renesas-soc at vger.kernel.org
> Cc: linux-rpi-kernel at lists.infradead.org
> ---
>  drivers/regulator/Kconfig                  |  10 ++
>  drivers/regulator/Makefile                 |   1 +
>  drivers/regulator/rpi-panel-v2-regulator.c | 114 +++++++++++++++++++++
>  3 files changed, 125 insertions(+)
>  create mode 100644 drivers/regulator/rpi-panel-v2-regulator.c
>
> diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
> index 6d8988387da4..21ad6d938e4d 100644
> --- a/drivers/regulator/Kconfig
> +++ b/drivers/regulator/Kconfig
> @@ -1153,6 +1153,16 @@ config REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY
>           touchscreen unit. The regulator is used to enable power to the
>           TC358762, display and to control backlight.
>
> +config REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2
> +       tristate "Raspberry Pi 7-inch touchscreen panel V2 regulator"
> +       depends on I2C
> +       select GPIO_REGMAP
> +       select REGMAP_I2C
> +       help
> +         This driver supports regulator on the V2 Raspberry Pi touchscreen
> +         unit. The regulator is used to enable power to the display and to
> +         control backlight PWM.
> +
>  config REGULATOR_RC5T583
>         tristate "RICOH RC5T583 Power regulators"
>         depends on MFD_RC5T583
> diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
> index c0bc7a0f4e67..be98b29d6675 100644
> --- a/drivers/regulator/Makefile
> +++ b/drivers/regulator/Makefile
> @@ -136,6 +136,7 @@ obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o
>  obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
>  obj-$(CONFIG_REGULATOR_RAA215300) += raa215300.o
>  obj-$(CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY)  += rpi-panel-attiny-regulator.o
> +obj-$(CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2)  += rpi-panel-v2-regulator.o
>  obj-$(CONFIG_REGULATOR_RC5T583)  += rc5t583-regulator.o
>  obj-$(CONFIG_REGULATOR_RK808)   += rk808-regulator.o
>  obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
> diff --git a/drivers/regulator/rpi-panel-v2-regulator.c b/drivers/regulator/rpi-panel-v2-regulator.c
> new file mode 100644
> index 000000000000..b77383584a3a
> --- /dev/null
> +++ b/drivers/regulator/rpi-panel-v2-regulator.c
> @@ -0,0 +1,114 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2022 Raspberry Pi Ltd.
> + * Copyright (C) 2025 Marek Vasut
> + */
> +
> +#include <linux/err.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/gpio/regmap.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/pwm.h>
> +#include <linux/regmap.h>
> +
> +/* I2C registers of the microcontroller. */
> +#define REG_ID         0x01
> +#define REG_POWERON    0x02
> +#define REG_PWM                0x03
> +
> +/* Bits for poweron register */
> +#define LCD_RESET_BIT  BIT(0)
> +#define CTP_RESET_BIT  BIT(1)
> +
> +/* Bits for the PWM register */
> +#define PWM_BL_ENABLE  BIT(7)
> +#define PWM_BL_MASK    GENMASK(4, 0)
> +
> +/* Treat LCD_RESET and CTP_RESET as GPIOs */
> +#define NUM_GPIO       2
> +
> +static const struct regmap_config rpi_panel_regmap_config = {
> +       .reg_bits = 8,
> +       .val_bits = 8,
> +       .max_register = REG_PWM,
> +       .can_sleep = true,
> +};
> +
> +static int rpi_panel_v2_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> +                                 const struct pwm_state *state)
> +{
> +       struct regmap *regmap = pwmchip_get_drvdata(chip);
> +       unsigned int duty;
> +
> +       if (state->polarity != PWM_POLARITY_NORMAL)
> +               return -EINVAL;
> +
> +       if (!state->enabled)
> +               return regmap_write(regmap, REG_PWM, 0);
> +
> +       duty = pwm_get_relative_duty_cycle(state, PWM_BL_MASK);
> +       return regmap_write(regmap, REG_PWM, duty | PWM_BL_ENABLE);
> +}
> +
> +static const struct pwm_ops rpi_panel_v2_pwm_ops = {
> +       .apply = rpi_panel_v2_pwm_apply,
> +};
> +
> +/*
> + * I2C driver interface functions
> + */
> +static int rpi_panel_v2_i2c_probe(struct i2c_client *i2c)
> +{
> +       struct gpio_regmap_config gconfig = {
> +               .ngpio          = NUM_GPIO,
> +               .ngpio_per_reg  = NUM_GPIO,
> +               .parent         = &i2c->dev,
> +               .reg_set_base   = REG_POWERON,
> +       };
> +       struct regmap *regmap;
> +       struct pwm_chip *pc;
> +       int ret;
> +
> +       pc = devm_pwmchip_alloc(&i2c->dev, 1, 0);
> +       if (IS_ERR(pc))
> +               return PTR_ERR(pc);
> +
> +       pc->ops = &rpi_panel_v2_pwm_ops;
> +
> +       regmap = devm_regmap_init_i2c(i2c, &rpi_panel_regmap_config);
> +       if (IS_ERR(regmap))
> +               return dev_err_probe(&i2c->dev, PTR_ERR(regmap), "Failed to allocate regmap\n");
> +
> +       pwmchip_set_drvdata(pc, regmap);
> +
> +       regmap_write(regmap, REG_POWERON, 0);
> +
> +       gconfig.regmap = regmap;
> +       ret = PTR_ERR_OR_ZERO(devm_gpio_regmap_register(&i2c->dev, &gconfig));
> +       if (ret)
> +               return dev_err_probe(&i2c->dev, ret, "Failed to create gpiochip\n");
> +
> +       return devm_pwmchip_add(&i2c->dev, pc);
> +}
> +
> +static const struct of_device_id rpi_panel_v2_dt_ids[] = {
> +       { .compatible = "raspberrypi,touchscreen-panel-regulator-v2" },
> +       { },
> +};
> +MODULE_DEVICE_TABLE(of, rpi_panel_v2_dt_ids);
> +
> +static struct i2c_driver rpi_panel_v2_regulator_driver = {
> +       .driver = {
> +               .name = "rpi_touchscreen_v2",
> +               .probe_type = PROBE_PREFER_ASYNCHRONOUS,
> +               .of_match_table = of_match_ptr(rpi_panel_v2_dt_ids),
> +       },
> +       .probe = rpi_panel_v2_i2c_probe,
> +};
> +
> +module_i2c_driver(rpi_panel_v2_regulator_driver);
> +
> +MODULE_AUTHOR("Dave Stevenson <dave.stevenson at raspberrypi.com>");
> +MODULE_DESCRIPTION("Regulator device driver for Raspberry Pi 7-inch V2 touchscreen");
> +MODULE_LICENSE("GPL");
> --
> 2.47.2



More information about the linux-arm-kernel mailing list