
Pull regulator updates from Mark Brown: "The bulk of the changes for this release are a few new drivers however there are a couple of noticable core changes and the usual stream of cleanups and fixes: - move disable of unused regulators later in init so it comes after deferred probe has iterated making startup smoother. - fixes to reference counting of the DT nodes for constraints from Charles Keepax. This has little practical impact since all real users of the regulator bindings use FDT which doesn't need the reference counting. - lots of cleanups, especially to the Samsung drivers. - support for Linear Technologies LTC3589, Texas Instruments TPS658640 and X-Powers AXP20x" * tag 'regulator-v3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (64 commits) regulator: pbias: remove unnecessary OOM messages regulator: max8649: remove unnecessary OOM messages regulator: core: Fix the init of DT defined fixed regulators regulator: core: Disable unused regulators after deferred probing is done regulator: Don't disable unused regulators we don't have permission for regulator: axp20x: Use regulator_map_voltage_ascend for LDO4 regulator: use of_property_read_{bool|u32}() regulator: Fix regulator_get_{optional,exclusive}() documentation regulators: Add definition of regulator_set_voltage_time() for !CONFIG_REGULATOR regulator: arizona-ldo1: add missing #include regulator: pfuze100: Support enable/disable for fixed regulator regulator: ltc3589: Remove ltc3589_list_voltage_fixed function regulator: ltc3589: Fix module dependency regulator: tps6586x: Remove unused to_tps6586x_dev() function regulator: tps65218: Convert to use regulator_set_voltage_time_sel regulator: tps6586x: Add support for the TPS658640 regulator: tps6586x: Prepare supporting fixed regulators regulator: pfuze100: Don't allocate an invalid gpio regulator: pfuze100: Support SWB enable/disable regulator: fixed: use of_property_read_{bool|u32}() ...
121 lines
3.3 KiB
C
121 lines
3.3 KiB
C
/*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* Copyright (C) 2012 ARM Limited
|
|
*/
|
|
|
|
#define DRVNAME "vexpress-regulator"
|
|
#define pr_fmt(fmt) DRVNAME ": " fmt
|
|
|
|
#include <linux/device.h>
|
|
#include <linux/err.h>
|
|
#include <linux/module.h>
|
|
#include <linux/of_device.h>
|
|
#include <linux/regulator/driver.h>
|
|
#include <linux/regulator/machine.h>
|
|
#include <linux/regulator/of_regulator.h>
|
|
#include <linux/vexpress.h>
|
|
|
|
struct vexpress_regulator {
|
|
struct regulator_desc desc;
|
|
struct regulator_dev *regdev;
|
|
struct regmap *regmap;
|
|
};
|
|
|
|
static int vexpress_regulator_get_voltage(struct regulator_dev *regdev)
|
|
{
|
|
struct vexpress_regulator *reg = rdev_get_drvdata(regdev);
|
|
u32 uV;
|
|
int err = regmap_read(reg->regmap, 0, &uV);
|
|
|
|
return err ? err : uV;
|
|
}
|
|
|
|
static int vexpress_regulator_set_voltage(struct regulator_dev *regdev,
|
|
int min_uV, int max_uV, unsigned *selector)
|
|
{
|
|
struct vexpress_regulator *reg = rdev_get_drvdata(regdev);
|
|
|
|
return regmap_write(reg->regmap, 0, min_uV);
|
|
}
|
|
|
|
static struct regulator_ops vexpress_regulator_ops_ro = {
|
|
.get_voltage = vexpress_regulator_get_voltage,
|
|
};
|
|
|
|
static struct regulator_ops vexpress_regulator_ops = {
|
|
.get_voltage = vexpress_regulator_get_voltage,
|
|
.set_voltage = vexpress_regulator_set_voltage,
|
|
};
|
|
|
|
static int vexpress_regulator_probe(struct platform_device *pdev)
|
|
{
|
|
struct vexpress_regulator *reg;
|
|
struct regulator_init_data *init_data;
|
|
struct regulator_config config = { };
|
|
|
|
reg = devm_kzalloc(&pdev->dev, sizeof(*reg), GFP_KERNEL);
|
|
if (!reg)
|
|
return -ENOMEM;
|
|
|
|
reg->regmap = devm_regmap_init_vexpress_config(&pdev->dev);
|
|
if (IS_ERR(reg->regmap))
|
|
return PTR_ERR(reg->regmap);
|
|
|
|
reg->desc.name = dev_name(&pdev->dev);
|
|
reg->desc.type = REGULATOR_VOLTAGE;
|
|
reg->desc.owner = THIS_MODULE;
|
|
reg->desc.continuous_voltage_range = true;
|
|
|
|
init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node);
|
|
if (!init_data)
|
|
return -EINVAL;
|
|
|
|
init_data->constraints.apply_uV = 0;
|
|
if (init_data->constraints.min_uV && init_data->constraints.max_uV)
|
|
reg->desc.ops = &vexpress_regulator_ops;
|
|
else
|
|
reg->desc.ops = &vexpress_regulator_ops_ro;
|
|
|
|
config.dev = &pdev->dev;
|
|
config.init_data = init_data;
|
|
config.driver_data = reg;
|
|
config.of_node = pdev->dev.of_node;
|
|
|
|
reg->regdev = devm_regulator_register(&pdev->dev, ®->desc, &config);
|
|
if (IS_ERR(reg->regdev))
|
|
return PTR_ERR(reg->regdev);
|
|
|
|
platform_set_drvdata(pdev, reg);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct of_device_id vexpress_regulator_of_match[] = {
|
|
{ .compatible = "arm,vexpress-volt", },
|
|
{ }
|
|
};
|
|
|
|
static struct platform_driver vexpress_regulator_driver = {
|
|
.probe = vexpress_regulator_probe,
|
|
.driver = {
|
|
.name = DRVNAME,
|
|
.owner = THIS_MODULE,
|
|
.of_match_table = vexpress_regulator_of_match,
|
|
},
|
|
};
|
|
|
|
module_platform_driver(vexpress_regulator_driver);
|
|
|
|
MODULE_AUTHOR("Pawel Moll <pawel.moll@arm.com>");
|
|
MODULE_DESCRIPTION("Versatile Express regulator");
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_ALIAS("platform:vexpress-regulator");
|