Linux下的regulator调试

先看regulator使用的小demo,如

i2c8{
    touchscreen@28 {
           vddcama-supply = <&xxxxx>;
    };
}
int ret;
struct regulator *power;
static int ts_probe(struct i2c_client *client,const struct i2c_device_id *id)
{
    power=regulator_get(&client->dev,"vddcama");
    if (IS_ERR(power)) {
		ret = PTR_ERR(power);
		dev_err(dev, "Failed to request vddcama: %d\n", ret);
  }
    ret=regulator_set_voltage(power, 1800000, 1800000);//mV
    ret=regulator_enable(power);
    ret=regulator_disable(power);
}
/**
 * regulator_get - lookup and obtain a reference to a regulator.
 * @dev: device for regulator "consumer"
 * @id: Supply name or regulator ID.
 *
 * Returns a struct regulator corresponding to the regulator producer,
 * or IS_ERR() condition containing errno.
 *
 * Use of supply names configured via regulator_set_device_supply() is
 * strongly encouraged.  It is recommended that the supply name used
 * should match the name used for the supply and/or the relevant
 * device pins in the datasheet.
 */
struct regulator *regulator_get(struct device *dev, const char *id)
{
	return _regulator_get(dev, id, false, true);
}
EXPORT_SYMBOL_GPL(regulator_get);

regulator_get如果找不到该电源,换返回一个无效的电源,该结果不是我们想要的,可使用regulator_get_exclusive代替。

static struct regulator *_regulator_get(struct device *dev, const char *id,
					bool exclusive, bool allow_dummy)
{
	if (have_full_constraints() && allow_dummy) {
		pr_warn("%s supply %s not found, using dummy regulator\n",
			devname, id);

		rdev = dummy_regulator_rdev;
		get_device(&rdev->dev);
		goto found;
	/* Don't log an error when called from regulator_get_optional() */
	} else if (!have_full_constraints() || exclusive) {
		dev_warn(dev, "dummy supplies not allowed\n");
	}
}
struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
{
	return _regulator_get(dev, id, true, false);
}
EXPORT_SYMBOL_GPL(regulator_get_exclusive);

如果是共享电源,其他使用者没有关闭电源,调用regulator_disable不能关闭电源。

int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
{
	int ret = 0;

	regulator_lock_supply(regulator->rdev);

	ret = regulator_set_voltage_unlocked(regulator, min_uV, max_uV);

	regulator_unlock_supply(regulator->rdev);

	return ret;
}
EXPORT_SYMBOL_GPL(regulator_set_voltage);

int regulator_disable(struct regulator *regulator)
{
	struct regulator_dev *rdev = regulator->rdev;
	int ret = 0;

	if (regulator->always_on)
		return 0;

	mutex_lock(&rdev->mutex);
	ret = _regulator_disable(rdev);
	mutex_unlock(&rdev->mutex);

	if (ret == 0 && rdev->supply)
		regulator_disable(rdev->supply);

	return ret;
}

/**
 * regulator_enable - enable regulator output
 * @regulator: regulator source
 *
 * Request that the regulator be enabled with the regulator output at
 * the predefined voltage or current value.  Calls to regulator_enable()
 * must be balanced with calls to regulator_disable().
 *
 * NOTE: the output value can be set by other drivers, boot loader or may be
 * hardwired in the regulator.
 */
int regulator_enable(struct regulator *regulator)
{
	struct regulator_dev *rdev = regulator->rdev;
	int ret = 0;

	if (regulator->always_on)
		return 0;

	if (rdev->supply) {
		ret = regulator_enable(rdev->supply);
		if (ret != 0)
			return ret;
	}

	mutex_lock(&rdev->mutex);
	ret = _regulator_enable(rdev);
	mutex_unlock(&rdev->mutex);

	if (ret != 0 && rdev->supply)
		regulator_disable(rdev->supply);

	return ret;
}
EXPORT_SYMBOL_GPL(regulator_enable);

/sys/class/regulator下有所有的regular,如

每个节点有如下的属性

cpu0-cpu                   使用者名字
device
max_microvolts       最大电压
microvolts
min_microvolts       最小电压
name                            电源名字
num_users               当前的使用者数量(use_count)
of_node                     dts配置信息        
power
state                           当前状态(打开或关闭)
subsystem
suspend_disk_state
suspend_mem_state
suspend_standby_state   
type                        电源类型(电压或电流)
uevent

查看/d/regulator/regulator_summary有所有电源的信息,如

use 同上面的num_users(use_count)  (_regulator_enable+1   _regulator_disable-1)该参数可表明当前ldo的开光状态

open当前打开次数(open_count)(_regulator_get+1    _regulator_put-1)
 

static int _regulator_disable(struct regulator_dev *rdev)
{
...
	rdev->use_count--;
...
}

static int _regulator_enable(struct regulator_dev *rdev)
{
...
	rdev->use_count++;
...
}

struct regulator *_regulator_get(struct device *dev, const char *id,enum regulator_get_type get_type)
{
...
	rdev->open_count++;
...
}

static void _regulator_put(struct regulator *regulator)
{
...
	rdev->open_count--;
...
}

如果无法确认电源被异常关闭的情况 ,可以在平台的电源开关中加入如下函数,来追踪电源的开关状态。

static int mt6357_regulator_disable(struct regulator_dev *rdev)
{
    int ret = 0;
    pr_info("QQQQQQQQQQQQQQQQQQQQQQQQQQ==%s\n",rdev_get_name(rdev));
    if(strncmp(rdev_get_name(rdev),"vldo28",strlen("vldo28"))==0)
        WARN(1,"mt6370_ldo_disable\n");
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值