gpio.c
上传用户:beauty0755
上传日期:2022-02-24
资源大小:7k
文件大小:4k
- #include <linux/init.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/delay.h>
- #include <linux/proc_fs.h>
- #include <asm/uaccess.h>
- #include "gpio.h"
- #ifdef DEBUG
- #define PRINTK(format,argument...) printk(format,##argument)
- #else
- #define PRINTK(format,argument...)
- #endif
- MODULE_DESCRIPTION("IXP400 GPIO driver");
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("ONet Corporation");
- #define MODULE_NAME "gpio"
- #define MOD_VERSION "0.1"
- static struct semaphore led_sem;
- static spinlock_t device_lock;
- static struct timer_list led_slow_timer;
- int led_atoi( char *name)
- {
- int val = 0;
- for(;;name++)
- {
- switch(*name)
- {
- case '0'...'9':
- val = val*10+(*name - '0');
- break;
- default:
- return val;
- }
- }
- }
- void led_on(unsigned long gpio,int logic)
- {
- *IXP4XX_GPIO_GPOUTR |= gpio;
- *IXP4XX_GPIO_GPOER &= ~gpio;
- }
- void led_off(unsigned long gpio,int logic)
- {
- *IXP4XX_GPIO_GPOUTR &= ~gpio;
- *IXP4XX_GPIO_GPOER &= ~gpio;
- }
- static void led_blink_timer(unsigned long speed)
- {
- if(speed)
- {
- led_on (1 << 10,-1);
- led_slow_timer.expires=jiffies+FAST_INTERVAL;
- }
- else
- {
- led_off(1 << 10,-1);
- led_slow_timer.expires=jiffies+SLOW_INTERVAL;
- }
-
- led_slow_timer.data = !speed;
- add_timer(&led_slow_timer);
- }
- void led_getall(void)
- {
- PRINTK("IXP4XX_GPIO_GPINR == 0x%08xn", *IXP4XX_GPIO_GPINR);
- }
- ssize_t proc_read_gpio_fops(struct file *filp,
- char *buf, size_t count, loff_t *offp)
- {
- char tmp[32]="";
- int len;
- memset(tmp, ' ', 32);
- sprintf(tmp,"%d", *IXP4XX_GPIO_GPINR);
- // printk("IXP4XX_GPIO_GPINR == 0x%04x, tmp is %sn", *IXP4XX_GPIO_GPINR, tmp);
-
- if (copy_to_user(buf, tmp, strlen(tmp)+1))
- return -EFAULT;
- *offp = strlen(tmp)+1;
-
- // printk("len is %dn", strlen(tmp)+1);
-
- return 0;
- }
- ssize_t proc_write_gpio_fops(struct file *filp,const char *buffer,
- size_t count , loff_t *offp)
- {
- char line[10];
- unsigned long irqflags = 0x00;
- int k;
-
- copy_from_user(line,buffer,count);
- line[count]=0x00;
-
- if(count<1)
- return count;
-
- down_interruptible(&led_sem);
- spin_lock_irqsave(&device_lock, irqflags);
- switch(line[0])
- {
- case 'i':
- for(k = 0; k < 16; k++)
- led_on(1 << k,-1);
- break;
- case 'I':
- for(k = 0; k < 16; k++)
- led_off(1 << k,-1);
- break;
- case 'b':
- case 'x':
- led_on(1 << led_atoi(&line[1]),-1);
- break;
- case 'l':
- case 'X':
- led_off(1 << led_atoi(&line[1]),-1);
- mdelay(50);
- break;
- case 'a':
- led_getall();
- break;
- default:
- break;
- }
-
- spin_unlock_irqrestore(&device_lock, irqflags);
- up(&led_sem);
- return count;
- }
- static struct proc_dir_entry *gpio_module_file;
- struct file_operations gpio_module_fops = {
- read: proc_read_gpio_fops,
- write: proc_write_gpio_fops,
- };
- static int __init gpio_module_init(void)
- {
-
- gpio_module_file = create_proc_entry("gpio",0666,&proc_root);
- gpio_module_file->owner = THIS_MODULE;
- gpio_module_file->proc_fops = &gpio_module_fops;
- init_timer(&led_slow_timer);
- led_slow_timer.data=1;
- led_slow_timer.expires=jiffies+FAST_INTERVAL;
- led_slow_timer.function=led_blink_timer;
- add_timer(&led_slow_timer);
-
- sema_init(&led_sem,1);
-
- return 0;
- }
- static void __exit gpio_module_cleanup(void)
- {
- del_timer(&led_slow_timer);
- remove_proc_entry("gpio",&proc_root);
- }
- module_init(gpio_module_init);
- module_exit(gpio_module_cleanup);