Linux-libre 4.14.68-gnu
[librecmc/linux-libre.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 }