/* * Linux Broadcom BCM47xx GPIO char driver * * Copyright 2007, Broadcom Corporation * All Rights Reserved. * * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. * $Id: linux_gpio.c,v 1.1.1.1 2008/07/21 09:20:53 james26_jang Exp $ * */ #include #include #include #include #include #include #include #include #include #include /* handle to the sb */ static sb_t *gpio_sbh; /* major number assigned to the device and device handles */ static int gpio_major; devfs_handle_t gpiodev_handle; static int gpio_open(struct inode *inode, struct file * file) { MOD_INC_USE_COUNT; return 0; } static int gpio_release(struct inode *inode, struct file * file) { MOD_DEC_USE_COUNT; return 0; } static int gpio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct gpio_ioctl gpioioc; if (copy_from_user(&gpioioc, (struct gpio_ioctl *)arg, sizeof(struct gpio_ioctl))) return -EFAULT; switch (cmd) { case GPIO_IOC_RESERVE: gpioioc.val = sb_gpioreserve(gpio_sbh, gpioioc.mask, GPIO_APP_PRIORITY); break; case GPIO_IOC_RELEASE: /* * releasing the gpio doesn't change the current * value on the GPIO last write value * persists till some one overwrites it */ gpioioc.val = sb_gpiorelease(gpio_sbh, gpioioc.mask, GPIO_APP_PRIORITY); break; case GPIO_IOC_OUT: gpioioc.val = sb_gpioout(gpio_sbh, gpioioc.mask, gpioioc.val, GPIO_APP_PRIORITY); break; case GPIO_IOC_OUTEN: gpioioc.val = sb_gpioouten(gpio_sbh, gpioioc.mask, gpioioc.val, GPIO_APP_PRIORITY); break; case GPIO_IOC_IN: gpioioc.val = sb_gpioin(gpio_sbh); break; default: break; } if (copy_to_user((struct gpio_ioctl *)arg, &gpioioc, sizeof(struct gpio_ioctl))) return -EFAULT; return 0; } static struct file_operations gpio_fops = { owner: THIS_MODULE, open: gpio_open, release: gpio_release, ioctl: gpio_ioctl, }; static int __init gpio_init(void) { if (!(gpio_sbh = sb_kattach(SB_OSH))) return -ENODEV; if ((gpio_major = devfs_register_chrdev(0, "gpio", &gpio_fops)) < 0) return gpio_major; gpiodev_handle = devfs_register(NULL, "gpio", DEVFS_FL_DEFAULT, gpio_major, 0, S_IFCHR | S_IRUGO | S_IWUGO, &gpio_fops, NULL); return 0; } static void __exit gpio_exit(void) { if (gpiodev_handle != NULL) devfs_unregister(gpiodev_handle); gpiodev_handle = NULL; devfs_unregister_chrdev(gpio_major, "gpio"); sb_detach(gpio_sbh); } module_init(gpio_init); module_exit(gpio_exit);