linux驱动编写(电源管理驱动)
对于嵌入式设备来说,合适的电源管理,不仅可以延长电池的寿命,而且可以省电,延长设备运行时间,在提高用户体验方面有很大的好处。所以,各个soc厂家在这方面花了很多的功夫。下面,我们可以看看linux是如何处理电源管理驱动的。
1、代码目录
drivers/regulator
2、查看目录下的Kconfig文件
-
menuconfig REGULATOR
-
bool "Voltage and Current Regulator Support"
-
help
-
Generic Voltage and Current Regulator support.
-
-
This framework is designed to provide a generic interface to voltage
-
and current regulators within the Linux kernel. It's intended to
-
provide voltage and current control to client or consumer drivers and
-
also provide status information to user space applications through a
-
sysfs interface.
-
-
The intention is to allow systems to dynamically control regulator
-
output in order to save power and prolong battery life. This applies
-
to both voltage regulators (where voltage output is controllable) and
-
current sinks (where current output is controllable).
-
-
This framework safely compiles out if not selected so that client
-
drivers can still be used in systems with no software controllable
-
regulators.
-
-
If unsure, say no.
3、阅读文件,得知REGULATOR是最核心的模块macro,那我们可以找一个设备的macro看看
-
config REGULATOR_STM32_VREFBUF
-
tristate "STMicroelectronics STM32 VREFBUF"
-
depends on ARCH_STM32 || COMPILE_TEST
-
help
-
This driver supports STMicroelectronics STM32 VREFBUF (voltage
-
reference buffer) which can be used as voltage reference for
-
internal ADCs, DACs and also for external components through
-
dedicated Vref+ pin.
-
-
This driver can also be built as a module. If so, the module
-
will be called stm32-vrefbuf.
4、没有找到s3c,可以看一下stm32芯片的依赖属性,接着看Makefile
-
obj-$(CONFIG_REGULATOR) += core.o dummy.o fixed-helper.o helpers.o devres.o
-
obj-$(CONFIG_OF) += of_regulator.o
-
obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
-
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
-
obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
-
-
obj-$(CONFIG_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
5、看的出来stm32只依赖于stm32-verfbuf.c文件,继续查看
-
static const struct of_device_id stm32_vrefbuf_of_match[] = {
-
{ .compatible = "st,stm32-vrefbuf", },
-
{},
-
};
-
MODULE_DEVICE_TABLE(of, stm32_vrefbuf_of_match);
-
-
static struct platform_driver stm32_vrefbuf_driver = {
-
.probe = stm32_vrefbuf_probe,
-
.remove = stm32_vrefbuf_remove,
-
.driver = {
-
.name = "stm32-vrefbuf",
-
.of_match_table = of_match_ptr(stm32_vrefbuf_of_match),
-
},
-
};
-
module_platform_driver(stm32_vrefbuf_driver);
6、确认驱动为platform驱动,寻找regulator特有的数据结构
-
static const struct regulator_ops stm32_vrefbuf_volt_ops = {
-
.enable = stm32_vrefbuf_enable,
-
.disable = stm32_vrefbuf_disable,
-
.is_enabled = stm32_vrefbuf_is_enabled,
-
.get_voltage_sel = stm32_vrefbuf_get_voltage_sel,
-
.set_voltage_sel = stm32_vrefbuf_set_voltage_sel,
-
.list_voltage = regulator_list_voltage_table,
-
};
-
-
static const struct regulator_desc stm32_vrefbuf_regu = {
-
.name = "vref",
-
.supply_name = "vdda",
-
.volt_table = stm32_vrefbuf_voltages,
-
.n_voltages = ARRAY_SIZE(stm32_vrefbuf_voltages),
-
.ops = &stm32_vrefbuf_volt_ops,
-
.type = REGULATOR_VOLTAGE,
-
.owner = THIS_MODULE,
-
};
7、由代码得知,regulator_ops和regulator_desc才是特有的regulator数据结构,当然也少不了注册函数
-
rdev = regulator_register(&stm32_vrefbuf_regu, &config);
-
if (IS_ERR(rdev)) {
-
ret = PTR_ERR(rdev);
-
dev_err(&pdev->dev, "register failed with error %d\n", ret);
-
goto err_clk_dis;
-
}
-
platform_set_drvdata(pdev, rdev);
8、进一步确认of_device_id是不是真实存在,可以在arch/arm/boot/dts/stm32h743.dtsi找到对应内容
-
vrefbuf: regulator@58003C00 {
-
compatible = "st,stm32-vrefbuf";
-
reg = <0x58003C00 0x8>;
-
clocks = <&rcc VREF_CK>;
-
regulator-min-microvolt = <1500000>;
-
regulator-max-microvolt = <2500000>;
-
status = "disabled";
-
};