aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/palmas-regulator.c822
1 files changed, 822 insertions, 0 deletions
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
new file mode 100644
index 000000000000..c4435f608df7
--- /dev/null
+++ b/drivers/regulator/palmas-regulator.c
@@ -0,0 +1,822 @@
1/*
2 * Driver for Regulator part of Palmas PMIC Chips
3 *
4 * Copyright 2011-2012 Texas Instruments Inc.
5 *
6 * Author: Graeme Gregory <gg@slimlogic.co.uk>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/err.h>
19#include <linux/platform_device.h>
20#include <linux/regulator/driver.h>
21#include <linux/regulator/machine.h>
22#include <linux/slab.h>
23#include <linux/regmap.h>
24#include <linux/mfd/palmas.h>
25
26struct regs_info {
27 char *name;
28 u8 vsel_addr;
29 u8 ctrl_addr;
30 u8 tstep_addr;
31};
32
33static const struct regs_info palmas_regs_info[] = {
34 {
35 .name = "SMPS12",
36 .vsel_addr = PALMAS_SMPS12_VOLTAGE,
37 .ctrl_addr = PALMAS_SMPS12_CTRL,
38 .tstep_addr = PALMAS_SMPS12_TSTEP,
39 },
40 {
41 .name = "SMPS123",
42 .vsel_addr = PALMAS_SMPS12_VOLTAGE,
43 .ctrl_addr = PALMAS_SMPS12_CTRL,
44 .tstep_addr = PALMAS_SMPS12_TSTEP,
45 },
46 {
47 .name = "SMPS3",
48 .vsel_addr = PALMAS_SMPS3_VOLTAGE,
49 .ctrl_addr = PALMAS_SMPS3_CTRL,
50 },
51 {
52 .name = "SMPS45",
53 .vsel_addr = PALMAS_SMPS45_VOLTAGE,
54 .ctrl_addr = PALMAS_SMPS45_CTRL,
55 .tstep_addr = PALMAS_SMPS45_TSTEP,
56 },
57 {
58 .name = "SMPS457",
59 .vsel_addr = PALMAS_SMPS45_VOLTAGE,
60 .ctrl_addr = PALMAS_SMPS45_CTRL,
61 .tstep_addr = PALMAS_SMPS45_TSTEP,
62 },
63 {
64 .name = "SMPS6",
65 .vsel_addr = PALMAS_SMPS6_VOLTAGE,
66 .ctrl_addr = PALMAS_SMPS6_CTRL,
67 .tstep_addr = PALMAS_SMPS6_TSTEP,
68 },
69 {
70 .name = "SMPS7",
71 .vsel_addr = PALMAS_SMPS7_VOLTAGE,
72 .ctrl_addr = PALMAS_SMPS7_CTRL,
73 },
74 {
75 .name = "SMPS8",
76 .vsel_addr = PALMAS_SMPS8_VOLTAGE,
77 .ctrl_addr = PALMAS_SMPS8_CTRL,
78 .tstep_addr = PALMAS_SMPS8_TSTEP,
79 },
80 {
81 .name = "SMPS9",
82 .vsel_addr = PALMAS_SMPS9_VOLTAGE,
83 .ctrl_addr = PALMAS_SMPS9_CTRL,
84 },
85 {
86 .name = "SMPS10",
87 },
88 {
89 .name = "LDO1",
90 .vsel_addr = PALMAS_LDO1_VOLTAGE,
91 .ctrl_addr = PALMAS_LDO1_CTRL,
92 },
93 {
94 .name = "LDO2",
95 .vsel_addr = PALMAS_LDO2_VOLTAGE,
96 .ctrl_addr = PALMAS_LDO2_CTRL,
97 },
98 {
99 .name = "LDO3",
100 .vsel_addr = PALMAS_LDO3_VOLTAGE,
101 .ctrl_addr = PALMAS_LDO3_CTRL,
102 },
103 {
104 .name = "LDO4",
105 .vsel_addr = PALMAS_LDO4_VOLTAGE,
106 .ctrl_addr = PALMAS_LDO4_CTRL,
107 },
108 {
109 .name = "LDO5",
110 .vsel_addr = PALMAS_LDO5_VOLTAGE,
111 .ctrl_addr = PALMAS_LDO5_CTRL,
112 },
113 {
114 .name = "LDO6",
115 .vsel_addr = PALMAS_LDO6_VOLTAGE,
116 .ctrl_addr = PALMAS_LDO6_CTRL,
117 },
118 {
119 .name = "LDO7",
120 .vsel_addr = PALMAS_LDO7_VOLTAGE,
121 .ctrl_addr = PALMAS_LDO7_CTRL,
122 },
123 {
124 .name = "LDO8",
125 .vsel_addr = PALMAS_LDO8_VOLTAGE,
126 .ctrl_addr = PALMAS_LDO8_CTRL,
127 },
128 {
129 .name = "LDO9",
130 .vsel_addr = PALMAS_LDO9_VOLTAGE,
131 .ctrl_addr = PALMAS_LDO9_CTRL,
132 },
133 {
134 .name = "LDOLN",
135 .vsel_addr = PALMAS_LDOLN_VOLTAGE,
136 .ctrl_addr = PALMAS_LDOLN_CTRL,
137 },
138 {
139 .name = "LDOUSB",
140 .vsel_addr = PALMAS_LDOUSB_VOLTAGE,
141 .ctrl_addr = PALMAS_LDOUSB_CTRL,
142 },
143};
144
145#define SMPS_CTRL_MODE_OFF 0x00
146#define SMPS_CTRL_MODE_ON 0x01
147#define SMPS_CTRL_MODE_ECO 0x02
148#define SMPS_CTRL_MODE_PWM 0x03
149
150/* These values are derived from the data sheet. And are the number of steps
151 * where there is a voltage change, the ranges at beginning and end of register
152 * max/min values where there are no change are ommitted.
153 *
154 * So they are basically (maxV-minV)/stepV
155 */
156#define PALMAS_SMPS_NUM_VOLTAGES 116
157#define PALMAS_SMPS10_NUM_VOLTAGES 2
158#define PALMAS_LDO_NUM_VOLTAGES 50
159
160#define SMPS10_VSEL (1<<3)
161#define SMPS10_BOOST_EN (1<<2)
162#define SMPS10_BYPASS_EN (1<<1)
163#define SMPS10_SWITCH_EN (1<<0)
164
165#define REGULATOR_SLAVE 0
166
167static int palmas_smps_read(struct palmas *palmas, unsigned int reg,
168 unsigned int *dest)
169{
170 unsigned int addr;
171
172 addr = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, reg);
173
174 return regmap_read(palmas->regmap[REGULATOR_SLAVE], addr, dest);
175}
176
177static int palmas_smps_write(struct palmas *palmas, unsigned int reg,
178 unsigned int value)
179{
180 unsigned int addr;
181
182 addr = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, reg);
183
184 return regmap_write(palmas->regmap[REGULATOR_SLAVE], addr, value);
185}
186
187static int palmas_ldo_read(struct palmas *palmas, unsigned int reg,
188 unsigned int *dest)
189{
190 unsigned int addr;
191
192 addr = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, reg);
193
194 return regmap_read(palmas->regmap[REGULATOR_SLAVE], addr, dest);
195}
196
197static int palmas_ldo_write(struct palmas *palmas, unsigned int reg,