90d0892b7a13a166da616d956661337646596e62
2 * gpio_test.c - GPIO test driver
4 * Copyright (C) 2008 Peter Henn
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * It just triggers a specified GPIO line setup the output
22 #include <linux/kernel.h>
23 #include <linux/init.h>
24 #include <linux/device.h>
25 #include <linux/interrupt.h>
26 #include <linux/gpio.h>
29 //*****************************************************************************
31 //*****************************************************************************
32 #define DRVNAME "gpio_test" /* name of the driver */
33 #define DRIVER_VERSION "0.1" /* helps identifing different versions of that driver */
36 static unsigned int gpi
;
37 static unsigned int gpo
;
38 static unsigned int val
;
39 static unsigned int irq
= -1;
48 static gpio_t_struct gt
;
50 static irqreturn_t
gpio_test_irq_handler(int irq
, void *dev_id
)
53 // todo use dev_id to get pointer to own driver structure data;
54 // container can be memory init with GPK_KERNEL
58 if (!gt
.in_cansleep
) {
59 pr_info("%s: GPIO #%d in value %d with counter %d\n", DRVNAME
, gpi
, gpio_get_value(gpi
), gt
.cnt
);
61 if (!gt
.out_cansleep
) {
62 gpio_set_value(gpo
, !val
);
69 ** just set here the value
71 static int __init
gpio_test_init(void)
74 err
= gpio_is_valid(gpo
);
76 pr_err("%s: GPIO #%d for output is not usable\n", DRVNAME
, gpo
);
79 //ToDo: Test, how a text might be used as LABEL
80 err
= gpio_request(gpo
, LABEL
);
82 pr_err("%s: GPIO #%d for output is can not be requested\n", DRVNAME
, gpo
);
85 gt
.out_cansleep
= gpio_cansleep(gpo
);
86 pr_info("%s: GPIO #%d for output %s sleep\n", DRVNAME
, gpo
, ((gt
.out_cansleep
>0) ?
"can" : "will not"));
87 err
= gpio_direction_output(gpo
, val
);
89 pr_err("%s: GPIO #%d output direction is not possible\n", DRVNAME
, gpo
);
94 err
= gpio_is_valid(gpi
);
96 pr_err("%s: GPIO #%d for inout is not usable\n", DRVNAME
, gpi
);
100 err
= gpio_request(gpi
, LABEL
);
102 pr_err("%s: GPIO #%d for input is can not be requested\n", DRVNAME
, gpi
);
106 gt
.in_cansleep
= gpio_cansleep(gpi
);
107 pr_info("%s: GPIO #%d for input %s sleep\n", DRVNAME
, gpi
, ((gt
.in_cansleep
>0) ?
"can" : "will not"));
108 gt
.irq
= gpio_to_irq(gpi
);
110 pr_info("%s: GPIO #%d IRQ is not supported\n", DRVNAME
, gpi
);
113 pr_info("%s: we force interrupt to IRQ %d\n", DRVNAME
, gt
.irq
);
116 pr_info("%s: GPIO #%d IRQ %d is supported\n", DRVNAME
, gpi
, gt
.irq
);
118 /* gpio_direction_output must be call from task context, we use insmod as task context here */
119 err
= gpio_direction_input(gpi
);
121 pr_err("%s: GPIO #%d input direction is not possible\n", DRVNAME
, gpi
);
127 /* register irq handler */
128 // ToDo: Test with other flag types: IRQF_SHARED, IRQF_TRIGGER_*
130 err
= request_irq(gt
.irq
, gpio_test_irq_handler
, IRQF_TRIGGER_NONE
, "gpio_test_handler", NULL
);
132 pr_err("%s: GPIO #%d IRQ %d can not be requested, got %d\n", DRVNAME
, gpi
, gt
.irq
, err
);
139 device_initcall(gpio_test_init
);
142 ** just restore here the old value
144 static void __exit
gpio_test_exit(void)
146 if (gt
.out_cansleep
) {
147 gpio_set_value_cansleep(gpo
, !val
);
149 gpio_set_value(gpo
, !val
);
151 if (gt
.irq
>= 0) free_irq(gt
.irq
, NULL
);
155 module_exit(gpio_test_exit
);
157 module_param(gpo
, uint
, S_IRUGO
);
158 MODULE_PARM_DESC(gpo
, "GPIO output address or number");
160 module_param(gpi
, uint
, S_IRUGO
);
161 MODULE_PARM_DESC(gpi
, "GPIO input address or number");
163 module_param(val
, bool, S_IRUGO
);
164 MODULE_PARM_DESC(val
, "GPIO output value 0 or 1");
166 module_param(irq
, uint
, S_IRUGO
);
167 MODULE_PARM_DESC(irq
, "GPIO interrupt number");
170 MODULE_AUTHOR("Option Wireless");
171 MODULE_DESCRIPTION("GPIO output test");
172 MODULE_LICENSE("GPL");
174 MODULE_INFO(Version
, DRIVER_VERSION
);