Lines Matching +full:- +full:spi

1 // SPDX-License-Identifier: GPL-2.0-only
3 * datasheet: https://www.nxp.com/docs/en/data-sheet/K20P144M120SF3.pdf
5 * Copyright (C) 2018-2021 Collabora
6 * Copyright (C) 2018-2021 GE Healthcare
15 #include <linux/spi/spi.h>
42 #define EZPORT_SECTOR_MASK (EZPORT_SECTOR_SIZE - 1)
59 static int ezport_start_programming(struct spi_device *spi, struct gpio_desc *reset) in ezport_start_programming() argument
68 spi_bus_lock(spi->controller); in ezport_start_programming()
73 ret = spi_sync_locked(spi, &msg); in ezport_start_programming()
85 ret = spi_sync_locked(spi, &msg); in ezport_start_programming()
88 spi_bus_unlock(spi->controller); in ezport_start_programming()
92 static void ezport_stop_programming(struct spi_device *spi, struct gpio_desc *reset) in ezport_stop_programming() argument
95 spi_bus_lock(spi->controller); in ezport_stop_programming()
97 spi_bus_unlock(spi->controller); in ezport_stop_programming()
100 static int ezport_get_status_register(struct spi_device *spi) in ezport_get_status_register() argument
104 ret = spi_w8r8(spi, EZPORT_CMD_RDSR); in ezport_get_status_register()
108 dev_err(&spi->dev, "Invalid EzPort status, EzPort is not functional!\n"); in ezport_get_status_register()
109 return -EINVAL; in ezport_get_status_register()
115 static int ezport_soft_reset(struct spi_device *spi) in ezport_soft_reset() argument
120 ret = spi_write(spi, &cmd, 1); in ezport_soft_reset()
129 static int ezport_send_simple(struct spi_device *spi, u8 cmd) in ezport_send_simple() argument
133 ret = spi_write(spi, &cmd, 1); in ezport_send_simple()
137 return ezport_get_status_register(spi); in ezport_send_simple()
140 static int ezport_wait_write(struct spi_device *spi, u32 retries) in ezport_wait_write() argument
146 ret = ezport_get_status_register(spi); in ezport_wait_write()
155 static int ezport_write_enable(struct spi_device *spi) in ezport_write_enable() argument
160 ret = ezport_send_simple(spi, EZPORT_CMD_WREN); in ezport_write_enable()
166 dev_err(&spi->dev, "EzPort write enable timed out\n"); in ezport_write_enable()
167 return -ETIMEDOUT; in ezport_write_enable()
172 static int ezport_bulk_erase(struct spi_device *spi) in ezport_bulk_erase() argument
177 dev_dbg(&spi->dev, "EzPort bulk erase...\n"); in ezport_bulk_erase()
179 ret = ezport_write_enable(spi); in ezport_bulk_erase()
183 ret = spi_write(spi, &cmd, 1); in ezport_bulk_erase()
187 ret = ezport_wait_write(spi, 1000); in ezport_bulk_erase()
194 static int ezport_section_erase(struct spi_device *spi, u32 address) in ezport_section_erase() argument
199 dev_dbg(&spi->dev, "Ezport section erase @ 0x%06x...\n", address); in ezport_section_erase()
202 return -EINVAL; in ezport_section_erase()
204 ret = ezport_write_enable(spi); in ezport_section_erase()
208 ret = spi_write(spi, query, sizeof(query)); in ezport_section_erase()
212 return ezport_wait_write(spi, 200); in ezport_section_erase()
215 static int ezport_flash_transfer(struct spi_device *spi, u32 address, in ezport_flash_transfer() argument
222 dev_dbg(&spi->dev, "EzPort write %zu bytes @ 0x%06x...\n", payload_size, address); in ezport_flash_transfer()
224 ret = ezport_write_enable(spi); in ezport_flash_transfer()
230 return -ENOMEM; in ezport_flash_transfer()
243 ret = spi_sync_transfer(spi, xfers, 2); in ezport_flash_transfer()
248 return ezport_wait_write(spi, 40); in ezport_flash_transfer()
251 static int ezport_flash_compare(struct spi_device *spi, u32 address, in ezport_flash_compare() argument
260 return -ENOMEM; in ezport_flash_compare()
275 ret = spi_sync_transfer(spi, xfers, 2); in ezport_flash_compare()
282 ret = -EBADMSG; in ezport_flash_compare()
283 dev_dbg(&spi->dev, "Verification failure @ %06x", address); in ezport_flash_compare()
293 static int ezport_firmware_compare_data(struct spi_device *spi, in ezport_firmware_compare_data() argument
300 dev_dbg(&spi->dev, "EzPort compare data with %zu bytes...\n", size); in ezport_firmware_compare_data()
302 ret = ezport_get_status_register(spi); in ezport_firmware_compare_data()
307 dev_info(&spi->dev, "Device is in secure mode (status=0x%02x)!\n", ret); in ezport_firmware_compare_data()
308 dev_info(&spi->dev, "FW verification is not possible\n"); in ezport_firmware_compare_data()
309 return -EACCES; in ezport_firmware_compare_data()
312 while (size - address > 0) { in ezport_firmware_compare_data()
313 transfer_size = min((size_t) EZPORT_TRANSFER_SIZE, size - address); in ezport_firmware_compare_data()
315 ret = ezport_flash_compare(spi, address, data+address, transfer_size); in ezport_firmware_compare_data()
325 static int ezport_firmware_flash_data(struct spi_device *spi, in ezport_firmware_flash_data() argument
332 dev_dbg(&spi->dev, "EzPort flash data with %zu bytes...\n", size); in ezport_firmware_flash_data()
334 ret = ezport_get_status_register(spi); in ezport_firmware_flash_data()
339 ret = ezport_bulk_erase(spi); in ezport_firmware_flash_data()
343 return -EINVAL; in ezport_firmware_flash_data()
346 while (size - address > 0) { in ezport_firmware_flash_data()
348 ret = ezport_section_erase(spi, address); in ezport_firmware_flash_data()
352 return -EIO; in ezport_firmware_flash_data()
355 transfer_size = min((size_t) EZPORT_TRANSFER_SIZE, size - address); in ezport_firmware_flash_data()
357 ret = ezport_flash_transfer(spi, address, in ezport_firmware_flash_data()
362 return -ETIMEDOUT; in ezport_firmware_flash_data()
364 return -EIO; in ezport_firmware_flash_data()
369 dev_dbg(&spi->dev, "EzPort verify flashed data...\n"); in ezport_firmware_flash_data()
370 ret = ezport_firmware_compare_data(spi, data, size); in ezport_firmware_flash_data()
373 if (ret == -EACCES) in ezport_firmware_flash_data()
377 dev_err(&spi->dev, "Failed to verify flashed data: %d\n", ret); in ezport_firmware_flash_data()
379 ret = ezport_soft_reset(spi); in ezport_firmware_flash_data()
381 dev_warn(&spi->dev, "EzPort reset failed!\n"); in ezport_firmware_flash_data()
386 static int ezport_firmware_load(struct spi_device *spi, const char *fwname) in ezport_firmware_load() argument
391 ret = request_firmware(&fw, fwname, &spi->dev); in ezport_firmware_load()
393 dev_err(&spi->dev, "Could not get firmware: %d\n", ret); in ezport_firmware_load()
397 ret = ezport_firmware_flash_data(spi, fw->data, fw->size); in ezport_firmware_load()
405 * ezport_flash - flash device firmware
406 * @spi: SPI device for NXP EzPort interface
414 static int ezport_flash(struct spi_device *spi, struct gpio_desc *reset, const char *fwname) in ezport_flash() argument
418 ret = ezport_start_programming(spi, reset); in ezport_flash()
422 ret = ezport_firmware_load(spi, fwname); in ezport_flash()
424 ezport_stop_programming(spi, reset); in ezport_flash()
427 dev_err(&spi->dev, "Failed to flash firmware: %d\n", ret); in ezport_flash()
429 dev_dbg(&spi->dev, "Finished FW flashing!\n"); in ezport_flash()
443 return -EINVAL; in update_firmware_store()
445 mutex_lock(&achc->device_lock); in update_firmware_store()
446 ret = ezport_flash(achc->ezport, achc->reset, "achc.bin"); in update_firmware_store()
447 mutex_unlock(&achc->device_lock); in update_firmware_store()
461 mutex_lock(&achc->device_lock); in reset_show()
462 ret = gpiod_get_value(achc->reset); in reset_show()
463 mutex_unlock(&achc->device_lock); in reset_show()
480 return -EINVAL; in reset_store()
482 mutex_lock(&achc->device_lock); in reset_store()
483 gpiod_set_value(achc->reset, value); in reset_store()
484 mutex_unlock(&achc->device_lock); in reset_store()
504 static int gehc_achc_probe(struct spi_device *spi) in gehc_achc_probe() argument
509 spi->max_speed_hz = ACHC_MAX_FREQ_HZ; in gehc_achc_probe()
510 spi->bits_per_word = 8; in gehc_achc_probe()
511 spi->mode = SPI_MODE_0; in gehc_achc_probe()
513 achc = devm_kzalloc(&spi->dev, sizeof(*achc), GFP_KERNEL); in gehc_achc_probe()
515 return -ENOMEM; in gehc_achc_probe()
516 spi_set_drvdata(spi, achc); in gehc_achc_probe()
517 achc->main = spi; in gehc_achc_probe()
519 mutex_init(&achc->device_lock); in gehc_achc_probe()
521 ret = of_property_read_u32_index(spi->dev.of_node, "reg", 1, &ezport_reg); in gehc_achc_probe()
523 return dev_err_probe(&spi->dev, ret, "missing second reg entry!\n"); in gehc_achc_probe()
525 achc->ezport = spi_new_ancillary_device(spi, ezport_reg); in gehc_achc_probe()
526 if (IS_ERR(achc->ezport)) in gehc_achc_probe()
527 return PTR_ERR(achc->ezport); in gehc_achc_probe()
529 ret = devm_add_action_or_reset(&spi->dev, unregister_ezport, achc->ezport); in gehc_achc_probe()
533 achc->reset = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_LOW); in gehc_achc_probe()
534 if (IS_ERR(achc->reset)) in gehc_achc_probe()
535 return dev_err_probe(&spi->dev, PTR_ERR(achc->reset), "Could not get reset gpio\n"); in gehc_achc_probe()
545 MODULE_DEVICE_TABLE(spi, gehc_achc_id);
555 .name = "gehc-achc",