/*
* Voltage regulator support for AMS AS3722 PMIC
*
* Copyright (C) 2013 ams
*
* Author: Florian Lobmaier <florian.lobmaier@ams.com>
* Author: Laxman Dewangan <ldewangan@nvidia.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mfd/as3722.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>
/* Regulator IDs */
enum as3722_regulators_id {
AS3722_REGULATOR_ID_SD0,
AS3722_REGULATOR_ID_SD1,
AS3722_REGULATOR_ID_SD2,
AS3722_REGULATOR_ID_SD3,
AS3722_REGULATOR_ID_SD4,
AS3722_REGULATOR_ID_SD5,
AS3722_REGULATOR_ID_SD6,
AS3722_REGULATOR_ID_LDO0,
AS3722_REGULATOR_ID_LDO1,
AS3722_REGULATOR_ID_LDO2,
AS3722_REGULATOR_ID_LDO3,
AS3722_REGULATOR_ID_LDO4,
AS3722_REGULATOR_ID_LDO5,
AS3722_REGULATOR_ID_LDO6,
AS3722_REGULATOR_ID_LDO7,
AS3722_REGULATOR_ID_LDO9,
AS3722_REGULATOR_ID_LDO10,
AS3722_REGULATOR_ID_LDO11,
AS3722_REGULATOR_ID_MAX,
};
struct as3722_register_mapping {
u8 regulator_id;
const char *name;
const char *sname;
u8 vsel_reg;
u8 vsel_mask;
int n_voltages;
u32 enable_reg;
u8 enable_mask;
u32 control_reg;
u8 mode_mask;
u32 sleep_ctrl_reg;
u8 sleep_ctrl_mask;
};
struct as3722_regulator_config_data {
struct regulator_init_data *reg_init;
bool enable_tracking;
int ext_control;
};
struct as3722_regulators {
struct device *dev;
struct as3722 *as3722;
struct regulator_dev *rdevs[AS3722_REGULATOR_ID_MAX];
struct regulator_desc desc[AS3722_REGULATOR_ID_MAX];
struct as3722_regulator_config_data
reg_config_data[AS3722_REGULATOR_ID_MAX];
};
static const struct as3722_register_mapping as3722_reg_lookup[] = {
{
.regulator_id = AS3722_REGULATOR_ID_SD0,
.name = "as3722-sd0",
.vsel_reg = AS3722_SD0_VOLTAGE_REG,
.vsel_mask = AS3722_SD_VSEL_MASK,
.enable_reg = AS3722_SD_CONTROL_REG,
.enable_mask = AS3722_SDn_CTRL(0),
.sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
.sleep_ctrl_mask = AS3722_SD0_EXT_ENABLE_MASK,
.control_reg = AS3722_SD0_CONTROL_REG,
.mode_mask = AS3722_SD0_MODE_FAST,
},
{
.regulator_id = AS3722_REGULATOR_ID_SD1,
.name = "as3722-sd1",
.vsel_reg = AS3722_SD1_VOLTAGE_REG,
.vsel_mask = AS3722_SD_VSEL_MASK,
.enable_reg = AS3722_SD_CONTROL_REG,
.enable_mask = AS3722_SDn_CTRL(1),
.sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
.sleep_ctrl_mask = AS3722_SD1_EXT_ENABLE_MASK,
.control_reg = AS3722_SD1_CONTROL_REG,
.mode_mask = AS3722_SD1_MODE_FAST,
},
{
.regulator_id = AS3722_REGULATOR_ID_SD2,
.name = "as3722-sd2",
.sname = "vsup-sd2",
.vsel_reg = AS3722_SD2_VOLTAGE_REG,
.vsel_mask = AS3722_SD_VSEL_MASK,
.enable_reg = AS3722_SD_CONTROL_REG,
.enable_mask = AS3722_SDn_CTRL(2),
.sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
.sleep_ctrl_mask = AS3722_SD2_EXT_ENABLE_MASK,
.control_reg = AS3722_SD23_CONTROL_REG,
.mode_mask = AS3722_SD2_MODE_FAST,
.n_voltages = AS3722_SD2_VSEL_MAX + 1,
},
{
.regulator_id = AS3722_REGULATOR_ID_SD3,
.name = "as3722-sd3",
.sname = "vsup-sd3",
.vsel_reg = AS3722_SD3_VOLTAGE_REG,
.vsel_mask = AS3722_SD_VSEL_MASK,
.enable_reg = AS3722_SD_CONTROL_REG,
.enable_mask = AS3722_SDn_CTRL(3),
.sleep_ctrl_reg = AS3722_ENABLE_CTRL1_REG,
.sleep_ctrl_mask = AS3722_SD3_EXT_ENABLE_MASK,
.control_reg = AS3722_SD23_CONTROL_REG,
.mode_mask = AS3722_SD3_MODE_FAST,
.n_voltages = AS3722_SD2_VSEL_MAX + 1,
},
{
.regulator_id = AS3722_REGULATOR_ID_SD4,
.name = "as3722-sd4",
.sname = "vsup-sd4",
.vsel_reg = AS3722_SD4_VOLTAGE_REG,
.vsel_mask = AS3722_SD_VSEL_MASK,
.enable_reg = AS3722_SD_CONTROL_REG,
.enable_mask = AS3722_SDn_CTRL(4),
.sleep_ctrl_reg = AS3722_ENABLE_CTRL2_REG,
.sleep_ctrl_mask = AS3722_SD4_EXT_ENABLE_MASK,
.control_reg = AS3722_SD4_CONTROL_REG,
.mode_mask = AS3722_SD4_MODE_FAST,
.n_voltages = AS3722_SD2_VSEL_MAX + 1,
},
{
.regulator_id = AS3722_REGULATOR_ID_SD5,
.name = "as3722-sd5",
.sname = "vsup-sd5",
.vsel_reg =