00001
00050 #include <assert.h>
00051 #include <debug.h>
00052 #include <intc.h>
00053 #include <physmem.h>
00054 #include <stdbool.h>
00055 #include <interrupt.h>
00056
00057 #include <clk/sys.h>
00058
00059 #include <chip/clk.h>
00060 #include <chip/regs.h>
00061 #include <chip/at90usb.h>
00062 #include <chip/irq-map.h>
00063
00064 #include <cpu/io.h>
00065
00066 #include <usb/udc.h>
00067
00068 #include <app/usb.h>
00069
00070 #include "at90usb_internal.h"
00071 #include "at90usb_regs.h"
00072
00073
00074 #if defined(CONFIG_UDC) && !defined(CHIP_AT90USB_HAS_DEVICE)
00075 # error AT90USB: This chip does not have a Device Controller
00076 #endif
00077 #if defined(CONFIG_AT90USB_OTG) && !defined(CHIP_AT90USB_HAS_OTG)
00078 # error AT90USB: This chip does not support USB On-The-Go
00079 #endif
00080
00089 static inline
00090 struct at90usb_udc *at90usb_get_udc(struct at90usb_controller *at90usb)
00091 {
00092 #ifdef CONFIG_UDC
00093 return at90usb->udc;
00094 #else
00095 return NULL;
00096 #endif
00097 }
00098
00107 static inline
00108 struct at90usb_host *at90usb_get_host(struct at90usb_controller *at90usb)
00109 {
00110 return NULL;
00111 }
00112
00121 static inline bool at90usb_is_otg(struct at90usb_controller *at90usb)
00122 {
00123 #ifdef CONFIG_AT90USB_OTG
00124 return true;
00125 #else
00126 return false;
00127 #endif
00128 }
00129
00139 static void at90usb_check_vbus(struct at90usb_controller *at90usb)
00140 {
00141 struct at90usb_udc *udc = at90usb_get_udc(at90usb);
00142
00143 if (avr_read_reg8(USBSTA) & AT90USB_USBSTA_VBUS)
00144 at90usb_udc_vbus_on(udc);
00145 else
00146 at90usb_udc_vbus_off(udc);
00147 }
00148
00158 static void at90usb_enter_device_mode(struct at90usb_controller *at90usb)
00159 {
00160 struct at90usb_host *host = at90usb_get_host(at90usb);
00161 struct at90usb_udc *udc = at90usb_get_udc(at90usb);
00162
00163 dbg_verbose("AT90USB: Entering device mode...\n");
00164
00165 if (at90usb_host_is_enabled(host))
00166 at90usb_host_disable(host);
00167 if (!at90usb_udc_is_enabled(udc))
00168 at90usb_udc_enable(udc);
00169
00170 avr_write_reg8(USBINT, avr_read_reg8(USBINT) & ~AT90USB_USBINT_VBUSTI);
00171
00172 at90usb_check_vbus(at90usb);
00173
00174 avr_write_reg8(USBCON, avr_read_reg8(USBCON) | AT90USB_USBCON_VBUSTE);
00175
00176 dbg_verbose("AT90USB: USBCON=%02x\n", avr_read_reg8(USBCON));
00177 }
00178
00187 static void at90usb_enter_host_mode(struct at90usb_controller *at90usb)
00188 {
00189 struct at90usb_host *host = at90usb_get_host(at90usb);
00190 struct at90usb_udc *udc = at90usb_get_udc(at90usb);
00191
00192 if (host) {
00193 if (at90usb_udc_is_enabled(udc))
00194 at90usb_udc_disable(udc);
00195 if (!at90usb_host_is_enabled(host))
00196 at90usb_host_enable(host);
00197 }
00198 }
00199
00209 static void at90usb_check_id(struct at90usb_controller *at90usb)
00210 {
00211 if (avr_read_reg8(USBSTA) & AT90USB_USBSTA_ID)
00212 at90usb_enter_device_mode(at90usb);
00213 else
00214 at90usb_enter_host_mode(at90usb);
00215 }
00216
00217 static struct at90usb_controller the_at90usb_controller;
00218
00230 static void at90usb_generic_interrupt(void *data)
00231 {
00232 struct at90usb_controller *at90usb = data;
00233 struct at90usb_udc *udc;
00234 struct at90usb_host *hostb;
00235 uint8_t reg;
00236
00237 reg = avr_read_reg8(USBINT);
00238
00239 if (at90usb_is_otg(at90usb)) {
00240 if (reg & AT90USB_USBINT_IDTI) {
00241 avr_write_reg8(USBINT, reg & ~AT90USB_USBINT_IDTI);
00242 at90usb_check_id(at90usb);
00243 }
00244
00245
00246 }
00247
00248 udc = at90usb_get_udc(at90usb);
00249 if (at90usb_udc_is_enabled(udc)) {
00250 if (reg & AT90USB_USBINT_VBUSTI) {
00251 avr_write_reg8(USBINT, reg & ~AT90USB_USBINT_VBUSTI);
00252 at90usb_check_vbus(at90usb);
00253 }
00254
00255 if (avr_read_reg8(UDINT) & avr_read_reg8(UDIEN)) {
00256 avr_write_reg8(UDIEN, avr_read_reg8(UDIEN)
00257 & ~avr_read_reg8(UDINT));
00258 workqueue_add_task(&main_workqueue, &udc->task);
00259 }
00260 }
00261
00262 hostb = at90usb_get_host(at90usb);
00263 if (at90usb_host_is_enabled(hostb)) {
00264
00265 }
00266 }
00267 INTC_DEFINE_HANDLER(USB_GEN_IRQ, at90usb_generic_interrupt, 0);
00268
00280 static void at90usb_ep_interrupt(void *data)
00281 {
00282 struct at90usb_controller *at90usb = data;
00283 struct at90usb_udc *udc;
00284 struct at90usb_host *hostb;
00285
00286 uint8_t uenum = avr_read_reg8(UENUM);
00287
00288 if (at90usb_is_otg(at90usb)) {
00289
00290 }
00291
00292 udc = at90usb_get_udc(at90usb);
00293 if (at90usb_udc_is_enabled(udc)) {
00294 usb_ep_id_t ep_id;
00295 uint8_t ueint = avr_read_reg8(UEINT);
00296
00297 for (ep_id = 0; ep_id < APP_UDC_NR_ENDPOINTS; ep_id++) {
00298 if (ueint & AT90USB_UEINT_EP(ep_id)) {
00299 struct at90usb_udc_ep *ep = &udc->ep[ep_id];
00300 avr_write_reg8(UENUM, ep_id);
00301 ep->ueienx = avr_read_reg8(UEIENX);
00302 avr_write_reg8(UEIENX, ep->ueienx
00303 & ~avr_read_reg8(UEINTX));
00304 workqueue_add_task(&main_workqueue,
00305 &ep->task);
00306 }
00307 }
00308 }
00309
00310 hostb = at90usb_get_host(at90usb);
00311 if (at90usb_host_is_enabled(hostb)) {
00312
00313 }
00314
00315
00316 avr_write_reg8(UENUM, uenum);
00317 }
00318 INTC_DEFINE_HANDLER(USB_EP_IRQ, at90usb_ep_interrupt, 0);
00319
00336 static struct at90usb_controller *at90usb_init(void)
00337 {
00338 struct at90usb_controller *at90usb = &the_at90usb_controller;
00339 uint8_t usbcon;
00340
00341
00342
00343
00344
00345 if (at90usb_get_host(at90usb) || at90usb_get_udc(at90usb))
00346 return at90usb;
00347
00348 sysclk_enable_module(SYSCLK_USB);
00349 intc_setup_handler(USB_GEN_IRQ, 0, at90usb);
00350 intc_setup_handler(USB_EP_IRQ, 0, at90usb);
00351
00352 #ifdef CONFIG_UDC
00353 at90usb->udc = at90usb_udc_init();
00354 if (!at90usb->udc)
00355 goto err_udc;
00356 #endif
00357 #ifdef CONFIG_AT90USB_HOST
00358 at90usb->host = at90usb_host_init();
00359 if (!at90usb->host)
00360 goto err_host;
00361 #endif
00362
00363 clk_enable_at90usb();
00364
00365
00366
00367
00368 usbcon = (avr_read_reg8(USBCON) & AT90USB_USBCON_FRZCLK)
00369 | AT90USB_USBCON_USBE
00370 | AT90USB_USBCON_OTGPADE;
00371
00372 if (at90usb_is_otg(at90usb)) {
00373
00374 usbcon |= AT90USB_USBCON_IDTE;
00375
00376 avr_write_reg8(UHWCON, AT90USB_UHWCON_UIDE);
00377 avr_write_reg8(USBINT, avr_read_reg8(USBINT)
00378 & ~AT90USB_USBINT_IDTI);
00379 avr_write_reg8(USBCON, usbcon);
00380 avr_write_reg8(USBCON, usbcon & ~AT90USB_USBCON_FRZCLK);
00381
00382 at90usb_check_id(at90usb);
00383
00384
00385 } else if (at90usb_get_udc(at90usb)) {
00386
00387 avr_write_reg8(UHWCON, AT90USB_UHWCON_UIMOD);
00388 avr_write_reg8(USBCON, usbcon);
00389 avr_write_reg8(USBCON, usbcon & ~AT90USB_USBCON_FRZCLK);
00390
00391 at90usb_enter_device_mode(at90usb);
00392 } else if (at90usb_get_host(at90usb)) {
00393
00394 avr_write_reg8(UHWCON, AT90USB_UHWCON_UVREGE);
00395 avr_write_reg8(USBCON, usbcon);
00396 avr_write_reg8(USBCON, usbcon & ~AT90USB_USBCON_FRZCLK);
00397
00398 at90usb_enter_host_mode(at90usb);
00399 }
00400
00401 return at90usb;
00402
00403 #ifdef CONFIG_AT90USB_HOST
00404 err_host:
00405 at90usb_udc_shutdown(at90usb_get_udc(at90usb));
00406 #endif
00407 #ifdef CONFIG_UDC
00408 err_udc:
00409 #endif
00410 return NULL;
00411 }
00412
00426 struct udc *udc_init(void)
00427 {
00428 struct at90usb_controller *at90usb;
00429
00430 at90usb = at90usb_init();
00431 if (!at90usb)
00432 return NULL;
00433
00434 return &at90usb_get_udc(at90usb)->udc;
00435 }