Skip to content

Commit

Permalink
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/bluetooth/bluetooth-next

Johan Hedberg says:

====================
pull request: bluetooth-next 2015-03-19

This wont the last 4.1 bluetooth-next pull request, but we've piled up
enough patches in less than a week that I wanted to save you from a
single huge "last-minute" pull somewhere closer to the merge window.

The main changes are:

 - Simultaneous LE & BR/EDR discovery support for HW that can do it
 - Complete LE OOB pairing support
 - More fine-grained mgmt-command access control (normal user can now do
   harmless read-only operations).
 - Added RF power amplifier support in cc2520 ieee802154 driver
 - Some cleanups/fixes in ieee802154 code

Please let me know if there are any issues pulling. Thanks.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 19, 2015
2 parents c9bdc0d + ea6edfb commit 970282d
Show file tree
Hide file tree
Showing 20 changed files with 1,485 additions and 640 deletions.
4 changes: 4 additions & 0 deletions Documentation/devicetree/bindings/net/ieee802154/cc2520.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ Required properties:
- cca-gpio: GPIO spec for the CCA pin
- vreg-gpio: GPIO spec for the VREG pin
- reset-gpio: GPIO spec for the RESET pin
Optional properties:
- amplified: include if the CC2520 is connected to a CC2591 amplifier

Example:
cc2520@0 {
compatible = "ti,cc2520";
reg = <0>;
spi-max-frequency = <4000000>;
amplified;
pinctrl-names = "default";
pinctrl-0 = <&cc2520_cape_pins>;
fifo-gpio = <&gpio1 18 0>;
Expand Down
8 changes: 6 additions & 2 deletions drivers/bluetooth/btusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },

/* QCA ROME chipset */
{ USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME},
{ USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME},
{ USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME },
{ USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME },

/* Broadcom BCM2035 */
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
Expand Down Expand Up @@ -3019,6 +3019,7 @@ static int btusb_probe(struct usb_interface *intf,
hdev->shutdown = btusb_shutdown_intel;
hdev->set_bdaddr = btusb_set_bdaddr_intel;
set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
}

if (id->driver_info & BTUSB_INTEL_NEW) {
Expand All @@ -3042,6 +3043,7 @@ static int btusb_probe(struct usb_interface *intf,

if (id->driver_info & BTUSB_ATH3012) {
hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
}

Expand Down Expand Up @@ -3085,6 +3087,8 @@ static int btusb_probe(struct usb_interface *intf,
/* Fake CSR devices with broken commands */
if (bcdDevice <= 0x100)
hdev->setup = btusb_setup_csr;

set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
}

if (id->driver_info & BTUSB_SNIFFER) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ieee802154/at86rf230.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ at86rf230_read_subreg(struct at86rf230_local *lp,
int rc;

rc = __at86rf230_read(lp, addr, data);
if (rc > 0)
if (!rc)
*data = (*data & mask) >> shift;

return rc;
Expand Down
150 changes: 93 additions & 57 deletions drivers/net/ieee802154/cc2520.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,11 +714,45 @@ static irqreturn_t cc2520_sfd_isr(int irq, void *data)
return IRQ_HANDLED;
}

static int cc2520_get_platform_data(struct spi_device *spi,
struct cc2520_platform_data *pdata)
{
struct device_node *np = spi->dev.of_node;
struct cc2520_private *priv = spi_get_drvdata(spi);

if (!np) {
struct cc2520_platform_data *spi_pdata = spi->dev.platform_data;
if (!spi_pdata)
return -ENOENT;
*pdata = *spi_pdata;
return 0;
}

pdata->fifo = of_get_named_gpio(np, "fifo-gpio", 0);
priv->fifo_pin = pdata->fifo;

pdata->fifop = of_get_named_gpio(np, "fifop-gpio", 0);

pdata->sfd = of_get_named_gpio(np, "sfd-gpio", 0);
pdata->cca = of_get_named_gpio(np, "cca-gpio", 0);
pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0);
pdata->reset = of_get_named_gpio(np, "reset-gpio", 0);

pdata->amplified = of_property_read_bool(np, "amplified");

return 0;
}

static int cc2520_hw_init(struct cc2520_private *priv)
{
u8 status = 0, state = 0xff;
int ret;
int timeout = 100;
struct cc2520_platform_data pdata;

ret = cc2520_get_platform_data(priv->spi, &pdata);
if (ret)
goto err_ret;

ret = cc2520_read_register(priv, CC2520_FSMSTAT1, &state);
if (ret)
Expand All @@ -741,11 +775,47 @@ static int cc2520_hw_init(struct cc2520_private *priv)

dev_vdbg(&priv->spi->dev, "oscillator brought up\n");

/* Registers default value: section 28.1 in Datasheet */
ret = cc2520_write_register(priv, CC2520_TXPOWER, 0xF7);
if (ret)
goto err_ret;
/* If the CC2520 is connected to a CC2591 amplifier, we must both
* configure GPIOs on the CC2520 to correctly configure the CC2591
* and change a couple settings of the CC2520 to work with the
* amplifier. See section 8 page 17 of TI application note AN065.
* http://www.ti.com/lit/an/swra229a/swra229a.pdf
*/
if (pdata.amplified) {
ret = cc2520_write_register(priv, CC2520_TXPOWER, 0xF9);
if (ret)
goto err_ret;

ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x16);
if (ret)
goto err_ret;

ret = cc2520_write_register(priv, CC2520_GPIOCTRL0, 0x46);
if (ret)
goto err_ret;

ret = cc2520_write_register(priv, CC2520_GPIOCTRL5, 0x47);
if (ret)
goto err_ret;

ret = cc2520_write_register(priv, CC2520_GPIOPOLARITY, 0x1e);
if (ret)
goto err_ret;

ret = cc2520_write_register(priv, CC2520_TXCTRL, 0xc1);
if (ret)
goto err_ret;
} else {
ret = cc2520_write_register(priv, CC2520_TXPOWER, 0xF7);
if (ret)
goto err_ret;

ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x11);
if (ret)
goto err_ret;
}

/* Registers default value: section 28.1 in Datasheet */
ret = cc2520_write_register(priv, CC2520_CCACTRL0, 0x1A);
if (ret)
goto err_ret;
Expand All @@ -770,10 +840,6 @@ static int cc2520_hw_init(struct cc2520_private *priv)
if (ret)
goto err_ret;

ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x11);
if (ret)
goto err_ret;

ret = cc2520_write_register(priv, CC2520_ADCTEST0, 0x10);
if (ret)
goto err_ret;
Expand Down Expand Up @@ -808,40 +874,10 @@ static int cc2520_hw_init(struct cc2520_private *priv)
return ret;
}

static struct cc2520_platform_data *
cc2520_get_platform_data(struct spi_device *spi)
{
struct cc2520_platform_data *pdata;
struct device_node *np = spi->dev.of_node;
struct cc2520_private *priv = spi_get_drvdata(spi);

if (!np)
return spi->dev.platform_data;

pdata = devm_kzalloc(&spi->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
goto done;

pdata->fifo = of_get_named_gpio(np, "fifo-gpio", 0);
priv->fifo_pin = pdata->fifo;

pdata->fifop = of_get_named_gpio(np, "fifop-gpio", 0);

pdata->sfd = of_get_named_gpio(np, "sfd-gpio", 0);
pdata->cca = of_get_named_gpio(np, "cca-gpio", 0);
pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0);
pdata->reset = of_get_named_gpio(np, "reset-gpio", 0);

spi->dev.platform_data = pdata;

done:
return pdata;
}

static int cc2520_probe(struct spi_device *spi)
{
struct cc2520_private *priv;
struct cc2520_platform_data *pdata;
struct cc2520_platform_data pdata;
int ret;

priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
Expand All @@ -850,8 +886,8 @@ static int cc2520_probe(struct spi_device *spi)

spi_set_drvdata(spi, priv);

pdata = cc2520_get_platform_data(spi);
if (!pdata) {
ret = cc2520_get_platform_data(spi, &pdata);
if (ret < 0) {
dev_err(&spi->dev, "no platform data\n");
return -EINVAL;
}
Expand All @@ -869,76 +905,76 @@ static int cc2520_probe(struct spi_device *spi)
init_completion(&priv->tx_complete);

/* Request all the gpio's */
if (!gpio_is_valid(pdata->fifo)) {
if (!gpio_is_valid(pdata.fifo)) {
dev_err(&spi->dev, "fifo gpio is not valid\n");
ret = -EINVAL;
goto err_hw_init;
}

ret = devm_gpio_request_one(&spi->dev, pdata->fifo,
ret = devm_gpio_request_one(&spi->dev, pdata.fifo,
GPIOF_IN, "fifo");
if (ret)
goto err_hw_init;

if (!gpio_is_valid(pdata->cca)) {
if (!gpio_is_valid(pdata.cca)) {
dev_err(&spi->dev, "cca gpio is not valid\n");
ret = -EINVAL;
goto err_hw_init;
}

ret = devm_gpio_request_one(&spi->dev, pdata->cca,
ret = devm_gpio_request_one(&spi->dev, pdata.cca,
GPIOF_IN, "cca");
if (ret)
goto err_hw_init;

if (!gpio_is_valid(pdata->fifop)) {
if (!gpio_is_valid(pdata.fifop)) {
dev_err(&spi->dev, "fifop gpio is not valid\n");
ret = -EINVAL;
goto err_hw_init;
}

ret = devm_gpio_request_one(&spi->dev, pdata->fifop,
ret = devm_gpio_request_one(&spi->dev, pdata.fifop,
GPIOF_IN, "fifop");
if (ret)
goto err_hw_init;

if (!gpio_is_valid(pdata->sfd)) {
if (!gpio_is_valid(pdata.sfd)) {
dev_err(&spi->dev, "sfd gpio is not valid\n");
ret = -EINVAL;
goto err_hw_init;
}

ret = devm_gpio_request_one(&spi->dev, pdata->sfd,
ret = devm_gpio_request_one(&spi->dev, pdata.sfd,
GPIOF_IN, "sfd");
if (ret)
goto err_hw_init;

if (!gpio_is_valid(pdata->reset)) {
if (!gpio_is_valid(pdata.reset)) {
dev_err(&spi->dev, "reset gpio is not valid\n");
ret = -EINVAL;
goto err_hw_init;
}

ret = devm_gpio_request_one(&spi->dev, pdata->reset,
ret = devm_gpio_request_one(&spi->dev, pdata.reset,
GPIOF_OUT_INIT_LOW, "reset");
if (ret)
goto err_hw_init;

if (!gpio_is_valid(pdata->vreg)) {
if (!gpio_is_valid(pdata.vreg)) {
dev_err(&spi->dev, "vreg gpio is not valid\n");
ret = -EINVAL;
goto err_hw_init;
}

ret = devm_gpio_request_one(&spi->dev, pdata->vreg,
ret = devm_gpio_request_one(&spi->dev, pdata.vreg,
GPIOF_OUT_INIT_LOW, "vreg");
if (ret)
goto err_hw_init;

gpio_set_value(pdata->vreg, HIGH);
gpio_set_value(pdata.vreg, HIGH);
usleep_range(100, 150);

gpio_set_value(pdata->reset, HIGH);
gpio_set_value(pdata.reset, HIGH);
usleep_range(200, 250);

ret = cc2520_hw_init(priv);
Expand All @@ -947,7 +983,7 @@ static int cc2520_probe(struct spi_device *spi)

/* Set up fifop interrupt */
ret = devm_request_irq(&spi->dev,
gpio_to_irq(pdata->fifop),
gpio_to_irq(pdata.fifop),
cc2520_fifop_isr,
IRQF_TRIGGER_RISING,
dev_name(&spi->dev),
Expand All @@ -959,7 +995,7 @@ static int cc2520_probe(struct spi_device *spi)

/* Set up sfd interrupt */
ret = devm_request_irq(&spi->dev,
gpio_to_irq(pdata->sfd),
gpio_to_irq(pdata.sfd),
cc2520_sfd_isr,
IRQF_TRIGGER_FALLING,
dev_name(&spi->dev),
Expand Down
1 change: 1 addition & 0 deletions include/linux/spi/cc2520.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct cc2520_platform_data {
int sfd;
int reset;
int vreg;
bool amplified;
};

#endif
5 changes: 5 additions & 0 deletions include/net/bluetooth/bluetooth.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,11 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk,

int bt_to_errno(__u16 code);

void hci_sock_set_flag(struct sock *sk, int nr);
void hci_sock_clear_flag(struct sock *sk, int nr);
int hci_sock_test_flag(struct sock *sk, int nr);
unsigned short hci_sock_get_channel(struct sock *sk);

int hci_sock_init(void);
void hci_sock_cleanup(void);

Expand Down
22 changes: 22 additions & 0 deletions include/net/bluetooth/hci.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,14 @@ enum {
* during the hdev->setup vendor callback.
*/
HCI_QUIRK_STRICT_DUPLICATE_FILTER,

/* When this quirk is set, LE scan and BR/EDR inquiry is done
* simultaneously, otherwise it's interleaved.
*
* This quirk can be set before hci_register_dev is called or
* during the hdev->setup vendor callback.
*/
HCI_QUIRK_SIMULTANEOUS_DISCOVERY,
};

/* HCI device flags */
Expand All @@ -179,6 +187,16 @@ enum {
HCI_RESET,
};

/* HCI socket flags */
enum {
HCI_SOCK_TRUSTED,
HCI_MGMT_INDEX_EVENTS,
HCI_MGMT_UNCONF_INDEX_EVENTS,
HCI_MGMT_EXT_INDEX_EVENTS,
HCI_MGMT_GENERIC_EVENTS,
HCI_MGMT_OOB_DATA_EVENTS,
};

/*
* BR/EDR and/or LE controller flags: the flags defined here should represent
* states from the controller.
Expand Down Expand Up @@ -447,6 +465,10 @@ enum {
#define EIR_SSP_HASH_C 0x0E /* Simple Pairing Hash C */
#define EIR_SSP_RAND_R 0x0F /* Simple Pairing Randomizer R */
#define EIR_DEVICE_ID 0x10 /* device ID */
#define EIR_LE_BDADDR 0x1B /* LE Bluetooth device address */
#define EIR_LE_ROLE 0x1C /* LE role */
#define EIR_LE_SC_CONFIRM 0x22 /* LE SC Confirmation Value */
#define EIR_LE_SC_RANDOM 0x23 /* LE SC Random Value */

/* Low Energy Advertising Flags */
#define LE_AD_LIMITED 0x01 /* Limited Discoverable */
Expand Down
Loading

0 comments on commit 970282d

Please sign in to comment.