lpc3250 linux下的 LM75A 驱动


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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值