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

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

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

/*****************************************************************************
  Description:
    This function is the ioctl interface to the driver.   

  Parameters:
    inode  ptr to inode
    filp   ptr to file struct
    cmd    ioctl command
    arg    passed in argument

  Returns:
      0 => success
    < 0 => error
******************************************************************************/
int spi_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
                unsigned long arg)
{
    ioctl_arg_t info;
    unsigned int start, end;
    int i;
   
    switch(cmd)
    {
        case IOCTL_ERASE_CHIP:
            if( !erase_chip())
            {
                return (-EFAULT);
            }
            break;
         
        case IOCTL_ERASE_BLOCK:
            if((void *)arg == NULL)
            {
                return(-EINVAL);
            }
            //get the ioctl struct passed in by user
       if ( copy_from_user(&info, (ioctl_arg_t*)arg, sizeof(ioctl_arg_t)) )
       {
           SPI_ERR("%s:spi_ioctl::copy_from_user error./n", DRIVERNAME);
           return -EFAULT;
           }
            
             /* sector & address index start from 0 */
            start = (info.data.erase_range.start) >> SPI_FLASH_SECTOR_BIT;
            end = (info.data.erase_range.end) >> SPI_FLASH_SECTOR_BIT;
            /* start = (info.data.erase_range.start + SPI_FLASH_SECTOR_SIZE -1) >> SPI_FLASH_SECTOR_BIT;
            end = (info.data.erase_range.end + SPI_FLASH_SECTOR_SIZE -1) >> SPI_FLASH_SECTOR_BIT;
            start--;
            end--; */
            if(start > end || start < 0 || end >= SPI_FLASH_SIZE/SPI_FLASH_SECTOR_SIZE)
            {
                return (-EINVAL);
            }
           
                SPI_DBG("start=%d,end=%d/n", start, end);               

            for(i = start; i <= end; i++)
            {
                if(!erase_4K_sector(i))
                {
                    return (-EFAULT);
                }
            }
            break;
            
            default:
                return (-EINVAL);
                    break;
    }
            
   
    return 0;
}



void EP80579_spi_init(uint32_t base)
{
    uint8_t byte;
    uint16_t word;
    uint32_t dword,val;
    uint64_t qword;
    uint32_t addr;
        
    /* print some information for debug */
    val = readw((void *)(spi_char.mem_virt+SPI_STATUS));
    SPI_DBG("status=%08x/n", val);
    val = readw((void *)(spi_char.mem_virt+SPI_CTRL));
    SPI_DBG("ctrl=%08x/n", val);
    val = readl((void *)(spi_char.mem_virt+SPI_ADDR));
    SPI_DBG("addr=%08x/n", val);
    val = readl((void *)(spi_char.mem_virt+SPI_DATA0));
    SPI_DBG("data0=%08x/n", val);
    val = readl((void *)(spi_char.mem_virt+SPI_BBAR));
    SPI_DBG("BBAR=%08x/n", val);
    val = readl((void *)(spi_char.mem_virt+SPI_PBAR0));
    SPI_DBG("PBAR0=%08x/n", val);

    /* enable configuration */
    addr = base + SPI_STATUS;
    word = readw((void *)addr);
    word &= ~SPI_STATUS_CFG_LOCK;
    writew(word, (void *)addr);
   
    /* fill opcode */
    addr = base + SPI_OPMENU;
    val = readl((void *)(spi_char.mem_virt+SPI_OPMENU));
    SPI_DBG("before init, SPI_OPMENU.0=%08x/n", val);
    val = readl((void *)(spi_char.mem_virt+SPI_OPMENU+4));
    SPI_DBG("before init, SPI_OPMENU.1=%08x/n", val);
    dword = SPI_RD_DATA + (SPI_RD_STATUS<<8) + (SPI_WR_DATA<<16) + (SPI_WR_STATUS<<24);
    writel(dword, (void *)addr);
    dword = (SPI_4K_ERASE)+(SPI_CHIP_ERASE<<8);
    writel(dword, (void *)(addr+4));
    val = readl((void *)(spi_char.mem_virt+SPI_OPMENU));
    SPI_DBG("after init, SPI_OPMENU.0=%08x/n", val);
    val = readl((void *)(spi_char.mem_virt+SPI_OPMENU+4));
    SPI_DBG("after init, SPI_OPMENU.1=%08x/n", val);
   
    /* fill opcode type */
    val = readw((void *)(spi_char.mem_virt+SPI_OPTYPE));
    SPI_DBG("before init, SPI_OPTTYPE=%08x/n", val);
    val &= 0x0000;
    val = val |SPI_RD_ADDR|(SPI_RD_NOADDR<<SPI_OPTYPE_WIDTH)|(SPI_WR_ADDR<<SPI_OPTYPE_WIDTH*2)
              |(SPI_WR_NOADDR<<SPI_OPTYPE_WIDTH*3)|(SPI_WR_ADDR<<SPI_OPTYPE_WIDTH*4)|(SPI_WR_NOADDR<<SPI_OPTYPE_WIDTH*5);
    writew(val, (void *)(spi_char.mem_virt+SPI_OPTYPE));
    val = readw((void *)(spi_char.mem_virt+SPI_OPTYPE));/* check the status */
    SPI_DBG("after init, SPI_OPTTYPE=%08x/n", val);
继承事业,薪火相传
返回列表