linux驱动程序,编译正确,加载不行:
linux驱动程序,编译正确,加载不行:
#define PCONF (*(volatile unsigned *)0x56000040)
在初始化函数中有这句*(volatile unsigned *) PCONF |=0x0a;或 //PCONF |=0x0a;
出去上面的两句加载正确,加上就出现以下情况,请问是怎么回事啊?
[root@FriendlyARM 2.6.32.2-FriendlyARM]# insmod memdev.ko
module init WO KAO !
Unable to handle kernel paging request at virtual address 56000040
pgd = c3b14000
[56000040] *pgd=00000000
Internal error: Oops: 5 [#1]
last sysfs file: /sys/devices/virtual/vc/vcs4/dev
Modules linked in: memdev(+) hello
CPU: 0 Not tainted (2.6.32.2-FriendlyARM #3)
PC is at memdev_init+0x1c/0x168 [memdev]
LR is at release_console_sem+0x188/0x1e4
pc : [<bf0182e8>] lr : [<c004a6d8>] psr: 60000013
sp : c3b1bf10 ip : c3b1be28 fp : c3b1bf34
r10: bf0182cc r9 : 00000000 r8 : c0503660
r7 : c3b1a000 r6 : bf01855c r5 : 000a18b7 r4 : 00001329
r3 : 56000000 r2 : c04c9638 r1 : 0000512f r0 : 0000001e
Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: c000717f Table: 33b14000 DAC: 00000015
Process insmod (pid: 747, stack limit = 0xc3b1a270)
Stack: (0xc3b1bf10 to 0xc3b1c000)
bf00: c4840b2c 00000043 00000002 00001329
bf20: 000a18b7 bf01855c c3b1bf7c c3b1bf38 c003032c bf0182dc 00000000 00000000
bf40: 00000000 00001329 000a18b7 bf01855c 00000000 00001329 000a18b7 bf01855c
bf60: 00000000 c00310c8 c3b1a000 00000000 c3b1bfa4 c3b1bf80 c0070344 c0030300
bf80: c009b6b0 c009b5a0 4001d838 00000000 bebe4e68 00000080 00000000 c3b1bfa8
bfa0: c0030f20 c0070284 4001d838 00000000 000b5038 00001329 000a18b7 00000000
bfc0: 4001d838 00000000 bebe4e68 00000080 bebe4e64 bebe4e68 00000001 00000000
bfe0: 00000069 bebe4b34 0001778c 401d3c24 60000010 000b5038 305bb031 305bb431
Backtrace:
[<bf0182cc>] (memdev_init+0x0/0x168 [memdev]) from [<c003032c>] (do_one_initcall
+0x3c/0x1c
r6:bf01855c r5:000a18b7 r4:00001329
[<c00302f0>] (do_one_initcall+0x0/0x1c from [<c0070344>] (sys_init_module+0xd0
/0x204)
[<c0070274>] (sys_init_module+0x0/0x204) from [<c0030f20>] (ret_fast_syscall+0x0
/0x2
r7:00000080 r6:bebe4e68 r5:00000000 r4:4001d838
Code: e24dd00c e59f0130 eb4df5d0 e3a03456 (e5932040)
---[ end trace 04628c8e3797af5d ]---
Segmentation fault
[root@FriendlyARM 2.6.32.2-FriendlyARM]#
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
顶一下。。。
我不知道你开发板提供的BSP操作的地址是不是直接通过那种形式来操作,有一些需要使用虚拟地址进行操作,敬请确认。
Unable to handle kernel paging request at virtual address 56000040
pgd = c3b14000
[56000040] *pgd=00000000
这块虚拟地址对应的物理地址未映射。
看程序你应该是想要访问物理地址0x56000040吧,用这个物理地址对应的虚拟地址访问。
linux驱动中,对那些物理地址的访问,是要先转换成对应虚拟地址,才能访问的。
具体的,有page_to_virt之类的宏(或函数),记不清了,自己网上找找。
回复 4# l2y3n2
大哥这是源程序,麻烦帮我看一下,我实在搞不来了,谢啦O(∩_∩)O~
#include <linux/autoconf.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <linux/interrupt.h>
#include <plat/iic.h>
#define u32 unsigned int
#define u16 unsigned short
#define s32 int
#define s16 short int
#define u8 unsigned char
/* I/O PORT */
#define PCONF (*(volatile unsigned *)0x56000040)
#define PDATF (*(volatile unsigned *)0x56000044)
#define PUPF (*(volatile unsigned *)0x5600004
#define IICCON (*(volatile unsigned *)0x54000000)
#define IICSTAT (*(volatile unsigned *)0x54000004)
#define IICADD (*(volatile unsigned *)0x5400000
#define IICDS (*(volatile unsigned *)0x5400000c)
#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_iic_dir, devfs_iicraw;
#endif
#define SKQ_IIC_MODULE_NAME "IICBUS"
/*60--63,120--127,240--254*/
#define IICBUS_MAJOR 240
#define IICBUSRAW_MINOR 1
#define IICBUS_INT IRQ_IIC
static char *IICBUD_id = "SKQ IICBUS driver v1.0 (2005-06-02)<psc@hualiangtech.com>";
/* debug macros */
#undef DEBUG
//#define DEBUG
#ifdef DEBUG
#define DPRINTK( x... ) printk("SKQ IICBUS: "##x)
#else
#define DPRINTK( x... )
#endif
#define WRDATA (1)
#define POLLACK (2)
#define RDDATA (3)
#define SETRDADDR (4)
#define IICBUFSIZE 2048
char IICBUS_Buf[IICBUFSIZE];
static int opencount=0;
static int tsMajor=0;
static loff_t newpos=0;
int writenFM24CL16(char * buffer, size_t count, int address)
{
unsigned long timeo;
u16 i;
u16 PageAdd;
char slvAddr, tpICON,tempIICSTAT;
IICCON=(1<<7)|(0<<6)|(1<<5)|(0xf);
IICSTAT=0x10;
slvAddr=0xa0;
PageAdd=address;
/* send the bit of start and address of device and page of address */
PageAdd>>7;
PageAdd&=0x0e;
slvAddr=(char)PageAdd;
slvAddr|=0xa0;
IICDS=slvAddr; //0xa0
IICSTAT=0xf0; //MasTx,Start
timeo = jiffies + (HZ/100);
while(1)
{
tpICON=IICCON;
tpICON&=0x10; /* pending */
tempIICSTAT=IICSTAT;
tempIICSTAT&=0x01; /* ack */
if((tpICON==0x10))
{
IICSTAT=0xd0;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf; /*pending */
IICDS=(char)address; //0xa0
timeo = jiffies +(HZ/100);
while(1)
{
tpICON=IICCON;
tpICON&=0x10;
tempIICSTAT=IICSTAT;
tempIICSTAT&=0x01;
if((tpICON==0x10)) break; // &&tempIICSTAT==0x00)
if(time_after(jiffies,timeo))
{
IICSTAT=0xd0;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf;
for(i=0;i<count;i++)
{
IICDS=buffer;
timeo=jiffies + (HZ/100);
while(1)
{
tpICON=IICCON;
tpICON&=0x10;
tempIICSTAT=IICSTAT;
tempIICSTAT&=0x01;
if((tpICON==0x10)&&(tempIICSTAT==0x00)) break;
if(time_after(jiffies,timeo))
{
IICSTAT=0xd0;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf; /* clr pending */
}
IICSTAT =0xd0;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return count;
}
int ReadFM24CL16(char *buffer, size_t count, int address)
{
unsigned long timeo;
u16 i;
u8 slvAddr ,tpICON,tempIICSTAT;
u16 PageAdd;
PageAdd=address;
/* 发送起始位和设备地址和页地址 */
PageAdd>>=7;
PageAdd&=0x0e;
slvAddr=(char )PageAdd;
slvAddr|=0xa0;
IICDS=slvAddr; //0xa0;
IICSTAT=0Xf0; //MasTx,Start
timeo = jiffies +(HZ/100);
while(1){
tpICON=IICCON;
tpICON&=0x10;
// tempIICSTAT=rIICSTAT;
//tempEECSTAT&=0x01;
if((tpICON==0x10)) break; //&&(tempIICSTAT==0x00)
if(time_after(jiffies,timeo))
{
IICSTAT=0x90;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf;
/* 发送地址低8位 */
IICDS=(char)address;
timeo = jiffies + (HZ/100);
while(1){
tpICON=IICCON;
tpICON&=0x10;
tempIICSTAT=IICSTAT;
tempIICSTAT&=0X01;
if((tpICON==0x01)) break; //&&(tempIICSTAT==0x00)
if(time_after(jiffies, timeo))
{
IICSTAT=0x90;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf;
//IICSTAT&=0xef;
/* 发送起始位和设备地址和页地址 */
PageAdd>>=7;
PageAdd&=0x0e;
slvAddr=(char )PageAdd;
slvAddr|=0xa1;
IICDS=slvAddr;
IICSTAT=0xb0; //MasRx,Start
timeo = jiffies +(HZ/100);
while(1){
tpICON=IICCON;
tpICON&=0x10;
tempIICSTAT=IICSTAT;
tempIICSTAT&=0x01;
if((tpICON==0x10)) break; // &&(tempIICSTAT==0x00)
{
IICSTAT=0x90;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf;
for(i=0;i<count;i++)
{
IICDS=slvAddr;
//timeo =jiffies +(HZ/100);
while(1){
tpICON=IICCON;
tpICON&=0x10;
tempIICSTAT=IICSTAT;
tempIICSTAT&=0x01;
if((tpICON==0x10)) break ;//(tempIICSTAT==0x00)
//else
// {
// if((tpICON==0x10)&&(i==count-1))break;
// }
if(time_after(jiffies, timeo))
{
IICSTAT=0x90;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
IICSTAT=0x10;
return -1;
}
};
buffer=IICDS;
if(i==count-1) IICCON=0x2f;
else IICCON=0xaf;
}
IICSTAT=0x90;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return count;
}
loff_t IICBUS_llseek(struct file *filp, loff_t off,int whence)
{
switch(whence){
case 0 : /* SEEK_SET */
newpos=off;
break;
default: /* cant,t happen */
return -EINVAL;
}
if(newpos<0) return -EINVAL;
return newpos;
}
static ssize_t IICBUS_write(struct file *file,const char *buffer,size_t count, loff_t *ppos)
{
int ret;
int address=(int)newpos;
if(count>204 return 0;
// copy_from_user(&address,ppos, sizeof(loff_t));
// address=(int)*ppos;
// printk("IICBUS_write address=%ld\n",address);
if(address+count>204 return 0;
copy_from_user(IICBUS_Buf, count, address);
return ret;
}
static ssize_t IICBUS_read(struct file *filp,char *buffer,size_t count, loff_t *ppos)
{
int len;
int address=(int)newpos;
//int address1;
if(count>204 return 0;
//copy_from_user(&address,ppos, sizeof(loff_t));
//address=(int)*ppos;
//printk("IICBUS_read address=%d\n",address);
if(address+count>204 return 0;
//address1=(int)*ppos;
//printk("IICBUS_read address1=%ld\n",address);
//printk("IICBUS_read ppos=%ld\n",ppos);
len=ReadFM24CL16(IICBUS_Buf,count,address);
copy_to_user(buffer,IICBUS_Buf,len);
DPRINTK("read data=%d\n",data);
return len;
}
static int IICBUS_open(struct inode *inode, struct file *file)
{
//if(opencount==1)
//return -EBUSY;
opencount++;
try_module_get(THIS_MODULE); //MOD_INC_USE_COUNT;
DPRINTK("device open\n";
return 0;
}
static int IICBUS_release(struct inode *inode, struct file *filp)
{
opencount--;
module_put(THIS_MODULE); //MOD_DEC_USE_COUNT;
DPRINTK("device release\n";
return 0;
}
static struct file_operations s3c44b0_iicbus_fops ={
owner: THIS_MODULE,
llseek: IICBUS_llseek,
write: IICBUS_write,
read: IICBUS_read,
open: IICBUS_open,
release: IICBUS_release,
};
static int __init IICBUS_init(void)
{
int ret;
int flags;
//local_irq_save(flags);
/* port F */
/* Bit8 7 6 5 4 3 2
SPICKL SPIMISO SPICS SPIMOSI INCARD2 NC NC */
PCONF |=0x0a; //PF0:IICSCL,PF1:IICSDA
PUPF |=0x03; //pull-up disable
IICCON=(1<<7)|(0<<6)|(0<<5)|(0xf);
//Enable interrupt,IICCLK=MCKL/16,Enable ACK
//40Mhz/16/(15+1)=257khz
IICADD=0x10; //s3c44B0X slave address
IICSTAT=0X10;
local_irq_restore(flags);
opencount=0;
ret = register_chrdev(IICBUS_MAJOR, SKQ_IIC_MODULE_NAME,&s3c44b0_iicbus_fops);
if (ret<0)
{
printk( ":can't get major number\n",__FUNCTION__);
return -1;
}
tsMajor=ret;
#if 0
if(0 !=request_irq(IICBUS_INT,IICBUS_isr,SA_INTERRUPT,IICBUD_ID,NULL))
{
printk(KERN_WARNING "tce44b0_usb:failed to get IRQ\n";
return 1;
}
#endif
#ifdef CONFIG_DEVFS_FS
devfs_iic_dir = devfs_mkdir(NULL,SKQ_IIC_MODULE_NAME,NULL);
devfs_iicraw = devfs_register(devfs_iic_dir, "0",DEVFS_FL_DEFAULT,
tsMajor,IICBUSRAW_MINOR,S_IFCHR | S_IRUSR | S_IWUSR,
&s3c44b0_iicbus_fops,NULL);
#endif
printk(SKQ_IIC_MODULE_NAME " initialized\n";
return 0;
}
static void __exit IICBUS_exit(void)
{
printk(":SKQ IIC Exit.\n",__FUNCTION__);
// free_irq(IICBUS_INT, IICBUD_id);
unregister_chrdev_region(IICBUS_MAJOR,1);
}
module_init(IICBUS_init);
module_exit(IICBUS_exit);
MODULE_DESCRIPTION("SKQ IIC driver";
MODULE_AUTHOR("pengshicao ";
MODULE_LICENSE("GPL";
回复 3# nazily2150
我用的是S3C2440开发板,帮我看一下,我把源程序贴出来了
谢谢O(∩_∩)O~
是I2C控制器的物理地址没有转化成虚拟地址就直接访问了!
在init函数里面这样:
复制代码然后对PCONF、PDATA、PUPF的访问使用pbase、pbase+4、pbase+8
II2系列寄存器也一样用iicbase、iicbase+4、iicbase+8、iicbase+12
回复 9# l2y3n2
我后来把代码改成下列形式了,编译正确,加载出错: Segmentation fault
什么问题啊?
#include <asm/io.h>
#include "config.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include "hardware.h"
// #include <linux/interrupt.h>
// #include <plat/iic.h>
#include <linux/gpio.h>
#include <mach/regs-gpio.h>
#define u32 unsigned int
#define u16 unsigned short
#define s32 int
#define s16 short int
#define u8 unsigned char
#define iiccon 0x54000000
#define iicstat 0x54000004
#define iicds 0x5400000c
#define iicadd 0x54000008
#define iicl 0x54000010
#define clkcon 0x4c00000c
static void *IICSTAT;
static void *IICCON;
static void *IICDS;
static void *IICADD;
static void *IICLC;
#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_iic_dir, devfs_iicraw;
#endif
#define SKQ_IIC_MODULE_NAME "IICBUS"
/*60--63,120--127,240--254*/
#define IICBUS_MAJOR 240
#define IICBUSRAW_MINOR 1
#define IICBUS_INT IRQ_IIC
static char *IICBUD_id = "SKQ IICBUS driver v1.0 (2005-06-02)<psc@hualiangtech.com>";
/* debug macros */
#undef DEBUG
//#define DEBUG
#ifdef DEBUG
#define DPRINTK( x... ) printk("SKQ IICBUS: "##x)
#else
#define DPRINTK( x... )
#endif
#define WRDATA (1)
#define POLLACK (2)
#define RDDATA (3)
#define SETRDADDR (4)
#define IICBUFSIZE 2048
char IICBUS_Buf[IICBUFSIZE];
static int opencount=0;
static int tsMajor=0;
static loff_t newpos=0;
int writenFM24CL16(char * buffer, size_t count, int address)
{
unsigned long timeo;
u16 i;
u16 PageAdd;
char slvAddr, tpICON,tempIICSTAT;
IICCON=(1<<7)|(0<<6)|(1<<5)|(0xf);
IICSTAT=0x10;
slvAddr=0xa0;
PageAdd=address;
/* send the bit of start and address of device and page of address */
PageAdd>>7;
PageAdd&=0x0e;
slvAddr=(char)PageAdd;
slvAddr|=0xa0;
IICDS=slvAddr; //0xa0
IICSTAT=0xf0; //MasTx,Start
timeo = jiffies + (HZ/100);
while(1)
{
tpICON=IICCON;
tpICON&=0x10; /* pending */
tempIICSTAT=IICSTAT;
tempIICSTAT&=0x01; /* ack */
if((tpICON==0x10))
{
IICSTAT=0xd0;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf; /*pending */
IICDS=(char)address; //0xa0
timeo = jiffies +(HZ/100);
while(1)
{
tpICON=IICCON;
tpICON&=0x10;
tempIICSTAT=IICSTAT;
tempIICSTAT&=0x01;
if((tpICON==0x10)) break; // &&tempIICSTAT==0x00)
if(time_after(jiffies,timeo))
{
IICSTAT=0xd0;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf;
for(i=0;i<count;i++)
{
IICDS=buffer;
timeo=jiffies + (HZ/100);
while(1)
{
tpICON=IICCON;
tpICON&=0x10;
tempIICSTAT=IICSTAT;
tempIICSTAT&=0x01;
if((tpICON==0x10)&&(tempIICSTAT==0x00)) break;
if(time_after(jiffies,timeo))
{
IICSTAT=0xd0;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf; /* clr pending */
}
IICSTAT =0xd0;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return count;
}
int ReadFM24CL16(char *buffer, size_t count, int address)
{
unsigned long timeo;
u16 i;
u8 slvAddr ,tpICON,tempIICSTAT;
u16 PageAdd;
PageAdd=address;
/* 发送起始位和设备地址和页地址 */
PageAdd>>=7;
PageAdd&=0x0e;
slvAddr=(char )PageAdd;
slvAddr|=0xa0;
IICDS=slvAddr; //0xa0;
IICSTAT=0Xf0; //MasTx,Start
timeo = jiffies +(HZ/100);
while(1){
tpICON=IICCON;
tpICON&=0x10;
// tempIICSTAT=rIICSTAT;
//tempEECSTAT&=0x01;
if((tpICON==0x10)) break; //&&(tempIICSTAT==0x00)
if(time_after(jiffies,timeo))
{
IICSTAT=0x90;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf;
/* 发送地址低8位 */
IICDS=(char)address;
timeo = jiffies + (HZ/100);
while(1){
tpICON=IICCON;
tpICON&=0x10;
tempIICSTAT=IICSTAT;
tempIICSTAT&=0X01;
if((tpICON==0x01)) break; //&&(tempIICSTAT==0x00)
if(time_after(jiffies, timeo))
{
IICSTAT=0x90;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf;
//IICSTAT&=0xef;
/* 发送起始位和设备地址和页地址 */
PageAdd>>=7;
PageAdd&=0x0e;
slvAddr=(char )PageAdd;
slvAddr|=0xa1;
IICDS=slvAddr;
IICSTAT=0xb0; //MasRx,Start
timeo = jiffies +(HZ/100);
while(1){
tpICON=IICCON;
tpICON&=0x10;
tempIICSTAT=IICSTAT;
tempIICSTAT&=0x01;
if((tpICON==0x10)) break; // &&(tempIICSTAT==0x00)
{
IICSTAT=0x90;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return -1;
}
};
IICCON=0xaf;
for(i=0;i<count;i++)
{
IICDS=slvAddr;
//timeo =jiffies +(HZ/100);
while(1){
tpICON=IICCON;
tpICON&=0x10;
tempIICSTAT=IICSTAT;
tempIICSTAT&=0x01;
if((tpICON==0x10)) break ;//(tempIICSTAT==0x00)
//else
// {
// if((tpICON==0x10)&&(i==count-1))break;
// }
if(time_after(jiffies, timeo))
{
IICSTAT=0x90;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
IICSTAT=0x10;
return -1;
}
};
buffer=IICDS;
if(i==count-1) IICCON=0x2f;
else IICCON=0xaf;
}
IICSTAT=0x90;
IICCON=0xaf;
udelay(200);
IICCON=0xaf;
IICSTAT=0x10;
return count;
}
loff_t IICBUS_llseek(struct file *filp, loff_t off,int whence)
{
switch(whence){
case 0 : /* SEEK_SET */
newpos=off;
break;
default: /* cant,t happen */
return -EINVAL;
}
if(newpos<0) return -EINVAL;
return newpos;
}
static ssize_t IICBUS_write(struct file *file,const char *buffer,size_t count, loff_t *ppos)
{
int ret;
int address=(int)newpos;
if(count>204 return 0;
// copy_from_user(&address,ppos, sizeof(loff_t));
// address=(int)*ppos;
// printk("IICBUS_write address=%ld\n",address);
if(address+count>204 return 0;
copy_from_user(IICBUS_Buf, count, address);
return ret;
}
static ssize_t IICBUS_read(struct file *filp,char *buffer,size_t count, loff_t *ppos)
{
int len;
int address=(int)newpos;
//int address1;
if(count>204 return 0;
//copy_from_user(&address,ppos, sizeof(loff_t));
//address=(int)*ppos;
//printk("IICBUS_read address=%d\n",address);
if(address+count>204 return 0;
//address1=(int)*ppos;
//printk("IICBUS_read address1=%ld\n",address);
//printk("IICBUS_read ppos=%ld\n",ppos);
len=ReadFM24CL16(IICBUS_Buf,count,address);
copy_to_user(buffer,IICBUS_Buf,len);
DPRINTK("read data=%d\n",data);
return len;
}
static int IICBUS_open(struct inode *inode, struct file *file)
{
//if(opencount==1)
//return -EBUSY;
opencount++;
try_module_get(THIS_MODULE); //MOD_INC_USE_COUNT;
DPRINTK("device open\n";
return 0;
}
static int IICBUS_release(struct inode *inode, struct file *filp)
{
opencount--;
module_put(THIS_MODULE); //MOD_DEC_USE_COUNT;
DPRINTK("device release\n";
return 0;
}
static struct file_operations s3c44b0_iicbus_fops ={
owner: THIS_MODULE,
llseek: IICBUS_llseek,
write: IICBUS_write,
read: IICBUS_read,
open: IICBUS_open,
release: IICBUS_release,
};
static int __init IICBUS_init(void)
{
s3c2410_gpio_cfgpin(S3C2410_GPB(14),S3C2410_GPE14_IICSCL);
s3c2410_gpio_cfgpin(S3C2410_GPB(15),S3C2410_GPE15_IICSDA);
IICCON=ioremap(iiccon,0x00000004);
IICSTAT=ioremap(iicstat,0x00000004);
IICDS=ioremap(iicds,0x00000004);
IICADD=ioremap(iicadd,0x00000004);
IICLC=ioremap(iicl,0X00000004);
int ret;
int flags;
//local_irq_save(flags);
/* port F */
/* Bit8 7 6 5 4 3 2
SPICKL SPIMISO SPICS SPIMOSI INCARD2 NC NC */
// PCONF |=0x0a; //PF0:IICSCL,PF1:IICSDA
// PUPF |=0x03; //pull-up disable
IICCON=(1<<7)|(0<<6)|(0<<5)|(0xf);
//Enable interrupt,IICCLK=MCKL/16,Enable ACK
//40Mhz/16/(15+1)=257khz
IICADD=0x10; //s3c44B0X slave address
IICSTAT=0X10;
local_irq_restore(flags);
opencount=0;
ret = register_chrdev(IICBUS_MAJOR, SKQ_IIC_MODULE_NAME,&s3c44b0_iicbus_fops);
if (ret<0)
{
printk( ":can't get major number\n",__FUNCTION__);
return -1;
}
tsMajor=ret;
#if 0
if(0 !=request_irq(IICBUS_INT,IICBUS_isr,SA_INTERRUPT,IICBUD_ID,NULL))
{
printk(KERN_WARNING "tce44b0_usb:failed to get IRQ\n";
return 1;
}
#endif
#ifdef CONFIG_DEVFS_FS
devfs_iic_dir = devfs_mkdir(NULL,SKQ_IIC_MODULE_NAME,NULL);
devfs_iicraw = devfs_register(devfs_iic_dir, "0",DEVFS_FL_DEFAULT,
tsMajor,IICBUSRAW_MINOR,S_IFCHR | S_IRUSR | S_IWUSR,
&s3c44b0_iicbus_fops,NULL);
#endif
printk(SKQ_IIC_MODULE_NAME " initialized\n";
return 0;
}
static void __exit IICBUS_exit(void)
{
printk(":SKQ IIC Exit.\n",__FUNCTION__);
// free_irq(IICBUS_INT, IICBUD_id);
unregister_chrdev_region(IICBUS_MAJOR,1);
}
module_init(IICBUS_init);
module_exit(IICBUS_exit);
MODULE_DESCRIPTION("SKQ IIC driver";
MODULE_AUTHOR("pengshicao ";
MODULE_LICENSE("GPL";