Просмотр исходного кода

Added abstraction layer for a three-wire serial device (e.g. the EEPROM

used on RTL8139 cards).
tags/v0.9.3
Michael Brown 18 лет назад
Родитель
Сommit
aa2468babe
3 измененных файлов: 171 добавлений и 0 удалений
  1. 1
    0
      src/Makefile
  2. 68
    0
      src/drivers/nvs/threewire.c
  3. 102
    0
      src/include/gpxe/nvs/threewire.h

+ 1
- 0
src/Makefile Просмотреть файл

@@ -138,6 +138,7 @@ SRCDIRS		+= drivers/bus
138 138
 SRCDIRS		+= drivers/net
139 139
 SRCDIRS		+= drivers/block
140 140
 SRCDIRS		+= drivers/scsi
141
+SRCDIRS		+= drivers/nvs
141 142
 SRCDIRS		+= interface/pxe
142 143
 
143 144
 # NON_AUTO_SRCS lists files that are excluded from the normal

+ 68
- 0
src/drivers/nvs/threewire.c Просмотреть файл

@@ -0,0 +1,68 @@
1
+/*
2
+ * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <timer.h>
20
+#include <gpxe/nvs/threewire.h>
21
+
22
+/** @file
23
+ *
24
+ * Three-wire serial interface
25
+ *
26
+ */
27
+
28
+/**
29
+ * Read from a three-wire device
30
+ *
31
+ * @v three	Three-wire interface
32
+ * @v address	Address
33
+ * @ret data	Data
34
+ */
35
+unsigned long threewire_read ( struct threewire *three,
36
+			       unsigned long address ) {
37
+	struct threewire_operations *ops = three->ops;
38
+	unsigned long command;
39
+	unsigned long data;
40
+	int i;
41
+
42
+	ops->setcs ( three, 1 );
43
+	
44
+	/* Send command and address */
45
+	command = threewire_cmd_read ( three, address );
46
+	for ( i = ( threewire_cmd_len ( three ) - 1 ) ; i >= 0 ; i-- ) {
47
+		ops->setdi ( three, ( command >> i ) & 0x1 );
48
+		udelay ( three->udelay );
49
+		ops->setsk ( three, 1 );
50
+		udelay ( three->udelay );
51
+		ops->setsk ( three, 0 );
52
+	}
53
+
54
+	/* Read back data */
55
+	data = 0;
56
+	for ( i = three->datasize ; i ; i-- ) {
57
+		udelay ( three->udelay );
58
+		ops->setsk ( three, 1 );
59
+		udelay ( three->udelay );
60
+		data <<= 1;
61
+		data |= ops->getdo ( three );
62
+		ops->setsk ( three, 0 );
63
+	}
64
+
65
+	ops->setcs ( three, 0 );
66
+
67
+	return data;
68
+}

+ 102
- 0
src/include/gpxe/nvs/threewire.h Просмотреть файл

@@ -0,0 +1,102 @@
1
+#ifndef _GPXE_NVS_THREEWIRE_H
2
+#define _GPXE_NVS_THREEWIRE_H
3
+
4
+/** @file
5
+ *
6
+ * Three-wire serial interface
7
+ *
8
+ */
9
+
10
+struct threewire;
11
+
12
+/** Three-wire interface methods */
13
+struct threewire_operations {
14
+	/**
15
+	 * Set status of Chip Select line
16
+	 *
17
+	 * @v three	Three-wire interface
18
+	 * @v cs	New status for chip select line
19
+	 */
20
+	void ( * setcs ) ( struct threewire *three, int cs );
21
+	/**
22
+	 * Set status of Serial Clock line
23
+	 *
24
+	 * @v three	Three-wire interface
25
+	 * @v sk	New status for serial clock line
26
+	 */
27
+	void ( * setsk ) ( struct threewire *three, int sk );
28
+	/**
29
+	 * Set status of Data Input line
30
+	 *
31
+	 * @v three	Three-wire interface
32
+	 * @v di	New status for data input line
33
+	 */
34
+	void ( * setdi ) ( struct threewire *three, int di );
35
+	/**
36
+	 * Get status of Data Output line
37
+	 *
38
+	 * @v three	Three-wire interface
39
+	 * @ret do	Status of data output line
40
+	 */
41
+	int ( * getdo ) ( struct threewire *three );
42
+};
43
+
44
+/**
45
+ * A three-wire serial interface
46
+ *
47
+ * This interface consists of a clock line (SK), data input (DI) and
48
+ * data output (DO).  There is also a chip select line (CS) which is
49
+ * integral to the operation of the device, but Atmel still calls it a
50
+ * three-wire interface.
51
+ *
52
+ */
53
+struct threewire {
54
+	/** Interface methods */
55
+	struct threewire_operations *ops;
56
+	/** Address size (in bits) */
57
+	unsigned int adrsize;
58
+	/** Data size (in bits) */
59
+	unsigned int datasize;
60
+	/** Delay between SK transitions (in us) */
61
+	unsigned int udelay;
62
+};
63
+
64
+/**
65
+ * Calculate read command for a specified address
66
+ *
67
+ * @v three	Three-wire interface
68
+ * @v address	Address
69
+ * @ret cmd	Command
70
+ */
71
+static inline __attribute__ (( always_inline )) unsigned long
72
+threewire_cmd_read ( struct threewire *three, unsigned long address ) {
73
+	return ( ( 0x6 << three->adrsize ) | address );
74
+}
75
+
76
+/**
77
+ * Calculate command length
78
+ *
79
+ * @v three	Three-wire interface
80
+ * @ret len	Command length, in bits
81
+ */
82
+static inline __attribute__ (( always_inline )) int
83
+threewire_cmd_len ( struct threewire *three ) {
84
+	return ( three->adrsize + 3 );
85
+}
86
+
87
+/* Constants for some standard parts */
88
+#define AT93C46_ORG8_ADRSIZE	7
89
+#define AT93C46_ORG8_DATASIZE	8
90
+#define AT93C46_ORG16_ADRSIZE	6
91
+#define AT93C46_ORG16_DATASIZE	16
92
+#define AT93C46_UDELAY		1
93
+#define AT93C56_ORG8_ADRSIZE	9
94
+#define AT93C56_ORG8_DATASIZE	8
95
+#define AT93C56_ORG16_ADRSIZE	8
96
+#define AT93C56_ORG16_DATASIZE	16
97
+#define AT93C56_UDELAY		1
98
+
99
+extern unsigned long threewire_read ( struct threewire *three,
100
+				      unsigned long address );
101
+
102
+#endif /* _GPXE_NVS_THREEWIRE_H */

Загрузка…
Отмена
Сохранить