-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branches 'regulator/topic/discharge', 'regulato…
…r/topic/fan53555', 'regulator/topic/gpio', 'regulator/topic/hi655x' and 'regulator/topic/lp872x' into regulator-next
- Loading branch information
Showing
15 changed files
with
402 additions
and
5 deletions.
There are no files selected for viewing
29 changes: 29 additions & 0 deletions
29
Documentation/devicetree/bindings/regulator/hisilicon,hi655x-regulator.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
Hisilicon Hi655x Voltage regulators | ||
|
||
Note: | ||
The Hi655x regulator control is managed by Hi655x PMIC. | ||
So the node of this regulator must be child node of Hi655x | ||
PMIC node. | ||
|
||
The driver uses the regulator core framework, so please also | ||
take the bindings of regulator.txt for reference. | ||
|
||
The valid names for regulators are: | ||
|
||
LDO2_2V8 LDO7_SDIO LDO10_2V85 LDO13_1V8 LDO14_2V8 | ||
LDO15_1V8 LDO17_2V5 LDO19_3V0 LDO21_1V8 LDO22_1V2 | ||
|
||
Example: | ||
pmic: pmic@f8000000 { | ||
compatible = "hisilicon,hi655x-pmic"; | ||
... | ||
regulators { | ||
ldo2: LDO2@a21 { | ||
regulator-name = "LDO2_2V8"; | ||
regulator-min-microvolt = <2500000>; | ||
regulator-max-microvolt = <3200000>; | ||
regulator-enable-ramp-delay = <120>; | ||
}; | ||
... | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
/* | ||
* Device driver for regulators in Hi655x IC | ||
* | ||
* Copyright (c) 2016 Hisilicon. | ||
* | ||
* Authors: | ||
* Chen Feng <puck.chen@hisilicon.com> | ||
* Fei Wang <w.f@huawei.com> | ||
* | ||
* 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. | ||
*/ | ||
|
||
#include <linux/bitops.h> | ||
#include <linux/device.h> | ||
#include <linux/err.h> | ||
#include <linux/module.h> | ||
#include <linux/io.h> | ||
#include <linux/of.h> | ||
#include <linux/platform_device.h> | ||
#include <linux/regmap.h> | ||
#include <linux/regulator/driver.h> | ||
#include <linux/regulator/machine.h> | ||
#include <linux/regulator/of_regulator.h> | ||
#include <linux/mfd/hi655x-pmic.h> | ||
|
||
struct hi655x_regulator { | ||
unsigned int disable_reg; | ||
unsigned int status_reg; | ||
unsigned int ctrl_regs; | ||
unsigned int ctrl_mask; | ||
struct regulator_desc rdesc; | ||
}; | ||
|
||
/* LDO7 & LDO10 */ | ||
static const unsigned int ldo7_voltages[] = { | ||
1800000, 1850000, 2850000, 2900000, | ||
3000000, 3100000, 3200000, 3300000, | ||
}; | ||
|
||
static const unsigned int ldo19_voltages[] = { | ||
1800000, 1850000, 1900000, 1750000, | ||
2800000, 2850000, 2900000, 3000000, | ||
}; | ||
|
||
static const unsigned int ldo22_voltages[] = { | ||
900000, 1000000, 1050000, 1100000, | ||
1150000, 1175000, 1185000, 1200000, | ||
}; | ||
|
||
enum hi655x_regulator_id { | ||
HI655X_LDO0, | ||
HI655X_LDO1, | ||
HI655X_LDO2, | ||
HI655X_LDO3, | ||
HI655X_LDO4, | ||
HI655X_LDO5, | ||
HI655X_LDO6, | ||
HI655X_LDO7, | ||
HI655X_LDO8, | ||
HI655X_LDO9, | ||
HI655X_LDO10, | ||
HI655X_LDO11, | ||
HI655X_LDO12, | ||
HI655X_LDO13, | ||
HI655X_LDO14, | ||
HI655X_LDO15, | ||
HI655X_LDO16, | ||
HI655X_LDO17, | ||
HI655X_LDO18, | ||
HI655X_LDO19, | ||
HI655X_LDO20, | ||
HI655X_LDO21, | ||
HI655X_LDO22, | ||
}; | ||
|
||
static int hi655x_is_enabled(struct regulator_dev *rdev) | ||
{ | ||
unsigned int value = 0; | ||
|
||
struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); | ||
|
||
regmap_read(rdev->regmap, regulator->status_reg, &value); | ||
return (value & BIT(regulator->ctrl_mask)); | ||
} | ||
|
||
static int hi655x_disable(struct regulator_dev *rdev) | ||
{ | ||
int ret = 0; | ||
|
||
struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); | ||
|
||
ret = regmap_write(rdev->regmap, regulator->disable_reg, | ||
BIT(regulator->ctrl_mask)); | ||
return ret; | ||
} | ||
|
||
static struct regulator_ops hi655x_regulator_ops = { | ||
.enable = regulator_enable_regmap, | ||
.disable = hi655x_disable, | ||
.is_enabled = hi655x_is_enabled, | ||
.list_voltage = regulator_list_voltage_table, | ||
.get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
.set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
}; | ||
|
||
static struct regulator_ops hi655x_ldo_linear_ops = { | ||
.enable = regulator_enable_regmap, | ||
.disable = hi655x_disable, | ||
.is_enabled = hi655x_is_enabled, | ||
.list_voltage = regulator_list_voltage_linear, | ||
.get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
.set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
}; | ||
|
||
#define HI655X_LDO(_ID, vreg, vmask, ereg, dreg, \ | ||
sreg, cmask, vtable) { \ | ||
.rdesc = { \ | ||
.name = #_ID, \ | ||
.of_match = of_match_ptr(#_ID), \ | ||
.ops = &hi655x_regulator_ops, \ | ||
.regulators_node = of_match_ptr("regulators"), \ | ||
.type = REGULATOR_VOLTAGE, \ | ||
.id = HI655X_##_ID, \ | ||
.owner = THIS_MODULE, \ | ||
.n_voltages = ARRAY_SIZE(vtable), \ | ||
.volt_table = vtable, \ | ||
.vsel_reg = HI655X_BUS_ADDR(vreg), \ | ||
.vsel_mask = vmask, \ | ||
.enable_reg = HI655X_BUS_ADDR(ereg), \ | ||
.enable_mask = BIT(cmask), \ | ||
}, \ | ||
.disable_reg = HI655X_BUS_ADDR(dreg), \ | ||
.status_reg = HI655X_BUS_ADDR(sreg), \ | ||
.ctrl_mask = cmask, \ | ||
} | ||
|
||
#define HI655X_LDO_LINEAR(_ID, vreg, vmask, ereg, dreg, \ | ||
sreg, cmask, minv, nvolt, vstep) { \ | ||
.rdesc = { \ | ||
.name = #_ID, \ | ||
.of_match = of_match_ptr(#_ID), \ | ||
.ops = &hi655x_ldo_linear_ops, \ | ||
.regulators_node = of_match_ptr("regulators"), \ | ||
.type = REGULATOR_VOLTAGE, \ | ||
.id = HI655X_##_ID, \ | ||
.owner = THIS_MODULE, \ | ||
.min_uV = minv, \ | ||
.n_voltages = nvolt, \ | ||
.uV_step = vstep, \ | ||
.vsel_reg = HI655X_BUS_ADDR(vreg), \ | ||
.vsel_mask = vmask, \ | ||
.enable_reg = HI655X_BUS_ADDR(ereg), \ | ||
.enable_mask = BIT(cmask), \ | ||
}, \ | ||
.disable_reg = HI655X_BUS_ADDR(dreg), \ | ||
.status_reg = HI655X_BUS_ADDR(sreg), \ | ||
.ctrl_mask = cmask, \ | ||
} | ||
|
||
static struct hi655x_regulator regulators[] = { | ||
HI655X_LDO_LINEAR(LDO2, 0x72, 0x07, 0x29, 0x2a, 0x2b, 0x01, | ||
2500000, 8, 100000), | ||
HI655X_LDO(LDO7, 0x78, 0x07, 0x29, 0x2a, 0x2b, 0x06, ldo7_voltages), | ||
HI655X_LDO(LDO10, 0x78, 0x07, 0x29, 0x2a, 0x2b, 0x01, ldo7_voltages), | ||
HI655X_LDO_LINEAR(LDO13, 0x7e, 0x07, 0x2c, 0x2d, 0x2e, 0x04, | ||
1600000, 8, 50000), | ||
HI655X_LDO_LINEAR(LDO14, 0x7f, 0x07, 0x2c, 0x2d, 0x2e, 0x05, | ||
2500000, 8, 100000), | ||
HI655X_LDO_LINEAR(LDO15, 0x80, 0x07, 0x2c, 0x2d, 0x2e, 0x06, | ||
1600000, 8, 50000), | ||
HI655X_LDO_LINEAR(LDO17, 0x82, 0x07, 0x2f, 0x30, 0x31, 0x00, | ||
2500000, 8, 100000), | ||
HI655X_LDO(LDO19, 0x84, 0x07, 0x2f, 0x30, 0x31, 0x02, ldo19_voltages), | ||
HI655X_LDO_LINEAR(LDO21, 0x86, 0x07, 0x2f, 0x30, 0x31, 0x04, | ||
1650000, 8, 50000), | ||
HI655X_LDO(LDO22, 0x87, 0x07, 0x2f, 0x30, 0x31, 0x05, ldo22_voltages), | ||
}; | ||
|
||
static int hi655x_regulator_probe(struct platform_device *pdev) | ||
{ | ||
unsigned int i; | ||
struct hi655x_regulator *regulator; | ||
struct hi655x_pmic *pmic; | ||
struct regulator_config config = { }; | ||
struct regulator_dev *rdev; | ||
|
||
pmic = dev_get_drvdata(pdev->dev.parent); | ||
if (!pmic) { | ||
dev_err(&pdev->dev, "no pmic in the regulator parent node\n"); | ||
return -ENODEV; | ||
} | ||
|
||
regulator = devm_kzalloc(&pdev->dev, sizeof(*regulator), GFP_KERNEL); | ||
if (!regulator) | ||
return -ENOMEM; | ||
|
||
platform_set_drvdata(pdev, regulator); | ||
|
||
config.dev = pdev->dev.parent; | ||
config.regmap = pmic->regmap; | ||
config.driver_data = regulator; | ||
for (i = 0; i < ARRAY_SIZE(regulators); i++) { | ||
rdev = devm_regulator_register(&pdev->dev, | ||
®ulators[i].rdesc, | ||
&config); | ||
if (IS_ERR(rdev)) { | ||
dev_err(&pdev->dev, "failed to register regulator %s\n", | ||
regulator->rdesc.name); | ||
return PTR_ERR(rdev); | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
static struct platform_driver hi655x_regulator_driver = { | ||
.driver = { | ||
.name = "hi655x-regulator", | ||
}, | ||
.probe = hi655x_regulator_probe, | ||
}; | ||
module_platform_driver(hi655x_regulator_driver); | ||
|
||
MODULE_AUTHOR("Chen Feng <puck.chen@hisilicon.com>"); | ||
MODULE_DESCRIPTION("Hisilicon Hi655x regulator driver"); | ||
MODULE_LICENSE("GPL v2"); |
Oops, something went wrong.