1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Hardware monitoring driver for Maxim MAX16064
4  *
5  * Copyright (c) 2011 Ericsson AB.
6  */
7 
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/err.h>
12 #include <linux/i2c.h>
13 #include "pmbus.h"
14 
15 #define MAX16064_MFR_VOUT_PEAK		0xd4
16 #define MAX16064_MFR_TEMPERATURE_PEAK	0xd6
17 
max16064_read_word_data(struct i2c_client * client,int page,int phase,int reg)18 static int max16064_read_word_data(struct i2c_client *client, int page,
19 				   int phase, int reg)
20 {
21 	int ret;
22 
23 	switch (reg) {
24 	case PMBUS_VIRT_READ_VOUT_MAX:
25 		ret = pmbus_read_word_data(client, page, phase,
26 					   MAX16064_MFR_VOUT_PEAK);
27 		break;
28 	case PMBUS_VIRT_READ_TEMP_MAX:
29 		ret = pmbus_read_word_data(client, page, phase,
30 					   MAX16064_MFR_TEMPERATURE_PEAK);
31 		break;
32 	case PMBUS_VIRT_RESET_VOUT_HISTORY:
33 	case PMBUS_VIRT_RESET_TEMP_HISTORY:
34 		ret = 0;
35 		break;
36 	default:
37 		ret = -ENODATA;
38 		break;
39 	}
40 	return ret;
41 }
42 
max16064_write_word_data(struct i2c_client * client,int page,int reg,u16 word)43 static int max16064_write_word_data(struct i2c_client *client, int page,
44 				    int reg, u16 word)
45 {
46 	int ret;
47 
48 	switch (reg) {
49 	case PMBUS_VIRT_RESET_VOUT_HISTORY:
50 		ret = pmbus_write_word_data(client, page,
51 					    MAX16064_MFR_VOUT_PEAK, 0);
52 		break;
53 	case PMBUS_VIRT_RESET_TEMP_HISTORY:
54 		ret = pmbus_write_word_data(client, page,
55 					    MAX16064_MFR_TEMPERATURE_PEAK,
56 					    0xffff);
57 		break;
58 	default:
59 		ret = -ENODATA;
60 		break;
61 	}
62 	return ret;
63 }
64 
65 static struct pmbus_driver_info max16064_info = {
66 	.pages = 4,
67 	.format[PSC_VOLTAGE_IN] = direct,
68 	.format[PSC_VOLTAGE_OUT] = direct,
69 	.format[PSC_TEMPERATURE] = direct,
70 	.m[PSC_VOLTAGE_IN] = 19995,
71 	.b[PSC_VOLTAGE_IN] = 0,
72 	.R[PSC_VOLTAGE_IN] = -1,
73 	.m[PSC_VOLTAGE_OUT] = 19995,
74 	.b[PSC_VOLTAGE_OUT] = 0,
75 	.R[PSC_VOLTAGE_OUT] = -1,
76 	.m[PSC_TEMPERATURE] = -7612,
77 	.b[PSC_TEMPERATURE] = 335,
78 	.R[PSC_TEMPERATURE] = -3,
79 	.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_TEMP
80 		| PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_TEMP,
81 	.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
82 	.func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
83 	.func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT,
84 	.read_word_data = max16064_read_word_data,
85 	.write_word_data = max16064_write_word_data,
86 };
87 
max16064_probe(struct i2c_client * client)88 static int max16064_probe(struct i2c_client *client)
89 {
90 	return pmbus_do_probe(client, &max16064_info);
91 }
92 
93 static const struct i2c_device_id max16064_id[] = {
94 	{"max16064", 0},
95 	{}
96 };
97 
98 MODULE_DEVICE_TABLE(i2c, max16064_id);
99 
100 /* This is the driver that will be inserted */
101 static struct i2c_driver max16064_driver = {
102 	.driver = {
103 		   .name = "max16064",
104 		   },
105 	.probe_new = max16064_probe,
106 	.id_table = max16064_id,
107 };
108 
109 module_i2c_driver(max16064_driver);
110 
111 MODULE_AUTHOR("Guenter Roeck");
112 MODULE_DESCRIPTION("PMBus driver for Maxim MAX16064");
113 MODULE_LICENSE("GPL");
114 MODULE_IMPORT_NS(PMBUS);
115