Lines Matching +full:spi +full:- +full:slave
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Xilinx Spartan6 and 7 Series Slave Serial SPI Driver
9 * Manage Xilinx FPGA firmware that is loaded over SPI using
10 * the slave serial configuration interface.
15 #include <linux/fpga/fpga-mgr.h>
20 #include <linux/spi/spi.h>
24 struct spi_device *spi; member
32 struct xilinx_spi_conf *conf = mgr->priv; in get_done_gpio()
35 ret = gpiod_get_value(conf->done); in get_done_gpio()
38 dev_err(&mgr->dev, "Error reading DONE (%d)\n", ret); in get_done_gpio()
52 * wait_for_init_b - wait for the INIT_B pin to have a given state, or wait
59 * Returns 0 when the INIT_B GPIO reached the given state or -ETIMEDOUT if
66 struct xilinx_spi_conf *conf = mgr->priv; in wait_for_init_b()
69 if (conf->init_b) { in wait_for_init_b()
71 int ret = gpiod_get_value(conf->init_b); in wait_for_init_b()
77 dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret); in wait_for_init_b()
84 dev_err(&mgr->dev, "Timeout waiting for INIT_B to %s\n", in wait_for_init_b()
86 return -ETIMEDOUT; in wait_for_init_b()
98 struct xilinx_spi_conf *conf = mgr->priv; in xilinx_spi_write_init()
101 if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) { in xilinx_spi_write_init()
102 dev_err(&mgr->dev, "Partial reconfiguration not supported\n"); in xilinx_spi_write_init()
103 return -EINVAL; in xilinx_spi_write_init()
106 gpiod_set_value(conf->prog_b, 1); in xilinx_spi_write_init()
110 gpiod_set_value(conf->prog_b, 0); in xilinx_spi_write_init()
114 gpiod_set_value(conf->prog_b, 0); in xilinx_spi_write_init()
121 dev_err(&mgr->dev, "Unexpected DONE pin state...\n"); in xilinx_spi_write_init()
122 return -EIO; in xilinx_spi_write_init()
133 struct xilinx_spi_conf *conf = mgr->priv; in xilinx_spi_write()
141 remaining = fw_data_end - fw_data; in xilinx_spi_write()
144 ret = spi_write(conf->spi, fw_data, stride); in xilinx_spi_write()
146 dev_err(&mgr->dev, "SPI error in firmware write: %d\n", in xilinx_spi_write()
158 struct spi_device *spi = conf->spi; in xilinx_spi_apply_cclk_cycles() local
162 ret = spi_write(conf->spi, din_data, sizeof(din_data)); in xilinx_spi_apply_cclk_cycles()
164 dev_err(&spi->dev, "applying CCLK cycles failed: %d\n", ret); in xilinx_spi_apply_cclk_cycles()
172 struct xilinx_spi_conf *conf = mgr->priv; in xilinx_spi_write_complete()
173 unsigned long timeout = jiffies + usecs_to_jiffies(info->config_complete_timeout_us); in xilinx_spi_write_complete()
198 if (conf->init_b) { in xilinx_spi_write_complete()
199 ret = gpiod_get_value(conf->init_b); in xilinx_spi_write_complete()
202 dev_err(&mgr->dev, "Error reading INIT_B (%d)\n", ret); in xilinx_spi_write_complete()
206 dev_err(&mgr->dev, in xilinx_spi_write_complete()
210 dev_err(&mgr->dev, "Timeout after config data transfer\n"); in xilinx_spi_write_complete()
213 return -ETIMEDOUT; in xilinx_spi_write_complete()
223 static int xilinx_spi_probe(struct spi_device *spi) in xilinx_spi_probe() argument
228 conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL); in xilinx_spi_probe()
230 return -ENOMEM; in xilinx_spi_probe()
232 conf->spi = spi; in xilinx_spi_probe()
235 conf->prog_b = devm_gpiod_get(&spi->dev, "prog_b", GPIOD_OUT_LOW); in xilinx_spi_probe()
236 if (IS_ERR(conf->prog_b)) { in xilinx_spi_probe()
237 dev_err(&spi->dev, "Failed to get PROGRAM_B gpio: %ld\n", in xilinx_spi_probe()
238 PTR_ERR(conf->prog_b)); in xilinx_spi_probe()
239 return PTR_ERR(conf->prog_b); in xilinx_spi_probe()
242 conf->init_b = devm_gpiod_get_optional(&spi->dev, "init-b", GPIOD_IN); in xilinx_spi_probe()
243 if (IS_ERR(conf->init_b)) { in xilinx_spi_probe()
244 dev_err(&spi->dev, "Failed to get INIT_B gpio: %ld\n", in xilinx_spi_probe()
245 PTR_ERR(conf->init_b)); in xilinx_spi_probe()
246 return PTR_ERR(conf->init_b); in xilinx_spi_probe()
249 conf->done = devm_gpiod_get(&spi->dev, "done", GPIOD_IN); in xilinx_spi_probe()
250 if (IS_ERR(conf->done)) { in xilinx_spi_probe()
251 dev_err(&spi->dev, "Failed to get DONE gpio: %ld\n", in xilinx_spi_probe()
252 PTR_ERR(conf->done)); in xilinx_spi_probe()
253 return PTR_ERR(conf->done); in xilinx_spi_probe()
256 mgr = devm_fpga_mgr_create(&spi->dev, in xilinx_spi_probe()
257 "Xilinx Slave Serial FPGA Manager", in xilinx_spi_probe()
260 return -ENOMEM; in xilinx_spi_probe()
262 spi_set_drvdata(spi, mgr); in xilinx_spi_probe()
267 static int xilinx_spi_remove(struct spi_device *spi) in xilinx_spi_remove() argument
269 struct fpga_manager *mgr = spi_get_drvdata(spi); in xilinx_spi_remove()
277 { .compatible = "xlnx,fpga-slave-serial", },
284 .name = "xlnx-slave-spi",
295 MODULE_DESCRIPTION("Load Xilinx FPGA firmware over SPI");