GNU Linux-libre 4.9.301-gnu1
[releases.git] / drivers / staging / rtl8192u / r8180_93cx6.c
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  <andrea.merello@gmail.com>
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 thank the Authors of those projects and the Ndiswrapper
18    project Authors.
19 */
20
21 #include "r8180_93cx6.h"
22
23 static void eprom_cs(struct net_device *dev, short bit)
24 {
25         u8 cmdreg;
26         int err;
27
28         err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
29         if (err)
30                 return;
31         if (bit)
32                 /* enable EPROM */
33                 write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CS_BIT);
34         else
35                 /* disable EPROM */
36                 write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CS_BIT);
37
38         force_pci_posting(dev);
39         udelay(EPROM_DELAY);
40 }
41
42
43 static void eprom_ck_cycle(struct net_device *dev)
44 {
45         u8 cmdreg;
46         int err;
47
48         err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
49         if (err)
50                 return;
51         write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_CK_BIT);
52         force_pci_posting(dev);
53         udelay(EPROM_DELAY);
54
55         read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
56         write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_CK_BIT);
57         force_pci_posting(dev);
58         udelay(EPROM_DELAY);
59 }
60
61
62 static void eprom_w(struct net_device *dev, short bit)
63 {
64         u8 cmdreg;
65         int err;
66
67         err = read_nic_byte_E(dev, EPROM_CMD, &cmdreg);
68         if (err)
69                 return;
70         if (bit)
71                 write_nic_byte_E(dev, EPROM_CMD, cmdreg | EPROM_W_BIT);
72         else
73                 write_nic_byte_E(dev, EPROM_CMD, cmdreg & ~EPROM_W_BIT);
74
75         force_pci_posting(dev);
76         udelay(EPROM_DELAY);
77 }
78
79
80 static short eprom_r(struct net_device *dev)
81 {
82         u8 bit;
83         int err;
84
85         err = read_nic_byte_E(dev, EPROM_CMD, &bit);
86         if (err)
87                 return err;
88
89         udelay(EPROM_DELAY);
90
91         if (bit & EPROM_R_BIT)
92                 return 1;
93
94         return 0;
95 }
96
97
98 static void eprom_send_bits_string(struct net_device *dev, short b[], int len)
99 {
100         int i;
101
102         for (i = 0; i < len; i++) {
103                 eprom_w(dev, b[i]);
104                 eprom_ck_cycle(dev);
105         }
106 }
107
108
109 int eprom_read(struct net_device *dev, u32 addr)
110 {
111         struct r8192_priv *priv = ieee80211_priv(dev);
112         short read_cmd[] = {1, 1, 0};
113         short addr_str[8];
114         int i;
115         int addr_len;
116         u32 ret;
117         int err;
118
119         ret = 0;
120         /* enable EPROM programming */
121         write_nic_byte_E(dev, EPROM_CMD,
122                        (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
123         force_pci_posting(dev);
124         udelay(EPROM_DELAY);
125
126         if (priv->epromtype == EPROM_93c56) {
127                 addr_str[7] = addr & 1;
128                 addr_str[6] = addr & (1<<1);
129                 addr_str[5] = addr & (1<<2);
130                 addr_str[4] = addr & (1<<3);
131                 addr_str[3] = addr & (1<<4);
132                 addr_str[2] = addr & (1<<5);
133                 addr_str[1] = addr & (1<<6);
134                 addr_str[0] = addr & (1<<7);
135                 addr_len = 8;
136         } else {
137                 addr_str[5] = addr & 1;
138                 addr_str[4] = addr & (1<<1);
139                 addr_str[3] = addr & (1<<2);
140                 addr_str[2] = addr & (1<<3);
141                 addr_str[1] = addr & (1<<4);
142                 addr_str[0] = addr & (1<<5);
143                 addr_len = 6;
144         }
145         eprom_cs(dev, 1);
146         eprom_ck_cycle(dev);
147         eprom_send_bits_string(dev, read_cmd, 3);
148         eprom_send_bits_string(dev, addr_str, addr_len);
149
150         /*
151          * keep chip pin D to low state while reading.
152          * I'm unsure if it is necessary, but anyway shouldn't hurt
153          */
154         eprom_w(dev, 0);
155
156         for (i = 0; i < 16; i++) {
157                 /* eeprom needs a clk cycle between writing opcode&adr
158                  * and reading data. (eeprom outs a dummy 0)
159                  */
160                 eprom_ck_cycle(dev);
161                 err = eprom_r(dev);
162                 if (err < 0)
163                         return err;
164
165                 ret |= err<<(15-i);
166         }
167
168         eprom_cs(dev, 0);
169         eprom_ck_cycle(dev);
170
171         /* disable EPROM programming */
172         write_nic_byte_E(dev, EPROM_CMD,
173                        (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
174         return ret;
175 }