mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-09-01 06:39:05 +00:00
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:
parent
6d09c6e474
commit
d49305862f
@ -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
|
||||
|
@ -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
|
||||
|
114
drivers/regulator/rpi-panel-v2-regulator.c
Normal file
114
drivers/regulator/rpi-panel-v2-regulator.c
Normal 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");
|
Loading…
Reference in New Issue
Block a user