Merge tag 'v3.8-rc1' into staging/for_v3.9
[deliverable/linux.git] / arch / arm / mach-msm / vreg.c
CommitLineData
f030d7b6
BS
1/* arch/arm/mach-msm/vreg.c
2 *
3 * Copyright (C) 2008 Google, Inc.
4783de9b 4 * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
f030d7b6
BS
5 * Author: Brian Swetland <swetland@google.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/kernel.h>
19#include <linux/device.h>
20#include <linux/init.h>
21#include <linux/debugfs.h>
5e1a0f9f 22#include <linux/module.h>
0e44106d 23#include <linux/string.h>
f030d7b6
BS
24#include <mach/vreg.h>
25
26#include "proc_comm.h"
27
28struct vreg {
29 const char *name;
30 unsigned id;
4783de9b 31 int status;
0e44106d 32 unsigned refcnt;
f030d7b6
BS
33};
34
0e44106d
MW
35#define VREG(_name, _id, _status, _refcnt) \
36 { .name = _name, .id = _id, .status = _status, .refcnt = _refcnt }
f030d7b6
BS
37
38static struct vreg vregs[] = {
0e44106d
MW
39 VREG("msma", 0, 0, 0),
40 VREG("msmp", 1, 0, 0),
41 VREG("msme1", 2, 0, 0),
42 VREG("msmc1", 3, 0, 0),
43 VREG("msmc2", 4, 0, 0),
44 VREG("gp3", 5, 0, 0),
45 VREG("msme2", 6, 0, 0),
46 VREG("gp4", 7, 0, 0),
47 VREG("gp1", 8, 0, 0),
48 VREG("tcxo", 9, 0, 0),
49 VREG("pa", 10, 0, 0),
50 VREG("rftx", 11, 0, 0),
51 VREG("rfrx1", 12, 0, 0),
52 VREG("rfrx2", 13, 0, 0),
53 VREG("synt", 14, 0, 0),
54 VREG("wlan", 15, 0, 0),
55 VREG("usb", 16, 0, 0),
56 VREG("boost", 17, 0, 0),
57 VREG("mmc", 18, 0, 0),
58 VREG("ruim", 19, 0, 0),
59 VREG("msmc0", 20, 0, 0),
60 VREG("gp2", 21, 0, 0),
61 VREG("gp5", 22, 0, 0),
62 VREG("gp6", 23, 0, 0),
63 VREG("rf", 24, 0, 0),
64 VREG("rf_vco", 26, 0, 0),
65 VREG("mpll", 27, 0, 0),
66 VREG("s2", 28, 0, 0),
67 VREG("s3", 29, 0, 0),
68 VREG("rfubm", 30, 0, 0),
69 VREG("ncp", 31, 0, 0),
1b70de32
WR
70 VREG("gp7", 32, 0, 0),
71 VREG("gp8", 33, 0, 0),
72 VREG("gp9", 34, 0, 0),
73 VREG("gp10", 35, 0, 0),
74 VREG("gp11", 36, 0, 0),
75 VREG("gp12", 37, 0, 0),
76 VREG("gp13", 38, 0, 0),
77 VREG("gp14", 39, 0, 0),
78 VREG("gp15", 40, 0, 0),
79 VREG("gp16", 41, 0, 0),
80 VREG("gp17", 42, 0, 0),
81 VREG("s4", 43, 0, 0),
82 VREG("usb2", 44, 0, 0),
83 VREG("wlan2", 45, 0, 0),
84 VREG("xo_out", 46, 0, 0),
85 VREG("lvsw0", 47, 0, 0),
86 VREG("lvsw1", 48, 0, 0),
f030d7b6
BS
87};
88
89struct vreg *vreg_get(struct device *dev, const char *id)
90{
91 int n;
92 for (n = 0; n < ARRAY_SIZE(vregs); n++) {
93 if (!strcmp(vregs[n].name, id))
94 return vregs + n;
95 }
0c50b444 96 return ERR_PTR(-ENOENT);
f030d7b6
BS
97}
98
99void vreg_put(struct vreg *vreg)
100{
101}
102
103int vreg_enable(struct vreg *vreg)
104{
105 unsigned id = vreg->id;
106 unsigned enable = 1;
4783de9b 107
0e44106d
MW
108 if (vreg->refcnt == 0)
109 vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
110
111 if ((vreg->refcnt < UINT_MAX) && (!vreg->status))
112 vreg->refcnt++;
113
4783de9b 114 return vreg->status;
f030d7b6
BS
115}
116
4783de9b 117int vreg_disable(struct vreg *vreg)
f030d7b6
BS
118{
119 unsigned id = vreg->id;
120 unsigned enable = 0;
4783de9b 121
0e44106d
MW
122 if (!vreg->refcnt)
123 return 0;
124
125 if (vreg->refcnt == 1)
126 vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
127
128 if (!vreg->status)
129 vreg->refcnt--;
130
4783de9b 131 return vreg->status;
f030d7b6
BS
132}
133
134int vreg_set_level(struct vreg *vreg, unsigned mv)
135{
136 unsigned id = vreg->id;
4783de9b
SM
137
138 vreg->status = msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
139 return vreg->status;
f030d7b6
BS
140}
141
142#if defined(CONFIG_DEBUG_FS)
143
144static int vreg_debug_set(void *data, u64 val)
145{
146 struct vreg *vreg = data;
147 switch (val) {
148 case 0:
149 vreg_disable(vreg);
150 break;
151 case 1:
152 vreg_enable(vreg);
153 break;
154 default:
155 vreg_set_level(vreg, val);
156 break;
157 }
158 return 0;
159}
160
161static int vreg_debug_get(void *data, u64 *val)
162{
4783de9b
SM
163 struct vreg *vreg = data;
164
165 if (!vreg->status)
166 *val = 0;
167 else
168 *val = 1;
169
170 return 0;
f030d7b6
BS
171}
172
0e44106d
MW
173static int vreg_debug_count_set(void *data, u64 val)
174{
175 struct vreg *vreg = data;
176 if (val > UINT_MAX)
177 val = UINT_MAX;
178 vreg->refcnt = val;
179 return 0;
180}
181
182static int vreg_debug_count_get(void *data, u64 *val)
183{
184 struct vreg *vreg = data;
185
186 *val = vreg->refcnt;
187
188 return 0;
189}
190
f030d7b6 191DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n");
0e44106d
MW
192DEFINE_SIMPLE_ATTRIBUTE(vreg_count_fops, vreg_debug_count_get,
193 vreg_debug_count_set, "%llu\n");
f030d7b6
BS
194
195static int __init vreg_debug_init(void)
196{
197 struct dentry *dent;
198 int n;
0e44106d
MW
199 char name[32];
200 const char *refcnt_name = "_refcnt";
f030d7b6
BS
201
202 dent = debugfs_create_dir("vreg", 0);
203 if (IS_ERR(dent))
204 return 0;
205
0e44106d 206 for (n = 0; n < ARRAY_SIZE(vregs); n++) {
f030d7b6
BS
207 (void) debugfs_create_file(vregs[n].name, 0644,
208 dent, vregs + n, &vreg_fops);
209
0e44106d
MW
210 strlcpy(name, vregs[n].name, sizeof(name));
211 strlcat(name, refcnt_name, sizeof(name));
212 (void) debugfs_create_file(name, 0644,
213 dent, vregs + n, &vreg_count_fops);
214 }
215
f030d7b6
BS
216 return 0;
217}
218
219device_initcall(vreg_debug_init);
220#endif
This page took 0.273697 seconds and 5 git commands to generate.