spi: pxa2xx-pci: Remove unused code
[linux-2.6-block.git] / drivers / spi / spi-pxa2xx-pci.c
CommitLineData
d6ea3df0
SAS
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>
d7614de4 8#include <linux/module.h>
d6ea3df0 9#include <linux/spi/pxa2xx_spi.h>
afa93c90 10#include <linux/clk-provider.h>
d6ea3df0 11
b729bf34
MW
12#include <linux/dmaengine.h>
13#include <linux/platform_data/dma-dw.h>
14
d6ba32d5
CCE
15enum {
16 PORT_CE4100,
17 PORT_BYT,
4f470910 18 PORT_MRFLD,
39d36536
MW
19 PORT_BSW0,
20 PORT_BSW1,
21 PORT_BSW2,
e5262d05 22 PORT_QUARK_X1000,
caba248d 23 PORT_LPT,
d6ba32d5
CCE
24};
25
26struct pxa_spi_info {
27 enum pxa_ssp_type type;
28 int port_id;
29 int num_chipselect;
afa93c90 30 unsigned long max_clk_rate;
b729bf34
MW
31
32 /* DMA channel request parameters */
743485ea 33 bool (*dma_filter)(struct dma_chan *chan, void *param);
b729bf34
MW
34 void *tx_param;
35 void *rx_param;
743485ea
AS
36
37 int (*setup)(struct pci_dev *pdev, struct pxa_spi_info *c);
d6ba32d5
CCE
38};
39
b729bf34
MW
40static struct dw_dma_slave byt_tx_param = { .dst_id = 0 };
41static struct dw_dma_slave byt_rx_param = { .src_id = 1 };
42
39d36536
MW
43static struct dw_dma_slave bsw0_tx_param = { .dst_id = 0 };
44static struct dw_dma_slave bsw0_rx_param = { .src_id = 1 };
45static struct dw_dma_slave bsw1_tx_param = { .dst_id = 6 };
46static struct dw_dma_slave bsw1_rx_param = { .src_id = 7 };
47static struct dw_dma_slave bsw2_tx_param = { .dst_id = 8 };
48static struct dw_dma_slave bsw2_rx_param = { .src_id = 9 };
49
caba248d
LL
50static struct dw_dma_slave lpt_tx_param = { .dst_id = 0 };
51static struct dw_dma_slave lpt_rx_param = { .src_id = 1 };
52
b729bf34
MW
53static bool lpss_dma_filter(struct dma_chan *chan, void *param)
54{
55 struct dw_dma_slave *dws = param;
56
57 if (dws->dma_dev != chan->device->dev)
58 return false;
59
60 chan->private = dws;
61 return true;
62}
63
743485ea
AS
64static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
65{
66 struct pci_dev *dma_dev;
67
68 c->num_chipselect = 1;
69 c->max_clk_rate = 50000000;
70
71 dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
72
73 if (c->tx_param) {
74 struct dw_dma_slave *slave = c->tx_param;
75
76 slave->dma_dev = &dma_dev->dev;
77 slave->m_master = 0;
78 slave->p_master = 1;
79 }
80
81 if (c->rx_param) {
82 struct dw_dma_slave *slave = c->rx_param;
83
84 slave->dma_dev = &dma_dev->dev;
85 slave->m_master = 0;
86 slave->p_master = 1;
87 }
88
89 c->dma_filter = lpss_dma_filter;
90 return 0;
91}
92
4f470910
AS
93static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
94{
95 switch (PCI_FUNC(dev->devfn)) {
96 case 0:
97 c->port_id = 3;
98 c->num_chipselect = 1;
99 break;
100 case 1:
101 c->port_id = 5;
102 c->num_chipselect = 4;
103 break;
104 case 2:
105 c->port_id = 6;
106 c->num_chipselect = 1;
107 break;
108 default:
109 return -ENODEV;
110 }
111 return 0;
112}
113
d6ba32d5
CCE
114static struct pxa_spi_info spi_info_configs[] = {
115 [PORT_CE4100] = {
116 .type = PXA25x_SSP,
117 .port_id = -1,
118 .num_chipselect = -1,
afa93c90 119 .max_clk_rate = 3686400,
d6ba32d5
CCE
120 },
121 [PORT_BYT] = {
03fbf488 122 .type = LPSS_BYT_SSP,
d6ba32d5 123 .port_id = 0,
743485ea 124 .setup = lpss_spi_setup,
b729bf34
MW
125 .tx_param = &byt_tx_param,
126 .rx_param = &byt_rx_param,
d6ba32d5 127 },
39d36536 128 [PORT_BSW0] = {
03fbf488 129 .type = LPSS_BYT_SSP,
39d36536 130 .port_id = 0,
743485ea 131 .setup = lpss_spi_setup,
39d36536
MW
132 .tx_param = &bsw0_tx_param,
133 .rx_param = &bsw0_rx_param,
134 },
135 [PORT_BSW1] = {
03fbf488 136 .type = LPSS_BYT_SSP,
39d36536 137 .port_id = 1,
743485ea 138 .setup = lpss_spi_setup,
39d36536
MW
139 .tx_param = &bsw1_tx_param,
140 .rx_param = &bsw1_rx_param,
141 },
142 [PORT_BSW2] = {
03fbf488 143 .type = LPSS_BYT_SSP,
39d36536 144 .port_id = 2,
743485ea 145 .setup = lpss_spi_setup,
39d36536
MW
146 .tx_param = &bsw2_tx_param,
147 .rx_param = &bsw2_rx_param,
d6ba32d5 148 },
4f470910
AS
149 [PORT_MRFLD] = {
150 .type = PXA27x_SSP,
151 .max_clk_rate = 25000000,
152 .setup = mrfld_spi_setup,
153 },
e5262d05
WC
154 [PORT_QUARK_X1000] = {
155 .type = QUARK_X1000_SSP,
156 .port_id = -1,
157 .num_chipselect = 1,
158 .max_clk_rate = 50000000,
159 },
caba248d
LL
160 [PORT_LPT] = {
161 .type = LPSS_LPT_SSP,
162 .port_id = 0,
743485ea 163 .setup = lpss_spi_setup,
caba248d
LL
164 .tx_param = &lpt_tx_param,
165 .rx_param = &lpt_rx_param,
166 },
d6ba32d5
CCE
167};
168
169static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
d6ea3df0
SAS
170 const struct pci_device_id *ent)
171{
0202775b 172 struct platform_device_info pi;
d6ea3df0 173 int ret;
d6ea3df0 174 struct platform_device *pdev;
0f3e1d27 175 struct pxa2xx_spi_master spi_pdata;
d6ea3df0 176 struct ssp_device *ssp;
d6ba32d5 177 struct pxa_spi_info *c;
afa93c90 178 char buf[40];
d6ea3df0 179
0202775b 180 ret = pcim_enable_device(dev);
d6ea3df0
SAS
181 if (ret)
182 return ret;
183
0202775b 184 ret = pcim_iomap_regions(dev, 1 << 0, "PXA2xx SPI");
c1346340 185 if (ret)
d6ea3df0 186 return ret;
d6ea3df0 187
d6ba32d5 188 c = &spi_info_configs[ent->driver_data];
743485ea
AS
189 if (c->setup) {
190 ret = c->setup(dev, c);
191 if (ret)
192 return ret;
b729bf34
MW
193 }
194
743485ea
AS
195 memset(&spi_pdata, 0, sizeof(spi_pdata));
196 spi_pdata.num_chipselect = (c->num_chipselect > 0) ? c->num_chipselect : dev->devfn;
197 spi_pdata.dma_filter = c->dma_filter;
b729bf34
MW
198 spi_pdata.tx_param = c->tx_param;
199 spi_pdata.rx_param = c->rx_param;
200 spi_pdata.enable_dma = c->rx_param && c->tx_param;
d6ea3df0 201
851bacf5 202 ssp = &spi_pdata.ssp;
d6ea3df0 203 ssp->phys_base = pci_resource_start(dev, 0);
0202775b 204 ssp->mmio_base = pcim_iomap_table(dev)[0];
d6ea3df0 205 ssp->irq = dev->irq;
d6ba32d5
CCE
206 ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn;
207 ssp->type = c->type;
d6ea3df0 208
afa93c90 209 snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id);
280af2b8
SB
210 ssp->clk = clk_register_fixed_rate(&dev->dev, buf , NULL, 0,
211 c->max_clk_rate);
afa93c90
CCE
212 if (IS_ERR(ssp->clk))
213 return PTR_ERR(ssp->clk);
214
0202775b
MW
215 memset(&pi, 0, sizeof(pi));
216 pi.parent = &dev->dev;
217 pi.name = "pxa2xx-spi";
218 pi.id = ssp->port_id;
219 pi.data = &spi_pdata;
220 pi.size_data = sizeof(spi_pdata);
d6ea3df0 221
0202775b 222 pdev = platform_device_register_full(&pi);
afa93c90
CCE
223 if (IS_ERR(pdev)) {
224 clk_unregister(ssp->clk);
d77b5382 225 return PTR_ERR(pdev);
afa93c90 226 }
d6ea3df0 227
851bacf5 228 pci_set_drvdata(dev, pdev);
d6ea3df0 229
0202775b 230 return 0;
d6ea3df0
SAS
231}
232
d6ba32d5 233static void pxa2xx_spi_pci_remove(struct pci_dev *dev)
d6ea3df0 234{
851bacf5 235 struct platform_device *pdev = pci_get_drvdata(dev);
afa93c90
CCE
236 struct pxa2xx_spi_master *spi_pdata;
237
238 spi_pdata = dev_get_platdata(&pdev->dev);
d6ea3df0 239
851bacf5 240 platform_device_unregister(pdev);
afa93c90 241 clk_unregister(spi_pdata->ssp.clk);
d6ea3df0
SAS
242}
243
d6ba32d5
CCE
244static const struct pci_device_id pxa2xx_spi_pci_devices[] = {
245 { PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 },
e5262d05 246 { PCI_VDEVICE(INTEL, 0x0935), PORT_QUARK_X1000 },
d6ba32d5 247 { PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT },
4f470910 248 { PCI_VDEVICE(INTEL, 0x1194), PORT_MRFLD },
39d36536
MW
249 { PCI_VDEVICE(INTEL, 0x228e), PORT_BSW0 },
250 { PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 },
251 { PCI_VDEVICE(INTEL, 0x22ac), PORT_BSW2 },
caba248d 252 { PCI_VDEVICE(INTEL, 0x9ce6), PORT_LPT },
d6ea3df0
SAS
253 { },
254};
d6ba32d5 255MODULE_DEVICE_TABLE(pci, pxa2xx_spi_pci_devices);
d6ea3df0 256
d6ba32d5
CCE
257static struct pci_driver pxa2xx_spi_pci_driver = {
258 .name = "pxa2xx_spi_pci",
259 .id_table = pxa2xx_spi_pci_devices,
260 .probe = pxa2xx_spi_pci_probe,
261 .remove = pxa2xx_spi_pci_remove,
d6ea3df0
SAS
262};
263
d6ba32d5 264module_pci_driver(pxa2xx_spi_pci_driver);
d6ea3df0 265
d6ba32d5 266MODULE_DESCRIPTION("CE4100/LPSS PCI-SPI glue code for PXA's driver");
d6ea3df0
SAS
267MODULE_LICENSE("GPL v2");
268MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>");