diff options
Diffstat (limited to 'drivers/gpio/gpio-max3191x.c')
-rw-r--r-- | drivers/gpio/gpio-max3191x.c | 492 |
1 files changed, 492 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-max3191x.c b/drivers/gpio/gpio-max3191x.c new file mode 100644 index 000000000000..f74b1072e84b --- /dev/null +++ b/drivers/gpio/gpio-max3191x.c | |||
@@ -0,0 +1,492 @@ | |||
1 | /* | ||
2 | * gpio-max3191x.c - GPIO driver for Maxim MAX3191x industrial serializer | ||
3 | * | ||
4 | * Copyright (C) 2017 KUNBUS GmbH | ||
5 | * | ||
6 | * The MAX3191x makes 8 digital 24V inputs available via SPI. | ||
7 | * Multiple chips can be daisy-chained, the spec does not impose | ||
8 | * a limit on the number of chips and neither does this driver. | ||
9 | * | ||
10 | * Either of two modes is selectable: In 8-bit mode, only the state | ||
11 | * of the inputs is clocked out to achieve high readout speeds; | ||
12 | * In 16-bit mode, an additional status byte is clocked out with | ||
13 | * a CRC and indicator bits for undervoltage and overtemperature. | ||
14 | * The driver returns an error instead of potentially bogus data | ||
15 | * if any of these fault conditions occur. However it does allow | ||
16 | * readout of non-faulting chips in the same daisy-chain. | ||
17 | * | ||
18 | * MAX3191x supports four debounce settings and the driver is | ||
19 | * capable of configuring these differently for each chip in the | ||
20 | * daisy-chain. | ||
21 | * | ||
22 | * If the chips are hardwired to 8-bit mode ("modesel" pulled high), | ||
23 | * gpio-pisosr.c can be used alternatively to this driver. | ||
24 | * | ||
25 | * https://datasheets.maximintegrated.com/en/ds/MAX31910.pdf | ||
26 | * https://datasheets.maximintegrated.com/en/ds/MAX31911.pdf | ||
27 | * https://datasheets.maximintegrated.com/en/ds/MAX31912.pdf | ||
28 | * https://datasheets.maximintegrated.com/en/ds/MAX31913.pdf | ||
29 | * https://datasheets.maximintegrated.com/en/ds/MAX31953-MAX31963.pdf | ||
30 | * | ||
31 | * This program is free software; you can redistribute it and/or modify | ||
32 | * it under the terms of the GNU General Public License (version 2) as | ||
33 | * published by the Free Software Foundation. | ||
34 | */ | ||
35 | |||
36 | #include <linux/bitmap.h> | ||
37 | #include <linux/crc8.h> | ||
38 | #include <linux/gpio/consumer.h> | ||
39 | #include <linux/gpio/driver.h> | ||
40 | #include <linux/module.h> | ||
41 | #include <linux/spi/spi.h> | ||
42 | |||
43 | enum max3191x_mode { | ||
44 | STATUS_BYTE_ENABLED, | ||
45 | STATUS_BYTE_DISABLED, | ||
46 | }; | ||
47 | |||
48 | /** | ||
49 | * struct max3191x_chip - max3191x daisy-chain | ||
50 | * @gpio: GPIO controller struct | ||
51 | * @lock: protects read sequences | ||
52 | * @nchips: number of chips in the daisy-chain | ||
53 | * @mode: current mode, 0 for 16-bit, 1 for 8-bit; | ||
54 | * for simplicity, all chips in the daisy-chain are assumed | ||
55 | * to use the same mode | ||
56 | * @modesel_pins: GPIO pins to configure modesel of each chip | ||
57 | * @fault_pins: GPIO pins to detect fault of each chip | ||
58 | * @db0_pins: GPIO pins to configure debounce of each chip | ||
59 | * @db1_pins: GPIO pins to configure debounce of each chip | ||
60 | * @mesg: SPI message to perform a readout | ||
61 | * @xfer: SPI transfer used by @mesg | ||
62 | * @crc_error: bitmap signaling CRC error for each chip | ||
63 | * @overtemp: bitmap signaling overtemperature alarm for each chip | ||
64 | * @undervolt1: bitmap signaling undervoltage alarm for each chip | ||
65 | * @undervolt2: bitmap signaling undervoltage warning for each chip | ||
66 | * @fault: bitmap signaling assertion of @fault_pins for each chip | ||
67 | * @ignore_uv: whether to ignore undervoltage alarms; | ||
68 | * set by a device property if the chips are powered through | ||
69 | * 5VOUT instead of VCC24V, in which case they will constantly | ||
70 | * signal undervoltage; | ||
71 | * for simplicity, all chips in the daisy-chain are assumed | ||
72 | * to be powered the same way | ||
73 | */ | ||
74 | struct max3191x_chip { | ||
75 | struct gpio_chip gpio; | ||
76 | struct mutex lock; | ||
77 | u32 nchips; | ||
78 | enum max3191x_mode mode; | ||
79 | struct gpio_descs *modesel_pins; | ||
80 | struct gpio_descs *fault_pins; | ||
81 | struct gpio_descs *db0_pins; | ||
82 | struct gpio_descs *db1_pins; | ||
83 | struct spi_message mesg; | ||
84 | struct spi_transfer xfer; | ||
85 | unsigned long *crc_error; | ||
86 | unsigned long *overtemp; | ||
87 | unsigned long *undervolt1; | ||
88 | unsigned long *undervolt2; | ||
89 | unsigned long *fault; | ||
90 | bool ignore_uv; | ||
91 | }; | ||
92 | |||
93 | #define MAX3191X_NGPIO 8 | ||
94 | #define MAX3191X_CRC8_POLYNOMIAL 0xa8 /* (x^5) + x^4 + x^2 + x^0 */ | ||
95 | |||
96 | DECLARE_CRC8_TABLE(max3191x_crc8); | ||
97 | |||
98 | static int max3191x_get_direction(struct gpio_chip *gpio, unsigned int offset) | ||
99 | { | ||
100 | return 1; /* always in */ | ||
101 | } | ||
102 | |||
103 | static int max3191x_direction_input(struct gpio_chip *gpio, unsigned int offset) | ||
104 | { | ||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static int max3191x_direction_output(struct gpio_chip *gpio, | ||
109 | unsigned int offset, int value) | ||
110 | { | ||
111 | return -EINVAL; | ||
112 | } | ||
113 | |||
114 | static void max3191x_set(struct gpio_chip *gpio, unsigned int offset, int value) | ||
115 | { } | ||
116 | |||
117 | static void max3191x_set_multiple(struct gpio_chip *gpio, unsigned long *mask, | ||
118 | unsigned long *bits) | ||
119 | { } | ||
120 | |||
121 | static unsigned int max3191x_wordlen(struct max3191x_chip *max3191x) | ||
122 | { | ||
123 | return max3191x->mode == STATUS_BYTE_ENABLED ? 2 : 1; | ||
124 | } | ||
125 | |||
126 | static int max3191x_readout_locked(struct max3191x_chip *max3191x) | ||
127 | { | ||
128 | struct device *dev = max3191x->gpio.parent; | ||
129 | struct spi_device *spi = to_spi_device(dev); | ||
130 | int val, i, ot = 0, uv1 = 0; | ||
131 | |||
132 | val = spi_sync(spi, &max3191x->mesg); | ||
133 | if (val) { | ||
134 | dev_err_ratelimited(dev, "SPI receive error %d\n", val); | ||
135 | return val; | ||
136 | } | ||
137 | |||
138 | for (i = 0; i < max3191x->nchips; i++) { | ||
139 | if (max3191x->mode == STATUS_BYTE_ENABLED) { | ||
140 | u8 in = ((u8 *)max3191x->xfer.rx_buf)[i * 2]; | ||
141 | u8 status = ((u8 *)max3191x->xfer.rx_buf)[i * 2 + 1]; | ||
142 | |||
143 | val = (status & 0xf8) != crc8(max3191x_crc8, &in, 1, 0); | ||
144 | __assign_bit(i, max3191x->crc_error, val); | ||
145 | if (val) | ||
146 | dev_err_ratelimited(dev, | ||
147 | "chip %d: CRC error\n", i); | ||
148 | |||
149 | ot = (status >> 1) & 1; | ||
150 | __assign_bit(i, max3191x->overtemp, ot); | ||
151 | if (ot) | ||
152 | dev_err_ratelimited(dev, | ||
153 | "chip %d: overtemperature\n", i); | ||
154 | |||
155 | if (!max3191x->ignore_uv) { | ||
156 | uv1 = !((status >> 2) & 1); | ||
157 | __assign_bit(i, max3191x->undervolt1, uv1); | ||
158 | if (uv1) | ||
159 | dev_err_ratelimited(dev, | ||
160 | "chip %d: undervoltage\n", i); | ||
161 | |||
162 | val = !(status & 1); | ||
163 | __assign_bit(i, max3191x->undervolt2, val); | ||
164 | if (val && !uv1) | ||
165 | dev_warn_ratelimited(dev, | ||
166 | "chip %d: voltage warn\n", i); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | if (max3191x->fault_pins && !max3191x->ignore_uv) { | ||
171 | /* fault pin shared by all chips or per chip */ | ||
172 | struct gpio_desc *fault_pin = | ||
173 | (max3191x->fault_pins->ndescs == 1) | ||
174 | ? max3191x->fault_pins->desc[0] | ||
175 | : max3191x->fault_pins->desc[i]; | ||
176 | |||
177 | val = gpiod_get_value_cansleep(fault_pin); | ||
178 | if (val < 0) { | ||
179 | dev_err_ratelimited(dev, | ||
180 | "GPIO read error %d\n", val); | ||
181 | return val; | ||
182 | } | ||
183 | __assign_bit(i, max3191x->fault, val); | ||
184 | if (val && !uv1 && !ot) | ||
185 | dev_err_ratelimited(dev, | ||
186 | "chip %d: fault\n", i); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static bool max3191x_chip_is_faulting(struct max3191x_chip *max3191x, | ||
194 | unsigned int chipnum) | ||
195 | { | ||
196 | /* without status byte the only diagnostic is the fault pin */ | ||
197 | if (!max3191x->ignore_uv && test_bit(chipnum, max3191x->fault)) | ||
198 | return true; | ||
199 | |||
200 | if (max3191x->mode == STATUS_BYTE_DISABLED) | ||
201 | return false; | ||
202 | |||
203 | return test_bit(chipnum, max3191x->crc_error) || | ||
204 | test_bit(chipnum, max3191x->overtemp) || | ||
205 | (!max3191x->ignore_uv && | ||
206 | test_bit(chipnum, max3191x->undervolt1)); | ||
207 | } | ||
208 | |||
209 | static int max3191x_get(struct gpio_chip *gpio, unsigned int offset) | ||
210 | { | ||
211 | struct max3191x_chip *max3191x = gpiochip_get_data(gpio); | ||
212 | int ret, chipnum, wordlen = max3191x_wordlen(max3191x); | ||
213 | u8 in; | ||
214 | |||
215 | mutex_lock(&max3191x->lock); | ||
216 | ret = max3191x_readout_locked(max3191x); | ||
217 | if (ret) | ||
218 | goto out_unlock; | ||
219 | |||
220 | chipnum = offset / MAX3191X_NGPIO; | ||
221 | if (max3191x_chip_is_faulting(max3191x, chipnum)) { | ||
222 | ret = -EIO; | ||
223 | goto out_unlock; | ||
224 | } | ||
225 | |||
226 | in = ((u8 *)max3191x->xfer.rx_buf)[chipnum * wordlen]; | ||
227 | ret = (in >> (offset % MAX3191X_NGPIO)) & 1; | ||
228 | |||
229 | out_unlock: | ||
230 | mutex_unlock(&max3191x->lock); | ||
231 | return ret; | ||
232 | } | ||
233 | |||
234 | static int max3191x_get_multiple(struct gpio_chip *gpio, unsigned long *mask, | ||
235 | unsigned long *bits) | ||
236 | { | ||
237 | struct max3191x_chip *max3191x = gpiochip_get_data(gpio); | ||
238 | int ret, bit = 0, wordlen = max3191x_wordlen(max3191x); | ||
239 | |||
240 | mutex_lock(&max3191x->lock); | ||
241 | ret = max3191x_readout_locked(max3191x); | ||
242 | if (ret) | ||
243 | goto out_unlock; | ||
244 | |||
245 | while ((bit = find_next_bit(mask, gpio->ngpio, bit)) != gpio->ngpio) { | ||
246 | unsigned int chipnum = bit / MAX3191X_NGPIO; | ||
247 | unsigned long in, shift, index; | ||
248 | |||
249 | if (max3191x_chip_is_faulting(max3191x, chipnum)) { | ||
250 | ret = -EIO; | ||
251 | goto out_unlock; | ||
252 | } | ||
253 | |||
254 | in = ((u8 *)max3191x->xfer.rx_buf)[chipnum * wordlen]; | ||
255 | shift = round_down(bit % BITS_PER_LONG, MAX3191X_NGPIO); | ||
256 | index = bit / BITS_PER_LONG; | ||
257 | bits[index] &= ~(mask[index] & (0xff << shift)); | ||
258 | bits[index] |= mask[index] & (in << shift); /* copy bits */ | ||
259 | |||
260 | bit = (chipnum + 1) * MAX3191X_NGPIO; /* go to next chip */ | ||
261 | } | ||
262 | |||
263 | out_unlock: | ||
264 | mutex_unlock(&max3191x->lock); | ||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | static int max3191x_set_config(struct gpio_chip *gpio, unsigned int offset, | ||
269 | unsigned long config) | ||
270 | { | ||
271 | struct max3191x_chip *max3191x = gpiochip_get_data(gpio); | ||
272 | u32 debounce, chipnum, db0_val, db1_val; | ||
273 | |||
274 | if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) | ||
275 | return -ENOTSUPP; | ||
276 | |||
277 | if (!max3191x->db0_pins || !max3191x->db1_pins) | ||
278 | return -EINVAL; | ||
279 | |||
280 | debounce = pinconf_to_config_argument(config); | ||
281 | switch (debounce) { | ||
282 | case 0: | ||
283 | db0_val = 0; | ||
284 | db1_val = 0; | ||
285 | break; | ||
286 | case 1 ... 25: | ||
287 | db0_val = 0; | ||
288 | db1_val = 1; | ||
289 | break; | ||
290 | case 26 ... 750: | ||
291 | db0_val = 1; | ||
292 | db1_val = 0; | ||
293 | break; | ||
294 | case 751 ... 3000: | ||
295 | db0_val = 1; | ||
296 | db1_val = 1; | ||
297 | break; | ||
298 | default: | ||
299 | return -EINVAL; | ||
300 | } | ||
301 | |||
302 | if (max3191x->db0_pins->ndescs == 1) | ||
303 | chipnum = 0; /* all chips use the same pair of debounce pins */ | ||
304 | else | ||
305 | chipnum = offset / MAX3191X_NGPIO; /* per chip debounce pins */ | ||
306 | |||
307 | mutex_lock(&max3191x->lock); | ||
308 | gpiod_set_value_cansleep(max3191x->db0_pins->desc[chipnum], db0_val); | ||
309 | gpiod_set_value_cansleep(max3191x->db1_pins->desc[chipnum], db1_val); | ||
310 | mutex_unlock(&max3191x->lock); | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static void gpiod_set_array_single_value_cansleep(unsigned int ndescs, | ||
315 | struct gpio_desc **desc, | ||
316 | int value) | ||
317 | { | ||
318 | int i, values[ndescs]; | ||
319 | |||
320 | for (i = 0; i < ndescs; i++) | ||
321 | values[i] = value; | ||
322 | |||
323 | gpiod_set_array_value_cansleep(ndescs, desc, values); | ||
324 | } | ||
325 | |||
326 | static struct gpio_descs *devm_gpiod_get_array_optional_count( | ||
327 | struct device *dev, const char *con_id, | ||
328 | enum gpiod_flags flags, unsigned int expected) | ||
329 | { | ||
330 | struct gpio_descs *descs; | ||
331 | int found = gpiod_count(dev, con_id); | ||
332 | |||
333 | if (found == -ENOENT) | ||
334 | return NULL; | ||
335 | |||
336 | if (found != expected && found != 1) { | ||
337 | dev_err(dev, "ignoring %s-gpios: found %d, expected %u or 1\n", | ||
338 | con_id, found, expected); | ||
339 | return NULL; | ||
340 | } | ||
341 | |||
342 | descs = devm_gpiod_get_array_optional(dev, con_id, flags); | ||
343 | |||
344 | if (IS_ERR(descs)) { | ||
345 | dev_err(dev, "failed to get %s-gpios: %ld\n", | ||
346 | con_id, PTR_ERR(descs)); | ||
347 | return NULL; | ||
348 | } | ||
349 | |||
350 | return descs; | ||
351 | } | ||
352 | |||
353 | static int max3191x_probe(struct spi_device *spi) | ||
354 | { | ||
355 | struct device *dev = &spi->dev; | ||
356 | struct max3191x_chip *max3191x; | ||
357 | int n, ret; | ||
358 | |||
359 | max3191x = devm_kzalloc(dev, sizeof(*max3191x), GFP_KERNEL); | ||
360 | if (!max3191x) | ||
361 | return -ENOMEM; | ||
362 | spi_set_drvdata(spi, max3191x); | ||
363 | |||
364 | max3191x->nchips = 1; | ||
365 | device_property_read_u32(dev, "#daisy-chained-devices", | ||
366 | &max3191x->nchips); | ||
367 | |||
368 | n = BITS_TO_LONGS(max3191x->nchips); | ||
369 | max3191x->crc_error = devm_kcalloc(dev, n, sizeof(long), GFP_KERNEL); | ||
370 | max3191x->undervolt1 = devm_kcalloc(dev, n, sizeof(long), GFP_KERNEL); | ||
371 | max3191x->undervolt2 = devm_kcalloc(dev, n, sizeof(long), GFP_KERNEL); | ||
372 | max3191x->overtemp = devm_kcalloc(dev, n, sizeof(long), GFP_KERNEL); | ||
373 | max3191x->fault = devm_kcalloc(dev, n, sizeof(long), GFP_KERNEL); | ||
374 | max3191x->xfer.rx_buf = devm_kcalloc(dev, max3191x->nchips, | ||
375 | 2, GFP_KERNEL); | ||
376 | if (!max3191x->crc_error || !max3191x->undervolt1 || | ||
377 | !max3191x->overtemp || !max3191x->undervolt2 || | ||
378 | !max3191x->fault || !max3191x->xfer.rx_buf) | ||
379 | return -ENOMEM; | ||
380 | |||
381 | max3191x->modesel_pins = devm_gpiod_get_array_optional_count(dev, | ||
382 | "maxim,modesel", GPIOD_ASIS, max3191x->nchips); | ||
383 | max3191x->fault_pins = devm_gpiod_get_array_optional_count(dev, | ||
384 | "maxim,fault", GPIOD_IN, max3191x->nchips); | ||
385 | max3191x->db0_pins = devm_gpiod_get_array_optional_count(dev, | ||
386 | "maxim,db0", GPIOD_OUT_LOW, max3191x->nchips); | ||
387 | max3191x->db1_pins = devm_gpiod_get_array_optional_count(dev, | ||
388 | "maxim,db1", GPIOD_OUT_LOW, max3191x->nchips); | ||
389 | |||
390 | max3191x->mode = device_property_read_bool(dev, "maxim,modesel-8bit") | ||
391 | ? STATUS_BYTE_DISABLED : STATUS_BYTE_ENABLED; | ||
392 | if (max3191x->modesel_pins) | ||
393 | gpiod_set_array_single_value_cansleep( | ||
394 | max3191x->modesel_pins->ndescs, | ||
395 | max3191x->modesel_pins->desc, max3191x->mode); | ||
396 | |||
397 | max3191x->ignore_uv = device_property_read_bool(dev, | ||
398 | "maxim,ignore-undervoltage"); | ||
399 | |||
400 | if (max3191x->db0_pins && max3191x->db1_pins && | ||
401 | max3191x->db0_pins->ndescs != max3191x->db1_pins->ndescs) { | ||
402 | dev_err(dev, "ignoring maxim,db*-gpios: array len mismatch\n"); | ||
403 | devm_gpiod_put_array(dev, max3191x->db0_pins); | ||
404 | devm_gpiod_put_array(dev, max3191x->db1_pins); | ||
405 | max3191x->db0_pins = NULL; | ||
406 | max3191x->db1_pins = NULL; | ||
407 | } | ||
408 | |||
409 | max3191x->xfer.len = max3191x->nchips * max3191x_wordlen(max3191x); | ||
410 | spi_message_init_with_transfers(&max3191x->mesg, &max3191x->xfer, 1); | ||
411 | |||
412 | max3191x->gpio.label = spi->modalias; | ||
413 | max3191x->gpio.owner = THIS_MODULE; | ||
414 | max3191x->gpio.parent = dev; | ||
415 | max3191x->gpio.base = -1; | ||
416 | max3191x->gpio.ngpio = max3191x->nchips * MAX3191X_NGPIO; | ||
417 | max3191x->gpio.can_sleep = true; | ||
418 | |||
419 | max3191x->gpio.get_direction = max3191x_get_direction; | ||
420 | max3191x->gpio.direction_input = max3191x_direction_input; | ||
421 | max3191x->gpio.direction_output = max3191x_direction_output; | ||
422 | max3191x->gpio.set = max3191x_set; | ||
423 | max3191x->gpio.set_multiple = max3191x_set_multiple; | ||
424 | max3191x->gpio.get = max3191x_get; | ||
425 | max3191x->gpio.get_multiple = max3191x_get_multiple; | ||
426 | max3191x->gpio.set_config = max3191x_set_config; | ||
427 | |||
428 | mutex_init(&max3191x->lock); | ||
429 | |||
430 | ret = gpiochip_add_data(&max3191x->gpio, max3191x); | ||
431 | if (ret) { | ||
432 | mutex_destroy(&max3191x->lock); | ||
433 | return ret; | ||
434 | } | ||
435 | |||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | static int max3191x_remove(struct spi_device *spi) | ||
440 | { | ||
441 | struct max3191x_chip *max3191x = spi_get_drvdata(spi); | ||
442 | |||
443 | gpiochip_remove(&max3191x->gpio); | ||
444 | mutex_destroy(&max3191x->lock); | ||
445 | |||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | static int __init max3191x_register_driver(struct spi_driver *sdrv) | ||
450 | { | ||
451 | crc8_populate_msb(max3191x_crc8, MAX3191X_CRC8_POLYNOMIAL); | ||
452 | return spi_register_driver(sdrv); | ||
453 | } | ||
454 | |||
455 | #ifdef CONFIG_OF | ||
456 | static const struct of_device_id max3191x_of_id[] = { | ||
457 | { .compatible = "maxim,max31910" }, | ||
458 | { .compatible = "maxim,max31911" }, | ||
459 | { .compatible = "maxim,max31912" }, | ||
460 | { .compatible = "maxim,max31913" }, | ||
461 | { .compatible = "maxim,max31953" }, | ||
462 | { .compatible = "maxim,max31963" }, | ||
463 | { } | ||
464 | }; | ||
465 | MODULE_DEVICE_TABLE(of, max3191x_of_id); | ||
466 | #endif | ||
467 | |||
468 | static const struct spi_device_id max3191x_spi_id[] = { | ||
469 | { "max31910" }, | ||
470 | { "max31911" }, | ||
471 | { "max31912" }, | ||
472 | { "max31913" }, | ||
473 | { "max31953" }, | ||
474 | { "max31963" }, | ||
475 | { } | ||
476 | }; | ||
477 | MODULE_DEVICE_TABLE(spi, max3191x_spi_id); | ||
478 | |||
479 | static struct spi_driver max3191x_driver = { | ||
480 | .driver = { | ||
481 | .name = "max3191x", | ||
482 | .of_match_table = of_match_ptr(max3191x_of_id), | ||
483 | }, | ||
484 | .probe = max3191x_probe, | ||
485 | .remove = max3191x_remove, | ||
486 | .id_table = max3191x_spi_id, | ||
487 | }; | ||
488 | module_driver(max3191x_driver, max3191x_register_driver, spi_unregister_driver); | ||
489 | |||
490 | MODULE_AUTHOR("Lukas Wunner <lukas@wunner.de>"); | ||
491 | MODULE_DESCRIPTION("GPIO driver for Maxim MAX3191x industrial serializer"); | ||
492 | MODULE_LICENSE("GPL v2"); | ||