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

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

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

/*****************************************************************************
  Description:
    Entry point for the driver.   

  Parameters:
    none

  Returns:
      0 => success
    < 0 => error
******************************************************************************/
int spi_init(void)
{
    int ret;
    dev_t devno;
    struct pci_dev *pdev = NULL;
   
    spi_char.mem_base = 0;
    spi_char.mem_ready = 0;

    //request and reserve a device number
   /* ret = alloc_chrdev_region(&spi_char.dev, 0, 1, DRIVERNAME);

    if ( ret < 0)
    {
        SPI_ERR("%s:spi_init-Could not register module/n", DRIVERNAME);
        return ret;
    } */

    //init cdev struct for adding device to kernel
    cdev_init(&spi_char.cdev, &file_ops);
    spi_char.cdev.owner = THIS_MODULE;
    spi_char.cdev.ops = &file_ops;
    spi_char.mem_size = SPI_FLASH_SIZE;
      
    //devno = MKDEV(MAJOR(spi_char.dev), 0);
    devno = MKDEV(MAJOR_NO, MINOR_NO);
    SPI_DBG("major id:%d, minor id:%d/n", MAJOR(devno), MINOR(devno));
    if(cdev_add(&spi_char.cdev, devno, 1))
    {
        SPI_ERR("%s:spi_init-cdev_add failed/n", DRIVERNAME);
        goto Exit_Error;
    }
   

    //Get dev struct for the LPC device. The GPIO BAR is located in the
    //LPC device config space
    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);
        goto Exit_Error;
    }
        
    //Get base address from the LPC configuration space.
    pci_read_config_dword(pdev, CRBA_BAR, &(spi_char.mem_base));
    SPI_DBG("base addr1 %08x/n", spi_char.mem_base);
    //Get BIOS Contrl address
    pci_read_config_byte(pdev, BIOS_CTRL, &(spi_char.bios_ctrl_addr));
    SPI_DBG("bios ctrl addr %08x/n", spi_char.bios_ctrl_addr);

    /* Get own base address */
    spi_char.mem_base &= 0xFFFFC000;
    SPI_DBG("base addr11 %08x/n", spi_char.mem_base);
    spi_char.mem_base += SPI_BAR_OFFSET;
    SPI_DBG("base addr21 %08x/n", spi_char.mem_base);

    //release reference to device
    pci_dev_put(pdev);


    //obtain memory space
    if ( !request_mem_region(spi_char.mem_base, SPI_MEM_SIZE, DRIVERNAME) )
    {
        spi_char.iomem_ready = 0;
        SPI_ERR("%s:spi_init-IO memory region has been reserved?/n", DRIVERNAME);
    }
    else
    {
        spi_char.iomem_ready = 1;
    }
    spi_char.mem_virt = ioremap(spi_char.mem_base, SPI_MEM_SIZE);
    SPI_DBG("virtual addr %08x/n", spi_char.mem_virt);
    //indicate memory space reserved
    spi_char.mem_ready = 1;
   
   
    //do some special initiation
    EP80579_spi_init(spi_char.mem_virt);
   

    goto Exit;

Exit_Error:
    SPI_ERR("%s:spi_init-Initialization failed/n", DRIVERNAME);
    spi_cleanup();
    return -ENODEV;
   
Exit:
    SPI_DBG("%s:spi_init-Initialization complete/n", DRIVERNAME);
    return 0;
}
继承事业,薪火相传
返回列表