X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=carlfw%2Fusb%2Fmain.c;h=4199a218618e9a6af57481f80108b8a7f6d4f3a6;hb=6598140e430d622be926aed43ec19fec8326cd11;hp=48ece0e99d4455119229ed584b7908c686d02583;hpb=e8448cf14674dafd86899f191475ea54b151d08a;p=carl9170fw.git diff --git a/carlfw/usb/main.c b/carlfw/usb/main.c index 48ece0e..4199a21 100644 --- a/carlfw/usb/main.c +++ b/carlfw/usb/main.c @@ -4,7 +4,7 @@ * Copyright (c) 2000-2005 ZyDAS Technology Corporation * Copyright (c) 2007-2009 Atheros Communications, Inc. * Copyright 2009 Johannes Berg - * Copyright 2009 Christian Lamparter + * Copyright 2009-2011 Christian Lamparter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,17 +17,18 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * with this program; If not, see . */ #include "carl9170.h" +#include "shared/phy.h" #include "hostif.h" #include "printf.h" #include "timer.h" #include "rom.h" -#include "shared/phy.h" +#include "wl.h" +#include "wol.h" #ifdef CONFIG_CARL9170FW_DEBUG_USB void usb_putc(const char c) @@ -244,7 +245,7 @@ static void turn_power_off(void) AR9170_PWR_RESET_WLAN_MASK); set(AR9170_PWR_REG_RESET, 0x0); - clock_set(false, AHB_20_22MHZ); + clock_set(AHB_20_22MHZ, false); set(AR9170_PWR_REG_PLL_ADDAC, 0x5163); /* 0x502b; */ set(AR9170_PHY_REG_ADC_SERIAL_CTL, AR9170_PHY_ADC_SCTL_SEL_EXTERNAL_RADIO); @@ -281,14 +282,22 @@ static void turn_power_off(void) set(AR9170_PHY_REG_ADC_SERIAL_CTL, AR9170_PHY_ADC_SCTL_SEL_INTERNAL_ADDAC); } -void __noreturn reboot(void) +static void disable_watchdog(void) { + if (!fw.watchdog_enable) + return; + /* write watchdog magic pattern for suspend */ andl(AR9170_PWR_REG_WATCH_DOG_MAGIC, 0xffff); orl(AR9170_PWR_REG_WATCH_DOG_MAGIC, 0x98760000); /* Disable watchdog */ set(AR9170_TIMER_REG_WATCH_DOG, 0xffff); +} + +void __noreturn reboot(void) +{ + disable_watchdog(); /* Turn off power */ turn_power_off(); @@ -320,21 +329,22 @@ static void usb_handler(uint8_t usb_interrupt_level1) if (usb_interrupt_level1 & BIT(0)) { usb_interrupt_level2 = getb(AR9170_USB_REG_INTR_SOURCE_0); - if (usb_interrupt_level2 & BIT(0)) + if (usb_interrupt_level2 & AR9170_USB_INTR_SRC0_SETUP) usb_ep0setup(); - if (usb_interrupt_level2 & BIT(1)) + if (usb_interrupt_level2 & AR9170_USB_INTR_SRC0_IN) usb_ep0tx(); - if (usb_interrupt_level2 & BIT(2)) + if (usb_interrupt_level2 & AR9170_USB_INTR_SRC0_OUT) usb_ep0rx(); - if (usb_interrupt_level2 & BIT(7)) { + if (usb_interrupt_level2 & AR9170_USB_INTR_SRC0_ABORT) { /* Clear the command abort interrupt */ - andb(AR9170_USB_REG_INTR_SOURCE_0, 0x7f); + andb(AR9170_USB_REG_INTR_SOURCE_0, (uint8_t) + ~AR9170_USB_INTR_SRC0_ABORT); } - if (usb_interrupt_level2 & BIT(3) || + if (usb_interrupt_level2 & AR9170_USB_INTR_SRC0_FAIL || fw.usb.ep0_action & CARL9170_EP0_STALL) { /* * transmission failure. @@ -344,7 +354,7 @@ static void usb_handler(uint8_t usb_interrupt_level1) fw.usb.ep0_action &= ~CARL9170_EP0_STALL; } - if (usb_interrupt_level2 & BIT(4) || + if (usb_interrupt_level2 & AR9170_USB_INTR_SRC0_END || fw.usb.ep0_action & CARL9170_EP0_TRIGGER) { /* * transmission done. @@ -358,32 +368,49 @@ static void usb_handler(uint8_t usb_interrupt_level1) if (usb_interrupt_level1 & BIT(7)) { usb_interrupt_level2 = getb(AR9170_USB_REG_INTR_SOURCE_7); - if (usb_interrupt_level2 & BIT(7)) + if (usb_interrupt_level2 & AR9170_USB_INTR_SRC7_RX0BYTE) usb_data_out0Byte(); - if (usb_interrupt_level2 & BIT(6)) + if (usb_interrupt_level2 & AR9170_USB_INTR_SRC7_TX0BYTE) usb_data_in0Byte(); - if (usb_interrupt_level2 & BIT(1)) { + if (usb_interrupt_level2 & AR9170_USB_INTR_SRC7_USB_RESET) { usb_reset_ack(); + usb_reset_eps(); reboot(); } - if (usb_interrupt_level2 & BIT(2)) { - /* ACK USB suspend interrupt */ + if (usb_interrupt_level2 & AR9170_USB_INTR_SRC7_USB_SUSPEND) { usb_suspend_ack(); - /* Set GO_TO_SUSPEND bit to USB main control register */ - setb(AR9170_USB_REG_MAIN_CTRL, BIT(3)); + fw.suspend_mode = CARL9170_HOST_SUSPENDED; - /* add by ygwei for work around USB PHY chirp sequence problem */ - set(0x10f100, 0x12345678); +#ifdef CONFIG_CARL9170FW_WOL + if (!(fw.usb.device_feature & USB_DEVICE_REMOTE_WAKEUP) || + !fw.wol.cmd.flags) { + disable_watchdog(); - reboot(); + /* GO_TO_SUSPEND stops the CPU clock too. */ + orb(AR9170_USB_REG_MAIN_CTRL, AR9170_USB_MAIN_CTRL_GO_TO_SUSPEND); + } else { + wol_prepare(); + } +#else /* CONFIG_CARL9170FW_WOL */ + disable_watchdog(); + + /* GO_TO_SUSPEND stops the CPU clock too. */ + orb(AR9170_USB_REG_MAIN_CTRL, AR9170_USB_MAIN_CTRL_GO_TO_SUSPEND); +#endif /* CONFIG_CARL9170FW_WOL */ } - if (usb_interrupt_level2 & BIT(3)) + if (usb_interrupt_level2 & AR9170_USB_INTR_SRC7_USB_RESUME) { usb_resume_ack(); + + fw.suspend_mode = CARL9170_HOST_AWAKE; + set(AR9170_USB_REG_WAKE_UP, 0); + + reboot(); + } } } @@ -400,3 +427,6 @@ void handle_usb(void) usb_trigger_in(); } +void usb_timer(void) +{ +}