2 * Linux Broadcom BCM47xx GPIO char driver
4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved.
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 * $Id: linux_gpio.c,v 1.10 2008-03-28 19:25:35 Exp $
20 #include <linux/module.h>
21 #include <linux/init.h>
23 #include <linux/miscdevice.h>
24 #include <asm/uaccess.h>
31 #include <linux_gpio.h>
33 /* handle to the sb */
34 static si_t
*gpio_sih
;
36 /* major number assigned to the device and device handles */
37 static int gpio_major
;
38 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
39 static struct class *gpiodev_class
= NULL
;
41 devfs_handle_t gpiodev_handle
;
45 gpio_open(struct inode
*inode
, struct file
* file
)
52 gpio_release(struct inode
*inode
, struct file
* file
)
59 gpio_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
61 struct gpio_ioctl gpioioc
;
63 if (copy_from_user(&gpioioc
, (struct gpio_ioctl
*)arg
, sizeof(struct gpio_ioctl
)))
67 case GPIO_IOC_RESERVE
:
68 gpioioc
.val
= si_gpioreserve(gpio_sih
, gpioioc
.mask
, GPIO_APP_PRIORITY
);
70 case GPIO_IOC_RELEASE
:
72 * releasing the gpio doesn't change the current
73 * value on the GPIO last write value
74 * persists till some one overwrites it
76 gpioioc
.val
= si_gpiorelease(gpio_sih
, gpioioc
.mask
, GPIO_APP_PRIORITY
);
79 gpioioc
.val
= si_gpioout(gpio_sih
, gpioioc
.mask
, gpioioc
.val
,
83 gpioioc
.val
= si_gpioouten(gpio_sih
, gpioioc
.mask
, gpioioc
.val
,
87 gpioioc
.val
= si_gpioin(gpio_sih
);
92 if (copy_to_user((struct gpio_ioctl
*)arg
, &gpioioc
, sizeof(struct gpio_ioctl
)))
98 static struct file_operations gpio_fops
= {
101 release
: gpio_release
,
108 if (!(gpio_sih
= si_kattach(SI_OSH
)))
111 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
112 if ((gpio_major
= register_chrdev(0, "gpio", &gpio_fops
)) < 0)
114 if ((gpio_major
= devfs_register_chrdev(0, "gpio", &gpio_fops
)) < 0)
117 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
118 gpiodev_class
= class_create(THIS_MODULE
, "gpio");
119 if (IS_ERR(gpiodev_class
)) {
120 printk("Error creating gpio class\n");
124 /* Add the device gpio0 */
125 class_device_create(gpiodev_class
, NULL
, MKDEV(gpio_major
, 0), NULL
, "gpio");
127 gpiodev_handle
= devfs_register(NULL
, "gpio", DEVFS_FL_DEFAULT
,
128 gpio_major
, 0, S_IFCHR
| S_IRUGO
| S_IWUGO
,
138 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
139 if (gpiodev_class
!= NULL
) {
140 class_device_destroy(gpiodev_class
, MKDEV(gpio_major
, 0));
141 class_destroy(gpiodev_class
);
144 gpiodev_class
= NULL
;
146 unregister_chrdev(gpio_major
, "gpio");
148 if (gpiodev_handle
!= NULL
)
149 devfs_unregister(gpiodev_handle
);
150 gpiodev_handle
= NULL
;
151 devfs_unregister_chrdev(gpio_major
, "gpio");
156 module_init(gpio_init
);
157 module_exit(gpio_exit
);