1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Lattice MachXO2 Slave SPI Driver
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Manage Lattice FPGA firmware that is loaded over SPI using
6*4882a593Smuzhiyun * the slave serial configuration interface.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Copyright (C) 2018 Paolo Pisati <p.pisati@gmail.com>
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/delay.h>
12*4882a593Smuzhiyun #include <linux/fpga/fpga-mgr.h>
13*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun #include <linux/of.h>
16*4882a593Smuzhiyun #include <linux/spi/spi.h>
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun /* MachXO2 Programming Guide - sysCONFIG Programming Commands */
19*4882a593Smuzhiyun #define IDCODE_PUB {0xe0, 0x00, 0x00, 0x00}
20*4882a593Smuzhiyun #define ISC_ENABLE {0xc6, 0x08, 0x00, 0x00}
21*4882a593Smuzhiyun #define ISC_ERASE {0x0e, 0x04, 0x00, 0x00}
22*4882a593Smuzhiyun #define ISC_PROGRAMDONE {0x5e, 0x00, 0x00, 0x00}
23*4882a593Smuzhiyun #define LSC_INITADDRESS {0x46, 0x00, 0x00, 0x00}
24*4882a593Smuzhiyun #define LSC_PROGINCRNV {0x70, 0x00, 0x00, 0x01}
25*4882a593Smuzhiyun #define LSC_READ_STATUS {0x3c, 0x00, 0x00, 0x00}
26*4882a593Smuzhiyun #define LSC_REFRESH {0x79, 0x00, 0x00, 0x00}
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun /*
29*4882a593Smuzhiyun * Max CCLK in Slave SPI mode according to 'MachXO2 Family Data
30*4882a593Smuzhiyun * Sheet' sysCONFIG Port Timing Specifications (3-36)
31*4882a593Smuzhiyun */
32*4882a593Smuzhiyun #define MACHXO2_MAX_SPEED 66000000
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #define MACHXO2_LOW_DELAY_USEC 5
35*4882a593Smuzhiyun #define MACHXO2_HIGH_DELAY_USEC 200
36*4882a593Smuzhiyun #define MACHXO2_REFRESH_USEC 4800
37*4882a593Smuzhiyun #define MACHXO2_MAX_BUSY_LOOP 128
38*4882a593Smuzhiyun #define MACHXO2_MAX_REFRESH_LOOP 16
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #define MACHXO2_PAGE_SIZE 16
41*4882a593Smuzhiyun #define MACHXO2_BUF_SIZE (MACHXO2_PAGE_SIZE + 4)
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun /* Status register bits, errors and error mask */
44*4882a593Smuzhiyun #define BUSY 12
45*4882a593Smuzhiyun #define DONE 8
46*4882a593Smuzhiyun #define DVER 27
47*4882a593Smuzhiyun #define ENAB 9
48*4882a593Smuzhiyun #define ERRBITS 23
49*4882a593Smuzhiyun #define ERRMASK 7
50*4882a593Smuzhiyun #define FAIL 13
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun #define ENOERR 0 /* no error */
53*4882a593Smuzhiyun #define EID 1
54*4882a593Smuzhiyun #define ECMD 2
55*4882a593Smuzhiyun #define ECRC 3
56*4882a593Smuzhiyun #define EPREAM 4 /* preamble error */
57*4882a593Smuzhiyun #define EABRT 5 /* abort error */
58*4882a593Smuzhiyun #define EOVERFL 6 /* overflow error */
59*4882a593Smuzhiyun #define ESDMEOF 7 /* SDM EOF */
60*4882a593Smuzhiyun
get_err(unsigned long * status)61*4882a593Smuzhiyun static inline u8 get_err(unsigned long *status)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun return (*status >> ERRBITS) & ERRMASK;
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun
get_status(struct spi_device * spi,unsigned long * status)66*4882a593Smuzhiyun static int get_status(struct spi_device *spi, unsigned long *status)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun struct spi_message msg;
69*4882a593Smuzhiyun struct spi_transfer rx, tx;
70*4882a593Smuzhiyun static const u8 cmd[] = LSC_READ_STATUS;
71*4882a593Smuzhiyun int ret;
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun memset(&rx, 0, sizeof(rx));
74*4882a593Smuzhiyun memset(&tx, 0, sizeof(tx));
75*4882a593Smuzhiyun tx.tx_buf = cmd;
76*4882a593Smuzhiyun tx.len = sizeof(cmd);
77*4882a593Smuzhiyun rx.rx_buf = status;
78*4882a593Smuzhiyun rx.len = 4;
79*4882a593Smuzhiyun spi_message_init(&msg);
80*4882a593Smuzhiyun spi_message_add_tail(&tx, &msg);
81*4882a593Smuzhiyun spi_message_add_tail(&rx, &msg);
82*4882a593Smuzhiyun ret = spi_sync(spi, &msg);
83*4882a593Smuzhiyun if (ret)
84*4882a593Smuzhiyun return ret;
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun *status = be32_to_cpu(*status);
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun return 0;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun #ifdef DEBUG
get_err_string(u8 err)92*4882a593Smuzhiyun static const char *get_err_string(u8 err)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun switch (err) {
95*4882a593Smuzhiyun case ENOERR: return "No Error";
96*4882a593Smuzhiyun case EID: return "ID ERR";
97*4882a593Smuzhiyun case ECMD: return "CMD ERR";
98*4882a593Smuzhiyun case ECRC: return "CRC ERR";
99*4882a593Smuzhiyun case EPREAM: return "Preamble ERR";
100*4882a593Smuzhiyun case EABRT: return "Abort ERR";
101*4882a593Smuzhiyun case EOVERFL: return "Overflow ERR";
102*4882a593Smuzhiyun case ESDMEOF: return "SDM EOF";
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun return "Default switch case";
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun #endif
108*4882a593Smuzhiyun
dump_status_reg(unsigned long * status)109*4882a593Smuzhiyun static void dump_status_reg(unsigned long *status)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun #ifdef DEBUG
112*4882a593Smuzhiyun pr_debug("machxo2 status: 0x%08lX - done=%d, cfgena=%d, busy=%d, fail=%d, devver=%d, err=%s\n",
113*4882a593Smuzhiyun *status, test_bit(DONE, status), test_bit(ENAB, status),
114*4882a593Smuzhiyun test_bit(BUSY, status), test_bit(FAIL, status),
115*4882a593Smuzhiyun test_bit(DVER, status), get_err_string(get_err(status)));
116*4882a593Smuzhiyun #endif
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun
wait_until_not_busy(struct spi_device * spi)119*4882a593Smuzhiyun static int wait_until_not_busy(struct spi_device *spi)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun unsigned long status;
122*4882a593Smuzhiyun int ret, loop = 0;
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun do {
125*4882a593Smuzhiyun ret = get_status(spi, &status);
126*4882a593Smuzhiyun if (ret)
127*4882a593Smuzhiyun return ret;
128*4882a593Smuzhiyun if (++loop >= MACHXO2_MAX_BUSY_LOOP)
129*4882a593Smuzhiyun return -EBUSY;
130*4882a593Smuzhiyun } while (test_bit(BUSY, &status));
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun return 0;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun
machxo2_cleanup(struct fpga_manager * mgr)135*4882a593Smuzhiyun static int machxo2_cleanup(struct fpga_manager *mgr)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun struct spi_device *spi = mgr->priv;
138*4882a593Smuzhiyun struct spi_message msg;
139*4882a593Smuzhiyun struct spi_transfer tx[2];
140*4882a593Smuzhiyun static const u8 erase[] = ISC_ERASE;
141*4882a593Smuzhiyun static const u8 refresh[] = LSC_REFRESH;
142*4882a593Smuzhiyun int ret;
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun memset(tx, 0, sizeof(tx));
145*4882a593Smuzhiyun spi_message_init(&msg);
146*4882a593Smuzhiyun tx[0].tx_buf = &erase;
147*4882a593Smuzhiyun tx[0].len = sizeof(erase);
148*4882a593Smuzhiyun spi_message_add_tail(&tx[0], &msg);
149*4882a593Smuzhiyun ret = spi_sync(spi, &msg);
150*4882a593Smuzhiyun if (ret)
151*4882a593Smuzhiyun goto fail;
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun ret = wait_until_not_busy(spi);
154*4882a593Smuzhiyun if (ret)
155*4882a593Smuzhiyun goto fail;
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun spi_message_init(&msg);
158*4882a593Smuzhiyun tx[1].tx_buf = &refresh;
159*4882a593Smuzhiyun tx[1].len = sizeof(refresh);
160*4882a593Smuzhiyun tx[1].delay.value = MACHXO2_REFRESH_USEC;
161*4882a593Smuzhiyun tx[1].delay.unit = SPI_DELAY_UNIT_USECS;
162*4882a593Smuzhiyun spi_message_add_tail(&tx[1], &msg);
163*4882a593Smuzhiyun ret = spi_sync(spi, &msg);
164*4882a593Smuzhiyun if (ret)
165*4882a593Smuzhiyun goto fail;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun return 0;
168*4882a593Smuzhiyun fail:
169*4882a593Smuzhiyun dev_err(&mgr->dev, "Cleanup failed\n");
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun return ret;
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun
machxo2_spi_state(struct fpga_manager * mgr)174*4882a593Smuzhiyun static enum fpga_mgr_states machxo2_spi_state(struct fpga_manager *mgr)
175*4882a593Smuzhiyun {
176*4882a593Smuzhiyun struct spi_device *spi = mgr->priv;
177*4882a593Smuzhiyun unsigned long status;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun get_status(spi, &status);
180*4882a593Smuzhiyun if (!test_bit(BUSY, &status) && test_bit(DONE, &status) &&
181*4882a593Smuzhiyun get_err(&status) == ENOERR)
182*4882a593Smuzhiyun return FPGA_MGR_STATE_OPERATING;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun return FPGA_MGR_STATE_UNKNOWN;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
machxo2_write_init(struct fpga_manager * mgr,struct fpga_image_info * info,const char * buf,size_t count)187*4882a593Smuzhiyun static int machxo2_write_init(struct fpga_manager *mgr,
188*4882a593Smuzhiyun struct fpga_image_info *info,
189*4882a593Smuzhiyun const char *buf, size_t count)
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun struct spi_device *spi = mgr->priv;
192*4882a593Smuzhiyun struct spi_message msg;
193*4882a593Smuzhiyun struct spi_transfer tx[3];
194*4882a593Smuzhiyun static const u8 enable[] = ISC_ENABLE;
195*4882a593Smuzhiyun static const u8 erase[] = ISC_ERASE;
196*4882a593Smuzhiyun static const u8 initaddr[] = LSC_INITADDRESS;
197*4882a593Smuzhiyun unsigned long status;
198*4882a593Smuzhiyun int ret;
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun if ((info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
201*4882a593Smuzhiyun dev_err(&mgr->dev,
202*4882a593Smuzhiyun "Partial reconfiguration is not supported\n");
203*4882a593Smuzhiyun return -ENOTSUPP;
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun get_status(spi, &status);
207*4882a593Smuzhiyun dump_status_reg(&status);
208*4882a593Smuzhiyun memset(tx, 0, sizeof(tx));
209*4882a593Smuzhiyun spi_message_init(&msg);
210*4882a593Smuzhiyun tx[0].tx_buf = &enable;
211*4882a593Smuzhiyun tx[0].len = sizeof(enable);
212*4882a593Smuzhiyun tx[0].delay.value = MACHXO2_LOW_DELAY_USEC;
213*4882a593Smuzhiyun tx[0].delay.unit = SPI_DELAY_UNIT_USECS;
214*4882a593Smuzhiyun spi_message_add_tail(&tx[0], &msg);
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun tx[1].tx_buf = &erase;
217*4882a593Smuzhiyun tx[1].len = sizeof(erase);
218*4882a593Smuzhiyun spi_message_add_tail(&tx[1], &msg);
219*4882a593Smuzhiyun ret = spi_sync(spi, &msg);
220*4882a593Smuzhiyun if (ret)
221*4882a593Smuzhiyun goto fail;
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun ret = wait_until_not_busy(spi);
224*4882a593Smuzhiyun if (ret)
225*4882a593Smuzhiyun goto fail;
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun get_status(spi, &status);
228*4882a593Smuzhiyun if (test_bit(FAIL, &status)) {
229*4882a593Smuzhiyun ret = -EINVAL;
230*4882a593Smuzhiyun goto fail;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun dump_status_reg(&status);
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun spi_message_init(&msg);
235*4882a593Smuzhiyun tx[2].tx_buf = &initaddr;
236*4882a593Smuzhiyun tx[2].len = sizeof(initaddr);
237*4882a593Smuzhiyun spi_message_add_tail(&tx[2], &msg);
238*4882a593Smuzhiyun ret = spi_sync(spi, &msg);
239*4882a593Smuzhiyun if (ret)
240*4882a593Smuzhiyun goto fail;
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun get_status(spi, &status);
243*4882a593Smuzhiyun dump_status_reg(&status);
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun return 0;
246*4882a593Smuzhiyun fail:
247*4882a593Smuzhiyun dev_err(&mgr->dev, "Error during FPGA init.\n");
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun return ret;
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun
machxo2_write(struct fpga_manager * mgr,const char * buf,size_t count)252*4882a593Smuzhiyun static int machxo2_write(struct fpga_manager *mgr, const char *buf,
253*4882a593Smuzhiyun size_t count)
254*4882a593Smuzhiyun {
255*4882a593Smuzhiyun struct spi_device *spi = mgr->priv;
256*4882a593Smuzhiyun struct spi_message msg;
257*4882a593Smuzhiyun struct spi_transfer tx;
258*4882a593Smuzhiyun static const u8 progincr[] = LSC_PROGINCRNV;
259*4882a593Smuzhiyun u8 payload[MACHXO2_BUF_SIZE];
260*4882a593Smuzhiyun unsigned long status;
261*4882a593Smuzhiyun int i, ret;
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun if (count % MACHXO2_PAGE_SIZE != 0) {
264*4882a593Smuzhiyun dev_err(&mgr->dev, "Malformed payload.\n");
265*4882a593Smuzhiyun return -EINVAL;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun get_status(spi, &status);
268*4882a593Smuzhiyun dump_status_reg(&status);
269*4882a593Smuzhiyun memcpy(payload, &progincr, sizeof(progincr));
270*4882a593Smuzhiyun for (i = 0; i < count; i += MACHXO2_PAGE_SIZE) {
271*4882a593Smuzhiyun memcpy(&payload[sizeof(progincr)], &buf[i], MACHXO2_PAGE_SIZE);
272*4882a593Smuzhiyun memset(&tx, 0, sizeof(tx));
273*4882a593Smuzhiyun spi_message_init(&msg);
274*4882a593Smuzhiyun tx.tx_buf = payload;
275*4882a593Smuzhiyun tx.len = MACHXO2_BUF_SIZE;
276*4882a593Smuzhiyun tx.delay.value = MACHXO2_HIGH_DELAY_USEC;
277*4882a593Smuzhiyun tx.delay.unit = SPI_DELAY_UNIT_USECS;
278*4882a593Smuzhiyun spi_message_add_tail(&tx, &msg);
279*4882a593Smuzhiyun ret = spi_sync(spi, &msg);
280*4882a593Smuzhiyun if (ret) {
281*4882a593Smuzhiyun dev_err(&mgr->dev, "Error loading the bitstream.\n");
282*4882a593Smuzhiyun return ret;
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun get_status(spi, &status);
286*4882a593Smuzhiyun dump_status_reg(&status);
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun return 0;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
machxo2_write_complete(struct fpga_manager * mgr,struct fpga_image_info * info)291*4882a593Smuzhiyun static int machxo2_write_complete(struct fpga_manager *mgr,
292*4882a593Smuzhiyun struct fpga_image_info *info)
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun struct spi_device *spi = mgr->priv;
295*4882a593Smuzhiyun struct spi_message msg;
296*4882a593Smuzhiyun struct spi_transfer tx[2];
297*4882a593Smuzhiyun static const u8 progdone[] = ISC_PROGRAMDONE;
298*4882a593Smuzhiyun static const u8 refresh[] = LSC_REFRESH;
299*4882a593Smuzhiyun unsigned long status;
300*4882a593Smuzhiyun int ret, refreshloop = 0;
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun memset(tx, 0, sizeof(tx));
303*4882a593Smuzhiyun spi_message_init(&msg);
304*4882a593Smuzhiyun tx[0].tx_buf = &progdone;
305*4882a593Smuzhiyun tx[0].len = sizeof(progdone);
306*4882a593Smuzhiyun spi_message_add_tail(&tx[0], &msg);
307*4882a593Smuzhiyun ret = spi_sync(spi, &msg);
308*4882a593Smuzhiyun if (ret)
309*4882a593Smuzhiyun goto fail;
310*4882a593Smuzhiyun ret = wait_until_not_busy(spi);
311*4882a593Smuzhiyun if (ret)
312*4882a593Smuzhiyun goto fail;
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun get_status(spi, &status);
315*4882a593Smuzhiyun dump_status_reg(&status);
316*4882a593Smuzhiyun if (!test_bit(DONE, &status)) {
317*4882a593Smuzhiyun machxo2_cleanup(mgr);
318*4882a593Smuzhiyun ret = -EINVAL;
319*4882a593Smuzhiyun goto fail;
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun do {
323*4882a593Smuzhiyun spi_message_init(&msg);
324*4882a593Smuzhiyun tx[1].tx_buf = &refresh;
325*4882a593Smuzhiyun tx[1].len = sizeof(refresh);
326*4882a593Smuzhiyun tx[1].delay.value = MACHXO2_REFRESH_USEC;
327*4882a593Smuzhiyun tx[1].delay.unit = SPI_DELAY_UNIT_USECS;
328*4882a593Smuzhiyun spi_message_add_tail(&tx[1], &msg);
329*4882a593Smuzhiyun ret = spi_sync(spi, &msg);
330*4882a593Smuzhiyun if (ret)
331*4882a593Smuzhiyun goto fail;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun /* check refresh status */
334*4882a593Smuzhiyun get_status(spi, &status);
335*4882a593Smuzhiyun dump_status_reg(&status);
336*4882a593Smuzhiyun if (!test_bit(BUSY, &status) && test_bit(DONE, &status) &&
337*4882a593Smuzhiyun get_err(&status) == ENOERR)
338*4882a593Smuzhiyun break;
339*4882a593Smuzhiyun if (++refreshloop == MACHXO2_MAX_REFRESH_LOOP) {
340*4882a593Smuzhiyun machxo2_cleanup(mgr);
341*4882a593Smuzhiyun ret = -EINVAL;
342*4882a593Smuzhiyun goto fail;
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun } while (1);
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun get_status(spi, &status);
347*4882a593Smuzhiyun dump_status_reg(&status);
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun return 0;
350*4882a593Smuzhiyun fail:
351*4882a593Smuzhiyun dev_err(&mgr->dev, "Refresh failed.\n");
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun return ret;
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun static const struct fpga_manager_ops machxo2_ops = {
357*4882a593Smuzhiyun .state = machxo2_spi_state,
358*4882a593Smuzhiyun .write_init = machxo2_write_init,
359*4882a593Smuzhiyun .write = machxo2_write,
360*4882a593Smuzhiyun .write_complete = machxo2_write_complete,
361*4882a593Smuzhiyun };
362*4882a593Smuzhiyun
machxo2_spi_probe(struct spi_device * spi)363*4882a593Smuzhiyun static int machxo2_spi_probe(struct spi_device *spi)
364*4882a593Smuzhiyun {
365*4882a593Smuzhiyun struct device *dev = &spi->dev;
366*4882a593Smuzhiyun struct fpga_manager *mgr;
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun if (spi->max_speed_hz > MACHXO2_MAX_SPEED) {
369*4882a593Smuzhiyun dev_err(dev, "Speed is too high\n");
370*4882a593Smuzhiyun return -EINVAL;
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun mgr = devm_fpga_mgr_create(dev, "Lattice MachXO2 SPI FPGA Manager",
374*4882a593Smuzhiyun &machxo2_ops, spi);
375*4882a593Smuzhiyun if (!mgr)
376*4882a593Smuzhiyun return -ENOMEM;
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun spi_set_drvdata(spi, mgr);
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun return fpga_mgr_register(mgr);
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun
machxo2_spi_remove(struct spi_device * spi)383*4882a593Smuzhiyun static int machxo2_spi_remove(struct spi_device *spi)
384*4882a593Smuzhiyun {
385*4882a593Smuzhiyun struct fpga_manager *mgr = spi_get_drvdata(spi);
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun fpga_mgr_unregister(mgr);
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun return 0;
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun static const struct of_device_id of_match[] = {
393*4882a593Smuzhiyun { .compatible = "lattice,machxo2-slave-spi", },
394*4882a593Smuzhiyun {}
395*4882a593Smuzhiyun };
396*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, of_match);
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun static const struct spi_device_id lattice_ids[] = {
399*4882a593Smuzhiyun { "machxo2-slave-spi", 0 },
400*4882a593Smuzhiyun { },
401*4882a593Smuzhiyun };
402*4882a593Smuzhiyun MODULE_DEVICE_TABLE(spi, lattice_ids);
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun static struct spi_driver machxo2_spi_driver = {
405*4882a593Smuzhiyun .driver = {
406*4882a593Smuzhiyun .name = "machxo2-slave-spi",
407*4882a593Smuzhiyun .of_match_table = of_match_ptr(of_match),
408*4882a593Smuzhiyun },
409*4882a593Smuzhiyun .probe = machxo2_spi_probe,
410*4882a593Smuzhiyun .remove = machxo2_spi_remove,
411*4882a593Smuzhiyun .id_table = lattice_ids,
412*4882a593Smuzhiyun };
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun module_spi_driver(machxo2_spi_driver)
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun MODULE_AUTHOR("Paolo Pisati <p.pisati@gmail.com>");
417*4882a593Smuzhiyun MODULE_DESCRIPTION("Load Lattice FPGA firmware over SPI");
418*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
419