自己写了一个....各种参考以前大神发在网上的2440的ds18b20的驱动,最后能装上,就是最后读不出来温度。全是0,一个星期了....求大神们给个调试好的ds18b20驱动,我来研究下,我写的那个到底错在哪里!!
/*#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
#include <mach/regs-gpio.h>
#include <mach/io.h>
#include <mach/map.h>
#include <mach/regs-clock.h>*/
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/miscdevice.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <mach/regs-clock.h>
#include <plat/regs-timer.h>
#include <mach/regs-gpio.h>
#include <mach/gpio.h>
#include <linux/cdev.h>
#define DQ S3C2410_GPG11
#define CPG_IN S3C2410_GPG11_INP
#define CPG_OUT S3C2410_GPG11_OUTP
#define DEVICE_NAME "ds18b20" //自定义驱动称为“ds18b20”。
#define DS18B20_MAJOR 210
static int opencount = 0;
static char data[2];
//ds18b20复位,返回0成功,返回1失败
static unsigned char init_ds18b20(void)
{
unsigned char ret = 0;
s3c2410_gpio_cfgpin(DQ, CPG_OUT);
//s3c2410_gpio_pullup(DQ, 0);
s3c2410_gpio_setpin(DQ, 1);
udelay(100);
s3c2410_gpio_setpin(DQ, 0);
udelay(600);
s3c2410_gpio_setpin(DQ, 1);
udelay(50);
s3c2410_gpio_cfgpin(DQ, CPG_IN);
ret = s3c2410_gpio_getpin(DQ);
udelay(200);
return ret;
}
static void write_onechar(char data)
{
unsigned char i;
s3c2410_gpio_cfgpin(DQ, CPG_OUT);
s3c2410_gpio_pullup(DQ, 1);
for(i=0; i<8; i++)
{
s3c2410_gpio_setpin(DQ, 0);
udelay(15);
s3c2410_gpio_setpin(DQ, data&0x01);
udelay(60);
s3c2410_gpio_setpin(DQ, 1);
udelay(2);
data >>= 1;
}
}
static unsigned char read_onechar(void)
{
unsigned char i;
unsigned char data=0;
for(i=0; i<8; i++)
{
s3c2410_gpio_cfgpin(DQ, CPG_OUT);
s3c2410_gpio_setpin(DQ, 0);
udelay(1);
data >>= 1;
s3c2410_gpio_setpin(DQ, 1);
s3c2410_gpio_cfgpin(DQ, CPG_IN);
if(s3c2410_gpio_getpin(DQ))
data |= 0x80;
udelay(50);
}
return data;
}
static ssize_t read_ds18b20(struct file *filp, char *buffer,
size_t count, loff_t *ppos)
{
if(init_ds18b20())
return -1;
write_onechar(0x0cc);
write_onechar(0x44);
udelay(5);
while(init_ds18b20());
udelay(200);
write_onechar(0x0cc);
write_onechar(0x0be);
data[0] = read_onechar();
data[1] = read_onechar();
// copy_to_user(buffer, &data, 2);
buffer[0]=data[0];
buffer[1]=data[1];
return 1;
}
static int open_ds18b20(struct inode *node, struct file *file)
{
unsigned char flag;
if(opencount == 1)
return -EBUSY;
flag = init_ds18b20();
if(flag&0x01)
{
printk("uable to open device!\n");
return -1;
}
else
{
opencount++;
printk("device opened!\n");
return 0;
}
}
static int release_ds18b20(struct inode *node, struct file *file)
{
opencount--;
printk("device released!\n");
return 0;
}
static struct file_operations ds18b20_fops = {
.owner = THIS_MODULE,
.read = read_ds18b20,
.release = release_ds18b20,
.open = open_ds18b20,
};
static char __initdata banner[] = "TQ2440/SKY2440 ds18b20\n";
static struct class *ds18b20_class;
static int __init ds18b20_init(void)
{
int ret;
printk(banner);
ret = register_chrdev(DS18B20_MAJOR, DEVICE_NAME, &ds18b20_fops);
if (ret < 0)
{
printk(DEVICE_NAME " can't register major number\n");
return ret;
}
ds18b20_class = class_create(THIS_MODULE, DEVICE_NAME);
if(IS_ERR(ds18b20_class))
{
printk("Err: failed in tope-leds class. \n");
return -1;
}
device_create(ds18b20_class, NULL, MKDEV(DS18B20_MAJOR, 0), NULL, DEVICE_NAME);
printk(DEVICE_NAME " initialized\n");
return 0;
}
static void __exit ds18b20_exit(void)
{
printk(DEVICE_NAME " exit\n");
unregister_chrdev(DS18B20_MAJOR, DEVICE_NAME);
device_destroy(ds18b20_class, MKDEV(DS18B20_MAJOR, 0));
class_destroy(ds18b20_class);
}
module_init(ds18b20_init);
module_exit(ds18b20_exit);
MODULE_LICENSE("GPL");
这是我修改后的驱动代码, 读不出温度数据来。
|