Lines Matching +full:spi +full:- +full:lsb +full:- +full:first
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Altera Passive Serial SPI Driver
9 * Manage Altera FPGA firmware that is loaded over SPI using the passive
18 #include <linux/fpga/fpga-mgr.h>
23 #include <linux/spi/spi.h>
43 struct spi_device *spi; member
82 { .compatible = "altr,fpga-passive-serial", .data = &c5_data },
83 { .compatible = "altr,fpga-arria10-passive-serial", .data = &a10_data },
90 struct altera_ps_conf *conf = mgr->priv; in altera_ps_state()
92 if (gpiod_get_value_cansleep(conf->status)) in altera_ps_state()
110 struct altera_ps_conf *conf = mgr->priv; in altera_ps_write_init()
114 conf->info_flags = info->flags; in altera_ps_write_init()
116 if (info->flags & FPGA_MGR_PARTIAL_RECONFIG) { in altera_ps_write_init()
117 dev_err(&mgr->dev, "Partial reconfiguration not supported.\n"); in altera_ps_write_init()
118 return -EINVAL; in altera_ps_write_init()
121 gpiod_set_value_cansleep(conf->config, 1); in altera_ps_write_init()
124 altera_ps_delay(conf->data->t_cfg_us); in altera_ps_write_init()
126 if (!gpiod_get_value_cansleep(conf->status)) { in altera_ps_write_init()
127 dev_err(&mgr->dev, "Status pin failed to show a reset\n"); in altera_ps_write_init()
128 return -EIO; in altera_ps_write_init()
131 gpiod_set_value_cansleep(conf->config, 0); in altera_ps_write_init()
133 min = conf->data->status_wait_min_us; in altera_ps_write_init()
134 max = conf->data->status_wait_max_us; in altera_ps_write_init()
142 if (!gpiod_get_value_cansleep(conf->status)) { in altera_ps_write_init()
144 altera_ps_delay(conf->data->t_st2ck_us); in altera_ps_write_init()
149 dev_err(&mgr->dev, "Status pin not ready.\n"); in altera_ps_write_init()
150 return -EIO; in altera_ps_write_init()
157 const u32 *fw_end = (u32 *)(buf + len - extra_bytes); in rev_buf()
159 /* set buffer to lsb first */ in rev_buf()
170 extra_bytes--; in rev_buf()
178 struct altera_ps_conf *conf = mgr->priv; in altera_ps_write()
184 size_t stride = min_t(size_t, fw_data_end - fw_data, SZ_4K); in altera_ps_write()
186 if (!(conf->info_flags & FPGA_MGR_BITSTREAM_LSB_FIRST)) in altera_ps_write()
189 ret = spi_write(conf->spi, fw_data, stride); in altera_ps_write()
191 dev_err(&mgr->dev, "spi error in firmware write: %d\n", in altera_ps_write()
204 struct altera_ps_conf *conf = mgr->priv; in altera_ps_write_complete()
208 if (gpiod_get_value_cansleep(conf->status)) { in altera_ps_write_complete()
209 dev_err(&mgr->dev, "Error during configuration.\n"); in altera_ps_write_complete()
210 return -EIO; in altera_ps_write_complete()
213 if (conf->confd) { in altera_ps_write_complete()
214 if (!gpiod_get_raw_value_cansleep(conf->confd)) { in altera_ps_write_complete()
215 dev_err(&mgr->dev, "CONF_DONE is inactive!\n"); in altera_ps_write_complete()
216 return -EIO; in altera_ps_write_complete()
224 ret = spi_write(conf->spi, dummy, 1); in altera_ps_write_complete()
226 dev_err(&mgr->dev, "spi error during end sequence: %d\n", ret); in altera_ps_write_complete()
242 kernel_ulong_t devtype = id->driver_data; in id_to_data()
250 if (!data || data->devtype != devtype) in id_to_data()
256 static int altera_ps_probe(struct spi_device *spi) in altera_ps_probe() argument
262 conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL); in altera_ps_probe()
264 return -ENOMEM; in altera_ps_probe()
266 if (spi->dev.of_node) { in altera_ps_probe()
267 of_id = of_match_device(of_ef_match, &spi->dev); in altera_ps_probe()
269 return -ENODEV; in altera_ps_probe()
270 conf->data = of_id->data; in altera_ps_probe()
272 conf->data = id_to_data(spi_get_device_id(spi)); in altera_ps_probe()
273 if (!conf->data) in altera_ps_probe()
274 return -ENODEV; in altera_ps_probe()
277 conf->spi = spi; in altera_ps_probe()
278 conf->config = devm_gpiod_get(&spi->dev, "nconfig", GPIOD_OUT_LOW); in altera_ps_probe()
279 if (IS_ERR(conf->config)) { in altera_ps_probe()
280 dev_err(&spi->dev, "Failed to get config gpio: %ld\n", in altera_ps_probe()
281 PTR_ERR(conf->config)); in altera_ps_probe()
282 return PTR_ERR(conf->config); in altera_ps_probe()
285 conf->status = devm_gpiod_get(&spi->dev, "nstat", GPIOD_IN); in altera_ps_probe()
286 if (IS_ERR(conf->status)) { in altera_ps_probe()
287 dev_err(&spi->dev, "Failed to get status gpio: %ld\n", in altera_ps_probe()
288 PTR_ERR(conf->status)); in altera_ps_probe()
289 return PTR_ERR(conf->status); in altera_ps_probe()
292 conf->confd = devm_gpiod_get_optional(&spi->dev, "confd", GPIOD_IN); in altera_ps_probe()
293 if (IS_ERR(conf->confd)) { in altera_ps_probe()
294 dev_err(&spi->dev, "Failed to get confd gpio: %ld\n", in altera_ps_probe()
295 PTR_ERR(conf->confd)); in altera_ps_probe()
296 return PTR_ERR(conf->confd); in altera_ps_probe()
297 } else if (!conf->confd) { in altera_ps_probe()
298 dev_warn(&spi->dev, "Not using confd gpio"); in altera_ps_probe()
302 snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s %s", in altera_ps_probe()
303 dev_driver_string(&spi->dev), dev_name(&spi->dev)); in altera_ps_probe()
305 mgr = devm_fpga_mgr_register(&spi->dev, conf->mgr_name, in altera_ps_probe()
311 { "cyclone-ps-spi", CYCLONE5 },
312 { "fpga-passive-serial", CYCLONE5 },
313 { "fpga-arria10-passive-serial", ARRIA10 },
316 MODULE_DEVICE_TABLE(spi, altera_ps_spi_ids);
320 .name = "altera-ps-spi",
332 MODULE_DESCRIPTION("Module to load Altera FPGA firmware over SPI");