Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi/pxa2xx: Add CE4100 support

Sodaville's SPI controller is very much the same as in PXA25x. The
difference:
- The RX/TX FIFO is only 4 words deep instead of 16
- No DMA support
- The SPI controller offers a CS functionality

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>

+314 -7
+8 -5
drivers/spi/Kconfig
··· 267 267 268 268 config SPI_PXA2XX 269 269 tristate "PXA2xx SSP SPI master" 270 - depends on ARCH_PXA && EXPERIMENTAL 271 - select PXA_SSP 270 + depends on (ARCH_PXA || (X86_32 && PCI)) && EXPERIMENTAL 271 + select PXA_SSP if ARCH_PXA 272 272 help 273 - This enables using a PXA2xx SSP port as a SPI master controller. 274 - The driver can be configured to use any SSP port and additional 275 - documentation can be found a Documentation/spi/pxa2xx. 273 + This enables using a PXA2xx or Sodaville SSP port as a SPI master 274 + controller. The driver can be configured to use any SSP port and 275 + additional documentation can be found a Documentation/spi/pxa2xx. 276 + 277 + config SPI_PXA2XX_PCI 278 + def_bool SPI_PXA2XX && X86_32 && PCI 276 279 277 280 config SPI_S3C24XX 278 281 tristate "Samsung S3C24XX series SPI"
+1
drivers/spi/Makefile
··· 24 24 obj-$(CONFIG_SPI_IMX) += spi_imx.o 25 25 obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o 26 26 obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o 27 + obj-$(CONFIG_SPI_PXA2XX_PCI) += pxa2xx_spi_pci.o 27 28 obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o 28 29 obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o 29 30 obj-$(CONFIG_SPI_OMAP_100K) += omap_spi_100k.o
-1
drivers/spi/pxa2xx_spi.c
··· 28 28 #include <linux/spi/spi.h> 29 29 #include <linux/workqueue.h> 30 30 #include <linux/delay.h> 31 - #include <linux/clk.h> 32 31 #include <linux/gpio.h> 33 32 #include <linux/slab.h> 34 33
+201
drivers/spi/pxa2xx_spi_pci.c
··· 1 + /* 2 + * CE4100's SPI device is more or less the same one as found on PXA 3 + * 4 + */ 5 + #include <linux/pci.h> 6 + #include <linux/platform_device.h> 7 + #include <linux/of_device.h> 8 + #include <linux/spi/pxa2xx_spi.h> 9 + 10 + struct awesome_struct { 11 + struct ssp_device ssp; 12 + struct platform_device spi_pdev; 13 + struct pxa2xx_spi_master spi_pdata; 14 + }; 15 + 16 + static DEFINE_MUTEX(ssp_lock); 17 + static LIST_HEAD(ssp_list); 18 + 19 + struct ssp_device *pxa_ssp_request(int port, const char *label) 20 + { 21 + struct ssp_device *ssp = NULL; 22 + 23 + mutex_lock(&ssp_lock); 24 + 25 + list_for_each_entry(ssp, &ssp_list, node) { 26 + if (ssp->port_id == port && ssp->use_count == 0) { 27 + ssp->use_count++; 28 + ssp->label = label; 29 + break; 30 + } 31 + } 32 + 33 + mutex_unlock(&ssp_lock); 34 + 35 + if (&ssp->node == &ssp_list) 36 + return NULL; 37 + 38 + return ssp; 39 + } 40 + EXPORT_SYMBOL_GPL(pxa_ssp_request); 41 + 42 + void pxa_ssp_free(struct ssp_device *ssp) 43 + { 44 + mutex_lock(&ssp_lock); 45 + if (ssp->use_count) { 46 + ssp->use_count--; 47 + ssp->label = NULL; 48 + } else 49 + dev_err(&ssp->pdev->dev, "device already free\n"); 50 + mutex_unlock(&ssp_lock); 51 + } 52 + EXPORT_SYMBOL_GPL(pxa_ssp_free); 53 + 54 + static void plat_dev_release(struct device *dev) 55 + { 56 + struct awesome_struct *as = container_of(dev, 57 + struct awesome_struct, spi_pdev.dev); 58 + 59 + of_device_node_put(&as->spi_pdev.dev); 60 + } 61 + 62 + static int __devinit ce4100_spi_probe(struct pci_dev *dev, 63 + const struct pci_device_id *ent) 64 + { 65 + int ret; 66 + resource_size_t phys_beg; 67 + resource_size_t phys_len; 68 + struct awesome_struct *spi_info; 69 + struct platform_device *pdev; 70 + struct pxa2xx_spi_master *spi_pdata; 71 + struct ssp_device *ssp; 72 + 73 + ret = pci_enable_device(dev); 74 + if (ret) 75 + return ret; 76 + 77 + phys_beg = pci_resource_start(dev, 0); 78 + phys_len = pci_resource_len(dev, 0); 79 + 80 + if (!request_mem_region(phys_beg, phys_len, 81 + "CE4100 SPI")) { 82 + dev_err(&dev->dev, "Can't request register space.\n"); 83 + ret = -EBUSY; 84 + return ret; 85 + } 86 + 87 + spi_info = kzalloc(sizeof(*spi_info), GFP_KERNEL); 88 + if (!spi_info) { 89 + ret = -ENOMEM; 90 + goto err_kz; 91 + } 92 + ssp = &spi_info->ssp; 93 + pdev = &spi_info->spi_pdev; 94 + spi_pdata = &spi_info->spi_pdata; 95 + 96 + pdev->name = "pxa2xx-spi"; 97 + pdev->id = dev->devfn; 98 + pdev->dev.parent = &dev->dev; 99 + pdev->dev.platform_data = &spi_info->spi_pdata; 100 + 101 + #ifdef CONFIG_OF 102 + pdev->dev.of_node = dev->dev.of_node; 103 + #endif 104 + pdev->dev.release = plat_dev_release; 105 + 106 + spi_pdata->num_chipselect = dev->devfn; 107 + 108 + ssp->phys_base = pci_resource_start(dev, 0); 109 + ssp->mmio_base = ioremap(phys_beg, phys_len); 110 + if (!ssp->mmio_base) { 111 + dev_err(&pdev->dev, "failed to ioremap() registers\n"); 112 + ret = -EIO; 113 + goto err_remap; 114 + } 115 + ssp->irq = dev->irq; 116 + ssp->port_id = pdev->id; 117 + ssp->type = PXA25x_SSP; 118 + 119 + mutex_lock(&ssp_lock); 120 + list_add(&ssp->node, &ssp_list); 121 + mutex_unlock(&ssp_lock); 122 + 123 + pci_set_drvdata(dev, spi_info); 124 + 125 + ret = platform_device_register(pdev); 126 + if (ret) 127 + goto err_dev_add; 128 + 129 + return ret; 130 + 131 + err_dev_add: 132 + pci_set_drvdata(dev, NULL); 133 + mutex_lock(&ssp_lock); 134 + list_del(&ssp->node); 135 + mutex_unlock(&ssp_lock); 136 + iounmap(ssp->mmio_base); 137 + 138 + err_remap: 139 + kfree(spi_info); 140 + 141 + err_kz: 142 + release_mem_region(phys_beg, phys_len); 143 + 144 + return ret; 145 + } 146 + 147 + static void __devexit ce4100_spi_remove(struct pci_dev *dev) 148 + { 149 + struct awesome_struct *spi_info; 150 + struct platform_device *pdev; 151 + struct ssp_device *ssp; 152 + 153 + spi_info = pci_get_drvdata(dev); 154 + 155 + ssp = &spi_info->ssp; 156 + pdev = &spi_info->spi_pdev; 157 + 158 + platform_device_unregister(pdev); 159 + 160 + iounmap(ssp->mmio_base); 161 + release_mem_region(pci_resource_start(dev, 0), 162 + pci_resource_len(dev, 0)); 163 + 164 + mutex_lock(&ssp_lock); 165 + list_del(&ssp->node); 166 + mutex_unlock(&ssp_lock); 167 + 168 + pci_set_drvdata(dev, NULL); 169 + pci_disable_device(dev); 170 + kfree(spi_info); 171 + } 172 + 173 + static struct pci_device_id ce4100_spi_devices[] __devinitdata = { 174 + 175 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) }, 176 + { }, 177 + }; 178 + MODULE_DEVICE_TABLE(pci, ce4100_spi_devices); 179 + 180 + static struct pci_driver ce4100_spi_driver = { 181 + .name = "ce4100_spi", 182 + .id_table = ce4100_spi_devices, 183 + .probe = ce4100_spi_probe, 184 + .remove = __devexit_p(ce4100_spi_remove), 185 + }; 186 + 187 + static int __init ce4100_spi_init(void) 188 + { 189 + return pci_register_driver(&ce4100_spi_driver); 190 + } 191 + module_init(ce4100_spi_init); 192 + 193 + static void __exit ce4100_spi_exit(void) 194 + { 195 + pci_unregister_driver(&ce4100_spi_driver); 196 + } 197 + module_exit(ce4100_spi_exit); 198 + 199 + MODULE_DESCRIPTION("CE4100 PCI-SPI glue code for PXA's driver"); 200 + MODULE_LICENSE("GPL v2"); 201 + MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>");
+104 -1
include/linux/spi/pxa2xx_spi.h
··· 19 19 #define __linux_pxa2xx_spi_h 20 20 21 21 #include <linux/pxa2xx_ssp.h> 22 - #include <mach/dma.h> 23 22 24 23 #define PXA2XX_CS_ASSERT (0x01) 25 24 #define PXA2XX_CS_DEASSERT (0x02) ··· 43 44 void (*cs_control)(u32 command); 44 45 }; 45 46 47 + #ifdef CONFIG_ARCH_PXA 48 + 49 + #include <linux/clk.h> 50 + #include <mach/dma.h> 51 + 46 52 extern void pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info); 47 53 54 + #else 55 + /* 56 + * This is the implemtation for CE4100 on x86. ARM defines them in mach/ or 57 + * plat/ include path. 58 + * The CE4100 does not provide DMA support. This bits are here to let the driver 59 + * compile and will never be used. Maybe we get DMA support at a later point in 60 + * time. 61 + */ 62 + 63 + #define DCSR(n) (n) 64 + #define DSADR(n) (n) 65 + #define DTADR(n) (n) 66 + #define DCMD(n) (n) 67 + #define DRCMR(n) (n) 68 + 69 + #define DCSR_RUN (1 << 31) /* Run Bit */ 70 + #define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch */ 71 + #define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable */ 72 + #define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */ 73 + #define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */ 74 + #define DCSR_ENDINTR (1 << 2) /* End Interrupt */ 75 + #define DCSR_STARTINTR (1 << 1) /* Start Interrupt */ 76 + #define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt */ 77 + 78 + #define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable */ 79 + #define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */ 80 + #define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */ 81 + #define DCSR_SETCMPST (1 << 25) /* Set Descriptor Compare Status */ 82 + #define DCSR_CLRCMPST (1 << 24) /* Clear Descriptor Compare Status */ 83 + #define DCSR_CMPST (1 << 10) /* The Descriptor Compare Status */ 84 + #define DCSR_EORINTR (1 << 9) /* The end of Receive */ 85 + 86 + #define DRCMR_MAPVLD (1 << 7) /* Map Valid */ 87 + #define DRCMR_CHLNUM 0x1f /* mask for Channel Number */ 88 + 89 + #define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor */ 90 + #define DDADR_STOP (1 << 0) /* Stop */ 91 + 92 + #define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */ 93 + #define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */ 94 + #define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */ 95 + #define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */ 96 + #define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */ 97 + #define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */ 98 + #define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */ 99 + #define DCMD_BURST8 (1 << 16) /* 8 byte burst */ 100 + #define DCMD_BURST16 (2 << 16) /* 16 byte burst */ 101 + #define DCMD_BURST32 (3 << 16) /* 32 byte burst */ 102 + #define DCMD_WIDTH1 (1 << 14) /* 1 byte width */ 103 + #define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */ 104 + #define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */ 105 + #define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */ 106 + 107 + /* 108 + * Descriptor structure for PXA's DMA engine 109 + * Note: this structure must always be aligned to a 16-byte boundary. 110 + */ 111 + 112 + typedef enum { 113 + DMA_PRIO_HIGH = 0, 114 + DMA_PRIO_MEDIUM = 1, 115 + DMA_PRIO_LOW = 2 116 + } pxa_dma_prio; 117 + 118 + /* 119 + * DMA registration 120 + */ 121 + 122 + static inline int pxa_request_dma(char *name, 123 + pxa_dma_prio prio, 124 + void (*irq_handler)(int, void *), 125 + void *data) 126 + { 127 + return -ENODEV; 128 + } 129 + 130 + static inline void pxa_free_dma(int dma_ch) 131 + { 132 + } 133 + 134 + /* 135 + * The CE4100 does not have the clk framework implemented and SPI clock can 136 + * not be switched on/off or the divider changed. 137 + */ 138 + static inline void clk_disable(struct clk *clk) 139 + { 140 + } 141 + 142 + static inline int clk_enable(struct clk *clk) 143 + { 144 + return 0; 145 + } 146 + 147 + static inline unsigned long clk_get_rate(struct clk *clk) 148 + { 149 + return 3686400; 150 + } 151 + 152 + #endif 48 153 #endif