]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
regulator: rpi-panel-v2: Add regulator for 7" Raspberry Pi 720x1280
authorDave Stevenson <dave.stevenson@raspberrypi.com>
Mon, 9 Jun 2025 00:06:42 +0000 (02:06 +0200)
committerMark Brown <broonie@kernel.org>
Mon, 9 Jun 2025 12:06:29 +0000 (13:06 +0100)
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>
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/rpi-panel-v2-regulator.c [new file with mode: 0644]

index 6d8988387da4599633ca9bde2698b9711e34a245..21ad6d938e4d458e9b7233dc8ca81aaaee7b6568 100644 (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
index c0bc7a0f4e67098c50ac3cf887ae95f46b2eac44..be98b29d6675d8be1ca984c2d137bdfc4ba2de87 100644 (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
diff --git a/drivers/regulator/rpi-panel-v2-regulator.c b/drivers/regulator/rpi-panel-v2-regulator.c
new file mode 100644 (file)
index 0000000..b773835
--- /dev/null
@@ -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");