lkml.org 
[lkml]   [2020]   [Nov]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v1 1/2] mfd: rt4831: Adds support for Richtek RT4831 MFD core
    Date
    From: ChiYuan Huang <cy_huang@richtek.com>

    Adds support Richtek RT4831 MFD core.
    RT4831 includes backlight and DSV part that can provode display panel
    for postive and negative voltage and WLED driving.

    Signed-off-by: ChiYuan Huang <cy_huang@richtek.com>
    ---
    drivers/mfd/Kconfig | 11 +++++
    drivers/mfd/Makefile | 1 +
    drivers/mfd/rt4831-core.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++
    3 files changed, 131 insertions(+)
    create mode 100644 drivers/mfd/rt4831-core.c

    diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
    index 8b99a13..a22f002 100644
    --- a/drivers/mfd/Kconfig
    +++ b/drivers/mfd/Kconfig
    @@ -1088,6 +1088,17 @@ config MFD_RDC321X
    southbridge which provides access to GPIOs and Watchdog using the
    southbridge PCI device configuration space.

    +config MFD_RT4831
    + tristate "Richtek RT4831 WLED and DSV IC"
    + depends on I2C
    + select MFD_CORE
    + select REGMAP_I2C
    + help
    + This enables support for the Richtek RT4831.
    + RT4831 includes WLED driver and DisplayBias voltage(+/-) regulator.
    + It's common used to provide the display power and to drive the
    + display backlight WLED.
    +
    config MFD_RT5033
    tristate "Richtek RT5033 Power Management IC"
    depends on I2C
    diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
    index 1780019..4108141 100644
    --- a/drivers/mfd/Makefile
    +++ b/drivers/mfd/Makefile
    @@ -235,6 +235,7 @@ obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o
    obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-pmic-core.o
    obj-$(CONFIG_MFD_HI655X_PMIC) += hi655x-pmic.o
    obj-$(CONFIG_MFD_DLN2) += dln2.o
    +obj-$(CONFIG_MFD_RT4831) += rt4831-core.o
    obj-$(CONFIG_MFD_RT5033) += rt5033.o
    obj-$(CONFIG_MFD_SKY81452) += sky81452.o

    diff --git a/drivers/mfd/rt4831-core.c b/drivers/mfd/rt4831-core.c
    new file mode 100644
    index 00000000..5342959
    --- /dev/null
    +++ b/drivers/mfd/rt4831-core.c
    @@ -0,0 +1,119 @@
    +// SPDX-License-Identifier: GPL-2.0+
    +
    +#include <linux/gpio/consumer.h>
    +#include <linux/i2c.h>
    +#include <linux/kernel.h>
    +#include <linux/mfd/core.h>
    +#include <linux/module.h>
    +#include <linux/regmap.h>
    +
    +#define RT4831_REG_REVISION 0x01
    +#define RT4831_REG_ENABLE 0x08
    +#define RT4831_REG_I2CPROT 0x15
    +
    +#define RICHTEK_VID 0x03
    +#define RT4831_VID_MASK GENMASK(1, 0)
    +#define RT4831_RESET_MASK BIT(7)
    +#define RT4831_I2CSAFETMR_MASK BIT(0)
    +
    +static const struct mfd_cell rt4831_subdevs[] = {
    + OF_MFD_CELL("rt4831-backlight", NULL, NULL, 0, 0, "richtek,rt4831-backlight"),
    + MFD_CELL_NAME("rt4831-regulator")
    +};
    +
    +static bool rt4831_is_accessible_reg(struct device *dev, unsigned int reg)
    +{
    + if (reg >= RT4831_REG_REVISION && reg <= RT4831_REG_I2CPROT)
    + return true;
    + return false;
    +}
    +
    +static const struct regmap_config rt4831_regmap_config = {
    + .reg_bits = 8,
    + .val_bits = 8,
    + .max_register = RT4831_REG_I2CPROT,
    +
    + .readable_reg = rt4831_is_accessible_reg,
    + .writeable_reg = rt4831_is_accessible_reg,
    +};
    +
    +static int rt4831_probe(struct i2c_client *client)
    +{
    + struct gpio_desc *enable;
    + struct regmap *regmap;
    + unsigned int val;
    + int ret;
    +
    + enable = devm_gpiod_get_optional(&client->dev, "enable", GPIOD_OUT_HIGH);
    + if (IS_ERR(enable)) {
    + dev_err(&client->dev, "Failed to get chip enable gpio\n");
    + return PTR_ERR(enable);
    + }
    +
    + regmap = devm_regmap_init_i2c(client, &rt4831_regmap_config);
    + if (IS_ERR(regmap)) {
    + dev_err(&client->dev, "Failed to init regmap\n");
    + return PTR_ERR(regmap);
    + }
    +
    + ret = regmap_read(regmap, RT4831_REG_REVISION, &val);
    + if (ret) {
    + dev_err(&client->dev, "Fail to get version id\n");
    + return ret;
    + }
    +
    + if ((val & RT4831_VID_MASK) != RICHTEK_VID) {
    + dev_err(&client->dev, "VID not matched, val = 0x%02x\n", val);
    + return -ENODEV;
    + }
    +
    + /*
    + * Used to prevent the abnormal shutdown.
    + * If SCL/SDA both keep low for one second to reset HW.
    + */
    + ret = regmap_update_bits(regmap, RT4831_REG_I2CPROT, RT4831_I2CSAFETMR_MASK,
    + RT4831_I2CSAFETMR_MASK);
    + if (ret) {
    + dev_err(&client->dev, "Failed to enable I2C safety timer\n");
    + return ret;
    + }
    +
    + return devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO, rt4831_subdevs,
    + ARRAY_SIZE(rt4831_subdevs), NULL, 0, NULL);
    +}
    +
    +static int rt4831_remove(struct i2c_client *client)
    +{
    + struct regmap *regmap = dev_get_regmap(&client->dev, NULL);
    +
    + /* Make sure all off before module removal */
    + return regmap_update_bits(regmap, RT4831_REG_ENABLE, RT4831_RESET_MASK, RT4831_RESET_MASK);
    +}
    +
    +static void rt4831_shutdown(struct i2c_client *client)
    +{
    + struct regmap *regmap = dev_get_regmap(&client->dev, NULL);
    +
    + /* Make sure all off before machine shutdown */
    + regmap_update_bits(regmap, RT4831_REG_ENABLE, RT4831_RESET_MASK, RT4831_RESET_MASK);
    +}
    +
    +static const struct of_device_id __maybe_unused rt4831_of_match[] = {
    + { .compatible = "richtek,rt4831", },
    + {}
    +};
    +MODULE_DEVICE_TABLE(of, rt4831_of_match);
    +
    +static struct i2c_driver rt4831_driver = {
    + .driver = {
    + .name = "rt4831",
    + .of_match_table = of_match_ptr(rt4831_of_match),
    + },
    + .probe_new = rt4831_probe,
    + .remove = rt4831_remove,
    + .shutdown = rt4831_shutdown,
    +};
    +module_i2c_driver(rt4831_driver);
    +
    +MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
    +MODULE_LICENSE("GPL v2");
    --
    2.7.4
    \
     
     \ /
      Last update: 2020-11-02 04:14    [W:2.678 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site