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
62696579
Commit
62696579
authored
Sep 01, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regulator/topic/da9063' into regulator-next
parents
1ad13028
632b3d62
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1440 additions
and
0 deletions
+1440
-0
drivers/regulator/Kconfig
drivers/regulator/Kconfig
+20
-0
drivers/regulator/Makefile
drivers/regulator/Makefile
+2
-0
drivers/regulator/da9063-regulator.c
drivers/regulator/da9063-regulator.c
+934
-0
drivers/regulator/da9210-regulator.c
drivers/regulator/da9210-regulator.c
+196
-0
drivers/regulator/da9210-regulator.h
drivers/regulator/da9210-regulator.h
+288
-0
No files found.
drivers/regulator/Kconfig
View file @
62696579
...
...
@@ -157,6 +157,26 @@ config REGULATOR_DA9055
This driver can also be built as a module. If so, the module
will be called da9055-regulator.
config REGULATOR_DA9063
tristate "Dialog Semiconductor DA9063 regulators"
depends on MFD_DA9063
help
Say y here to support the BUCKs and LDOs regulators found on
DA9063 PMICs.
This driver can also be built as a module. If so, the module
will be called da9063-regulator.
config REGULATOR_DA9210
tristate "Dialog Semiconductor DA9210 regulator"
depends on I2C
select REGMAP_I2C
help
Say y here to support for the Dialog Semiconductor DA9210.
The DA9210 is a multi-phase synchronous step down
converter 12A DC-DC Buck controlled through an I2C
interface.
config REGULATOR_DBX500_PRCMU
bool
...
...
drivers/regulator/Makefile
View file @
62696579
...
...
@@ -21,6 +21,8 @@ obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
obj-$(CONFIG_REGULATOR_DA903X)
+=
da903x.o
obj-$(CONFIG_REGULATOR_DA9052)
+=
da9052-regulator.o
obj-$(CONFIG_REGULATOR_DA9055)
+=
da9055-regulator.o
obj-$(CONFIG_REGULATOR_DA9063)
+=
da9063-regulator.o
obj-$(CONFIG_REGULATOR_DA9210)
+=
da9210-regulator.o
obj-$(CONFIG_REGULATOR_DBX500_PRCMU)
+=
dbx500-prcmu.o
obj-$(CONFIG_REGULATOR_DB8500_PRCMU)
+=
db8500-prcmu.o
obj-$(CONFIG_REGULATOR_FAN53555)
+=
fan53555.o
...
...
drivers/regulator/da9063-regulator.c
0 → 100644
View file @
62696579
/*
* Regulator driver for DA9063 PMIC series
*
* Copyright 2012 Dialog Semiconductors Ltd.
* Copyright 2013 Philipp Zabel, Pengutronix
*
* Author: Krystian Garbaciak <krystian.garbaciak@diasemi.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/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/mfd/da9063/core.h>
#include <linux/mfd/da9063/pdata.h>
#include <linux/mfd/da9063/registers.h>
/* Definition for registering regmap bit fields using a mask */
#define BFIELD(_reg, _mask) \
REG_FIELD(_reg, __builtin_ffs((int)_mask) - 1, \
sizeof(unsigned int) * 8 - __builtin_clz((_mask)) - 1)
/* Regulator capabilities and registers description */
struct
da9063_regulator_info
{
struct
regulator_desc
desc
;
/* Current limiting */
unsigned
n_current_limits
;
const
int
*
current_limits
;
/* DA9063 main register fields */
struct
reg_field
mode
;
/* buck mode of operation */
struct
reg_field
suspend
;
struct
reg_field
sleep
;
struct
reg_field
suspend_sleep
;
unsigned
int
suspend_vsel_reg
;
struct
reg_field
ilimit
;
/* DA9063 event detection bit */
struct
reg_field
oc_event
;
};
/* Macros for LDO */
#define DA9063_LDO(chip, regl_name, min_mV, step_mV, max_mV) \
.desc.id = chip##_ID_##regl_name, \
.desc.name = __stringify(chip##_##regl_name), \
.desc.ops = &da9063_ldo_ops, \
.desc.min_uV = (min_mV) * 1000, \
.desc.uV_step = (step_mV) * 1000, \
.desc.n_voltages = (((max_mV) - (min_mV))/(step_mV) + 1), \
.desc.enable_reg = DA9063_REG_##regl_name##_CONT, \
.desc.enable_mask = DA9063_LDO_EN, \
.desc.vsel_reg = DA9063_REG_V##regl_name##_A, \
.desc.vsel_mask = DA9063_V##regl_name##_MASK, \
.desc.linear_min_sel = DA9063_V##regl_name##_BIAS, \
.sleep = BFIELD(DA9063_REG_V##regl_name##_A, DA9063_LDO_SL), \
.suspend_sleep = BFIELD(DA9063_REG_V##regl_name##_B, DA9063_LDO_SL), \
.suspend_vsel_reg = DA9063_REG_V##regl_name##_B
/* Macros for voltage DC/DC converters (BUCKs) */
#define DA9063_BUCK(chip, regl_name, min_mV, step_mV, max_mV, limits_array) \
.desc.id = chip##_ID_##regl_name, \
.desc.name = __stringify(chip##_##regl_name), \
.desc.ops = &da9063_buck_ops, \
.desc.min_uV = (min_mV) * 1000, \
.desc.uV_step = (step_mV) * 1000, \
.desc.n_voltages = ((max_mV) - (min_mV))/(step_mV) + 1, \
.current_limits = limits_array, \
.n_current_limits = ARRAY_SIZE(limits_array)
#define DA9063_BUCK_COMMON_FIELDS(regl_name) \
.desc.enable_reg = DA9063_REG_##regl_name##_CONT, \
.desc.enable_mask = DA9063_BUCK_EN, \
.desc.vsel_reg = DA9063_REG_V##regl_name##_A, \
.desc.vsel_mask = DA9063_VBUCK_MASK, \
.desc.linear_min_sel = DA9063_VBUCK_BIAS, \
.sleep = BFIELD(DA9063_REG_V##regl_name##_A, DA9063_BUCK_SL), \
.suspend_sleep = BFIELD(DA9063_REG_V##regl_name##_B, DA9063_BUCK_SL), \
.suspend_vsel_reg = DA9063_REG_V##regl_name##_B, \
.mode = BFIELD(DA9063_REG_##regl_name##_CFG, DA9063_BUCK_MODE_MASK)
/* Defines asignment of regulators info table to chip model */
struct
da9063_dev_model
{
const
struct
da9063_regulator_info
*
regulator_info
;
unsigned
n_regulators
;
unsigned
dev_model
;
};
/* Single regulator settings */
struct
da9063_regulator
{
struct
regulator_desc
desc
;
struct
regulator_dev
*
rdev
;
struct
da9063
*
hw
;
const
struct
da9063_regulator_info
*
info
;
struct
regmap_field
*
mode
;
struct
regmap_field
*
suspend
;
struct
regmap_field
*
sleep
;
struct
regmap_field
*
suspend_sleep
;
struct
regmap_field
*
ilimit
;
};
/* Encapsulates all information for the regulators driver */
struct
da9063_regulators
{
int
irq_ldo_lim
;
int
irq_uvov
;
unsigned
n_regulators
;
/* Array size to be defined during init. Keep at end. */
struct
da9063_regulator
regulator
[
0
];
};
/* BUCK modes for DA9063 */
enum
{
BUCK_MODE_MANUAL
,
/* 0 */
BUCK_MODE_SLEEP
,
/* 1 */
BUCK_MODE_SYNC
,
/* 2 */
BUCK_MODE_AUTO
/* 3 */
};
/* Regulator operations */
/* Current limits array (in uA) for BCORE1, BCORE2, BPRO.
Entry indexes corresponds to register values. */
static
const
int
da9063_buck_a_limits
[]
=
{
500000
,
600000
,
700000
,
800000
,
900000
,
1000000
,
1100000
,
1200000
,
1300000
,
1400000
,
1500000
,
1600000
,
1700000
,
1800000
,
1900000
,
2000000
};
/* Current limits array (in uA) for BMEM, BIO, BPERI.
Entry indexes corresponds to register values. */
static
const
int
da9063_buck_b_limits
[]
=
{
1500000
,
1600000
,
1700000
,
1800000
,
1900000
,
2000000
,
2100000
,
2200000
,
2300000
,
2400000
,
2500000
,
2600000
,
2700000
,
2800000
,
2900000
,
3000000
};
/* Current limits array (in uA) for merged BCORE1 and BCORE2.
Entry indexes corresponds to register values. */
static
const
int
da9063_bcores_merged_limits
[]
=
{
1000000
,
1200000
,
1400000
,
1600000
,
1800000
,
2000000
,
2200000
,
2400000
,
2600000
,
2800000
,
3000000
,
3200000
,
3400000
,
3600000
,
3800000
,
4000000
};
/* Current limits array (in uA) for merged BMEM and BIO.
Entry indexes corresponds to register values. */
static
const
int
da9063_bmem_bio_merged_limits
[]
=
{
3000000
,
3200000
,
3400000
,
3600000
,
3800000
,
4000000
,
4200000
,
4400000
,
4600000
,
4800000
,
5000000
,
5200000
,
5400000
,
5600000
,
5800000
,
6000000
};
static
int
da9063_set_current_limit
(
struct
regulator_dev
*
rdev
,
int
min_uA
,
int
max_uA
)
{
struct
da9063_regulator
*
regl
=
rdev_get_drvdata
(
rdev
);
const
struct
da9063_regulator_info
*
rinfo
=
regl
->
info
;
int
n
,
tval
;
for
(
n
=
0
;
n
<
rinfo
->
n_current_limits
;
n
++
)
{
tval
=
rinfo
->
current_limits
[
n
];
if
(
tval
>=
min_uA
&&
tval
<=
max_uA
)
return
regmap_field_write
(
regl
->
ilimit
,
n
);
}
return
-
EINVAL
;
}
static
int
da9063_get_current_limit
(
struct
regulator_dev
*
rdev
)
{
struct
da9063_regulator
*
regl
=
rdev_get_drvdata
(
rdev
);
const
struct
da9063_regulator_info
*
rinfo
=
regl
->
info
;
unsigned
int
sel
;
int
ret
;
ret
=
regmap_field_read
(
regl
->
ilimit
,
&
sel
);
if
(
ret
<
0
)
return
ret
;
if
(
sel
>=
rinfo
->
n_current_limits
)
sel
=
rinfo
->
n_current_limits
-
1
;
return
rinfo
->
current_limits
[
sel
];
}
static
int
da9063_buck_set_mode
(
struct
regulator_dev
*
rdev
,
unsigned
mode
)
{
struct
da9063_regulator
*
regl
=
rdev_get_drvdata
(
rdev
);
unsigned
val
;
switch
(
mode
)
{
case
REGULATOR_MODE_FAST
:
val
=
BUCK_MODE_SYNC
;
break
;
case
REGULATOR_MODE_NORMAL
:
val
=
BUCK_MODE_AUTO
;
break
;
case
REGULATOR_MODE_STANDBY
:
val
=
BUCK_MODE_SLEEP
;
break
;
default:
return
-
EINVAL
;
}
return
regmap_field_write
(
regl
->
mode
,
val
);
}
/*
* Bucks use single mode register field for normal operation
* and suspend state.
* There are 3 modes to map to: FAST, NORMAL, and STANDBY.
*/
static
unsigned
da9063_buck_get_mode
(
struct
regulator_dev
*
rdev
)
{
struct
da9063_regulator
*
regl
=
rdev_get_drvdata
(
rdev
);
struct
regmap_field
*
field
;
unsigned
int
val
,
mode
=
0
;
int
ret
;
ret
=
regmap_field_read
(
regl
->
mode
,
&
val
);
if
(
ret
<
0
)
return
ret
;
switch
(
val
)
{
default:
case
BUCK_MODE_MANUAL
:
mode
=
REGULATOR_MODE_FAST
|
REGULATOR_MODE_STANDBY
;
/* Sleep flag bit decides the mode */
break
;
case
BUCK_MODE_SLEEP
:
return
REGULATOR_MODE_STANDBY
;
case
BUCK_MODE_SYNC
:
return
REGULATOR_MODE_FAST
;
case
BUCK_MODE_AUTO
:
return
REGULATOR_MODE_NORMAL
;
}
/* Detect current regulator state */
ret
=
regmap_field_read
(
regl
->
suspend
,
&
val
);
if
(
ret
<
0
)
return
0
;
/* Read regulator mode from proper register, depending on state */
if
(
val
)
field
=
regl
->
suspend_sleep
;
else
field
=
regl
->
sleep
;
ret
=
regmap_field_read
(
field
,
&
val
);
if
(
ret
<
0
)
return
0
;
if
(
val
)
mode
&=
REGULATOR_MODE_STANDBY
;
else
mode
&=
REGULATOR_MODE_NORMAL
|
REGULATOR_MODE_FAST
;
return
mode
;
}
/*
* LDOs use sleep flags - one for normal and one for suspend state.
* There are 2 modes to map to: NORMAL and STANDBY (sleep) for each state.
*/
static
int
da9063_ldo_set_mode
(
struct
regulator_dev
*
rdev
,
unsigned
mode
)
{
struct
da9063_regulator
*
regl
=
rdev_get_drvdata
(
rdev
);
unsigned
val
;
switch
(
mode
)
{
case
REGULATOR_MODE_NORMAL
:
val
=
0
;
break
;
case
REGULATOR_MODE_STANDBY
:
val
=
1
;
break
;
default:
return
-
EINVAL
;
}
return
regmap_field_write
(
regl
->
sleep
,
val
);
}
static
unsigned
da9063_ldo_get_mode
(
struct
regulator_dev
*
rdev
)
{
struct
da9063_regulator
*
regl
=
rdev_get_drvdata
(
rdev
);
struct
regmap_field
*
field
;
int
ret
,
val
;
/* Detect current regulator state */
ret
=
regmap_field_read
(
regl
->
suspend
,
&
val
);
if
(
ret
<
0
)
return
0
;
/* Read regulator mode from proper register, depending on state */
if
(
val
)
field
=
regl
->
suspend_sleep
;
else
field
=
regl
->
sleep
;
ret
=
regmap_field_read
(
field
,
&
val
);
if
(
ret
<
0
)
return
0
;
if
(
val
)
return
REGULATOR_MODE_STANDBY
;
else
return
REGULATOR_MODE_NORMAL
;
}
static
int
da9063_buck_get_status
(
struct
regulator_dev
*
rdev
)
{
int
ret
=
regulator_is_enabled_regmap
(
rdev
);
if
(
ret
==
0
)
{
ret
=
REGULATOR_STATUS_OFF
;
}
else
if
(
ret
>
0
)
{
ret
=
da9063_buck_get_mode
(
rdev
);
if
(
ret
>
0
)
ret
=
regulator_mode_to_status
(
ret
);
else
if
(
ret
==
0
)
ret
=
-
EIO
;
}
return
ret
;
}
static
int
da9063_ldo_get_status
(
struct
regulator_dev
*
rdev
)
{
int
ret
=
regulator_is_enabled_regmap
(
rdev
);
if
(
ret
==
0
)
{
ret
=
REGULATOR_STATUS_OFF
;
}
else
if
(
ret
>
0
)
{
ret
=
da9063_ldo_get_mode
(
rdev
);
if
(
ret
>
0
)
ret
=
regulator_mode_to_status
(
ret
);
else
if
(
ret
==
0
)
ret
=
-
EIO
;
}
return
ret
;
}
static
int
da9063_set_suspend_voltage
(
struct
regulator_dev
*
rdev
,
int
uV
)
{
struct
da9063_regulator
*
regl
=
rdev_get_drvdata
(
rdev
);
const
struct
da9063_regulator_info
*
rinfo
=
regl
->
info
;
int
ret
,
sel
;
sel
=
regulator_map_voltage_linear
(
rdev
,
uV
,
uV
);
if
(
sel
<
0
)
return
-
EINVAL
;
sel
<<=
ffs
(
rdev
->
desc
->
vsel_mask
)
-
1
;
ret
=
regmap_update_bits
(
regl
->
hw
->
regmap
,
rinfo
->
suspend_vsel_reg
,
rdev
->
desc
->
vsel_mask
,
sel
);
return
ret
;
}
static
int
da9063_suspend_enable
(
struct
regulator_dev
*
rdev
)
{
struct
da9063_regulator
*
regl
=
rdev_get_drvdata
(
rdev
);
return
regmap_field_write
(
regl
->
suspend
,
1
);
}
static
int
da9063_suspend_disable
(
struct
regulator_dev
*
rdev
)
{
struct
da9063_regulator
*
regl
=
rdev_get_drvdata
(
rdev
);
return
regmap_field_write
(
regl
->
suspend
,
0
);
}
static
int
da9063_buck_set_suspend_mode
(
struct
regulator_dev
*
rdev
,
unsigned
mode
)
{
struct
da9063_regulator
*
regl
=
rdev_get_drvdata
(
rdev
);
int
val
;
switch
(
mode
)
{
case
REGULATOR_MODE_FAST
:
val
=
BUCK_MODE_SYNC
;
break
;
case
REGULATOR_MODE_NORMAL
:
val
=
BUCK_MODE_AUTO
;
break
;
case
REGULATOR_MODE_STANDBY
:
val
=
BUCK_MODE_SLEEP
;
break
;
default:
return
-
EINVAL
;
}
return
regmap_field_write
(
regl
->
mode
,
val
);
}
static
int
da9063_ldo_set_suspend_mode
(
struct
regulator_dev
*
rdev
,
unsigned
mode
)
{
struct
da9063_regulator
*
regl
=
rdev_get_drvdata
(
rdev
);
unsigned
val
;
switch
(
mode
)
{
case
REGULATOR_MODE_NORMAL
:
val
=
0
;
break
;
case
REGULATOR_MODE_STANDBY
:
val
=
1
;
break
;
default:
return
-
EINVAL
;
}
return
regmap_field_write
(
regl
->
suspend_sleep
,
val
);
}
static
struct
regulator_ops
da9063_buck_ops
=
{
.
enable
=
regulator_enable_regmap
,
.
disable
=
regulator_disable_regmap
,
.
is_enabled
=
regulator_is_enabled_regmap
,
.
get_voltage_sel
=
regulator_get_voltage_sel_regmap
,
.
set_voltage_sel
=
regulator_set_voltage_sel_regmap
,
.
list_voltage
=
regulator_list_voltage_linear
,
.
set_current_limit
=
da9063_set_current_limit
,
.
get_current_limit
=
da9063_get_current_limit
,
.
set_mode
=
da9063_buck_set_mode
,
.
get_mode
=
da9063_buck_get_mode
,
.
get_status
=
da9063_buck_get_status
,
.
set_suspend_voltage
=
da9063_set_suspend_voltage
,
.
set_suspend_enable
=
da9063_suspend_enable
,
.
set_suspend_disable
=
da9063_suspend_disable
,
.
set_suspend_mode
=
da9063_buck_set_suspend_mode
,
};
static
struct
regulator_ops
da9063_ldo_ops
=
{
.
enable
=
regulator_enable_regmap
,
.
disable
=
regulator_disable_regmap
,
.
is_enabled
=
regulator_is_enabled_regmap
,
.
get_voltage_sel
=
regulator_get_voltage_sel_regmap
,
.
set_voltage_sel
=
regulator_set_voltage_sel_regmap
,
.
list_voltage
=
regulator_list_voltage_linear
,
.
set_mode
=
da9063_ldo_set_mode
,
.
get_mode
=
da9063_ldo_get_mode
,
.
get_status
=
da9063_ldo_get_status
,
.
set_suspend_voltage
=
da9063_set_suspend_voltage
,
.
set_suspend_enable
=
da9063_suspend_enable
,
.
set_suspend_disable
=
da9063_suspend_disable
,
.
set_suspend_mode
=
da9063_ldo_set_suspend_mode
,
};
/* Info of regulators for DA9063 */
static
const
struct
da9063_regulator_info
da9063_regulator_info
[]
=
{
{
DA9063_BUCK
(
DA9063
,
BCORE1
,
300
,
10
,
1570
,
da9063_buck_a_limits
),
DA9063_BUCK_COMMON_FIELDS
(
BCORE1
),
.
suspend
=
BFIELD
(
DA9063_REG_DVC_1
,
DA9063_VBCORE1_SEL
),
.
ilimit
=
BFIELD
(
DA9063_REG_BUCK_ILIM_C
,
DA9063_BCORE1_ILIM_MASK
),
},
{
DA9063_BUCK
(
DA9063
,
BCORE2
,
300
,
10
,
1570
,
da9063_buck_a_limits
),
DA9063_BUCK_COMMON_FIELDS
(
BCORE2
),
.
suspend
=
BFIELD
(
DA9063_REG_DVC_1
,
DA9063_VBCORE2_SEL
),
.
ilimit
=
BFIELD
(
DA9063_REG_BUCK_ILIM_C
,
DA9063_BCORE2_ILIM_MASK
),
},
{
DA9063_BUCK
(
DA9063
,
BPRO
,
530
,
10
,
1800
,
da9063_buck_a_limits
),
DA9063_BUCK_COMMON_FIELDS
(
BPRO
),
.
suspend
=
BFIELD
(
DA9063_REG_DVC_1
,
DA9063_VBPRO_SEL
),
.
ilimit
=
BFIELD
(
DA9063_REG_BUCK_ILIM_B
,
DA9063_BPRO_ILIM_MASK
),
},
{
DA9063_BUCK
(
DA9063
,
BMEM
,
800
,
20
,
3340
,
da9063_buck_b_limits
),
DA9063_BUCK_COMMON_FIELDS
(
BMEM
),
.
suspend
=
BFIELD
(
DA9063_REG_DVC_1
,
DA9063_VBMEM_SEL
),
.
ilimit
=
BFIELD
(
DA9063_REG_BUCK_ILIM_A
,
DA9063_BMEM_ILIM_MASK
),
},
{
DA9063_BUCK
(
DA9063
,
BIO
,
800
,
20
,
3340
,
da9063_buck_b_limits
),
DA9063_BUCK_COMMON_FIELDS
(
BIO
),
.
suspend
=
BFIELD
(
DA9063_REG_DVC_2
,
DA9063_VBIO_SEL
),
.
ilimit
=
BFIELD
(
DA9063_REG_BUCK_ILIM_A
,
DA9063_BIO_ILIM_MASK
),
},
{
DA9063_BUCK
(
DA9063
,
BPERI
,
800
,
20
,
3340
,
da9063_buck_b_limits
),
DA9063_BUCK_COMMON_FIELDS
(
BPERI
),
.
suspend
=
BFIELD
(
DA9063_REG_DVC_1
,
DA9063_VBPERI_SEL
),
.
ilimit
=
BFIELD
(
DA9063_REG_BUCK_ILIM_B
,
DA9063_BPERI_ILIM_MASK
),
},
{
DA9063_BUCK
(
DA9063
,
BCORES_MERGED
,
300
,
10
,
1570
,
da9063_bcores_merged_limits
),
/* BCORES_MERGED uses the same register fields as BCORE1 */
DA9063_BUCK_COMMON_FIELDS
(
BCORE1
),
.
suspend
=
BFIELD
(
DA9063_REG_DVC_1
,
DA9063_VBCORE1_SEL
),
.
ilimit
=
BFIELD
(
DA9063_REG_BUCK_ILIM_C
,
DA9063_BCORE1_ILIM_MASK
),
},
{
DA9063_BUCK
(
DA9063
,
BMEM_BIO_MERGED
,
800
,
20
,
3340
,
da9063_bmem_bio_merged_limits
),
/* BMEM_BIO_MERGED uses the same register fields as BMEM */
DA9063_BUCK_COMMON_FIELDS
(
BMEM
),
.
suspend
=
BFIELD
(
DA9063_REG_DVC_1
,
DA9063_VBMEM_SEL
),
.
ilimit
=
BFIELD
(
DA9063_REG_BUCK_ILIM_A
,
DA9063_BMEM_ILIM_MASK
),
},
{
DA9063_LDO
(
DA9063
,
LDO1
,
600
,
20
,
1860
),
.
suspend
=
BFIELD
(
DA9063_REG_DVC_1
,
DA9063_VLDO1_SEL
),
},
{
DA9063_LDO
(
DA9063
,
LDO2
,
600
,
20
,
1860
),
.
suspend
=
BFIELD
(
DA9063_REG_DVC_1
,
DA9063_VLDO2_SEL
),
},
{
DA9063_LDO
(
DA9063
,
LDO3
,
900
,
20
,
3440
),
.
suspend
=
BFIELD
(
DA9063_REG_DVC_1
,
DA9063_VLDO3_SEL
),
.
oc_event
=
BFIELD
(
DA9063_REG_STATUS_D
,
DA9063_LDO3_LIM
),
},
{
DA9063_LDO
(
DA9063
,
LDO4
,
900
,
20
,
3440
),
.
suspend
=
BFIELD
(
DA9063_REG_DVC_2
,
DA9063_VLDO4_SEL
),
.
oc_event
=
BFIELD
(
DA9063_REG_STATUS_D
,
DA9063_LDO4_LIM
),
},
{
DA9063_LDO
(
DA9063
,
LDO5
,
900
,
50
,
3600
),
.
suspend
=
BFIELD
(
DA9063_REG_LDO5_CONT
,
DA9063_VLDO5_SEL
),
},
{
DA9063_LDO
(
DA9063
,
LDO6
,
900
,
50
,
3600
),
.
suspend
=
BFIELD
(
DA9063_REG_LDO6_CONT
,
DA9063_VLDO6_SEL
),
},
{
DA9063_LDO
(
DA9063
,
LDO7
,
900
,
50
,
3600
),
.
suspend
=
BFIELD
(
DA9063_REG_LDO7_CONT
,
DA9063_VLDO7_SEL
),
.
oc_event
=
BFIELD
(
DA9063_REG_STATUS_D
,
DA9063_LDO7_LIM
),
},
{
DA9063_LDO
(
DA9063
,
LDO8
,
900
,
50
,
3600
),
.
suspend
=
BFIELD
(
DA9063_REG_LDO8_CONT
,
DA9063_VLDO8_SEL
),
.
oc_event
=
BFIELD
(
DA9063_REG_STATUS_D
,
DA9063_LDO8_LIM
),
},
{
DA9063_LDO
(
DA9063
,
LDO9
,
950
,
50
,
3600
),
.
suspend
=
BFIELD
(
DA9063_REG_LDO9_CONT
,
DA9063_VLDO9_SEL
),
},
{
DA9063_LDO
(
DA9063
,
LDO10
,
900
,
50
,
3600
),
.
suspend
=
BFIELD
(
DA9063_REG_LDO10_CONT
,
DA9063_VLDO10_SEL
),
},
{
DA9063_LDO
(
DA9063
,
LDO11
,
900
,
50
,
3600
),
.
suspend
=
BFIELD
(
DA9063_REG_LDO11_CONT
,
DA9063_VLDO11_SEL
),
.
oc_event
=
BFIELD
(
DA9063_REG_STATUS_D
,
DA9063_LDO11_LIM
),
},
};
/* Link chip model with regulators info table */
static
struct
da9063_dev_model
regulators_models
[]
=
{
{
.
regulator_info
=
da9063_regulator_info
,
.
n_regulators
=
ARRAY_SIZE
(
da9063_regulator_info
),
.
dev_model
=
PMIC_DA9063
,
},
{
}
};
/* Regulator interrupt handlers */
static
irqreturn_t
da9063_ldo_lim_event
(
int
irq
,
void
*
data
)
{
struct
da9063_regulators
*
regulators
=
data
;
struct
da9063
*
hw
=
regulators
->
regulator
[
0
].
hw
;
struct
da9063_regulator
*
regl
;
int
bits
,
i
,
ret
;
ret
=
regmap_read
(
hw
->
regmap
,
DA9063_REG_STATUS_D
,
&
bits
);
if
(
ret
<
0
)
return
IRQ_NONE
;
for
(
i
=
regulators
->
n_regulators
-
1
;
i
>=
0
;
i
--
)
{
regl
=
&
regulators
->
regulator
[
i
];
if
(
regl
->
info
->
oc_event
.
reg
!=
DA9063_REG_STATUS_D
)
continue
;
if
(
BIT
(
regl
->
info
->
oc_event
.
lsb
)
&
bits
)
regulator_notifier_call_chain
(
regl
->
rdev
,
REGULATOR_EVENT_OVER_CURRENT
,
NULL
);
}
return
IRQ_HANDLED
;
}
/*
* Probing and Initialisation functions
*/
static
const
struct
regulator_init_data
*
da9063_get_regulator_initdata
(
const
struct
da9063_regulators_pdata
*
regl_pdata
,
int
id
)
{
int
i
;
for
(
i
=
0
;
i
<
regl_pdata
->
n_regulators
;
i
++
)
{
if
(
id
==
regl_pdata
->
regulator_data
[
i
].
id
)
return
regl_pdata
->
regulator_data
[
i
].
initdata
;
}
return
NULL
;
}
#ifdef CONFIG_OF
static
struct
of_regulator_match
da9063_matches
[]
=
{
[
DA9063_ID_BCORE1
]
=
{
.
name
=
"bcore1"
},
[
DA9063_ID_BCORE2
]
=
{
.
name
=
"bcore2"
},
[
DA9063_ID_BPRO
]
=
{
.
name
=
"bpro"
,
},
[
DA9063_ID_BMEM
]
=
{
.
name
=
"bmem"
,
},
[
DA9063_ID_BIO
]
=
{
.
name
=
"bio"
,
},
[
DA9063_ID_BPERI
]
=
{
.
name
=
"bperi"
,
},
[
DA9063_ID_BCORES_MERGED
]
=
{
.
name
=
"bcores-merged"
},
[
DA9063_ID_BMEM_BIO_MERGED
]
=
{
.
name
=
"bmem-bio-merged"
,
},
[
DA9063_ID_LDO1
]
=
{
.
name
=
"ldo1"
,
},
[
DA9063_ID_LDO2
]
=
{
.
name
=
"ldo2"
,
},
[
DA9063_ID_LDO3
]
=
{
.
name
=
"ldo3"
,
},
[
DA9063_ID_LDO4
]
=
{
.
name
=
"ldo4"
,
},
[
DA9063_ID_LDO5
]
=
{
.
name
=
"ldo5"
,
},
[
DA9063_ID_LDO6
]
=
{
.
name
=
"ldo6"
,
},
[
DA9063_ID_LDO7
]
=
{
.
name
=
"ldo7"
,
},
[
DA9063_ID_LDO8
]
=
{
.
name
=
"ldo8"
,
},
[
DA9063_ID_LDO9
]
=
{
.
name
=
"ldo9"
,
},
[
DA9063_ID_LDO10
]
=
{
.
name
=
"ldo10"
,
},
[
DA9063_ID_LDO11
]
=
{
.
name
=
"ldo11"
,
},
};
static
struct
da9063_regulators_pdata
*
da9063_parse_regulators_dt
(
struct
platform_device
*
pdev
,
struct
of_regulator_match
**
da9063_reg_matches
)
{
struct
da9063_regulators_pdata
*
pdata
;
struct
da9063_regulator_data
*
rdata
;
struct
device_node
*
node
;
int
i
,
n
,
num
;
node
=
of_find_node_by_name
(
pdev
->
dev
.
parent
->
of_node
,
"regulators"
);
if
(
!
node
)
{
dev_err
(
&
pdev
->
dev
,
"Regulators device node not found
\n
"
);
return
ERR_PTR
(
-
ENODEV
);
}
num
=
of_regulator_match
(
&
pdev
->
dev
,
node
,
da9063_matches
,
ARRAY_SIZE
(
da9063_matches
));
if
(
num
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to match regulators
\n
"
);
return
ERR_PTR
(
-
EINVAL
);
}
pdata
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
pdata
),
GFP_KERNEL
);
if
(
!
pdata
)
return
ERR_PTR
(
-
ENOMEM
);
pdata
->
regulator_data
=
devm_kzalloc
(
&
pdev
->
dev
,
num
*
sizeof
(
*
pdata
->
regulator_data
),
GFP_KERNEL
);
if
(
!
pdata
->
regulator_data
)
return
ERR_PTR
(
-
ENOMEM
);
pdata
->
n_regulators
=
num
;
n
=
0
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
da9063_matches
);
i
++
)
{
if
(
!
da9063_matches
[
i
].
init_data
)
continue
;
rdata
=
&
pdata
->
regulator_data
[
n
];
rdata
->
id
=
i
;
rdata
->
initdata
=
da9063_matches
[
i
].
init_data
;
n
++
;
};
*
da9063_reg_matches
=
da9063_matches
;
return
pdata
;
}
#else
static
struct
da9063_regulators_pdata
*
da9063_parse_regulators_dt
(
struct
platform_device
*
pdev
,
struct
of_regulator_match
**
da9063_reg_matches
)
{
da9063_reg_matches
=
NULL
;
return
PTR_ERR
(
-
ENODEV
);
}
#endif
static
int
da9063_regulator_probe
(
struct
platform_device
*
pdev
)
{
struct
da9063
*
da9063
=
dev_get_drvdata
(
pdev
->
dev
.
parent
);
struct
da9063_pdata
*
da9063_pdata
=
dev_get_platdata
(
da9063
->
dev
);
struct
of_regulator_match
*
da9063_reg_matches
;
struct
da9063_regulators_pdata
*
regl_pdata
;
const
struct
da9063_dev_model
*
model
;
struct
da9063_regulators
*
regulators
;
struct
da9063_regulator
*
regl
;
struct
regulator_config
config
;
bool
bcores_merged
,
bmem_bio_merged
;
int
id
,
irq
,
n
,
n_regulators
,
ret
,
val
;
size_t
size
;
regl_pdata
=
da9063_pdata
?
da9063_pdata
->
regulators_pdata
:
NULL
;
if
(
!
regl_pdata
)
regl_pdata
=
da9063_parse_regulators_dt
(
pdev
,
&
da9063_reg_matches
);
if
(
IS_ERR
(
regl_pdata
)
||
regl_pdata
->
n_regulators
==
0
)
{
dev_err
(
&
pdev
->
dev
,
"No regulators defined for the platform
\n
"
);
return
PTR_ERR
(
regl_pdata
);
}
/* Find regulators set for particular device model */
for
(
model
=
regulators_models
;
model
->
regulator_info
;
model
++
)
{
if
(
model
->
dev_model
==
da9063
->
model
)
break
;
}
if
(
!
model
->
regulator_info
)
{
dev_err
(
&
pdev
->
dev
,
"Chip model not recognised (%u)
\n
"
,
da9063
->
model
);
return
-
ENODEV
;
}
ret
=
regmap_read
(
da9063
->
regmap
,
DA9063_REG_CONFIG_H
,
&
val
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"Error while reading BUCKs configuration
\n
"
);
return
-
EIO
;
}
bcores_merged
=
val
&
DA9063_BCORE_MERGE
;
bmem_bio_merged
=
val
&
DA9063_BUCK_MERGE
;
n_regulators
=
model
->
n_regulators
;
if
(
bcores_merged
)
n_regulators
-=
2
;
/* remove BCORE1, BCORE2 */
else
n_regulators
--
;
/* remove BCORES_MERGED */
if
(
bmem_bio_merged
)
n_regulators
-=
2
;
/* remove BMEM, BIO */
else
n_regulators
--
;
/* remove BMEM_BIO_MERGED */
/* Allocate memory required by usable regulators */
size
=
sizeof
(
struct
da9063_regulators
)
+
n_regulators
*
sizeof
(
struct
da9063_regulator
);
regulators
=
devm_kzalloc
(
&
pdev
->
dev
,
size
,
GFP_KERNEL
);
if
(
!
regulators
)
{
dev_err
(
&
pdev
->
dev
,
"No memory for regulators
\n
"
);
return
-
ENOMEM
;
}
regulators
->
n_regulators
=
n_regulators
;
platform_set_drvdata
(
pdev
,
regulators
);
/* Register all regulators declared in platform information */
n
=
0
;
id
=
0
;
while
(
n
<
regulators
->
n_regulators
)
{
/* Skip regulator IDs depending on merge mode configuration */
switch
(
id
)
{
case
DA9063_ID_BCORE1
:
case
DA9063_ID_BCORE2
:
if
(
bcores_merged
)
{
id
++
;
continue
;
}
break
;
case
DA9063_ID_BMEM
:
case
DA9063_ID_BIO
:
if
(
bmem_bio_merged
)
{
id
++
;
continue
;
}
break
;
case
DA9063_ID_BCORES_MERGED
:
if
(
!
bcores_merged
)
{
id
++
;
continue
;
}
break
;
case
DA9063_ID_BMEM_BIO_MERGED
:
if
(
!
bmem_bio_merged
)
{
id
++
;
continue
;
}
break
;
}
/* Initialise regulator structure */
regl
=
&
regulators
->
regulator
[
n
];
regl
->
hw
=
da9063
;
regl
->
info
=
&
model
->
regulator_info
[
id
];
regl
->
desc
=
regl
->
info
->
desc
;
regl
->
desc
.
type
=
REGULATOR_VOLTAGE
;
regl
->
desc
.
owner
=
THIS_MODULE
;
if
(
regl
->
info
->
mode
.
reg
)
regl
->
mode
=
devm_regmap_field_alloc
(
&
pdev
->
dev
,
da9063
->
regmap
,
regl
->
info
->
mode
);
if
(
regl
->
info
->
suspend
.
reg
)
regl
->
suspend
=
devm_regmap_field_alloc
(
&
pdev
->
dev
,
da9063
->
regmap
,
regl
->
info
->
suspend
);
if
(
regl
->
info
->
sleep
.
reg
)
regl
->
sleep
=
devm_regmap_field_alloc
(
&
pdev
->
dev
,
da9063
->
regmap
,
regl
->
info
->
sleep
);
if
(
regl
->
info
->
suspend_sleep
.
reg
)
regl
->
suspend_sleep
=
devm_regmap_field_alloc
(
&
pdev
->
dev
,
da9063
->
regmap
,
regl
->
info
->
suspend_sleep
);
if
(
regl
->
info
->
ilimit
.
reg
)
regl
->
ilimit
=
devm_regmap_field_alloc
(
&
pdev
->
dev
,
da9063
->
regmap
,
regl
->
info
->
ilimit
);
/* Register regulator */
memset
(
&
config
,
0
,
sizeof
(
config
));
config
.
dev
=
&
pdev
->
dev
;
config
.
init_data
=
da9063_get_regulator_initdata
(
regl_pdata
,
id
);
config
.
driver_data
=
regl
;
if
(
da9063_reg_matches
)
config
.
of_node
=
da9063_reg_matches
[
id
].
of_node
;
config
.
regmap
=
da9063
->
regmap
;
regl
->
rdev
=
regulator_register
(
&
regl
->
desc
,
&
config
);
if
(
IS_ERR
(
regl
->
rdev
))
{
dev_err
(
&
pdev
->
dev
,
"Failed to register %s regulator
\n
"
,
regl
->
desc
.
name
);
ret
=
PTR_ERR
(
regl
->
rdev
);
goto
err
;
}
id
++
;
n
++
;
}
/* LDOs overcurrent event support */
irq
=
platform_get_irq_byname
(
pdev
,
"LDO_LIM"
);
if
(
irq
<
0
)
{
ret
=
irq
;
dev_err
(
&
pdev
->
dev
,
"Failed to get IRQ.
\n
"
);
goto
err
;
}
regulators
->
irq_ldo_lim
=
regmap_irq_get_virq
(
da9063
->
regmap_irq
,
irq
);
if
(
regulators
->
irq_ldo_lim
>=
0
)
{
ret
=
request_threaded_irq
(
regulators
->
irq_ldo_lim
,
NULL
,
da9063_ldo_lim_event
,
IRQF_TRIGGER_LOW
|
IRQF_ONESHOT
,
"LDO_LIM"
,
regulators
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to request LDO_LIM IRQ.
\n
"
);
regulators
->
irq_ldo_lim
=
-
ENXIO
;
}
}
return
0
;
err:
/* Wind back regulators registeration */
while
(
--
n
>=
0
)
regulator_unregister
(
regulators
->
regulator
[
n
].
rdev
);
return
ret
;
}
static
int
da9063_regulator_remove
(
struct
platform_device
*
pdev
)
{
struct
da9063_regulators
*
regulators
=
platform_get_drvdata
(
pdev
);
struct
da9063_regulator
*
regl
;
free_irq
(
regulators
->
irq_ldo_lim
,
regulators
);
free_irq
(
regulators
->
irq_uvov
,
regulators
);
for
(
regl
=
&
regulators
->
regulator
[
regulators
->
n_regulators
-
1
];
regl
>=
&
regulators
->
regulator
[
0
];
regl
--
)
regulator_unregister
(
regl
->
rdev
);
return
0
;
}
static
struct
platform_driver
da9063_regulator_driver
=
{
.
driver
=
{
.
name
=
DA9063_DRVNAME_REGULATORS
,
.
owner
=
THIS_MODULE
,
},
.
probe
=
da9063_regulator_probe
,
.
remove
=
da9063_regulator_remove
,
};
static
int
__init
da9063_regulator_init
(
void
)
{
return
platform_driver_register
(
&
da9063_regulator_driver
);
}
subsys_initcall
(
da9063_regulator_init
);
static
void
__exit
da9063_regulator_cleanup
(
void
)
{
platform_driver_unregister
(
&
da9063_regulator_driver
);
}
module_exit
(
da9063_regulator_cleanup
);
/* Module information */
MODULE_AUTHOR
(
"Krystian Garbaciak <krystian.garbaciak@diasemi.com>"
);
MODULE_DESCRIPTION
(
"DA9063 regulators driver"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_ALIAS
(
"paltform:"
DA9063_DRVNAME_REGULATORS
);
drivers/regulator/da9210-regulator.c
0 → 100644
View file @
62696579
/*
* da9210-regulator.c - Regulator device driver for DA9210
* Copyright (C) 2013 Dialog Semiconductor Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regmap.h>
#include "da9210-regulator.h"
struct
da9210
{
struct
regulator_dev
*
rdev
;
struct
regmap
*
regmap
;
};
static
const
struct
regmap_config
da9210_regmap_config
=
{
.
reg_bits
=
8
,
.
val_bits
=
8
,
};
static
int
da9210_set_current_limit
(
struct
regulator_dev
*
rdev
,
int
min_uA
,
int
max_uA
);
static
int
da9210_get_current_limit
(
struct
regulator_dev
*
rdev
);
static
struct
regulator_ops
da9210_buck_ops
=
{
.
enable
=
regulator_enable_regmap
,
.
disable
=
regulator_disable_regmap
,
.
is_enabled
=
regulator_is_enabled_regmap
,
.
set_voltage_sel
=
regulator_set_voltage_sel_regmap
,
.
get_voltage_sel
=
regulator_get_voltage_sel_regmap
,
.
list_voltage
=
regulator_list_voltage_linear
,
.
set_current_limit
=
da9210_set_current_limit
,
.
get_current_limit
=
da9210_get_current_limit
,
};
/* Default limits measured in millivolts and milliamps */
#define DA9210_MIN_MV 300
#define DA9210_MAX_MV 1570
#define DA9210_STEP_MV 10
/* Current limits for buck (uA) indices corresponds with register values */
static
const
int
da9210_buck_limits
[]
=
{
1600000
,
1800000
,
2000000
,
2200000
,
2400000
,
2600000
,
2800000
,
3000000
,
3200000
,
3400000
,
3600000
,
3800000
,
4000000
,
4200000
,
4400000
,
4600000
};
static
const
struct
regulator_desc
da9210_reg
=
{
.
name
=
"DA9210"
,
.
id
=
0
,
.
ops
=
&
da9210_buck_ops
,
.
type
=
REGULATOR_VOLTAGE
,
.
n_voltages
=
((
DA9210_MAX_MV
-
DA9210_MIN_MV
)
/
DA9210_STEP_MV
)
+
1
,
.
min_uV
=
(
DA9210_MIN_MV
*
1000
),
.
uV_step
=
(
DA9210_STEP_MV
*
1000
),
.
vsel_reg
=
DA9210_REG_VBUCK_A
,
.
vsel_mask
=
DA9210_VBUCK_MASK
,
.
enable_reg
=
DA9210_REG_BUCK_CONT
,
.
enable_mask
=
DA9210_BUCK_EN
,
.
owner
=
THIS_MODULE
,
};
static
int
da9210_set_current_limit
(
struct
regulator_dev
*
rdev
,
int
min_uA
,
int
max_uA
)
{
struct
da9210
*
chip
=
rdev_get_drvdata
(
rdev
);
unsigned
int
sel
;
int
i
;
/* search for closest to maximum */
for
(
i
=
ARRAY_SIZE
(
da9210_buck_limits
)
-
1
;
i
>=
0
;
i
--
)
{
if
(
min_uA
<=
da9210_buck_limits
[
i
]
&&
max_uA
>=
da9210_buck_limits
[
i
])
{
sel
=
i
;
sel
=
sel
<<
DA9210_BUCK_ILIM_SHIFT
;
return
regmap_update_bits
(
chip
->
regmap
,
DA9210_REG_BUCK_ILIM
,
DA9210_BUCK_ILIM_MASK
,
sel
);
}
}
return
-
EINVAL
;
}
static
int
da9210_get_current_limit
(
struct
regulator_dev
*
rdev
)
{
struct
da9210
*
chip
=
rdev_get_drvdata
(
rdev
);
unsigned
int
data
;
unsigned
int
sel
;
int
ret
;
ret
=
regmap_read
(
chip
->
regmap
,
DA9210_REG_BUCK_ILIM
,
&
data
);
if
(
ret
<
0
)
return
ret
;
/* select one of 16 values: 0000 (1600mA) to 1111 (4600mA) */
sel
=
(
data
&
DA9210_BUCK_ILIM_MASK
)
>>
DA9210_BUCK_ILIM_SHIFT
;
return
da9210_buck_limits
[
sel
];
}
/*
* I2C driver interface functions
*/
static
int
da9210_i2c_probe
(
struct
i2c_client
*
i2c
,
const
struct
i2c_device_id
*
id
)
{
struct
da9210
*
chip
;
struct
da9210_pdata
*
pdata
=
i2c
->
dev
.
platform_data
;
struct
regulator_dev
*
rdev
=
NULL
;
struct
regulator_config
config
=
{
};
int
error
;
chip
=
devm_kzalloc
(
&
i2c
->
dev
,
sizeof
(
struct
da9210
),
GFP_KERNEL
);
if
(
NULL
==
chip
)
{
dev_err
(
&
i2c
->
dev
,
"Cannot kzalloc memory for regulator structure
\n
"
);
return
-
ENOMEM
;
}
chip
->
regmap
=
devm_regmap_init_i2c
(
i2c
,
&
da9210_regmap_config
);
if
(
IS_ERR
(
chip
->
regmap
))
{
error
=
PTR_ERR
(
chip
->
regmap
);
dev_err
(
&
i2c
->
dev
,
"Failed to allocate register map: %d
\n
"
,
error
);
return
error
;
}
config
.
dev
=
&
i2c
->
dev
;
if
(
pdata
)
config
.
init_data
=
&
pdata
->
da9210_constraints
;
config
.
driver_data
=
chip
;
config
.
regmap
=
chip
->
regmap
;
rdev
=
regulator_register
(
&
da9210_reg
,
&
config
);
if
(
IS_ERR
(
rdev
))
{
dev_err
(
&
i2c
->
dev
,
"Failed to register DA9210 regulator
\n
"
);
return
PTR_ERR
(
rdev
);
}
chip
->
rdev
=
rdev
;
i2c_set_clientdata
(
i2c
,
chip
);
return
0
;
}
static
int
da9210_i2c_remove
(
struct
i2c_client
*
i2c
)
{
struct
da9210
*
chip
=
i2c_get_clientdata
(
i2c
);
regulator_unregister
(
chip
->
rdev
);
return
0
;
}
static
const
struct
i2c_device_id
da9210_i2c_id
[]
=
{
{
"da9210"
,
0
},
{},
};
MODULE_DEVICE_TABLE
(
i2c
,
da9210_i2c_id
);
static
struct
i2c_driver
da9210_regulator_driver
=
{
.
driver
=
{
.
name
=
"da9210"
,
.
owner
=
THIS_MODULE
,
},
.
probe
=
da9210_i2c_probe
,
.
remove
=
da9210_i2c_remove
,
.
id_table
=
da9210_i2c_id
,
};
module_i2c_driver
(
da9210_regulator_driver
);
MODULE_AUTHOR
(
"S Twiss <stwiss.opensource@diasemi.com>"
);
MODULE_DESCRIPTION
(
"Regulator device driver for Dialog DA9210"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/regulator/da9210-regulator.h
0 → 100644
View file @
62696579
/*
* da9210-regulator.h - Regulator definitions for DA9210
* Copyright (C) 2013 Dialog Semiconductor Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __DA9210_REGISTERS_H__
#define __DA9210_REGISTERS_H__
struct
da9210_pdata
{
struct
regulator_init_data
da9210_constraints
;
};
/* Page selection */
#define DA9210_REG_PAGE_CON 0x00
/* System Control and Event Registers */
#define DA9210_REG_STATUS_A 0x50
#define DA9210_REG_STATUS_B 0x51
#define DA9210_REG_EVENT_A 0x52
#define DA9210_REG_EVENT_B 0x53
#define DA9210_REG_MASK_A 0x54
#define DA9210_REG_MASK_B 0x55
#define DA9210_REG_CONTROL_A 0x56
/* GPIO Control Registers */
#define DA9210_REG_GPIO_0_1 0x58
#define DA9210_REG_GPIO_2_3 0x59
#define DA9210_REG_GPIO_4_5 0x5A
#define DA9210_REG_GPIO_6 0x5B
/* Regulator Registers */
#define DA9210_REG_BUCK_CONT 0x5D
#define DA9210_REG_BUCK_ILIM 0xD0
#define DA9210_REG_BUCK_CONF1 0xD1
#define DA9210_REG_BUCK_CONF2 0xD2
#define DA9210_REG_VBACK_AUTO 0xD4
#define DA9210_REG_VBACK_BASE 0xD5
#define DA9210_REG_VBACK_MAX_DVC_IF 0xD6
#define DA9210_REG_VBACK_DVC 0xD7
#define DA9210_REG_VBUCK_A 0xD8
#define DA9210_REG_VBUCK_B 0xD9
/* I2C Interface Settings */
#define DA9210_REG_INTERFACE 0x105
/* OTP */
#define DA9210_REG_OPT_COUNT 0x140
#define DA9210_REG_OPT_ADDR 0x141
#define DA9210_REG_OPT_DATA 0x142
/* Customer Trim and Configuration */
#define DA9210_REG_CONFIG_A 0x143
#define DA9210_REG_CONFIG_B 0x144
#define DA9210_REG_CONFIG_C 0x145
#define DA9210_REG_CONFIG_D 0x146
#define DA9210_REG_CONFIG_E 0x147
/*
* Registers bits
*/
/* DA9210_REG_PAGE_CON (addr=0x00) */
#define DA9210_PEG_PAGE_SHIFT 0
#define DA9210_REG_PAGE_MASK 0x0F
/* On I2C registers 0x00 - 0xFF */
#define DA9210_REG_PAGE0 0
/* On I2C registers 0x100 - 0x1FF */
#define DA9210_REG_PAGE2 2
#define DA9210_PAGE_WRITE_MODE 0x00
#define DA9210_REPEAT_WRITE_MODE 0x40
#define DA9210_PAGE_REVERT 0x80
/* DA9210_REG_STATUS_A (addr=0x50) */
#define DA9210_GPI0 0x01
#define DA9210_GPI1 0x02
#define DA9210_GPI2 0x04
#define DA9210_GPI3 0x08
#define DA9210_GPI4 0x10
#define DA9210_GPI5 0x20
#define DA9210_GPI6 0x40
/* DA9210_REG_EVENT_A (addr=0x52) */
#define DA9210_E_GPI0 0x01
#define DA9210_E_GPI1 0x02
#define DA9210_E_GPI2 0x04
#define DA9210_E_GPI3 0x08
#define DA9210_E_GPI4 0x10
#define DA9210_E_GPI5 0x20
#define DA9210_E_GPI6 0x40
/* DA9210_REG_EVENT_B (addr=0x53) */
#define DA9210_E_OVCURR 0x01
#define DA9210_E_NPWRGOOD 0x02
#define DA9210_E_TEMP_WARN 0x04
#define DA9210_E_TEMP_CRIT 0x08
#define DA9210_E_VMAX 0x10
/* DA9210_REG_MASK_A (addr=0x54) */
#define DA9210_M_GPI0 0x01
#define DA9210_M_GPI1 0x02
#define DA9210_M_GPI2 0x04
#define DA9210_M_GPI3 0x08
#define DA9210_M_GPI4 0x10
#define DA9210_M_GPI5 0x20
#define DA9210_M_GPI6 0x40
/* DA9210_REG_MASK_B (addr=0x55) */
#define DA9210_M_OVCURR 0x01
#define DA9210_M_NPWRGOOD 0x02
#define DA9210_M_TEMP_WARN 0x04
#define DA9210_M_TEMP_CRIT 0x08
#define DA9210_M_VMAX 0x10
/* DA9210_REG_CONTROL_A (addr=0x56) */
#define DA9210_DEBOUNCING_SHIFT 0
#define DA9210_DEBOUNCING_MASK 0x07
#define DA9210_SLEW_RATE_SHIFT 3
#define DA9210_SLEW_RATE_MASK 0x18
#define DA9210_V_LOCK 0x20
/* DA9210_REG_GPIO_0_1 (addr=0x58) */
#define DA9210_GPIO0_PIN_SHIFT 0
#define DA9210_GPIO0_PIN_MASK 0x03
#define DA9210_GPIO0_PIN_GPI 0x00
#define DA9210_GPIO0_PIN_GPO_OD 0x02
#define DA9210_GPIO0_PIN_GPO 0x03
#define DA9210_GPIO0_TYPE 0x04
#define DA9210_GPIO0_TYPE_GPI 0x00
#define DA9210_GPIO0_TYPE_GPO 0x04
#define DA9210_GPIO0_MODE 0x08
#define DA9210_GPIO1_PIN_SHIFT 4
#define DA9210_GPIO1_PIN_MASK 0x30
#define DA9210_GPIO1_PIN_GPI 0x00
#define DA9210_GPIO1_PIN_VERROR 0x10
#define DA9210_GPIO1_PIN_GPO_OD 0x20
#define DA9210_GPIO1_PIN_GPO 0x30
#define DA9210_GPIO1_TYPE_SHIFT 0x40
#define DA9210_GPIO1_TYPE_GPI 0x00
#define DA9210_GPIO1_TYPE_GPO 0x40
#define DA9210_GPIO1_MODE 0x80
/* DA9210_REG_GPIO_2_3 (addr=0x59) */
#define DA9210_GPIO2_PIN_SHIFT 0
#define DA9210_GPIO2_PIN_MASK 0x03
#define DA9210_GPIO2_PIN_GPI 0x00
#define DA9210_GPIO5_PIN_BUCK_CLK 0x10
#define DA9210_GPIO2_PIN_GPO_OD 0x02
#define DA9210_GPIO2_PIN_GPO 0x03
#define DA9210_GPIO2_TYPE 0x04
#define DA9210_GPIO2_TYPE_GPI 0x00
#define DA9210_GPIO2_TYPE_GPO 0x04
#define DA9210_GPIO2_MODE 0x08
#define DA9210_GPIO3_PIN_SHIFT 4
#define DA9210_GPIO3_PIN_MASK 0x30
#define DA9210_GPIO3_PIN_GPI 0x00
#define DA9210_GPIO3_PIN_IERROR 0x10
#define DA9210_GPIO3_PIN_GPO_OD 0x20
#define DA9210_GPIO3_PIN_GPO 0x30
#define DA9210_GPIO3_TYPE_SHIFT 0x40
#define DA9210_GPIO3_TYPE_GPI 0x00
#define DA9210_GPIO3_TYPE_GPO 0x40
#define DA9210_GPIO3_MODE 0x80
/* DA9210_REG_GPIO_4_5 (addr=0x5A) */
#define DA9210_GPIO4_PIN_SHIFT 0
#define DA9210_GPIO4_PIN_MASK 0x03
#define DA9210_GPIO4_PIN_GPI 0x00
#define DA9210_GPIO4_PIN_GPO_OD 0x02
#define DA9210_GPIO4_PIN_GPO 0x03
#define DA9210_GPIO4_TYPE 0x04
#define DA9210_GPIO4_TYPE_GPI 0x00
#define DA9210_GPIO4_TYPE_GPO 0x04
#define DA9210_GPIO4_MODE 0x08
#define DA9210_GPIO5_PIN_SHIFT 4
#define DA9210_GPIO5_PIN_MASK 0x30
#define DA9210_GPIO5_PIN_GPI 0x00
#define DA9210_GPIO5_PIN_INTERFACE 0x01
#define DA9210_GPIO5_PIN_GPO_OD 0x20
#define DA9210_GPIO5_PIN_GPO 0x30
#define DA9210_GPIO5_TYPE_SHIFT 0x40
#define DA9210_GPIO5_TYPE_GPI 0x00
#define DA9210_GPIO5_TYPE_GPO 0x40
#define DA9210_GPIO5_MODE 0x80
/* DA9210_REG_GPIO_6 (addr=0x5B) */
#define DA9210_GPIO6_PIN_SHIFT 0
#define DA9210_GPIO6_PIN_MASK 0x03
#define DA9210_GPIO6_PIN_GPI 0x00
#define DA9210_GPIO6_PIN_INTERFACE 0x01
#define DA9210_GPIO6_PIN_GPO_OD 0x02
#define DA9210_GPIO6_PIN_GPO 0x03
#define DA9210_GPIO6_TYPE 0x04
#define DA9210_GPIO6_TYPE_GPI 0x00
#define DA9210_GPIO6_TYPE_GPO 0x04
#define DA9210_GPIO6_MODE 0x08
/* DA9210_REG_BUCK_CONT (addr=0x5D) */
#define DA9210_BUCK_EN 0x01
#define DA9210_BUCK_GPI_SHIFT 1
#define DA9210_BUCK_GPI_MASK 0x06
#define DA9210_BUCK_GPI_OFF 0x00
#define DA9210_BUCK_GPI_GPIO0 0x02
#define DA9210_BUCK_GPI_GPIO3 0x04
#define DA9210_BUCK_GPI_GPIO4 0x06
#define DA9210_BUCK_PD_DIS 0x08
#define DA9210_VBUCK_SEL 0x10
#define DA9210_VBUCK_SEL_A 0x00
#define DA9210_VBUCK_SEL_B 0x10
#define DA9210_VBUCK_GPI_SHIFT 5
#define DA9210_VBUCK_GPI_MASK 0x60
#define DA9210_VBUCK_GPI_OFF 0x00
#define DA9210_VBUCK_GPI_GPIO0 0x20
#define DA9210_VBUCK_GPI_GPIO3 0x40
#define DA9210_VBUCK_GPI_GPIO4 0x60
#define DA9210_DVC_CTRL_EN 0x80
/* DA9210_REG_BUCK_ILIM (addr=0xD0) */
#define DA9210_BUCK_ILIM_SHIFT 0
#define DA9210_BUCK_ILIM_MASK 0x0F
#define DA9210_BUCK_IALARM 0x10
/* DA9210_REG_BUCK_CONF1 (addr=0xD1) */
#define DA9210_BUCK_MODE_SHIFT 0
#define DA9210_BUCK_MODE_MASK 0x03
#define DA9210_BUCK_MODE_MANUAL 0x00
#define DA9210_BUCK_MODE_SLEEP 0x01
#define DA9210_BUCK_MODE_SYNC 0x02
#define DA9210_BUCK_MODE_AUTO 0x03
#define DA9210_STARTUP_CTRL_SHIFT 2
#define DA9210_STARTUP_CTRL_MASK 0x1C
#define DA9210_PWR_DOWN_CTRL_SHIFT 5
#define DA9210_PWR_DOWN_CTRL_MASK 0xE0
/* DA9210_REG_BUCK_CONF2 (addr=0xD2) */
#define DA9210_PHASE_SEL_SHIFT 0
#define DA9210_PHASE_SEL_MASK 0x03
#define DA9210_FREQ_SEL 0x40
/* DA9210_REG_BUCK_AUTO (addr=0xD4) */
#define DA9210_VBUCK_AUTO_SHIFT 0
#define DA9210_VBUCK_AUTO_MASK 0x7F
/* DA9210_REG_BUCK_BASE (addr=0xD5) */
#define DA9210_VBUCK_BASE_SHIFT 0
#define DA9210_VBUCK_BASE_MASK 0x7F
/* DA9210_REG_VBUCK_MAX_DVC_IF (addr=0xD6) */
#define DA9210_VBUCK_MAX_SHIFT 0
#define DA9210_VBUCK_MAX_MASK 0x7F
#define DA9210_DVC_STEP_SIZE 0x80
#define DA9210_DVC_STEP_SIZE_10MV 0x00
#define DA9210_DVC_STEP_SIZE_20MV 0x80
/* DA9210_REG_VBUCK_DVC (addr=0xD7) */
#define DA9210_VBUCK_DVC_SHIFT 0
#define DA9210_VBUCK_DVC_MASK 0x7F
/* DA9210_REG_VBUCK_A/B (addr=0xD8/0xD9) */
#define DA9210_VBUCK_SHIFT 0
#define DA9210_VBUCK_MASK 0x7F
#define DA9210_VBUCK_BIAS 0
#define DA9210_BUCK_SL 0x80
/* DA9210_REG_INTERFACE (addr=0x105) */
#define DA9210_IF_BASE_ADDR_SHIFT 4
#define DA9210_IF_BASE_ADDR_MASK 0xF0
/* DA9210_REG_CONFIG_E (addr=0x147) */
#define DA9210_STAND_ALONE 0x01
#endif
/* __DA9210_REGISTERS_H__ */
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