Commit | Line | Data |
---|---|---|
ecdfa446 GKH |
1 | /* |
2 | This files contains card eeprom (93c46 or 93c56) programming routines, | |
3 | memory is addressed by 16 bits words. | |
4 | ||
5 | This is part of rtl8180 OpenSource driver. | |
6 | Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it> | |
7 | Released under the terms of GPL (General Public Licence) | |
8 | ||
9 | Parts of this driver are based on the GPL part of the | |
10 | official realtek driver. | |
11 | ||
12 | Parts of this driver are based on the rtl8180 driver skeleton | |
13 | from Patric Schenke & Andres Salomon. | |
14 | ||
15 | Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. | |
16 | ||
17 | We want to tanks the Authors of those projects and the Ndiswrapper | |
18 | project Authors. | |
19 | */ | |
20 | ||
21 | #include "r8180_93cx6.h" | |
22 | ||
5e1ad18a | 23 | static void eprom_cs(struct net_device *dev, short bit) |
ecdfa446 | 24 | { |
01823a13 | 25 | if (bit) |
ecdfa446 | 26 | write_nic_byte(dev, EPROM_CMD, |
207b58fb | 27 | (1<<EPROM_CS_SHIFT) | |
ecdfa446 GKH |
28 | read_nic_byte(dev, EPROM_CMD)); //enable EPROM |
29 | else | |
207b58fb | 30 | write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD) |
ecdfa446 GKH |
31 | &~(1<<EPROM_CS_SHIFT)); //disable EPROM |
32 | ||
ecdfa446 GKH |
33 | udelay(EPROM_DELAY); |
34 | } | |
35 | ||
36 | ||
5e1ad18a | 37 | static void eprom_ck_cycle(struct net_device *dev) |
ecdfa446 GKH |
38 | { |
39 | write_nic_byte(dev, EPROM_CMD, | |
01823a13 | 40 | (1<<EPROM_CK_SHIFT) | read_nic_byte(dev, EPROM_CMD)); |
ecdfa446 GKH |
41 | udelay(EPROM_DELAY); |
42 | write_nic_byte(dev, EPROM_CMD, | |
01823a13 | 43 | read_nic_byte(dev, EPROM_CMD) & ~(1<<EPROM_CK_SHIFT)); |
ecdfa446 GKH |
44 | udelay(EPROM_DELAY); |
45 | } | |
46 | ||
47 | ||
01823a13 | 48 | static void eprom_w(struct net_device *dev, short bit) |
ecdfa446 | 49 | { |
01823a13 | 50 | if (bit) |
207b58fb | 51 | write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | |
01823a13 | 52 | read_nic_byte(dev, EPROM_CMD)); |
ecdfa446 | 53 | else |
207b58fb | 54 | write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD) |
ecdfa446 GKH |
55 | &~(1<<EPROM_W_SHIFT)); |
56 | ||
ecdfa446 GKH |
57 | udelay(EPROM_DELAY); |
58 | } | |
59 | ||
60 | ||
5e1ad18a | 61 | static short eprom_r(struct net_device *dev) |
ecdfa446 GKH |
62 | { |
63 | short bit; | |
64 | ||
01823a13 | 65 | bit = (read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT)); |
ecdfa446 GKH |
66 | udelay(EPROM_DELAY); |
67 | ||
01823a13 TS |
68 | if (bit) |
69 | return 1; | |
ecdfa446 GKH |
70 | return 0; |
71 | } | |
72 | ||
73 | ||
5e1ad18a | 74 | static void eprom_send_bits_string(struct net_device *dev, short b[], int len) |
ecdfa446 GKH |
75 | { |
76 | int i; | |
77 | ||
01823a13 | 78 | for (i = 0; i < len; i++) { |
ecdfa446 GKH |
79 | eprom_w(dev, b[i]); |
80 | eprom_ck_cycle(dev); | |
81 | } | |
82 | } | |
83 | ||
84 | ||
85 | u32 eprom_read(struct net_device *dev, u32 addr) | |
86 | { | |
87 | struct r8192_priv *priv = ieee80211_priv(dev); | |
01823a13 | 88 | short read_cmd[] = {1, 1, 0}; |
ecdfa446 GKH |
89 | short addr_str[8]; |
90 | int i; | |
91 | int addr_len; | |
92 | u32 ret; | |
93 | ||
01823a13 | 94 | ret = 0; |
ecdfa446 GKH |
95 | //enable EPROM programming |
96 | write_nic_byte(dev, EPROM_CMD, | |
97 | (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT)); | |
ecdfa446 GKH |
98 | udelay(EPROM_DELAY); |
99 | ||
01823a13 TS |
100 | if (priv->epromtype == EPROM_93c56) { |
101 | addr_str[7] = addr & 1; | |
102 | addr_str[6] = addr & (1<<1); | |
103 | addr_str[5] = addr & (1<<2); | |
104 | addr_str[4] = addr & (1<<3); | |
105 | addr_str[3] = addr & (1<<4); | |
106 | addr_str[2] = addr & (1<<5); | |
107 | addr_str[1] = addr & (1<<6); | |
108 | addr_str[0] = addr & (1<<7); | |
109 | addr_len = 8; | |
110 | } else { | |
111 | addr_str[5] = addr & 1; | |
112 | addr_str[4] = addr & (1<<1); | |
113 | addr_str[3] = addr & (1<<2); | |
114 | addr_str[2] = addr & (1<<3); | |
115 | addr_str[1] = addr & (1<<4); | |
116 | addr_str[0] = addr & (1<<5); | |
117 | addr_len = 6; | |
ecdfa446 GKH |
118 | } |
119 | eprom_cs(dev, 1); | |
120 | eprom_ck_cycle(dev); | |
121 | eprom_send_bits_string(dev, read_cmd, 3); | |
122 | eprom_send_bits_string(dev, addr_str, addr_len); | |
123 | ||
124 | //keep chip pin D to low state while reading. | |
125 | //I'm unsure if it is necessary, but anyway shouldn't hurt | |
126 | eprom_w(dev, 0); | |
127 | ||
01823a13 | 128 | for (i = 0; i < 16; i++) { |
ecdfa446 GKH |
129 | //eeprom needs a clk cycle between writing opcode&adr |
130 | //and reading data. (eeprom outs a dummy 0) | |
131 | eprom_ck_cycle(dev); | |
132 | ret |= (eprom_r(dev)<<(15-i)); | |
133 | } | |
134 | ||
135 | eprom_cs(dev, 0); | |
136 | eprom_ck_cycle(dev); | |
137 | ||
138 | //disable EPROM programming | |
139 | write_nic_byte(dev, EPROM_CMD, | |
140 | (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT)); | |
141 | return ret; | |
142 | } |