Commit | Line | Data |
---|---|---|
8fc8598e JC |
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 | ||
ffae3055 | 17 | We want to thank the Authors of those projects and the Ndiswrapper |
8fc8598e JC |
18 | project Authors. |
19 | */ | |
20 | ||
21 | #include "r8180_93cx6.h" | |
22 | ||
23 | void eprom_cs(struct net_device *dev, short bit) | |
24 | { | |
25 | if(bit) | |
26 | write_nic_byte_E(dev, EPROM_CMD, | |
27 | (1<<EPROM_CS_SHIFT) | \ | |
28 | read_nic_byte_E(dev, EPROM_CMD)); //enable EPROM | |
29 | else | |
30 | write_nic_byte_E(dev, EPROM_CMD, read_nic_byte_E(dev, EPROM_CMD)\ | |
31 | &~(1<<EPROM_CS_SHIFT)); //disable EPROM | |
32 | ||
33 | force_pci_posting(dev); | |
34 | udelay(EPROM_DELAY); | |
35 | } | |
36 | ||
37 | ||
38 | void eprom_ck_cycle(struct net_device *dev) | |
39 | { | |
40 | write_nic_byte_E(dev, EPROM_CMD, | |
41 | (1<<EPROM_CK_SHIFT) | read_nic_byte_E(dev,EPROM_CMD)); | |
42 | force_pci_posting(dev); | |
43 | udelay(EPROM_DELAY); | |
44 | write_nic_byte_E(dev, EPROM_CMD, | |
45 | read_nic_byte_E(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT)); | |
46 | force_pci_posting(dev); | |
47 | udelay(EPROM_DELAY); | |
48 | } | |
49 | ||
50 | ||
51 | void eprom_w(struct net_device *dev,short bit) | |
52 | { | |
53 | if(bit) | |
54 | write_nic_byte_E(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \ | |
55 | read_nic_byte_E(dev,EPROM_CMD)); | |
56 | else | |
57 | write_nic_byte_E(dev, EPROM_CMD, read_nic_byte_E(dev,EPROM_CMD)\ | |
58 | &~(1<<EPROM_W_SHIFT)); | |
59 | ||
60 | force_pci_posting(dev); | |
61 | udelay(EPROM_DELAY); | |
62 | } | |
63 | ||
64 | ||
65 | short eprom_r(struct net_device *dev) | |
66 | { | |
67 | short bit; | |
68 | ||
69 | bit=(read_nic_byte_E(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) ); | |
70 | udelay(EPROM_DELAY); | |
71 | ||
72 | if(bit) return 1; | |
73 | return 0; | |
74 | } | |
75 | ||
76 | ||
77 | void eprom_send_bits_string(struct net_device *dev, short b[], int len) | |
78 | { | |
79 | int i; | |
80 | ||
81 | for(i=0; i<len; i++){ | |
82 | eprom_w(dev, b[i]); | |
83 | eprom_ck_cycle(dev); | |
84 | } | |
85 | } | |
86 | ||
87 | ||
88 | u32 eprom_read(struct net_device *dev, u32 addr) | |
89 | { | |
90 | struct r8192_priv *priv = ieee80211_priv(dev); | |
91 | short read_cmd[]={1,1,0}; | |
92 | short addr_str[8]; | |
93 | int i; | |
94 | int addr_len; | |
95 | u32 ret; | |
96 | ||
97 | ret=0; | |
98 | //enable EPROM programming | |
99 | write_nic_byte_E(dev, EPROM_CMD, | |
100 | (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT)); | |
101 | force_pci_posting(dev); | |
102 | udelay(EPROM_DELAY); | |
103 | ||
104 | if (priv->epromtype==EPROM_93c56){ | |
105 | addr_str[7]=addr & 1; | |
106 | addr_str[6]=addr & (1<<1); | |
107 | addr_str[5]=addr & (1<<2); | |
108 | addr_str[4]=addr & (1<<3); | |
109 | addr_str[3]=addr & (1<<4); | |
110 | addr_str[2]=addr & (1<<5); | |
111 | addr_str[1]=addr & (1<<6); | |
112 | addr_str[0]=addr & (1<<7); | |
113 | addr_len=8; | |
114 | }else{ | |
115 | addr_str[5]=addr & 1; | |
116 | addr_str[4]=addr & (1<<1); | |
117 | addr_str[3]=addr & (1<<2); | |
118 | addr_str[2]=addr & (1<<3); | |
119 | addr_str[1]=addr & (1<<4); | |
120 | addr_str[0]=addr & (1<<5); | |
121 | addr_len=6; | |
122 | } | |
123 | eprom_cs(dev, 1); | |
124 | eprom_ck_cycle(dev); | |
125 | eprom_send_bits_string(dev, read_cmd, 3); | |
126 | eprom_send_bits_string(dev, addr_str, addr_len); | |
127 | ||
128 | //keep chip pin D to low state while reading. | |
129 | //I'm unsure if it is necessary, but anyway shouldn't hurt | |
130 | eprom_w(dev, 0); | |
131 | ||
132 | for(i=0;i<16;i++){ | |
133 | //eeprom needs a clk cycle between writing opcode&adr | |
134 | //and reading data. (eeprom outs a dummy 0) | |
135 | eprom_ck_cycle(dev); | |
136 | ret |= (eprom_r(dev)<<(15-i)); | |
137 | } | |
138 | ||
139 | eprom_cs(dev, 0); | |
140 | eprom_ck_cycle(dev); | |
141 | ||
142 | //disable EPROM programming | |
143 | write_nic_byte_E(dev, EPROM_CMD, | |
144 | (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT)); | |
145 | return ret; | |
146 | } |