CC pwm On Wed, 11 Jun 2025 at 10:19, Marek Vasut <marek.vasut+renesas@xxxxxxxxxxx> wrote: > From: Dave Stevenson <dave.stevenson@xxxxxxxxxxxxxxx> > > 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@xxxxxxxxxxxxxxx> > Signed-off-by: Marek Vasut <marek.vasut+renesas@xxxxxxxxxxx> > --- > 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@xxxxxxxxxxxx> > Cc: Conor Dooley <conor+dt@xxxxxxxxxx> > Cc: Dave Stevenson <dave.stevenson@xxxxxxxxxxxxxxx> > Cc: Florian Fainelli <florian.fainelli@xxxxxxxxxxxx> > Cc: Krzysztof Kozlowski <krzk+dt@xxxxxxxxxx> > Cc: Liam Girdwood <lgirdwood@xxxxxxxxx> > Cc: Mark Brown <broonie@xxxxxxxxxx> > Cc: Rob Herring <robh@xxxxxxxxxx> > Cc: devicetree@xxxxxxxxxxxxxxx > Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx > Cc: linux-renesas-soc@xxxxxxxxxxxxxxx > Cc: linux-rpi-kernel@xxxxxxxxxxxxxxxxxxx > --- > 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@xxxxxxxxxxxxxxx>"); > +MODULE_DESCRIPTION("Regulator device driver for Raspberry Pi 7-inch V2 touchscreen"); > +MODULE_LICENSE("GPL"); > -- > 2.47.2