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");
4、调试接口
在linux内核中,提供了sysfs的debug节点接口,可以用来查看当前的ldo都有哪些注册,被打开了几次。如下所示:
xxx:/sys/kernel/debug/regulator/vldo28 # ls
MAINAF-camaf_m1_pmic  bypass_count  open_count  touch-vtouch  use_count
xxx:/sys/kernel/debug/regulator/vldo28 #
其中:
- vldo28是ldo在内核中定义的名字
- open_count 表示有几个设备使用了该ldo
- use_count 表示当前有几个设备正在使用该ldo
- MAINAF-camaf_m1_pmic和touch-vtouch 是使用该ldo的设备名。
 注:如果use_count不等于0,那么ldo的power不会被关闭,只有当没有一个设备使用时才会被关闭下电。
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号