/*****驱动源代码*****/ /****wzk_ds18b20.c*****/ #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/miscdevice.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/cdev.h> #include <asm/irq.h> #include <mach/gpio.h> #include <mach/regs-gpio.h> #include <mach/gpio-bank-n.h> #include <mach/map.h> //S3C64XX_VA_GPIO #include <plat/gpio-cfg.h> #include <mach/hardware.h> #include <linux/io.h> #include <asm/io.h> #define DEVICE_NAME "ds18b20" static unsigned long ds18b20_table [] = { S3C64XX_GPN(8), }; unsigned int init_ds18b20(void) { unsigned tmp; unsigned int val; s3c_gpio_cfgpin(ds18b20_table[0],S3C_GPIO_SFN(1)); tmp = readl(S3C64XX_GPNDAT); tmp = tmp | 0x0100; writel(tmp,S3C64XX_GPNDAT); udelay(2); tmp = tmp & 0xfeff; writel(tmp,S3C64XX_GPNDAT); udelay(500); tmp = tmp | 0x0100; writel(tmp,S3C64XX_GPNDAT); udelay(60); s3c_gpio_cfgpin(ds18b20_table[0],S3C_GPIO_SFN(0)); tmp = readl(S3C64XX_GPNDAT); val = tmp & 0x0100; udelay(500); s3c_gpio_cfgpin(ds18b20_table[0],S3C_GPIO_SFN(1)); tmp = readl(S3C64XX_GPNDAT); tmp = tmp | 0x0100; writel(tmp,S3C64XX_GPNDAT); return val; } static void write_ds18b20(unsigned char data) { unsigned tmp; //unsigned char tmp1; int i; s3c_gpio_cfgpin(ds18b20_table[0],S3C_GPIO_SFN(1)); for(i = 0;i < 8;i ++) { tmp = readl(S3C64XX_GPNDAT); tmp = tmp | 0x0100; writel(tmp,S3C64XX_GPNDAT); udelay(2); tmp = tmp & 0xfeff; writel(tmp,S3C64XX_GPNDAT); if(data & 0x01) { tmp = tmp | 0x0100; }else { tmp = tmp & 0xfeff; } writel(tmp,S3C64XX_GPNDAT); udelay(60); data >>= 1; } tmp = tmp | 0x0100; writel(tmp,S3C64XX_GPNDAT); return; } unsigned char read_ds18b20(void) { unsigned tmp; unsigned char data; int i; data = 0; for(i = 0; i < 8;i ++) { s3c_gpio_cfgpin(ds18b20_table[0],S3C_GPIO_SFN(1)); tmp = readl(S3C64XX_GPNDAT); tmp = tmp | 0x0100; writel(tmp,S3C64XX_GPNDAT); udelay(2); tmp = tmp & 0xfeff; writel(tmp,S3C64XX_GPNDAT); udelay(2); tmp = tmp | 0x0100; writel(tmp,S3C64XX_GPNDAT); udelay(8); data >>= 1; s3c_gpio_cfgpin(ds18b20_table[0],S3C_GPIO_SFN(0)); tmp = readl(S3C64XX_GPNDAT); if(tmp & 0x0100) { data = data | 0x80; } udelay(50); } s3c_gpio_cfgpin(ds18b20_table[0],S3C_GPIO_SFN(1)); tmp = readl(S3C64XX_GPNDAT); tmp = tmp | 0x0100; writel(tmp,S3C64XX_GPNDAT); return data; } int s3c6410_ds18b20_open(struct inode *inode,struct file *file) { unsigned int reset; reset = init_ds18b20(); if(reset) { printk("reset error!\n"); return -1; } printk("reset successes!\n"); return 0; } static long s3c6410_ds18b20_ioctl(struct file *file, unsigned int cmd,unsigned long arg) { unsigned int result[2]; unsigned int ret; ret = init_ds18b20(); if(ret) { printk("reset error!\n"); return -1; } // write_data(0); write_ds18b20(0xcc); write_ds18b20(0x44); // mdelay(800); ret = init_ds18b20(); if(ret) { printk("reset error!\n"); return -1; } write_ds18b20(0xcc); write_ds18b20(0xbe); result[0] = read_ds18b20(); result[1] = read_ds18b20(); // printk("%x,%x\n",result[0],result[1]); result[1] <<= 8; result[0] = result[0] | result[1]; return (long)result[0]; // return 0; } static ssize_t s3c6410_ds18b20_read(struct file *filp, char __user *buf,size_t count,loff_t *f_ops) {/* unsigned int reset; reset = init_ds18b20(); if(reset) { printk("reset error!\n"); return -1; } printk("reset successes!\n"); */ // write_data(0); return 0; } static struct file_operations s3c6410_ds18b20_fops = { .owner = THIS_MODULE, .open = s3c6410_ds18b20_open, .unlocked_ioctl = s3c6410_ds18b20_ioctl, .read = s3c6410_ds18b20_read, }; static struct cdev cdev_ds18b20; struct class * my_class; dev_t devno; static int __init s3c6410_ds18b20_init(void) { int ret; // dev_t devno; printk(KERN_NOTICE "enter s3c6410_ds18b20_init\n"); ret = alloc_chrdev_region(&devno,0,1,DEVICE_NAME); if(ret) { printk(KERN_NOTICE "can not register ds18b20 device"); return ret; } cdev_init(&cdev_ds18b20,&s3c6410_ds18b20_fops); cdev_ds18b20.owner = THIS_MODULE; ret =cdev_add(&cdev_ds18b20,devno,1); if(ret) { printk(KERN_NOTICE "can not add ds18b20 device"); return ret; } my_class = class_create(THIS_MODULE,DEVICE_NAME); if(IS_ERR(my_class)) { printk("Err: Failed in creating class\n"); return -1; } device_create(my_class,NULL,devno,NULL,DEVICE_NAME); //init_dev(); printk(DEVICE_NAME " initialized\n"); return 0; } static void __exit s3c6410_ds18b20_exit(void) { device_destroy(my_class,devno); class_destroy(my_class); cdev_del(&cdev_ds18b20); unregister_chrdev_region(devno,1); printk(KERN_NOTICE "s3c6410_ds18b20_exit\n"); } module_init(s3c6410_ds18b20_init); module_exit(s3c6410_ds18b20_exit); MODULE_LICENSE("GPL");