summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/hci_core.h5
-rw-r--r--net/bluetooth/Kconfig11
-rw-r--r--net/bluetooth/Makefile3
-rw-r--r--net/bluetooth/hci_core.c10
-rw-r--r--net/bluetooth/led.c70
-rw-r--r--net/bluetooth/led.h37
6 files changed, 134 insertions, 2 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 1878d0a96333..2d9d19c3e051 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -370,6 +370,11 @@ struct hci_dev {
DECLARE_BITMAP(dev_flags, __HCI_NUM_FLAGS);
+#ifdef CONFIG_BT_LEDS
+ struct led_trigger *tx_led, *rx_led;
+ char tx_led_name[32], rx_led_name[32];
+#endif
+
struct delayed_work le_scan_disable;
struct delayed_work le_scan_restart;
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 95d1a66ba03a..a4062d382724 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -27,7 +27,7 @@ menuconfig BT
L2CAP (Logical Link Control and Adaptation Protocol)
SMP (Security Manager Protocol) on LE (Low Energy) links
HCI Device drivers (Interface to the hardware)
- RFCOMM Module (RFCOMM Protocol)
+ RFCOMM Module (RFCOMM Protocol)
BNEP Module (Bluetooth Network Encapsulation Protocol)
CMTP Module (CAPI Message Transport Protocol)
HIDP Module (Human Interface Device Protocol)
@@ -45,6 +45,15 @@ config BT_BREDR
depends on BT
default y
+config BT_LEDS
+ bool "Enable LED triggers"
+ depends on BT
+ depends on LEDS_CLASS
+ select LEDS_TRIGGERS
+ ---help---
+ This option enables LED triggers for bluetooth
+ packet receive/transmit.
+
source "net/bluetooth/rfcomm/Kconfig"
source "net/bluetooth/bnep/Kconfig"
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index 2b15ae8c1def..e80a64d9f4f1 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_BT_BNEP) += bnep/
obj-$(CONFIG_BT_CMTP) += cmtp/
obj-$(CONFIG_BT_HIDP) += hidp/
obj-$(CONFIG_BT_6LOWPAN) += bluetooth_6lowpan.o
-
bluetooth_6lowpan-y := 6lowpan.o
bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
@@ -20,4 +19,6 @@ bluetooth-$(CONFIG_BT_HS) += a2mp.o amp.o
bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o
bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o
+bluetooth-$(CONFIG_BT_LEDS) += led.o
+
subdir-ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 62edbf1b114e..208aab09d1bf 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -39,6 +39,7 @@
#include "hci_request.h"
#include "hci_debugfs.h"
+#include "led.h"
#include "smp.h"
static void hci_rx_work(struct work_struct *work);
@@ -3392,6 +3393,9 @@ int hci_register_dev(struct hci_dev *hdev)
if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
hci_dev_set_flag(hdev, HCI_RFKILLED);
+ bluetooth_led_names(hdev);
+ bluetooth_led_init(hdev);
+
hci_dev_set_flag(hdev, HCI_SETUP);
hci_dev_set_flag(hdev, HCI_AUTO_OFF);
@@ -3462,6 +3466,8 @@ void hci_unregister_dev(struct hci_dev *hdev)
hci_sock_dev_event(hdev, HCI_DEV_UNREG);
+ bluetooth_led_exit(hdev);
+
if (hdev->rfkill) {
rfkill_unregister(hdev->rfkill);
rfkill_destroy(hdev->rfkill);
@@ -3553,6 +3559,8 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
skb_queue_tail(&hdev->rx_q, skb);
queue_work(hdev->workqueue, &hdev->rx_work);
+ bluetooth_led_rx(hdev);
+
return 0;
}
EXPORT_SYMBOL(hci_recv_frame);
@@ -3629,6 +3637,8 @@ static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
BT_ERR("%s sending frame failed (%d)", hdev->name, err);
kfree_skb(skb);
}
+
+ bluetooth_led_tx(hdev);
}
/* Send HCI command */
diff --git a/net/bluetooth/led.c b/net/bluetooth/led.c
new file mode 100644
index 000000000000..8dd3516f6ae7
--- /dev/null
+++ b/net/bluetooth/led.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2015, Guodong Xu <guodong.xu@linaro.org>
+ * Copyright 2006, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/slab.h>
+#include "led.h"
+
+#define BLUETOOTH_BLINK_DELAY 50 /* ms */
+
+void bluetooth_led_rx(struct hci_dev *hdev)
+{
+ unsigned long led_delay = BLUETOOTH_BLINK_DELAY;
+ if (unlikely(!hdev->rx_led))
+ return;
+ led_trigger_blink_oneshot(hdev->rx_led, &led_delay, &led_delay, 0);
+}
+
+void bluetooth_led_tx(struct hci_dev *hdev)
+{
+ unsigned long led_delay = BLUETOOTH_BLINK_DELAY;
+ if (unlikely(!hdev->tx_led))
+ return;
+ led_trigger_blink_oneshot(hdev->tx_led, &led_delay, &led_delay, 0);
+}
+
+void bluetooth_led_names(struct hci_dev *hdev)
+{
+ snprintf(hdev->rx_led_name, sizeof(hdev->rx_led_name),
+ "%srx", hdev->name);
+ snprintf(hdev->tx_led_name, sizeof(hdev->tx_led_name),
+ "%stx", hdev->name);
+}
+
+void bluetooth_led_init(struct hci_dev *hdev)
+{
+ hdev->rx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
+ if (hdev->rx_led) {
+ hdev->rx_led->name = hdev->rx_led_name;
+ if (led_trigger_register(hdev->rx_led)) {
+ kfree(hdev->rx_led);
+ hdev->rx_led = NULL;
+ }
+ }
+
+ hdev->tx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
+ if (hdev->tx_led) {
+ hdev->tx_led->name = hdev->tx_led_name;
+ if (led_trigger_register(hdev->tx_led)) {
+ kfree(hdev->tx_led);
+ hdev->tx_led = NULL;
+ }
+ }
+}
+
+void bluetooth_led_exit(struct hci_dev *hdev)
+{
+ if (hdev->tx_led) {
+ led_trigger_unregister(hdev->tx_led);
+ kfree(hdev->tx_led);
+ }
+ if (hdev->rx_led) {
+ led_trigger_unregister(hdev->rx_led);
+ kfree(hdev->rx_led);
+ }
+}
diff --git a/net/bluetooth/led.h b/net/bluetooth/led.h
new file mode 100644
index 000000000000..766a211203ff
--- /dev/null
+++ b/net/bluetooth/led.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2015, Guodong Xu <guodong.xu@linaro.org>
+ * Copyright 2006, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/leds.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#ifdef CONFIG_BT_LEDS
+void bluetooth_led_rx(struct hci_dev *hdev);
+void bluetooth_led_tx(struct hci_dev *hdev);
+void bluetooth_led_names(struct hci_dev *hdev);
+void bluetooth_led_init(struct hci_dev *hdev);
+void bluetooth_led_exit(struct hci_dev *hdev);
+#else
+static inline void bluetooth_led_rx(struct hci_dev *hdev)
+{
+}
+static inline void bluetooth_led_tx(struct hci_dev *hdev)
+{
+}
+static inline void bluetooth_led_names(struct hci_dev *hdev)
+{
+}
+static inline void bluetooth_led_init(struct hci_dev *hdev)
+{
+}
+static inline void bluetooth_led_exit(struct hci_dev *hdev)
+{
+}
+#endif