diff options
author | Simon Glass <sjg@chromium.org> | 2019-12-06 21:41:40 -0700 |
---|---|---|
committer | Bin Meng <bmeng.cn@gmail.com> | 2019-12-15 11:44:08 +0800 |
commit | 457df2337fc90431dc60b9b256ac1fdb8809f4cf (patch) | |
tree | 314e61460ac2a14e68d358d242f45dfa7505f090 /drivers/i2c/designware_i2c_pci.c | |
parent | d721001fd6d4162738578ba03c94c1198a5ef462 (diff) |
i2c: designware: Tidy up PCI support
This is hacked into the driver at present. It seems better to have it as
a separate driver that uses the base driver. Create a new file and put
the X86 code into it.
Actually the Baytrail settings should really come from the device tree.
Note that 'has_max_speed' is added as well. This is currently always false
but since only Baytrail provides the config, it does not affect operation
for other devices.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Heiko Schocher <hs@denx.de>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'drivers/i2c/designware_i2c_pci.c')
-rw-r--r-- | drivers/i2c/designware_i2c_pci.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/i2c/designware_i2c_pci.c b/drivers/i2c/designware_i2c_pci.c new file mode 100644 index 0000000000..e8fc6f2a90 --- /dev/null +++ b/drivers/i2c/designware_i2c_pci.c @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2009 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. + * Copyright 2019 Google Inc + */ + +#include <common.h> +#include <dm.h> +#include "designware_i2c.h" + +/* BayTrail HCNT/LCNT/SDA hold time */ +static struct dw_scl_sda_cfg byt_config = { + .ss_hcnt = 0x200, + .fs_hcnt = 0x55, + .ss_lcnt = 0x200, + .fs_lcnt = 0x99, + .sda_hold = 0x6, +}; + +static int designware_i2c_pci_probe(struct udevice *dev) +{ + struct dw_i2c *priv = dev_get_priv(dev); + + /* Save base address from PCI BAR */ + priv->regs = (struct i2c_regs *) + dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM); + if (IS_ENABLED(CONFIG_INTEL_BAYTRAIL)) + /* Use BayTrail specific timing values */ + priv->scl_sda_cfg = &byt_config; + + return designware_i2c_probe(dev); +} + +static int designware_i2c_pci_bind(struct udevice *dev) +{ + static int num_cards; + char name[20]; + + /* + * Create a unique device name for PCI type devices + * ToDo: + * Setting req_seq in the driver is probably not recommended. + * But without a DT alias the number is not configured. And + * using this driver is impossible for PCIe I2C devices. + * This can be removed, once a better (correct) way for this + * is found and implemented. + */ + dev->req_seq = num_cards; + sprintf(name, "i2c_designware#%u", num_cards++); + device_set_name(dev, name); + + return 0; +} + +U_BOOT_DRIVER(i2c_designware_pci) = { + .name = "i2c_designware_pci", + .id = UCLASS_I2C, + .bind = designware_i2c_pci_bind, + .probe = designware_i2c_pci_probe, + .priv_auto_alloc_size = sizeof(struct dw_i2c), + .remove = designware_i2c_remove, + .flags = DM_FLAG_OS_PREPARE, + .ops = &designware_i2c_ops, +}; + +static struct pci_device_id designware_pci_supported[] = { + /* Intel BayTrail has 7 I2C controller located on the PCI bus */ + { PCI_VDEVICE(INTEL, 0x0f41) }, + { PCI_VDEVICE(INTEL, 0x0f42) }, + { PCI_VDEVICE(INTEL, 0x0f43) }, + { PCI_VDEVICE(INTEL, 0x0f44) }, + { PCI_VDEVICE(INTEL, 0x0f45) }, + { PCI_VDEVICE(INTEL, 0x0f46) }, + { PCI_VDEVICE(INTEL, 0x0f47) }, + {}, +}; + +U_BOOT_PCI_DEVICE(i2c_designware_pci, designware_pci_supported); |