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 13FILE_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 44extern int threewire_read ( struct nvs_device *nvs, unsigned int address, 45 void *data, size_t len ); 46extern int threewire_write ( struct nvs_device *nvs, unsigned int address, 47 const void *data, size_t len ); 48extern int threewire_detect_address_len ( struct spi_device *device ); 49 50/** 51 * @defgroup tdevs Three-wire device types 52 * @{ 53 */ 54 55static inline __attribute__ (( always_inline )) void 56init_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 */ 70static inline __attribute__ (( always_inline )) void 71init_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 */ 83static inline __attribute__ (( always_inline )) void 84init_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 */ 96static inline __attribute__ (( always_inline )) void 97init_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