⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3c2410_spi.c

📁 三星ARM9 2410 SPI接口驱动源代码 for linux 2.4 内核
💻 C
📖 第 1 页 / 共 2 页
字号:
    // 安装 SPI 中断处理程序
    if (request_irq(IRQ_SPI, spi_intr, SA_INTERRUPT, "spi_drv", spi_local)){
      SPI_DEBUG("s3c2410_spi: unable to get IRQ %d\n", IRQ_SPI);
      return -EAGAIN;
    }

    DisInt_SPI;
    
    set_external_irq(IRQ_PWR,3,0);
    // 安装 power off 中断处理程序
    if (request_irq(IRQ_PWR, powerOff, SA_INTERRUPT, "spi_drv", spi_local)){
      SPI_DEBUG("s3c2410_power: unable to get IRQ %d\n", IRQ_SPI);
      return -EAGAIN;
    }

    printk(KERN_INFO "SPI Module success load!!!\n");  
    return 0;
}


static void __exit spi_cleanup_module( )
{
    free_irq(IRQ_SPI, spi_local);
    free_irq(IRQ_PWR, spi_local);
    printk(KERN_INFO "Exit SPI module!\n");
    devfs_unregister_chrdev(spi_drv_major, "spi_drv");
    devfs_unregister(dev_handle);
    return;
}

static void send_packet(struct spi_dev *pdev)
{
    int i,tail;
    unsigned char *p=(unsigned char*)&ADSL_Packet;
    
    //填写发送缓冲区 
    while(pdev->send_buf.size+ADSL_Packet.Length>BUF_SIZE)
      schedule();
    tail=pdev->send_buf.tail;
    for(i=0;i<6;i++){ 
      pdev->send_buf.buffer[tail++]=p[i];
      tail%=BUF_SIZE;
    }
    if(ADSL_Packet.Data!=NULL)
      for(i=0;i<ADSL_Packet.Length-10;i++){
	pdev->send_buf.buffer[tail++]=ADSL_Packet.Data[i];
	tail%=BUF_SIZE;	
      }
    for(i=0;i<4;i++){ 
      pdev->send_buf.buffer[tail++]=p[i+10];
      tail%=BUF_SIZE;
    }  
    pdev->send_buf.size+=ADSL_Packet.Length;
    pdev->send_buf.tail=tail;
    HaveSendPacket=YES;
    DisInt_SPI;
    TimeOut=NO;
    inb(SPRDAT);
    EnInt_SPI;
    return;
}
 
static int spi_ioctl(struct inode *inode, struct file *p_file, unsigned int cmd, unsigned long arg)
{
    struct spi_dev *plocal=p_file->private_data;
    int head;
    unsigned char *p;
    unsigned long j,jj;
    unsigned char tempdata;

    /*
    if ( _IOC_TYPE(cmd) != SPI_IOC_MAGIC )
        return -ENOTTY;
    */
    if ( _IOC_NR(cmd) > SPI_IOC_MAXNR )
        return -ENOTTY;
        
    switch (cmd){
    case SPI_SET_BOOTLEN:
      BootDataLen=arg;
      SPI_DEBUG("Boot file length=%li\n",arg);
      break;

    case SPI_SEND_BOOTDATA:
      write_gpio_bit(RESET,0);
      Delay10ms(300);
      write_gpio_bit(nSS,1);
      write_gpio_bit(RESET,1);
      j=jiffies+1000*(HZ/100);
      
      while(read_gpio_bit(IO4)&&j>jiffies);

      //wait IO4 to low
      if(read_gpio_bit(IO4)){
	printk(KERN_INFO "DSP Reset failor\n");
	return -EINVAL;
      }
      cli();
      for(i=0;i<BootDataLen;i++){
	while(read_gpio_bit(IO4));          //wait IO4 to low
	while(!(SPSTA&SPSTA_READY));
	tempdata=*(unsigned char*)(arg+i);
	write_gpio_bit(nSS,1);
	outb(tempdata>>1,SPTDAT);
	while(!(SPSTA&SPSTA_READY));
	write_gpio_bit(nSS,0);
	outb(tempdata<<7,SPTDAT);
      }
      sti();
      Delay10ms(300);
      write_gpio_bit(GPIO_G4,1);	
      SPI_DEBUG("Success send boot data to DSP\n");
      break;
		
    case SPI_ADSL_PSD:
      ADSL_Packet.HeadFlag=0x55aa;
      if(arg==5){
	ADSL_Packet.CmdType=CalibrateMode;
	SPI_DEBUG("PSD Calibrate!\n");
      }
      else{
	ADSL_Packet.CmdType=NormalModeTest;	  
	SPI_DEBUG("PSD Test!\n");
      }
      ADSL_Packet.TestType=SPI_ADSL_PSD;
      ADSL_Packet.Data=NULL;
      ADSL_Packet.CRC32=0;
      ADSL_Packet.Length=10;
      CurTestType=SPI_ADSL_PSD;
      send_packet(plocal);
      break;

    case SPI_ADSL_RMS:
      ADSL_Packet.HeadFlag=0x55aa;
      if(arg==5){
	ADSL_Packet.CmdType=CalibrateMode;
      }
      else{
	ADSL_Packet.CmdType=NormalModeTest;	  
      }
      ADSL_Packet.TestType=SPI_ADSL_RMS;
      ADSL_Packet.Data=NULL;
      ADSL_Packet.CRC32=0;
      ADSL_Packet.Length=10;
      CurTestType=SPI_ADSL_RMS;
      send_packet(plocal);
      break;
      
    case SPI_VALUE_UP:
      ADSL_Packet.HeadFlag=0x55aa;
      ADSL_Packet.CmdType=CalibrateMode;
      ADSL_Packet.TestType=SPI_VALUE_UP;
      ADSL_Packet.Data=NULL;
      ADSL_Packet.CRC32=0;
      ADSL_Packet.Length=10;
      CurTestType=SPI_VALUE_UP;
      send_packet(plocal);
      break;
      
    case SPI_VALUE_DOWN:
      ADSL_Packet.HeadFlag=0x55aa;
      ADSL_Packet.CmdType=CalibrateMode;
      ADSL_Packet.TestType=SPI_VALUE_DOWN;
      ADSL_Packet.Data=NULL;
      ADSL_Packet.CRC32=0;
      ADSL_Packet.Length=10;
      CurTestType=SPI_VALUE_DOWN;
      send_packet(plocal);
      break;
	
    case SPI_SEND:
      ADSL_Packet.HeadFlag=0x55aa;
      ADSL_Packet.CmdType=CalibrateMode;
      ADSL_Packet.TestType=SPI_SEND;
      ADSL_Packet.Data=NULL;
      ADSL_Packet.CRC32=0;
      ADSL_Packet.Length=10;
      CurTestType=SPI_SEND;
      send_packet(plocal);
      break;
	
    case SPI_SEND_END:
      ADSL_Packet.HeadFlag=0x55aa;
      ADSL_Packet.CmdType=CalibrateMode;
      ADSL_Packet.TestType=SPI_SEND_END;
      ADSL_Packet.Data=NULL;
      ADSL_Packet.CRC32=0;
      ADSL_Packet.Length=10;
      CurTestType=SPI_SEND_END;
      send_packet(plocal);
      break;
      
    case SPI_ADSL_ATT:
      ADSL_Packet.HeadFlag=0x55aa;
      if(arg==5){
	ADSL_Packet.CmdType=CalibrateMode;
	SPI_DEBUG("Att Calibrate!\n");
      }
      else{
	if(arg==0)
	  ADSL_Packet.CmdType=MasterModeTest;
	else
	  ADSL_Packet.CmdType=SlaveModeTest;
	SPI_DEBUG("Att Test!\n");
      }
      ADSL_Packet.TestType=SPI_ADSL_ATT;
      ADSL_Packet.Data=NULL;
      ADSL_Packet.CRC32=0;
      ADSL_Packet.Length=10;
      CurTestType=SPI_ADSL_ATT;
      send_packet(plocal);
      break;
	
    case SPI_ADSL_BALANCE:
      ADSL_Packet.HeadFlag=0x55aa;
      if(arg==5){
	ADSL_Packet.CmdType=CalibrateMode;
	SPI_DEBUG("Balance Calibrate!\n");
      }
      else{
	ADSL_Packet.CmdType=NormalModeTest;
	SPI_DEBUG("Balance Test!\n");
      }
      ADSL_Packet.TestType=SPI_ADSL_BALANCE;
      ADSL_Packet.Data=NULL;
      ADSL_Packet.CRC32=0;
      ADSL_Packet.Length=10;
      CurTestType=SPI_ADSL_BALANCE;
      send_packet(plocal);
      break;
      
    case SPI_ADSL_FEXT:
      ADSL_Packet.HeadFlag=0x55aa;
      if(arg==5){
	ADSL_Packet.CmdType=CalibrateMode;
	SPI_DEBUG("FEXT Calibrate!\n");
      }
      else{
	if(arg==0)                                            //arg=0,master mode
	  ADSL_Packet.CmdType=MasterModeTest;
	else
	  ADSL_Packet.CmdType=SlaveModeTest;                  //arg=1,slave mode
	SPI_DEBUG("FEXT Test!\n");
      }
      ADSL_Packet.TestType=SPI_ADSL_FEXT;
      ADSL_Packet.Data=NULL;
      ADSL_Packet.CRC32=0;
      ADSL_Packet.Length=10;
      CurTestType=SPI_ADSL_FEXT;
      send_packet(plocal);
      break;
      
    case SPI_ADSL_NEXT:
      ADSL_Packet.HeadFlag=0x55aa;
      if(arg==5){
	ADSL_Packet.CmdType=CalibrateMode;
	SPI_DEBUG("NEXT Calibrate!\n");
      }
      else{
	ADSL_Packet.CmdType=NormalModeTest;
	SPI_DEBUG("NEXT Test!\n");
      }
      ADSL_Packet.TestType=SPI_ADSL_NEXT;
      ADSL_Packet.Data=NULL;
      ADSL_Packet.CRC32=0;
      ADSL_Packet.Length=10;
      CurTestType=SPI_ADSL_NEXT;
      send_packet(plocal);
      break;

    case SPI_ADSL_VOL:
      ADSL_Packet.HeadFlag=0x55aa;
      if(arg==5){
	ADSL_Packet.CmdType=CalibrateMode;
	SPI_DEBUG("Vol Calibrate!\n");
      }
      else{
	ADSL_Packet.CmdType=NormalModeTest;
	SPI_DEBUG("Vol Test!\n");
      }
      ADSL_Packet.TestType=SPI_ADSL_VOL;
      ADSL_Packet.Data=NULL;
      ADSL_Packet.CRC32=0;
      ADSL_Packet.Length=10;
      CurTestType=SPI_ADSL_VOL;
      send_packet(plocal);
      break;
      
    case SPI_ADSL_RES:
      ADSL_Packet.HeadFlag=0x55aa;
      if(arg==5){
	ADSL_Packet.CmdType=CalibrateMode;
	SPI_DEBUG("Res Calibrate!\n");
      }
      else{
	ADSL_Packet.CmdType=NormalModeTest;
	SPI_DEBUG("Res Test!\n");
      }
      ADSL_Packet.TestType=SPI_ADSL_RES;
      ADSL_Packet.Data=NULL;
      ADSL_Packet.CRC32=0;
      ADSL_Packet.Length=10;
      CurTestType=SPI_ADSL_RES;
      send_packet(plocal);
      break;
	
    case SPI_ADSL_STOPTEST:
      ADSL_Packet.HeadFlag=0x55aa;
      ADSL_Packet.CmdType=StopTest;
      ADSL_Packet.TestType=SPI_ADSL_RESERVE;
      ADSL_Packet.Data=NULL;
      ADSL_Packet.CRC32=0;
      ADSL_Packet.Length=10;
      CurTestType=SPI_ADSL_RESERVE;
      send_packet(plocal);
      break;
      
    case SPI_CHECK_DATA:
      
      if(TimeOut==YES)
	return TestDataTimeOut;
      
      if(RxPacketNum>0){
	*(unsigned int*)arg=RxPacketNum;
	return TestDataReady;
      }
      else
	return TestDataNotReady;
      break;
      
    case SPI_GET_DATA:
      head=plocal->recv_buf.head;
      i=0;
      p=(unsigned char*)arg;
      while(RxCounters[RxPacketHead]--){
	p[i]=plocal->recv_buf.buffer[head++];
	head%=BUF_SIZE;
	i++;
      }
      RxPacketHead++;
      RxPacketHead%=1024;
      RxPacketNum--;
      plocal->recv_buf.head=head;
      plocal->recv_buf.size-=i;
      SPI_DEBUG("Get %d byte from recv\n",i);
      break;
      
    case SPI_POWER_OFF:
      if(powerCTL_EN){
	write_gpio_bit(GPIO_G8,0);
      }
      break;
      
    case SPI_POWER_ON:
      write_gpio_bit(GPIO_G8,1);
      break;

    case SPI_MODEM_RESET:
      write_gpio_bit(GPIO_H4,0);
      Delay10ms(500);
      write_gpio_bit(GPIO_H4,1);
      modem_reset = 1;                                          //send signal to modem daemon.
      break;

    case SPI_BLIGHT_ON:
      write_gpio_bit(GPIO_G4,1);
      break;

    case SPI_BLIGHT_OFF:
      write_gpio_bit(GPIO_G4,0);
      break;

    case SPI_MODEM_STARTUP:  //2005-5-8
      enable_config = read_gpio_bit(GPIO_G9);
      *(unsigned int*)arg = enable_config;
      break;
      
    case SPI_MODEM_RESET_FLAG:
      *(unsigned int*)arg = modem_reset;
      break;

    case SPI_MODEM_FLAG_CLEAR:
      modem_reset = 0; 
      enable_config = 0;
      SPI_DEBUG("Modem FLAG CLEARED!\n");
      break;
      
    case SPI_PWRCTL_ENABLE:
      powerCTL_EN = 1;
      SPI_DEBUG("Enable PWR interrupt!\n");
      break;
  	
    default:
      return -EINVAL;
    }
    return ACCESS_OK;
}


static inline  void Delay10ms(int num)
{
    unsigned long j=jiffies+num*(HZ/100);
    while(j>jiffies);
    return;
}

module_init(spi_init_module);
module_exit(spi_cleanup_module);
MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -