xref: /OK3568_Linux_fs/kernel/drivers/hwmon/pmbus/pmbus.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Hardware monitoring driver for PMBus devices
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2010, 2011 Ericsson AB.
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/kernel.h>
9*4882a593Smuzhiyun #include <linux/module.h>
10*4882a593Smuzhiyun #include <linux/init.h>
11*4882a593Smuzhiyun #include <linux/err.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun #include <linux/mutex.h>
14*4882a593Smuzhiyun #include <linux/i2c.h>
15*4882a593Smuzhiyun #include <linux/pmbus.h>
16*4882a593Smuzhiyun #include "pmbus.h"
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun struct pmbus_device_info {
19*4882a593Smuzhiyun 	int pages;
20*4882a593Smuzhiyun 	u32 flags;
21*4882a593Smuzhiyun };
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun static const struct i2c_device_id pmbus_id[];
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun /*
26*4882a593Smuzhiyun  * Find sensor groups and status registers on each page.
27*4882a593Smuzhiyun  */
pmbus_find_sensor_groups(struct i2c_client * client,struct pmbus_driver_info * info)28*4882a593Smuzhiyun static void pmbus_find_sensor_groups(struct i2c_client *client,
29*4882a593Smuzhiyun 				     struct pmbus_driver_info *info)
30*4882a593Smuzhiyun {
31*4882a593Smuzhiyun 	int page;
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun 	/* Sensors detected on page 0 only */
34*4882a593Smuzhiyun 	if (pmbus_check_word_register(client, 0, PMBUS_READ_VIN))
35*4882a593Smuzhiyun 		info->func[0] |= PMBUS_HAVE_VIN;
36*4882a593Smuzhiyun 	if (pmbus_check_word_register(client, 0, PMBUS_READ_VCAP))
37*4882a593Smuzhiyun 		info->func[0] |= PMBUS_HAVE_VCAP;
38*4882a593Smuzhiyun 	if (pmbus_check_word_register(client, 0, PMBUS_READ_IIN))
39*4882a593Smuzhiyun 		info->func[0] |= PMBUS_HAVE_IIN;
40*4882a593Smuzhiyun 	if (pmbus_check_word_register(client, 0, PMBUS_READ_PIN))
41*4882a593Smuzhiyun 		info->func[0] |= PMBUS_HAVE_PIN;
42*4882a593Smuzhiyun 	if (info->func[0]
43*4882a593Smuzhiyun 	    && pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT))
44*4882a593Smuzhiyun 		info->func[0] |= PMBUS_HAVE_STATUS_INPUT;
45*4882a593Smuzhiyun 	if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) &&
46*4882a593Smuzhiyun 	    pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
47*4882a593Smuzhiyun 		info->func[0] |= PMBUS_HAVE_FAN12;
48*4882a593Smuzhiyun 		if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12))
49*4882a593Smuzhiyun 			info->func[0] |= PMBUS_HAVE_STATUS_FAN12;
50*4882a593Smuzhiyun 	}
51*4882a593Smuzhiyun 	if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) &&
52*4882a593Smuzhiyun 	    pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
53*4882a593Smuzhiyun 		info->func[0] |= PMBUS_HAVE_FAN34;
54*4882a593Smuzhiyun 		if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34))
55*4882a593Smuzhiyun 			info->func[0] |= PMBUS_HAVE_STATUS_FAN34;
56*4882a593Smuzhiyun 	}
57*4882a593Smuzhiyun 	if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1))
58*4882a593Smuzhiyun 		info->func[0] |= PMBUS_HAVE_TEMP;
59*4882a593Smuzhiyun 	if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2))
60*4882a593Smuzhiyun 		info->func[0] |= PMBUS_HAVE_TEMP2;
61*4882a593Smuzhiyun 	if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3))
62*4882a593Smuzhiyun 		info->func[0] |= PMBUS_HAVE_TEMP3;
63*4882a593Smuzhiyun 	if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2
64*4882a593Smuzhiyun 			     | PMBUS_HAVE_TEMP3)
65*4882a593Smuzhiyun 	    && pmbus_check_byte_register(client, 0,
66*4882a593Smuzhiyun 					 PMBUS_STATUS_TEMPERATURE))
67*4882a593Smuzhiyun 			info->func[0] |= PMBUS_HAVE_STATUS_TEMP;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	/* Sensors detected on all pages */
70*4882a593Smuzhiyun 	for (page = 0; page < info->pages; page++) {
71*4882a593Smuzhiyun 		if (pmbus_check_word_register(client, page, PMBUS_READ_VOUT)) {
72*4882a593Smuzhiyun 			info->func[page] |= PMBUS_HAVE_VOUT;
73*4882a593Smuzhiyun 			if (pmbus_check_byte_register(client, page,
74*4882a593Smuzhiyun 						      PMBUS_STATUS_VOUT))
75*4882a593Smuzhiyun 				info->func[page] |= PMBUS_HAVE_STATUS_VOUT;
76*4882a593Smuzhiyun 		}
77*4882a593Smuzhiyun 		if (pmbus_check_word_register(client, page, PMBUS_READ_IOUT)) {
78*4882a593Smuzhiyun 			info->func[page] |= PMBUS_HAVE_IOUT;
79*4882a593Smuzhiyun 			if (pmbus_check_byte_register(client, 0,
80*4882a593Smuzhiyun 						      PMBUS_STATUS_IOUT))
81*4882a593Smuzhiyun 				info->func[page] |= PMBUS_HAVE_STATUS_IOUT;
82*4882a593Smuzhiyun 		}
83*4882a593Smuzhiyun 		if (pmbus_check_word_register(client, page, PMBUS_READ_POUT))
84*4882a593Smuzhiyun 			info->func[page] |= PMBUS_HAVE_POUT;
85*4882a593Smuzhiyun 	}
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun /*
89*4882a593Smuzhiyun  * Identify chip parameters.
90*4882a593Smuzhiyun  */
pmbus_identify(struct i2c_client * client,struct pmbus_driver_info * info)91*4882a593Smuzhiyun static int pmbus_identify(struct i2c_client *client,
92*4882a593Smuzhiyun 			  struct pmbus_driver_info *info)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun 	int ret = 0;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	if (!info->pages) {
97*4882a593Smuzhiyun 		/*
98*4882a593Smuzhiyun 		 * Check if the PAGE command is supported. If it is,
99*4882a593Smuzhiyun 		 * keep setting the page number until it fails or until the
100*4882a593Smuzhiyun 		 * maximum number of pages has been reached. Assume that
101*4882a593Smuzhiyun 		 * this is the number of pages supported by the chip.
102*4882a593Smuzhiyun 		 */
103*4882a593Smuzhiyun 		if (pmbus_check_byte_register(client, 0, PMBUS_PAGE)) {
104*4882a593Smuzhiyun 			int page;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 			for (page = 1; page < PMBUS_PAGES; page++) {
107*4882a593Smuzhiyun 				if (pmbus_set_page(client, page, 0xff) < 0)
108*4882a593Smuzhiyun 					break;
109*4882a593Smuzhiyun 			}
110*4882a593Smuzhiyun 			pmbus_set_page(client, 0, 0xff);
111*4882a593Smuzhiyun 			info->pages = page;
112*4882a593Smuzhiyun 		} else {
113*4882a593Smuzhiyun 			info->pages = 1;
114*4882a593Smuzhiyun 		}
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 		pmbus_clear_faults(client);
117*4882a593Smuzhiyun 	}
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) {
120*4882a593Smuzhiyun 		int vout_mode, i;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 		vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE);
123*4882a593Smuzhiyun 		if (vout_mode >= 0 && vout_mode != 0xff) {
124*4882a593Smuzhiyun 			switch (vout_mode >> 5) {
125*4882a593Smuzhiyun 			case 0:
126*4882a593Smuzhiyun 				break;
127*4882a593Smuzhiyun 			case 1:
128*4882a593Smuzhiyun 				info->format[PSC_VOLTAGE_OUT] = vid;
129*4882a593Smuzhiyun 				for (i = 0; i < info->pages; i++)
130*4882a593Smuzhiyun 					info->vrm_version[i] = vr11;
131*4882a593Smuzhiyun 				break;
132*4882a593Smuzhiyun 			case 2:
133*4882a593Smuzhiyun 				info->format[PSC_VOLTAGE_OUT] = direct;
134*4882a593Smuzhiyun 				break;
135*4882a593Smuzhiyun 			default:
136*4882a593Smuzhiyun 				ret = -ENODEV;
137*4882a593Smuzhiyun 				goto abort;
138*4882a593Smuzhiyun 			}
139*4882a593Smuzhiyun 		}
140*4882a593Smuzhiyun 	}
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	/*
143*4882a593Smuzhiyun 	 * We should check if the COEFFICIENTS register is supported.
144*4882a593Smuzhiyun 	 * If it is, and the chip is configured for direct mode, we can read
145*4882a593Smuzhiyun 	 * the coefficients from the chip, one set per group of sensor
146*4882a593Smuzhiyun 	 * registers.
147*4882a593Smuzhiyun 	 *
148*4882a593Smuzhiyun 	 * To do this, we will need access to a chip which actually supports the
149*4882a593Smuzhiyun 	 * COEFFICIENTS command, since the command is too complex to implement
150*4882a593Smuzhiyun 	 * without testing it. Until then, abort if a chip configured for direct
151*4882a593Smuzhiyun 	 * mode was detected.
152*4882a593Smuzhiyun 	 */
153*4882a593Smuzhiyun 	if (info->format[PSC_VOLTAGE_OUT] == direct) {
154*4882a593Smuzhiyun 		ret = -ENODEV;
155*4882a593Smuzhiyun 		goto abort;
156*4882a593Smuzhiyun 	}
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	/* Try to find sensor groups  */
159*4882a593Smuzhiyun 	pmbus_find_sensor_groups(client, info);
160*4882a593Smuzhiyun abort:
161*4882a593Smuzhiyun 	return ret;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun 
pmbus_probe(struct i2c_client * client)164*4882a593Smuzhiyun static int pmbus_probe(struct i2c_client *client)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun 	struct pmbus_driver_info *info;
167*4882a593Smuzhiyun 	struct pmbus_platform_data *pdata = NULL;
168*4882a593Smuzhiyun 	struct device *dev = &client->dev;
169*4882a593Smuzhiyun 	struct pmbus_device_info *device_info;
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	info = devm_kzalloc(dev, sizeof(struct pmbus_driver_info), GFP_KERNEL);
172*4882a593Smuzhiyun 	if (!info)
173*4882a593Smuzhiyun 		return -ENOMEM;
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	device_info = (struct pmbus_device_info *)i2c_match_id(pmbus_id, client)->driver_data;
176*4882a593Smuzhiyun 	if (device_info->flags & PMBUS_SKIP_STATUS_CHECK) {
177*4882a593Smuzhiyun 		pdata = devm_kzalloc(dev, sizeof(struct pmbus_platform_data),
178*4882a593Smuzhiyun 				     GFP_KERNEL);
179*4882a593Smuzhiyun 		if (!pdata)
180*4882a593Smuzhiyun 			return -ENOMEM;
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 		pdata->flags = PMBUS_SKIP_STATUS_CHECK;
183*4882a593Smuzhiyun 	}
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	info->pages = device_info->pages;
186*4882a593Smuzhiyun 	info->identify = pmbus_identify;
187*4882a593Smuzhiyun 	dev->platform_data = pdata;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	return pmbus_do_probe(client, info);
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun static const struct pmbus_device_info pmbus_info_one = {
193*4882a593Smuzhiyun 	.pages = 1,
194*4882a593Smuzhiyun 	.flags = 0
195*4882a593Smuzhiyun };
196*4882a593Smuzhiyun static const struct pmbus_device_info pmbus_info_zero = {
197*4882a593Smuzhiyun 	.pages = 0,
198*4882a593Smuzhiyun 	.flags = 0
199*4882a593Smuzhiyun };
200*4882a593Smuzhiyun static const struct pmbus_device_info pmbus_info_one_skip = {
201*4882a593Smuzhiyun 	.pages = 1,
202*4882a593Smuzhiyun 	.flags = PMBUS_SKIP_STATUS_CHECK
203*4882a593Smuzhiyun };
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun /*
206*4882a593Smuzhiyun  * Use driver_data to set the number of pages supported by the chip.
207*4882a593Smuzhiyun  */
208*4882a593Smuzhiyun static const struct i2c_device_id pmbus_id[] = {
209*4882a593Smuzhiyun 	{"adp4000", (kernel_ulong_t)&pmbus_info_one},
210*4882a593Smuzhiyun 	{"bmr453", (kernel_ulong_t)&pmbus_info_one},
211*4882a593Smuzhiyun 	{"bmr454", (kernel_ulong_t)&pmbus_info_one},
212*4882a593Smuzhiyun 	{"dps460", (kernel_ulong_t)&pmbus_info_one_skip},
213*4882a593Smuzhiyun 	{"dps650ab", (kernel_ulong_t)&pmbus_info_one_skip},
214*4882a593Smuzhiyun 	{"dps800", (kernel_ulong_t)&pmbus_info_one_skip},
215*4882a593Smuzhiyun 	{"max20796", (kernel_ulong_t)&pmbus_info_one},
216*4882a593Smuzhiyun 	{"mdt040", (kernel_ulong_t)&pmbus_info_one},
217*4882a593Smuzhiyun 	{"ncp4200", (kernel_ulong_t)&pmbus_info_one},
218*4882a593Smuzhiyun 	{"ncp4208", (kernel_ulong_t)&pmbus_info_one},
219*4882a593Smuzhiyun 	{"pdt003", (kernel_ulong_t)&pmbus_info_one},
220*4882a593Smuzhiyun 	{"pdt006", (kernel_ulong_t)&pmbus_info_one},
221*4882a593Smuzhiyun 	{"pdt012", (kernel_ulong_t)&pmbus_info_one},
222*4882a593Smuzhiyun 	{"pmbus", (kernel_ulong_t)&pmbus_info_zero},
223*4882a593Smuzhiyun 	{"sgd009", (kernel_ulong_t)&pmbus_info_one_skip},
224*4882a593Smuzhiyun 	{"tps40400", (kernel_ulong_t)&pmbus_info_one},
225*4882a593Smuzhiyun 	{"tps544b20", (kernel_ulong_t)&pmbus_info_one},
226*4882a593Smuzhiyun 	{"tps544b25", (kernel_ulong_t)&pmbus_info_one},
227*4882a593Smuzhiyun 	{"tps544c20", (kernel_ulong_t)&pmbus_info_one},
228*4882a593Smuzhiyun 	{"tps544c25", (kernel_ulong_t)&pmbus_info_one},
229*4882a593Smuzhiyun 	{"udt020", (kernel_ulong_t)&pmbus_info_one},
230*4882a593Smuzhiyun 	{}
231*4882a593Smuzhiyun };
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, pmbus_id);
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun /* This is the driver that will be inserted */
236*4882a593Smuzhiyun static struct i2c_driver pmbus_driver = {
237*4882a593Smuzhiyun 	.driver = {
238*4882a593Smuzhiyun 		   .name = "pmbus",
239*4882a593Smuzhiyun 		   },
240*4882a593Smuzhiyun 	.probe_new = pmbus_probe,
241*4882a593Smuzhiyun 	.remove = pmbus_do_remove,
242*4882a593Smuzhiyun 	.id_table = pmbus_id,
243*4882a593Smuzhiyun };
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun module_i2c_driver(pmbus_driver);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun MODULE_AUTHOR("Guenter Roeck");
248*4882a593Smuzhiyun MODULE_DESCRIPTION("Generic PMBus driver");
249*4882a593Smuzhiyun MODULE_LICENSE("GPL");
250