diff options
author | Chew, Chiau Ee <chiau.ee.chew@intel.com> | 2014-04-17 12:26:06 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-04-18 13:06:07 -0400 |
commit | d6ba32d5c60f569d252ec9dcd96cd46b19785b60 (patch) | |
tree | 89d76a1a9d3ba8b7bfc23d9626de3836ea83b40d /drivers/spi/spi-pxa2xx-pci.c | |
parent | c9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff) |
spi/pxa2xx-pci: Add PCI mode support for BayTrail LPSS SPI
Similar to CE4100, BayTrail LPSS SPI can be PCI enumerated
as well. Thus, the functions are renamed from ce4100_xxx
to pxa2xx_spi_pci_xxx to clarify that this is a generic
PCI glue layer. Also, added required infrastructure to
support SPI hosts with different configurations.
This patch is based on Mika Westerberg's previous work.
Signed-off-by: Chew, Chiau Ee <chiau.ee.chew@intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-pxa2xx-pci.c')
-rw-r--r-- | drivers/spi/spi-pxa2xx-pci.c | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index 3f006d3ed2a8..c1865c92ccb9 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c | |||
@@ -8,7 +8,43 @@ | |||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/spi/pxa2xx_spi.h> | 9 | #include <linux/spi/pxa2xx_spi.h> |
10 | 10 | ||
11 | static int ce4100_spi_probe(struct pci_dev *dev, | 11 | enum { |
12 | PORT_CE4100, | ||
13 | PORT_BYT, | ||
14 | }; | ||
15 | |||
16 | struct pxa_spi_info { | ||
17 | enum pxa_ssp_type type; | ||
18 | int port_id; | ||
19 | int num_chipselect; | ||
20 | int tx_slave_id; | ||
21 | int tx_chan_id; | ||
22 | int rx_slave_id; | ||
23 | int rx_chan_id; | ||
24 | }; | ||
25 | |||
26 | static struct pxa_spi_info spi_info_configs[] = { | ||
27 | [PORT_CE4100] = { | ||
28 | .type = PXA25x_SSP, | ||
29 | .port_id = -1, | ||
30 | .num_chipselect = -1, | ||
31 | .tx_slave_id = -1, | ||
32 | .tx_chan_id = -1, | ||
33 | .rx_slave_id = -1, | ||
34 | .rx_chan_id = -1, | ||
35 | }, | ||
36 | [PORT_BYT] = { | ||
37 | .type = LPSS_SSP, | ||
38 | .port_id = 0, | ||
39 | .num_chipselect = 1, | ||
40 | .tx_slave_id = 0, | ||
41 | .tx_chan_id = 0, | ||
42 | .rx_slave_id = 1, | ||
43 | .rx_chan_id = 1, | ||
44 | }, | ||
45 | }; | ||
46 | |||
47 | static int pxa2xx_spi_pci_probe(struct pci_dev *dev, | ||
12 | const struct pci_device_id *ent) | 48 | const struct pci_device_id *ent) |
13 | { | 49 | { |
14 | struct platform_device_info pi; | 50 | struct platform_device_info pi; |
@@ -16,6 +52,7 @@ static int ce4100_spi_probe(struct pci_dev *dev, | |||
16 | struct platform_device *pdev; | 52 | struct platform_device *pdev; |
17 | struct pxa2xx_spi_master spi_pdata; | 53 | struct pxa2xx_spi_master spi_pdata; |
18 | struct ssp_device *ssp; | 54 | struct ssp_device *ssp; |
55 | struct pxa_spi_info *c; | ||
19 | 56 | ||
20 | ret = pcim_enable_device(dev); | 57 | ret = pcim_enable_device(dev); |
21 | if (ret) | 58 | if (ret) |
@@ -25,8 +62,16 @@ static int ce4100_spi_probe(struct pci_dev *dev, | |||
25 | if (ret) | 62 | if (ret) |
26 | return ret; | 63 | return ret; |
27 | 64 | ||
65 | c = &spi_info_configs[ent->driver_data]; | ||
66 | |||
28 | memset(&spi_pdata, 0, sizeof(spi_pdata)); | 67 | memset(&spi_pdata, 0, sizeof(spi_pdata)); |
29 | spi_pdata.num_chipselect = dev->devfn; | 68 | spi_pdata.num_chipselect = (c->num_chipselect > 0) ? |
69 | c->num_chipselect : dev->devfn; | ||
70 | spi_pdata.tx_slave_id = c->tx_slave_id; | ||
71 | spi_pdata.tx_chan_id = c->tx_chan_id; | ||
72 | spi_pdata.rx_slave_id = c->rx_slave_id; | ||
73 | spi_pdata.rx_chan_id = c->rx_chan_id; | ||
74 | spi_pdata.enable_dma = c->rx_slave_id >= 0 && c->tx_slave_id >= 0; | ||
30 | 75 | ||
31 | ssp = &spi_pdata.ssp; | 76 | ssp = &spi_pdata.ssp; |
32 | ssp->phys_base = pci_resource_start(dev, 0); | 77 | ssp->phys_base = pci_resource_start(dev, 0); |
@@ -36,8 +81,8 @@ static int ce4100_spi_probe(struct pci_dev *dev, | |||
36 | return -EIO; | 81 | return -EIO; |
37 | } | 82 | } |
38 | ssp->irq = dev->irq; | 83 | ssp->irq = dev->irq; |
39 | ssp->port_id = dev->devfn; | 84 | ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn; |
40 | ssp->type = PXA25x_SSP; | 85 | ssp->type = c->type; |
41 | 86 | ||
42 | memset(&pi, 0, sizeof(pi)); | 87 | memset(&pi, 0, sizeof(pi)); |
43 | pi.parent = &dev->dev; | 88 | pi.parent = &dev->dev; |
@@ -55,28 +100,29 @@ static int ce4100_spi_probe(struct pci_dev *dev, | |||
55 | return 0; | 100 | return 0; |
56 | } | 101 | } |
57 | 102 | ||
58 | static void ce4100_spi_remove(struct pci_dev *dev) | 103 | static void pxa2xx_spi_pci_remove(struct pci_dev *dev) |
59 | { | 104 | { |
60 | struct platform_device *pdev = pci_get_drvdata(dev); | 105 | struct platform_device *pdev = pci_get_drvdata(dev); |
61 | 106 | ||
62 | platform_device_unregister(pdev); | 107 | platform_device_unregister(pdev); |
63 | } | 108 | } |
64 | 109 | ||
65 | static const struct pci_device_id ce4100_spi_devices[] = { | 110 | static const struct pci_device_id pxa2xx_spi_pci_devices[] = { |
66 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) }, | 111 | { PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 }, |
112 | { PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT }, | ||
67 | { }, | 113 | { }, |
68 | }; | 114 | }; |
69 | MODULE_DEVICE_TABLE(pci, ce4100_spi_devices); | 115 | MODULE_DEVICE_TABLE(pci, pxa2xx_spi_pci_devices); |
70 | 116 | ||
71 | static struct pci_driver ce4100_spi_driver = { | 117 | static struct pci_driver pxa2xx_spi_pci_driver = { |
72 | .name = "ce4100_spi", | 118 | .name = "pxa2xx_spi_pci", |
73 | .id_table = ce4100_spi_devices, | 119 | .id_table = pxa2xx_spi_pci_devices, |
74 | .probe = ce4100_spi_probe, | 120 | .probe = pxa2xx_spi_pci_probe, |
75 | .remove = ce4100_spi_remove, | 121 | .remove = pxa2xx_spi_pci_remove, |
76 | }; | 122 | }; |
77 | 123 | ||
78 | module_pci_driver(ce4100_spi_driver); | 124 | module_pci_driver(pxa2xx_spi_pci_driver); |
79 | 125 | ||
80 | MODULE_DESCRIPTION("CE4100 PCI-SPI glue code for PXA's driver"); | 126 | MODULE_DESCRIPTION("CE4100/LPSS PCI-SPI glue code for PXA's driver"); |
81 | MODULE_LICENSE("GPL v2"); | 127 | MODULE_LICENSE("GPL v2"); |
82 | MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>"); | 128 | MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>"); |