]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/libs4c/usb/pdiusb/pdi.c
Merge master into can-usb1 branch to include proc update for 3.12+ kernels.
[lincan.git] / embedded / libs4c / usb / pdiusb / pdi.c
1 /*****************************************************/
2 /***   Module : USB PDI                            ***/
3 /***   Author : Roman Bartosinski (C) 28.04.2002   ***/
4 /***   Modify : 08.08.2002, 16.04.2003             ***/
5 /*****************************************************/
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <system_def.h>
10
11 #define USB_PDI_EXPORT_FNC
12
13 #include <usb/pdiusb.h>
14 #include <usb/pdi.h>
15 #include <usb/usbdebug.h>
16
17
18 /* init chip state */
19   void pdiInitChipState( void) {
20    #ifdef PDIUSBD11
21     pdiSetHUBAddressEnable( 0, 0);
22    #endif /*PDIUSBD11*/
23     pdiSetAddressEnable( PDI_ENAD_ENABLE);
24     pdiSetEndpointEnable( PDI_EPEN_ENABLE);
25   }
26  
27 #ifdef PDIUSBD11
28
29   #define PDI_MODE_BASE_VALUE (PDI_MODE_MUSTBEONE | \
30   PDI_MODE_REMOTE_WAKEUP | PDI_MODE_NO_LAZY_CLOCK | \
31   PDI_MODE_CLOCK_RUNNING | PDI_CLOCK_4M)
32
33 #else /*PDIUSBD11*/
34
35   #define PDI_MODE_BASE_VALUE (PDI_CLOCK_SET_TO_ONE | \
36   PDI_MODE_NO_LAZY_CLOCK | PDI_MODE_CLOCK_RUNNING | \
37   PDI_CLOCK_4M)
38
39 #endif /*PDIUSBD11*/
40
41   int usb_pdi_set_addr( usb_device_t *udev, unsigned char addr) {
42    #if !defined(PDIUSBH11A_MULTIPLE) // D11,D12,H11,H11A_S(emb.fnc)
43     pdiSetAddressEnable(addr | PDI_ENAD_ENABLE);
44    #else
45     /*void pdiSetEmbFncAddressEnable( unsigned char byFnc, unsigned char byAddress, unsigned char byEnable);*/
46     #error usb_pdi_set_addr not implemented for PDIUSBH11A_MULTIPLE
47    #endif
48     return 0;
49   }
50
51   int usb_pdi_set_configuration( usb_device_t *udev, unsigned char iCfg) USB_UDEV_REENTRANT_SIGN
52   {
53     pdiSetEndpointEnable( 0); // USBInitUnconfig();
54     if ( iCfg) {
55       pdiSetEndpointEnable( PDI_EPEN_ENABLE); //USBInitConfig();
56     }
57     return 0;
58   }
59
60 /* connect usb */
61   int usb_pdi_connect( usb_device_t *udev) {
62     pdiSetMode( PDI_MODE_BASE_VALUE | PDI_MODE_SOFT_CONNECT );
63     return 0;
64   }
65
66 /* disconnect usb */
67   int usb_pdi_disconnect( usb_device_t *udev) {
68     pdiSetMode( PDI_MODE_BASE_VALUE & ~PDI_MODE_SOFT_CONNECT );
69     return 0;
70   }
71
72 /* acknowledge control transfer */
73   void usb_pdi_ack_setup( usb_device_t *udev) {
74     pdiWriteEndpoint( PDI_EP0_TX, 0, 0);
75   }
76
77
78 /* acknowledge control transfer */
79   void usb_pdi_ack_control_setup( usb_device_t *udev) {
80     pdiAckSetupControl();
81   }
82
83   
84 /**
85  * usb_pdi_check events
86  * function reads interrupt register and sets event flags
87  * function returns 1 if there is some new event.
88  * function returns 0 if there isn't new event but all is OK
89  * function returns -1 if there is any error
90 */
91   int usb_pdi_check_events( usb_device_t *udev) {
92     volatile unsigned char LastTrans = 0;
93     volatile unsigned int LastInt;
94     int ret = 0, i;
95
96     LastInt = pdiGetInterrupt();
97 if ( LastInt) {
98   usb_debug_print( DEBUG_LEVEL_LOW, ("PI=0x%04X\n", LastInt));
99 }
100     usb_debug_print( DEBUG_LEVEL_HIGH, ("PDI Int=0x%04X\n", LastInt));
101     
102     if ( LastInt & PDI_INT_BUSRESET) {                 // D12 - Bus reset reached
103       pdiInitChipState();
104       udev->flags |= USB_FLAG_BUS_RESET;
105       ret = 1;
106     } else {
107       #ifdef PDIUSBD12
108       if ( LastInt & PDI_INT_SUSPEND) {                 // D12 - Suspend flag changed
109         udev->flags |= USB_FLAG_SUSPEND;
110         ret = 1;
111       }
112       #endif
113
114             
115       if ( LastInt & PDI_INT_EP0_OUT) {                // D12 - Ep0RxDone - some data was received in EP0
116         LastTrans = pdiGetLastTransStatus( PDI_EP0_RX);
117         if ( LastTrans & PDI_LTSTAT_SETUP) { // setup packet
118           udev->flags |= USB_FLAG_SETUP;
119         } else {
120           udev->flags |= USB_FLAG_EVENT_RX0;
121         }
122         ret = 1;
123       }      
124       if ( LastInt & PDI_INT_EP0_IN) {                 // D12 - Ep0TxDone - data in EP0 was sended
125         LastTrans = pdiGetLastTransStatus( PDI_EP0_TX);
126         udev->flags |= USB_FLAG_EVENT_TX0;
127         ret = 1;
128       }
129
130       
131       for( i=0; i<udev->cntep; i++) {
132         if ( LastInt & (udev->ep+i)->event_mask) {
133           LastTrans = pdiGetLastTransStatus( (udev->ep+i)->epnum);
134           udev->ep_events |= 1<<i;
135           LastInt &= ~((udev->ep+i)->event_mask);
136           ret = 1;
137         }
138       }
139
140       /* check unsupported endpoints */
141       if ( LastInt & PDI_INT_EP1_OUT) {                // D12 - Ep1RxDone - some data was received in EP1
142         LastTrans = pdiGetLastTransStatus( PDI_EP1_RX);
143         pdiSetEpStatus( PDI_EP1_RX, PDI_SET_EP_STALLED);
144       }
145       if ( LastInt & PDI_INT_EP1_IN) {                 // D12 - Ep1TxDone - data in EP1 was sended
146         LastTrans = pdiGetLastTransStatus( PDI_EP1_TX);
147         pdiSetEpStatus( PDI_EP1_TX, PDI_SET_EP_STALLED);
148       }
149       if ( LastInt & PDI_INT_EP2_OUT) {                // D12 - Ep2RxDone - some data was received in EP2
150         LastTrans = pdiGetLastTransStatus( PDI_EP2_RX);
151         pdiSetEpStatus( PDI_EP2_RX, PDI_SET_EP_STALLED);
152       }
153       if ( LastInt & PDI_INT_EP2_IN) {                 // D12 - Ep2TxDone - data in EP2 was sended
154         LastTrans = pdiGetLastTransStatus( PDI_EP2_TX);
155         pdiSetEpStatus( PDI_EP2_TX, PDI_SET_EP_STALLED);
156       }
157      #if defined(PDIUSBD11) || defined(PDIUSBH11A_SINGLE)  // D11,H11_S
158       if ( LastInt & PDI_INT_EP3_OUT) {                // D11 - Ep3RxDone - some data was received in EP3
159         LastTrans = pdiGetLastTransStatus( PDI_EP3_RX);
160         pdiSetEpStatus( PDI_EP3_RX, PDI_SET_EP_STALLED);
161       }    
162       if ( LastInt & PDI_INT_EP3_IN) {                 // D11 - Ep3TxDone - data in EP3 was sended
163         LastTrans = pdiGetLastTransStatus( PDI_EP3_TX);
164         pdiSetEpStatus( PDI_EP3_TX, PDI_SET_EP_STALLED);
165       }
166      #endif /* D11,H11_S */
167     }
168     return ret;
169   }
170
171
172 /* stall endpoint X */
173   void usb_pdi_stall( usb_ep_t *ep) {
174     if ( ep->epnum) {
175       pdiSetEpStatus( ep->epnum, PDI_SET_EP_STALLED);
176     } else { // endpoint0
177       pdiSetEpStatus( PDI_EP0_TX, PDI_SET_EP_STALLED);
178       pdiSetEpStatus( PDI_EP0_RX, PDI_SET_EP_STALLED);
179     }
180   }
181
182 /* stall endpoint X */
183   void usb_pdi_unstall( usb_ep_t *ep) {
184     if ( ep->epnum) {
185       pdiSetEpStatus( ep->epnum, 0);
186     } else { // endpoint0
187       pdiSetEpStatus( PDI_EP0_TX, 0);
188       pdiSetEpStatus( PDI_EP0_RX, 0); 
189     }
190   }
191
192   int usb_pdi_read_endpoint( usb_ep_t *ep, void *ptr, int size) USB_UDEV_REENTRANT_SIGN
193   {
194     if(!ep->epnum)
195        return pdiReadEndpoint( PDI_EP0_RX, size, ptr);
196     else
197        return pdiReadEndpoint( ep->epnum, size, ptr);
198   }
199  
200   int usb_pdi_write_endpoint( usb_ep_t *ep, const void *ptr, int size) USB_UDEV_REENTRANT_SIGN
201   {
202     if(!ep->epnum)
203        pdiWriteEndpoint( PDI_EP0_TX, size, ptr);
204     else
205        pdiWriteEndpoint( ep->epnum, size, ptr);
206     return size;
207   }
208
209     
210 /* init usb structures and chip */
211   int usb_pdi_init( usb_device_t *udev) {
212
213    #ifndef USB_PDI_DIRECT_FNC
214     udev->connect = usb_pdi_connect;
215     udev->set_addr = usb_pdi_set_addr;
216     udev->set_configuration = usb_pdi_set_configuration;
217     udev->disconnect = usb_pdi_disconnect;
218     udev->ack_setup = usb_pdi_ack_setup;
219     udev->ack_control_setup = usb_pdi_ack_control_setup;
220     udev->stall = usb_pdi_stall;
221     udev->unstall = usb_pdi_unstall;
222     udev->check_events = usb_pdi_check_events;
223     udev->read_endpoint = usb_pdi_read_endpoint;
224     udev->write_endpoint = usb_pdi_write_endpoint;
225    #endif /*USB_PDI_DIRECT_FNC*/
226
227     udev->ep0.max_packet_size = PDI_EP0_PACKET_SIZE;
228
229     pdiInitChipState();
230     pdiSetMode( PDI_MODE_BASE_VALUE);
231     return 0;
232   }