- 论坛徽章:
- 0
|
medfield 平台中,i2c总线,通过pci总线来配置。 代码位于: /drivers/i2c/busses/i2c-designware-pcidrv.c 中
首先是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
-
};
代码开始,注册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,
-
},
-
};
1. DRIVER_NAME:
- #define DRIVER_NAME "i2c-designware-pci"
2. 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);
3. 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);
4. 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)
-
};
|
|