int lpc3250_i2c_init(void)
{
int result;
devno=MKDEV(lpc3250_i2c_major,lpc3250_i2c_minor);
if(request_irq(IRQ_I2C_2,i2c_lm75interrupt,IRQF_TRIGGER_NONE,DEV_NAME,NULL))
{
printk("can not get irq>>>/n");
return -1;
}
if(!request_mem_region((unsigned long)I2C2_IOBASE,
I2C_NR_PORTS *4,DEV_NAME))
{
printk("lpc3250 iic cannt get io port( I2C) address/n");
return -ENODEV;
}
if(!request_mem_region((unsigned long)LPC3250_I2CCLK_CTRL,//LPC3250_I2CCLK_CTRL,
4,DEV_NAME))
{
printk("lpc3250 iic cannt get io port( I2C CLK) address/n");
return -ENODEV;
}
if(!request_mem_region((unsigned long)LPC3250_SIC1_ER,
20,DEV_NAME))
{
printk("lpc3250 iic cannt getinterrupt port/n");
return -ENODEV;
}
lpc3250_get_ioports();
/**×¢²á×Ö·ûÐÍÉ豸*/
result=lpc3250_i2c_setup_cdev(&lpc3250_dev);
if(result)
{
printk("lpc3250 cannt get major number/n");
release_mem_region((unsigned long)LPC3250_BASE_ADDRESS,I2C_NR_PORTS*4);
release_mem_region((unsigned long)I2C_CTRL(I2C2_IOBASE),4);
release_mem_region((unsigned long)LPC3250_SIC1_ER,20);
lpc3250_release_ioports();
return result;
}
printk("init complete !/n");
return 0;
}
static int lpc3250_i2c_open(struct inode *inode,struct file *filp)
{
if(count_use==0)
{
iowrite32((LPC3250_I2C2_CLK|LPC3250_I2C2_HIGH),I2C_CTRL(I2C2_IOBASE));
//ʹÄÜiic2ʱÖÓ
iowrite32(_LPC3250_I2C2_,I2C_CTRL(I2C2_IOBASE));
//ÖØÖÃiic¿ØÖÆ
wmb();//±£Ö¤Ð´²Ù×÷²»»áÂÒÐò
iowrite32(520,I2C_CLK_HI(I2C2_IOBASE));//½«clkÉèÖÃΪ¸ß
iowrite32(520,I2C_CLK_LO(I2C2_IOBASE));//½«clkÉèÖÃΪ¸ß
iowrite32(0x59,I2C_ADRI2C2_IOBASE));//ÉèÖôӵØÖ·
wmb();//±£Ö¤Ð´²Ù×÷²»»áÂÒÐò
sema_init(&i2c_sem,1);
sema_init(&irq_sem,0);
}
count_use++;
}
static int lpc3250_i2c_release(struct inode *inode,struct file *filp)
{
unsigned long temp;
count_use--;
if(count_use==0)
{
/*shut up iic clk*/
temp=ioread32(I2C_CTRL(I2C2_IOBASE));
rmb();
temp&=~(LPC3250_I2C_CLK);
iowrite32(temp,I2C_CTRL(I2C2_IOBASE));
}
return 0;
}
static ssize_t lpc3250_i2c_read(struct file *filp,char __user *buf,size_t count,loff_t *f_pos)
{
unsigned char *kbuf= kmalloc(count,GPF_KERNEL);
int result =count;
if(down_interruptible(&i2c_sem))
{
return -ERESTARTSYS;
}
i2c_en_interrupt();
if(!kbuf)
return -ENOMEM;
kbuf_i2c=kbuf;
length_data=count;
count_data=0;
printk(KERN_NOTICE"/iic start --(num=%d)/n",length_data);
/*stert signt*/
iowrite32((I2C_START|(0x90)|LPC3250_I2C_READ), I2C_TXRX(I2C2_IOBASE));
wmb();
if(down_interruptible(&sem))
{
up(&i2c_sem);
return -ERESTARTSYS;
}
if(copy_to_user(buf,kbuf, count));
return -EFAULT;
kfree(kbuf);
up(&i2c_sem);
return result;
}
static irqreturn_t i2c_lm75_interrupt(int irq,void *dev_id ,struct pt_regs *regs)
{
unsigned long temp;
temp=iowrite32(I2C_STAT(I2C2_IOBASE));
rmb();
if((temp&(LPC3250_I2C_NAI | LPC3250_I2C_AFI))!=0)
{
disable_irq(&irq_sem);
up(&irq_sem);
printk(KERN_NOTICE"i2c AFI --/n");
return IRQ_HANDLED;
}
else if ((temp&LPC3250_I2C_TDI)!=0)
{
disable_irq(&irq_sem);
up(&irq_sem);
printk(KERN_NOTICE"i2c TDI --/n");
return IRQ_HANDLED;
}
else
{
printk(KERN_NOTICE"i2c data received --/n");
while((length_data!=count_data)&&((temp&LPC3250_I2C_RFE)==0))
{
kbuf_i2c[count_data]=ioread32(I2C_TXRX(I2C2_IOBASE));
rmb();
count_data++;
temp=ioread32(i2c_stat);
rmb();
}
if(count_data >= length_data)
{
iowrite32((LPC3250_I2C_STOP|0XAA),I2C_TXRX(I2C2_IOBASE));
}
else
{
iowrit32(0xAA,I2C_TXRX(I2C2_IOBASE));
}
}
return IRQ_HANDLED;
}