static int hci_uart_setup(struct hci_dev *hdev) { struct hci_uart *hu = hci_get_drvdata(hdev); struct hci_rp_read_local_version *ver; struct sk_buff *skb; unsigned int speed; int err; /* Init speed if any */ if (hu->init_speed) speed = hu->init_speed; else if (hu->proto->init_speed) speed = hu->proto->init_speed; else speed = 0; if (speed) serdev_device_set_baudrate(hu->serdev, speed); /* Operational speed if any */ if (hu->oper_speed) speed = hu->oper_speed; else if (hu->proto->oper_speed) speed = hu->proto->oper_speed; else speed = 0; if (hu->proto->set_baudrate && speed) { err = hu->proto->set_baudrate(hu, speed); if (err) BT_ERR("%s: failed to set baudrate", hdev->name); else serdev_device_set_baudrate(hu->serdev, speed); } if (hu->proto->setup) return hu->proto->setup(hu); if (!test_bit(HCI_UART_VND_DETECT, &hu->hdev_flags)) return 0; skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL, HCI_INIT_TIMEOUT); if (IS_ERR(skb)) { BT_ERR("%s: Reading local version information failed (%ld)", hdev->name, PTR_ERR(skb)); return 0; } if (skb->len != sizeof(*ver)) { BT_ERR("%s: Event length mismatch for version information", hdev->name); } kfree_skb(skb); return 0; }
static int sirf_open(struct gnss_device *gdev) { struct sirf_data *data = gnss_get_drvdata(gdev); struct serdev_device *serdev = data->serdev; int ret; ret = serdev_device_open(serdev); if (ret) return ret; serdev_device_set_baudrate(serdev, data->speed); serdev_device_set_flow_control(serdev, false); ret = pm_runtime_get_sync(&serdev->dev); if (ret < 0) { dev_err(&gdev->dev, "failed to runtime resume: %d\n", ret); pm_runtime_put_noidle(&serdev->dev); goto err_close; } return 0; err_close: serdev_device_close(serdev); return ret; }
static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed) { if (hu->serdev) serdev_device_set_baudrate(hu->serdev, speed); else hci_uart_set_baudrate(hu, speed); }
static int nokia_reset(struct hci_uart *hu) { struct nokia_bt_dev *btdev = hu->priv; struct device *dev = &btdev->serdev->dev; int err; /* reset routine */ gpiod_set_value_cansleep(btdev->reset, 1); gpiod_set_value_cansleep(btdev->wakeup_bt, 1); msleep(100); /* safety check */ err = gpiod_get_value_cansleep(btdev->wakeup_host); if (err == 1) { dev_err(dev, "reset: host wakeup not low!"); return -EPROTO; } /* flush queue */ serdev_device_write_flush(btdev->serdev); /* init uart */ nokia_flow_control(btdev->serdev, false); serdev_device_set_baudrate(btdev->serdev, INIT_BAUD_RATE); gpiod_set_value_cansleep(btdev->reset, 0); /* wait for cts */ err = serdev_device_wait_for_cts(btdev->serdev, true, 200); if (err < 0) { dev_err(dev, "CTS not received: %d", err); return err; } nokia_flow_control(btdev->serdev, true); return 0; }
static int nokia_setup(struct hci_uart *hu) { struct nokia_bt_dev *btdev = hu->priv; struct device *dev = &btdev->serdev->dev; int err; btdev->initialized = false; nokia_flow_control(btdev->serdev, false); pm_runtime_get_sync(dev); if (btdev->tx_enabled) { gpiod_set_value_cansleep(btdev->wakeup_bt, 0); pm_runtime_put(&btdev->serdev->dev); btdev->tx_enabled = false; } dev_dbg(dev, "protocol setup"); /* 0. reset connection */ err = nokia_reset(hu); if (err < 0) { dev_err(dev, "Reset failed: %d", err); goto out; } /* 1. negotiate speed etc */ err = nokia_send_negotiation(hu); if (err < 0) { dev_err(dev, "Negotiation failed: %d", err); goto out; } /* 2. verify correct setup using alive packet */ err = nokia_send_alive_packet(hu); if (err < 0) { dev_err(dev, "Alive check failed: %d", err); goto out; } /* 3. send firmware */ err = nokia_setup_fw(hu); if (err < 0) { dev_err(dev, "Could not setup FW: %d", err); goto out; } nokia_flow_control(btdev->serdev, false); serdev_device_set_baudrate(btdev->serdev, MAX_BAUD_RATE); nokia_flow_control(btdev->serdev, true); if (btdev->man_id == NOKIA_ID_BCM2048) { hu->hdev->set_bdaddr = btbcm_set_bdaddr; set_bit(HCI_QUIRK_INVALID_BDADDR, &hu->hdev->quirks); dev_dbg(dev, "bcm2048 has invalid bluetooth address!"); } dev_dbg(dev, "protocol setup done!"); gpiod_set_value_cansleep(btdev->wakeup_bt, 0); pm_runtime_put(dev); btdev->tx_enabled = false; btdev->initialized = true; return 0; out: pm_runtime_put(dev); return err; }
static int nokia_send_negotiation(struct hci_uart *hu) { struct nokia_bt_dev *btdev = hu->priv; struct device *dev = &btdev->serdev->dev; struct hci_nokia_neg_cmd *neg_cmd; struct hci_nokia_neg_hdr *neg_hdr; struct sk_buff *skb; int len, err; u16 baud = DIV_ROUND_CLOSEST(btdev->sysclk_speed * 10, SETUP_BAUD_RATE); int sysclk = btdev->sysclk_speed / 1000; len = H4_TYPE_SIZE + sizeof(*neg_hdr) + sizeof(*neg_cmd); skb = bt_skb_alloc(len, GFP_KERNEL); if (!skb) return -ENOMEM; hci_skb_pkt_type(skb) = HCI_NOKIA_NEG_PKT; neg_hdr = skb_put(skb, sizeof(*neg_hdr)); neg_hdr->dlen = sizeof(*neg_cmd); neg_cmd = skb_put(skb, sizeof(*neg_cmd)); neg_cmd->ack = NOKIA_NEG_REQ; neg_cmd->baud = cpu_to_le16(baud); neg_cmd->unused1 = 0x0000; neg_cmd->proto = NOKIA_PROTO_BYTE; neg_cmd->sys_clk = cpu_to_le16(sysclk); neg_cmd->unused2 = 0x0000; btdev->init_error = 0; init_completion(&btdev->init_completion); nokia_enqueue(hu, skb); hci_uart_tx_wakeup(hu); dev_dbg(dev, "Negotiation sent"); if (!wait_for_completion_interruptible_timeout(&btdev->init_completion, msecs_to_jiffies(10000))) { return -ETIMEDOUT; } if (btdev->init_error < 0) return btdev->init_error; /* Change to previously negotiated speed. Flow Control * is disabled until bluetooth adapter is ready to avoid * broken bytes being received. */ nokia_flow_control(btdev->serdev, false); serdev_device_set_baudrate(btdev->serdev, SETUP_BAUD_RATE); err = serdev_device_wait_for_cts(btdev->serdev, true, 200); if (err < 0) { dev_err(dev, "CTS not received: %d", err); return err; } nokia_flow_control(btdev->serdev, true); dev_dbg(dev, "Negotiation successful"); return 0; }