summaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2016-06-15 18:05:05 +0300
committerWolfram Sang <wsa@the-dreams.de>2016-06-19 19:34:16 +0200
commited1bf03470b8c666d6d0d81e8faa8cbb32a5656e (patch)
tree6e9a34448adb5a1fef3fc6341604611d3d70657a /drivers/i2c
parentf41021bba68371b7ff4bcb0fc764473de1782c14 (diff)
downloadlinux-ed1bf03470b8c666d6d0d81e8faa8cbb32a5656e.tar.bz2
i2c: designware-pci: Make bus number allocation robust
On some platforms, such as Intel Medfield, the I2C slave devices are enumerated through SFI tables where bus numbering is expected to be defined in the OS. Make the bus number allocation robust for such platforms. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-designware-core.h1
-rw-r--r--drivers/i2c/busses/i2c-designware-pcidrv.c87
2 files changed, 38 insertions, 50 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index cd409e7fbc71..38493a7142ad 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -26,6 +26,7 @@
#define DW_IC_CON_MASTER 0x1
#define DW_IC_CON_SPEED_STD 0x2
#define DW_IC_CON_SPEED_FAST 0x4
+#define DW_IC_CON_SPEED_MASK 0x6
#define DW_IC_CON_10BITADDR_MASTER 0x10
#define DW_IC_CON_RESTART_EN 0x20
#define DW_IC_CON_SLAVE_DISABLE 0x40
diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
index 7368be000c96..586c8d85b4eb 100644
--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
+++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
@@ -41,13 +41,7 @@
#define DRIVER_NAME "i2c-designware-pci"
enum dw_pci_ctl_id_t {
- medfield_0,
- medfield_1,
- medfield_2,
- medfield_3,
- medfield_4,
- medfield_5,
-
+ medfield,
baytrail,
haswell,
};
@@ -68,6 +62,7 @@ struct dw_pci_controller {
u32 clk_khz;
u32 functionality;
struct dw_scl_sda_cfg *scl_sda_cfg;
+ int (*setup)(struct pci_dev *pdev, struct dw_pci_controller *c);
};
#define INTEL_MID_STD_CFG (DW_IC_CON_MASTER | \
@@ -98,48 +93,33 @@ static struct dw_scl_sda_cfg hsw_config = {
.sda_hold = 0x9,
};
+static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
+{
+ switch (pdev->device) {
+ case 0x0817:
+ c->bus_cfg &= ~DW_IC_CON_SPEED_MASK;
+ c->bus_cfg |= DW_IC_CON_SPEED_STD;
+ case 0x0818:
+ case 0x0819:
+ c->bus_num = pdev->device - 0x817 + 3;
+ return 0;
+ case 0x082C:
+ case 0x082D:
+ case 0x082E:
+ c->bus_num = pdev->device - 0x82C + 0;
+ return 0;
+ }
+ return -ENODEV;
+}
+
static struct dw_pci_controller dw_pci_controllers[] = {
- [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,
+ [medfield] = {
+ .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,
+ .setup = mfld_setup,
},
[baytrail] = {
.bus_num = -1,
@@ -224,6 +204,13 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
dev->base = pcim_iomap_table(pdev)[0];
dev->dev = &pdev->dev;
dev->irq = pdev->irq;
+
+ if (controller->setup) {
+ r = controller->setup(pdev, controller);
+ if (r)
+ return r;
+ }
+
dev->functionality = controller->functionality |
DW_DEFAULT_FUNCTIONALITY;
@@ -276,12 +263,12 @@ MODULE_ALIAS("i2c_designware-pci");
static const struct pci_device_id i2_designware_pci_ids[] = {
/* 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 },
+ { PCI_VDEVICE(INTEL, 0x0817), medfield },
+ { PCI_VDEVICE(INTEL, 0x0818), medfield },
+ { PCI_VDEVICE(INTEL, 0x0819), medfield },
+ { PCI_VDEVICE(INTEL, 0x082C), medfield },
+ { PCI_VDEVICE(INTEL, 0x082D), medfield },
+ { PCI_VDEVICE(INTEL, 0x082E), medfield },
/* Baytrail */
{ PCI_VDEVICE(INTEL, 0x0F41), baytrail },
{ PCI_VDEVICE(INTEL, 0x0F42), baytrail },