diff options
Diffstat (limited to 'drivers/regulator/fixed.c')
| -rw-r--r-- | drivers/regulator/fixed.c | 85 | 
1 files changed, 82 insertions, 3 deletions
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 21ecf212a522..e24e3a174c4b 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -27,6 +27,10 @@  #include <linux/gpio.h>  #include <linux/delay.h>  #include <linux/slab.h> +#include <linux/of.h> +#include <linux/of_gpio.h> +#include <linux/regulator/of_regulator.h> +#include <linux/regulator/machine.h>  struct fixed_voltage_data {  	struct regulator_desc desc; @@ -38,6 +42,58 @@ struct fixed_voltage_data {  	bool is_enabled;  }; + +/** + * of_get_fixed_voltage_config - extract fixed_voltage_config structure info + * @dev: device requesting for fixed_voltage_config + * + * Populates fixed_voltage_config structure by extracting data from device + * tree node, returns a pointer to the populated structure of NULL if memory + * alloc fails. + */ +static struct fixed_voltage_config * +of_get_fixed_voltage_config(struct device *dev) +{ +	struct fixed_voltage_config *config; +	struct device_node *np = dev->of_node; +	const __be32 *delay; +	struct regulator_init_data *init_data; + +	config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config), +								 GFP_KERNEL); +	if (!config) +		return NULL; + +	config->init_data = of_get_regulator_init_data(dev, dev->of_node); +	if (!config->init_data) +		return NULL; + +	init_data = config->init_data; +	init_data->constraints.apply_uV = 0; + +	config->supply_name = init_data->constraints.name; +	if (init_data->constraints.min_uV == init_data->constraints.max_uV) { +		config->microvolts = init_data->constraints.min_uV; +	} else { +		dev_err(dev, +			 "Fixed regulator specified with variable voltages\n"); +		return NULL; +	} + +	if (init_data->constraints.boot_on) +		config->enabled_at_boot = true; + +	config->gpio = of_get_named_gpio(np, "gpio", 0); +	delay = of_get_property(np, "startup-delay-us", NULL); +	if (delay) +		config->startup_delay = be32_to_cpu(*delay); + +	if (of_find_property(np, "enable-active-high", NULL)) +		config->enable_high = true; + +	return config; +} +  static int fixed_voltage_is_enabled(struct regulator_dev *dev)  {  	struct fixed_voltage_data *data = rdev_get_drvdata(dev); @@ -80,7 +136,10 @@ static int fixed_voltage_get_voltage(struct regulator_dev *dev)  {  	struct fixed_voltage_data *data = rdev_get_drvdata(dev); -	return data->microvolts; +	if (data->microvolts) +		return data->microvolts; +	else +		return -EINVAL;  }  static int fixed_voltage_list_voltage(struct regulator_dev *dev, @@ -105,10 +164,18 @@ static struct regulator_ops fixed_voltage_ops = {  static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)  { -	struct fixed_voltage_config *config = pdev->dev.platform_data; +	struct fixed_voltage_config *config;  	struct fixed_voltage_data *drvdata;  	int ret; +	if (pdev->dev.of_node) +		config = of_get_fixed_voltage_config(&pdev->dev); +	else +		config = pdev->dev.platform_data; + +	if (!config) +		return -ENOMEM; +  	drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL);  	if (drvdata == NULL) {  		dev_err(&pdev->dev, "Failed to allocate device data\n"); @@ -180,7 +247,8 @@ static int __devinit reg_fixed_voltage_probe(struct platform_device *pdev)  	}  	drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev, -					  config->init_data, drvdata); +					  config->init_data, drvdata, +					  pdev->dev.of_node);  	if (IS_ERR(drvdata->dev)) {  		ret = PTR_ERR(drvdata->dev);  		dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); @@ -217,12 +285,23 @@ static int __devexit reg_fixed_voltage_remove(struct platform_device *pdev)  	return 0;  } +#if defined(CONFIG_OF) +static const struct of_device_id fixed_of_match[] __devinitconst = { +	{ .compatible = "regulator-fixed", }, +	{}, +}; +MODULE_DEVICE_TABLE(of, fixed_of_match); +#else +#define fixed_of_match NULL +#endif +  static struct platform_driver regulator_fixed_voltage_driver = {  	.probe		= reg_fixed_voltage_probe,  	.remove		= __devexit_p(reg_fixed_voltage_remove),  	.driver		= {  		.name		= "reg-fixed-voltage",  		.owner		= THIS_MODULE, +		.of_match_table = fixed_of_match,  	},  };  |