Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added abstraction layer for a three-wire serial device (e.g. the EEPROM
used on RTL8139 cards).
- Loading branch information
Michael Brown
committed
May 26, 2006
1 parent
2f392ee
commit aa2468b
Showing
3 changed files
with
171 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License as | ||
* published by the Free Software Foundation; either version 2 of the | ||
* License, or any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, but | ||
* WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
*/ | ||
|
||
#include <timer.h> | ||
#include <gpxe/nvs/threewire.h> | ||
|
||
/** @file | ||
* | ||
* Three-wire serial interface | ||
* | ||
*/ | ||
|
||
/** | ||
* Read from a three-wire device | ||
* | ||
* @v three Three-wire interface | ||
* @v address Address | ||
* @ret data Data | ||
*/ | ||
unsigned long threewire_read ( struct threewire *three, | ||
unsigned long address ) { | ||
struct threewire_operations *ops = three->ops; | ||
unsigned long command; | ||
unsigned long data; | ||
int i; | ||
|
||
ops->setcs ( three, 1 ); | ||
|
||
/* Send command and address */ | ||
command = threewire_cmd_read ( three, address ); | ||
for ( i = ( threewire_cmd_len ( three ) - 1 ) ; i >= 0 ; i-- ) { | ||
ops->setdi ( three, ( command >> i ) & 0x1 ); | ||
udelay ( three->udelay ); | ||
ops->setsk ( three, 1 ); | ||
udelay ( three->udelay ); | ||
ops->setsk ( three, 0 ); | ||
} | ||
|
||
/* Read back data */ | ||
data = 0; | ||
for ( i = three->datasize ; i ; i-- ) { | ||
udelay ( three->udelay ); | ||
ops->setsk ( three, 1 ); | ||
udelay ( three->udelay ); | ||
data <<= 1; | ||
data |= ops->getdo ( three ); | ||
ops->setsk ( three, 0 ); | ||
} | ||
|
||
ops->setcs ( three, 0 ); | ||
|
||
return data; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
#ifndef _GPXE_NVS_THREEWIRE_H | ||
#define _GPXE_NVS_THREEWIRE_H | ||
|
||
/** @file | ||
* | ||
* Three-wire serial interface | ||
* | ||
*/ | ||
|
||
struct threewire; | ||
|
||
/** Three-wire interface methods */ | ||
struct threewire_operations { | ||
/** | ||
* Set status of Chip Select line | ||
* | ||
* @v three Three-wire interface | ||
* @v cs New status for chip select line | ||
*/ | ||
void ( * setcs ) ( struct threewire *three, int cs ); | ||
/** | ||
* Set status of Serial Clock line | ||
* | ||
* @v three Three-wire interface | ||
* @v sk New status for serial clock line | ||
*/ | ||
void ( * setsk ) ( struct threewire *three, int sk ); | ||
/** | ||
* Set status of Data Input line | ||
* | ||
* @v three Three-wire interface | ||
* @v di New status for data input line | ||
*/ | ||
void ( * setdi ) ( struct threewire *three, int di ); | ||
/** | ||
* Get status of Data Output line | ||
* | ||
* @v three Three-wire interface | ||
* @ret do Status of data output line | ||
*/ | ||
int ( * getdo ) ( struct threewire *three ); | ||
}; | ||
|
||
/** | ||
* A three-wire serial interface | ||
* | ||
* This interface consists of a clock line (SK), data input (DI) and | ||
* data output (DO). There is also a chip select line (CS) which is | ||
* integral to the operation of the device, but Atmel still calls it a | ||
* three-wire interface. | ||
* | ||
*/ | ||
struct threewire { | ||
/** Interface methods */ | ||
struct threewire_operations *ops; | ||
/** Address size (in bits) */ | ||
unsigned int adrsize; | ||
/** Data size (in bits) */ | ||
unsigned int datasize; | ||
/** Delay between SK transitions (in us) */ | ||
unsigned int udelay; | ||
}; | ||
|
||
/** | ||
* Calculate read command for a specified address | ||
* | ||
* @v three Three-wire interface | ||
* @v address Address | ||
* @ret cmd Command | ||
*/ | ||
static inline __attribute__ (( always_inline )) unsigned long | ||
threewire_cmd_read ( struct threewire *three, unsigned long address ) { | ||
return ( ( 0x6 << three->adrsize ) | address ); | ||
} | ||
|
||
/** | ||
* Calculate command length | ||
* | ||
* @v three Three-wire interface | ||
* @ret len Command length, in bits | ||
*/ | ||
static inline __attribute__ (( always_inline )) int | ||
threewire_cmd_len ( struct threewire *three ) { | ||
return ( three->adrsize + 3 ); | ||
} | ||
|
||
/* Constants for some standard parts */ | ||
#define AT93C46_ORG8_ADRSIZE 7 | ||
#define AT93C46_ORG8_DATASIZE 8 | ||
#define AT93C46_ORG16_ADRSIZE 6 | ||
#define AT93C46_ORG16_DATASIZE 16 | ||
#define AT93C46_UDELAY 1 | ||
#define AT93C56_ORG8_ADRSIZE 9 | ||
#define AT93C56_ORG8_DATASIZE 8 | ||
#define AT93C56_ORG16_ADRSIZE 8 | ||
#define AT93C56_ORG16_DATASIZE 16 | ||
#define AT93C56_UDELAY 1 | ||
|
||
extern unsigned long threewire_read ( struct threewire *three, | ||
unsigned long address ); | ||
|
||
#endif /* _GPXE_NVS_THREEWIRE_H */ |