2 * GPIO Testing Device Driver
4 * Copyright (C) 2014 Kamlakant Patel <kamlakant.patel@broadcom.com>
5 * Copyright (C) 2015-2016 Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
14 #include <linux/init.h>
15 #include <linux/module.h>
16 #include <linux/gpio/driver.h>
17 #include <linux/platform_device.h>
19 #define GPIO_NAME "gpio-mockup"
28 * struct gpio_pin_status - structure describing a GPIO status
29 * @dir: Configures direction of gpio as "in" or "out", 0=in, 1=out
30 * @value: Configures status of the gpio as 0(low) or 1(high)
32 struct gpio_pin_status
{
37 struct mockup_gpio_controller
{
39 struct gpio_pin_status
*stats
;
42 static int gpio_mockup_ranges
[MAX_GC
<< 1];
43 static int gpio_mockup_params_nr
;
44 module_param_array(gpio_mockup_ranges
, int, &gpio_mockup_params_nr
, 0400);
46 const char pins_name_start
= 'A';
48 static int mockup_gpio_get(struct gpio_chip
*gc
, unsigned int offset
)
50 struct mockup_gpio_controller
*cntr
= gpiochip_get_data(gc
);
52 return cntr
->stats
[offset
].value
;
55 static void mockup_gpio_set(struct gpio_chip
*gc
, unsigned int offset
,
58 struct mockup_gpio_controller
*cntr
= gpiochip_get_data(gc
);
60 cntr
->stats
[offset
].value
= !!value
;
63 static int mockup_gpio_dirout(struct gpio_chip
*gc
, unsigned int offset
,
66 struct mockup_gpio_controller
*cntr
= gpiochip_get_data(gc
);
68 mockup_gpio_set(gc
, offset
, value
);
69 cntr
->stats
[offset
].dir
= OUT
;
73 static int mockup_gpio_dirin(struct gpio_chip
*gc
, unsigned int offset
)
75 struct mockup_gpio_controller
*cntr
= gpiochip_get_data(gc
);
77 cntr
->stats
[offset
].dir
= IN
;
81 static int mockup_gpio_get_direction(struct gpio_chip
*gc
, unsigned int offset
)
83 struct mockup_gpio_controller
*cntr
= gpiochip_get_data(gc
);
85 return cntr
->stats
[offset
].dir
;
88 static int mockup_gpio_add(struct device
*dev
,
89 struct mockup_gpio_controller
*cntr
,
90 const char *name
, int base
, int ngpio
)
95 cntr
->gc
.ngpio
= ngpio
;
96 cntr
->gc
.label
= name
;
97 cntr
->gc
.owner
= THIS_MODULE
;
98 cntr
->gc
.parent
= dev
;
99 cntr
->gc
.get
= mockup_gpio_get
;
100 cntr
->gc
.set
= mockup_gpio_set
;
101 cntr
->gc
.direction_output
= mockup_gpio_dirout
;
102 cntr
->gc
.direction_input
= mockup_gpio_dirin
;
103 cntr
->gc
.get_direction
= mockup_gpio_get_direction
;
104 cntr
->stats
= devm_kzalloc(dev
, sizeof(*cntr
->stats
) * cntr
->gc
.ngpio
,
110 ret
= devm_gpiochip_add_data(dev
, &cntr
->gc
, cntr
);
114 dev_info(dev
, "gpio<%d..%d> add successful!", base
, base
+ ngpio
);
117 dev_err(dev
, "gpio<%d..%d> add failed!", base
, base
+ ngpio
);
121 static int mockup_gpio_probe(struct platform_device
*pdev
)
123 struct device
*dev
= &pdev
->dev
;
124 struct mockup_gpio_controller
*cntr
;
129 char chip_name
[sizeof(GPIO_NAME
) + 3];
131 if (gpio_mockup_params_nr
< 2)
134 cntr
= devm_kzalloc(dev
, sizeof(*cntr
) * (gpio_mockup_params_nr
>> 1),
139 platform_set_drvdata(pdev
, cntr
);
141 for (i
= 0; i
< gpio_mockup_params_nr
>> 1; i
++) {
142 base
= gpio_mockup_ranges
[i
* 2];
144 ngpio
= gpio_mockup_ranges
[i
* 2 + 1];
146 ngpio
= gpio_mockup_ranges
[i
* 2 + 1] - base
;
149 sprintf(chip_name
, "%s-%c", GPIO_NAME
,
150 pins_name_start
+ i
);
151 ret
= mockup_gpio_add(dev
, &cntr
[i
],
152 chip_name
, base
, ngpio
);
158 dev_err(dev
, "gpio<%d..%d> add failed\n",
161 dev_err(dev
, "gpio<%d..%d> add failed\n",
171 static struct platform_driver mockup_gpio_driver
= {
175 .probe
= mockup_gpio_probe
,
178 static struct platform_device
*pdev
;
179 static int __init
mock_device_init(void)
183 pdev
= platform_device_alloc(GPIO_NAME
, -1);
187 err
= platform_device_add(pdev
);
189 platform_device_put(pdev
);
193 err
= platform_driver_register(&mockup_gpio_driver
);
195 platform_device_unregister(pdev
);
202 static void __exit
mock_device_exit(void)
204 platform_driver_unregister(&mockup_gpio_driver
);
205 platform_device_unregister(pdev
);
208 module_init(mock_device_init
);
209 module_exit(mock_device_exit
);
211 MODULE_AUTHOR("Kamlakant Patel <kamlakant.patel@broadcom.com>");
212 MODULE_AUTHOR("Bamvor Jian Zhang <bamvor.zhangjian@linaro.org>");
213 MODULE_DESCRIPTION("GPIO Testing driver");
214 MODULE_LICENSE("GPL v2");