xref: /linux/drivers/hwmon/pmbus/max34440.c (revision 50115ac9b6f35ce6bbb61e5ae21fc3bbd01d490c)
19d2ecfb7SGuenter Roeck /*
29d2ecfb7SGuenter Roeck  * Hardware monitoring driver for Maxim MAX34440/MAX34441
39d2ecfb7SGuenter Roeck  *
49d2ecfb7SGuenter Roeck  * Copyright (c) 2011 Ericsson AB.
5*50115ac9SGuenter 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 
229d2ecfb7SGuenter Roeck #include <linux/kernel.h>
239d2ecfb7SGuenter Roeck #include <linux/module.h>
249d2ecfb7SGuenter Roeck #include <linux/init.h>
259d2ecfb7SGuenter Roeck #include <linux/err.h>
269d2ecfb7SGuenter Roeck #include <linux/i2c.h>
279d2ecfb7SGuenter Roeck #include "pmbus.h"
289d2ecfb7SGuenter Roeck 
29*50115ac9SGuenter Roeck enum chips { max34440, max34441, max34446, max34460, max34461 };
309d2ecfb7SGuenter Roeck 
3198591dbeSGuenter Roeck #define MAX34440_MFR_VOUT_PEAK		0xd4
3298591dbeSGuenter Roeck #define MAX34440_MFR_IOUT_PEAK		0xd5
3398591dbeSGuenter Roeck #define MAX34440_MFR_TEMPERATURE_PEAK	0xd6
3456aad5d1SGuenter Roeck #define MAX34440_MFR_VOUT_MIN		0xd7
3598591dbeSGuenter Roeck 
36590defe5SGuenter Roeck #define MAX34446_MFR_POUT_PEAK		0xe0
37590defe5SGuenter Roeck #define MAX34446_MFR_POUT_AVG		0xe1
38590defe5SGuenter Roeck #define MAX34446_MFR_IOUT_AVG		0xe2
39590defe5SGuenter Roeck #define MAX34446_MFR_TEMPERATURE_AVG	0xe3
40590defe5SGuenter Roeck 
419d2ecfb7SGuenter Roeck #define MAX34440_STATUS_OC_WARN		(1 << 0)
429d2ecfb7SGuenter Roeck #define MAX34440_STATUS_OC_FAULT	(1 << 1)
439d2ecfb7SGuenter Roeck #define MAX34440_STATUS_OT_FAULT	(1 << 5)
449d2ecfb7SGuenter Roeck #define MAX34440_STATUS_OT_WARN		(1 << 6)
459d2ecfb7SGuenter Roeck 
46590defe5SGuenter Roeck struct max34440_data {
47590defe5SGuenter Roeck 	int id;
48590defe5SGuenter Roeck 	struct pmbus_driver_info info;
49590defe5SGuenter Roeck };
50590defe5SGuenter Roeck 
51590defe5SGuenter Roeck #define to_max34440_data(x)  container_of(x, struct max34440_data, info)
52590defe5SGuenter Roeck 
5398591dbeSGuenter Roeck static int max34440_read_word_data(struct i2c_client *client, int page, int reg)
5498591dbeSGuenter Roeck {
5598591dbeSGuenter Roeck 	int ret;
56590defe5SGuenter Roeck 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
57590defe5SGuenter Roeck 	const struct max34440_data *data = to_max34440_data(info);
5898591dbeSGuenter Roeck 
5998591dbeSGuenter Roeck 	switch (reg) {
6056aad5d1SGuenter Roeck 	case PMBUS_VIRT_READ_VOUT_MIN:
6156aad5d1SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
6256aad5d1SGuenter Roeck 					   MAX34440_MFR_VOUT_MIN);
6356aad5d1SGuenter Roeck 		break;
6498591dbeSGuenter Roeck 	case PMBUS_VIRT_READ_VOUT_MAX:
6598591dbeSGuenter Roeck 		ret = pmbus_read_word_data(client, page,
6698591dbeSGuenter Roeck 					   MAX34440_MFR_VOUT_PEAK);
6798591dbeSGuenter Roeck 		break;
68590defe5SGuenter Roeck 	case PMBUS_VIRT_READ_IOUT_AVG:
69590defe5SGuenter Roeck 		if (data->id != max34446)
70590defe5SGuenter Roeck 			return -ENXIO;
71590defe5SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
72590defe5SGuenter Roeck 					   MAX34446_MFR_IOUT_AVG);
73590defe5SGuenter Roeck 		break;
7498591dbeSGuenter Roeck 	case PMBUS_VIRT_READ_IOUT_MAX:
7598591dbeSGuenter Roeck 		ret = pmbus_read_word_data(client, page,
7698591dbeSGuenter Roeck 					   MAX34440_MFR_IOUT_PEAK);
7798591dbeSGuenter Roeck 		break;
78590defe5SGuenter Roeck 	case PMBUS_VIRT_READ_POUT_AVG:
79590defe5SGuenter Roeck 		if (data->id != max34446)
80590defe5SGuenter Roeck 			return -ENXIO;
81590defe5SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
82590defe5SGuenter Roeck 					   MAX34446_MFR_POUT_AVG);
83590defe5SGuenter Roeck 		break;
84590defe5SGuenter Roeck 	case PMBUS_VIRT_READ_POUT_MAX:
85590defe5SGuenter Roeck 		if (data->id != max34446)
86590defe5SGuenter Roeck 			return -ENXIO;
87590defe5SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
88590defe5SGuenter Roeck 					   MAX34446_MFR_POUT_PEAK);
89590defe5SGuenter Roeck 		break;
90590defe5SGuenter Roeck 	case PMBUS_VIRT_READ_TEMP_AVG:
91*50115ac9SGuenter Roeck 		if (data->id != max34446 && data->id != max34460 &&
92*50115ac9SGuenter Roeck 		    data->id != max34461)
93590defe5SGuenter Roeck 			return -ENXIO;
94590defe5SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
95590defe5SGuenter Roeck 					   MAX34446_MFR_TEMPERATURE_AVG);
96590defe5SGuenter Roeck 		break;
9798591dbeSGuenter Roeck 	case PMBUS_VIRT_READ_TEMP_MAX:
9898591dbeSGuenter Roeck 		ret = pmbus_read_word_data(client, page,
9998591dbeSGuenter Roeck 					   MAX34440_MFR_TEMPERATURE_PEAK);
10098591dbeSGuenter Roeck 		break;
101590defe5SGuenter Roeck 	case PMBUS_VIRT_RESET_POUT_HISTORY:
102590defe5SGuenter Roeck 		if (data->id != max34446)
103590defe5SGuenter Roeck 			return -ENXIO;
104590defe5SGuenter Roeck 		ret = 0;
105590defe5SGuenter Roeck 		break;
10698591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_VOUT_HISTORY:
10798591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_IOUT_HISTORY:
10898591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_TEMP_HISTORY:
10998591dbeSGuenter Roeck 		ret = 0;
11098591dbeSGuenter Roeck 		break;
11198591dbeSGuenter Roeck 	default:
11298591dbeSGuenter Roeck 		ret = -ENODATA;
11398591dbeSGuenter Roeck 		break;
11498591dbeSGuenter Roeck 	}
11598591dbeSGuenter Roeck 	return ret;
11698591dbeSGuenter Roeck }
11798591dbeSGuenter Roeck 
11898591dbeSGuenter Roeck static int max34440_write_word_data(struct i2c_client *client, int page,
11998591dbeSGuenter Roeck 				    int reg, u16 word)
12098591dbeSGuenter Roeck {
121590defe5SGuenter Roeck 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
122590defe5SGuenter Roeck 	const struct max34440_data *data = to_max34440_data(info);
12398591dbeSGuenter Roeck 	int ret;
12498591dbeSGuenter Roeck 
12598591dbeSGuenter Roeck 	switch (reg) {
126590defe5SGuenter Roeck 	case PMBUS_VIRT_RESET_POUT_HISTORY:
127590defe5SGuenter Roeck 		ret = pmbus_write_word_data(client, page,
128590defe5SGuenter Roeck 					    MAX34446_MFR_POUT_PEAK, 0);
129590defe5SGuenter Roeck 		if (ret)
130590defe5SGuenter Roeck 			break;
131590defe5SGuenter Roeck 		ret = pmbus_write_word_data(client, page,
132590defe5SGuenter Roeck 					    MAX34446_MFR_POUT_AVG, 0);
133590defe5SGuenter Roeck 		break;
13498591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_VOUT_HISTORY:
13598591dbeSGuenter Roeck 		ret = pmbus_write_word_data(client, page,
13656aad5d1SGuenter Roeck 					    MAX34440_MFR_VOUT_MIN, 0x7fff);
13756aad5d1SGuenter Roeck 		if (ret)
13856aad5d1SGuenter Roeck 			break;
13956aad5d1SGuenter Roeck 		ret = pmbus_write_word_data(client, page,
14098591dbeSGuenter Roeck 					    MAX34440_MFR_VOUT_PEAK, 0);
14198591dbeSGuenter Roeck 		break;
14298591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_IOUT_HISTORY:
14398591dbeSGuenter Roeck 		ret = pmbus_write_word_data(client, page,
14498591dbeSGuenter Roeck 					    MAX34440_MFR_IOUT_PEAK, 0);
145590defe5SGuenter Roeck 		if (!ret && data->id == max34446)
146590defe5SGuenter Roeck 			ret = pmbus_write_word_data(client, page,
147590defe5SGuenter Roeck 					MAX34446_MFR_IOUT_AVG, 0);
148590defe5SGuenter Roeck 
14998591dbeSGuenter Roeck 		break;
15098591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_TEMP_HISTORY:
15198591dbeSGuenter Roeck 		ret = pmbus_write_word_data(client, page,
15298591dbeSGuenter Roeck 					    MAX34440_MFR_TEMPERATURE_PEAK,
153dc91ad8eSGuenter Roeck 					    0x8000);
154590defe5SGuenter Roeck 		if (!ret && data->id == max34446)
155590defe5SGuenter Roeck 			ret = pmbus_write_word_data(client, page,
156590defe5SGuenter Roeck 					MAX34446_MFR_TEMPERATURE_AVG, 0);
15798591dbeSGuenter Roeck 		break;
15898591dbeSGuenter Roeck 	default:
15998591dbeSGuenter Roeck 		ret = -ENODATA;
16098591dbeSGuenter Roeck 		break;
16198591dbeSGuenter Roeck 	}
16298591dbeSGuenter Roeck 	return ret;
16398591dbeSGuenter Roeck }
16498591dbeSGuenter Roeck 
1659d2ecfb7SGuenter Roeck static int max34440_read_byte_data(struct i2c_client *client, int page, int reg)
1669d2ecfb7SGuenter Roeck {
167da8e48abSGuenter Roeck 	int ret = 0;
1689d2ecfb7SGuenter Roeck 	int mfg_status;
1699d2ecfb7SGuenter Roeck 
170da8e48abSGuenter Roeck 	if (page >= 0) {
1719d2ecfb7SGuenter Roeck 		ret = pmbus_set_page(client, page);
1729d2ecfb7SGuenter Roeck 		if (ret < 0)
1739d2ecfb7SGuenter Roeck 			return ret;
174da8e48abSGuenter Roeck 	}
1759d2ecfb7SGuenter Roeck 
1769d2ecfb7SGuenter Roeck 	switch (reg) {
1779d2ecfb7SGuenter Roeck 	case PMBUS_STATUS_IOUT:
1789d2ecfb7SGuenter Roeck 		mfg_status = pmbus_read_word_data(client, 0,
1799d2ecfb7SGuenter Roeck 						  PMBUS_STATUS_MFR_SPECIFIC);
1809d2ecfb7SGuenter Roeck 		if (mfg_status < 0)
1819d2ecfb7SGuenter Roeck 			return mfg_status;
1829d2ecfb7SGuenter Roeck 		if (mfg_status & MAX34440_STATUS_OC_WARN)
1839d2ecfb7SGuenter Roeck 			ret |= PB_IOUT_OC_WARNING;
1849d2ecfb7SGuenter Roeck 		if (mfg_status & MAX34440_STATUS_OC_FAULT)
1859d2ecfb7SGuenter Roeck 			ret |= PB_IOUT_OC_FAULT;
1869d2ecfb7SGuenter Roeck 		break;
1879d2ecfb7SGuenter Roeck 	case PMBUS_STATUS_TEMPERATURE:
1889d2ecfb7SGuenter Roeck 		mfg_status = pmbus_read_word_data(client, 0,
1899d2ecfb7SGuenter Roeck 						  PMBUS_STATUS_MFR_SPECIFIC);
1909d2ecfb7SGuenter Roeck 		if (mfg_status < 0)
1919d2ecfb7SGuenter Roeck 			return mfg_status;
1929d2ecfb7SGuenter Roeck 		if (mfg_status & MAX34440_STATUS_OT_WARN)
1939d2ecfb7SGuenter Roeck 			ret |= PB_TEMP_OT_WARNING;
1949d2ecfb7SGuenter Roeck 		if (mfg_status & MAX34440_STATUS_OT_FAULT)
1959d2ecfb7SGuenter Roeck 			ret |= PB_TEMP_OT_FAULT;
1969d2ecfb7SGuenter Roeck 		break;
1979d2ecfb7SGuenter Roeck 	default:
1989d2ecfb7SGuenter Roeck 		ret = -ENODATA;
1999d2ecfb7SGuenter Roeck 		break;
2009d2ecfb7SGuenter Roeck 	}
2019d2ecfb7SGuenter Roeck 	return ret;
2029d2ecfb7SGuenter Roeck }
2039d2ecfb7SGuenter Roeck 
2049d2ecfb7SGuenter Roeck static struct pmbus_driver_info max34440_info[] = {
2059d2ecfb7SGuenter Roeck 	[max34440] = {
2069d2ecfb7SGuenter Roeck 		.pages = 14,
2071061d851SGuenter Roeck 		.format[PSC_VOLTAGE_IN] = direct,
2081061d851SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
2091061d851SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
2101061d851SGuenter Roeck 		.format[PSC_CURRENT_OUT] = direct,
2119d2ecfb7SGuenter Roeck 		.m[PSC_VOLTAGE_IN] = 1,
2129d2ecfb7SGuenter Roeck 		.b[PSC_VOLTAGE_IN] = 0,
2139d2ecfb7SGuenter Roeck 		.R[PSC_VOLTAGE_IN] = 3,	    /* R = 0 in datasheet reflects mV */
2149d2ecfb7SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
2159d2ecfb7SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
2169d2ecfb7SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,    /* R = 0 in datasheet reflects mV */
2179d2ecfb7SGuenter Roeck 		.m[PSC_CURRENT_OUT] = 1,
2189d2ecfb7SGuenter Roeck 		.b[PSC_CURRENT_OUT] = 0,
2199d2ecfb7SGuenter Roeck 		.R[PSC_CURRENT_OUT] = 3,    /* R = 0 in datasheet reflects mA */
2209d2ecfb7SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
2219d2ecfb7SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
2229d2ecfb7SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
2239d2ecfb7SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2249d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2259d2ecfb7SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2269d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2279d2ecfb7SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2289d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2299d2ecfb7SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2309d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2319d2ecfb7SGuenter Roeck 		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2329d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2339d2ecfb7SGuenter Roeck 		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2349d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2359d2ecfb7SGuenter Roeck 		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2369d2ecfb7SGuenter Roeck 		.func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2379d2ecfb7SGuenter Roeck 		.func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2389d2ecfb7SGuenter Roeck 		.func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2399d2ecfb7SGuenter Roeck 		.func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2409d2ecfb7SGuenter Roeck 		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2419d2ecfb7SGuenter Roeck 		.func[12] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2429d2ecfb7SGuenter Roeck 		.func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2439d2ecfb7SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
24498591dbeSGuenter Roeck 		.read_word_data = max34440_read_word_data,
24598591dbeSGuenter Roeck 		.write_word_data = max34440_write_word_data,
2469d2ecfb7SGuenter Roeck 	},
2479d2ecfb7SGuenter Roeck 	[max34441] = {
2489d2ecfb7SGuenter Roeck 		.pages = 12,
2491061d851SGuenter Roeck 		.format[PSC_VOLTAGE_IN] = direct,
2501061d851SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
2511061d851SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
2521061d851SGuenter Roeck 		.format[PSC_CURRENT_OUT] = direct,
2531061d851SGuenter Roeck 		.format[PSC_FAN] = direct,
2549d2ecfb7SGuenter Roeck 		.m[PSC_VOLTAGE_IN] = 1,
2559d2ecfb7SGuenter Roeck 		.b[PSC_VOLTAGE_IN] = 0,
2569d2ecfb7SGuenter Roeck 		.R[PSC_VOLTAGE_IN] = 3,
2579d2ecfb7SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
2589d2ecfb7SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
2599d2ecfb7SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,
2609d2ecfb7SGuenter Roeck 		.m[PSC_CURRENT_OUT] = 1,
2619d2ecfb7SGuenter Roeck 		.b[PSC_CURRENT_OUT] = 0,
2629d2ecfb7SGuenter Roeck 		.R[PSC_CURRENT_OUT] = 3,
2639d2ecfb7SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
2649d2ecfb7SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
2659d2ecfb7SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
2669d2ecfb7SGuenter Roeck 		.m[PSC_FAN] = 1,
2679d2ecfb7SGuenter Roeck 		.b[PSC_FAN] = 0,
2689d2ecfb7SGuenter Roeck 		.R[PSC_FAN] = 0,
2699d2ecfb7SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2709d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2719d2ecfb7SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2729d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2739d2ecfb7SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2749d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2759d2ecfb7SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2769d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2779d2ecfb7SGuenter Roeck 		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2789d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2799d2ecfb7SGuenter Roeck 		.func[5] = PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
2809d2ecfb7SGuenter Roeck 		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2819d2ecfb7SGuenter Roeck 		.func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2829d2ecfb7SGuenter Roeck 		.func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2839d2ecfb7SGuenter Roeck 		.func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2849d2ecfb7SGuenter Roeck 		.func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2859d2ecfb7SGuenter Roeck 		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2869d2ecfb7SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
28798591dbeSGuenter Roeck 		.read_word_data = max34440_read_word_data,
28898591dbeSGuenter Roeck 		.write_word_data = max34440_write_word_data,
2899d2ecfb7SGuenter Roeck 	},
290590defe5SGuenter Roeck 	[max34446] = {
291590defe5SGuenter Roeck 		.pages = 7,
292590defe5SGuenter Roeck 		.format[PSC_VOLTAGE_IN] = direct,
293590defe5SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
294590defe5SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
295590defe5SGuenter Roeck 		.format[PSC_CURRENT_OUT] = direct,
296590defe5SGuenter Roeck 		.format[PSC_POWER] = direct,
297590defe5SGuenter Roeck 		.m[PSC_VOLTAGE_IN] = 1,
298590defe5SGuenter Roeck 		.b[PSC_VOLTAGE_IN] = 0,
299590defe5SGuenter Roeck 		.R[PSC_VOLTAGE_IN] = 3,
300590defe5SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
301590defe5SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
302590defe5SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,
303590defe5SGuenter Roeck 		.m[PSC_CURRENT_OUT] = 1,
304590defe5SGuenter Roeck 		.b[PSC_CURRENT_OUT] = 0,
305590defe5SGuenter Roeck 		.R[PSC_CURRENT_OUT] = 3,
306590defe5SGuenter Roeck 		.m[PSC_POWER] = 1,
307590defe5SGuenter Roeck 		.b[PSC_POWER] = 0,
308590defe5SGuenter Roeck 		.R[PSC_POWER] = 3,
309590defe5SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
310590defe5SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
311590defe5SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
312590defe5SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
313590defe5SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
314590defe5SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
315590defe5SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
316590defe5SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
317590defe5SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
318590defe5SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
319590defe5SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
320590defe5SGuenter Roeck 		.func[4] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
321590defe5SGuenter Roeck 		.func[5] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
322590defe5SGuenter Roeck 		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
323590defe5SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
324590defe5SGuenter Roeck 		.read_word_data = max34440_read_word_data,
325590defe5SGuenter Roeck 		.write_word_data = max34440_write_word_data,
326590defe5SGuenter Roeck 	},
327*50115ac9SGuenter Roeck 	[max34460] = {
328*50115ac9SGuenter Roeck 		.pages = 18,
329*50115ac9SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
330*50115ac9SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
331*50115ac9SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
332*50115ac9SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
333*50115ac9SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,
334*50115ac9SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
335*50115ac9SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
336*50115ac9SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
337*50115ac9SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
338*50115ac9SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
339*50115ac9SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
340*50115ac9SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
341*50115ac9SGuenter Roeck 		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
342*50115ac9SGuenter Roeck 		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
343*50115ac9SGuenter Roeck 		.func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
344*50115ac9SGuenter Roeck 		.func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
345*50115ac9SGuenter Roeck 		.func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
346*50115ac9SGuenter Roeck 		.func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
347*50115ac9SGuenter Roeck 		.func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
348*50115ac9SGuenter Roeck 		.func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
349*50115ac9SGuenter Roeck 		.func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
350*50115ac9SGuenter Roeck 		.func[14] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
351*50115ac9SGuenter Roeck 		.func[15] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
352*50115ac9SGuenter Roeck 		.func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
353*50115ac9SGuenter Roeck 		.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
354*50115ac9SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
355*50115ac9SGuenter Roeck 		.read_word_data = max34440_read_word_data,
356*50115ac9SGuenter Roeck 		.write_word_data = max34440_write_word_data,
357*50115ac9SGuenter Roeck 	},
358*50115ac9SGuenter Roeck 	[max34461] = {
359*50115ac9SGuenter Roeck 		.pages = 23,
360*50115ac9SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
361*50115ac9SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
362*50115ac9SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
363*50115ac9SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
364*50115ac9SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,
365*50115ac9SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
366*50115ac9SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
367*50115ac9SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
368*50115ac9SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
369*50115ac9SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
370*50115ac9SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
371*50115ac9SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
372*50115ac9SGuenter Roeck 		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
373*50115ac9SGuenter Roeck 		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
374*50115ac9SGuenter Roeck 		.func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
375*50115ac9SGuenter Roeck 		.func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
376*50115ac9SGuenter Roeck 		.func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
377*50115ac9SGuenter Roeck 		.func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
378*50115ac9SGuenter Roeck 		.func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
379*50115ac9SGuenter Roeck 		.func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
380*50115ac9SGuenter Roeck 		.func[12] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
381*50115ac9SGuenter Roeck 		.func[13] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
382*50115ac9SGuenter Roeck 		.func[14] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
383*50115ac9SGuenter Roeck 		.func[15] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
384*50115ac9SGuenter Roeck 		/* page 16 is reserved */
385*50115ac9SGuenter Roeck 		.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
386*50115ac9SGuenter Roeck 		.func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
387*50115ac9SGuenter Roeck 		.func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
388*50115ac9SGuenter Roeck 		.func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
389*50115ac9SGuenter Roeck 		.func[21] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
390*50115ac9SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
391*50115ac9SGuenter Roeck 		.read_word_data = max34440_read_word_data,
392*50115ac9SGuenter Roeck 		.write_word_data = max34440_write_word_data,
393*50115ac9SGuenter Roeck 	},
3949d2ecfb7SGuenter Roeck };
3959d2ecfb7SGuenter Roeck 
3969d2ecfb7SGuenter Roeck static int max34440_probe(struct i2c_client *client,
3979d2ecfb7SGuenter Roeck 			  const struct i2c_device_id *id)
3989d2ecfb7SGuenter Roeck {
399590defe5SGuenter Roeck 	struct max34440_data *data;
400590defe5SGuenter Roeck 
401590defe5SGuenter Roeck 	data = devm_kzalloc(&client->dev, sizeof(struct max34440_data),
402590defe5SGuenter Roeck 			    GFP_KERNEL);
403590defe5SGuenter Roeck 	if (!data)
404590defe5SGuenter Roeck 		return -ENOMEM;
405590defe5SGuenter Roeck 	data->id = id->driver_data;
406590defe5SGuenter Roeck 	data->info = max34440_info[id->driver_data];
407590defe5SGuenter Roeck 
408590defe5SGuenter Roeck 	return pmbus_do_probe(client, id, &data->info);
4099d2ecfb7SGuenter Roeck }
4109d2ecfb7SGuenter Roeck 
4119d2ecfb7SGuenter Roeck static const struct i2c_device_id max34440_id[] = {
4129d2ecfb7SGuenter Roeck 	{"max34440", max34440},
4139d2ecfb7SGuenter Roeck 	{"max34441", max34441},
414590defe5SGuenter Roeck 	{"max34446", max34446},
415*50115ac9SGuenter Roeck 	{"max34460", max34460},
416*50115ac9SGuenter Roeck 	{"max34461", max34461},
4179d2ecfb7SGuenter Roeck 	{}
4189d2ecfb7SGuenter Roeck };
4199d2ecfb7SGuenter Roeck MODULE_DEVICE_TABLE(i2c, max34440_id);
4209d2ecfb7SGuenter Roeck 
4219d2ecfb7SGuenter Roeck /* This is the driver that will be inserted */
4229d2ecfb7SGuenter Roeck static struct i2c_driver max34440_driver = {
4239d2ecfb7SGuenter Roeck 	.driver = {
4249d2ecfb7SGuenter Roeck 		   .name = "max34440",
4259d2ecfb7SGuenter Roeck 		   },
4269d2ecfb7SGuenter Roeck 	.probe = max34440_probe,
427dd285ad7SGuenter Roeck 	.remove = pmbus_do_remove,
4289d2ecfb7SGuenter Roeck 	.id_table = max34440_id,
4299d2ecfb7SGuenter Roeck };
4309d2ecfb7SGuenter Roeck 
431f0967eeaSAxel Lin module_i2c_driver(max34440_driver);
4329d2ecfb7SGuenter Roeck 
4339d2ecfb7SGuenter Roeck MODULE_AUTHOR("Guenter Roeck");
4349d2ecfb7SGuenter Roeck MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441");
4359d2ecfb7SGuenter Roeck MODULE_LICENSE("GPL");
436