Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
hwmon
pmbus
lm25066.c
Go to the documentation of this file.
1
/*
2
* Hardware monitoring driver for LM25066 / LM5064 / LM5066
3
*
4
* Copyright (c) 2011 Ericsson AB.
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
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
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
*/
20
21
#include <linux/kernel.h>
22
#include <linux/module.h>
23
#include <
linux/init.h
>
24
#include <
linux/err.h
>
25
#include <linux/slab.h>
26
#include <linux/i2c.h>
27
#include "
pmbus.h
"
28
29
enum
chips
{
lm25066
,
lm5064
,
lm5066
};
30
31
#define LM25066_READ_VAUX 0xd0
32
#define LM25066_MFR_READ_IIN 0xd1
33
#define LM25066_MFR_READ_PIN 0xd2
34
#define LM25066_MFR_IIN_OC_WARN_LIMIT 0xd3
35
#define LM25066_MFR_PIN_OP_WARN_LIMIT 0xd4
36
#define LM25066_READ_PIN_PEAK 0xd5
37
#define LM25066_CLEAR_PIN_PEAK 0xd6
38
#define LM25066_DEVICE_SETUP 0xd9
39
#define LM25066_READ_AVG_VIN 0xdc
40
#define LM25066_READ_AVG_VOUT 0xdd
41
#define LM25066_READ_AVG_IIN 0xde
42
#define LM25066_READ_AVG_PIN 0xdf
43
44
#define LM25066_DEV_SETUP_CL (1 << 4)
/* Current limit */
45
46
struct
lm25066_data
{
47
int
id
;
48
struct
pmbus_driver_info
info
;
49
};
50
51
#define to_lm25066_data(x) container_of(x, struct lm25066_data, info)
52
53
static
int
lm25066_read_word_data(
struct
i2c_client
*
client
,
int
page
,
int
reg
)
54
{
55
const
struct
pmbus_driver_info
*
info
=
pmbus_get_driver_info
(client);
56
const
struct
lm25066_data
*
data
=
to_lm25066_data
(info);
57
int
ret
;
58
59
if
(page > 1)
60
return
-
ENXIO
;
61
62
/* Map READ_VAUX into READ_VOUT register on page 1 */
63
if
(page == 1) {
64
switch
(reg) {
65
case
PMBUS_READ_VOUT
:
66
ret =
pmbus_read_word_data
(client, 0,
67
LM25066_READ_VAUX
);
68
if
(ret < 0)
69
break
;
70
/* Adjust returned value to match VOUT coefficients */
71
switch
(data->
id
) {
72
case
lm25066
:
73
/* VOUT: 4.54 mV VAUX: 283.2 uV LSB */
74
ret =
DIV_ROUND_CLOSEST
(ret * 2832, 45400);
75
break
;
76
case
lm5064
:
77
/* VOUT: 4.53 mV VAUX: 700 uV LSB */
78
ret =
DIV_ROUND_CLOSEST
(ret * 70, 453);
79
break
;
80
case
lm5066
:
81
/* VOUT: 2.18 mV VAUX: 725 uV LSB */
82
ret =
DIV_ROUND_CLOSEST
(ret * 725, 2180);
83
break
;
84
}
85
break
;
86
default
:
87
/* No other valid registers on page 1 */
88
ret = -
ENXIO
;
89
break
;
90
}
91
goto
done
;
92
}
93
94
switch
(reg) {
95
case
PMBUS_READ_IIN
:
96
ret =
pmbus_read_word_data
(client, 0,
LM25066_MFR_READ_IIN
);
97
break
;
98
case
PMBUS_READ_PIN
:
99
ret =
pmbus_read_word_data
(client, 0,
LM25066_MFR_READ_PIN
);
100
break
;
101
case
PMBUS_IIN_OC_WARN_LIMIT
:
102
ret =
pmbus_read_word_data
(client, 0,
103
LM25066_MFR_IIN_OC_WARN_LIMIT
);
104
break
;
105
case
PMBUS_PIN_OP_WARN_LIMIT
:
106
ret =
pmbus_read_word_data
(client, 0,
107
LM25066_MFR_PIN_OP_WARN_LIMIT
);
108
break
;
109
case
PMBUS_VIRT_READ_VIN_AVG
:
110
ret =
pmbus_read_word_data
(client, 0,
LM25066_READ_AVG_VIN
);
111
break
;
112
case
PMBUS_VIRT_READ_VOUT_AVG
:
113
ret =
pmbus_read_word_data
(client, 0,
LM25066_READ_AVG_VOUT
);
114
break
;
115
case
PMBUS_VIRT_READ_IIN_AVG
:
116
ret =
pmbus_read_word_data
(client, 0,
LM25066_READ_AVG_IIN
);
117
break
;
118
case
PMBUS_VIRT_READ_PIN_AVG
:
119
ret =
pmbus_read_word_data
(client, 0,
LM25066_READ_AVG_PIN
);
120
break
;
121
case
PMBUS_VIRT_READ_PIN_MAX
:
122
ret =
pmbus_read_word_data
(client, 0,
LM25066_READ_PIN_PEAK
);
123
break
;
124
case
PMBUS_VIRT_RESET_PIN_HISTORY
:
125
ret = 0;
126
break
;
127
default
:
128
ret = -
ENODATA
;
129
break
;
130
}
131
done
:
132
return
ret
;
133
}
134
135
static
int
lm25066_write_word_data(
struct
i2c_client
*
client
,
int
page
,
int
reg
,
136
u16
word
)
137
{
138
int
ret
;
139
140
if
(page > 1)
141
return
-
ENXIO
;
142
143
switch
(reg) {
144
case
PMBUS_IIN_OC_WARN_LIMIT
:
145
ret =
pmbus_write_word_data
(client, 0,
146
LM25066_MFR_IIN_OC_WARN_LIMIT
,
147
word);
148
break
;
149
case
PMBUS_PIN_OP_WARN_LIMIT
:
150
ret =
pmbus_write_word_data
(client, 0,
151
LM25066_MFR_PIN_OP_WARN_LIMIT
,
152
word);
153
break
;
154
case
PMBUS_VIRT_RESET_PIN_HISTORY
:
155
ret =
pmbus_write_byte
(client, 0,
LM25066_CLEAR_PIN_PEAK
);
156
break
;
157
default
:
158
ret = -
ENODATA
;
159
break
;
160
}
161
return
ret
;
162
}
163
164
static
int
lm25066_write_byte(
struct
i2c_client
*client,
int
page,
u8
value
)
165
{
166
if
(page > 1)
167
return
-
ENXIO
;
168
169
if
(page <= 0)
170
return
pmbus_write_byte
(client, page, value);
171
172
return
0;
173
}
174
175
static
int
lm25066_probe(
struct
i2c_client
*client,
176
const
struct
i2c_device_id
*
id
)
177
{
178
int
config
;
179
struct
lm25066_data
*
data
;
180
struct
pmbus_driver_info
*
info
;
181
182
if
(!i2c_check_functionality(client->
adapter
,
183
I2C_FUNC_SMBUS_READ_BYTE_DATA
))
184
return
-
ENODEV
;
185
186
data =
devm_kzalloc
(&client->
dev
,
sizeof
(
struct
lm25066_data
),
187
GFP_KERNEL
);
188
if
(!data)
189
return
-
ENOMEM
;
190
191
config =
i2c_smbus_read_byte_data
(client,
LM25066_DEVICE_SETUP
);
192
if
(config < 0)
193
return
config
;
194
195
data->
id
=
id
->driver_data;
196
info = &data->
info
;
197
198
info->
pages
= 2;
199
info->
format
[
PSC_VOLTAGE_IN
] =
direct
;
200
info->
format
[
PSC_VOLTAGE_OUT
] =
direct
;
201
info->
format
[
PSC_CURRENT_IN
] =
direct
;
202
info->
format
[
PSC_TEMPERATURE
] =
direct
;
203
info->
format
[
PSC_POWER
] =
direct
;
204
205
info->
m
[
PSC_TEMPERATURE
] = 16;
206
info->
b
[
PSC_TEMPERATURE
] = 0;
207
info->
R
[
PSC_TEMPERATURE
] = 0;
208
209
info->
func
[0] =
PMBUS_HAVE_VIN
|
PMBUS_HAVE_VOUT
210
|
PMBUS_HAVE_STATUS_VOUT
|
PMBUS_HAVE_PIN
|
PMBUS_HAVE_IIN
211
|
PMBUS_HAVE_STATUS_INPUT
|
PMBUS_HAVE_TEMP
|
PMBUS_HAVE_STATUS_TEMP
;
212
info->
func
[1] =
PMBUS_HAVE_VOUT
;
213
214
info->
read_word_data
= lm25066_read_word_data;
215
info->
write_word_data
= lm25066_write_word_data;
216
info->
write_byte
= lm25066_write_byte;
217
218
switch
(id->driver_data) {
219
case
lm25066
:
220
info->
m
[
PSC_VOLTAGE_IN
] = 22070;
221
info->
b
[
PSC_VOLTAGE_IN
] = 0;
222
info->
R
[
PSC_VOLTAGE_IN
] = -2;
223
info->
m
[
PSC_VOLTAGE_OUT
] = 22070;
224
info->
b
[
PSC_VOLTAGE_OUT
] = 0;
225
info->
R
[
PSC_VOLTAGE_OUT
] = -2;
226
227
if
(config &
LM25066_DEV_SETUP_CL
) {
228
info->
m
[
PSC_CURRENT_IN
] = 6852;
229
info->
b
[
PSC_CURRENT_IN
] = 0;
230
info->
R
[
PSC_CURRENT_IN
] = -2;
231
info->
m
[
PSC_POWER
] = 369;
232
info->
b
[
PSC_POWER
] = 0;
233
info->
R
[
PSC_POWER
] = -2;
234
}
else
{
235
info->
m
[
PSC_CURRENT_IN
] = 13661;
236
info->
b
[
PSC_CURRENT_IN
] = 0;
237
info->
R
[
PSC_CURRENT_IN
] = -2;
238
info->
m
[
PSC_POWER
] = 736;
239
info->
b
[
PSC_POWER
] = 0;
240
info->
R
[
PSC_POWER
] = -2;
241
}
242
break
;
243
case
lm5064
:
244
info->
m
[
PSC_VOLTAGE_IN
] = 22075;
245
info->
b
[
PSC_VOLTAGE_IN
] = 0;
246
info->
R
[
PSC_VOLTAGE_IN
] = -2;
247
info->
m
[
PSC_VOLTAGE_OUT
] = 22075;
248
info->
b
[
PSC_VOLTAGE_OUT
] = 0;
249
info->
R
[
PSC_VOLTAGE_OUT
] = -2;
250
251
if
(config & LM25066_DEV_SETUP_CL) {
252
info->
m
[
PSC_CURRENT_IN
] = 6713;
253
info->
b
[
PSC_CURRENT_IN
] = 0;
254
info->
R
[
PSC_CURRENT_IN
] = -2;
255
info->
m
[
PSC_POWER
] = 3619;
256
info->
b
[
PSC_POWER
] = 0;
257
info->
R
[
PSC_POWER
] = -3;
258
}
else
{
259
info->
m
[
PSC_CURRENT_IN
] = 13426;
260
info->
b
[
PSC_CURRENT_IN
] = 0;
261
info->
R
[
PSC_CURRENT_IN
] = -2;
262
info->
m
[
PSC_POWER
] = 7238;
263
info->
b
[
PSC_POWER
] = 0;
264
info->
R
[
PSC_POWER
] = -3;
265
}
266
break
;
267
case
lm5066
:
268
info->
m
[
PSC_VOLTAGE_IN
] = 4587;
269
info->
b
[
PSC_VOLTAGE_IN
] = 0;
270
info->
R
[
PSC_VOLTAGE_IN
] = -2;
271
info->
m
[
PSC_VOLTAGE_OUT
] = 4587;
272
info->
b
[
PSC_VOLTAGE_OUT
] = 0;
273
info->
R
[
PSC_VOLTAGE_OUT
] = -2;
274
275
if
(config & LM25066_DEV_SETUP_CL) {
276
info->
m
[
PSC_CURRENT_IN
] = 10753;
277
info->
b
[
PSC_CURRENT_IN
] = 0;
278
info->
R
[
PSC_CURRENT_IN
] = -2;
279
info->
m
[
PSC_POWER
] = 1204;
280
info->
b
[
PSC_POWER
] = 0;
281
info->
R
[
PSC_POWER
] = -3;
282
}
else
{
283
info->
m
[
PSC_CURRENT_IN
] = 5405;
284
info->
b
[
PSC_CURRENT_IN
] = 0;
285
info->
R
[
PSC_CURRENT_IN
] = -2;
286
info->
m
[
PSC_POWER
] = 605;
287
info->
b
[
PSC_POWER
] = 0;
288
info->
R
[
PSC_POWER
] = -3;
289
}
290
break
;
291
default
:
292
return
-
ENODEV
;
293
}
294
295
return
pmbus_do_probe
(client,
id
, info);
296
}
297
298
static
const
struct
i2c_device_id
lm25066_id[] = {
299
{
"lm25066"
,
lm25066
},
300
{
"lm5064"
,
lm5064
},
301
{
"lm5066"
,
lm5066
},
302
{ }
303
};
304
305
MODULE_DEVICE_TABLE
(i2c, lm25066_id);
306
307
/* This is the driver that will be inserted */
308
static
struct
i2c_driver
lm25066_driver = {
309
.driver = {
310
.name =
"lm25066"
,
311
},
312
.probe = lm25066_probe,
313
.remove =
pmbus_do_remove
,
314
.id_table = lm25066_id,
315
};
316
317
module_i2c_driver
(lm25066_driver);
318
319
MODULE_AUTHOR
(
"Guenter Roeck"
);
320
MODULE_DESCRIPTION
(
"PMBus driver for LM25066/LM5064/LM5066"
);
321
MODULE_LICENSE
(
"GPL"
);
Generated on Thu Jan 10 2013 13:35:09 for Linux Kernel by
1.8.2