/*
* max8998.c - Voltage regulator driver for the Maxim 8998
*
* Copyright (C) 2009-2010 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
* Marek Szyprowski <m.szyprowski@samsung.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/module.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/mfd/max8998.h>
#include <linux/mfd/max8998-private.h>
struct max8998_data {
struct device *dev;
struct max8998_dev *iodev;
int num_regulators;
struct regulator_dev **rdev;
u8 buck1_vol[4]; /* voltages for selection */
u8 buck2_vol[2];
unsigned int buck1_idx; /* index to last changed voltage */
/* value in a set */
unsigned int buck2_idx;
};
struct voltage_map_desc {
int min;
int max;
int step;
};
/* Voltage maps in uV*/
static const struct voltage_map_desc ldo23_voltage_map_desc = {
.min = 800000, .step = 50000, .max = 1300000,
};
static const struct voltage_map_desc ldo456711_voltage_map_desc = {
.min = 1600000, .step = 100000, .max = 3600000,
};
static const struct voltage_map_desc ldo8_voltage_map_desc = {
.min = 3000000, .step = 100000, .max = 3600000,
};
static const struct voltage_map_desc ldo9_voltage_map_desc = {
.min = 2800000, .step = 100000, .max = 3100000,
};
static const struct voltage_map_desc ldo10_voltage_map_desc = {
.min = 950000, .step = 50000, .max = 1300000,
};
static const struct voltage_map_desc ldo1213_voltage_map_desc = {
.min = 800000, .step = 100000, .max = 3300000,
};
static const struct voltage_map_desc ldo1415_voltage_map_desc = {
.min = 1200000, .step = 100000, .max = 3300000,
};
static const struct voltage_map_desc ldo1617_voltage_map_desc = {
.min = 1600000, .step = 100000, .max = 3600000,
};
static const struct voltage_map_desc buck12_voltage_map_desc = {
.min = 750000, .step = 25000, .max = 1525000,
};
static const struct voltage_map_desc buck3_voltage_map_desc = {
.min = 1600000, .step = 100000, .max = 3600000,
};
static const struct voltage_map_desc buck4_voltage_map_desc = {
.min = 800000, .step = 100000, .max = 2300000,
};
static const struct voltage_map_desc *ldo_voltage_map[] = {
NULL,
NULL,
&ldo23_voltage_map_desc, /* LDO2 */
&ldo23_voltage_map_desc, /* LDO3 */
&ldo456711_voltage_map_desc, /* LDO4 */
&ldo456711_voltage_map_desc, /* LDO5 */
&ldo456711_voltage_map_desc, /* LDO6 */
&ldo456711_voltage_map_desc, /* LDO7 */
&ldo8_voltage_map_desc, /* LDO8 */
&ldo9_voltage_map_desc, /* LDO9 */
&ldo10_voltage_map_desc, /* LDO10 */
&ldo456711_voltage_map_desc, /* LDO11 */
&ldo1213_voltage_map_desc, /* LDO12 */
&ldo1213_voltage_map_desc, /* LDO13 */
&ldo1415_voltage_map_desc, /* LDO14 */
&ldo1415_voltage_map_desc, /* LDO15 */
&ldo1617_voltage_map_desc, /* LDO16 */
&ldo1617_voltage_map_desc, /* LDO17 */
&buck12_voltage_map_desc, /* BUCK1 */
&buck12_voltage_map_desc, /* BUCK2 */
&buck3_voltage_map_desc, /* BUCK3 */
&buck4_voltage_map_desc, /* BUCK4 */
};
static int max8998_get_enable_register(struct regulator_dev *rdev,
int *reg, int *shift)
{
int ldo = rdev_get_id(rdev);
switch (ldo) {
case MAX8998_LDO2 ... MAX8998_LDO5:
*reg = MAX8998_REG_ONOFF1;
*shift = 3 - (ldo - MAX8998_LDO2);
break;
case MAX8998_LDO6 ... MAX8998_LDO13:
*reg = MAX8998_REG_ONOFF2;
*shift = 7 - (ldo - MAX8998_LDO6);
break;
case MAX8998_LDO14 ... MAX8998_LDO17:
*reg = MAX8998_REG_ONOFF3;
*shift = 7 - (ldo - MAX8998_LDO14);
break;
case MAX8998_BUCK1 ... MAX8998_BUCK4:
*reg = MAX8998_REG_ONOFF1