led.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2009-2010 Realtek Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * The full GNU General Public License is included in this distribution in the
  15. * file called LICENSE.
  16. *
  17. * Contact Information:
  18. * wlanfae <wlanfae@realtek.com>
  19. * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  20. * Hsinchu 300, Taiwan.
  21. *
  22. * Larry Finger <Larry.Finger@lwfinger.net>
  23. *
  24. *****************************************************************************/
  25. #include "../wifi.h"
  26. #include "../pci.h"
  27. #include "reg.h"
  28. #include "led.h"
  29. static void _rtl8821ae_init_led(struct ieee80211_hw *hw,
  30. struct rtl_led *pled,
  31. enum rtl_led_pin ledpin)
  32. {
  33. pled->hw = hw;
  34. pled->ledpin = ledpin;
  35. pled->ledon = false;
  36. }
  37. void rtl8821ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
  38. {
  39. u8 ledcfg;
  40. struct rtl_priv *rtlpriv = rtl_priv(hw);
  41. RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
  42. "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
  43. switch (pled->ledpin) {
  44. case LED_PIN_GPIO0:
  45. break;
  46. case LED_PIN_LED0:
  47. ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
  48. ledcfg &= ~BIT(6);
  49. rtl_write_byte(rtlpriv,
  50. REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5));
  51. break;
  52. case LED_PIN_LED1:
  53. ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
  54. rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg & 0x10);
  55. break;
  56. default:
  57. RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
  58. "switch case not process\n");
  59. break;
  60. }
  61. pled->ledon = true;
  62. }
  63. void rtl8812ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
  64. {
  65. u16 ledreg = REG_LEDCFG1;
  66. u8 ledcfg = 0;
  67. struct rtl_priv *rtlpriv = rtl_priv(hw);
  68. switch (pled->ledpin) {
  69. case LED_PIN_LED0:
  70. ledreg = REG_LEDCFG1;
  71. break;
  72. case LED_PIN_LED1:
  73. ledreg = REG_LEDCFG2;
  74. break;
  75. case LED_PIN_GPIO0:
  76. default:
  77. break;
  78. }
  79. RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
  80. "In SwLedOn, LedAddr:%X LEDPIN=%d\n",
  81. ledreg, pled->ledpin);
  82. ledcfg = rtl_read_byte(rtlpriv, ledreg);
  83. ledcfg |= BIT(5); /*Set 0x4c[21]*/
  84. ledcfg &= ~(BIT(7) | BIT(6) | BIT(3) | BIT(2) | BIT(1) | BIT(0));
  85. /*Clear 0x4c[23:22] and 0x4c[19:16]*/
  86. rtl_write_byte(rtlpriv, ledreg, ledcfg); /*SW control led0 on.*/
  87. pled->ledon = true;
  88. }
  89. void rtl8821ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
  90. {
  91. struct rtl_priv *rtlpriv = rtl_priv(hw);
  92. struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
  93. u8 ledcfg;
  94. RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
  95. "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin);
  96. ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2);
  97. switch (pled->ledpin) {
  98. case LED_PIN_GPIO0:
  99. break;
  100. case LED_PIN_LED0:
  101. ledcfg &= 0xf0;
  102. if (pcipriv->ledctl.led_opendrain) {
  103. ledcfg &= 0x90; /* Set to software control. */
  104. rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg|BIT(3)));
  105. ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
  106. ledcfg &= 0xFE;
  107. rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
  108. } else {
  109. ledcfg &= ~BIT(6);
  110. rtl_write_byte(rtlpriv, REG_LEDCFG2,
  111. (ledcfg | BIT(3) | BIT(5)));
  112. }
  113. break;
  114. case LED_PIN_LED1:
  115. ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG1);
  116. ledcfg &= 0x10; /* Set to software control. */
  117. rtl_write_byte(rtlpriv, REG_LEDCFG1, ledcfg|BIT(3));
  118. break;
  119. default:
  120. RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
  121. "switch case not process\n");
  122. break;
  123. }
  124. pled->ledon = false;
  125. }
  126. void rtl8812ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
  127. {
  128. u16 ledreg = REG_LEDCFG1;
  129. struct rtl_priv *rtlpriv = rtl_priv(hw);
  130. struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
  131. switch (pled->ledpin) {
  132. case LED_PIN_LED0:
  133. ledreg = REG_LEDCFG1;
  134. break;
  135. case LED_PIN_LED1:
  136. ledreg = REG_LEDCFG2;
  137. break;
  138. case LED_PIN_GPIO0:
  139. default:
  140. break;
  141. }
  142. RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
  143. "In SwLedOff,LedAddr:%X LEDPIN=%d\n",
  144. ledreg, pled->ledpin);
  145. /*Open-drain arrangement for controlling the LED*/
  146. if (pcipriv->ledctl.led_opendrain) {
  147. u8 ledcfg = rtl_read_byte(rtlpriv, ledreg);
  148. ledreg &= 0xd0; /* Set to software control.*/
  149. rtl_write_byte(rtlpriv, ledreg, (ledcfg | BIT(3)));
  150. /*Open-drain arrangement*/
  151. ledcfg = rtl_read_byte(rtlpriv, REG_MAC_PINMUX_CFG);
  152. ledcfg &= 0xFE;/*Set GPIO[8] to input mode*/
  153. rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, ledcfg);
  154. } else {
  155. rtl_write_byte(rtlpriv, ledreg, 0x28);
  156. }
  157. pled->ledon = false;
  158. }
  159. void rtl8821ae_init_sw_leds(struct ieee80211_hw *hw)
  160. {
  161. struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
  162. _rtl8821ae_init_led(hw, &pcipriv->ledctl.sw_led0, LED_PIN_LED0);
  163. _rtl8821ae_init_led(hw, &pcipriv->ledctl.sw_led1, LED_PIN_LED1);
  164. }
  165. static void _rtl8821ae_sw_led_control(struct ieee80211_hw *hw,
  166. enum led_ctl_mode ledaction)
  167. {
  168. struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
  169. struct rtl_led *pLed0 = &pcipriv->ledctl.sw_led0;
  170. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  171. switch (ledaction) {
  172. case LED_CTL_POWER_ON:
  173. case LED_CTL_LINK:
  174. case LED_CTL_NO_LINK:
  175. if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
  176. rtl8812ae_sw_led_on(hw, pLed0);
  177. else
  178. rtl8821ae_sw_led_on(hw, pLed0);
  179. break;
  180. case LED_CTL_POWER_OFF:
  181. if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
  182. rtl8812ae_sw_led_off(hw, pLed0);
  183. else
  184. rtl8821ae_sw_led_off(hw, pLed0);
  185. break;
  186. default:
  187. break;
  188. }
  189. }
  190. void rtl8821ae_led_control(struct ieee80211_hw *hw,
  191. enum led_ctl_mode ledaction)
  192. {
  193. struct rtl_priv *rtlpriv = rtl_priv(hw);
  194. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  195. if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
  196. (ledaction == LED_CTL_TX ||
  197. ledaction == LED_CTL_RX ||
  198. ledaction == LED_CTL_SITE_SURVEY ||
  199. ledaction == LED_CTL_LINK ||
  200. ledaction == LED_CTL_NO_LINK ||
  201. ledaction == LED_CTL_START_TO_LINK ||
  202. ledaction == LED_CTL_POWER_ON)) {
  203. return;
  204. }
  205. RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n",
  206. ledaction);
  207. _rtl8821ae_sw_led_control(hw, ledaction);
  208. }