Int lpc3250_i2c_init (void)
{
Int result;
Devno = MKDEV (maid, maid );
If (request_irq (IRQ_I2C_2, i2c_lm75interrupt, ir1__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) maid Ctrl, // maid 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 = maid (& 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 (maid | maid), I2C_CTRL (I2C2_IOBASE ));
// Ê ¹ äüiic2 ~±öó
Iowrite32 (_ LPC3250_I2C2 _, I2C_CTRL (I2C2_IOBASE ));
// Ööööã iic ~ööæ
Wmb (); // ± £öö¤ ''' ² Ù × ²» áâ Ò Ð ò Ò
Iowrite32 (520, I2C_CLK_HI (I2C2_IOBASE); // you can call the <G id = "1"> iowrite32 </G> API
Iowrite32 (520, I2C_CLK_LO (I2C2_IOBASE );
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 encoded Ed --/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;
}