1 // SPDX-License-Identifier: GPL-2.0-only
3 * GPIO driver for the MikroTik RouterBoard 4xx series
5 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
6 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7 * Copyright (C) 2015 Bert Vermeulen <bert@biot.com>
8 * Copyright (C) 2020 Christopher Hill <ch6574@gmail.com>
10 * This file was based on the driver for Linux 2.6.22 published by
11 * MikroTik for their RouterBoard 4xx series devices.
13 * N.B. driver probe reports "DMA mask not set" warnings which are
14 * an artifact of using a platform_driver as an MFD device child.
15 * See conversation here https://lkml.org/lkml/2020/4/28/675
17 #include <linux/platform_device.h>
18 #include <linux/gpio/driver.h>
19 #include <linux/module.h>
20 #include <linux/of_device.h>
22 #include <mfd/rb4xx-cpld.h>
25 struct rb4xx_cpld
*cpld
;
28 struct gpio_chip chip
;
30 u16 values
; /* bitfield of GPIO 0-8 current values */
33 static int rb4xx_gpio_cpld_set(struct rb4xx_gpio
*gpio
, unsigned int offset
,
36 struct rb4xx_cpld
*cpld
= gpio
->cpld
;
40 mutex_lock(&gpio
->lock
);
41 values
= gpio
->values
;
44 values
|= BIT(offset
);
46 values
&= ~(BIT(offset
));
48 if (values
== gpio
->values
) {
54 ret
= cpld
->gpio_set_0_7(cpld
, values
& 0xff);
55 } else if (offset
== 8) {
56 ret
= cpld
->gpio_set_8(cpld
, values
>> 8);
60 gpio
->values
= values
;
63 mutex_unlock(&gpio
->lock
);
67 static int rb4xx_gpio_get_direction(struct gpio_chip
*chip
, unsigned int offset
)
69 return 0; /* All 9 GPIOs are out */
72 static int rb4xx_gpio_direction_input(struct gpio_chip
*chip
,
78 static int rb4xx_gpio_direction_output(struct gpio_chip
*chip
,
79 unsigned int offset
, int value
)
81 return rb4xx_gpio_cpld_set(gpiochip_get_data(chip
), offset
, value
);
84 static int rb4xx_gpio_get(struct gpio_chip
*chip
, unsigned int offset
)
86 struct rb4xx_gpio
*gpio
= gpiochip_get_data(chip
);
89 mutex_lock(&gpio
->lock
);
90 ret
= (gpio
->values
>> offset
) & 0x1;
91 mutex_unlock(&gpio
->lock
);
96 static void rb4xx_gpio_set(struct gpio_chip
*chip
, unsigned int offset
,
99 rb4xx_gpio_cpld_set(gpiochip_get_data(chip
), offset
, value
);
102 static int rb4xx_gpio_probe(struct platform_device
*pdev
)
104 struct device
*dev
= &pdev
->dev
;
105 struct device
*parent
= dev
->parent
;
106 struct rb4xx_gpio
*gpio
;
112 gpio
= devm_kzalloc(dev
, sizeof(*gpio
), GFP_KERNEL
);
116 platform_set_drvdata(pdev
, gpio
);
117 gpio
->cpld
= dev_get_drvdata(parent
);
120 mutex_init(&gpio
->lock
);
122 gpio
->chip
.label
= "rb4xx-gpio";
123 gpio
->chip
.parent
= dev
;
124 gpio
->chip
.owner
= THIS_MODULE
;
125 gpio
->chip
.get_direction
= rb4xx_gpio_get_direction
;
126 gpio
->chip
.direction_input
= rb4xx_gpio_direction_input
;
127 gpio
->chip
.direction_output
= rb4xx_gpio_direction_output
;
128 gpio
->chip
.get
= rb4xx_gpio_get
;
129 gpio
->chip
.set
= rb4xx_gpio_set
;
130 gpio
->chip
.ngpio
= 9;
131 gpio
->chip
.base
= -1;
132 gpio
->chip
.can_sleep
= 1;
134 if (!of_property_read_u32(dev
->of_node
, "base", &val
))
135 gpio
->chip
.base
= val
;
137 return gpiochip_add_data(&gpio
->chip
, gpio
);
140 static int rb4xx_gpio_remove(struct platform_device
*pdev
)
142 struct rb4xx_gpio
*gpio
= platform_get_drvdata(pdev
);
144 gpiochip_remove(&gpio
->chip
);
145 mutex_destroy(&gpio
->lock
);
150 static const struct platform_device_id rb4xx_gpio_id_table
[] = {
151 { "mikrotik,rb4xx-gpio", },
154 MODULE_DEVICE_TABLE(platform
, rb4xx_gpio_id_table
);
156 static struct platform_driver rb4xx_gpio_driver
= {
157 .probe
= rb4xx_gpio_probe
,
158 .remove
= rb4xx_gpio_remove
,
159 .id_table
= rb4xx_gpio_id_table
,
161 .name
= "rb4xx-gpio",
165 module_platform_driver(rb4xx_gpio_driver
);
167 MODULE_DESCRIPTION("Mikrotik RB4xx GPIO driver");
168 MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
169 MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org>");
170 MODULE_AUTHOR("Bert Vermeulen <bert@biot.com>");
171 MODULE_AUTHOR("Christopher Hill <ch6574@gmail.com");
172 MODULE_LICENSE("GPL v2");