1 #ifndef _GPXE_THREEWIRE_H 2 #define _GPXE_THREEWIRE_H 3 4 /** @file 5 * 6 * Three-wire serial interface 7 * 8 * The Atmel three-wire interface is a subset of the (newer) SPI 9 * interface, and is implemented here as a layer on top of the SPI 10 * support. 11 */ 12 13 FILE_LICENCE ( GPL2_OR_LATER ); 14 15 #include <gpxe/spi.h> 16 #include <limits.h> 17 18 /** 19 * @defgroup tcmds Three-wire commands 20 * @{ 21 */ 22 23 /** Read data from memory array */ 24 #define THREEWIRE_READ 0x6 25 26 /** Write data to memory array */ 27 #define THREEWIRE_WRITE 0x5 28 29 /** Write enable */ 30 #define THREEWIRE_EWEN 0x4 31 32 /** Address to be used for write enable command */ 33 #define THREEWIRE_EWEN_ADDRESS INT_MAX 34 35 /** Time to wait for write cycles to complete 36 * 37 * This is sufficient for AT93C46/AT93C56 devices, but may need to be 38 * increased in future when other devices are added. 39 */ 40 #define THREEWIRE_WRITE_MDELAY 10 41 42 /** @} */ 43 44 extern int threewire_read ( struct nvs_device *nvs, unsigned int address, 45 void *data, size_t len ); 46 extern int threewire_write ( struct nvs_device *nvs, unsigned int address, 47 const void *data, size_t len ); 48 extern int threewire_detect_address_len ( struct spi_device *device ); 49 50 /** 51 * @defgroup tdevs Three-wire device types 52 * @{ 53 */ 54 55 static inline __attribute__ (( always_inline )) void 56 init_at93cx6 ( struct spi_device *device, unsigned int organisation ) { 57 device->nvs.word_len_log2 = ( ( organisation == 8 ) ? 0 : 1 ); 58 device->nvs.block_size = 1; 59 device->command_len = 3, 60 device->nvs.read = threewire_read; 61 device->nvs.write = threewire_write; 62 } 63 64 /** 65 * Initialise Atmel AT93C46 serial EEPROM 66 * 67 * @v device SPI device 68 * @v organisation Word organisation (8 or 16) 69 */ 70 static inline __attribute__ (( always_inline )) void 71 init_at93c46 ( struct spi_device *device, unsigned int organisation ) { 72 device->nvs.size = ( 1024 / organisation ); 73 device->address_len = ( ( organisation == 8 ) ? 7 : 6 ); 74 init_at93cx6 ( device, organisation ); 75 } 76 77 /** 78 * Initialise Atmel AT93C56 serial EEPROM 79 * 80 * @v device SPI device 81 * @v organisation Word organisation (8 or 16) 82 */ 83 static inline __attribute__ (( always_inline )) void 84 init_at93c56 ( struct spi_device *device, unsigned int organisation ) { 85 device->nvs.size = ( 2048 / organisation ); 86 device->address_len = ( ( organisation == 8 ) ? 9 : 8 ); 87 init_at93cx6 ( device, organisation ); 88 } 89 90 /** 91 * Initialise Atmel AT93C66 serial EEPROM 92 * 93 * @v device SPI device 94 * @v organisation Word organisation (8 or 16) 95 */ 96 static inline __attribute__ (( always_inline )) void 97 init_at93c66 ( struct spi_device *device, unsigned int organisation ) { 98 device->nvs.size = ( 4096 / organisation ); 99 device->address_len = ( ( organisation == 8 ) ? 9 : 8 ); 100 init_at93cx6 ( device, organisation ); 101 } 102 103 /** @} */ 104 105 #endif /* _GPXE_THREEWIRE_H */ 106