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");
|