tps65023-regulator.c revision 43530b69d758328d3ffe6ab98fd640463e8e3667
130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/*
230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * tps65023-regulator.c
330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal *
430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * Supports TPS65023 Regulator
530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal *
630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * Copyright (C) 2009 Texas Instrument Incorporated - http://www.ti.com/
730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal *
830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * This program is free software; you can redistribute it and/or
930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * modify it under the terms of the GNU General Public License as
1030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * published by the Free Software Foundation version 2.
1130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal *
1230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
1330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * whether express or implied; without even the implied warranty of
1430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * General Public License for more details.
1630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal */
1730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
1830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#include <linux/kernel.h>
1930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#include <linux/module.h>
2030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#include <linux/init.h>
2130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#include <linux/err.h>
2230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#include <linux/platform_device.h>
2330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#include <linux/regulator/driver.h>
2430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#include <linux/regulator/machine.h>
2530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#include <linux/i2c.h>
2630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#include <linux/delay.h>
275a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
2890923351d480fffd0d24646db83f6f8315eed0d9Mark Brown#include <linux/regmap.h>
2930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
3030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* Register definitions */
3130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_REG_VERSION		0
3230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_REG_PGOODZ		1
3330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_REG_MASK		2
3430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_REG_REG_CTRL		3
3530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_REG_CON_CTRL		4
3630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_REG_CON_CTRL2		5
3730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_REG_DEF_CORE		6
3830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_REG_DEFSLEW		7
3930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_REG_LDO_CTRL		8
4030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
4130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* PGOODZ bitfields */
4230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_PGOODZ_PWRFAILZ	BIT(7)
4330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_PGOODZ_LOWBATTZ	BIT(6)
4430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_PGOODZ_VDCDC1		BIT(5)
4530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_PGOODZ_VDCDC2		BIT(4)
4630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_PGOODZ_VDCDC3		BIT(3)
4730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_PGOODZ_LDO2		BIT(2)
4830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_PGOODZ_LDO1		BIT(1)
4930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
5030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* MASK bitfields */
5130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_MASK_PWRFAILZ		BIT(7)
5230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_MASK_LOWBATTZ		BIT(6)
5330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_MASK_VDCDC1		BIT(5)
5430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_MASK_VDCDC2		BIT(4)
5530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_MASK_VDCDC3		BIT(3)
5630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_MASK_LDO2		BIT(2)
5730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define	TPS65023_MASK_LDO1		BIT(1)
5830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
5930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* REG_CTRL bitfields */
6030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_REG_CTRL_VDCDC1_EN	BIT(5)
6130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_REG_CTRL_VDCDC2_EN	BIT(4)
6230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_REG_CTRL_VDCDC3_EN	BIT(3)
6330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_REG_CTRL_LDO2_EN	BIT(2)
6430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_REG_CTRL_LDO1_EN	BIT(1)
6530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
66fc999b83799074832367d3cfd724c341c849a7daMarcus Folkesson/* REG_CTRL2 bitfields */
67fc999b83799074832367d3cfd724c341c849a7daMarcus Folkesson#define TPS65023_REG_CTRL2_GO		BIT(7)
68fc999b83799074832367d3cfd724c341c849a7daMarcus Folkesson#define TPS65023_REG_CTRL2_CORE_ADJ	BIT(6)
69fc999b83799074832367d3cfd724c341c849a7daMarcus Folkesson#define TPS65023_REG_CTRL2_DCDC2	BIT(2)
70f068ad8cca7532bc42115d61489de00fe57c3909Marcus Folkesson#define TPS65023_REG_CTRL2_DCDC1	BIT(1)
71f068ad8cca7532bc42115d61489de00fe57c3909Marcus Folkesson#define TPS65023_REG_CTRL2_DCDC3	BIT(0)
72f068ad8cca7532bc42115d61489de00fe57c3909Marcus Folkesson
7330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* LDO_CTRL bitfields */
7430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id)	((ldo_id)*4)
7530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id)	(0xF0 >> ((ldo_id)*4))
7630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
7730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* Number of step-down converters available */
7830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_NUM_DCDC		3
7930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* Number of LDO voltage regulators  available */
8030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_NUM_LDO		2
8130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* Number of total regulators available */
8230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_NUM_REGULATOR	(TPS65023_NUM_DCDC + TPS65023_NUM_LDO)
8330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
8430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* DCDCs */
8530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_DCDC_1			0
8630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_DCDC_2			1
8730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_DCDC_3			2
8830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* LDOs */
8930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_LDO_1			3
9030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_LDO_2			4
9130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
9230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal#define TPS65023_MAX_REG_ID		TPS65023_LDO_2
9330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
9430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* Supported voltage values for regulators */
951c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkessonstatic const u16 VCORE_VSEL_table[] = {
9630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	800, 825, 850, 875,
9730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	900, 925, 950, 975,
9830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	1000, 1025, 1050, 1075,
9930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	1100, 1125, 1150, 1175,
10030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	1200, 1225, 1250, 1275,
10130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	1300, 1325, 1350, 1375,
10230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	1400, 1425, 1450, 1475,
10330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	1500, 1525, 1550, 1600,
10430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal};
10530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
106437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson/* Supported voltage values for LDO regulators for tps65020 */
107437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkessonstatic const u16 TPS65020_LDO1_VSEL_table[] = {
108437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	1000, 1050, 1100, 1300,
109437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	1800, 2500, 3000, 3300,
110437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson};
1111c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson
112437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkessonstatic const u16 TPS65020_LDO2_VSEL_table[] = {
113437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	1000, 1050, 1100, 1300,
114437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	1800, 2500, 3000, 3300,
115437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson};
1161c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson
1171c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson/* Supported voltage values for LDO regulators
1181c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson * for tps65021 and tps65023 */
1191c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkessonstatic const u16 TPS65023_LDO1_VSEL_table[] = {
12030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	1000, 1100, 1300, 1800,
12130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	2200, 2600, 2800, 3150,
12230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal};
12330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
1241c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkessonstatic const u16 TPS65023_LDO2_VSEL_table[] = {
12530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	1050, 1200, 1300, 1800,
12630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	2500, 2800, 3000, 3300,
12730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal};
12830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
12930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* Regulator specific details */
13030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstruct tps_info {
13130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	const char *name;
13230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	unsigned min_uV;
13330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	unsigned max_uV;
13430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	bool fixed;
13530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	u8 table_len;
13630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	const u16 *table;
13730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal};
13830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
13930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* PMIC details */
14030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstruct tps_pmic {
14130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct regulator_desc desc[TPS65023_NUM_REGULATOR];
14230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct i2c_client *client;
14330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct regulator_dev *rdev[TPS65023_NUM_REGULATOR];
14430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	const struct tps_info *info[TPS65023_NUM_REGULATOR];
14590923351d480fffd0d24646db83f6f8315eed0d9Mark Brown	struct regmap *regmap;
1461c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	u8 core_regulator;
1471c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson};
1481c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson
1491c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson/* Struct passed as driver data */
1501c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkessonstruct tps_driver_data {
1511c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	const struct tps_info *info;
1521c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	u8 core_regulator;
15330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal};
15430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
15530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int tps65023_dcdc_is_enabled(struct regulator_dev *dev)
15630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
15730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps = rdev_get_drvdata(dev);
15830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int data, dcdc = rdev_get_id(dev);
15943530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	int ret;
16030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	u8 shift;
16130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
16230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
16330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
16430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
16530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	shift = TPS65023_NUM_REGULATOR - dcdc;
16643530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	ret = regmap_read(tps->regmap, TPS65023_REG_REG_CTRL, &data);
16730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
16843530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	if (ret != 0)
16943530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi		return ret;
17030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	else
17130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return (data & 1<<shift) ? 1 : 0;
17230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
17330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
17430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int tps65023_ldo_is_enabled(struct regulator_dev *dev)
17530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
17630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps = rdev_get_drvdata(dev);
17730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int data, ldo = rdev_get_id(dev);
17843530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	int ret;
17930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	u8 shift;
18030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
18130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
18230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
18330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
18430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
18543530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	ret = regmap_read(tps->regmap, TPS65023_REG_REG_CTRL, &data);
18630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
18743530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	if (ret != 0)
18843530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi		return ret;
18930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	else
19030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return (data & 1<<shift) ? 1 : 0;
19130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
19230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
19330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int tps65023_dcdc_enable(struct regulator_dev *dev)
19430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
19530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps = rdev_get_drvdata(dev);
19630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int dcdc = rdev_get_id(dev);
19730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	u8 shift;
19830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
19930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
20030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
20130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
20230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	shift = TPS65023_NUM_REGULATOR - dcdc;
20343530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 1 << shift);
20430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
20530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
20630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int tps65023_dcdc_disable(struct regulator_dev *dev)
20730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
20830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps = rdev_get_drvdata(dev);
20930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int dcdc = rdev_get_id(dev);
21030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	u8 shift;
21130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
21230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
21330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
21430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
21530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	shift = TPS65023_NUM_REGULATOR - dcdc;
21643530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 0);
21730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
21830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
21930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int tps65023_ldo_enable(struct regulator_dev *dev)
22030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
22130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps = rdev_get_drvdata(dev);
22230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int ldo = rdev_get_id(dev);
22330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	u8 shift;
22430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
22530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
22630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
22730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
22830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
22943530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 1 << shift);
23030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
23130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
23230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int tps65023_ldo_disable(struct regulator_dev *dev)
23330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
23430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps = rdev_get_drvdata(dev);
23530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int ldo = rdev_get_id(dev);
23630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	u8 shift;
23730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
23830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
23930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
24030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
24130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	shift = (ldo == TPS65023_LDO_1 ? 1 : 2);
24243530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	return regmap_update_bits(tps->regmap, TPS65023_REG_REG_CTRL, 1 << shift, 0);
24330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
24430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
24530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int tps65023_dcdc_get_voltage(struct regulator_dev *dev)
24630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
24730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps = rdev_get_drvdata(dev);
24843530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	int ret;
24930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int data, dcdc = rdev_get_id(dev);
25030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
25130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
25230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
25330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
2541c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	if (dcdc == tps->core_regulator) {
25543530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi		ret = regmap_read(tps->regmap, TPS65023_REG_DEF_CORE, &data);
25643530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi		if (ret != 0)
25743530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi			return ret;
25830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		data &= (tps->info[dcdc]->table_len - 1);
25930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return tps->info[dcdc]->table[data] * 1000;
26030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	} else
26130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return tps->info[dcdc]->min_uV;
26230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
26330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
26430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int tps65023_dcdc_set_voltage(struct regulator_dev *dev,
2653a93f2a9f4d8f73d74c0e552feb68a10f778a219Mark Brown				     int min_uV, int max_uV,
2663a93f2a9f4d8f73d74c0e552feb68a10f778a219Mark Brown				     unsigned *selector)
26730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
26830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps = rdev_get_drvdata(dev);
26930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int dcdc = rdev_get_id(dev);
27030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int vsel;
271cc17ef3f0463ba17c8767578da8c4e5fbdd4b447Marcus Folkesson	int ret;
27230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
2731c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	if (dcdc != tps->core_regulator)
27430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
27530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (min_uV < tps->info[dcdc]->min_uV
27630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal			|| min_uV > tps->info[dcdc]->max_uV)
27730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
27830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (max_uV < tps->info[dcdc]->min_uV
27930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal			|| max_uV > tps->info[dcdc]->max_uV)
28030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
28130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
28230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	for (vsel = 0; vsel < tps->info[dcdc]->table_len; vsel++) {
28330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		int mV = tps->info[dcdc]->table[vsel];
28430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		int uV = mV * 1000;
28530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
28630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		/* Break at the first in-range value */
28730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		if (min_uV <= uV && uV <= max_uV)
28830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal			break;
28930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	}
29030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
2913a93f2a9f4d8f73d74c0e552feb68a10f778a219Mark Brown	*selector = vsel;
2923a93f2a9f4d8f73d74c0e552feb68a10f778a219Mark Brown
29330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (vsel == tps->info[dcdc]->table_len)
294cc17ef3f0463ba17c8767578da8c4e5fbdd4b447Marcus Folkesson		goto failed;
295cc17ef3f0463ba17c8767578da8c4e5fbdd4b447Marcus Folkesson
29643530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	ret = regmap_write(tps->regmap, TPS65023_REG_DEF_CORE, vsel);
297cc17ef3f0463ba17c8767578da8c4e5fbdd4b447Marcus Folkesson
298cc17ef3f0463ba17c8767578da8c4e5fbdd4b447Marcus Folkesson	/* Tell the chip that we have changed the value in DEFCORE
299cc17ef3f0463ba17c8767578da8c4e5fbdd4b447Marcus Folkesson	 * and its time to update the core voltage
300cc17ef3f0463ba17c8767578da8c4e5fbdd4b447Marcus Folkesson	 */
30143530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
30243530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi			TPS65023_REG_CTRL2_GO, TPS65023_REG_CTRL2_GO);
303cc17ef3f0463ba17c8767578da8c4e5fbdd4b447Marcus Folkesson
304cc17ef3f0463ba17c8767578da8c4e5fbdd4b447Marcus Folkesson	return ret;
305cc17ef3f0463ba17c8767578da8c4e5fbdd4b447Marcus Folkesson
306cc17ef3f0463ba17c8767578da8c4e5fbdd4b447Marcus Folkessonfailed:
307cc17ef3f0463ba17c8767578da8c4e5fbdd4b447Marcus Folkesson	return -EINVAL;
30830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
30930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
31030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int tps65023_ldo_get_voltage(struct regulator_dev *dev)
31130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
31230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps = rdev_get_drvdata(dev);
31330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int data, ldo = rdev_get_id(dev);
31443530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	int ret;
31530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
31630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
31730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
31830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
31943530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	ret = regmap_read(tps->regmap, TPS65023_REG_LDO_CTRL, &data);
32043530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	if (ret != 0)
32143530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi		return ret;
32230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
32330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	data >>= (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1));
32430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	data &= (tps->info[ldo]->table_len - 1);
32530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	return tps->info[ldo]->table[data] * 1000;
32630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
32730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
32830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int tps65023_ldo_set_voltage(struct regulator_dev *dev,
3293a93f2a9f4d8f73d74c0e552feb68a10f778a219Mark Brown				    int min_uV, int max_uV, unsigned *selector)
33030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
33130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps = rdev_get_drvdata(dev);
33230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int data, vsel, ldo = rdev_get_id(dev);
33343530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	int ret;
33430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
33530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
33630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
33730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
33830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (min_uV < tps->info[ldo]->min_uV || min_uV > tps->info[ldo]->max_uV)
33930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
34030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (max_uV < tps->info[ldo]->min_uV || max_uV > tps->info[ldo]->max_uV)
34130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
34230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
34330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	for (vsel = 0; vsel < tps->info[ldo]->table_len; vsel++) {
34430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		int mV = tps->info[ldo]->table[vsel];
34530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		int uV = mV * 1000;
34630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
34730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		/* Break at the first in-range value */
34830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		if (min_uV <= uV && uV <= max_uV)
34930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal			break;
35030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	}
35130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
35230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (vsel == tps->info[ldo]->table_len)
35330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
35430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
3553a93f2a9f4d8f73d74c0e552feb68a10f778a219Mark Brown	*selector = vsel;
3563a93f2a9f4d8f73d74c0e552feb68a10f778a219Mark Brown
35743530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	ret = regmap_read(tps->regmap, TPS65023_REG_LDO_CTRL, &data);
35843530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	if (ret != 0)
35943530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi		return ret;
36030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
36130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	data &= TPS65023_LDO_CTRL_LDOx_MASK(ldo - TPS65023_LDO_1);
36230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	data |= (vsel << (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1)));
36343530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	return regmap_write(tps->regmap, TPS65023_REG_LDO_CTRL, data);
36430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
36530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
36630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int tps65023_dcdc_list_voltage(struct regulator_dev *dev,
36730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal					unsigned selector)
36830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
36930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps = rdev_get_drvdata(dev);
37030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int dcdc = rdev_get_id(dev);
37130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
37230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3)
37330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
37430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
3751c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	if (dcdc == tps->core_regulator) {
37630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		if (selector >= tps->info[dcdc]->table_len)
37730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal			return -EINVAL;
37830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		else
37930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal			return tps->info[dcdc]->table[selector] * 1000;
38030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	} else
38130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return tps->info[dcdc]->min_uV;
38230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
38330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
38430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int tps65023_ldo_list_voltage(struct regulator_dev *dev,
38530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal					unsigned selector)
38630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
38730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps = rdev_get_drvdata(dev);
38830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int ldo = rdev_get_id(dev);
38930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
39030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2)
39130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
39230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
39330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (selector >= tps->info[ldo]->table_len)
39430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EINVAL;
39530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	else
39630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return tps->info[ldo]->table[selector] * 1000;
39730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
39830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
39930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* Operations permitted on VDCDCx */
40030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic struct regulator_ops tps65023_dcdc_ops = {
40130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.is_enabled = tps65023_dcdc_is_enabled,
40230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.enable = tps65023_dcdc_enable,
40330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.disable = tps65023_dcdc_disable,
40430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.get_voltage = tps65023_dcdc_get_voltage,
40530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.set_voltage = tps65023_dcdc_set_voltage,
40630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.list_voltage = tps65023_dcdc_list_voltage,
40730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal};
40830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
40930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/* Operations permitted on LDOx */
41030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic struct regulator_ops tps65023_ldo_ops = {
41130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.is_enabled = tps65023_ldo_is_enabled,
41230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.enable = tps65023_ldo_enable,
41330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.disable = tps65023_ldo_disable,
41430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.get_voltage = tps65023_ldo_get_voltage,
41530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.set_voltage = tps65023_ldo_set_voltage,
41630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.list_voltage = tps65023_ldo_list_voltage,
41730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal};
41830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
41990923351d480fffd0d24646db83f6f8315eed0d9Mark Brownstatic struct regmap_config tps65023_regmap_config = {
42090923351d480fffd0d24646db83f6f8315eed0d9Mark Brown	.reg_bits = 8,
42190923351d480fffd0d24646db83f6f8315eed0d9Mark Brown	.val_bits = 8,
42290923351d480fffd0d24646db83f6f8315eed0d9Mark Brown};
42390923351d480fffd0d24646db83f6f8315eed0d9Mark Brown
42454d13ab1038911249fc5769efee87fed000623c0Dmitry Torokhovstatic int __devinit tps_65023_probe(struct i2c_client *client,
42554d13ab1038911249fc5769efee87fed000623c0Dmitry Torokhov				     const struct i2c_device_id *id)
42630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
4271c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	const struct tps_driver_data *drv_data = (void *)id->driver_data;
4281c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	const struct tps_info *info = drv_data->info;
42930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct regulator_init_data *init_data;
43030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct regulator_dev *rdev;
43130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps;
43230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int i;
43354d13ab1038911249fc5769efee87fed000623c0Dmitry Torokhov	int error;
43430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
43530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
43630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EIO;
43730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
43830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	/**
43930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	 * init_data points to array of regulator_init structures
44030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	 * coming from the board-evm file.
44130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	 */
44230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	init_data = client->dev.platform_data;
44330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (!init_data)
44430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -EIO;
44530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
44630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	tps = kzalloc(sizeof(*tps), GFP_KERNEL);
44730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	if (!tps)
44830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		return -ENOMEM;
44930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
45090923351d480fffd0d24646db83f6f8315eed0d9Mark Brown	tps->regmap = regmap_init_i2c(client, &tps65023_regmap_config);
45190923351d480fffd0d24646db83f6f8315eed0d9Mark Brown	if (IS_ERR(tps->regmap)) {
45290923351d480fffd0d24646db83f6f8315eed0d9Mark Brown		error = PTR_ERR(tps->regmap);
45390923351d480fffd0d24646db83f6f8315eed0d9Mark Brown		dev_err(&client->dev, "Failed to allocate register map: %d\n",
45490923351d480fffd0d24646db83f6f8315eed0d9Mark Brown			error);
45590923351d480fffd0d24646db83f6f8315eed0d9Mark Brown		goto fail_alloc;
45690923351d480fffd0d24646db83f6f8315eed0d9Mark Brown	}
45730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
45830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	/* common for all regulators */
45930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	tps->client = client;
4601c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	tps->core_regulator = drv_data->core_regulator;
46130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
46230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	for (i = 0; i < TPS65023_NUM_REGULATOR; i++, info++, init_data++) {
46330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		/* Store regulator specific information */
46430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		tps->info[i] = info;
46530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
46630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		tps->desc[i].name = info->name;
46777fa44d0e10711e899788c58fe53f8f7b18c7f67Axel Lin		tps->desc[i].id = i;
4681c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		tps->desc[i].n_voltages = info->table_len;
46930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		tps->desc[i].ops = (i > TPS65023_DCDC_3 ?
47030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal					&tps65023_ldo_ops : &tps65023_dcdc_ops);
47130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		tps->desc[i].type = REGULATOR_VOLTAGE;
47230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		tps->desc[i].owner = THIS_MODULE;
47330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
47430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		/* Register the regulators */
47530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		rdev = regulator_register(&tps->desc[i], &client->dev,
47654d13ab1038911249fc5769efee87fed000623c0Dmitry Torokhov					  init_data, tps);
47730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		if (IS_ERR(rdev)) {
47830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal			dev_err(&client->dev, "failed to register %s\n",
47930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal				id->name);
48054d13ab1038911249fc5769efee87fed000623c0Dmitry Torokhov			error = PTR_ERR(rdev);
48154d13ab1038911249fc5769efee87fed000623c0Dmitry Torokhov			goto fail;
48230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		}
48330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
48430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		/* Save regulator for cleanup */
48530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		tps->rdev[i] = rdev;
48630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	}
48730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
48830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	i2c_set_clientdata(client, tps);
48930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
490fc999b83799074832367d3cfd724c341c849a7daMarcus Folkesson	/* Enable setting output voltage by I2C */
49143530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
49243530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi			TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ);
493fc999b83799074832367d3cfd724c341c849a7daMarcus Folkesson
494f068ad8cca7532bc42115d61489de00fe57c3909Marcus Folkesson	/* Enable setting output voltage by I2C */
49543530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi	regmap_update_bits(tps->regmap, TPS65023_REG_CON_CTRL2,
49643530b69d758328d3ffe6ab98fd640463e8e3667Jonghwan Choi			TPS65023_REG_CTRL2_CORE_ADJ, TPS65023_REG_CTRL2_CORE_ADJ);
497f068ad8cca7532bc42115d61489de00fe57c3909Marcus Folkesson
49830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	return 0;
49954d13ab1038911249fc5769efee87fed000623c0Dmitry Torokhov
50054d13ab1038911249fc5769efee87fed000623c0Dmitry Torokhov fail:
50154d13ab1038911249fc5769efee87fed000623c0Dmitry Torokhov	while (--i >= 0)
50254d13ab1038911249fc5769efee87fed000623c0Dmitry Torokhov		regulator_unregister(tps->rdev[i]);
50354d13ab1038911249fc5769efee87fed000623c0Dmitry Torokhov
50490923351d480fffd0d24646db83f6f8315eed0d9Mark Brown	regmap_exit(tps->regmap);
50590923351d480fffd0d24646db83f6f8315eed0d9Mark Brown fail_alloc:
50654d13ab1038911249fc5769efee87fed000623c0Dmitry Torokhov	kfree(tps);
50754d13ab1038911249fc5769efee87fed000623c0Dmitry Torokhov	return error;
50830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
50930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
51030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/**
51130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * tps_65023_remove - TPS65023 driver i2c remove handler
51230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * @client: i2c driver client device structure
51330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal *
51430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * Unregister TPS driver as an i2c client device driver
51530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal */
51630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int __devexit tps_65023_remove(struct i2c_client *client)
51730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
51830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	struct tps_pmic *tps = i2c_get_clientdata(client);
51930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	int i;
52030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
52130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	for (i = 0; i < TPS65023_NUM_REGULATOR; i++)
52230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		regulator_unregister(tps->rdev[i]);
52330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
52490923351d480fffd0d24646db83f6f8315eed0d9Mark Brown	regmap_exit(tps->regmap);
52530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	kfree(tps);
52630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
52730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	return 0;
52830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
52930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
530437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkessonstatic const struct tps_info tps65020_regs[] = {
531437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	{
532437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.name = "VDCDC1",
533437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.min_uV = 3300000,
534437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.max_uV = 3300000,
535437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.fixed	= 1,
536437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	},
537437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	{
538437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.name = "VDCDC2",
539437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.min_uV =  1800000,
540437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.max_uV = 1800000,
541437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.fixed = 1,
542437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	},
543437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	{
544437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.name = "VDCDC3",
545437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.min_uV =  800000,
546437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.max_uV = 1600000,
547437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.table_len = ARRAY_SIZE(VCORE_VSEL_table),
548437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.table = VCORE_VSEL_table,
549437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	},
550437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson
551437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	{
552437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.name = "LDO1",
553437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.min_uV = 1000000,
554437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.max_uV = 3150000,
555437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.table_len = ARRAY_SIZE(TPS65020_LDO1_VSEL_table),
556437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.table = TPS65020_LDO1_VSEL_table,
557437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	},
558437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	{
559437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.name = "LDO2",
560437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.min_uV = 1050000,
561437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.max_uV = 3300000,
562437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.table_len = ARRAY_SIZE(TPS65020_LDO2_VSEL_table),
563437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson		.table = TPS65020_LDO2_VSEL_table,
564437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	},
565437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson};
566437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson
5671c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkessonstatic const struct tps_info tps65021_regs[] = {
5681c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	{
5691c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.name = "VDCDC1",
5701c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.min_uV =  3300000,
5711c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.max_uV = 3300000,
5721c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.fixed = 1,
5731c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	},
5741c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	{
5751c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.name = "VDCDC2",
5761c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.min_uV =  1800000,
5771c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.max_uV = 1800000,
5781c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.fixed = 1,
5791c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	},
5801c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	{
5811c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.name = "VDCDC3",
5821c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.min_uV =  800000,
5831c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.max_uV = 1600000,
5841c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.table_len = ARRAY_SIZE(VCORE_VSEL_table),
5851c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.table = VCORE_VSEL_table,
5861c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	},
5871c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	{
5881c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.name = "LDO1",
5891c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.min_uV = 1000000,
5901c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.max_uV = 3150000,
5911c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table),
5921c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.table = TPS65023_LDO1_VSEL_table,
5931c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	},
5941c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	{
5951c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.name = "LDO2",
5961c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.min_uV = 1050000,
5971c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.max_uV = 3300000,
5981c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table),
5991c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.table = TPS65023_LDO2_VSEL_table,
6001c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	},
6011c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson};
6021c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson
60330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic const struct tps_info tps65023_regs[] = {
60430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	{
60530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.name = "VDCDC1",
60630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.min_uV =  800000,
60730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.max_uV = 1600000,
6081c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.table_len = ARRAY_SIZE(VCORE_VSEL_table),
6091c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.table = VCORE_VSEL_table,
61030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	},
61130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	{
61230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.name = "VDCDC2",
61330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.min_uV =  3300000,
61430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.max_uV = 3300000,
61530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.fixed = 1,
61630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	},
61730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	{
61830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.name = "VDCDC3",
61930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.min_uV =  1800000,
62030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.max_uV = 1800000,
62130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.fixed = 1,
62230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	},
62330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	{
62430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.name = "LDO1",
62530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.min_uV = 1000000,
62630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.max_uV = 3150000,
6271c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.table_len = ARRAY_SIZE(TPS65023_LDO1_VSEL_table),
6281c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.table = TPS65023_LDO1_VSEL_table,
62930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	},
63030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	{
63130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.name = "LDO2",
63230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.min_uV = 1050000,
63330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.max_uV = 3300000,
6341c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.table_len = ARRAY_SIZE(TPS65023_LDO2_VSEL_table),
6351c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.table = TPS65023_LDO2_VSEL_table,
63630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	},
63730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal};
63830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
639437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkessonstatic struct tps_driver_data tps65020_drv_data = {
640437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	.info = tps65020_regs,
641437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	.core_regulator = TPS65023_DCDC_3,
642437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson};
643437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson
6441c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkessonstatic struct tps_driver_data tps65021_drv_data = {
6451c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.info = tps65021_regs,
6461c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.core_regulator = TPS65023_DCDC_3,
6471c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson};
6481c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson
6491c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkessonstatic struct tps_driver_data tps65023_drv_data = {
6501c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.info = tps65023_regs,
6511c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson		.core_regulator = TPS65023_DCDC_1,
6521c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson};
6531c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson
6549e108d33edcb88bac3db39ba1683fc2c0591d7d4Liam Girdwoodstatic const struct i2c_device_id tps_65023_id[] = {
6559e108d33edcb88bac3db39ba1683fc2c0591d7d4Liam Girdwood	{.name = "tps65023",
6561c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	.driver_data = (unsigned long) &tps65023_drv_data},
6571880a2fc59d2afabc142a311497cf7c320d64506Marek Vasut	{.name = "tps65021",
6581c3ede05d123f1484b28fa7c8500a1a29e34e3baMarcus Folkesson	.driver_data = (unsigned long) &tps65021_drv_data,},
659437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	{.name = "tps65020",
660437afd2ad6ba252fdbad9a1ad2610992fea55bd6Marcus Folkesson	.driver_data = (unsigned long) &tps65020_drv_data},
6619e108d33edcb88bac3db39ba1683fc2c0591d7d4Liam Girdwood	{ },
66230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal};
66330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
66430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj AggarwalMODULE_DEVICE_TABLE(i2c, tps_65023_id);
66530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
66630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic struct i2c_driver tps_65023_i2c_driver = {
66730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.driver = {
66830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.name = "tps65023",
66930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal		.owner = THIS_MODULE,
67030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	},
67130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.probe = tps_65023_probe,
67230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	.remove = __devexit_p(tps_65023_remove),
6739e108d33edcb88bac3db39ba1683fc2c0591d7d4Liam Girdwood	.id_table = tps_65023_id,
67430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal};
67530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
67630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/**
67730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * tps_65023_init
67830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal *
67930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * Module init function
68030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal */
68130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic int __init tps_65023_init(void)
68230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
68330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	return i2c_add_driver(&tps_65023_i2c_driver);
68430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
68530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalsubsys_initcall(tps_65023_init);
68630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
68730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal/**
68830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * tps_65023_cleanup
68930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal *
69030e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal * Module exit function
69130e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal */
69230e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalstatic void __exit tps_65023_cleanup(void)
69330e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal{
69430e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal	i2c_del_driver(&tps_65023_i2c_driver);
69530e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal}
69630e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwalmodule_exit(tps_65023_cleanup);
69730e6599d317ec83c664f341f18b5b2b57b831a6dAnuj Aggarwal
69830e6599d317ec83c664f341f18b5b2b57b831a6dAnuj AggarwalMODULE_AUTHOR("Texas Instruments");
69930e6599d317ec83c664f341f18b5b2b57b831a6dAnuj AggarwalMODULE_DESCRIPTION("TPS65023 voltage regulator driver");
7009e108d33edcb88bac3db39ba1683fc2c0591d7d4Liam GirdwoodMODULE_LICENSE("GPL v2");
701