]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/bluetooth/hci_bcm.c
Merge remote-tracking branch 'omap/for-next'
[karo-tx-linux.git] / drivers / bluetooth / hci_bcm.c
index 0c791ac279d05bcb5bff9540f7404f93b1ea800d..cb852cc750b78256cd05fb62eda18dfb28c246aa 100644 (file)
@@ -41,6 +41,9 @@
 #include "btbcm.h"
 #include "hci_uart.h"
 
+#define BCM_LM_DIAG_PKT 0x07
+#define BCM_LM_DIAG_SIZE 63
+
 #define BCM_AUTOSUSPEND_DELAY  5000 /* default autosleep delay */
 
 struct bcm_device {
@@ -246,6 +249,29 @@ static inline int bcm_request_irq(struct bcm_data *bcm) { return 0; }
 static inline int bcm_setup_sleep(struct hci_uart *hu) { return 0; }
 #endif
 
+static int bcm_set_diag(struct hci_dev *hdev, bool enable)
+{
+       struct hci_uart *hu = hci_get_drvdata(hdev);
+       struct bcm_data *bcm = hu->priv;
+       struct sk_buff *skb;
+
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
+               return -ENETDOWN;
+
+       skb = bt_skb_alloc(3, GFP_KERNEL);
+       if (!skb)
+               return -ENOMEM;
+
+       *skb_put(skb, 1) = BCM_LM_DIAG_PKT;
+       *skb_put(skb, 1) = 0xf0;
+       *skb_put(skb, 1) = enable;
+
+       skb_queue_tail(&bcm->txq, skb);
+       hci_uart_tx_wakeup(hu);
+
+       return 0;
+}
+
 static int bcm_open(struct hci_uart *hu)
 {
        struct bcm_data *bcm;
@@ -339,6 +365,7 @@ static int bcm_setup(struct hci_uart *hu)
 
        bt_dev_dbg(hu->hdev, "hu %p", hu);
 
+       hu->hdev->set_diag = bcm_set_diag;
        hu->hdev->set_bdaddr = btbcm_set_bdaddr;
 
        err = btbcm_initialize(hu->hdev, fw_name, sizeof(fw_name));
@@ -396,10 +423,18 @@ finalize:
        return err;
 }
 
+#define BCM_RECV_LM_DIAG \
+       .type = BCM_LM_DIAG_PKT, \
+       .hlen = BCM_LM_DIAG_SIZE, \
+       .loff = 0, \
+       .lsize = 0, \
+       .maxlen = BCM_LM_DIAG_SIZE
+
 static const struct h4_recv_pkt bcm_recv_pkts[] = {
-       { H4_RECV_ACL,   .recv = hci_recv_frame },
-       { H4_RECV_SCO,   .recv = hci_recv_frame },
-       { H4_RECV_EVENT, .recv = hci_recv_frame },
+       { H4_RECV_ACL,      .recv = hci_recv_frame },
+       { H4_RECV_SCO,      .recv = hci_recv_frame },
+       { H4_RECV_EVENT,    .recv = hci_recv_frame },
+       { BCM_RECV_LM_DIAG, .recv = hci_recv_diag  },
 };
 
 static int bcm_recv(struct hci_uart *hu, const void *data, int count)
@@ -647,16 +682,10 @@ static int bcm_resource(struct acpi_resource *ares, void *data)
 static int bcm_acpi_probe(struct bcm_device *dev)
 {
        struct platform_device *pdev = dev->pdev;
-       const struct acpi_device_id *id;
-       struct acpi_device *adev;
        LIST_HEAD(resources);
        const struct dmi_system_id *dmi_id;
        int ret;
 
-       id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
-       if (!id)
-               return -ENODEV;
-
        /* Retrieve GPIO data */
        dev->name = dev_name(&pdev->dev);
        ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(&pdev->dev),
@@ -701,11 +730,11 @@ static int bcm_acpi_probe(struct bcm_device *dev)
        }
 
        /* Retrieve UART ACPI info */
-       adev = ACPI_COMPANION(&dev->pdev->dev);
-       if (!adev)
-               return 0;
-
-       acpi_dev_get_resources(adev, &resources, bcm_resource, dev);
+       ret = acpi_dev_get_resources(ACPI_COMPANION(&dev->pdev->dev),
+                                    &resources, bcm_resource, dev);
+       if (ret < 0)
+               return ret;
+       acpi_dev_free_resource_list(&resources);
 
        dmi_id = dmi_first_match(bcm_wrong_irq_dmi_table);
        if (dmi_id) {
@@ -726,7 +755,6 @@ static int bcm_acpi_probe(struct bcm_device *dev)
 static int bcm_probe(struct platform_device *pdev)
 {
        struct bcm_device *dev;
-       struct acpi_device_id *pdata = pdev->dev.platform_data;
        int ret;
 
        dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
@@ -735,15 +763,9 @@ static int bcm_probe(struct platform_device *pdev)
 
        dev->pdev = pdev;
 
-       if (ACPI_HANDLE(&pdev->dev)) {
-               ret = bcm_acpi_probe(dev);
-               if (ret)
-                       return ret;
-       } else if (pdata) {
-               dev->name = pdata->id;
-       } else {
-               return -ENODEV;
-       }
+       ret = bcm_acpi_probe(dev);
+       if (ret)
+               return ret;
 
        platform_set_drvdata(pdev, dev);
 
@@ -777,6 +799,7 @@ static int bcm_remove(struct platform_device *pdev)
 static const struct hci_uart_proto bcm_proto = {
        .id             = HCI_UART_BCM,
        .name           = "BCM",
+       .manufacturer   = 15,
        .init_speed     = 115200,
        .oper_speed     = 4000000,
        .open           = bcm_open,