Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
724d0544
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
161
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
724d0544
编写于
9月 01, 2013
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'regulator/topic/helpers' into regulator-next
上级
446b4665
d295f767
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
458 addition
and
463 deletion
+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
未找到文件。
drivers/regulator/Makefile
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录