高通QSDK是基於openwrt的,在控制LED gpio方面,也可以參考openwrt原生對LED燈號控制的機制。
在網路上有看到openwrt中對LED燈號控制的博文。
openwrt中LED的控制_hzlarm的博客-CSDN博客_openwrt怎么配置led灯
其中的內容直接提到了/sys/class/leds/<路由器名>:顏色:<功能> 節點的控制方式。這麼簡單就姑且一試。發現我的系統中 /sys/class/leds/ 這個目錄是空的,是空的。好吧,照著原理圖的說明。MAPLE 2G WIFI LED是使用IPQ_GPIO30。
那我們就來定義這個項目吧。
Index: qsdk/qca/src/linux-4.4/arch/arm64/boot/dts/qcom/qcom-ipq5018-mp03.3.dts
===================================================================
--- qsdk.orig/qca/src/linux-4.4/arch/arm64/boot/dts/qcom/qcom-ipq5018-mp03.3.dts
+++ qsdk/qca/src/linux-4.4/arch/arm64/boot/dts/qcom/qcom-ipq5018-mp03.3.dts
@@ -757,6 +757,14 @@
};
};
+ led_pins: led_pins {
+ led_2g {
+ pins = "gpio30";
+ function = "gpio";
+ drive-strength = <8>;
+ bias-pull-down;
+ };
+ };
};
&soc {
@@ -773,6 +781,19 @@
debounce-interval = <60>;
};
};
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&led_pins>;
+ pinctrl-names = "default";
+
+ led_2g {
+ label = "led_2g";
+ gpio = <&tlmm 30 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+
};
&usb3 {
改好之後趕快來試下:
有個led_2g 的node跑出來了。操作一下 echo 1 > brightness ,2.4G的LED燈可以被點亮了。
此時,也就可利用 /sys/class/leds/led_2g 來點亮與熄滅 LED燈號了。
現在,改個gpio的逻辑,开启wifi时输出高电平,wifi通讯时是blink,关闭wifi时是低电平。
Index: qsdk/qca/src/qca-wifi/offload/wlan/include/ol_if_athvar.h
===================================================================
--- qsdk.orig/qca/src/qca-wifi/offload/wlan/include/ol_if_athvar.h
+++ qsdk/qca/src/qca-wifi/offload/wlan/include/ol_if_athvar.h
@@ -429,6 +429,7 @@ typedef struct ieee80211_mib_cycle_cnts
#define IPQ4019_LED_GPIO 58
#define IPQ8074_2G_LED_GPIO 42
#define IPQ8074_5G_LED_GPIO 43
+#define IPQ5018_2G_LED_GPIO 30
#define LED_POLL_TIMER 500
Index: qsdk/qca/src/qca-wifi/offload/wlan/lmac_offload_if/ol_if_ath.c
===================================================================
--- qsdk.orig/qca/src/qca-wifi/offload/wlan/lmac_offload_if/ol_if_ath.c
+++ qsdk/qca/src/qca-wifi/offload/wlan/lmac_offload_if/ol_if_ath.c
@@ -8837,7 +8837,9 @@ int ol_ath_pdev_attach(struct ol_ath_sof
} else {
scn->scn_led_gpio = IPQ8074_5G_LED_GPIO ;
}
- }
+ } else if (target_type == TARGET_TYPE_QCA5018) {
+ scn->scn_led_gpio = IPQ5018_2G_LED_GPIO ;
+ }
if(target_type == TARGET_TYPE_IPQ4019) {
scn->scn_led_gpio = 0; //will get initialized later
Index: qsdk/qca/src/qca-wifi/offload/wlan/lmac_offload_if/ol_if_led.c
===================================================================
--- qsdk.orig/qca/src/qca-wifi/offload/wlan/lmac_offload_if/ol_if_led.c
+++ qsdk/qca/src/qca-wifi/offload/wlan/lmac_offload_if/ol_if_led.c
@@ -114,7 +114,6 @@ static void ol_ath_led_blink_timed_out(v
(lmac_get_tgt_type(psoc) == TARGET_TYPE_QCA8074) ||
(lmac_get_tgt_type(psoc) == TARGET_TYPE_QCA8074V2 && scn->scn_led_gpio == 0) ||
(lmac_get_tgt_type(psoc) == TARGET_TYPE_QCA9574) ||
- (lmac_get_tgt_type(psoc) == TARGET_TYPE_QCA5018) ||
(lmac_get_tgt_type(psoc) == TARGET_TYPE_QCA6018) ||
(lmac_get_tgt_type(psoc) == TARGET_TYPE_QCN9224) ||
(lmac_get_tgt_type(psoc) == TARGET_TYPE_QCN9000)) {
@@ -134,11 +133,11 @@ static void ol_ath_led_blink_timed_out(v
if ((target_type == TARGET_TYPE_QCA8074) ||
(target_type == TARGET_TYPE_QCA8074V2 && scn->scn_led_gpio == 0) ||
(target_type == TARGET_TYPE_QCA9574) ||
- (target_type == TARGET_TYPE_QCA5018) ||
(target_type == TARGET_TYPE_QCA6018)) {
} else if(target_type == TARGET_TYPE_IPQ4019) {
ipq4019_wifi_led(scn, OL_LED_OFF);
- } else if(target_type == TARGET_TYPE_QCA8074V2) {
+ } else if((target_type == TARGET_TYPE_QCA8074V2) ||
+ (target_type == TARGET_TYPE_QCA5018)) {
gpio_set_value_cansleep(scn->scn_led_gpio, OL_LED_OFF);
} else {
tgt_gpio_output(psoc, scn->scn_led_gpio, 0);
@@ -151,11 +150,11 @@ static void ol_ath_led_blink_timed_out(v
if ((target_type == TARGET_TYPE_QCA8074) ||
(target_type == TARGET_TYPE_QCA8074V2 && scn->scn_led_gpio == 0) ||
(target_type == TARGET_TYPE_QCA9574) ||
- (target_type == TARGET_TYPE_QCA5018) ||
(target_type == TARGET_TYPE_QCA6018)) {
} else if(target_type == TARGET_TYPE_IPQ4019) {
ipq4019_wifi_led(scn, OL_LED_ON);
- } else if(target_type == TARGET_TYPE_QCA8074V2) {
+ } else if((target_type == TARGET_TYPE_QCA8074V2) ||
+ (target_type == TARGET_TYPE_QCA5018)) {
gpio_set_value_cansleep(scn->scn_led_gpio, OL_LED_ON);
} else {
tgt_gpio_output(psoc, scn->scn_led_gpio, 1);
@@ -206,7 +205,6 @@ ol_ath_led_blink(struct ol_ath_softc_net
if ((target_type == TARGET_TYPE_QCA8074) ||
(target_type == TARGET_TYPE_QCA8074V2 && scn->scn_led_gpio == 0) ||
(target_type == TARGET_TYPE_QCA9574) ||
- (target_type == TARGET_TYPE_QCA5018) ||
(target_type == TARGET_TYPE_QCA6018)) {
#ifdef QCA_SUPPORT_CP_STATS
struct ieee80211com *ic = &scn->sc_ic;
@@ -227,7 +225,8 @@ ol_ath_led_blink(struct ol_ath_softc_net
#endif
} else if(target_type == TARGET_TYPE_IPQ4019) {
ipq4019_wifi_led(scn, OL_LED_ON);
- } else if(target_type == TARGET_TYPE_QCA8074V2) {
+ } else if((target_type == TARGET_TYPE_QCA8074V2) ||
+ (target_type == TARGET_TYPE_QCA5018)) {
gpio_set_value_cansleep(scn->scn_led_gpio, OL_LED_ON);
} else {
tgt_gpio_output(psoc, scn->scn_led_gpio, 1);
@@ -236,7 +235,6 @@ ol_ath_led_blink(struct ol_ath_softc_net
if ((target_type == TARGET_TYPE_QCA8074) ||
(target_type == TARGET_TYPE_QCA8074V2 && scn->scn_led_gpio == 0) ||
(target_type == TARGET_TYPE_QCA9574) ||
- (target_type == TARGET_TYPE_QCA5018) ||
(target_type == TARGET_TYPE_QCA6018)) {
#if OL_ATH_SUPPORT_LED_POLL
scn->scn_blinking = OL_BLINK_DONE;
這樣IPQ5018 GPIO30 就會被用來控制2.4G WiFi LED 燈號囉。 ifup 就會亮燈、有流量的時候就會閃燈、ifdown 就會熄燈。
改好wifi driver之後會發現 /sys/class/leds/led_2g 無法使用echo 1 > brightness來控制點亮燈了,這說明這個GPIO已經被wifi driver給搶去控制了。那麼修改dts的動作是需要的嗎? 我想就看硬件的設計了,這裡就是給個default值的概念了,因為wifi driver的啟動會比較慢,在kernel 初始化的過程中是很排後的,優先在leds 驅動啟動的時候給個default,這樣在燈號的顯示上來說會比較明確一點。
結語:
QSDK中可透過修改dts的方式,來使用gpio-leds這個kernel module來支持 openwrt對LED的操作方式,此時在user space 對 /sys/class/leds下的node來設定就行,這個方式需要額外的寫個程式來運作點燈邏輯。另外,針對WiFi LED 可以直接修改wifi Driver來支持內建的有流量時【閃燈】的功能。
想了解更多,請關注大大通。
參考來源