diff options
Diffstat (limited to 'src/drivers/nvs/threewire.c')
| -rw-r--r-- | src/drivers/nvs/threewire.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/src/drivers/nvs/threewire.c b/src/drivers/nvs/threewire.c index f7a20bbef..8e5213893 100644 --- a/src/drivers/nvs/threewire.c +++ b/src/drivers/nvs/threewire.c @@ -19,6 +19,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <stddef.h> +#include <string.h> #include <assert.h> #include <unistd.h> #include <gpxe/threewire.h> @@ -42,13 +43,21 @@ int threewire_read ( struct nvs_device *nvs, unsigned int address, void *data, size_t len ) { struct spi_device *device = nvs_to_spi ( nvs ); struct spi_bus *bus = device->bus; + int rc; assert ( bus->mode == SPI_MODE_THREEWIRE ); - DBG ( "3wire %p reading %zd bytes at %04x\n", device, len, address ); + DBGC ( device, "3wire %p reading %zd bytes at %04x\n", + device, len, address ); + + if ( ( rc = bus->rw ( bus, device, THREEWIRE_READ, address, + NULL, data, len ) ) != 0 ) { + DBGC ( device, "3wire %p could not read: %s\n", + device, strerror ( rc ) ); + return rc; + } - return bus->rw ( bus, device, THREEWIRE_READ, address, - NULL, data, len ); + return 0; } /** @@ -68,17 +77,24 @@ int threewire_write ( struct nvs_device *nvs, unsigned int address, assert ( bus->mode == SPI_MODE_THREEWIRE ); - DBG ( "3wire %p writing %zd bytes at %04x\n", device, len, address ); + DBGC ( device, "3wire %p writing %zd bytes at %04x\n", + device, len, address ); /* Enable device for writing */ if ( ( rc = bus->rw ( bus, device, THREEWIRE_EWEN, - THREEWIRE_EWEN_ADDRESS, NULL, NULL, 0 ) ) != 0 ) + THREEWIRE_EWEN_ADDRESS, NULL, NULL, 0 ) ) != 0 ){ + DBGC ( device, "3wire %p could not enable writing: %s\n", + device, strerror ( rc ) ); return rc; + } /* Write data */ if ( ( rc = bus->rw ( bus, device, THREEWIRE_WRITE, address, - data, NULL, len ) ) != 0 ) + data, NULL, len ) ) != 0 ) { + DBGC ( device, "3wire %p could not write: %s\n", + device, strerror ( rc ) ); return rc; + } /* Our model of an SPI bus doesn't provide a mechanism for * "assert CS, wait for MISO to become high, so just wait for @@ -88,3 +104,28 @@ int threewire_write ( struct nvs_device *nvs, unsigned int address, return 0; } + +/** + * Autodetect device address length + * + * @v device SPI device + * @ret rc Return status code + */ +int threewire_detect_address_len ( struct spi_device *device ) { + struct nvs_device *nvs = &device->nvs; + int rc; + + DBGC ( device, "3wire %p autodetecting address length\n", device ); + + device->address_len = SPI_AUTODETECT_ADDRESS_LEN; + if ( ( rc = threewire_read ( nvs, 0, NULL, + ( 1 << nvs->word_len_log2 ) ) ) != 0 ) { + DBGC ( device, "3wire %p could not autodetect address " + "length: %s\n", device, strerror ( rc ) ); + return rc; + } + + DBGC ( device, "3wire %p autodetected address length %d\n", + device, device->address_len ); + return 0; +} |
