diff options
author | David S. Miller <davem@davemloft.net> | 2015-03-02 14:47:12 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-02 14:47:12 -0500 |
commit | 70c836a4d15f12aa50195937083b30a6945c2556 (patch) | |
tree | f76867215487fd7626acae395b412056eb8fde74 /drivers | |
parent | b4844353c0577bef6db54e5b276ede1acbed5b3d (diff) | |
parent | c91799c50a14137ecee6d60d2f1d9ab8bc895e52 (diff) | |
download | linux-70c836a4d15f12aa50195937083b30a6945c2556.tar.bz2 |
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
Johan Hedberg says:
====================
pull request: bluetooth-next 2015-03-02
Here's the first bluetooth-next pull request targeting the 4.1 kernel:
- ieee802154/6lowpan cleanups
- SCO routing to host interface support for the btmrvl driver
- AMP code cleanups
- Fixes to AMP HCI init sequence
- Refactoring of the HCI callback mechanism
- Added shutdown routine for Intel controllers in the btusb driver
- New config option to enable/disable Bluetooth debugfs information
- Fix for early data reception on L2CAP fixed channels
Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/bluetooth/ath3k.c | 1 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_drv.h | 1 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_main.c | 14 | ||||
-rw-r--r-- | drivers/bluetooth/btusb.c | 120 | ||||
-rw-r--r-- | drivers/net/ieee802154/at86rf230.c | 120 |
5 files changed, 183 insertions, 73 deletions
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index de4c8499cbac..288547a3c566 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -65,6 +65,7 @@ static const struct usb_device_id ath3k_table[] = { /* Atheros AR3011 with sflash firmware*/ { USB_DEVICE(0x0489, 0xE027) }, { USB_DEVICE(0x0489, 0xE03D) }, + { USB_DEVICE(0x04F2, 0xAFF1) }, { USB_DEVICE(0x0930, 0x0215) }, { USB_DEVICE(0x0CF3, 0x3002) }, { USB_DEVICE(0x0CF3, 0xE019) }, diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h index e75f8ee2512c..086f0ec89580 100644 --- a/drivers/bluetooth/btmrvl_drv.h +++ b/drivers/bluetooth/btmrvl_drv.h @@ -111,6 +111,7 @@ struct btmrvl_private { /* Vendor specific Bluetooth commands */ #define BT_CMD_PSCAN_WIN_REPORT_ENABLE 0xFC03 +#define BT_CMD_ROUTE_SCO_TO_HOST 0xFC1D #define BT_CMD_SET_BDADDR 0xFC22 #define BT_CMD_AUTO_SLEEP_MODE 0xFC23 #define BT_CMD_HOST_SLEEP_CONFIG 0xFC59 diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 413597789c61..de05deb444ce 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -230,6 +230,18 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, u8 subcmd) } EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd); +static int btmrvl_enable_sco_routing_to_host(struct btmrvl_private *priv) +{ + int ret; + u8 subcmd = 0; + + ret = btmrvl_send_sync_cmd(priv, BT_CMD_ROUTE_SCO_TO_HOST, &subcmd, 1); + if (ret) + BT_ERR("BT_CMD_ROUTE_SCO_TO_HOST command failed: %#x", ret); + + return ret; +} + int btmrvl_pscan_window_reporting(struct btmrvl_private *priv, u8 subcmd) { struct btmrvl_sdio_card *card = priv->btmrvl_dev.card; @@ -558,6 +570,8 @@ static int btmrvl_setup(struct hci_dev *hdev) btmrvl_check_device_tree(priv); + btmrvl_enable_sco_routing_to_host(priv); + btmrvl_pscan_window_reporting(priv, 0x01); priv->btmrvl_dev.psmode = 1; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index b87688881143..3ca2e1bf7bfa 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -159,6 +159,7 @@ static const struct usb_device_id blacklist_table[] = { /* Atheros 3011 with sflash firmware */ { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x04f2, 0xaff1), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE }, @@ -338,16 +339,6 @@ struct btusb_data { int (*recv_bulk)(struct btusb_data *data, void *buffer, int count); }; -static int btusb_wait_on_bit_timeout(void *word, int bit, unsigned long timeout, - unsigned mode) -{ - might_sleep(); - if (!test_bit(bit, word)) - return 0; - return out_of_line_wait_on_bit_timeout(word, bit, bit_wait_timeout, - mode, timeout); -} - static inline void btusb_free_frags(struct btusb_data *data) { unsigned long flags; @@ -2196,9 +2187,9 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) * and thus just timeout if that happens and fail the setup * of this device. */ - err = btusb_wait_on_bit_timeout(&data->flags, BTUSB_DOWNLOADING, - msecs_to_jiffies(5000), - TASK_INTERRUPTIBLE); + err = wait_on_bit_timeout(&data->flags, BTUSB_DOWNLOADING, + TASK_INTERRUPTIBLE, + msecs_to_jiffies(5000)); if (err == 1) { BT_ERR("%s: Firmware loading interrupted", hdev->name); err = -EINTR; @@ -2249,9 +2240,9 @@ done: */ BT_INFO("%s: Waiting for device to boot", hdev->name); - err = btusb_wait_on_bit_timeout(&data->flags, BTUSB_BOOTING, - msecs_to_jiffies(1000), - TASK_INTERRUPTIBLE); + err = wait_on_bit_timeout(&data->flags, BTUSB_BOOTING, + TASK_INTERRUPTIBLE, + msecs_to_jiffies(1000)); if (err == 1) { BT_ERR("%s: Device boot interrupted", hdev->name); @@ -2331,6 +2322,27 @@ static int btusb_set_bdaddr_intel(struct hci_dev *hdev, const bdaddr_t *bdaddr) return 0; } +static int btusb_shutdown_intel(struct hci_dev *hdev) +{ + struct sk_buff *skb; + long ret; + + /* Some platforms have an issue with BT LED when the interface is + * down or BT radio is turned off, which takes 5 seconds to BT LED + * goes off. This command turns off the BT LED immediately. + */ + skb = __hci_cmd_sync(hdev, 0xfc3f, 0, NULL, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + ret = PTR_ERR(skb); + BT_ERR("%s: turning off Intel device LED failed (%ld)", + hdev->name, ret); + return ret; + } + kfree_skb(skb); + + return 0; +} + static int btusb_set_bdaddr_marvell(struct hci_dev *hdev, const bdaddr_t *bdaddr) { @@ -2354,6 +2366,23 @@ static int btusb_set_bdaddr_marvell(struct hci_dev *hdev, return 0; } +static const struct { + u16 subver; + const char *name; +} bcm_subver_table[] = { + { 0x210b, "BCM43142A0" }, /* 001.001.011 */ + { 0x2112, "BCM4314A0" }, /* 001.001.018 */ + { 0x2118, "BCM20702A0" }, /* 001.001.024 */ + { 0x2126, "BCM4335A0" }, /* 001.001.038 */ + { 0x220e, "BCM20702A1" }, /* 001.002.014 */ + { 0x230f, "BCM4354A2" }, /* 001.003.015 */ + { 0x4106, "BCM4335B0" }, /* 002.001.006 */ + { 0x410e, "BCM20702B0" }, /* 002.001.014 */ + { 0x6109, "BCM4335C0" }, /* 003.001.009 */ + { 0x610c, "BCM4354" }, /* 003.001.012 */ + { } +}; + #define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}}) static int btusb_setup_bcm_patchram(struct hci_dev *hdev) @@ -2366,29 +2395,20 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev) size_t fw_size; const struct hci_command_hdr *cmd; const u8 *cmd_param; - u16 opcode; + u16 opcode, subver, rev; + const char *hw_name = NULL; struct sk_buff *skb; struct hci_rp_read_local_version *ver; struct hci_rp_read_bd_addr *bda; long ret; - - snprintf(fw_name, sizeof(fw_name), "brcm/%s-%04x-%04x.hcd", - udev->product ? udev->product : "BCM", - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct)); - - ret = request_firmware(&fw, fw_name, &hdev->dev); - if (ret < 0) { - BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name); - return 0; - } + int i; /* Reset */ skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { ret = PTR_ERR(skb); BT_ERR("%s: HCI_OP_RESET failed (%ld)", hdev->name, ret); - goto done; + return ret; } kfree_skb(skb); @@ -2399,23 +2419,43 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev) ret = PTR_ERR(skb); BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION failed (%ld)", hdev->name, ret); - goto done; + return ret; } if (skb->len != sizeof(*ver)) { BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION event length mismatch", hdev->name); kfree_skb(skb); - ret = -EIO; - goto done; + return -EIO; } ver = (struct hci_rp_read_local_version *)skb->data; - BT_INFO("%s: BCM: patching hci_ver=%02x hci_rev=%04x lmp_ver=%02x " - "lmp_subver=%04x", hdev->name, ver->hci_ver, ver->hci_rev, - ver->lmp_ver, ver->lmp_subver); + rev = le16_to_cpu(ver->hci_rev); + subver = le16_to_cpu(ver->lmp_subver); kfree_skb(skb); + for (i = 0; bcm_subver_table[i].name; i++) { + if (subver == bcm_subver_table[i].subver) { + hw_name = bcm_subver_table[i].name; + break; + } + } + + BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name, + hw_name ? : "BCM", (subver & 0x7000) >> 13, + (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); + + snprintf(fw_name, sizeof(fw_name), "brcm/%s-%4.4x-%4.4x.hcd", + hw_name ? : "BCM", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct)); + + ret = request_firmware(&fw, fw_name, &hdev->dev); + if (ret < 0) { + BT_INFO("%s: BCM: patch %s not found", hdev->name, fw_name); + return 0; + } + /* Start Download */ skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { @@ -2493,11 +2533,14 @@ reset_fw: } ver = (struct hci_rp_read_local_version *)skb->data; - BT_INFO("%s: BCM: firmware hci_ver=%02x hci_rev=%04x lmp_ver=%02x " - "lmp_subver=%04x", hdev->name, ver->hci_ver, ver->hci_rev, - ver->lmp_ver, ver->lmp_subver); + rev = le16_to_cpu(ver->hci_rev); + subver = le16_to_cpu(ver->lmp_subver); kfree_skb(skb); + BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name, + hw_name ? : "BCM", (subver & 0x7000) >> 13, + (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); + /* Read BD Address */ skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL, HCI_INIT_TIMEOUT); @@ -2708,6 +2751,7 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_INTEL) { hdev->setup = btusb_setup_intel; + hdev->shutdown = btusb_shutdown_intel; hdev->set_bdaddr = btusb_set_bdaddr_intel; set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); } diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 7b051eacb7f1..1d438bc54189 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -46,8 +46,6 @@ struct at86rf2xx_chip_data { u16 t_off_to_tx_on; u16 t_frame; u16 t_p_ack; - /* completion timeout for tx in msecs */ - u16 t_tx_timeout; int rssi_base_val; int (*set_channel)(struct at86rf230_local *, u8, u8); @@ -689,7 +687,7 @@ at86rf230_sync_state_change_complete(void *context) static int at86rf230_sync_state_change(struct at86rf230_local *lp, unsigned int state) { - int rc; + unsigned long rc; at86rf230_async_state_change(lp, &lp->state, state, at86rf230_sync_state_change_complete, @@ -1281,7 +1279,6 @@ static struct at86rf2xx_chip_data at86rf233_data = { .t_off_to_tx_on = 80, .t_frame = 4096, .t_p_ack = 545, - .t_tx_timeout = 2000, .rssi_base_val = -91, .set_channel = at86rf23x_set_channel, .get_desense_steps = at86rf23x_get_desens_steps @@ -1295,7 +1292,6 @@ static struct at86rf2xx_chip_data at86rf231_data = { .t_off_to_tx_on = 110, .t_frame = 4096, .t_p_ack = 545, - .t_tx_timeout = 2000, .rssi_base_val = -91, .set_channel = at86rf23x_set_channel, .get_desense_steps = at86rf23x_get_desens_steps @@ -1309,13 +1305,12 @@ static struct at86rf2xx_chip_data at86rf212_data = { .t_off_to_tx_on = 200, .t_frame = 4096, .t_p_ack = 545, - .t_tx_timeout = 2000, .rssi_base_val = -100, .set_channel = at86rf212_set_channel, .get_desense_steps = at86rf212_get_desens_steps }; -static int at86rf230_hw_init(struct at86rf230_local *lp) +static int at86rf230_hw_init(struct at86rf230_local *lp, u8 xtal_trim) { int rc, irq_type, irq_pol = IRQ_ACTIVE_HIGH; unsigned int dvdd; @@ -1326,7 +1321,12 @@ static int at86rf230_hw_init(struct at86rf230_local *lp) return rc; irq_type = irq_get_trigger_type(lp->spi->irq); - if (irq_type == IRQ_TYPE_EDGE_FALLING) + if (irq_type == IRQ_TYPE_EDGE_RISING || + irq_type == IRQ_TYPE_EDGE_FALLING) + dev_warn(&lp->spi->dev, + "Using edge triggered irq's are not recommended!\n"); + if (irq_type == IRQ_TYPE_EDGE_FALLING || + irq_type == IRQ_TYPE_LEVEL_LOW) irq_pol = IRQ_ACTIVE_LOW; rc = at86rf230_write_subreg(lp, SR_IRQ_POLARITY, irq_pol); @@ -1341,6 +1341,11 @@ static int at86rf230_hw_init(struct at86rf230_local *lp) if (rc) return rc; + /* reset values differs in at86rf231 and at86rf233 */ + rc = at86rf230_write_subreg(lp, SR_IRQ_MASK_MODE, 0); + if (rc) + return rc; + get_random_bytes(csma_seed, ARRAY_SIZE(csma_seed)); rc = at86rf230_write_subreg(lp, SR_CSMA_SEED_0, csma_seed[0]); if (rc) @@ -1362,6 +1367,45 @@ static int at86rf230_hw_init(struct at86rf230_local *lp) usleep_range(lp->data->t_sleep_cycle, lp->data->t_sleep_cycle + 100); + /* xtal_trim value is calculated by: + * CL = 0.5 * (CX + CTRIM + CPAR) + * + * whereas: + * CL = capacitor of used crystal + * CX = connected capacitors at xtal pins + * CPAR = in all at86rf2xx datasheets this is a constant value 3 pF, + * but this is different on each board setup. You need to fine + * tuning this value via CTRIM. + * CTRIM = variable capacitor setting. Resolution is 0.3 pF range is + * 0 pF upto 4.5 pF. + * + * Examples: + * atben transceiver: + * + * CL = 8 pF + * CX = 12 pF + * CPAR = 3 pF (We assume the magic constant from datasheet) + * CTRIM = 0.9 pF + * + * (12+0.9+3)/2 = 7.95 which is nearly at 8 pF + * + * xtal_trim = 0x3 + * + * openlabs transceiver: + * + * CL = 16 pF + * CX = 22 pF + * CPAR = 3 pF (We assume the magic constant from datasheet) + * CTRIM = 4.5 pF + * + * (22+4.5+3)/2 = 14.75 which is the nearest value to 16 pF + * + * xtal_trim = 0xf + */ + rc = at86rf230_write_subreg(lp, SR_XTAL_TRIM, xtal_trim); + if (rc) + return rc; + rc = at86rf230_read_subreg(lp, SR_DVDD_OK, &dvdd); if (rc) return rc; @@ -1377,24 +1421,30 @@ static int at86rf230_hw_init(struct at86rf230_local *lp) return at86rf230_write_subreg(lp, SR_SLOTTED_OPERATION, 0); } -static struct at86rf230_platform_data * -at86rf230_get_pdata(struct spi_device *spi) +static int +at86rf230_get_pdata(struct spi_device *spi, int *rstn, int *slp_tr, + u8 *xtal_trim) { - struct at86rf230_platform_data *pdata; + struct at86rf230_platform_data *pdata = spi->dev.platform_data; + int ret; - if (!IS_ENABLED(CONFIG_OF) || !spi->dev.of_node) - return spi->dev.platform_data; + if (!IS_ENABLED(CONFIG_OF) || !spi->dev.of_node) { + if (!pdata) + return -ENOENT; - pdata = devm_kzalloc(&spi->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - goto done; + *rstn = pdata->rstn; + *slp_tr = pdata->slp_tr; + *xtal_trim = pdata->xtal_trim; + return 0; + } - pdata->rstn = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0); - pdata->slp_tr = of_get_named_gpio(spi->dev.of_node, "sleep-gpio", 0); + *rstn = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0); + *slp_tr = of_get_named_gpio(spi->dev.of_node, "sleep-gpio", 0); + ret = of_property_read_u8(spi->dev.of_node, "xtal-trim", xtal_trim); + if (ret < 0 && ret != -EINVAL) + return ret; - spi->dev.platform_data = pdata; -done: - return pdata; + return 0; } static int @@ -1501,43 +1551,43 @@ at86rf230_setup_spi_messages(struct at86rf230_local *lp) static int at86rf230_probe(struct spi_device *spi) { - struct at86rf230_platform_data *pdata; struct ieee802154_hw *hw; struct at86rf230_local *lp; unsigned int status; - int rc, irq_type; + int rc, irq_type, rstn, slp_tr; + u8 xtal_trim; if (!spi->irq) { dev_err(&spi->dev, "no IRQ specified\n"); return -EINVAL; } - pdata = at86rf230_get_pdata(spi); - if (!pdata) { - dev_err(&spi->dev, "no platform_data\n"); - return -EINVAL; + rc = at86rf230_get_pdata(spi, &rstn, &slp_tr, &xtal_trim); + if (rc < 0) { + dev_err(&spi->dev, "failed to parse platform_data: %d\n", rc); + return rc; } - if (gpio_is_valid(pdata->rstn)) { - rc = devm_gpio_request_one(&spi->dev, pdata->rstn, + if (gpio_is_valid(rstn)) { + rc = devm_gpio_request_one(&spi->dev, rstn, GPIOF_OUT_INIT_HIGH, "rstn"); if (rc) return rc; } - if (gpio_is_valid(pdata->slp_tr)) { - rc = devm_gpio_request_one(&spi->dev, pdata->slp_tr, + if (gpio_is_valid(slp_tr)) { + rc = devm_gpio_request_one(&spi->dev, slp_tr, GPIOF_OUT_INIT_LOW, "slp_tr"); if (rc) return rc; } /* Reset */ - if (gpio_is_valid(pdata->rstn)) { + if (gpio_is_valid(rstn)) { udelay(1); - gpio_set_value(pdata->rstn, 0); + gpio_set_value(rstn, 0); udelay(1); - gpio_set_value(pdata->rstn, 1); + gpio_set_value(rstn, 1); usleep_range(120, 240); } @@ -1571,7 +1621,7 @@ static int at86rf230_probe(struct spi_device *spi) spi_set_drvdata(spi, lp); - rc = at86rf230_hw_init(lp); + rc = at86rf230_hw_init(lp, xtal_trim); if (rc) goto free_dev; |