01-[Linux][Regulator]使用LDO编程示例
1、在驱动代码中使用LDO供电操作的步骤如下:
- 找到需要操作的LDO名字,如MTK平台:vio28
- 在dts中找到相应的节点,如下所示:
mt_pmic_vio28_ldo_reg: ldo_vio28 {
regulator-name = "vio28";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-enable-ramp-delay = <264>;
};
- 在设备树中自己定义的节点中引用上述节点:
ldo_sample: ldo_sample {
compatible = "mediatek,ldo_sample";
ldo_sample-supply = <&mt_pmic_vio28_ldo_reg>;
status = "okay";
};
- 编写驱动代码,使用devm_regulator_get,regulator_enable,regulator_disable等接口来进行操作LDO
2、regulator consumer常用操作接口如下:
/* regulator get and put */
struct regulator *__must_check regulator_get(struct device *dev,
const char *id);
struct regulator *__must_check devm_regulator_get(struct device *dev,
const char *id);
void regulator_put(struct regulator *regulator);
void devm_regulator_put(struct regulator *regulator);
/* regulator output control and status */
int __must_check regulator_enable(struct regulator *regulator);
int regulator_disable(struct regulator *regulator);
int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
int regulator_get_voltage(struct regulator *regulator);
具体更详细的接口定义参考头文件:<linux/regulator/consumer.h>
3、驱动示例代码如下:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ioctl.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/compat.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/acpi.h>
#include <linux/regulator/consumer.h>
struct ldo_sample_dev {
struct regulator *vcc;
};
struct ldo_sample_dev *pldo;
static ssize_t show_ldo_val(struct device *dev,
struct device_attribute *attr, char *buf)
{
return 0;
}
static ssize_t store_ldo_val(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int val = 0;
if (kstrtoint(buf, 10, &val))
return -EINVAL;
pr_err("596 store_ldo_val val=%d\n", val);
if (val == 1) {
regulator_enable(pldo->vcc);
} else {
regulator_disable(pldo->vcc);
}
return count;
}
static DEVICE_ATTR(ldo_sample, 0664, show_ldo_val, store_ldo_val);
static int ldo_sample_probe(struct platform_device *pdev)
{
int err = 0;
pr_info("596 %s enter.\n", __func__);
/* 1. alloc memory */
pldo = devm_kzalloc(&pdev->dev, sizeof(*pldo), GFP_KERNEL);
if (!pldo)
return -ENOMEM;
/* 2. get regulator */
pldo->vcc = devm_regulator_get(&pdev->dev, "ldo_sample");
if (IS_ERR(pldo->vcc)) {
err = PTR_ERR(pldo->vcc);
pr_err("596 regulator request failed (%d)\n", err);
return err;
}
/* 3. create device attr */
device_create_file(&(pdev->dev), &dev_attr_ldo_sample);
pr_info("596 %s exit.\n", __func__);
return 0;
}
static int ldo_sample_remove(struct platform_device *pdev)
{
pr_info("596 %s enter\n", __func__);
return 0;
}
const struct of_device_id ldo_sample_table[] = {
{ .compatible = "mediatek,ldo_sample" },
{}
};
static struct platform_driver ldo_sample_driver = {
.probe = ldo_sample_probe,
.remove = ldo_sample_remove,
.driver = {
.name = "ldo_sample",
.of_match_table = ldo_sample_table,
},
};
module_platform_driver(ldo_sample_driver);
MODULE_AUTHOR("596");
MODULE_DESCRIPTION("Mediatek LDO driver sample");
MODULE_LICENSE("GPL");