Skip to content

Commit d493058

Browse files
6by9broonie
authored andcommitted
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 <[email protected]> Signed-off-by: Marek Vasut <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 6d09c6e commit d493058

File tree

3 files changed

+125
-0
lines changed

3 files changed

+125
-0
lines changed

drivers/regulator/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,16 @@ config REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY
11531153
touchscreen unit. The regulator is used to enable power to the
11541154
TC358762, display and to control backlight.
11551155

1156+
config REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2
1157+
tristate "Raspberry Pi 7-inch touchscreen panel V2 regulator"
1158+
depends on I2C
1159+
select GPIO_REGMAP
1160+
select REGMAP_I2C
1161+
help
1162+
This driver supports regulator on the V2 Raspberry Pi touchscreen
1163+
unit. The regulator is used to enable power to the display and to
1164+
control backlight PWM.
1165+
11561166
config REGULATOR_RC5T583
11571167
tristate "RICOH RC5T583 Power regulators"
11581168
depends on MFD_RC5T583

drivers/regulator/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o
136136
obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
137137
obj-$(CONFIG_REGULATOR_RAA215300) += raa215300.o
138138
obj-$(CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY) += rpi-panel-attiny-regulator.o
139+
obj-$(CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2) += rpi-panel-v2-regulator.o
139140
obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o
140141
obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o
141142
obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (C) 2022 Raspberry Pi Ltd.
4+
* Copyright (C) 2025 Marek Vasut
5+
*/
6+
7+
#include <linux/err.h>
8+
#include <linux/gpio/driver.h>
9+
#include <linux/gpio/regmap.h>
10+
#include <linux/i2c.h>
11+
#include <linux/module.h>
12+
#include <linux/pwm.h>
13+
#include <linux/regmap.h>
14+
15+
/* I2C registers of the microcontroller. */
16+
#define REG_ID 0x01
17+
#define REG_POWERON 0x02
18+
#define REG_PWM 0x03
19+
20+
/* Bits for poweron register */
21+
#define LCD_RESET_BIT BIT(0)
22+
#define CTP_RESET_BIT BIT(1)
23+
24+
/* Bits for the PWM register */
25+
#define PWM_BL_ENABLE BIT(7)
26+
#define PWM_BL_MASK GENMASK(4, 0)
27+
28+
/* Treat LCD_RESET and CTP_RESET as GPIOs */
29+
#define NUM_GPIO 2
30+
31+
static const struct regmap_config rpi_panel_regmap_config = {
32+
.reg_bits = 8,
33+
.val_bits = 8,
34+
.max_register = REG_PWM,
35+
.can_sleep = true,
36+
};
37+
38+
static int rpi_panel_v2_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
39+
const struct pwm_state *state)
40+
{
41+
struct regmap *regmap = pwmchip_get_drvdata(chip);
42+
unsigned int duty;
43+
44+
if (state->polarity != PWM_POLARITY_NORMAL)
45+
return -EINVAL;
46+
47+
if (!state->enabled)
48+
return regmap_write(regmap, REG_PWM, 0);
49+
50+
duty = pwm_get_relative_duty_cycle(state, PWM_BL_MASK);
51+
return regmap_write(regmap, REG_PWM, duty | PWM_BL_ENABLE);
52+
}
53+
54+
static const struct pwm_ops rpi_panel_v2_pwm_ops = {
55+
.apply = rpi_panel_v2_pwm_apply,
56+
};
57+
58+
/*
59+
* I2C driver interface functions
60+
*/
61+
static int rpi_panel_v2_i2c_probe(struct i2c_client *i2c)
62+
{
63+
struct gpio_regmap_config gconfig = {
64+
.ngpio = NUM_GPIO,
65+
.ngpio_per_reg = NUM_GPIO,
66+
.parent = &i2c->dev,
67+
.reg_set_base = REG_POWERON,
68+
};
69+
struct regmap *regmap;
70+
struct pwm_chip *pc;
71+
int ret;
72+
73+
pc = devm_pwmchip_alloc(&i2c->dev, 1, 0);
74+
if (IS_ERR(pc))
75+
return PTR_ERR(pc);
76+
77+
pc->ops = &rpi_panel_v2_pwm_ops;
78+
79+
regmap = devm_regmap_init_i2c(i2c, &rpi_panel_regmap_config);
80+
if (IS_ERR(regmap))
81+
return dev_err_probe(&i2c->dev, PTR_ERR(regmap), "Failed to allocate regmap\n");
82+
83+
pwmchip_set_drvdata(pc, regmap);
84+
85+
regmap_write(regmap, REG_POWERON, 0);
86+
87+
gconfig.regmap = regmap;
88+
ret = PTR_ERR_OR_ZERO(devm_gpio_regmap_register(&i2c->dev, &gconfig));
89+
if (ret)
90+
return dev_err_probe(&i2c->dev, ret, "Failed to create gpiochip\n");
91+
92+
return devm_pwmchip_add(&i2c->dev, pc);
93+
}
94+
95+
static const struct of_device_id rpi_panel_v2_dt_ids[] = {
96+
{ .compatible = "raspberrypi,touchscreen-panel-regulator-v2" },
97+
{ },
98+
};
99+
MODULE_DEVICE_TABLE(of, rpi_panel_v2_dt_ids);
100+
101+
static struct i2c_driver rpi_panel_v2_regulator_driver = {
102+
.driver = {
103+
.name = "rpi_touchscreen_v2",
104+
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
105+
.of_match_table = of_match_ptr(rpi_panel_v2_dt_ids),
106+
},
107+
.probe = rpi_panel_v2_i2c_probe,
108+
};
109+
110+
module_i2c_driver(rpi_panel_v2_regulator_driver);
111+
112+
MODULE_AUTHOR("Dave Stevenson <[email protected]>");
113+
MODULE_DESCRIPTION("Regulator device driver for Raspberry Pi 7-inch V2 touchscreen");
114+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)