regulator: rpi-panel-v2: Add regulator for 7" Raspberry Pi 720x1280

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@raspberrypi.com>
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Link: https://patch.msgid.link/20250609000748.1665219-2-marek.vasut+renesas@mailbox.org
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Dave Stevenson 2025-06-09 02:06:42 +02:00 committed by Mark Brown
parent 6d09c6e474
commit d49305862f
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
3 changed files with 125 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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@raspberrypi.com>");
MODULE_DESCRIPTION("Regulator device driver for Raspberry Pi 7-inch V2 touchscreen");
MODULE_LICENSE("GPL");