summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/gpio-twl4030.c2
-rw-r--r--drivers/hwmon/da9052-hwmon.c285
-rw-r--r--drivers/iio/adc/twl4030-madc.c2
-rw-r--r--drivers/iio/adc/twl6030-gpadc.c2
-rw-r--r--drivers/input/keyboard/twl4030_keypad.c2
-rw-r--r--drivers/input/misc/dm355evm_keys.c2
-rw-r--r--drivers/input/misc/twl4030-pwrbutton.c2
-rw-r--r--drivers/input/misc/twl4030-vibra.c2
-rw-r--r--drivers/mfd/Kconfig4
-rw-r--r--drivers/mfd/da9052-core.c26
-rw-r--r--drivers/mfd/dm355evm_msp.c2
-rw-r--r--drivers/mfd/retu-mfd.c12
-rw-r--r--drivers/mfd/rk808.c147
-rw-r--r--drivers/mfd/tps6105x.c8
-rw-r--r--drivers/mfd/tps65010.c2
-rw-r--r--drivers/mfd/twl-core.c6
-rw-r--r--drivers/mfd/twl4030-audio.c2
-rw-r--r--drivers/mfd/twl4030-irq.c2
-rw-r--r--drivers/mfd/twl4030-power.c2
-rw-r--r--drivers/mfd/twl6030-irq.c2
-rw-r--r--drivers/phy/ti/phy-twl4030-usb.c2
-rw-r--r--drivers/pinctrl/Kconfig9
-rw-r--r--drivers/pinctrl/Makefile1
-rw-r--r--drivers/pinctrl/pinctrl-rk805.c493
-rw-r--r--drivers/power/supply/twl4030_charger.c2
-rw-r--r--drivers/pwm/pwm-twl-led.c2
-rw-r--r--drivers/pwm/pwm-twl.c2
-rw-r--r--drivers/regulator/Kconfig4
-rw-r--r--drivers/regulator/rk808-regulator.c130
-rw-r--r--drivers/regulator/twl-regulator.c2
-rw-r--r--drivers/regulator/twl6030-regulator.c2
-rw-r--r--drivers/rtc/rtc-dm355evm.c2
-rw-r--r--drivers/rtc/rtc-twl.c2
-rw-r--r--drivers/usb/host/ohci-omap.c2
-rw-r--r--drivers/usb/phy/phy-isp1301-omap.c2
-rw-r--r--drivers/usb/phy/phy-twl6030-usb.c2
-rw-r--r--drivers/video/backlight/pandora_bl.c2
-rw-r--r--drivers/video/fbdev/omap/lcd_h3.c2
-rw-r--r--drivers/watchdog/twl4030_wdt.c2
39 files changed, 1112 insertions, 67 deletions
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index 24f388ed46d4..9b511df5450e 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -35,7 +35,7 @@
#include <linux/of.h>
#include <linux/irqdomain.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
/*
* The GPIO "subchip" supports 18 GPIOs which can be configured as
diff --git a/drivers/hwmon/da9052-hwmon.c b/drivers/hwmon/da9052-hwmon.c
index c9832bfacfe5..97a62f5b9ea4 100644
--- a/drivers/hwmon/da9052-hwmon.c
+++ b/drivers/hwmon/da9052-hwmon.c
@@ -20,13 +20,19 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
+#include <linux/property.h>
#include <linux/mfd/da9052/da9052.h>
#include <linux/mfd/da9052/reg.h>
+#include <linux/regulator/consumer.h>
struct da9052_hwmon {
- struct da9052 *da9052;
- struct mutex hwmon_lock;
+ struct da9052 *da9052;
+ struct mutex hwmon_lock;
+ bool tsi_as_adc;
+ int tsiref_mv;
+ struct regulator *tsiref;
+ struct completion tsidone;
};
static const char * const input_names[] = {
@@ -37,6 +43,10 @@ static const char * const input_names[] = {
[DA9052_ADC_IN4] = "ADC IN4",
[DA9052_ADC_IN5] = "ADC IN5",
[DA9052_ADC_IN6] = "ADC IN6",
+ [DA9052_ADC_TSI_XP] = "ADC TS X+",
+ [DA9052_ADC_TSI_YP] = "ADC TS Y+",
+ [DA9052_ADC_TSI_XN] = "ADC TS X-",
+ [DA9052_ADC_TSI_YN] = "ADC TS Y-",
[DA9052_ADC_TJUNC] = "BATTERY JUNCTION TEMP",
[DA9052_ADC_VBBAT] = "BACK-UP BATTERY VOLTAGE",
};
@@ -59,6 +69,11 @@ static inline int vbbat_reg_to_mv(int value)
return DIV_ROUND_CLOSEST(value * 5000, 1023);
}
+static inline int input_tsireg_to_mv(struct da9052_hwmon *hwmon, int value)
+{
+ return DIV_ROUND_CLOSEST(value * hwmon->tsiref_mv, 1023);
+}
+
static inline int da9052_enable_vddout_channel(struct da9052 *da9052)
{
return da9052_reg_update(da9052, DA9052_ADC_CONT_REG,
@@ -154,6 +169,97 @@ static ssize_t da9052_read_misc_channel(struct device *dev,
return sprintf(buf, "%d\n", input_reg_to_mv(ret));
}
+static int da9052_request_tsi_read(struct da9052_hwmon *hwmon, int channel)
+{
+ u8 val = DA9052_TSICONTB_TSIMAN;
+
+ switch (channel) {
+ case DA9052_ADC_TSI_XP:
+ val |= DA9052_TSICONTB_TSIMUX_XP;
+ break;
+ case DA9052_ADC_TSI_YP:
+ val |= DA9052_TSICONTB_TSIMUX_YP;
+ break;
+ case DA9052_ADC_TSI_XN:
+ val |= DA9052_TSICONTB_TSIMUX_XN;
+ break;
+ case DA9052_ADC_TSI_YN:
+ val |= DA9052_TSICONTB_TSIMUX_YN;
+ break;
+ }
+
+ return da9052_reg_write(hwmon->da9052, DA9052_TSI_CONT_B_REG, val);
+}
+
+static int da9052_get_tsi_result(struct da9052_hwmon *hwmon, int channel)
+{
+ u8 regs[3];
+ int msb, lsb, err;
+
+ /* block read to avoid separation of MSB and LSB */
+ err = da9052_group_read(hwmon->da9052, DA9052_TSI_X_MSB_REG,
+ ARRAY_SIZE(regs), regs);
+ if (err)
+ return err;
+
+ switch (channel) {
+ case DA9052_ADC_TSI_XP:
+ case DA9052_ADC_TSI_XN:
+ msb = regs[0] << DA9052_TSILSB_TSIXL_BITS;
+ lsb = regs[2] & DA9052_TSILSB_TSIXL;
+ lsb >>= DA9052_TSILSB_TSIXL_SHIFT;
+ break;
+ case DA9052_ADC_TSI_YP:
+ case DA9052_ADC_TSI_YN:
+ msb = regs[1] << DA9052_TSILSB_TSIYL_BITS;
+ lsb = regs[2] & DA9052_TSILSB_TSIYL;
+ lsb >>= DA9052_TSILSB_TSIYL_SHIFT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return msb | lsb;
+}
+
+
+static ssize_t __da9052_read_tsi(struct device *dev, int channel)
+{
+ struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
+ int ret;
+
+ reinit_completion(&hwmon->tsidone);
+
+ ret = da9052_request_tsi_read(hwmon, channel);
+ if (ret < 0)
+ return ret;
+
+ /* Wait for an conversion done interrupt */
+ if (!wait_for_completion_timeout(&hwmon->tsidone,
+ msecs_to_jiffies(500)))
+ return -ETIMEDOUT;
+
+ return da9052_get_tsi_result(hwmon, channel);
+}
+
+static ssize_t da9052_read_tsi(struct device *dev,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
+ int channel = to_sensor_dev_attr(devattr)->index;
+ int ret;
+
+ mutex_lock(&hwmon->hwmon_lock);
+ ret = __da9052_read_tsi(dev, channel);
+ mutex_unlock(&hwmon->hwmon_lock);
+
+ if (ret < 0)
+ return ret;
+ else
+ return sprintf(buf, "%d\n", input_tsireg_to_mv(hwmon, ret));
+}
+
static ssize_t da9052_read_tjunc(struct device *dev,
struct device_attribute *devattr, char *buf)
{
@@ -196,43 +302,82 @@ static ssize_t show_label(struct device *dev,
input_names[to_sensor_dev_attr(devattr)->index]);
}
-static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, da9052_read_vddout, NULL,
+static umode_t da9052_channel_is_visible(struct kobject *kobj,
+ struct attribute *attr, int index)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct da9052_hwmon *hwmon = dev_get_drvdata(dev);
+ struct device_attribute *dattr = container_of(attr,
+ struct device_attribute, attr);
+ struct sensor_device_attribute *sattr = to_sensor_dev_attr(dattr);
+
+ if (!hwmon->tsi_as_adc) {
+ switch (sattr->index) {
+ case DA9052_ADC_TSI_XP:
+ case DA9052_ADC_TSI_YP:
+ case DA9052_ADC_TSI_XN:
+ case DA9052_ADC_TSI_YN:
+ return 0;
+ }
+ }
+
+ return attr->mode;
+}
+
+static SENSOR_DEVICE_ATTR(in0_input, 0444, da9052_read_vddout, NULL,
DA9052_ADC_VDDOUT);
-static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(in0_label, 0444, show_label, NULL,
DA9052_ADC_VDDOUT);
-static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, da9052_read_vbat, NULL,
+static SENSOR_DEVICE_ATTR(in3_input, 0444, da9052_read_vbat, NULL,
DA9052_ADC_VBAT);
-static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(in3_label, 0444, show_label, NULL,
DA9052_ADC_VBAT);
-static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, da9052_read_misc_channel, NULL,
+static SENSOR_DEVICE_ATTR(in4_input, 0444, da9052_read_misc_channel, NULL,
DA9052_ADC_IN4);
-static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(in4_label, 0444, show_label, NULL,
DA9052_ADC_IN4);
-static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, da9052_read_misc_channel, NULL,
+static SENSOR_DEVICE_ATTR(in5_input, 0444, da9052_read_misc_channel, NULL,
DA9052_ADC_IN5);
-static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(in5_label, 0444, show_label, NULL,
DA9052_ADC_IN5);
-static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, da9052_read_misc_channel, NULL,
+static SENSOR_DEVICE_ATTR(in6_input, 0444, da9052_read_misc_channel, NULL,
DA9052_ADC_IN6);
-static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(in6_label, 0444, show_label, NULL,
DA9052_ADC_IN6);
-static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, da9052_read_vbbat, NULL,
+static SENSOR_DEVICE_ATTR(in9_input, 0444, da9052_read_vbbat, NULL,
DA9052_ADC_VBBAT);
-static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(in9_label, 0444, show_label, NULL,
DA9052_ADC_VBBAT);
-static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, da9052_read_ich, NULL,
+static SENSOR_DEVICE_ATTR(in70_input, 0444, da9052_read_tsi, NULL,
+ DA9052_ADC_TSI_XP);
+static SENSOR_DEVICE_ATTR(in70_label, 0444, show_label, NULL,
+ DA9052_ADC_TSI_XP);
+static SENSOR_DEVICE_ATTR(in71_input, 0444, da9052_read_tsi, NULL,
+ DA9052_ADC_TSI_XN);
+static SENSOR_DEVICE_ATTR(in71_label, 0444, show_label, NULL,
+ DA9052_ADC_TSI_XN);
+static SENSOR_DEVICE_ATTR(in72_input, 0444, da9052_read_tsi, NULL,
+ DA9052_ADC_TSI_YP);
+static SENSOR_DEVICE_ATTR(in72_label, 0444, show_label, NULL,
+ DA9052_ADC_TSI_YP);
+static SENSOR_DEVICE_ATTR(in73_input, 0444, da9052_read_tsi, NULL,
+ DA9052_ADC_TSI_YN);
+static SENSOR_DEVICE_ATTR(in73_label, 0444, show_label, NULL,
+ DA9052_ADC_TSI_YN);
+
+static SENSOR_DEVICE_ATTR(curr1_input, 0444, da9052_read_ich, NULL,
DA9052_ADC_ICH);
-static SENSOR_DEVICE_ATTR(curr1_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(curr1_label, 0444, show_label, NULL,
DA9052_ADC_ICH);
-static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, da9052_read_tbat, NULL,
+static SENSOR_DEVICE_ATTR(temp2_input, 0444, da9052_read_tbat, NULL,
DA9052_ADC_TBAT);
-static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(temp2_label, 0444, show_label, NULL,
DA9052_ADC_TBAT);
-static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, da9052_read_tjunc, NULL,
+static SENSOR_DEVICE_ATTR(temp8_input, 0444, da9052_read_tjunc, NULL,
DA9052_ADC_TJUNC);
-static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, show_label, NULL,
+static SENSOR_DEVICE_ATTR(temp8_label, 0444, show_label, NULL,
DA9052_ADC_TJUNC);
static struct attribute *da9052_attrs[] = {
@@ -246,6 +391,14 @@ static struct attribute *da9052_attrs[] = {
&sensor_dev_attr_in5_label.dev_attr.attr,
&sensor_dev_attr_in6_input.dev_attr.attr,
&sensor_dev_attr_in6_label.dev_attr.attr,
+ &sensor_dev_attr_in70_input.dev_attr.attr,
+ &sensor_dev_attr_in70_label.dev_attr.attr,
+ &sensor_dev_attr_in71_input.dev_attr.attr,
+ &sensor_dev_attr_in71_label.dev_attr.attr,
+ &sensor_dev_attr_in72_input.dev_attr.attr,
+ &sensor_dev_attr_in72_label.dev_attr.attr,
+ &sensor_dev_attr_in73_input.dev_attr.attr,
+ &sensor_dev_attr_in73_label.dev_attr.attr,
&sensor_dev_attr_in9_input.dev_attr.attr,
&sensor_dev_attr_in9_label.dev_attr.attr,
&sensor_dev_attr_curr1_input.dev_attr.attr,
@@ -257,29 +410,117 @@ static struct attribute *da9052_attrs[] = {
NULL
};
-ATTRIBUTE_GROUPS(da9052);
+static const struct attribute_group da9052_group = {
+ .attrs = da9052_attrs,
+ .is_visible = da9052_channel_is_visible,
+};
+__ATTRIBUTE_GROUPS(da9052);
+
+static irqreturn_t da9052_tsi_datardy_irq(int irq, void *data)
+{
+ struct da9052_hwmon *hwmon = data;
+
+ complete(&hwmon->tsidone);
+ return IRQ_HANDLED;
+}
static int da9052_hwmon_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct da9052_hwmon *hwmon;
struct device *hwmon_dev;
+ int err;
hwmon = devm_kzalloc(dev, sizeof(struct da9052_hwmon), GFP_KERNEL);
if (!hwmon)
return -ENOMEM;
+ platform_set_drvdata(pdev, hwmon);
+
mutex_init(&hwmon->hwmon_lock);
hwmon->da9052 = dev_get_drvdata(pdev->dev.parent);
+ init_completion(&hwmon->tsidone);
+
+ hwmon->tsi_as_adc =
+ device_property_read_bool(pdev->dev.parent, "dlg,tsi-as-adc");
+
+ if (hwmon->tsi_as_adc) {
+ hwmon->tsiref = devm_regulator_get(pdev->dev.parent, "tsiref");
+ if (IS_ERR(hwmon->tsiref)) {
+ err = PTR_ERR(hwmon->tsiref);
+ dev_err(&pdev->dev, "failed to get tsiref: %d", err);
+ return err;
+ }
+
+ err = regulator_enable(hwmon->tsiref);
+ if (err)
+ return err;
+
+ hwmon->tsiref_mv = regulator_get_voltage(hwmon->tsiref);
+ if (hwmon->tsiref_mv < 0) {
+ err = hwmon->tsiref_mv;
+ goto exit_regulator;
+ }
+
+ /* convert from microvolt (DT) to millivolt (hwmon) */
+ hwmon->tsiref_mv /= 1000;
+
+ /* TSIREF limits from datasheet */
+ if (hwmon->tsiref_mv < 1800 || hwmon->tsiref_mv > 2600) {
+ dev_err(hwmon->da9052->dev, "invalid TSIREF voltage: %d",
+ hwmon->tsiref_mv);
+ err = -ENXIO;
+ goto exit_regulator;
+ }
+
+ /* disable touchscreen features */
+ da9052_reg_write(hwmon->da9052, DA9052_TSI_CONT_A_REG, 0x00);
+
+ err = da9052_request_irq(hwmon->da9052, DA9052_IRQ_TSIREADY,
+ "tsiready-irq", da9052_tsi_datardy_irq,
+ hwmon);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to register TSIRDY IRQ: %d",
+ err);
+ goto exit_regulator;
+ }
+ }
+
hwmon_dev = devm_hwmon_device_register_with_groups(dev, "da9052",
hwmon,
da9052_groups);
- return PTR_ERR_OR_ZERO(hwmon_dev);
+ err = PTR_ERR_OR_ZERO(hwmon_dev);
+ if (err)
+ goto exit_irq;
+
+ return 0;
+
+exit_irq:
+ if (hwmon->tsi_as_adc)
+ da9052_free_irq(hwmon->da9052, DA9052_IRQ_TSIREADY, hwmon);
+exit_regulator:
+ if (hwmon->tsiref)
+ regulator_disable(hwmon->tsiref);
+
+ return err;
+}
+
+static int da9052_hwmon_remove(struct platform_device *pdev)
+{
+ struct da9052_hwmon *hwmon = platform_get_drvdata(pdev);
+
+ if (hwmon->tsi_as_adc) {
+ da9052_free_irq(hwmon->da9052, DA9052_IRQ_TSIREADY, hwmon);
+ regulator_disable(hwmon->tsiref);
+ }
+
+ return 0;
}
static struct platform_driver da9052_hwmon_driver = {
.probe = da9052_hwmon_probe,
+ .remove = da9052_hwmon_remove,
.driver = {
.name = "da9052-hwmon",
},
diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c
index bd3d37fc2144..1edd99f0c5e5 100644
--- a/drivers/iio/adc/twl4030-madc.c
+++ b/drivers/iio/adc/twl4030-madc.c
@@ -35,7 +35,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/module.h>
#include <linux/stddef.h>
#include <linux/mutex.h>
diff --git a/drivers/iio/adc/twl6030-gpadc.c b/drivers/iio/adc/twl6030-gpadc.c
index becbb0aef232..bc0e60b9da45 100644
--- a/drivers/iio/adc/twl6030-gpadc.c
+++ b/drivers/iio/adc/twl6030-gpadc.c
@@ -33,7 +33,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c
index 39e72b3219d8..f9f98ef1d98e 100644
--- a/drivers/input/keyboard/twl4030_keypad.c
+++ b/drivers/input/keyboard/twl4030_keypad.c
@@ -30,7 +30,7 @@
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/platform_device.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/slab.h>
#include <linux/of.h>
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c
index bab256ef32b9..c803db64a376 100644
--- a/drivers/input/misc/dm355evm_keys.c
+++ b/drivers/input/misc/dm355evm_keys.c
@@ -15,7 +15,7 @@
#include <linux/platform_device.h>
#include <linux/interrupt.h>
-#include <linux/i2c/dm355evm_msp.h>
+#include <linux/mfd/dm355evm_msp.h>
#include <linux/module.h>
diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c
index 1c13005b228f..b307cca17022 100644
--- a/drivers/input/misc/twl4030-pwrbutton.c
+++ b/drivers/input/misc/twl4030-pwrbutton.c
@@ -27,7 +27,7 @@
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#define PWR_PWRON_IRQ (1 << 0)
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
index caa5a62c42fb..6c51d404874b 100644
--- a/drivers/input/misc/twl4030-vibra.c
+++ b/drivers/input/misc/twl4030-vibra.c
@@ -28,7 +28,7 @@
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/workqueue.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/mfd/twl4030-audio.h>
#include <linux/input.h>
#include <linux/slab.h>
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index fe76db945f46..7a01e70ac0ab 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -951,13 +951,13 @@ config MFD_RC5T583
different functionality of the device.
config MFD_RK808
- tristate "Rockchip RK808/RK818 Power Management Chip"
+ tristate "Rockchip RK805/RK808/RK818 Power Management Chip"
depends on I2C && OF
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
help
- If you say yes here you get support for the RK808 and RK818
+ If you say yes here you get support for the RK805, RK808 and RK818
Power Management chips.
This driver provides common support for accessing the device
through I2C interface. The device supports multiple sub-devices
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c
index a88c2065d8ab..a23a3a1c7061 100644
--- a/drivers/mfd/da9052-core.c
+++ b/drivers/mfd/da9052-core.c
@@ -18,6 +18,7 @@
#include <linux/mfd/core.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/property.h>
#include <linux/mfd/da9052/da9052.h>
#include <linux/mfd/da9052/pdata.h>
@@ -519,9 +520,6 @@ static const struct mfd_cell da9052_subdev_info[] = {
.name = "da9052-wled3",
},
{
- .name = "da9052-tsi",
- },
- {
.name = "da9052-bat",
},
{
@@ -529,6 +527,10 @@ static const struct mfd_cell da9052_subdev_info[] = {
},
};
+static const struct mfd_cell da9052_tsi_subdev_info[] = {
+ { .name = "da9052-tsi" },
+};
+
const struct regmap_config da9052_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -619,9 +621,27 @@ int da9052_device_init(struct da9052 *da9052, u8 chip_id)
goto err;
}
+ /*
+ * Check if touchscreen pins are used are analogue input instead
+ * of having a touchscreen connected to them. The analogue input
+ * functionality will be provided by hwmon driver (if enabled).
+ */
+ if (!device_property_read_bool(da9052->dev, "dlg,tsi-as-adc")) {
+ ret = mfd_add_devices(da9052->dev, PLATFORM_DEVID_AUTO,
+ da9052_tsi_subdev_info,
+ ARRAY_SIZE(da9052_tsi_subdev_info),
+ NULL, 0, NULL);
+ if (ret) {
+ dev_err(da9052->dev, "failed to add TSI subdev: %d\n",
+ ret);
+ goto err;
+ }
+ }
+
return 0;
err:
+ mfd_remove_devices(da9052->dev);
da9052_irq_exit(da9052);
return ret;
diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c
index 86eca614507b..2a2756709f22 100644
--- a/drivers/mfd/dm355evm_msp.c
+++ b/drivers/mfd/dm355evm_msp.c
@@ -18,7 +18,7 @@
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/i2c.h>
-#include <linux/i2c/dm355evm_msp.h>
+#include <linux/mfd/dm355evm_msp.h>
/*
diff --git a/drivers/mfd/retu-mfd.c b/drivers/mfd/retu-mfd.c
index d4c114abeb75..e7d27b7861c1 100644
--- a/drivers/mfd/retu-mfd.c
+++ b/drivers/mfd/retu-mfd.c
@@ -302,15 +302,23 @@ static int retu_remove(struct i2c_client *i2c)
}
static const struct i2c_device_id retu_id[] = {
- { "retu-mfd", 0 },
- { "tahvo-mfd", 0 },
+ { "retu", 0 },
+ { "tahvo", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, retu_id);
+static const struct of_device_id retu_of_match[] = {
+ { .compatible = "nokia,retu" },
+ { .compatible = "nokia,tahvo" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, retu_of_match);
+
static struct i2c_driver retu_driver = {
.driver = {
.name = "retu-mfd",
+ .of_match_table = retu_of_match,
},
.probe = retu_probe,
.remove = retu_remove,
diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c
index fd087cbb0bde..216fbf6adec9 100644
--- a/drivers/mfd/rk808.c
+++ b/drivers/mfd/rk808.c
@@ -70,6 +70,14 @@ static const struct regmap_config rk818_regmap_config = {
.volatile_reg = rk808_is_volatile_reg,
};
+static const struct regmap_config rk805_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = RK805_OFF_SOURCE_REG,
+ .cache_type = REGCACHE_RBTREE,
+ .volatile_reg = rk808_is_volatile_reg,
+};
+
static const struct regmap_config rk808_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -86,6 +94,34 @@ static struct resource rtc_resources[] = {
}
};
+static struct resource rk805_key_resources[] = {
+ {
+ .start = RK805_IRQ_PWRON_FALL,
+ .end = RK805_IRQ_PWRON_FALL,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = RK805_IRQ_PWRON_RISE,
+ .end = RK805_IRQ_PWRON_RISE,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static const struct mfd_cell rk805s[] = {
+ { .name = "rk808-clkout", },
+ { .name = "rk808-regulator", },
+ { .name = "rk805-pinctrl", },
+ {
+ .name = "rk808-rtc",
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resources = &rtc_resources[0],
+ },
+ { .name = "rk805-pwrkey",
+ .num_resources = ARRAY_SIZE(rk805_key_resources),
+ .resources = &rk805_key_resources[0],
+ },
+};
+
static const struct mfd_cell rk808s[] = {
{ .name = "rk808-clkout", },
{ .name = "rk808-regulator", },
@@ -106,6 +142,20 @@ static const struct mfd_cell rk818s[] = {
},
};
+static const struct rk808_reg_data rk805_pre_init_reg[] = {
+ {RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
+ RK805_BUCK1_2_ILMAX_4000MA},
+ {RK805_BUCK2_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
+ RK805_BUCK1_2_ILMAX_4000MA},
+ {RK805_BUCK3_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
+ RK805_BUCK3_ILMAX_3000MA},
+ {RK805_BUCK4_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
+ RK805_BUCK4_ILMAX_3500MA},
+ {RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA},
+ {RK805_GPIO_IO_POL_REG, SLP_SD_MSK, SLEEP_FUN},
+ {RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
+};
+
static const struct rk808_reg_data rk808_pre_init_reg[] = {
{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_150MA },
{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_200MA },
@@ -135,6 +185,41 @@ static const struct rk808_reg_data rk818_pre_init_reg[] = {
VB_LO_SEL_3500MV },
};
+static const struct regmap_irq rk805_irqs[] = {
+ [RK805_IRQ_PWRON_RISE] = {
+ .mask = RK805_IRQ_PWRON_RISE_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_VB_LOW] = {
+ .mask = RK805_IRQ_VB_LOW_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_PWRON] = {
+ .mask = RK805_IRQ_PWRON_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_PWRON_LP] = {
+ .mask = RK805_IRQ_PWRON_LP_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_HOTDIE] = {
+ .mask = RK805_IRQ_HOTDIE_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_RTC_ALARM] = {
+ .mask = RK805_IRQ_RTC_ALARM_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_RTC_PERIOD] = {
+ .mask = RK805_IRQ_RTC_PERIOD_MSK,
+ .reg_offset = 0,
+ },
+ [RK805_IRQ_PWRON_FALL] = {
+ .mask = RK805_IRQ_PWRON_FALL_MSK,
+ .reg_offset = 0,
+ },
+};
+
static const struct regmap_irq rk808_irqs[] = {
/* INT_STS */
[RK808_IRQ_VOUT_LO] = {
@@ -247,6 +332,17 @@ static const struct regmap_irq rk818_irqs[] = {
},
};
+static struct regmap_irq_chip rk805_irq_chip = {
+ .name = "rk805",
+ .irqs = rk805_irqs,
+ .num_irqs = ARRAY_SIZE(rk805_irqs),
+ .num_regs = 1,
+ .status_base = RK805_INT_STS_REG,
+ .mask_base = RK805_INT_STS_MSK_REG,
+ .ack_base = RK805_INT_STS_REG,
+ .init_ack_masked = true,
+};
+
static const struct regmap_irq_chip rk808_irq_chip = {
.name = "rk808",
.irqs = rk808_irqs,
@@ -272,6 +368,25 @@ static const struct regmap_irq_chip rk818_irq_chip = {
};
static struct i2c_client *rk808_i2c_client;
+
+static void rk805_device_shutdown(void)
+{
+ int ret;
+ struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
+
+ if (!rk808) {
+ dev_warn(&rk808_i2c_client->dev,
+ "have no rk805, so do nothing here\n");
+ return;
+ }
+
+ ret = regmap_update_bits(rk808->regmap,
+ RK805_DEV_CTRL_REG,
+ DEV_OFF, DEV_OFF);
+ if (ret)
+ dev_err(&rk808_i2c_client->dev, "power off error!\n");
+}
+
static void rk808_device_shutdown(void)
{
int ret;
@@ -309,6 +424,7 @@ static void rk818_device_shutdown(void)
}
static const struct of_device_id rk808_of_match[] = {
+ { .compatible = "rockchip,rk805" },
{ .compatible = "rockchip,rk808" },
{ .compatible = "rockchip,rk818" },
{ },
@@ -325,7 +441,7 @@ static int rk808_probe(struct i2c_client *client,
void (*pm_pwroff_fn)(void);
int nr_pre_init_regs;
int nr_cells;
- int pm_off = 0;
+ int pm_off = 0, msb, lsb;
int ret;
int i;
@@ -333,16 +449,34 @@ static int rk808_probe(struct i2c_client *client,
if (!rk808)
return -ENOMEM;
- rk808->variant = i2c_smbus_read_word_data(client, RK808_ID_MSB);
- if (rk808->variant < 0) {
- dev_err(&client->dev, "Failed to read the chip id at 0x%02x\n",
+ /* Read chip variant */
+ msb = i2c_smbus_read_byte_data(client, RK808_ID_MSB);
+ if (msb < 0) {
+ dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
RK808_ID_MSB);
- return rk808->variant;
+ return msb;
+ }
+
+ lsb = i2c_smbus_read_byte_data(client, RK808_ID_LSB);
+ if (lsb < 0) {
+ dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
+ RK808_ID_LSB);
+ return lsb;
}
- dev_dbg(&client->dev, "Chip id: 0x%x\n", (unsigned int)rk808->variant);
+ rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
+ dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
switch (rk808->variant) {
+ case RK805_ID:
+ rk808->regmap_cfg = &rk805_regmap_config;
+ rk808->regmap_irq_chip = &rk805_irq_chip;
+ pre_init_reg = rk805_pre_init_reg;
+ nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
+ cells = rk805s;
+ nr_cells = ARRAY_SIZE(rk805s);
+ pm_pwroff_fn = rk805_device_shutdown;
+ break;
case RK808_ID:
rk808->regmap_cfg = &rk808_regmap_config;
rk808->regmap_irq_chip = &rk808_irq_chip;
@@ -435,6 +569,7 @@ static int rk808_remove(struct i2c_client *client)
}
static const struct i2c_device_id rk808_ids[] = {
+ { "rk805" },
{ "rk808" },
{ "rk818" },
{ },
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c
index baa12ea666fb..187848c93779 100644
--- a/drivers/mfd/tps6105x.c
+++ b/drivers/mfd/tps6105x.c
@@ -173,9 +173,17 @@ static const struct i2c_device_id tps6105x_id[] = {
};
MODULE_DEVICE_TABLE(i2c, tps6105x_id);
+static const struct of_device_id tps6105x_of_match[] = {
+ { .compatible = "ti,tps61050" },
+ { .compatible = "ti,tps61052" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, tps6105x_of_match);
+
static struct i2c_driver tps6105x_driver = {
.driver = {
.name = "tps6105x",
+ .of_match_table = tps6105x_of_match,
},
.probe = tps6105x_probe,
.remove = tps6105x_remove,
diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c
index d829a6131f09..2ab67386b4ef 100644
--- a/drivers/mfd/tps65010.c
+++ b/drivers/mfd/tps65010.c
@@ -32,7 +32,7 @@
#include <linux/mutex.h>
#include <linux/platform_device.h>
-#include <linux/i2c/tps65010.h>
+#include <linux/mfd/tps65010.h>
#include <linux/gpio/driver.h>
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index c64615dca2bd..2a09dde4ca6e 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -44,7 +44,7 @@
#include <linux/regulator/machine.h>
#include <linux/i2c.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
/* Register descriptions for audio */
#include <linux/mfd/twl4030-audio.h>
@@ -173,7 +173,7 @@ static struct twl_private *twl_priv;
static struct twl_mapping twl4030_map[] = {
/*
* NOTE: don't change this table without updating the
- * <linux/i2c/twl.h> defines for TWL4030_MODULE_*
+ * <linux/mfd/twl.h> defines for TWL4030_MODULE_*
* so they continue to match the order in this table.
*/
@@ -344,7 +344,7 @@ static const struct regmap_config twl4030_regmap_config[4] = {
static struct twl_mapping twl6030_map[] = {
/*
* NOTE: don't change this table without updating the
- * <linux/i2c/twl.h> defines for TWL4030_MODULE_*
+ * <linux/mfd/twl.h> defines for TWL4030_MODULE_*
* so they continue to match the order in this table.
*/
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c
index 0a1606480023..da16bf45fab4 100644
--- a/drivers/mfd/twl4030-audio.c
+++ b/drivers/mfd/twl4030-audio.c
@@ -30,7 +30,7 @@
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_platform.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/mfd/core.h>
#include <linux/mfd/twl4030-audio.h>
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index 378c02d43bf7..b16c16f194fd 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -33,7 +33,7 @@
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/irqdomain.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include "twl-core.h"
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index f4b2c29d77e3..6b36932263ba 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -25,7 +25,7 @@
#include <linux/module.h>
#include <linux/pm.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c
index 53574508a613..e3ec8dfa9f1e 100644
--- a/drivers/mfd/twl6030-irq.c
+++ b/drivers/mfd/twl6030-irq.c
@@ -35,7 +35,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kthread.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/platform_device.h>
#include <linux/suspend.h>
#include <linux/of.h>
diff --git a/drivers/phy/ti/phy-twl4030-usb.c b/drivers/phy/ti/phy-twl4030-usb.c
index 2990b3965460..28f49902760d 100644
--- a/drivers/phy/ti/phy-twl4030-usb.c
+++ b/drivers/phy/ti/phy-twl4030-usb.c
@@ -36,7 +36,7 @@
#include <linux/pm_runtime.h>
#include <linux/usb/musb.h>
#include <linux/usb/ulpi.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/regulator/consumer.h>
#include <linux/err.h>
#include <linux/slab.h>
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index e14b46c7b37f..124fe2c09c61 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -331,6 +331,15 @@ config PINCTRL_INGENIC
select GENERIC_PINMUX_FUNCTIONS
select REGMAP_MMIO
+config PINCTRL_RK805
+ tristate "Pinctrl and GPIO driver for RK805 PMIC"
+ depends on MFD_RK808
+ select GPIOLIB
+ select PINMUX
+ select GENERIC_PINCONF
+ help
+ This selects the pinctrl driver for RK805.
+
source "drivers/pinctrl/aspeed/Kconfig"
source "drivers/pinctrl/bcm/Kconfig"
source "drivers/pinctrl/berlin/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 2bc641d62400..792ffaeaf340 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o
obj-$(CONFIG_PINCTRL_INGENIC) += pinctrl-ingenic.o
+obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-y += bcm/
diff --git a/drivers/pinctrl/pinctrl-rk805.c b/drivers/pinctrl/pinctrl-rk805.c
new file mode 100644
index 000000000000..b0bfd3082a1b
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-rk805.c
@@ -0,0 +1,493 @@
+/*
+ * Pinctrl driver for Rockchip RK805 PMIC
+ *
+ * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * Author: Joseph Chen <chenjh@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Based on the pinctrl-as3722 driver
+ */
+
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mfd/rk808.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+
+#include "core.h"
+#include "pinconf.h"
+#include "pinctrl-utils.h"
+
+struct rk805_pin_function {
+ const char *name;
+ const char *const *groups;
+ unsigned int ngroups;
+ int mux_option;
+};
+
+struct rk805_pin_group {
+ const char *name;
+ const unsigned int pins[1];
+ unsigned int npins;
+};
+
+/*
+ * @reg: gpio setting register;
+ * @fun_mask: functions select mask value, when set is gpio;
+ * @dir_mask: input or output mask value, when set is output, otherwise input;
+ * @val_mask: gpio set value, when set is level high, otherwise low;
+ *
+ * Different PMIC has different pin features, belowing 3 mask members are not
+ * all necessary for every PMIC. For example, RK805 has 2 pins that can be used
+ * as output only GPIOs, so func_mask and dir_mask are not needed. RK816 has 1
+ * pin that can be used as TS/GPIO, so fun_mask, dir_mask and val_mask are all
+ * necessary.
+ */
+struct rk805_pin_config {
+ u8 reg;
+ u8 fun_msk;
+ u8 dir_msk;
+ u8 val_msk;
+};
+
+struct rk805_pctrl_info {
+ struct rk808 *rk808;
+ struct device *dev;
+ struct pinctrl_dev *pctl;
+ struct gpio_chip gpio_chip;
+ struct pinctrl_desc pinctrl_desc;
+ const struct rk805_pin_function *functions;
+ unsigned int num_functions;
+ const struct rk805_pin_group *groups;
+ int num_pin_groups;
+ const struct pinctrl_pin_desc *pins;
+ unsigned int num_pins;
+ struct rk805_pin_config *pin_cfg;
+};
+
+enum rk805_pinmux_option {
+ RK805_PINMUX_GPIO,
+};
+
+enum {
+ RK805_GPIO0,
+ RK805_GPIO1,
+};
+
+static const char *const rk805_gpio_groups[] = {
+ "gpio0",
+ "gpio1",
+};
+
+/* RK805: 2 output only GPIOs */
+static const struct pinctrl_pin_desc rk805_pins_desc[] = {
+ PINCTRL_PIN(RK805_GPIO0, "gpio0"),
+ PINCTRL_PIN(RK805_GPIO1, "gpio1"),
+};
+
+static const struct rk805_pin_function rk805_pin_functions[] = {
+ {
+ .name = "gpio",
+ .groups = rk805_gpio_groups,
+ .ngroups = ARRAY_SIZE(rk805_gpio_groups),
+ .mux_option = RK805_PINMUX_GPIO,
+ },
+};
+
+static const struct rk805_pin_group rk805_pin_groups[] = {
+ {
+ .name = "gpio0",
+ .pins = { RK805_GPIO0 },
+ .npins = 1,
+ },
+ {
+ .name = "gpio1",
+ .pins = { RK805_GPIO1 },
+ .npins = 1,
+ },
+};
+
+#define RK805_GPIO0_VAL_MSK BIT(0)
+#define RK805_GPIO1_VAL_MSK BIT(1)
+
+static struct rk805_pin_config rk805_gpio_cfgs[] = {
+ {
+ .reg = RK805_OUT_REG,
+ .val_msk = RK805_GPIO0_VAL_MSK,
+ },
+ {
+ .reg = RK805_OUT_REG,
+ .val_msk = RK805_GPIO1_VAL_MSK,
+ },
+};
+
+/* generic gpio chip */
+static int rk805_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+ struct rk805_pctrl_info *pci = gpiochip_get_data(chip);
+ int ret, val;
+
+ ret = regmap_read(pci->rk808->regmap, pci->pin_cfg[offset].reg, &val);
+ if (ret) {
+ dev_err(pci->dev, "get gpio%d value failed\n", offset);
+ return ret;
+ }
+
+ return !!(val & pci->pin_cfg[offset].val_msk);
+}
+
+static void rk805_gpio_set(struct gpio_chip *chip,
+ unsigned int offset,
+ int value)
+{
+ struct rk805_pctrl_info *pci = gpiochip_get_data(chip);
+ int ret;
+
+ ret = regmap_update_bits(pci->rk808->regmap,
+ pci->pin_cfg[offset].reg,
+ pci->pin_cfg[offset].val_msk,
+ value ? pci->pin_cfg[offset].val_msk : 0);
+ if (ret)
+ dev_err(pci->dev, "set gpio%d value %d failed\n",
+ offset, value);
+}
+
+static int rk805_gpio_direction_input(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ return pinctrl_gpio_direction_input(chip->base + offset);
+}
+
+static int rk805_gpio_direction_output(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ rk805_gpio_set(chip, offset, value);
+ return pinctrl_gpio_direction_output(chip->base + offset);
+}
+
+static int rk805_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+ struct rk805_pctrl_info *pci = gpiochip_get_data(chip);
+ unsigned int val;
+ int ret;
+
+ /* default output*/
+ if (!pci->pin_cfg[offset].dir_msk)
+ return 0;
+
+ ret = regmap_read(pci->rk808->regmap,
+ pci->pin_cfg[offset].reg,
+ &val);
+ if (ret) {
+ dev_err(pci->dev, "get gpio%d direction failed\n", offset);
+ return ret;
+ }
+
+ return !(val & pci->pin_cfg[offset].dir_msk);
+}
+
+static struct gpio_chip rk805_gpio_chip = {
+ .label = "rk805-gpio",
+ .request = gpiochip_generic_request,
+ .free = gpiochip_generic_free,
+ .get_direction = rk805_gpio_get_direction,
+ .get = rk805_gpio_get,
+ .set = rk805_gpio_set,
+ .direction_input = rk805_gpio_direction_input,
+ .direction_output = rk805_gpio_direction_output,
+ .can_sleep = true,
+ .base = -1,
+ .owner = THIS_MODULE,
+};
+
+/* generic pinctrl */
+static int rk805_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+
+ return pci->num_pin_groups;
+}
+
+static const char *rk805_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned int group)
+{
+ struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+
+ return pci->groups[group].name;
+}
+
+static int rk805_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned int group,
+ const unsigned int **pins,
+ unsigned int *num_pins)
+{
+ struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+
+ *pins = pci->groups[group].pins;
+ *num_pins = pci->groups[group].npins;
+
+ return 0;
+}
+
+static const struct pinctrl_ops rk805_pinctrl_ops = {
+ .get_groups_count = rk805_pinctrl_get_groups_count,
+ .get_group_name = rk805_pinctrl_get_group_name,
+ .get_group_pins = rk805_pinctrl_get_group_pins,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+ .dt_free_map = pinctrl_utils_free_map,
+};
+
+static int rk805_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+ struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+
+ return pci->num_functions;
+}
+
+static const char *rk805_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+ unsigned int function)
+{
+ struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+
+ return pci->functions[function].name;
+}
+
+static int rk805_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
+ unsigned int function,
+ const char *const **groups,
+ unsigned int *const num_groups)
+{
+ struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+
+ *groups = pci->functions[function].groups;
+ *num_groups = pci->functions[function].ngroups;
+
+ return 0;
+}
+
+static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+ unsigned int offset,
+ int mux)
+{
+ struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+ int ret;
+
+ if (!pci->pin_cfg[offset].fun_msk)
+ return 0;
+
+ if (mux == RK805_PINMUX_GPIO) {
+ ret = regmap_update_bits(pci->rk808->regmap,
+ pci->pin_cfg[offset].reg,
+ pci->pin_cfg[offset].fun_msk,
+ pci->pin_cfg[offset].fun_msk);
+ if (ret) {
+ dev_err(pci->dev, "set gpio%d GPIO failed\n", offset);
+ return ret;
+ }
+ } else {
+ dev_err(pci->dev, "Couldn't find function mux %d\n", mux);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
+ unsigned int function,
+ unsigned int group)
+{
+ struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+ int mux = pci->functions[function].mux_option;
+ int offset = group;
+
+ return _rk805_pinctrl_set_mux(pctldev, offset, mux);
+}
+
+static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned int offset, bool input)
+{
+ struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+ int ret;
+
+ /* switch to gpio function */
+ ret = _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO);
+ if (ret) {
+ dev_err(pci->dev, "set gpio%d mux failed\n", offset);
+ return ret;
+ }
+
+ /* set direction */
+ if (!pci->pin_cfg[offset].dir_msk)
+ return 0;
+
+ ret = regmap_update_bits(pci->rk808->regmap,
+ pci->pin_cfg[offset].reg,
+ pci->pin_cfg[offset].dir_msk,
+ input ? 0 : pci->pin_cfg[offset].dir_msk);
+ if (ret) {
+ dev_err(pci->dev, "set gpio%d direction failed\n", offset);
+ return ret;
+ }
+
+ return ret;
+}
+
+static const struct pinmux_ops rk805_pinmux_ops = {
+ .get_functions_count = rk805_pinctrl_get_funcs_count,
+ .get_function_name = rk805_pinctrl_get_func_name,
+ .get_function_groups = rk805_pinctrl_get_func_groups,
+ .set_mux = rk805_pinctrl_set_mux,
+ .gpio_set_direction = rk805_pmx_gpio_set_direction,
+};
+
+static int rk805_pinconf_get(struct pinctrl_dev *pctldev,
+ unsigned int pin, unsigned long *config)
+{
+ struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+ enum pin_config_param param = pinconf_to_config_param(*config);
+ u32 arg = 0;
+
+ switch (param) {
+ case PIN_CONFIG_OUTPUT:
+ arg = rk805_gpio_get(&pci->gpio_chip, pin);
+ break;
+ default:
+ dev_err(pci->dev, "Properties not supported\n");
+ return -ENOTSUPP;
+ }
+
+ *config = pinconf_to_config_packed(param, (u16)arg);
+
+ return 0;
+}
+
+static int rk805_pinconf_set(struct pinctrl_dev *pctldev,
+ unsigned int pin, unsigned long *configs,
+ unsigned int num_configs)
+{
+ struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
+ enum pin_config_param param;
+ u32 i, arg = 0;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_OUTPUT:
+ rk805_gpio_set(&pci->gpio_chip, pin, arg);
+ rk805_pmx_gpio_set_direction(pctldev, NULL, pin, false);
+ break;
+ default:
+ dev_err(pci->dev, "Properties not supported\n");
+ return -ENOTSUPP;
+ }
+ }
+
+ return 0;
+}
+
+static const struct pinconf_ops rk805_pinconf_ops = {
+ .pin_config_get = rk805_pinconf_get,
+ .pin_config_set = rk805_pinconf_set,
+};
+
+static struct pinctrl_desc rk805_pinctrl_desc = {
+ .name = "rk805-pinctrl",
+ .pctlops = &rk805_pinctrl_ops,
+ .pmxops = &rk805_pinmux_ops,
+ .confops = &rk805_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+static int rk805_pinctrl_probe(struct platform_device *pdev)
+{
+ struct rk805_pctrl_info *pci;
+ int ret;
+
+ pci = devm_kzalloc(&pdev->dev, sizeof(*pci), GFP_KERNEL);
+ if (!pci)
+ return -ENOMEM;
+
+ pci->dev = &pdev->dev;
+ pci->dev->of_node = pdev->dev.parent->of_node;
+ pci->rk808 = dev_get_drvdata(pdev->dev.parent);
+
+ pci->pinctrl_desc = rk805_pinctrl_desc;
+ pci->gpio_chip = rk805_gpio_chip;
+ pci->gpio_chip.parent = &pdev->dev;
+ pci->gpio_chip.of_node = pdev->dev.parent->of_node;
+
+ platform_set_drvdata(pdev, pci);
+
+ switch (pci->rk808->variant) {
+ case RK805_ID:
+ pci->pins = rk805_pins_desc;
+ pci->num_pins = ARRAY_SIZE(rk805_pins_desc);
+ pci->functions = rk805_pin_functions;
+ pci->num_functions = ARRAY_SIZE(rk805_pin_functions);
+ pci->groups = rk805_pin_groups;
+ pci->num_pin_groups = ARRAY_SIZE(rk805_pin_groups);
+ pci->pinctrl_desc.pins = rk805_pins_desc;
+ pci->pinctrl_desc.npins = ARRAY_SIZE(rk805_pins_desc);
+ pci->pin_cfg = rk805_gpio_cfgs;
+ pci->gpio_chip.ngpio = ARRAY_SIZE(rk805_gpio_cfgs);
+ break;
+ default:
+ dev_err(&pdev->dev, "unsupported RK805 ID %lu\n",
+ pci->rk808->variant);
+ return -EINVAL;
+ }
+
+ /* Add gpio chip */
+ ret = devm_gpiochip_add_data(&pdev->dev, &pci->gpio_chip, pci);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Couldn't add gpiochip\n");
+ return ret;
+ }
+
+ /* Add pinctrl */
+ pci->pctl = devm_pinctrl_register(&pdev->dev, &pci->pinctrl_desc, pci);
+ if (IS_ERR(pci->pctl)) {
+ dev_err(&pdev->dev, "Couldn't add pinctrl\n");
+ return PTR_ERR(pci->pctl);
+ }
+
+ /* Add pin range */
+ ret = gpiochip_add_pin_range(&pci->gpio_chip, dev_name(&pdev->dev),
+ 0, 0, pci->gpio_chip.ngpio);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Couldn't add gpiochip pin range\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct platform_driver rk805_pinctrl_driver = {
+ .probe = rk805_pinctrl_probe,
+ .driver = {
+ .name = "rk805-pinctrl",
+ },
+};
+module_platform_driver(rk805_pinctrl_driver);
+
+MODULE_DESCRIPTION("RK805 pin control and GPIO driver");
+MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/power/supply/twl4030_charger.c b/drivers/power/supply/twl4030_charger.c
index 9dff1b4b85fc..a5915f498eea 100644
--- a/drivers/power/supply/twl4030_charger.c
+++ b/drivers/power/supply/twl4030_charger.c
@@ -18,7 +18,7 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/power_supply.h>
#include <linux/notifier.h>
#include <linux/usb/otg.h>
diff --git a/drivers/pwm/pwm-twl-led.c b/drivers/pwm/pwm-twl-led.c
index 21eff991d0e3..01153622778b 100644
--- a/drivers/pwm/pwm-twl-led.c
+++ b/drivers/pwm/pwm-twl-led.c
@@ -24,7 +24,7 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/slab.h>
/*
diff --git a/drivers/pwm/pwm-twl.c b/drivers/pwm/pwm-twl.c
index 9de617b76680..b7a45be99815 100644
--- a/drivers/pwm/pwm-twl.c
+++ b/drivers/pwm/pwm-twl.c
@@ -21,7 +21,7 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/slab.h>
/*
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 99b9362331b5..008ab58cd19b 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -687,11 +687,11 @@ config REGULATOR_RC5T583
outputs which can be controlled by i2c communication.
config REGULATOR_RK808
- tristate "Rockchip RK808/RK818 Power regulators"
+ tristate "Rockchip RK805/RK808/RK818 Power regulators"
depends on MFD_RK808
help
Select this option to enable the power regulator of ROCKCHIP
- PMIC RK808 and RK818.
+ PMIC RK805,RK808 and RK818.
This driver supports the control of different power rails of device
through regulator interface. The device supports multiple DCDC/LDO
outputs which can be controlled by i2c communication.
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index a16d81420612..213b68743cc8 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -65,6 +65,27 @@
/* max steps for increase voltage of Buck1/2, equal 100mv*/
#define MAX_STEPS_ONE_TIME 8
+#define RK805_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \
+ _vmask, _ereg, _emask, _etime) \
+ [_id] = { \
+ .name = (_match), \
+ .supply_name = (_supply), \
+ .of_match = of_match_ptr(_match), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .type = REGULATOR_VOLTAGE, \
+ .id = (_id), \
+ .n_voltages = (((_max) - (_min)) / (_step) + 1), \
+ .owner = THIS_MODULE, \
+ .min_uV = (_min) * 1000, \
+ .uV_step = (_step) * 1000, \
+ .vsel_reg = (_vreg), \
+ .vsel_mask = (_vmask), \
+ .enable_reg = (_ereg), \
+ .enable_mask = (_emask), \
+ .enable_time = (_etime), \
+ .ops = &rk805_reg_ops, \
+ }
+
#define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \
_vmask, _ereg, _emask, _etime) \
[_id] = { \
@@ -298,6 +319,28 @@ static int rk808_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
sel);
}
+static int rk805_set_suspend_enable(struct regulator_dev *rdev)
+{
+ unsigned int reg;
+
+ reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
+
+ return regmap_update_bits(rdev->regmap, reg,
+ rdev->desc->enable_mask,
+ rdev->desc->enable_mask);
+}
+
+static int rk805_set_suspend_disable(struct regulator_dev *rdev)
+{
+ unsigned int reg;
+
+ reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
+
+ return regmap_update_bits(rdev->regmap, reg,
+ rdev->desc->enable_mask,
+ 0);
+}
+
static int rk808_set_suspend_enable(struct regulator_dev *rdev)
{
unsigned int reg;
@@ -320,6 +363,27 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
rdev->desc->enable_mask);
}
+static struct regulator_ops rk805_reg_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .map_voltage = regulator_map_voltage_linear,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .set_suspend_voltage = rk808_set_suspend_voltage,
+ .set_suspend_enable = rk805_set_suspend_enable,
+ .set_suspend_disable = rk805_set_suspend_disable,
+};
+
+static struct regulator_ops rk805_switch_ops = {
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .set_suspend_enable = rk805_set_suspend_enable,
+ .set_suspend_disable = rk805_set_suspend_disable,
+};
+
static struct regulator_ops rk808_buck1_2_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
@@ -369,6 +433,68 @@ static struct regulator_ops rk808_switch_ops = {
.set_suspend_disable = rk808_set_suspend_disable,
};
+static const struct regulator_desc rk805_reg[] = {
+ {
+ .name = "DCDC_REG1",
+ .supply_name = "vcc1",
+ .of_match = of_match_ptr("DCDC_REG1"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = RK805_ID_DCDC1,
+ .ops = &rk805_reg_ops,
+ .type = REGULATOR_VOLTAGE,
+ .min_uV = 712500,
+ .uV_step = 12500,
+ .n_voltages = 64,
+ .vsel_reg = RK805_BUCK1_ON_VSEL_REG,
+ .vsel_mask = RK818_BUCK_VSEL_MASK,
+ .enable_reg = RK805_DCDC_EN_REG,
+ .enable_mask = BIT(0),
+ .owner = THIS_MODULE,
+ }, {
+ .name = "DCDC_REG2",
+ .supply_name = "vcc2",
+ .of_match = of_match_ptr("DCDC_REG2"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = RK805_ID_DCDC2,
+ .ops = &rk805_reg_ops,
+ .type = REGULATOR_VOLTAGE,
+ .min_uV = 712500,
+ .uV_step = 12500,
+ .n_voltages = 64,
+ .vsel_reg = RK805_BUCK2_ON_VSEL_REG,
+ .vsel_mask = RK818_BUCK_VSEL_MASK,
+ .enable_reg = RK805_DCDC_EN_REG,
+ .enable_mask = BIT(1),
+ .owner = THIS_MODULE,
+ }, {
+ .name = "DCDC_REG3",
+ .supply_name = "vcc3",
+ .of_match = of_match_ptr("DCDC_REG3"),
+ .regulators_node = of_match_ptr("regulators"),
+ .id = RK805_ID_DCDC3,
+ .ops = &rk805_switch_ops,
+ .type = REGULATOR_VOLTAGE,
+ .n_voltages = 1,
+ .enable_reg = RK805_DCDC_EN_REG,
+ .enable_mask = BIT(2),
+ .owner = THIS_MODULE,
+ },
+
+ RK805_DESC(RK805_ID_DCDC4, "DCDC_REG4", "vcc4", 800, 3400, 100,
+ RK805_BUCK4_ON_VSEL_REG, RK818_BUCK4_VSEL_MASK,
+ RK805_DCDC_EN_REG, BIT(3), 0),
+
+ RK805_DESC(RK805_ID_LDO1, "LDO_REG1", "vcc5", 800, 3400, 100,
+ RK805_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK805_LDO_EN_REG,
+ BIT(0), 400),
+ RK805_DESC(RK805_ID_LDO2, "LDO_REG2", "vcc5", 800, 3400, 100,
+ RK805_LDO2_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK805_LDO_EN_REG,
+ BIT(1), 400),
+ RK805_DESC(RK805_ID_LDO3, "LDO_REG3", "vcc6", 800, 3400, 100,
+ RK805_LDO3_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK805_LDO_EN_REG,
+ BIT(2), 400),
+};
+
static const struct regulator_desc rk808_reg[] = {
{
.name = "DCDC_REG1",
@@ -625,6 +751,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pdata);
switch (rk808->variant) {
+ case RK805_ID:
+ regulators = rk805_reg;
+ nregulators = RK805_NUM_REGULATORS;
+ break;
case RK808_ID:
regulators = rk808_reg;
nregulators = RK808_NUM_REGULATORS;
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index 6c9ec84121bd..a4456db5849d 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -20,7 +20,7 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/delay.h>
/*
diff --git a/drivers/regulator/twl6030-regulator.c b/drivers/regulator/twl6030-regulator.c
index 56aada387887..219cbd910dbf 100644
--- a/drivers/regulator/twl6030-regulator.c
+++ b/drivers/regulator/twl6030-regulator.c
@@ -21,7 +21,7 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/delay.h>
struct twlreg_info {
diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c
index f225cd873ff6..97d8259b9494 100644
--- a/drivers/rtc/rtc-dm355evm.c
+++ b/drivers/rtc/rtc-dm355evm.c
@@ -13,7 +13,7 @@
#include <linux/rtc.h>
#include <linux/platform_device.h>
-#include <linux/i2c/dm355evm_msp.h>
+#include <linux/mfd/dm355evm_msp.h>
#include <linux/module.h>
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index c18c39212ce6..3472e79f2b17 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -31,7 +31,7 @@
#include <linux/interrupt.h>
#include <linux/of.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
enum twl_class {
TWL_4030 = 0,
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index a4d814b7f380..91393ec7d850 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -53,7 +53,7 @@
#define DRIVER_DESC "OHCI OMAP driver"
#ifdef CONFIG_TPS65010
-#include <linux/i2c/tps65010.h>
+#include <linux/mfd/tps65010.h>
#else
#define LOW 0
diff --git a/drivers/usb/phy/phy-isp1301-omap.c b/drivers/usb/phy/phy-isp1301-omap.c
index 042c5a8fd423..c6052c814bcc 100644
--- a/drivers/usb/phy/phy-isp1301-omap.c
+++ b/drivers/usb/phy/phy-isp1301-omap.c
@@ -96,7 +96,7 @@ struct isp1301 {
#if IS_REACHABLE(CONFIG_TPS65010)
-#include <linux/i2c/tps65010.h>
+#include <linux/mfd/tps65010.h>
#else
diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c
index 628b600b02b1..b5dc077ed7d3 100644
--- a/drivers/usb/phy/phy-twl6030-usb.c
+++ b/drivers/usb/phy/phy-twl6030-usb.c
@@ -28,7 +28,7 @@
#include <linux/usb/musb.h>
#include <linux/usb/phy_companion.h>
#include <linux/phy/omap_usb.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/regulator/consumer.h>
#include <linux/err.h>
#include <linux/slab.h>
diff --git a/drivers/video/backlight/pandora_bl.c b/drivers/video/backlight/pandora_bl.c
index 5d8bb8b20183..a186bc677c7d 100644
--- a/drivers/video/backlight/pandora_bl.c
+++ b/drivers/video/backlight/pandora_bl.c
@@ -16,7 +16,7 @@
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/backlight.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#include <linux/err.h>
#define TWL_PWM0_ON 0x00
diff --git a/drivers/video/fbdev/omap/lcd_h3.c b/drivers/video/fbdev/omap/lcd_h3.c
index 9d2da146813e..796f4634c4c6 100644
--- a/drivers/video/fbdev/omap/lcd_h3.c
+++ b/drivers/video/fbdev/omap/lcd_h3.c
@@ -21,7 +21,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/i2c/tps65010.h>
+#include <linux/mfd/tps65010.h>
#include <linux/gpio.h>
#include "omapfb.h"
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c
index 9bf3cc0f3961..569fe85e52da 100644
--- a/drivers/watchdog/twl4030_wdt.c
+++ b/drivers/watchdog/twl4030_wdt.c
@@ -24,7 +24,7 @@
#include <linux/kernel.h>
#include <linux/watchdog.h>
#include <linux/platform_device.h>
-#include <linux/i2c/twl.h>
+#include <linux/mfd/twl.h>
#define TWL4030_WATCHDOG_CFG_REG_OFFS 0x3