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);
v5.4
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Hardware monitoring driver for Maxim MAX34440/MAX34441
  4 *
  5 * Copyright (c) 2011 Ericsson AB.
  6 * Copyright (c) 2012 Guenter Roeck
 
 
 
 
 
 
 
 
 
 
 
 
 
  7 */
  8
  9#include <linux/bitops.h>
 10#include <linux/kernel.h>
 11#include <linux/module.h>
 12#include <linux/init.h>
 13#include <linux/err.h>
 14#include <linux/i2c.h>
 15#include "pmbus.h"
 16
 17enum chips { max34440, max34441, max34446, max34451, max34460, max34461 };
 18
 19#define MAX34440_MFR_VOUT_PEAK		0xd4
 20#define MAX34440_MFR_IOUT_PEAK		0xd5
 21#define MAX34440_MFR_TEMPERATURE_PEAK	0xd6
 22#define MAX34440_MFR_VOUT_MIN		0xd7
 23
 24#define MAX34446_MFR_POUT_PEAK		0xe0
 25#define MAX34446_MFR_POUT_AVG		0xe1
 26#define MAX34446_MFR_IOUT_AVG		0xe2
 27#define MAX34446_MFR_TEMPERATURE_AVG	0xe3
 28
 29#define MAX34440_STATUS_OC_WARN		BIT(0)
 30#define MAX34440_STATUS_OC_FAULT	BIT(1)
 31#define MAX34440_STATUS_OT_FAULT	BIT(5)
 32#define MAX34440_STATUS_OT_WARN		BIT(6)
 33
 34#define MAX34451_MFR_CHANNEL_CONFIG	0xe4
 35#define MAX34451_MFR_CHANNEL_CONFIG_SEL_MASK	0x3f
 36
 37struct max34440_data {
 38	int id;
 39	struct pmbus_driver_info info;
 40};
 41
 42#define to_max34440_data(x)  container_of(x, struct max34440_data, info)
 43
 44static int max34440_read_word_data(struct i2c_client *client, int page, int reg)
 45{
 46	int ret;
 47	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
 48	const struct max34440_data *data = to_max34440_data(info);
 49
 50	switch (reg) {
 51	case PMBUS_VIRT_READ_VOUT_MIN:
 52		ret = pmbus_read_word_data(client, page,
 53					   MAX34440_MFR_VOUT_MIN);
 54		break;
 55	case PMBUS_VIRT_READ_VOUT_MAX:
 56		ret = pmbus_read_word_data(client, page,
 57					   MAX34440_MFR_VOUT_PEAK);
 58		break;
 59	case PMBUS_VIRT_READ_IOUT_AVG:
 60		if (data->id != max34446 && data->id != max34451)
 61			return -ENXIO;
 62		ret = pmbus_read_word_data(client, page,
 63					   MAX34446_MFR_IOUT_AVG);
 64		break;
 65	case PMBUS_VIRT_READ_IOUT_MAX:
 66		ret = pmbus_read_word_data(client, page,
 67					   MAX34440_MFR_IOUT_PEAK);
 68		break;
 69	case PMBUS_VIRT_READ_POUT_AVG:
 70		if (data->id != max34446)
 71			return -ENXIO;
 72		ret = pmbus_read_word_data(client, page,
 73					   MAX34446_MFR_POUT_AVG);
 74		break;
 75	case PMBUS_VIRT_READ_POUT_MAX:
 76		if (data->id != max34446)
 77			return -ENXIO;
 78		ret = pmbus_read_word_data(client, page,
 79					   MAX34446_MFR_POUT_PEAK);
 80		break;
 81	case PMBUS_VIRT_READ_TEMP_AVG:
 82		if (data->id != max34446 && data->id != max34460 &&
 83		    data->id != max34461)
 84			return -ENXIO;
 85		ret = pmbus_read_word_data(client, page,
 86					   MAX34446_MFR_TEMPERATURE_AVG);
 87		break;
 88	case PMBUS_VIRT_READ_TEMP_MAX:
 89		ret = pmbus_read_word_data(client, page,
 90					   MAX34440_MFR_TEMPERATURE_PEAK);
 91		break;
 92	case PMBUS_VIRT_RESET_POUT_HISTORY:
 93		if (data->id != max34446)
 94			return -ENXIO;
 95		ret = 0;
 96		break;
 97	case PMBUS_VIRT_RESET_VOUT_HISTORY:
 98	case PMBUS_VIRT_RESET_IOUT_HISTORY:
 99	case PMBUS_VIRT_RESET_TEMP_HISTORY:
100		ret = 0;
101		break;
102	default:
103		ret = -ENODATA;
104		break;
105	}
106	return ret;
107}
108
109static int max34440_write_word_data(struct i2c_client *client, int page,
110				    int reg, u16 word)
111{
112	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
113	const struct max34440_data *data = to_max34440_data(info);
114	int ret;
115
116	switch (reg) {
117	case PMBUS_VIRT_RESET_POUT_HISTORY:
118		ret = pmbus_write_word_data(client, page,
119					    MAX34446_MFR_POUT_PEAK, 0);
120		if (ret)
121			break;
122		ret = pmbus_write_word_data(client, page,
123					    MAX34446_MFR_POUT_AVG, 0);
124		break;
125	case PMBUS_VIRT_RESET_VOUT_HISTORY:
126		ret = pmbus_write_word_data(client, page,
127					    MAX34440_MFR_VOUT_MIN, 0x7fff);
128		if (ret)
129			break;
130		ret = pmbus_write_word_data(client, page,
131					    MAX34440_MFR_VOUT_PEAK, 0);
132		break;
133	case PMBUS_VIRT_RESET_IOUT_HISTORY:
134		ret = pmbus_write_word_data(client, page,
135					    MAX34440_MFR_IOUT_PEAK, 0);
136		if (!ret && (data->id == max34446 || data->id == max34451))
137			ret = pmbus_write_word_data(client, page,
138					MAX34446_MFR_IOUT_AVG, 0);
139
140		break;
141	case PMBUS_VIRT_RESET_TEMP_HISTORY:
142		ret = pmbus_write_word_data(client, page,
143					    MAX34440_MFR_TEMPERATURE_PEAK,
144					    0x8000);
145		if (!ret && data->id == max34446)
146			ret = pmbus_write_word_data(client, page,
147					MAX34446_MFR_TEMPERATURE_AVG, 0);
148		break;
149	default:
150		ret = -ENODATA;
151		break;
152	}
153	return ret;
154}
155
156static int max34440_read_byte_data(struct i2c_client *client, int page, int reg)
157{
158	int ret = 0;
159	int mfg_status;
160
161	if (page >= 0) {
162		ret = pmbus_set_page(client, page);
163		if (ret < 0)
164			return ret;
165	}
166
167	switch (reg) {
168	case PMBUS_STATUS_IOUT:
169		mfg_status = pmbus_read_word_data(client, 0,
170						  PMBUS_STATUS_MFR_SPECIFIC);
171		if (mfg_status < 0)
172			return mfg_status;
173		if (mfg_status & MAX34440_STATUS_OC_WARN)
174			ret |= PB_IOUT_OC_WARNING;
175		if (mfg_status & MAX34440_STATUS_OC_FAULT)
176			ret |= PB_IOUT_OC_FAULT;
177		break;
178	case PMBUS_STATUS_TEMPERATURE:
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_OT_WARN)
184			ret |= PB_TEMP_OT_WARNING;
185		if (mfg_status & MAX34440_STATUS_OT_FAULT)
186			ret |= PB_TEMP_OT_FAULT;
187		break;
188	default:
189		ret = -ENODATA;
190		break;
191	}
192	return ret;
193}
194
195static int max34451_set_supported_funcs(struct i2c_client *client,
196					 struct max34440_data *data)
197{
198	/*
199	 * Each of the channel 0-15 can be configured to monitor the following
200	 * functions based on MFR_CHANNEL_CONFIG[5:0]
201	 * 0x10: Sequencing + voltage monitoring (only valid for PAGES 0–11)
202	 * 0x20: Voltage monitoring (no sequencing)
203	 * 0x21: Voltage read only
204	 * 0x22: Current monitoring
205	 * 0x23: Current read only
206	 * 0x30: General-purpose input active low
207	 * 0x34: General-purpose input active high
208	 * 0x00:  Disabled
209	 */
210
211	int page, rv;
212
213	for (page = 0; page < 16; page++) {
214		rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
215		if (rv < 0)
216			return rv;
217
218		rv = i2c_smbus_read_word_data(client,
219					      MAX34451_MFR_CHANNEL_CONFIG);
220		if (rv < 0)
221			return rv;
222
223		switch (rv & MAX34451_MFR_CHANNEL_CONFIG_SEL_MASK) {
224		case 0x10:
225		case 0x20:
226			data->info.func[page] = PMBUS_HAVE_VOUT |
227				PMBUS_HAVE_STATUS_VOUT;
228			break;
229		case 0x21:
230			data->info.func[page] = PMBUS_HAVE_VOUT;
231			break;
232		case 0x22:
233			data->info.func[page] = PMBUS_HAVE_IOUT |
234				PMBUS_HAVE_STATUS_IOUT;
235			break;
236		case 0x23:
237			data->info.func[page] = PMBUS_HAVE_IOUT;
238			break;
239		default:
240			break;
241		}
242	}
243
244	return 0;
245}
246
247static struct pmbus_driver_info max34440_info[] = {
248	[max34440] = {
249		.pages = 14,
250		.format[PSC_VOLTAGE_IN] = direct,
251		.format[PSC_VOLTAGE_OUT] = direct,
252		.format[PSC_TEMPERATURE] = direct,
253		.format[PSC_CURRENT_OUT] = direct,
254		.m[PSC_VOLTAGE_IN] = 1,
255		.b[PSC_VOLTAGE_IN] = 0,
256		.R[PSC_VOLTAGE_IN] = 3,	    /* R = 0 in datasheet reflects mV */
257		.m[PSC_VOLTAGE_OUT] = 1,
258		.b[PSC_VOLTAGE_OUT] = 0,
259		.R[PSC_VOLTAGE_OUT] = 3,    /* R = 0 in datasheet reflects mV */
260		.m[PSC_CURRENT_OUT] = 1,
261		.b[PSC_CURRENT_OUT] = 0,
262		.R[PSC_CURRENT_OUT] = 3,    /* R = 0 in datasheet reflects mA */
263		.m[PSC_TEMPERATURE] = 1,
264		.b[PSC_TEMPERATURE] = 0,
265		.R[PSC_TEMPERATURE] = 2,
266		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
267		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
268		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
269		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
270		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
271		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
272		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
273		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
274		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
275		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
276		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
277		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
278		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
279		.func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
280		.func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
281		.func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
282		.func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
283		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
284		.func[12] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
285		.func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
286		.read_byte_data = max34440_read_byte_data,
287		.read_word_data = max34440_read_word_data,
288		.write_word_data = max34440_write_word_data,
289	},
290	[max34441] = {
291		.pages = 12,
292		.format[PSC_VOLTAGE_IN] = direct,
293		.format[PSC_VOLTAGE_OUT] = direct,
294		.format[PSC_TEMPERATURE] = direct,
295		.format[PSC_CURRENT_OUT] = direct,
296		.format[PSC_FAN] = direct,
297		.m[PSC_VOLTAGE_IN] = 1,
298		.b[PSC_VOLTAGE_IN] = 0,
299		.R[PSC_VOLTAGE_IN] = 3,
300		.m[PSC_VOLTAGE_OUT] = 1,
301		.b[PSC_VOLTAGE_OUT] = 0,
302		.R[PSC_VOLTAGE_OUT] = 3,
303		.m[PSC_CURRENT_OUT] = 1,
304		.b[PSC_CURRENT_OUT] = 0,
305		.R[PSC_CURRENT_OUT] = 3,
306		.m[PSC_TEMPERATURE] = 1,
307		.b[PSC_TEMPERATURE] = 0,
308		.R[PSC_TEMPERATURE] = 2,
309		.m[PSC_FAN] = 1,
310		.b[PSC_FAN] = 0,
311		.R[PSC_FAN] = 0,
312		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
313		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
314		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
315		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
316		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
317		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
318		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
319		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
320		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
321		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
322		.func[5] = PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
323		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
324		.func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
325		.func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
326		.func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
327		.func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
328		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
329		.read_byte_data = max34440_read_byte_data,
330		.read_word_data = max34440_read_word_data,
331		.write_word_data = max34440_write_word_data,
332	},
333	[max34446] = {
334		.pages = 7,
335		.format[PSC_VOLTAGE_IN] = direct,
336		.format[PSC_VOLTAGE_OUT] = direct,
337		.format[PSC_TEMPERATURE] = direct,
338		.format[PSC_CURRENT_OUT] = direct,
339		.format[PSC_POWER] = direct,
340		.m[PSC_VOLTAGE_IN] = 1,
341		.b[PSC_VOLTAGE_IN] = 0,
342		.R[PSC_VOLTAGE_IN] = 3,
343		.m[PSC_VOLTAGE_OUT] = 1,
344		.b[PSC_VOLTAGE_OUT] = 0,
345		.R[PSC_VOLTAGE_OUT] = 3,
346		.m[PSC_CURRENT_OUT] = 1,
347		.b[PSC_CURRENT_OUT] = 0,
348		.R[PSC_CURRENT_OUT] = 3,
349		.m[PSC_POWER] = 1,
350		.b[PSC_POWER] = 0,
351		.R[PSC_POWER] = 3,
352		.m[PSC_TEMPERATURE] = 1,
353		.b[PSC_TEMPERATURE] = 0,
354		.R[PSC_TEMPERATURE] = 2,
355		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
356		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
357		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
358		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
359		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
360		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
361		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
362		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
363		.func[4] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
364		.func[5] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
365		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
366		.read_byte_data = max34440_read_byte_data,
367		.read_word_data = max34440_read_word_data,
368		.write_word_data = max34440_write_word_data,
369	},
370	[max34451] = {
371		.pages = 21,
372		.format[PSC_VOLTAGE_OUT] = direct,
373		.format[PSC_TEMPERATURE] = direct,
374		.format[PSC_CURRENT_OUT] = direct,
375		.m[PSC_VOLTAGE_OUT] = 1,
376		.b[PSC_VOLTAGE_OUT] = 0,
377		.R[PSC_VOLTAGE_OUT] = 3,
378		.m[PSC_CURRENT_OUT] = 1,
379		.b[PSC_CURRENT_OUT] = 0,
380		.R[PSC_CURRENT_OUT] = 2,
381		.m[PSC_TEMPERATURE] = 1,
382		.b[PSC_TEMPERATURE] = 0,
383		.R[PSC_TEMPERATURE] = 2,
384		/* func 0-15 is set dynamically before probing */
385		.func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
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		.read_byte_data = max34440_read_byte_data,
391		.read_word_data = max34440_read_word_data,
392		.write_word_data = max34440_write_word_data,
393	},
394	[max34460] = {
395		.pages = 18,
396		.format[PSC_VOLTAGE_OUT] = direct,
397		.format[PSC_TEMPERATURE] = direct,
398		.m[PSC_VOLTAGE_OUT] = 1,
399		.b[PSC_VOLTAGE_OUT] = 0,
400		.R[PSC_VOLTAGE_OUT] = 3,
401		.m[PSC_TEMPERATURE] = 1,
402		.b[PSC_TEMPERATURE] = 0,
403		.R[PSC_TEMPERATURE] = 2,
404		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
405		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
406		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
407		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
408		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
409		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
410		.func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
411		.func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
412		.func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
413		.func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
414		.func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
415		.func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
416		.func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
417		.func[14] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
418		.func[15] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
419		.func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
420		.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
421		.read_byte_data = max34440_read_byte_data,
422		.read_word_data = max34440_read_word_data,
423		.write_word_data = max34440_write_word_data,
424	},
425	[max34461] = {
426		.pages = 23,
427		.format[PSC_VOLTAGE_OUT] = direct,
428		.format[PSC_TEMPERATURE] = direct,
429		.m[PSC_VOLTAGE_OUT] = 1,
430		.b[PSC_VOLTAGE_OUT] = 0,
431		.R[PSC_VOLTAGE_OUT] = 3,
432		.m[PSC_TEMPERATURE] = 1,
433		.b[PSC_TEMPERATURE] = 0,
434		.R[PSC_TEMPERATURE] = 2,
435		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
436		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
437		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
438		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
439		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
440		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
441		.func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
442		.func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
443		.func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
444		.func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
445		.func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
446		.func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
447		.func[12] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
448		.func[13] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
449		.func[14] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
450		.func[15] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
451		/* page 16 is reserved */
452		.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
453		.func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
454		.func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
455		.func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
456		.func[21] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
457		.read_byte_data = max34440_read_byte_data,
458		.read_word_data = max34440_read_word_data,
459		.write_word_data = max34440_write_word_data,
460	},
461};
462
463static int max34440_probe(struct i2c_client *client,
464			  const struct i2c_device_id *id)
465{
466	struct max34440_data *data;
467	int rv;
468
469	data = devm_kzalloc(&client->dev, sizeof(struct max34440_data),
470			    GFP_KERNEL);
471	if (!data)
472		return -ENOMEM;
473	data->id = id->driver_data;
474	data->info = max34440_info[id->driver_data];
475
476	if (data->id == max34451) {
477		rv = max34451_set_supported_funcs(client, data);
478		if (rv)
479			return rv;
480	}
481
482	return pmbus_do_probe(client, id, &data->info);
483}
484
485static const struct i2c_device_id max34440_id[] = {
486	{"max34440", max34440},
487	{"max34441", max34441},
488	{"max34446", max34446},
489	{"max34451", max34451},
490	{"max34460", max34460},
491	{"max34461", max34461},
492	{}
493};
 
494MODULE_DEVICE_TABLE(i2c, max34440_id);
495
496/* This is the driver that will be inserted */
497static struct i2c_driver max34440_driver = {
498	.driver = {
499		   .name = "max34440",
500		   },
501	.probe = max34440_probe,
502	.remove = pmbus_do_remove,
503	.id_table = max34440_id,
504};
505
506module_i2c_driver(max34440_driver);
 
 
 
 
 
 
 
 
507
508MODULE_AUTHOR("Guenter Roeck");
509MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441");
510MODULE_LICENSE("GPL");