• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Hardware monitoring driver for Analog Devices ADM1275 Hot-Swap Controller
3  * and Digital Power Monitor
4  *
5  * Copyright (c) 2011 Ericsson AB.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  */
17 
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/err.h>
22 #include <linux/slab.h>
23 #include <linux/i2c.h>
24 #include "pmbus.h"
25 
26 enum chips { adm1075, adm1275, adm1276 };
27 
28 #define ADM1275_PEAK_IOUT		0xd0
29 #define ADM1275_PEAK_VIN		0xd1
30 #define ADM1275_PEAK_VOUT		0xd2
31 #define ADM1275_PMON_CONFIG		0xd4
32 
33 #define ADM1275_VIN_VOUT_SELECT		(1 << 6)
34 #define ADM1275_VRANGE			(1 << 5)
35 #define ADM1075_IRANGE_50		(1 << 4)
36 #define ADM1075_IRANGE_25		(1 << 3)
37 #define ADM1075_IRANGE_MASK		((1 << 3) | (1 << 4))
38 
39 #define ADM1275_IOUT_WARN2_LIMIT	0xd7
40 #define ADM1275_DEVICE_CONFIG		0xd8
41 
42 #define ADM1275_IOUT_WARN2_SELECT	(1 << 4)
43 
44 #define ADM1276_PEAK_PIN		0xda
45 
46 #define ADM1275_MFR_STATUS_IOUT_WARN2	(1 << 0)
47 
48 #define ADM1075_READ_VAUX		0xdd
49 #define ADM1075_VAUX_OV_WARN_LIMIT	0xde
50 #define ADM1075_VAUX_UV_WARN_LIMIT	0xdf
51 #define ADM1075_VAUX_STATUS		0xf6
52 
53 #define ADM1075_VAUX_OV_WARN		(1<<7)
54 #define ADM1075_VAUX_UV_WARN		(1<<6)
55 
56 struct adm1275_data {
57 	int id;
58 	bool have_oc_fault;
59 	struct pmbus_driver_info info;
60 };
61 
62 #define to_adm1275_data(x)  container_of(x, struct adm1275_data, info)
63 
adm1275_read_word_data(struct i2c_client * client,int page,int reg)64 static int adm1275_read_word_data(struct i2c_client *client, int page, int reg)
65 {
66 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
67 	const struct adm1275_data *data = to_adm1275_data(info);
68 	int ret = 0;
69 
70 	if (page)
71 		return -ENXIO;
72 
73 	switch (reg) {
74 	case PMBUS_IOUT_UC_FAULT_LIMIT:
75 		if (data->have_oc_fault) {
76 			ret = -ENXIO;
77 			break;
78 		}
79 		ret = pmbus_read_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT);
80 		break;
81 	case PMBUS_IOUT_OC_FAULT_LIMIT:
82 		if (!data->have_oc_fault) {
83 			ret = -ENXIO;
84 			break;
85 		}
86 		ret = pmbus_read_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT);
87 		break;
88 	case PMBUS_VOUT_OV_WARN_LIMIT:
89 		if (data->id != adm1075) {
90 			ret = -ENODATA;
91 			break;
92 		}
93 		ret = pmbus_read_word_data(client, 0,
94 					   ADM1075_VAUX_OV_WARN_LIMIT);
95 		break;
96 	case PMBUS_VOUT_UV_WARN_LIMIT:
97 		if (data->id != adm1075) {
98 			ret = -ENODATA;
99 			break;
100 		}
101 		ret = pmbus_read_word_data(client, 0,
102 					   ADM1075_VAUX_UV_WARN_LIMIT);
103 		break;
104 	case PMBUS_READ_VOUT:
105 		if (data->id != adm1075) {
106 			ret = -ENODATA;
107 			break;
108 		}
109 		ret = pmbus_read_word_data(client, 0, ADM1075_READ_VAUX);
110 		break;
111 	case PMBUS_VIRT_READ_IOUT_MAX:
112 		ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_IOUT);
113 		break;
114 	case PMBUS_VIRT_READ_VOUT_MAX:
115 		ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VOUT);
116 		break;
117 	case PMBUS_VIRT_READ_VIN_MAX:
118 		ret = pmbus_read_word_data(client, 0, ADM1275_PEAK_VIN);
119 		break;
120 	case PMBUS_VIRT_READ_PIN_MAX:
121 		if (data->id == adm1275) {
122 			ret = -ENXIO;
123 			break;
124 		}
125 		ret = pmbus_read_word_data(client, 0, ADM1276_PEAK_PIN);
126 		break;
127 	case PMBUS_VIRT_RESET_IOUT_HISTORY:
128 	case PMBUS_VIRT_RESET_VOUT_HISTORY:
129 	case PMBUS_VIRT_RESET_VIN_HISTORY:
130 		break;
131 	case PMBUS_VIRT_RESET_PIN_HISTORY:
132 		if (data->id == adm1275)
133 			ret = -ENXIO;
134 		break;
135 	default:
136 		ret = -ENODATA;
137 		break;
138 	}
139 	return ret;
140 }
141 
adm1275_write_word_data(struct i2c_client * client,int page,int reg,u16 word)142 static int adm1275_write_word_data(struct i2c_client *client, int page, int reg,
143 				   u16 word)
144 {
145 	int ret;
146 
147 	if (page)
148 		return -ENXIO;
149 
150 	switch (reg) {
151 	case PMBUS_IOUT_UC_FAULT_LIMIT:
152 	case PMBUS_IOUT_OC_FAULT_LIMIT:
153 		ret = pmbus_write_word_data(client, 0, ADM1275_IOUT_WARN2_LIMIT,
154 					    word);
155 		break;
156 	case PMBUS_VIRT_RESET_IOUT_HISTORY:
157 		ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_IOUT, 0);
158 		break;
159 	case PMBUS_VIRT_RESET_VOUT_HISTORY:
160 		ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_VOUT, 0);
161 		break;
162 	case PMBUS_VIRT_RESET_VIN_HISTORY:
163 		ret = pmbus_write_word_data(client, 0, ADM1275_PEAK_VIN, 0);
164 		break;
165 	case PMBUS_VIRT_RESET_PIN_HISTORY:
166 		ret = pmbus_write_word_data(client, 0, ADM1276_PEAK_PIN, 0);
167 		break;
168 	default:
169 		ret = -ENODATA;
170 		break;
171 	}
172 	return ret;
173 }
174 
adm1275_read_byte_data(struct i2c_client * client,int page,int reg)175 static int adm1275_read_byte_data(struct i2c_client *client, int page, int reg)
176 {
177 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
178 	const struct adm1275_data *data = to_adm1275_data(info);
179 	int mfr_status, ret;
180 
181 	if (page > 0)
182 		return -ENXIO;
183 
184 	switch (reg) {
185 	case PMBUS_STATUS_IOUT:
186 		ret = pmbus_read_byte_data(client, page, PMBUS_STATUS_IOUT);
187 		if (ret < 0)
188 			break;
189 		mfr_status = pmbus_read_byte_data(client, page,
190 						  PMBUS_STATUS_MFR_SPECIFIC);
191 		if (mfr_status < 0) {
192 			ret = mfr_status;
193 			break;
194 		}
195 		if (mfr_status & ADM1275_MFR_STATUS_IOUT_WARN2) {
196 			ret |= data->have_oc_fault ?
197 			  PB_IOUT_OC_FAULT : PB_IOUT_UC_FAULT;
198 		}
199 		break;
200 	case PMBUS_STATUS_VOUT:
201 		if (data->id != adm1075) {
202 			ret = -ENODATA;
203 			break;
204 		}
205 		ret = 0;
206 		mfr_status = pmbus_read_byte_data(client, 0,
207 						  ADM1075_VAUX_STATUS);
208 		if (mfr_status & ADM1075_VAUX_OV_WARN)
209 			ret |= PB_VOLTAGE_OV_WARNING;
210 		if (mfr_status & ADM1075_VAUX_UV_WARN)
211 			ret |= PB_VOLTAGE_UV_WARNING;
212 		break;
213 	default:
214 		ret = -ENODATA;
215 		break;
216 	}
217 	return ret;
218 }
219 
220 static const struct i2c_device_id adm1275_id[] = {
221 	{ "adm1075", adm1075 },
222 	{ "adm1275", adm1275 },
223 	{ "adm1276", adm1276 },
224 	{ }
225 };
226 MODULE_DEVICE_TABLE(i2c, adm1275_id);
227 
adm1275_probe(struct i2c_client * client,const struct i2c_device_id * id)228 static int adm1275_probe(struct i2c_client *client,
229 			 const struct i2c_device_id *id)
230 {
231 	u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
232 	int config, device_config;
233 	int ret;
234 	struct pmbus_driver_info *info;
235 	struct adm1275_data *data;
236 	const struct i2c_device_id *mid;
237 
238 	if (!i2c_check_functionality(client->adapter,
239 				     I2C_FUNC_SMBUS_READ_BYTE_DATA
240 				     | I2C_FUNC_SMBUS_BLOCK_DATA))
241 		return -ENODEV;
242 
243 	ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, block_buffer);
244 	if (ret < 0) {
245 		dev_err(&client->dev, "Failed to read Manufacturer ID\n");
246 		return ret;
247 	}
248 	if (ret != 3 || strncmp(block_buffer, "ADI", 3)) {
249 		dev_err(&client->dev, "Unsupported Manufacturer ID\n");
250 		return -ENODEV;
251 	}
252 
253 	ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, block_buffer);
254 	if (ret < 0) {
255 		dev_err(&client->dev, "Failed to read Manufacturer Model\n");
256 		return ret;
257 	}
258 	for (mid = adm1275_id; mid->name[0]; mid++) {
259 		if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
260 			break;
261 	}
262 	if (!mid->name[0]) {
263 		dev_err(&client->dev, "Unsupported device\n");
264 		return -ENODEV;
265 	}
266 
267 	if (id->driver_data != mid->driver_data)
268 		dev_notice(&client->dev,
269 			   "Device mismatch: Configured %s, detected %s\n",
270 			   id->name, mid->name);
271 
272 	config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG);
273 	if (config < 0)
274 		return config;
275 
276 	device_config = i2c_smbus_read_byte_data(client, ADM1275_DEVICE_CONFIG);
277 	if (device_config < 0)
278 		return device_config;
279 
280 	data = devm_kzalloc(&client->dev, sizeof(struct adm1275_data),
281 			    GFP_KERNEL);
282 	if (!data)
283 		return -ENOMEM;
284 
285 	data->id = mid->driver_data;
286 
287 	info = &data->info;
288 
289 	info->pages = 1;
290 	info->format[PSC_VOLTAGE_IN] = direct;
291 	info->format[PSC_VOLTAGE_OUT] = direct;
292 	info->format[PSC_CURRENT_OUT] = direct;
293 	info->m[PSC_CURRENT_OUT] = 807;
294 	info->b[PSC_CURRENT_OUT] = 20475;
295 	info->R[PSC_CURRENT_OUT] = -1;
296 	info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
297 
298 	info->read_word_data = adm1275_read_word_data;
299 	info->read_byte_data = adm1275_read_byte_data;
300 	info->write_word_data = adm1275_write_word_data;
301 
302 	if (data->id == adm1075) {
303 		info->m[PSC_VOLTAGE_IN] = 27169;
304 		info->b[PSC_VOLTAGE_IN] = 0;
305 		info->R[PSC_VOLTAGE_IN] = -1;
306 		info->m[PSC_VOLTAGE_OUT] = 27169;
307 		info->b[PSC_VOLTAGE_OUT] = 0;
308 		info->R[PSC_VOLTAGE_OUT] = -1;
309 	} else if (config & ADM1275_VRANGE) {
310 		info->m[PSC_VOLTAGE_IN] = 19199;
311 		info->b[PSC_VOLTAGE_IN] = 0;
312 		info->R[PSC_VOLTAGE_IN] = -2;
313 		info->m[PSC_VOLTAGE_OUT] = 19199;
314 		info->b[PSC_VOLTAGE_OUT] = 0;
315 		info->R[PSC_VOLTAGE_OUT] = -2;
316 	} else {
317 		info->m[PSC_VOLTAGE_IN] = 6720;
318 		info->b[PSC_VOLTAGE_IN] = 0;
319 		info->R[PSC_VOLTAGE_IN] = -1;
320 		info->m[PSC_VOLTAGE_OUT] = 6720;
321 		info->b[PSC_VOLTAGE_OUT] = 0;
322 		info->R[PSC_VOLTAGE_OUT] = -1;
323 	}
324 
325 	if (device_config & ADM1275_IOUT_WARN2_SELECT)
326 		data->have_oc_fault = true;
327 
328 	switch (data->id) {
329 	case adm1075:
330 		info->format[PSC_POWER] = direct;
331 		info->b[PSC_POWER] = 0;
332 		info->R[PSC_POWER] = -1;
333 		switch (config & ADM1075_IRANGE_MASK) {
334 		case ADM1075_IRANGE_25:
335 			info->m[PSC_POWER] = 8549;
336 			info->m[PSC_CURRENT_OUT] = 806;
337 			break;
338 		case ADM1075_IRANGE_50:
339 			info->m[PSC_POWER] = 4279;
340 			info->m[PSC_CURRENT_OUT] = 404;
341 			break;
342 		default:
343 			dev_err(&client->dev, "Invalid input current range");
344 			info->m[PSC_POWER] = 0;
345 			info->m[PSC_CURRENT_OUT] = 0;
346 			break;
347 		}
348 		info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_PIN
349 		  | PMBUS_HAVE_STATUS_INPUT;
350 		if (config & ADM1275_VIN_VOUT_SELECT)
351 			info->func[0] |=
352 			  PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
353 		break;
354 	case adm1275:
355 		if (config & ADM1275_VIN_VOUT_SELECT)
356 			info->func[0] |=
357 			  PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
358 		else
359 			info->func[0] |=
360 			  PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT;
361 		break;
362 	case adm1276:
363 		info->format[PSC_POWER] = direct;
364 		info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_PIN
365 		  | PMBUS_HAVE_STATUS_INPUT;
366 		if (config & ADM1275_VIN_VOUT_SELECT)
367 			info->func[0] |=
368 			  PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
369 		if (config & ADM1275_VRANGE) {
370 			info->m[PSC_POWER] = 6043;
371 			info->b[PSC_POWER] = 0;
372 			info->R[PSC_POWER] = -2;
373 		} else {
374 			info->m[PSC_POWER] = 2115;
375 			info->b[PSC_POWER] = 0;
376 			info->R[PSC_POWER] = -1;
377 		}
378 		break;
379 	}
380 
381 	return pmbus_do_probe(client, id, info);
382 }
383 
384 static struct i2c_driver adm1275_driver = {
385 	.driver = {
386 		   .name = "adm1275",
387 		   },
388 	.probe = adm1275_probe,
389 	.remove = pmbus_do_remove,
390 	.id_table = adm1275_id,
391 };
392 
393 module_i2c_driver(adm1275_driver);
394 
395 MODULE_AUTHOR("Guenter Roeck");
396 MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275 and compatibles");
397 MODULE_LICENSE("GPL");
398