首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

读写SPI FLASH--驱动部分(8)

读写SPI FLASH--驱动部分(8)

module_init(spi_init);
module_exit(spi_cleanup);



static uint8_t get_flash_status(void)
{
    uint32_t word, val;
    uint8_t ret;
   
     word = readw((void *)(spi_char.mem_virt+SPI_CTRL));
     word |= SPI_CTRL_SCGO; /* set cycle */
     word |= SPI_CTRL_ACS; /* Enable Atomic Cycle Sequence */
     word |= SPI_CTRL_SPOP;
     word &= ~SPI_CTRL_COP;     
     word = word | SPI_CTRL_OPMENU_RDSR<<SPI_CTRL_COP_SHIFT; /* read */
     word &= ~SPI_CTRL_DBC;     
     word = word | 0x00<<SPI_CTRL_DBC_SHIFT; /* read count=1 */
     word |= SPI_CTRL_DC;
     
      /* check the status */
     val = readw((void *)(spi_char.mem_virt+SPI_STATUS));
     while(val & SPI_STATUS_SCIP)
     {
            val = readw((void *)(spi_char.mem_virt+SPI_STATUS));/* check the status */
     }
         
     writew(word, (void *)(spi_char.mem_virt+SPI_CTRL));
         
     /* check the status */
     val = readw((void *)(spi_char.mem_virt+SPI_STATUS));
     while(val & SPI_STATUS_SCIP)
     {
        val = readw((void *)(spi_char.mem_virt+SPI_STATUS));/* check the status */
     }
        
     val = readl((void *)(spi_char.mem_virt+SPI_DATA0));
     SPI_DBG("get_flash_status:%08x/n", val);     
     ret = (val&0xFF);
     
     word = readw((void *)(spi_char.mem_virt+SPI_STATUS));
     word |= SPI_STATUS_CDS; /* clear Cycle Done Status flag */
     word |= SPI_STATUS_BAS;  /* clear blocked flag */
     writew(word, (void *)(spi_char.mem_virt+SPI_STATUS));
         
     return (ret);
}

static uint8_t set_flash_status(uint8_t value)
{
     uint32_t word, var, val;
   
     var = value;
     writel(var, (void *)(spi_char.mem_virt+SPI_DATA0));
     word = readw((void *)(spi_char.mem_virt+SPI_CTRL));
     word |= SPI_CTRL_SCGO; /* set cycle */
     word |= SPI_CTRL_ACS; /* Enable Atomic Cycle Sequence */
     word |= SPI_CTRL_SPOP;
     word &= ~SPI_CTRL_COP;     
     word = word | SPI_CTRL_OPMENU_WRSR<<SPI_CTRL_COP_SHIFT; /* read */
     word &= ~SPI_CTRL_DBC;     
     word = word | 0x00<<SPI_CTRL_DBC_SHIFT; /* write count=1 */
     word |= SPI_CTRL_DC;
     
      /* check the status */
     val = readw((void *)(spi_char.mem_virt+SPI_STATUS));
     while(val & SPI_STATUS_SCIP)
     {
            val = readw((void *)(spi_char.mem_virt+SPI_STATUS));/* check the status */
     }
         
     writew(word, (void *)(spi_char.mem_virt+SPI_CTRL));
         
     /* check the status */
     val = readw((void *)(spi_char.mem_virt+SPI_STATUS));
     while(val & SPI_STATUS_SCIP)
     {
        val = readw((void *)(spi_char.mem_virt+SPI_STATUS));/* check the status */
     }
     word = readw((void *)(spi_char.mem_virt+SPI_STATUS));
     word |= SPI_STATUS_CDS; /* clear Cycle Done Status flag */
     word |= SPI_STATUS_BAS;  /* clear blocked flag */
     writew(word, (void *)(spi_char.mem_virt+SPI_STATUS));
     
     var = get_flash_status();
     return (var);
}

static int is_bios_protection(void)
{
    unsigned int ret;
   
    ret = spi_char.bios_ctrl_addr & BIOS_NOPROTECTION;
   
    return (!ret);
}

static  int disable_bios_protection(void)
{
    unsigned int temp;
    struct pci_dev *pdev = NULL;
   
    if(is_bios_protection())
    {
        temp = spi_char.bios_ctrl_addr | BIOS_NOPROTECTION;
        pdev = pci_get_device(SPI_VENDOR_ID, SPI_DEVICE_ID, NULL);
        if ( !pdev )
        {
            SPI_ERR("%s:spi_char_init-Could not find pci device/n", DRIVERNAME);
            return (0);
         }
        pci_write_config_byte(pdev, BIOS_CTRL, temp);
        spi_char.bios_ctrl_addr = temp;
    //release reference to device
    pci_dev_put(pdev);
    }
   
    return (1);
}


static int  is_flash_protection(void)
{
    unsigned int var;
   
    var = get_flash_status();
    var &= SPI_FLASH_PROTECTION;
    if(var || is_bios_protection())
    {
        return (1);
    }
    return (0);
}


static int disable_flash_protection(void)
{
    uint32_t word, var;
    uint8_t ret1, ret2;
   
    var = get_flash_status();
    var &= ~SPI_FLASH_PROTECTION;
    ret1 = set_flash_status(var);
   
    ret2 = disable_bios_protection();
   
    if(ret1 != var || !ret2)
    {
        return 0;
    }
   
    return (1);
}
继承事业,薪火相传
返回列表