1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Hardware monitoring driver for Maxim MAX15301 |
4 | * |
5 | * Copyright (c) 2021 Flextronics International Sweden AB |
6 | * |
7 | * Even though the specification does not specifically mention it, |
8 | * extensive empirical testing has revealed that auto-detection of |
9 | * limit-registers will fail in a random fashion unless the delay |
10 | * parameter is set to above about 80us. The default delay is set |
11 | * to 100us to include some safety margin. |
12 | */ |
13 | |
14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> |
16 | #include <linux/init.h> |
17 | #include <linux/err.h> |
18 | #include <linux/slab.h> |
19 | #include <linux/i2c.h> |
20 | #include <linux/ktime.h> |
21 | #include <linux/delay.h> |
22 | #include <linux/pmbus.h> |
23 | #include "pmbus.h" |
24 | |
25 | static const struct i2c_device_id max15301_id[] = { |
26 | {"bmr461" , 0}, |
27 | {"max15301" , 0}, |
28 | {} |
29 | }; |
30 | MODULE_DEVICE_TABLE(i2c, max15301_id); |
31 | |
32 | struct max15301_data { |
33 | int id; |
34 | ktime_t access; /* Chip access time */ |
35 | int delay; /* Delay between chip accesses in us */ |
36 | struct pmbus_driver_info info; |
37 | }; |
38 | |
39 | #define to_max15301_data(x) container_of(x, struct max15301_data, info) |
40 | |
41 | #define MAX15301_WAIT_TIME 100 /* us */ |
42 | |
43 | static ushort delay = MAX15301_WAIT_TIME; |
44 | module_param(delay, ushort, 0644); |
45 | MODULE_PARM_DESC(delay, "Delay between chip accesses in us" ); |
46 | |
47 | static struct max15301_data max15301_data = { |
48 | .info = { |
49 | .pages = 1, |
50 | .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
51 | | PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
52 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
53 | | PMBUS_HAVE_STATUS_TEMP |
54 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, |
55 | } |
56 | }; |
57 | |
58 | /* This chip needs a delay between accesses */ |
59 | static inline void max15301_wait(const struct max15301_data *data) |
60 | { |
61 | if (data->delay) { |
62 | s64 delta = ktime_us_delta(later: ktime_get(), earlier: data->access); |
63 | |
64 | if (delta < data->delay) |
65 | udelay(data->delay - delta); |
66 | } |
67 | } |
68 | |
69 | static int max15301_read_word_data(struct i2c_client *client, int page, |
70 | int phase, int reg) |
71 | { |
72 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); |
73 | struct max15301_data *data = to_max15301_data(info); |
74 | int ret; |
75 | |
76 | if (page > 0) |
77 | return -ENXIO; |
78 | |
79 | if (reg >= PMBUS_VIRT_BASE) |
80 | return -ENXIO; |
81 | |
82 | max15301_wait(data); |
83 | ret = pmbus_read_word_data(client, page, phase, reg); |
84 | data->access = ktime_get(); |
85 | |
86 | return ret; |
87 | } |
88 | |
89 | static int max15301_read_byte_data(struct i2c_client *client, int page, int reg) |
90 | { |
91 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); |
92 | struct max15301_data *data = to_max15301_data(info); |
93 | int ret; |
94 | |
95 | if (page > 0) |
96 | return -ENXIO; |
97 | |
98 | max15301_wait(data); |
99 | ret = pmbus_read_byte_data(client, page, reg); |
100 | data->access = ktime_get(); |
101 | |
102 | return ret; |
103 | } |
104 | |
105 | static int max15301_write_word_data(struct i2c_client *client, int page, int reg, |
106 | u16 word) |
107 | { |
108 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); |
109 | struct max15301_data *data = to_max15301_data(info); |
110 | int ret; |
111 | |
112 | if (page > 0) |
113 | return -ENXIO; |
114 | |
115 | if (reg >= PMBUS_VIRT_BASE) |
116 | return -ENXIO; |
117 | |
118 | max15301_wait(data); |
119 | ret = pmbus_write_word_data(client, page, reg, word); |
120 | data->access = ktime_get(); |
121 | |
122 | return ret; |
123 | } |
124 | |
125 | static int max15301_write_byte(struct i2c_client *client, int page, u8 value) |
126 | { |
127 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); |
128 | struct max15301_data *data = to_max15301_data(info); |
129 | int ret; |
130 | |
131 | if (page > 0) |
132 | return -ENXIO; |
133 | |
134 | max15301_wait(data); |
135 | ret = pmbus_write_byte(client, page, value); |
136 | data->access = ktime_get(); |
137 | |
138 | return ret; |
139 | } |
140 | |
141 | static int max15301_probe(struct i2c_client *client) |
142 | { |
143 | int status; |
144 | u8 device_id[I2C_SMBUS_BLOCK_MAX + 1]; |
145 | const struct i2c_device_id *mid; |
146 | struct pmbus_driver_info *info = &max15301_data.info; |
147 | |
148 | if (!i2c_check_functionality(adap: client->adapter, |
149 | I2C_FUNC_SMBUS_READ_BYTE_DATA |
150 | | I2C_FUNC_SMBUS_BLOCK_DATA)) |
151 | return -ENODEV; |
152 | |
153 | status = i2c_smbus_read_block_data(client, command: PMBUS_IC_DEVICE_ID, values: device_id); |
154 | if (status < 0) { |
155 | dev_err(&client->dev, "Failed to read Device Id\n" ); |
156 | return status; |
157 | } |
158 | for (mid = max15301_id; mid->name[0]; mid++) { |
159 | if (!strncasecmp(s1: mid->name, s2: device_id, strlen(mid->name))) |
160 | break; |
161 | } |
162 | if (!mid->name[0]) { |
163 | dev_err(&client->dev, "Unsupported device\n" ); |
164 | return -ENODEV; |
165 | } |
166 | |
167 | max15301_data.delay = delay; |
168 | |
169 | info->read_byte_data = max15301_read_byte_data; |
170 | info->read_word_data = max15301_read_word_data; |
171 | info->write_byte = max15301_write_byte; |
172 | info->write_word_data = max15301_write_word_data; |
173 | |
174 | return pmbus_do_probe(client, info); |
175 | } |
176 | |
177 | static struct i2c_driver max15301_driver = { |
178 | .driver = { |
179 | .name = "max15301" , |
180 | }, |
181 | .probe = max15301_probe, |
182 | .id_table = max15301_id, |
183 | }; |
184 | |
185 | module_i2c_driver(max15301_driver); |
186 | |
187 | MODULE_AUTHOR("Erik Rosen <erik.rosen@metormote.com>" ); |
188 | MODULE_DESCRIPTION("PMBus driver for Maxim MAX15301" ); |
189 | MODULE_LICENSE("GPL" ); |
190 | MODULE_IMPORT_NS(PMBUS); |
191 | |