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
Kirill Smelkov
linux
Commits
724d0544
Commit
724d0544
authored
Sep 01, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regulator/topic/helpers' into regulator-next
parents
446b4665
d295f767
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
458 additions
and
463 deletions
+458
-463
drivers/regulator/Makefile
drivers/regulator/Makefile
+1
-1
drivers/regulator/core.c
drivers/regulator/core.c
+0
-427
drivers/regulator/da903x.c
drivers/regulator/da903x.c
+10
-35
drivers/regulator/helpers.c
drivers/regulator/helpers.c
+447
-0
No files found.
drivers/regulator/Makefile
View file @
724d0544
...
...
@@ -3,7 +3,7 @@
#
obj-$(CONFIG_REGULATOR)
+=
core.o dummy.o fixed-helper.o
obj-$(CONFIG_REGULATOR)
+=
core.o dummy.o fixed-helper.o
helpers.o
obj-$(CONFIG_OF)
+=
of_regulator.o
obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE)
+=
fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER)
+=
virtual.o
...
...
drivers/regulator/core.c
View file @
724d0544
...
...
@@ -1904,77 +1904,6 @@ int regulator_disable_deferred(struct regulator *regulator, int ms)
}
EXPORT_SYMBOL_GPL
(
regulator_disable_deferred
);
/**
* regulator_is_enabled_regmap - standard is_enabled() for regmap users
*
* @rdev: regulator to operate on
*
* Regulators that use regmap for their register I/O can set the
* enable_reg and enable_mask fields in their descriptor and then use
* this as their is_enabled operation, saving some code.
*/
int
regulator_is_enabled_regmap
(
struct
regulator_dev
*
rdev
)
{
unsigned
int
val
;
int
ret
;
ret
=
regmap_read
(
rdev
->
regmap
,
rdev
->
desc
->
enable_reg
,
&
val
);
if
(
ret
!=
0
)
return
ret
;
if
(
rdev
->
desc
->
enable_is_inverted
)
return
(
val
&
rdev
->
desc
->
enable_mask
)
==
0
;
else
return
(
val
&
rdev
->
desc
->
enable_mask
)
!=
0
;
}
EXPORT_SYMBOL_GPL
(
regulator_is_enabled_regmap
);
/**
* regulator_enable_regmap - standard enable() for regmap users
*
* @rdev: regulator to operate on
*
* Regulators that use regmap for their register I/O can set the
* enable_reg and enable_mask fields in their descriptor and then use
* this as their enable() operation, saving some code.
*/
int
regulator_enable_regmap
(
struct
regulator_dev
*
rdev
)
{
unsigned
int
val
;
if
(
rdev
->
desc
->
enable_is_inverted
)
val
=
0
;
else
val
=
rdev
->
desc
->
enable_mask
;
return
regmap_update_bits
(
rdev
->
regmap
,
rdev
->
desc
->
enable_reg
,
rdev
->
desc
->
enable_mask
,
val
);
}
EXPORT_SYMBOL_GPL
(
regulator_enable_regmap
);
/**
* regulator_disable_regmap - standard disable() for regmap users
*
* @rdev: regulator to operate on
*
* Regulators that use regmap for their register I/O can set the
* enable_reg and enable_mask fields in their descriptor and then use
* this as their disable() operation, saving some code.
*/
int
regulator_disable_regmap
(
struct
regulator_dev
*
rdev
)
{
unsigned
int
val
;
if
(
rdev
->
desc
->
enable_is_inverted
)
val
=
rdev
->
desc
->
enable_mask
;
else
val
=
0
;
return
regmap_update_bits
(
rdev
->
regmap
,
rdev
->
desc
->
enable_reg
,
rdev
->
desc
->
enable_mask
,
val
);
}
EXPORT_SYMBOL_GPL
(
regulator_disable_regmap
);
static
int
_regulator_is_enabled
(
struct
regulator_dev
*
rdev
)
{
/* A GPIO control always takes precedence */
...
...
@@ -2059,92 +1988,6 @@ int regulator_count_voltages(struct regulator *regulator)
}
EXPORT_SYMBOL_GPL
(
regulator_count_voltages
);
/**
* regulator_list_voltage_linear - List voltages with simple calculation
*
* @rdev: Regulator device
* @selector: Selector to convert into a voltage
*
* Regulators with a simple linear mapping between voltages and
* selectors can set min_uV and uV_step in the regulator descriptor
* and then use this function as their list_voltage() operation,
*/
int
regulator_list_voltage_linear
(
struct
regulator_dev
*
rdev
,
unsigned
int
selector
)
{
if
(
selector
>=
rdev
->
desc
->
n_voltages
)
return
-
EINVAL
;
if
(
selector
<
rdev
->
desc
->
linear_min_sel
)
return
0
;
selector
-=
rdev
->
desc
->
linear_min_sel
;
return
rdev
->
desc
->
min_uV
+
(
rdev
->
desc
->
uV_step
*
selector
);
}
EXPORT_SYMBOL_GPL
(
regulator_list_voltage_linear
);
/**
* regulator_list_voltage_linear_range - List voltages for linear ranges
*
* @rdev: Regulator device
* @selector: Selector to convert into a voltage
*
* Regulators with a series of simple linear mappings between voltages
* and selectors can set linear_ranges in the regulator descriptor and
* then use this function as their list_voltage() operation,
*/
int
regulator_list_voltage_linear_range
(
struct
regulator_dev
*
rdev
,
unsigned
int
selector
)
{
const
struct
regulator_linear_range
*
range
;
int
i
;
if
(
!
rdev
->
desc
->
n_linear_ranges
)
{
BUG_ON
(
!
rdev
->
desc
->
n_linear_ranges
);
return
-
EINVAL
;
}
for
(
i
=
0
;
i
<
rdev
->
desc
->
n_linear_ranges
;
i
++
)
{
range
=
&
rdev
->
desc
->
linear_ranges
[
i
];
if
(
!
(
selector
>=
range
->
min_sel
&&
selector
<=
range
->
max_sel
))
continue
;
selector
-=
range
->
min_sel
;
return
range
->
min_uV
+
(
range
->
uV_step
*
selector
);
}
return
-
EINVAL
;
}
EXPORT_SYMBOL_GPL
(
regulator_list_voltage_linear_range
);
/**
* regulator_list_voltage_table - List voltages with table based mapping
*
* @rdev: Regulator device
* @selector: Selector to convert into a voltage
*
* Regulators with table based mapping between voltages and
* selectors can set volt_table in the regulator descriptor
* and then use this function as their list_voltage() operation.
*/
int
regulator_list_voltage_table
(
struct
regulator_dev
*
rdev
,
unsigned
int
selector
)
{
if
(
!
rdev
->
desc
->
volt_table
)
{
BUG_ON
(
!
rdev
->
desc
->
volt_table
);
return
-
EINVAL
;
}
if
(
selector
>=
rdev
->
desc
->
n_voltages
)
return
-
EINVAL
;
return
rdev
->
desc
->
volt_table
[
selector
];
}
EXPORT_SYMBOL_GPL
(
regulator_list_voltage_table
);
/**
* regulator_list_voltage - enumerate supported voltages
* @regulator: regulator source
...
...
@@ -2239,235 +2082,6 @@ int regulator_is_supported_voltage(struct regulator *regulator,
}
EXPORT_SYMBOL_GPL
(
regulator_is_supported_voltage
);
/**
* regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
*
* @rdev: regulator to operate on
*
* Regulators that use regmap for their register I/O can set the
* vsel_reg and vsel_mask fields in their descriptor and then use this
* as their get_voltage_vsel operation, saving some code.
*/
int
regulator_get_voltage_sel_regmap
(
struct
regulator_dev
*
rdev
)
{
unsigned
int
val
;
int
ret
;
ret
=
regmap_read
(
rdev
->
regmap
,
rdev
->
desc
->
vsel_reg
,
&
val
);
if
(
ret
!=
0
)
return
ret
;
val
&=
rdev
->
desc
->
vsel_mask
;
val
>>=
ffs
(
rdev
->
desc
->
vsel_mask
)
-
1
;
return
val
;
}
EXPORT_SYMBOL_GPL
(
regulator_get_voltage_sel_regmap
);
/**
* regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
*
* @rdev: regulator to operate on
* @sel: Selector to set
*
* Regulators that use regmap for their register I/O can set the
* vsel_reg and vsel_mask fields in their descriptor and then use this
* as their set_voltage_vsel operation, saving some code.
*/
int
regulator_set_voltage_sel_regmap
(
struct
regulator_dev
*
rdev
,
unsigned
sel
)
{
int
ret
;
sel
<<=
ffs
(
rdev
->
desc
->
vsel_mask
)
-
1
;
ret
=
regmap_update_bits
(
rdev
->
regmap
,
rdev
->
desc
->
vsel_reg
,
rdev
->
desc
->
vsel_mask
,
sel
);
if
(
ret
)
return
ret
;
if
(
rdev
->
desc
->
apply_bit
)
ret
=
regmap_update_bits
(
rdev
->
regmap
,
rdev
->
desc
->
apply_reg
,
rdev
->
desc
->
apply_bit
,
rdev
->
desc
->
apply_bit
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
regulator_set_voltage_sel_regmap
);
/**
* regulator_map_voltage_iterate - map_voltage() based on list_voltage()
*
* @rdev: Regulator to operate on
* @min_uV: Lower bound for voltage
* @max_uV: Upper bound for voltage
*
* Drivers implementing set_voltage_sel() and list_voltage() can use
* this as their map_voltage() operation. It will find a suitable
* voltage by calling list_voltage() until it gets something in bounds
* for the requested voltages.
*/
int
regulator_map_voltage_iterate
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
)
{
int
best_val
=
INT_MAX
;
int
selector
=
0
;
int
i
,
ret
;
/* Find the smallest voltage that falls within the specified
* range.
*/
for
(
i
=
0
;
i
<
rdev
->
desc
->
n_voltages
;
i
++
)
{
ret
=
rdev
->
desc
->
ops
->
list_voltage
(
rdev
,
i
);
if
(
ret
<
0
)
continue
;
if
(
ret
<
best_val
&&
ret
>=
min_uV
&&
ret
<=
max_uV
)
{
best_val
=
ret
;
selector
=
i
;
}
}
if
(
best_val
!=
INT_MAX
)
return
selector
;
else
return
-
EINVAL
;
}
EXPORT_SYMBOL_GPL
(
regulator_map_voltage_iterate
);
/**
* regulator_map_voltage_ascend - map_voltage() for ascendant voltage list
*
* @rdev: Regulator to operate on
* @min_uV: Lower bound for voltage
* @max_uV: Upper bound for voltage
*
* Drivers that have ascendant voltage list can use this as their
* map_voltage() operation.
*/
int
regulator_map_voltage_ascend
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
)
{
int
i
,
ret
;
for
(
i
=
0
;
i
<
rdev
->
desc
->
n_voltages
;
i
++
)
{
ret
=
rdev
->
desc
->
ops
->
list_voltage
(
rdev
,
i
);
if
(
ret
<
0
)
continue
;
if
(
ret
>
max_uV
)
break
;
if
(
ret
>=
min_uV
&&
ret
<=
max_uV
)
return
i
;
}
return
-
EINVAL
;
}
EXPORT_SYMBOL_GPL
(
regulator_map_voltage_ascend
);
/**
* regulator_map_voltage_linear - map_voltage() for simple linear mappings
*
* @rdev: Regulator to operate on
* @min_uV: Lower bound for voltage
* @max_uV: Upper bound for voltage
*
* Drivers providing min_uV and uV_step in their regulator_desc can
* use this as their map_voltage() operation.
*/
int
regulator_map_voltage_linear
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
)
{
int
ret
,
voltage
;
/* Allow uV_step to be 0 for fixed voltage */
if
(
rdev
->
desc
->
n_voltages
==
1
&&
rdev
->
desc
->
uV_step
==
0
)
{
if
(
min_uV
<=
rdev
->
desc
->
min_uV
&&
rdev
->
desc
->
min_uV
<=
max_uV
)
return
0
;
else
return
-
EINVAL
;
}
if
(
!
rdev
->
desc
->
uV_step
)
{
BUG_ON
(
!
rdev
->
desc
->
uV_step
);
return
-
EINVAL
;
}
if
(
min_uV
<
rdev
->
desc
->
min_uV
)
min_uV
=
rdev
->
desc
->
min_uV
;
ret
=
DIV_ROUND_UP
(
min_uV
-
rdev
->
desc
->
min_uV
,
rdev
->
desc
->
uV_step
);
if
(
ret
<
0
)
return
ret
;
ret
+=
rdev
->
desc
->
linear_min_sel
;
/* Map back into a voltage to verify we're still in bounds */
voltage
=
rdev
->
desc
->
ops
->
list_voltage
(
rdev
,
ret
);
if
(
voltage
<
min_uV
||
voltage
>
max_uV
)
return
-
EINVAL
;
return
ret
;
}
EXPORT_SYMBOL_GPL
(
regulator_map_voltage_linear
);
/**
* regulator_map_voltage_linear - map_voltage() for multiple linear ranges
*
* @rdev: Regulator to operate on
* @min_uV: Lower bound for voltage
* @max_uV: Upper bound for voltage
*
* Drivers providing linear_ranges in their descriptor can use this as
* their map_voltage() callback.
*/
int
regulator_map_voltage_linear_range
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
)
{
const
struct
regulator_linear_range
*
range
;
int
ret
=
-
EINVAL
;
int
voltage
,
i
;
if
(
!
rdev
->
desc
->
n_linear_ranges
)
{
BUG_ON
(
!
rdev
->
desc
->
n_linear_ranges
);
return
-
EINVAL
;
}
for
(
i
=
0
;
i
<
rdev
->
desc
->
n_linear_ranges
;
i
++
)
{
range
=
&
rdev
->
desc
->
linear_ranges
[
i
];
if
(
!
(
min_uV
<=
range
->
max_uV
&&
max_uV
>=
range
->
min_uV
))
continue
;
if
(
min_uV
<=
range
->
min_uV
)
min_uV
=
range
->
min_uV
;
/* range->uV_step == 0 means fixed voltage range */
if
(
range
->
uV_step
==
0
)
{
ret
=
0
;
}
else
{
ret
=
DIV_ROUND_UP
(
min_uV
-
range
->
min_uV
,
range
->
uV_step
);
if
(
ret
<
0
)
return
ret
;
}
ret
+=
range
->
min_sel
;
break
;
}
if
(
i
==
rdev
->
desc
->
n_linear_ranges
)
return
-
EINVAL
;
/* Map back into a voltage to verify we're still in bounds */
voltage
=
rdev
->
desc
->
ops
->
list_voltage
(
rdev
,
ret
);
if
(
voltage
<
min_uV
||
voltage
>
max_uV
)
return
-
EINVAL
;
return
ret
;
}
EXPORT_SYMBOL_GPL
(
regulator_map_voltage_linear_range
);
static
int
_regulator_do_set_voltage
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
)
{
...
...
@@ -3070,47 +2684,6 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
}
EXPORT_SYMBOL_GPL
(
regulator_set_optimum_mode
);
/**
* regulator_set_bypass_regmap - Default set_bypass() using regmap
*
* @rdev: device to operate on.
* @enable: state to set.
*/
int
regulator_set_bypass_regmap
(
struct
regulator_dev
*
rdev
,
bool
enable
)
{
unsigned
int
val
;
if
(
enable
)
val
=
rdev
->
desc
->
bypass_mask
;
else
val
=
0
;
return
regmap_update_bits
(
rdev
->
regmap
,
rdev
->
desc
->
bypass_reg
,
rdev
->
desc
->
bypass_mask
,
val
);
}
EXPORT_SYMBOL_GPL
(
regulator_set_bypass_regmap
);
/**
* regulator_get_bypass_regmap - Default get_bypass() using regmap
*
* @rdev: device to operate on.
* @enable: current state.
*/
int
regulator_get_bypass_regmap
(
struct
regulator_dev
*
rdev
,
bool
*
enable
)
{
unsigned
int
val
;
int
ret
;
ret
=
regmap_read
(
rdev
->
regmap
,
rdev
->
desc
->
bypass_reg
,
&
val
);
if
(
ret
!=
0
)
return
ret
;
*
enable
=
val
&
rdev
->
desc
->
bypass_mask
;
return
0
;
}
EXPORT_SYMBOL_GPL
(
regulator_get_bypass_regmap
);
/**
* regulator_allow_bypass - allow the regulator to go into bypass mode
*
...
...
drivers/regulator/da903x.c
View file @
724d0544
...
...
@@ -252,39 +252,12 @@ static int da9034_set_dvc_voltage_sel(struct regulator_dev *rdev,
return
ret
;
}
static
int
da9034_map_ldo12_voltage
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
)
{
struct
da903x_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
int
sel
;
if
(
check_range
(
info
,
min_uV
,
max_uV
))
{
pr_err
(
"invalid voltage range (%d, %d) uV
\n
"
,
min_uV
,
max_uV
);
return
-
EINVAL
;
}
sel
=
DIV_ROUND_UP
(
min_uV
-
info
->
desc
.
min_uV
,
info
->
desc
.
uV_step
);
sel
=
(
sel
>=
20
)
?
sel
-
12
:
((
sel
>
7
)
?
8
:
sel
);
return
sel
;
}
static
int
da9034_list_ldo12_voltage
(
struct
regulator_dev
*
rdev
,
unsigned
selector
)
{
struct
da903x_regulator_info
*
info
=
rdev_get_drvdata
(
rdev
);
int
volt
;
if
(
selector
>=
8
)
volt
=
2700000
+
rdev
->
desc
->
uV_step
*
(
selector
-
8
);
else
volt
=
rdev
->
desc
->
min_uV
+
rdev
->
desc
->
uV_step
*
selector
;
if
(
volt
>
info
->
max_uV
)
return
-
EINVAL
;
return
volt
;
}
static
const
struct
regulator_linear_range
da9034_ldo12_ranges
[]
=
{
{
.
min_uV
=
1700000
,
.
max_uV
=
2050000
,
.
min_sel
=
0
,
.
max_sel
=
7
,
.
uV_step
=
50000
},
{
.
min_uV
=
2700000
,
.
max_uV
=
3050000
,
.
min_sel
=
8
,
.
max_sel
=
15
,
.
uV_step
=
50000
},
};
static
struct
regulator_ops
da903x_regulator_ldo_ops
=
{
.
set_voltage_sel
=
da903x_set_voltage_sel
,
...
...
@@ -332,8 +305,8 @@ static struct regulator_ops da9034_regulator_dvc_ops = {
static
struct
regulator_ops
da9034_regulator_ldo12_ops
=
{
.
set_voltage_sel
=
da903x_set_voltage_sel
,
.
get_voltage_sel
=
da903x_get_voltage_sel
,
.
list_voltage
=
da9034_list_ldo12_volta
ge
,
.
map_voltage
=
da9034_map_ldo12_volta
ge
,
.
list_voltage
=
regulator_list_voltage_linear_ran
ge
,
.
map_voltage
=
regulator_map_voltage_linear_ran
ge
,
.
enable
=
da903x_enable
,
.
disable
=
da903x_disable
,
.
is_enabled
=
da903x_is_enabled
,
...
...
@@ -476,6 +449,8 @@ static int da903x_regulator_probe(struct platform_device *pdev)
if
(
ri
->
desc
.
id
==
DA9034_ID_LDO12
)
{
ri
->
desc
.
ops
=
&
da9034_regulator_ldo12_ops
;
ri
->
desc
.
n_voltages
=
16
;
ri
->
desc
.
linear_ranges
=
da9034_ldo12_ranges
;
ri
->
desc
.
n_linear_ranges
=
ARRAY_SIZE
(
da9034_ldo12_ranges
);
}
if
(
ri
->
desc
.
id
==
DA9030_ID_LDO14
)
...
...
drivers/regulator/helpers.c
0 → 100644
View file @
724d0544
/*
* helpers.c -- Voltage/Current Regulator framework helper functions.
*
* Copyright 2007, 2008 Wolfson Microelectronics PLC.
* Copyright 2008 SlimLogic Ltd.
*
* 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/err.h>
#include <linux/delay.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
#include <linux/module.h>
/**
* regulator_is_enabled_regmap - standard is_enabled() for regmap users
*
* @rdev: regulator to operate on
*
* Regulators that use regmap for their register I/O can set the
* enable_reg and enable_mask fields in their descriptor and then use
* this as their is_enabled operation, saving some code.
*/
int
regulator_is_enabled_regmap
(
struct
regulator_dev
*
rdev
)
{
unsigned
int
val
;
int
ret
;
ret
=
regmap_read
(
rdev
->
regmap
,
rdev
->
desc
->
enable_reg
,
&
val
);
if
(
ret
!=
0
)
return
ret
;
if
(
rdev
->
desc
->
enable_is_inverted
)
return
(
val
&
rdev
->
desc
->
enable_mask
)
==
0
;
else
return
(
val
&
rdev
->
desc
->
enable_mask
)
!=
0
;
}
EXPORT_SYMBOL_GPL
(
regulator_is_enabled_regmap
);
/**
* regulator_enable_regmap - standard enable() for regmap users
*
* @rdev: regulator to operate on
*
* Regulators that use regmap for their register I/O can set the
* enable_reg and enable_mask fields in their descriptor and then use
* this as their enable() operation, saving some code.
*/
int
regulator_enable_regmap
(
struct
regulator_dev
*
rdev
)
{
unsigned
int
val
;
if
(
rdev
->
desc
->
enable_is_inverted
)
val
=
0
;
else
val
=
rdev
->
desc
->
enable_mask
;
return
regmap_update_bits
(
rdev
->
regmap
,
rdev
->
desc
->
enable_reg
,
rdev
->
desc
->
enable_mask
,
val
);
}
EXPORT_SYMBOL_GPL
(
regulator_enable_regmap
);
/**
* regulator_disable_regmap - standard disable() for regmap users
*
* @rdev: regulator to operate on
*
* Regulators that use regmap for their register I/O can set the
* enable_reg and enable_mask fields in their descriptor and then use
* this as their disable() operation, saving some code.
*/
int
regulator_disable_regmap
(
struct
regulator_dev
*
rdev
)
{
unsigned
int
val
;
if
(
rdev
->
desc
->
enable_is_inverted
)
val
=
rdev
->
desc
->
enable_mask
;
else
val
=
0
;
return
regmap_update_bits
(
rdev
->
regmap
,
rdev
->
desc
->
enable_reg
,
rdev
->
desc
->
enable_mask
,
val
);
}
EXPORT_SYMBOL_GPL
(
regulator_disable_regmap
);
/**
* regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users
*
* @rdev: regulator to operate on
*
* Regulators that use regmap for their register I/O can set the
* vsel_reg and vsel_mask fields in their descriptor and then use this
* as their get_voltage_vsel operation, saving some code.
*/
int
regulator_get_voltage_sel_regmap
(
struct
regulator_dev
*
rdev
)
{
unsigned
int
val
;
int
ret
;
ret
=
regmap_read
(
rdev
->
regmap
,
rdev
->
desc
->
vsel_reg
,
&
val
);
if
(
ret
!=
0
)
return
ret
;
val
&=
rdev
->
desc
->
vsel_mask
;
val
>>=
ffs
(
rdev
->
desc
->
vsel_mask
)
-
1
;
return
val
;
}
EXPORT_SYMBOL_GPL
(
regulator_get_voltage_sel_regmap
);
/**
* regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users
*
* @rdev: regulator to operate on
* @sel: Selector to set
*
* Regulators that use regmap for their register I/O can set the
* vsel_reg and vsel_mask fields in their descriptor and then use this
* as their set_voltage_vsel operation, saving some code.
*/
int
regulator_set_voltage_sel_regmap
(
struct
regulator_dev
*
rdev
,
unsigned
sel
)
{
int
ret
;
sel
<<=
ffs
(
rdev
->
desc
->
vsel_mask
)
-
1
;
ret
=
regmap_update_bits
(
rdev
->
regmap
,
rdev
->
desc
->
vsel_reg
,
rdev
->
desc
->
vsel_mask
,
sel
);
if
(
ret
)
return
ret
;
if
(
rdev
->
desc
->
apply_bit
)
ret
=
regmap_update_bits
(
rdev
->
regmap
,
rdev
->
desc
->
apply_reg
,
rdev
->
desc
->
apply_bit
,
rdev
->
desc
->
apply_bit
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
regulator_set_voltage_sel_regmap
);
/**
* regulator_map_voltage_iterate - map_voltage() based on list_voltage()
*
* @rdev: Regulator to operate on
* @min_uV: Lower bound for voltage
* @max_uV: Upper bound for voltage
*
* Drivers implementing set_voltage_sel() and list_voltage() can use
* this as their map_voltage() operation. It will find a suitable
* voltage by calling list_voltage() until it gets something in bounds
* for the requested voltages.
*/
int
regulator_map_voltage_iterate
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
)
{
int
best_val
=
INT_MAX
;
int
selector
=
0
;
int
i
,
ret
;
/* Find the smallest voltage that falls within the specified
* range.
*/
for
(
i
=
0
;
i
<
rdev
->
desc
->
n_voltages
;
i
++
)
{
ret
=
rdev
->
desc
->
ops
->
list_voltage
(
rdev
,
i
);
if
(
ret
<
0
)
continue
;
if
(
ret
<
best_val
&&
ret
>=
min_uV
&&
ret
<=
max_uV
)
{
best_val
=
ret
;
selector
=
i
;
}
}
if
(
best_val
!=
INT_MAX
)
return
selector
;
else
return
-
EINVAL
;
}
EXPORT_SYMBOL_GPL
(
regulator_map_voltage_iterate
);
/**
* regulator_map_voltage_ascend - map_voltage() for ascendant voltage list
*
* @rdev: Regulator to operate on
* @min_uV: Lower bound for voltage
* @max_uV: Upper bound for voltage
*
* Drivers that have ascendant voltage list can use this as their
* map_voltage() operation.
*/
int
regulator_map_voltage_ascend
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
)
{
int
i
,
ret
;
for
(
i
=
0
;
i
<
rdev
->
desc
->
n_voltages
;
i
++
)
{
ret
=
rdev
->
desc
->
ops
->
list_voltage
(
rdev
,
i
);
if
(
ret
<
0
)
continue
;
if
(
ret
>
max_uV
)
break
;
if
(
ret
>=
min_uV
&&
ret
<=
max_uV
)
return
i
;
}
return
-
EINVAL
;
}
EXPORT_SYMBOL_GPL
(
regulator_map_voltage_ascend
);
/**
* regulator_map_voltage_linear - map_voltage() for simple linear mappings
*
* @rdev: Regulator to operate on
* @min_uV: Lower bound for voltage
* @max_uV: Upper bound for voltage
*
* Drivers providing min_uV and uV_step in their regulator_desc can
* use this as their map_voltage() operation.
*/
int
regulator_map_voltage_linear
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
)
{
int
ret
,
voltage
;
/* Allow uV_step to be 0 for fixed voltage */
if
(
rdev
->
desc
->
n_voltages
==
1
&&
rdev
->
desc
->
uV_step
==
0
)
{
if
(
min_uV
<=
rdev
->
desc
->
min_uV
&&
rdev
->
desc
->
min_uV
<=
max_uV
)
return
0
;
else
return
-
EINVAL
;
}
if
(
!
rdev
->
desc
->
uV_step
)
{
BUG_ON
(
!
rdev
->
desc
->
uV_step
);
return
-
EINVAL
;
}
if
(
min_uV
<
rdev
->
desc
->
min_uV
)
min_uV
=
rdev
->
desc
->
min_uV
;
ret
=
DIV_ROUND_UP
(
min_uV
-
rdev
->
desc
->
min_uV
,
rdev
->
desc
->
uV_step
);
if
(
ret
<
0
)
return
ret
;
ret
+=
rdev
->
desc
->
linear_min_sel
;
/* Map back into a voltage to verify we're still in bounds */
voltage
=
rdev
->
desc
->
ops
->
list_voltage
(
rdev
,
ret
);
if
(
voltage
<
min_uV
||
voltage
>
max_uV
)
return
-
EINVAL
;
return
ret
;
}
EXPORT_SYMBOL_GPL
(
regulator_map_voltage_linear
);
/**
* regulator_map_voltage_linear - map_voltage() for multiple linear ranges
*
* @rdev: Regulator to operate on
* @min_uV: Lower bound for voltage
* @max_uV: Upper bound for voltage
*
* Drivers providing linear_ranges in their descriptor can use this as
* their map_voltage() callback.
*/
int
regulator_map_voltage_linear_range
(
struct
regulator_dev
*
rdev
,
int
min_uV
,
int
max_uV
)
{
const
struct
regulator_linear_range
*
range
;
int
ret
=
-
EINVAL
;
int
voltage
,
i
;
if
(
!
rdev
->
desc
->
n_linear_ranges
)
{
BUG_ON
(
!
rdev
->
desc
->
n_linear_ranges
);
return
-
EINVAL
;
}
for
(
i
=
0
;
i
<
rdev
->
desc
->
n_linear_ranges
;
i
++
)
{
range
=
&
rdev
->
desc
->
linear_ranges
[
i
];
if
(
!
(
min_uV
<=
range
->
max_uV
&&
max_uV
>=
range
->
min_uV
))
continue
;
if
(
min_uV
<=
range
->
min_uV
)
min_uV
=
range
->
min_uV
;
/* range->uV_step == 0 means fixed voltage range */
if
(
range
->
uV_step
==
0
)
{
ret
=
0
;
}
else
{
ret
=
DIV_ROUND_UP
(
min_uV
-
range
->
min_uV
,
range
->
uV_step
);
if
(
ret
<
0
)
return
ret
;
}
ret
+=
range
->
min_sel
;
break
;
}
if
(
i
==
rdev
->
desc
->
n_linear_ranges
)
return
-
EINVAL
;
/* Map back into a voltage to verify we're still in bounds */
voltage
=
rdev
->
desc
->
ops
->
list_voltage
(
rdev
,
ret
);
if
(
voltage
<
min_uV
||
voltage
>
max_uV
)
return
-
EINVAL
;
return
ret
;
}
EXPORT_SYMBOL_GPL
(
regulator_map_voltage_linear_range
);
/**
* regulator_list_voltage_linear - List voltages with simple calculation
*
* @rdev: Regulator device
* @selector: Selector to convert into a voltage
*
* Regulators with a simple linear mapping between voltages and
* selectors can set min_uV and uV_step in the regulator descriptor
* and then use this function as their list_voltage() operation,
*/
int
regulator_list_voltage_linear
(
struct
regulator_dev
*
rdev
,
unsigned
int
selector
)
{
if
(
selector
>=
rdev
->
desc
->
n_voltages
)
return
-
EINVAL
;
if
(
selector
<
rdev
->
desc
->
linear_min_sel
)
return
0
;
selector
-=
rdev
->
desc
->
linear_min_sel
;
return
rdev
->
desc
->
min_uV
+
(
rdev
->
desc
->
uV_step
*
selector
);
}
EXPORT_SYMBOL_GPL
(
regulator_list_voltage_linear
);
/**
* regulator_list_voltage_linear_range - List voltages for linear ranges
*
* @rdev: Regulator device
* @selector: Selector to convert into a voltage
*
* Regulators with a series of simple linear mappings between voltages
* and selectors can set linear_ranges in the regulator descriptor and
* then use this function as their list_voltage() operation,
*/
int
regulator_list_voltage_linear_range
(
struct
regulator_dev
*
rdev
,
unsigned
int
selector
)
{
const
struct
regulator_linear_range
*
range
;
int
i
;
if
(
!
rdev
->
desc
->
n_linear_ranges
)
{
BUG_ON
(
!
rdev
->
desc
->
n_linear_ranges
);
return
-
EINVAL
;
}
for
(
i
=
0
;
i
<
rdev
->
desc
->
n_linear_ranges
;
i
++
)
{
range
=
&
rdev
->
desc
->
linear_ranges
[
i
];
if
(
!
(
selector
>=
range
->
min_sel
&&
selector
<=
range
->
max_sel
))
continue
;
selector
-=
range
->
min_sel
;
return
range
->
min_uV
+
(
range
->
uV_step
*
selector
);
}
return
-
EINVAL
;
}
EXPORT_SYMBOL_GPL
(
regulator_list_voltage_linear_range
);
/**
* regulator_list_voltage_table - List voltages with table based mapping
*
* @rdev: Regulator device
* @selector: Selector to convert into a voltage
*
* Regulators with table based mapping between voltages and
* selectors can set volt_table in the regulator descriptor
* and then use this function as their list_voltage() operation.
*/
int
regulator_list_voltage_table
(
struct
regulator_dev
*
rdev
,
unsigned
int
selector
)
{
if
(
!
rdev
->
desc
->
volt_table
)
{
BUG_ON
(
!
rdev
->
desc
->
volt_table
);
return
-
EINVAL
;
}
if
(
selector
>=
rdev
->
desc
->
n_voltages
)
return
-
EINVAL
;
return
rdev
->
desc
->
volt_table
[
selector
];
}
EXPORT_SYMBOL_GPL
(
regulator_list_voltage_table
);
/**
* regulator_set_bypass_regmap - Default set_bypass() using regmap
*
* @rdev: device to operate on.
* @enable: state to set.
*/
int
regulator_set_bypass_regmap
(
struct
regulator_dev
*
rdev
,
bool
enable
)
{
unsigned
int
val
;
if
(
enable
)
val
=
rdev
->
desc
->
bypass_mask
;
else
val
=
0
;
return
regmap_update_bits
(
rdev
->
regmap
,
rdev
->
desc
->
bypass_reg
,
rdev
->
desc
->
bypass_mask
,
val
);
}
EXPORT_SYMBOL_GPL
(
regulator_set_bypass_regmap
);
/**
* regulator_get_bypass_regmap - Default get_bypass() using regmap
*
* @rdev: device to operate on.
* @enable: current state.
*/
int
regulator_get_bypass_regmap
(
struct
regulator_dev
*
rdev
,
bool
*
enable
)
{
unsigned
int
val
;
int
ret
;
ret
=
regmap_read
(
rdev
->
regmap
,
rdev
->
desc
->
bypass_reg
,
&
val
);
if
(
ret
!=
0
)
return
ret
;
*
enable
=
val
&
rdev
->
desc
->
bypass_mask
;
return
0
;
}
EXPORT_SYMBOL_GPL
(
regulator_get_bypass_regmap
);
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