Linux Audio

Check our new training course

Loading...
v3.1
  1/*
  2 * Hardware monitoring driver for Maxim MAX34440/MAX34441
  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/i2c.h>
 26#include "pmbus.h"
 27
 28enum chips { max34440, max34441 };
 29
 30#define MAX34440_MFR_VOUT_PEAK		0xd4
 31#define MAX34440_MFR_IOUT_PEAK		0xd5
 32#define MAX34440_MFR_TEMPERATURE_PEAK	0xd6
 
 33
 34#define MAX34440_STATUS_OC_WARN		(1 << 0)
 35#define MAX34440_STATUS_OC_FAULT	(1 << 1)
 36#define MAX34440_STATUS_OT_FAULT	(1 << 5)
 37#define MAX34440_STATUS_OT_WARN		(1 << 6)
 
 
 
 
 
 
 
 
 
 
 
 
 38
 39static int max34440_read_word_data(struct i2c_client *client, int page, int reg)
 40{
 41	int ret;
 
 
 42
 43	switch (reg) {
 
 
 
 
 44	case PMBUS_VIRT_READ_VOUT_MAX:
 45		ret = pmbus_read_word_data(client, page,
 46					   MAX34440_MFR_VOUT_PEAK);
 47		break;
 
 
 
 
 
 
 48	case PMBUS_VIRT_READ_IOUT_MAX:
 49		ret = pmbus_read_word_data(client, page,
 50					   MAX34440_MFR_IOUT_PEAK);
 51		break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 52	case PMBUS_VIRT_READ_TEMP_MAX:
 53		ret = pmbus_read_word_data(client, page,
 54					   MAX34440_MFR_TEMPERATURE_PEAK);
 55		break;
 
 
 
 
 
 56	case PMBUS_VIRT_RESET_VOUT_HISTORY:
 57	case PMBUS_VIRT_RESET_IOUT_HISTORY:
 58	case PMBUS_VIRT_RESET_TEMP_HISTORY:
 59		ret = 0;
 60		break;
 61	default:
 62		ret = -ENODATA;
 63		break;
 64	}
 65	return ret;
 66}
 67
 68static int max34440_write_word_data(struct i2c_client *client, int page,
 69				    int reg, u16 word)
 70{
 
 
 71	int ret;
 72
 73	switch (reg) {
 
 
 
 
 
 
 
 
 74	case PMBUS_VIRT_RESET_VOUT_HISTORY:
 75		ret = pmbus_write_word_data(client, page,
 
 
 
 
 76					    MAX34440_MFR_VOUT_PEAK, 0);
 77		break;
 78	case PMBUS_VIRT_RESET_IOUT_HISTORY:
 79		ret = pmbus_write_word_data(client, page,
 80					    MAX34440_MFR_IOUT_PEAK, 0);
 
 
 
 
 81		break;
 82	case PMBUS_VIRT_RESET_TEMP_HISTORY:
 83		ret = pmbus_write_word_data(client, page,
 84					    MAX34440_MFR_TEMPERATURE_PEAK,
 85					    0xffff);
 
 
 
 86		break;
 87	default:
 88		ret = -ENODATA;
 89		break;
 90	}
 91	return ret;
 92}
 93
 94static int max34440_read_byte_data(struct i2c_client *client, int page, int reg)
 95{
 96	int ret;
 97	int mfg_status;
 98
 99	ret = pmbus_set_page(client, page);
100	if (ret < 0)
101		return ret;
 
 
102
103	switch (reg) {
104	case PMBUS_STATUS_IOUT:
105		mfg_status = pmbus_read_word_data(client, 0,
106						  PMBUS_STATUS_MFR_SPECIFIC);
107		if (mfg_status < 0)
108			return mfg_status;
109		if (mfg_status & MAX34440_STATUS_OC_WARN)
110			ret |= PB_IOUT_OC_WARNING;
111		if (mfg_status & MAX34440_STATUS_OC_FAULT)
112			ret |= PB_IOUT_OC_FAULT;
113		break;
114	case PMBUS_STATUS_TEMPERATURE:
115		mfg_status = pmbus_read_word_data(client, 0,
116						  PMBUS_STATUS_MFR_SPECIFIC);
117		if (mfg_status < 0)
118			return mfg_status;
119		if (mfg_status & MAX34440_STATUS_OT_WARN)
120			ret |= PB_TEMP_OT_WARNING;
121		if (mfg_status & MAX34440_STATUS_OT_FAULT)
122			ret |= PB_TEMP_OT_FAULT;
123		break;
124	default:
125		ret = -ENODATA;
126		break;
127	}
128	return ret;
129}
130
131static struct pmbus_driver_info max34440_info[] = {
132	[max34440] = {
133		.pages = 14,
134		.format[PSC_VOLTAGE_IN] = direct,
135		.format[PSC_VOLTAGE_OUT] = direct,
136		.format[PSC_TEMPERATURE] = direct,
137		.format[PSC_CURRENT_OUT] = direct,
138		.m[PSC_VOLTAGE_IN] = 1,
139		.b[PSC_VOLTAGE_IN] = 0,
140		.R[PSC_VOLTAGE_IN] = 3,	    /* R = 0 in datasheet reflects mV */
141		.m[PSC_VOLTAGE_OUT] = 1,
142		.b[PSC_VOLTAGE_OUT] = 0,
143		.R[PSC_VOLTAGE_OUT] = 3,    /* R = 0 in datasheet reflects mV */
144		.m[PSC_CURRENT_OUT] = 1,
145		.b[PSC_CURRENT_OUT] = 0,
146		.R[PSC_CURRENT_OUT] = 3,    /* R = 0 in datasheet reflects mA */
147		.m[PSC_TEMPERATURE] = 1,
148		.b[PSC_TEMPERATURE] = 0,
149		.R[PSC_TEMPERATURE] = 2,
150		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
151		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
152		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
153		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
154		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
155		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
156		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
157		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
158		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
159		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
160		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
161		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
162		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
163		.func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
164		.func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
165		.func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
166		.func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
167		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
168		.func[12] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
169		.func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
170		.read_byte_data = max34440_read_byte_data,
171		.read_word_data = max34440_read_word_data,
172		.write_word_data = max34440_write_word_data,
173	},
174	[max34441] = {
175		.pages = 12,
176		.format[PSC_VOLTAGE_IN] = direct,
177		.format[PSC_VOLTAGE_OUT] = direct,
178		.format[PSC_TEMPERATURE] = direct,
179		.format[PSC_CURRENT_OUT] = direct,
180		.format[PSC_FAN] = direct,
181		.m[PSC_VOLTAGE_IN] = 1,
182		.b[PSC_VOLTAGE_IN] = 0,
183		.R[PSC_VOLTAGE_IN] = 3,
184		.m[PSC_VOLTAGE_OUT] = 1,
185		.b[PSC_VOLTAGE_OUT] = 0,
186		.R[PSC_VOLTAGE_OUT] = 3,
187		.m[PSC_CURRENT_OUT] = 1,
188		.b[PSC_CURRENT_OUT] = 0,
189		.R[PSC_CURRENT_OUT] = 3,
190		.m[PSC_TEMPERATURE] = 1,
191		.b[PSC_TEMPERATURE] = 0,
192		.R[PSC_TEMPERATURE] = 2,
193		.m[PSC_FAN] = 1,
194		.b[PSC_FAN] = 0,
195		.R[PSC_FAN] = 0,
196		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
197		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
198		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
199		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
200		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
201		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
202		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
203		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
204		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
205		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
206		.func[5] = PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
207		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
208		.func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
209		.func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
210		.func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
211		.func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
212		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
213		.read_byte_data = max34440_read_byte_data,
214		.read_word_data = max34440_read_word_data,
215		.write_word_data = max34440_write_word_data,
216	},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217};
218
219static int max34440_probe(struct i2c_client *client,
220			  const struct i2c_device_id *id)
221{
222	return pmbus_do_probe(client, id, &max34440_info[id->driver_data]);
223}
224
225static int max34440_remove(struct i2c_client *client)
226{
227	return pmbus_do_remove(client);
 
 
 
 
 
228}
229
230static const struct i2c_device_id max34440_id[] = {
231	{"max34440", max34440},
232	{"max34441", max34441},
 
 
 
233	{}
234};
235
236MODULE_DEVICE_TABLE(i2c, max34440_id);
237
238/* This is the driver that will be inserted */
239static struct i2c_driver max34440_driver = {
240	.driver = {
241		   .name = "max34440",
242		   },
243	.probe = max34440_probe,
244	.remove = max34440_remove,
245	.id_table = max34440_id,
246};
247
248static int __init max34440_init(void)
249{
250	return i2c_add_driver(&max34440_driver);
251}
252
253static void __exit max34440_exit(void)
254{
255	i2c_del_driver(&max34440_driver);
256}
257
258MODULE_AUTHOR("Guenter Roeck");
259MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441");
260MODULE_LICENSE("GPL");
261module_init(max34440_init);
262module_exit(max34440_exit);
v4.17
  1/*
  2 * Hardware monitoring driver for Maxim MAX34440/MAX34441
  3 *
  4 * Copyright (c) 2011 Ericsson AB.
  5 * Copyright (c) 2012 Guenter Roeck
  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 * You should have received a copy of the GNU General Public License
 18 * along with this program; if not, write to the Free Software
 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20 */
 21
 22#include <linux/bitops.h>
 23#include <linux/kernel.h>
 24#include <linux/module.h>
 25#include <linux/init.h>
 26#include <linux/err.h>
 27#include <linux/i2c.h>
 28#include "pmbus.h"
 29
 30enum chips { max34440, max34441, max34446, max34460, max34461 };
 31
 32#define MAX34440_MFR_VOUT_PEAK		0xd4
 33#define MAX34440_MFR_IOUT_PEAK		0xd5
 34#define MAX34440_MFR_TEMPERATURE_PEAK	0xd6
 35#define MAX34440_MFR_VOUT_MIN		0xd7
 36
 37#define MAX34446_MFR_POUT_PEAK		0xe0
 38#define MAX34446_MFR_POUT_AVG		0xe1
 39#define MAX34446_MFR_IOUT_AVG		0xe2
 40#define MAX34446_MFR_TEMPERATURE_AVG	0xe3
 41
 42#define MAX34440_STATUS_OC_WARN		BIT(0)
 43#define MAX34440_STATUS_OC_FAULT	BIT(1)
 44#define MAX34440_STATUS_OT_FAULT	BIT(5)
 45#define MAX34440_STATUS_OT_WARN		BIT(6)
 46
 47struct max34440_data {
 48	int id;
 49	struct pmbus_driver_info info;
 50};
 51
 52#define to_max34440_data(x)  container_of(x, struct max34440_data, info)
 53
 54static int max34440_read_word_data(struct i2c_client *client, int page, int reg)
 55{
 56	int ret;
 57	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
 58	const struct max34440_data *data = to_max34440_data(info);
 59
 60	switch (reg) {
 61	case PMBUS_VIRT_READ_VOUT_MIN:
 62		ret = pmbus_read_word_data(client, page,
 63					   MAX34440_MFR_VOUT_MIN);
 64		break;
 65	case PMBUS_VIRT_READ_VOUT_MAX:
 66		ret = pmbus_read_word_data(client, page,
 67					   MAX34440_MFR_VOUT_PEAK);
 68		break;
 69	case PMBUS_VIRT_READ_IOUT_AVG:
 70		if (data->id != max34446)
 71			return -ENXIO;
 72		ret = pmbus_read_word_data(client, page,
 73					   MAX34446_MFR_IOUT_AVG);
 74		break;
 75	case PMBUS_VIRT_READ_IOUT_MAX:
 76		ret = pmbus_read_word_data(client, page,
 77					   MAX34440_MFR_IOUT_PEAK);
 78		break;
 79	case PMBUS_VIRT_READ_POUT_AVG:
 80		if (data->id != max34446)
 81			return -ENXIO;
 82		ret = pmbus_read_word_data(client, page,
 83					   MAX34446_MFR_POUT_AVG);
 84		break;
 85	case PMBUS_VIRT_READ_POUT_MAX:
 86		if (data->id != max34446)
 87			return -ENXIO;
 88		ret = pmbus_read_word_data(client, page,
 89					   MAX34446_MFR_POUT_PEAK);
 90		break;
 91	case PMBUS_VIRT_READ_TEMP_AVG:
 92		if (data->id != max34446 && data->id != max34460 &&
 93		    data->id != max34461)
 94			return -ENXIO;
 95		ret = pmbus_read_word_data(client, page,
 96					   MAX34446_MFR_TEMPERATURE_AVG);
 97		break;
 98	case PMBUS_VIRT_READ_TEMP_MAX:
 99		ret = pmbus_read_word_data(client, page,
100					   MAX34440_MFR_TEMPERATURE_PEAK);
101		break;
102	case PMBUS_VIRT_RESET_POUT_HISTORY:
103		if (data->id != max34446)
104			return -ENXIO;
105		ret = 0;
106		break;
107	case PMBUS_VIRT_RESET_VOUT_HISTORY:
108	case PMBUS_VIRT_RESET_IOUT_HISTORY:
109	case PMBUS_VIRT_RESET_TEMP_HISTORY:
110		ret = 0;
111		break;
112	default:
113		ret = -ENODATA;
114		break;
115	}
116	return ret;
117}
118
119static int max34440_write_word_data(struct i2c_client *client, int page,
120				    int reg, u16 word)
121{
122	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
123	const struct max34440_data *data = to_max34440_data(info);
124	int ret;
125
126	switch (reg) {
127	case PMBUS_VIRT_RESET_POUT_HISTORY:
128		ret = pmbus_write_word_data(client, page,
129					    MAX34446_MFR_POUT_PEAK, 0);
130		if (ret)
131			break;
132		ret = pmbus_write_word_data(client, page,
133					    MAX34446_MFR_POUT_AVG, 0);
134		break;
135	case PMBUS_VIRT_RESET_VOUT_HISTORY:
136		ret = pmbus_write_word_data(client, page,
137					    MAX34440_MFR_VOUT_MIN, 0x7fff);
138		if (ret)
139			break;
140		ret = pmbus_write_word_data(client, page,
141					    MAX34440_MFR_VOUT_PEAK, 0);
142		break;
143	case PMBUS_VIRT_RESET_IOUT_HISTORY:
144		ret = pmbus_write_word_data(client, page,
145					    MAX34440_MFR_IOUT_PEAK, 0);
146		if (!ret && data->id == max34446)
147			ret = pmbus_write_word_data(client, page,
148					MAX34446_MFR_IOUT_AVG, 0);
149
150		break;
151	case PMBUS_VIRT_RESET_TEMP_HISTORY:
152		ret = pmbus_write_word_data(client, page,
153					    MAX34440_MFR_TEMPERATURE_PEAK,
154					    0x8000);
155		if (!ret && data->id == max34446)
156			ret = pmbus_write_word_data(client, page,
157					MAX34446_MFR_TEMPERATURE_AVG, 0);
158		break;
159	default:
160		ret = -ENODATA;
161		break;
162	}
163	return ret;
164}
165
166static int max34440_read_byte_data(struct i2c_client *client, int page, int reg)
167{
168	int ret = 0;
169	int mfg_status;
170
171	if (page >= 0) {
172		ret = pmbus_set_page(client, page);
173		if (ret < 0)
174			return ret;
175	}
176
177	switch (reg) {
178	case PMBUS_STATUS_IOUT:
179		mfg_status = pmbus_read_word_data(client, 0,
180						  PMBUS_STATUS_MFR_SPECIFIC);
181		if (mfg_status < 0)
182			return mfg_status;
183		if (mfg_status & MAX34440_STATUS_OC_WARN)
184			ret |= PB_IOUT_OC_WARNING;
185		if (mfg_status & MAX34440_STATUS_OC_FAULT)
186			ret |= PB_IOUT_OC_FAULT;
187		break;
188	case PMBUS_STATUS_TEMPERATURE:
189		mfg_status = pmbus_read_word_data(client, 0,
190						  PMBUS_STATUS_MFR_SPECIFIC);
191		if (mfg_status < 0)
192			return mfg_status;
193		if (mfg_status & MAX34440_STATUS_OT_WARN)
194			ret |= PB_TEMP_OT_WARNING;
195		if (mfg_status & MAX34440_STATUS_OT_FAULT)
196			ret |= PB_TEMP_OT_FAULT;
197		break;
198	default:
199		ret = -ENODATA;
200		break;
201	}
202	return ret;
203}
204
205static struct pmbus_driver_info max34440_info[] = {
206	[max34440] = {
207		.pages = 14,
208		.format[PSC_VOLTAGE_IN] = direct,
209		.format[PSC_VOLTAGE_OUT] = direct,
210		.format[PSC_TEMPERATURE] = direct,
211		.format[PSC_CURRENT_OUT] = direct,
212		.m[PSC_VOLTAGE_IN] = 1,
213		.b[PSC_VOLTAGE_IN] = 0,
214		.R[PSC_VOLTAGE_IN] = 3,	    /* R = 0 in datasheet reflects mV */
215		.m[PSC_VOLTAGE_OUT] = 1,
216		.b[PSC_VOLTAGE_OUT] = 0,
217		.R[PSC_VOLTAGE_OUT] = 3,    /* R = 0 in datasheet reflects mV */
218		.m[PSC_CURRENT_OUT] = 1,
219		.b[PSC_CURRENT_OUT] = 0,
220		.R[PSC_CURRENT_OUT] = 3,    /* R = 0 in datasheet reflects mA */
221		.m[PSC_TEMPERATURE] = 1,
222		.b[PSC_TEMPERATURE] = 0,
223		.R[PSC_TEMPERATURE] = 2,
224		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
225		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
226		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
227		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
228		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
229		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
230		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
231		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
232		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
233		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
234		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
235		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
236		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
237		.func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
238		.func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
239		.func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
240		.func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
241		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
242		.func[12] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
243		.func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
244		.read_byte_data = max34440_read_byte_data,
245		.read_word_data = max34440_read_word_data,
246		.write_word_data = max34440_write_word_data,
247	},
248	[max34441] = {
249		.pages = 12,
250		.format[PSC_VOLTAGE_IN] = direct,
251		.format[PSC_VOLTAGE_OUT] = direct,
252		.format[PSC_TEMPERATURE] = direct,
253		.format[PSC_CURRENT_OUT] = direct,
254		.format[PSC_FAN] = direct,
255		.m[PSC_VOLTAGE_IN] = 1,
256		.b[PSC_VOLTAGE_IN] = 0,
257		.R[PSC_VOLTAGE_IN] = 3,
258		.m[PSC_VOLTAGE_OUT] = 1,
259		.b[PSC_VOLTAGE_OUT] = 0,
260		.R[PSC_VOLTAGE_OUT] = 3,
261		.m[PSC_CURRENT_OUT] = 1,
262		.b[PSC_CURRENT_OUT] = 0,
263		.R[PSC_CURRENT_OUT] = 3,
264		.m[PSC_TEMPERATURE] = 1,
265		.b[PSC_TEMPERATURE] = 0,
266		.R[PSC_TEMPERATURE] = 2,
267		.m[PSC_FAN] = 1,
268		.b[PSC_FAN] = 0,
269		.R[PSC_FAN] = 0,
270		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
271		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
272		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
273		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
274		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
275		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
276		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
277		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
278		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
279		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
280		.func[5] = PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
281		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
282		.func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
283		.func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
284		.func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
285		.func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
286		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
287		.read_byte_data = max34440_read_byte_data,
288		.read_word_data = max34440_read_word_data,
289		.write_word_data = max34440_write_word_data,
290	},
291	[max34446] = {
292		.pages = 7,
293		.format[PSC_VOLTAGE_IN] = direct,
294		.format[PSC_VOLTAGE_OUT] = direct,
295		.format[PSC_TEMPERATURE] = direct,
296		.format[PSC_CURRENT_OUT] = direct,
297		.format[PSC_POWER] = direct,
298		.m[PSC_VOLTAGE_IN] = 1,
299		.b[PSC_VOLTAGE_IN] = 0,
300		.R[PSC_VOLTAGE_IN] = 3,
301		.m[PSC_VOLTAGE_OUT] = 1,
302		.b[PSC_VOLTAGE_OUT] = 0,
303		.R[PSC_VOLTAGE_OUT] = 3,
304		.m[PSC_CURRENT_OUT] = 1,
305		.b[PSC_CURRENT_OUT] = 0,
306		.R[PSC_CURRENT_OUT] = 3,
307		.m[PSC_POWER] = 1,
308		.b[PSC_POWER] = 0,
309		.R[PSC_POWER] = 3,
310		.m[PSC_TEMPERATURE] = 1,
311		.b[PSC_TEMPERATURE] = 0,
312		.R[PSC_TEMPERATURE] = 2,
313		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
314		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
315		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
316		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
317		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
318		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
319		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
320		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
321		.func[4] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
322		.func[5] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
323		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
324		.read_byte_data = max34440_read_byte_data,
325		.read_word_data = max34440_read_word_data,
326		.write_word_data = max34440_write_word_data,
327	},
328	[max34460] = {
329		.pages = 18,
330		.format[PSC_VOLTAGE_OUT] = direct,
331		.format[PSC_TEMPERATURE] = direct,
332		.m[PSC_VOLTAGE_OUT] = 1,
333		.b[PSC_VOLTAGE_OUT] = 0,
334		.R[PSC_VOLTAGE_OUT] = 3,
335		.m[PSC_TEMPERATURE] = 1,
336		.b[PSC_TEMPERATURE] = 0,
337		.R[PSC_TEMPERATURE] = 2,
338		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
339		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
340		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
341		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
342		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
343		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
344		.func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
345		.func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
346		.func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
347		.func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
348		.func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
349		.func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
350		.func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
351		.func[14] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
352		.func[15] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
353		.func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
354		.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
355		.read_byte_data = max34440_read_byte_data,
356		.read_word_data = max34440_read_word_data,
357		.write_word_data = max34440_write_word_data,
358	},
359	[max34461] = {
360		.pages = 23,
361		.format[PSC_VOLTAGE_OUT] = direct,
362		.format[PSC_TEMPERATURE] = direct,
363		.m[PSC_VOLTAGE_OUT] = 1,
364		.b[PSC_VOLTAGE_OUT] = 0,
365		.R[PSC_VOLTAGE_OUT] = 3,
366		.m[PSC_TEMPERATURE] = 1,
367		.b[PSC_TEMPERATURE] = 0,
368		.R[PSC_TEMPERATURE] = 2,
369		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
370		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
371		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
372		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
373		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
374		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
375		.func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
376		.func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
377		.func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
378		.func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
379		.func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
380		.func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
381		.func[12] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
382		.func[13] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
383		.func[14] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
384		.func[15] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
385		/* page 16 is reserved */
386		.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
387		.func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
388		.func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
389		.func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
390		.func[21] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
391		.read_byte_data = max34440_read_byte_data,
392		.read_word_data = max34440_read_word_data,
393		.write_word_data = max34440_write_word_data,
394	},
395};
396
397static int max34440_probe(struct i2c_client *client,
398			  const struct i2c_device_id *id)
399{
400	struct max34440_data *data;
 
401
402	data = devm_kzalloc(&client->dev, sizeof(struct max34440_data),
403			    GFP_KERNEL);
404	if (!data)
405		return -ENOMEM;
406	data->id = id->driver_data;
407	data->info = max34440_info[id->driver_data];
408
409	return pmbus_do_probe(client, id, &data->info);
410}
411
412static const struct i2c_device_id max34440_id[] = {
413	{"max34440", max34440},
414	{"max34441", max34441},
415	{"max34446", max34446},
416	{"max34460", max34460},
417	{"max34461", max34461},
418	{}
419};
 
420MODULE_DEVICE_TABLE(i2c, max34440_id);
421
422/* This is the driver that will be inserted */
423static struct i2c_driver max34440_driver = {
424	.driver = {
425		   .name = "max34440",
426		   },
427	.probe = max34440_probe,
428	.remove = pmbus_do_remove,
429	.id_table = max34440_id,
430};
431
432module_i2c_driver(max34440_driver);
 
 
 
 
 
 
 
 
433
434MODULE_AUTHOR("Guenter Roeck");
435MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441");
436MODULE_LICENSE("GPL");