Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
28120bf8
Commit
28120bf8
authored
Jul 01, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regulator/fix/max77693' into regulator-linus
parents
8bb495e3
8c7e7ddf
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
418 additions
and
0 deletions
+418
-0
Documentation/devicetree/bindings/mfd/max77693.txt
Documentation/devicetree/bindings/mfd/max77693.txt
+55
-0
drivers/regulator/Kconfig
drivers/regulator/Kconfig
+9
-0
drivers/regulator/Makefile
drivers/regulator/Makefile
+1
-0
drivers/regulator/max77693.c
drivers/regulator/max77693.c
+322
-0
include/linux/mfd/max77693-private.h
include/linux/mfd/max77693-private.h
+13
-0
include/linux/mfd/max77693.h
include/linux/mfd/max77693.h
+18
-0
No files found.
Documentation/devicetree/bindings/mfd/max77693.txt
0 → 100644
View file @
28120bf8
Maxim MAX77693 multi-function device
MAX77693 is a Multifunction device with the following submodules:
- PMIC,
- CHARGER,
- LED,
- MUIC,
- HAPTIC
It is interfaced to host controller using i2c.
This document describes the bindings for the mfd device.
Required properties:
- compatible : Must be "maxim,max77693".
- reg : Specifies the i2c slave address of PMIC block.
- interrupts : This i2c device has an IRQ line connected to the main SoC.
- interrupt-parent : The parent interrupt controller.
Optional properties:
- regulators : The regulators of max77693 have to be instantiated under subnod
named "regulators" using the following format.
regulators {
regualtor-compatible = ESAFEOUT1/ESAFEOUT2/CHARGER
standard regulator constratints[*].
};
[*] refer Documentation/devicetree/bindings/regulator/regulator.txt
Example:
max77693@66 {
compatible = "maxim,max77693";
reg = <0x66>;
interrupt-parent = <&gpx1>;
interrupts = <5 2>;
regulators {
esafeout@1 {
regulator-compatible = "ESAFEOUT1";
regulator-name = "ESAFEOUT1";
regulator-boot-on;
};
esafeout@2 {
regulator-compatible = "ESAFEOUT2";
regulator-name = "ESAFEOUT2";
};
charger@0 {
regulator-compatible = "CHARGER";
regulator-name = "CHARGER";
regulator-min-microamp = <60000>;
regulator-max-microamp = <2580000>;
regulator-boot-on;
};
};
};
drivers/regulator/Kconfig
View file @
28120bf8
...
...
@@ -250,6 +250,15 @@ config REGULATOR_MAX77686
via I2C bus. The provided regulator is suitable for
Exynos-4 chips to control VARM and VINT voltages.
config REGULATOR_MAX77693
tristate "Maxim MAX77693 regulator"
depends on MFD_MAX77693
help
This driver controls a Maxim 77693 regulator via I2C bus.
The regulators include two LDOs, 'SAFEOUT1', 'SAFEOUT2'
and one current regulator 'CHARGER'. This is suitable for
Exynos-4x12 chips.
config REGULATOR_PCAP
tristate "Motorola PCAP2 regulator driver"
depends on EZX_PCAP
...
...
drivers/regulator/Makefile
View file @
28120bf8
...
...
@@ -41,6 +41,7 @@ obj-$(CONFIG_REGULATOR_MAX8973) += max8973-regulator.o
obj-$(CONFIG_REGULATOR_MAX8997)
+=
max8997.o
obj-$(CONFIG_REGULATOR_MAX8998)
+=
max8998.o
obj-$(CONFIG_REGULATOR_MAX77686)
+=
max77686.o
obj-$(CONFIG_REGULATOR_MAX77693)
+=
max77693.o
obj-$(CONFIG_REGULATOR_MC13783)
+=
mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892)
+=
mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE)
+=
mc13xxx-regulator-core.o
...
...
drivers/regulator/max77693.c
0 → 100644
View file @
28120bf8
/*
* max77693.c - Regulator driver for the Maxim 77693
*
* Copyright (C) 2013 Samsung Electronics
* Jonghwa Lee <jonghwa3.lee@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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This driver is based on max77686.c
*/
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/export.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/max77693.h>
#include <linux/mfd/max77693-private.h>
#include <linux/regulator/of_regulator.h>
#define CHGIN_ILIM_STEP_20mA 20000
struct
max77693_pmic_dev
{
struct
device
*
dev
;
struct
max77693_dev
*
iodev
;
int
num_regulators
;
struct
regulator_dev
**
rdev
;
};
/* CHARGER regulator ops */
/* CHARGER regulator uses two bits for enabling */
static
int
max77693_chg_is_enabled
(
struct
regulator_dev
*
rdev
)
{
int
ret
;
u8
val
;
ret
=
max77693_read_reg
(
rdev
->
regmap
,
rdev
->
desc
->
enable_reg
,
&
val
);
if
(
ret
)
return
ret
;
return
(
val
&
rdev
->
desc
->
enable_mask
)
==
rdev
->
desc
->
enable_mask
;
}
/*
* CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA
* 0x00, 0x01, 0x2, 0x03 = 60 mA
* 0x04 ~ 0x7E = (60 + (X - 3) * 20) mA
*/
static
int
max77693_chg_get_current_limit
(
struct
regulator_dev
*
rdev
)
{
unsigned
int
chg_min_uA
=
rdev
->
constraints
->
min_uA
;
unsigned
int
chg_max_uA
=
rdev
->
constraints
->
max_uA
;
u8
reg
,
sel
;
unsigned
int
val
;
int
ret
;
ret
=
max77693_read_reg
(
rdev
->
regmap
,
MAX77693_CHG_REG_CHG_CNFG_09
,
&
reg
);
if
(
ret
<
0
)
return
ret
;
sel
=
reg
&
CHG_CNFG_09_CHGIN_ILIM_MASK
;
/* the first four codes for charger current are all 60mA */
if
(
sel
<=
3
)
sel
=
0
;
else
sel
-=
3
;
val
=
chg_min_uA
+
CHGIN_ILIM_STEP_20mA
*
sel
;
if
(
val
>
chg_max_uA
)
return
-
EINVAL
;
return
val
;
}
static
int
max77693_chg_set_current_limit
(
struct
regulator_dev
*
rdev
,
int
min_uA
,
int
max_uA
)
{
unsigned
int
chg_min_uA
=
rdev
->
constraints
->
min_uA
;
int
sel
=
0
;
while
(
chg_min_uA
+
CHGIN_ILIM_STEP_20mA
*
sel
<
min_uA
)
sel
++
;
if
(
chg_min_uA
+
CHGIN_ILIM_STEP_20mA
*
sel
>
max_uA
)
return
-
EINVAL
;
/* the first four codes for charger current are all 60mA */
sel
+=
3
;
return
max77693_write_reg
(
rdev
->
regmap
,
MAX77693_CHG_REG_CHG_CNFG_09
,
sel
);
}
/* end of CHARGER regulator ops */
static
const
unsigned
int
max77693_safeout_table
[]
=
{
4850000
,
4900000
,
4950000
,
3300000
,
};
static
struct
regulator_ops
max77693_safeout_ops
=
{
.
list_voltage
=
regulator_list_voltage_table
,
.
is_enabled
=
regulator_is_enabled_regmap
,
.
enable
=
regulator_enable_regmap
,
.
disable
=
regulator_disable_regmap
,
.
get_voltage_sel
=
regulator_get_voltage_sel_regmap
,
.
set_voltage_sel
=
regulator_set_voltage_sel_regmap
,
};
static
struct
regulator_ops
max77693_charger_ops
=
{
.
is_enabled
=
max77693_chg_is_enabled
,
.
enable
=
regulator_enable_regmap
,
.
disable
=
regulator_disable_regmap
,
.
get_current_limit
=
max77693_chg_get_current_limit
,
.
set_current_limit
=
max77693_chg_set_current_limit
,
};
#define regulator_desc_esafeout(_num) { \
.name = "ESAFEOUT"#_num, \
.id = MAX77693_ESAFEOUT##_num, \
.n_voltages = 4, \
.ops = &max77693_safeout_ops, \
.type = REGULATOR_VOLTAGE, \
.volt_table = max77693_safeout_table, \
.vsel_reg = MAX77693_CHG_REG_SAFEOUT_CTRL, \
.vsel_mask = SAFEOUT_CTRL_SAFEOUT##_num##_MASK, \
.enable_reg = MAX77693_CHG_REG_SAFEOUT_CTRL, \
.enable_mask = SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK , \
}
static
struct
regulator_desc
regulators
[]
=
{
regulator_desc_esafeout
(
1
),
regulator_desc_esafeout
(
2
),
{
.
name
=
"CHARGER"
,
.
id
=
MAX77693_CHARGER
,
.
ops
=
&
max77693_charger_ops
,
.
type
=
REGULATOR_CURRENT
,
.
owner
=
THIS_MODULE
,
.
enable_reg
=
MAX77693_CHG_REG_CHG_CNFG_00
,
.
enable_mask
=
CHG_CNFG_00_CHG_MASK
|
CHG_CNFG_00_BUCK_MASK
,
},
};
#ifdef CONFIG_OF
static
int
max77693_pmic_dt_parse_rdata
(
struct
device
*
dev
,
struct
max77693_regulator_data
**
rdata
)
{
struct
device_node
*
np
;
struct
of_regulator_match
*
rmatch
;
struct
max77693_regulator_data
*
tmp
;
int
i
,
matched
=
0
;
np
=
of_find_node_by_name
(
dev
->
parent
->
of_node
,
"regulators"
);
if
(
!
np
)
return
-
EINVAL
;
rmatch
=
devm_kzalloc
(
dev
,
sizeof
(
*
rmatch
)
*
ARRAY_SIZE
(
regulators
),
GFP_KERNEL
);
if
(
!
rmatch
)
return
-
ENOMEM
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
regulators
);
i
++
)
rmatch
[
i
].
name
=
regulators
[
i
].
name
;
matched
=
of_regulator_match
(
dev
,
np
,
rmatch
,
ARRAY_SIZE
(
regulators
));
if
(
matched
<=
0
)
return
matched
;
*
rdata
=
devm_kzalloc
(
dev
,
sizeof
(
**
rdata
)
*
matched
,
GFP_KERNEL
);
if
(
!
(
*
rdata
))
return
-
ENOMEM
;
tmp
=
*
rdata
;
for
(
i
=
0
;
i
<
matched
;
i
++
)
{
tmp
->
initdata
=
rmatch
[
i
].
init_data
;
tmp
->
of_node
=
rmatch
[
i
].
of_node
;
tmp
->
id
=
regulators
[
i
].
id
;
tmp
++
;
}
return
matched
;
}
#else
static
int
max77693_pmic_dt_parse_rdata
(
struct
device
*
dev
,
struct
max77693_regulator_data
**
rdata
)
{
return
0
;
}
#endif
/* CONFIG_OF */
static
int
max77693_pmic_init_rdata
(
struct
device
*
dev
,
struct
max77693_regulator_data
**
rdata
)
{
struct
max77693_platform_data
*
pdata
;
int
num_regulators
=
0
;
pdata
=
dev_get_platdata
(
dev
->
parent
);
if
(
pdata
)
{
*
rdata
=
pdata
->
regulators
;
num_regulators
=
pdata
->
num_regulators
;
}
if
(
!
(
*
rdata
)
&&
dev
->
parent
->
of_node
)
num_regulators
=
max77693_pmic_dt_parse_rdata
(
dev
,
rdata
);
return
num_regulators
;
}
static
int
max77693_pmic_probe
(
struct
platform_device
*
pdev
)
{
struct
max77693_dev
*
iodev
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
struct
max77693_pmic_dev
*
max77693_pmic
;
struct
max77693_regulator_data
*
rdata
=
NULL
;
int
num_rdata
,
i
,
ret
;
struct
regulator_config
config
;
num_rdata
=
max77693_pmic_init_rdata
(
&
pdev
->
dev
,
&
rdata
);
if
(
!
rdata
||
num_rdata
<=
0
)
{
dev_err
(
&
pdev
->
dev
,
"No init data supplied.
\n
"
);
return
-
ENODEV
;
}
max77693_pmic
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
struct
max77693_pmic_dev
),
GFP_KERNEL
);
if
(
!
max77693_pmic
)
return
-
ENOMEM
;
max77693_pmic
->
rdev
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
struct
regulator_dev
*
)
*
num_rdata
,
GFP_KERNEL
);
if
(
!
max77693_pmic
->
rdev
)
return
-
ENOMEM
;
max77693_pmic
->
dev
=
&
pdev
->
dev
;
max77693_pmic
->
iodev
=
iodev
;
max77693_pmic
->
num_regulators
=
num_rdata
;
config
.
dev
=
&
pdev
->
dev
;
config
.
regmap
=
iodev
->
regmap
;
config
.
driver_data
=
max77693_pmic
;
platform_set_drvdata
(
pdev
,
max77693_pmic
);
for
(
i
=
0
;
i
<
max77693_pmic
->
num_regulators
;
i
++
)
{
int
id
=
rdata
[
i
].
id
;
config
.
init_data
=
rdata
[
i
].
initdata
;
config
.
of_node
=
rdata
[
i
].
of_node
;
max77693_pmic
->
rdev
[
i
]
=
regulator_register
(
&
regulators
[
id
],
&
config
);
if
(
IS_ERR
(
max77693_pmic
->
rdev
[
i
]))
{
ret
=
PTR_ERR
(
max77693_pmic
->
rdev
[
i
]);
dev_err
(
max77693_pmic
->
dev
,
"Failed to initialize regulator-%d
\n
"
,
id
);
max77693_pmic
->
rdev
[
i
]
=
NULL
;
goto
err
;
}
}
return
0
;
err:
while
(
--
i
>=
0
)
regulator_unregister
(
max77693_pmic
->
rdev
[
i
]);
return
ret
;
}
static
int
max77693_pmic_remove
(
struct
platform_device
*
pdev
)
{
struct
max77693_pmic_dev
*
max77693_pmic
=
platform_get_drvdata
(
pdev
);
struct
regulator_dev
**
rdev
=
max77693_pmic
->
rdev
;
int
i
;
for
(
i
=
0
;
i
<
max77693_pmic
->
num_regulators
;
i
++
)
if
(
rdev
[
i
])
regulator_unregister
(
rdev
[
i
]);
return
0
;
}
static
const
struct
platform_device_id
max77693_pmic_id
[]
=
{
{
"max77693-pmic"
,
0
},
{},
};
MODULE_DEVICE_TABLE
(
platform
,
max77693_pmic_id
);
static
struct
platform_driver
max77693_pmic_driver
=
{
.
driver
=
{
.
name
=
"max77693-pmic"
,
.
owner
=
THIS_MODULE
,
},
.
probe
=
max77693_pmic_probe
,
.
remove
=
max77693_pmic_remove
,
.
id_table
=
max77693_pmic_id
,
};
module_platform_driver
(
max77693_pmic_driver
);
MODULE_DESCRIPTION
(
"MAXIM MAX77693 regulator driver"
);
MODULE_AUTHOR
(
"Jonghwa Lee <jonghwa3.lee@samsung.com>"
);
MODULE_LICENSE
(
"GPL"
);
include/linux/mfd/max77693-private.h
View file @
28120bf8
...
...
@@ -85,6 +85,19 @@ enum max77693_pmic_reg {
MAX77693_PMIC_REG_END
,
};
/* MAX77693 CHG_CNFG_00 register */
#define CHG_CNFG_00_CHG_MASK 0x1
#define CHG_CNFG_00_BUCK_MASK 0x4
/* MAX77693 CHG_CNFG_09 Register */
#define CHG_CNFG_09_CHGIN_ILIM_MASK 0x7F
/* MAX77693 CHG_CTRL Register */
#define SAFEOUT_CTRL_SAFEOUT1_MASK 0x3
#define SAFEOUT_CTRL_SAFEOUT2_MASK 0xC
#define SAFEOUT_CTRL_ENSAFEOUT1_MASK 0x40
#define SAFEOUT_CTRL_ENSAFEOUT2_MASK 0x80
/* Slave addr = 0x4A: MUIC */
enum
max77693_muic_reg
{
MAX77693_MUIC_REG_ID
=
0x00
,
...
...
include/linux/mfd/max77693.h
View file @
28120bf8
...
...
@@ -30,6 +30,20 @@
#ifndef __LINUX_MFD_MAX77693_H
#define __LINUX_MFD_MAX77693_H
/* MAX77686 regulator IDs */
enum
max77693_regulators
{
MAX77693_ESAFEOUT1
=
0
,
MAX77693_ESAFEOUT2
,
MAX77693_CHARGER
,
MAX77693_REG_MAX
,
};
struct
max77693_regulator_data
{
int
id
;
struct
regulator_init_data
*
initdata
;
struct
device_node
*
of_node
;
};
struct
max77693_reg_data
{
u8
addr
;
u8
data
;
...
...
@@ -52,6 +66,10 @@ struct max77693_muic_platform_data {
struct
max77693_platform_data
{
int
wakeup
;
/* regulator data */
struct
max77693_regulator_data
*
regulators
;
int
num_regulators
;
/* muic data */
struct
max77693_muic_platform_data
*
muic_data
;
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment