[PATCH v6 1/4] mfd: rt4831: Adds support for Richtek RT4831

2021-03-28 Thread cy_huang
From: ChiYuan Huang 

This adds support Richtek RT4831 core. It includes four channel WLED driver
and Display Bias Voltage outputs.

Signed-off-by: ChiYuan Huang 
---
The RT4831 regulator patches are already on main stream, and can be referred to
9351ab8b0cb6 regulator: rt4831: Adds support for Richtek RT4831 DSV regulator
934b05e81862 regulator: rt4831: Adds DT binding document for Richtek RT4831 DSV 
regulator

since v6
- Respin the date from 2020 to 2021.
- Rmove the shutdown routine.
- Change the macro OF_MFD_CELL to MFD_CELL_OF.


since v5
- Rename file name from rt4831-core.c to rt4831.c
- Change RICHTEK_VID to RICHTEK_VENDOR_ID.
- Change gpio_desc nameing from 'enable' to 'enable_gpio' in probe.
- Change variable 'val' to the meaningful name 'chip_id'.
- Refine the error log when vendor id is not matched.
- Remove of_match_ptr.

since v2
- Refine Kconfig descriptions.
- Add copyright.
- Refine error logs in probe.
- Refine comment lines in remove and shutdown.
---
 drivers/mfd/Kconfig  |  10 +
 drivers/mfd/Makefile |   1 +
 drivers/mfd/rt4831.c | 115 +++
 3 files changed, 126 insertions(+)
 create mode 100644 drivers/mfd/rt4831.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b74efa4..3f43834 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1065,6 +1065,16 @@ config MFD_RDC321X
  southbridge which provides access to GPIOs and Watchdog using the
  southbridge PCI device configuration space.
 
+config MFD_RT4831
+   tristate "Richtek RT4831 four channel WLED and Display Bias Voltage"
+   depends on I2C
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ This enables support for the Richtek RT4831 that includes 4 channel
+ WLED driving and Display Bias Voltage. It's commonly used to provide
+ power to the LCD display and LCD backlight.
+
 config MFD_RT5033
tristate "Richtek RT5033 Power Management IC"
depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 834f546..5986914 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.o
 obj-$(CONFIG_MFD_RT5033)   += rt5033.o
 obj-$(CONFIG_MFD_SKY81452) += sky81452.o
 
diff --git a/drivers/mfd/rt4831.c b/drivers/mfd/rt4831.c
new file mode 100644
index ..b169781
--- /dev/null
+++ b/drivers/mfd/rt4831.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 Richtek Technology Corp.
+ *
+ * Author: ChiYuan Huang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4831_REG_REVISION0x01
+#define RT4831_REG_ENABLE  0x08
+#define RT4831_REG_I2CPROT 0x15
+
+#define RICHTEK_VENDOR_ID  0x03
+#define RT4831_VID_MASKGENMASK(1, 0)
+#define RT4831_RESET_MASK  BIT(7)
+#define RT4831_I2CSAFETMR_MASK BIT(0)
+
+static const struct mfd_cell rt4831_subdevs[] = {
+   MFD_CELL_OF("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_gpio;
+   struct regmap *regmap;
+   unsigned int chip_id;
+   int ret;
+
+   enable_gpio = devm_gpiod_get_optional(>dev, "enable", 
GPIOD_OUT_HIGH);
+   if (IS_ERR(enable_gpio)) {
+   dev_err(>dev, "Failed to get 'enable' GPIO\n");
+   return PTR_ERR(enable_gpio);
+   }
+
+   regmap = devm_regmap_init_i2c(client, _regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Failed to initialize regmap\n");
+   return PTR_ERR(regmap);
+   }
+
+   ret = regmap_read(regmap, RT4831_REG_REVISION, _id);
+   if (ret) {
+   dev_err(>dev, "Failed to get H/W revision\n");
+   return ret;
+   }
+
+   if ((chip_id & RT4831_VID_MASK) != RICHTEK_VENDOR_ID) {
+   dev_err(>dev, "Chip vendor ID 0x%02x not matched\n", 
chip_id);
+   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, 

[PATCH v6 4/4] backlight: rt4831: Adds support for Richtek RT4831 backlight

2021-03-28 Thread cy_huang
From: ChiYuan Huang 

Adds support for Richtek RT4831 backlight.

Signed-off-by: ChiYuan Huang 
---
since v6
- Fix Kconfig typo.
- Remove internal mutex lock.
- Add the prefix for max brightness.
- rename init_device_properties to parse_backlight_properties.
- Remove some warning message if default value is adopted.
- Add backlight property scale to LINEAR mapping.
- Fix regmap get to check NULL not IS_ERR.
---
 drivers/video/backlight/Kconfig|   8 ++
 drivers/video/backlight/Makefile   |   1 +
 drivers/video/backlight/rt4831-backlight.c | 203 +
 3 files changed, 212 insertions(+)
 create mode 100644 drivers/video/backlight/rt4831-backlight.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index d83c87b..de96441 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -289,6 +289,14 @@ config BACKLIGHT_QCOM_WLED
  If you have the Qualcomm PMIC, say Y to enable a driver for the
  WLED block. Currently it supports PM8941 and PMI8998.
 
+config BACKLIGHT_RT4831
+   tristate "Richtek RT4831 Backlight Driver"
+   depends on MFD_RT4831
+   help
+ This enables support for Richtek RT4831 Backlight driver.
+ It's common used to drive the display WLED. There're four channels
+ inisde, and each channel can provide up to 30mA current.
+
 config BACKLIGHT_SAHARA
tristate "Tabletkiosk Sahara Touch-iT Backlight Driver"
depends on X86
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 685f3f1..cae2c83 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_BACKLIGHT_PANDORA)   += pandora_bl.o
 obj-$(CONFIG_BACKLIGHT_PCF50633)   += pcf50633-backlight.o
 obj-$(CONFIG_BACKLIGHT_PWM)+= pwm_bl.o
 obj-$(CONFIG_BACKLIGHT_QCOM_WLED)  += qcom-wled.o
+obj-$(CONFIG_BACKLIGHT_RT4831) += rt4831-backlight.o
 obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
 obj-$(CONFIG_BACKLIGHT_SKY81452)   += sky81452-backlight.o
 obj-$(CONFIG_BACKLIGHT_TOSA)   += tosa_bl.o
diff --git a/drivers/video/backlight/rt4831-backlight.c 
b/drivers/video/backlight/rt4831-backlight.c
new file mode 100644
index ..42155c7
--- /dev/null
+++ b/drivers/video/backlight/rt4831-backlight.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4831_REG_BLCFG   0x02
+#define RT4831_REG_BLDIML  0x04
+#define RT4831_REG_ENABLE  0x08
+
+#define RT4831_BLMAX_BRIGHTNESS2048
+
+#define RT4831_BLOVP_MASK  GENMASK(7, 5)
+#define RT4831_BLOVP_SHIFT 5
+#define RT4831_BLPWMEN_MASKBIT(0)
+#define RT4831_BLEN_MASK   BIT(4)
+#define RT4831_BLCH_MASK   GENMASK(3, 0)
+#define RT4831_BLDIML_MASK GENMASK(2, 0)
+#define RT4831_BLDIMH_MASK GENMASK(10, 3)
+#define RT4831_BLDIMH_SHIFT3
+
+struct rt4831_priv {
+   struct device *dev;
+   struct regmap *regmap;
+   struct backlight_device *bl;
+};
+
+static int rt4831_bl_update_status(struct backlight_device *bl_dev)
+{
+   struct rt4831_priv *priv = bl_get_data(bl_dev);
+   int brightness = backlight_get_brightness(bl_dev);
+   unsigned int enable = brightness ? RT4831_BLEN_MASK : 0;
+   u8 v[2];
+   int ret;
+
+   if (brightness) {
+   v[0] = (brightness - 1) & RT4831_BLDIML_MASK;
+   v[1] = ((brightness - 1) & RT4831_BLDIMH_MASK) >> 
RT4831_BLDIMH_SHIFT;
+
+   ret = regmap_raw_write(priv->regmap, RT4831_REG_BLDIML, v, 
sizeof(v));
+   if (ret)
+   return ret;
+   }
+
+   return regmap_update_bits(priv->regmap, RT4831_REG_ENABLE, 
RT4831_BLEN_MASK, enable);
+
+}
+
+static int rt4831_bl_get_brightness(struct backlight_device *bl_dev)
+{
+   struct rt4831_priv *priv = bl_get_data(bl_dev);
+   unsigned int val;
+   u8 v[2];
+   int ret;
+
+   ret = regmap_read(priv->regmap, RT4831_REG_ENABLE, );
+   if (ret)
+   return ret;
+
+   if (!(val & RT4831_BLEN_MASK))
+   return 0;
+
+   ret = regmap_raw_read(priv->regmap, RT4831_REG_BLDIML, v, sizeof(v));
+   if (ret)
+   return ret;
+
+   ret = (v[1] << RT4831_BLDIMH_SHIFT) + (v[0] & RT4831_BLDIML_MASK) + 1;
+
+   return ret;
+}
+
+static const struct backlight_ops rt4831_bl_ops = {
+   .options = BL_CORE_SUSPENDRESUME,
+   .update_status = rt4831_bl_update_status,
+   .get_brightness = rt4831_bl_get_brightness,
+};
+
+static int rt4831_parse_backlight_properties(struct rt4831_priv *priv,
+struct backlight_properties 
*bl_props)
+{
+   struct device *dev = priv->dev;
+   u8 propval;
+   u32 brightness;
+   unsigned int val = 0;
+   int ret;
+
+

[PATCH v6 2/4] backlight: rt4831: Adds DT binding document for Richtek RT4831 backlight

2021-03-28 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831 backlight.

Signed-off-by: ChiYuan Huang 
---
 .../leds/backlight/richtek,rt4831-backlight.yaml   | 65 ++
 include/dt-bindings/leds/rt4831-backlight.h| 23 
 2 files changed, 88 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
 create mode 100644 include/dt-bindings/leds/rt4831-backlight.h

diff --git 
a/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
 
b/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
new file mode 100644
index ..4da6a66
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: 
http://devicetree.org/schemas/leds/backlight/richtek,rt4831-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 Backlight
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a mutifunctional device that can provide power to the LCD display
+  and LCD backlight.
+
+  For the LCD backlight, it can provide four channel WLED driving capability.
+  Each channel driving current is up to 30mA
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+properties:
+  compatible:
+const: richtek,rt4831-backlight
+
+  default-brightness:
+description: |
+  The default brightness that applied to the system on start-up.
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 2048
+
+  max-brightness:
+description: |
+  The max brightness for the H/W limit
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 2048
+
+  richtek,pwm-enable:
+description: |
+  Specify the backlight dimming following by PWM duty or by SW control.
+type: boolean
+
+  richtek,bled-ovp-sel:
+description: |
+  Backlight OVP level selection, currently support 17V/21V/25V/29V.
+$ref: /schemas/types.yaml#/definitions/uint8
+default: 1
+minimum: 0
+maximum: 3
+
+  richtek,channel-use:
+description: |
+  Backlight LED channel to be used.
+  BIT 0/1/2/3 is used to indicate led channel 1/2/3/4 enable or disable.
+$ref: /schemas/types.yaml#/definitions/uint8
+minimum: 1
+maximum: 15
+
+required:
+  - compatible
+  - richtek,channel-use
+
+additionalProperties: false
diff --git a/include/dt-bindings/leds/rt4831-backlight.h 
b/include/dt-bindings/leds/rt4831-backlight.h
new file mode 100644
index ..125c635
--- /dev/null
+++ b/include/dt-bindings/leds/rt4831-backlight.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * This header provides constants for rt4831 backlight bindings.
+ *
+ * Copyright (C) 2020, Richtek Technology Corp.
+ * Author: ChiYuan Huang 
+ */
+
+#ifndef _DT_BINDINGS_RT4831_BACKLIGHT_H
+#define _DT_BINDINGS_RT4831_BACKLIGHT_H
+
+#define RT4831_BLOVPLVL_17V0
+#define RT4831_BLOVPLVL_21V1
+#define RT4831_BLOVPLVL_25V2
+#define RT4831_BLOVPLVL_29V3
+
+#define RT4831_BLED_CH1EN  (1 << 0)
+#define RT4831_BLED_CH2EN  (1 << 1)
+#define RT4831_BLED_CH3EN  (1 << 2)
+#define RT4831_BLED_CH4EN  (1 << 3)
+#define RT4831_BLED_ALLCHEN((1 << 4) - 1)
+
+#endif /* _DT_BINDINGS_RT4831_BACKLIGHT_H */
-- 
2.7.4



[PATCH v6 3/4] mfd: rt4831: Adds DT binding document for Richtek RT4831

2021-03-28 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831.

Signed-off-by: ChiYuan Huang 
---
 .../devicetree/bindings/mfd/richtek,rt4831.yaml| 90 ++
 1 file changed, 90 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml

diff --git a/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml 
b/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
new file mode 100644
index ..4762eb1
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
@@ -0,0 +1,90 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/richtek,rt4831.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 DSV and Backlight Integrated IC
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a multifunctional device that can provide power to the LCD display
+  and LCD backlight.
+
+  For Display Bias Voltage DSVP and DSVN, the output range is about 4V to 6.5V.
+  It's sufficient to meet the current LCD power requirement.
+
+  For the LCD backlight, it can provide four channel WLED driving capability.
+  Each channel driving current is up to 30mA
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+properties:
+  compatible:
+const: richtek,rt4831
+
+  reg:
+description: I2C device address.
+maxItems: 1
+
+  enable-gpios:
+description: |
+  GPIO to enable/disable the chip. It is optional.
+  Some usage directly tied this pin to follow VIO 1.8V power on sequence.
+maxItems: 1
+
+  regulators:
+$ref: ../regulator/richtek,rt4831-regulator.yaml
+
+  backlight:
+$ref: ../leds/backlight/richtek,rt4831-backlight.yaml
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+i2c {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  rt4831@11 {
+compatible = "richtek,rt4831";
+reg = <0x11>;
+
+regulators {
+  DSVLCM {
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <715>;
+regulator-allow-bypass;
+  };
+  DSVP {
+regulator-name = "rt4831-dsvp";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+  DSVN {
+regulator-name = "rt4831-dsvn";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+};
+
+backlight {
+  compatible = "richtek,rt4831-backlight";
+  default-brightness = <1024>;
+  max-brightness = <2048>;
+  richtek,bled-ovp-sel = /bits/ 8 ;
+  richtek,channel-use = /bits/ 8 ;
+};
+  };
+};
-- 
2.7.4



[PATCH v3 2/2] leds: rt4505: Add support for Richtek RT4505 flash LED controller

2021-03-26 Thread cy_huang
From: ChiYuan Huang 

Add support for RT4505 flash LED controller. It can support up to 1.5A
flash current with hardware timeout and low input voltage protection.

Signed-off-by: ChiYuan Huang 
Acked-by: Jacek Anaszewski 
---
 drivers/leds/flash/Kconfig   |  11 +
 drivers/leds/flash/Makefile  |   1 +
 drivers/leds/flash/leds-rt4505.c | 430 +++
 3 files changed, 442 insertions(+)
 create mode 100644 drivers/leds/flash/leds-rt4505.c

diff --git a/drivers/leds/flash/Kconfig b/drivers/leds/flash/Kconfig
index b580b41..3f49f3e 100644
--- a/drivers/leds/flash/Kconfig
+++ b/drivers/leds/flash/Kconfig
@@ -2,6 +2,17 @@
 
 if LEDS_CLASS_FLASH
 
+config LEDS_RT4505
+   tristate "LED support for RT4505 flashlight controller"
+   depends on I2C && OF
+   depends on V4L2_FLASH_LED_CLASS || !V4L2_FLASH_LED_CLASS
+   select REGMAP_I2C
+   help
+ This option enables support for the RT4505 flash LED controller.
+ RT4505 includes torch and flash functions with programmable current.
+ And it's commonly used to compensate the illuminance for the camera
+ inside the mobile product like as phones or tablets.
+
 config LEDS_RT8515
tristate "LED support for Richtek RT8515 flash/torch LED"
depends on GPIOLIB
diff --git a/drivers/leds/flash/Makefile b/drivers/leds/flash/Makefile
index e990e25..09aee56 100644
--- a/drivers/leds/flash/Makefile
+++ b/drivers/leds/flash/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 
+obj-$(CONFIG_LEDS_RT4505)  += leds-rt4505.o
 obj-$(CONFIG_LEDS_RT8515)  += leds-rt8515.o
diff --git a/drivers/leds/flash/leds-rt4505.c b/drivers/leds/flash/leds-rt4505.c
new file mode 100644
index ..ee129ab
--- /dev/null
+++ b/drivers/leds/flash/leds-rt4505.c
@@ -0,0 +1,430 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4505_REG_RESET   0x0
+#define RT4505_REG_CONFIG  0x8
+#define RT4505_REG_ILED0x9
+#define RT4505_REG_ENABLE  0xA
+#define RT4505_REG_FLAGS   0xB
+
+#define RT4505_RESET_MASK  BIT(7)
+#define RT4505_FLASHTO_MASKGENMASK(2, 0)
+#define RT4505_ITORCH_MASK GENMASK(7, 5)
+#define RT4505_ITORCH_SHIFT5
+#define RT4505_IFLASH_MASK GENMASK(4, 0)
+#define RT4505_ENABLE_MASK GENMASK(5, 0)
+#define RT4505_TORCH_SET   (BIT(0) | BIT(4))
+#define RT4505_FLASH_SET   (BIT(0) | BIT(1) | BIT(2) | BIT(4))
+#define RT4505_EXT_FLASH_SET   (BIT(0) | BIT(1) | BIT(4) | BIT(5))
+#define RT4505_FLASH_GET   (BIT(0) | BIT(1) | BIT(4))
+#define RT4505_OVP_MASKBIT(3)
+#define RT4505_SHORT_MASK  BIT(2)
+#define RT4505_OTP_MASKBIT(1)
+#define RT4505_TIMEOUT_MASKBIT(0)
+
+#define RT4505_ITORCH_MINUA46000
+#define RT4505_ITORCH_MAXUA375000
+#define RT4505_ITORCH_STPUA47000
+#define RT4505_IFLASH_MINUA93750
+#define RT4505_IFLASH_MAXUA150
+#define RT4505_IFLASH_STPUA93750
+#define RT4505_FLASHTO_MINUS   10
+#define RT4505_FLASHTO_MAXUS   80
+#define RT4505_FLASHTO_STPUS   10
+
+struct rt4505_priv {
+   struct device *dev;
+   struct regmap *regmap;
+   struct mutex lock;
+   struct led_classdev_flash flash;
+   struct v4l2_flash *v4l2_flash;
+};
+
+static int rt4505_torch_brightness_set(struct led_classdev *lcdev,
+  enum led_brightness level)
+{
+   struct rt4505_priv *priv =
+   container_of(lcdev, struct rt4505_priv, flash.led_cdev);
+   u32 val = 0;
+   int ret;
+
+   mutex_lock(>lock);
+
+   if (level != LED_OFF) {
+   ret = regmap_update_bits(priv->regmap,
+RT4505_REG_ILED, RT4505_ITORCH_MASK,
+(level - 1) << RT4505_ITORCH_SHIFT);
+   if (ret)
+   goto unlock;
+
+   val = RT4505_TORCH_SET;
+   }
+
+   ret = regmap_update_bits(priv->regmap, RT4505_REG_ENABLE,
+RT4505_ENABLE_MASK, val);
+
+unlock:
+   mutex_unlock(>lock);
+   return ret;
+}
+
+static enum led_brightness rt4505_torch_brightness_get(
+   struct led_classdev *lcdev)
+{
+   struct rt4505_priv *priv =
+   container_of(lcdev, struct rt4505_priv, flash.led_cdev);
+   u32 val;
+   int ret;
+
+   mutex_lock(>lock);
+
+   ret = regmap_read(priv->regmap, RT4505_REG_ENABLE, );
+   if (ret) {
+   dev_err(lcdev->dev, "Failed to get LED enable\n");
+   ret = LED_OFF;
+   goto unlock;
+   }
+
+   if ((val & RT4505_ENABLE_MASK) != RT4505_TORCH_SET) {
+   ret = LED_OFF;
+   goto unlock;
+   }
+
+   ret = regmap_read(priv->regmap, RT4505_REG_ILED, );
+   if (ret) {
+  

[PATCH v3 1/2] leds: rt4505: Add DT binding document for Richtek RT4505

2021-03-26 Thread cy_huang
From: ChiYuan Huang 

Add DT binding document for Richtek RT4505 flash LED controller.

Signed-off-by: ChiYuan Huang 
Reviewed-by: Rob Herring 
---
Changes since v3
- Port this patch to led for-next tree.
- Merge Acks in the commit context.
- Reorder the patch series from the docs first.

Changes since v2

- Create flash directory into drvers/leds.
- Coding style fix to meet 80 charactors per line limit.
- Refine the description in the Kconfig help text.
- Change all descriptions for 'led' text to uppercase 'LED'.
---
 .../devicetree/bindings/leds/leds-rt4505.yaml  | 57 ++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-rt4505.yaml

diff --git a/Documentation/devicetree/bindings/leds/leds-rt4505.yaml 
b/Documentation/devicetree/bindings/leds/leds-rt4505.yaml
new file mode 100644
index ..5b0c74a
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-rt4505.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/leds-rt4505.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4505 Single Channel LED Driver
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  The RT4505 is a flash LED driver that can support up to 375mA and 1.5A for
+  torch and flash mode, respectively.
+
+  The data sheet can be found at:
+https://www.richtek.com/assets/product_file/RT4505/DS4505-02.pdf
+
+properties:
+  compatible:
+const: richtek,rt4505
+
+  reg:
+description: I2C slave address of the controller.
+maxItems: 1
+
+  led:
+type: object
+$ref: common.yaml#
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+
+i2c0 {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  led-controller@63 {
+compatible = "richtek,rt4505";
+reg = <0x63>;
+
+rt4505_flash: led {
+  function = LED_FUNCTION_FLASH;
+  color = ;
+  led-max-microamp = <375000>;
+  flash-max-microamp = <150>;
+  flash-max-timeout-us = <80>;
+};
+  };
+};
-- 
2.7.4



[PATCH 2/2] usb typec: tcpci: mt6360: Add vbus supply into dt-binding description

2021-01-15 Thread cy_huang
From: ChiYuan Huang 

Add external vbus source into dt-binding description.

Signed-off-by: ChiYuan Huang 
---
 Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml 
b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
index 1e8e1c2..b8d842b 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
+++ b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
@@ -26,6 +26,11 @@ properties:
 items:
   - const: PD_IRQB
 
+  vbus-supply:
+description:
+  Vbus source supply regulator.
+maxItems: 1
+
   connector:
 type: object
 $ref: ../connector/usb-connector.yaml#
@@ -38,6 +43,7 @@ required:
   - compatible
   - interrupts
   - interrupt-names
+  - vbus-supply
 
 examples:
   - |
@@ -54,6 +60,7 @@ examples:
   compatible = "mediatek,mt6360-tcpc";
   interrupts-extended = < 3 IRQ_TYPE_LEVEL_LOW>;
   interrupt-names = "PD_IRQB";
+  vbus-supply = <_vbus>;
 
   connector {
 compatible = "usb-c-connector";
-- 
2.7.4



[PATCH 1/2] usb typec: tcpci: mt6360: Add vsafe0v support and external vbus supply control

2021-01-15 Thread cy_huang
From: ChiYuan Huang 

MT6360 not support for TCPC command to control source and sink.
Uses external 5V vbus regulator as the vbus source control.

Also adds the capability to report vsafe0v.

Signed-off-by: ChiYuan Huang 
---
 drivers/usb/typec/tcpm/tcpci_mt6360.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/drivers/usb/typec/tcpm/tcpci_mt6360.c 
b/drivers/usb/typec/tcpm/tcpci_mt6360.c
index f1bd9e0..0edf4b6 100644
--- a/drivers/usb/typec/tcpm/tcpci_mt6360.c
+++ b/drivers/usb/typec/tcpm/tcpci_mt6360.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "tcpci.h"
@@ -36,6 +37,7 @@ struct mt6360_tcpc_info {
struct tcpci_data tdata;
struct tcpci *tcpci;
struct device *dev;
+   struct regulator *vbus;
int irq;
 };
 
@@ -51,6 +53,27 @@ static inline int mt6360_tcpc_write16(struct regmap *regmap,
return regmap_raw_write(regmap, reg, , sizeof(u16));
 }
 
+static int mt6360_tcpc_set_vbus(struct tcpci *tcpci, struct tcpci_data *data, 
bool src, bool snk)
+{
+   struct mt6360_tcpc_info *mti = container_of(data, struct 
mt6360_tcpc_info, tdata);
+   int ret;
+
+   /* To correctly handle the already enabled vbus and disable its supply 
first */
+   if (regulator_is_enabled(mti->vbus)) {
+   ret = regulator_disable(mti->vbus);
+   if (ret)
+   return ret;
+   }
+
+   if (src) {
+   ret = regulator_enable(mti->vbus);
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+
 static int mt6360_tcpc_init(struct tcpci *tcpci, struct tcpci_data *tdata)
 {
struct regmap *regmap = tdata->regmap;
@@ -138,7 +161,13 @@ static int mt6360_tcpc_probe(struct platform_device *pdev)
if (mti->irq < 0)
return mti->irq;
 
+   mti->vbus = devm_regulator_get(>dev, "vbus");
+   if (IS_ERR(mti->vbus))
+   return PTR_ERR(mti->vbus);
+
mti->tdata.init = mt6360_tcpc_init;
+   mti->tdata.set_vbus = mt6360_tcpc_set_vbus;
+   mti->tdata.vbus_vsafe0v = 1;
mti->tcpci = tcpci_register_port(>dev, >tdata);
if (IS_ERR(mti->tcpci)) {
dev_err(>dev, "Failed to register tcpci port\n");
-- 
2.7.4



[PATCH v5 6/6] regulator: rt4831: Adds support for Richtek RT4831 DSV regulator

2020-12-17 Thread cy_huang
From: ChiYuan Huang 

Adds support for Richtek RT4831 DSV Regulator

Signed-off-by: ChiYuan Huang 
---
 drivers/regulator/Kconfig|  10 ++
 drivers/regulator/Makefile   |   1 +
 drivers/regulator/rt4831-regulator.c | 198 +++
 3 files changed, 209 insertions(+)
 create mode 100644 drivers/regulator/rt4831-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 020a00d..3e875ad 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -931,6 +931,16 @@ config REGULATOR_RT4801
  This adds support for voltage regulators in Richtek RT4801 Display 
Bias IC.
  The device supports two regulators (DSVP/DSVN).
 
+config REGULATOR_RT4831
+   tristate "Richtek RT4831 DSV Regulators"
+   depends on MFD_RT4831
+   help
+ This adds support for voltage regulators in Richtek RT4831.
+ There are three regulators (VLCM/DSVP/DSVN).
+ VLCM is a virtual voltage input for DSVP/DSVN inside IC.
+ And DSVP/DSVN is the real Vout range from 4V to 6.5V.
+ It's common used to provide the power for the display panel.
+
 config REGULATOR_RT5033
tristate "Richtek RT5033 Regulators"
depends on MFD_RT5033
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 6ebae51..eb587d4 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -115,6 +115,7 @@ obj-$(CONFIG_REGULATOR_RK808)   += rk808-regulator.o
 obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
 obj-$(CONFIG_REGULATOR_ROHM)   += rohm-regulator.o
 obj-$(CONFIG_REGULATOR_RT4801) += rt4801-regulator.o
+obj-$(CONFIG_REGULATOR_RT4831) += rt4831-regulator.o
 obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
 obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
diff --git a/drivers/regulator/rt4831-regulator.c 
b/drivers/regulator/rt4831-regulator.c
new file mode 100644
index ..3d4695d
--- /dev/null
+++ b/drivers/regulator/rt4831-regulator.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+enum {
+   DSV_OUT_VLCM = 0,
+   DSV_OUT_VPOS,
+   DSV_OUT_VNEG,
+   DSV_OUT_MAX
+};
+
+#define RT4831_REG_DSVEN   0x09
+#define RT4831_REG_VLCM0x0c
+#define RT4831_REG_VPOS0x0d
+#define RT4831_REG_VNEG0x0e
+#define RT4831_REG_FLAGS   0x0f
+
+#define RT4831_VOLT_MASK   GENMASK(5, 0)
+#define RT4831_DSVMODE_SHIFT   5
+#define RT4831_DSVMODE_MASKGENMASK(7, 5)
+#define RT4831_POSADEN_MASKBIT(4)
+#define RT4831_NEGADEN_MASKBIT(3)
+#define RT4831_POSEN_MASK  BIT(2)
+#define RT4831_NEGEN_MASK  BIT(1)
+
+#define RT4831_OTP_MASKBIT(6)
+#define RT4831_LCMOVP_MASK BIT(5)
+#define RT4831_VPOSSCP_MASKBIT(3)
+#define RT4831_VNEGSCP_MASKBIT(2)
+
+#define DSV_MODE_NORMAL(0x4 << RT4831_DSVMODE_SHIFT)
+#define DSV_MODE_BYPASS(0x6 << RT4831_DSVMODE_SHIFT)
+#define STEP_UV5
+#define VLCM_MIN_UV400
+#define VLCM_MAX_UV715
+#define VLCM_N_VOLTAGES((VLCM_MAX_UV - VLCM_MIN_UV) / STEP_UV 
+ 1)
+#define VPN_MIN_UV 400
+#define VPN_MAX_UV 650
+#define VPN_N_VOLTAGES ((VPN_MAX_UV - VPN_MIN_UV) / STEP_UV + 1)
+
+static int rt4831_get_error_flags(struct regulator_dev *rdev, unsigned int 
*flags)
+{
+   struct regmap *regmap = rdev_get_regmap(rdev);
+   int rid = rdev_get_id(rdev);
+   unsigned int val, events = 0;
+   int ret;
+
+   ret = regmap_read(regmap, RT4831_REG_FLAGS, );
+   if (ret)
+   return ret;
+
+   if (val & RT4831_OTP_MASK)
+   events |= REGULATOR_ERROR_OVER_TEMP;
+
+   if (rid == DSV_OUT_VLCM && (val & RT4831_LCMOVP_MASK))
+   events |= REGULATOR_ERROR_OVER_CURRENT;
+
+   if (rid == DSV_OUT_VPOS && (val & RT4831_VPOSSCP_MASK))
+   events |= REGULATOR_ERROR_OVER_CURRENT;
+
+   if (rid == DSV_OUT_VNEG && (val & RT4831_VNEGSCP_MASK))
+   events |= REGULATOR_ERROR_OVER_CURRENT;
+
+   *flags = events;
+   return 0;
+}
+
+static const struct regulator_ops rt4831_dsvlcm_ops = {
+   .list_voltage = regulator_list_voltage_linear,
+   .set_voltage_sel = regulator_set_voltage_sel_regmap,
+   .get_voltage_sel = regulator_get_voltage_sel_regmap,
+   .set_bypass = regulator_set_bypass_regmap,
+   .get_bypass = regulator_get_bypass_regmap,
+   .get_error_flags = rt4831_get_error_flags,
+};
+
+static const struct regulator_ops rt4831_dsvpn_ops = {
+   .list_voltage = regulator_list_voltage_linear,
+   .set_voltage_sel = regulator_set_voltage_sel_regmap,
+   .get_voltage_sel = regulator_get_voltage_sel_regmap,
+   .enable = 

[PATCH v5 5/6] backlight: rt4831: Adds support for Richtek RT4831 backlight

2020-12-17 Thread cy_huang
From: ChiYuan Huang 

Adds support for Richtek RT4831 backlight.

Signed-off-by: ChiYuan Huang 
---
 drivers/video/backlight/Kconfig|   8 ++
 drivers/video/backlight/Makefile   |   1 +
 drivers/video/backlight/rt4831-backlight.c | 219 +
 3 files changed, 228 insertions(+)
 create mode 100644 drivers/video/backlight/rt4831-backlight.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index d83c87b..666bdb0 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -289,6 +289,14 @@ config BACKLIGHT_QCOM_WLED
  If you have the Qualcomm PMIC, say Y to enable a driver for the
  WLED block. Currently it supports PM8941 and PMI8998.
 
+config BACKLIGHT_RT4831
+   tristate "Richtek RT4831 Backlight Driver"
+   depends on MFD_RT4831
+   help
+ This enables support for Richtek RT4831 Backlight driver.
+ It's commont used to drive the display WLED. There're four channels
+ inisde, and each channel can provide up to 30mA current.
+
 config BACKLIGHT_SAHARA
tristate "Tabletkiosk Sahara Touch-iT Backlight Driver"
depends on X86
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 685f3f1..cae2c83 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_BACKLIGHT_PANDORA)   += pandora_bl.o
 obj-$(CONFIG_BACKLIGHT_PCF50633)   += pcf50633-backlight.o
 obj-$(CONFIG_BACKLIGHT_PWM)+= pwm_bl.o
 obj-$(CONFIG_BACKLIGHT_QCOM_WLED)  += qcom-wled.o
+obj-$(CONFIG_BACKLIGHT_RT4831) += rt4831-backlight.o
 obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
 obj-$(CONFIG_BACKLIGHT_SKY81452)   += sky81452-backlight.o
 obj-$(CONFIG_BACKLIGHT_TOSA)   += tosa_bl.o
diff --git a/drivers/video/backlight/rt4831-backlight.c 
b/drivers/video/backlight/rt4831-backlight.c
new file mode 100644
index ..816c4d6
--- /dev/null
+++ b/drivers/video/backlight/rt4831-backlight.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4831_REG_BLCFG   0x02
+#define RT4831_REG_BLDIML  0x04
+#define RT4831_REG_ENABLE  0x08
+
+#define BL_MAX_BRIGHTNESS  2048
+
+#define RT4831_BLOVP_MASK  GENMASK(7, 5)
+#define RT4831_BLOVP_SHIFT 5
+#define RT4831_BLPWMEN_MASKBIT(0)
+#define RT4831_BLEN_MASK   BIT(4)
+#define RT4831_BLCH_MASK   GENMASK(3, 0)
+#define RT4831_BLDIML_MASK GENMASK(2, 0)
+#define RT4831_BLDIMH_MASK GENMASK(10, 3)
+#define RT4831_BLDIMH_SHIFT3
+
+struct rt4831_priv {
+   struct regmap *regmap;
+   struct mutex lock;
+   struct backlight_device *bl;
+};
+
+static int rt4831_bl_update_status(struct backlight_device *bl_dev)
+{
+   struct rt4831_priv *priv = bl_get_data(bl_dev);
+   int brightness = backlight_get_brightness(bl_dev);
+   unsigned int enable = brightness ? RT4831_BLEN_MASK : 0;
+   u8 v[2];
+   int ret;
+
+   mutex_lock(>lock);
+
+   if (brightness) {
+   v[0] = (brightness - 1) & RT4831_BLDIML_MASK;
+   v[1] = ((brightness - 1) & RT4831_BLDIMH_MASK) >> 
RT4831_BLDIMH_SHIFT;
+
+   ret = regmap_raw_write(priv->regmap, RT4831_REG_BLDIML, v, 
sizeof(v));
+   if (ret)
+   goto unlock;
+   }
+
+   ret = regmap_update_bits(priv->regmap, RT4831_REG_ENABLE, 
RT4831_BLEN_MASK, enable);
+
+unlock:
+   mutex_unlock(>lock);
+   return ret;
+}
+
+static int rt4831_bl_get_brightness(struct backlight_device *bl_dev)
+{
+   struct rt4831_priv *priv = bl_get_data(bl_dev);
+   unsigned int val;
+   u8 v[2];
+   int ret;
+
+   mutex_lock(>lock);
+
+   ret = regmap_read(priv->regmap, RT4831_REG_ENABLE, );
+   if (ret)
+   return ret;
+
+   if (!(val & RT4831_BLEN_MASK)) {
+   ret = 0;
+   goto unlock;
+   }
+
+   ret = regmap_raw_read(priv->regmap, RT4831_REG_BLDIML, v, sizeof(v));
+   if (ret)
+   goto unlock;
+
+   ret = (v[1] << RT4831_BLDIMH_SHIFT) + (v[0] & RT4831_BLDIML_MASK) + 1;
+
+unlock:
+   mutex_unlock(>lock);
+   return ret;
+}
+
+static const struct backlight_ops rt4831_bl_ops = {
+   .options = BL_CORE_SUSPENDRESUME,
+   .update_status = rt4831_bl_update_status,
+   .get_brightness = rt4831_bl_get_brightness,
+};
+
+static int rt4831_init_device_properties(struct rt4831_priv *priv, struct 
device *dev,
+ struct backlight_properties *bl_props)
+{
+   u8 propval;
+   u32 brightness;
+   unsigned int val = 0;
+   int ret;
+
+   /* common properties */
+   ret = device_property_read_u32(dev, "max-brightness", );
+   if (ret) {
+   dev_warn(dev, 

[PATCH v5 4/6] mfd: rt4831: Adds DT binding document for Richtek RT4831 core

2020-12-17 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831 core.

Signed-off-by: ChiYuan Huang 
---
This patch depends on
 "backlight: rt4831: Adds DT binding document for Richtek RT4831 backlight"
 "regulator: rt4831: Adds DT binding document for Richtek RT4831 DSV regulator"

since v5
- Revert mfd dt-binding to v3 patch.

since v4
- remove v3 regulator binding patch, directly merge it into mfd binding.

since v3
- Move include/dt-bindings/leds/rt4831-backlight.h to patch 0002.
- Add dual license tag in mfd binding document.

since v2
- Add regulator-allow-bypass flag in DSVLCM.
---
 .../devicetree/bindings/mfd/richtek,rt4831.yaml| 90 ++
 1 file changed, 90 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml

diff --git a/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml 
b/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
new file mode 100644
index ..4762eb1
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
@@ -0,0 +1,90 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/richtek,rt4831.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 DSV and Backlight Integrated IC
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a multifunctional device that can provide power to the LCD display
+  and LCD backlight.
+
+  For Display Bias Voltage DSVP and DSVN, the output range is about 4V to 6.5V.
+  It's sufficient to meet the current LCD power requirement.
+
+  For the LCD backlight, it can provide four channel WLED driving capability.
+  Each channel driving current is up to 30mA
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+properties:
+  compatible:
+const: richtek,rt4831
+
+  reg:
+description: I2C device address.
+maxItems: 1
+
+  enable-gpios:
+description: |
+  GPIO to enable/disable the chip. It is optional.
+  Some usage directly tied this pin to follow VIO 1.8V power on sequence.
+maxItems: 1
+
+  regulators:
+$ref: ../regulator/richtek,rt4831-regulator.yaml
+
+  backlight:
+$ref: ../leds/backlight/richtek,rt4831-backlight.yaml
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+i2c {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  rt4831@11 {
+compatible = "richtek,rt4831";
+reg = <0x11>;
+
+regulators {
+  DSVLCM {
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <715>;
+regulator-allow-bypass;
+  };
+  DSVP {
+regulator-name = "rt4831-dsvp";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+  DSVN {
+regulator-name = "rt4831-dsvn";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+};
+
+backlight {
+  compatible = "richtek,rt4831-backlight";
+  default-brightness = <1024>;
+  max-brightness = <2048>;
+  richtek,bled-ovp-sel = /bits/ 8 ;
+  richtek,channel-use = /bits/ 8 ;
+};
+  };
+};
-- 
2.7.4



[PATCH v5 3/6] regulator: rt4831: Adds DT binding document for Richtek RT4831 DSV regulator

2020-12-17 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831 DSV regulator.

Signed-off-by: ChiYuan Huang 
---
since v5
- Revert it back from v3 patch.
- Drop the example in dt-binding, Already full example in mfd dt-binding.
---
 .../regulator/richtek,rt4831-regulator.yaml| 35 ++
 1 file changed, 35 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml

diff --git 
a/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml 
b/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml
new file mode 100644
index ..d9c2333
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/richtek,rt4831-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 Display Bias Voltage Regulator
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a multifunctional device that can provide power to the LCD display
+  and LCD backlight.
+
+  For Display Bias Voltage DSVP and DSVN, the output range is about 4V to 6.5V.
+  It is sufficient to meet the current LCD power requirement.
+
+  DSVLCM is a boost regulator in IC internal as DSVP and DSVN input power.
+  Its voltage should be configured above 0.15V to 0.2V gap larger than the
+  voltage needed for DSVP and DSVN. Too much voltage gap could improve the
+  voltage drop from the heavy loading scenario. But it also make the power
+  efficiency worse. It's a trade-off.
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+patternProperties:
+  "^DSV(LCM|P|N)$":
+type: object
+$ref: regulator.yaml#
+description:
+  Properties for single Display Bias Voltage regulator.
+
+additionalProperties: false
-- 
2.7.4



[PATCH v5 2/6] backlight: rt4831: Adds DT binding document for Richtek RT4831 backlight

2020-12-17 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831 backlight.

Signed-off-by: ChiYuan Huang 
---
since v5
- Drop the example in dt-binding. Aready full example in mfd dt-binding.

since v3
- Move inlcude/dt-bindings/leds/rt4831-backlight.h from patch 0004 to here.
- Add dual license tag in header and backlight binding document.
- Left backlight dt-binding example only.
---
 .../leds/backlight/richtek,rt4831-backlight.yaml   | 65 ++
 include/dt-bindings/leds/rt4831-backlight.h| 23 
 2 files changed, 88 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
 create mode 100644 include/dt-bindings/leds/rt4831-backlight.h

diff --git 
a/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
 
b/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
new file mode 100644
index ..4da6a66
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: 
http://devicetree.org/schemas/leds/backlight/richtek,rt4831-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 Backlight
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a mutifunctional device that can provide power to the LCD display
+  and LCD backlight.
+
+  For the LCD backlight, it can provide four channel WLED driving capability.
+  Each channel driving current is up to 30mA
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+properties:
+  compatible:
+const: richtek,rt4831-backlight
+
+  default-brightness:
+description: |
+  The default brightness that applied to the system on start-up.
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 2048
+
+  max-brightness:
+description: |
+  The max brightness for the H/W limit
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 2048
+
+  richtek,pwm-enable:
+description: |
+  Specify the backlight dimming following by PWM duty or by SW control.
+type: boolean
+
+  richtek,bled-ovp-sel:
+description: |
+  Backlight OVP level selection, currently support 17V/21V/25V/29V.
+$ref: /schemas/types.yaml#/definitions/uint8
+default: 1
+minimum: 0
+maximum: 3
+
+  richtek,channel-use:
+description: |
+  Backlight LED channel to be used.
+  BIT 0/1/2/3 is used to indicate led channel 1/2/3/4 enable or disable.
+$ref: /schemas/types.yaml#/definitions/uint8
+minimum: 1
+maximum: 15
+
+required:
+  - compatible
+  - richtek,channel-use
+
+additionalProperties: false
diff --git a/include/dt-bindings/leds/rt4831-backlight.h 
b/include/dt-bindings/leds/rt4831-backlight.h
new file mode 100644
index ..125c635
--- /dev/null
+++ b/include/dt-bindings/leds/rt4831-backlight.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * This header provides constants for rt4831 backlight bindings.
+ *
+ * Copyright (C) 2020, Richtek Technology Corp.
+ * Author: ChiYuan Huang 
+ */
+
+#ifndef _DT_BINDINGS_RT4831_BACKLIGHT_H
+#define _DT_BINDINGS_RT4831_BACKLIGHT_H
+
+#define RT4831_BLOVPLVL_17V0
+#define RT4831_BLOVPLVL_21V1
+#define RT4831_BLOVPLVL_25V2
+#define RT4831_BLOVPLVL_29V3
+
+#define RT4831_BLED_CH1EN  (1 << 0)
+#define RT4831_BLED_CH2EN  (1 << 1)
+#define RT4831_BLED_CH3EN  (1 << 2)
+#define RT4831_BLED_CH4EN  (1 << 3)
+#define RT4831_BLED_ALLCHEN((1 << 4) - 1)
+
+#endif /* _DT_BINDINGS_RT4831_BACKLIGHT_H */
-- 
2.7.4



[PATCH v5 1/6] mfd: rt4831: Adds support for Richtek RT4831 core

2020-12-17 Thread cy_huang
From: ChiYuan Huang 

This adds support Richtek RT4831 core. It includes four channel WLED driver
and Display Bias Voltage outputs.

Signed-off-by: ChiYuan Huang 
---
since v5
- Rename file name from rt4831-core.c to rt4831.c
- Change RICHTEK_VID to RICHTEK_VENDOR_ID.
- Change gpio_desc nameing from 'enable' to 'enable_gpio' in probe.
- Change variable 'val' to the meaningful name 'chip_id'.
- Refine the error log when vendor id is not matched.
- Remove of_match_ptr.

since v2
- Refine Kconfig descriptions.
- Add copyright.
- Refine error logs in probe.
- Refine comment lines in remove and shutdown.
---
 drivers/mfd/Kconfig  |  10 +
 drivers/mfd/Makefile |   1 +
 drivers/mfd/rt4831.c | 124 +++
 3 files changed, 135 insertions(+)
 create mode 100644 drivers/mfd/rt4831.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 8b99a13..dfb2640 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1088,6 +1088,16 @@ config MFD_RDC321X
  southbridge which provides access to GPIOs and Watchdog using the
  southbridge PCI device configuration space.
 
+config MFD_RT4831
+   tristate "Richtek RT4831 four channel WLED and Display Bias Voltage"
+   depends on I2C
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ This enables support for the Richtek RT4831 that includes 4 channel
+ WLED driving and Display Bias Voltage. It's commonly used to provide
+ power to the LCD display and LCD backlight.
+
 config MFD_RT5033
tristate "Richtek RT5033 Power Management IC"
depends on I2C
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 1780019..28d247b 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.o
 obj-$(CONFIG_MFD_RT5033)   += rt5033.o
 obj-$(CONFIG_MFD_SKY81452) += sky81452.o
 
diff --git a/drivers/mfd/rt4831.c b/drivers/mfd/rt4831.c
new file mode 100644
index ..2bf8364
--- /dev/null
+++ b/drivers/mfd/rt4831.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020 Richtek Technology Corp.
+ *
+ * Author: ChiYuan Huang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4831_REG_REVISION0x01
+#define RT4831_REG_ENABLE  0x08
+#define RT4831_REG_I2CPROT 0x15
+
+#define RICHTEK_VENDOR_ID  0x03
+#define RT4831_VID_MASKGENMASK(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_gpio;
+   struct regmap *regmap;
+   unsigned int chip_id;
+   int ret;
+
+   enable_gpio = devm_gpiod_get_optional(>dev, "enable", 
GPIOD_OUT_HIGH);
+   if (IS_ERR(enable_gpio)) {
+   dev_err(>dev, "Failed to get 'enable' GPIO\n");
+   return PTR_ERR(enable_gpio);
+   }
+
+   regmap = devm_regmap_init_i2c(client, _regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Failed to initialize regmap\n");
+   return PTR_ERR(regmap);
+   }
+
+   ret = regmap_read(regmap, RT4831_REG_REVISION, _id);
+   if (ret) {
+   dev_err(>dev, "Failed to get H/W revision\n");
+   return ret;
+   }
+
+   if ((chip_id & RT4831_VID_MASK) != RICHTEK_VENDOR_ID) {
+   dev_err(>dev, "Chip vendor ID 0x%02x not matched\n", 
chip_id);
+   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(>dev, "Failed to enable I2C safety timer\n");
+   return ret;
+   }
+
+   return devm_mfd_add_devices(>dev, PLATFORM_DEVID_AUTO, 
rt4831_subdevs,
+   ARRAY_SIZE(rt4831_subdevs), NULL, 0, NULL);
+}
+
+static int 

[PATCH v4 2/3] backlight: rt4831: Adds DT binding document for Richtek RT4831 backlight

2020-12-11 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831 backlight.

Signed-off-by: ChiYuan Huang 
---
since v3
- Move inlcude/dt-bindings/leds/rt4831-backlight.h from v3 mfd binding patch to 
here.
- Add dual license tag in header and backlight binding document.
- Left backlight dt-binding example only.
---
 .../leds/backlight/richtek,rt4831-backlight.yaml   | 76 ++
 include/dt-bindings/leds/rt4831-backlight.h| 23 +++
 2 files changed, 99 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
 create mode 100644 include/dt-bindings/leds/rt4831-backlight.h

diff --git 
a/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
 
b/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
new file mode 100644
index ..f24c8d1
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: 
http://devicetree.org/schemas/leds/backlight/richtek,rt4831-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 Backlight
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a mutifunctional device that can provide power to the LCD display
+  and LCD backlight.
+
+  For the LCD backlight, it can provide four channel WLED driving capability.
+  Each channel driving current is up to 30mA
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+properties:
+  compatible:
+const: richtek,rt4831-backlight
+
+  default-brightness:
+description: |
+  The default brightness that applied to the system on start-up.
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 2048
+
+  max-brightness:
+description: |
+  The max brightness for the H/W limit
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 2048
+
+  richtek,pwm-enable:
+description: |
+  Specify the backlight dimming following by PWM duty or by SW control.
+type: boolean
+
+  richtek,bled-ovp-sel:
+description: |
+  Backlight OVP level selection, currently support 17V/21V/25V/29V.
+$ref: /schemas/types.yaml#/definitions/uint8
+default: 1
+minimum: 0
+maximum: 3
+
+  richtek,channel-use:
+description: |
+  Backlight LED channel to be used.
+  BIT 0/1/2/3 is used to indicate led channel 1/2/3/4 enable or disable.
+$ref: /schemas/types.yaml#/definitions/uint8
+minimum: 1
+maximum: 15
+
+required:
+  - compatible
+  - richtek,channel-use
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+backlight {
+  compatible = "richtek,rt4831-backlight";
+  default-brightness = <1024>;
+  max-brightness = <2048>;
+  richtek,bled-ovp-sel = /bits/ 8 ;
+  richtek,channel-use = /bits/ 8 ;
+};
diff --git a/include/dt-bindings/leds/rt4831-backlight.h 
b/include/dt-bindings/leds/rt4831-backlight.h
new file mode 100644
index ..125c635
--- /dev/null
+++ b/include/dt-bindings/leds/rt4831-backlight.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * This header provides constants for rt4831 backlight bindings.
+ *
+ * Copyright (C) 2020, Richtek Technology Corp.
+ * Author: ChiYuan Huang 
+ */
+
+#ifndef _DT_BINDINGS_RT4831_BACKLIGHT_H
+#define _DT_BINDINGS_RT4831_BACKLIGHT_H
+
+#define RT4831_BLOVPLVL_17V0
+#define RT4831_BLOVPLVL_21V1
+#define RT4831_BLOVPLVL_25V2
+#define RT4831_BLOVPLVL_29V3
+
+#define RT4831_BLED_CH1EN  (1 << 0)
+#define RT4831_BLED_CH2EN  (1 << 1)
+#define RT4831_BLED_CH3EN  (1 << 2)
+#define RT4831_BLED_CH4EN  (1 << 3)
+#define RT4831_BLED_ALLCHEN((1 << 4) - 1)
+
+#endif /* _DT_BINDINGS_RT4831_BACKLIGHT_H */
-- 
2.7.4



[PATCH v4 1/3] mfd: rt4831: Adds support for Richtek RT4831 MFD core

2020-12-11 Thread cy_huang
From: ChiYuan Huang 

This adds support Richtek RT4831 MFD core. It includes four channel WLED driver
and Display Bias Voltage outputs.

Signed-off-by: ChiYuan Huang 
---
since v2
- Refine Kconfig descriptions.
- Add copyright.
- Refine error logs in probe.
- Refine comment lines in remove and shutdown.
---
 drivers/mfd/Kconfig   |  10 
 drivers/mfd/Makefile  |   1 +
 drivers/mfd/rt4831-core.c | 124 ++
 3 files changed, 135 insertions(+)
 create mode 100644 drivers/mfd/rt4831-core.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 8b99a13..dfb2640 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1088,6 +1088,16 @@ config MFD_RDC321X
  southbridge which provides access to GPIOs and Watchdog using the
  southbridge PCI device configuration space.
 
+config MFD_RT4831
+   tristate "Richtek RT4831 four channel WLED and Display Bias Voltage"
+   depends on I2C
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ This enables support for the Richtek RT4831 that includes 4 channel
+ WLED driving and Display Bias Voltage. It's commonly used to provide
+ power to the LCD display and LCD backlight.
+
 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 ..f837c06
--- /dev/null
+++ b/drivers/mfd/rt4831-core.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020 Richtek Technology Corp.
+ *
+ * Author: ChiYuan Huang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4831_REG_REVISION0x01
+#define RT4831_REG_ENABLE  0x08
+#define RT4831_REG_I2CPROT 0x15
+
+#define RICHTEK_VID0x03
+#define RT4831_VID_MASKGENMASK(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(>dev, "enable", 
GPIOD_OUT_HIGH);
+   if (IS_ERR(enable)) {
+   dev_err(>dev, "Failed to get 'enable' GPIO\n");
+   return PTR_ERR(enable);
+   }
+
+   regmap = devm_regmap_init_i2c(client, _regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Failed to initialize regmap\n");
+   return PTR_ERR(regmap);
+   }
+
+   ret = regmap_read(regmap, RT4831_REG_REVISION, );
+   if (ret) {
+   dev_err(>dev, "Failed to get H/W revision\n");
+   return ret;
+   }
+
+   if ((val & RT4831_VID_MASK) != RICHTEK_VID) {
+   dev_err(>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(>dev, "Failed to enable I2C safety timer\n");
+   return ret;
+   }
+
+   return devm_mfd_add_devices(>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(>dev, NULL);
+
+   /* Disable WLED and DSV outputs */
+   return regmap_update_bits(regmap, RT4831_REG_ENABLE, RT4831_RESET_MASK, 
RT4831_RESET_MASK);
+}
+
+static void rt4831_shutdown(struct i2c_client *client)
+{
+   

[PATCH v4 3/3] mfd: rt4831: Adds DT binding document for Richtek RT4831 MFD core

2020-12-11 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831 MFD core.

Signed-off-by: ChiYuan Huang 
---
This patch depends on
 "backlight: rt4831: Adds DT binding document for Richtek RT4831 backlight".

since v4
- remove v3 regulator binding patch, directly merge it into mfd binding.

since v3
- Move include/dt-bindings/leds/rt4831-backlight.h to patch 0002.
- Add dual license tag in mfd binding document.

since v2
- Add regulator-allow-bypass flag in DSVLCM.
---
 .../devicetree/bindings/mfd/richtek,rt4831.yaml| 108 +
 1 file changed, 108 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml

diff --git a/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml 
b/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
new file mode 100644
index ..9de7c4a
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
@@ -0,0 +1,108 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/richtek,rt4831.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 DSV and Backlight Integrated IC
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a multifunctional device that can provide power to the LCD display
+  and LCD backlight.
+
+  For Display Bias Voltage DSVP and DSVN, the output range is about 4V to 6.5V.
+  It's sufficient to meet the current LCD power requirement.
+
+  DSVLCM is a boost regulator in IC internal as DSVP and DSVN input power.
+  Its voltage should be configured above 0.15V to 0.2V gap larger than the
+  voltage needed for DSVP and DSVN. Too much voltage gap could improve the
+  voltage drop from the heavy loading scenario. But it also make the power
+  efficiency worse. It's a trade-off.
+
+  For the LCD backlight, it can provide four channel WLED driving capability.
+  Each channel driving current is up to 30mA
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+properties:
+  compatible:
+const: richtek,rt4831
+
+  reg:
+description: I2C device address.
+maxItems: 1
+
+  enable-gpios:
+description: |
+  GPIO to enable/disable the chip. It is optional.
+  Some usage directly tied this pin to follow VIO 1.8V power on sequence.
+maxItems: 1
+
+  regulators:
+type: object
+
+patternProperties:
+  "^DSV(LCM|P|N)$":
+type: object
+$ref: /schemas/regulator/regulator.yaml#
+
+required:
+  - DSVLCM
+  - DSVP
+  - DSVN
+
+additionalProperties: false
+
+  backlight:
+$ref: ../leds/backlight/richtek,rt4831-backlight.yaml
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+i2c {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  rt4831@11 {
+compatible = "richtek,rt4831";
+reg = <0x11>;
+
+regulators {
+  DSVLCM {
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <715>;
+regulator-allow-bypass;
+  };
+  DSVP {
+regulator-name = "rt4831-dsvp";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+  DSVN {
+regulator-name = "rt4831-dsvn";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+};
+
+backlight {
+  compatible = "richtek,rt4831-backlight";
+  default-brightness = <1024>;
+  max-brightness = <2048>;
+  richtek,bled-ovp-sel = /bits/ 8 ;
+  richtek,channel-use = /bits/ 8 ;
+};
+  };
+};
-- 
2.7.4



[PATCH v3 3/4] regulator: rt4831: Adds DT binding document for Richtek RT4831 DSV regulator

2020-12-08 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831 DSV regulator.

Signed-off-by: ChiYuan Huang 
---
since v3
- Add dual license tag in regulator binding document.
- Left regulator dt-binding example only.
---
 .../regulator/richtek,rt4831-regulator.yaml| 57 ++
 1 file changed, 57 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml

diff --git 
a/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml 
b/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml
new file mode 100644
index ..c6741f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/richtek,rt4831-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 Display Bias Voltage Regulator
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a multifunctional device that can provide power to the LCD display
+  and LCD backlight.
+
+  For Display Bias Voltage DSVP and DSVN, the output range is about 4V to 6.5V.
+  It is sufficient to meet the current LCD power requirement.
+
+  DSVLCM is a boost regulator in IC internal as DSVP and DSVN input power.
+  Its voltage should be configured above 0.15V to 0.2V gap larger than the
+  voltage needed for DSVP and DSVN. Too much voltage gap could improve the
+  voltage drop from the heavy loading scenario. But it also make the power
+  efficiency worse. It's a trade-off.
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+patternProperties:
+  "^DSV(LCM|P|N)$":
+type: object
+$ref: regulator.yaml#
+description:
+  Properties for single Display Bias Voltage regulator.
+
+additionalProperties: false
+
+examples:
+  - |
+regulators {
+  DSVLCM {
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <715>;
+regulator-allow-bypass;
+  };
+  DSVP {
+regulator-name = "rt4831-dsvp";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+  DSVN {
+regulator-name = "rt4831-dsvn";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+};
-- 
2.7.4



[PATCH v3 4/4] mfd: rt4831: Adds DT binding document for Richtek RT4831 MFD core

2020-12-08 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831 MFD core.

Signed-off-by: ChiYuan Huang 
---
This patch depends on
 "backlight: rt4831: Adds DT binding document for Richtek RT4831 backlight".
 "regulator: rt4831: Adds DT binding document for Richtek RT4831 DSV regulator".

since v3
- Move include/dt-bindings/leds/rt4831-backlight.h to patch 0002.
- Add dual license tag in mfd binding document.

since v2
- Add regulator-allow-bypass flag in DSVLCM.
---
 .../devicetree/bindings/mfd/richtek,rt4831.yaml| 90 ++
 1 file changed, 90 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml

diff --git a/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml 
b/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
new file mode 100644
index ..4762eb1
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
@@ -0,0 +1,90 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/richtek,rt4831.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 DSV and Backlight Integrated IC
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a multifunctional device that can provide power to the LCD display
+  and LCD backlight.
+
+  For Display Bias Voltage DSVP and DSVN, the output range is about 4V to 6.5V.
+  It's sufficient to meet the current LCD power requirement.
+
+  For the LCD backlight, it can provide four channel WLED driving capability.
+  Each channel driving current is up to 30mA
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+properties:
+  compatible:
+const: richtek,rt4831
+
+  reg:
+description: I2C device address.
+maxItems: 1
+
+  enable-gpios:
+description: |
+  GPIO to enable/disable the chip. It is optional.
+  Some usage directly tied this pin to follow VIO 1.8V power on sequence.
+maxItems: 1
+
+  regulators:
+$ref: ../regulator/richtek,rt4831-regulator.yaml
+
+  backlight:
+$ref: ../leds/backlight/richtek,rt4831-backlight.yaml
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+i2c {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  rt4831@11 {
+compatible = "richtek,rt4831";
+reg = <0x11>;
+
+regulators {
+  DSVLCM {
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <715>;
+regulator-allow-bypass;
+  };
+  DSVP {
+regulator-name = "rt4831-dsvp";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+  DSVN {
+regulator-name = "rt4831-dsvn";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+};
+
+backlight {
+  compatible = "richtek,rt4831-backlight";
+  default-brightness = <1024>;
+  max-brightness = <2048>;
+  richtek,bled-ovp-sel = /bits/ 8 ;
+  richtek,channel-use = /bits/ 8 ;
+};
+  };
+};
-- 
2.7.4



[PATCH v3 2/4] backlight: rt4831: Adds DT binding document for Richtek RT4831 backlight

2020-12-08 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831 backlight.

Signed-off-by: ChiYuan Huang 
---
since v3
- Move inlcude/dt-bindings/leds/rt4831-backlight.h from patch 0004 to here.
- Add dual license tag in header and backlight binding document.
- Left backlight dt-binding example only.
---
 .../leds/backlight/richtek,rt4831-backlight.yaml   | 76 ++
 include/dt-bindings/leds/rt4831-backlight.h| 23 +++
 2 files changed, 99 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
 create mode 100644 include/dt-bindings/leds/rt4831-backlight.h

diff --git 
a/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
 
b/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
new file mode 100644
index ..f24c8d1
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: 
http://devicetree.org/schemas/leds/backlight/richtek,rt4831-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 Backlight
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a mutifunctional device that can provide power to the LCD display
+  and LCD backlight.
+
+  For the LCD backlight, it can provide four channel WLED driving capability.
+  Each channel driving current is up to 30mA
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+properties:
+  compatible:
+const: richtek,rt4831-backlight
+
+  default-brightness:
+description: |
+  The default brightness that applied to the system on start-up.
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 2048
+
+  max-brightness:
+description: |
+  The max brightness for the H/W limit
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 2048
+
+  richtek,pwm-enable:
+description: |
+  Specify the backlight dimming following by PWM duty or by SW control.
+type: boolean
+
+  richtek,bled-ovp-sel:
+description: |
+  Backlight OVP level selection, currently support 17V/21V/25V/29V.
+$ref: /schemas/types.yaml#/definitions/uint8
+default: 1
+minimum: 0
+maximum: 3
+
+  richtek,channel-use:
+description: |
+  Backlight LED channel to be used.
+  BIT 0/1/2/3 is used to indicate led channel 1/2/3/4 enable or disable.
+$ref: /schemas/types.yaml#/definitions/uint8
+minimum: 1
+maximum: 15
+
+required:
+  - compatible
+  - richtek,channel-use
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+backlight {
+  compatible = "richtek,rt4831-backlight";
+  default-brightness = <1024>;
+  max-brightness = <2048>;
+  richtek,bled-ovp-sel = /bits/ 8 ;
+  richtek,channel-use = /bits/ 8 ;
+};
diff --git a/include/dt-bindings/leds/rt4831-backlight.h 
b/include/dt-bindings/leds/rt4831-backlight.h
new file mode 100644
index ..125c635
--- /dev/null
+++ b/include/dt-bindings/leds/rt4831-backlight.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * This header provides constants for rt4831 backlight bindings.
+ *
+ * Copyright (C) 2020, Richtek Technology Corp.
+ * Author: ChiYuan Huang 
+ */
+
+#ifndef _DT_BINDINGS_RT4831_BACKLIGHT_H
+#define _DT_BINDINGS_RT4831_BACKLIGHT_H
+
+#define RT4831_BLOVPLVL_17V0
+#define RT4831_BLOVPLVL_21V1
+#define RT4831_BLOVPLVL_25V2
+#define RT4831_BLOVPLVL_29V3
+
+#define RT4831_BLED_CH1EN  (1 << 0)
+#define RT4831_BLED_CH2EN  (1 << 1)
+#define RT4831_BLED_CH3EN  (1 << 2)
+#define RT4831_BLED_CH4EN  (1 << 3)
+#define RT4831_BLED_ALLCHEN((1 << 4) - 1)
+
+#endif /* _DT_BINDINGS_RT4831_BACKLIGHT_H */
-- 
2.7.4



[PATCH v3 1/4] mfd: rt4831: Adds support for Richtek RT4831 MFD core

2020-12-08 Thread cy_huang
From: ChiYuan Huang 

This adds support Richtek RT4831 MFD core. It includes four channel WLED driver
and Display Bias Voltage outputs.

Signed-off-by: ChiYuan Huang 
---
since v2
- Refine Kconfig descriptions.
- Add copyright.
- Refine error logs in probe.
- Refine comment lines in remove and shutdown.
---
 drivers/mfd/Kconfig   |  10 
 drivers/mfd/Makefile  |   1 +
 drivers/mfd/rt4831-core.c | 124 ++
 3 files changed, 135 insertions(+)
 create mode 100644 drivers/mfd/rt4831-core.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 8b99a13..dfb2640 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1088,6 +1088,16 @@ config MFD_RDC321X
  southbridge which provides access to GPIOs and Watchdog using the
  southbridge PCI device configuration space.
 
+config MFD_RT4831
+   tristate "Richtek RT4831 four channel WLED and Display Bias Voltage"
+   depends on I2C
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ This enables support for the Richtek RT4831 that includes 4 channel
+ WLED driving and Display Bias Voltage. It's commonly used to provide
+ power to the LCD display and LCD backlight.
+
 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 ..f837c06
--- /dev/null
+++ b/drivers/mfd/rt4831-core.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020 Richtek Technology Corp.
+ *
+ * Author: ChiYuan Huang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4831_REG_REVISION0x01
+#define RT4831_REG_ENABLE  0x08
+#define RT4831_REG_I2CPROT 0x15
+
+#define RICHTEK_VID0x03
+#define RT4831_VID_MASKGENMASK(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(>dev, "enable", 
GPIOD_OUT_HIGH);
+   if (IS_ERR(enable)) {
+   dev_err(>dev, "Failed to get 'enable' GPIO\n");
+   return PTR_ERR(enable);
+   }
+
+   regmap = devm_regmap_init_i2c(client, _regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Failed to initialize regmap\n");
+   return PTR_ERR(regmap);
+   }
+
+   ret = regmap_read(regmap, RT4831_REG_REVISION, );
+   if (ret) {
+   dev_err(>dev, "Failed to get H/W revision\n");
+   return ret;
+   }
+
+   if ((val & RT4831_VID_MASK) != RICHTEK_VID) {
+   dev_err(>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(>dev, "Failed to enable I2C safety timer\n");
+   return ret;
+   }
+
+   return devm_mfd_add_devices(>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(>dev, NULL);
+
+   /* Disable WLED and DSV outputs */
+   return regmap_update_bits(regmap, RT4831_REG_ENABLE, RT4831_RESET_MASK, 
RT4831_RESET_MASK);
+}
+
+static void rt4831_shutdown(struct i2c_client *client)
+{
+   

[PATCH v2 4/4] mfd: rt4831: Adds DT binding document for Richtek RT4831 MFD core

2020-12-03 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831 MFD core.

This patch depends on

"backlight: rt4831: Adds DT binding document for Richtek RT4831 backlight".
"regulator: rt4831: Adds DT binding document for Richtek RT4831 DSV regulator".

Signed-off-by: ChiYuan Huang 
---
Changes since v2
- Add "patch depends on" in commit description.
- Adds regulator-allow-bypass flag in DSVLCM.
---
 .../devicetree/bindings/mfd/richtek,rt4831.yaml| 90 ++
 include/dt-bindings/leds/rt4831-backlight.h| 23 ++
 2 files changed, 113 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
 create mode 100644 include/dt-bindings/leds/rt4831-backlight.h

diff --git a/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml 
b/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
new file mode 100644
index ..c6ca953
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
@@ -0,0 +1,90 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/richtek,rt4831.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 DSV and Backlight Integrated IC
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a multifunctional device that can provide power to the LCD display
+  and LCD backlight.
+
+  For Display Bias Voltage DSVP and DSVN, the output range is about 4V to 6.5V.
+  It's sufficient to meet the current LCD power requirement.
+
+  For the LCD backlight, it can provide four channel WLED driving capability.
+  Each channel driving current is up to 30mA
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+properties:
+  compatible:
+const: richtek,rt4831
+
+  reg:
+description: I2C device address.
+maxItems: 1
+
+  enable-gpios:
+description: |
+  GPIO to enable/disable the chip. It is optional.
+  Some usage directly tied this pin to follow VIO 1.8V power on sequence.
+maxItems: 1
+
+  regulators:
+$ref: ../regulator/richtek,rt4831-regulator.yaml
+
+  backlight:
+$ref: ../leds/backlight/richtek,rt4831-backlight.yaml
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+i2c {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  rt4831@11 {
+compatible = "richtek,rt4831";
+reg = <0x11>;
+
+regulators {
+  DSVLCM {
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <715>;
+regulator-allow-bypass;
+  };
+  DSVP {
+regulator-name = "rt4831-dsvp";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+  DSVN {
+regulator-name = "rt4831-dsvn";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+};
+
+backlight {
+  compatible = "richtek,rt4831-backlight";
+  default-brightness = <1024>;
+  max-brightness = <2048>;
+  richtek,bled-ovp-sel = /bits/ 8 ;
+  richtek,channel-use = /bits/ 8 ;
+};
+  };
+};
diff --git a/include/dt-bindings/leds/rt4831-backlight.h 
b/include/dt-bindings/leds/rt4831-backlight.h
new file mode 100644
index ..7084906
--- /dev/null
+++ b/include/dt-bindings/leds/rt4831-backlight.h
@@ -0,0 +1,23 @@
+/*
+ * This header provides constants for rt4831 backlight bindings.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef _DT_BINDINGS_RT4831_BACKLIGHT_H
+#define _DT_BINDINGS_RT4831_BACKLIGHT_H
+
+#define RT4831_BLOVPLVL_17V0
+#define RT4831_BLOVPLVL_21V1
+#define RT4831_BLOVPLVL_25V2
+#define RT4831_BLOVPLVL_29V3
+
+#define RT4831_BLED_CH1EN  (1 << 0)
+#define RT4831_BLED_CH2EN  (1 << 1)
+#define RT4831_BLED_CH3EN  (1 << 2)
+#define RT4831_BLED_CH4EN  (1 << 3)
+#define RT4831_BLED_ALLCHEN((1 << 4) - 1)
+
+#endif /* _DT_BINDINGS_RT4831_BACKLIGHT_H */
-- 
2.7.4



[PATCH v2 2/4] backlight: rt4831: Adds DT binding document for Richtek RT4831 backlight

2020-12-03 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831 backlight.

Signed-off-by: ChiYuan Huang 
---
 .../leds/backlight/richtek,rt4831-backlight.yaml   | 86 ++
 1 file changed, 86 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml

diff --git 
a/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
 
b/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
new file mode 100644
index ..df1439a
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/leds/backlight/richtek,rt4831-backlight.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: 
http://devicetree.org/schemas/leds/backlight/richtek,rt4831-backlight.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 Backlight
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a mutifunctional device that can provide power to the LCD display
+  and LCD backlight.
+
+  For the LCD backlight, it can provide four channel WLED driving capability.
+  Each channel driving current is up to 30mA
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+properties:
+  compatible:
+const: richtek,rt4831-backlight
+
+  default-brightness:
+description: |
+  The default brightness that applied to the system on start-up.
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 2048
+
+  max-brightness:
+description: |
+  The max brightness for the H/W limit
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 2048
+
+  richtek,pwm-enable:
+description: |
+  Specify the backlight dimming following by PWM duty or by SW control.
+type: boolean
+
+  richtek,bled-ovp-sel:
+description: |
+  Backlight OVP level selection, currently support 17V/21V/25V/29V.
+$ref: /schemas/types.yaml#/definitions/uint8
+default: 1
+minimum: 0
+maximum: 3
+
+  richtek,channel-use:
+description: |
+  Backlight LED channel to be used.
+  BIT 0/1/2/3 is used to indicate led channel 1/2/3/4 enable or disable.
+$ref: /schemas/types.yaml#/definitions/uint8
+minimum: 1
+maximum: 15
+
+required:
+  - compatible
+  - richtek,channel-use
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+i2c {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  rt4831@11 {
+compatible = "richtek,rt4831";
+reg = <0x11>;
+
+backlight {
+  compatible = "richtek,rt4831-backlight";
+  default-brightness = <1024>;
+  max-brightness = <2048>;
+  richtek,bled-ovp-sel = /bits/ 8 ;
+  richtek,channel-use = /bits/ 8 ;
+};
+  };
+};
-- 
2.7.4



[PATCH v2 3/4] regulator: rt4831: Adds DT binding document for Richtek RT4831 DSV regulator

2020-12-03 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831 DSV regulator.

Signed-off-by: ChiYuan Huang 
---
 .../regulator/richtek,rt4831-regulator.yaml| 67 ++
 1 file changed, 67 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml

diff --git 
a/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml 
b/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml
new file mode 100644
index ..bc1e976
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/richtek,rt4831-regulator.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/richtek,rt4831-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 Display Bias Voltage Regulator
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a multifunctional device that can provide power to the LCD display
+  and LCD backlight.
+
+  For Display Bias Voltage DSVP and DSVN, the output range is about 4V to 6.5V.
+  It is sufficient to meet the current LCD power requirement.
+
+  DSVLCM is a boost regulator in IC internal as DSVP and DSVN input power.
+  Its voltage should be configured above 0.15V to 0.2V gap larger than the
+  voltage needed for DSVP and DSVN. Too much voltage gap could improve the
+  voltage drop from the heavy loading scenario. But it also make the power
+  efficiency worse. It's a trade-off.
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+patternProperties:
+  "^DSV(LCM|P|N)$":
+type: object
+$ref: regulator.yaml#
+description:
+  Properties for single Display Bias Voltage regulator.
+
+additionalProperties: false
+
+examples:
+  - |
+i2c {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  rt4831@11 {
+compatible = "richtek,rt4831";
+reg = <0x11>;
+
+regulators {
+  DSVLCM {
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <715>;
+regulator-allow-bypass;
+  };
+  DSVP {
+regulator-name = "rt4831-dsvp";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+  DSVN {
+regulator-name = "rt4831-dsvn";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+};
+  };
+};
-- 
2.7.4



[PATCH v2 1/4] mfd: rt4831: Adds support for Richtek RT4831 MFD core

2020-12-03 Thread cy_huang
From: ChiYuan Huang 

This adds support Richtek RT4831 MFD core. It includes four channel WLED driver
and Display Bias Voltage outputs.

Signed-off-by: ChiYuan Huang 
---
Changes since v2
- Add copyright.
- Refine error log text in probe.
- Refine comment lines in remove and shutdown callback.
- Refine Kconfig descriptions.
---
 drivers/mfd/Kconfig   |  10 
 drivers/mfd/Makefile  |   1 +
 drivers/mfd/rt4831-core.c | 124 ++
 3 files changed, 135 insertions(+)
 create mode 100644 drivers/mfd/rt4831-core.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 8b99a13..dfb2640 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1088,6 +1088,16 @@ config MFD_RDC321X
  southbridge which provides access to GPIOs and Watchdog using the
  southbridge PCI device configuration space.
 
+config MFD_RT4831
+   tristate "Richtek RT4831 four channel WLED and Display Bias Voltage"
+   depends on I2C
+   select MFD_CORE
+   select REGMAP_I2C
+   help
+ This enables support for the Richtek RT4831 that includes 4 channel
+ WLED driving and Display Bias Voltage. It's commonly used to provide
+ power to the LCD display and LCD backlight.
+
 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 ..f837c06
--- /dev/null
+++ b/drivers/mfd/rt4831-core.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2020 Richtek Technology Corp.
+ *
+ * Author: ChiYuan Huang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4831_REG_REVISION0x01
+#define RT4831_REG_ENABLE  0x08
+#define RT4831_REG_I2CPROT 0x15
+
+#define RICHTEK_VID0x03
+#define RT4831_VID_MASKGENMASK(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(>dev, "enable", 
GPIOD_OUT_HIGH);
+   if (IS_ERR(enable)) {
+   dev_err(>dev, "Failed to get 'enable' GPIO\n");
+   return PTR_ERR(enable);
+   }
+
+   regmap = devm_regmap_init_i2c(client, _regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Failed to initialize regmap\n");
+   return PTR_ERR(regmap);
+   }
+
+   ret = regmap_read(regmap, RT4831_REG_REVISION, );
+   if (ret) {
+   dev_err(>dev, "Failed to get H/W revision\n");
+   return ret;
+   }
+
+   if ((val & RT4831_VID_MASK) != RICHTEK_VID) {
+   dev_err(>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(>dev, "Failed to enable I2C safety timer\n");
+   return ret;
+   }
+
+   return devm_mfd_add_devices(>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(>dev, NULL);
+
+   /* Disable WLED and DSV outputs */
+   return regmap_update_bits(regmap, RT4831_REG_ENABLE, RT4831_RESET_MASK, 
RT4831_RESET_MASK);
+}
+
+static void rt4831_shutdown(struct i2c_client 

[PATCH v1 2/2] mfd: rt4505: Adds DT binding document for Richtek RT4831 MFD core

2020-11-01 Thread cy_huang
From: ChiYuan Huang 

Adds DT binding document for Richtek RT4831 MFD core.

Signed-off-by: ChiYuan Huang 
---
 .../devicetree/bindings/mfd/richtek,rt4831.yaml| 89 ++
 include/dt-bindings/leds/rt4831-backlight.h| 23 ++
 2 files changed, 112 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
 create mode 100644 include/dt-bindings/leds/rt4831-backlight.h

diff --git a/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml 
b/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
new file mode 100644
index ..c602d50
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/richtek,rt4831.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/richtek,rt4831.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4831 DSV and Backlight Integrated IC
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  RT4831 is a mutifunctional device that can provide display panel power for
+  positive/negative voltage and also display panel wled driving.
+
+  For the display voltage output, the range is about 4V to 6.5V. It is 
sufficient
+  to meet the current display panel design.
+
+  For the panel backlight, it can provide four channels driving capability
+  Each driving current is up to 30mA
+
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4831A/DS4831A-05.pdf
+
+properties:
+  compatible:
+const: richtek,rt4831
+
+  reg:
+description: I2C device address.
+maxItems: 1
+
+  enable-gpios:
+description: |
+  GPIO to enable/disable the chip. It is optional.
+  Some usage directly tied this pin to follow VIO 1.8V power on sequence.
+maxItems: 1
+
+  regulators:
+$ref: ../regulator/richtek,rt4831-regulator.yaml
+
+  backlight:
+$ref: ../leds/backlight/richtek,rt4831-backlight.yaml
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+i2c {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  rt4831@11 {
+compatible = "richtek,rt4831";
+reg = <0x11>;
+
+regulators {
+  DSVLCM {
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <715>;
+  };
+  DSVP {
+regulator-name = "rt4831-dsvp";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+  DSVN {
+regulator-name = "rt4831-dsvn";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <650>;
+regulator-boot-on;
+  };
+};
+
+backlight {
+  compatible = "richtek,rt4831-backlight";
+  default-brightness = <1024>;
+  max-brightness = <2048>;
+  richtek,bled-ovp-sel = /bits/ 8 ;
+  richtek,channel-use = /bits/ 8 ;
+};
+  };
+};
diff --git a/include/dt-bindings/leds/rt4831-backlight.h 
b/include/dt-bindings/leds/rt4831-backlight.h
new file mode 100644
index ..7084906
--- /dev/null
+++ b/include/dt-bindings/leds/rt4831-backlight.h
@@ -0,0 +1,23 @@
+/*
+ * This header provides constants for rt4831 backlight bindings.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef _DT_BINDINGS_RT4831_BACKLIGHT_H
+#define _DT_BINDINGS_RT4831_BACKLIGHT_H
+
+#define RT4831_BLOVPLVL_17V0
+#define RT4831_BLOVPLVL_21V1
+#define RT4831_BLOVPLVL_25V2
+#define RT4831_BLOVPLVL_29V3
+
+#define RT4831_BLED_CH1EN  (1 << 0)
+#define RT4831_BLED_CH2EN  (1 << 1)
+#define RT4831_BLED_CH3EN  (1 << 2)
+#define RT4831_BLED_CH4EN  (1 << 3)
+#define RT4831_BLED_ALLCHEN((1 << 4) - 1)
+
+#endif /* _DT_BINDINGS_RT4831_BACKLIGHT_H */
-- 
2.7.4



[PATCH v1 1/2] mfd: rt4831: Adds support for Richtek RT4831 MFD core

2020-11-01 Thread cy_huang
From: ChiYuan Huang 

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 
---
 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 ..5342959
--- /dev/null
+++ b/drivers/mfd/rt4831-core.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4831_REG_REVISION0x01
+#define RT4831_REG_ENABLE  0x08
+#define RT4831_REG_I2CPROT 0x15
+
+#define RICHTEK_VID0x03
+#define RT4831_VID_MASKGENMASK(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(>dev, "enable", 
GPIOD_OUT_HIGH);
+   if (IS_ERR(enable)) {
+   dev_err(>dev, "Failed to get chip enable gpio\n");
+   return PTR_ERR(enable);
+   }
+
+   regmap = devm_regmap_init_i2c(client, _regmap_config);
+   if (IS_ERR(regmap)) {
+   dev_err(>dev, "Failed to init regmap\n");
+   return PTR_ERR(regmap);
+   }
+
+   ret = regmap_read(regmap, RT4831_REG_REVISION, );
+   if (ret) {
+   dev_err(>dev, "Fail to get version id\n");
+   return ret;
+   }
+
+   if ((val & RT4831_VID_MASK) != RICHTEK_VID) {
+   dev_err(>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(>dev, "Failed to enable I2C safety timer\n");
+   return ret;
+   }
+
+   return devm_mfd_add_devices(>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(>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(>dev, NULL);
+
+   /* Make sure all off before machine shutdown */
+   regmap_update_bits(regmap, RT4831_REG_ENABLE, 

[PATCH v2 1/2] leds: rt4505: Add support for Richtek RT4505 flash LED controller

2020-11-01 Thread cy_huang
From: ChiYuan Huang 

Add support for RT4505 flash LED controller. It can support up to 1.5A
flash current with hardware timeout and low input voltage protection.

Signed-off-by: ChiYuan Huang 
---
Changes since v1 to v2

- Create flash directory into drvers/leds.
- Coding style fix to meet 80 charactors per line limit.
- Refine the description in the Kconfig help text.
- Change all descriptions for 'led' text to uppercase 'LED'.

---
 drivers/leds/Kconfig |   2 +
 drivers/leds/Makefile|   3 +
 drivers/leds/flash/Kconfig   |  17 ++
 drivers/leds/flash/Makefile  |   2 +
 drivers/leds/flash/leds-rt4505.c | 430 +++
 5 files changed, 454 insertions(+)
 create mode 100644 drivers/leds/flash/Kconfig
 create mode 100644 drivers/leds/flash/Makefile
 create mode 100644 drivers/leds/flash/leds-rt4505.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 849d3c5..e4ad5ab 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -30,6 +30,8 @@ config LEDS_CLASS_FLASH
  for the flash related features of a LED device. It can be built
  as a module.
 
+source "drivers/leds/flash/Kconfig"
+
 config LEDS_CLASS_MULTICOLOR
tristate "LED Multicolor Class Support"
depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 73e603e..1564a83 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -103,5 +103,8 @@ obj-$(CONFIG_LEDS_SPI_BYTE) += leds-spi-byte.o
 # LED Userspace Drivers
 obj-$(CONFIG_LEDS_USER)+= uleds.o
 
+# LED Flash Drivers
+obj-y  += flash/
+
 # LED Triggers
 obj-$(CONFIG_LEDS_TRIGGERS)+= trigger/
diff --git a/drivers/leds/flash/Kconfig b/drivers/leds/flash/Kconfig
new file mode 100644
index ..df32764
--- /dev/null
+++ b/drivers/leds/flash/Kconfig
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+menu "LED Flash Chip support"
+   depends on LEDS_CLASS_FLASH
+
+config LEDS_RT4505
+   tristate "LED support for RT4505 flashlight controller"
+   depends on I2C && OF
+   depends on V4L2_FLASH_LED_CLASS || !V4L2_FLASH_LED_CLASS
+   select REGMAP_I2C
+   help
+ This option enables support for the RT4505 flash LED controller.
+ RT4505 includes torch and flash functions with programmable current.
+ And it's commonly used to compensate the illuminance for the camera
+ inside the mobile product like as phones or tablets.
+
+endmenu
diff --git a/drivers/leds/flash/Makefile b/drivers/leds/flash/Makefile
new file mode 100644
index ..1b2eded
--- /dev/null
+++ b/drivers/leds/flash/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_LEDS_RT4505)  += leds-rt4505.o
diff --git a/drivers/leds/flash/leds-rt4505.c b/drivers/leds/flash/leds-rt4505.c
new file mode 100644
index ..ee129ab
--- /dev/null
+++ b/drivers/leds/flash/leds-rt4505.c
@@ -0,0 +1,430 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4505_REG_RESET   0x0
+#define RT4505_REG_CONFIG  0x8
+#define RT4505_REG_ILED0x9
+#define RT4505_REG_ENABLE  0xA
+#define RT4505_REG_FLAGS   0xB
+
+#define RT4505_RESET_MASK  BIT(7)
+#define RT4505_FLASHTO_MASKGENMASK(2, 0)
+#define RT4505_ITORCH_MASK GENMASK(7, 5)
+#define RT4505_ITORCH_SHIFT5
+#define RT4505_IFLASH_MASK GENMASK(4, 0)
+#define RT4505_ENABLE_MASK GENMASK(5, 0)
+#define RT4505_TORCH_SET   (BIT(0) | BIT(4))
+#define RT4505_FLASH_SET   (BIT(0) | BIT(1) | BIT(2) | BIT(4))
+#define RT4505_EXT_FLASH_SET   (BIT(0) | BIT(1) | BIT(4) | BIT(5))
+#define RT4505_FLASH_GET   (BIT(0) | BIT(1) | BIT(4))
+#define RT4505_OVP_MASKBIT(3)
+#define RT4505_SHORT_MASK  BIT(2)
+#define RT4505_OTP_MASKBIT(1)
+#define RT4505_TIMEOUT_MASKBIT(0)
+
+#define RT4505_ITORCH_MINUA46000
+#define RT4505_ITORCH_MAXUA375000
+#define RT4505_ITORCH_STPUA47000
+#define RT4505_IFLASH_MINUA93750
+#define RT4505_IFLASH_MAXUA150
+#define RT4505_IFLASH_STPUA93750
+#define RT4505_FLASHTO_MINUS   10
+#define RT4505_FLASHTO_MAXUS   80
+#define RT4505_FLASHTO_STPUS   10
+
+struct rt4505_priv {
+   struct device *dev;
+   struct regmap *regmap;
+   struct mutex lock;
+   struct led_classdev_flash flash;
+   struct v4l2_flash *v4l2_flash;
+};
+
+static int rt4505_torch_brightness_set(struct led_classdev *lcdev,
+  enum led_brightness level)
+{
+   struct rt4505_priv *priv =
+   container_of(lcdev, struct rt4505_priv, flash.led_cdev);
+   u32 val = 0;
+   int ret;
+
+   mutex_lock(>lock);
+
+   if (level != LED_OFF) {
+   ret = regmap_update_bits(priv->regmap,
+  

[PATCH v2 2/2] leds: rt4505: Add DT binding document for Richtek RT4505

2020-11-01 Thread cy_huang
From: ChiYuan Huang 

Add DT binding document for Richtek RT4505 flash LED controller.

Signed-off-by: ChiYuan Huang 
Reviewed-by: Rob Herring 
---
Changes since v1 to v2

- Change the descriptions for 'led' text to uppercase 'LED'.

---
 .../devicetree/bindings/leds/leds-rt4505.yaml  | 57 ++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-rt4505.yaml

diff --git a/Documentation/devicetree/bindings/leds/leds-rt4505.yaml 
b/Documentation/devicetree/bindings/leds/leds-rt4505.yaml
new file mode 100644
index ..5b0c74a
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-rt4505.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/leds-rt4505.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4505 Single Channel LED Driver
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  The RT4505 is a flash LED driver that can support up to 375mA and 1.5A for
+  torch and flash mode, respectively.
+
+  The data sheet can be found at:
+https://www.richtek.com/assets/product_file/RT4505/DS4505-02.pdf
+
+properties:
+  compatible:
+const: richtek,rt4505
+
+  reg:
+description: I2C slave address of the controller.
+maxItems: 1
+
+  led:
+type: object
+$ref: common.yaml#
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+
+i2c0 {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  led-controller@63 {
+compatible = "richtek,rt4505";
+reg = <0x63>;
+
+rt4505_flash: led {
+  function = LED_FUNCTION_FLASH;
+  color = ;
+  led-max-microamp = <375000>;
+  flash-max-microamp = <150>;
+  flash-max-timeout-us = <80>;
+};
+  };
+};
-- 
2.7.4



[PATCH v1 1/2] leds: rt4505: Add support for Richtek RT4505 flash led controller

2020-10-27 Thread cy_huang
From: ChiYuan Huang 

Add support for RT4505 flash led controller. It can support up to 1.5A
flash current with hardware timeout and low input voltage protection.

Signed-off-by: ChiYuan Huang 
---
 drivers/leds/Kconfig   |  11 ++
 drivers/leds/Makefile  |   1 +
 drivers/leds/leds-rt4505.c | 397 +
 3 files changed, 409 insertions(+)
 create mode 100644 drivers/leds/leds-rt4505.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 849d3c5..71ebd1d 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -717,6 +717,17 @@ config LEDS_MAX8997
  This option enables support for on-chip LED drivers on
  MAXIM MAX8997 PMIC.
 
+config LEDS_RT4505
+   tristate "LED driver for RT4505 single channel flash led controller"
+   depends on I2C
+   depends on LEDS_CLASS_FLASH && OF
+   depends on V4L2_FLASH_LED_CLASS || !V4L2_FLASH_LED_CLASS
+   select REGMAP_I2C
+   help
+ This option enables support for the RT4505 flash led controller.
+ It can support up to 1.5A flash strobe current with hardware timeout
+ and low input voltage protection.
+
 config LEDS_LM355x
tristate "LED support for LM3554 and LM3556 chips"
depends on LEDS_CLASS && I2C
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 73e603e..1aca2b6 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -80,6 +80,7 @@ obj-$(CONFIG_LEDS_PM8058) += leds-pm8058.o
 obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o
 obj-$(CONFIG_LEDS_PWM) += leds-pwm.o
 obj-$(CONFIG_LEDS_REGULATOR)   += leds-regulator.o
+obj-$(CONFIG_LEDS_RT4505)  += leds-rt4505.o
 obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
 obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o
 obj-$(CONFIG_LEDS_SGM3140) += leds-sgm3140.o
diff --git a/drivers/leds/leds-rt4505.c b/drivers/leds/leds-rt4505.c
new file mode 100644
index ..46d2c030
--- /dev/null
+++ b/drivers/leds/leds-rt4505.c
@@ -0,0 +1,397 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4505_REG_RESET   0x0
+#define RT4505_REG_CONFIG  0x8
+#define RT4505_REG_ILED0x9
+#define RT4505_REG_ENABLE  0xA
+#define RT4505_REG_FLAGS   0xB
+
+#define RT4505_RESET_MASK  BIT(7)
+#define RT4505_FLASHTO_MASKGENMASK(2, 0)
+#define RT4505_ITORCH_MASK GENMASK(7, 5)
+#define RT4505_ITORCH_SHIFT5
+#define RT4505_IFLASH_MASK GENMASK(4, 0)
+#define RT4505_ENABLE_MASK GENMASK(5, 0)
+#define RT4505_TORCH_SET   (BIT(0) | BIT(4))
+#define RT4505_FLASH_SET   (BIT(0) | BIT(1) | BIT(2) | BIT(4))
+#define RT4505_EXT_FLASH_SET   (BIT(0) | BIT(1) | BIT(4) | BIT(5))
+#define RT4505_FLASH_GET   (BIT(0) | BIT(1) | BIT(4))
+#define RT4505_OVP_MASKBIT(3)
+#define RT4505_SHORT_MASK  BIT(2)
+#define RT4505_OTP_MASKBIT(1)
+#define RT4505_TIMEOUT_MASKBIT(0)
+
+#define RT4505_ITORCH_MINUA46000
+#define RT4505_ITORCH_MAXUA375000
+#define RT4505_ITORCH_STPUA47000
+#define RT4505_IFLASH_MINUA93750
+#define RT4505_IFLASH_MAXUA150
+#define RT4505_IFLASH_STPUA93750
+#define RT4505_FLASHTO_MINUS   10
+#define RT4505_FLASHTO_MAXUS   80
+#define RT4505_FLASHTO_STPUS   10
+
+struct rt4505_priv {
+   struct device *dev;
+   struct regmap *regmap;
+   struct mutex lock;
+   struct led_classdev_flash flash;
+   struct v4l2_flash *v4l2_flash;
+};
+
+static int rt4505_torch_brightness_set(struct led_classdev *lcdev, enum 
led_brightness level)
+{
+   struct rt4505_priv *priv = container_of(lcdev, struct rt4505_priv, 
flash.led_cdev);
+   u32 val = 0;
+   int ret;
+
+   mutex_lock(>lock);
+
+   if (level != LED_OFF) {
+   ret = regmap_update_bits(priv->regmap, RT4505_REG_ILED, 
RT4505_ITORCH_MASK,
+(level - 1) << RT4505_ITORCH_SHIFT);
+   if (ret)
+   goto unlock;
+
+   val = RT4505_TORCH_SET;
+   }
+
+   ret = regmap_update_bits(priv->regmap, RT4505_REG_ENABLE, 
RT4505_ENABLE_MASK, val);
+
+unlock:
+   mutex_unlock(>lock);
+   return ret;
+}
+
+static enum led_brightness rt4505_torch_brightness_get(struct led_classdev 
*lcdev)
+{
+   struct rt4505_priv *priv = container_of(lcdev, struct rt4505_priv, 
flash.led_cdev);
+   u32 val = 0;
+   int ret;
+
+   mutex_lock(>lock);
+
+   ret = regmap_read(priv->regmap, RT4505_REG_ENABLE, );
+   if (ret) {
+   dev_err(lcdev->dev, "Failed to get LED enable\n");
+   ret = LED_OFF;
+   goto unlock;
+   }
+
+   if ((val & RT4505_ENABLE_MASK) != RT4505_TORCH_SET) {
+   ret = LED_OFF;
+   goto unlock;
+   }
+

[PATCH v1 2/2] leds: rt4505: Add DT binding document for Richtek RT4505

2020-10-27 Thread cy_huang
From: ChiYuan Huang 

Add DT binding document for Richtek RT4505 flash led controller.

Signed-off-by: ChiYuan Huang 
---
 .../devicetree/bindings/leds/leds-rt4505.yaml  | 57 ++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-rt4505.yaml

diff --git a/Documentation/devicetree/bindings/leds/leds-rt4505.yaml 
b/Documentation/devicetree/bindings/leds/leds-rt4505.yaml
new file mode 100644
index ..da1681a
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-rt4505.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/leds-rt4505.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4505 Single Channel LED Driver
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  The RT4505 is a flash led driver that can support up to 375mA and 1.5A for
+  torch and flash mode, respectively.
+
+  The data sheet can be found at:
+https://www.richtek.com/assets/product_file/RT4505/DS4505-02.pdf
+
+properties:
+  compatible:
+const: richtek,rt4505
+
+  reg:
+description: I2C slave address of the controller.
+maxItems: 1
+
+  led:
+type: object
+$ref: common.yaml#
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+
+i2c0 {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  led-controller@63 {
+compatible = "richtek,rt4505";
+reg = <0x63>;
+
+rt4505_flash: led {
+  function = LED_FUNCTION_FLASH;
+  color = ;
+  led-max-microamp = <375000>;
+  flash-max-microamp = <150>;
+  flash-max-timeout-us = <80>;
+};
+  };
+};
-- 
2.7.4



[PATCH] regulator: rtmv20: Add missing regcache cache only before marked as dirty

2020-09-30 Thread cy_huang
From: ChiYuan Huang 

Add missing regcache cache only before masked as dirty.

Signed-off-by: ChiYuan Huang 
---
 drivers/regulator/rtmv20-regulator.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/regulator/rtmv20-regulator.c 
b/drivers/regulator/rtmv20-regulator.c
index 1075b10..0a07598 100644
--- a/drivers/regulator/rtmv20-regulator.c
+++ b/drivers/regulator/rtmv20-regulator.c
@@ -321,6 +321,7 @@ static int rtmv20_probe(struct i2c_client *i2c)
 * keep in shutdown mode to minimize the current consumption
 * and also mark regcache as dirty
 */
+   regcache_cache_only(priv->regmap, true);
regcache_mark_dirty(priv->regmap);
gpiod_set_value(priv->enable_gpio, 0);
 
-- 
2.7.4



[PATCH] regulator: rtmv20: Update DT binding document and property name parsing

2020-09-30 Thread cy_huang
From: ChiYuan Huang 

1. Add vendor suffix to all proprietary properties.
2. Fix typo.
3. Change lsw to normal property, not pattern property.
4. Due to item 1, modify source code for property parsing.

Signed-off-by: ChiYuan Huang 
---
 .../regulator/richtek,rtmv20-regulator.yaml| 53 +-
 drivers/regulator/rtmv20-regulator.c   | 36 ---
 2 files changed, 42 insertions(+), 47 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml 
b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml
index 4cb4b68..a8ccb5c 100644
--- a/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml
@@ -26,108 +26,99 @@ properties:
 
   wakeup-source: true
 
-  interrupts-extend:
+  interrupts:
 maxItems: 1
 
   enable-gpios:
 description: A connection of the 'enable' gpio line.
 maxItems: 1
 
-  ld-pulse-delay-us:
+  richtek,ld-pulse-delay-us:
 description: |
   load current pulse delay in microsecond after strobe pin pulse high.
-$ref: "/schemas/types.yaml#/definitions/uint32"
 minimum: 0
 maximum: 10
 default: 0
 
-  ld-pulse-width-us:
+  richtek,ld-pulse-width-us:
 description: |
   Load current pulse width in microsecond after strobe pin pulse high.
-$ref: "/schemas/types.yaml#/definitions/uint32"
 minimum: 0
 maximum: 1
 default: 1200
 
-  fsin1-delay-us:
+  richtek,fsin1-delay-us:
 description: |
   Fsin1 pulse high delay in microsecond after vsync signal pulse high.
-$ref: "/schemas/types.yaml#/definitions/uint32"
 minimum: 0
 maximum: 10
 default: 23000
 
-  fsin1-width-us:
+  richtek,fsin1-width-us:
 description: |
   Fsin1 pulse high width in microsecond after vsync signal pulse high.
-$ref: "/schemas/types.yaml#/definitions/uint32"
 minimum: 40
 maximum: 1
 default: 160
 
-  fsin2-delay-us:
+  richtek,fsin2-delay-us:
 description: |
   Fsin2 pulse high delay in microsecond after vsync signal pulse high.
-$ref: "/schemas/types.yaml#/definitions/uint32"
 minimum: 0
 maximum: 10
 default: 23000
 
-  fsin2-width-us:
+  richtek,fsin2-width-us:
 description: |
   Fsin2 pulse high width in microsecond after vsync signal pulse high.
-$ref: "/schemas/types.yaml#/definitions/uint32"
 minimum: 40
 maximum: 1
 default: 160
 
-  es-pulse-width-us:
+  richtek,es-pulse-width-us:
 description: Eye safety function pulse width limit in microsecond.
-$ref: "/schemas/types.yaml#/definitions/uint32"
 minimum: 0
 maximum: 1
 default: 1200
 
-  es-ld-current-microamp:
+  richtek,es-ld-current-microamp:
 description: Eye safety function load current limit in microamp.
-$ref: "/schemas/types.yaml#/definitions/uint32"
 minimum: 0
 maximum: 600
 default: 300
 
-  lbp-level-microvolt:
+  richtek,lbp-level-microvolt:
 description: Low battery protection level in microvolt.
-$ref: "/schemas/types.yaml#/definitions/uint32"
 minimum: 240
 maximum: 370
 default: 270
 
-  lbp-enable:
+  richtek,lbp-enable:
 description: Low battery protection function enable control.
 type: boolean
 
-  strobe-polarity-high:
+  richtek,strobe-polarity-high:
 description: Strobe pin active polarity control.
 type: boolean
 
-  vsync-polarity-high:
+  richtek,vsync-polarity-high:
 description: Vsync pin active polarity control.
 type: boolean
 
-  fsin-enable:
+  richtek,fsin-enable:
 description: Fsin function enable control.
 type: boolean
 
-  fsin-output:
+  richtek,fsin-output:
 description: Fsin function output control.
 type: boolean
 
-  es-enable:
+  richtek,es-enable:
 description: Eye safety function enable control.
 type: boolean
 
-patternProperties:
-  "lsw":
+  lsw:
+description: load switch current regulator description.
 type: object
 $ref: "regulator.yaml#"
 
@@ -135,7 +126,7 @@ required:
   - compatible
   - reg
   - wakeup-source
-  - interrupts-extend
+  - interrupts
   - enable-gpios
   - lsw
 
@@ -152,11 +143,11 @@ examples:
 compatible = "richtek,rtmv20";
 reg = <0x34>;
 wakeup-source;
-interrupts-extend = < 2 IRQ_TYPE_LEVEL_LOW>;
+interrupts-extended = < 2 IRQ_TYPE_LEVEL_LOW>;
 enable-gpios = < 3 0>;
 
-strobe-polarity-high;
-vsync-polarity-high;
+richtek,strobe-polarity-high;
+richtek,vsync-polarity-high;
 
 lsw {
 regulator-name = "rtmv20,lsw";
diff --git a/drivers/regulator/rtmv20-regulator.c 
b/drivers/regulator/rtmv20-regulator.c
index 1075b10..05fd8e7c 100644
--- a/drivers/regulator/rtmv20-regulator.c
+++ b/drivers/regulator/rtmv20-regulator.c
@@ -166,28 +166,32 @@ static int rtmv20_properties_init(struct 

[PATCH v2 1/2] regulator: rtmv20: Adds support for Richtek RTMV20 load switch regulator

2020-09-28 Thread cy_huang
From: ChiYuan Huang 

Add support for Richtek RTMV20 load switch regulator.

Signed-off-by: ChiYuan Huang 
---
v1 to v2
1. Use regcache related APIs when HW disable and enable.
2. Because of regcache, refine the initial properties flow.
3. Change all propertiy name to use dash, not underline.
4. Re-check all the comment lines not to over 80 characters.
5. Same as item 3, and also change all 0/1 properties to boolean type in
   dt-binding document.
6. No need is_chip_enabled flag.

---
 drivers/regulator/Kconfig|   9 +
 drivers/regulator/Makefile   |   1 +
 drivers/regulator/rtmv20-regulator.c | 392 +++
 3 files changed, 402 insertions(+)
 create mode 100644 drivers/regulator/rtmv20-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index de17ef7..400ad4c 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -902,6 +902,15 @@ config REGULATOR_RT5033
  RT5033 PMIC. The device supports multiple regulators like
  current source, LDO and Buck.
 
+config REGULATOR_RTMV20
+   tristate "RTMV20 Laser Diode Regulator"
+   depends on I2C
+   select REGMAP_I2C
+   help
+ This driver adds support for the load switch current regulator on
+ the Richtek RTMV20. It can support the load current up to 6A and
+ integrate strobe/vsync/fsin signal to synchronize the IR camera.
+
 config REGULATOR_S2MPA01
tristate "Samsung S2MPA01 voltage regulator"
depends on MFD_SEC_CORE
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index d8d3ecf..89a1cb0 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -112,6 +112,7 @@ obj-$(CONFIG_REGULATOR_RK808)   += rk808-regulator.o
 obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
 obj-$(CONFIG_REGULATOR_ROHM)   += rohm-regulator.o
 obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
+obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
diff --git a/drivers/regulator/rtmv20-regulator.c 
b/drivers/regulator/rtmv20-regulator.c
new file mode 100644
index ..1075b10
--- /dev/null
+++ b/drivers/regulator/rtmv20-regulator.c
@@ -0,0 +1,392 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RTMV20_REG_DEVINFO 0x00
+#define RTMV20_REG_PULSEDELAY  0x01
+#define RTMV20_REG_PULSEWIDTH  0x03
+#define RTMV20_REG_LDCTRL1 0x05
+#define RTMV20_REG_ESPULSEWIDTH0x06
+#define RTMV20_REG_ESLDCTRL1   0x08
+#define RTMV20_REG_LBP 0x0A
+#define RTMV20_REG_LDCTRL2 0x0B
+#define RTMV20_REG_FSIN1CTRL1  0x0D
+#define RTMV20_REG_FSIN1CTRL3  0x0F
+#define RTMV20_REG_FSIN2CTRL1  0x10
+#define RTMV20_REG_FSIN2CTRL3  0x12
+#define RTMV20_REG_ENCTRL  0x13
+#define RTMV20_REG_STRBVSYNDLYL 0x29
+#define RTMV20_REG_LDIRQ   0x30
+#define RTMV20_REG_LDSTAT  0x40
+#define RTMV20_REG_LDMASK  0x50
+
+#define RTMV20_VID_MASKGENMASK(7, 4)
+#define RICHTEK_VID0x80
+#define RTMV20_LDCURR_MASK GENMASK(7, 0)
+#define RTMV20_DELAY_MASK  GENMASK(9, 0)
+#define RTMV20_WIDTH_MASK  GENMASK(13, 0)
+#define RTMV20_WIDTH2_MASK GENMASK(7, 0)
+#define RTMV20_LBPLVL_MASK GENMASK(3, 0)
+#define RTMV20_LBPEN_MASK  BIT(7)
+#define RTMV20_STROBEPOL_MASK  BIT(1)
+#define RTMV20_VSYNPOL_MASKBIT(1)
+#define RTMV20_FSINEN_MASK BIT(7)
+#define RTMV20_ESEN_MASK   BIT(6)
+#define RTMV20_FSINOUT_MASKBIT(2)
+#define LDENABLE_MASK  (BIT(3) | BIT(0))
+
+#define OTPEVT_MASKBIT(4)
+#define SHORTEVT_MASK  BIT(3)
+#define OPENEVT_MASK   BIT(2)
+#define LBPEVT_MASKBIT(1)
+#define OCPEVT_MASKBIT(0)
+#define FAILEVT_MASK   (SHORTEVT_MASK | OPENEVT_MASK | LBPEVT_MASK)
+
+#define RTMV20_LSW_MINUA   0
+#define RTMV20_LSW_MAXUA   600
+#define RTMV20_LSW_STEPUA  3
+
+#define RTMV20_LSW_DEFAULTUA   300
+
+#define RTMV20_I2CRDY_TIMEUS   200
+#define RTMV20_CSRDY_TIMEUS2000
+
+struct rtmv20_priv {
+   struct device *dev;
+   struct regmap *regmap;
+   struct gpio_desc *enable_gpio;
+   struct regulator_dev *rdev;
+};
+
+static int rtmv20_lsw_enable(struct regulator_dev *rdev)
+{
+   struct rtmv20_priv *priv = rdev_get_drvdata(rdev);
+   int ret;
+
+   gpiod_set_value(priv->enable_gpio, 1);
+
+   /* Wait for I2C can be accessed */
+   usleep_range(RTMV20_I2CRDY_TIMEUS, RTMV20_I2CRDY_TIMEUS + 100);
+
+   /* HW re-enable, disable cache only and sync regcache here */
+   regcache_cache_only(priv->regmap, false);
+   ret = regcache_sync(priv->regmap);
+   if (ret)
+   return ret;
+
+   return regulator_enable_regmap(rdev);
+}
+
+static int 

[PATCH v2 2/2] regulator: rtmv20: Add DT-binding document for Richtek RTMV20

2020-09-28 Thread cy_huang
From: ChiYuan Huang 

Add DT-binding document for Richtek RTMV20

Signed-off-by: ChiYuan Huang 
---
 .../regulator/richtek,rtmv20-regulator.yaml| 168 +
 1 file changed, 168 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml

diff --git 
a/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml 
b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml
new file mode 100644
index ..4cb4b68
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml
@@ -0,0 +1,168 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/richtek,rtmv20-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RTMV20 laser diode regulator
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  Richtek RTMV20 is a load switch current regulator that can supply up to 6A.
+  It is used to drive laser diode. There're two signals for chip controls
+  (Enable/Fail), Enable pin to turn chip on, and Fail pin as fault indication.
+  There're still four pins for camera control, two inputs (strobe and vsync),
+  the others for outputs (fsin1 and fsin2). Strobe input to start the current
+  supply, vsync input from IR camera, and fsin1/fsin2 output for the optional.
+
+properties:
+  compatible:
+const: richtek,rtmv20
+
+  reg:
+maxItems: 1
+
+  wakeup-source: true
+
+  interrupts-extend:
+maxItems: 1
+
+  enable-gpios:
+description: A connection of the 'enable' gpio line.
+maxItems: 1
+
+  ld-pulse-delay-us:
+description: |
+  load current pulse delay in microsecond after strobe pin pulse high.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 10
+default: 0
+
+  ld-pulse-width-us:
+description: |
+  Load current pulse width in microsecond after strobe pin pulse high.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 1
+default: 1200
+
+  fsin1-delay-us:
+description: |
+  Fsin1 pulse high delay in microsecond after vsync signal pulse high.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 10
+default: 23000
+
+  fsin1-width-us:
+description: |
+  Fsin1 pulse high width in microsecond after vsync signal pulse high.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 40
+maximum: 1
+default: 160
+
+  fsin2-delay-us:
+description: |
+  Fsin2 pulse high delay in microsecond after vsync signal pulse high.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 10
+default: 23000
+
+  fsin2-width-us:
+description: |
+  Fsin2 pulse high width in microsecond after vsync signal pulse high.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 40
+maximum: 1
+default: 160
+
+  es-pulse-width-us:
+description: Eye safety function pulse width limit in microsecond.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 1
+default: 1200
+
+  es-ld-current-microamp:
+description: Eye safety function load current limit in microamp.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 600
+default: 300
+
+  lbp-level-microvolt:
+description: Low battery protection level in microvolt.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 240
+maximum: 370
+default: 270
+
+  lbp-enable:
+description: Low battery protection function enable control.
+type: boolean
+
+  strobe-polarity-high:
+description: Strobe pin active polarity control.
+type: boolean
+
+  vsync-polarity-high:
+description: Vsync pin active polarity control.
+type: boolean
+
+  fsin-enable:
+description: Fsin function enable control.
+type: boolean
+
+  fsin-output:
+description: Fsin function output control.
+type: boolean
+
+  es-enable:
+description: Eye safety function enable control.
+type: boolean
+
+patternProperties:
+  "lsw":
+type: object
+$ref: "regulator.yaml#"
+
+required:
+  - compatible
+  - reg
+  - wakeup-source
+  - interrupts-extend
+  - enable-gpios
+  - lsw
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+i2c {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  rtmv20@34 {
+compatible = "richtek,rtmv20";
+reg = <0x34>;
+wakeup-source;
+interrupts-extend = < 2 IRQ_TYPE_LEVEL_LOW>;
+enable-gpios = < 3 0>;
+
+strobe-polarity-high;
+vsync-polarity-high;
+
+lsw {
+regulator-name = "rtmv20,lsw";
+regulator-min-microamp = <0>;
+regulator-max-microamp = <600>;
+};
+  };
+};
+...
-- 
2.7.4



[PATCH v1 2/2] regulator: rtmv20: Add DT-binding document for Richtek RTMV20

2020-09-24 Thread cy_huang
From: ChiYuan Huang 

Add DT-binding document for Richtek RTMV20

Signed-off-by: ChiYuan Huang 
---
 .../regulator/richtek,rtmv20-regulator.yaml| 183 +
 1 file changed, 183 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml

diff --git 
a/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml 
b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml
new file mode 100644
index ..0e906af
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml
@@ -0,0 +1,183 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/richtek,rtmv20-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RTMV20 laser diode regulator
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  Richtek RTMV20 is a load switch current regulator that can supply up to 6A.
+  It is used to drive laser diode. There're two signals for chip controls
+  (Enable/Fail), Enable pin to turn chip on, and Fail pin as fault indication.
+  There're still four pins for camera control, two inputs (strobe and vsync),
+  the others for outputs (fsin1 and fsin2). Strobe input to start the current
+  supply, vsync input from IR camera, and fsin1/fsin2 output for the optional.
+
+properties:
+  compatible:
+const: richtek,rtmv20
+
+  reg:
+maxItems: 1
+
+  wakeup-source: true
+
+  interrupts-extend:
+maxItems: 1
+
+  enable-gpio:
+description: A connection of the 'enable' gpio line.
+maxItems: 1
+
+  ld_pulse_delay:
+description: |
+  load current pulse delay in microsecond after strobe pin pulse high.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 10
+default: 0
+
+  ld_pulse_width:
+description: |
+  Load current pulse width in microsecond after strobe pin pulse high.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 1
+default: 1200
+
+  fsin1_delay:
+description: |
+  Fsin1 pulse high delay in microsecond after vsync signal pulse high.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 10
+default: 23000
+
+  fsin1_width:
+description: |
+  Fsin1 pulse high width in microsecond after vsync signal pulse high.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 40
+maximum: 1
+default: 160
+
+  fsin2_delay:
+description: |
+  Fsin2 pulse high delay in microsecond after vsync signal pulse high.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 10
+default: 23000
+
+  fsin2_width:
+description: |
+  Fsin2 pulse high width in microsecond after vsync signal pulse high.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 40
+maximum: 1
+default: 160
+
+  es_pulse_width:
+description: Eye safety function pulse width limit in microsecond.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 1
+default: 1200
+
+  es_ld_current:
+description: Eye safety function load current limit in microamp.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 600
+default: 300
+
+  lbp_level:
+description: Low battery protection level in microvolt.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 240
+maximum: 370
+default: 270
+
+  lbp_enable:
+description: Low battery protection function enable control.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 1
+default: 0
+
+  strobe_polarity:
+description: Strobe pin active polarity control.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 1
+default: 1
+
+  vsync_polarity:
+description: Vsync pin active polarity control.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 1
+default: 1
+
+  fsin_enable:
+description: Fsin function enable control.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 1
+default: 0
+
+  fsin_output:
+description: Fsin function output control.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 1
+default: 0
+
+  es_enable:
+description: Eye safety function enable control.
+$ref: "/schemas/types.yaml#/definitions/uint32"
+minimum: 0
+maximum: 1
+default: 0
+
+patternProperties:
+  "lsw":
+type: object
+$ref: "regulator.yaml#"
+
+required:
+  - compatible
+  - reg
+  - wakeup-source
+  - interrupts-extend
+  - enable-gpio
+  - lsw
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+i2c {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  rtmv20@34 {
+compatible = "richtek,rtmv20";
+ 

[PATCH v1 1/2] regulator: rtmv20: Adds support for Richtek RTMV20 load switch regulator

2020-09-24 Thread cy_huang
From: ChiYuan Huang 

Add support for Richtek RTMV20 load switch regulator.

Signed-off-by: ChiYuan Huang 
---
 drivers/regulator/Kconfig|   9 +
 drivers/regulator/Makefile   |   1 +
 drivers/regulator/rtmv20-regulator.c | 512 +++
 3 files changed, 522 insertions(+)
 create mode 100644 drivers/regulator/rtmv20-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index de17ef7..400ad4c 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -902,6 +902,15 @@ config REGULATOR_RT5033
  RT5033 PMIC. The device supports multiple regulators like
  current source, LDO and Buck.
 
+config REGULATOR_RTMV20
+   tristate "RTMV20 Laser Diode Regulator"
+   depends on I2C
+   select REGMAP_I2C
+   help
+ This driver adds support for the load switch current regulator on
+ the Richtek RTMV20. It can support the load current up to 6A and
+ integrate strobe/vsync/fsin signal to synchronize the IR camera.
+
 config REGULATOR_S2MPA01
tristate "Samsung S2MPA01 voltage regulator"
depends on MFD_SEC_CORE
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index d8d3ecf..89a1cb0 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -112,6 +112,7 @@ obj-$(CONFIG_REGULATOR_RK808)   += rk808-regulator.o
 obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
 obj-$(CONFIG_REGULATOR_ROHM)   += rohm-regulator.o
 obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
+obj-$(CONFIG_REGULATOR_RTMV20) += rtmv20-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
 obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
diff --git a/drivers/regulator/rtmv20-regulator.c 
b/drivers/regulator/rtmv20-regulator.c
new file mode 100644
index ..8fa083c
--- /dev/null
+++ b/drivers/regulator/rtmv20-regulator.c
@@ -0,0 +1,512 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RTMV20_REG_DEVINFO 0x00
+#define RTMV20_REG_PULSEDELAY  0x01
+#define RTMV20_REG_PULSEWIDTH  0x03
+#define RTMV20_REG_LDCTRL1 0x05
+#define RTMV20_REG_ESPULSEWIDTH0x06
+#define RTMV20_REG_ESLDCTRL1   0x08
+#define RTMV20_REG_LBP 0x0A
+#define RTMV20_REG_LDCTRL2 0x0B
+#define RTMV20_REG_FSIN1CTRL1  0x0D
+#define RTMV20_REG_FSIN1CTRL3  0x0F
+#define RTMV20_REG_FSIN2CTRL1  0x10
+#define RTMV20_REG_FSIN2CTRL3  0x12
+#define RTMV20_REG_ENCTRL  0x13
+#define RTMV20_REG_STRBVSYNDLYL 0x29
+#define RTMV20_REG_LDIRQ   0x30
+#define RTMV20_REG_LDSTAT  0x40
+#define RTMV20_REG_LDMASK  0x50
+
+#define RTMV20_VID_MASKGENMASK(7, 4)
+#define RICHTEK_VID0x80
+#define RTMV20_LDCURR_MASK GENMASK(7, 0)
+#define RTMV20_DELAY_MASK  GENMASK(9, 0)
+#define RTMV20_WIDTH_MASK  GENMASK(13, 0)
+#define RTMV20_WIDTH2_MASK GENMASK(7, 0)
+#define RTMV20_LBPLVL_MASK GENMASK(3, 0)
+#define RTMV20_LBPEN_MASK  BIT(7)
+#define RTMV20_STROBEPOL_MASK  BIT(1)
+#define RTMV20_VSYNPOL_MASKBIT(1)
+#define RTMV20_FSINEN_MASK BIT(7)
+#define RTMV20_ESEN_MASK   BIT(6)
+#define RTMV20_FSINOUT_MASKBIT(2)
+#define LDENABLE_MASK  (BIT(3) | BIT(0))
+
+#define OTPEVT_MASKBIT(4)
+#define SHORTEVT_MASK  BIT(3)
+#define OPENEVT_MASK   BIT(2)
+#define LBPEVT_MASKBIT(1)
+#define OCPEVT_MASKBIT(0)
+#define FAILEVT_MASK   (SHORTEVT_MASK | OPENEVT_MASK | LBPEVT_MASK)
+
+#define RTMV20_1BYTE_ACCES 1
+#define RTMV20_2BYTE_ACCES 2
+
+#define RTMV20_LSW_MINUA   0
+#define RTMV20_LSW_MAXUA   600
+#define RTMV20_LSW_STEPUA  3
+
+#define RTMV20_LSW_DEFAULTUA   300
+
+#define RTMV20_I2CRDY_TIMEUS   200
+#define RTMV20_CSRDY_TIMEUS2000
+
+/* All uint in microsecond or microamp */
+struct init_properties {
+   u16 ld_pulse_delay;
+   u16 ld_pulse_width;
+   u16 fsin1_delay;
+   u8 fsin1_width;
+   u16 fsin2_delay;
+   u8 fsin2_width;
+   u16 es_pulse_width;
+   u8 es_ld_current;
+   u8 lbp_level;
+   u8 lbp_enable;
+   u8 strobe_polarity;
+   u8 vsync_polarity;
+   u8 fsin_enable;
+   u8 fsin_output;
+   u8 es_enable;
+};
+
+struct rtmv20_priv {
+   struct device *dev;
+   struct regmap *regmap;
+   struct gpio_desc *enable_gpio;
+   struct regulator_dev *rdev;
+   struct init_properties properties;
+   bool is_chip_enabled;
+   unsigned int curr_selector;
+};
+
+#define PROP_REG_DECL(_name, reg, mask) \
+{ offsetof(struct init_properties, _name), sizeof_field(struct 
init_properties, _name), reg, mask }
+
+static int rtmv20_apply_properties(struct rtmv20_priv *priv)
+{
+   const struct {
+   int offset;
+   int len;
+   unsigned int reg;
+   

[PATCH] usb: typec: tcpm: Fix if vbus before cc, hard_reset_count not reset issue

2020-09-02 Thread cy_huang
From: ChiYuan Huang 

Fix: If vbus event is before cc_event trigger, hard_reset_count
won't bt reset for some case.

Signed-off-by: ChiYuan Huang 
---
Below's the flow.

_tcpm_pd_vbus_off() -> run_state_machine to change state to SNK_UNATTACHED
call tcpm_snk_detach() -> tcpm_snk_detach() -> tcpm_detach()
tcpm_port_is_disconnected() will be called.
But port->attached is still true and port->cc1=open and port->cc2=open

It cause tcpm_port_is_disconnected return false, then hard_reset_count won't be 
reset.
After that, tcpm_reset_port() is called.
port->attached become false.

After that, cc now trigger cc_change event, the hard_reset_count will be kept.
Even tcpm_detach will be called, due to port->attached is false, tcpm_detach()
will directly return.

CC_EVENT will only trigger drp toggling again.
---
 drivers/usb/typec/tcpm/tcpm.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index a48e3f90..5c73e1d 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -2797,8 +2797,7 @@ static void tcpm_detach(struct tcpm_port *port)
port->tcpc->set_bist_data(port->tcpc, false);
}
 
-   if (tcpm_port_is_disconnected(port))
-   port->hard_reset_count = 0;
+   port->hard_reset_count = 0;
 
tcpm_reset_port(port);
 }
-- 
2.7.4



[PATCH v5 2/2] usb typec: mt6360: Add MT6360 Type-C DT binding documentation

2020-08-31 Thread cy_huang
From: ChiYuan Huang 

Add a devicetree binding documentation for the MT6360 Type-C driver.

Signed-off-by: ChiYuan Huang 
---
 .../bindings/usb/mediatek,mt6360-tcpc.yaml | 95 ++
 1 file changed, 95 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml 
b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
new file mode 100644
index ..1e8e1c2
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
@@ -0,0 +1,95 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/mediatek,mt6360-tcpc.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: Mediatek MT6360 Type-C Port Switch and Power Delivery controller DT 
bindings
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  Mediatek MT6360 is a multi-functional device. It integrates charger, ADC, 
flash, RGB indicators,
+  regulators (BUCKs/LDOs), and TypeC Port Switch with Power Delivery 
controller.
+  This document only describes MT6360 Type-C Port Switch and Power Delivery 
controller.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt6360-tcpc
+
+  interrupts:
+maxItems: 1
+
+  interrupt-names:
+items:
+  - const: PD_IRQB
+
+  connector:
+type: object
+$ref: ../connector/usb-connector.yaml#
+description:
+  Properties for usb c connector.
+
+additionalProperties: false
+
+required:
+  - compatible
+  - interrupts
+  - interrupt-names
+
+examples:
+  - |
+#include 
+#include 
+i2c0 {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  mt6360@34 {
+compatible = "mediatek,mt6360";
+reg = <0x34>;
+tcpc {
+  compatible = "mediatek,mt6360-tcpc";
+  interrupts-extended = < 3 IRQ_TYPE_LEVEL_LOW>;
+  interrupt-names = "PD_IRQB";
+
+  connector {
+compatible = "usb-c-connector";
+label = "USB-C";
+data-role = "dual";
+power-role = "dual";
+try-power-role = "sink";
+source-pdos = ;
+sink-pdos = ;
+op-sink-microwatt = <1000>;
+
+ports {
+  #address-cells = <1>;
+  #size-cells = <0>;
+
+  port@0 {
+reg = <0>;
+endpoint {
+  remote-endpoint = <_hs>;
+};
+  };
+  port@1 {
+reg = <1>;
+endpoint {
+  remote-endpoint = <_ss>;
+};
+  };
+  port@2 {
+reg = <2>;
+endpoint {
+  remote-endpoint = <_aux>;
+};
+  };
+};
+  };
+};
+  };
+};
+...
-- 
2.7.4



[PATCH v5 1/2] usb typec: mt6360: Add support for mt6360 Type-C driver

2020-08-31 Thread cy_huang
From: ChiYuan Huang 

Mediatek MT6360 is a multi-functional IC that includes USB Type-C.
It works with Type-C Port Controller Manager to provide USB PD
and USB Type-C functionalities.

Signed-off-by: ChiYuan Huang 
---
v1 to v2
1. Add fix to Prevent the race condition from interrupt and tcpci port
   unregister during module remove.

v2 to v3
1. Change comment style for the head of source code.
2. No need to print error for platform_get_irq_byname.
3. Fix tcpci_register_port check from IS_ERR_OR_NULL to IS_ERR.
4. Rename driver/Kconfig/Makefile form mt6360 to mt636x.
5. Rename DT binding documents from mt6360 to mt636x.

v3 to v4
1. revert v3 item 4 for mt636x patch in driver/Kconfig/Makefile
2. revert v3 item 5 for mt636x DT binding document.

v4 to v5
All changes are for DT binding document. See patch 2.
1. Fix schema style (using spaces instead of tabs)
2. move connector into the properties block.
3. Add ports node into the binding example refer to USB HS/SS/DPMux.

---
 drivers/usb/typec/tcpm/Kconfig|   8 ++
 drivers/usb/typec/tcpm/Makefile   |   1 +
 drivers/usb/typec/tcpm/tcpci_mt6360.c | 212 ++
 3 files changed, 221 insertions(+)
 create mode 100644 drivers/usb/typec/tcpm/tcpci_mt6360.c

diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index fa3f393..58a64e1 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -27,6 +27,14 @@ config TYPEC_RT1711H
  Type-C Port Controller Manager to provide USB PD and USB
  Type-C functionalities.
 
+config TYPEC_MT6360
+   tristate "Mediatek MT6360 Type-C driver"
+   depends on MFD_MT6360
+   help
+ Mediatek MT6360 is a multi-functional IC that includes
+ USB Type-C. It works with Type-C Port Controller Manager
+ to provide USB PD and USB Type-C functionalities.
+
 endif # TYPEC_TCPCI
 
 config TYPEC_FUSB302
diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile
index a5ff6c8..7592ccb 100644
--- a/drivers/usb/typec/tcpm/Makefile
+++ b/drivers/usb/typec/tcpm/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_TYPEC_WCOVE)   += typec_wcove.o
 typec_wcove-y  := wcove.o
 obj-$(CONFIG_TYPEC_TCPCI)  += tcpci.o
 obj-$(CONFIG_TYPEC_RT1711H)+= tcpci_rt1711h.o
+obj-$(CONFIG_TYPEC_MT6360) += tcpci_mt6360.o
diff --git a/drivers/usb/typec/tcpm/tcpci_mt6360.c 
b/drivers/usb/typec/tcpm/tcpci_mt6360.c
new file mode 100644
index ..f1bd9e0
--- /dev/null
+++ b/drivers/usb/typec/tcpm/tcpci_mt6360.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: ChiYuan Huang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tcpci.h"
+
+#define MT6360_REG_VCONNCTRL1  0x8C
+#define MT6360_REG_MODECTRL2   0x8F
+#define MT6360_REG_SWRESET 0xA0
+#define MT6360_REG_DEBCTRL10xA1
+#define MT6360_REG_DRPCTRL10xA2
+#define MT6360_REG_DRPCTRL20xA3
+#define MT6360_REG_I2CTORST0xBF
+#define MT6360_REG_RXCTRL2 0xCF
+#define MT6360_REG_CTDCTRL20xEC
+
+/* MT6360_REG_VCONNCTRL1 */
+#define MT6360_VCONNCL_ENABLE  BIT(0)
+/* MT6360_REG_RXCTRL2 */
+#define MT6360_OPEN40M_ENABLE  BIT(7)
+/* MT6360_REG_CTDCTRL2 */
+#define MT6360_RPONESHOT_ENABLEBIT(6)
+
+struct mt6360_tcpc_info {
+   struct tcpci_data tdata;
+   struct tcpci *tcpci;
+   struct device *dev;
+   int irq;
+};
+
+static inline int mt6360_tcpc_read16(struct regmap *regmap,
+unsigned int reg, u16 *val)
+{
+   return regmap_raw_read(regmap, reg, val, sizeof(u16));
+}
+
+static inline int mt6360_tcpc_write16(struct regmap *regmap,
+ unsigned int reg, u16 val)
+{
+   return regmap_raw_write(regmap, reg, , sizeof(u16));
+}
+
+static int mt6360_tcpc_init(struct tcpci *tcpci, struct tcpci_data *tdata)
+{
+   struct regmap *regmap = tdata->regmap;
+   int ret;
+
+   ret = regmap_write(regmap, MT6360_REG_SWRESET, 0x01);
+   if (ret)
+   return ret;
+
+   /* after reset command, wait 1~2ms to wait IC action */
+   usleep_range(1000, 2000);
+
+   /* write all alert to masked */
+   ret = mt6360_tcpc_write16(regmap, TCPC_ALERT_MASK, 0);
+   if (ret)
+   return ret;
+
+   /* config I2C timeout reset enable , and timeout to 200ms */
+   ret = regmap_write(regmap, MT6360_REG_I2CTORST, 0x8F);
+   if (ret)
+   return ret;
+
+   /* config CC Detect Debounce : 26.7*val us */
+   ret = regmap_write(regmap, MT6360_REG_DEBCTRL1, 0x10);
+   if (ret)
+   return ret;
+
+   /* DRP Toggle Cycle : 51.2 + 6.4*val ms */
+   ret = regmap_write(regmap, MT6360_REG_DRPCTRL1, 4);
+   if (ret)
+   return ret;
+
+   /* DRP Duyt Ctrl : dcSRC: /1024 */
+   ret = mt6360_tcpc_write16(regmap, MT6360_REG_DRPCTRL2, 

[PATCH v4 2/2] usb typec: mt6360: Add MT6360 Type-C DT binding documentation

2020-08-28 Thread cy_huang
From: ChiYuan Huang 

Add a devicetree binding documentation for the MT6360 Type-C driver.

usb typec: mt6360: Rename DT binding doument from mt6360 to mt636x

Signed-off-by: ChiYuan Huang 
---
 .../bindings/usb/mediatek,mt6360-tcpc.yaml | 73 ++
 1 file changed, 73 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml 
b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
new file mode 100644
index ..9e8ab0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/mediatek,mt6360-tcpc.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: Mediatek MT6360 Type-C Port Switch and Power Delivery controller DT 
bindings
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  Mediatek MT6360 is a multi-functional device. It integrates charger, ADC, 
flash, RGB indicators,
+  regulators (BUCKs/LDOs), and TypeC Port Switch with Power Delivery 
controller.
+  This document only describes MT6360 Type-C Port Switch and Power Delivery 
controller.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt6360-tcpc
+
+  interrupts-extended:
+maxItems: 1
+
+  interrupt-names:
+items:
+  - const: PD_IRQB
+
+patternProperties:
+  "connector":
+type: object
+$ref: ../connector/usb-connector.yaml#
+description:
+  Properties for usb c connector.
+
+additionalProperties: false
+
+required:
+  - compatible
+  - interrupts-extended
+  - interrupt-names
+
+examples:
+  - |
+#include 
+#include 
+i2c0 {
+#address-cells = <1>;
+#size-cells = <0>;
+
+mt6360@34 {
+compatible = "mediatek,mt6360";
+reg = <0x34>;
+
+tcpc {
+compatible = "mediatek,mt6360-tcpc";
+interrupts-extended = < 3 IRQ_TYPE_LEVEL_LOW>;
+interrupt-names = "PD_IRQB";
+
+connector {
+compatible = "usb-c-connector";
+label = "USB-C";
+data-role = "dual";
+power-role = "dual";
+try-power-role = "sink";
+source-pdos = ;
+sink-pdos = ;
+op-sink-microwatt = <1000>;
+};
+};
+};
+};
+...
-- 
2.7.4



[PATCH v4 1/2] usb typec: mt6360: Add support for mt6360 Type-C driver

2020-08-28 Thread cy_huang
From: ChiYuan Huang 

Mediatek MT6360 is a multi-functional IC that includes USB Type-C.
It works with Type-C Port Controller Manager to provide USB PD
and USB Type-C functionalities.

Signed-off-by: ChiYuan Huang 
---
v2
1. Add fix to Prevent the race condition from interrupt and tcpci port
unregister during module remove.

v3
1. Change comment style for the head of source code.
2. No need to print error for platform_get_irq_byname.
3. Fix tcpci_register_port check from IS_ERR_OR_NULL to IS_ERR.
4. Rename driver/Kconfig/Makefile form mt6360 to mt636x.
5. Rename DT binding documents from mt6360 to mt636x.

v4
1. revert v3 item 4 for mt636x patch in driver/Kconfig/Makefile
2. revert v3 item 5 for mt636x DT binding document.

added the mark line after changelog ended.
---
 drivers/usb/typec/tcpm/Kconfig|   8 ++
 drivers/usb/typec/tcpm/Makefile   |   1 +
 drivers/usb/typec/tcpm/tcpci_mt6360.c | 212 ++
 3 files changed, 221 insertions(+)
 create mode 100644 drivers/usb/typec/tcpm/tcpci_mt6360.c

diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index fa3f393..58a64e1 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -27,6 +27,14 @@ config TYPEC_RT1711H
  Type-C Port Controller Manager to provide USB PD and USB
  Type-C functionalities.
 
+config TYPEC_MT6360
+   tristate "Mediatek MT6360 Type-C driver"
+   depends on MFD_MT6360
+   help
+ Mediatek MT6360 is a multi-functional IC that includes
+ USB Type-C. It works with Type-C Port Controller Manager
+ to provide USB PD and USB Type-C functionalities.
+
 endif # TYPEC_TCPCI
 
 config TYPEC_FUSB302
diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile
index a5ff6c8..7592ccb 100644
--- a/drivers/usb/typec/tcpm/Makefile
+++ b/drivers/usb/typec/tcpm/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_TYPEC_WCOVE)   += typec_wcove.o
 typec_wcove-y  := wcove.o
 obj-$(CONFIG_TYPEC_TCPCI)  += tcpci.o
 obj-$(CONFIG_TYPEC_RT1711H)+= tcpci_rt1711h.o
+obj-$(CONFIG_TYPEC_MT6360) += tcpci_mt6360.o
diff --git a/drivers/usb/typec/tcpm/tcpci_mt6360.c 
b/drivers/usb/typec/tcpm/tcpci_mt6360.c
new file mode 100644
index ..f1bd9e0
--- /dev/null
+++ b/drivers/usb/typec/tcpm/tcpci_mt6360.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: ChiYuan Huang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tcpci.h"
+
+#define MT6360_REG_VCONNCTRL1  0x8C
+#define MT6360_REG_MODECTRL2   0x8F
+#define MT6360_REG_SWRESET 0xA0
+#define MT6360_REG_DEBCTRL10xA1
+#define MT6360_REG_DRPCTRL10xA2
+#define MT6360_REG_DRPCTRL20xA3
+#define MT6360_REG_I2CTORST0xBF
+#define MT6360_REG_RXCTRL2 0xCF
+#define MT6360_REG_CTDCTRL20xEC
+
+/* MT6360_REG_VCONNCTRL1 */
+#define MT6360_VCONNCL_ENABLE  BIT(0)
+/* MT6360_REG_RXCTRL2 */
+#define MT6360_OPEN40M_ENABLE  BIT(7)
+/* MT6360_REG_CTDCTRL2 */
+#define MT6360_RPONESHOT_ENABLEBIT(6)
+
+struct mt6360_tcpc_info {
+   struct tcpci_data tdata;
+   struct tcpci *tcpci;
+   struct device *dev;
+   int irq;
+};
+
+static inline int mt6360_tcpc_read16(struct regmap *regmap,
+unsigned int reg, u16 *val)
+{
+   return regmap_raw_read(regmap, reg, val, sizeof(u16));
+}
+
+static inline int mt6360_tcpc_write16(struct regmap *regmap,
+ unsigned int reg, u16 val)
+{
+   return regmap_raw_write(regmap, reg, , sizeof(u16));
+}
+
+static int mt6360_tcpc_init(struct tcpci *tcpci, struct tcpci_data *tdata)
+{
+   struct regmap *regmap = tdata->regmap;
+   int ret;
+
+   ret = regmap_write(regmap, MT6360_REG_SWRESET, 0x01);
+   if (ret)
+   return ret;
+
+   /* after reset command, wait 1~2ms to wait IC action */
+   usleep_range(1000, 2000);
+
+   /* write all alert to masked */
+   ret = mt6360_tcpc_write16(regmap, TCPC_ALERT_MASK, 0);
+   if (ret)
+   return ret;
+
+   /* config I2C timeout reset enable , and timeout to 200ms */
+   ret = regmap_write(regmap, MT6360_REG_I2CTORST, 0x8F);
+   if (ret)
+   return ret;
+
+   /* config CC Detect Debounce : 26.7*val us */
+   ret = regmap_write(regmap, MT6360_REG_DEBCTRL1, 0x10);
+   if (ret)
+   return ret;
+
+   /* DRP Toggle Cycle : 51.2 + 6.4*val ms */
+   ret = regmap_write(regmap, MT6360_REG_DRPCTRL1, 4);
+   if (ret)
+   return ret;
+
+   /* DRP Duyt Ctrl : dcSRC: /1024 */
+   ret = mt6360_tcpc_write16(regmap, MT6360_REG_DRPCTRL2, 330);
+   if (ret)
+   return ret;
+
+   /* Enable VCONN Current Limit function */
+   ret = regmap_update_bits(regmap, MT6360_REG_VCONNCTRL1, 
MT6360_VCONNCL_ENABLE,
+

[PATCH v4 2/2] usb typec: mt6360: Add MT6360 Type-C DT binding documentation

2020-08-28 Thread cy_huang
From: ChiYuan Huang 

Add a devicetree binding documentation for the MT6360 Type-C driver.

usb typec: mt6360: Rename DT binding doument from mt6360 to mt636x

Signed-off-by: ChiYuan Huang 
---
 .../bindings/usb/mediatek,mt6360-tcpc.yaml | 73 ++
 1 file changed, 73 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml 
b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
new file mode 100644
index ..9e8ab0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/mediatek,mt6360-tcpc.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: Mediatek MT6360 Type-C Port Switch and Power Delivery controller DT 
bindings
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  Mediatek MT6360 is a multi-functional device. It integrates charger, ADC, 
flash, RGB indicators,
+  regulators (BUCKs/LDOs), and TypeC Port Switch with Power Delivery 
controller.
+  This document only describes MT6360 Type-C Port Switch and Power Delivery 
controller.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt6360-tcpc
+
+  interrupts-extended:
+maxItems: 1
+
+  interrupt-names:
+items:
+  - const: PD_IRQB
+
+patternProperties:
+  "connector":
+type: object
+$ref: ../connector/usb-connector.yaml#
+description:
+  Properties for usb c connector.
+
+additionalProperties: false
+
+required:
+  - compatible
+  - interrupts-extended
+  - interrupt-names
+
+examples:
+  - |
+#include 
+#include 
+i2c0 {
+#address-cells = <1>;
+#size-cells = <0>;
+
+mt6360@34 {
+compatible = "mediatek,mt6360";
+reg = <0x34>;
+
+tcpc {
+compatible = "mediatek,mt6360-tcpc";
+interrupts-extended = < 3 IRQ_TYPE_LEVEL_LOW>;
+interrupt-names = "PD_IRQB";
+
+connector {
+compatible = "usb-c-connector";
+label = "USB-C";
+data-role = "dual";
+power-role = "dual";
+try-power-role = "sink";
+source-pdos = ;
+sink-pdos = ;
+op-sink-microwatt = <1000>;
+};
+};
+};
+};
+...
-- 
2.7.4



[PATCH v4 1/2] usb typec: mt6360: Add support for mt6360 Type-C driver

2020-08-28 Thread cy_huang
From: ChiYuan Huang 

Mediatek MT6360 is a multi-functional IC that includes USB Type-C.
It works with Type-C Port Controller Manager to provide USB PD
and USB Type-C functionalities.

Signed-off-by: ChiYuan Huang 
---
v1 to v2
1. Add fix to Prevent the race condition from interrupt and tcpci port
unregister during module remove.

v2 to v3
1. Change comment style for the head of source code.
2. No need to print error for platform_get_irq_byname.
3. Fix tcpci_register_port check from IS_ERR_OR_NULL to IS_ERR.
4. Rename driver/Kconfig/Makefile form mt6360 to mt636x.
5. Rename DT binding documents from mt6360 to mt636x.

v3 to v4
1. revert v3 item 4 for mt636x patch in driver/Kconfig/Makefile.
2. revert v3 item 5 for mt636x DT binding document.

 drivers/usb/typec/tcpm/Kconfig|   8 ++
 drivers/usb/typec/tcpm/Makefile   |   1 +
 drivers/usb/typec/tcpm/tcpci_mt6360.c | 212 ++
 3 files changed, 221 insertions(+)
 create mode 100644 drivers/usb/typec/tcpm/tcpci_mt6360.c

diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index fa3f393..58a64e1 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -27,6 +27,14 @@ config TYPEC_RT1711H
  Type-C Port Controller Manager to provide USB PD and USB
  Type-C functionalities.
 
+config TYPEC_MT6360
+   tristate "Mediatek MT6360 Type-C driver"
+   depends on MFD_MT6360
+   help
+ Mediatek MT6360 is a multi-functional IC that includes
+ USB Type-C. It works with Type-C Port Controller Manager
+ to provide USB PD and USB Type-C functionalities.
+
 endif # TYPEC_TCPCI
 
 config TYPEC_FUSB302
diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile
index a5ff6c8..7592ccb 100644
--- a/drivers/usb/typec/tcpm/Makefile
+++ b/drivers/usb/typec/tcpm/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_TYPEC_WCOVE)   += typec_wcove.o
 typec_wcove-y  := wcove.o
 obj-$(CONFIG_TYPEC_TCPCI)  += tcpci.o
 obj-$(CONFIG_TYPEC_RT1711H)+= tcpci_rt1711h.o
+obj-$(CONFIG_TYPEC_MT6360) += tcpci_mt6360.o
diff --git a/drivers/usb/typec/tcpm/tcpci_mt6360.c 
b/drivers/usb/typec/tcpm/tcpci_mt6360.c
new file mode 100644
index ..f1bd9e0
--- /dev/null
+++ b/drivers/usb/typec/tcpm/tcpci_mt6360.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: ChiYuan Huang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tcpci.h"
+
+#define MT6360_REG_VCONNCTRL1  0x8C
+#define MT6360_REG_MODECTRL2   0x8F
+#define MT6360_REG_SWRESET 0xA0
+#define MT6360_REG_DEBCTRL10xA1
+#define MT6360_REG_DRPCTRL10xA2
+#define MT6360_REG_DRPCTRL20xA3
+#define MT6360_REG_I2CTORST0xBF
+#define MT6360_REG_RXCTRL2 0xCF
+#define MT6360_REG_CTDCTRL20xEC
+
+/* MT6360_REG_VCONNCTRL1 */
+#define MT6360_VCONNCL_ENABLE  BIT(0)
+/* MT6360_REG_RXCTRL2 */
+#define MT6360_OPEN40M_ENABLE  BIT(7)
+/* MT6360_REG_CTDCTRL2 */
+#define MT6360_RPONESHOT_ENABLEBIT(6)
+
+struct mt6360_tcpc_info {
+   struct tcpci_data tdata;
+   struct tcpci *tcpci;
+   struct device *dev;
+   int irq;
+};
+
+static inline int mt6360_tcpc_read16(struct regmap *regmap,
+unsigned int reg, u16 *val)
+{
+   return regmap_raw_read(regmap, reg, val, sizeof(u16));
+}
+
+static inline int mt6360_tcpc_write16(struct regmap *regmap,
+ unsigned int reg, u16 val)
+{
+   return regmap_raw_write(regmap, reg, , sizeof(u16));
+}
+
+static int mt6360_tcpc_init(struct tcpci *tcpci, struct tcpci_data *tdata)
+{
+   struct regmap *regmap = tdata->regmap;
+   int ret;
+
+   ret = regmap_write(regmap, MT6360_REG_SWRESET, 0x01);
+   if (ret)
+   return ret;
+
+   /* after reset command, wait 1~2ms to wait IC action */
+   usleep_range(1000, 2000);
+
+   /* write all alert to masked */
+   ret = mt6360_tcpc_write16(regmap, TCPC_ALERT_MASK, 0);
+   if (ret)
+   return ret;
+
+   /* config I2C timeout reset enable , and timeout to 200ms */
+   ret = regmap_write(regmap, MT6360_REG_I2CTORST, 0x8F);
+   if (ret)
+   return ret;
+
+   /* config CC Detect Debounce : 26.7*val us */
+   ret = regmap_write(regmap, MT6360_REG_DEBCTRL1, 0x10);
+   if (ret)
+   return ret;
+
+   /* DRP Toggle Cycle : 51.2 + 6.4*val ms */
+   ret = regmap_write(regmap, MT6360_REG_DRPCTRL1, 4);
+   if (ret)
+   return ret;
+
+   /* DRP Duyt Ctrl : dcSRC: /1024 */
+   ret = mt6360_tcpc_write16(regmap, MT6360_REG_DRPCTRL2, 330);
+   if (ret)
+   return ret;
+
+   /* Enable VCONN Current Limit function */
+   ret = regmap_update_bits(regmap, MT6360_REG_VCONNCTRL1, 
MT6360_VCONNCL_ENABLE,
+

[PATCH v3 3/3] usb typec: mt6360: Add MT6360 Type-C DT binding documentation

2020-08-27 Thread cy_huang
From: ChiYuan Huang 

Add a devicetree binding documentation for the MT6360 Type-C driver.

usb typec: mt6360: Rename DT binding doument from mt6360 to mt636x

Change binding document file name from mt6360 to mt636xfor the
future compatible.
Also change internal description from mt6360 to mt636x.

Signed-off-by: ChiYuan Huang 
---
 .../bindings/usb/mediatek,mt636x-tcpc.yaml | 73 ++
 1 file changed, 73 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/usb/mediatek,mt636x-tcpc.yaml

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mt636x-tcpc.yaml 
b/Documentation/devicetree/bindings/usb/mediatek,mt636x-tcpc.yaml
new file mode 100644
index ..e6d2b3d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/mediatek,mt636x-tcpc.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/mediatek,mt636x-tcpc.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: Mediatek MT636x Type-C Port Switch and Power Delivery controller DT 
bindings
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  Mediatek MT636x is a multi-functional device. It integrates charger, ADC, 
flash, RGB indicators,
+  regulators (BUCKs/LDOs), and TypeC Port Switch with Power Delivery 
controller.
+  This document only describes MT636x Type-C Port Switch and Power Delivery 
controller.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt6360-tcpc
+
+  interrupts-extended:
+maxItems: 1
+
+  interrupt-names:
+items:
+  - const: PD_IRQB
+
+patternProperties:
+  "connector":
+type: object
+$ref: ../connector/usb-connector.yaml#
+description:
+  Properties for usb c connector.
+
+additionalProperties: false
+
+required:
+  - compatible
+  - interrupts-extended
+  - interrupt-names
+
+examples:
+  - |
+#include 
+#include 
+i2c0 {
+#address-cells = <1>;
+#size-cells = <0>;
+
+mt6360@34 {
+compatible = "mediatek,mt6360";
+reg = <0x34>;
+
+tcpc {
+compatible = "mediatek,mt6360-tcpc";
+interrupts-extended = < 3 IRQ_TYPE_LEVEL_LOW>;
+interrupt-names = "PD_IRQB";
+
+connector {
+compatible = "usb-c-connector";
+label = "USB-C";
+data-role = "dual";
+power-role = "dual";
+try-power-role = "sink";
+source-pdos = ;
+sink-pdos = ;
+op-sink-microwatt = <1000>;
+};
+};
+};
+};
+...
-- 
2.7.4



[PATCH v3 1/3] usb typec: mt6360: Add support for mt6360 Type-C driver

2020-08-27 Thread cy_huang
From: ChiYuan Huang 

Mediatek MT6360 is a multi-functional IC that includes USB Type-C.
It works with Type-C Port Controller Manager to provide USB PD
and USB Type-C functionalities.

v1 to v2
1. Add fix to Prevent the race condition from interrupt and tcpci port
unregister during module remove.

v2 to v3
1. Change comment style for the head of source code.
2. No need to print error for platform_get_irq_byname.
3. Fix tcpci_register_port check from IS_ERR_OR_NULL to IS_ERR.
4. Rename driver/Kconfig/Makefile form mt6360 to mt636x.
5. Rename DT binding documents from mt6360 to mt636x.

Signed-off-by: ChiYuan Huang 
---
 drivers/usb/typec/tcpm/Kconfig|   8 ++
 drivers/usb/typec/tcpm/Makefile   |   1 +
 drivers/usb/typec/tcpm/tcpci_mt6360.c | 212 ++
 3 files changed, 221 insertions(+)
 create mode 100644 drivers/usb/typec/tcpm/tcpci_mt6360.c

diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index fa3f393..58a64e1 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -27,6 +27,14 @@ config TYPEC_RT1711H
  Type-C Port Controller Manager to provide USB PD and USB
  Type-C functionalities.
 
+config TYPEC_MT6360
+   tristate "Mediatek MT6360 Type-C driver"
+   depends on MFD_MT6360
+   help
+ Mediatek MT6360 is a multi-functional IC that includes
+ USB Type-C. It works with Type-C Port Controller Manager
+ to provide USB PD and USB Type-C functionalities.
+
 endif # TYPEC_TCPCI
 
 config TYPEC_FUSB302
diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile
index a5ff6c8..7592ccb 100644
--- a/drivers/usb/typec/tcpm/Makefile
+++ b/drivers/usb/typec/tcpm/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_TYPEC_WCOVE)   += typec_wcove.o
 typec_wcove-y  := wcove.o
 obj-$(CONFIG_TYPEC_TCPCI)  += tcpci.o
 obj-$(CONFIG_TYPEC_RT1711H)+= tcpci_rt1711h.o
+obj-$(CONFIG_TYPEC_MT6360) += tcpci_mt6360.o
diff --git a/drivers/usb/typec/tcpm/tcpci_mt6360.c 
b/drivers/usb/typec/tcpm/tcpci_mt6360.c
new file mode 100644
index ..f1bd9e0
--- /dev/null
+++ b/drivers/usb/typec/tcpm/tcpci_mt6360.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: ChiYuan Huang 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tcpci.h"
+
+#define MT6360_REG_VCONNCTRL1  0x8C
+#define MT6360_REG_MODECTRL2   0x8F
+#define MT6360_REG_SWRESET 0xA0
+#define MT6360_REG_DEBCTRL10xA1
+#define MT6360_REG_DRPCTRL10xA2
+#define MT6360_REG_DRPCTRL20xA3
+#define MT6360_REG_I2CTORST0xBF
+#define MT6360_REG_RXCTRL2 0xCF
+#define MT6360_REG_CTDCTRL20xEC
+
+/* MT6360_REG_VCONNCTRL1 */
+#define MT6360_VCONNCL_ENABLE  BIT(0)
+/* MT6360_REG_RXCTRL2 */
+#define MT6360_OPEN40M_ENABLE  BIT(7)
+/* MT6360_REG_CTDCTRL2 */
+#define MT6360_RPONESHOT_ENABLEBIT(6)
+
+struct mt6360_tcpc_info {
+   struct tcpci_data tdata;
+   struct tcpci *tcpci;
+   struct device *dev;
+   int irq;
+};
+
+static inline int mt6360_tcpc_read16(struct regmap *regmap,
+unsigned int reg, u16 *val)
+{
+   return regmap_raw_read(regmap, reg, val, sizeof(u16));
+}
+
+static inline int mt6360_tcpc_write16(struct regmap *regmap,
+ unsigned int reg, u16 val)
+{
+   return regmap_raw_write(regmap, reg, , sizeof(u16));
+}
+
+static int mt6360_tcpc_init(struct tcpci *tcpci, struct tcpci_data *tdata)
+{
+   struct regmap *regmap = tdata->regmap;
+   int ret;
+
+   ret = regmap_write(regmap, MT6360_REG_SWRESET, 0x01);
+   if (ret)
+   return ret;
+
+   /* after reset command, wait 1~2ms to wait IC action */
+   usleep_range(1000, 2000);
+
+   /* write all alert to masked */
+   ret = mt6360_tcpc_write16(regmap, TCPC_ALERT_MASK, 0);
+   if (ret)
+   return ret;
+
+   /* config I2C timeout reset enable , and timeout to 200ms */
+   ret = regmap_write(regmap, MT6360_REG_I2CTORST, 0x8F);
+   if (ret)
+   return ret;
+
+   /* config CC Detect Debounce : 26.7*val us */
+   ret = regmap_write(regmap, MT6360_REG_DEBCTRL1, 0x10);
+   if (ret)
+   return ret;
+
+   /* DRP Toggle Cycle : 51.2 + 6.4*val ms */
+   ret = regmap_write(regmap, MT6360_REG_DRPCTRL1, 4);
+   if (ret)
+   return ret;
+
+   /* DRP Duyt Ctrl : dcSRC: /1024 */
+   ret = mt6360_tcpc_write16(regmap, MT6360_REG_DRPCTRL2, 330);
+   if (ret)
+   return ret;
+
+   /* Enable VCONN Current Limit function */
+   ret = regmap_update_bits(regmap, MT6360_REG_VCONNCTRL1, 
MT6360_VCONNCL_ENABLE,
+MT6360_VCONNCL_ENABLE);
+   if (ret)
+   return ret;
+
+   /* Enable cc open 40ms when pmic send vsysuv signal */
+   

[PATCH v3 2/3] usb typec: mt6360: Rename driver/Kconfig/Makefile from mt6360 to mt636x

2020-08-27 Thread cy_huang
From: ChiYuan Huang 

1. Rename file form tcpci_mt6360.c to tcpci_mt636x.c
2. Rename internal function from mt6360 to mt636x, except the register
definition.
3. Change Kconfig/Makefile from MT6360 to MT636X.

Signed-off-by: ChiYuan Huang 
---
 drivers/usb/typec/tcpm/Kconfig|   6 +-
 drivers/usb/typec/tcpm/Makefile   |   2 +-
 drivers/usb/typec/tcpm/tcpci_mt6360.c | 212 --
 drivers/usb/typec/tcpm/tcpci_mt636x.c | 212 ++
 4 files changed, 216 insertions(+), 216 deletions(-)
 delete mode 100644 drivers/usb/typec/tcpm/tcpci_mt6360.c
 create mode 100644 drivers/usb/typec/tcpm/tcpci_mt636x.c

diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index 58a64e1..c96141f 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -27,11 +27,11 @@ config TYPEC_RT1711H
  Type-C Port Controller Manager to provide USB PD and USB
  Type-C functionalities.
 
-config TYPEC_MT6360
-   tristate "Mediatek MT6360 Type-C driver"
+config TYPEC_MT636X
+   tristate "Mediatek MT636x Type-C driver"
depends on MFD_MT6360
help
- Mediatek MT6360 is a multi-functional IC that includes
+ Mediatek MT636x is a multi-functional IC that includes
  USB Type-C. It works with Type-C Port Controller Manager
  to provide USB PD and USB Type-C functionalities.
 
diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile
index 7592ccb..ccd7923 100644
--- a/drivers/usb/typec/tcpm/Makefile
+++ b/drivers/usb/typec/tcpm/Makefile
@@ -5,4 +5,4 @@ obj-$(CONFIG_TYPEC_WCOVE)   += typec_wcove.o
 typec_wcove-y  := wcove.o
 obj-$(CONFIG_TYPEC_TCPCI)  += tcpci.o
 obj-$(CONFIG_TYPEC_RT1711H)+= tcpci_rt1711h.o
-obj-$(CONFIG_TYPEC_MT6360) += tcpci_mt6360.o
+obj-$(CONFIG_TYPEC_MT636X) += tcpci_mt636x.o
diff --git a/drivers/usb/typec/tcpm/tcpci_mt6360.c 
b/drivers/usb/typec/tcpm/tcpci_mt6360.c
deleted file mode 100644
index f1bd9e0..
--- a/drivers/usb/typec/tcpm/tcpci_mt6360.c
+++ /dev/null
@@ -1,212 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2020 MediaTek Inc.
- *
- * Author: ChiYuan Huang 
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "tcpci.h"
-
-#define MT6360_REG_VCONNCTRL1  0x8C
-#define MT6360_REG_MODECTRL2   0x8F
-#define MT6360_REG_SWRESET 0xA0
-#define MT6360_REG_DEBCTRL10xA1
-#define MT6360_REG_DRPCTRL10xA2
-#define MT6360_REG_DRPCTRL20xA3
-#define MT6360_REG_I2CTORST0xBF
-#define MT6360_REG_RXCTRL2 0xCF
-#define MT6360_REG_CTDCTRL20xEC
-
-/* MT6360_REG_VCONNCTRL1 */
-#define MT6360_VCONNCL_ENABLE  BIT(0)
-/* MT6360_REG_RXCTRL2 */
-#define MT6360_OPEN40M_ENABLE  BIT(7)
-/* MT6360_REG_CTDCTRL2 */
-#define MT6360_RPONESHOT_ENABLEBIT(6)
-
-struct mt6360_tcpc_info {
-   struct tcpci_data tdata;
-   struct tcpci *tcpci;
-   struct device *dev;
-   int irq;
-};
-
-static inline int mt6360_tcpc_read16(struct regmap *regmap,
-unsigned int reg, u16 *val)
-{
-   return regmap_raw_read(regmap, reg, val, sizeof(u16));
-}
-
-static inline int mt6360_tcpc_write16(struct regmap *regmap,
- unsigned int reg, u16 val)
-{
-   return regmap_raw_write(regmap, reg, , sizeof(u16));
-}
-
-static int mt6360_tcpc_init(struct tcpci *tcpci, struct tcpci_data *tdata)
-{
-   struct regmap *regmap = tdata->regmap;
-   int ret;
-
-   ret = regmap_write(regmap, MT6360_REG_SWRESET, 0x01);
-   if (ret)
-   return ret;
-
-   /* after reset command, wait 1~2ms to wait IC action */
-   usleep_range(1000, 2000);
-
-   /* write all alert to masked */
-   ret = mt6360_tcpc_write16(regmap, TCPC_ALERT_MASK, 0);
-   if (ret)
-   return ret;
-
-   /* config I2C timeout reset enable , and timeout to 200ms */
-   ret = regmap_write(regmap, MT6360_REG_I2CTORST, 0x8F);
-   if (ret)
-   return ret;
-
-   /* config CC Detect Debounce : 26.7*val us */
-   ret = regmap_write(regmap, MT6360_REG_DEBCTRL1, 0x10);
-   if (ret)
-   return ret;
-
-   /* DRP Toggle Cycle : 51.2 + 6.4*val ms */
-   ret = regmap_write(regmap, MT6360_REG_DRPCTRL1, 4);
-   if (ret)
-   return ret;
-
-   /* DRP Duyt Ctrl : dcSRC: /1024 */
-   ret = mt6360_tcpc_write16(regmap, MT6360_REG_DRPCTRL2, 330);
-   if (ret)
-   return ret;
-
-   /* Enable VCONN Current Limit function */
-   ret = regmap_update_bits(regmap, MT6360_REG_VCONNCTRL1, 
MT6360_VCONNCL_ENABLE,
-MT6360_VCONNCL_ENABLE);
-   if (ret)
-   return ret;
-
-   /* Enable cc open 40ms when pmic send vsysuv signal */
-   ret = regmap_update_bits(regmap, MT6360_REG_RXCTRL2, 
MT6360_OPEN40M_ENABLE,
-

[PATCH v2 1/2] usb typec: mt6360: Add support for mt6360 Type-C driver

2020-08-26 Thread cy_huang
From: ChiYuan Huang 

Mediatek MT6360 is a multi-functional IC that includes USB Type-C.
It works with Type-C Port Controller Manager to provide USB PD
and USB Type-C functionalities.

Add fix to Prevent the race condition from interrupt and tcpci port unregister
during module remove.

Signed-off-by: ChiYuan Huang 
---
 drivers/usb/typec/tcpm/Kconfig|   8 ++
 drivers/usb/typec/tcpm/Makefile   |   1 +
 drivers/usb/typec/tcpm/tcpci_mt6360.c | 213 ++
 3 files changed, 222 insertions(+)
 create mode 100644 drivers/usb/typec/tcpm/tcpci_mt6360.c

diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index fa3f393..58a64e1 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -27,6 +27,14 @@ config TYPEC_RT1711H
  Type-C Port Controller Manager to provide USB PD and USB
  Type-C functionalities.
 
+config TYPEC_MT6360
+   tristate "Mediatek MT6360 Type-C driver"
+   depends on MFD_MT6360
+   help
+ Mediatek MT6360 is a multi-functional IC that includes
+ USB Type-C. It works with Type-C Port Controller Manager
+ to provide USB PD and USB Type-C functionalities.
+
 endif # TYPEC_TCPCI
 
 config TYPEC_FUSB302
diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile
index a5ff6c8..7592ccb 100644
--- a/drivers/usb/typec/tcpm/Makefile
+++ b/drivers/usb/typec/tcpm/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_TYPEC_WCOVE)   += typec_wcove.o
 typec_wcove-y  := wcove.o
 obj-$(CONFIG_TYPEC_TCPCI)  += tcpci.o
 obj-$(CONFIG_TYPEC_RT1711H)+= tcpci_rt1711h.o
+obj-$(CONFIG_TYPEC_MT6360) += tcpci_mt6360.o
diff --git a/drivers/usb/typec/tcpm/tcpci_mt6360.c 
b/drivers/usb/typec/tcpm/tcpci_mt6360.c
new file mode 100644
index ..a381b5d
--- /dev/null
+++ b/drivers/usb/typec/tcpm/tcpci_mt6360.c
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (C) 2020 MediaTek Inc.
+//
+// Author: ChiYuan Huang 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tcpci.h"
+
+#define MT6360_REG_VCONNCTRL1  0x8C
+#define MT6360_REG_MODECTRL2   0x8F
+#define MT6360_REG_SWRESET 0xA0
+#define MT6360_REG_DEBCTRL10xA1
+#define MT6360_REG_DRPCTRL10xA2
+#define MT6360_REG_DRPCTRL20xA3
+#define MT6360_REG_I2CTORST0xBF
+#define MT6360_REG_RXCTRL2 0xCF
+#define MT6360_REG_CTDCTRL20xEC
+
+/* MT6360_REG_VCONNCTRL1 */
+#define MT6360_VCONNCL_ENABLE  BIT(0)
+/* MT6360_REG_RXCTRL2 */
+#define MT6360_OPEN40M_ENABLE  BIT(7)
+/* MT6360_REG_CTDCTRL2 */
+#define MT6360_RPONESHOT_ENABLEBIT(6)
+
+struct mt6360_tcpc_info {
+   struct tcpci_data tdata;
+   struct tcpci *tcpci;
+   struct device *dev;
+   int irq;
+};
+
+static inline int mt6360_tcpc_read16(struct regmap *regmap,
+unsigned int reg, u16 *val)
+{
+   return regmap_raw_read(regmap, reg, val, sizeof(u16));
+}
+
+static inline int mt6360_tcpc_write16(struct regmap *regmap,
+ unsigned int reg, u16 val)
+{
+   return regmap_raw_write(regmap, reg, , sizeof(u16));
+}
+
+static int mt6360_tcpc_init(struct tcpci *tcpci, struct tcpci_data *tdata)
+{
+   struct regmap *regmap = tdata->regmap;
+   int ret;
+
+   ret = regmap_write(regmap, MT6360_REG_SWRESET, 0x01);
+   if (ret)
+   return ret;
+
+   /* after reset command, wait 1~2ms to wait IC action */
+   usleep_range(1000, 2000);
+
+   /* write all alert to masked */
+   ret = mt6360_tcpc_write16(regmap, TCPC_ALERT_MASK, 0);
+   if (ret)
+   return ret;
+
+   /* config I2C timeout reset enable , and timeout to 200ms */
+   ret = regmap_write(regmap, MT6360_REG_I2CTORST, 0x8F);
+   if (ret)
+   return ret;
+
+   /* config CC Detect Debounce : 26.7*val us */
+   ret = regmap_write(regmap, MT6360_REG_DEBCTRL1, 0x10);
+   if (ret)
+   return ret;
+
+   /* DRP Toggle Cycle : 51.2 + 6.4*val ms */
+   ret = regmap_write(regmap, MT6360_REG_DRPCTRL1, 4);
+   if (ret)
+   return ret;
+
+   /* DRP Duyt Ctrl : dcSRC: /1024 */
+   ret = mt6360_tcpc_write16(regmap, MT6360_REG_DRPCTRL2, 330);
+   if (ret)
+   return ret;
+
+   /* Enable VCONN Current Limit function */
+   ret = regmap_update_bits(regmap, MT6360_REG_VCONNCTRL1, 
MT6360_VCONNCL_ENABLE,
+MT6360_VCONNCL_ENABLE);
+   if (ret)
+   return ret;
+
+   /* Enable cc open 40ms when pmic send vsysuv signal */
+   ret = regmap_update_bits(regmap, MT6360_REG_RXCTRL2, 
MT6360_OPEN40M_ENABLE,
+MT6360_OPEN40M_ENABLE);
+   if (ret)
+   return ret;
+
+   /* Enable Rpdet oneshot detection */
+   ret = regmap_update_bits(regmap, MT6360_REG_CTDCTRL2, 

[PATCH v2 2/2] usb typec: mt6360: Add MT6360 Type-C DT binding documentation

2020-08-26 Thread cy_huang
From: ChiYuan Huang 

Add a devicetree binding documentation for the MT6360 Type-C driver.

Signed-off-by: ChiYuan Huang 
---
 .../bindings/usb/mediatek,mt6360-tcpc.yaml | 73 ++
 1 file changed, 73 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml 
b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
new file mode 100644
index ..9e8ab0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/mediatek,mt6360-tcpc.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: Mediatek MT6360 Type-C Port Switch and Power Delivery controller DT 
bindings
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  Mediatek MT6360 is a multi-functional device. It integrates charger, ADC, 
flash, RGB indicators,
+  regulators (BUCKs/LDOs), and TypeC Port Switch with Power Delivery 
controller.
+  This document only describes MT6360 Type-C Port Switch and Power Delivery 
controller.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt6360-tcpc
+
+  interrupts-extended:
+maxItems: 1
+
+  interrupt-names:
+items:
+  - const: PD_IRQB
+
+patternProperties:
+  "connector":
+type: object
+$ref: ../connector/usb-connector.yaml#
+description:
+  Properties for usb c connector.
+
+additionalProperties: false
+
+required:
+  - compatible
+  - interrupts-extended
+  - interrupt-names
+
+examples:
+  - |
+#include 
+#include 
+i2c0 {
+#address-cells = <1>;
+#size-cells = <0>;
+
+mt6360@34 {
+compatible = "mediatek,mt6360";
+reg = <0x34>;
+
+tcpc {
+compatible = "mediatek,mt6360-tcpc";
+interrupts-extended = < 3 IRQ_TYPE_LEVEL_LOW>;
+interrupt-names = "PD_IRQB";
+
+connector {
+compatible = "usb-c-connector";
+label = "USB-C";
+data-role = "dual";
+power-role = "dual";
+try-power-role = "sink";
+source-pdos = ;
+sink-pdos = ;
+op-sink-microwatt = <1000>;
+};
+};
+};
+};
+...
-- 
2.7.4



[PATCH v2 3/3] usb typec: mt6360: Prevent the race condition during module remove

2020-08-26 Thread cy_huang
From: ChiYuan Huang 

Prevent the race condition from interrupt and tcpci port unregister
during module remove.

Signed-off-by: ChiYuan Huang 
---
 drivers/usb/typec/tcpm/tcpci_mt6360.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/usb/typec/tcpm/tcpci_mt6360.c 
b/drivers/usb/typec/tcpm/tcpci_mt6360.c
index 6a28193..a381b5d 100644
--- a/drivers/usb/typec/tcpm/tcpci_mt6360.c
+++ b/drivers/usb/typec/tcpm/tcpci_mt6360.c
@@ -164,6 +164,7 @@ static int mt6360_tcpc_remove(struct platform_device *pdev)
 {
struct mt6360_tcpc_info *mti = platform_get_drvdata(pdev);
 
+   disable_irq(mti->irq);
tcpci_unregister_port(mti->tcpci);
return 0;
 }
-- 
2.7.4



[PATCH v2 1/3] usb typec: mt6360: Add support for mt6360 Type-C driver

2020-08-26 Thread cy_huang
From: ChiYuan Huang 

Mediatek MT6360 is a multi-functional IC that includes USB Type-C.
It works with Type-C Port Controller Manager to provide USB PD
and USB Type-C functionalities.

Signed-off-by: ChiYuan Huang 
---
 drivers/usb/typec/tcpm/Kconfig|   8 ++
 drivers/usb/typec/tcpm/Makefile   |   1 +
 drivers/usb/typec/tcpm/tcpci_mt6360.c | 212 ++
 3 files changed, 221 insertions(+)
 create mode 100644 drivers/usb/typec/tcpm/tcpci_mt6360.c

diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index fa3f393..58a64e1 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -27,6 +27,14 @@ config TYPEC_RT1711H
  Type-C Port Controller Manager to provide USB PD and USB
  Type-C functionalities.
 
+config TYPEC_MT6360
+   tristate "Mediatek MT6360 Type-C driver"
+   depends on MFD_MT6360
+   help
+ Mediatek MT6360 is a multi-functional IC that includes
+ USB Type-C. It works with Type-C Port Controller Manager
+ to provide USB PD and USB Type-C functionalities.
+
 endif # TYPEC_TCPCI
 
 config TYPEC_FUSB302
diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile
index a5ff6c8..7592ccb 100644
--- a/drivers/usb/typec/tcpm/Makefile
+++ b/drivers/usb/typec/tcpm/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_TYPEC_WCOVE)   += typec_wcove.o
 typec_wcove-y  := wcove.o
 obj-$(CONFIG_TYPEC_TCPCI)  += tcpci.o
 obj-$(CONFIG_TYPEC_RT1711H)+= tcpci_rt1711h.o
+obj-$(CONFIG_TYPEC_MT6360) += tcpci_mt6360.o
diff --git a/drivers/usb/typec/tcpm/tcpci_mt6360.c 
b/drivers/usb/typec/tcpm/tcpci_mt6360.c
new file mode 100644
index ..6a28193
--- /dev/null
+++ b/drivers/usb/typec/tcpm/tcpci_mt6360.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (C) 2020 MediaTek Inc.
+//
+// Author: ChiYuan Huang 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tcpci.h"
+
+#define MT6360_REG_VCONNCTRL1  0x8C
+#define MT6360_REG_MODECTRL2   0x8F
+#define MT6360_REG_SWRESET 0xA0
+#define MT6360_REG_DEBCTRL10xA1
+#define MT6360_REG_DRPCTRL10xA2
+#define MT6360_REG_DRPCTRL20xA3
+#define MT6360_REG_I2CTORST0xBF
+#define MT6360_REG_RXCTRL2 0xCF
+#define MT6360_REG_CTDCTRL20xEC
+
+/* MT6360_REG_VCONNCTRL1 */
+#define MT6360_VCONNCL_ENABLE  BIT(0)
+/* MT6360_REG_RXCTRL2 */
+#define MT6360_OPEN40M_ENABLE  BIT(7)
+/* MT6360_REG_CTDCTRL2 */
+#define MT6360_RPONESHOT_ENABLEBIT(6)
+
+struct mt6360_tcpc_info {
+   struct tcpci_data tdata;
+   struct tcpci *tcpci;
+   struct device *dev;
+   int irq;
+};
+
+static inline int mt6360_tcpc_read16(struct regmap *regmap,
+unsigned int reg, u16 *val)
+{
+   return regmap_raw_read(regmap, reg, val, sizeof(u16));
+}
+
+static inline int mt6360_tcpc_write16(struct regmap *regmap,
+ unsigned int reg, u16 val)
+{
+   return regmap_raw_write(regmap, reg, , sizeof(u16));
+}
+
+static int mt6360_tcpc_init(struct tcpci *tcpci, struct tcpci_data *tdata)
+{
+   struct regmap *regmap = tdata->regmap;
+   int ret;
+
+   ret = regmap_write(regmap, MT6360_REG_SWRESET, 0x01);
+   if (ret)
+   return ret;
+
+   /* after reset command, wait 1~2ms to wait IC action */
+   usleep_range(1000, 2000);
+
+   /* write all alert to masked */
+   ret = mt6360_tcpc_write16(regmap, TCPC_ALERT_MASK, 0);
+   if (ret)
+   return ret;
+
+   /* config I2C timeout reset enable , and timeout to 200ms */
+   ret = regmap_write(regmap, MT6360_REG_I2CTORST, 0x8F);
+   if (ret)
+   return ret;
+
+   /* config CC Detect Debounce : 26.7*val us */
+   ret = regmap_write(regmap, MT6360_REG_DEBCTRL1, 0x10);
+   if (ret)
+   return ret;
+
+   /* DRP Toggle Cycle : 51.2 + 6.4*val ms */
+   ret = regmap_write(regmap, MT6360_REG_DRPCTRL1, 4);
+   if (ret)
+   return ret;
+
+   /* DRP Duyt Ctrl : dcSRC: /1024 */
+   ret = mt6360_tcpc_write16(regmap, MT6360_REG_DRPCTRL2, 330);
+   if (ret)
+   return ret;
+
+   /* Enable VCONN Current Limit function */
+   ret = regmap_update_bits(regmap, MT6360_REG_VCONNCTRL1, 
MT6360_VCONNCL_ENABLE,
+MT6360_VCONNCL_ENABLE);
+   if (ret)
+   return ret;
+
+   /* Enable cc open 40ms when pmic send vsysuv signal */
+   ret = regmap_update_bits(regmap, MT6360_REG_RXCTRL2, 
MT6360_OPEN40M_ENABLE,
+MT6360_OPEN40M_ENABLE);
+   if (ret)
+   return ret;
+
+   /* Enable Rpdet oneshot detection */
+   ret = regmap_update_bits(regmap, MT6360_REG_CTDCTRL2, 
MT6360_RPONESHOT_ENABLE,
+MT6360_RPONESHOT_ENABLE);
+   if (ret)
+   return 

[PATCH v2 2/3] usb typec: mt6360: Add MT6360 Type-C DT binding documentation

2020-08-26 Thread cy_huang
From: ChiYuan Huang 

Add a devicetree binding documentation for the MT6360 Type-C driver.

Signed-off-by: ChiYuan Huang 
---
 .../bindings/usb/mediatek,mt6360-tcpc.yaml | 73 ++
 1 file changed, 73 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml 
b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
new file mode 100644
index ..9e8ab0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/mediatek,mt6360-tcpc.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: Mediatek MT6360 Type-C Port Switch and Power Delivery controller DT 
bindings
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  Mediatek MT6360 is a multi-functional device. It integrates charger, ADC, 
flash, RGB indicators,
+  regulators (BUCKs/LDOs), and TypeC Port Switch with Power Delivery 
controller.
+  This document only describes MT6360 Type-C Port Switch and Power Delivery 
controller.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt6360-tcpc
+
+  interrupts-extended:
+maxItems: 1
+
+  interrupt-names:
+items:
+  - const: PD_IRQB
+
+patternProperties:
+  "connector":
+type: object
+$ref: ../connector/usb-connector.yaml#
+description:
+  Properties for usb c connector.
+
+additionalProperties: false
+
+required:
+  - compatible
+  - interrupts-extended
+  - interrupt-names
+
+examples:
+  - |
+#include 
+#include 
+i2c0 {
+#address-cells = <1>;
+#size-cells = <0>;
+
+mt6360@34 {
+compatible = "mediatek,mt6360";
+reg = <0x34>;
+
+tcpc {
+compatible = "mediatek,mt6360-tcpc";
+interrupts-extended = < 3 IRQ_TYPE_LEVEL_LOW>;
+interrupt-names = "PD_IRQB";
+
+connector {
+compatible = "usb-c-connector";
+label = "USB-C";
+data-role = "dual";
+power-role = "dual";
+try-power-role = "sink";
+source-pdos = ;
+sink-pdos = ;
+op-sink-microwatt = <1000>;
+};
+};
+};
+};
+...
-- 
2.7.4



[PATCH 2/2] usb typec: mt6360: Add MT6360 Type-C DT binding documentation

2020-08-26 Thread cy_huang
From: ChiYuan Huang 

Add a devicetree binding documentation for the MT6360 Type-C driver.

Signed-off-by: ChiYuan Huang 
---
 .../bindings/usb/mediatek,mt6360-tcpc.yaml | 73 ++
 1 file changed, 73 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml 
b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
new file mode 100644
index ..9e8ab0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/mediatek,mt6360-tcpc.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/usb/mediatek,mt6360-tcpc.yaml#;
+$schema: "http://devicetree.org/meta-schemas/core.yaml#;
+
+title: Mediatek MT6360 Type-C Port Switch and Power Delivery controller DT 
bindings
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  Mediatek MT6360 is a multi-functional device. It integrates charger, ADC, 
flash, RGB indicators,
+  regulators (BUCKs/LDOs), and TypeC Port Switch with Power Delivery 
controller.
+  This document only describes MT6360 Type-C Port Switch and Power Delivery 
controller.
+
+properties:
+  compatible:
+enum:
+  - mediatek,mt6360-tcpc
+
+  interrupts-extended:
+maxItems: 1
+
+  interrupt-names:
+items:
+  - const: PD_IRQB
+
+patternProperties:
+  "connector":
+type: object
+$ref: ../connector/usb-connector.yaml#
+description:
+  Properties for usb c connector.
+
+additionalProperties: false
+
+required:
+  - compatible
+  - interrupts-extended
+  - interrupt-names
+
+examples:
+  - |
+#include 
+#include 
+i2c0 {
+#address-cells = <1>;
+#size-cells = <0>;
+
+mt6360@34 {
+compatible = "mediatek,mt6360";
+reg = <0x34>;
+
+tcpc {
+compatible = "mediatek,mt6360-tcpc";
+interrupts-extended = < 3 IRQ_TYPE_LEVEL_LOW>;
+interrupt-names = "PD_IRQB";
+
+connector {
+compatible = "usb-c-connector";
+label = "USB-C";
+data-role = "dual";
+power-role = "dual";
+try-power-role = "sink";
+source-pdos = ;
+sink-pdos = ;
+op-sink-microwatt = <1000>;
+};
+};
+};
+};
+...
-- 
2.7.4



[PATCH 1/2] usb typec: mt6360: Add support for mt6360 Type-C driver

2020-08-26 Thread cy_huang
From: ChiYuan Huang 

Mediatek MT6360 is a multi-functional IC that includes USB Type-C.
It works with Type-C Port Controller Manager to provide USB PD
and USB Type-C functionalities.

Signed-off-by: ChiYuan Huang 
---
 drivers/usb/typec/tcpm/Kconfig|   8 ++
 drivers/usb/typec/tcpm/Makefile   |   1 +
 drivers/usb/typec/tcpm/tcpci_mt6360.c | 212 ++
 3 files changed, 221 insertions(+)
 create mode 100644 drivers/usb/typec/tcpm/tcpci_mt6360.c

diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index fa3f393..58a64e1 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -27,6 +27,14 @@ config TYPEC_RT1711H
  Type-C Port Controller Manager to provide USB PD and USB
  Type-C functionalities.
 
+config TYPEC_MT6360
+   tristate "Mediatek MT6360 Type-C driver"
+   depends on MFD_MT6360
+   help
+ Mediatek MT6360 is a multi-functional IC that includes
+ USB Type-C. It works with Type-C Port Controller Manager
+ to provide USB PD and USB Type-C functionalities.
+
 endif # TYPEC_TCPCI
 
 config TYPEC_FUSB302
diff --git a/drivers/usb/typec/tcpm/Makefile b/drivers/usb/typec/tcpm/Makefile
index a5ff6c8..7592ccb 100644
--- a/drivers/usb/typec/tcpm/Makefile
+++ b/drivers/usb/typec/tcpm/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_TYPEC_WCOVE)   += typec_wcove.o
 typec_wcove-y  := wcove.o
 obj-$(CONFIG_TYPEC_TCPCI)  += tcpci.o
 obj-$(CONFIG_TYPEC_RT1711H)+= tcpci_rt1711h.o
+obj-$(CONFIG_TYPEC_MT6360) += tcpci_mt6360.o
diff --git a/drivers/usb/typec/tcpm/tcpci_mt6360.c 
b/drivers/usb/typec/tcpm/tcpci_mt6360.c
new file mode 100644
index ..6a28193
--- /dev/null
+++ b/drivers/usb/typec/tcpm/tcpci_mt6360.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (C) 2020 MediaTek Inc.
+//
+// Author: ChiYuan Huang 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tcpci.h"
+
+#define MT6360_REG_VCONNCTRL1  0x8C
+#define MT6360_REG_MODECTRL2   0x8F
+#define MT6360_REG_SWRESET 0xA0
+#define MT6360_REG_DEBCTRL10xA1
+#define MT6360_REG_DRPCTRL10xA2
+#define MT6360_REG_DRPCTRL20xA3
+#define MT6360_REG_I2CTORST0xBF
+#define MT6360_REG_RXCTRL2 0xCF
+#define MT6360_REG_CTDCTRL20xEC
+
+/* MT6360_REG_VCONNCTRL1 */
+#define MT6360_VCONNCL_ENABLE  BIT(0)
+/* MT6360_REG_RXCTRL2 */
+#define MT6360_OPEN40M_ENABLE  BIT(7)
+/* MT6360_REG_CTDCTRL2 */
+#define MT6360_RPONESHOT_ENABLEBIT(6)
+
+struct mt6360_tcpc_info {
+   struct tcpci_data tdata;
+   struct tcpci *tcpci;
+   struct device *dev;
+   int irq;
+};
+
+static inline int mt6360_tcpc_read16(struct regmap *regmap,
+unsigned int reg, u16 *val)
+{
+   return regmap_raw_read(regmap, reg, val, sizeof(u16));
+}
+
+static inline int mt6360_tcpc_write16(struct regmap *regmap,
+ unsigned int reg, u16 val)
+{
+   return regmap_raw_write(regmap, reg, , sizeof(u16));
+}
+
+static int mt6360_tcpc_init(struct tcpci *tcpci, struct tcpci_data *tdata)
+{
+   struct regmap *regmap = tdata->regmap;
+   int ret;
+
+   ret = regmap_write(regmap, MT6360_REG_SWRESET, 0x01);
+   if (ret)
+   return ret;
+
+   /* after reset command, wait 1~2ms to wait IC action */
+   usleep_range(1000, 2000);
+
+   /* write all alert to masked */
+   ret = mt6360_tcpc_write16(regmap, TCPC_ALERT_MASK, 0);
+   if (ret)
+   return ret;
+
+   /* config I2C timeout reset enable , and timeout to 200ms */
+   ret = regmap_write(regmap, MT6360_REG_I2CTORST, 0x8F);
+   if (ret)
+   return ret;
+
+   /* config CC Detect Debounce : 26.7*val us */
+   ret = regmap_write(regmap, MT6360_REG_DEBCTRL1, 0x10);
+   if (ret)
+   return ret;
+
+   /* DRP Toggle Cycle : 51.2 + 6.4*val ms */
+   ret = regmap_write(regmap, MT6360_REG_DRPCTRL1, 4);
+   if (ret)
+   return ret;
+
+   /* DRP Duyt Ctrl : dcSRC: /1024 */
+   ret = mt6360_tcpc_write16(regmap, MT6360_REG_DRPCTRL2, 330);
+   if (ret)
+   return ret;
+
+   /* Enable VCONN Current Limit function */
+   ret = regmap_update_bits(regmap, MT6360_REG_VCONNCTRL1, 
MT6360_VCONNCL_ENABLE,
+MT6360_VCONNCL_ENABLE);
+   if (ret)
+   return ret;
+
+   /* Enable cc open 40ms when pmic send vsysuv signal */
+   ret = regmap_update_bits(regmap, MT6360_REG_RXCTRL2, 
MT6360_OPEN40M_ENABLE,
+MT6360_OPEN40M_ENABLE);
+   if (ret)
+   return ret;
+
+   /* Enable Rpdet oneshot detection */
+   ret = regmap_update_bits(regmap, MT6360_REG_CTDCTRL2, 
MT6360_RPONESHOT_ENABLE,
+MT6360_RPONESHOT_ENABLE);
+   if (ret)
+   return 

[PATCH] regulator: rt4801: Fix W=1 build warning when CONFIG_OF=n

2020-08-23 Thread cy_huang
From: ChiYuan Huang 

Fix below warning when CONFIG_OF=n:

drivers/regulator/rt4801-regulator.c:206:34: warning: unused variable 
'rt4801_of_id' [-Wunused-const-variable]
  206 | static const struct of_device_id rt4801_of_id[] = {
  |  ^~~~

Signed-off-by: ChiYuan Huang 
Reported-by: kernel test robot 
---
 drivers/regulator/rt4801-regulator.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/regulator/rt4801-regulator.c 
b/drivers/regulator/rt4801-regulator.c
index 0ddc670..2055a9c 100644
--- a/drivers/regulator/rt4801-regulator.c
+++ b/drivers/regulator/rt4801-regulator.c
@@ -203,7 +203,7 @@ static int rt4801_probe(struct i2c_client *i2c)
return 0;
 }
 
-static const struct of_device_id rt4801_of_id[] = {
+static const struct of_device_id __maybe_unused rt4801_of_id[] = {
{ .compatible = "richtek,rt4801", },
{ },
 };
-- 
2.7.4



[PATCH 1/3] regulator: rt4801: Add support for RT4801 Display Bias regulator driver

2020-08-15 Thread cy_huang
From: ChiYuan Huang 

Adds support for the RT4801 DSV. It has two regulators (DSVP/DSVN) with
an I2C interface. DSVP/DSVN can provide the display panel module for the
positive/negative voltage range from (+/-)4V to (+/-)6V.

Signed-off-by: ChiYuan Huang 
---
 drivers/regulator/Kconfig|   7 ++
 drivers/regulator/Makefile   |   1 +
 drivers/regulator/rt4801-regulator.c | 223 +++
 3 files changed, 231 insertions(+)
 create mode 100644 drivers/regulator/rt4801-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index de17ef7..2786f11 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -894,6 +894,13 @@ config REGULATOR_RN5T618
 config REGULATOR_ROHM
tristate
 
+config REGULATOR_RT4801
+   tristate "Richtek RT4801 Regulators"
+   depends on I2C
+   help
+ This adds support for voltage regulators in Richtek RT4801 Display 
Bias IC.
+ The device supports two regulators (DSVP/DSVN).
+
 config REGULATOR_RT5033
tristate "Richtek RT5033 Regulators"
depends on MFD_RT5033
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index d8d3ecf..d091e52d 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -111,6 +111,7 @@ obj-$(CONFIG_REGULATOR_RC5T583)  += rc5t583-regulator.o
 obj-$(CONFIG_REGULATOR_RK808)   += rk808-regulator.o
 obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
 obj-$(CONFIG_REGULATOR_ROHM)   += rohm-regulator.o
+obj-$(CONFIG_REGULATOR_RT4801) += rt4801-regulator.o
 obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
diff --git a/drivers/regulator/rt4801-regulator.c 
b/drivers/regulator/rt4801-regulator.c
new file mode 100644
index ..0ddc670
--- /dev/null
+++ b/drivers/regulator/rt4801-regulator.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4801_REG_VOP 0x00
+#define RT4801_REG_VON 0x01
+#define RT4801_REG_APPS0x03
+
+#define VOUT_MASK  0x1F
+
+#define MIN_UV 400
+#define STEP_UV10
+#define MAX_UV 600
+#define N_VOLTAGES ((MAX_UV - MIN_UV) / STEP_UV + 1)
+
+#define DSV_OUT_POS0
+#define DSV_OUT_NEG1
+#define DSV_OUT_MAX2
+
+#define DSVP_ENABLEBIT(0)
+#define DSVN_ENABLEBIT(1)
+#define DSVALL_ENABLE  (DSVP_ENABLE | DSVN_ENABLE)
+
+struct rt4801_priv {
+   struct device *dev;
+   struct gpio_descs *enable_gpios;
+   unsigned int enable_flag;
+   unsigned int volt_sel[DSV_OUT_MAX];
+};
+
+static int rt4801_set_voltage_sel(struct regulator_dev *rdev, unsigned int 
selector)
+{
+   struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+   int id = rdev_get_id(rdev), ret;
+
+   if (priv->enable_flag & BIT(id)) {
+   ret = regulator_set_voltage_sel_regmap(rdev, selector);
+   if (ret)
+   return ret;
+   }
+
+   priv->volt_sel[id] = selector;
+   return 0;
+}
+
+static int rt4801_get_voltage_sel(struct regulator_dev *rdev)
+{
+   struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+   int id = rdev_get_id(rdev);
+
+   if (priv->enable_flag & BIT(id))
+   return regulator_get_voltage_sel_regmap(rdev);
+
+   return priv->volt_sel[id];
+}
+
+static int rt4801_enable(struct regulator_dev *rdev)
+{
+   struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+   struct gpio_descs *gpios = priv->enable_gpios;
+   int id = rdev_get_id(rdev), ret;
+
+   if (gpios->ndescs <= id) {
+   dev_warn(>dev, "no dedicated gpio can control\n");
+   goto bypass_gpio;
+   }
+
+   gpiod_set_value(gpios->desc[id], 1);
+
+bypass_gpio:
+   ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, 
priv->volt_sel[id]);
+   if (ret)
+   return ret;
+
+   priv->enable_flag |= BIT(id);
+   return 0;
+}
+
+static int rt4801_disable(struct regulator_dev *rdev)
+{
+   struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+   struct gpio_descs *gpios = priv->enable_gpios;
+   int id = rdev_get_id(rdev);
+
+   if (gpios->ndescs <= id) {
+   dev_warn(>dev, "no dedicated gpio can control\n");
+   goto bypass_gpio;
+   }
+
+   gpiod_set_value(gpios->desc[id], 0);
+
+bypass_gpio:
+   priv->enable_flag &= ~BIT(id);
+   return 0;
+}
+
+static int rt4801_is_enabled(struct regulator_dev *rdev)
+{
+   struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+   int id = rdev_get_id(rdev);
+
+   return !!(priv->enable_flag & BIT(id));
+}
+
+static const struct regulator_ops rt4801_regulator_ops = {
+   .list_voltage = regulator_list_voltage_linear,
+   .set_voltage_sel = rt4801_set_voltage_sel,
+   .get_voltage_sel = rt4801_get_voltage_sel,

[PATCH 3/3] regulator: rt4801: Fix the dt-binding document for dtc check.

2020-08-15 Thread cy_huang
From: ChiYuan Huang 

Fix the dt-binding document for dtc check.

Signed-off-by: ChiYuan Huang 
---
 .../devicetree/bindings/regulator/richtek,rt4801-regulator.yaml| 3 ---
 1 file changed, 3 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml 
b/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
index 28d30e2..fa075c6 100644
--- a/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
@@ -49,9 +49,6 @@ required:
   - compatible
   - reg
 
-additionalProperties:
-  - enable-gpios
-
 examples:
   - |
 i2c {
-- 
2.7.4



[PATCH 2/3] regulator: rt4801: Add DT binding documentation

2020-08-15 Thread cy_huang
From: ChiYuan Huang 

Add a devicetree binding documentation for the rt4801 regulator driver.

Signed-off-by: ChiYuan Huang 
---
 .../regulator/richtek,rt4801-regulator.yaml| 80 ++
 1 file changed, 80 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml

diff --git 
a/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml 
b/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
new file mode 100644
index ..28d30e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/richtek,rt4801-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4801 Display Bias regulators
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  Regulator nodes should be named to DSVP and DSVN. The
+  definition for each of these nodes is defined using the standard
+  binding for regulators at
+  Documentation/devicetree/bindings/regulator/regulator.txt.
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4801H/DS4801H-00.pdf
+
+#The valid names for RT4801 regulator nodes are:
+#DSVP, DSVN
+
+properties:
+  compatible:
+enum:
+  - richtek,rt4801
+
+  reg:
+maxItems: 1
+
+  enable-gpios:
+description: GPIOs to use to enable DSVP/DSVN regulator.
+  The first one is ENP to enable DSVP, and second one is ENM to enable 
DSVN.
+  Number of GPIO in the array list could be 1 or 2.
+  If only one gpio is specified, only one gpio used to control ENP/ENM.
+  Else both are spefied, DSVP/DSVN could be controlled individually.
+  Othersie, this property not specified. treat both as always-on regulator.
+minItems: 1
+maxItems: 2
+
+patternProperties:
+  "^DSV(P|N)$":
+type: object
+$ref: regulator.yaml#
+description:
+  Properties for single display bias regulator.
+
+required:
+  - compatible
+  - reg
+
+additionalProperties:
+  - enable-gpios
+
+examples:
+  - |
+i2c {
+#address-cells = <1>;
+#size-cells = <0>;
+
+rt4801@73 {
+compatible = "richtek,rt4801";
+reg = <0x73>;
+enable-gpios = < 2 0>, < 3 0>;
+
+dsvp: DSVP {
+regulator-name = "rt4801,dsvp";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <600>;
+regulator-boot-on;
+};
+dsvn: DSVN {
+regulator-name = "rt4801,dsvn";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <600>;
+regulator-boot-on;
+};
+
+};
+};
-- 
2.7.4



[PATCH 2/2] regulator: rt4801: Add DT binding documentation

2020-08-14 Thread cy_huang
From: ChiYuan Huang 

Add a devicetree binding documentation for the rt4801 regulator driver.

Signed-off-by: ChiYuan Huang 
---
 .../regulator/richtek,rt4801-regulator.yaml| 80 ++
 1 file changed, 80 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml

diff --git 
a/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml 
b/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
new file mode 100644
index ..28d30e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/richtek,rt4801-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4801 Display Bias regulators
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  Regulator nodes should be named to DSVP and DSVN. The
+  definition for each of these nodes is defined using the standard
+  binding for regulators at
+  Documentation/devicetree/bindings/regulator/regulator.txt.
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4801H/DS4801H-00.pdf
+
+#The valid names for RT4801 regulator nodes are:
+#DSVP, DSVN
+
+properties:
+  compatible:
+enum:
+  - richtek,rt4801
+
+  reg:
+maxItems: 1
+
+  enable-gpios:
+description: GPIOs to use to enable DSVP/DSVN regulator.
+  The first one is ENP to enable DSVP, and second one is ENM to enable 
DSVN.
+  Number of GPIO in the array list could be 1 or 2.
+  If only one gpio is specified, only one gpio used to control ENP/ENM.
+  Else both are spefied, DSVP/DSVN could be controlled individually.
+  Othersie, this property not specified. treat both as always-on regulator.
+minItems: 1
+maxItems: 2
+
+patternProperties:
+  "^DSV(P|N)$":
+type: object
+$ref: regulator.yaml#
+description:
+  Properties for single display bias regulator.
+
+required:
+  - compatible
+  - reg
+
+additionalProperties:
+  - enable-gpios
+
+examples:
+  - |
+i2c {
+#address-cells = <1>;
+#size-cells = <0>;
+
+rt4801@73 {
+compatible = "richtek,rt4801";
+reg = <0x73>;
+enable-gpios = < 2 0>, < 3 0>;
+
+dsvp: DSVP {
+regulator-name = "rt4801,dsvp";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <600>;
+regulator-boot-on;
+};
+dsvn: DSVN {
+regulator-name = "rt4801,dsvn";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <600>;
+regulator-boot-on;
+};
+
+};
+};
-- 
2.7.4



[PATCH 1/2] regulator: rt4801: Add support for RT4801 Display Bias regulator driver

2020-08-14 Thread cy_huang
From: ChiYuan Huang 

Adds support for the RT4801 DSV. It has two regulators (DSVP/DSVN) with
an I2C interface. DSVP/DSVN can provide the display panel module for the
positive/negative voltage range from (+/-)4V to (+/-)6V.

Signed-off-by: ChiYuan Huang 
---
 drivers/regulator/Kconfig|   7 ++
 drivers/regulator/Makefile   |   1 +
 drivers/regulator/rt4801-regulator.c | 223 +++
 3 files changed, 231 insertions(+)
 create mode 100644 drivers/regulator/rt4801-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index de17ef7..2786f11 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -894,6 +894,13 @@ config REGULATOR_RN5T618
 config REGULATOR_ROHM
tristate
 
+config REGULATOR_RT4801
+   tristate "Richtek RT4801 Regulators"
+   depends on I2C
+   help
+ This adds support for voltage regulators in Richtek RT4801 Display 
Bias IC.
+ The device supports two regulators (DSVP/DSVN).
+
 config REGULATOR_RT5033
tristate "Richtek RT5033 Regulators"
depends on MFD_RT5033
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index d8d3ecf..d091e52d 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -111,6 +111,7 @@ obj-$(CONFIG_REGULATOR_RC5T583)  += rc5t583-regulator.o
 obj-$(CONFIG_REGULATOR_RK808)   += rk808-regulator.o
 obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
 obj-$(CONFIG_REGULATOR_ROHM)   += rohm-regulator.o
+obj-$(CONFIG_REGULATOR_RT4801) += rt4801-regulator.o
 obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
diff --git a/drivers/regulator/rt4801-regulator.c 
b/drivers/regulator/rt4801-regulator.c
new file mode 100644
index ..0ddc670
--- /dev/null
+++ b/drivers/regulator/rt4801-regulator.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4801_REG_VOP 0x00
+#define RT4801_REG_VON 0x01
+#define RT4801_REG_APPS0x03
+
+#define VOUT_MASK  0x1F
+
+#define MIN_UV 400
+#define STEP_UV10
+#define MAX_UV 600
+#define N_VOLTAGES ((MAX_UV - MIN_UV) / STEP_UV + 1)
+
+#define DSV_OUT_POS0
+#define DSV_OUT_NEG1
+#define DSV_OUT_MAX2
+
+#define DSVP_ENABLEBIT(0)
+#define DSVN_ENABLEBIT(1)
+#define DSVALL_ENABLE  (DSVP_ENABLE | DSVN_ENABLE)
+
+struct rt4801_priv {
+   struct device *dev;
+   struct gpio_descs *enable_gpios;
+   unsigned int enable_flag;
+   unsigned int volt_sel[DSV_OUT_MAX];
+};
+
+static int rt4801_set_voltage_sel(struct regulator_dev *rdev, unsigned int 
selector)
+{
+   struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+   int id = rdev_get_id(rdev), ret;
+
+   if (priv->enable_flag & BIT(id)) {
+   ret = regulator_set_voltage_sel_regmap(rdev, selector);
+   if (ret)
+   return ret;
+   }
+
+   priv->volt_sel[id] = selector;
+   return 0;
+}
+
+static int rt4801_get_voltage_sel(struct regulator_dev *rdev)
+{
+   struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+   int id = rdev_get_id(rdev);
+
+   if (priv->enable_flag & BIT(id))
+   return regulator_get_voltage_sel_regmap(rdev);
+
+   return priv->volt_sel[id];
+}
+
+static int rt4801_enable(struct regulator_dev *rdev)
+{
+   struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+   struct gpio_descs *gpios = priv->enable_gpios;
+   int id = rdev_get_id(rdev), ret;
+
+   if (gpios->ndescs <= id) {
+   dev_warn(>dev, "no dedicated gpio can control\n");
+   goto bypass_gpio;
+   }
+
+   gpiod_set_value(gpios->desc[id], 1);
+
+bypass_gpio:
+   ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, 
priv->volt_sel[id]);
+   if (ret)
+   return ret;
+
+   priv->enable_flag |= BIT(id);
+   return 0;
+}
+
+static int rt4801_disable(struct regulator_dev *rdev)
+{
+   struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+   struct gpio_descs *gpios = priv->enable_gpios;
+   int id = rdev_get_id(rdev);
+
+   if (gpios->ndescs <= id) {
+   dev_warn(>dev, "no dedicated gpio can control\n");
+   goto bypass_gpio;
+   }
+
+   gpiod_set_value(gpios->desc[id], 0);
+
+bypass_gpio:
+   priv->enable_flag &= ~BIT(id);
+   return 0;
+}
+
+static int rt4801_is_enabled(struct regulator_dev *rdev)
+{
+   struct rt4801_priv *priv = rdev_get_drvdata(rdev);
+   int id = rdev_get_id(rdev);
+
+   return !!(priv->enable_flag & BIT(id));
+}
+
+static const struct regulator_ops rt4801_regulator_ops = {
+   .list_voltage = regulator_list_voltage_linear,
+   .set_voltage_sel = rt4801_set_voltage_sel,
+   .get_voltage_sel = rt4801_get_voltage_sel,

[PATCH] regulator: Add support for RT4801 Display Bias regulator driver

2020-08-13 Thread cy_huang
From: ChiYuan Huang 

Adds support for the RT4801 DSV. It has two regulators (DSVP/DSVN) with an I2C
interface. DSVP/DSVN can provide the display panel module for the 
positive/negative
voltage range from (+/-)4V to (+/-)6V.
---
 .../regulator/richtek,rt4801-regulator.yaml|  80 
 drivers/regulator/Kconfig  |   7 +
 drivers/regulator/Makefile |   1 +
 drivers/regulator/rt4801-regulator.c   | 223 +
 4 files changed, 311 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
 create mode 100644 drivers/regulator/rt4801-regulator.c

diff --git 
a/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml 
b/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
new file mode 100644
index ..28d30e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/richtek,rt4801-regulator.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/richtek,rt4801-regulator.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Richtek RT4801 Display Bias regulators
+
+maintainers:
+  - ChiYuan Huang 
+
+description: |
+  Regulator nodes should be named to DSVP and DSVN. The
+  definition for each of these nodes is defined using the standard
+  binding for regulators at
+  Documentation/devicetree/bindings/regulator/regulator.txt.
+  Datasheet is available at
+  https://www.richtek.com/assets/product_file/RT4801H/DS4801H-00.pdf
+
+#The valid names for RT4801 regulator nodes are:
+#DSVP, DSVN
+
+properties:
+  compatible:
+enum:
+  - richtek,rt4801
+
+  reg:
+maxItems: 1
+
+  enable-gpios:
+description: GPIOs to use to enable DSVP/DSVN regulator.
+  The first one is ENP to enable DSVP, and second one is ENM to enable 
DSVN.
+  Number of GPIO in the array list could be 1 or 2.
+  If only one gpio is specified, only one gpio used to control ENP/ENM.
+  Else both are spefied, DSVP/DSVN could be controlled individually.
+  Othersie, this property not specified. treat both as always-on regulator.
+minItems: 1
+maxItems: 2
+
+patternProperties:
+  "^DSV(P|N)$":
+type: object
+$ref: regulator.yaml#
+description:
+  Properties for single display bias regulator.
+
+required:
+  - compatible
+  - reg
+
+additionalProperties:
+  - enable-gpios
+
+examples:
+  - |
+i2c {
+#address-cells = <1>;
+#size-cells = <0>;
+
+rt4801@73 {
+compatible = "richtek,rt4801";
+reg = <0x73>;
+enable-gpios = < 2 0>, < 3 0>;
+
+dsvp: DSVP {
+regulator-name = "rt4801,dsvp";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <600>;
+regulator-boot-on;
+};
+dsvn: DSVN {
+regulator-name = "rt4801,dsvn";
+regulator-min-microvolt = <400>;
+regulator-max-microvolt = <600>;
+regulator-boot-on;
+};
+
+};
+};
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index de17ef7..2786f11 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -894,6 +894,13 @@ config REGULATOR_RN5T618
 config REGULATOR_ROHM
tristate
 
+config REGULATOR_RT4801
+   tristate "Richtek RT4801 Regulators"
+   depends on I2C
+   help
+ This adds support for voltage regulators in Richtek RT4801 Display 
Bias IC.
+ The device supports two regulators (DSVP/DSVN).
+
 config REGULATOR_RT5033
tristate "Richtek RT5033 Regulators"
depends on MFD_RT5033
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index d8d3ecf..d091e52d 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -111,6 +111,7 @@ obj-$(CONFIG_REGULATOR_RC5T583)  += rc5t583-regulator.o
 obj-$(CONFIG_REGULATOR_RK808)   += rk808-regulator.o
 obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
 obj-$(CONFIG_REGULATOR_ROHM)   += rohm-regulator.o
+obj-$(CONFIG_REGULATOR_RT4801) += rt4801-regulator.o
 obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
diff --git a/drivers/regulator/rt4801-regulator.c 
b/drivers/regulator/rt4801-regulator.c
new file mode 100644
index ..0ddc670
--- /dev/null
+++ b/drivers/regulator/rt4801-regulator.c
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RT4801_REG_VOP 0x00
+#define RT4801_REG_VON 0x01
+#define RT4801_REG_APPS0x03
+
+#define VOUT_MASK  0x1F
+
+#define MIN_UV 400
+#define STEP_UV10
+#define MAX_UV 600