/* * distance_sensor.c - driver for distance_sensor * 8bits out, 4bits in * * Copyright (C) 2012 Loongson Corporation * * 2013-03-15 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#define GPIOTRI 16 //#define GPIOECHO 17 #define GPIOTRI 3 #define GPIOECHO 2 #define SOUND_SPEED 340 static int distance_sensor_open(struct inode *inode, struct file *file) { //printk(KERN_ALERT"#####################sensor open ok!!!\n"); gpio_request(GPIOTRI,"TRIGGER"); gpio_request(GPIOECHO, "ECHO"); gpio_direction_input(GPIOECHO); gpio_direction_output(GPIOTRI,0); return 0; } static int distance_sensor_close(struct inode *inode, struct file *file) { gpio_free(GPIOTRI); gpio_free(GPIOECHO); //printk(KERN_ALERT"sensor close ok!!!\n"); return 0; } static ssize_t distance_sensor_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) { return 0; } static ssize_t distance_sensor_write(struct file *file, const char __user *buf, size_t count, loff_t *ptr) { return 0; } #if 0 static int get_time(void) { printk(KERN_ALERT"recive ok!"); struct timeval timeval1, timeval2; int count = 0; //int s; int us; while(!gpio_get_value(GPIOECHO)){ count ++; if(count > 0xf0000) break; }; printk(KERN_ALERT"step 1, count is 0x%x\n",count); do_gettimeofday(&timeval1); count = 0; while(gpio_get_value(GPIOECHO)){ count ++; if(count > 0xf00000) break; }; do_gettimeofday(&timeval2); printk(KERN_ALERT"step 2, count is 0x%x\n",count); //int s = (float)(timeval2.tv_sec-timeval1.tv_sec); us = (timeval2.tv_usec-timeval1.tv_usec) * SOUND_SPEED; printk(KERN_ALERT"distance is %d /1000000 m\n", us ); return us; } #endif static int get_time(void) { return gpio_get_value(GPIOECHO); } static long distance_sensor_ioctl( struct file *file, unsigned int cmd, unsigned long arg) { int ret; // printk(KERN_ALERT"in ioctl func!"); switch(cmd){ case 0: gpio_set_value(GPIOTRI, 1); break; case 1: { void __user *p = (void __user *)arg; ret = get_time(); copy_to_user(p, &ret, sizeof(ret)); } break; case 2: gpio_set_value(GPIOTRI, 0); break; default: printk(KERN_ALERT"in ioctl default!\n"); } return 0; } static const struct file_operations distance_sensor_ops = { .owner = THIS_MODULE, .open = distance_sensor_open, .release = distance_sensor_close, .read = distance_sensor_read, .write = distance_sensor_write, .unlocked_ioctl = distance_sensor_ioctl }; static struct miscdevice distance_sensor_miscdev = { MISC_DYNAMIC_MINOR, "d_s", &distance_sensor_ops, }; static int __init distance_sensor_init(void) { if (misc_register(&distance_sensor_miscdev)) { printk(KERN_ALERT"###############: Couldn't register device 0, %d.\n", 255); return -EBUSY; } return 0; } static void __exit distance_sensor_exit(void) { misc_deregister(&distance_sensor_miscdev); } module_init(distance_sensor_init); module_exit(distance_sensor_exit); MODULE_LICENSE("GPL");