xref: /linux/drivers/hwmon/pmbus/max34440.c (revision 7a001dbab4ade869a149318f5f112c4f185a40dc)
19d2ecfb7SGuenter Roeck /*
29d2ecfb7SGuenter Roeck  * Hardware monitoring driver for Maxim MAX34440/MAX34441
39d2ecfb7SGuenter Roeck  *
49d2ecfb7SGuenter Roeck  * Copyright (c) 2011 Ericsson AB.
550115ac9SGuenter Roeck  * Copyright (c) 2012 Guenter Roeck
69d2ecfb7SGuenter Roeck  *
79d2ecfb7SGuenter Roeck  * This program is free software; you can redistribute it and/or modify
89d2ecfb7SGuenter Roeck  * it under the terms of the GNU General Public License as published by
99d2ecfb7SGuenter Roeck  * the Free Software Foundation; either version 2 of the License, or
109d2ecfb7SGuenter Roeck  * (at your option) any later version.
119d2ecfb7SGuenter Roeck  *
129d2ecfb7SGuenter Roeck  * This program is distributed in the hope that it will be useful,
139d2ecfb7SGuenter Roeck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
149d2ecfb7SGuenter Roeck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
159d2ecfb7SGuenter Roeck  * GNU General Public License for more details.
169d2ecfb7SGuenter Roeck  *
179d2ecfb7SGuenter Roeck  * You should have received a copy of the GNU General Public License
189d2ecfb7SGuenter Roeck  * along with this program; if not, write to the Free Software
199d2ecfb7SGuenter Roeck  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
209d2ecfb7SGuenter Roeck  */
219d2ecfb7SGuenter Roeck 
222c052d42SGuenter Roeck #include <linux/bitops.h>
239d2ecfb7SGuenter Roeck #include <linux/kernel.h>
249d2ecfb7SGuenter Roeck #include <linux/module.h>
259d2ecfb7SGuenter Roeck #include <linux/init.h>
269d2ecfb7SGuenter Roeck #include <linux/err.h>
279d2ecfb7SGuenter Roeck #include <linux/i2c.h>
289d2ecfb7SGuenter Roeck #include "pmbus.h"
299d2ecfb7SGuenter Roeck 
30*7a001dbaSKun Yi enum chips { max34440, max34441, max34446, max34451, max34460, max34461 };
319d2ecfb7SGuenter Roeck 
3298591dbeSGuenter Roeck #define MAX34440_MFR_VOUT_PEAK		0xd4
3398591dbeSGuenter Roeck #define MAX34440_MFR_IOUT_PEAK		0xd5
3498591dbeSGuenter Roeck #define MAX34440_MFR_TEMPERATURE_PEAK	0xd6
3556aad5d1SGuenter Roeck #define MAX34440_MFR_VOUT_MIN		0xd7
3698591dbeSGuenter Roeck 
37590defe5SGuenter Roeck #define MAX34446_MFR_POUT_PEAK		0xe0
38590defe5SGuenter Roeck #define MAX34446_MFR_POUT_AVG		0xe1
39590defe5SGuenter Roeck #define MAX34446_MFR_IOUT_AVG		0xe2
40590defe5SGuenter Roeck #define MAX34446_MFR_TEMPERATURE_AVG	0xe3
41590defe5SGuenter Roeck 
422c052d42SGuenter Roeck #define MAX34440_STATUS_OC_WARN		BIT(0)
432c052d42SGuenter Roeck #define MAX34440_STATUS_OC_FAULT	BIT(1)
442c052d42SGuenter Roeck #define MAX34440_STATUS_OT_FAULT	BIT(5)
452c052d42SGuenter Roeck #define MAX34440_STATUS_OT_WARN		BIT(6)
469d2ecfb7SGuenter Roeck 
47*7a001dbaSKun Yi #define MAX34451_MFR_CHANNEL_CONFIG	0xe4
48*7a001dbaSKun Yi #define MAX34451_MFR_CHANNEL_CONFIG_SEL_MASK	0x3f
49*7a001dbaSKun Yi 
50590defe5SGuenter Roeck struct max34440_data {
51590defe5SGuenter Roeck 	int id;
52590defe5SGuenter Roeck 	struct pmbus_driver_info info;
53590defe5SGuenter Roeck };
54590defe5SGuenter Roeck 
55590defe5SGuenter Roeck #define to_max34440_data(x)  container_of(x, struct max34440_data, info)
56590defe5SGuenter Roeck 
5798591dbeSGuenter Roeck static int max34440_read_word_data(struct i2c_client *client, int page, int reg)
5898591dbeSGuenter Roeck {
5998591dbeSGuenter Roeck 	int ret;
60590defe5SGuenter Roeck 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
61590defe5SGuenter Roeck 	const struct max34440_data *data = to_max34440_data(info);
6298591dbeSGuenter Roeck 
6398591dbeSGuenter Roeck 	switch (reg) {
6456aad5d1SGuenter Roeck 	case PMBUS_VIRT_READ_VOUT_MIN:
6556aad5d1SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
6656aad5d1SGuenter Roeck 					   MAX34440_MFR_VOUT_MIN);
6756aad5d1SGuenter Roeck 		break;
6898591dbeSGuenter Roeck 	case PMBUS_VIRT_READ_VOUT_MAX:
6998591dbeSGuenter Roeck 		ret = pmbus_read_word_data(client, page,
7098591dbeSGuenter Roeck 					   MAX34440_MFR_VOUT_PEAK);
7198591dbeSGuenter Roeck 		break;
72590defe5SGuenter Roeck 	case PMBUS_VIRT_READ_IOUT_AVG:
73*7a001dbaSKun Yi 		if (data->id != max34446 && data->id != max34451)
74590defe5SGuenter Roeck 			return -ENXIO;
75590defe5SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
76590defe5SGuenter Roeck 					   MAX34446_MFR_IOUT_AVG);
77590defe5SGuenter Roeck 		break;
7898591dbeSGuenter Roeck 	case PMBUS_VIRT_READ_IOUT_MAX:
7998591dbeSGuenter Roeck 		ret = pmbus_read_word_data(client, page,
8098591dbeSGuenter Roeck 					   MAX34440_MFR_IOUT_PEAK);
8198591dbeSGuenter Roeck 		break;
82590defe5SGuenter Roeck 	case PMBUS_VIRT_READ_POUT_AVG:
83590defe5SGuenter Roeck 		if (data->id != max34446)
84590defe5SGuenter Roeck 			return -ENXIO;
85590defe5SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
86590defe5SGuenter Roeck 					   MAX34446_MFR_POUT_AVG);
87590defe5SGuenter Roeck 		break;
88590defe5SGuenter Roeck 	case PMBUS_VIRT_READ_POUT_MAX:
89590defe5SGuenter Roeck 		if (data->id != max34446)
90590defe5SGuenter Roeck 			return -ENXIO;
91590defe5SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
92590defe5SGuenter Roeck 					   MAX34446_MFR_POUT_PEAK);
93590defe5SGuenter Roeck 		break;
94590defe5SGuenter Roeck 	case PMBUS_VIRT_READ_TEMP_AVG:
9550115ac9SGuenter Roeck 		if (data->id != max34446 && data->id != max34460 &&
9650115ac9SGuenter Roeck 		    data->id != max34461)
97590defe5SGuenter Roeck 			return -ENXIO;
98590defe5SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
99590defe5SGuenter Roeck 					   MAX34446_MFR_TEMPERATURE_AVG);
100590defe5SGuenter Roeck 		break;
10198591dbeSGuenter Roeck 	case PMBUS_VIRT_READ_TEMP_MAX:
10298591dbeSGuenter Roeck 		ret = pmbus_read_word_data(client, page,
10398591dbeSGuenter Roeck 					   MAX34440_MFR_TEMPERATURE_PEAK);
10498591dbeSGuenter Roeck 		break;
105590defe5SGuenter Roeck 	case PMBUS_VIRT_RESET_POUT_HISTORY:
106590defe5SGuenter Roeck 		if (data->id != max34446)
107590defe5SGuenter Roeck 			return -ENXIO;
108590defe5SGuenter Roeck 		ret = 0;
109590defe5SGuenter Roeck 		break;
11098591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_VOUT_HISTORY:
11198591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_IOUT_HISTORY:
11298591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_TEMP_HISTORY:
11398591dbeSGuenter Roeck 		ret = 0;
11498591dbeSGuenter Roeck 		break;
11598591dbeSGuenter Roeck 	default:
11698591dbeSGuenter Roeck 		ret = -ENODATA;
11798591dbeSGuenter Roeck 		break;
11898591dbeSGuenter Roeck 	}
11998591dbeSGuenter Roeck 	return ret;
12098591dbeSGuenter Roeck }
12198591dbeSGuenter Roeck 
12298591dbeSGuenter Roeck static int max34440_write_word_data(struct i2c_client *client, int page,
12398591dbeSGuenter Roeck 				    int reg, u16 word)
12498591dbeSGuenter Roeck {
125590defe5SGuenter Roeck 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
126590defe5SGuenter Roeck 	const struct max34440_data *data = to_max34440_data(info);
12798591dbeSGuenter Roeck 	int ret;
12898591dbeSGuenter Roeck 
12998591dbeSGuenter Roeck 	switch (reg) {
130590defe5SGuenter Roeck 	case PMBUS_VIRT_RESET_POUT_HISTORY:
131590defe5SGuenter Roeck 		ret = pmbus_write_word_data(client, page,
132590defe5SGuenter Roeck 					    MAX34446_MFR_POUT_PEAK, 0);
133590defe5SGuenter Roeck 		if (ret)
134590defe5SGuenter Roeck 			break;
135590defe5SGuenter Roeck 		ret = pmbus_write_word_data(client, page,
136590defe5SGuenter Roeck 					    MAX34446_MFR_POUT_AVG, 0);
137590defe5SGuenter Roeck 		break;
13898591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_VOUT_HISTORY:
13998591dbeSGuenter Roeck 		ret = pmbus_write_word_data(client, page,
14056aad5d1SGuenter Roeck 					    MAX34440_MFR_VOUT_MIN, 0x7fff);
14156aad5d1SGuenter Roeck 		if (ret)
14256aad5d1SGuenter Roeck 			break;
14356aad5d1SGuenter Roeck 		ret = pmbus_write_word_data(client, page,
14498591dbeSGuenter Roeck 					    MAX34440_MFR_VOUT_PEAK, 0);
14598591dbeSGuenter Roeck 		break;
14698591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_IOUT_HISTORY:
14798591dbeSGuenter Roeck 		ret = pmbus_write_word_data(client, page,
14898591dbeSGuenter Roeck 					    MAX34440_MFR_IOUT_PEAK, 0);
149*7a001dbaSKun Yi 		if (!ret && (data->id == max34446 || data->id == max34451))
150590defe5SGuenter Roeck 			ret = pmbus_write_word_data(client, page,
151590defe5SGuenter Roeck 					MAX34446_MFR_IOUT_AVG, 0);
152590defe5SGuenter Roeck 
15398591dbeSGuenter Roeck 		break;
15498591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_TEMP_HISTORY:
15598591dbeSGuenter Roeck 		ret = pmbus_write_word_data(client, page,
15698591dbeSGuenter Roeck 					    MAX34440_MFR_TEMPERATURE_PEAK,
157dc91ad8eSGuenter Roeck 					    0x8000);
158590defe5SGuenter Roeck 		if (!ret && data->id == max34446)
159590defe5SGuenter Roeck 			ret = pmbus_write_word_data(client, page,
160590defe5SGuenter Roeck 					MAX34446_MFR_TEMPERATURE_AVG, 0);
16198591dbeSGuenter Roeck 		break;
16298591dbeSGuenter Roeck 	default:
16398591dbeSGuenter Roeck 		ret = -ENODATA;
16498591dbeSGuenter Roeck 		break;
16598591dbeSGuenter Roeck 	}
16698591dbeSGuenter Roeck 	return ret;
16798591dbeSGuenter Roeck }
16898591dbeSGuenter Roeck 
1699d2ecfb7SGuenter Roeck static int max34440_read_byte_data(struct i2c_client *client, int page, int reg)
1709d2ecfb7SGuenter Roeck {
171da8e48abSGuenter Roeck 	int ret = 0;
1729d2ecfb7SGuenter Roeck 	int mfg_status;
1739d2ecfb7SGuenter Roeck 
174da8e48abSGuenter Roeck 	if (page >= 0) {
1759d2ecfb7SGuenter Roeck 		ret = pmbus_set_page(client, page);
1769d2ecfb7SGuenter Roeck 		if (ret < 0)
1779d2ecfb7SGuenter Roeck 			return ret;
178da8e48abSGuenter Roeck 	}
1799d2ecfb7SGuenter Roeck 
1809d2ecfb7SGuenter Roeck 	switch (reg) {
1819d2ecfb7SGuenter Roeck 	case PMBUS_STATUS_IOUT:
1829d2ecfb7SGuenter Roeck 		mfg_status = pmbus_read_word_data(client, 0,
1839d2ecfb7SGuenter Roeck 						  PMBUS_STATUS_MFR_SPECIFIC);
1849d2ecfb7SGuenter Roeck 		if (mfg_status < 0)
1859d2ecfb7SGuenter Roeck 			return mfg_status;
1869d2ecfb7SGuenter Roeck 		if (mfg_status & MAX34440_STATUS_OC_WARN)
1879d2ecfb7SGuenter Roeck 			ret |= PB_IOUT_OC_WARNING;
1889d2ecfb7SGuenter Roeck 		if (mfg_status & MAX34440_STATUS_OC_FAULT)
1899d2ecfb7SGuenter Roeck 			ret |= PB_IOUT_OC_FAULT;
1909d2ecfb7SGuenter Roeck 		break;
1919d2ecfb7SGuenter Roeck 	case PMBUS_STATUS_TEMPERATURE:
1929d2ecfb7SGuenter Roeck 		mfg_status = pmbus_read_word_data(client, 0,
1939d2ecfb7SGuenter Roeck 						  PMBUS_STATUS_MFR_SPECIFIC);
1949d2ecfb7SGuenter Roeck 		if (mfg_status < 0)
1959d2ecfb7SGuenter Roeck 			return mfg_status;
1969d2ecfb7SGuenter Roeck 		if (mfg_status & MAX34440_STATUS_OT_WARN)
1979d2ecfb7SGuenter Roeck 			ret |= PB_TEMP_OT_WARNING;
1989d2ecfb7SGuenter Roeck 		if (mfg_status & MAX34440_STATUS_OT_FAULT)
1999d2ecfb7SGuenter Roeck 			ret |= PB_TEMP_OT_FAULT;
2009d2ecfb7SGuenter Roeck 		break;
2019d2ecfb7SGuenter Roeck 	default:
2029d2ecfb7SGuenter Roeck 		ret = -ENODATA;
2039d2ecfb7SGuenter Roeck 		break;
2049d2ecfb7SGuenter Roeck 	}
2059d2ecfb7SGuenter Roeck 	return ret;
2069d2ecfb7SGuenter Roeck }
2079d2ecfb7SGuenter Roeck 
208*7a001dbaSKun Yi static int max34451_set_supported_funcs(struct i2c_client *client,
209*7a001dbaSKun Yi 					 struct max34440_data *data)
210*7a001dbaSKun Yi {
211*7a001dbaSKun Yi 	/*
212*7a001dbaSKun Yi 	 * Each of the channel 0-15 can be configured to monitor the following
213*7a001dbaSKun Yi 	 * functions based on MFR_CHANNEL_CONFIG[5:0]
214*7a001dbaSKun Yi 	 * 0x10: Sequencing + voltage monitoring (only valid for PAGES 0–11)
215*7a001dbaSKun Yi 	 * 0x20: Voltage monitoring (no sequencing)
216*7a001dbaSKun Yi 	 * 0x21: Voltage read only
217*7a001dbaSKun Yi 	 * 0x22: Current monitoring
218*7a001dbaSKun Yi 	 * 0x23: Current read only
219*7a001dbaSKun Yi 	 * 0x30: General-purpose input active low
220*7a001dbaSKun Yi 	 * 0x34: General-purpose input active high
221*7a001dbaSKun Yi 	 * 0x00:  Disabled
222*7a001dbaSKun Yi 	 */
223*7a001dbaSKun Yi 
224*7a001dbaSKun Yi 	int page, rv;
225*7a001dbaSKun Yi 
226*7a001dbaSKun Yi 	for (page = 0; page < 16; page++) {
227*7a001dbaSKun Yi 		rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
228*7a001dbaSKun Yi 		if (rv < 0)
229*7a001dbaSKun Yi 			return rv;
230*7a001dbaSKun Yi 
231*7a001dbaSKun Yi 		rv = i2c_smbus_read_word_data(client,
232*7a001dbaSKun Yi 					      MAX34451_MFR_CHANNEL_CONFIG);
233*7a001dbaSKun Yi 		if (rv < 0)
234*7a001dbaSKun Yi 			return rv;
235*7a001dbaSKun Yi 
236*7a001dbaSKun Yi 		switch (rv & MAX34451_MFR_CHANNEL_CONFIG_SEL_MASK) {
237*7a001dbaSKun Yi 		case 0x10:
238*7a001dbaSKun Yi 		case 0x20:
239*7a001dbaSKun Yi 			data->info.func[page] = PMBUS_HAVE_VOUT |
240*7a001dbaSKun Yi 				PMBUS_HAVE_STATUS_VOUT;
241*7a001dbaSKun Yi 			break;
242*7a001dbaSKun Yi 		case 0x21:
243*7a001dbaSKun Yi 			data->info.func[page] = PMBUS_HAVE_VOUT;
244*7a001dbaSKun Yi 			break;
245*7a001dbaSKun Yi 		case 0x22:
246*7a001dbaSKun Yi 			data->info.func[page] = PMBUS_HAVE_IOUT |
247*7a001dbaSKun Yi 				PMBUS_HAVE_STATUS_IOUT;
248*7a001dbaSKun Yi 			break;
249*7a001dbaSKun Yi 		case 0x23:
250*7a001dbaSKun Yi 			data->info.func[page] = PMBUS_HAVE_IOUT;
251*7a001dbaSKun Yi 			break;
252*7a001dbaSKun Yi 		default:
253*7a001dbaSKun Yi 			break;
254*7a001dbaSKun Yi 		}
255*7a001dbaSKun Yi 	}
256*7a001dbaSKun Yi 
257*7a001dbaSKun Yi 	return 0;
258*7a001dbaSKun Yi }
259*7a001dbaSKun Yi 
2609d2ecfb7SGuenter Roeck static struct pmbus_driver_info max34440_info[] = {
2619d2ecfb7SGuenter Roeck 	[max34440] = {
2629d2ecfb7SGuenter Roeck 		.pages = 14,
2631061d851SGuenter Roeck 		.format[PSC_VOLTAGE_IN] = direct,
2641061d851SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
2651061d851SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
2661061d851SGuenter Roeck 		.format[PSC_CURRENT_OUT] = direct,
2679d2ecfb7SGuenter Roeck 		.m[PSC_VOLTAGE_IN] = 1,
2689d2ecfb7SGuenter Roeck 		.b[PSC_VOLTAGE_IN] = 0,
2699d2ecfb7SGuenter Roeck 		.R[PSC_VOLTAGE_IN] = 3,	    /* R = 0 in datasheet reflects mV */
2709d2ecfb7SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
2719d2ecfb7SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
2729d2ecfb7SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,    /* R = 0 in datasheet reflects mV */
2739d2ecfb7SGuenter Roeck 		.m[PSC_CURRENT_OUT] = 1,
2749d2ecfb7SGuenter Roeck 		.b[PSC_CURRENT_OUT] = 0,
2759d2ecfb7SGuenter Roeck 		.R[PSC_CURRENT_OUT] = 3,    /* R = 0 in datasheet reflects mA */
2769d2ecfb7SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
2779d2ecfb7SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
2789d2ecfb7SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
2799d2ecfb7SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2809d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2819d2ecfb7SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2829d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2839d2ecfb7SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2849d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2859d2ecfb7SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2869d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2879d2ecfb7SGuenter Roeck 		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2889d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2899d2ecfb7SGuenter Roeck 		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2909d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2919d2ecfb7SGuenter Roeck 		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2929d2ecfb7SGuenter Roeck 		.func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2939d2ecfb7SGuenter Roeck 		.func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2949d2ecfb7SGuenter Roeck 		.func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2959d2ecfb7SGuenter Roeck 		.func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2969d2ecfb7SGuenter Roeck 		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2979d2ecfb7SGuenter Roeck 		.func[12] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2989d2ecfb7SGuenter Roeck 		.func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2999d2ecfb7SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
30098591dbeSGuenter Roeck 		.read_word_data = max34440_read_word_data,
30198591dbeSGuenter Roeck 		.write_word_data = max34440_write_word_data,
3029d2ecfb7SGuenter Roeck 	},
3039d2ecfb7SGuenter Roeck 	[max34441] = {
3049d2ecfb7SGuenter Roeck 		.pages = 12,
3051061d851SGuenter Roeck 		.format[PSC_VOLTAGE_IN] = direct,
3061061d851SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
3071061d851SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
3081061d851SGuenter Roeck 		.format[PSC_CURRENT_OUT] = direct,
3091061d851SGuenter Roeck 		.format[PSC_FAN] = direct,
3109d2ecfb7SGuenter Roeck 		.m[PSC_VOLTAGE_IN] = 1,
3119d2ecfb7SGuenter Roeck 		.b[PSC_VOLTAGE_IN] = 0,
3129d2ecfb7SGuenter Roeck 		.R[PSC_VOLTAGE_IN] = 3,
3139d2ecfb7SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
3149d2ecfb7SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
3159d2ecfb7SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,
3169d2ecfb7SGuenter Roeck 		.m[PSC_CURRENT_OUT] = 1,
3179d2ecfb7SGuenter Roeck 		.b[PSC_CURRENT_OUT] = 0,
3189d2ecfb7SGuenter Roeck 		.R[PSC_CURRENT_OUT] = 3,
3199d2ecfb7SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
3209d2ecfb7SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
3219d2ecfb7SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
3229d2ecfb7SGuenter Roeck 		.m[PSC_FAN] = 1,
3239d2ecfb7SGuenter Roeck 		.b[PSC_FAN] = 0,
3249d2ecfb7SGuenter Roeck 		.R[PSC_FAN] = 0,
3259d2ecfb7SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
3269d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
3279d2ecfb7SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
3289d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
3299d2ecfb7SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
3309d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
3319d2ecfb7SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
3329d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
3339d2ecfb7SGuenter Roeck 		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
3349d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
3359d2ecfb7SGuenter Roeck 		.func[5] = PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
3369d2ecfb7SGuenter Roeck 		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
3379d2ecfb7SGuenter Roeck 		.func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
3389d2ecfb7SGuenter Roeck 		.func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
3399d2ecfb7SGuenter Roeck 		.func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
3409d2ecfb7SGuenter Roeck 		.func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
3419d2ecfb7SGuenter Roeck 		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
3429d2ecfb7SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
34398591dbeSGuenter Roeck 		.read_word_data = max34440_read_word_data,
34498591dbeSGuenter Roeck 		.write_word_data = max34440_write_word_data,
3459d2ecfb7SGuenter Roeck 	},
346590defe5SGuenter Roeck 	[max34446] = {
347590defe5SGuenter Roeck 		.pages = 7,
348590defe5SGuenter Roeck 		.format[PSC_VOLTAGE_IN] = direct,
349590defe5SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
350590defe5SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
351590defe5SGuenter Roeck 		.format[PSC_CURRENT_OUT] = direct,
352590defe5SGuenter Roeck 		.format[PSC_POWER] = direct,
353590defe5SGuenter Roeck 		.m[PSC_VOLTAGE_IN] = 1,
354590defe5SGuenter Roeck 		.b[PSC_VOLTAGE_IN] = 0,
355590defe5SGuenter Roeck 		.R[PSC_VOLTAGE_IN] = 3,
356590defe5SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
357590defe5SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
358590defe5SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,
359590defe5SGuenter Roeck 		.m[PSC_CURRENT_OUT] = 1,
360590defe5SGuenter Roeck 		.b[PSC_CURRENT_OUT] = 0,
361590defe5SGuenter Roeck 		.R[PSC_CURRENT_OUT] = 3,
362590defe5SGuenter Roeck 		.m[PSC_POWER] = 1,
363590defe5SGuenter Roeck 		.b[PSC_POWER] = 0,
364590defe5SGuenter Roeck 		.R[PSC_POWER] = 3,
365590defe5SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
366590defe5SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
367590defe5SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
368590defe5SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
369590defe5SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
370590defe5SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
371590defe5SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
372590defe5SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
373590defe5SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
374590defe5SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
375590defe5SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
376590defe5SGuenter Roeck 		.func[4] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
377590defe5SGuenter Roeck 		.func[5] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
378590defe5SGuenter Roeck 		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
379590defe5SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
380590defe5SGuenter Roeck 		.read_word_data = max34440_read_word_data,
381590defe5SGuenter Roeck 		.write_word_data = max34440_write_word_data,
382590defe5SGuenter Roeck 	},
383*7a001dbaSKun Yi 	[max34451] = {
384*7a001dbaSKun Yi 		.pages = 21,
385*7a001dbaSKun Yi 		.format[PSC_VOLTAGE_OUT] = direct,
386*7a001dbaSKun Yi 		.format[PSC_TEMPERATURE] = direct,
387*7a001dbaSKun Yi 		.format[PSC_CURRENT_OUT] = direct,
388*7a001dbaSKun Yi 		.m[PSC_VOLTAGE_OUT] = 1,
389*7a001dbaSKun Yi 		.b[PSC_VOLTAGE_OUT] = 0,
390*7a001dbaSKun Yi 		.R[PSC_VOLTAGE_OUT] = 3,
391*7a001dbaSKun Yi 		.m[PSC_CURRENT_OUT] = 1,
392*7a001dbaSKun Yi 		.b[PSC_CURRENT_OUT] = 0,
393*7a001dbaSKun Yi 		.R[PSC_CURRENT_OUT] = 2,
394*7a001dbaSKun Yi 		.m[PSC_TEMPERATURE] = 1,
395*7a001dbaSKun Yi 		.b[PSC_TEMPERATURE] = 0,
396*7a001dbaSKun Yi 		.R[PSC_TEMPERATURE] = 2,
397*7a001dbaSKun Yi 		/* func 0-15 is set dynamically before probing */
398*7a001dbaSKun Yi 		.func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
399*7a001dbaSKun Yi 		.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
400*7a001dbaSKun Yi 		.func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
401*7a001dbaSKun Yi 		.func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
402*7a001dbaSKun Yi 		.func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
403*7a001dbaSKun Yi 		.read_byte_data = max34440_read_byte_data,
404*7a001dbaSKun Yi 		.read_word_data = max34440_read_word_data,
405*7a001dbaSKun Yi 		.write_word_data = max34440_write_word_data,
406*7a001dbaSKun Yi 	},
40750115ac9SGuenter Roeck 	[max34460] = {
40850115ac9SGuenter Roeck 		.pages = 18,
40950115ac9SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
41050115ac9SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
41150115ac9SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
41250115ac9SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
41350115ac9SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,
41450115ac9SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
41550115ac9SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
41650115ac9SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
41750115ac9SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
41850115ac9SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
41950115ac9SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
42050115ac9SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
42150115ac9SGuenter Roeck 		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
42250115ac9SGuenter Roeck 		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
42350115ac9SGuenter Roeck 		.func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
42450115ac9SGuenter Roeck 		.func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
42550115ac9SGuenter Roeck 		.func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
42650115ac9SGuenter Roeck 		.func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
42750115ac9SGuenter Roeck 		.func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
42850115ac9SGuenter Roeck 		.func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
42950115ac9SGuenter Roeck 		.func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
43050115ac9SGuenter Roeck 		.func[14] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
43150115ac9SGuenter Roeck 		.func[15] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
43250115ac9SGuenter Roeck 		.func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
43350115ac9SGuenter Roeck 		.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
43450115ac9SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
43550115ac9SGuenter Roeck 		.read_word_data = max34440_read_word_data,
43650115ac9SGuenter Roeck 		.write_word_data = max34440_write_word_data,
43750115ac9SGuenter Roeck 	},
43850115ac9SGuenter Roeck 	[max34461] = {
43950115ac9SGuenter Roeck 		.pages = 23,
44050115ac9SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
44150115ac9SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
44250115ac9SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
44350115ac9SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
44450115ac9SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,
44550115ac9SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
44650115ac9SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
44750115ac9SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
44850115ac9SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
44950115ac9SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
45050115ac9SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
45150115ac9SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
45250115ac9SGuenter Roeck 		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
45350115ac9SGuenter Roeck 		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
45450115ac9SGuenter Roeck 		.func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
45550115ac9SGuenter Roeck 		.func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
45650115ac9SGuenter Roeck 		.func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
45750115ac9SGuenter Roeck 		.func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
45850115ac9SGuenter Roeck 		.func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
45950115ac9SGuenter Roeck 		.func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
46050115ac9SGuenter Roeck 		.func[12] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
46150115ac9SGuenter Roeck 		.func[13] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
46250115ac9SGuenter Roeck 		.func[14] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
46350115ac9SGuenter Roeck 		.func[15] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
46450115ac9SGuenter Roeck 		/* page 16 is reserved */
46550115ac9SGuenter Roeck 		.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
46650115ac9SGuenter Roeck 		.func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
46750115ac9SGuenter Roeck 		.func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
46850115ac9SGuenter Roeck 		.func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
46950115ac9SGuenter Roeck 		.func[21] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
47050115ac9SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
47150115ac9SGuenter Roeck 		.read_word_data = max34440_read_word_data,
47250115ac9SGuenter Roeck 		.write_word_data = max34440_write_word_data,
47350115ac9SGuenter Roeck 	},
4749d2ecfb7SGuenter Roeck };
4759d2ecfb7SGuenter Roeck 
4769d2ecfb7SGuenter Roeck static int max34440_probe(struct i2c_client *client,
4779d2ecfb7SGuenter Roeck 			  const struct i2c_device_id *id)
4789d2ecfb7SGuenter Roeck {
479590defe5SGuenter Roeck 	struct max34440_data *data;
480*7a001dbaSKun Yi 	int rv;
481590defe5SGuenter Roeck 
482590defe5SGuenter Roeck 	data = devm_kzalloc(&client->dev, sizeof(struct max34440_data),
483590defe5SGuenter Roeck 			    GFP_KERNEL);
484590defe5SGuenter Roeck 	if (!data)
485590defe5SGuenter Roeck 		return -ENOMEM;
486590defe5SGuenter Roeck 	data->id = id->driver_data;
487590defe5SGuenter Roeck 	data->info = max34440_info[id->driver_data];
488590defe5SGuenter Roeck 
489*7a001dbaSKun Yi 	if (data->id == max34451) {
490*7a001dbaSKun Yi 		rv = max34451_set_supported_funcs(client, data);
491*7a001dbaSKun Yi 		if (rv)
492*7a001dbaSKun Yi 			return rv;
493*7a001dbaSKun Yi 	}
494*7a001dbaSKun Yi 
495590defe5SGuenter Roeck 	return pmbus_do_probe(client, id, &data->info);
4969d2ecfb7SGuenter Roeck }
4979d2ecfb7SGuenter Roeck 
4989d2ecfb7SGuenter Roeck static const struct i2c_device_id max34440_id[] = {
4999d2ecfb7SGuenter Roeck 	{"max34440", max34440},
5009d2ecfb7SGuenter Roeck 	{"max34441", max34441},
501590defe5SGuenter Roeck 	{"max34446", max34446},
502*7a001dbaSKun Yi 	{"max34451", max34451},
50350115ac9SGuenter Roeck 	{"max34460", max34460},
50450115ac9SGuenter Roeck 	{"max34461", max34461},
5059d2ecfb7SGuenter Roeck 	{}
5069d2ecfb7SGuenter Roeck };
5079d2ecfb7SGuenter Roeck MODULE_DEVICE_TABLE(i2c, max34440_id);
5089d2ecfb7SGuenter Roeck 
5099d2ecfb7SGuenter Roeck /* This is the driver that will be inserted */
5109d2ecfb7SGuenter Roeck static struct i2c_driver max34440_driver = {
5119d2ecfb7SGuenter Roeck 	.driver = {
5129d2ecfb7SGuenter Roeck 		   .name = "max34440",
5139d2ecfb7SGuenter Roeck 		   },
5149d2ecfb7SGuenter Roeck 	.probe = max34440_probe,
515dd285ad7SGuenter Roeck 	.remove = pmbus_do_remove,
5169d2ecfb7SGuenter Roeck 	.id_table = max34440_id,
5179d2ecfb7SGuenter Roeck };
5189d2ecfb7SGuenter Roeck 
519f0967eeaSAxel Lin module_i2c_driver(max34440_driver);
5209d2ecfb7SGuenter Roeck 
5219d2ecfb7SGuenter Roeck MODULE_AUTHOR("Guenter Roeck");
5229d2ecfb7SGuenter Roeck MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441");
5239d2ecfb7SGuenter Roeck MODULE_LICENSE("GPL");
524