NXP bluetooth chip shares power supply and reset gpio with a WLAN chip. Add support for power supply and reset and enforce powerup sequence: 1. apply power supply 2. deassert reset/powerdown Signed-off-by: Catalin Popescu <catalin.popescu@xxxxxxxxxxxxxxxxxxxx> --- drivers/bluetooth/btnxpuart.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c index 4f493be763b8..e58e7ac7999f 100644 --- a/drivers/bluetooth/btnxpuart.c +++ b/drivers/bluetooth/btnxpuart.c @@ -16,6 +16,8 @@ #include <linux/crc8.h> #include <linux/crc32.h> #include <linux/string_helpers.h> +#include <linux/regulator/consumer.h> +#include <linux/reset.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> @@ -188,6 +190,7 @@ struct btnxpuart_dev { struct ps_data psdata; struct btnxpuart_data *nxp_data; + struct reset_control *pdn; }; #define NXP_V1_FW_REQ_PKT 0xa5 @@ -1458,6 +1461,7 @@ static int nxp_serdev_probe(struct serdev_device *serdev) { struct hci_dev *hdev; struct btnxpuart_dev *nxpdev; + int err; nxpdev = devm_kzalloc(&serdev->dev, sizeof(*nxpdev), GFP_KERNEL); if (!nxpdev) @@ -1485,6 +1489,16 @@ static int nxp_serdev_probe(struct serdev_device *serdev) crc8_populate_msb(crc8_table, POLYNOMIAL8); + nxpdev->pdn = devm_reset_control_get_optional_shared(&serdev->dev, NULL); + if (IS_ERR(nxpdev->pdn)) + return PTR_ERR(nxpdev->pdn); + + err = devm_regulator_get_enable(&serdev->dev, "vcc"); + if (err) { + dev_err(&serdev->dev, "Failed to enable vcc regulator\n"); + return err; + } + /* Initialize and register HCI device */ hdev = hci_alloc_dev(); if (!hdev) { @@ -1492,6 +1506,8 @@ static int nxp_serdev_probe(struct serdev_device *serdev) return -ENOMEM; } + reset_control_deassert(nxpdev->pdn); + nxpdev->hdev = hdev; hdev->bus = HCI_UART; @@ -1509,6 +1525,7 @@ static int nxp_serdev_probe(struct serdev_device *serdev) if (hci_register_dev(hdev) < 0) { dev_err(&serdev->dev, "Can't register HCI device\n"); + reset_control_assert(nxpdev->pdn); hci_free_dev(hdev); return -ENODEV; } @@ -1540,6 +1557,7 @@ static void nxp_serdev_remove(struct serdev_device *serdev) } ps_cleanup(nxpdev); hci_unregister_dev(hdev); + reset_control_assert(nxpdev->pdn); hci_free_dev(hdev); } -- 2.34.1