1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include "wl1251.h"
23#include "reg.h"
24#include "io.h"
25
26
27static enum wl12xx_acx_int_reg wl1251_io_reg_table[ACX_REG_TABLE_LEN] = {
28 [ACX_REG_INTERRUPT_TRIG] = (REGISTERS_BASE + 0x0474),
29 [ACX_REG_INTERRUPT_TRIG_H] = (REGISTERS_BASE + 0x0478),
30 [ACX_REG_INTERRUPT_MASK] = (REGISTERS_BASE + 0x0494),
31 [ACX_REG_HINT_MASK_SET] = (REGISTERS_BASE + 0x0498),
32 [ACX_REG_HINT_MASK_CLR] = (REGISTERS_BASE + 0x049C),
33 [ACX_REG_INTERRUPT_NO_CLEAR] = (REGISTERS_BASE + 0x04B0),
34 [ACX_REG_INTERRUPT_CLEAR] = (REGISTERS_BASE + 0x04A4),
35 [ACX_REG_INTERRUPT_ACK] = (REGISTERS_BASE + 0x04A8),
36 [ACX_REG_SLV_SOFT_RESET] = (REGISTERS_BASE + 0x0000),
37 [ACX_REG_EE_START] = (REGISTERS_BASE + 0x080C),
38 [ACX_REG_ECPU_CONTROL] = (REGISTERS_BASE + 0x0804)
39};
40
41static int wl1251_translate_reg_addr(struct wl1251 *wl, int addr)
42{
43
44
45
46 if (addr < REGISTERS_BASE) {
47
48 if (addr >= ACX_REG_TABLE_LEN) {
49 wl1251_error("address out of range (%d)", addr);
50 return -EINVAL;
51 }
52 addr = wl1251_io_reg_table[addr];
53 }
54
55 return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
56}
57
58static int wl1251_translate_mem_addr(struct wl1251 *wl, int addr)
59{
60 return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
61}
62
63void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len)
64{
65 int physical;
66
67 physical = wl1251_translate_mem_addr(wl, addr);
68
69 wl->if_ops->read(wl, physical, buf, len);
70}
71
72void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len)
73{
74 int physical;
75
76 physical = wl1251_translate_mem_addr(wl, addr);
77
78 wl->if_ops->write(wl, physical, buf, len);
79}
80
81u32 wl1251_mem_read32(struct wl1251 *wl, int addr)
82{
83 return wl1251_read32(wl, wl1251_translate_mem_addr(wl, addr));
84}
85
86void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val)
87{
88 wl1251_write32(wl, wl1251_translate_mem_addr(wl, addr), val);
89}
90
91u32 wl1251_reg_read32(struct wl1251 *wl, int addr)
92{
93 return wl1251_read32(wl, wl1251_translate_reg_addr(wl, addr));
94}
95
96void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val)
97{
98 wl1251_write32(wl, wl1251_translate_reg_addr(wl, addr), val);
99}
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134void wl1251_set_partition(struct wl1251 *wl,
135 u32 mem_start, u32 mem_size,
136 u32 reg_start, u32 reg_size)
137{
138 struct wl1251_partition partition[2];
139
140 wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
141 mem_start, mem_size);
142 wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
143 reg_start, reg_size);
144
145
146
147 if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
148 wl1251_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
149 " address range. Truncating partition[0].");
150 mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
151 wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
152 mem_start, mem_size);
153 wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
154 reg_start, reg_size);
155 }
156
157 if ((mem_start < reg_start) &&
158 ((mem_start + mem_size) > reg_start)) {
159
160
161 wl1251_debug(DEBUG_SPI, "End of partition[0] is "
162 "overlapping partition[1]. Adjusted.");
163 mem_size = reg_start - mem_start;
164 wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
165 mem_start, mem_size);
166 wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
167 reg_start, reg_size);
168 } else if ((reg_start < mem_start) &&
169 ((reg_start + reg_size) > mem_start)) {
170
171
172 wl1251_debug(DEBUG_SPI, "End of partition[1] is"
173 " overlapping partition[0]. Adjusted.");
174 reg_size = mem_start - reg_start;
175 wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
176 mem_start, mem_size);
177 wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
178 reg_start, reg_size);
179 }
180
181 partition[0].start = mem_start;
182 partition[0].size = mem_size;
183 partition[1].start = reg_start;
184 partition[1].size = reg_size;
185
186 wl->physical_mem_addr = mem_start;
187 wl->physical_reg_addr = reg_start;
188
189 wl->virtual_mem_addr = 0;
190 wl->virtual_reg_addr = mem_size;
191
192 wl->if_ops->write(wl, HW_ACCESS_PART0_SIZE_ADDR, partition,
193 sizeof(partition));
194}
195