From: "Chew, Chiau Ee" <chiau.ee.c...@intel.com>

The pxa2xx pci glue layer only support CE4100 SPI port
by default. To add BYT SPI port support, we make it a
generic PCI glue layer by renaming ce4100_xxx to
pxa2xx_spi_xxx.

This commit is created in reference to Mika's commit
during kernel-3.5 development, as below:

spi/pxa2xx-pci: convert to use pxa2xx-spi core
spi/pxa2xx-pci: add support for different PCI port types
spi/pxa2xx-pci: add support for ValleyView2 SPI

Signed-off-by: Chew, Chiau Ee <chiau.ee.c...@intel.com>
Signed-off-by: Maurice Petallo <mauricex.r.peta...@intel.com>
---
 drivers/spi/Kconfig          |  5 ++-
 drivers/spi/spi-pxa2xx-pci.c | 85 ++++++++++++++++++++++++++++++++++++--------
 2 files changed, 74 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 92775c5..f3fecc4 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -337,7 +337,10 @@ config SPI_PXA2XX
          additional documentation can be found a Documentation/spi/pxa2xx.
 
 config SPI_PXA2XX_PCI
-       def_tristate SPI_PXA2XX && PCI
+       tristate "PCI glue for PXA2xx SSP SPI master"
+       depends on SPI_PXA2XX && PCI
+       help
+         This enables using PXA2xx SPI controller via PCI interface.
 
 config SPI_RSPI
        tristate "Renesas RSPI controller"
diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c
index 74bc187..974d4fe 100644
--- a/drivers/spi/spi-pxa2xx-pci.c
+++ b/drivers/spi/spi-pxa2xx-pci.c
@@ -7,10 +7,48 @@
 #include <linux/of_device.h>
 #include <linux/module.h>
 #include <linux/spi/pxa2xx_spi.h>
+#include <linux/clk.h>
 
-static int ce4100_spi_probe(struct pci_dev *dev,
+enum {
+       PORT_CE4100,
+       PORT_BYT,
+};
+
+struct pxa2xx_spi_pci_config {
+       enum pxa_ssp_type type;
+       int num_cs;
+       int bus_num;
+       int tx_slave_id;
+       int tx_chan_id;
+       int rx_slave_id;
+       int rx_chan_id;
+};
+
+static struct pxa2xx_spi_pci_config spi_pci_configs[] = {
+       [PORT_CE4100] = {
+               .type = PXA25x_SSP,
+               .num_cs =  -1,
+               .bus_num = -1,
+               .tx_slave_id = -1,
+               .tx_chan_id = -1,
+               .rx_slave_id = -1,
+               .rx_chan_id = -1,
+       },
+       [PORT_BYT] = {
+               .type = LPSS_SSP,
+               .num_cs = 1,
+               .bus_num = 0,
+               .tx_slave_id = 0,
+               .tx_chan_id = 0,
+               .rx_slave_id = 1,
+               .rx_chan_id = 1,
+       },
+};
+
+static int pxa2xx_spi_probe(struct pci_dev *dev,
                const struct pci_device_id *ent)
 {
+       struct pxa2xx_spi_pci_config *c;
        struct platform_device_info pi;
        int ret;
        struct platform_device *pdev;
@@ -25,8 +63,16 @@ static int ce4100_spi_probe(struct pci_dev *dev,
        if (ret)
                return ret;
 
+
+       c = &spi_pci_configs[ent->driver_data];
+
        memset(&spi_pdata, 0, sizeof(spi_pdata));
-       spi_pdata.num_chipselect = dev->devfn;
+       spi_pdata.num_chipselect = (c->num_cs >= 0) ? c->num_cs : dev->devfn;
+       spi_pdata.tx_slave_id = c->tx_slave_id;
+       spi_pdata.tx_chan_id = c->tx_chan_id;
+       spi_pdata.rx_slave_id = c->rx_slave_id;
+       spi_pdata.rx_chan_id = c->rx_chan_id;
+       spi_pdata.enable_dma = c->rx_slave_id >= 0 && c->tx_slave_id >= 0;
 
        ssp = &spi_pdata.ssp;
        ssp->phys_base = pci_resource_start(dev, 0);
@@ -35,9 +81,15 @@ static int ce4100_spi_probe(struct pci_dev *dev,
                dev_err(&dev->dev, "failed to ioremap() registers\n");
                return -EIO;
        }
+       ssp->clk =  devm_clk_get(&dev->dev, NULL);
+       if (IS_ERR(ssp->clk)) {
+               dev_err(&dev->dev, "failed to get clock\n");
+               return PTR_ERR(ssp->clk);
+       }
+
        ssp->irq = dev->irq;
-       ssp->port_id = dev->devfn;
-       ssp->type = PXA25x_SSP;
+       ssp->port_id = (c->bus_num >= 0) ? c->bus_num : dev->devfn;
+       ssp->type = c->type;
 
        memset(&pi, 0, sizeof(pi));
        pi.parent = &dev->dev;
@@ -55,28 +107,31 @@ static int ce4100_spi_probe(struct pci_dev *dev,
        return 0;
 }
 
-static void ce4100_spi_remove(struct pci_dev *dev)
+static void pxa2xx_spi_remove(struct pci_dev *dev)
 {
        struct platform_device *pdev = pci_get_drvdata(dev);
 
        platform_device_unregister(pdev);
 }
 
-static DEFINE_PCI_DEVICE_TABLE(ce4100_spi_devices) = {
-       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) },
+static DEFINE_PCI_DEVICE_TABLE(pxa2xx_spi_devices) = {
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a),
+         .driver_data =  PORT_CE4100 },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0f0e),
+         .driver_data = PORT_BYT },
        { },
 };
-MODULE_DEVICE_TABLE(pci, ce4100_spi_devices);
+MODULE_DEVICE_TABLE(pci, pxa2xx_spi_devices);
 
-static struct pci_driver ce4100_spi_driver = {
-       .name           = "ce4100_spi",
-       .id_table       = ce4100_spi_devices,
-       .probe          = ce4100_spi_probe,
-       .remove         = ce4100_spi_remove,
+static struct pci_driver pxa2xx_spi_driver = {
+       .name           = "pxa2xx_spi",
+       .id_table       = pxa2xx_spi_devices,
+       .probe          = pxa2xx_spi_probe,
+       .remove         = pxa2xx_spi_remove,
 };
 
-module_pci_driver(ce4100_spi_driver);
+module_pci_driver(pxa2xx_spi_driver);
 
-MODULE_DESCRIPTION("CE4100 PCI-SPI glue code for PXA's driver");
+MODULE_DESCRIPTION("PCI-SPI glue code for PXA's driver");
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Sebastian Andrzej Siewior <bige...@linutronix.de>");
-- 
1.9.1

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to