S3C6410 DS18B20温度传感器驱动(三) --- 驱动源代码

/*****驱动源代码*****/
/****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");

你可能感兴趣的:(c,struct,Module,File,table,Class)