1038a9c3dSMaxim Sloyko // SPDX-License-Identifier: GPL-2.0+
2038a9c3dSMaxim Sloyko /*
3f621d61fSGrant Peltier * Hardware monitoring driver for Renesas Digital Multiphase Voltage Regulators
4038a9c3dSMaxim Sloyko *
5038a9c3dSMaxim Sloyko * Copyright (c) 2017 Google Inc
6f621d61fSGrant Peltier * Copyright (c) 2020 Renesas Electronics America
7038a9c3dSMaxim Sloyko *
8038a9c3dSMaxim Sloyko */
9038a9c3dSMaxim Sloyko
10038a9c3dSMaxim Sloyko #include <linux/err.h>
11038a9c3dSMaxim Sloyko #include <linux/hwmon-sysfs.h>
12038a9c3dSMaxim Sloyko #include <linux/i2c.h>
13038a9c3dSMaxim Sloyko #include <linux/init.h>
14038a9c3dSMaxim Sloyko #include <linux/kernel.h>
15038a9c3dSMaxim Sloyko #include <linux/module.h>
16038a9c3dSMaxim Sloyko #include <linux/string.h>
17038a9c3dSMaxim Sloyko #include <linux/sysfs.h>
18f621d61fSGrant Peltier
19038a9c3dSMaxim Sloyko #include "pmbus.h"
20038a9c3dSMaxim Sloyko
21038a9c3dSMaxim Sloyko #define ISL68137_VOUT_AVS 0x30
22f621d61fSGrant Peltier #define RAA_DMPVR2_READ_VMON 0xc8
23f621d61fSGrant Peltier
2437d59d10SGuenter Roeck enum chips {
25f621d61fSGrant Peltier isl68137,
2637d59d10SGuenter Roeck isl68220,
2737d59d10SGuenter Roeck isl68221,
2837d59d10SGuenter Roeck isl68222,
2937d59d10SGuenter Roeck isl68223,
3037d59d10SGuenter Roeck isl68224,
3137d59d10SGuenter Roeck isl68225,
3237d59d10SGuenter Roeck isl68226,
3337d59d10SGuenter Roeck isl68227,
3437d59d10SGuenter Roeck isl68229,
3537d59d10SGuenter Roeck isl68233,
3637d59d10SGuenter Roeck isl68239,
3737d59d10SGuenter Roeck isl69222,
3837d59d10SGuenter Roeck isl69223,
3937d59d10SGuenter Roeck isl69224,
4037d59d10SGuenter Roeck isl69225,
4137d59d10SGuenter Roeck isl69227,
4237d59d10SGuenter Roeck isl69228,
4337d59d10SGuenter Roeck isl69234,
4437d59d10SGuenter Roeck isl69236,
4537d59d10SGuenter Roeck isl69239,
4637d59d10SGuenter Roeck isl69242,
4737d59d10SGuenter Roeck isl69243,
4837d59d10SGuenter Roeck isl69247,
4937d59d10SGuenter Roeck isl69248,
5037d59d10SGuenter Roeck isl69254,
5137d59d10SGuenter Roeck isl69255,
5237d59d10SGuenter Roeck isl69256,
5337d59d10SGuenter Roeck isl69259,
5437d59d10SGuenter Roeck isl69260,
5537d59d10SGuenter Roeck isl69268,
5637d59d10SGuenter Roeck isl69269,
5737d59d10SGuenter Roeck isl69298,
5837d59d10SGuenter Roeck raa228000,
5937d59d10SGuenter Roeck raa228004,
6037d59d10SGuenter Roeck raa228006,
6137d59d10SGuenter Roeck raa228228,
6237d59d10SGuenter Roeck raa229001,
6337d59d10SGuenter Roeck raa229004,
6437d59d10SGuenter Roeck };
6537d59d10SGuenter Roeck
6637d59d10SGuenter Roeck enum variants {
6737d59d10SGuenter Roeck raa_dmpvr1_2rail,
68f621d61fSGrant Peltier raa_dmpvr2_1rail,
69f621d61fSGrant Peltier raa_dmpvr2_2rail,
7051fb91edSGrant Peltier raa_dmpvr2_2rail_nontc,
71f621d61fSGrant Peltier raa_dmpvr2_3rail,
72f621d61fSGrant Peltier raa_dmpvr2_hv,
73f621d61fSGrant Peltier };
74038a9c3dSMaxim Sloyko
75dd431939SStephen Kitt static const struct i2c_device_id raa_dmpvr_id[];
76dd431939SStephen Kitt
isl68137_avs_enable_show_page(struct i2c_client * client,int page,char * buf)77038a9c3dSMaxim Sloyko static ssize_t isl68137_avs_enable_show_page(struct i2c_client *client,
78038a9c3dSMaxim Sloyko int page,
79038a9c3dSMaxim Sloyko char *buf)
80038a9c3dSMaxim Sloyko {
81038a9c3dSMaxim Sloyko int val = pmbus_read_byte_data(client, page, PMBUS_OPERATION);
82038a9c3dSMaxim Sloyko
83038a9c3dSMaxim Sloyko return sprintf(buf, "%d\n",
84038a9c3dSMaxim Sloyko (val & ISL68137_VOUT_AVS) == ISL68137_VOUT_AVS ? 1 : 0);
85038a9c3dSMaxim Sloyko }
86038a9c3dSMaxim Sloyko
isl68137_avs_enable_store_page(struct i2c_client * client,int page,const char * buf,size_t count)87038a9c3dSMaxim Sloyko static ssize_t isl68137_avs_enable_store_page(struct i2c_client *client,
88038a9c3dSMaxim Sloyko int page,
89038a9c3dSMaxim Sloyko const char *buf, size_t count)
90038a9c3dSMaxim Sloyko {
91038a9c3dSMaxim Sloyko int rc, op_val;
92038a9c3dSMaxim Sloyko bool result;
93038a9c3dSMaxim Sloyko
94038a9c3dSMaxim Sloyko rc = kstrtobool(buf, &result);
95038a9c3dSMaxim Sloyko if (rc)
96038a9c3dSMaxim Sloyko return rc;
97038a9c3dSMaxim Sloyko
98038a9c3dSMaxim Sloyko op_val = result ? ISL68137_VOUT_AVS : 0;
99038a9c3dSMaxim Sloyko
100038a9c3dSMaxim Sloyko /*
101038a9c3dSMaxim Sloyko * Writes to VOUT setpoint over AVSBus will persist after the VRM is
102038a9c3dSMaxim Sloyko * switched to PMBus control. Switching back to AVSBus control
103038a9c3dSMaxim Sloyko * restores this persisted setpoint rather than re-initializing to
104038a9c3dSMaxim Sloyko * PMBus VOUT_COMMAND. Writing VOUT_COMMAND first over PMBus before
105038a9c3dSMaxim Sloyko * enabling AVS control is the workaround.
106038a9c3dSMaxim Sloyko */
107038a9c3dSMaxim Sloyko if (op_val == ISL68137_VOUT_AVS) {
10843f33b6eSGuenter Roeck rc = pmbus_read_word_data(client, page, 0xff,
10943f33b6eSGuenter Roeck PMBUS_VOUT_COMMAND);
110038a9c3dSMaxim Sloyko if (rc < 0)
111038a9c3dSMaxim Sloyko return rc;
112038a9c3dSMaxim Sloyko
113038a9c3dSMaxim Sloyko rc = pmbus_write_word_data(client, page, PMBUS_VOUT_COMMAND,
114038a9c3dSMaxim Sloyko rc);
115038a9c3dSMaxim Sloyko if (rc < 0)
116038a9c3dSMaxim Sloyko return rc;
117038a9c3dSMaxim Sloyko }
118038a9c3dSMaxim Sloyko
119038a9c3dSMaxim Sloyko rc = pmbus_update_byte_data(client, page, PMBUS_OPERATION,
120038a9c3dSMaxim Sloyko ISL68137_VOUT_AVS, op_val);
121038a9c3dSMaxim Sloyko
122038a9c3dSMaxim Sloyko return (rc < 0) ? rc : count;
123038a9c3dSMaxim Sloyko }
124038a9c3dSMaxim Sloyko
isl68137_avs_enable_show(struct device * dev,struct device_attribute * devattr,char * buf)125038a9c3dSMaxim Sloyko static ssize_t isl68137_avs_enable_show(struct device *dev,
126038a9c3dSMaxim Sloyko struct device_attribute *devattr,
127038a9c3dSMaxim Sloyko char *buf)
128038a9c3dSMaxim Sloyko {
129038a9c3dSMaxim Sloyko struct i2c_client *client = to_i2c_client(dev->parent);
130038a9c3dSMaxim Sloyko struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
131038a9c3dSMaxim Sloyko
132038a9c3dSMaxim Sloyko return isl68137_avs_enable_show_page(client, attr->index, buf);
133038a9c3dSMaxim Sloyko }
134038a9c3dSMaxim Sloyko
isl68137_avs_enable_store(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)135038a9c3dSMaxim Sloyko static ssize_t isl68137_avs_enable_store(struct device *dev,
136038a9c3dSMaxim Sloyko struct device_attribute *devattr,
137038a9c3dSMaxim Sloyko const char *buf, size_t count)
138038a9c3dSMaxim Sloyko {
139038a9c3dSMaxim Sloyko struct i2c_client *client = to_i2c_client(dev->parent);
140038a9c3dSMaxim Sloyko struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
141038a9c3dSMaxim Sloyko
142038a9c3dSMaxim Sloyko return isl68137_avs_enable_store_page(client, attr->index, buf, count);
143038a9c3dSMaxim Sloyko }
144038a9c3dSMaxim Sloyko
145038a9c3dSMaxim Sloyko static SENSOR_DEVICE_ATTR_RW(avs0_enable, isl68137_avs_enable, 0);
146038a9c3dSMaxim Sloyko static SENSOR_DEVICE_ATTR_RW(avs1_enable, isl68137_avs_enable, 1);
147038a9c3dSMaxim Sloyko
148038a9c3dSMaxim Sloyko static struct attribute *enable_attrs[] = {
149038a9c3dSMaxim Sloyko &sensor_dev_attr_avs0_enable.dev_attr.attr,
150038a9c3dSMaxim Sloyko &sensor_dev_attr_avs1_enable.dev_attr.attr,
151038a9c3dSMaxim Sloyko NULL,
152038a9c3dSMaxim Sloyko };
153038a9c3dSMaxim Sloyko
154038a9c3dSMaxim Sloyko static const struct attribute_group enable_group = {
155038a9c3dSMaxim Sloyko .attrs = enable_attrs,
156038a9c3dSMaxim Sloyko };
157038a9c3dSMaxim Sloyko
158f621d61fSGrant Peltier static const struct attribute_group *isl68137_attribute_groups[] = {
159038a9c3dSMaxim Sloyko &enable_group,
160038a9c3dSMaxim Sloyko NULL,
161038a9c3dSMaxim Sloyko };
162038a9c3dSMaxim Sloyko
raa_dmpvr2_read_word_data(struct i2c_client * client,int page,int phase,int reg)163f621d61fSGrant Peltier static int raa_dmpvr2_read_word_data(struct i2c_client *client, int page,
164f621d61fSGrant Peltier int phase, int reg)
165f621d61fSGrant Peltier {
166f621d61fSGrant Peltier int ret;
167f621d61fSGrant Peltier
168f621d61fSGrant Peltier switch (reg) {
169f621d61fSGrant Peltier case PMBUS_VIRT_READ_VMON:
170f621d61fSGrant Peltier ret = pmbus_read_word_data(client, page, phase,
171f621d61fSGrant Peltier RAA_DMPVR2_READ_VMON);
172f621d61fSGrant Peltier break;
173f621d61fSGrant Peltier default:
174f621d61fSGrant Peltier ret = -ENODATA;
175f621d61fSGrant Peltier break;
176f621d61fSGrant Peltier }
177f621d61fSGrant Peltier
178f621d61fSGrant Peltier return ret;
179f621d61fSGrant Peltier }
180f621d61fSGrant Peltier
181f621d61fSGrant Peltier static struct pmbus_driver_info raa_dmpvr_info = {
182f621d61fSGrant Peltier .pages = 3,
183038a9c3dSMaxim Sloyko .format[PSC_VOLTAGE_IN] = direct,
184038a9c3dSMaxim Sloyko .format[PSC_VOLTAGE_OUT] = direct,
185038a9c3dSMaxim Sloyko .format[PSC_CURRENT_IN] = direct,
186038a9c3dSMaxim Sloyko .format[PSC_CURRENT_OUT] = direct,
187038a9c3dSMaxim Sloyko .format[PSC_POWER] = direct,
188038a9c3dSMaxim Sloyko .format[PSC_TEMPERATURE] = direct,
189038a9c3dSMaxim Sloyko .m[PSC_VOLTAGE_IN] = 1,
190038a9c3dSMaxim Sloyko .b[PSC_VOLTAGE_IN] = 0,
191f621d61fSGrant Peltier .R[PSC_VOLTAGE_IN] = 2,
192038a9c3dSMaxim Sloyko .m[PSC_VOLTAGE_OUT] = 1,
193038a9c3dSMaxim Sloyko .b[PSC_VOLTAGE_OUT] = 0,
194038a9c3dSMaxim Sloyko .R[PSC_VOLTAGE_OUT] = 3,
195038a9c3dSMaxim Sloyko .m[PSC_CURRENT_IN] = 1,
196038a9c3dSMaxim Sloyko .b[PSC_CURRENT_IN] = 0,
197038a9c3dSMaxim Sloyko .R[PSC_CURRENT_IN] = 2,
198038a9c3dSMaxim Sloyko .m[PSC_CURRENT_OUT] = 1,
199038a9c3dSMaxim Sloyko .b[PSC_CURRENT_OUT] = 0,
200038a9c3dSMaxim Sloyko .R[PSC_CURRENT_OUT] = 1,
201038a9c3dSMaxim Sloyko .m[PSC_POWER] = 1,
202038a9c3dSMaxim Sloyko .b[PSC_POWER] = 0,
203038a9c3dSMaxim Sloyko .R[PSC_POWER] = 0,
204038a9c3dSMaxim Sloyko .m[PSC_TEMPERATURE] = 1,
205038a9c3dSMaxim Sloyko .b[PSC_TEMPERATURE] = 0,
206038a9c3dSMaxim Sloyko .R[PSC_TEMPERATURE] = 0,
207038a9c3dSMaxim Sloyko .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN
208038a9c3dSMaxim Sloyko | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2
209038a9c3dSMaxim Sloyko | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP
210038a9c3dSMaxim Sloyko | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
211f621d61fSGrant Peltier | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT
212f621d61fSGrant Peltier | PMBUS_HAVE_VMON,
213f621d61fSGrant Peltier .func[1] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT
214f621d61fSGrant Peltier | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP
215f621d61fSGrant Peltier | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT
216f621d61fSGrant Peltier | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
217f621d61fSGrant Peltier .func[2] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT
218f621d61fSGrant Peltier | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP
219f621d61fSGrant Peltier | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT
220f621d61fSGrant Peltier | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
221038a9c3dSMaxim Sloyko };
222038a9c3dSMaxim Sloyko
isl68137_probe(struct i2c_client * client)223dd431939SStephen Kitt static int isl68137_probe(struct i2c_client *client)
224038a9c3dSMaxim Sloyko {
225f621d61fSGrant Peltier struct pmbus_driver_info *info;
226f621d61fSGrant Peltier
227f621d61fSGrant Peltier info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
228f621d61fSGrant Peltier if (!info)
229f621d61fSGrant Peltier return -ENOMEM;
230f621d61fSGrant Peltier memcpy(info, &raa_dmpvr_info, sizeof(*info));
231f621d61fSGrant Peltier
232dd431939SStephen Kitt switch (i2c_match_id(raa_dmpvr_id, client)->driver_data) {
23337d59d10SGuenter Roeck case raa_dmpvr1_2rail:
234f621d61fSGrant Peltier info->pages = 2;
235f621d61fSGrant Peltier info->R[PSC_VOLTAGE_IN] = 3;
236f621d61fSGrant Peltier info->func[0] &= ~PMBUS_HAVE_VMON;
237f621d61fSGrant Peltier info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
238f621d61fSGrant Peltier | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
239f621d61fSGrant Peltier | PMBUS_HAVE_POUT;
240f621d61fSGrant Peltier info->groups = isl68137_attribute_groups;
241f621d61fSGrant Peltier break;
242f621d61fSGrant Peltier case raa_dmpvr2_1rail:
243f621d61fSGrant Peltier info->pages = 1;
244f621d61fSGrant Peltier info->read_word_data = raa_dmpvr2_read_word_data;
245f621d61fSGrant Peltier break;
24651fb91edSGrant Peltier case raa_dmpvr2_2rail_nontc:
2472a29db08SGrant Peltier info->func[0] &= ~PMBUS_HAVE_TEMP3;
2482a29db08SGrant Peltier info->func[1] &= ~PMBUS_HAVE_TEMP3;
24951fb91edSGrant Peltier fallthrough;
250f621d61fSGrant Peltier case raa_dmpvr2_2rail:
251f621d61fSGrant Peltier info->pages = 2;
252f621d61fSGrant Peltier info->read_word_data = raa_dmpvr2_read_word_data;
253f621d61fSGrant Peltier break;
254f621d61fSGrant Peltier case raa_dmpvr2_3rail:
255f621d61fSGrant Peltier info->read_word_data = raa_dmpvr2_read_word_data;
256f621d61fSGrant Peltier break;
257f621d61fSGrant Peltier case raa_dmpvr2_hv:
258f621d61fSGrant Peltier info->pages = 1;
259f621d61fSGrant Peltier info->R[PSC_VOLTAGE_IN] = 1;
260f621d61fSGrant Peltier info->m[PSC_VOLTAGE_OUT] = 2;
261f621d61fSGrant Peltier info->R[PSC_VOLTAGE_OUT] = 2;
262f621d61fSGrant Peltier info->m[PSC_CURRENT_IN] = 2;
263f621d61fSGrant Peltier info->m[PSC_POWER] = 2;
264f621d61fSGrant Peltier info->R[PSC_POWER] = -1;
265f621d61fSGrant Peltier info->read_word_data = raa_dmpvr2_read_word_data;
266f621d61fSGrant Peltier break;
267f621d61fSGrant Peltier default:
268f621d61fSGrant Peltier return -ENODEV;
269038a9c3dSMaxim Sloyko }
270038a9c3dSMaxim Sloyko
271dd431939SStephen Kitt return pmbus_do_probe(client, info);
272f621d61fSGrant Peltier }
273f621d61fSGrant Peltier
274f621d61fSGrant Peltier static const struct i2c_device_id raa_dmpvr_id[] = {
27537d59d10SGuenter Roeck {"isl68137", raa_dmpvr1_2rail},
27637d59d10SGuenter Roeck {"isl68220", raa_dmpvr2_2rail},
27737d59d10SGuenter Roeck {"isl68221", raa_dmpvr2_3rail},
27837d59d10SGuenter Roeck {"isl68222", raa_dmpvr2_2rail},
27937d59d10SGuenter Roeck {"isl68223", raa_dmpvr2_2rail},
28037d59d10SGuenter Roeck {"isl68224", raa_dmpvr2_3rail},
28137d59d10SGuenter Roeck {"isl68225", raa_dmpvr2_2rail},
28237d59d10SGuenter Roeck {"isl68226", raa_dmpvr2_3rail},
28337d59d10SGuenter Roeck {"isl68227", raa_dmpvr2_1rail},
28437d59d10SGuenter Roeck {"isl68229", raa_dmpvr2_3rail},
28537d59d10SGuenter Roeck {"isl68233", raa_dmpvr2_2rail},
28637d59d10SGuenter Roeck {"isl68239", raa_dmpvr2_3rail},
28737d59d10SGuenter Roeck
28837d59d10SGuenter Roeck {"isl69222", raa_dmpvr2_2rail},
28937d59d10SGuenter Roeck {"isl69223", raa_dmpvr2_3rail},
29037d59d10SGuenter Roeck {"isl69224", raa_dmpvr2_2rail},
29137d59d10SGuenter Roeck {"isl69225", raa_dmpvr2_2rail},
29237d59d10SGuenter Roeck {"isl69227", raa_dmpvr2_3rail},
29337d59d10SGuenter Roeck {"isl69228", raa_dmpvr2_3rail},
29437d59d10SGuenter Roeck {"isl69234", raa_dmpvr2_2rail},
29537d59d10SGuenter Roeck {"isl69236", raa_dmpvr2_2rail},
29637d59d10SGuenter Roeck {"isl69239", raa_dmpvr2_3rail},
29737d59d10SGuenter Roeck {"isl69242", raa_dmpvr2_2rail},
29837d59d10SGuenter Roeck {"isl69243", raa_dmpvr2_1rail},
29937d59d10SGuenter Roeck {"isl69247", raa_dmpvr2_2rail},
30037d59d10SGuenter Roeck {"isl69248", raa_dmpvr2_2rail},
30137d59d10SGuenter Roeck {"isl69254", raa_dmpvr2_2rail},
30237d59d10SGuenter Roeck {"isl69255", raa_dmpvr2_2rail},
30337d59d10SGuenter Roeck {"isl69256", raa_dmpvr2_2rail},
30437d59d10SGuenter Roeck {"isl69259", raa_dmpvr2_2rail},
30537d59d10SGuenter Roeck {"isl69260", raa_dmpvr2_2rail},
30637d59d10SGuenter Roeck {"isl69268", raa_dmpvr2_2rail},
30737d59d10SGuenter Roeck {"isl69269", raa_dmpvr2_3rail},
30837d59d10SGuenter Roeck {"isl69298", raa_dmpvr2_2rail},
30937d59d10SGuenter Roeck
31037d59d10SGuenter Roeck {"raa228000", raa_dmpvr2_hv},
31137d59d10SGuenter Roeck {"raa228004", raa_dmpvr2_hv},
31237d59d10SGuenter Roeck {"raa228006", raa_dmpvr2_hv},
31351fb91edSGrant Peltier {"raa228228", raa_dmpvr2_2rail_nontc},
31437d59d10SGuenter Roeck {"raa229001", raa_dmpvr2_2rail},
31537d59d10SGuenter Roeck {"raa229004", raa_dmpvr2_2rail},
316038a9c3dSMaxim Sloyko {}
317038a9c3dSMaxim Sloyko };
318038a9c3dSMaxim Sloyko
319f621d61fSGrant Peltier MODULE_DEVICE_TABLE(i2c, raa_dmpvr_id);
320038a9c3dSMaxim Sloyko
321038a9c3dSMaxim Sloyko /* This is the driver that will be inserted */
322038a9c3dSMaxim Sloyko static struct i2c_driver isl68137_driver = {
323038a9c3dSMaxim Sloyko .driver = {
324038a9c3dSMaxim Sloyko .name = "isl68137",
325038a9c3dSMaxim Sloyko },
326*1975d167SUwe Kleine-König .probe = isl68137_probe,
327f621d61fSGrant Peltier .id_table = raa_dmpvr_id,
328038a9c3dSMaxim Sloyko };
329038a9c3dSMaxim Sloyko
330038a9c3dSMaxim Sloyko module_i2c_driver(isl68137_driver);
331038a9c3dSMaxim Sloyko
332038a9c3dSMaxim Sloyko MODULE_AUTHOR("Maxim Sloyko <maxims@google.com>");
333f621d61fSGrant Peltier MODULE_DESCRIPTION("PMBus driver for Renesas digital multiphase voltage regulators");
334038a9c3dSMaxim Sloyko MODULE_LICENSE("GPL");
335b94ca77eSGuenter Roeck MODULE_IMPORT_NS(PMBUS);
336