xref: /OK3568_Linux_fs/kernel/drivers/fpga/machxo2-spi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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