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

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

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

/*****************************************************************************
  Description:
    This function is called when the driver interface is closed   

  Parameters:
    none

  Returns:
      0 => success
    < 0 => error

******************************************************************************/
int spi_release(struct inode *inode, struct file *filp)
{
    spi_char.fp = 0;
    SPI_DBG("spi_char.fp = %08x/n", spi_char.fp);
    SPI_DBG("%s:spi_release-module released/n", DRIVERNAME);
    return 0;
}



int spi_read (struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
    int i;
    uint32_t addr, val;
    uint16_t word;
    unsigned char data[BUF_SIZE];
    ssize_t retval = 0;
   
    /* print some information for debug */
    SPI_DBG("start spi_read/n");
    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 = readw((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.0=%08x/n", val);
    val = readl((void *)(spi_char.mem_virt+SPI_DATA0+4));
    SPI_DBG("data0.1=%08x/n", val);
   
    /* check count */
    if(count > BUF_SIZE)
    {
        count = BUF_SIZE;
    }
    if(spi_char.fp+count > SPI_FLASH_SIZE)
    {
        count = SPI_FLASH_SIZE-spi_char.fp;
    }
   
   
    SPI_DBG("spi_char.fp = %08x/n", spi_char.fp);
    addr = spi_char.fp;
    SPI_DBG("spi_read: addr = %08x/n", addr);
    for(i = 0; i < count; i++)
    {
        data[i] = read_byte(addr+i);
    }
   
    if(copy_to_user(buf, data, count))
    {
        SPI_ERR("spi_read::copty_to_user eror/n");
        return (-EFAULT);
    }
    spi_char.fp += count;
    SPI_DBG("leave spi_read, count=%d/n", count);
     
    return (count);
}
   

int spi_write (struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
    int i;
    uint32_t addr, val;
    uint16_t word;
    unsigned char data[BUF_SIZE];
    ssize_t retval = 0;
   
    /* print some information for debug */
    SPI_DBG("start spi_write/n");
    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 = readw((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.0=%08x/n", val);
    val = readl((void *)(spi_char.mem_virt+SPI_DATA0+4));
    SPI_DBG("data0.1=%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);
   
    /* check count */
    if(count > BUF_SIZE)
    {
        count = BUF_SIZE;
    }
    if(spi_char.fp+count > SPI_FLASH_SIZE)
    {
        count = SPI_FLASH_SIZE-spi_char.fp;
    }
   
    if(copy_from_user(data, buf, count))
    {
         SPI_ERR("spi_read::copy_from_user error/n");
         return(-EFAULT);
    }
   
    /* disable flash protection */
    if(is_flash_protection())
    {
        if(!disable_flash_protection())
        {
            SPI_ERR("can't disable flash protection/n");
            return(-EFAULT);
        }
    }
   
    addr = spi_char.fp;
    for(i = 0; i < count; i++)
    {
        if(!write_byte(addr+i, data[i]))
        {
            SPI_ERR("spi_write error/n");
        }
         
         /* print some information for debug */
         val = readl((void *)(spi_char.mem_virt+SPI_DATA0));
         SPI_DBG("after write, data=%08x/n", val);
         val = readw((void *)(spi_char.mem_virt+SPI_CTRL));
         SPI_DBG("after write, ctrl=%08x/n", val);
         val = readw((void *)(spi_char.mem_virt+SPI_STATUS));
         SPI_DBG("after write, status=%08x/n", val);
         word = readw((void *)(spi_char.mem_virt+SPI_STATUS));
         word |= SPI_STATUS_CDS;
         word |= SPI_STATUS_BAS;
         writew(word, (void *)(spi_char.mem_virt+SPI_STATUS));
         val = readw((void *)(spi_char.mem_virt+SPI_STATUS));
         SPI_DBG("after write1, status=%08x/n", val);
    }
   
    spi_char.fp += count;
    SPI_DBG("leave spi_write, count=%d/n", count);
    return (count);
}
继承事业,薪火相传
返回列表