hif/usb_api: remove dup code - ep6 fix
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / target / hif / usb_api_main_patch.c
1
2 #include "usb_defs.h"
3 #include "usb_type.h"
4 #include "usb_pre.h"
5 #include "usb_extr.h"
6 #include "usb_std.h"
7 #include "reg_defs.h"
8 #include "athos_api.h"
9 #include "usbfifo_api.h"
10
11 #include "sys_cfg.h"
12
13 #define USB_EP4_MAX_PKT_SIZE bUSB_EP_MAX_PKT_SIZE_64
14 #define USB_EP3_MAX_PKT_SIZE bUSB_EP_MAX_PKT_SIZE_64
15
16 extern USB_FIFO_CONFIG usbFifoConf;
17 extern Action eUsbCxFinishAction;
18
19 void cold_reboot(void)
20 {
21         A_PRINTF("Cold reboot initiated.");
22 #if defined(PROJECT_MAGPIE)
23         HAL_WORD_REG_WRITE(WATCH_DOG_MAGIC_PATTERN_ADDR, 0);
24 #elif defined(PROJECT_K2)
25         HAL_WORD_REG_WRITE(MAGPIE_REG_RST_STATUS_ADDR, 0);
26 #endif /* #if defined(PROJECT_MAGPIE) */
27         A_USB_JUMP_BOOT();
28 }
29
30 /*
31  * support more than 64 bytes command on ep3
32  */
33 void usb_status_in_patch(void)
34 {
35         uint16_t count;
36         uint16_t remainder;
37         uint16_t reg_buf_len;
38         static uint16_t buf_len;
39         static VBUF *evntbuf = NULL;
40         static volatile uint32_t *regaddr;
41         static BOOLEAN cmd_is_new = TRUE;
42         BOOLEAN cmd_end = FALSE;
43
44         if (cmd_is_new) {
45                 evntbuf = usbFifoConf.get_event_buf();
46                 if (evntbuf != NULL) {
47                         regaddr = (uint32_t *)VBUF_GET_DATA_ADDR(evntbuf);
48                         buf_len = evntbuf->buf_length;
49                 } else {
50                         mUSB_STATUS_IN_INT_DISABLE();
51                         return;
52                 }
53
54                 cmd_is_new = FALSE;
55         }
56
57         if (buf_len > USB_EP3_MAX_PKT_SIZE) {
58                 reg_buf_len = USB_EP3_MAX_PKT_SIZE;
59                 buf_len -= USB_EP3_MAX_PKT_SIZE;
60         }
61         /* TODO: 64 bytes...
62          * controller supposed will take care of zero-length? */
63         else {
64                 reg_buf_len = buf_len;
65                 cmd_end = TRUE;
66         }
67
68         /* INT use EP3 */
69         for (count = 0; count < (reg_buf_len / 4); count++)
70         {
71                 USB_WORD_REG_WRITE(ZM_EP3_DATA_OFFSET, *regaddr);
72                 regaddr++;
73         }
74
75         remainder = reg_buf_len % 4;
76
77         if (remainder) {
78                 switch(remainder) {
79                 case 3:
80                         USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x7);
81                         break;
82                 case 2:
83                         USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x3);
84                         break;
85                 case 1:
86                         USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0x1);
87                         break;
88                 }
89
90                 USB_WORD_REG_WRITE(ZM_EP3_DATA_OFFSET, *regaddr);
91
92                 /* Restore CBus FIFO size to word size */
93                 USB_WORD_REG_WRITE(ZM_CBUS_FIFO_SIZE_OFFSET, 0xF);
94         }
95
96         mUSB_EP3_XFER_DONE();
97
98         if (evntbuf != NULL && cmd_end) {
99                 usbFifoConf.send_event_done(evntbuf);
100                 cmd_is_new = TRUE;
101         }
102 }
103
104 /*
105  * support more than 64 bytes command on ep4 
106  */
107 void usb_reg_out_patch(void)
108 {
109         uint16_t usbfifolen;
110         uint16_t ii;
111         uint32_t ep4_data;
112         static volatile uint32_t *regaddr;
113         static uint16_t cmd_len;
114         static VBUF *buf;
115         BOOLEAN cmd_is_last = FALSE;
116         static BOOLEAN cmd_is_new = TRUE;
117
118         /* get the size of this transcation */
119         usbfifolen = USB_BYTE_REG_READ(ZM_EP4_BYTE_COUNT_LOW_OFFSET);
120
121         if (usbfifolen > USB_EP4_MAX_PKT_SIZE) {
122                 A_PRINTF("EP4 FIFO Bug? Buffer is too big: %x\n", usbfifolen);
123                 cold_reboot();
124         }
125
126         /* check is command is new */
127         if(cmd_is_new) {
128
129                 buf = usbFifoConf.get_command_buf();
130                 cmd_len = 0;
131
132                 if(!buf) {
133                         A_PRINTF("%s: Filed to get new buffer.\n", __func__);
134                         goto err;
135                 }
136
137                 /* copy free, assignment buffer of the address */
138                 regaddr = (uint32_t *)buf->desc_list->buf_addr;
139
140                 cmd_is_new = FALSE;
141         }
142
143         /* just in case, suppose should not happen */
144         if(!buf)
145                 goto err;
146
147         /* if size is smaller, this is the last command!
148          * zero-length supposed should be set through 0x27/bit7->0x19/bit4, not here
149          */
150         if(usbfifolen < USB_EP4_MAX_PKT_SIZE)
151                 cmd_is_last = TRUE;
152
153         /* accumulate the size */
154         cmd_len += usbfifolen;
155
156         if (cmd_len > buf->desc_list->buf_size) {
157                 A_PRINTF("%s: Data length on EP4 FIFO is bigger as "
158                          "allocated buffer data! Drop it!\n", __func__);
159                 goto err;
160         }
161
162         /* round it to alignment */
163         if(usbfifolen % 4)
164                 usbfifolen = (usbfifolen >> 2) + 1;
165         else
166                 usbfifolen = usbfifolen >> 2;
167
168         /* retrieve the data from fifo */
169         for(ii = 0; ii < usbfifolen; ii++) {
170                 /* read fifo data out */
171                 ep4_data = USB_WORD_REG_READ(ZM_EP4_DATA_OFFSET);
172                 *regaddr = ep4_data;
173                 regaddr++;
174         }
175
176         /* if this is the last command, callback to HTC */
177         if (cmd_is_last) {
178                 buf->desc_list->next_desc = NULL;
179                 buf->desc_list->data_offset = 0;
180                 buf->desc_list->data_size = cmd_len;
181                 buf->desc_list->control = 0;
182                 buf->next_buf = NULL;
183                 buf->buf_length = cmd_len;
184
185                 usbFifoConf.recv_command(buf);
186
187                 cmd_is_new = TRUE;
188         }
189
190         goto done;
191 err:
192         /* we might get no command buffer here?
193          * but if we return here, the ep4 fifo will be lock out,
194          * so that we still read them out but just drop it? */
195         for(ii = 0; ii < usbfifolen; ii++)
196                 ep4_data = USB_WORD_REG_READ(ZM_EP4_DATA_OFFSET);
197
198 done:
199         /* mUSB_STATUS_IN_INT_ENABLE(); */
200         ;
201 }
202
203 /*
204  * usb1.1 ep6 fix
205  * TODO:
206  * - theoretically ep6 configured same way as ep1
207  * so, if there are some problems we should have it
208  * there too.
209  * - do we really need support usb1.1?
210  */
211 extern uint16_t         u8UsbConfigValue;
212 extern uint16_t         u8UsbInterfaceValue;
213 extern uint16_t         u8UsbInterfaceAlternateSetting;
214 extern SetupPacket      ControlCmd;
215 extern void             vUsbClrEPx(void);
216
217 #undef FS_C1_I0_A0_EP_NUMBER
218 #define FS_C1_I0_A0_EP_NUMBER 6
219
220 #define FS_C1_I0_A0_EP6_BLKSIZE    BLK512BYTE
221 #define FS_C1_I0_A0_EP6_BLKNO      DOUBLE_BLK
222 #define FS_C1_I0_A0_EP6_DIRECTION  DIRECTION_OUT
223 #define FS_C1_I0_A0_EP6_TYPE       TF_TYPE_BULK
224 #define FS_C1_I0_A0_EP6_MAX_PACKET 0x0040
225 #define FS_C1_I0_A0_EP6_bInterval  0
226
227 /* EP6 */
228 #define FS_C1_I0_A0_EP6_FIFO_START      \
229          (FS_C1_I0_A0_EP5_FIFO_START + FS_C1_I0_A0_EP5_FIFO_NO)
230 #define FS_C1_I0_A0_EP6_FIFO_NO         \
231          (FS_C1_I0_A0_EP6_BLKNO * FS_C1_I0_A0_EP6_BLKSIZE)
232 #define FS_C1_I0_A0_EP6_FIFO_CONFIG     \
233          (0x80 | ((FS_C1_I0_A0_EP6_BLKSIZE - 1) << 4) | \
234           ((FS_C1_I0_A0_EP6_BLKNO - 1) << 2) | FS_C1_I0_A0_EP6_TYPE)
235 #define FS_C1_I0_A0_EP6_FIFO_MAP        \
236          (((1 - FS_C1_I0_A0_EP6_DIRECTION) << 4) | EP6)
237 #define FS_C1_I0_A0_EP6_MAP             \
238          (FS_C1_I0_A0_EP6_FIFO_START | (FS_C1_I0_A0_EP6_FIFO_START << 4) | \
239           (MASK_F0 >> (4*FS_C1_I0_A0_EP6_DIRECTION)))
240
241 void vUSBFIFO_EP6Cfg_FS_patch(void)
242 {
243 #if (FS_C1_I0_A0_EP_NUMBER >= 6)
244         int i;
245
246         /* EP0X06 */
247         mUsbEPMap(EP6, FS_C1_I0_A0_EP6_MAP);
248         mUsbFIFOMap(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_MAP);
249         mUsbFIFOConfig(FS_C1_I0_A0_EP6_FIFO_START, FS_C1_I0_A0_EP6_FIFO_CONFIG);
250
251         for(i = FS_C1_I0_A0_EP6_FIFO_START + 1 ;
252             i < FS_C1_I0_A0_EP6_FIFO_START + FS_C1_I0_A0_EP6_FIFO_NO ; i ++)
253         {
254                 mUsbFIFOConfig(i, (FS_C1_I0_A0_EP6_FIFO_CONFIG & (~BIT7)) );
255         }
256
257         mUsbEPMxPtSzHigh(EP6, FS_C1_I0_A0_EP6_DIRECTION,
258                          (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
259         mUsbEPMxPtSzLow(EP6, FS_C1_I0_A0_EP6_DIRECTION,
260                         (FS_C1_I0_A0_EP6_MAX_PACKET & 0x7ff));
261         mUsbEPinHighBandSet(EP6, FS_C1_I0_A0_EP6_DIRECTION,
262                             FS_C1_I0_A0_EP6_MAX_PACKET);
263 #endif
264 }
265
266 void vUsbFIFO_EPxCfg_FS_patch(void)
267 {
268         switch (u8UsbConfigValue)
269         {
270 #if (FS_CONFIGURATION_NUMBER >= 1)
271                 /* Configuration 0X01 */
272         case 0X01:
273                 switch (u8UsbInterfaceValue)
274                 {
275 #if (FS_C1_INTERFACE_NUMBER >= 1)
276                         /* Interface 0 */
277                 case 0:
278                         switch (u8UsbInterfaceAlternateSetting)
279                         {
280
281 #if (FS_C1_I0_ALT_NUMBER >= 1)
282                                 /* AlternateSetting 0 */
283                         case 0:
284
285                                 /* snapped.... */
286
287                                 /* patch up this ep6_fs config */
288                                 vUSBFIFO_EP6Cfg_FS_patch();
289
290                                 break;
291
292 #endif
293                         default:
294                                 break;
295                         }
296                         break;
297 #endif
298                 default:
299                         break;
300                 }
301                 break;
302 #endif
303         default:
304                 break;
305         }
306         /* mCHECK_STACK(); */
307 }
308
309 BOOLEAN bSet_configuration_patch(void)
310 {
311         /* do some defaul configuration */
312         bSet_configuration();
313
314         /* overwrite defaul FIFO configuration for FullSpeed USB */
315         if ((mLOW_BYTE(mDEV_REQ_VALUE()) != 0) && !mUsbHighSpeedST())
316                         vUsbFIFO_EPxCfg_FS_patch();
317
318         eUsbCxFinishAction = ACT_DONE;
319         return TRUE;
320 }
321
322 extern BOOLEAN bStandardCommand(void);
323
324 BOOLEAN bStandardCommand_patch(void)
325 {
326         if (mDEV_REQ_REQ() == USB_SET_CONFIGURATION) {
327                 A_USB_SET_CONFIG();
328
329 #if ENABLE_SWAP_DATA_MODE
330                 /* SWAP FUNCTION should be enabled while DMA engine
331                  * is not working, the best place to enable it
332                  * is before we trigger the DMA */
333                 MAGPIE_REG_USB_RX0_SWAP_DATA = 0x1;
334                 MAGPIE_REG_USB_TX0_SWAP_DATA = 0x1;
335
336 #if SYSTEM_MODULE_HP_EP5
337                 MAGPIE_REG_USB_RX1_SWAP_DATA = 0x1;
338 #endif
339
340 #if SYSTEM_MODULE_HP_EP6
341                 MAGPIE_REG_USB_RX2_SWAP_DATA = 0x1;
342 #endif
343
344 #endif /* ENABLE_SWAP_DATA_MODE */
345                 return TRUE;
346         } else
347                 return bStandardCommand();
348 }
349