188fb3a00SPaolo Pisati // SPDX-License-Identifier: GPL-2.0 288fb3a00SPaolo Pisati /* 388fb3a00SPaolo Pisati * Lattice MachXO2 Slave SPI Driver 488fb3a00SPaolo Pisati * 588fb3a00SPaolo Pisati * Manage Lattice FPGA firmware that is loaded over SPI using 688fb3a00SPaolo Pisati * the slave serial configuration interface. 788fb3a00SPaolo Pisati * 888fb3a00SPaolo Pisati * Copyright (C) 2018 Paolo Pisati <p.pisati@gmail.com> 988fb3a00SPaolo Pisati */ 1088fb3a00SPaolo Pisati 1188fb3a00SPaolo Pisati #include <linux/delay.h> 1288fb3a00SPaolo Pisati #include <linux/fpga/fpga-mgr.h> 1388fb3a00SPaolo Pisati #include <linux/gpio/consumer.h> 1488fb3a00SPaolo Pisati #include <linux/module.h> 1588fb3a00SPaolo Pisati #include <linux/of.h> 1688fb3a00SPaolo Pisati #include <linux/spi/spi.h> 1788fb3a00SPaolo Pisati 1888fb3a00SPaolo Pisati /* MachXO2 Programming Guide - sysCONFIG Programming Commands */ 1988fb3a00SPaolo Pisati #define IDCODE_PUB {0xe0, 0x00, 0x00, 0x00} 2088fb3a00SPaolo Pisati #define ISC_ENABLE {0xc6, 0x08, 0x00, 0x00} 2188fb3a00SPaolo Pisati #define ISC_ERASE {0x0e, 0x04, 0x00, 0x00} 2288fb3a00SPaolo Pisati #define ISC_PROGRAMDONE {0x5e, 0x00, 0x00, 0x00} 2388fb3a00SPaolo Pisati #define LSC_INITADDRESS {0x46, 0x00, 0x00, 0x00} 2488fb3a00SPaolo Pisati #define LSC_PROGINCRNV {0x70, 0x00, 0x00, 0x01} 2588fb3a00SPaolo Pisati #define LSC_READ_STATUS {0x3c, 0x00, 0x00, 0x00} 2688fb3a00SPaolo Pisati #define LSC_REFRESH {0x79, 0x00, 0x00, 0x00} 2788fb3a00SPaolo Pisati 2888fb3a00SPaolo Pisati /* 2988fb3a00SPaolo Pisati * Max CCLK in Slave SPI mode according to 'MachXO2 Family Data 3088fb3a00SPaolo Pisati * Sheet' sysCONFIG Port Timing Specifications (3-36) 3188fb3a00SPaolo Pisati */ 3288fb3a00SPaolo Pisati #define MACHXO2_MAX_SPEED 66000000 3388fb3a00SPaolo Pisati 3488fb3a00SPaolo Pisati #define MACHXO2_LOW_DELAY_USEC 5 3588fb3a00SPaolo Pisati #define MACHXO2_HIGH_DELAY_USEC 200 3688fb3a00SPaolo Pisati #define MACHXO2_REFRESH_USEC 4800 3788fb3a00SPaolo Pisati #define MACHXO2_MAX_BUSY_LOOP 128 3888fb3a00SPaolo Pisati #define MACHXO2_MAX_REFRESH_LOOP 16 3988fb3a00SPaolo Pisati 4088fb3a00SPaolo Pisati #define MACHXO2_PAGE_SIZE 16 4188fb3a00SPaolo Pisati #define MACHXO2_BUF_SIZE (MACHXO2_PAGE_SIZE + 4) 4288fb3a00SPaolo Pisati 4388fb3a00SPaolo Pisati /* Status register bits, errors and error mask */ 4488fb3a00SPaolo Pisati #define BUSY 12 4588fb3a00SPaolo Pisati #define DONE 8 4688fb3a00SPaolo Pisati #define DVER 27 4788fb3a00SPaolo Pisati #define ENAB 9 4888fb3a00SPaolo Pisati #define ERRBITS 23 4988fb3a00SPaolo Pisati #define ERRMASK 7 5088fb3a00SPaolo Pisati #define FAIL 13 5188fb3a00SPaolo Pisati 5288fb3a00SPaolo Pisati #define ENOERR 0 /* no error */ 5388fb3a00SPaolo Pisati #define EID 1 5488fb3a00SPaolo Pisati #define ECMD 2 5588fb3a00SPaolo Pisati #define ECRC 3 5688fb3a00SPaolo Pisati #define EPREAM 4 /* preamble error */ 5788fb3a00SPaolo Pisati #define EABRT 5 /* abort error */ 5888fb3a00SPaolo Pisati #define EOVERFL 6 /* overflow error */ 5988fb3a00SPaolo Pisati #define ESDMEOF 7 /* SDM EOF */ 6088fb3a00SPaolo Pisati 6188fb3a00SPaolo Pisati static inline u8 get_err(unsigned long *status) 6288fb3a00SPaolo Pisati { 6388fb3a00SPaolo Pisati return (*status >> ERRBITS) & ERRMASK; 6488fb3a00SPaolo Pisati } 6588fb3a00SPaolo Pisati 6688fb3a00SPaolo Pisati static int get_status(struct spi_device *spi, unsigned long *status) 6788fb3a00SPaolo Pisati { 6888fb3a00SPaolo Pisati struct spi_message msg; 6988fb3a00SPaolo Pisati struct spi_transfer rx, tx; 7088fb3a00SPaolo Pisati static const u8 cmd[] = LSC_READ_STATUS; 7188fb3a00SPaolo Pisati int ret; 7288fb3a00SPaolo Pisati 7388fb3a00SPaolo Pisati memset(&rx, 0, sizeof(rx)); 7488fb3a00SPaolo Pisati memset(&tx, 0, sizeof(tx)); 7588fb3a00SPaolo Pisati tx.tx_buf = cmd; 7688fb3a00SPaolo Pisati tx.len = sizeof(cmd); 7788fb3a00SPaolo Pisati rx.rx_buf = status; 7888fb3a00SPaolo Pisati rx.len = 4; 7988fb3a00SPaolo Pisati spi_message_init(&msg); 8088fb3a00SPaolo Pisati spi_message_add_tail(&tx, &msg); 8188fb3a00SPaolo Pisati spi_message_add_tail(&rx, &msg); 8288fb3a00SPaolo Pisati ret = spi_sync(spi, &msg); 8388fb3a00SPaolo Pisati if (ret) 8488fb3a00SPaolo Pisati return ret; 8588fb3a00SPaolo Pisati 8688fb3a00SPaolo Pisati *status = be32_to_cpu(*status); 8788fb3a00SPaolo Pisati 8888fb3a00SPaolo Pisati return 0; 8988fb3a00SPaolo Pisati } 9088fb3a00SPaolo Pisati 9188fb3a00SPaolo Pisati #ifdef DEBUG 9288fb3a00SPaolo Pisati static const char *get_err_string(u8 err) 9388fb3a00SPaolo Pisati { 9488fb3a00SPaolo Pisati switch (err) { 9588fb3a00SPaolo Pisati case ENOERR: return "No Error"; 9688fb3a00SPaolo Pisati case EID: return "ID ERR"; 9788fb3a00SPaolo Pisati case ECMD: return "CMD ERR"; 9888fb3a00SPaolo Pisati case ECRC: return "CRC ERR"; 9988fb3a00SPaolo Pisati case EPREAM: return "Preamble ERR"; 10088fb3a00SPaolo Pisati case EABRT: return "Abort ERR"; 10188fb3a00SPaolo Pisati case EOVERFL: return "Overflow ERR"; 10288fb3a00SPaolo Pisati case ESDMEOF: return "SDM EOF"; 10388fb3a00SPaolo Pisati } 10488fb3a00SPaolo Pisati 10588fb3a00SPaolo Pisati return "Default switch case"; 10688fb3a00SPaolo Pisati } 10788fb3a00SPaolo Pisati #endif 10888fb3a00SPaolo Pisati 10988fb3a00SPaolo Pisati static void dump_status_reg(unsigned long *status) 11088fb3a00SPaolo Pisati { 11188fb3a00SPaolo Pisati #ifdef DEBUG 11288fb3a00SPaolo Pisati pr_debug("machxo2 status: 0x%08lX - done=%d, cfgena=%d, busy=%d, fail=%d, devver=%d, err=%s\n", 11388fb3a00SPaolo Pisati *status, test_bit(DONE, status), test_bit(ENAB, status), 11488fb3a00SPaolo Pisati test_bit(BUSY, status), test_bit(FAIL, status), 11588fb3a00SPaolo Pisati test_bit(DVER, status), get_err_string(get_err(status))); 11688fb3a00SPaolo Pisati #endif 11788fb3a00SPaolo Pisati } 11888fb3a00SPaolo Pisati 11988fb3a00SPaolo Pisati static int wait_until_not_busy(struct spi_device *spi) 12088fb3a00SPaolo Pisati { 12188fb3a00SPaolo Pisati unsigned long status; 12288fb3a00SPaolo Pisati int ret, loop = 0; 12388fb3a00SPaolo Pisati 12488fb3a00SPaolo Pisati do { 12588fb3a00SPaolo Pisati ret = get_status(spi, &status); 12688fb3a00SPaolo Pisati if (ret) 12788fb3a00SPaolo Pisati return ret; 12888fb3a00SPaolo Pisati if (++loop >= MACHXO2_MAX_BUSY_LOOP) 12988fb3a00SPaolo Pisati return -EBUSY; 13088fb3a00SPaolo Pisati } while (test_bit(BUSY, &status)); 13188fb3a00SPaolo Pisati 13288fb3a00SPaolo Pisati return 0; 13388fb3a00SPaolo Pisati } 13488fb3a00SPaolo Pisati 13588fb3a00SPaolo Pisati static int machxo2_cleanup(struct fpga_manager *mgr) 13688fb3a00SPaolo Pisati { 13788fb3a00SPaolo Pisati struct spi_device *spi = mgr->priv; 13888fb3a00SPaolo Pisati struct spi_message msg; 13988fb3a00SPaolo Pisati struct spi_transfer tx[2]; 14088fb3a00SPaolo Pisati static const u8 erase[] = ISC_ERASE; 14188fb3a00SPaolo Pisati static const u8 refresh[] = LSC_REFRESH; 14288fb3a00SPaolo Pisati int ret; 14388fb3a00SPaolo Pisati 14488fb3a00SPaolo Pisati memset(tx, 0, sizeof(tx)); 14588fb3a00SPaolo Pisati spi_message_init(&msg); 14688fb3a00SPaolo Pisati tx[0].tx_buf = &erase; 14788fb3a00SPaolo Pisati tx[0].len = sizeof(erase); 14888fb3a00SPaolo Pisati spi_message_add_tail(&tx[0], &msg); 14988fb3a00SPaolo Pisati ret = spi_sync(spi, &msg); 15088fb3a00SPaolo Pisati if (ret) 15188fb3a00SPaolo Pisati goto fail; 15288fb3a00SPaolo Pisati 15388fb3a00SPaolo Pisati ret = wait_until_not_busy(spi); 15488fb3a00SPaolo Pisati if (ret) 15588fb3a00SPaolo Pisati goto fail; 15688fb3a00SPaolo Pisati 15788fb3a00SPaolo Pisati spi_message_init(&msg); 15888fb3a00SPaolo Pisati tx[1].tx_buf = &refresh; 15988fb3a00SPaolo Pisati tx[1].len = sizeof(refresh); 160a1d1f5d4SSergiu Cuciurean tx[1].delay.value = MACHXO2_REFRESH_USEC; 161a1d1f5d4SSergiu Cuciurean tx[1].delay.unit = SPI_DELAY_UNIT_USECS; 16288fb3a00SPaolo Pisati spi_message_add_tail(&tx[1], &msg); 16388fb3a00SPaolo Pisati ret = spi_sync(spi, &msg); 16488fb3a00SPaolo Pisati if (ret) 16588fb3a00SPaolo Pisati goto fail; 16688fb3a00SPaolo Pisati 16788fb3a00SPaolo Pisati return 0; 16888fb3a00SPaolo Pisati fail: 16988fb3a00SPaolo Pisati dev_err(&mgr->dev, "Cleanup failed\n"); 17088fb3a00SPaolo Pisati 17188fb3a00SPaolo Pisati return ret; 17288fb3a00SPaolo Pisati } 17388fb3a00SPaolo Pisati 17488fb3a00SPaolo Pisati static enum fpga_mgr_states machxo2_spi_state(struct fpga_manager *mgr) 17588fb3a00SPaolo Pisati { 17688fb3a00SPaolo Pisati struct spi_device *spi = mgr->priv; 17788fb3a00SPaolo Pisati unsigned long status; 17888fb3a00SPaolo Pisati 17988fb3a00SPaolo Pisati get_status(spi, &status); 18088fb3a00SPaolo Pisati if (!test_bit(BUSY, &status) && test_bit(DONE, &status) && 18188fb3a00SPaolo Pisati get_err(&status) == ENOERR) 18288fb3a00SPaolo Pisati return FPGA_MGR_STATE_OPERATING; 18388fb3a00SPaolo Pisati 18488fb3a00SPaolo Pisati return FPGA_MGR_STATE_UNKNOWN; 18588fb3a00SPaolo Pisati } 18688fb3a00SPaolo Pisati 18788fb3a00SPaolo Pisati static int machxo2_write_init(struct fpga_manager *mgr, 18888fb3a00SPaolo Pisati struct fpga_image_info *info, 18988fb3a00SPaolo Pisati const char *buf, size_t count) 19088fb3a00SPaolo Pisati { 19188fb3a00SPaolo Pisati struct spi_device *spi = mgr->priv; 19288fb3a00SPaolo Pisati struct spi_message msg; 19388fb3a00SPaolo Pisati struct spi_transfer tx[3]; 19488fb3a00SPaolo Pisati static const u8 enable[] = ISC_ENABLE; 19588fb3a00SPaolo Pisati static const u8 erase[] = ISC_ERASE; 19688fb3a00SPaolo Pisati static const u8 initaddr[] = LSC_INITADDRESS; 19788fb3a00SPaolo Pisati unsigned long status; 19888fb3a00SPaolo Pisati int ret; 19988fb3a00SPaolo Pisati 20088fb3a00SPaolo Pisati if ((info->flags & FPGA_MGR_PARTIAL_RECONFIG)) { 20188fb3a00SPaolo Pisati dev_err(&mgr->dev, 20288fb3a00SPaolo Pisati "Partial reconfiguration is not supported\n"); 20388fb3a00SPaolo Pisati return -ENOTSUPP; 20488fb3a00SPaolo Pisati } 20588fb3a00SPaolo Pisati 20688fb3a00SPaolo Pisati get_status(spi, &status); 20788fb3a00SPaolo Pisati dump_status_reg(&status); 20888fb3a00SPaolo Pisati memset(tx, 0, sizeof(tx)); 20988fb3a00SPaolo Pisati spi_message_init(&msg); 21088fb3a00SPaolo Pisati tx[0].tx_buf = &enable; 21188fb3a00SPaolo Pisati tx[0].len = sizeof(enable); 212a1d1f5d4SSergiu Cuciurean tx[0].delay.value = MACHXO2_LOW_DELAY_USEC; 213a1d1f5d4SSergiu Cuciurean tx[0].delay.unit = SPI_DELAY_UNIT_USECS; 21488fb3a00SPaolo Pisati spi_message_add_tail(&tx[0], &msg); 21588fb3a00SPaolo Pisati 21688fb3a00SPaolo Pisati tx[1].tx_buf = &erase; 21788fb3a00SPaolo Pisati tx[1].len = sizeof(erase); 21888fb3a00SPaolo Pisati spi_message_add_tail(&tx[1], &msg); 21988fb3a00SPaolo Pisati ret = spi_sync(spi, &msg); 22088fb3a00SPaolo Pisati if (ret) 22188fb3a00SPaolo Pisati goto fail; 22288fb3a00SPaolo Pisati 22388fb3a00SPaolo Pisati ret = wait_until_not_busy(spi); 22488fb3a00SPaolo Pisati if (ret) 22588fb3a00SPaolo Pisati goto fail; 22688fb3a00SPaolo Pisati 22788fb3a00SPaolo Pisati get_status(spi, &status); 22888fb3a00SPaolo Pisati if (test_bit(FAIL, &status)) 22988fb3a00SPaolo Pisati goto fail; 23088fb3a00SPaolo Pisati dump_status_reg(&status); 23188fb3a00SPaolo Pisati 23288fb3a00SPaolo Pisati spi_message_init(&msg); 23388fb3a00SPaolo Pisati tx[2].tx_buf = &initaddr; 23488fb3a00SPaolo Pisati tx[2].len = sizeof(initaddr); 23588fb3a00SPaolo Pisati spi_message_add_tail(&tx[2], &msg); 23688fb3a00SPaolo Pisati ret = spi_sync(spi, &msg); 23788fb3a00SPaolo Pisati if (ret) 23888fb3a00SPaolo Pisati goto fail; 23988fb3a00SPaolo Pisati 24088fb3a00SPaolo Pisati get_status(spi, &status); 24188fb3a00SPaolo Pisati dump_status_reg(&status); 24288fb3a00SPaolo Pisati 24388fb3a00SPaolo Pisati return 0; 24488fb3a00SPaolo Pisati fail: 24588fb3a00SPaolo Pisati dev_err(&mgr->dev, "Error during FPGA init.\n"); 24688fb3a00SPaolo Pisati 24788fb3a00SPaolo Pisati return ret; 24888fb3a00SPaolo Pisati } 24988fb3a00SPaolo Pisati 25088fb3a00SPaolo Pisati static int machxo2_write(struct fpga_manager *mgr, const char *buf, 25188fb3a00SPaolo Pisati size_t count) 25288fb3a00SPaolo Pisati { 25388fb3a00SPaolo Pisati struct spi_device *spi = mgr->priv; 25488fb3a00SPaolo Pisati struct spi_message msg; 25588fb3a00SPaolo Pisati struct spi_transfer tx; 25688fb3a00SPaolo Pisati static const u8 progincr[] = LSC_PROGINCRNV; 25788fb3a00SPaolo Pisati u8 payload[MACHXO2_BUF_SIZE]; 25888fb3a00SPaolo Pisati unsigned long status; 25988fb3a00SPaolo Pisati int i, ret; 26088fb3a00SPaolo Pisati 26188fb3a00SPaolo Pisati if (count % MACHXO2_PAGE_SIZE != 0) { 26288fb3a00SPaolo Pisati dev_err(&mgr->dev, "Malformed payload.\n"); 26388fb3a00SPaolo Pisati return -EINVAL; 26488fb3a00SPaolo Pisati } 26588fb3a00SPaolo Pisati get_status(spi, &status); 26688fb3a00SPaolo Pisati dump_status_reg(&status); 26788fb3a00SPaolo Pisati memcpy(payload, &progincr, sizeof(progincr)); 26888fb3a00SPaolo Pisati for (i = 0; i < count; i += MACHXO2_PAGE_SIZE) { 26988fb3a00SPaolo Pisati memcpy(&payload[sizeof(progincr)], &buf[i], MACHXO2_PAGE_SIZE); 27088fb3a00SPaolo Pisati memset(&tx, 0, sizeof(tx)); 27188fb3a00SPaolo Pisati spi_message_init(&msg); 27288fb3a00SPaolo Pisati tx.tx_buf = payload; 27388fb3a00SPaolo Pisati tx.len = MACHXO2_BUF_SIZE; 274a1d1f5d4SSergiu Cuciurean tx.delay.value = MACHXO2_HIGH_DELAY_USEC; 275a1d1f5d4SSergiu Cuciurean tx.delay.unit = SPI_DELAY_UNIT_USECS; 27688fb3a00SPaolo Pisati spi_message_add_tail(&tx, &msg); 27788fb3a00SPaolo Pisati ret = spi_sync(spi, &msg); 27888fb3a00SPaolo Pisati if (ret) { 27988fb3a00SPaolo Pisati dev_err(&mgr->dev, "Error loading the bitstream.\n"); 28088fb3a00SPaolo Pisati return ret; 28188fb3a00SPaolo Pisati } 28288fb3a00SPaolo Pisati } 28388fb3a00SPaolo Pisati get_status(spi, &status); 28488fb3a00SPaolo Pisati dump_status_reg(&status); 28588fb3a00SPaolo Pisati 28688fb3a00SPaolo Pisati return 0; 28788fb3a00SPaolo Pisati } 28888fb3a00SPaolo Pisati 28988fb3a00SPaolo Pisati static int machxo2_write_complete(struct fpga_manager *mgr, 29088fb3a00SPaolo Pisati struct fpga_image_info *info) 29188fb3a00SPaolo Pisati { 29288fb3a00SPaolo Pisati struct spi_device *spi = mgr->priv; 29388fb3a00SPaolo Pisati struct spi_message msg; 29488fb3a00SPaolo Pisati struct spi_transfer tx[2]; 29588fb3a00SPaolo Pisati static const u8 progdone[] = ISC_PROGRAMDONE; 29688fb3a00SPaolo Pisati static const u8 refresh[] = LSC_REFRESH; 29788fb3a00SPaolo Pisati unsigned long status; 29888fb3a00SPaolo Pisati int ret, refreshloop = 0; 29988fb3a00SPaolo Pisati 30088fb3a00SPaolo Pisati memset(tx, 0, sizeof(tx)); 30188fb3a00SPaolo Pisati spi_message_init(&msg); 30288fb3a00SPaolo Pisati tx[0].tx_buf = &progdone; 30388fb3a00SPaolo Pisati tx[0].len = sizeof(progdone); 30488fb3a00SPaolo Pisati spi_message_add_tail(&tx[0], &msg); 30588fb3a00SPaolo Pisati ret = spi_sync(spi, &msg); 30688fb3a00SPaolo Pisati if (ret) 30788fb3a00SPaolo Pisati goto fail; 30888fb3a00SPaolo Pisati ret = wait_until_not_busy(spi); 30988fb3a00SPaolo Pisati if (ret) 31088fb3a00SPaolo Pisati goto fail; 31188fb3a00SPaolo Pisati 31288fb3a00SPaolo Pisati get_status(spi, &status); 31388fb3a00SPaolo Pisati dump_status_reg(&status); 31488fb3a00SPaolo Pisati if (!test_bit(DONE, &status)) { 31588fb3a00SPaolo Pisati machxo2_cleanup(mgr); 31688fb3a00SPaolo Pisati goto fail; 31788fb3a00SPaolo Pisati } 31888fb3a00SPaolo Pisati 31988fb3a00SPaolo Pisati do { 32088fb3a00SPaolo Pisati spi_message_init(&msg); 32188fb3a00SPaolo Pisati tx[1].tx_buf = &refresh; 32288fb3a00SPaolo Pisati tx[1].len = sizeof(refresh); 323a1d1f5d4SSergiu Cuciurean tx[1].delay.value = MACHXO2_REFRESH_USEC; 324a1d1f5d4SSergiu Cuciurean tx[1].delay.unit = SPI_DELAY_UNIT_USECS; 32588fb3a00SPaolo Pisati spi_message_add_tail(&tx[1], &msg); 32688fb3a00SPaolo Pisati ret = spi_sync(spi, &msg); 32788fb3a00SPaolo Pisati if (ret) 32888fb3a00SPaolo Pisati goto fail; 32988fb3a00SPaolo Pisati 33088fb3a00SPaolo Pisati /* check refresh status */ 33188fb3a00SPaolo Pisati get_status(spi, &status); 33288fb3a00SPaolo Pisati dump_status_reg(&status); 33388fb3a00SPaolo Pisati if (!test_bit(BUSY, &status) && test_bit(DONE, &status) && 33488fb3a00SPaolo Pisati get_err(&status) == ENOERR) 33588fb3a00SPaolo Pisati break; 33688fb3a00SPaolo Pisati if (++refreshloop == MACHXO2_MAX_REFRESH_LOOP) { 33788fb3a00SPaolo Pisati machxo2_cleanup(mgr); 33888fb3a00SPaolo Pisati goto fail; 33988fb3a00SPaolo Pisati } 34088fb3a00SPaolo Pisati } while (1); 34188fb3a00SPaolo Pisati 34288fb3a00SPaolo Pisati get_status(spi, &status); 34388fb3a00SPaolo Pisati dump_status_reg(&status); 34488fb3a00SPaolo Pisati 34588fb3a00SPaolo Pisati return 0; 34688fb3a00SPaolo Pisati fail: 34788fb3a00SPaolo Pisati dev_err(&mgr->dev, "Refresh failed.\n"); 34888fb3a00SPaolo Pisati 34988fb3a00SPaolo Pisati return ret; 35088fb3a00SPaolo Pisati } 35188fb3a00SPaolo Pisati 35288fb3a00SPaolo Pisati static const struct fpga_manager_ops machxo2_ops = { 35388fb3a00SPaolo Pisati .state = machxo2_spi_state, 35488fb3a00SPaolo Pisati .write_init = machxo2_write_init, 35588fb3a00SPaolo Pisati .write = machxo2_write, 35688fb3a00SPaolo Pisati .write_complete = machxo2_write_complete, 35788fb3a00SPaolo Pisati }; 35888fb3a00SPaolo Pisati 35988fb3a00SPaolo Pisati static int machxo2_spi_probe(struct spi_device *spi) 36088fb3a00SPaolo Pisati { 36188fb3a00SPaolo Pisati struct device *dev = &spi->dev; 3627085e2a9SAlan Tull struct fpga_manager *mgr; 36388fb3a00SPaolo Pisati 36488fb3a00SPaolo Pisati if (spi->max_speed_hz > MACHXO2_MAX_SPEED) { 36588fb3a00SPaolo Pisati dev_err(dev, "Speed is too high\n"); 36688fb3a00SPaolo Pisati return -EINVAL; 36788fb3a00SPaolo Pisati } 36888fb3a00SPaolo Pisati 369084181feSAlan Tull mgr = devm_fpga_mgr_create(dev, "Lattice MachXO2 SPI FPGA Manager", 37088fb3a00SPaolo Pisati &machxo2_ops, spi); 3717085e2a9SAlan Tull if (!mgr) 3727085e2a9SAlan Tull return -ENOMEM; 3737085e2a9SAlan Tull 374*a3b79b2aSMoritz Fischer return devm_fpga_mgr_register(dev, mgr); 37588fb3a00SPaolo Pisati } 37688fb3a00SPaolo Pisati 37788fb3a00SPaolo Pisati static const struct of_device_id of_match[] = { 37888fb3a00SPaolo Pisati { .compatible = "lattice,machxo2-slave-spi", }, 37988fb3a00SPaolo Pisati {} 38088fb3a00SPaolo Pisati }; 38188fb3a00SPaolo Pisati MODULE_DEVICE_TABLE(of, of_match); 38288fb3a00SPaolo Pisati 38388fb3a00SPaolo Pisati static const struct spi_device_id lattice_ids[] = { 38488fb3a00SPaolo Pisati { "machxo2-slave-spi", 0 }, 38588fb3a00SPaolo Pisati { }, 38688fb3a00SPaolo Pisati }; 38788fb3a00SPaolo Pisati MODULE_DEVICE_TABLE(spi, lattice_ids); 38888fb3a00SPaolo Pisati 38988fb3a00SPaolo Pisati static struct spi_driver machxo2_spi_driver = { 39088fb3a00SPaolo Pisati .driver = { 39188fb3a00SPaolo Pisati .name = "machxo2-slave-spi", 39288fb3a00SPaolo Pisati .of_match_table = of_match_ptr(of_match), 39388fb3a00SPaolo Pisati }, 39488fb3a00SPaolo Pisati .probe = machxo2_spi_probe, 39588fb3a00SPaolo Pisati .id_table = lattice_ids, 39688fb3a00SPaolo Pisati }; 39788fb3a00SPaolo Pisati 39888fb3a00SPaolo Pisati module_spi_driver(machxo2_spi_driver) 39988fb3a00SPaolo Pisati 40088fb3a00SPaolo Pisati MODULE_AUTHOR("Paolo Pisati <p.pisati@gmail.com>"); 40188fb3a00SPaolo Pisati MODULE_DESCRIPTION("Load Lattice FPGA firmware over SPI"); 40288fb3a00SPaolo Pisati MODULE_LICENSE("GPL v2"); 403