Medfield 平台 I2C 驱动配置

medfield 平台中,i2c总线,通过pci总线来配置。
代码位于: /drivers/i2c/busses/i2c-designware-pcidrv.c

1. 首先是pci 设备表:

    static struct dw_pci_controller dw_pci_controllers[] = {
        [moorestown_0] = {
            .bus_num = 0,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 25000,
        },
        [moorestown_1] = {
            .bus_num = 1,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 25000,
        },
        [moorestown_2] = {
            .bus_num = 2,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 25000,
        },
    #ifdef FIXME_MLD // DV0.9 changes to match the GB tree
        [medfield_0] = {
            .bus_num = 0,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 25000,
        },
        [medfield_1] = {
            .bus_num = 1,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 25000,
        },
        [medfield_2] = {
            .bus_num = 2,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 25000,
        },
        [medfield_3] = {
            .bus_num = 3,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_STD,
            .tx_fifo_depth = 32,
           .rx_fifo_depth = 32,
            .clk_khz = 25000,
        },
        [medfield_4] = {
            .bus_num = 4,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 25000,
        },
        [medfield_5] = {
            .bus_num = 5,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 25000,
        },
    #else
        [medfield_0] = {
            .bus_num = 0,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_STD,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 17000,
        },
        [medfield_1] = {
            .bus_num = 1,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 25000,
        },
        [medfield_2] = {
            .bus_num = 2,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 25000,
        },
        [medfield_3] = {
            .bus_num = 3,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_STD,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 25000,
       },
        [medfield_4] = {
            .bus_num = 4,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 25000,
        },
        [medfield_5] = {
            .bus_num = 5,
            .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST,
            .tx_fifo_depth = 32,
            .rx_fifo_depth = 32,
            .clk_khz = 25000,
        },
    #endif
    };
2. 代码开始,注册PCI 驱动:

    static int __init dw_i2c_init_driver(void)
    {
        return pci_register_driver(&dw_i2c_driver);  //把dw_i2c_driver 注册进pci总线。
    }
    module_init(dw_i2c_init_driver);
    static void __exit dw_i2c_exit_driver(void)
    {
        pci_unregister_driver(&dw_i2c_driver);
    }
    module_exit(dw_i2c_exit_driver);
    MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
    MODULE_DESCRIPTION("Synopsys DesignWare PCI I2C bus adapter");
    MODULE_LICENSE("GPL");

dw_i2c_driver 内容:

    static struct pci_driver dw_i2c_driver = {
        .name = DRIVER_NAME,
        .id_table = i2_designware_pci_ids,
        .probe = i2c_dw_pci_probe,
        .remove = __devexit_p(i2c_dw_pci_remove),
        .driver = {
            .pm = &i2c_dw_pm_ops,
        },
    };
3. DRIVER_NAME:
    #define DRIVER_NAME "i2c-designware-pci"
4. i2_designware_pci_ids:  pci的设备表。
    DEFINE_PCI_DEVICE_TABLE(i2_designware_pci_ids) = {
        /* Moorestown */
        { PCI_VDEVICE(INTEL, 0x0802), moorestown_0 },
        { PCI_VDEVICE(INTEL, 0x0803), moorestown_1 },
        { PCI_VDEVICE(INTEL, 0x0804), moorestown_2 },
        /* Medfield */
        { PCI_VDEVICE(INTEL, 0x0817), medfield_3,},
        { PCI_VDEVICE(INTEL, 0x0818), medfield_4 },
        { PCI_VDEVICE(INTEL, 0x0819), medfield_5 },
        { PCI_VDEVICE(INTEL, 0x082C), medfield_0 },
        { PCI_VDEVICE(INTEL, 0x082D), medfield_1 },
        { PCI_VDEVICE(INTEL, 0x082E), medfield_2 },
        { 0,}
    };
    MODULE_DEVICE_TABLE(pci, i2_designware_pci_ids);
5. i2c_dw_pci_probe()
    static int __devinit i2c_dw_pci_probe(struct pci_dev *pdev,
    const struct pci_device_id *id)
    {
        struct dw_i2c_dev *dev;
        struct i2c_adapter *adap;
        unsigned long start, len;
        void __iomem *base;
        int r;
        struct dw_pci_controller *controller;
        if (id->driver_data >= ARRAY_SIZE(dw_pci_controllers)) {
            printk(KERN_ERR "dw_i2c_pci_probe: invalid driver data %ld\n",
                id->driver_data);
            return -EINVAL;
        }
        controller = &dw_pci_controllers[id->driver_data];
        r = pci_enable_device(pdev);
        if (r) {
            dev_err(&pdev->dev, "Failed to enable I2C PCI device (%d)\n",
                r);
            goto exit;
        }
        /* Determine the address of the I2C area */
        start = pci_resource_start(pdev, 0);
        len = pci_resource_len(pdev, 0);
        if (!start || len == 0) {
            dev_err(&pdev->dev, "base address not set\n");
            r = -ENODEV;
            goto exit;
        }
        r = pci_request_region(pdev, 0, DRIVER_NAME);
        if (r) {
            dev_err(&pdev->dev, "failed to request I2C region "
                "0x%lx-0x%lx\n", start,
                (unsigned long)pci_resource_end(pdev, 0));
            goto exit;
        }
        base = ioremap_nocache(start, len);
        if (!base) {
            dev_err(&pdev->dev, "I/O memory remapping failed\n");
            r = -ENOMEM;
            goto err_release_region;
        }
        dev = kzalloc(sizeof(struct dw_i2c_dev), GFP_KERNEL);

6. i2c_dw_pm_ops :
    static const struct dev_pm_ops i2c_dw_pm_ops = {
        .resume = i2c_dw_pci_resume,
        .suspend = i2c_dw_pci_suspend,
        SET_RUNTIME_PM_OPS(i2c_dw_pci_suspend,
                i2c_dw_pci_resume,
                i2c_dw_pci_runtime_idle)
    };



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值