aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2015-07-23 12:42:00 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2015-07-23 12:42:00 +1000
commitf83de9b1b98f3d292c31792d7234afd51f567b50 (patch)
treed39ddff4790b781c8eaf1675604da22a6f7a665f
parentfe8a337c949f7591e1c3ca64e7e11a9a374250c5 (diff)
parentd57fda46ced767950f6dd45bd574c1f11b9fc5a9 (diff)
Merge remote-tracking branch 'regulator/for-next'
-rw-r--r--Documentation/devicetree/bindings/mfd/rk808.txt8
-rw-r--r--Documentation/devicetree/bindings/regulator/da9210.txt4
-rw-r--r--Documentation/devicetree/bindings/regulator/da9211.txt32
-rw-r--r--Documentation/devicetree/bindings/regulator/max8973-regulator.txt6
-rw-r--r--Documentation/devicetree/bindings/regulator/pwm-regulator.txt65
-rw-r--r--drivers/extcon/extcon-max77693.c94
-rw-r--r--drivers/extcon/extcon-max77843.c66
-rw-r--r--drivers/input/misc/max77693-haptic.c1
-rw-r--r--drivers/input/misc/max77843-haptic.c3
-rw-r--r--drivers/leds/leds-max77693.c1
-rw-r--r--drivers/mfd/max77693.c31
-rw-r--r--drivers/mfd/max77843.c20
-rw-r--r--drivers/power/max77693_charger.c1
-rw-r--r--drivers/regulator/88pm800.c236
-rw-r--r--drivers/regulator/Kconfig22
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/act8865-regulator.c1
-rw-r--r--drivers/regulator/core.c33
-rw-r--r--drivers/regulator/da9062-regulator.c1
-rw-r--r--drivers/regulator/da9210-regulator.c76
-rw-r--r--drivers/regulator/da9211-regulator.c41
-rw-r--r--drivers/regulator/da9211-regulator.h18
-rw-r--r--drivers/regulator/isl6271a-regulator.c1
-rw-r--r--drivers/regulator/isl9305.c1
-rw-r--r--drivers/regulator/lp3971.c1
-rw-r--r--drivers/regulator/lp3972.c1
-rw-r--r--drivers/regulator/lp872x.c1
-rw-r--r--drivers/regulator/ltc3589.c3
-rw-r--r--drivers/regulator/max1586.c1
-rw-r--r--drivers/regulator/max77693.c161
-rw-r--r--drivers/regulator/max77843.c201
-rw-r--r--drivers/regulator/max8660.c1
-rw-r--r--drivers/regulator/max8973-regulator.c74
-rw-r--r--drivers/regulator/pfuze100-regulator.c1
-rw-r--r--drivers/regulator/pwm-regulator.c160
-rw-r--r--drivers/regulator/qcom_spmi-regulator.c3
-rw-r--r--drivers/regulator/rk808-regulator.c212
-rw-r--r--drivers/regulator/s2mps11.c14
-rw-r--r--drivers/regulator/tps51632-regulator.c1
-rw-r--r--drivers/regulator/tps62360-regulator.c1
-rw-r--r--drivers/regulator/tps65023-regulator.c1
-rw-r--r--include/linux/mfd/max77693-common.h49
-rw-r--r--include/linux/mfd/max77693-private.h134
-rw-r--r--include/linux/mfd/max77843-private.h174
-rw-r--r--include/linux/regulator/consumer.h6
-rw-r--r--include/linux/regulator/da9211.h19
46 files changed, 1185 insertions, 797 deletions
diff --git a/Documentation/devicetree/bindings/mfd/rk808.txt b/Documentation/devicetree/bindings/mfd/rk808.txt
index 9e6e2592e5c8..4ca6aab4273a 100644
--- a/Documentation/devicetree/bindings/mfd/rk808.txt
+++ b/Documentation/devicetree/bindings/mfd/rk808.txt
@@ -24,6 +24,10 @@ Optional properties:
- vcc10-supply: The input supply for LDO_REG6
- vcc11-supply: The input supply for LDO_REG8
- vcc12-supply: The input supply for SWITCH_REG2
+- dvs-gpios: buck1/2 can be controlled by gpio dvs, this is GPIO specifiers
+ for 2 host gpio's used for dvs. The format of the gpio specifier depends in
+ the gpio controller. If DVS GPIOs aren't present, voltage changes will happen
+ very quickly with no slow ramp time.
Regulators: All the regulators of RK808 to be instantiated shall be
listed in a child node named 'regulators'. Each regulator is represented
@@ -55,7 +59,9 @@ Example:
interrupt-parent = <&gpio0>;
interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
- pinctrl-0 = <&pmic_int>;
+ pinctrl-0 = <&pmic_int &dvs_1 &dvs_2>;
+ dvs-gpios = <&gpio7 11 GPIO_ACTIVE_HIGH>,
+ <&gpio7 15 GPIO_ACTIVE_HIGH>;
reg = <0x1b>;
rockchip,system-power-controller;
wakeup-source;
diff --git a/Documentation/devicetree/bindings/regulator/da9210.txt b/Documentation/devicetree/bindings/regulator/da9210.txt
index 3297c53cb915..7aa9b1fa6b21 100644
--- a/Documentation/devicetree/bindings/regulator/da9210.txt
+++ b/Documentation/devicetree/bindings/regulator/da9210.txt
@@ -5,6 +5,10 @@ Required properties:
- compatible: must be "dlg,da9210"
- reg: the i2c slave address of the regulator. It should be 0x68.
+Optional properties:
+
+- interrupts: a reference to the DA9210 interrupt, if available.
+
Any standard regulator properties can be used to configure the single da9210
DCDC.
diff --git a/Documentation/devicetree/bindings/regulator/da9211.txt b/Documentation/devicetree/bindings/regulator/da9211.txt
index eb618907c7de..c620493e8dbe 100644
--- a/Documentation/devicetree/bindings/regulator/da9211.txt
+++ b/Documentation/devicetree/bindings/regulator/da9211.txt
@@ -1,7 +1,7 @@
-* Dialog Semiconductor DA9211/DA9213 Voltage Regulator
+* Dialog Semiconductor DA9211/DA9213/DA9215 Voltage Regulator
Required properties:
-- compatible: "dlg,da9211" or "dlg,da9213".
+- compatible: "dlg,da9211" or "dlg,da9213" or "dlg,da9215"
- reg: I2C slave address, usually 0x68.
- interrupts: the interrupt outputs of the controller
- regulators: A node that houses a sub-node for each regulator within the
@@ -66,3 +66,31 @@ Example 2) DA9213
};
};
};
+
+
+Example 3) DA9215
+ pmic: da9215@68 {
+ compatible = "dlg,da9215";
+ reg = <0x68>;
+ interrupts = <3 27>;
+
+ regulators {
+ BUCKA {
+ regulator-name = "VBUCKA";
+ regulator-min-microvolt = < 300000>;
+ regulator-max-microvolt = <1570000>;
+ regulator-min-microamp = <4000000>;
+ regulator-max-microamp = <7000000>;
+ enable-gpios = <&gpio 27 0>;
+ };
+ BUCKB {
+ regulator-name = "VBUCKB";
+ regulator-min-microvolt = < 300000>;
+ regulator-max-microvolt = <1570000>;
+ regulator-min-microamp = <4000000>;
+ regulator-max-microamp = <7000000>;
+ enable-gpios = <&gpio 17 0>;
+ };
+ };
+ };
+
diff --git a/Documentation/devicetree/bindings/regulator/max8973-regulator.txt b/Documentation/devicetree/bindings/regulator/max8973-regulator.txt
index 55efb24e5683..f80ea2fe27e6 100644
--- a/Documentation/devicetree/bindings/regulator/max8973-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/max8973-regulator.txt
@@ -25,6 +25,12 @@ Optional properties:
-maxim,enable-frequency-shift: boolean, enable 9% frequency shift.
-maxim,enable-bias-control: boolean, enable bias control. By enabling this
startup delay can be reduce to 20us from 220us.
+-maxim,enable-etr: boolean, enable Enhanced Transient Response.
+-maxim,enable-high-etr-sensitivity: boolean, Enhanced transient response
+ circuit is enabled and set for high sensitivity. If this
+ property is available then etr will be enable default.
+
+Enhanced transient response (ETR) will affect the configuration of CKADV.
Example:
diff --git a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt
index ce91f61feb12..ed936f0f34f2 100644
--- a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt
@@ -1,27 +1,68 @@
-pwm regulator bindings
+Bindings for the Generic PWM Regulator
+======================================
+
+Currently supports 2 modes of operation:
+
+Voltage Table: When in this mode, a voltage table (See below) of
+ predefined voltage <=> duty-cycle values must be
+ provided via DT. Limitations are that the regulator can
+ only operate at the voltages supplied in the table.
+ Intermediary duty-cycle values which would normally
+ allow finer grained voltage selection are ignored and
+ rendered useless. Although more control is given to
+ the user if the assumptions made in continuous-voltage
+ mode do not reign true.
+
+Continuous Voltage: This mode uses the regulator's maximum and minimum
+ supplied voltages specified in the
+ regulator-{min,max}-microvolt properties to calculate
+ appropriate duty-cycle values. This allows for a much
+ more fine grained solution when compared with
+ voltage-table mode above. This solution does make an
+ assumption that a %50 duty-cycle value will cause the
+ regulator voltage to run at half way between the
+ supplied max_uV and min_uV values.
Required properties:
-- compatible: Should be "pwm-regulator"
-- pwms: OF device-tree PWM specification (see PWM binding pwm.txt)
-- voltage-table: voltage and duty table, include 2 members in each set of
- brackets, first one is voltage(unit: uv), the next is duty(unit: percent)
+--------------------
+- compatible: Should be "pwm-regulator"
+
+- pwms: PWM specification (See: ../pwm/pwm.txt)
+
+Only required for Voltage Table Mode:
+- voltage-table: Voltage and Duty-Cycle table consisting of 2 cells
+ First cell is voltage in microvolts (uV)
+ Second cell is duty-cycle in percent (%)
+
+NB: To be clear, if voltage-table is provided, then the device will be used
+in Voltage Table Mode. If no voltage-table is provided, then the device will
+be used in Continuous Voltage Mode.
-Any property defined as part of the core regulator binding defined in
-regulator.txt can also be used.
+Any property defined as part of the core regulator binding can also be used.
+(See: ../regulator/regulator.txt)
-Example:
+Continuous Voltage Example:
pwm_regulator {
compatible = "pwm-regulator;
pwms = <&pwm1 0 8448 0>;
+ regulator-min-microvolt = <1016000>;
+ regulator-max-microvolt = <1114000>;
+ regulator-name = "vdd_logic";
+ };
+Voltage Table Example:
+ pwm_regulator {
+ compatible = "pwm-regulator;
+ pwms = <&pwm1 0 8448 0>;
+ regulator-min-microvolt = <1016000>;
+ regulator-max-microvolt = <1114000>;
+ regulator-name = "vdd_logic";
+
+ /* Voltage Duty-Cycle */
voltage-table = <1114000 0>,
<1095000 10>,
<1076000 20>,
<1056000 30>,
<1036000 40>,
<1016000 50>;
-
- regulator-min-microvolt = <1016000>;
- regulator-max-microvolt = <1114000>;
- regulator-name = "vdd_logic";
};
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
index f4f3b3d53928..35b9e118b2fb 100644
--- a/drivers/extcon/extcon-max77693.c
+++ b/drivers/extcon/extcon-max77693.c
@@ -24,6 +24,7 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/mfd/max77693.h>
+#include <linux/mfd/max77693-common.h>
#include <linux/mfd/max77693-private.h>
#include <linux/extcon.h>
#include <linux/regmap.h>
@@ -42,7 +43,7 @@ static struct max77693_reg_data default_init_data[] = {
{
/* STATUS2 - [3]ChgDetRun */
.addr = MAX77693_MUIC_REG_STATUS2,
- .data = STATUS2_CHGDETRUN_MASK,
+ .data = MAX77693_STATUS2_CHGDETRUN_MASK,
}, {
/* INTMASK1 - Unmask [3]ADC1KM,[0]ADCM */
.addr = MAX77693_MUIC_REG_INTMASK1,
@@ -235,7 +236,7 @@ static int max77693_muic_set_debounce_time(struct max77693_muic_info *info,
*/
ret = regmap_write(info->max77693->regmap_muic,
MAX77693_MUIC_REG_CTRL3,
- time << CONTROL3_ADCDBSET_SHIFT);
+ time << MAX77693_CONTROL3_ADCDBSET_SHIFT);
if (ret) {
dev_err(info->dev, "failed to set ADC debounce time\n");
return ret;
@@ -268,7 +269,7 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
if (attached)
ctrl1 = val;
else
- ctrl1 = CONTROL1_SW_OPEN;
+ ctrl1 = MAX77693_CONTROL1_SW_OPEN;
ret = regmap_update_bits(info->max77693->regmap_muic,
MAX77693_MUIC_REG_CTRL1, COMP_SW_MASK, ctrl1);
@@ -278,13 +279,14 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
}
if (attached)
- ctrl2 |= CONTROL2_CPEN_MASK; /* LowPwr=0, CPEn=1 */
+ ctrl2 |= MAX77693_CONTROL2_CPEN_MASK; /* LowPwr=0, CPEn=1 */
else
- ctrl2 |= CONTROL2_LOWPWR_MASK; /* LowPwr=1, CPEn=0 */
+ ctrl2 |= MAX77693_CONTROL2_LOWPWR_MASK; /* LowPwr=1, CPEn=0 */
ret = regmap_update_bits(info->max77693->regmap_muic,
MAX77693_MUIC_REG_CTRL2,
- CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK, ctrl2);
+ MAX77693_CONTROL2_LOWPWR_MASK | MAX77693_CONTROL2_CPEN_MASK,
+ ctrl2);
if (ret < 0) {
dev_err(info->dev, "failed to update MUIC register\n");
return ret;
@@ -326,8 +328,8 @@ static int max77693_muic_get_cable_type(struct max77693_muic_info *info,
* Read ADC value to check cable type and decide cable state
* according to cable type
*/
- adc = info->status[0] & STATUS1_ADC_MASK;
- adc >>= STATUS1_ADC_SHIFT;
+ adc = info->status[0] & MAX77693_STATUS1_ADC_MASK;
+ adc >>= MAX77693_STATUS1_ADC_SHIFT;
/*
* Check current cable state/cable type and store cable type
@@ -350,8 +352,8 @@ static int max77693_muic_get_cable_type(struct max77693_muic_info *info,
* Read ADC value to check cable type and decide cable state
* according to cable type
*/
- adc = info->status[0] & STATUS1_ADC_MASK;
- adc >>= STATUS1_ADC_SHIFT;
+ adc = info->status[0] & MAX77693_STATUS1_ADC_MASK;
+ adc >>= MAX77693_STATUS1_ADC_SHIFT;
/*
* Check current cable state/cable type and store cable type
@@ -366,13 +368,13 @@ static int max77693_muic_get_cable_type(struct max77693_muic_info *info,
} else {
*attached = true;
- adclow = info->status[0] & STATUS1_ADCLOW_MASK;
- adclow >>= STATUS1_ADCLOW_SHIFT;
- adc1k = info->status[0] & STATUS1_ADC1K_MASK;
- adc1k >>= STATUS1_ADC1K_SHIFT;
+ adclow = info->status[0] & MAX77693_STATUS1_ADCLOW_MASK;
+ adclow >>= MAX77693_STATUS1_ADCLOW_SHIFT;
+ adc1k = info->status[0] & MAX77693_STATUS1_ADC1K_MASK;
+ adc1k >>= MAX77693_STATUS1_ADC1K_SHIFT;
- vbvolt = info->status[1] & STATUS2_VBVOLT_MASK;
- vbvolt >>= STATUS2_VBVOLT_SHIFT;
+ vbvolt = info->status[1] & MAX77693_STATUS2_VBVOLT_MASK;
+ vbvolt >>= MAX77693_STATUS2_VBVOLT_SHIFT;
/**
* [0x1|VBVolt|ADCLow|ADC1K]
@@ -397,8 +399,8 @@ static int max77693_muic_get_cable_type(struct max77693_muic_info *info,
* Read charger type to check cable type and decide cable state
* according to type of charger cable.
*/
- chg_type = info->status[1] & STATUS2_CHGTYP_MASK;
- chg_type >>= STATUS2_CHGTYP_SHIFT;
+ chg_type = info->status[1] & MAX77693_STATUS2_CHGTYP_MASK;
+ chg_type >>= MAX77693_STATUS2_CHGTYP_SHIFT;
if (chg_type == MAX77693_CHARGER_TYPE_NONE) {
*attached = false;
@@ -422,10 +424,10 @@ static int max77693_muic_get_cable_type(struct max77693_muic_info *info,
* Read ADC value to check cable type and decide cable state
* according to cable type
*/
- adc = info->status[0] & STATUS1_ADC_MASK;
- adc >>= STATUS1_ADC_SHIFT;
- chg_type = info->status[1] & STATUS2_CHGTYP_MASK;
- chg_type >>= STATUS2_CHGTYP_SHIFT;
+ adc = info->status[0] & MAX77693_STATUS1_ADC_MASK;
+ adc >>= MAX77693_STATUS1_ADC_SHIFT;
+ chg_type = info->status[1] & MAX77693_STATUS2_CHGTYP_MASK;
+ chg_type >>= MAX77693_STATUS2_CHGTYP_SHIFT;
if (adc == MAX77693_MUIC_ADC_OPEN
&& chg_type == MAX77693_CHARGER_TYPE_NONE)
@@ -437,8 +439,8 @@ static int max77693_muic_get_cable_type(struct max77693_muic_info *info,
* Read vbvolt field, if vbvolt is 1,
* this cable is used for charging.
*/
- vbvolt = info->status[1] & STATUS2_VBVOLT_MASK;
- vbvolt >>= STATUS2_VBVOLT_SHIFT;
+ vbvolt = info->status[1] & MAX77693_STATUS2_VBVOLT_MASK;
+ vbvolt >>= MAX77693_STATUS2_VBVOLT_SHIFT;
cable_type = vbvolt;
break;
@@ -520,7 +522,8 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info,
}
/* Dock-Car/Desk/Audio, PATH:AUDIO */
- ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached);
+ ret = max77693_muic_set_path(info, MAX77693_CONTROL1_SW_AUDIO,
+ attached);
if (ret < 0)
return ret;
extcon_set_cable_state_(info->edev, dock_id, attached);
@@ -585,14 +588,16 @@ static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info)
case MAX77693_MUIC_GND_USB_HOST:
case MAX77693_MUIC_GND_USB_HOST_VB:
/* USB_HOST, PATH: AP_USB */
- ret = max77693_muic_set_path(info, CONTROL1_SW_USB, attached);
+ ret = max77693_muic_set_path(info, MAX77693_CONTROL1_SW_USB,
+ attached);
if (ret < 0)
return ret;
extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, attached);
break;
case MAX77693_MUIC_GND_AV_CABLE_LOAD:
/* Audio Video Cable with load, PATH:AUDIO */
- ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached);
+ ret = max77693_muic_set_path(info, MAX77693_CONTROL1_SW_AUDIO,
+ attached);
if (ret < 0)
return ret;
extcon_set_cable_state_(info->edev, EXTCON_USB, attached);
@@ -615,7 +620,7 @@ static int max77693_muic_jig_handler(struct max77693_muic_info *info,
int cable_type, bool attached)
{
int ret = 0;
- u8 path = CONTROL1_SW_OPEN;
+ u8 path = MAX77693_CONTROL1_SW_OPEN;
dev_info(info->dev,
"external connector is %s (adc:0x%02x)\n",
@@ -625,12 +630,12 @@ static int max77693_muic_jig_handler(struct max77693_muic_info *info,
case MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF: /* ADC_JIG_USB_OFF */
case MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON: /* ADC_JIG_USB_ON */
/* PATH:AP_USB */
- path = CONTROL1_SW_USB;
+ path = MAX77693_CONTROL1_SW_USB;
break;
case MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF: /* ADC_JIG_UART_OFF */
case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON: /* ADC_JIG_UART_ON */
/* PATH:AP_UART */
- path = CONTROL1_SW_UART;
+ path = MAX77693_CONTROL1_SW_UART;
break;
default:
dev_err(info->dev, "failed to detect %s jig cable\n",
@@ -1077,7 +1082,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "allocate register map\n");
} else {
info->max77693->regmap_muic = devm_regmap_init_i2c(
- info->max77693->muic,
+ info->max77693->i2c_muic,
&max77693_muic_regmap_config);
if (IS_ERR(info->max77693->regmap_muic)) {
ret = PTR_ERR(info->max77693->regmap_muic);
@@ -1164,28 +1169,9 @@ static int max77693_muic_probe(struct platform_device *pdev)
}
for (i = 0; i < num_init_data; i++) {
- enum max77693_irq_source irq_src
- = MAX77693_IRQ_GROUP_NR;
-
regmap_write(info->max77693->regmap_muic,
init_data[i].addr,
init_data[i].data);
-
- switch (init_data[i].addr) {
- case MAX77693_MUIC_REG_INTMASK1:
- irq_src = MUIC_INT1;
- break;
- case MAX77693_MUIC_REG_INTMASK2:
- irq_src = MUIC_INT2;
- break;
- case MAX77693_MUIC_REG_INTMASK3:
- irq_src = MUIC_INT3;
- break;
- }
-
- if (irq_src < MAX77693_IRQ_GROUP_NR)
- info->max77693->irq_masks_cur[irq_src]
- = init_data[i].data;
}
if (pdata && pdata->muic_data) {
@@ -1199,12 +1185,12 @@ static int max77693_muic_probe(struct platform_device *pdev)
if (muic_pdata->path_uart)
info->path_uart = muic_pdata->path_uart;
else
- info->path_uart = CONTROL1_SW_UART;
+ info->path_uart = MAX77693_CONTROL1_SW_UART;
if (muic_pdata->path_usb)
info->path_usb = muic_pdata->path_usb;
else
- info->path_usb = CONTROL1_SW_USB;
+ info->path_usb = MAX77693_CONTROL1_SW_USB;
/*
* Default delay time for detecting cable state
@@ -1216,8 +1202,8 @@ static int max77693_muic_probe(struct platform_device *pdev)
else
delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
} else {
- info->path_usb = CONTROL1_SW_USB;
- info->path_uart = CONTROL1_SW_UART;
+ info->path_usb = MAX77693_CONTROL1_SW_USB;
+ info->path_uart = MAX77693_CONTROL1_SW_UART;
delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
}
diff --git a/drivers/extcon/extcon-max77843.c b/drivers/extcon/extcon-max77843.c
index fac2f1417a79..f652c4199870 100644
--- a/drivers/extcon/extcon-max77843.c
+++ b/drivers/extcon/extcon-max77843.c
@@ -15,6 +15,7 @@
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
+#include <linux/mfd/max77693-common.h>
#include <linux/mfd/max77843-private.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -32,7 +33,7 @@ enum max77843_muic_status {
struct max77843_muic_info {
struct device *dev;
- struct max77843 *max77843;
+ struct max77693_dev *max77843;
struct extcon_dev *edev;
struct mutex mutex;
@@ -198,18 +199,18 @@ static const struct regmap_irq_chip max77843_muic_irq_chip = {
static int max77843_muic_set_path(struct max77843_muic_info *info,
u8 val, bool attached)
{
- struct max77843 *max77843 = info->max77843;
+ struct max77693_dev *max77843 = info->max77843;
int ret = 0;
unsigned int ctrl1, ctrl2;
if (attached)
ctrl1 = val;
else
- ctrl1 = CONTROL1_SW_OPEN;
+ ctrl1 = MAX77843_MUIC_CONTROL1_SW_OPEN;
ret = regmap_update_bits(max77843->regmap_muic,
MAX77843_MUIC_REG_CONTROL1,
- CONTROL1_COM_SW, ctrl1);
+ MAX77843_MUIC_CONTROL1_COM_SW, ctrl1);
if (ret < 0) {
dev_err(info->dev, "Cannot switch MUIC port\n");
return ret;
@@ -243,7 +244,7 @@ static int max77843_muic_get_cable_type(struct max77843_muic_info *info,
adc = info->status[MAX77843_MUIC_STATUS1] &
MAX77843_MUIC_STATUS1_ADC_MASK;
- adc >>= STATUS1_ADC_SHIFT;
+ adc >>= MAX77843_MUIC_STATUS1_ADC_SHIFT;
switch (group) {
case MAX77843_CABLE_GROUP_ADC:
@@ -309,7 +310,7 @@ static int max77843_muic_get_cable_type(struct max77843_muic_info *info,
/* Get VBVolt register bit */
gnd_type |= (info->status[MAX77843_MUIC_STATUS2] &
MAX77843_MUIC_STATUS2_VBVOLT_MASK);
- gnd_type >>= STATUS2_VBVOLT_SHIFT;
+ gnd_type >>= MAX77843_MUIC_STATUS2_VBVOLT_SHIFT;
/* Offset of GND cable */
gnd_type |= MAX77843_MUIC_GND_USB_HOST;
@@ -338,7 +339,9 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info)
switch (gnd_cable_type) {
case MAX77843_MUIC_GND_USB_HOST:
case MAX77843_MUIC_GND_USB_HOST_VB:
- ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached);
+ ret = max77843_muic_set_path(info,
+ MAX77843_MUIC_CONTROL1_SW_USB,
+ attached);
if (ret < 0)
return ret;
@@ -346,7 +349,9 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info)
break;
case MAX77843_MUIC_GND_MHL_VB:
case MAX77843_MUIC_GND_MHL:
- ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached);
+ ret = max77843_muic_set_path(info,
+ MAX77843_MUIC_CONTROL1_SW_OPEN,
+ attached);
if (ret < 0)
return ret;
@@ -365,7 +370,7 @@ static int max77843_muic_jig_handler(struct max77843_muic_info *info,
int cable_type, bool attached)
{
int ret;
- u8 path = CONTROL1_SW_OPEN;
+ u8 path = MAX77843_MUIC_CONTROL1_SW_OPEN;
dev_dbg(info->dev, "external connector is %s (adc:0x%02x)\n",
attached ? "attached" : "detached", cable_type);
@@ -373,10 +378,10 @@ static int max77843_muic_jig_handler(struct max77843_muic_info *info,
switch (cable_type) {
case MAX77843_MUIC_ADC_FACTORY_MODE_USB_OFF:
case MAX77843_MUIC_ADC_FACTORY_MODE_USB_ON:
- path = CONTROL1_SW_USB;
+ path = MAX77843_MUIC_CONTROL1_SW_USB;
break;
case MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF:
- path = CONTROL1_SW_UART;
+ path = MAX77843_MUIC_CONTROL1_SW_UART;
break;
default:
return -EINVAL;
@@ -474,14 +479,18 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
switch (chg_type) {
case MAX77843_MUIC_CHG_USB:
- ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached);
+ ret = max77843_muic_set_path(info,
+ MAX77843_MUIC_CONTROL1_SW_USB,
+ attached);
if (ret < 0)
return ret;
extcon_set_cable_state_(info->edev, EXTCON_USB, attached);
break;
case MAX77843_MUIC_CHG_DOWNSTREAM:
- ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached);
+ ret = max77843_muic_set_path(info,
+ MAX77843_MUIC_CONTROL1_SW_OPEN,
+ attached);
if (ret < 0)
return ret;
@@ -489,14 +498,18 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
attached);
break;
case MAX77843_MUIC_CHG_DEDICATED:
- ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached);
+ ret = max77843_muic_set_path(info,
+ MAX77843_MUIC_CONTROL1_SW_OPEN,
+ attached);
if (ret < 0)
return ret;
extcon_set_cable_state_(info->edev, EXTCON_TA, attached);
break;
case MAX77843_MUIC_CHG_SPECIAL_500MA:
- ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached);
+ ret = max77843_muic_set_path(info,
+ MAX77843_MUIC_CONTROL1_SW_OPEN,
+ attached);
if (ret < 0)
return ret;
@@ -504,7 +517,9 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
attached);
break;
case MAX77843_MUIC_CHG_SPECIAL_1A:
- ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached);
+ ret = max77843_muic_set_path(info,
+ MAX77843_MUIC_CONTROL1_SW_OPEN,
+ attached);
if (ret < 0)
return ret;
@@ -528,7 +543,8 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
"failed to detect %s accessory (chg_type:0x%x)\n",
attached ? "attached" : "detached", chg_type);
- max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached);
+ max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_OPEN,
+ attached);
return -EINVAL;
}
@@ -539,7 +555,7 @@ static void max77843_muic_irq_work(struct work_struct *work)
{
struct max77843_muic_info *info = container_of(work,
struct max77843_muic_info, irq_work);
- struct max77843 *max77843 = info->max77843;
+ struct max77693_dev *max77843 = info->max77843;
int ret = 0;
mutex_lock(&info->mutex);
@@ -615,7 +631,7 @@ static void max77843_muic_detect_cable_wq(struct work_struct *work)
{
struct max77843_muic_info *info = container_of(to_delayed_work(work),
struct max77843_muic_info, wq_detcable);
- struct max77843 *max77843 = info->max77843;
+ struct max77693_dev *max77843 = info->max77843;
int chg_type, adc, ret;
bool attached;
@@ -656,7 +672,7 @@ err_cable_wq:
static int max77843_muic_set_debounce_time(struct max77843_muic_info *info,
enum max77843_muic_adc_debounce_time time)
{
- struct max77843 *max77843 = info->max77843;
+ struct max77693_dev *max77843 = info->max77843;
int ret;
switch (time) {
@@ -667,7 +683,7 @@ static int max77843_muic_set_debounce_time(struct max77843_muic_info *info,
ret = regmap_update_bits(max77843->regmap_muic,
MAX77843_MUIC_REG_CONTROL4,
MAX77843_MUIC_CONTROL4_ADCDBSET_MASK,
- time << CONTROL4_ADCDBSET_SHIFT);
+ time << MAX77843_MUIC_CONTROL4_ADCDBSET_SHIFT);
if (ret < 0) {
dev_err(info->dev, "Cannot write MUIC regmap\n");
return ret;
@@ -681,7 +697,7 @@ static int max77843_muic_set_debounce_time(struct max77843_muic_info *info,
return 0;
}
-static int max77843_init_muic_regmap(struct max77843 *max77843)
+static int max77843_init_muic_regmap(struct max77693_dev *max77843)
{
int ret;
@@ -720,7 +736,7 @@ err_muic_i2c:
static int max77843_muic_probe(struct platform_device *pdev)
{
- struct max77843 *max77843 = dev_get_drvdata(pdev->dev.parent);
+ struct max77693_dev *max77843 = dev_get_drvdata(pdev->dev.parent);
struct max77843_muic_info *info;
unsigned int id;
int i, ret;
@@ -768,7 +784,7 @@ static int max77843_muic_probe(struct platform_device *pdev)
max77843_muic_set_debounce_time(info, MAX77843_DEBOUNCE_TIME_25MS);
/* Set initial path for UART */
- max77843_muic_set_path(info, CONTROL1_SW_UART, true);
+ max77843_muic_set_path(info, MAX77843_MUIC_CONTROL1_SW_UART, true);
/* Check revision number of MUIC device */
ret = regmap_read(max77843->regmap_muic, MAX77843_MUIC_REG_ID, &id);
@@ -821,7 +837,7 @@ err_muic_irq:
static int max77843_muic_remove(struct platform_device *pdev)
{
struct max77843_muic_info *info = platform_get_drvdata(pdev);
- struct max77843 *max77843 = info->max77843;
+ struct max77693_dev *max77843 = info->max77843;
cancel_work_sync(&info->irq_work);
regmap_del_irq_chip(max77843->irq, max77843->irq_data_muic);
diff --git a/drivers/input/misc/max77693-haptic.c b/drivers/input/misc/max77693-haptic.c
index 39e930c10ebb..4524499ea72f 100644
--- a/drivers/input/misc/max77693-haptic.c
+++ b/drivers/input/misc/max77693-haptic.c
@@ -24,6 +24,7 @@
#include <linux/workqueue.h>
#include <linux/regulator/consumer.h>
#include <linux/mfd/max77693.h>
+#include <linux/mfd/max77693-common.h>
#include <linux/mfd/max77693-private.h>
#define MAX_MAGNITUDE_SHIFT 16
diff --git a/drivers/input/misc/max77843-haptic.c b/drivers/input/misc/max77843-haptic.c
index dccbb465a055..30da81ab5a21 100644
--- a/drivers/input/misc/max77843-haptic.c
+++ b/drivers/input/misc/max77843-haptic.c
@@ -14,6 +14,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/input.h>
+#include <linux/mfd/max77693-common.h>
#include <linux/mfd/max77843-private.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -243,7 +244,7 @@ static void max77843_haptic_close(struct input_dev *dev)
static int max77843_haptic_probe(struct platform_device *pdev)
{
- struct max77843 *max77843 = dev_get_drvdata(pdev->dev.parent);
+ struct max77693_dev *max77843 = dev_get_drvdata(pdev->dev.parent);
struct max77843_haptic *haptic;
int error;
diff --git a/drivers/leds/leds-max77693.c b/drivers/leds/leds-max77693.c
index b8b0eec7b540..df348a06d8c7 100644
--- a/drivers/leds/leds-max77693.c
+++ b/drivers/leds/leds-max77693.c
@@ -13,6 +13,7 @@
#include <linux/led-class-flash.h>
#include <linux/mfd/max77693.h>
+#include <linux/mfd/max77693-common.h>
#include <linux/mfd/max77693-private.h>
#include <linux/module.h>
#include <linux/mutex.h>
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c
index cb14afa97e6f..67bc53fdc389 100644
--- a/drivers/mfd/max77693.c
+++ b/drivers/mfd/max77693.c
@@ -33,6 +33,7 @@
#include <linux/mutex.h>
#include <linux/mfd/core.h>
#include <linux/mfd/max77693.h>
+#include <linux/mfd/max77693-common.h>
#include <linux/mfd/max77693-private.h>
#include <linux/regulator/machine.h>
#include <linux/regmap.h>
@@ -193,22 +194,22 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
} else
dev_info(max77693->dev, "device ID: 0x%x\n", reg_data);
- max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
- if (!max77693->muic) {
+ max77693->i2c_muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
+ if (!max77693->i2c_muic) {
dev_err(max77693->dev, "Failed to allocate I2C device for MUIC\n");
return -ENODEV;
}
- i2c_set_clientdata(max77693->muic, max77693);
+ i2c_set_clientdata(max77693->i2c_muic, max77693);
- max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
- if (!max77693->haptic) {
+ max77693->i2c_haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
+ if (!max77693->i2c_haptic) {
dev_err(max77693->dev, "Failed to allocate I2C device for Haptic\n");
ret = -ENODEV;
goto err_i2c_haptic;
}
- i2c_set_clientdata(max77693->haptic, max77693);
+ i2c_set_clientdata(max77693->i2c_haptic, max77693);
- max77693->regmap_haptic = devm_regmap_init_i2c(max77693->haptic,
+ max77693->regmap_haptic = devm_regmap_init_i2c(max77693->i2c_haptic,
&max77693_regmap_haptic_config);
if (IS_ERR(max77693->regmap_haptic)) {
ret = PTR_ERR(max77693->regmap_haptic);
@@ -222,7 +223,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
* instance of MUIC device when irq of max77693 is initialized
* before call max77693-muic probe() function.
*/
- max77693->regmap_muic = devm_regmap_init_i2c(max77693->muic,
+ max77693->regmap_muic = devm_regmap_init_i2c(max77693->i2c_muic,
&max77693_regmap_muic_config);
if (IS_ERR(max77693->regmap_muic)) {
ret = PTR_ERR(max77693->regmap_muic);
@@ -255,7 +256,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
IRQF_ONESHOT | IRQF_SHARED |
IRQF_TRIGGER_FALLING, 0,
&max77693_charger_irq_chip,
- &max77693->irq_data_charger);
+ &max77693->irq_data_chg);
if (ret) {
dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
goto err_irq_charger;
@@ -296,15 +297,15 @@ err_mfd:
err_intsrc:
regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
err_irq_muic:
- regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
+ regmap_del_irq_chip(max77693->irq, max77693->irq_data_chg);
err_irq_charger:
regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
err_irq_topsys:
regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
err_regmap:
- i2c_unregister_device(max77693->haptic);
+ i2c_unregister_device(max77693->i2c_haptic);
err_i2c_haptic:
- i2c_unregister_device(max77693->muic);
+ i2c_unregister_device(max77693->i2c_muic);
return ret;
}
@@ -315,12 +316,12 @@ static int max77693_i2c_remove(struct i2c_client *i2c)
mfd_remove_devices(max77693->dev);
regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
- regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
+ regmap_del_irq_chip(max77693->irq, max77693->irq_data_chg);
regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
- i2c_unregister_device(max77693->muic);
- i2c_unregister_device(max77693->haptic);
+ i2c_unregister_device(max77693->i2c_muic);
+ i2c_unregister_device(max77693->i2c_haptic);
return 0;
}
diff --git a/drivers/mfd/max77843.c b/drivers/mfd/max77843.c
index a354ac677ec7..c52162ea3d0a 100644
--- a/drivers/mfd/max77843.c
+++ b/drivers/mfd/max77843.c
@@ -17,6 +17,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/mfd/core.h>
+#include <linux/mfd/max77693-common.h>
#include <linux/mfd/max77843-private.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
@@ -71,7 +72,7 @@ static const struct regmap_irq_chip max77843_irq_chip = {
};
/* Charger and Charger regulator use same regmap. */
-static int max77843_chg_init(struct max77843 *max77843)
+static int max77843_chg_init(struct max77693_dev *max77843)
{
int ret;
@@ -101,7 +102,7 @@ err_chg_i2c:
static int max77843_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
- struct max77843 *max77843;
+ struct max77693_dev *max77843;
unsigned int reg_data;
int ret;
@@ -113,6 +114,7 @@ static int max77843_probe(struct i2c_client *i2c,
max77843->dev = &i2c->dev;
max77843->i2c = i2c;
max77843->irq = i2c->irq;
+ max77843->type = id->driver_data;
max77843->regmap = devm_regmap_init_i2c(i2c,
&max77843_regmap_config);
@@ -123,7 +125,7 @@ static int max77843_probe(struct i2c_client *i2c,
ret = regmap_add_irq_chip(max77843->regmap, max77843->irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
- 0, &max77843_irq_chip, &max77843->irq_data);
+ 0, &max77843_irq_chip, &max77843->irq_data_topsys);
if (ret) {
dev_err(&i2c->dev, "Failed to add TOPSYS IRQ chip\n");
return ret;
@@ -164,18 +166,18 @@ static int max77843_probe(struct i2c_client *i2c,
return 0;
err_pmic_id:
- regmap_del_irq_chip(max77843->irq, max77843->irq_data);
+ regmap_del_irq_chip(max77843->irq, max77843->irq_data_topsys);
return ret;
}
static int max77843_remove(struct i2c_client *i2c)
{
- struct max77843 *max77843 = i2c_get_clientdata(i2c);
+ struct max77693_dev *max77843 = i2c_get_clientdata(i2c);
mfd_remove_devices(max77843->dev);
- regmap_del_irq_chip(max77843->irq, max77843->irq_data);
+ regmap_del_irq_chip(max77843->irq, max77843->irq_data_topsys);
i2c_unregister_device(max77843->i2c_chg);
@@ -188,7 +190,7 @@ static const struct of_device_id max77843_dt_match[] = {
};
static const struct i2c_device_id max77843_id[] = {
- { "max77843", },
+ { "max77843", TYPE_MAX77843, },
{ },
};
MODULE_DEVICE_TABLE(i2c, max77843_id);
@@ -196,7 +198,7 @@ MODULE_DEVICE_TABLE(i2c, max77843_id);
static int __maybe_unused max77843_suspend(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
- struct max77843 *max77843 = i2c_get_clientdata(i2c);
+ struct max77693_dev *max77843 = i2c_get_clientdata(i2c);
disable_irq(max77843->irq);
if (device_may_wakeup(dev))
@@ -208,7 +210,7 @@ static int __maybe_unused max77843_suspend(struct device *dev)
static int __maybe_unused max77843_resume(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
- struct max77843 *max77843 = i2c_get_clientdata(i2c);
+ struct max77693_dev *max77843 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))
disable_irq_wake(max77843->irq);
diff --git a/drivers/power/max77693_charger.c b/drivers/power/max77693_charger.c
index 754879eb59f6..060cab5ae3aa 100644
--- a/drivers/power/max77693_charger.c
+++ b/drivers/power/max77693_charger.c
@@ -20,6 +20,7 @@
#include <linux/power_supply.h>
#include <linux/regmap.h>
#include <linux/mfd/max77693.h>
+#include <linux/mfd/max77693-common.h>
#include <linux/mfd/max77693-private.h>
#define MAX77693_CHARGER_NAME "max77693-charger"
diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c
index 832932bdc977..a62a89674fb5 100644
--- a/drivers/regulator/88pm800.c
+++ b/drivers/regulator/88pm800.c
@@ -78,7 +78,6 @@ struct pm800_regulator_info {
};
struct pm800_regulators {
- struct regulator_dev *regulators[PM800_ID_RG_MAX];
struct pm80x_chip *chip;
struct regmap *map;
};
@@ -92,14 +91,16 @@ struct pm800_regulators {
* not the constant voltage table.
* n_volt - Number of available selectors
*/
-#define PM800_BUCK(vreg, ereg, ebit, amax, volt_ranges, n_volt) \
+#define PM800_BUCK(match, vreg, ereg, ebit, amax, volt_ranges, n_volt) \
{ \
.desc = { \
- .name = #vreg, \
- .ops = &pm800_volt_range_ops, \
- .type = REGULATOR_VOLTAGE, \
- .id = PM800_ID_##vreg, \
- .owner = THIS_MODULE, \
+ .name = #vreg, \
+ .of_match = of_match_ptr(#match), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .ops = &pm800_volt_range_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = PM800_ID_##vreg, \
+ .owner = THIS_MODULE, \
.n_voltages = n_volt, \
.linear_ranges = volt_ranges, \
.n_linear_ranges = ARRAY_SIZE(volt_ranges), \
@@ -108,7 +109,7 @@ struct pm800_regulators {
.enable_reg = PM800_##ereg, \
.enable_mask = 1 << (ebit), \
}, \
- .max_ua = (amax), \
+ .max_ua = (amax), \
}
/*
@@ -120,22 +121,24 @@ struct pm800_regulators {
* For all the LDOes, there are too many ranges. Using volt_table will be
* simpler and faster.
*/
-#define PM800_LDO(vreg, ereg, ebit, amax, ldo_volt_table) \
+#define PM800_LDO(match, vreg, ereg, ebit, amax, ldo_volt_table) \
{ \
.desc = { \
- .name = #vreg, \
- .ops = &pm800_volt_table_ops, \
- .type = REGULATOR_VOLTAGE, \
- .id = PM800_ID_##vreg, \
- .owner = THIS_MODULE, \
- .n_voltages = ARRAY_SIZE(ldo_volt_table), \
- .vsel_reg = PM800_##vreg##_VOUT, \
- .vsel_mask = 0x1f, \
- .enable_reg = PM800_##ereg, \
- .enable_mask = 1 << (ebit), \
- .volt_table = ldo_volt_table, \
+ .name = #vreg, \
+ .of_match = of_match_ptr(#match), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .ops = &pm800_volt_table_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = PM800_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = ARRAY_SIZE(ldo_volt_table), \
+ .vsel_reg = PM800_##vreg##_VOUT, \
+ .vsel_mask = 0xf, \
+ .enable_reg = PM800_##ereg, \
+ .enable_mask = 1 << (ebit), \
+ .volt_table = ldo_volt_table, \
}, \
- .max_ua = (amax), \
+ .max_ua = (amax), \
}
/* Ranges are sorted in ascending order. */
@@ -178,122 +181,66 @@ static int pm800_get_current_limit(struct regulator_dev *rdev)
}
static struct regulator_ops pm800_volt_range_ops = {
- .list_voltage = regulator_list_voltage_linear_range,
- .map_voltage = regulator_map_voltage_linear_range,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .get_current_limit = pm800_get_current_limit,
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_current_limit = pm800_get_current_limit,
};
static struct regulator_ops pm800_volt_table_ops = {
- .list_voltage = regulator_list_voltage_table,
- .map_voltage = regulator_map_voltage_iterate,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .is_enabled = regulator_is_enabled_regmap,
- .get_current_limit = pm800_get_current_limit,
+ .list_voltage = regulator_list_voltage_table,
+ .map_voltage = regulator_map_voltage_iterate,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_current_limit = pm800_get_current_limit,
};
/* The array is indexed by id(PM800_ID_XXX) */
static struct pm800_regulator_info pm800_regulator_info[] = {
- PM800_BUCK(BUCK1, BUCK_ENA, 0, 3000000, buck1_volt_range, 0x55),
- PM800_BUCK(BUCK2, BUCK_ENA, 1, 1200000, buck2_5_volt_range, 0x73),
- PM800_BUCK(BUCK3, BUCK_ENA, 2, 1200000, buck2_5_volt_range, 0x73),
- PM800_BUCK(BUCK4, BUCK_ENA, 3, 1200000, buck2_5_volt_range, 0x73),
- PM800_BUCK(BUCK5, BUCK_ENA, 4, 1200000, buck2_5_volt_range, 0x73),
-
- PM800_LDO(LDO1, LDO_ENA1_1, 0, 200000, ldo1_volt_table),
- PM800_LDO(LDO2, LDO_ENA1_1, 1, 10000, ldo2_volt_table),
- PM800_LDO(LDO3, LDO_ENA1_1, 2, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO4, LDO_ENA1_1, 3, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO5, LDO_ENA1_1, 4, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO6, LDO_ENA1_1, 5, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO7, LDO_ENA1_1, 6, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO8, LDO_ENA1_1, 7, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO9, LDO_ENA1_2, 0, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO10, LDO_ENA1_2, 1, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO11, LDO_ENA1_2, 2, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO12, LDO_ENA1_2, 3, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO13, LDO_ENA1_2, 4, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO14, LDO_ENA1_2, 5, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO15, LDO_ENA1_2, 6, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO16, LDO_ENA1_2, 7, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO17, LDO_ENA1_3, 0, 300000, ldo3_17_volt_table),
- PM800_LDO(LDO18, LDO_ENA1_3, 1, 200000, ldo18_19_volt_table),
- PM800_LDO(LDO19, LDO_ENA1_3, 2, 200000, ldo18_19_volt_table),
-};
-
-#define PM800_REGULATOR_OF_MATCH(_name, _id) \
- [PM800_ID_##_id] = { \
- .name = #_name, \
- .driver_data = &pm800_regulator_info[PM800_ID_##_id], \
- }
-
-static struct of_regulator_match pm800_regulator_matches[] = {
- PM800_REGULATOR_OF_MATCH(buck1, BUCK1),
- PM800_REGULATOR_OF_MATCH(buck2, BUCK2),
- PM800_REGULATOR_OF_MATCH(buck3, BUCK3),
- PM800_REGULATOR_OF_MATCH(buck4, BUCK4),
- PM800_REGULATOR_OF_MATCH(buck5, BUCK5),
- PM800_REGULATOR_OF_MATCH(ldo1, LDO1),
- PM800_REGULATOR_OF_MATCH(ldo2, LDO2),
- PM800_REGULATOR_OF_MATCH(ldo3, LDO3),
- PM800_REGULATOR_OF_MATCH(ldo4, LDO4),
- PM800_REGULATOR_OF_MATCH(ldo5, LDO5),
- PM800_REGULATOR_OF_MATCH(ldo6, LDO6),
- PM800_REGULATOR_OF_MATCH(ldo7, LDO7),
- PM800_REGULATOR_OF_MATCH(ldo8, LDO8),
- PM800_REGULATOR_OF_MATCH(ldo9, LDO9),
- PM800_REGULATOR_OF_MATCH(ldo10, LDO10),
- PM800_REGULATOR_OF_MATCH(ldo11, LDO11),
- PM800_REGULATOR_OF_MATCH(ldo12, LDO12),
- PM800_REGULATOR_OF_MATCH(ldo13, LDO13),
- PM800_REGULATOR_OF_MATCH(ldo14, LDO14),
- PM800_REGULATOR_OF_MATCH(ldo15, LDO15),
- PM800_REGULATOR_OF_MATCH(ldo16, LDO16),
- PM800_REGULATOR_OF_MATCH(ldo17, LDO17),
- PM800_REGULATOR_OF_MATCH(ldo18, LDO18),
- PM800_REGULATOR_OF_MATCH(ldo19, LDO19),
+ PM800_BUCK(buck1, BUCK1, BUCK_ENA, 0, 3000000, buck1_volt_range, 0x55),
+ PM800_BUCK(buck2, BUCK2, BUCK_ENA, 1, 1200000, buck2_5_volt_range, 0x73),
+ PM800_BUCK(buck3, BUCK3, BUCK_ENA, 2, 1200000, buck2_5_volt_range, 0x73),
+ PM800_BUCK(buck4, BUCK4, BUCK_ENA, 3, 1200000, buck2_5_volt_range, 0x73),
+ PM800_BUCK(buck5, BUCK5, BUCK_ENA, 4, 1200000, buck2_5_volt_range, 0x73),
+
+ PM800_LDO(ldo1, LDO1, LDO_ENA1_1, 0, 200000, ldo1_volt_table),
+ PM800_LDO(ldo2, LDO2, LDO_ENA1_1, 1, 10000, ldo2_volt_table),
+ PM800_LDO(ldo3, LDO3, LDO_ENA1_1, 2, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo4, LDO4, LDO_ENA1_1, 3, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo5, LDO5, LDO_ENA1_1, 4, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo6, LDO6, LDO_ENA1_1, 5, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo7, LDO7, LDO_ENA1_1, 6, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo8, LDO8, LDO_ENA1_1, 7, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo9, LDO9, LDO_ENA1_2, 0, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo10, LDO10, LDO_ENA1_2, 1, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo11, LDO11, LDO_ENA1_2, 2, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo12, LDO12, LDO_ENA1_2, 3, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo13, LDO13, LDO_ENA1_2, 4, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo14, LDO14, LDO_ENA1_2, 5, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo15, LDO15, LDO_ENA1_2, 6, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo16, LDO16, LDO_ENA1_2, 7, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo17, LDO17, LDO_ENA1_3, 0, 300000, ldo3_17_volt_table),
+ PM800_LDO(ldo18, LDO18, LDO_ENA1_3, 1, 200000, ldo18_19_volt_table),
+ PM800_LDO(ldo19, LDO19, LDO_ENA1_3, 2, 200000, ldo18_19_volt_table),
};
-static int pm800_regulator_dt_init(struct platform_device *pdev)
-{
- struct device_node *np = pdev->dev.of_node;
- int ret;
-
- ret = of_regulator_match(&pdev->dev, np,
- pm800_regulator_matches,
- ARRAY_SIZE(pm800_regulator_matches));
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
static int pm800_regulator_probe(struct platform_device *pdev)
{
struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
struct pm80x_platform_data *pdata = dev_get_platdata(pdev->dev.parent);
struct pm800_regulators *pm800_data;
- struct pm800_regulator_info *info;
struct regulator_config config = { };
struct regulator_init_data *init_data;
int i, ret;
- if (!pdata || pdata->num_regulators == 0) {
- if (IS_ENABLED(CONFIG_OF)) {
- ret = pm800_regulator_dt_init(pdev);
- if (ret)
- return ret;
- } else {
- return -ENODEV;
- }
- } else if (pdata->num_regulators) {
+ if (pdata && pdata->num_regulators) {
unsigned int count = 0;
/* Check whether num_regulator is valid. */
@@ -303,8 +250,6 @@ static int pm800_regulator_probe(struct platform_device *pdev)
}
if (count != pdata->num_regulators)
return -EINVAL;
- } else {
- return -EINVAL;
}
pm800_data = devm_kzalloc(&pdev->dev, sizeof(*pm800_data),
@@ -317,30 +262,27 @@ static int pm800_regulator_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pm800_data);
+ config.dev = chip->dev;
+ config.regmap = pm800_data->map;
for (i = 0; i < PM800_ID_RG_MAX; i++) {
- if (!pdata || pdata->num_regulators == 0)
- init_data = pm800_regulator_matches[i].init_data;
- else
+ struct regulator_dev *regulator;
+
+ if (pdata && pdata->num_regulators) {
init_data = pdata->regulators[i];
- if (!init_data)
- continue;
- info = pm800_regulator_matches[i].driver_data;
- config.dev = &pdev->dev;
- config.init_data = init_data;
- config.driver_data = info;
- config.regmap = pm800_data->map;
- config.of_node = pm800_regulator_matches[i].of_node;
-
- pm800_data->regulators[i] =
- regulator_register(&info->desc, &config);
- if (IS_ERR(pm800_data->regulators[i])) {
- ret = PTR_ERR(pm800_data->regulators[i]);
- dev_err(&pdev->dev, "Failed to register %s\n",
- info->desc.name);
+ if (!init_data)
+ continue;
- while (--i >= 0)
- regulator_unregister(pm800_data->regulators[i]);
+ config.init_data = init_data;
+ }
+
+ config.driver_data = &pm800_regulator_info[i];
+ regulator = devm_regulator_register(&pdev->dev,
+ &pm800_regulator_info[i].desc, &config);
+ if (IS_ERR(regulator)) {
+ ret = PTR_ERR(regulator);
+ dev_err(&pdev->dev, "Failed to register %s\n",
+ pm800_regulator_info[i].desc.name);
return ret;
}
}
@@ -348,23 +290,11 @@ static int pm800_regulator_probe(struct platform_device *pdev)
return 0;
}
-static int pm800_regulator_remove(struct platform_device *pdev)
-{
- struct pm800_regulators *pm800_data = platform_get_drvdata(pdev);
- int i;
-
- for (i = 0; i < PM800_ID_RG_MAX; i++)
- regulator_unregister(pm800_data->regulators[i]);
-
- return 0;
-}
-
static struct platform_driver pm800_regulator_driver = {
.driver = {
.name = "88pm80x-regulator",
},
.probe = pm800_regulator_probe,
- .remove = pm800_regulator_remove,
};
module_platform_driver(pm800_regulator_driver);
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index bef3bde6971b..a7b81f0185b5 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -209,13 +209,13 @@ config REGULATOR_DA9210
interface.
config REGULATOR_DA9211
- tristate "Dialog Semiconductor DA9211/DA9212/DA9213/DA9214 regulator"
+ tristate "Dialog Semiconductor DA9211/DA9212/DA9213/DA9214/DA9215 regulator"
depends on I2C
select REGMAP_I2C
help
Say y here to support for the Dialog Semiconductor DA9211/DA9212
- /DA9213/DA9214.
- The DA9211/DA9212/DA9213/DA9214 is a multi-phase synchronous
+ /DA9213/DA9214/DA9215.
+ The DA9211/DA9212/DA9213/DA9214/DA9215 is a multi-phase synchronous
step down converter 12A or 16A DC-DC Buck controlled through an I2C
interface.
@@ -407,13 +407,13 @@ config REGULATOR_MAX77686
Exynos-4 chips to control VARM and VINT voltages.
config REGULATOR_MAX77693
- tristate "Maxim MAX77693 regulator"
- depends on MFD_MAX77693
+ tristate "Maxim 77693/77843 regulator"
+ depends on (MFD_MAX77693 || MFD_MAX77843)
help
- This driver controls a Maxim 77693 regulator via I2C bus.
+ This driver controls a Maxim 77693/77843 regulators via I2C bus.
The regulators include two LDOs, 'SAFEOUT1', 'SAFEOUT2'
and one current regulator 'CHARGER'. This is suitable for
- Exynos-4x12 chips.
+ Exynos-4x12 (MAX77693) or Exynos5433 (MAX77843) SoC chips.
config REGULATOR_MAX77802
tristate "Maxim 77802 regulator"
@@ -424,14 +424,6 @@ config REGULATOR_MAX77802
Exynos5420/Exynos5800 SoCs to control various voltages.
It includes support for control of voltage and ramp speed.
-config REGULATOR_MAX77843
- tristate "Maxim 77843 regulator"
- depends on MFD_MAX77843
- help
- This driver controls a Maxim 77843 regulator.
- The regulator include two 'SAFEOUT' for USB(Universal Serial Bus)
- This is suitable for Exynos5433 SoC chips.
-
config REGULATOR_MC13XXX_CORE
tristate
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 91bf76267404..6429e629dcb6 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -56,7 +56,6 @@ obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o
obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o
obj-$(CONFIG_REGULATOR_MAX77802) += max77802.o
-obj-$(CONFIG_REGULATOR_MAX77843) += max77843.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c
index 2ff73d72ca34..896db168e4bd 100644
--- a/drivers/regulator/act8865-regulator.c
+++ b/drivers/regulator/act8865-regulator.c
@@ -530,7 +530,6 @@ MODULE_DEVICE_TABLE(i2c, act8865_ids);
static struct i2c_driver act8865_pmic_driver = {
.driver = {
.name = "act8865",
- .owner = THIS_MODULE,
},
.probe = act8865_pmic_probe,
.id_table = act8865_ids,
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index c9f72019bd68..d16d9c848dc5 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -109,6 +109,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
static struct regulator *create_regulator(struct regulator_dev *rdev,
struct device *dev,
const char *supply_name);
+static void _regulator_put(struct regulator *regulator);
static const char *rdev_get_name(struct regulator_dev *rdev)
{
@@ -640,6 +641,8 @@ static int drms_uA_update(struct regulator_dev *rdev)
int current_uA = 0, output_uV, input_uV, err;
unsigned int mode;
+ lockdep_assert_held_once(&rdev->mutex);
+
/*
* first check to see if we can set modes at all, otherwise just
* tell the consumer everything is OK.
@@ -760,6 +763,8 @@ static int suspend_set_state(struct regulator_dev *rdev,
/* locks held by caller */
static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state)
{
+ lockdep_assert_held_once(&rdev->mutex);
+
if (!rdev->constraints)
return -EINVAL;
@@ -1105,6 +1110,9 @@ static int set_supply(struct regulator_dev *rdev,
rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev));
+ if (!try_module_get(supply_rdev->owner))
+ return -ENODEV;
+
rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
if (rdev->supply == NULL) {
err = -ENOMEM;
@@ -1381,9 +1389,13 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
}
if (!r) {
- dev_err(dev, "Failed to resolve %s-supply for %s\n",
- rdev->supply_name, rdev->desc->name);
- return -EPROBE_DEFER;
+ if (have_full_constraints()) {
+ r = dummy_regulator_rdev;
+ } else {
+ dev_err(dev, "Failed to resolve %s-supply for %s\n",
+ rdev->supply_name, rdev->desc->name);
+ return -EPROBE_DEFER;
+ }
}
/* Recursively resolve the supply of the supply */
@@ -1398,8 +1410,11 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
/* Cascade always-on state to supply */
if (_regulator_is_enabled(rdev)) {
ret = regulator_enable(rdev->supply);
- if (ret < 0)
+ if (ret < 0) {
+ if (rdev->supply)
+ _regulator_put(rdev->supply);
return ret;
+ }
}
return 0;
@@ -1587,6 +1602,8 @@ static void _regulator_put(struct regulator *regulator)
if (regulator == NULL || IS_ERR(regulator))
return;
+ lockdep_assert_held_once(&regulator_list_mutex);
+
rdev = regulator->rdev;
debugfs_remove_recursive(regulator->debugfs);
@@ -1965,6 +1982,8 @@ static int _regulator_enable(struct regulator_dev *rdev)
{
int ret;
+ lockdep_assert_held_once(&rdev->mutex);
+
/* check voltage and requested load before enabling */
if (rdev->constraints &&
(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS))
@@ -2065,6 +2084,8 @@ static int _regulator_disable(struct regulator_dev *rdev)
{
int ret = 0;
+ lockdep_assert_held_once(&rdev->mutex);
+
if (WARN(rdev->use_count <= 0,
"unbalanced disables for %s\n", rdev_get_name(rdev)))
return -EIO;
@@ -2143,6 +2164,8 @@ static int _regulator_force_disable(struct regulator_dev *rdev)
{
int ret = 0;
+ lockdep_assert_held_once(&rdev->mutex);
+
ret = _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE |
REGULATOR_EVENT_PRE_DISABLE, NULL);
if (ret & NOTIFY_STOP_MASK)
@@ -3439,6 +3462,8 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free);
int regulator_notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data)
{
+ lockdep_assert_held_once(&rdev->mutex);
+
_notifier_call_chain(rdev, event, data);
return NOTIFY_DONE;
diff --git a/drivers/regulator/da9062-regulator.c b/drivers/regulator/da9062-regulator.c
index dd76da09b3c7..5638fe8d759d 100644
--- a/drivers/regulator/da9062-regulator.c
+++ b/drivers/regulator/da9062-regulator.c
@@ -818,7 +818,6 @@ static int da9062_regulator_probe(struct platform_device *pdev)
static struct platform_driver da9062_regulator_driver = {
.driver = {
.name = "da9062-regulators",
- .owner = THIS_MODULE,
},
.probe = da9062_regulator_probe,
};
diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c
index f0489cb9018b..b3517830edb6 100644
--- a/drivers/regulator/da9210-regulator.c
+++ b/drivers/regulator/da9210-regulator.c
@@ -22,6 +22,8 @@
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
@@ -120,6 +122,55 @@ static int da9210_get_current_limit(struct regulator_dev *rdev)
return da9210_buck_limits[sel];
}
+static irqreturn_t da9210_irq_handler(int irq, void *data)
+{
+ struct da9210 *chip = data;
+ unsigned int val, handled = 0;
+ int error, ret = IRQ_NONE;
+
+ error = regmap_read(chip->regmap, DA9210_REG_EVENT_B, &val);
+ if (error < 0)
+ goto error_i2c;
+
+ if (val & DA9210_E_OVCURR) {
+ regulator_notifier_call_chain(chip->rdev,
+ REGULATOR_EVENT_OVER_CURRENT,
+ NULL);
+ handled |= DA9210_E_OVCURR;
+ }
+ if (val & DA9210_E_NPWRGOOD) {
+ regulator_notifier_call_chain(chip->rdev,
+ REGULATOR_EVENT_UNDER_VOLTAGE,
+ NULL);
+ handled |= DA9210_E_NPWRGOOD;
+ }
+ if (val & (DA9210_E_TEMP_WARN | DA9210_E_TEMP_CRIT)) {
+ regulator_notifier_call_chain(chip->rdev,
+ REGULATOR_EVENT_OVER_TEMP, NULL);
+ handled |= val & (DA9210_E_TEMP_WARN | DA9210_E_TEMP_CRIT);
+ }
+ if (val & DA9210_E_VMAX) {
+ regulator_notifier_call_chain(chip->rdev,
+ REGULATOR_EVENT_REGULATION_OUT,
+ NULL);
+ handled |= DA9210_E_VMAX;
+ }
+ if (handled) {
+ /* Clear handled events */
+ error = regmap_write(chip->regmap, DA9210_REG_EVENT_B, handled);
+ if (error < 0)
+ goto error_i2c;
+
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+
+error_i2c:
+ dev_err(regmap_get_device(chip->regmap), "I2C error : %d\n", error);
+ return ret;
+}
+
/*
* I2C driver interface functions
*/
@@ -168,6 +219,30 @@ static int da9210_i2c_probe(struct i2c_client *i2c,
}
chip->rdev = rdev;
+ if (i2c->irq) {
+ error = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
+ da9210_irq_handler,
+ IRQF_TRIGGER_LOW |
+ IRQF_ONESHOT | IRQF_SHARED,
+ "da9210", chip);
+ if (error) {
+ dev_err(&i2c->dev, "Failed to request IRQ%u: %d\n",
+ i2c->irq, error);
+ return error;
+ }
+
+ error = regmap_update_bits(chip->regmap, DA9210_REG_MASK_B,
+ DA9210_M_OVCURR | DA9210_M_NPWRGOOD |
+ DA9210_M_TEMP_WARN |
+ DA9210_M_TEMP_CRIT | DA9210_M_VMAX, 0);
+ if (error < 0) {
+ dev_err(&i2c->dev, "Failed to update mask reg: %d\n",
+ error);
+ return error;
+ }
+ } else {
+ dev_warn(&i2c->dev, "No IRQ configured\n");
+ }
i2c_set_clientdata(i2c, chip);
@@ -184,7 +259,6 @@ MODULE_DEVICE_TABLE(i2c, da9210_i2c_id);
static struct i2c_driver da9210_regulator_driver = {
.driver = {
.name = "da9210",
- .owner = THIS_MODULE,
},
.probe = da9210_i2c_probe,
.id_table = da9210_i2c_id,
diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c
index df79e4b1946e..04ef65b7eb3d 100644
--- a/drivers/regulator/da9211-regulator.c
+++ b/drivers/regulator/da9211-regulator.c
@@ -1,6 +1,6 @@
/*
- * da9211-regulator.c - Regulator device driver for DA9211/DA9213
- * Copyright (C) 2014 Dialog Semiconductor Ltd.
+ * da9211-regulator.c - Regulator device driver for DA9211/DA9213/DA9215
+ * Copyright (C) 2015 Dialog Semiconductor Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -32,6 +32,7 @@
/* DEVICE IDs */
#define DA9211_DEVICE_ID 0x22
#define DA9213_DEVICE_ID 0x23
+#define DA9215_DEVICE_ID 0x24
#define DA9211_BUCK_MODE_SLEEP 1
#define DA9211_BUCK_MODE_SYNC 2
@@ -90,6 +91,13 @@ static const int da9213_current_limits[] = {
3000000, 3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000,
4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000
};
+/* Current limits for DA9215 buck (uA) indices
+ * corresponds with register values
+ */
+static const int da9215_current_limits[] = {
+ 4000000, 4200000, 4400000, 4600000, 4800000, 5000000, 5200000, 5400000,
+ 5600000, 5800000, 6000000, 6200000, 6400000, 6600000, 6800000, 7000000
+};
static unsigned int da9211_buck_get_mode(struct regulator_dev *rdev)
{
@@ -157,6 +165,10 @@ static int da9211_set_current_limit(struct regulator_dev *rdev, int min,
current_limits = da9213_current_limits;
max_size = ARRAY_SIZE(da9213_current_limits)-1;
break;
+ case DA9215:
+ current_limits = da9215_current_limits;
+ max_size = ARRAY_SIZE(da9215_current_limits)-1;
+ break;
default:
return -EINVAL;
}
@@ -189,6 +201,9 @@ static int da9211_get_current_limit(struct regulator_dev *rdev)
case DA9213:
current_limits = da9213_current_limits;
break;
+ case DA9215:
+ current_limits = da9215_current_limits;
+ break;
default:
return -EINVAL;
}
@@ -350,13 +365,11 @@ static int da9211_regulator_init(struct da9211 *chip)
/* If configuration for 1/2 bucks is different between platform data
* and the register, driver should exit.
*/
- if ((chip->pdata->num_buck == 2 && data == 0x40)
- || (chip->pdata->num_buck == 1 && data == 0x00)) {
- if (data == 0)
- chip->num_regulator = 1;
- else
- chip->num_regulator = 2;
- } else {
+ if (chip->pdata->num_buck == 1 && data == 0x00)
+ chip->num_regulator = 1;
+ else if (chip->pdata->num_buck == 2 && data != 0x00)
+ chip->num_regulator = 2;
+ else {
dev_err(chip->dev, "Configuration is mismatched\n");
return -EINVAL;
}
@@ -438,6 +451,9 @@ static int da9211_i2c_probe(struct i2c_client *i2c,
case DA9213_DEVICE_ID:
chip->chip_id = DA9213;
break;
+ case DA9215_DEVICE_ID:
+ chip->chip_id = DA9215;
+ break;
default:
dev_err(chip->dev, "Unsupported device id = 0x%x.\n", data);
return -ENODEV;
@@ -478,6 +494,7 @@ static int da9211_i2c_probe(struct i2c_client *i2c,
static const struct i2c_device_id da9211_i2c_id[] = {
{"da9211", DA9211},
{"da9213", DA9213},
+ {"da9215", DA9215},
{},
};
MODULE_DEVICE_TABLE(i2c, da9211_i2c_id);
@@ -486,6 +503,7 @@ MODULE_DEVICE_TABLE(i2c, da9211_i2c_id);
static const struct of_device_id da9211_dt_ids[] = {
{ .compatible = "dlg,da9211", .data = &da9211_i2c_id[0] },
{ .compatible = "dlg,da9213", .data = &da9211_i2c_id[1] },
+ { .compatible = "dlg,da9215", .data = &da9211_i2c_id[2] },
{},
};
MODULE_DEVICE_TABLE(of, da9211_dt_ids);
@@ -494,7 +512,6 @@ MODULE_DEVICE_TABLE(of, da9211_dt_ids);
static struct i2c_driver da9211_regulator_driver = {
.driver = {
.name = "da9211",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(da9211_dt_ids),
},
.probe = da9211_i2c_probe,
@@ -504,5 +521,5 @@ static struct i2c_driver da9211_regulator_driver = {
module_i2c_driver(da9211_regulator_driver);
MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>");
-MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211/DA9213");
-MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211/DA9213/DA9215");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/da9211-regulator.h b/drivers/regulator/da9211-regulator.h
index 93fa9df2721c..d6ad96fc64d3 100644
--- a/drivers/regulator/da9211-regulator.h
+++ b/drivers/regulator/da9211-regulator.h
@@ -1,16 +1,16 @@
/*
- * da9211-regulator.h - Regulator definitions for DA9211/DA9213
- * Copyright (C) 2014 Dialog Semiconductor Ltd.
+ * da9211-regulator.h - Regulator definitions for DA9211/DA9213/DA9215
+ * Copyright (C) 2015 Dialog Semiconductor Ltd.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * 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.
*
- * This library is distributed in the hope that it will be useful,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*/
#ifndef __DA9211_REGISTERS_H__
diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c
index 6e5da95fa025..4abd8e9c81e5 100644
--- a/drivers/regulator/isl6271a-regulator.c
+++ b/drivers/regulator/isl6271a-regulator.c
@@ -156,7 +156,6 @@ MODULE_DEVICE_TABLE(i2c, isl6271a_id);
static struct i2c_driver isl6271a_i2c_driver = {
.driver = {
.name = "isl6271a",
- .owner = THIS_MODULE,
},
.probe = isl6271a_probe,
.id_table = isl6271a_id,
diff --git a/drivers/regulator/isl9305.c b/drivers/regulator/isl9305.c
index 6e3a15fe00f1..eae9d1ffe641 100644
--- a/drivers/regulator/isl9305.c
+++ b/drivers/regulator/isl9305.c
@@ -195,7 +195,6 @@ MODULE_DEVICE_TABLE(i2c, isl9305_i2c_id);
static struct i2c_driver isl9305_regulator_driver = {
.driver = {
.name = "isl9305",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(isl9305_dt_ids),
},
.probe = isl9305_i2c_probe,
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c
index 66fd2330dca0..15c25c622edf 100644
--- a/drivers/regulator/lp3971.c
+++ b/drivers/regulator/lp3971.c
@@ -452,7 +452,6 @@ MODULE_DEVICE_TABLE(i2c, lp3971_i2c_id);
static struct i2c_driver lp3971_i2c_driver = {
.driver = {
.name = "LP3971",
- .owner = THIS_MODULE,
},
.probe = lp3971_i2c_probe,
.id_table = lp3971_i2c_id,
diff --git a/drivers/regulator/lp3972.c b/drivers/regulator/lp3972.c
index aea485afcc1a..3a7e96e2c7b3 100644
--- a/drivers/regulator/lp3972.c
+++ b/drivers/regulator/lp3972.c
@@ -550,7 +550,6 @@ MODULE_DEVICE_TABLE(i2c, lp3972_i2c_id);
static struct i2c_driver lp3972_i2c_driver = {
.driver = {
.name = "lp3972",
- .owner = THIS_MODULE,
},
.probe = lp3972_i2c_probe,
.id_table = lp3972_i2c_id,
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c
index 3de328ab41f3..171c7625dd67 100644
--- a/drivers/regulator/lp872x.c
+++ b/drivers/regulator/lp872x.c
@@ -955,7 +955,6 @@ MODULE_DEVICE_TABLE(i2c, lp872x_ids);
static struct i2c_driver lp872x_driver = {
.driver = {
.name = "lp872x",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(lp872x_dt_ids),
},
.probe = lp872x_probe,
diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c
index 0ce8e4e0fa73..f9adba002724 100644
--- a/drivers/regulator/ltc3589.c
+++ b/drivers/regulator/ltc3589.c
@@ -378,7 +378,7 @@ static bool ltc3589_volatile_reg(struct device *dev, unsigned int reg)
return false;
}
-static struct reg_default ltc3589_reg_defaults[] = {
+static const struct reg_default ltc3589_reg_defaults[] = {
{ LTC3589_SCR1, 0x00 },
{ LTC3589_OVEN, 0x00 },
{ LTC3589_SCR2, 0x00 },
@@ -542,7 +542,6 @@ MODULE_DEVICE_TABLE(i2c, ltc3589_i2c_id);
static struct i2c_driver ltc3589_driver = {
.driver = {
.name = DRIVER_NAME,
- .owner = THIS_MODULE,
},
.probe = ltc3589_probe,
.id_table = ltc3589_i2c_id,
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
index d2a8c64cae42..2c1228d5796a 100644
--- a/drivers/regulator/max1586.c
+++ b/drivers/regulator/max1586.c
@@ -304,7 +304,6 @@ static struct i2c_driver max1586_pmic_driver = {
.probe = max1586_pmic_probe,
.driver = {
.name = "max1586",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(max1586_of_match),
},
.id_table = max1586_id,
diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c
index 38722c8311a5..788379b87962 100644
--- a/drivers/regulator/max77693.c
+++ b/drivers/regulator/max77693.c
@@ -1,8 +1,9 @@
/*
- * max77693.c - Regulator driver for the Maxim 77693
+ * max77693.c - Regulator driver for the Maxim 77693 and 77843
*
- * Copyright (C) 2013 Samsung Electronics
+ * Copyright (C) 2013-2015 Samsung Electronics
* Jonghwa Lee <jonghwa3.lee@samsung.com>
+ * Krzysztof Kozlowski <k.kozlowski.k@gmail.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
@@ -29,38 +30,64 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/max77693.h>
+#include <linux/mfd/max77693-common.h>
#include <linux/mfd/max77693-private.h>
+#include <linux/mfd/max77843-private.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regmap.h>
-#define CHGIN_ILIM_STEP_20mA 20000
+/*
+ * ID for MAX77843 regulators.
+ * There is no need for such for MAX77693.
+ */
+enum max77843_regulator_type {
+ MAX77843_SAFEOUT1 = 0,
+ MAX77843_SAFEOUT2,
+ MAX77843_CHARGER,
+
+ MAX77843_NUM,
+};
+
+/* Register differences between chargers: MAX77693 and MAX77843 */
+struct chg_reg_data {
+ unsigned int linear_reg;
+ unsigned int linear_mask;
+ unsigned int uA_step;
+ unsigned int min_sel;
+};
/*
- * CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA
+ * MAX77693 CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA
* 0x00, 0x01, 0x2, 0x03 = 60 mA
* 0x04 ~ 0x7E = (60 + (X - 3) * 20) mA
+ * Actually for MAX77693 the driver manipulates the maximum input current,
+ * not the fast charge current (output). This should be fixed.
+ *
+ * On MAX77843 the calculation formula is the same (except values).
+ * Fortunately it properly manipulates the fast charge current.
*/
static int max77693_chg_get_current_limit(struct regulator_dev *rdev)
{
+ const struct chg_reg_data *reg_data = rdev_get_drvdata(rdev);
unsigned int chg_min_uA = rdev->constraints->min_uA;
unsigned int chg_max_uA = rdev->constraints->max_uA;
unsigned int reg, sel;
unsigned int val;
int ret;
- ret = regmap_read(rdev->regmap, MAX77693_CHG_REG_CHG_CNFG_09, &reg);
+ ret = regmap_read(rdev->regmap, reg_data->linear_reg, &reg);
if (ret < 0)
return ret;
- sel = reg & CHG_CNFG_09_CHGIN_ILIM_MASK;
+ sel = reg & reg_data->linear_mask;
/* the first four codes for charger current are all 60mA */
- if (sel <= 3)
+ if (sel <= reg_data->min_sel)
sel = 0;
else
- sel -= 3;
+ sel -= reg_data->min_sel;
- val = chg_min_uA + CHGIN_ILIM_STEP_20mA * sel;
+ val = chg_min_uA + reg_data->uA_step * sel;
if (val > chg_max_uA)
return -EINVAL;
@@ -70,23 +97,43 @@ static int max77693_chg_get_current_limit(struct regulator_dev *rdev)
static int max77693_chg_set_current_limit(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
+ const struct chg_reg_data *reg_data = rdev_get_drvdata(rdev);
unsigned int chg_min_uA = rdev->constraints->min_uA;
int sel = 0;
- while (chg_min_uA + CHGIN_ILIM_STEP_20mA * sel < min_uA)
+ while (chg_min_uA + reg_data->uA_step * sel < min_uA)
sel++;
- if (chg_min_uA + CHGIN_ILIM_STEP_20mA * sel > max_uA)
+ if (chg_min_uA + reg_data->uA_step * sel > max_uA)
return -EINVAL;
/* the first four codes for charger current are all 60mA */
- sel += 3;
+ sel += reg_data->min_sel;
- return regmap_write(rdev->regmap,
- MAX77693_CHG_REG_CHG_CNFG_09, sel);
+ return regmap_write(rdev->regmap, reg_data->linear_reg, sel);
}
/* end of CHARGER regulator ops */
+/* Returns regmap suitable for given regulator on chosen device */
+static struct regmap *max77693_get_regmap(enum max77693_types type,
+ struct max77693_dev *max77693,
+ int reg_id)
+{
+ if (type == TYPE_MAX77693)
+ return max77693->regmap;
+
+ /* Else: TYPE_MAX77843 */
+ switch (reg_id) {
+ case MAX77843_SAFEOUT1:
+ case MAX77843_SAFEOUT2:
+ return max77693->regmap;
+ case MAX77843_CHARGER:
+ return max77693->regmap_chg;
+ default:
+ return max77693->regmap;
+ }
+}
+
static const unsigned int max77693_safeout_table[] = {
4850000,
4900000,
@@ -111,7 +158,7 @@ static struct regulator_ops max77693_charger_ops = {
.set_current_limit = max77693_chg_set_current_limit,
};
-#define regulator_desc_esafeout(_num) { \
+#define max77693_regulator_desc_esafeout(_num) { \
.name = "ESAFEOUT"#_num, \
.id = MAX77693_ESAFEOUT##_num, \
.of_match = of_match_ptr("ESAFEOUT"#_num), \
@@ -127,9 +174,9 @@ static struct regulator_ops max77693_charger_ops = {
.enable_mask = SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK , \
}
-static const struct regulator_desc regulators[] = {
- regulator_desc_esafeout(1),
- regulator_desc_esafeout(2),
+static const struct regulator_desc max77693_supported_regulators[] = {
+ max77693_regulator_desc_esafeout(1),
+ max77693_regulator_desc_esafeout(2),
{
.name = "CHARGER",
.id = MAX77693_CHARGER,
@@ -145,18 +192,86 @@ static const struct regulator_desc regulators[] = {
},
};
+static const struct chg_reg_data max77693_chg_reg_data = {
+ .linear_reg = MAX77693_CHG_REG_CHG_CNFG_09,
+ .linear_mask = CHG_CNFG_09_CHGIN_ILIM_MASK,
+ .uA_step = 20000,
+ .min_sel = 3,
+};
+
+#define max77843_regulator_desc_esafeout(num) { \
+ .name = "SAFEOUT" # num, \
+ .id = MAX77843_SAFEOUT ## num, \
+ .ops = &max77693_safeout_ops, \
+ .of_match = of_match_ptr("SAFEOUT" # num), \
+ .regulators_node = of_match_ptr("regulators"), \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ .n_voltages = ARRAY_SIZE(max77693_safeout_table), \
+ .volt_table = max77693_safeout_table, \
+ .enable_reg = MAX77843_SYS_REG_SAFEOUTCTRL, \
+ .enable_mask = MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT ## num, \
+ .vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL, \
+ .vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT ## num ## _MASK, \
+}
+
+static const struct regulator_desc max77843_supported_regulators[] = {
+ [MAX77843_SAFEOUT1] = max77843_regulator_desc_esafeout(1),
+ [MAX77843_SAFEOUT2] = max77843_regulator_desc_esafeout(2),
+ [MAX77843_CHARGER] = {
+ .name = "CHARGER",
+ .id = MAX77843_CHARGER,
+ .ops = &max77693_charger_ops,
+ .of_match = of_match_ptr("CHARGER"),
+ .regulators_node = of_match_ptr("regulators"),
+ .type = REGULATOR_CURRENT,
+ .owner = THIS_MODULE,
+ .enable_reg = MAX77843_CHG_REG_CHG_CNFG_00,
+ .enable_mask = MAX77843_CHG_MASK,
+ .enable_val = MAX77843_CHG_MASK,
+ },
+};
+
+static const struct chg_reg_data max77843_chg_reg_data = {
+ .linear_reg = MAX77843_CHG_REG_CHG_CNFG_02,
+ .linear_mask = MAX77843_CHG_FAST_CHG_CURRENT_MASK,
+ .uA_step = MAX77843_CHG_FAST_CHG_CURRENT_STEP,
+ .min_sel = 2,
+};
+
static int max77693_pmic_probe(struct platform_device *pdev)
{
+ enum max77693_types type = platform_get_device_id(pdev)->driver_data;
struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+ const struct regulator_desc *regulators;
+ unsigned int regulators_size;
int i;
struct regulator_config config = { };
config.dev = iodev->dev;
- config.regmap = iodev->regmap;
- for (i = 0; i < ARRAY_SIZE(regulators); i++) {
+ switch (type) {
+ case TYPE_MAX77693:
+ regulators = max77693_supported_regulators;
+ regulators_size = ARRAY_SIZE(max77693_supported_regulators);
+ config.driver_data = (void *)&max77693_chg_reg_data;
+ break;
+ case TYPE_MAX77843:
+ regulators = max77843_supported_regulators;
+ regulators_size = ARRAY_SIZE(max77843_supported_regulators);
+ config.driver_data = (void *)&max77843_chg_reg_data;
+ break;
+ default:
+ dev_err(&pdev->dev, "Unsupported device type: %u\n", type);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < regulators_size; i++) {
struct regulator_dev *rdev;
+ config.regmap = max77693_get_regmap(type, iodev,
+ regulators[i].id);
+
rdev = devm_regulator_register(&pdev->dev,
&regulators[i], &config);
if (IS_ERR(rdev)) {
@@ -170,7 +285,8 @@ static int max77693_pmic_probe(struct platform_device *pdev)
}
static const struct platform_device_id max77693_pmic_id[] = {
- {"max77693-pmic", 0},
+ { "max77693-pmic", TYPE_MAX77693 },
+ { "max77843-regulator", TYPE_MAX77843 },
{},
};
@@ -186,6 +302,7 @@ static struct platform_driver max77693_pmic_driver = {
module_platform_driver(max77693_pmic_driver);
-MODULE_DESCRIPTION("MAXIM MAX77693 regulator driver");
+MODULE_DESCRIPTION("MAXIM 77693/77843 regulator driver");
MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>");
+MODULE_AUTHOR("Krzysztof Kozlowski <k.kozlowski.k@gmail.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/max77843.c b/drivers/regulator/max77843.c
deleted file mode 100644
index f4fd0d3cfa6e..000000000000
--- a/drivers/regulator/max77843.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * max77843.c - Regulator driver for the Maxim MAX77843
- *
- * Copyright (C) 2015 Samsung Electronics
- * Author: Jaewon Kim <jaewon02.kim@samsung.com>
- * Author: Beomho Seo <beomho.seo@samsung.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.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-#include <linux/mfd/max77843-private.h>
-#include <linux/regulator/of_regulator.h>
-
-enum max77843_regulator_type {
- MAX77843_SAFEOUT1 = 0,
- MAX77843_SAFEOUT2,
- MAX77843_CHARGER,
-
- MAX77843_NUM,
-};
-
-static const unsigned int max77843_safeout_voltage_table[] = {
- 4850000,
- 4900000,
- 4950000,
- 3300000,
-};
-
-static int max77843_reg_get_current_limit(struct regulator_dev *rdev)
-{
- struct regmap *regmap = rdev->regmap;
- unsigned int chg_min_uA = rdev->constraints->min_uA;
- unsigned int chg_max_uA = rdev->constraints->max_uA;
- unsigned int val;
- int ret;
- unsigned int reg, sel;
-
- ret = regmap_read(regmap, MAX77843_CHG_REG_CHG_CNFG_02, &reg);
- if (ret) {
- dev_err(&rdev->dev, "Failed to read charger register\n");
- return ret;
- }
-
- sel = reg & MAX77843_CHG_FAST_CHG_CURRENT_MASK;
-
- if (sel < 0x03)
- sel = 0;
- else
- sel -= 2;
-
- val = chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel;
- if (val > chg_max_uA)
- return -EINVAL;
-
- return val;
-}
-
-static int max77843_reg_set_current_limit(struct regulator_dev *rdev,
- int min_uA, int max_uA)
-{
- struct regmap *regmap = rdev->regmap;
- unsigned int chg_min_uA = rdev->constraints->min_uA;
- int sel = 0;
-
- while (chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel < min_uA)
- sel++;
-
- if (chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel > max_uA)
- return -EINVAL;
-
- sel += 2;
-
- return regmap_write(regmap, MAX77843_CHG_REG_CHG_CNFG_02, sel);
-}
-
-static struct regulator_ops max77843_charger_ops = {
- .is_enabled = regulator_is_enabled_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .get_current_limit = max77843_reg_get_current_limit,
- .set_current_limit = max77843_reg_set_current_limit,
-};
-
-static struct regulator_ops max77843_regulator_ops = {
- .is_enabled = regulator_is_enabled_regmap,
- .enable = regulator_enable_regmap,
- .disable = regulator_disable_regmap,
- .list_voltage = regulator_list_voltage_table,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
-};
-
-#define MAX77843_SAFEOUT(num) { \
- .name = "SAFEOUT" # num, \
- .id = MAX77843_SAFEOUT ## num, \
- .ops = &max77843_regulator_ops, \
- .of_match = of_match_ptr("SAFEOUT" # num), \
- .regulators_node = of_match_ptr("regulators"), \
- .type = REGULATOR_VOLTAGE, \
- .owner = THIS_MODULE, \
- .n_voltages = ARRAY_SIZE(max77843_safeout_voltage_table), \
- .volt_table = max77843_safeout_voltage_table, \
- .enable_reg = MAX77843_SYS_REG_SAFEOUTCTRL, \
- .enable_mask = MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT ## num, \
- .vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL, \
- .vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT ## num ## _MASK, \
-}
-
-static const struct regulator_desc max77843_supported_regulators[] = {
- [MAX77843_SAFEOUT1] = MAX77843_SAFEOUT(1),
- [MAX77843_SAFEOUT2] = MAX77843_SAFEOUT(2),
- [MAX77843_CHARGER] = {
- .name = "CHARGER",
- .id = MAX77843_CHARGER,
- .ops = &max77843_charger_ops,
- .of_match = of_match_ptr("CHARGER"),
- .regulators_node = of_match_ptr("regulators"),
- .type = REGULATOR_CURRENT,
- .owner = THIS_MODULE,
- .enable_reg = MAX77843_CHG_REG_CHG_CNFG_00,
- .enable_mask = MAX77843_CHG_MASK | MAX77843_CHG_BUCK_MASK,
- .enable_val = MAX77843_CHG_MASK | MAX77843_CHG_BUCK_MASK,
- },
-};
-
-static struct regmap *max77843_get_regmap(struct max77843 *max77843, int reg_id)
-{
- switch (reg_id) {
- case MAX77843_SAFEOUT1:
- case MAX77843_SAFEOUT2:
- return max77843->regmap;
- case MAX77843_CHARGER:
- return max77843->regmap_chg;
- default:
- return max77843->regmap;
- }
-}
-
-static int max77843_regulator_probe(struct platform_device *pdev)
-{
- struct max77843 *max77843 = dev_get_drvdata(pdev->dev.parent);
- struct regulator_config config = {};
- int i;
-
- config.dev = max77843->dev;
- config.driver_data = max77843;
-
- for (i = 0; i < ARRAY_SIZE(max77843_supported_regulators); i++) {
- struct regulator_dev *regulator;
-
- config.regmap = max77843_get_regmap(max77843,
- max77843_supported_regulators[i].id);
-
- regulator = devm_regulator_register(&pdev->dev,
- &max77843_supported_regulators[i], &config);
- if (IS_ERR(regulator)) {
- dev_err(&pdev->dev,
- "Failed to regiser regulator-%d\n", i);
- return PTR_ERR(regulator);
- }
- }
-
- return 0;
-}
-
-static const struct platform_device_id max77843_regulator_id[] = {
- { "max77843-regulator", },
- { /* sentinel */ },
-};
-
-static struct platform_driver max77843_regulator_driver = {
- .driver = {
- .name = "max77843-regulator",
- },
- .probe = max77843_regulator_probe,
- .id_table = max77843_regulator_id,
-};
-
-static int __init max77843_regulator_init(void)
-{
- return platform_driver_register(&max77843_regulator_driver);
-}
-subsys_initcall(max77843_regulator_init);
-
-static void __exit max77843_regulator_exit(void)
-{
- platform_driver_unregister(&max77843_regulator_driver);
-}
-module_exit(max77843_regulator_exit);
-
-MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
-MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
-MODULE_DESCRIPTION("Maxim MAX77843 regulator driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c
index 4071d74fa828..b87f62dd484e 100644
--- a/drivers/regulator/max8660.c
+++ b/drivers/regulator/max8660.c
@@ -518,7 +518,6 @@ static struct i2c_driver max8660_driver = {
.probe = max8660_probe,
.driver = {
.name = "max8660",
- .owner = THIS_MODULE,
},
.id_table = max8660_id,
};
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index 6f2bdad8b4d8..a3e0bccb3f7d 100644
--- a/drivers/regulator/max8973-regulator.c
+++ b/drivers/regulator/max8973-regulator.c
@@ -75,6 +75,7 @@
#define MAX8973_DISCH_ENBABLE BIT(5)
#define MAX8973_FT_ENABLE BIT(4)
+#define MAX8973_CKKADV_TRIP_MASK 0xC
#define MAX8973_CKKADV_TRIP_DISABLE 0xC
#define MAX8973_CKKADV_TRIP_75mV_PER_US 0x0
#define MAX8973_CKKADV_TRIP_150mV_PER_US 0x4
@@ -282,6 +283,55 @@ static int max8973_set_ramp_delay(struct regulator_dev *rdev,
return ret;
}
+static int max8973_set_current_limit(struct regulator_dev *rdev,
+ int min_ua, int max_ua)
+{
+ struct max8973_chip *max = rdev_get_drvdata(rdev);
+ unsigned int val;
+ int ret;
+
+ if (max_ua <= 9000000)
+ val = MAX8973_CKKADV_TRIP_75mV_PER_US;
+ else if (max_ua <= 12000000)
+ val = MAX8973_CKKADV_TRIP_150mV_PER_US;
+ else
+ val = MAX8973_CKKADV_TRIP_DISABLE;
+
+ ret = regmap_update_bits(max->regmap, MAX8973_CONTROL2,
+ MAX8973_CKKADV_TRIP_MASK, val);
+ if (ret < 0) {
+ dev_err(max->dev, "register %d update failed: %d\n",
+ MAX8973_CONTROL2, ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int max8973_get_current_limit(struct regulator_dev *rdev)
+{
+ struct max8973_chip *max = rdev_get_drvdata(rdev);
+ unsigned int control2;
+ int ret;
+
+ ret = regmap_read(max->regmap, MAX8973_CONTROL2, &control2);
+ if (ret < 0) {
+ dev_err(max->dev, "register %d read failed: %d\n",
+ MAX8973_CONTROL2, ret);
+ return ret;
+ }
+ switch (control2 & MAX8973_CKKADV_TRIP_MASK) {
+ case MAX8973_CKKADV_TRIP_DISABLE:
+ return 15000000;
+ case MAX8973_CKKADV_TRIP_150mV_PER_US:
+ return 12000000;
+ case MAX8973_CKKADV_TRIP_75mV_PER_US:
+ return 9000000;
+ default:
+ break;
+ }
+ return 9000000;
+}
+
static const struct regulator_ops max8973_dcdc_ops = {
.get_voltage_sel = max8973_dcdc_get_voltage_sel,
.set_voltage_sel = max8973_dcdc_set_voltage_sel,
@@ -421,6 +471,8 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
struct device_node *np = dev->of_node;
int ret;
u32 pval;
+ bool etr_enable;
+ bool etr_sensitivity_high;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
@@ -450,7 +502,24 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
pdata->control_flags |= MAX8973_CONTROL_FREQ_SHIFT_9PER_ENABLE;
if (of_property_read_bool(np, "maxim,enable-bias-control"))
- pdata->control_flags |= MAX8973_BIAS_ENABLE;
+ pdata->control_flags |= MAX8973_CONTROL_BIAS_ENABLE;
+
+ etr_enable = of_property_read_bool(np, "maxim,enable-etr");
+ etr_sensitivity_high = of_property_read_bool(np,
+ "maxim,enable-high-etr-sensitivity");
+ if (etr_sensitivity_high)
+ etr_enable = true;
+
+ if (etr_enable) {
+ if (etr_sensitivity_high)
+ pdata->control_flags |=
+ MAX8973_CONTROL_CLKADV_TRIP_75mV_PER_US;
+ else
+ pdata->control_flags |=
+ MAX8973_CONTROL_CLKADV_TRIP_150mV_PER_US;
+ } else {
+ pdata->control_flags |= MAX8973_CONTROL_CLKADV_TRIP_DISABLED;
+ }
return pdata;
}
@@ -613,6 +682,8 @@ static int max8973_probe(struct i2c_client *client,
max->ops.enable = regulator_enable_regmap;
max->ops.disable = regulator_disable_regmap;
max->ops.is_enabled = regulator_is_enabled_regmap;
+ max->ops.set_current_limit = max8973_set_current_limit;
+ max->ops.get_current_limit = max8973_get_current_limit;
break;
default:
break;
@@ -652,7 +723,6 @@ static struct i2c_driver max8973_i2c_driver = {
.driver = {
.name = "max8973",
.of_match_table = of_max8973_match_tbl,
- .owner = THIS_MODULE,
},
.probe = max8973_probe,
.id_table = max8973_id,
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
index 8cc8d1877c44..2f66821d53cb 100644
--- a/drivers/regulator/pfuze100-regulator.c
+++ b/drivers/regulator/pfuze100-regulator.c
@@ -643,7 +643,6 @@ static struct i2c_driver pfuze_driver = {
.id_table = pfuze_device_id,
.driver = {
.name = "pfuze100-regulator",
- .owner = THIS_MODULE,
.of_match_table = pfuze_dt_ids,
},
.probe = pfuze100_regulator_probe,
diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c
index ffa96124a5e7..fc3166dfcbfa 100644
--- a/drivers/regulator/pwm-regulator.c
+++ b/drivers/regulator/pwm-regulator.c
@@ -10,6 +10,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/delay.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
@@ -21,9 +22,15 @@
#include <linux/pwm.h>
struct pwm_regulator_data {
- struct pwm_voltages *duty_cycle_table;
+ /* Shared */
struct pwm_device *pwm;
+
+ /* Voltage table */
+ struct pwm_voltages *duty_cycle_table;
int state;
+
+ /* Continuous voltage */
+ int volt_uV;
};
struct pwm_voltages {
@@ -31,6 +38,9 @@ struct pwm_voltages {
unsigned int dutycycle;
};
+/**
+ * Voltage table call-backs
+ */
static int pwm_regulator_get_voltage_sel(struct regulator_dev *rdev)
{
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
@@ -79,29 +89,129 @@ static int pwm_regulator_list_voltage(struct regulator_dev *rdev,
return drvdata->duty_cycle_table[selector].uV;
}
-static struct regulator_ops pwm_regulator_voltage_ops = {
+/**
+ * Continuous voltage call-backs
+ */
+static int pwm_voltage_to_duty_cycle_percentage(struct regulator_dev *rdev, int req_uV)
+{
+ int min_uV = rdev->constraints->min_uV;
+ int max_uV = rdev->constraints->max_uV;
+ int diff = max_uV - min_uV;
+
+ return 100 - (((req_uV * 100) - (min_uV * 100)) / diff);
+}
+
+static int pwm_regulator_get_voltage(struct regulator_dev *rdev)
+{
+ struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
+
+ return drvdata->volt_uV;
+}
+
+static int pwm_regulator_set_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV,
+ unsigned *selector)
+{
+ struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
+ unsigned int ramp_delay = rdev->constraints->ramp_delay;
+ unsigned int period = pwm_get_period(drvdata->pwm);
+ int duty_cycle;
+ int ret;
+
+ duty_cycle = pwm_voltage_to_duty_cycle_percentage(rdev, min_uV);
+
+ ret = pwm_config(drvdata->pwm, (period / 100) * duty_cycle, period);
+ if (ret) {
+ dev_err(&rdev->dev, "Failed to configure PWM\n");
+ return ret;
+ }
+
+ ret = pwm_enable(drvdata->pwm);
+ if (ret) {
+ dev_err(&rdev->dev, "Failed to enable PWM\n");
+ return ret;
+ }
+ drvdata->volt_uV = min_uV;
+
+ /* Delay required by PWM regulator to settle to the new voltage */
+ usleep_range(ramp_delay, ramp_delay + 1000);
+
+ return 0;
+}
+
+static struct regulator_ops pwm_regulator_voltage_table_ops = {
.set_voltage_sel = pwm_regulator_set_voltage_sel,
.get_voltage_sel = pwm_regulator_get_voltage_sel,
.list_voltage = pwm_regulator_list_voltage,
.map_voltage = regulator_map_voltage_iterate,
};
+static struct regulator_ops pwm_regulator_voltage_continuous_ops = {
+ .get_voltage = pwm_regulator_get_voltage,
+ .set_voltage = pwm_regulator_set_voltage,
+};
+
static struct regulator_desc pwm_regulator_desc = {
.name = "pwm-regulator",
- .ops = &pwm_regulator_voltage_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.supply_name = "pwm",
};
+static int pwm_regulator_init_table(struct platform_device *pdev,
+ struct pwm_regulator_data *drvdata)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct pwm_voltages *duty_cycle_table;
+ unsigned int length = 0;
+ int ret;
+
+ of_find_property(np, "voltage-table", &length);
+
+ if ((length < sizeof(*duty_cycle_table)) ||
+ (length % sizeof(*duty_cycle_table))) {
+ dev_err(&pdev->dev,
+ "voltage-table length(%d) is invalid\n",
+ length);
+ return -EINVAL;
+ }
+
+ duty_cycle_table = devm_kzalloc(&pdev->dev, length, GFP_KERNEL);
+ if (!duty_cycle_table)
+ return -ENOMEM;
+
+ ret = of_property_read_u32_array(np, "voltage-table",
+ (u32 *)duty_cycle_table,
+ length / sizeof(u32));
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to read voltage-table\n");
+ return ret;
+ }
+
+ drvdata->duty_cycle_table = duty_cycle_table;
+ pwm_regulator_desc.ops = &pwm_regulator_voltage_table_ops;
+ pwm_regulator_desc.n_voltages = length / sizeof(*duty_cycle_table);
+
+ return 0;
+}
+
+static int pwm_regulator_init_continuous(struct platform_device *pdev,
+ struct pwm_regulator_data *drvdata)
+{
+ pwm_regulator_desc.ops = &pwm_regulator_voltage_continuous_ops;
+ pwm_regulator_desc.continuous_voltage_range = true;
+
+ return 0;
+}
+
static int pwm_regulator_probe(struct platform_device *pdev)
{
+ const struct regulator_init_data *init_data;
struct pwm_regulator_data *drvdata;
- struct property *prop;
struct regulator_dev *regulator;
struct regulator_config config = { };
struct device_node *np = pdev->dev.of_node;
- int length, ret;
+ int ret;
if (!np) {
dev_err(&pdev->dev, "Device Tree node missing\n");
@@ -112,44 +222,22 @@ static int pwm_regulator_probe(struct platform_device *pdev)
if (!drvdata)
return -ENOMEM;
- /* determine the number of voltage-table */
- prop = of_find_property(np, "voltage-table", &length);
- if (!prop) {
- dev_err(&pdev->dev, "No voltage-table\n");
- return -EINVAL;
- }
-
- if ((length < sizeof(*drvdata->duty_cycle_table)) ||
- (length % sizeof(*drvdata->duty_cycle_table))) {
- dev_err(&pdev->dev, "voltage-table length(%d) is invalid\n",
- length);
- return -EINVAL;
- }
-
- pwm_regulator_desc.n_voltages = length / sizeof(*drvdata->duty_cycle_table);
-
- drvdata->duty_cycle_table = devm_kzalloc(&pdev->dev,
- length, GFP_KERNEL);
- if (!drvdata->duty_cycle_table)
- return -ENOMEM;
-
- /* read voltage table from DT property */
- ret = of_property_read_u32_array(np, "voltage-table",
- (u32 *)drvdata->duty_cycle_table,
- length / sizeof(u32));
- if (ret < 0) {
- dev_err(&pdev->dev, "read voltage-table failed\n");
+ if (of_find_property(np, "voltage-table", NULL))
+ ret = pwm_regulator_init_table(pdev, drvdata);
+ else
+ ret = pwm_regulator_init_continuous(pdev, drvdata);
+ if (ret)
return ret;
- }
- config.init_data = of_get_regulator_init_data(&pdev->dev, np,
- &pwm_regulator_desc);
- if (!config.init_data)
+ init_data = of_get_regulator_init_data(&pdev->dev, np,
+ &pwm_regulator_desc);
+ if (!init_data)
return -ENOMEM;
config.of_node = np;
config.dev = &pdev->dev;
config.driver_data = drvdata;
+ config.init_data = init_data;
drvdata->pwm = devm_pwm_get(&pdev->dev, NULL);
if (IS_ERR(drvdata->pwm)) {
diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c
index 850a30a95b5b..9ef0e2f28ec4 100644
--- a/drivers/regulator/qcom_spmi-regulator.c
+++ b/drivers/regulator/qcom_spmi-regulator.c
@@ -504,8 +504,7 @@ static int spmi_regulator_select_voltage(struct spmi_regulator *vreg,
* Force uV to be an allowed set point by applying a ceiling function to
* the uV value.
*/
- *voltage_sel = (uV - range->min_uV + range->step_uV - 1)
- / range->step_uV;
+ *voltage_sel = DIV_ROUND_UP(uV - range->min_uV, range->step_uV);
uV = *voltage_sel * range->step_uV + range->min_uV;
if (uV > max_uV) {
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c
index 3fd44353cc80..d86a3dcd61e2 100644
--- a/drivers/regulator/rk808-regulator.c
+++ b/drivers/regulator/rk808-regulator.c
@@ -16,12 +16,16 @@
* more details.
*/
-#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
#include <linux/i2c.h>
-#include <linux/mfd/rk808.h>
+#include <linux/module.h>
#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/mfd/rk808.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
+#include <linux/gpio/consumer.h>
/* Field Definitions */
#define RK808_BUCK_VSEL_MASK 0x3f
@@ -36,12 +40,25 @@
#define RK808_RAMP_RATE_6MV_PER_US (2 << RK808_RAMP_RATE_OFFSET)
#define RK808_RAMP_RATE_10MV_PER_US (3 << RK808_RAMP_RATE_OFFSET)
+#define RK808_DVS2_POL BIT(2)
+#define RK808_DVS1_POL BIT(1)
+
/* Offset from XXX_ON_VSEL to XXX_SLP_VSEL */
#define RK808_SLP_REG_OFFSET 1
+/* Offset from XXX_ON_VSEL to XXX_DVS_VSEL */
+#define RK808_DVS_REG_OFFSET 2
+
/* Offset from XXX_EN_REG to SLEEP_SET_OFF_XXX */
#define RK808_SLP_SET_OFF_REG_OFFSET 2
+/* max steps for increase voltage of Buck1/2, equal 100mv*/
+#define MAX_STEPS_ONE_TIME 8
+
+struct rk808_regulator_data {
+ struct gpio_desc *dvs_gpio[2];
+};
+
static const int rk808_buck_config_regs[] = {
RK808_BUCK1_CONFIG_REG,
RK808_BUCK2_CONFIG_REG,
@@ -70,6 +87,131 @@ static const struct regulator_linear_range rk808_ldo6_voltage_ranges[] = {
REGULATOR_LINEAR_RANGE(800000, 0, 17, 100000),
};
+static int rk808_buck1_2_get_voltage_sel_regmap(struct regulator_dev *rdev)
+{
+ struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
+ int id = rdev->desc->id - RK808_ID_DCDC1;
+ struct gpio_desc *gpio = pdata->dvs_gpio[id];
+ unsigned int val;
+ int ret;
+
+ if (!gpio || gpiod_get_value(gpio) == 0)
+ return regulator_get_voltage_sel_regmap(rdev);
+
+ ret = regmap_read(rdev->regmap,
+ rdev->desc->vsel_reg + RK808_DVS_REG_OFFSET,
+ &val);
+ if (ret != 0)
+ return ret;
+
+ val &= rdev->desc->vsel_mask;
+ val >>= ffs(rdev->desc->vsel_mask) - 1;
+
+ return val;
+}
+
+static int rk808_buck1_2_i2c_set_voltage_sel(struct regulator_dev *rdev,
+ unsigned sel)
+{
+ int ret, delta_sel;
+ unsigned int old_sel, tmp, val, mask = rdev->desc->vsel_mask;
+
+ ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val);
+ if (ret != 0)
+ return ret;
+
+ tmp = val & ~mask;
+ old_sel = val & mask;
+ old_sel >>= ffs(mask) - 1;
+ delta_sel = sel - old_sel;
+
+ /*
+ * If directly modify the register to change the voltage, we will face
+ * the risk of overshoot. Put it into a multi-step, can effectively
+ * avoid this problem, a step is 100mv here.
+ */
+ while (delta_sel > MAX_STEPS_ONE_TIME) {
+ old_sel += MAX_STEPS_ONE_TIME;
+ val = old_sel << (ffs(mask) - 1);
+ val |= tmp;
+
+ /*
+ * i2c is 400kHz (2.5us per bit) and we must transmit _at least_
+ * 3 bytes (24 bits) plus start and stop so 26 bits. So we've
+ * got more than 65 us between each voltage change and thus
+ * won't ramp faster than ~1500 uV / us.
+ */
+ ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, val);
+ delta_sel = sel - old_sel;
+ }
+
+ sel <<= ffs(mask) - 1;
+ val = tmp | sel;
+ ret = regmap_write(rdev->regmap, rdev->desc->vsel_reg, val);
+
+ /*
+ * When we change the voltage register directly, the ramp rate is about
+ * 100000uv/us, wait 1us to make sure the target voltage to be stable,
+ * so we needn't wait extra time after that.
+ */
+ udelay(1);
+
+ return ret;
+}
+
+static int rk808_buck1_2_set_voltage_sel(struct regulator_dev *rdev,
+ unsigned sel)
+{
+ struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
+ int id = rdev->desc->id - RK808_ID_DCDC1;
+ struct gpio_desc *gpio = pdata->dvs_gpio[id];
+ unsigned int reg = rdev->desc->vsel_reg;
+ unsigned old_sel;
+ int ret, gpio_level;
+
+ if (!gpio)
+ return rk808_buck1_2_i2c_set_voltage_sel(rdev, sel);
+
+ gpio_level = gpiod_get_value(gpio);
+ if (gpio_level == 0) {
+ reg += RK808_DVS_REG_OFFSET;
+ ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &old_sel);
+ } else {
+ ret = regmap_read(rdev->regmap,
+ reg + RK808_DVS_REG_OFFSET,
+ &old_sel);
+ }
+
+ if (ret != 0)
+ return ret;
+
+ sel <<= ffs(rdev->desc->vsel_mask) - 1;
+ sel |= old_sel & ~rdev->desc->vsel_mask;
+
+ ret = regmap_write(rdev->regmap, reg, sel);
+ if (ret)
+ return ret;
+
+ gpiod_set_value(gpio, !gpio_level);
+
+ return ret;
+}
+
+static int rk808_buck1_2_set_voltage_time_sel(struct regulator_dev *rdev,
+ unsigned int old_selector,
+ unsigned int new_selector)
+{
+ struct rk808_regulator_data *pdata = rdev_get_drvdata(rdev);
+ int id = rdev->desc->id - RK808_ID_DCDC1;
+ struct gpio_desc *gpio = pdata->dvs_gpio[id];
+
+ /* if there is no dvs1/2 pin, we don't need wait extra time here. */
+ if (!gpio)
+ return 0;
+
+ return regulator_set_voltage_time_sel(rdev, old_selector, new_selector);
+}
+
static int rk808_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
unsigned int ramp_value = RK808_RAMP_RATE_10MV_PER_US;
@@ -137,8 +279,9 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
static struct regulator_ops rk808_buck1_2_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
- .get_voltage_sel = regulator_get_voltage_sel_regmap,
- .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = rk808_buck1_2_get_voltage_sel_regmap,
+ .set_voltage_sel = rk808_buck1_2_set_voltage_sel,
+ .set_voltage_time_sel = rk808_buck1_2_set_voltage_time_sel,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
@@ -380,25 +523,69 @@ static struct of_regulator_match rk808_reg_matches[] = {
[RK808_ID_SWITCH2] = { .name = "SWITCH_REG2" },
};
+static int rk808_regulator_dt_parse_pdata(struct device *dev,
+ struct device *client_dev,
+ struct regmap *map,
+ struct rk808_regulator_data *pdata)
+{
+ struct device_node *np;
+ int tmp, ret, i;
+
+ np = of_get_child_by_name(client_dev->of_node, "regulators");
+ if (!np)
+ return -ENXIO;
+
+ ret = of_regulator_match(dev, np, rk808_reg_matches,
+ RK808_NUM_REGULATORS);
+ if (ret < 0)
+ goto dt_parse_end;
+
+ for (i = 0; i < ARRAY_SIZE(pdata->dvs_gpio); i++) {
+ pdata->dvs_gpio[i] =
+ devm_gpiod_get_index_optional(client_dev, "dvs", i,
+ GPIOD_OUT_LOW);
+ if (IS_ERR(pdata->dvs_gpio[i])) {
+ ret = PTR_ERR(pdata->dvs_gpio[i]);
+ dev_err(dev, "failed to get dvs%d gpio (%d)\n", i, ret);
+ goto dt_parse_end;
+ }
+
+ if (!pdata->dvs_gpio[i]) {
+ dev_warn(dev, "there is no dvs%d gpio\n", i);
+ continue;
+ }
+
+ tmp = i ? RK808_DVS2_POL : RK808_DVS1_POL;
+ ret = regmap_update_bits(map, RK808_IO_POL_REG, tmp,
+ gpiod_is_active_low(pdata->dvs_gpio[i]) ?
+ 0 : tmp);
+ }
+
+dt_parse_end:
+ of_node_put(np);
+ return ret;
+}
+
static int rk808_regulator_probe(struct platform_device *pdev)
{
struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
struct i2c_client *client = rk808->i2c;
- struct device_node *reg_np;
struct regulator_config config = {};
struct regulator_dev *rk808_rdev;
+ struct rk808_regulator_data *pdata;
int ret, i;
- reg_np = of_get_child_by_name(client->dev.of_node, "regulators");
- if (!reg_np)
- return -ENXIO;
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
- ret = of_regulator_match(&pdev->dev, reg_np, rk808_reg_matches,
- RK808_NUM_REGULATORS);
- of_node_put(reg_np);
+ ret = rk808_regulator_dt_parse_pdata(&pdev->dev, &client->dev,
+ rk808->regmap, pdata);
if (ret < 0)
return ret;
+ platform_set_drvdata(pdev, pdata);
+
/* Instantiate the regulators */
for (i = 0; i < RK808_NUM_REGULATORS; i++) {
if (!rk808_reg_matches[i].init_data ||
@@ -406,7 +593,7 @@ static int rk808_regulator_probe(struct platform_device *pdev)
continue;
config.dev = &client->dev;
- config.driver_data = rk808;
+ config.driver_data = pdata;
config.regmap = rk808->regmap;
config.of_node = rk808_reg_matches[i].of_node;
config.init_data = rk808_reg_matches[i].init_data;
@@ -427,6 +614,7 @@ static struct platform_driver rk808_regulator_driver = {
.probe = rk808_regulator_probe,
.driver = {
.name = "rk808-regulator",
+ .owner = THIS_MODULE,
},
};
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c
index 326ffb553371..72fc3c32db49 100644
--- a/drivers/regulator/s2mps11.c
+++ b/drivers/regulator/s2mps11.c
@@ -34,6 +34,8 @@
#include <linux/mfd/samsung/s2mps14.h>
#include <linux/mfd/samsung/s2mpu02.h>
+/* The highest number of possible regulators for supported devices. */
+#define S2MPS_REGULATOR_MAX S2MPS13_REGULATOR_MAX
struct s2mps11_info {
unsigned int rdev_num;
int ramp_delay2;
@@ -49,7 +51,7 @@ struct s2mps11_info {
* One bit for each S2MPS13/S2MPS14/S2MPU02 regulator whether
* the suspend mode was enabled.
*/
- unsigned long long s2mps14_suspend_state:50;
+ DECLARE_BITMAP(suspend_state, S2MPS_REGULATOR_MAX);
/* Array of size rdev_num with GPIO-s for external sleep control */
int *ext_control_gpio;
@@ -500,7 +502,7 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev)
switch (s2mps11->dev_type) {
case S2MPS13X:
case S2MPS14X:
- if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev)))
+ if (test_bit(rdev_get_id(rdev), s2mps11->suspend_state))
val = S2MPS14_ENABLE_SUSPEND;
else if (gpio_is_valid(s2mps11->ext_control_gpio[rdev_get_id(rdev)]))
val = S2MPS14_ENABLE_EXT_CONTROL;
@@ -508,7 +510,7 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev)
val = rdev->desc->enable_mask;
break;
case S2MPU02:
- if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev)))
+ if (test_bit(rdev_get_id(rdev), s2mps11->suspend_state))
val = S2MPU02_ENABLE_SUSPEND;
else
val = rdev->desc->enable_mask;
@@ -562,7 +564,7 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev)
if (ret < 0)
return ret;
- s2mps11->s2mps14_suspend_state |= (1 << rdev_get_id(rdev));
+ set_bit(rdev_get_id(rdev), s2mps11->suspend_state);
/*
* Don't enable suspend mode if regulator is already disabled because
* this would effectively for a short time turn on the regulator after
@@ -960,18 +962,22 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
case S2MPS11X:
s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators);
regulators = s2mps11_regulators;
+ BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num);
break;
case S2MPS13X:
s2mps11->rdev_num = ARRAY_SIZE(s2mps13_regulators);
regulators = s2mps13_regulators;
+ BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num);
break;
case S2MPS14X:
s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators);
regulators = s2mps14_regulators;
+ BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num);
break;
case S2MPU02:
s2mps11->rdev_num = ARRAY_SIZE(s2mpu02_regulators);
regulators = s2mpu02_regulators;
+ BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num);
break;
default:
dev_err(&pdev->dev, "Invalid device type: %u\n",
diff --git a/drivers/regulator/tps51632-regulator.c b/drivers/regulator/tps51632-regulator.c
index c213e37eb69e..572816e30095 100644
--- a/drivers/regulator/tps51632-regulator.c
+++ b/drivers/regulator/tps51632-regulator.c
@@ -362,7 +362,6 @@ MODULE_DEVICE_TABLE(i2c, tps51632_id);
static struct i2c_driver tps51632_i2c_driver = {
.driver = {
.name = "tps51632",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(tps51632_of_match),
},
.probe = tps51632_probe,
diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c
index a1fd626c6c96..f6a6d36a6533 100644
--- a/drivers/regulator/tps62360-regulator.c
+++ b/drivers/regulator/tps62360-regulator.c
@@ -515,7 +515,6 @@ MODULE_DEVICE_TABLE(i2c, tps62360_id);
static struct i2c_driver tps62360_i2c_driver = {
.driver = {
.name = "tps62360",
- .owner = THIS_MODULE,
.of_match_table = of_match_ptr(tps62360_of_match),
},
.probe = tps62360_probe,
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c
index b941e564b3f3..5cc19b44974a 100644
--- a/drivers/regulator/tps65023-regulator.c
+++ b/drivers/regulator/tps65023-regulator.c
@@ -410,7 +410,6 @@ MODULE_DEVICE_TABLE(i2c, tps_65023_id);
static struct i2c_driver tps_65023_i2c_driver = {
.driver = {
.name = "tps65023",
- .owner = THIS_MODULE,
},
.probe = tps_65023_probe,
.id_table = tps_65023_id,
diff --git a/include/linux/mfd/max77693-common.h b/include/linux/mfd/max77693-common.h
new file mode 100644
index 000000000000..095b121aa725
--- /dev/null
+++ b/include/linux/mfd/max77693-common.h
@@ -0,0 +1,49 @@
+/*
+ * Common data shared between Maxim 77693 and 77843 drivers
+ *
+ * Copyright (C) 2015 Samsung Electronics
+ *
+ * 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.
+ */
+
+#ifndef __LINUX_MFD_MAX77693_COMMON_H
+#define __LINUX_MFD_MAX77693_COMMON_H
+
+enum max77693_types {
+ TYPE_MAX77693_UNKNOWN,
+ TYPE_MAX77693,
+ TYPE_MAX77843,
+
+ TYPE_MAX77693_NUM,
+};
+
+/*
+ * Shared also with max77843.
+ */
+struct max77693_dev {
+ struct device *dev;
+ struct i2c_client *i2c; /* 0xCC , PMIC, Charger, Flash LED */
+ struct i2c_client *i2c_muic; /* 0x4A , MUIC */
+ struct i2c_client *i2c_haptic; /* MAX77693: 0x90 , Haptic */
+ struct i2c_client *i2c_chg; /* MAX77843: 0xD2, Charger */
+
+ enum max77693_types type;
+
+ struct regmap *regmap;
+ struct regmap *regmap_muic;
+ struct regmap *regmap_haptic; /* Only MAX77693 */
+ struct regmap *regmap_chg; /* Only MAX77843 */
+
+ struct regmap_irq_chip_data *irq_data_led;
+ struct regmap_irq_chip_data *irq_data_topsys;
+ struct regmap_irq_chip_data *irq_data_chg; /* Only MAX77693 */
+ struct regmap_irq_chip_data *irq_data_muic;
+
+ int irq;
+};
+
+
+#endif /* __LINUX_MFD_MAX77693_COMMON_H */
diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h
index 51633ea6f910..3c7a63b98ad6 100644
--- a/include/linux/mfd/max77693-private.h
+++ b/include/linux/mfd/max77693-private.h
@@ -310,30 +310,30 @@ enum max77693_muic_reg {
#define INTMASK2_CHGTYP_MASK (1 << INTMASK2_CHGTYP_SHIFT)
/* MAX77693 MUIC - STATUS1~3 Register */
-#define STATUS1_ADC_SHIFT (0)
-#define STATUS1_ADCLOW_SHIFT (5)
-#define STATUS1_ADCERR_SHIFT (6)
-#define STATUS1_ADC1K_SHIFT (7)
-#define STATUS1_ADC_MASK (0x1f << STATUS1_ADC_SHIFT)
-#define STATUS1_ADCLOW_MASK (0x1 << STATUS1_ADCLOW_SHIFT)
-#define STATUS1_ADCERR_MASK (0x1 << STATUS1_ADCERR_SHIFT)
-#define STATUS1_ADC1K_MASK (0x1 << STATUS1_ADC1K_SHIFT)
-
-#define STATUS2_CHGTYP_SHIFT (0)
-#define STATUS2_CHGDETRUN_SHIFT (3)
-#define STATUS2_DCDTMR_SHIFT (4)
-#define STATUS2_DXOVP_SHIFT (5)
-#define STATUS2_VBVOLT_SHIFT (6)
-#define STATUS2_VIDRM_SHIFT (7)
-#define STATUS2_CHGTYP_MASK (0x7 << STATUS2_CHGTYP_SHIFT)
-#define STATUS2_CHGDETRUN_MASK (0x1 << STATUS2_CHGDETRUN_SHIFT)
-#define STATUS2_DCDTMR_MASK (0x1 << STATUS2_DCDTMR_SHIFT)
-#define STATUS2_DXOVP_MASK (0x1 << STATUS2_DXOVP_SHIFT)
-#define STATUS2_VBVOLT_MASK (0x1 << STATUS2_VBVOLT_SHIFT)
-#define STATUS2_VIDRM_MASK (0x1 << STATUS2_VIDRM_SHIFT)
-
-#define STATUS3_OVP_SHIFT (2)
-#define STATUS3_OVP_MASK (0x1 << STATUS3_OVP_SHIFT)
+#define MAX77693_STATUS1_ADC_SHIFT 0
+#define MAX77693_STATUS1_ADCLOW_SHIFT 5
+#define MAX77693_STATUS1_ADCERR_SHIFT 6
+#define MAX77693_STATUS1_ADC1K_SHIFT 7
+#define MAX77693_STATUS1_ADC_MASK (0x1f << MAX77693_STATUS1_ADC_SHIFT)
+#define MAX77693_STATUS1_ADCLOW_MASK BIT(MAX77693_STATUS1_ADCLOW_SHIFT)
+#define MAX77693_STATUS1_ADCERR_MASK BIT(MAX77693_STATUS1_ADCERR_SHIFT)
+#define MAX77693_STATUS1_ADC1K_MASK BIT(MAX77693_STATUS1_ADC1K_SHIFT)
+
+#define MAX77693_STATUS2_CHGTYP_SHIFT 0
+#define MAX77693_STATUS2_CHGDETRUN_SHIFT 3
+#define MAX77693_STATUS2_DCDTMR_SHIFT 4
+#define MAX77693_STATUS2_DXOVP_SHIFT 5
+#define MAX77693_STATUS2_VBVOLT_SHIFT 6
+#define MAX77693_STATUS2_VIDRM_SHIFT 7
+#define MAX77693_STATUS2_CHGTYP_MASK (0x7 << MAX77693_STATUS2_CHGTYP_SHIFT)
+#define MAX77693_STATUS2_CHGDETRUN_MASK BIT(MAX77693_STATUS2_CHGDETRUN_SHIFT)
+#define MAX77693_STATUS2_DCDTMR_MASK BIT(MAX77693_STATUS2_DCDTMR_SHIFT)
+#define MAX77693_STATUS2_DXOVP_MASK BIT(MAX77693_STATUS2_DXOVP_SHIFT)
+#define MAX77693_STATUS2_VBVOLT_MASK BIT(MAX77693_STATUS2_VBVOLT_SHIFT)
+#define MAX77693_STATUS2_VIDRM_MASK BIT(MAX77693_STATUS2_VIDRM_SHIFT)
+
+#define MAX77693_STATUS3_OVP_SHIFT 2
+#define MAX77693_STATUS3_OVP_MASK BIT(MAX77693_STATUS3_OVP_SHIFT)
/* MAX77693 CDETCTRL1~2 register */
#define CDETCTRL1_CHGDETEN_SHIFT (0)
@@ -362,38 +362,38 @@ enum max77693_muic_reg {
#define COMN1SW_MASK (0x7 << COMN1SW_SHIFT)
#define COMP2SW_MASK (0x7 << COMP2SW_SHIFT)
#define COMP_SW_MASK (COMP2SW_MASK | COMN1SW_MASK)
-#define CONTROL1_SW_USB ((1 << COMP2SW_SHIFT) \
+#define MAX77693_CONTROL1_SW_USB ((1 << COMP2SW_SHIFT) \
| (1 << COMN1SW_SHIFT))
-#define CONTROL1_SW_AUDIO ((2 << COMP2SW_SHIFT) \
+#define MAX77693_CONTROL1_SW_AUDIO ((2 << COMP2SW_SHIFT) \
| (2 << COMN1SW_SHIFT))
-#define CONTROL1_SW_UART ((3 << COMP2SW_SHIFT) \
+#define MAX77693_CONTROL1_SW_UART ((3 << COMP2SW_SHIFT) \
| (3 << COMN1SW_SHIFT))
-#define CONTROL1_SW_OPEN ((0 << COMP2SW_SHIFT) \
+#define MAX77693_CONTROL1_SW_OPEN ((0 << COMP2SW_SHIFT) \
| (0 << COMN1SW_SHIFT))
-#define CONTROL2_LOWPWR_SHIFT (0)
-#define CONTROL2_ADCEN_SHIFT (1)
-#define CONTROL2_CPEN_SHIFT (2)
-#define CONTROL2_SFOUTASRT_SHIFT (3)
-#define CONTROL2_SFOUTORD_SHIFT (4)
-#define CONTROL2_ACCDET_SHIFT (5)
-#define CONTROL2_USBCPINT_SHIFT (6)
-#define CONTROL2_RCPS_SHIFT (7)
-#define CONTROL2_LOWPWR_MASK (0x1 << CONTROL2_LOWPWR_SHIFT)
-#define CONTROL2_ADCEN_MASK (0x1 << CONTROL2_ADCEN_SHIFT)
-#define CONTROL2_CPEN_MASK (0x1 << CONTROL2_CPEN_SHIFT)
-#define CONTROL2_SFOUTASRT_MASK (0x1 << CONTROL2_SFOUTASRT_SHIFT)
-#define CONTROL2_SFOUTORD_MASK (0x1 << CONTROL2_SFOUTORD_SHIFT)
-#define CONTROL2_ACCDET_MASK (0x1 << CONTROL2_ACCDET_SHIFT)
-#define CONTROL2_USBCPINT_MASK (0x1 << CONTROL2_USBCPINT_SHIFT)
-#define CONTROL2_RCPS_MASK (0x1 << CONTROL2_RCPS_SHIFT)
-
-#define CONTROL3_JIGSET_SHIFT (0)
-#define CONTROL3_BTLDSET_SHIFT (2)
-#define CONTROL3_ADCDBSET_SHIFT (4)
-#define CONTROL3_JIGSET_MASK (0x3 << CONTROL3_JIGSET_SHIFT)
-#define CONTROL3_BTLDSET_MASK (0x3 << CONTROL3_BTLDSET_SHIFT)
-#define CONTROL3_ADCDBSET_MASK (0x3 << CONTROL3_ADCDBSET_SHIFT)
+#define MAX77693_CONTROL2_LOWPWR_SHIFT 0
+#define MAX77693_CONTROL2_ADCEN_SHIFT 1
+#define MAX77693_CONTROL2_CPEN_SHIFT 2
+#define MAX77693_CONTROL2_SFOUTASRT_SHIFT 3
+#define MAX77693_CONTROL2_SFOUTORD_SHIFT 4
+#define MAX77693_CONTROL2_ACCDET_SHIFT 5
+#define MAX77693_CONTROL2_USBCPINT_SHIFT 6
+#define MAX77693_CONTROL2_RCPS_SHIFT 7
+#define MAX77693_CONTROL2_LOWPWR_MASK BIT(MAX77693_CONTROL2_LOWPWR_SHIFT)
+#define MAX77693_CONTROL2_ADCEN_MASK BIT(MAX77693_CONTROL2_ADCEN_SHIFT)
+#define MAX77693_CONTROL2_CPEN_MASK BIT(MAX77693_CONTROL2_CPEN_SHIFT)
+#define MAX77693_CONTROL2_SFOUTASRT_MASK BIT(MAX77693_CONTROL2_SFOUTASRT_SHIFT)
+#define MAX77693_CONTROL2_SFOUTORD_MASK BIT(MAX77693_CONTROL2_SFOUTORD_SHIFT)
+#define MAX77693_CONTROL2_ACCDET_MASK BIT(MAX77693_CONTROL2_ACCDET_SHIFT)
+#define MAX77693_CONTROL2_USBCPINT_MASK BIT(MAX77693_CONTROL2_USBCPINT_SHIFT)
+#define MAX77693_CONTROL2_RCPS_MASK BIT(MAX77693_CONTROL2_RCPS_SHIFT)
+
+#define MAX77693_CONTROL3_JIGSET_SHIFT 0
+#define MAX77693_CONTROL3_BTLDSET_SHIFT 2
+#define MAX77693_CONTROL3_ADCDBSET_SHIFT 4
+#define MAX77693_CONTROL3_JIGSET_MASK (0x3 << MAX77693_CONTROL3_JIGSET_SHIFT)
+#define MAX77693_CONTROL3_BTLDSET_MASK (0x3 << MAX77693_CONTROL3_BTLDSET_SHIFT)
+#define MAX77693_CONTROL3_ADCDBSET_MASK (0x3 << MAX77693_CONTROL3_ADCDBSET_SHIFT)
/* Slave addr = 0x90: Haptic */
enum max77693_haptic_reg {
@@ -529,36 +529,4 @@ enum max77693_irq_muic {
MAX77693_MUIC_IRQ_NR,
};
-struct max77693_dev {
- struct device *dev;
- struct i2c_client *i2c; /* 0xCC , PMIC, Charger, Flash LED */
- struct i2c_client *muic; /* 0x4A , MUIC */
- struct i2c_client *haptic; /* 0x90 , Haptic */
-
- int type;
-
- struct regmap *regmap;
- struct regmap *regmap_muic;
- struct regmap *regmap_haptic;
-
- struct regmap_irq_chip_data *irq_data_led;
- struct regmap_irq_chip_data *irq_data_topsys;
- struct regmap_irq_chip_data *irq_data_charger;
- struct regmap_irq_chip_data *irq_data_muic;
-
- int irq;
- int irq_gpio;
- struct mutex irqlock;
- int irq_masks_cur[MAX77693_IRQ_GROUP_NR];
- int irq_masks_cache[MAX77693_IRQ_GROUP_NR];
-};
-
-enum max77693_types {
- TYPE_MAX77693,
-};
-
-extern int max77693_irq_init(struct max77693_dev *max77686);
-extern void max77693_irq_exit(struct max77693_dev *max77686);
-extern int max77693_irq_resume(struct max77693_dev *max77686);
-
#endif /* __LINUX_MFD_MAX77693_PRIV_H */
diff --git a/include/linux/mfd/max77843-private.h b/include/linux/mfd/max77843-private.h
index 7178ace8379e..c19303b0ccfd 100644
--- a/include/linux/mfd/max77843-private.h
+++ b/include/linux/mfd/max77843-private.h
@@ -318,62 +318,62 @@ enum max77843_irq_muic {
MAX77843_INTSRCMASK_SYS_MASK | MAX77843_INTSRCMASK_CHGR_MASK)
/* MAX77843 STATUS register*/
-#define STATUS1_ADC_SHIFT 0
-#define STATUS1_ADCERROR_SHIFT 6
-#define STATUS1_ADC1K_SHIFT 7
-#define STATUS2_CHGTYP_SHIFT 0
-#define STATUS2_CHGDETRUN_SHIFT 3
-#define STATUS2_DCDTMR_SHIFT 4
-#define STATUS2_DXOVP_SHIFT 5
-#define STATUS2_VBVOLT_SHIFT 6
-#define STATUS3_VBADC_SHIFT 0
-#define STATUS3_VDNMON_SHIFT 4
-#define STATUS3_DNRES_SHIFT 5
-#define STATUS3_MPNACK_SHIFT 6
-
-#define MAX77843_MUIC_STATUS1_ADC_MASK (0x1f << STATUS1_ADC_SHIFT)
-#define MAX77843_MUIC_STATUS1_ADCERROR_MASK BIT(STATUS1_ADCERROR_SHIFT)
-#define MAX77843_MUIC_STATUS1_ADC1K_MASK BIT(STATUS1_ADC1K_SHIFT)
-#define MAX77843_MUIC_STATUS2_CHGTYP_MASK (0x7 << STATUS2_CHGTYP_SHIFT)
-#define MAX77843_MUIC_STATUS2_CHGDETRUN_MASK BIT(STATUS2_CHGDETRUN_SHIFT)
-#define MAX77843_MUIC_STATUS2_DCDTMR_MASK BIT(STATUS2_DCDTMR_SHIFT)
-#define MAX77843_MUIC_STATUS2_DXOVP_MASK BIT(STATUS2_DXOVP_SHIFT)
-#define MAX77843_MUIC_STATUS2_VBVOLT_MASK BIT(STATUS2_VBVOLT_SHIFT)
-#define MAX77843_MUIC_STATUS3_VBADC_MASK (0xf << STATUS3_VBADC_SHIFT)
-#define MAX77843_MUIC_STATUS3_VDNMON_MASK BIT(STATUS3_VDNMON_SHIFT)
-#define MAX77843_MUIC_STATUS3_DNRES_MASK BIT(STATUS3_DNRES_SHIFT)
-#define MAX77843_MUIC_STATUS3_MPNACK_MASK BIT(STATUS3_MPNACK_SHIFT)
+#define MAX77843_MUIC_STATUS1_ADC_SHIFT 0
+#define MAX77843_MUIC_STATUS1_ADCERROR_SHIFT 6
+#define MAX77843_MUIC_STATUS1_ADC1K_SHIFT 7
+#define MAX77843_MUIC_STATUS2_CHGTYP_SHIFT 0
+#define MAX77843_MUIC_STATUS2_CHGDETRUN_SHIFT 3
+#define MAX77843_MUIC_STATUS2_DCDTMR_SHIFT 4
+#define MAX77843_MUIC_STATUS2_DXOVP_SHIFT 5
+#define MAX77843_MUIC_STATUS2_VBVOLT_SHIFT 6
+#define MAX77843_MUIC_STATUS3_VBADC_SHIFT 0
+#define MAX77843_MUIC_STATUS3_VDNMON_SHIFT 4
+#define MAX77843_MUIC_STATUS3_DNRES_SHIFT 5
+#define MAX77843_MUIC_STATUS3_MPNACK_SHIFT 6
+
+#define MAX77843_MUIC_STATUS1_ADC_MASK (0x1f << MAX77843_MUIC_STATUS1_ADC_SHIFT)
+#define MAX77843_MUIC_STATUS1_ADCERROR_MASK BIT(MAX77843_MUIC_STATUS1_ADCERROR_SHIFT)
+#define MAX77843_MUIC_STATUS1_ADC1K_MASK BIT(MAX77843_MUIC_STATUS1_ADC1K_SHIFT)
+#define MAX77843_MUIC_STATUS2_CHGTYP_MASK (0x7 << MAX77843_MUIC_STATUS2_CHGTYP_SHIFT)
+#define MAX77843_MUIC_STATUS2_CHGDETRUN_MASK BIT(MAX77843_MUIC_STATUS2_CHGDETRUN_SHIFT)
+#define MAX77843_MUIC_STATUS2_DCDTMR_MASK BIT(MAX77843_MUIC_STATUS2_DCDTMR_SHIFT)
+#define MAX77843_MUIC_STATUS2_DXOVP_MASK BIT(MAX77843_MUIC_STATUS2_DXOVP_SHIFT)
+#define MAX77843_MUIC_STATUS2_VBVOLT_MASK BIT(MAX77843_MUIC_STATUS2_VBVOLT_SHIFT)
+#define MAX77843_MUIC_STATUS3_VBADC_MASK (0xf << MAX77843_MUIC_STATUS3_VBADC_SHIFT)
+#define MAX77843_MUIC_STATUS3_VDNMON_MASK BIT(MAX77843_MUIC_STATUS3_VDNMON_SHIFT)
+#define MAX77843_MUIC_STATUS3_DNRES_MASK BIT(MAX77843_MUIC_STATUS3_DNRES_SHIFT)
+#define MAX77843_MUIC_STATUS3_MPNACK_MASK BIT(MAX77843_MUIC_STATUS3_MPNACK_SHIFT)
/* MAX77843 CONTROL register */
-#define CONTROL1_COMP1SW_SHIFT 0
-#define CONTROL1_COMP2SW_SHIFT 3
-#define CONTROL1_IDBEN_SHIFT 7
-#define CONTROL2_LOWPWR_SHIFT 0
-#define CONTROL2_ADCEN_SHIFT 1
-#define CONTROL2_CPEN_SHIFT 2
-#define CONTROL2_ACC_DET_SHIFT 5
-#define CONTROL2_USBCPINT_SHIFT 6
-#define CONTROL2_RCPS_SHIFT 7
-#define CONTROL3_JIGSET_SHIFT 0
-#define CONTROL4_ADCDBSET_SHIFT 0
-#define CONTROL4_USBAUTO_SHIFT 4
-#define CONTROL4_FCTAUTO_SHIFT 5
-#define CONTROL4_ADCMODE_SHIFT 6
-
-#define MAX77843_MUIC_CONTROL1_COMP1SW_MASK (0x7 << CONTROL1_COMP1SW_SHIFT)
-#define MAX77843_MUIC_CONTROL1_COMP2SW_MASK (0x7 << CONTROL1_COMP2SW_SHIFT)
-#define MAX77843_MUIC_CONTROL1_IDBEN_MASK BIT(CONTROL1_IDBEN_SHIFT)
-#define MAX77843_MUIC_CONTROL2_LOWPWR_MASK BIT(CONTROL2_LOWPWR_SHIFT)
-#define MAX77843_MUIC_CONTROL2_ADCEN_MASK BIT(CONTROL2_ADCEN_SHIFT)
-#define MAX77843_MUIC_CONTROL2_CPEN_MASK BIT(CONTROL2_CPEN_SHIFT)
-#define MAX77843_MUIC_CONTROL2_ACC_DET_MASK BIT(CONTROL2_ACC_DET_SHIFT)
-#define MAX77843_MUIC_CONTROL2_USBCPINT_MASK BIT(CONTROL2_USBCPINT_SHIFT)
-#define MAX77843_MUIC_CONTROL2_RCPS_MASK BIT(CONTROL2_RCPS_SHIFT)
-#define MAX77843_MUIC_CONTROL3_JIGSET_MASK (0x3 << CONTROL3_JIGSET_SHIFT)
-#define MAX77843_MUIC_CONTROL4_ADCDBSET_MASK (0x3 << CONTROL4_ADCDBSET_SHIFT)
-#define MAX77843_MUIC_CONTROL4_USBAUTO_MASK BIT(CONTROL4_USBAUTO_SHIFT)
-#define MAX77843_MUIC_CONTROL4_FCTAUTO_MASK BIT(CONTROL4_FCTAUTO_SHIFT)
-#define MAX77843_MUIC_CONTROL4_ADCMODE_MASK (0x3 << CONTROL4_ADCMODE_SHIFT)
+#define MAX77843_MUIC_CONTROL1_COMP1SW_SHIFT 0
+#define MAX77843_MUIC_CONTROL1_COMP2SW_SHIFT 3
+#define MAX77843_MUIC_CONTROL1_IDBEN_SHIFT 7
+#define MAX77843_MUIC_CONTROL2_LOWPWR_SHIFT 0
+#define MAX77843_MUIC_CONTROL2_ADCEN_SHIFT 1
+#define MAX77843_MUIC_CONTROL2_CPEN_SHIFT 2
+#define MAX77843_MUIC_CONTROL2_ACC_DET_SHIFT 5
+#define MAX77843_MUIC_CONTROL2_USBCPINT_SHIFT 6
+#define MAX77843_MUIC_CONTROL2_RCPS_SHIFT 7
+#define MAX77843_MUIC_CONTROL3_JIGSET_SHIFT 0
+#define MAX77843_MUIC_CONTROL4_ADCDBSET_SHIFT 0
+#define MAX77843_MUIC_CONTROL4_USBAUTO_SHIFT 4
+#define MAX77843_MUIC_CONTROL4_FCTAUTO_SHIFT 5
+#define MAX77843_MUIC_CONTROL4_ADCMODE_SHIFT 6
+
+#define MAX77843_MUIC_CONTROL1_COMP1SW_MASK (0x7 << MAX77843_MUIC_CONTROL1_COMP1SW_SHIFT)
+#define MAX77843_MUIC_CONTROL1_COMP2SW_MASK (0x7 << MAX77843_MUIC_CONTROL1_COMP2SW_SHIFT)
+#define MAX77843_MUIC_CONTROL1_IDBEN_MASK BIT(MAX77843_MUIC_CONTROL1_IDBEN_SHIFT)
+#define MAX77843_MUIC_CONTROL2_LOWPWR_MASK BIT(MAX77843_MUIC_CONTROL2_LOWPWR_SHIFT)
+#define MAX77843_MUIC_CONTROL2_ADCEN_MASK BIT(MAX77843_MUIC_CONTROL2_ADCEN_SHIFT)
+#define MAX77843_MUIC_CONTROL2_CPEN_MASK BIT(MAX77843_MUIC_CONTROL2_CPEN_SHIFT)
+#define MAX77843_MUIC_CONTROL2_ACC_DET_MASK BIT(MAX77843_MUIC_CONTROL2_ACC_DET_SHIFT)
+#define MAX77843_MUIC_CONTROL2_USBCPINT_MASK BIT(MAX77843_MUIC_CONTROL2_USBCPINT_SHIFT)
+#define MAX77843_MUIC_CONTROL2_RCPS_MASK BIT(MAX77843_MUIC_CONTROL2_RCPS_SHIFT)
+#define MAX77843_MUIC_CONTROL3_JIGSET_MASK (0x3 << MAX77843_MUIC_CONTROL3_JIGSET_SHIFT)
+#define MAX77843_MUIC_CONTROL4_ADCDBSET_MASK (0x3 << MAX77843_MUIC_CONTROL4_ADCDBSET_SHIFT)
+#define MAX77843_MUIC_CONTROL4_USBAUTO_MASK BIT(MAX77843_MUIC_CONTROL4_USBAUTO_SHIFT)
+#define MAX77843_MUIC_CONTROL4_FCTAUTO_MASK BIT(MAX77843_MUIC_CONTROL4_FCTAUTO_SHIFT)
+#define MAX77843_MUIC_CONTROL4_ADCMODE_MASK (0x3 << MAX77843_MUIC_CONTROL4_ADCMODE_SHIFT)
/* MAX77843 switch port */
#define COM_OPEN 0
@@ -383,38 +383,38 @@ enum max77843_irq_muic {
#define COM_AUX_USB 4
#define COM_AUX_UART 5
-#define CONTROL1_COM_SW \
+#define MAX77843_MUIC_CONTROL1_COM_SW \
((MAX77843_MUIC_CONTROL1_COMP1SW_MASK | \
MAX77843_MUIC_CONTROL1_COMP2SW_MASK))
-#define CONTROL1_SW_OPEN \
- ((COM_OPEN << CONTROL1_COMP1SW_SHIFT | \
- COM_OPEN << CONTROL1_COMP2SW_SHIFT))
-#define CONTROL1_SW_USB \
- ((COM_USB << CONTROL1_COMP1SW_SHIFT | \
- COM_USB << CONTROL1_COMP2SW_SHIFT))
-#define CONTROL1_SW_AUDIO \
- ((COM_AUDIO << CONTROL1_COMP1SW_SHIFT | \
- COM_AUDIO << CONTROL1_COMP2SW_SHIFT))
-#define CONTROL1_SW_UART \
- ((COM_UART << CONTROL1_COMP1SW_SHIFT | \
- COM_UART << CONTROL1_COMP2SW_SHIFT))
-#define CONTROL1_SW_AUX_USB \
- ((COM_AUX_USB << CONTROL1_COMP1SW_SHIFT | \
- COM_AUX_USB << CONTROL1_COMP2SW_SHIFT))
-#define CONTROL1_SW_AUX_UART \
- ((COM_AUX_UART << CONTROL1_COMP1SW_SHIFT | \
- COM_AUX_UART << CONTROL1_COMP2SW_SHIFT))
+#define MAX77843_MUIC_CONTROL1_SW_OPEN \
+ ((COM_OPEN << MAX77843_MUIC_CONTROL1_COMP1SW_SHIFT | \
+ COM_OPEN << MAX77843_MUIC_CONTROL1_COMP2SW_SHIFT))
+#define MAX77843_MUIC_CONTROL1_SW_USB \
+ ((COM_USB << MAX77843_MUIC_CONTROL1_COMP1SW_SHIFT | \
+ COM_USB << MAX77843_MUIC_CONTROL1_COMP2SW_SHIFT))
+#define MAX77843_MUIC_CONTROL1_SW_AUDIO \
+ ((COM_AUDIO << MAX77843_MUIC_CONTROL1_COMP1SW_SHIFT | \
+ COM_AUDIO << MAX77843_MUIC_CONTROL1_COMP2SW_SHIFT))
+#define MAX77843_MUIC_CONTROL1_SW_UART \
+ ((COM_UART << MAX77843_MUIC_CONTROL1_COMP1SW_SHIFT | \
+ COM_UART << MAX77843_MUIC_CONTROL1_COMP2SW_SHIFT))
+#define MAX77843_MUIC_CONTROL1_SW_AUX_USB \
+ ((COM_AUX_USB << MAX77843_MUIC_CONTROL1_COMP1SW_SHIFT | \
+ COM_AUX_USB << MAX77843_MUIC_CONTROL1_COMP2SW_SHIFT))
+#define MAX77843_MUIC_CONTROL1_SW_AUX_UART \
+ ((COM_AUX_UART << MAX77843_MUIC_CONTROL1_COMP1SW_SHIFT | \
+ COM_AUX_UART << MAX77843_MUIC_CONTROL1_COMP2SW_SHIFT))
#define MAX77843_DISABLE 0
#define MAX77843_ENABLE 1
#define CONTROL4_AUTO_DISABLE \
- ((MAX77843_DISABLE << CONTROL4_USBAUTO_SHIFT) | \
- (MAX77843_DISABLE << CONTROL4_FCTAUTO_SHIFT))
+ ((MAX77843_DISABLE << MAX77843_MUIC_CONTROL4_USBAUTO_SHIFT) | \
+ (MAX77843_DISABLE << MAX77843_MUIC_CONTROL4_FCTAUTO_SHIFT))
#define CONTROL4_AUTO_ENABLE \
- ((MAX77843_ENABLE << CONTROL4_USBAUTO_SHIFT) | \
- (MAX77843_ENABLE << CONTROL4_FCTAUTO_SHIFT))
+ ((MAX77843_ENABLE << MAX77843_MUIC_CONTROL4_USBAUTO_SHIFT) | \
+ (MAX77843_ENABLE << MAX77843_MUIC_CONTROL4_FCTAUTO_SHIFT))
/* MAX77843 SAFEOUT LDO Control register */
#define SAFEOUTCTRL_SAFEOUT1_SHIFT 0
@@ -431,24 +431,4 @@ enum max77843_irq_muic {
#define MAX77843_REG_SAFEOUTCTRL_SAFEOUT2_MASK \
(0x3 << SAFEOUTCTRL_SAFEOUT2_SHIFT)
-struct max77843 {
- struct device *dev;
-
- struct i2c_client *i2c;
- struct i2c_client *i2c_chg;
- struct i2c_client *i2c_fuel;
- struct i2c_client *i2c_muic;
-
- struct regmap *regmap;
- struct regmap *regmap_chg;
- struct regmap *regmap_fuel;
- struct regmap *regmap_muic;
-
- struct regmap_irq_chip_data *irq_data;
- struct regmap_irq_chip_data *irq_data_chg;
- struct regmap_irq_chip_data *irq_data_fuel;
- struct regmap_irq_chip_data *irq_data_muic;
-
- int irq;
-};
#endif /* __MAX77843_H__ */
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index f8a689ed62a5..2ba4a40919c8 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -550,6 +550,12 @@ static inline int regulator_count_voltages(struct regulator *regulator)
{
return 0;
}
+
+static inline int regulator_list_voltage(struct regulator *regulator, unsigned selector)
+{
+ return -EINVAL;
+}
+
#endif
static inline int regulator_set_voltage_tol(struct regulator *regulator,
diff --git a/include/linux/regulator/da9211.h b/include/linux/regulator/da9211.h
index 5dd65acc2a69..a43a5ca1167b 100644
--- a/include/linux/regulator/da9211.h
+++ b/include/linux/regulator/da9211.h
@@ -1,16 +1,16 @@
/*
- * da9211.h - Regulator device driver for DA9211/DA9213
- * Copyright (C) 2014 Dialog Semiconductor Ltd.
+ * da9211.h - Regulator device driver for DA9211/DA9213/DA9215
+ * Copyright (C) 2015 Dialog Semiconductor Ltd.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * 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.
*
- * This library is distributed in the hope that it will be useful,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*/
#ifndef __LINUX_REGULATOR_DA9211_H
@@ -23,6 +23,7 @@
enum da9211_chip_id {
DA9211,
DA9213,
+ DA9215,
};
struct da9211_pdata {