xref: /linux/drivers/hwmon/pmbus/max34440.c (revision 2c052d4280ca48fddc7a9ffd2329ada3628cab86)
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 
22*2c052d42SGuenter 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 
3050115ac9SGuenter Roeck enum chips { max34440, max34441, max34446, 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 
42*2c052d42SGuenter Roeck #define MAX34440_STATUS_OC_WARN		BIT(0)
43*2c052d42SGuenter Roeck #define MAX34440_STATUS_OC_FAULT	BIT(1)
44*2c052d42SGuenter Roeck #define MAX34440_STATUS_OT_FAULT	BIT(5)
45*2c052d42SGuenter Roeck #define MAX34440_STATUS_OT_WARN		BIT(6)
469d2ecfb7SGuenter Roeck 
47590defe5SGuenter Roeck struct max34440_data {
48590defe5SGuenter Roeck 	int id;
49590defe5SGuenter Roeck 	struct pmbus_driver_info info;
50590defe5SGuenter Roeck };
51590defe5SGuenter Roeck 
52590defe5SGuenter Roeck #define to_max34440_data(x)  container_of(x, struct max34440_data, info)
53590defe5SGuenter Roeck 
5498591dbeSGuenter Roeck static int max34440_read_word_data(struct i2c_client *client, int page, int reg)
5598591dbeSGuenter Roeck {
5698591dbeSGuenter Roeck 	int ret;
57590defe5SGuenter Roeck 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
58590defe5SGuenter Roeck 	const struct max34440_data *data = to_max34440_data(info);
5998591dbeSGuenter Roeck 
6098591dbeSGuenter Roeck 	switch (reg) {
6156aad5d1SGuenter Roeck 	case PMBUS_VIRT_READ_VOUT_MIN:
6256aad5d1SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
6356aad5d1SGuenter Roeck 					   MAX34440_MFR_VOUT_MIN);
6456aad5d1SGuenter Roeck 		break;
6598591dbeSGuenter Roeck 	case PMBUS_VIRT_READ_VOUT_MAX:
6698591dbeSGuenter Roeck 		ret = pmbus_read_word_data(client, page,
6798591dbeSGuenter Roeck 					   MAX34440_MFR_VOUT_PEAK);
6898591dbeSGuenter Roeck 		break;
69590defe5SGuenter Roeck 	case PMBUS_VIRT_READ_IOUT_AVG:
70590defe5SGuenter Roeck 		if (data->id != max34446)
71590defe5SGuenter Roeck 			return -ENXIO;
72590defe5SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
73590defe5SGuenter Roeck 					   MAX34446_MFR_IOUT_AVG);
74590defe5SGuenter Roeck 		break;
7598591dbeSGuenter Roeck 	case PMBUS_VIRT_READ_IOUT_MAX:
7698591dbeSGuenter Roeck 		ret = pmbus_read_word_data(client, page,
7798591dbeSGuenter Roeck 					   MAX34440_MFR_IOUT_PEAK);
7898591dbeSGuenter Roeck 		break;
79590defe5SGuenter Roeck 	case PMBUS_VIRT_READ_POUT_AVG:
80590defe5SGuenter Roeck 		if (data->id != max34446)
81590defe5SGuenter Roeck 			return -ENXIO;
82590defe5SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
83590defe5SGuenter Roeck 					   MAX34446_MFR_POUT_AVG);
84590defe5SGuenter Roeck 		break;
85590defe5SGuenter Roeck 	case PMBUS_VIRT_READ_POUT_MAX:
86590defe5SGuenter Roeck 		if (data->id != max34446)
87590defe5SGuenter Roeck 			return -ENXIO;
88590defe5SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
89590defe5SGuenter Roeck 					   MAX34446_MFR_POUT_PEAK);
90590defe5SGuenter Roeck 		break;
91590defe5SGuenter Roeck 	case PMBUS_VIRT_READ_TEMP_AVG:
9250115ac9SGuenter Roeck 		if (data->id != max34446 && data->id != max34460 &&
9350115ac9SGuenter Roeck 		    data->id != max34461)
94590defe5SGuenter Roeck 			return -ENXIO;
95590defe5SGuenter Roeck 		ret = pmbus_read_word_data(client, page,
96590defe5SGuenter Roeck 					   MAX34446_MFR_TEMPERATURE_AVG);
97590defe5SGuenter Roeck 		break;
9898591dbeSGuenter Roeck 	case PMBUS_VIRT_READ_TEMP_MAX:
9998591dbeSGuenter Roeck 		ret = pmbus_read_word_data(client, page,
10098591dbeSGuenter Roeck 					   MAX34440_MFR_TEMPERATURE_PEAK);
10198591dbeSGuenter Roeck 		break;
102590defe5SGuenter Roeck 	case PMBUS_VIRT_RESET_POUT_HISTORY:
103590defe5SGuenter Roeck 		if (data->id != max34446)
104590defe5SGuenter Roeck 			return -ENXIO;
105590defe5SGuenter Roeck 		ret = 0;
106590defe5SGuenter Roeck 		break;
10798591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_VOUT_HISTORY:
10898591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_IOUT_HISTORY:
10998591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_TEMP_HISTORY:
11098591dbeSGuenter Roeck 		ret = 0;
11198591dbeSGuenter Roeck 		break;
11298591dbeSGuenter Roeck 	default:
11398591dbeSGuenter Roeck 		ret = -ENODATA;
11498591dbeSGuenter Roeck 		break;
11598591dbeSGuenter Roeck 	}
11698591dbeSGuenter Roeck 	return ret;
11798591dbeSGuenter Roeck }
11898591dbeSGuenter Roeck 
11998591dbeSGuenter Roeck static int max34440_write_word_data(struct i2c_client *client, int page,
12098591dbeSGuenter Roeck 				    int reg, u16 word)
12198591dbeSGuenter Roeck {
122590defe5SGuenter Roeck 	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
123590defe5SGuenter Roeck 	const struct max34440_data *data = to_max34440_data(info);
12498591dbeSGuenter Roeck 	int ret;
12598591dbeSGuenter Roeck 
12698591dbeSGuenter Roeck 	switch (reg) {
127590defe5SGuenter Roeck 	case PMBUS_VIRT_RESET_POUT_HISTORY:
128590defe5SGuenter Roeck 		ret = pmbus_write_word_data(client, page,
129590defe5SGuenter Roeck 					    MAX34446_MFR_POUT_PEAK, 0);
130590defe5SGuenter Roeck 		if (ret)
131590defe5SGuenter Roeck 			break;
132590defe5SGuenter Roeck 		ret = pmbus_write_word_data(client, page,
133590defe5SGuenter Roeck 					    MAX34446_MFR_POUT_AVG, 0);
134590defe5SGuenter Roeck 		break;
13598591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_VOUT_HISTORY:
13698591dbeSGuenter Roeck 		ret = pmbus_write_word_data(client, page,
13756aad5d1SGuenter Roeck 					    MAX34440_MFR_VOUT_MIN, 0x7fff);
13856aad5d1SGuenter Roeck 		if (ret)
13956aad5d1SGuenter Roeck 			break;
14056aad5d1SGuenter Roeck 		ret = pmbus_write_word_data(client, page,
14198591dbeSGuenter Roeck 					    MAX34440_MFR_VOUT_PEAK, 0);
14298591dbeSGuenter Roeck 		break;
14398591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_IOUT_HISTORY:
14498591dbeSGuenter Roeck 		ret = pmbus_write_word_data(client, page,
14598591dbeSGuenter Roeck 					    MAX34440_MFR_IOUT_PEAK, 0);
146590defe5SGuenter Roeck 		if (!ret && data->id == max34446)
147590defe5SGuenter Roeck 			ret = pmbus_write_word_data(client, page,
148590defe5SGuenter Roeck 					MAX34446_MFR_IOUT_AVG, 0);
149590defe5SGuenter Roeck 
15098591dbeSGuenter Roeck 		break;
15198591dbeSGuenter Roeck 	case PMBUS_VIRT_RESET_TEMP_HISTORY:
15298591dbeSGuenter Roeck 		ret = pmbus_write_word_data(client, page,
15398591dbeSGuenter Roeck 					    MAX34440_MFR_TEMPERATURE_PEAK,
154dc91ad8eSGuenter Roeck 					    0x8000);
155590defe5SGuenter Roeck 		if (!ret && data->id == max34446)
156590defe5SGuenter Roeck 			ret = pmbus_write_word_data(client, page,
157590defe5SGuenter Roeck 					MAX34446_MFR_TEMPERATURE_AVG, 0);
15898591dbeSGuenter Roeck 		break;
15998591dbeSGuenter Roeck 	default:
16098591dbeSGuenter Roeck 		ret = -ENODATA;
16198591dbeSGuenter Roeck 		break;
16298591dbeSGuenter Roeck 	}
16398591dbeSGuenter Roeck 	return ret;
16498591dbeSGuenter Roeck }
16598591dbeSGuenter Roeck 
1669d2ecfb7SGuenter Roeck static int max34440_read_byte_data(struct i2c_client *client, int page, int reg)
1679d2ecfb7SGuenter Roeck {
168da8e48abSGuenter Roeck 	int ret = 0;
1699d2ecfb7SGuenter Roeck 	int mfg_status;
1709d2ecfb7SGuenter Roeck 
171da8e48abSGuenter Roeck 	if (page >= 0) {
1729d2ecfb7SGuenter Roeck 		ret = pmbus_set_page(client, page);
1739d2ecfb7SGuenter Roeck 		if (ret < 0)
1749d2ecfb7SGuenter Roeck 			return ret;
175da8e48abSGuenter Roeck 	}
1769d2ecfb7SGuenter Roeck 
1779d2ecfb7SGuenter Roeck 	switch (reg) {
1789d2ecfb7SGuenter Roeck 	case PMBUS_STATUS_IOUT:
1799d2ecfb7SGuenter Roeck 		mfg_status = pmbus_read_word_data(client, 0,
1809d2ecfb7SGuenter Roeck 						  PMBUS_STATUS_MFR_SPECIFIC);
1819d2ecfb7SGuenter Roeck 		if (mfg_status < 0)
1829d2ecfb7SGuenter Roeck 			return mfg_status;
1839d2ecfb7SGuenter Roeck 		if (mfg_status & MAX34440_STATUS_OC_WARN)
1849d2ecfb7SGuenter Roeck 			ret |= PB_IOUT_OC_WARNING;
1859d2ecfb7SGuenter Roeck 		if (mfg_status & MAX34440_STATUS_OC_FAULT)
1869d2ecfb7SGuenter Roeck 			ret |= PB_IOUT_OC_FAULT;
1879d2ecfb7SGuenter Roeck 		break;
1889d2ecfb7SGuenter Roeck 	case PMBUS_STATUS_TEMPERATURE:
1899d2ecfb7SGuenter Roeck 		mfg_status = pmbus_read_word_data(client, 0,
1909d2ecfb7SGuenter Roeck 						  PMBUS_STATUS_MFR_SPECIFIC);
1919d2ecfb7SGuenter Roeck 		if (mfg_status < 0)
1929d2ecfb7SGuenter Roeck 			return mfg_status;
1939d2ecfb7SGuenter Roeck 		if (mfg_status & MAX34440_STATUS_OT_WARN)
1949d2ecfb7SGuenter Roeck 			ret |= PB_TEMP_OT_WARNING;
1959d2ecfb7SGuenter Roeck 		if (mfg_status & MAX34440_STATUS_OT_FAULT)
1969d2ecfb7SGuenter Roeck 			ret |= PB_TEMP_OT_FAULT;
1979d2ecfb7SGuenter Roeck 		break;
1989d2ecfb7SGuenter Roeck 	default:
1999d2ecfb7SGuenter Roeck 		ret = -ENODATA;
2009d2ecfb7SGuenter Roeck 		break;
2019d2ecfb7SGuenter Roeck 	}
2029d2ecfb7SGuenter Roeck 	return ret;
2039d2ecfb7SGuenter Roeck }
2049d2ecfb7SGuenter Roeck 
2059d2ecfb7SGuenter Roeck static struct pmbus_driver_info max34440_info[] = {
2069d2ecfb7SGuenter Roeck 	[max34440] = {
2079d2ecfb7SGuenter Roeck 		.pages = 14,
2081061d851SGuenter Roeck 		.format[PSC_VOLTAGE_IN] = direct,
2091061d851SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
2101061d851SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
2111061d851SGuenter Roeck 		.format[PSC_CURRENT_OUT] = direct,
2129d2ecfb7SGuenter Roeck 		.m[PSC_VOLTAGE_IN] = 1,
2139d2ecfb7SGuenter Roeck 		.b[PSC_VOLTAGE_IN] = 0,
2149d2ecfb7SGuenter Roeck 		.R[PSC_VOLTAGE_IN] = 3,	    /* R = 0 in datasheet reflects mV */
2159d2ecfb7SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
2169d2ecfb7SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
2179d2ecfb7SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,    /* R = 0 in datasheet reflects mV */
2189d2ecfb7SGuenter Roeck 		.m[PSC_CURRENT_OUT] = 1,
2199d2ecfb7SGuenter Roeck 		.b[PSC_CURRENT_OUT] = 0,
2209d2ecfb7SGuenter Roeck 		.R[PSC_CURRENT_OUT] = 3,    /* R = 0 in datasheet reflects mA */
2219d2ecfb7SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
2229d2ecfb7SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
2239d2ecfb7SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
2249d2ecfb7SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2259d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2269d2ecfb7SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2279d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2289d2ecfb7SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2299d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2309d2ecfb7SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2319d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2329d2ecfb7SGuenter Roeck 		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2339d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2349d2ecfb7SGuenter Roeck 		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2359d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2369d2ecfb7SGuenter Roeck 		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2379d2ecfb7SGuenter Roeck 		.func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2389d2ecfb7SGuenter Roeck 		.func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2399d2ecfb7SGuenter Roeck 		.func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2409d2ecfb7SGuenter Roeck 		.func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2419d2ecfb7SGuenter Roeck 		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2429d2ecfb7SGuenter Roeck 		.func[12] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2439d2ecfb7SGuenter Roeck 		.func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2449d2ecfb7SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
24598591dbeSGuenter Roeck 		.read_word_data = max34440_read_word_data,
24698591dbeSGuenter Roeck 		.write_word_data = max34440_write_word_data,
2479d2ecfb7SGuenter Roeck 	},
2489d2ecfb7SGuenter Roeck 	[max34441] = {
2499d2ecfb7SGuenter Roeck 		.pages = 12,
2501061d851SGuenter Roeck 		.format[PSC_VOLTAGE_IN] = direct,
2511061d851SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
2521061d851SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
2531061d851SGuenter Roeck 		.format[PSC_CURRENT_OUT] = direct,
2541061d851SGuenter Roeck 		.format[PSC_FAN] = direct,
2559d2ecfb7SGuenter Roeck 		.m[PSC_VOLTAGE_IN] = 1,
2569d2ecfb7SGuenter Roeck 		.b[PSC_VOLTAGE_IN] = 0,
2579d2ecfb7SGuenter Roeck 		.R[PSC_VOLTAGE_IN] = 3,
2589d2ecfb7SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
2599d2ecfb7SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
2609d2ecfb7SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,
2619d2ecfb7SGuenter Roeck 		.m[PSC_CURRENT_OUT] = 1,
2629d2ecfb7SGuenter Roeck 		.b[PSC_CURRENT_OUT] = 0,
2639d2ecfb7SGuenter Roeck 		.R[PSC_CURRENT_OUT] = 3,
2649d2ecfb7SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
2659d2ecfb7SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
2669d2ecfb7SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
2679d2ecfb7SGuenter Roeck 		.m[PSC_FAN] = 1,
2689d2ecfb7SGuenter Roeck 		.b[PSC_FAN] = 0,
2699d2ecfb7SGuenter Roeck 		.R[PSC_FAN] = 0,
2709d2ecfb7SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2719d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2729d2ecfb7SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2739d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2749d2ecfb7SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2759d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2769d2ecfb7SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2779d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2789d2ecfb7SGuenter Roeck 		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
2799d2ecfb7SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
2809d2ecfb7SGuenter Roeck 		.func[5] = PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12,
2819d2ecfb7SGuenter Roeck 		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2829d2ecfb7SGuenter Roeck 		.func[7] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2839d2ecfb7SGuenter Roeck 		.func[8] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2849d2ecfb7SGuenter Roeck 		.func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2859d2ecfb7SGuenter Roeck 		.func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2869d2ecfb7SGuenter Roeck 		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
2879d2ecfb7SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
28898591dbeSGuenter Roeck 		.read_word_data = max34440_read_word_data,
28998591dbeSGuenter Roeck 		.write_word_data = max34440_write_word_data,
2909d2ecfb7SGuenter Roeck 	},
291590defe5SGuenter Roeck 	[max34446] = {
292590defe5SGuenter Roeck 		.pages = 7,
293590defe5SGuenter Roeck 		.format[PSC_VOLTAGE_IN] = direct,
294590defe5SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
295590defe5SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
296590defe5SGuenter Roeck 		.format[PSC_CURRENT_OUT] = direct,
297590defe5SGuenter Roeck 		.format[PSC_POWER] = direct,
298590defe5SGuenter Roeck 		.m[PSC_VOLTAGE_IN] = 1,
299590defe5SGuenter Roeck 		.b[PSC_VOLTAGE_IN] = 0,
300590defe5SGuenter Roeck 		.R[PSC_VOLTAGE_IN] = 3,
301590defe5SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
302590defe5SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
303590defe5SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,
304590defe5SGuenter Roeck 		.m[PSC_CURRENT_OUT] = 1,
305590defe5SGuenter Roeck 		.b[PSC_CURRENT_OUT] = 0,
306590defe5SGuenter Roeck 		.R[PSC_CURRENT_OUT] = 3,
307590defe5SGuenter Roeck 		.m[PSC_POWER] = 1,
308590defe5SGuenter Roeck 		.b[PSC_POWER] = 0,
309590defe5SGuenter Roeck 		.R[PSC_POWER] = 3,
310590defe5SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
311590defe5SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
312590defe5SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
313590defe5SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
314590defe5SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
315590defe5SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
316590defe5SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
317590defe5SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
318590defe5SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
319590defe5SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
320590defe5SGuenter Roeck 		  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
321590defe5SGuenter Roeck 		.func[4] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
322590defe5SGuenter Roeck 		.func[5] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
323590defe5SGuenter Roeck 		.func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
324590defe5SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
325590defe5SGuenter Roeck 		.read_word_data = max34440_read_word_data,
326590defe5SGuenter Roeck 		.write_word_data = max34440_write_word_data,
327590defe5SGuenter Roeck 	},
32850115ac9SGuenter Roeck 	[max34460] = {
32950115ac9SGuenter Roeck 		.pages = 18,
33050115ac9SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
33150115ac9SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
33250115ac9SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
33350115ac9SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
33450115ac9SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,
33550115ac9SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
33650115ac9SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
33750115ac9SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
33850115ac9SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
33950115ac9SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
34050115ac9SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
34150115ac9SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
34250115ac9SGuenter Roeck 		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
34350115ac9SGuenter Roeck 		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
34450115ac9SGuenter Roeck 		.func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
34550115ac9SGuenter Roeck 		.func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
34650115ac9SGuenter Roeck 		.func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
34750115ac9SGuenter Roeck 		.func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
34850115ac9SGuenter Roeck 		.func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
34950115ac9SGuenter Roeck 		.func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
35050115ac9SGuenter Roeck 		.func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
35150115ac9SGuenter Roeck 		.func[14] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
35250115ac9SGuenter Roeck 		.func[15] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
35350115ac9SGuenter Roeck 		.func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
35450115ac9SGuenter Roeck 		.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
35550115ac9SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
35650115ac9SGuenter Roeck 		.read_word_data = max34440_read_word_data,
35750115ac9SGuenter Roeck 		.write_word_data = max34440_write_word_data,
35850115ac9SGuenter Roeck 	},
35950115ac9SGuenter Roeck 	[max34461] = {
36050115ac9SGuenter Roeck 		.pages = 23,
36150115ac9SGuenter Roeck 		.format[PSC_VOLTAGE_OUT] = direct,
36250115ac9SGuenter Roeck 		.format[PSC_TEMPERATURE] = direct,
36350115ac9SGuenter Roeck 		.m[PSC_VOLTAGE_OUT] = 1,
36450115ac9SGuenter Roeck 		.b[PSC_VOLTAGE_OUT] = 0,
36550115ac9SGuenter Roeck 		.R[PSC_VOLTAGE_OUT] = 3,
36650115ac9SGuenter Roeck 		.m[PSC_TEMPERATURE] = 1,
36750115ac9SGuenter Roeck 		.b[PSC_TEMPERATURE] = 0,
36850115ac9SGuenter Roeck 		.R[PSC_TEMPERATURE] = 2,
36950115ac9SGuenter Roeck 		.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
37050115ac9SGuenter Roeck 		.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
37150115ac9SGuenter Roeck 		.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
37250115ac9SGuenter Roeck 		.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
37350115ac9SGuenter Roeck 		.func[4] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
37450115ac9SGuenter Roeck 		.func[5] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
37550115ac9SGuenter Roeck 		.func[6] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
37650115ac9SGuenter Roeck 		.func[7] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
37750115ac9SGuenter Roeck 		.func[8] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
37850115ac9SGuenter Roeck 		.func[9] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
37950115ac9SGuenter Roeck 		.func[10] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
38050115ac9SGuenter Roeck 		.func[11] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
38150115ac9SGuenter Roeck 		.func[12] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
38250115ac9SGuenter Roeck 		.func[13] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
38350115ac9SGuenter Roeck 		.func[14] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
38450115ac9SGuenter Roeck 		.func[15] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
38550115ac9SGuenter Roeck 		/* page 16 is reserved */
38650115ac9SGuenter Roeck 		.func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
38750115ac9SGuenter Roeck 		.func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
38850115ac9SGuenter Roeck 		.func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
38950115ac9SGuenter Roeck 		.func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
39050115ac9SGuenter Roeck 		.func[21] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
39150115ac9SGuenter Roeck 		.read_byte_data = max34440_read_byte_data,
39250115ac9SGuenter Roeck 		.read_word_data = max34440_read_word_data,
39350115ac9SGuenter Roeck 		.write_word_data = max34440_write_word_data,
39450115ac9SGuenter Roeck 	},
3959d2ecfb7SGuenter Roeck };
3969d2ecfb7SGuenter Roeck 
3979d2ecfb7SGuenter Roeck static int max34440_probe(struct i2c_client *client,
3989d2ecfb7SGuenter Roeck 			  const struct i2c_device_id *id)
3999d2ecfb7SGuenter Roeck {
400590defe5SGuenter Roeck 	struct max34440_data *data;
401590defe5SGuenter Roeck 
402590defe5SGuenter Roeck 	data = devm_kzalloc(&client->dev, sizeof(struct max34440_data),
403590defe5SGuenter Roeck 			    GFP_KERNEL);
404590defe5SGuenter Roeck 	if (!data)
405590defe5SGuenter Roeck 		return -ENOMEM;
406590defe5SGuenter Roeck 	data->id = id->driver_data;
407590defe5SGuenter Roeck 	data->info = max34440_info[id->driver_data];
408590defe5SGuenter Roeck 
409590defe5SGuenter Roeck 	return pmbus_do_probe(client, id, &data->info);
4109d2ecfb7SGuenter Roeck }
4119d2ecfb7SGuenter Roeck 
4129d2ecfb7SGuenter Roeck static const struct i2c_device_id max34440_id[] = {
4139d2ecfb7SGuenter Roeck 	{"max34440", max34440},
4149d2ecfb7SGuenter Roeck 	{"max34441", max34441},
415590defe5SGuenter Roeck 	{"max34446", max34446},
41650115ac9SGuenter Roeck 	{"max34460", max34460},
41750115ac9SGuenter Roeck 	{"max34461", max34461},
4189d2ecfb7SGuenter Roeck 	{}
4199d2ecfb7SGuenter Roeck };
4209d2ecfb7SGuenter Roeck MODULE_DEVICE_TABLE(i2c, max34440_id);
4219d2ecfb7SGuenter Roeck 
4229d2ecfb7SGuenter Roeck /* This is the driver that will be inserted */
4239d2ecfb7SGuenter Roeck static struct i2c_driver max34440_driver = {
4249d2ecfb7SGuenter Roeck 	.driver = {
4259d2ecfb7SGuenter Roeck 		   .name = "max34440",
4269d2ecfb7SGuenter Roeck 		   },
4279d2ecfb7SGuenter Roeck 	.probe = max34440_probe,
428dd285ad7SGuenter Roeck 	.remove = pmbus_do_remove,
4299d2ecfb7SGuenter Roeck 	.id_table = max34440_id,
4309d2ecfb7SGuenter Roeck };
4319d2ecfb7SGuenter Roeck 
432f0967eeaSAxel Lin module_i2c_driver(max34440_driver);
4339d2ecfb7SGuenter Roeck 
4349d2ecfb7SGuenter Roeck MODULE_AUTHOR("Guenter Roeck");
4359d2ecfb7SGuenter Roeck MODULE_DESCRIPTION("PMBus driver for Maxim MAX34440/MAX34441");
4369d2ecfb7SGuenter Roeck MODULE_LICENSE("GPL");
437