Merge remote-tracking branches 'regulator/topic/mt6311', 'regulator/topic/ocp', 'regulator/topic/owner', 'regulator/topic/pfuze100' and 'regulator/topic/pwm' into regulator-next

This commit is contained in:
Mark Brown 2015-08-30 14:39:48 +01:00
Коммит 3e683126f4
29 изменённых файлов: 510 добавлений и 65 удалений

Просмотреть файл

@ -0,0 +1,35 @@
Mediatek MT6311 Regulator Driver
Required properties:
- compatible: "mediatek,mt6311-regulator"
- reg: I2C slave address, usually 0x6b.
- regulators: List of regulators provided by this controller. It is named
to VDVFS and VBIASN.
The definition for each of these nodes is defined using the standard binding
for regulators at Documentation/devicetree/bindings/regulator/regulator.txt.
The valid names for regulators are:
BUCK:
VDVFS
LDO:
VBIASN
Example:
mt6311: pmic@6b {
compatible = "mediatek,mt6311-regulator";
reg = <0x6b>;
regulators {
mt6311_vcpu_reg: VDVFS {
regulator-name = "VDVFS";
regulator-min-microvolt = < 600000>;
regulator-max-microvolt = <1400000>;
regulator-ramp-delay = <10000>;
};
mt6311_ldo_reg: VBIASN {
regulator-name = "VBIASN";
regulator-min-microvolt = <200000>;
regulator-max-microvolt = <800000>;
};
};
};

Просмотреть файл

@ -1,27 +1,68 @@
pwm regulator bindings
Bindings for the Generic PWM Regulator
======================================
Currently supports 2 modes of operation:
Voltage Table: When in this mode, a voltage table (See below) of
predefined voltage <=> duty-cycle values must be
provided via DT. Limitations are that the regulator can
only operate at the voltages supplied in the table.
Intermediary duty-cycle values which would normally
allow finer grained voltage selection are ignored and
rendered useless. Although more control is given to
the user if the assumptions made in continuous-voltage
mode do not reign true.
Continuous Voltage: This mode uses the regulator's maximum and minimum
supplied voltages specified in the
regulator-{min,max}-microvolt properties to calculate
appropriate duty-cycle values. This allows for a much
more fine grained solution when compared with
voltage-table mode above. This solution does make an
assumption that a %50 duty-cycle value will cause the
regulator voltage to run at half way between the
supplied max_uV and min_uV values.
Required properties:
- compatible: Should be "pwm-regulator"
- pwms: OF device-tree PWM specification (see PWM binding pwm.txt)
- voltage-table: voltage and duty table, include 2 members in each set of
brackets, first one is voltage(unit: uv), the next is duty(unit: percent)
--------------------
- compatible: Should be "pwm-regulator"
Any property defined as part of the core regulator binding defined in
regulator.txt can also be used.
- pwms: PWM specification (See: ../pwm/pwm.txt)
Example:
Only required for Voltage Table Mode:
- voltage-table: Voltage and Duty-Cycle table consisting of 2 cells
First cell is voltage in microvolts (uV)
Second cell is duty-cycle in percent (%)
NB: To be clear, if voltage-table is provided, then the device will be used
in Voltage Table Mode. If no voltage-table is provided, then the device will
be used in Continuous Voltage Mode.
Any property defined as part of the core regulator binding can also be used.
(See: ../regulator/regulator.txt)
Continuous Voltage Example:
pwm_regulator {
compatible = "pwm-regulator;
pwms = <&pwm1 0 8448 0>;
regulator-min-microvolt = <1016000>;
regulator-max-microvolt = <1114000>;
regulator-name = "vdd_logic";
};
Voltage Table Example:
pwm_regulator {
compatible = "pwm-regulator;
pwms = <&pwm1 0 8448 0>;
regulator-min-microvolt = <1016000>;
regulator-max-microvolt = <1114000>;
regulator-name = "vdd_logic";
/* Voltage Duty-Cycle */
voltage-table = <1114000 0>,
<1095000 10>,
<1076000 20>,
<1056000 30>,
<1036000 40>,
<1016000 50>;
regulator-min-microvolt = <1016000>;
regulator-max-microvolt = <1114000>;
regulator-name = "vdd_logic";
};

Просмотреть файл

@ -42,6 +42,7 @@ Optional properties:
- regulator-system-load: Load in uA present on regulator that is not captured by
any consumer request.
- regulator-pull-down: Enable pull down resistor when the regulator is disabled.
- regulator-over-current-protection: Enable over current protection.
Deprecated properties:
- regulator-compatible: If a regulator chip contains multiple

Просмотреть файл

@ -443,6 +443,15 @@ config REGULATOR_MC13892
Say y here to support the regulators found on the Freescale MC13892
PMIC.
config REGULATOR_MT6311
tristate "MediaTek MT6311 PMIC"
depends on I2C
help
Say y here to select this option to enable the power regulator of
MediaTek MT6311 PMIC.
This driver supports the control of different power rails of device
through regulator interface.
config REGULATOR_MT6397
tristate "MediaTek MT6397 PMIC"
depends on MFD_MT6397

Просмотреть файл

@ -59,6 +59,7 @@ obj-$(CONFIG_REGULATOR_MAX77802) += max77802.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o

Просмотреть файл

@ -530,7 +530,6 @@ MODULE_DEVICE_TABLE(i2c, act8865_ids);
static struct i2c_driver act8865_pmic_driver = {
.driver = {
.name = "act8865",
.owner = THIS_MODULE,
},
.probe = act8865_pmic_probe,
.id_table = act8865_ids,

Просмотреть файл

@ -1091,6 +1091,15 @@ static int set_machine_constraints(struct regulator_dev *rdev,
}
}
if (rdev->constraints->over_current_protection
&& ops->set_over_current_protection) {
ret = ops->set_over_current_protection(rdev);
if (ret < 0) {
rdev_err(rdev, "failed to set over current protection\n");
goto out;
}
}
print_constraints(rdev);
return 0;
out:

Просмотреть файл

@ -259,7 +259,6 @@ MODULE_DEVICE_TABLE(i2c, da9210_i2c_id);
static struct i2c_driver da9210_regulator_driver = {
.driver = {
.name = "da9210",
.owner = THIS_MODULE,
},
.probe = da9210_i2c_probe,
.id_table = da9210_i2c_id,

Просмотреть файл

@ -512,7 +512,6 @@ MODULE_DEVICE_TABLE(of, da9211_dt_ids);
static struct i2c_driver da9211_regulator_driver = {
.driver = {
.name = "da9211",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(da9211_dt_ids),
},
.probe = da9211_i2c_probe,

Просмотреть файл

@ -156,7 +156,6 @@ MODULE_DEVICE_TABLE(i2c, isl6271a_id);
static struct i2c_driver isl6271a_i2c_driver = {
.driver = {
.name = "isl6271a",
.owner = THIS_MODULE,
},
.probe = isl6271a_probe,
.id_table = isl6271a_id,

Просмотреть файл

@ -196,7 +196,6 @@ MODULE_DEVICE_TABLE(i2c, isl9305_i2c_id);
static struct i2c_driver isl9305_regulator_driver = {
.driver = {
.name = "isl9305",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(isl9305_dt_ids),
},
.probe = isl9305_i2c_probe,

Просмотреть файл

@ -452,7 +452,6 @@ MODULE_DEVICE_TABLE(i2c, lp3971_i2c_id);
static struct i2c_driver lp3971_i2c_driver = {
.driver = {
.name = "LP3971",
.owner = THIS_MODULE,
},
.probe = lp3971_i2c_probe,
.id_table = lp3971_i2c_id,

Просмотреть файл

@ -550,7 +550,6 @@ MODULE_DEVICE_TABLE(i2c, lp3972_i2c_id);
static struct i2c_driver lp3972_i2c_driver = {
.driver = {
.name = "lp3972",
.owner = THIS_MODULE,
},
.probe = lp3972_i2c_probe,
.id_table = lp3972_i2c_id,

Просмотреть файл

@ -961,7 +961,6 @@ MODULE_DEVICE_TABLE(i2c, lp872x_ids);
static struct i2c_driver lp872x_driver = {
.driver = {
.name = "lp872x",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(lp872x_dt_ids),
},
.probe = lp872x_probe,

Просмотреть файл

@ -542,7 +542,6 @@ MODULE_DEVICE_TABLE(i2c, ltc3589_i2c_id);
static struct i2c_driver ltc3589_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
.probe = ltc3589_probe,
.id_table = ltc3589_i2c_id,

Просмотреть файл

@ -304,7 +304,6 @@ static struct i2c_driver max1586_pmic_driver = {
.probe = max1586_pmic_probe,
.driver = {
.name = "max1586",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(max1586_of_match),
},
.id_table = max1586_id,

Просмотреть файл

@ -518,7 +518,6 @@ static struct i2c_driver max8660_driver = {
.probe = max8660_probe,
.driver = {
.name = "max8660",
.owner = THIS_MODULE,
},
.id_table = max8660_id,
};

Просмотреть файл

@ -732,7 +732,6 @@ static struct i2c_driver max8973_i2c_driver = {
.driver = {
.name = "max8973",
.of_match_table = of_max8973_match_tbl,
.owner = THIS_MODULE,
},
.probe = max8973_probe,
.id_table = max8973_id,

Просмотреть файл

@ -0,0 +1,179 @@
/*
* Copyright (c) 2015 MediaTek Inc.
* Author: Henry Chen <henryc.chen@mediatek.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.
*
* 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.
*/
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/mt6311.h>
#include <linux/slab.h>
#include "mt6311-regulator.h"
static const struct regmap_config mt6311_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MT6311_FQMTR_CON4,
};
/* Default limits measured in millivolts and milliamps */
#define MT6311_MIN_UV 600000
#define MT6311_MAX_UV 1393750
#define MT6311_STEP_UV 6250
static const struct regulator_linear_range buck_volt_range[] = {
REGULATOR_LINEAR_RANGE(MT6311_MIN_UV, 0, 0x7f, MT6311_STEP_UV),
};
static const struct regulator_ops mt6311_buck_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
static const struct regulator_ops mt6311_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
#define MT6311_BUCK(_id) \
{\
.name = #_id,\
.ops = &mt6311_buck_ops,\
.of_match = of_match_ptr(#_id),\
.regulators_node = of_match_ptr("regulators"),\
.type = REGULATOR_VOLTAGE,\
.id = MT6311_ID_##_id,\
.n_voltages = (MT6311_MAX_UV - MT6311_MIN_UV) / MT6311_STEP_UV + 1,\
.min_uV = MT6311_MIN_UV,\
.uV_step = MT6311_STEP_UV,\
.owner = THIS_MODULE,\
.linear_ranges = buck_volt_range, \
.n_linear_ranges = ARRAY_SIZE(buck_volt_range), \
.enable_reg = MT6311_VDVFS11_CON9,\
.enable_mask = MT6311_PMIC_VDVFS11_EN_MASK,\
.vsel_reg = MT6311_VDVFS11_CON12,\
.vsel_mask = MT6311_PMIC_VDVFS11_VOSEL_MASK,\
}
#define MT6311_LDO(_id) \
{\
.name = #_id,\
.ops = &mt6311_ldo_ops,\
.of_match = of_match_ptr(#_id),\
.regulators_node = of_match_ptr("regulators"),\
.type = REGULATOR_VOLTAGE,\
.id = MT6311_ID_##_id,\
.owner = THIS_MODULE,\
.enable_reg = MT6311_LDO_CON3,\
.enable_mask = MT6311_PMIC_RG_VBIASN_EN_MASK,\
}
static const struct regulator_desc mt6311_regulators[] = {
MT6311_BUCK(VDVFS),
MT6311_LDO(VBIASN),
};
/*
* I2C driver interface functions
*/
static int mt6311_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct regulator_config config = { };
struct regulator_dev *rdev;
struct regmap *regmap;
int i, ret;
unsigned int data;
regmap = devm_regmap_init_i2c(i2c, &mt6311_regmap_config);
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
ret);
return ret;
}
ret = regmap_read(regmap, MT6311_SWCID, &data);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to read DEVICE_ID reg: %d\n", ret);
return ret;
}
switch (data) {
case MT6311_E1_CID_CODE:
case MT6311_E2_CID_CODE:
case MT6311_E3_CID_CODE:
break;
default:
dev_err(&i2c->dev, "Unsupported device id = 0x%x.\n", data);
return -ENODEV;
}
for (i = 0; i < MT6311_MAX_REGULATORS; i++) {
config.dev = &i2c->dev;
config.regmap = regmap;
rdev = devm_regulator_register(&i2c->dev,
&mt6311_regulators[i], &config);
if (IS_ERR(rdev)) {
dev_err(&i2c->dev,
"Failed to register MT6311 regulator\n");
return PTR_ERR(rdev);
}
}
return 0;
}
static const struct i2c_device_id mt6311_i2c_id[] = {
{"mt6311", 0},
{},
};
MODULE_DEVICE_TABLE(i2c, mt6311_i2c_id);
#ifdef CONFIG_OF
static const struct of_device_id mt6311_dt_ids[] = {
{ .compatible = "mediatek,mt6311-regulator",
.data = &mt6311_i2c_id[0] },
{},
};
MODULE_DEVICE_TABLE(of, mt6311_dt_ids);
#endif
static struct i2c_driver mt6311_regulator_driver = {
.driver = {
.name = "mt6311",
.of_match_table = of_match_ptr(mt6311_dt_ids),
},
.probe = mt6311_i2c_probe,
.id_table = mt6311_i2c_id,
};
module_i2c_driver(mt6311_regulator_driver);
MODULE_AUTHOR("Henry Chen <henryc.chen@mediatek.com>");
MODULE_DESCRIPTION("Regulator device driver for Mediatek MT6311");
MODULE_LICENSE("GPL v2");

Просмотреть файл

@ -0,0 +1,65 @@
/*
* Copyright (c) 2015 MediaTek Inc.
* Author: Henry Chen <henryc.chen@mediatek.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.
*
* 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.
*/
#ifndef __MT6311_REGULATOR_H__
#define __MT6311_REGULATOR_H__
#define MT6311_SWCID 0x01
#define MT6311_TOP_INT_CON 0x18
#define MT6311_TOP_INT_MON 0x19
#define MT6311_VDVFS11_CON0 0x87
#define MT6311_VDVFS11_CON7 0x88
#define MT6311_VDVFS11_CON8 0x89
#define MT6311_VDVFS11_CON9 0x8A
#define MT6311_VDVFS11_CON10 0x8B
#define MT6311_VDVFS11_CON11 0x8C
#define MT6311_VDVFS11_CON12 0x8D
#define MT6311_VDVFS11_CON13 0x8E
#define MT6311_VDVFS11_CON14 0x8F
#define MT6311_VDVFS11_CON15 0x90
#define MT6311_VDVFS11_CON16 0x91
#define MT6311_VDVFS11_CON17 0x92
#define MT6311_VDVFS11_CON18 0x93
#define MT6311_VDVFS11_CON19 0x94
#define MT6311_LDO_CON0 0xCC
#define MT6311_LDO_OCFB0 0xCD
#define MT6311_LDO_CON2 0xCE
#define MT6311_LDO_CON3 0xCF
#define MT6311_LDO_CON4 0xD0
#define MT6311_FQMTR_CON0 0xD1
#define MT6311_FQMTR_CON1 0xD2
#define MT6311_FQMTR_CON2 0xD3
#define MT6311_FQMTR_CON3 0xD4
#define MT6311_FQMTR_CON4 0xD5
#define MT6311_PMIC_RG_INT_POL_MASK 0x1
#define MT6311_PMIC_RG_INT_EN_MASK 0x2
#define MT6311_PMIC_RG_BUCK_OC_INT_STATUS_MASK 0x10
#define MT6311_PMIC_VDVFS11_EN_CTRL_MASK 0x1
#define MT6311_PMIC_VDVFS11_VOSEL_CTRL_MASK 0x2
#define MT6311_PMIC_VDVFS11_EN_SEL_MASK 0x3
#define MT6311_PMIC_VDVFS11_VOSEL_SEL_MASK 0xc
#define MT6311_PMIC_VDVFS11_EN_MASK 0x1
#define MT6311_PMIC_VDVFS11_VOSEL_MASK 0x7F
#define MT6311_PMIC_VDVFS11_VOSEL_ON_MASK 0x7F
#define MT6311_PMIC_VDVFS11_VOSEL_SLEEP_MASK 0x7F
#define MT6311_PMIC_NI_VDVFS11_VOSEL_MASK 0x7F
#define MT6311_PMIC_RG_VBIASN_EN_MASK 0x1
#endif

Просмотреть файл

@ -107,6 +107,9 @@ static void of_get_regulation_constraints(struct device_node *np,
if (!of_property_read_u32(np, "regulator-system-load", &pval))
constraints->system_load = pval;
constraints->over_current_protection = of_property_read_bool(np,
"regulator-over-current-protection");
for (i = 0; i < ARRAY_SIZE(regulator_states); i++) {
switch (i) {
case PM_SUSPEND_MEM:

Просмотреть файл

@ -643,7 +643,6 @@ static struct i2c_driver pfuze_driver = {
.id_table = pfuze_device_id,
.driver = {
.name = "pfuze100-regulator",
.owner = THIS_MODULE,
.of_match_table = pfuze_dt_ids,
},
.probe = pfuze100_regulator_probe,
@ -653,4 +652,3 @@ module_i2c_driver(pfuze_driver);
MODULE_AUTHOR("Robin Gong <b38343@freescale.com>");
MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100/PFUZE200 PMIC");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("i2c:pfuze100-regulator");

Просмотреть файл

@ -10,6 +10,7 @@
* published by the Free Software Foundation.
*/
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
@ -21,9 +22,15 @@
#include <linux/pwm.h>
struct pwm_regulator_data {
struct pwm_voltages *duty_cycle_table;
/* Shared */
struct pwm_device *pwm;
/* Voltage table */
struct pwm_voltages *duty_cycle_table;
int state;
/* Continuous voltage */
int volt_uV;
};
struct pwm_voltages {
@ -31,6 +38,9 @@ struct pwm_voltages {
unsigned int dutycycle;
};
/**
* Voltage table call-backs
*/
static int pwm_regulator_get_voltage_sel(struct regulator_dev *rdev)
{
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
@ -79,29 +89,129 @@ static int pwm_regulator_list_voltage(struct regulator_dev *rdev,
return drvdata->duty_cycle_table[selector].uV;
}
static struct regulator_ops pwm_regulator_voltage_ops = {
/**
* Continuous voltage call-backs
*/
static int pwm_voltage_to_duty_cycle_percentage(struct regulator_dev *rdev, int req_uV)
{
int min_uV = rdev->constraints->min_uV;
int max_uV = rdev->constraints->max_uV;
int diff = max_uV - min_uV;
return 100 - (((req_uV * 100) - (min_uV * 100)) / diff);
}
static int pwm_regulator_get_voltage(struct regulator_dev *rdev)
{
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
return drvdata->volt_uV;
}
static int pwm_regulator_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV,
unsigned *selector)
{
struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
unsigned int ramp_delay = rdev->constraints->ramp_delay;
unsigned int period = pwm_get_period(drvdata->pwm);
int duty_cycle;
int ret;
duty_cycle = pwm_voltage_to_duty_cycle_percentage(rdev, min_uV);
ret = pwm_config(drvdata->pwm, (period / 100) * duty_cycle, period);
if (ret) {
dev_err(&rdev->dev, "Failed to configure PWM\n");
return ret;
}
ret = pwm_enable(drvdata->pwm);
if (ret) {
dev_err(&rdev->dev, "Failed to enable PWM\n");
return ret;
}
drvdata->volt_uV = min_uV;
/* Delay required by PWM regulator to settle to the new voltage */
usleep_range(ramp_delay, ramp_delay + 1000);
return 0;
}
static struct regulator_ops pwm_regulator_voltage_table_ops = {
.set_voltage_sel = pwm_regulator_set_voltage_sel,
.get_voltage_sel = pwm_regulator_get_voltage_sel,
.list_voltage = pwm_regulator_list_voltage,
.map_voltage = regulator_map_voltage_iterate,
};
static struct regulator_ops pwm_regulator_voltage_continuous_ops = {
.get_voltage = pwm_regulator_get_voltage,
.set_voltage = pwm_regulator_set_voltage,
};
static struct regulator_desc pwm_regulator_desc = {
.name = "pwm-regulator",
.ops = &pwm_regulator_voltage_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.supply_name = "pwm",
};
static int pwm_regulator_init_table(struct platform_device *pdev,
struct pwm_regulator_data *drvdata)
{
struct device_node *np = pdev->dev.of_node;
struct pwm_voltages *duty_cycle_table;
unsigned int length = 0;
int ret;
of_find_property(np, "voltage-table", &length);
if ((length < sizeof(*duty_cycle_table)) ||
(length % sizeof(*duty_cycle_table))) {
dev_err(&pdev->dev,
"voltage-table length(%d) is invalid\n",
length);
return -EINVAL;
}
duty_cycle_table = devm_kzalloc(&pdev->dev, length, GFP_KERNEL);
if (!duty_cycle_table)
return -ENOMEM;
ret = of_property_read_u32_array(np, "voltage-table",
(u32 *)duty_cycle_table,
length / sizeof(u32));
if (ret) {
dev_err(&pdev->dev, "Failed to read voltage-table\n");
return ret;
}
drvdata->duty_cycle_table = duty_cycle_table;
pwm_regulator_desc.ops = &pwm_regulator_voltage_table_ops;
pwm_regulator_desc.n_voltages = length / sizeof(*duty_cycle_table);
return 0;
}
static int pwm_regulator_init_continuous(struct platform_device *pdev,
struct pwm_regulator_data *drvdata)
{
pwm_regulator_desc.ops = &pwm_regulator_voltage_continuous_ops;
pwm_regulator_desc.continuous_voltage_range = true;
return 0;
}
static int pwm_regulator_probe(struct platform_device *pdev)
{
const struct regulator_init_data *init_data;
struct pwm_regulator_data *drvdata;
struct property *prop;
struct regulator_dev *regulator;
struct regulator_config config = { };
struct device_node *np = pdev->dev.of_node;
int length, ret;
int ret;
if (!np) {
dev_err(&pdev->dev, "Device Tree node missing\n");
@ -112,44 +222,22 @@ static int pwm_regulator_probe(struct platform_device *pdev)
if (!drvdata)
return -ENOMEM;
/* determine the number of voltage-table */
prop = of_find_property(np, "voltage-table", &length);
if (!prop) {
dev_err(&pdev->dev, "No voltage-table\n");
return -EINVAL;
}
if ((length < sizeof(*drvdata->duty_cycle_table)) ||
(length % sizeof(*drvdata->duty_cycle_table))) {
dev_err(&pdev->dev, "voltage-table length(%d) is invalid\n",
length);
return -EINVAL;
}
pwm_regulator_desc.n_voltages = length / sizeof(*drvdata->duty_cycle_table);
drvdata->duty_cycle_table = devm_kzalloc(&pdev->dev,
length, GFP_KERNEL);
if (!drvdata->duty_cycle_table)
return -ENOMEM;
/* read voltage table from DT property */
ret = of_property_read_u32_array(np, "voltage-table",
(u32 *)drvdata->duty_cycle_table,
length / sizeof(u32));
if (ret < 0) {
dev_err(&pdev->dev, "read voltage-table failed\n");
if (of_find_property(np, "voltage-table", NULL))
ret = pwm_regulator_init_table(pdev, drvdata);
else
ret = pwm_regulator_init_continuous(pdev, drvdata);
if (ret)
return ret;
}
config.init_data = of_get_regulator_init_data(&pdev->dev, np,
&pwm_regulator_desc);
if (!config.init_data)
init_data = of_get_regulator_init_data(&pdev->dev, np,
&pwm_regulator_desc);
if (!init_data)
return -ENOMEM;
config.of_node = np;
config.dev = &pdev->dev;
config.driver_data = drvdata;
config.init_data = init_data;
drvdata->pwm = devm_pwm_get(&pdev->dev, NULL);
if (IS_ERR(drvdata->pwm)) {

Просмотреть файл

@ -362,7 +362,6 @@ MODULE_DEVICE_TABLE(i2c, tps51632_id);
static struct i2c_driver tps51632_i2c_driver = {
.driver = {
.name = "tps51632",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(tps51632_of_match),
},
.probe = tps51632_probe,

Просмотреть файл

@ -515,7 +515,6 @@ MODULE_DEVICE_TABLE(i2c, tps62360_id);
static struct i2c_driver tps62360_i2c_driver = {
.driver = {
.name = "tps62360",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(tps62360_of_match),
},
.probe = tps62360_probe,

Просмотреть файл

@ -410,7 +410,6 @@ MODULE_DEVICE_TABLE(i2c, tps_65023_id);
static struct i2c_driver tps_65023_i2c_driver = {
.driver = {
.name = "tps65023",
.owner = THIS_MODULE,
},
.probe = tps_65023_probe,
.id_table = tps_65023_id,

Просмотреть файл

@ -148,6 +148,7 @@ struct regulator_ops {
int (*get_current_limit) (struct regulator_dev *);
int (*set_input_current_limit) (struct regulator_dev *, int lim_uA);
int (*set_over_current_protection) (struct regulator_dev *);
/* enable/disable regulator */
int (*enable) (struct regulator_dev *);

Просмотреть файл

@ -147,6 +147,7 @@ struct regulation_constraints {
unsigned ramp_disable:1; /* disable ramp delay */
unsigned soft_start:1; /* ramp voltage slowly */
unsigned pull_down:1; /* pull down resistor when regulator off */
unsigned over_current_protection:1; /* auto disable on over current */
};
/**

Просмотреть файл

@ -0,0 +1,29 @@
/*
* Copyright (c) 2015 MediaTek Inc.
* Author: Henry Chen <henryc.chen@mediatek.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.
*
* 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.
*/
#ifndef __LINUX_REGULATOR_MT6311_H
#define __LINUX_REGULATOR_MT6311_H
#define MT6311_MAX_REGULATORS 2
enum {
MT6311_ID_VDVFS = 0,
MT6311_ID_VBIASN,
};
#define MT6311_E1_CID_CODE 0x10
#define MT6311_E2_CID_CODE 0x20
#define MT6311_E3_CID_CODE 0x30
#endif /* __LINUX_REGULATOR_MT6311_H */