summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/extcon/extcon-max77693.c94
-rw-r--r--drivers/extcon/extcon-max77843.c66
-rw-r--r--drivers/input/misc/Kconfig18
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/misc/max77693-haptic.c92
-rw-r--r--drivers/input/misc/max77843-haptic.c358
-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/Kconfig16
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/lp872x.c16
-rw-r--r--drivers/regulator/ltc3589.c3
-rw-r--r--drivers/regulator/max77693.c173
-rw-r--r--drivers/regulator/max77843.c201
-rw-r--r--drivers/regulator/max8973-regulator.c80
17 files changed, 439 insertions, 733 deletions
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/Kconfig b/drivers/input/misc/Kconfig
index d4f0a817e858..c41dec819cdf 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -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
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 53df07dcc23c..0357a088c6a9 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -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
diff --git a/drivers/input/misc/max77693-haptic.c b/drivers/input/misc/max77693-haptic.c
index 39e930c10ebb..6d96bff32a0e 100644
--- a/drivers/input/misc/max77693-haptic.c
+++ b/drivers/input/misc/max77693-haptic.c
@@ -1,8 +1,9 @@
/*
- * 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");
diff --git a/drivers/input/misc/max77843-haptic.c b/drivers/input/misc/max77843-haptic.c
deleted file mode 100644
index dccbb465a055..000000000000
--- a/drivers/input/misc/max77843-haptic.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * 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");
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/Kconfig b/drivers/regulator/Kconfig
index 23496da101de..a7b81f0185b5 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -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/lp872x.c b/drivers/regulator/lp872x.c
index 3de328ab41f3..8702e7384af7 100644
--- a/drivers/regulator/lp872x.c
+++ b/drivers/regulator/lp872x.c
@@ -849,7 +849,7 @@ static struct lp872x_platform_data
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
- goto out;
+ return ERR_PTR(-ENOMEM);
of_property_read_u8(np, "ti,general-config", &pdata->general_config);
if (of_find_property(np, "ti,update-config", NULL))
@@ -857,7 +857,7 @@ static struct lp872x_platform_data
pdata->dvs = devm_kzalloc(dev, sizeof(struct lp872x_dvs), GFP_KERNEL);
if (!pdata->dvs)
- goto out;
+ return ERR_PTR(-ENOMEM);
pdata->dvs->gpio = of_get_named_gpio(np, "ti,dvs-gpio", 0);
of_property_read_u8(np, "ti,dvs-vsel", (u8 *)&pdata->dvs->vsel);
@@ -903,15 +903,21 @@ static struct lp872x_platform_data
static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
{
struct lp872x *lp;
+ struct lp872x_platform_data *pdata;
int ret;
const int lp872x_num_regulators[] = {
[LP8720] = LP8720_NUM_REGULATORS,
[LP8725] = LP8725_NUM_REGULATORS,
};
- if (cl->dev.of_node)
- cl->dev.platform_data = lp872x_populate_pdata_from_dt(&cl->dev,
+ if (cl->dev.of_node) {
+ pdata = lp872x_populate_pdata_from_dt(&cl->dev,
(enum lp872x_id)id->driver_data);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+ } else {
+ pdata = dev_get_platdata(&cl->dev);
+ }
lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL);
if (!lp)
@@ -927,7 +933,7 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
}
lp->dev = &cl->dev;
- lp->pdata = dev_get_platdata(&cl->dev);
+ lp->pdata = pdata;
lp->chipid = id->driver_data;
i2c_set_clientdata(cl, lp);
diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c
index 0ce8e4e0fa73..cc22ac66c8fd 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 },
@@ -552,4 +552,3 @@ module_i2c_driver(ltc3589_driver);
MODULE_AUTHOR("Philipp Zabel <p.zabel@pengutronix.de>");
MODULE_DESCRIPTION("Regulator driver for Linear Technology LTC3589(-1,2)");
MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("i2c:ltc3589");
diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c
index 38722c8311a5..de730fd3f8a5 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 },
{},
};
@@ -184,8 +300,19 @@ static struct platform_driver max77693_pmic_driver = {
.id_table = max77693_pmic_id,
};
-module_platform_driver(max77693_pmic_driver);
+static int __init max77693_pmic_init(void)
+{
+ return platform_driver_register(&max77693_pmic_driver);
+}
+subsys_initcall(max77693_pmic_init);
+
+static void __exit max77693_pmic_cleanup(void)
+{
+ platform_driver_unregister(&max77693_pmic_driver);
+}
+module_exit(max77693_pmic_cleanup);
-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/max8973-regulator.c b/drivers/regulator/max8973-regulator.c
index e94ddcf97722..8857cc02d9a8 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)
@@ -452,6 +504,23 @@ static struct max8973_regulator_platform_data *max8973_parse_dt(
if (of_property_read_bool(np, "maxim,enable-bias-control"))
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;
}
@@ -568,6 +637,15 @@ static int max8973_probe(struct i2c_client *client,
max->lru_index[i] = i;
max->lru_index[0] = max->curr_vout_reg;
max->lru_index[max->curr_vout_reg] = 0;
+ } else {
+ /*
+ * If there is no DVS GPIO, the VOUT register
+ * address is fixed.
+ */
+ max->ops.set_voltage_sel = regulator_set_voltage_sel_regmap;
+ max->ops.get_voltage_sel = regulator_get_voltage_sel_regmap;
+ max->desc.vsel_reg = max->curr_vout_reg;
+ max->desc.vsel_mask = MAX8973_VOUT_MASK;
}
if (pdata_from_dt)
@@ -613,6 +691,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;