Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 424c3d4a authored by Liam Girdwood's avatar Liam Girdwood
Browse files

Merge branch 'for-next' into for-linus

parents 02f8c6ae 88cda60e
Loading
Loading
Loading
Loading
+110 −80
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/async.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/suspend.h>
@@ -33,6 +34,8 @@

#include "dummy.h"

#define rdev_crit(rdev, fmt, ...)					\
	pr_crit("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_err(rdev, fmt, ...)					\
	pr_err("%s: " fmt, rdev_get_name(rdev), ##__VA_ARGS__)
#define rdev_warn(rdev, fmt, ...)					\
@@ -78,11 +81,13 @@ struct regulator {
	char *supply_name;
	struct device_attribute dev_attr;
	struct regulator_dev *rdev;
#ifdef CONFIG_DEBUG_FS
	struct dentry *debugfs;
#endif
};

static int _regulator_is_enabled(struct regulator_dev *rdev);
static int _regulator_disable(struct regulator_dev *rdev,
		struct regulator_dev **supply_rdev_ptr);
static int _regulator_disable(struct regulator_dev *rdev);
static int _regulator_get_voltage(struct regulator_dev *rdev);
static int _regulator_get_current_limit(struct regulator_dev *rdev);
static unsigned int _regulator_get_mode(struct regulator_dev *rdev);
@@ -90,6 +95,9 @@ static void _notifier_call_chain(struct regulator_dev *rdev,
				  unsigned long event, void *data);
static int _regulator_do_set_voltage(struct regulator_dev *rdev,
				     int min_uV, int max_uV);
static struct regulator *create_regulator(struct regulator_dev *rdev,
					  struct device *dev,
					  const char *supply_name);

static const char *rdev_get_name(struct regulator_dev *rdev)
{
@@ -143,8 +151,11 @@ static int regulator_check_voltage(struct regulator_dev *rdev,
	if (*min_uV < rdev->constraints->min_uV)
		*min_uV = rdev->constraints->min_uV;

	if (*min_uV > *max_uV)
	if (*min_uV > *max_uV) {
		rdev_err(rdev, "unsupportable voltage range: %d-%duV\n",
			 *min_uV, *max_uV);
		return -EINVAL;
	}

	return 0;
}
@@ -197,8 +208,11 @@ static int regulator_check_current_limit(struct regulator_dev *rdev,
	if (*min_uA < rdev->constraints->min_uA)
		*min_uA = rdev->constraints->min_uA;

	if (*min_uA > *max_uA)
	if (*min_uA > *max_uA) {
		rdev_err(rdev, "unsupportable current range: %d-%duA\n",
			 *min_uA, *max_uA);
		return -EINVAL;
	}

	return 0;
}
@@ -213,6 +227,7 @@ static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode)
	case REGULATOR_MODE_STANDBY:
		break;
	default:
		rdev_err(rdev, "invalid mode %x specified\n", *mode);
		return -EINVAL;
	}

@@ -779,7 +794,6 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
		if (ret < 0) {
			rdev_err(rdev, "failed to apply %duV constraint\n",
				 rdev->constraints->min_uV);
			rdev->constraints = NULL;
			return ret;
		}
	}
@@ -882,7 +896,6 @@ static int set_machine_constraints(struct regulator_dev *rdev,
		ret = suspend_prepare(rdev, rdev->constraints->initial_state);
		if (ret < 0) {
			rdev_err(rdev, "failed to set suspend state\n");
			rdev->constraints = NULL;
			goto out;
		}
	}
@@ -909,13 +922,15 @@ static int set_machine_constraints(struct regulator_dev *rdev,
		ret = ops->enable(rdev);
		if (ret < 0) {
			rdev_err(rdev, "failed to enable\n");
			rdev->constraints = NULL;
			goto out;
		}
	}

	print_constraints(rdev);
	return 0;
out:
	kfree(rdev->constraints);
	rdev->constraints = NULL;
	return ret;
}

@@ -933,19 +948,18 @@ static int set_supply(struct regulator_dev *rdev,
{
	int err;

	err = sysfs_create_link(&rdev->dev.kobj, &supply_rdev->dev.kobj,
				"supply");
	if (err) {
		rdev_err(rdev, "could not add device link %s err %d\n",
			 supply_rdev->dev.kobj.name, err);
		       goto out;
	}
	rdev->supply = supply_rdev;
	list_add(&rdev->slist, &supply_rdev->supply_list);
out:
	rdev_info(rdev, "supplied by %s\n", rdev_get_name(supply_rdev));

	rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
	if (IS_ERR(rdev->supply)) {
		err = PTR_ERR(rdev->supply);
		rdev->supply = NULL;
		return err;
	}

	return 0;
}

/**
 * set_consumer_device_supply - Bind a regulator to a symbolic supply
 * @rdev:         regulator source
@@ -1032,7 +1046,7 @@ static void unset_regulator_supplies(struct regulator_dev *rdev)
	}
}

#define REG_STR_SIZE	32
#define REG_STR_SIZE	64

static struct regulator *create_regulator(struct regulator_dev *rdev,
					  struct device *dev,
@@ -1052,8 +1066,9 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,

	if (dev) {
		/* create a 'requested_microamps_name' sysfs entry */
		size = scnprintf(buf, REG_STR_SIZE, "microamps_requested_%s",
			supply_name);
		size = scnprintf(buf, REG_STR_SIZE,
				 "microamps_requested_%s-%s",
				 dev_name(dev), supply_name);
		if (size >= REG_STR_SIZE)
			goto overflow_err;

@@ -1088,7 +1103,28 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
				  dev->kobj.name, err);
			goto link_name_err;
		}
	} else {
		regulator->supply_name = kstrdup(supply_name, GFP_KERNEL);
		if (regulator->supply_name == NULL)
			goto attr_err;
	}

#ifdef CONFIG_DEBUG_FS
	regulator->debugfs = debugfs_create_dir(regulator->supply_name,
						rdev->debugfs);
	if (IS_ERR_OR_NULL(regulator->debugfs)) {
		rdev_warn(rdev, "Failed to create debugfs directory\n");
		regulator->debugfs = NULL;
	} else {
		debugfs_create_u32("uA_load", 0444, regulator->debugfs,
				   &regulator->uA_load);
		debugfs_create_u32("min_uV", 0444, regulator->debugfs,
				   &regulator->min_uV);
		debugfs_create_u32("max_uV", 0444, regulator->debugfs,
				   &regulator->max_uV);
	}
#endif

	mutex_unlock(&rdev->mutex);
	return regulator;
link_name_err:
@@ -1267,13 +1303,17 @@ void regulator_put(struct regulator *regulator)
	mutex_lock(&regulator_list_mutex);
	rdev = regulator->rdev;

#ifdef CONFIG_DEBUG_FS
	debugfs_remove_recursive(regulator->debugfs);
#endif

	/* remove any sysfs entries */
	if (regulator->dev) {
		sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
		kfree(regulator->supply_name);
		device_remove_file(regulator->dev, &regulator->dev_attr);
		kfree(regulator->dev_attr.attr.name);
	}
	kfree(regulator->supply_name);
	list_del(&regulator->list);
	kfree(regulator);

@@ -1301,19 +1341,6 @@ static int _regulator_enable(struct regulator_dev *rdev)
{
	int ret, delay;

	if (rdev->use_count == 0) {
		/* do we need to enable the supply regulator first */
		if (rdev->supply) {
			mutex_lock(&rdev->supply->mutex);
			ret = _regulator_enable(rdev->supply);
			mutex_unlock(&rdev->supply->mutex);
			if (ret < 0) {
				rdev_err(rdev, "failed to enable: %d\n", ret);
				return ret;
			}
		}
	}

	/* check voltage and requested load before enabling */
	if (rdev->constraints &&
	    (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS))
@@ -1388,19 +1415,27 @@ int regulator_enable(struct regulator *regulator)
	struct regulator_dev *rdev = regulator->rdev;
	int ret = 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)
		regulator_disable(rdev->supply);

	return ret;
}
EXPORT_SYMBOL_GPL(regulator_enable);

/* locks held by regulator_disable() */
static int _regulator_disable(struct regulator_dev *rdev,
		struct regulator_dev **supply_rdev_ptr)
static int _regulator_disable(struct regulator_dev *rdev)
{
	int ret = 0;
	*supply_rdev_ptr = NULL;

	if (WARN(rdev->use_count <= 0,
		 "unbalanced disables for %s\n", rdev_get_name(rdev)))
@@ -1427,9 +1462,6 @@ static int _regulator_disable(struct regulator_dev *rdev,
					     NULL);
		}

		/* decrease our supplies ref count and disable if required */
		*supply_rdev_ptr = rdev->supply;

		rdev->use_count = 0;
	} else if (rdev->use_count > 1) {

@@ -1440,6 +1472,7 @@ static int _regulator_disable(struct regulator_dev *rdev,

		rdev->use_count--;
	}

	return ret;
}

@@ -1458,29 +1491,21 @@ static int _regulator_disable(struct regulator_dev *rdev,
int regulator_disable(struct regulator *regulator)
{
	struct regulator_dev *rdev = regulator->rdev;
	struct regulator_dev *supply_rdev = NULL;
	int ret = 0;

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

	/* decrease our supplies ref count and disable if required */
	while (supply_rdev != NULL) {
		rdev = supply_rdev;

		mutex_lock(&rdev->mutex);
		_regulator_disable(rdev, &supply_rdev);
		mutex_unlock(&rdev->mutex);
	}
	if (ret == 0 && rdev->supply)
		regulator_disable(rdev->supply);

	return ret;
}
EXPORT_SYMBOL_GPL(regulator_disable);

/* locks held by regulator_force_disable() */
static int _regulator_force_disable(struct regulator_dev *rdev,
		struct regulator_dev **supply_rdev_ptr)
static int _regulator_force_disable(struct regulator_dev *rdev)
{
	int ret = 0;

@@ -1497,10 +1522,6 @@ static int _regulator_force_disable(struct regulator_dev *rdev,
			REGULATOR_EVENT_DISABLE, NULL);
	}

	/* decrease our supplies ref count and disable if required */
	*supply_rdev_ptr = rdev->supply;

	rdev->use_count = 0;
	return ret;
}

@@ -1516,16 +1537,16 @@ static int _regulator_force_disable(struct regulator_dev *rdev,
int regulator_force_disable(struct regulator *regulator)
{
	struct regulator_dev *rdev = regulator->rdev;
	struct regulator_dev *supply_rdev = NULL;
	int ret;

	mutex_lock(&rdev->mutex);
	regulator->uA_load = 0;
	ret = _regulator_force_disable(rdev, &supply_rdev);
	ret = _regulator_force_disable(regulator->rdev);
	mutex_unlock(&rdev->mutex);

	if (supply_rdev)
		regulator_disable(get_device_regulator(rdev_get_dev(supply_rdev)));
	if (rdev->supply)
		while (rdev->open_count--)
			regulator_disable(rdev->supply);

	return ret;
}
@@ -2136,7 +2157,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
	/* get input voltage */
	input_uV = 0;
	if (rdev->supply)
		input_uV = _regulator_get_voltage(rdev->supply);
		input_uV = regulator_get_voltage(rdev->supply);
	if (input_uV <= 0)
		input_uV = rdev->constraints->input_uV;
	if (input_uV <= 0) {
@@ -2206,17 +2227,8 @@ EXPORT_SYMBOL_GPL(regulator_unregister_notifier);
static void _notifier_call_chain(struct regulator_dev *rdev,
				  unsigned long event, void *data)
{
	struct regulator_dev *_rdev;

	/* call rdev chain first */
	blocking_notifier_call_chain(&rdev->notifier, event, NULL);

	/* now notify regulator we supply */
	list_for_each_entry(_rdev, &rdev->supply_list, slist) {
		mutex_lock(&_rdev->mutex);
		_notifier_call_chain(_rdev, event, data);
		mutex_unlock(&_rdev->mutex);
	}
}

/**
@@ -2264,6 +2276,13 @@ err:
}
EXPORT_SYMBOL_GPL(regulator_bulk_get);

static void regulator_bulk_enable_async(void *data, async_cookie_t cookie)
{
	struct regulator_bulk_data *bulk = data;

	bulk->ret = regulator_enable(bulk->consumer);
}

/**
 * regulator_bulk_enable - enable multiple regulator consumers
 *
@@ -2279,21 +2298,33 @@ EXPORT_SYMBOL_GPL(regulator_bulk_get);
int regulator_bulk_enable(int num_consumers,
			  struct regulator_bulk_data *consumers)
{
	LIST_HEAD(async_domain);
	int i;
	int ret;
	int ret = 0;

	for (i = 0; i < num_consumers; i++)
		async_schedule_domain(regulator_bulk_enable_async,
				      &consumers[i], &async_domain);

	async_synchronize_full_domain(&async_domain);

	/* If any consumer failed we need to unwind any that succeeded */
	for (i = 0; i < num_consumers; i++) {
		ret = regulator_enable(consumers[i].consumer);
		if (ret != 0)
		if (consumers[i].ret != 0) {
			ret = consumers[i].ret;
			goto err;
		}
	}

	return 0;

err:
	pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret);
	for (--i; i >= 0; --i)
	for (i = 0; i < num_consumers; i++)
		if (consumers[i].ret == 0)
			regulator_disable(consumers[i].consumer);
		else
			pr_err("Failed to enable %s: %d\n",
			       consumers[i].supply, consumers[i].ret);

	return ret;
}
@@ -2589,9 +2620,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
	rdev->owner = regulator_desc->owner;
	rdev->desc = regulator_desc;
	INIT_LIST_HEAD(&rdev->consumer_list);
	INIT_LIST_HEAD(&rdev->supply_list);
	INIT_LIST_HEAD(&rdev->list);
	INIT_LIST_HEAD(&rdev->slist);
	BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);

	/* preform any regulator specific init */
@@ -2672,6 +2701,7 @@ unset_supplies:
	unset_regulator_supplies(rdev);

scrub:
	kfree(rdev->constraints);
	device_unregister(&rdev->dev);
	/* device core frees rdev */
	rdev = ERR_PTR(ret);
@@ -2703,7 +2733,7 @@ void regulator_unregister(struct regulator_dev *rdev)
	unset_regulator_supplies(rdev);
	list_del(&rdev->list);
	if (rdev->supply)
		sysfs_remove_link(&rdev->dev.kobj, "supply");
		regulator_put(rdev->supply);
	device_unregister(&rdev->dev);
	kfree(rdev->constraints);
	mutex_unlock(&regulator_list_mutex);
+26 −6
Original line number Diff line number Diff line
@@ -36,6 +36,29 @@ static struct regulator_desc dummy_desc = {
	.ops = &dummy_ops,
};

static int __devinit dummy_regulator_probe(struct platform_device *pdev)
{
	int ret;

	dummy_regulator_rdev = regulator_register(&dummy_desc, NULL,
						  &dummy_initdata, NULL);
	if (IS_ERR(dummy_regulator_rdev)) {
		ret = PTR_ERR(dummy_regulator_rdev);
		pr_err("Failed to register regulator: %d\n", ret);
		return ret;
	}

	return 0;
}

static struct platform_driver dummy_regulator_driver = {
	.probe		= dummy_regulator_probe,
	.driver		= {
		.name		= "reg-dummy",
		.owner		= THIS_MODULE,
	},
};

static struct platform_device *dummy_pdev;

void __init regulator_dummy_init(void)
@@ -55,12 +78,9 @@ void __init regulator_dummy_init(void)
		return;
	}

	dummy_regulator_rdev = regulator_register(&dummy_desc, NULL,
						  &dummy_initdata, NULL);
	if (IS_ERR(dummy_regulator_rdev)) {
		ret = PTR_ERR(dummy_regulator_rdev);
		pr_err("Failed to register regulator: %d\n", ret);
	ret = platform_driver_register(&dummy_regulator_driver);
	if (ret != 0) {
		pr_err("Failed to register dummy regulator driver: %d\n", ret);
		platform_device_unregister(dummy_pdev);
		return;
	}
}
+51 −12
Original line number Diff line number Diff line
@@ -49,7 +49,6 @@
#define TPS65911_REG_LDO7		11
#define TPS65911_REG_LDO8		12

#define TPS65910_NUM_REGULATOR		13
#define TPS65910_SUPPLY_STATE_ENABLED	0x1

/* supported VIO voltages in milivolts */
@@ -264,11 +263,12 @@ static struct tps_info tps65911_regs[] = {
};

struct tps65910_reg {
	struct regulator_desc desc[TPS65910_NUM_REGULATOR];
	struct regulator_desc *desc;
	struct tps65910 *mfd;
	struct regulator_dev *rdev[TPS65910_NUM_REGULATOR];
	struct tps_info *info[TPS65910_NUM_REGULATOR];
	struct regulator_dev **rdev;
	struct tps_info **info;
	struct mutex mutex;
	int num_regulators;
	int mode;
	int  (*get_ctrl_reg)(int);
};
@@ -759,8 +759,13 @@ static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,
		mult = (selector / VDD1_2_NUM_VOLTS) + 1;
		volt = VDD1_2_MIN_VOLT +
				(selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET;
		break;
	case TPS65911_REG_VDDCTRL:
		volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET);
		break;
	default:
		BUG();
		return -EINVAL;
	}

	return  volt * 100 * mult;
@@ -897,16 +902,42 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
	switch(tps65910_chip_id(tps65910)) {
	case TPS65910:
		pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
		pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
		info = tps65910_regs;
		break;
	case TPS65911:
		pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
		pmic->num_regulators = ARRAY_SIZE(tps65911_regs);
		info = tps65911_regs;
		break;
	default:
		pr_err("Invalid tps chip version\n");
		kfree(pmic);
		return -ENODEV;
	}

	for (i = 0; i < TPS65910_NUM_REGULATOR; i++, info++, reg_data++) {
	pmic->desc = kcalloc(pmic->num_regulators,
			sizeof(struct regulator_desc), GFP_KERNEL);
	if (!pmic->desc) {
		err = -ENOMEM;
		goto err_free_pmic;
	}

	pmic->info = kcalloc(pmic->num_regulators,
			sizeof(struct tps_info *), GFP_KERNEL);
	if (!pmic->info) {
		err = -ENOMEM;
		goto err_free_desc;
	}

	pmic->rdev = kcalloc(pmic->num_regulators,
			sizeof(struct regulator_dev *), GFP_KERNEL);
	if (!pmic->rdev) {
		err = -ENOMEM;
		goto err_free_info;
	}

	for (i = 0; i < pmic->num_regulators; i++, info++, reg_data++) {
		/* Register the regulators */
		pmic->info[i] = info;

@@ -938,7 +969,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
				"failed to register %s regulator\n",
				pdev->name);
			err = PTR_ERR(rdev);
			goto err;
			goto err_unregister_regulator;
		}

		/* Save regulator for cleanup */
@@ -946,23 +977,31 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
	}
	return 0;

err:
err_unregister_regulator:
	while (--i >= 0)
		regulator_unregister(pmic->rdev[i]);

	kfree(pmic->rdev);
err_free_info:
	kfree(pmic->info);
err_free_desc:
	kfree(pmic->desc);
err_free_pmic:
	kfree(pmic);
	return err;
}

static int __devexit tps65910_remove(struct platform_device *pdev)
{
	struct tps65910_reg *tps65910_reg = platform_get_drvdata(pdev);
	struct tps65910_reg *pmic = platform_get_drvdata(pdev);
	int i;

	for (i = 0; i < TPS65910_NUM_REGULATOR; i++)
		regulator_unregister(tps65910_reg->rdev[i]);
	for (i = 0; i < pmic->num_regulators; i++)
		regulator_unregister(pmic->rdev[i]);

	kfree(tps65910_reg);
	kfree(pmic->rdev);
	kfree(pmic->info);
	kfree(pmic->desc);
	kfree(pmic);
	return 0;
}

+31 −35
Original line number Diff line number Diff line
@@ -835,8 +835,8 @@ static struct regulator_ops twlsmps_ops = {
			remap_conf) \
		TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
			remap_conf, TWL4030, twl4030fixed_ops)
#define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay) \
		TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
#define TWL6030_FIXED_LDO(label, offset, mVolts, turnon_delay) \
		TWL_FIXED_LDO(label, offset, mVolts, 0x0, turnon_delay, \
			0x0, TWL6030, twl6030fixed_ops)

#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \
@@ -856,24 +856,22 @@ static struct regulator_ops twlsmps_ops = {
		}, \
	}

#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \
#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \
	.base = offset, \
	.id = num, \
	.min_mV = min_mVolts, \
	.max_mV = max_mVolts, \
	.desc = { \
		.name = #label, \
		.id = TWL6030_REG_##label, \
		.n_voltages = (max_mVolts - min_mVolts)/100, \
		.n_voltages = (max_mVolts - min_mVolts)/100 + 1, \
		.ops = &twl6030ldo_ops, \
		.type = REGULATOR_VOLTAGE, \
		.owner = THIS_MODULE, \
		}, \
	}

#define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \
#define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts) { \
	.base = offset, \
	.id = num, \
	.min_mV = min_mVolts, \
	.max_mV = max_mVolts, \
	.desc = { \
@@ -903,9 +901,8 @@ static struct regulator_ops twlsmps_ops = {
		}, \
	}

#define TWL6030_FIXED_RESOURCE(label, offset, num, turnon_delay) { \
#define TWL6030_FIXED_RESOURCE(label, offset, turnon_delay) { \
	.base = offset, \
	.id = num, \
	.delay = turnon_delay, \
	.desc = { \
		.name = #label, \
@@ -916,9 +913,8 @@ static struct regulator_ops twlsmps_ops = {
		}, \
	}

#define TWL6025_ADJUSTABLE_SMPS(label, offset, num) { \
#define TWL6025_ADJUSTABLE_SMPS(label, offset) { \
	.base = offset, \
	.id = num, \
	.min_mV = 600, \
	.max_mV = 2100, \
	.desc = { \
@@ -961,32 +957,32 @@ static struct twlreg_info twl_regs[] = {
	/* 6030 REG with base as PMC Slave Misc : 0x0030 */
	/* Turnon-delay and remap configuration values for 6030 are not
	   verified since the specification is not public */
	TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1),
	TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2),
	TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3),
	TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4),
	TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5),
	TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7),
	TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0),
	TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0),
	TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0),
	TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0),
	TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0),
	TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300),
	TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300),
	TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300),
	TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300),
	TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300),
	TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300),
	TWL6030_FIXED_LDO(VANA, 0x50, 2100, 0),
	TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 0),
	TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0),
	TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0),
	TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 0),

	/* 6025 are renamed compared to 6030 versions */
	TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300, 1),
	TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300, 2),
	TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300, 3),
	TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300, 4),
	TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300, 5),
	TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300, 7),
	TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300, 16),
	TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300, 17),
	TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300, 18),

	TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34, 1),
	TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10, 2),
	TWL6025_ADJUSTABLE_SMPS(VIO, 0x16, 3),
	TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300),
	TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300),
	TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300),
	TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300),
	TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300),
	TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300),
	TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300),
	TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300),
	TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300),

	TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34),
	TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10),
	TWL6025_ADJUSTABLE_SMPS(VIO, 0x16),
};

static u8 twl_get_smps_offset(void)
+65 −61
Original line number Diff line number Diff line
@@ -267,23 +267,6 @@ static int wm831x_buckv_select_min_voltage(struct regulator_dev *rdev,
	return vsel;
}

static int wm831x_buckv_select_max_voltage(struct regulator_dev *rdev,
					   int min_uV, int max_uV)
{
	u16 vsel;

	if (max_uV < 600000 || max_uV > 1800000)
		return -EINVAL;

	vsel = ((max_uV - 600000) / 12500) + 8;

	if (wm831x_buckv_list_voltage(rdev, vsel) < min_uV ||
	    wm831x_buckv_list_voltage(rdev, vsel) < max_uV)
		return -EINVAL;

	return vsel;
}

static int wm831x_buckv_set_dvs(struct regulator_dev *rdev, int state)
{
	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
@@ -338,27 +321,22 @@ static int wm831x_buckv_set_voltage(struct regulator_dev *rdev,
	if (ret < 0)
		return ret;

	/* Set the high voltage as the DVS voltage.  This is optimised
	 * for CPUfreq usage, most processors will keep the maximum
	 * voltage constant and lower the minimum with the frequency. */
	vsel = wm831x_buckv_select_max_voltage(rdev, min_uV, max_uV);
	if (vsel < 0) {
		/* This should never happen - at worst the same vsel
		 * should be chosen */
		WARN_ON(vsel < 0);
		return 0;
	}

	/* Don't bother if it's the same VSEL we're already using */
	if (vsel == dcdc->on_vsel)
		return 0;

	ret = wm831x_set_bits(wm831x, dvs_reg, WM831X_DC1_DVS_VSEL_MASK, vsel);
	/*
	 * If this VSEL is higher than the last one we've seen then
	 * remember it as the DVS VSEL.  This is optimised for CPUfreq
	 * usage where we want to get to the highest voltage very
	 * quickly.
	 */
	if (vsel > dcdc->dvs_vsel) {
		ret = wm831x_set_bits(wm831x, dvs_reg,
				      WM831X_DC1_DVS_VSEL_MASK,
				      dcdc->dvs_vsel);
		if (ret == 0)
			dcdc->dvs_vsel = vsel;
		else
		dev_warn(wm831x->dev, "Failed to set DCDC DVS VSEL: %d\n",
			 ret);
			dev_warn(wm831x->dev,
				 "Failed to set DCDC DVS VSEL: %d\n", ret);
	}

	return 0;
}
@@ -456,27 +434,6 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc,
	if (!pdata || !pdata->dvs_gpio)
		return;

	switch (pdata->dvs_control_src) {
	case 1:
		ctrl = 2 << WM831X_DC1_DVS_SRC_SHIFT;
		break;
	case 2:
		ctrl = 3 << WM831X_DC1_DVS_SRC_SHIFT;
		break;
	default:
		dev_err(wm831x->dev, "Invalid DVS control source %d for %s\n",
			pdata->dvs_control_src, dcdc->name);
		return;
	}

	ret = wm831x_set_bits(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL,
			      WM831X_DC1_DVS_SRC_MASK, ctrl);
	if (ret < 0) {
		dev_err(wm831x->dev, "Failed to set %s DVS source: %d\n",
			dcdc->name, ret);
		return;
	}

	ret = gpio_request(pdata->dvs_gpio, "DCDC DVS");
	if (ret < 0) {
		dev_err(wm831x->dev, "Failed to get %s DVS GPIO: %d\n",
@@ -498,17 +455,57 @@ static __devinit void wm831x_buckv_dvs_init(struct wm831x_dcdc *dcdc,
	}

	dcdc->dvs_gpio = pdata->dvs_gpio;

	switch (pdata->dvs_control_src) {
	case 1:
		ctrl = 2 << WM831X_DC1_DVS_SRC_SHIFT;
		break;
	case 2:
		ctrl = 3 << WM831X_DC1_DVS_SRC_SHIFT;
		break;
	default:
		dev_err(wm831x->dev, "Invalid DVS control source %d for %s\n",
			pdata->dvs_control_src, dcdc->name);
		return;
	}

	/* If DVS_VSEL is set to the minimum value then raise it to ON_VSEL
	 * to make bootstrapping a bit smoother.
	 */
	if (!dcdc->dvs_vsel) {
		ret = wm831x_set_bits(wm831x,
				      dcdc->base + WM831X_DCDC_DVS_CONTROL,
				      WM831X_DC1_DVS_VSEL_MASK, dcdc->on_vsel);
		if (ret == 0)
			dcdc->dvs_vsel = dcdc->on_vsel;
		else
			dev_warn(wm831x->dev, "Failed to set DVS_VSEL: %d\n",
				 ret);
	}

	ret = wm831x_set_bits(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL,
			      WM831X_DC1_DVS_SRC_MASK, ctrl);
	if (ret < 0) {
		dev_err(wm831x->dev, "Failed to set %s DVS source: %d\n",
			dcdc->name, ret);
	}
}

static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
{
	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
	int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
	int id;
	struct wm831x_dcdc *dcdc;
	struct resource *res;
	int ret, irq;

	if (pdata && pdata->wm831x_num)
		id = (pdata->wm831x_num * 10) + 1;
	else
		id = 0;
	id = pdev->id - id;

	dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);

	if (pdata == NULL || pdata->dcdc[id] == NULL)
@@ -545,7 +542,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
	}
	dcdc->on_vsel = ret & WM831X_DC1_ON_VSEL_MASK;

	ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_ON_CONFIG);
	ret = wm831x_reg_read(wm831x, dcdc->base + WM831X_DCDC_DVS_CONTROL);
	if (ret < 0) {
		dev_err(wm831x->dev, "Failed to read DVS VSEL: %d\n", ret);
		goto err;
@@ -709,11 +706,17 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
{
	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
	int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
	int id;
	struct wm831x_dcdc *dcdc;
	struct resource *res;
	int ret, irq;

	if (pdata && pdata->wm831x_num)
		id = (pdata->wm831x_num * 10) + 1;
	else
		id = 0;
	id = pdev->id - id;

	dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);

	if (pdata == NULL || pdata->dcdc[id] == NULL)
@@ -1046,3 +1049,4 @@ MODULE_DESCRIPTION("WM831x DC-DC convertor driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:wm831x-buckv");
MODULE_ALIAS("platform:wm831x-buckp");
MODULE_ALIAS("platform:wm831x-epe");
Loading