Re: [PATCH 2/3] Bluetooth: hci_qca: Support QCA2066 on M.2 connector via pwrseq
From: Dmitry Baryshkov
Date: Sun May 24 2026 - 06:40:41 EST
On Fri, May 22, 2026 at 06:11:08PM +0200, Loic Poulain wrote:
> On Wed, May 20, 2026 at 2:33 PM Dmitry Baryshkov
> <dmitry.baryshkov@xxxxxxxxxxxxxxxx> wrote:
> >
> > On Wed, May 20, 2026 at 01:01:43PM +0200, Loic Poulain wrote:
> > > For QCA2066 (and other QCA chips) on M.2 connectors, the UART enable
> > > is controlled by the W_DISABLE2# signal managed by the pcie-m2 power
> > > sequencer rather than a dedicated BT enable GPIO.
> > >
> > > When the serdev controller has an OF graph (indicating it is connected
> > > to an M.2 connector), acquire the 'uart' pwrseq target from the
> > > connector's power sequencer and use it to control BT power instead of
> > > the bt-enable GPIO.
> > >
> > > Also allocate bt_power unconditionally for all SOC types since the
> > > pwrseq path is independent of the SOC type switch.
> > >
> > > Signed-off-by: Loic Poulain <loic.poulain@xxxxxxxxxxxxxxxx>
> > > ---
> > > drivers/bluetooth/hci_qca.c | 33 +++++++++++++--------------------
> > > 1 file changed, 13 insertions(+), 20 deletions(-)
> > >
> > > diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
> > > index b5439b9956cfb0497e6ba6ccd9ed61224d23a9dd..de5cba7b7f44e280a48dad5d670fa2758d3268d0 100644
> > > --- a/drivers/bluetooth/hci_qca.c
> > > +++ b/drivers/bluetooth/hci_qca.c
> > > @@ -1873,6 +1873,9 @@ static int qca_power_on(struct hci_dev *hdev)
> > > /* Controller needs time to bootup. */
> > > msleep(150);
> > > }
> > > +
> > > + if (qcadev->bt_power && qcadev->bt_power->pwrseq)
> > > + pwrseq_power_on(qcadev->bt_power->pwrseq);
> > > }
> > >
> > > clear_bit(QCA_BT_OFF, &qca->flags);
> > > @@ -2415,25 +2418,9 @@ static int qca_serdev_probe(struct serdev_device *serdev)
> > > else
> > > qcadev->btsoc_type = QCA_ROME;
> > >
> > > - switch (qcadev->btsoc_type) {
> > > - case QCA_QCA6390:
> > > - case QCA_WCN3950:
> > > - case QCA_WCN3988:
> > > - case QCA_WCN3990:
> > > - case QCA_WCN3991:
> > > - case QCA_WCN3998:
> > > - case QCA_WCN6750:
> > > - case QCA_WCN6855:
> > > - case QCA_WCN7850:
> > > - qcadev->bt_power = devm_kzalloc(&serdev->dev,
> > > - sizeof(struct qca_power),
> > > - GFP_KERNEL);
> > > - if (!qcadev->bt_power)
> > > - return -ENOMEM;
> > > - break;
> > > - default:
> > > - break;
> > > - }
> > > + qcadev->bt_power = devm_kzalloc(&serdev->dev, sizeof(struct qca_power), GFP_KERNEL);
> > > + if (!qcadev->bt_power)
> > > + return -ENOMEM;
> >
> > This builds bt_power for all devices even though it wasn't the case
> > beforehand. As such, you can drop all further `if (qcadev->bt_power)`
> > checks in the driver. But, you also need to check that this won't break
> > support for other (older) chips.
>
> Ok, I will do, and double check.
>
> >
> > >
> > > switch (qcadev->btsoc_type) {
> > > case QCA_WCN3950:
> > > @@ -2543,7 +2530,13 @@ static int qca_serdev_probe(struct serdev_device *serdev)
> > > return PTR_ERR(qcadev->bt_en);
> > > }
> > >
> > > - if (!qcadev->bt_en)
> > > + if (of_graph_is_present(dev_of_node(&serdev->ctrl->dev))) {
> >
> > And this breaks support for pwrseq for non-M.2 BT devices. There is no
> > OF graph in such a case.
>
> Not sure why, here we handle OF graph as an optional pwrseq provider,
> but still support legacy enablement.
What about the case when pwrseq is supposed to be used (via the PMU)?
There is no OF graph in such a case. Please check that your changes
don't break e.g. RB1.
> > > + qcadev->bt_power->pwrseq = devm_pwrseq_get(&serdev->ctrl->dev, "uart");
> > > + if (IS_ERR(qcadev->bt_power->pwrseq))
> > > + return PTR_ERR(qcadev->bt_power->pwrseq);
> > > + }
> > > +
> > > + if (!qcadev->bt_en && !qcadev->bt_power->pwrseq)
> > > bt_en_available = false;
> > >
> > > qcadev->susclk = devm_clk_get_optional_enabled_with_rate(
> > >
--
With best wishes
Dmitry