1 //------------------------------------------------------------------------------
2 // Copyright (c) 2004-2010 Atheros Communications Inc.
3 // All rights reserved.
7 // Permission to use, copy, modify, and/or distribute this software for any
8 // purpose with or without fee is hereby granted, provided that the above
9 // copyright notice and this permission notice appear in all copies.
11 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 // Author(s): ="Atheros"
22 //------------------------------------------------------------------------------
25 #include "ar6000_drv.h"
29 #include "AR6002/hw2.0/hw/gpio_reg.h"
30 #include "hw/si_reg.h"
36 #define MAX_FILENAME 1023
37 #define EEPROM_WAIT_LIMIT 16
39 #define HOST_INTEREST_ITEM_ADDRESS(item) \
40 (AR6002_HOST_INTEREST_ITEM_ADDRESS(item))
46 #define ATH_SOFT_MAC_TMP_BUF_LEN 64
47 unsigned char mac_addr
[ATH_MAC_LEN
];
48 unsigned char soft_mac_tmp_buf
[ATH_SOFT_MAC_TMP_BUF_LEN
];
56 static u8 eeprom_data
[EEPROM_SZ
];
57 static u32 sys_sleep_reg
;
58 static struct hif_device
*p_bmi_device
;
66 wmic_ether_aton(const char *orig
, u8
*eth
)
72 for(bufp
= orig
; *bufp
!= '\0'; ++bufp
) {
76 h
= hex_to_bin(*bufp
++);
79 printk("%s: MAC value is invalid\n", __FUNCTION__
);
83 l
= hex_to_bin(*bufp
++);
85 printk("%s: MAC value is invalid\n", __FUNCTION__
);
91 eth
[i
] = (unsigned char) (val
& 0377);
92 if(++i
== ATH_MAC_LEN
) {
93 /* That's it. Any trailing junk? */
106 update_mac(unsigned char *eeprom
, int size
, unsigned char *macaddr
)
109 u16
*ptr
= (u16
*)(eeprom
+4);
112 memcpy(eeprom
+10,macaddr
,6);
117 for (i
=0; i
<size
; i
+=2) {
120 checksum
= ~checksum
;
122 ptr
= (u16
*)(eeprom
+4);
128 /* Read a Target register and return its value. */
130 BMI_read_reg(u32 address
, u32
*pvalue
)
132 BMIReadSOCRegister(p_bmi_device
, address
, pvalue
);
135 /* Write a value to a Target register. */
137 BMI_write_reg(u32 address
, u32 value
)
139 BMIWriteSOCRegister(p_bmi_device
, address
, value
);
142 /* Read Target memory word and return its value. */
144 BMI_read_mem(u32 address
, u32
*pvalue
)
146 BMIReadMemory(p_bmi_device
, address
, (u8
*)(pvalue
), 4);
149 /* Write a word to a Target memory. */
151 BMI_write_mem(u32 address
, u8
*p_data
, u32 sz
)
153 BMIWriteMemory(p_bmi_device
, address
, (u8
*)(p_data
), sz
);
157 * Enable and configure the Target's Serial Interface
158 * so we can access the EEPROM.
161 enable_SI(struct hif_device
*p_device
)
165 printk("%s\n", __FUNCTION__
);
167 p_bmi_device
= p_device
;
169 BMI_read_reg(RTC_BASE_ADDRESS
+SYSTEM_SLEEP_OFFSET
, &sys_sleep_reg
);
170 BMI_write_reg(RTC_BASE_ADDRESS
+SYSTEM_SLEEP_OFFSET
, SYSTEM_SLEEP_DISABLE_SET(1)); //disable system sleep temporarily
172 BMI_read_reg(RTC_BASE_ADDRESS
+CLOCK_CONTROL_OFFSET
, ®val
);
173 regval
&= ~CLOCK_CONTROL_SI0_CLK_MASK
;
174 BMI_write_reg(RTC_BASE_ADDRESS
+CLOCK_CONTROL_OFFSET
, regval
);
176 BMI_read_reg(RTC_BASE_ADDRESS
+RESET_CONTROL_OFFSET
, ®val
);
177 regval
&= ~RESET_CONTROL_SI0_RST_MASK
;
178 BMI_write_reg(RTC_BASE_ADDRESS
+RESET_CONTROL_OFFSET
, regval
);
181 BMI_read_reg(GPIO_BASE_ADDRESS
+GPIO_PIN0_OFFSET
, ®val
);
182 regval
&= ~GPIO_PIN0_CONFIG_MASK
;
183 BMI_write_reg(GPIO_BASE_ADDRESS
+GPIO_PIN0_OFFSET
, regval
);
185 BMI_read_reg(GPIO_BASE_ADDRESS
+GPIO_PIN1_OFFSET
, ®val
);
186 regval
&= ~GPIO_PIN1_CONFIG_MASK
;
187 BMI_write_reg(GPIO_BASE_ADDRESS
+GPIO_PIN1_OFFSET
, regval
);
189 /* SI_CONFIG = 0x500a6; */
190 regval
= SI_CONFIG_BIDIR_OD_DATA_SET(1) |
191 SI_CONFIG_I2C_SET(1) |
192 SI_CONFIG_POS_SAMPLE_SET(1) |
193 SI_CONFIG_INACTIVE_CLK_SET(1) |
194 SI_CONFIG_INACTIVE_DATA_SET(1) |
195 SI_CONFIG_DIVIDER_SET(6);
196 BMI_write_reg(SI_BASE_ADDRESS
+SI_CONFIG_OFFSET
, regval
);
205 printk("%s\n", __FUNCTION__
);
207 BMI_write_reg(RTC_BASE_ADDRESS
+RESET_CONTROL_OFFSET
, RESET_CONTROL_SI0_RST_MASK
);
208 BMI_read_reg(RTC_BASE_ADDRESS
+CLOCK_CONTROL_OFFSET
, ®val
);
209 regval
|= CLOCK_CONTROL_SI0_CLK_MASK
;
210 BMI_write_reg(RTC_BASE_ADDRESS
+CLOCK_CONTROL_OFFSET
, regval
);//Gate SI0 clock
211 BMI_write_reg(RTC_BASE_ADDRESS
+SYSTEM_SLEEP_OFFSET
, sys_sleep_reg
); //restore system sleep setting
215 * Tell the Target to start an 8-byte read from EEPROM,
216 * putting the results in Target RX_DATA registers.
219 request_8byte_read(int offset
)
223 // printk("%s: request_8byte_read from offset 0x%x\n", __FUNCTION__, offset);
226 /* SI_TX_DATA0 = read from offset */
228 ((offset
& 0xff)<<8) |
229 (0xa0 | ((offset
& 0xff00)>>7));
231 BMI_write_reg(SI_BASE_ADDRESS
+SI_TX_DATA0_OFFSET
, regval
);
233 regval
= SI_CS_START_SET(1) |
234 SI_CS_RX_CNT_SET(8) |
236 BMI_write_reg(SI_BASE_ADDRESS
+SI_CS_OFFSET
, regval
);
240 * Tell the Target to start a 4-byte write to EEPROM,
241 * writing values from Target TX_DATA registers.
244 request_4byte_write(int offset
, u32 data
)
248 printk("%s: request_4byte_write (0x%x) to offset 0x%x\n", __FUNCTION__
, data
, offset
);
250 /* SI_TX_DATA0 = write data to offset */
251 regval
= ((data
& 0xffff) <<16) |
252 ((offset
& 0xff)<<8) |
253 (0xa0 | ((offset
& 0xff00)>>7));
254 BMI_write_reg(SI_BASE_ADDRESS
+SI_TX_DATA0_OFFSET
, regval
);
257 BMI_write_reg(SI_BASE_ADDRESS
+SI_TX_DATA1_OFFSET
, regval
);
259 regval
= SI_CS_START_SET(1) |
260 SI_CS_RX_CNT_SET(0) |
262 BMI_write_reg(SI_BASE_ADDRESS
+SI_CS_OFFSET
, regval
);
266 * Check whether or not an EEPROM request that was started
267 * earlier has completed yet.
270 request_in_progress(void)
274 /* Wait for DONE_INT in SI_CS */
275 BMI_read_reg(SI_BASE_ADDRESS
+SI_CS_OFFSET
, ®val
);
277 // printk("%s: request in progress SI_CS=0x%x\n", __FUNCTION__, regval);
278 if (regval
& SI_CS_DONE_ERR_MASK
) {
279 printk("%s: EEPROM signaled ERROR (0x%x)\n", __FUNCTION__
, regval
);
282 return (!(regval
& SI_CS_DONE_INT_MASK
));
286 * try to detect the type of EEPROM,16bit address or 8bit address
289 static void eeprom_type_detect(void)
294 request_8byte_read(0x100);
295 /* Wait for DONE_INT in SI_CS */
297 BMI_read_reg(SI_BASE_ADDRESS
+SI_CS_OFFSET
, ®val
);
298 if (regval
& SI_CS_DONE_ERR_MASK
) {
299 printk("%s: ERROR : address type was wrongly set\n", __FUNCTION__
);
302 if (i
++ == EEPROM_WAIT_LIMIT
) {
303 printk("%s: EEPROM not responding\n", __FUNCTION__
);
305 } while(!(regval
& SI_CS_DONE_INT_MASK
));
309 * Extract the results of a completed EEPROM Read request
310 * and return them to the caller.
313 read_8byte_results(u32
*data
)
315 /* Read SI_RX_DATA0 and SI_RX_DATA1 */
316 BMI_read_reg(SI_BASE_ADDRESS
+SI_RX_DATA0_OFFSET
, &data
[0]);
317 BMI_read_reg(SI_BASE_ADDRESS
+SI_RX_DATA1_OFFSET
, &data
[1]);
322 * Wait for a previously started command to complete.
323 * Timeout if the command is takes "too long".
326 wait_for_eeprom_completion(void)
330 while (request_in_progress()) {
331 if (i
++ == EEPROM_WAIT_LIMIT
) {
332 printk("%s: EEPROM not responding\n", __FUNCTION__
);
338 * High-level function which starts an 8-byte read,
339 * waits for it to complete, and returns the result.
342 fetch_8bytes(int offset
, u32
*data
)
344 request_8byte_read(offset
);
345 wait_for_eeprom_completion();
346 read_8byte_results(data
);
348 /* Clear any pending intr */
349 BMI_write_reg(SI_BASE_ADDRESS
+SI_CS_OFFSET
, SI_CS_DONE_INT_MASK
);
353 * High-level function which starts a 4-byte write,
354 * and waits for it to complete.
357 commit_4bytes(int offset
, u32 data
)
359 request_4byte_write(offset
, data
);
360 wait_for_eeprom_completion();