2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16 * Copyright (C) 2005 infineon
17 * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
21 #include <linux/module.h>
22 #include <linux/types.h>
23 #include <linux/errno.h>
24 #include <linux/proc_fs.h>
25 #include <linux/init.h>
26 #include <linux/ioctl.h>
27 #include <asm/semaphore.h>
28 #include <asm/uaccess.h>
29 #include <asm/danube/danube.h>
30 #include <asm/danube/danube_ioctl.h>
33 #define PORT_IOC_CALL(ret,port,pin,func) \
34 ret=danube_port_reserve_pin(port,pin,PORT_MODULE_ID); \
35 if (ret == 0) ret=func(port,pin,PORT_MODULE_ID); \
36 if (ret == 0) ret=danube_port_free_pin(port,pin,PORT_MODULE_ID);
40 #define PINS_PER_PORT 16
42 static unsigned int danube_gpio_major
= 0;
44 /* TODO do we need this ? */
45 static struct semaphore port_sem
;
47 /* TODO do we really need this ? return in a define is forbidden by coding style */
48 #define DANUBE_GPIO_SANITY {if (port > MAX_PORTS || pin > PINS_PER_PORT) return -EINVAL; }
51 danube_port_reserve_pin (unsigned int port
, unsigned int pin
)
54 printk("%s : call to obseleted function\n", __func__
);
58 EXPORT_SYMBOL(danube_port_reserve_pin
);
61 danube_port_free_pin (unsigned int port
, unsigned int pin
)
64 printk("%s : call to obseleted function\n", __func__
);
68 EXPORT_SYMBOL(danube_port_free_pin
);
71 danube_port_set_open_drain (unsigned int port
, unsigned int pin
)
74 writel(readl(DANUBE_GPIO_P0_OD
+ (port
* 0x30)) | (1 << pin
), DANUBE_GPIO_P0_OD
);
78 EXPORT_SYMBOL(danube_port_set_open_drain
);
81 danube_port_clear_open_drain (unsigned int port
, unsigned int pin
)
84 writel(readl(DANUBE_GPIO_P0_OD
+ (port
* 0x30)) & ~(1 << pin
), DANUBE_GPIO_P0_OD
);
88 EXPORT_SYMBOL(danube_port_clear_open_drain
);
91 danube_port_set_pudsel (unsigned int port
, unsigned int pin
)
94 writel(readl(DANUBE_GPIO_P0_PUDSEL
+ (port
* 0x30)) | (1 << pin
), DANUBE_GPIO_P0_PUDSEL
);
98 EXPORT_SYMBOL(danube_port_set_pudsel
);
101 danube_port_clear_pudsel (unsigned int port
, unsigned int pin
)
104 writel(readl(DANUBE_GPIO_P0_PUDSEL
+ (port
* 0x30)) & ~(1 << pin
), DANUBE_GPIO_P0_PUDSEL
);
108 EXPORT_SYMBOL(danube_port_clear_pudsel
);
111 danube_port_set_puden (unsigned int port
, unsigned int pin
)
114 writel(readl(DANUBE_GPIO_P0_PUDEN
+ (port
* 0x30)) | (1 << pin
), DANUBE_GPIO_P0_PUDEN
);
118 EXPORT_SYMBOL(danube_port_set_puden
);
121 danube_port_clear_puden (unsigned int port
, unsigned int pin
)
124 writel(readl(DANUBE_GPIO_P0_PUDEN
+ (port
* 0x30)) & ~(1 << pin
), DANUBE_GPIO_P0_PUDEN
);
128 EXPORT_SYMBOL(danube_port_clear_puden
);
131 danube_port_set_stoff (unsigned int port
, unsigned int pin
)
134 writel(readl(DANUBE_GPIO_P0_STOFF
+ (port
* 0x30)) | (1 << pin
), DANUBE_GPIO_P0_STOFF
);
138 EXPORT_SYMBOL(danube_port_set_stoff
);
141 danube_port_clear_stoff (unsigned int port
, unsigned int pin
)
144 writel(readl(DANUBE_GPIO_P0_STOFF
+ (port
* 0x30)) & ~(1 << pin
), DANUBE_GPIO_P0_STOFF
);
148 EXPORT_SYMBOL(danube_port_clear_stoff
);
151 danube_port_set_dir_out (unsigned int port
, unsigned int pin
)
154 writel(readl(DANUBE_GPIO_P0_DIR
+ (port
* 0x30)) | (1 << pin
), DANUBE_GPIO_P0_DIR
);
158 EXPORT_SYMBOL(danube_port_set_dir_out
);
161 danube_port_set_dir_in (unsigned int port
, unsigned int pin
)
164 writel(readl(DANUBE_GPIO_P0_DIR
+ (port
* 0x30)) & ~(1 << pin
), DANUBE_GPIO_P0_DIR
);
168 EXPORT_SYMBOL(danube_port_set_dir_in
);
171 danube_port_set_output (unsigned int port
, unsigned int pin
)
174 writel(readl(DANUBE_GPIO_P0_OUT
+ (port
* 0x30)) | (1 << pin
), DANUBE_GPIO_P0_OUT
);
178 EXPORT_SYMBOL(danube_port_set_output
);
181 danube_port_clear_output (unsigned int port
, unsigned int pin
)
184 writel(readl(DANUBE_GPIO_P0_OUT
+ (port
* 0x30)) & ~(1 << pin
), DANUBE_GPIO_P0_OUT
);
188 EXPORT_SYMBOL(danube_port_clear_output
);
191 danube_port_get_input (unsigned int port
, unsigned int pin
)
195 if (readl(DANUBE_GPIO_P0_IN
+ (port
* 0x30)) & (1 << pin
))
200 EXPORT_SYMBOL(danube_port_get_input
);
203 danube_port_set_altsel0 (unsigned int port
, unsigned int pin
)
206 writel(readl(DANUBE_GPIO_P0_ALTSEL0
+ (port
* 0x30)) | (1 << pin
), DANUBE_GPIO_P0_ALTSEL0
);
210 EXPORT_SYMBOL(danube_port_set_altsel0
);
213 danube_port_clear_altsel0 (unsigned int port
, unsigned int pin
)
216 writel(readl(DANUBE_GPIO_P0_ALTSEL0
+ (port
* 0x30)) & ~(1 << pin
), DANUBE_GPIO_P0_ALTSEL0
);
220 EXPORT_SYMBOL(danube_port_clear_altsel0
);
223 danube_port_set_altsel1 (unsigned int port
, unsigned int pin
)
226 writel(readl(DANUBE_GPIO_P0_ALTSEL1
+ (port
* 0x30)) | (1 << pin
), DANUBE_GPIO_P0_ALTSEL1
);
230 EXPORT_SYMBOL(danube_port_set_altsel1
);
233 danube_port_clear_altsel1 (unsigned int port
, unsigned int pin
)
236 writel(readl(DANUBE_GPIO_P0_ALTSEL1
+ (port
* 0x30)) & ~(1 << pin
), DANUBE_GPIO_P0_ALTSEL1
);
240 EXPORT_SYMBOL(danube_port_clear_altsel1
);
242 long danube_port_read_procmem_helper(char* tag
, u32
* in_reg
, char *buf
)
247 len
= sprintf(buf
, "\n%s: ", tag
);
250 for (t
= 0; t
< 32; t
++) {
252 len
= len
+ sprintf(buf
+ len
, "X");
254 len
= len
+ sprintf(buf
+ len
, " ");
262 danube_port_read_procmem (char *buf
, char **start
, off_t offset
, int count
,
263 int *eof
, void *data
)
265 long len
= sprintf (buf
, "\nDanube Port Settings\n");
267 len
+= sprintf (buf
+ len
,
269 len
+= sprintf (buf
+ len
,
270 " 10987654321098765432109876543210\n");
271 len
+= sprintf (buf
+ len
,
272 "----------------------------------------\n");
274 len
+= danube_port_read_procmem_helper("P0-OUT", DANUBE_GPIO_P0_OUT
, &buf
[len
]);
275 len
+= danube_port_read_procmem_helper("P1-OUT", DANUBE_GPIO_P1_OUT
, &buf
[len
]);
276 len
+= danube_port_read_procmem_helper("P0-IN ", DANUBE_GPIO_P0_IN
, &buf
[len
]);
277 len
+= danube_port_read_procmem_helper("P1-IN ", DANUBE_GPIO_P1_IN
, &buf
[len
]);
278 len
+= danube_port_read_procmem_helper("P0-DIR", DANUBE_GPIO_P0_DIR
, &buf
[len
]);
279 len
+= danube_port_read_procmem_helper("P1-DIR", DANUBE_GPIO_P1_DIR
, &buf
[len
]);
280 len
+= danube_port_read_procmem_helper("P0-STO ", DANUBE_GPIO_P0_STOFF
, &buf
[len
]);
281 len
+= danube_port_read_procmem_helper("P1-STO ", DANUBE_GPIO_P1_STOFF
, &buf
[len
]);
282 len
+= danube_port_read_procmem_helper("P0-PUDE", DANUBE_GPIO_P0_PUDEN
, &buf
[len
]);
283 len
+= danube_port_read_procmem_helper("P1-PUDE", DANUBE_GPIO_P1_PUDEN
, &buf
[len
]);
284 len
+= danube_port_read_procmem_helper("P0-OD ", DANUBE_GPIO_P0_OD
, &buf
[len
]);
285 len
+= danube_port_read_procmem_helper("P1-OD ", DANUBE_GPIO_P1_OD
, &buf
[len
]);
286 len
+= danube_port_read_procmem_helper("P0-PUDS", DANUBE_GPIO_P0_PUDSEL
, &buf
[len
]);
287 len
+= danube_port_read_procmem_helper("P1-PUDS", DANUBE_GPIO_P1_PUDSEL
, &buf
[len
]);
288 len
+= danube_port_read_procmem_helper("P0-ALT0", DANUBE_GPIO_P0_ALTSEL0
, &buf
[len
]);
289 len
+= danube_port_read_procmem_helper("P1-ALT0", DANUBE_GPIO_P1_ALTSEL0
, &buf
[len
]);
290 len
+= danube_port_read_procmem_helper("P0-ALT1", DANUBE_GPIO_P0_ALTSEL1
, &buf
[len
]);
291 len
+= danube_port_read_procmem_helper("P1-ALT1", DANUBE_GPIO_P1_ALTSEL1
, &buf
[len
]);
292 len
= len
+ sprintf (buf
+ len
, "\n\n");
300 danube_port_open (struct inode
*inode
, struct file
*filep
)
306 danube_port_release (struct inode
*inode
, struct file
*filelp
)
312 danube_port_ioctl (struct inode
*inode
, struct file
*filp
,
313 unsigned int cmd
, unsigned long arg
)
316 volatile struct danube_port_ioctl_parm parm
;
318 if (_IOC_TYPE (cmd
) != DANUBE_PORT_IOC_MAGIC
)
321 if (_IOC_DIR (cmd
) & _IOC_WRITE
) {
324 sizeof (struct danube_port_ioctl_parm
)))
326 ret
= copy_from_user ((void *) &parm
, (void *) arg
,
327 sizeof (struct danube_port_ioctl_parm
));
329 if (_IOC_DIR (cmd
) & _IOC_READ
) {
332 sizeof (struct danube_port_ioctl_parm
)))
336 if (down_trylock (&port_sem
) != 0)
340 case DANUBE_PORT_IOCOD
:
341 if (parm
.value
== 0x00) {
342 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
343 danube_port_clear_open_drain
);
346 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
347 danube_port_set_open_drain
);
350 case DANUBE_PORT_IOCPUDSEL
:
351 if (parm
.value
== 0x00) {
352 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
353 danube_port_clear_pudsel
);
356 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
357 danube_port_set_pudsel
);
360 case DANUBE_PORT_IOCPUDEN
:
361 if (parm
.value
== 0x00) {
362 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
363 danube_port_clear_puden
);
366 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
367 danube_port_set_puden
);
370 case DANUBE_PORT_IOCSTOFF
:
371 if (parm
.value
== 0x00) {
372 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
373 danube_port_clear_stoff
);
376 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
377 danube_port_set_stoff
);
380 case DANUBE_PORT_IOCDIR
:
381 if (parm
.value
== 0x00) {
382 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
383 danube_port_set_dir_in
);
386 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
387 danube_port_set_dir_out
);
390 case DANUBE_PORT_IOCOUTPUT
:
391 if (parm
.value
== 0x00) {
392 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
393 danube_port_clear_output
);
396 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
397 danube_port_set_output
);
400 case DANUBE_PORT_IOCALTSEL0
:
401 if (parm
.value
== 0x00) {
402 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
403 danube_port_clear_altsel0
);
406 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
407 danube_port_set_altsel0
);
410 case DANUBE_PORT_IOCALTSEL1
:
411 if (parm
.value
== 0x00) {
412 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
413 danube_port_clear_altsel1
);
416 PORT_IOC_CALL (ret
, parm
.port
, parm
.pin
,
417 danube_port_set_altsel1
);
420 case DANUBE_PORT_IOCINPUT
:
421 ret
= danube_port_reserve_pin (parm
.port
, parm
.pin
,
425 danube_port_get_input (parm
.port
, parm
.pin
,
427 ret
= danube_port_free_pin (parm
.port
, parm
.pin
,
429 copy_to_user ((void *) arg
, (void *) &parm
,
430 sizeof (struct danube_port_ioctl_parm
));
441 static struct file_operations port_fops
= {
442 .open
= danube_port_open
,
443 .release
= danube_port_release
,
444 .ioctl
= danube_port_ioctl
448 danube_gpio_init (void)
452 sema_init (&port_sem
, 1);
454 danube_gpio_major
= register_chrdev(0, "danube_gpio", &port_fops
);
455 if (!danube_gpio_major
)
457 printk("danube-port: Error! Could not register port device. #%d\n", danube_gpio_major
);
462 create_proc_read_entry("driver/danube_port", 0, NULL
,
463 danube_port_read_procmem
, NULL
);
465 printk("registered danube gpio driver\n");
472 danube_gpio_exit (void)
474 unregister_chrdev(danube_gpio_major
, "danube_gpio");
475 remove_proc_entry("danube_wdt", NULL
);
478 module_init(danube_gpio_init
);
479 module_exit(danube_gpio_exit
);