Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
9e63d230
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
9e63d230
编写于
4月 28, 2013
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'regulator/topic/ab3100' into v3.9-rc8
上级
78da0218
018fd856
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
187 addition
and
50 deletion
+187
-50
drivers/mfd/ab3100-core.c
drivers/mfd/ab3100-core.c
+1
-0
drivers/regulator/ab3100.c
drivers/regulator/ab3100.c
+186
-50
未找到文件。
drivers/mfd/ab3100-core.c
浏览文件 @
9e63d230
...
...
@@ -753,6 +753,7 @@ static struct mfd_cell ab3100_devs[] = {
},
{
.
name
=
"ab3100-regulators"
,
.
of_compatible
=
"stericsson,ab3100-regulators"
,
.
id
=
-
1
,
},
{
...
...
drivers/regulator/ab3100.c
浏览文件 @
9e63d230
...
...
@@ -17,6 +17,8 @@
#include <linux/regulator/driver.h>
#include <linux/mfd/ab3100.h>
#include <linux/mfd/abx500.h>
#include <linux/of.h>
#include <linux/regulator/of_regulator.h>
/* LDO registers and some handy masking definitions for AB3100 */
#define AB3100_LDO_A 0x40
...
...
@@ -345,7 +347,11 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg)
{
struct
ab3100_regulator
*
abreg
=
rdev_get_drvdata
(
reg
);
return
abreg
->
plfdata
->
external_voltage
;
if
(
abreg
->
plfdata
)
return
abreg
->
plfdata
->
external_voltage
;
else
/* TODO: encode external voltage into device tree */
return
0
;
}
static
struct
regulator_ops
regulator_ops_fixed
=
{
...
...
@@ -488,16 +494,174 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
},
};
static
int
ab3100_regulator_register
(
struct
platform_device
*
pdev
,
struct
ab3100_platform_data
*
plfdata
,
struct
regulator_init_data
*
init_data
,
struct
device_node
*
np
,
int
id
)
{
struct
regulator_desc
*
desc
;
struct
ab3100_regulator
*
reg
;
struct
regulator_dev
*
rdev
;
struct
regulator_config
config
=
{
};
int
err
,
i
;
for
(
i
=
0
;
i
<
AB3100_NUM_REGULATORS
;
i
++
)
{
desc
=
&
ab3100_regulator_desc
[
i
];
if
(
desc
->
id
==
id
)
break
;
}
if
(
desc
->
id
!=
id
)
return
-
ENODEV
;
/* Same index used for this array */
reg
=
&
ab3100_regulators
[
i
];
/*
* Initialize per-regulator struct.
* Inherit platform data, this comes down from the
* i2c boarddata, from the machine. So if you want to
* see what it looks like for a certain machine, go
* into the machine I2C setup.
*/
reg
->
dev
=
&
pdev
->
dev
;
if
(
plfdata
)
{
reg
->
plfdata
=
plfdata
;
config
.
init_data
=
&
plfdata
->
reg_constraints
[
i
];
}
else
if
(
np
)
{
config
.
of_node
=
np
;
config
.
init_data
=
init_data
;
}
config
.
dev
=
&
pdev
->
dev
;
config
.
driver_data
=
reg
;
rdev
=
regulator_register
(
desc
,
&
config
);
if
(
IS_ERR
(
rdev
))
{
err
=
PTR_ERR
(
rdev
);
dev_err
(
&
pdev
->
dev
,
"%s: failed to register regulator %s err %d
\n
"
,
__func__
,
desc
->
name
,
err
);
return
err
;
}
/* Then set a pointer back to the registered regulator */
reg
->
rdev
=
rdev
;
return
0
;
}
static
struct
of_regulator_match
ab3100_regulator_matches
[]
=
{
{
.
name
=
"ab3100_ldo_a"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_A
,
},
{
.
name
=
"ab3100_ldo_c"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_C
,
},
{
.
name
=
"ab3100_ldo_d"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_D
,
},
{
.
name
=
"ab3100_ldo_e"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_E
,
},
{
.
name
=
"ab3100_ldo_f"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_F
},
{
.
name
=
"ab3100_ldo_g"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_G
},
{
.
name
=
"ab3100_ldo_h"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_H
},
{
.
name
=
"ab3100_ldo_k"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_K
},
{
.
name
=
"ab3100_ext"
,
.
driver_data
=
(
void
*
)
AB3100_LDO_EXT
},
{
.
name
=
"ab3100_buck"
,
.
driver_data
=
(
void
*
)
AB3100_BUCK
},
};
/*
* NOTE: the following functions are regulators pluralis - it is the
* binding to the AB3100 core driver and the parent platform device
* for all the different regulators.
* Initial settings of ab3100 registers.
* Common for below LDO regulator settings are that
* bit 7-5 controls voltage. Bit 4 turns regulator ON(1) or OFF(0).
* Bit 3-2 controls sleep enable and bit 1-0 controls sleep mode.
*/
/* LDO_A 0x16: 2.75V, ON, SLEEP_A, SLEEP OFF GND */
#define LDO_A_SETTING 0x16
/* LDO_C 0x10: 2.65V, ON, SLEEP_A or B, SLEEP full power */
#define LDO_C_SETTING 0x10
/* LDO_D 0x10: 2.65V, ON, sleep mode not used */
#define LDO_D_SETTING 0x10
/* LDO_E 0x10: 1.8V, ON, SLEEP_A or B, SLEEP full power */
#define LDO_E_SETTING 0x10
/* LDO_E SLEEP 0x00: 1.8V, not used, SLEEP_A or B, not used */
#define LDO_E_SLEEP_SETTING 0x00
/* LDO_F 0xD0: 2.5V, ON, SLEEP_A or B, SLEEP full power */
#define LDO_F_SETTING 0xD0
/* LDO_G 0x00: 2.85V, OFF, SLEEP_A or B, SLEEP full power */
#define LDO_G_SETTING 0x00
/* LDO_H 0x18: 2.75V, ON, SLEEP_B, SLEEP full power */
#define LDO_H_SETTING 0x18
/* LDO_K 0x00: 2.75V, OFF, SLEEP_A or B, SLEEP full power */
#define LDO_K_SETTING 0x00
/* LDO_EXT 0x00: Voltage not set, OFF, not used, not used */
#define LDO_EXT_SETTING 0x00
/* BUCK 0x7D: 1.2V, ON, SLEEP_A and B, SLEEP low power */
#define BUCK_SETTING 0x7D
/* BUCK SLEEP 0xAC: 1.05V, Not used, SLEEP_A and B, Not used */
#define BUCK_SLEEP_SETTING 0xAC
static
const
u8
ab3100_reg_initvals
[]
=
{
LDO_A_SETTING
,
LDO_C_SETTING
,
LDO_E_SETTING
,
LDO_E_SLEEP_SETTING
,
LDO_F_SETTING
,
LDO_G_SETTING
,
LDO_H_SETTING
,
LDO_K_SETTING
,
LDO_EXT_SETTING
,
BUCK_SETTING
,
BUCK_SLEEP_SETTING
,
LDO_D_SETTING
,
};
static
int
ab3100_regulators_remove
(
struct
platform_device
*
pdev
)
{
int
i
;
for
(
i
=
0
;
i
<
AB3100_NUM_REGULATORS
;
i
++
)
{
struct
ab3100_regulator
*
reg
=
&
ab3100_regulators
[
i
];
regulator_unregister
(
reg
->
rdev
);
reg
->
rdev
=
NULL
;
}
return
0
;
}
static
int
ab3100_regulator_of_probe
(
struct
platform_device
*
pdev
,
struct
device_node
*
np
)
{
int
err
,
i
;
/*
* Set up the regulator registers, as was previously done with
* platform data.
*/
/* Set up regulators */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ab3100_reg_init_order
);
i
++
)
{
err
=
abx500_set_register_interruptible
(
&
pdev
->
dev
,
0
,
ab3100_reg_init_order
[
i
],
ab3100_reg_initvals
[
i
]);
if
(
err
)
{
dev_err
(
&
pdev
->
dev
,
"regulator initialization failed with error %d
\n
"
,
err
);
return
err
;
}
}
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ab3100_regulator_matches
);
i
++
)
{
err
=
ab3100_regulator_register
(
pdev
,
NULL
,
ab3100_regulator_matches
[
i
].
init_data
,
ab3100_regulator_matches
[
i
].
of_node
,
(
int
)
ab3100_regulator_matches
[
i
].
driver_data
);
if
(
err
)
{
ab3100_regulators_remove
(
pdev
);
return
err
;
}
}
return
0
;
}
static
int
ab3100_regulators_probe
(
struct
platform_device
*
pdev
)
{
struct
ab3100_platform_data
*
plfdata
=
pdev
->
dev
.
platform_data
;
struct
regulator_config
config
=
{
}
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
int
err
=
0
;
u8
data
;
int
i
;
...
...
@@ -516,6 +680,18 @@ static int ab3100_regulators_probe(struct platform_device *pdev)
dev_notice
(
&
pdev
->
dev
,
"chip is in inactive mode (Cold start)
\n
"
);
if
(
np
)
{
err
=
of_regulator_match
(
&
pdev
->
dev
,
np
,
ab3100_regulator_matches
,
ARRAY_SIZE
(
ab3100_regulator_matches
));
if
(
err
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"Error parsing regulator init data: %d
\n
"
,
err
);
return
err
;
}
return
ab3100_regulator_of_probe
(
pdev
,
np
);
}
/* Set up regulators */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ab3100_reg_init_order
);
i
++
)
{
err
=
abx500_set_register_interruptible
(
&
pdev
->
dev
,
0
,
...
...
@@ -530,59 +706,19 @@ static int ab3100_regulators_probe(struct platform_device *pdev)
/* Register the regulators */
for
(
i
=
0
;
i
<
AB3100_NUM_REGULATORS
;
i
++
)
{
struct
ab3100_regulator
*
reg
=
&
ab3100_regulators
[
i
];
struct
regulator_dev
*
rdev
;
/*
* Initialize per-regulator struct.
* Inherit platform data, this comes down from the
* i2c boarddata, from the machine. So if you want to
* see what it looks like for a certain machine, go
* into the machine I2C setup.
*/
reg
->
dev
=
&
pdev
->
dev
;
reg
->
plfdata
=
plfdata
;
struct
regulator_desc
*
desc
=
&
ab3100_regulator_desc
[
i
];
config
.
dev
=
&
pdev
->
dev
;
config
.
driver_data
=
reg
;
config
.
init_data
=
&
plfdata
->
reg_constraints
[
i
];
/*
* Register the regulator, pass around
* the ab3100_regulator struct
*/
rdev
=
regulator_register
(
&
ab3100_regulator_desc
[
i
],
&
config
);
if
(
IS_ERR
(
rdev
))
{
err
=
PTR_ERR
(
rdev
);
dev_err
(
&
pdev
->
dev
,
"%s: failed to register regulator %s err %d
\n
"
,
__func__
,
ab3100_regulator_desc
[
i
].
name
,
err
);
/* remove the already registered regulators */
while
(
--
i
>=
0
)
regulator_unregister
(
ab3100_regulators
[
i
].
rdev
);
err
=
ab3100_regulator_register
(
pdev
,
plfdata
,
NULL
,
NULL
,
desc
->
id
);
if
(
err
)
{
ab3100_regulators_remove
(
pdev
);
return
err
;
}
/* Then set a pointer back to the registered regulator */
reg
->
rdev
=
rdev
;
}
return
0
;
}
static
int
ab3100_regulators_remove
(
struct
platform_device
*
pdev
)
{
int
i
;
for
(
i
=
0
;
i
<
AB3100_NUM_REGULATORS
;
i
++
)
{
struct
ab3100_regulator
*
reg
=
&
ab3100_regulators
[
i
];
regulator_unregister
(
reg
->
rdev
);
}
return
0
;
}
static
struct
platform_driver
ab3100_regulators_driver
=
{
.
driver
=
{
.
name
=
"ab3100-regulators"
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录