Commit cf9d615f authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'regulator-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator updates from Mark Brown:
 "The biggest changes in the core this time around have been some
  refactorings that move us towards being able to drop the list of
  regulators maintained by the core and instead just use the driver
  model list maintained for the class devices for regulators which will
  make the code smaller and avoid some potential bugs.

  Otherwise another fairly quiet release for the regulator API,
  highlights include:

   - a new API for setting voltages based on a minimum, target, maximum
     triplet

   - support for continuous voltage ranges rather than tables of
     explicit steps in the PWM regulator, requiring less explicit
     configuration

   - new driver support for Dialog DA9215, Maxim 77843, Mediatek MT6311
     and Qualcomm RPM"

* tag 'regulator-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (70 commits)
  regulator: mt6311: fix platform_no_drv_owner.cocci warnings
  regulator: ltc3589: Remove unnecessary MODULE_ALIAS()
  regulator: ad5398: Remove unnecessary MODULE_ALIAS()
  regulator: pfuze100: Remove unnecessary MODULE_ALIAS()
  regulator: core: use debug level print in regulator_check_drms
  regulator: lp872x: handle error case
  regulator: lp872x: use the private data instead of updating I2C device platform data
  regulator: isl9305: Export OF module alias information
  regulators: max77693: register driver earlier to avoid deferred probe
  regulator: qcom_smd: Set n_voltages for pm8941_lnldo
  regulator: core: Use IS_ERR_OR_NULL()
  regulator: core: Define regulator_set_voltage_triplet()
  regulator: Regulator driver for the Qualcomm RPM
  regulator: pbias: Fix broken pbias disable functionality
  regulator: core: Spelling fix
  regulator: core: Use class device list for regulator_list in late init
  regulator: core: Move more deallocation into class unregister
  regulator: core: Reduce rdev locking region when releasing regulator
  Input: Remove the max77843 haptic driver
  Input: max77693: Add support for Maxim 77843
  ...
parents e2701603 f5164b88
......@@ -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;
......
......@@ -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.
......
* 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>;
};
};
};
......@@ -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:
......
Mediatek MT6311 Regulator Driver
Required properties:
- compatible: "mediatek,mt6311-regulator"
- reg: I2C slave address, usually 0x6b.
- regulators: List of regulators provided by this controller. It is named
to VDVFS and VBIASN.
The definition for each of these nodes is defined using the standard binding
for regulators at Documentation/devicetree/bindings/regulator/regulator.txt.
The valid names for regulators are:
BUCK:
VDVFS
LDO:
VBIASN
Example:
mt6311: pmic@6b {
compatible = "mediatek,mt6311-regulator";
reg = <0x6b>;
regulators {
mt6311_vcpu_reg: VDVFS {
regulator-name = "VDVFS";
regulator-min-microvolt = < 600000>;
regulator-max-microvolt = <1400000>;
regulator-ramp-delay = <10000>;
};
mt6311_ldo_reg: VBIASN {
regulator-name = "VBIASN";
regulator-min-microvolt = <200000>;
regulator-max-microvolt = <800000>;
};
};
};
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";
};
......@@ -91,13 +91,65 @@ see regulator.txt - with additional custom properties described below:
- regulator-initial-mode:
Usage: optional
Value type: <u32>
Descrption: 1 = Set initial mode to high power mode (HPM), also referred
to as NPM. HPM consumes more ground current than LPM, but
Description: 2 = Set initial mode to auto mode (automatically select
between HPM and LPM); not available on boost type
regulators.
1 = Set initial mode to high power mode (HPM), also referred
to as NPM. HPM consumes more ground current than LPM, but
it can source significantly higher load current. HPM is not
available on boost type regulators. For voltage switch type
regulators, HPM implies that over current protection and
soft start are active all the time. 0 = Set initial mode to
low power mode (LPM).
soft start are active all the time.
0 = Set initial mode to low power mode (LPM).
- qcom,ocp-max-retries:
Usage: optional
Value type: <u32>
Description: Maximum number of times to try toggling a voltage switch
off and back on as a result of consecutive over current
events.
- qcom,ocp-retry-delay:
Usage: optional
Value type: <u32>
Description: Time to delay in milliseconds between each voltage switch
toggle after an over current event takes place.
- qcom,pin-ctrl-enable:
Usage: optional
Value type: <u32>
Description: Bit mask specifying which hardware pins should be used to
enable the regulator, if any; supported bits are:
0 = ignore all hardware enable signals
BIT(0) = follow HW0_EN signal
BIT(1) = follow HW1_EN signal
BIT(2) = follow HW2_EN signal
BIT(3) = follow HW3_EN signal
- qcom,pin-ctrl-hpm:
Usage: optional
Value type: <u32>
Description: Bit mask specifying which hardware pins should be used to
force the regulator into high power mode, if any;
supported bits are:
0 = ignore all hardware enable signals
BIT(0) = follow HW0_EN signal
BIT(1) = follow HW1_EN signal
BIT(2) = follow HW2_EN signal
BIT(3) = follow HW3_EN signal
BIT(4) = follow PMIC awake state
- qcom,vs-soft-start-strength:
Usage: optional
Value type: <u32>
Description: This property sets the soft start strength for voltage
switch type regulators; supported values are:
0 = 0.05 uA
1 = 0.25 uA
2 = 0.55 uA
3 = 0.75 uA
Example:
......
......@@ -42,6 +42,7 @@ Optional properties:
- regulator-system-load: Load in uA present on regulator that is not captured by
any consumer request.
- regulator-pull-down: Enable pull down resistor when the regulator is disabled.
- regulator-over-current-protection: Enable over current protection.
Deprecated properties:
- regulator-compatible: If a regulator chip contains multiple
......
......@@ -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);
}
......
......@@ -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 @@ static void max77843_muic_detect_cable_wq(struct work_struct *work)
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 @@ static int max77843_init_muic_regmap(struct max77843 *max77843)
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);
......@@ -830,7 +846,7 @@ static int max77843_muic_probe(struct platform_device *pdev)
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);
......
......@@ -167,28 +167,16 @@ config INPUT_M68K_BEEP
depends on M68K
config INPUT_MAX77693_HAPTIC
tristate "MAXIM MAX77693 haptic controller support"
depends on MFD_MAX77693 && PWM
tristate "MAXIM MAX77693/MAX77843 haptic controller support"
depends on (MFD_MAX77693 || MFD_MAX77843) && PWM
select INPUT_FF_MEMLESS
help
This option enables support for the haptic controller on
MAXIM MAX77693 chip.
MAXIM MAX77693 and MAX77843 chips.
To compile this driver as module, choose M here: the
module will be called max77693-haptic.
config INPUT_MAX77843_HAPTIC
tristate "MAXIM MAX77843 haptic controller support"
depends on MFD_MAX77843 && REGULATOR
select INPUT_FF_MEMLESS
help
This option enables support for the haptic controller on
MAXIM MAX77843 chip. The driver supports ff-memless interface
from input framework.
To compile this driver as module, choose M here: the
module will be called max77843-haptic.
config INPUT_MAX8925_ONKEY
tristate "MAX8925 ONKEY support"
depends on MFD_MAX8925
......
......@@ -41,7 +41,6 @@ obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
obj-$(CONFIG_INPUT_MAX77693_HAPTIC) += max77693-haptic.o
obj-$(CONFIG_INPUT_MAX77843_HAPTIC) += max77843-haptic.o
obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o
obj-$(CONFIG_INPUT_MAX8997_HAPTIC) += max8997_haptic.o
obj-$(CONFIG_INPUT_MC13783_PWRBUTTON) += mc13783-pwrbutton.o
......
/*
* MAXIM MAX77693 Haptic device driver
* MAXIM MAX77693/MAX77843 Haptic device driver
*
* Copyright (C) 2014 Samsung Electronics
* Copyright (C) 2014,2015 Samsung Electronics
* Jaewon Kim <jaewon02.kim@samsung.com>
* Krzysztof Kozlowski <k.kozlowski@samsung.com>
*
* This program is not provided / owned by Maxim Integrated Products.
*
......@@ -24,7 +25,9 @@
#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>
#include <linux/mfd/max77843-private.h>
#define MAX_MAGNITUDE_SHIFT 16
......@@ -46,6 +49,8 @@ enum max77693_haptic_pwm_divisor {
};
struct max77693_haptic {
enum max77693_types dev_type;
struct regmap *regmap_pmic;
struct regmap *regmap_haptic;
struct device *dev;
......@@ -59,7 +64,6 @@ struct max77693_haptic {
unsigned int pwm_duty;
enum max77693_haptic_motor_type type;
enum max77693_haptic_pulse_mode mode;
enum max77693_haptic_pwm_divisor pwm_divisor;
struct work_struct work;
};
......@@ -78,19 +82,52 @@ static int max77693_haptic_set_duty_cycle(struct max77693_haptic *haptic)
return 0;
}
static int max77843_haptic_bias(struct max77693_haptic *haptic, bool on)
{
int error;
if (haptic->dev_type != TYPE_MAX77843)
return 0;
error = regmap_update_bits(haptic->regmap_haptic,
MAX77843_SYS_REG_MAINCTRL1,
MAX77843_MAINCTRL1_BIASEN_MASK,
on << MAINCTRL1_BIASEN_SHIFT);
if (error) {
dev_err(haptic->dev, "failed to %s bias: %d\n",
on ? "enable" : "disable", error);
return error;
}
return 0;
}
static int max77693_haptic_configure(struct max77693_haptic *haptic,
bool enable)
{
unsigned int value;
unsigned int value, config_reg;
int error;
value = ((haptic->type << MAX77693_CONFIG2_MODE) |
(enable << MAX77693_CONFIG2_MEN) |
(haptic->mode << MAX77693_CONFIG2_HTYP) |
(haptic->pwm_divisor));
switch (haptic->dev_type) {
case TYPE_MAX77693:
value = ((haptic->type << MAX77693_CONFIG2_MODE) |
(enable << MAX77693_CONFIG2_MEN) |
(haptic->mode << MAX77693_CONFIG2_HTYP) |
MAX77693_HAPTIC_PWM_DIVISOR_128);
config_reg = MAX77693_HAPTIC_REG_CONFIG2;
break;
case TYPE_MAX77843:
value = (haptic->type << MCONFIG_MODE_SHIFT) |
(enable << MCONFIG_MEN_SHIFT) |
MAX77693_HAPTIC_PWM_DIVISOR_128;
config_reg = MAX77843_HAP_REG_MCONFIG;
break;
default:
return -EINVAL;
}
error = regmap_write(haptic->regmap_haptic,
MAX77693_HAPTIC_REG_CONFIG2, value);
config_reg, value);
if (error) {
dev_err(haptic->dev,
"failed to update haptic config: %d\n", error);
......@@ -104,6 +141,9 @@ static int max77693_haptic_lowsys(struct max77693_haptic *haptic, bool enable)
{
int error;
if (haptic->dev_type != TYPE_MAX77693)
return 0;
error = regmap_update_bits(haptic->regmap_pmic,
MAX77693_PMIC_REG_LSCNFG,
MAX77693_PMIC_LOW_SYS_MASK,
......@@ -219,6 +259,10 @@ static int max77693_haptic_open(struct input_dev *dev)
struct max77693_haptic *haptic = input_get_drvdata(dev);
int error;
error = max77843_haptic_bias(haptic, true);
if (error)
return error;
error = regulator_enable(haptic->motor_reg);
if (error) {
dev_err(haptic->dev,
......@@ -241,6 +285,8 @@ static void max77693_haptic_close(struct input_dev *dev)
if (error)
dev_err(haptic->dev,
"failed to disable regulator: %d\n", error);
max77843_haptic_bias(haptic, false);
}
static int max77693_haptic_probe(struct platform_device *pdev)
......@@ -254,13 +300,26 @@ static int max77693_haptic_probe(struct platform_device *pdev)
return -ENOMEM;
haptic->regmap_pmic = max77693->regmap;
haptic->regmap_haptic = max77693->regmap_haptic;
haptic->dev = &pdev->dev;
haptic->type = MAX77693_HAPTIC_LRA;
haptic->mode = MAX77693_HAPTIC_EXTERNAL_MODE;
haptic->pwm_divisor = MAX77693_HAPTIC_PWM_DIVISOR_128;
haptic->suspend_state = false;
/* Variant-specific init */
haptic->dev_type = platform_get_device_id(pdev)->driver_data;
switch (haptic->dev_type) {
case TYPE_MAX77693:
haptic->regmap_haptic = max77693->regmap_haptic;
break;
case TYPE_MAX77843:
haptic->regmap_haptic = max77693->regmap;
break;
default:
dev_err(&pdev->dev, "unsupported device type: %u\n",
haptic->dev_type);
return -EINVAL;
}
INIT_WORK(&haptic->work, max77693_haptic_play_work);
/* Get pwm and regulatot for haptic device */
......@@ -338,16 +397,25 @@ static int __maybe_unused max77693_haptic_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(max77693_haptic_pm_ops,
max77693_haptic_suspend, max77693_haptic_resume);
static const struct platform_device_id max77693_haptic_id[] = {
{ "max77693-haptic", TYPE_MAX77693 },
{ "max77843-haptic", TYPE_MAX77843 },
{},
};
MODULE_DEVICE_TABLE(platform, max77693_haptic_id);
static struct platform_driver max77693_haptic_driver = {
.driver = {
.name = "max77693-haptic",
.pm = &max77693_haptic_pm_ops,
},
.probe = max77693_haptic_probe,
.id_table = max77693_haptic_id,
};
module_platform_driver(max77693_haptic_driver);
MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
MODULE_DESCRIPTION("MAXIM MAX77693 Haptic driver");
MODULE_AUTHOR("Krzysztof Kozlowski <k.kozlowski@samsung.com>");
MODULE_DESCRIPTION("MAXIM 77693/77843 Haptic driver");
MODULE_ALIAS("platform:max77693-haptic");
MODULE_LICENSE("GPL");
/*
* MAXIM MAX77693 Haptic device driver
*
* Copyright (C) 2015 Samsung Electronics
* Author: Jaewon Kim <jaewon02.kim@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/err.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/mfd/max77843-private.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#define MAX_MAGNITUDE_SHIFT 16
enum max77843_haptic_motor_type {
MAX77843_HAPTIC_ERM = 0,
MAX77843_HAPTIC_LRA,
};
enum max77843_haptic_pwm_divisor {
MAX77843_HAPTIC_PWM_DIVISOR_32 = 0,
MAX77843_HAPTIC_PWM_DIVISOR_64,
MAX77843_HAPTIC_PWM_DIVISOR_128,
MAX77843_HAPTIC_PWM_DIVISOR_256,
};
struct max77843_haptic {
struct regmap *regmap_haptic;
struct device *dev;
struct input_dev *input_dev;
struct pwm_device *pwm_dev;
struct regulator *motor_reg;
struct work_struct work;
struct mutex mutex;
unsigned int magnitude;
unsigned int pwm_duty;
bool active;
bool suspended;
enum max77843_haptic_motor_type type;
enum max77843_haptic_pwm_divisor pwm_divisor;
};
static int max77843_haptic_set_duty_cycle(struct max77843_haptic *haptic)
{
int delta = (haptic->pwm_dev->period + haptic->pwm_duty) / 2;
int error;
error = pwm_config(haptic->pwm_dev, delta, haptic->pwm_dev->period);
if (error) {
dev_err(haptic->dev, "failed to configure pwm: %d\n", error);
return error;
}
return 0;
}
static int max77843_haptic_bias(struct max77843_haptic *haptic, bool on)
{
int error;
error = regmap_update_bits(haptic->regmap_haptic,
MAX77843_SYS_REG_MAINCTRL1,
MAX77843_MAINCTRL1_BIASEN_MASK,
on << MAINCTRL1_BIASEN_SHIFT);
if (error) {
dev_err(haptic->dev, "failed to %s bias: %d\n",
on ? "enable" : "disable", error);
return error;
}
return 0;
}
static int max77843_haptic_config(struct max77843_haptic *haptic, bool enable)
{
unsigned int value;
int error;
value = (haptic->type << MCONFIG_MODE_SHIFT) |
(enable << MCONFIG_MEN_SHIFT) |
(haptic->pwm_divisor << MCONFIG_PDIV_SHIFT);
error = regmap_write(haptic->regmap_haptic,
MAX77843_HAP_REG_MCONFIG, value);
if (error) {
dev_err(haptic->dev,
"failed to update haptic config: %d\n", error);
return error;
}
return 0;
}
static int max77843_haptic_enable(struct max77843_haptic *haptic)
{
int error;
if (haptic->active)
return 0;
error = pwm_enable(haptic->pwm_dev);
if (error) {
dev_err(haptic->dev,
"failed to enable pwm device: %d\n", error);
return error;
}
error = max77843_haptic_config(haptic, true);
if (error)
goto err_config;
haptic->active = true;
return 0;
err_config:
pwm_disable(haptic->pwm_dev);
return error;
}
static int max77843_haptic_disable(struct max77843_haptic *haptic)
{
int error;
if (!haptic->active)
return 0;
error = max77843_haptic_config(haptic, false);
if (error)
return error;
pwm_disable(haptic->pwm_dev);
haptic->active = false;
return 0;
}
static void max77843_haptic_play_work(struct work_struct *work)
{
struct max77843_haptic *haptic =
container_of(work, struct max77843_haptic, work);
int error;
mutex_lock(&haptic->mutex);
if (haptic->suspended)
goto out_unlock;
if (haptic->magnitude) {
error = max77843_haptic_set_duty_cycle(haptic);
if (error) {
dev_err(haptic->dev,
"failed to set duty cycle: %d\n", error);
goto out_unlock;
}
error = max77843_haptic_enable(haptic);
if (error)
dev_err(haptic->dev,
"cannot enable haptic: %d\n", error);
} else {
error = max77843_haptic_disable(haptic);
if (error)
dev_err(haptic->dev,
"cannot disable haptic: %d\n", error);
}
out_unlock:
mutex_unlock(&haptic->mutex);
}
static int max77843_haptic_play_effect(struct input_dev *dev, void *data,
struct ff_effect *effect)
{
struct max77843_haptic *haptic = input_get_drvdata(dev);
u64 period_mag_multi;
haptic->magnitude = effect->u.rumble.strong_magnitude;
if (!haptic->magnitude)
haptic->magnitude = effect->u.rumble.weak_magnitude;
period_mag_multi = (u64)haptic->pwm_dev->period * haptic->magnitude;
haptic->pwm_duty = (unsigned int)(period_mag_multi >>
MAX_MAGNITUDE_SHIFT);
schedule_work(&haptic->work);
return 0;
}
static int max77843_haptic_open(struct input_dev *dev)
{
struct max77843_haptic *haptic = input_get_drvdata(dev);
int error;
error = max77843_haptic_bias(haptic, true);
if (error)
return error;
error = regulator_enable(haptic->motor_reg);
if (error) {
dev_err(haptic->dev,
"failed to enable regulator: %d\n", error);
return error;
}
return 0;
}
static void max77843_haptic_close(struct input_dev *dev)
{
struct max77843_haptic *haptic = input_get_drvdata(dev);
int error;
cancel_work_sync(&haptic->work);
max77843_haptic_disable(haptic);
error = regulator_disable(haptic->motor_reg);
if (error)
dev_err(haptic->dev,
"failed to disable regulator: %d\n", error);
max77843_haptic_bias(haptic, false);
}
static int max77843_haptic_probe(struct platform_device *pdev)
{
struct max77843 *max77843 = dev_get_drvdata(pdev->dev.parent);
struct max77843_haptic *haptic;
int error;
haptic = devm_kzalloc(&pdev->dev, sizeof(*haptic), GFP_KERNEL);
if (!haptic)
return -ENOMEM;
haptic->regmap_haptic = max77843->regmap;
haptic->dev = &pdev->dev;
haptic->type = MAX77843_HAPTIC_LRA;
haptic->pwm_divisor = MAX77843_HAPTIC_PWM_DIVISOR_128;
INIT_WORK(&haptic->work, max77843_haptic_play_work);
mutex_init(&haptic->mutex);
haptic->pwm_dev = devm_pwm_get(&pdev->dev, NULL);
if (IS_ERR(haptic->pwm_dev)) {
dev_err(&pdev->dev, "failed to get pwm device\n");
return PTR_ERR(haptic->pwm_dev);
}
haptic->motor_reg = devm_regulator_get_exclusive(&pdev->dev, "haptic");
if (IS_ERR(haptic->motor_reg)) {
dev_err(&pdev->dev, "failed to get regulator\n");
return PTR_ERR(haptic->motor_reg);
}
haptic->input_dev = devm_input_allocate_device(&pdev->dev);
if (!haptic->input_dev) {
dev_err(&pdev->dev, "failed to allocate input device\n");
return -ENOMEM;
}
haptic->input_dev->name = "max77843-haptic";
haptic->input_dev->id.version = 1;
haptic->input_dev->dev.parent = &pdev->dev;
haptic->input_dev->open = max77843_haptic_open;
haptic->input_dev->close = max77843_haptic_close;
input_set_drvdata(haptic->input_dev, haptic);
input_set_capability(haptic->input_dev, EV_FF, FF_RUMBLE);
error = input_ff_create_memless(haptic->input_dev, NULL,
max77843_haptic_play_effect);
if (error) {
dev_err(&pdev->dev, "failed to create force-feedback\n");
return error;
}
error = input_register_device(haptic->input_dev);
if (error) {
dev_err(&pdev->dev, "failed to register input device\n");
return error;
}
platform_set_drvdata(pdev, haptic);
return 0;
}
static int __maybe_unused max77843_haptic_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct max77843_haptic *haptic = platform_get_drvdata(pdev);
int error;
error = mutex_lock_interruptible(&haptic->mutex);
if (error)
return error;
max77843_haptic_disable(haptic);
haptic->suspended = true;
mutex_unlock(&haptic->mutex);
return 0;
}
static int __maybe_unused max77843_haptic_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct max77843_haptic *haptic = platform_get_drvdata(pdev);
unsigned int magnitude;
mutex_lock(&haptic->mutex);
haptic->suspended = false;
magnitude = ACCESS_ONCE(haptic->magnitude);
if (magnitude)
max77843_haptic_enable(haptic);
mutex_unlock(&haptic->mutex);
return 0;
}
static SIMPLE_DEV_PM_OPS(max77843_haptic_pm_ops,
max77843_haptic_suspend, max77843_haptic_resume);
static struct platform_driver max77843_haptic_driver = {
.driver = {
.name = "max77843-haptic",
.pm = &max77843_haptic_pm_ops,
},
.probe = max77843_haptic_probe,
};
module_platform_driver(max77843_haptic_driver);
MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>");
MODULE_DESCRIPTION("MAXIM MAX77843 Haptic driver");
MODULE_LICENSE("GPL");
......@@ -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>
......
......@@ -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 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
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;
}
......
......@@ -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 @@ static int max77843_chg_init(struct max77843 *max77843)
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);
......
......@@ -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"
......
......@@ -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 = 0xf, \
.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);
......
......@@ -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
......@@ -451,6 +443,15 @@ config REGULATOR_MC13892
Say y here to support the regulators found on the Freescale MC13892
PMIC.
config REGULATOR_MT6311
tristate "MediaTek MT6311 PMIC"
depends on I2C
help
Say y here to select this option to enable the power regulator of
MediaTek MT6311 PMIC.
This driver supports the control of different power rails of device
through regulator interface.
config REGULATOR_MT6397
tristate "MediaTek MT6397 PMIC"
depends on MFD_MT6397
......@@ -522,6 +523,18 @@ config REGULATOR_QCOM_RPM
Qualcomm RPM as a module. The module will be named
"qcom_rpm-regulator".
config REGULATOR_QCOM_SMD_RPM
tristate "Qualcomm SMD based RPM regulator driver"
depends on QCOM_SMD_RPM
help
If you say yes to this option, support will be included for the
regulators exposed by the Resource Power Manager found in Qualcomm
8974 based devices.
Say M here if you want to include support for the regulators on the
Qualcomm RPM as a module. The module will be named
"qcom_smd-regulator".
config REGULATOR_QCOM_SPMI
tristate "Qualcomm SPMI regulator driver"
depends on SPMI || COMPILE_TEST
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment