diff mbox

[Xenial] UBUNTU: SAUCE: Bluetooth: Support for LED on Edge Gateways

Message ID 1471348125-22241-1-git-send-email-jesse.sung@canonical.com
State New
Headers show

Commit Message

Wen-chien Jesse Sung Aug. 16, 2016, 11:48 a.m. UTC
BugLink: https://launchpad.net/bugs/1512999

For Edge Gateway 5000/5100 only.

Add code for controlling bluetooth LED via firmware, and turns
the LED on and off when the interface is up and down accordingly.

Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com>
---
 drivers/bluetooth/btusb.c        | 36 +++++++++++++++++++++++++++++++++++-
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_core.c         |  2 ++
 3 files changed, 38 insertions(+), 1 deletion(-)

Comments

Brad Figg Aug. 16, 2016, 5:09 p.m. UTC | #1
Looks specific to a make/model.
Tim Gardner Aug. 16, 2016, 5:16 p.m. UTC | #2
What is the Yakkety story for this patch ? Is it going upstream ?
Kamal Mostafa Aug. 16, 2016, 5:55 p.m. UTC | #3
Applied to Xenial.

 -Kamal
Wen-chien Jesse Sung Aug. 17, 2016, 6:43 a.m. UTC | #4
Hi Tim,

2016-08-17 1:16 GMT+08:00 Tim Gardner <tim.gardner@canonical.com>:
> What is the Yakkety story for this patch ? Is it going upstream ?

There's no plan to send it to upstream right now. I'll generate a
patch against Yakkety later.

Thanks,
Jesse

>
> --
> Tim Gardner tim.gardner@canonical.com
diff mbox

Patch

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index c306b48..5d0c92e 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -24,6 +24,7 @@ 
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/firmware.h>
+#include <linux/dmi.h>
 #include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
@@ -2775,6 +2776,33 @@  static int btusb_bcm_set_diag(struct hci_dev *hdev, bool enable)
 }
 #endif
 
+#define BTUSB_EDGE_LED_COMMAND		0xfc77
+static void btusb_edge_set_led(struct hci_dev *hdev, bool state)
+{
+	struct sk_buff *skb;
+	u8 config_led[] = { 0x09, 0x00, 0x01, 0x01 };
+
+	if (state)
+		config_led[1] = 0x01;
+
+	skb = __hci_cmd_sync(hdev, BTUSB_EDGE_LED_COMMAND, sizeof(config_led), config_led, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb))
+		BT_ERR("%s fail to set LED (%ld)", hdev->name, PTR_ERR(skb));
+	else
+		kfree_skb(skb);
+}
+
+static void btusb_edge_post_open(struct hci_dev *hdev)
+{
+	btusb_edge_set_led(hdev, true);
+}
+
+static int btusb_edge_shutdown(struct hci_dev *hdev)
+{
+	btusb_edge_set_led(hdev, false);
+	return 0;
+}
+
 static int btusb_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
 {
@@ -2945,8 +2973,14 @@  static int btusb_probe(struct usb_interface *intf,
 		set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks);
 	}
 
-	if (id->driver_info & BTUSB_MARVELL)
+	if (id->driver_info & BTUSB_MARVELL) {
 		hdev->set_bdaddr = btusb_set_bdaddr_marvell;
+		if (dmi_match(DMI_PRODUCT_NAME, "Edge Gateway 5000") ||
+			dmi_match(DMI_PRODUCT_NAME, "Edge Gateway 5100")) {
+			hdev->post_open = btusb_edge_post_open;
+			hdev->shutdown = btusb_edge_shutdown;
+		}
+	}
 
 	if (id->driver_info & BTUSB_SWAVE) {
 		set_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks);
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 1878d0a..a8e95d1 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -394,6 +394,7 @@  struct hci_dev {
 	int (*close)(struct hci_dev *hdev);
 	int (*flush)(struct hci_dev *hdev);
 	int (*setup)(struct hci_dev *hdev);
+	void (*post_open)(struct hci_dev *hdev);
 	int (*shutdown)(struct hci_dev *hdev);
 	int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
 	void (*notify)(struct hci_dev *hdev, unsigned int evt);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 62edbf1..eea796c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1532,6 +1532,8 @@  static int hci_dev_do_open(struct hci_dev *hdev)
 			mgmt_powered(hdev, 1);
 			hci_dev_unlock(hdev);
 		}
+		if (hdev->post_open)
+			hdev->post_open(hdev);
 	} else {
 		/* Init failed, cleanup */
 		flush_work(&hdev->tx_work);