2021-12-18 01:09:02

by Sean Wang

[permalink] [raw]
Subject: [PATCH RESEND 1/3] Bluetooth: btmtksdio: add the support of wake on bluetooth

From: Mark Chen <[email protected]>

Add the support to enable wake on bluetooth

Co-developed-by: Sean Wang <[email protected]>
Signed-off-by: Sean Wang <[email protected]>
Signed-off-by: Mark Chen <[email protected]>
---
drivers/bluetooth/btmtk.h | 8 ++++++++
drivers/bluetooth/btmtksdio.c | 31 ++++++++++++++++++++++++++++++-
2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
index 6e7b0c7567c0..2be1d2680ad8 100644
--- a/drivers/bluetooth/btmtk.h
+++ b/drivers/bluetooth/btmtk.h
@@ -68,6 +68,14 @@ struct btmtk_tci_sleep {
u8 time_compensation;
} __packed;

+struct btmtk_wakeon {
+ u8 mode;
+ u8 gpo;
+ u8 active_high;
+ __le16 enable_delay;
+ __le16 wakeup_delay;
+} __packed;
+
struct btmtk_hci_wmt_params {
u8 op;
u8 flag;
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index b5ea8d3bffaa..771733ce362b 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -958,6 +958,30 @@ static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
return 0;
}

+static bool btmtk_sdio_wakeup(struct hci_dev *hdev)
+{
+ struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
+ bool may_wakeup = device_may_wakeup(bdev->dev);
+ struct btmtk_wakeon bt_awake = {
+ .mode = 0x1,
+ .gpo = 0,
+ .active_high = 0x1,
+ .enable_delay = cpu_to_le16(0xc80),
+ .wakeup_delay = cpu_to_le16(0x20)
+ };
+ struct sk_buff *skb;
+
+ if (may_wakeup &&
+ bdev->data->chipid == 0x7921) {
+ skb = __hci_cmd_sync(hdev, 0xfc27, sizeof(bt_awake),
+ &bt_awake, HCI_CMD_TIMEOUT);
+ if (IS_ERR(skb))
+ may_wakeup = false;
+ }
+
+ return may_wakeup;
+}
+
static int btmtksdio_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
@@ -998,6 +1022,7 @@ static int btmtksdio_probe(struct sdio_func *func,
hdev->shutdown = btmtksdio_shutdown;
hdev->send = btmtksdio_send_frame;
hdev->set_bdaddr = btmtk_set_bdaddr;
+ hdev->wakeup = btmtk_sdio_wakeup;

SET_HCIDEV_DEV(hdev, &func->dev);

@@ -1032,7 +1057,11 @@ static int btmtksdio_probe(struct sdio_func *func,
*/
pm_runtime_put_noidle(bdev->dev);

- return 0;
+ err = device_init_wakeup(bdev->dev, true);
+ if (err)
+ bt_dev_err(hdev, "%s: failed to init_wakeup", __func__);
+
+ return err;
}

static void btmtksdio_remove(struct sdio_func *func)
--
2.25.1



2021-12-18 01:09:05

by Sean Wang

[permalink] [raw]
Subject: [PATCH 2/3] Bluetooth: btmtksdio: Enable SCO over I2S function

From: Mark Chen <[email protected]>

For MediaTek chipset, the driver has to issue the specific command to
enable Bluetooth SCO support over the I2S/PCM interface.

Co-developed-by: Sean Wang <[email protected]>
Signed-off-by: Sean Wang <[email protected]>
Signed-off-by: Mark Chen <[email protected]>
---
drivers/bluetooth/btmtk.h | 20 +++++++++
drivers/bluetooth/btmtksdio.c | 76 +++++++++++++++++++++++++++++++++++
2 files changed, 96 insertions(+)

diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
index 2be1d2680ad8..fc57ef09d132 100644
--- a/drivers/bluetooth/btmtk.h
+++ b/drivers/bluetooth/btmtk.h
@@ -7,8 +7,12 @@

#define HCI_WMT_MAX_EVENT_SIZE 64

+#define BTMTK_WMT_REG_WRITE 0x1
#define BTMTK_WMT_REG_READ 0x2

+#define MT7921_PINMUX_0 0x70005050
+#define MT7921_PINMUX_1 0x70005054
+
enum {
BTMTK_WMT_PATCH_DWNLD = 0x1,
BTMTK_WMT_TEST = 0x2,
@@ -76,6 +80,22 @@ struct btmtk_wakeon {
__le16 wakeup_delay;
} __packed;

+struct btmtk_sco {
+ u8 clock_config;
+ u8 transmit_format_config;
+ u8 channel_format_config;
+ u8 channel_select_config;
+} __packed;
+
+struct reg_write_cmd {
+ u8 type;
+ u8 rsv;
+ u8 num;
+ __le32 addr;
+ __le32 data;
+ __le32 mask;
+} __packed;
+
struct btmtk_hci_wmt_params {
u8 op;
u8 flag;
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index 771733ce362b..8e4d8c2da824 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -830,6 +830,74 @@ static int btsdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
return err;
}

+static int btsdio_mtk_reg_write(struct hci_dev *hdev, u32 reg, u32 val, u32 mask)
+{
+ struct btmtk_hci_wmt_params wmt_params;
+ struct reg_write_cmd reg_write = {
+ .type = 1,
+ .num = 1,
+ .addr = cpu_to_le32(reg),
+ .data = cpu_to_le32(val),
+ .mask = cpu_to_le32(mask),
+ };
+ int err, status;
+
+ wmt_params.op = BTMTK_WMT_REGISTER;
+ wmt_params.flag = BTMTK_WMT_REG_WRITE;
+ wmt_params.dlen = sizeof(reg_write);
+ wmt_params.data = &reg_write;
+ wmt_params.status = &status;
+
+ err = mtk_hci_wmt_sync(hdev, &wmt_params);
+ if (err < 0)
+ bt_dev_err(hdev, "Failed to write reg(%d)", err);
+
+ return err;
+}
+
+static int btsdio_mtk_sco_setting(struct hci_dev *hdev)
+{
+ struct btmtk_sco sco_setting = {
+ .clock_config = 0x49,
+ .channel_format_config = 0x80,
+ };
+ struct sk_buff *skb;
+ u32 val;
+ int err;
+
+ /* Enable SCO over i2s/pcm for Mediatek Chipset */
+ skb = __hci_cmd_sync(hdev, 0xfc72, sizeof(sco_setting),
+ &sco_setting, HCI_CMD_TIMEOUT);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ err = btsdio_mtk_reg_read(hdev, MT7921_PINMUX_0, &val);
+ if (err < 0) {
+ bt_dev_err(hdev, "Failed to read register (%d)", err);
+ return err;
+ }
+
+ val |= 0x11000000;
+ err = btsdio_mtk_reg_write(hdev, MT7921_PINMUX_0, val, ~0);
+ if (err < 0) {
+ bt_dev_err(hdev, "Failed to write register (%d)", err);
+ return err;
+ }
+
+ err = btsdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val);
+ if (err < 0) {
+ bt_dev_err(hdev, "Failed to read register (%d)", err);
+ return err;
+ }
+
+ val |= 0x00000101;
+ err = btsdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0);
+ if (err < 0)
+ bt_dev_err(hdev, "Failed to write register (%d)", err);
+
+ return err;
+}
+
static int btmtksdio_setup(struct hci_dev *hdev)
{
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
@@ -862,6 +930,14 @@ static int btmtksdio_setup(struct hci_dev *hdev)
err = mt79xx_setup(hdev, fwname);
if (err < 0)
return err;
+
+ /* Enable sco over i2s/pcm */
+ err = btsdio_mtk_sco_setting(hdev);
+ if (err < 0) {
+ bt_dev_err(hdev, "Failed to enable sco setting (%d)", err);
+ return err;
+ }
+
break;
case 0x7663:
case 0x7668:
--
2.25.1


2021-12-18 01:09:08

by Sean Wang

[permalink] [raw]
Subject: [PATCH 3/3] Bluetooth: btmtksdio: move struct reg_read_cmd to common file

From: Sean Wang <[email protected]>

move struct reg_read_cmd to btmtk.h to allow other mtk drivers refer to.

Signed-off-by: Sean Wang <[email protected]>
---
drivers/bluetooth/btmtk.h | 7 +++++++
drivers/bluetooth/btmtksdio.c | 7 +------
2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
index fc57ef09d132..fb76d9765ce0 100644
--- a/drivers/bluetooth/btmtk.h
+++ b/drivers/bluetooth/btmtk.h
@@ -87,6 +87,13 @@ struct btmtk_sco {
u8 channel_select_config;
} __packed;

+struct reg_read_cmd {
+ u8 type;
+ u8 rsv;
+ u8 num;
+ __le32 addr;
+} __packed;
+
struct reg_write_cmd {
u8 type;
u8 rsv;
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index 8e4d8c2da824..884678a3951d 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -800,12 +800,7 @@ static int mt79xx_setup(struct hci_dev *hdev, const char *fwname)
static int btsdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
{
struct btmtk_hci_wmt_params wmt_params;
- struct reg_read_cmd {
- u8 type;
- u8 rsv;
- u8 num;
- __le32 addr;
- } __packed reg_read = {
+ struct reg_read_cmd reg_read = {
.type = 1,
.num = 1,
};
--
2.25.1


2021-12-18 10:26:42

by Paul Menzel

[permalink] [raw]
Subject: Re: [PATCH RESEND 1/3] Bluetooth: btmtksdio: add the support of wake on bluetooth

Dear Sean, dear Mark,


Am 18.12.21 um 02:08 schrieb [email protected]:
> From: Mark Chen <[email protected]>

Shorter summary: Bluetooth: btmtksdio: Support wake on bluetooth

> Add the support to enable wake on bluetooth

Can you please list the datasheet name and revision used for the
implementation.

Please document how you tested this.

> Co-developed-by: Sean Wang <[email protected]>
> Signed-off-by: Sean Wang <[email protected]>
> Signed-off-by: Mark Chen <[email protected]>
> ---
> drivers/bluetooth/btmtk.h | 8 ++++++++
> drivers/bluetooth/btmtksdio.c | 31 ++++++++++++++++++++++++++++++-
> 2 files changed, 38 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
> index 6e7b0c7567c0..2be1d2680ad8 100644
> --- a/drivers/bluetooth/btmtk.h
> +++ b/drivers/bluetooth/btmtk.h
> @@ -68,6 +68,14 @@ struct btmtk_tci_sleep {
> u8 time_compensation;
> } __packed;
>
> +struct btmtk_wakeon {
> + u8 mode;
> + u8 gpo;
> + u8 active_high;
> + __le16 enable_delay;
> + __le16 wakeup_delay;
> +} __packed;
> +
> struct btmtk_hci_wmt_params {
> u8 op;
> u8 flag;
> diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
> index b5ea8d3bffaa..771733ce362b 100644
> --- a/drivers/bluetooth/btmtksdio.c
> +++ b/drivers/bluetooth/btmtksdio.c
> @@ -958,6 +958,30 @@ static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
> return 0;
> }
>
> +static bool btmtk_sdio_wakeup(struct hci_dev *hdev)
> +{
> + struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
> + bool may_wakeup = device_may_wakeup(bdev->dev);
> + struct btmtk_wakeon bt_awake = {
> + .mode = 0x1,
> + .gpo = 0,
> + .active_high = 0x1,
> + .enable_delay = cpu_to_le16(0xc80),
> + .wakeup_delay = cpu_to_le16(0x20)
> + };
> + struct sk_buff *skb;
> +
> + if (may_wakeup &&
> + bdev->data->chipid == 0x7921) {

Why the check for 0x7921? Is that device only supported? The commit
message does not say anything about it.

> + skb = __hci_cmd_sync(hdev, 0xfc27, sizeof(bt_awake),
> + &bt_awake, HCI_CMD_TIMEOUT);
> + if (IS_ERR(skb))
> + may_wakeup = false;
> + }
> +
> + return may_wakeup;
> +}
> +
> static int btmtksdio_probe(struct sdio_func *func,
> const struct sdio_device_id *id)
> {
> @@ -998,6 +1022,7 @@ static int btmtksdio_probe(struct sdio_func *func,
> hdev->shutdown = btmtksdio_shutdown;
> hdev->send = btmtksdio_send_frame;
> hdev->set_bdaddr = btmtk_set_bdaddr;
> + hdev->wakeup = btmtk_sdio_wakeup;
>
> SET_HCIDEV_DEV(hdev, &func->dev);
>
> @@ -1032,7 +1057,11 @@ static int btmtksdio_probe(struct sdio_func *func,
> */
> pm_runtime_put_noidle(bdev->dev);
>
> - return 0;
> + err = device_init_wakeup(bdev->dev, true);
> + if (err)
> + bt_dev_err(hdev, "%s: failed to init_wakeup", __func__);

Could the error message be extended, so normal users know what to do?
Currently it’s only useful for developers.

> +
> + return err;
> }
>
> static void btmtksdio_remove(struct sdio_func *func)


Kind regards,

Paul

2021-12-18 10:30:12

by Paul Menzel

[permalink] [raw]
Subject: Re: [PATCH 2/3] Bluetooth: btmtksdio: Enable SCO over I2S function

Dear Sean, dear Mark,


Am 18.12.21 um 02:08 schrieb [email protected]:
> From: Mark Chen <[email protected]>
>
> For MediaTek chipset, the driver has to issue the specific command to
> enable Bluetooth SCO support over the I2S/PCM interface.

Please document the datasheet name, revision and section, where this is
described.

Please add how SCO support can be tested. Are all Mediatek chipsets
supported?

> Co-developed-by: Sean Wang <[email protected]>
> Signed-off-by: Sean Wang <[email protected]>
> Signed-off-by: Mark Chen <[email protected]>
> ---
> drivers/bluetooth/btmtk.h | 20 +++++++++
> drivers/bluetooth/btmtksdio.c | 76 +++++++++++++++++++++++++++++++++++
> 2 files changed, 96 insertions(+)
>
> diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
> index 2be1d2680ad8..fc57ef09d132 100644
> --- a/drivers/bluetooth/btmtk.h
> +++ b/drivers/bluetooth/btmtk.h
> @@ -7,8 +7,12 @@
>
> #define HCI_WMT_MAX_EVENT_SIZE 64
>
> +#define BTMTK_WMT_REG_WRITE 0x1
> #define BTMTK_WMT_REG_READ 0x2
>
> +#define MT7921_PINMUX_0 0x70005050
> +#define MT7921_PINMUX_1 0x70005054
> +
> enum {
> BTMTK_WMT_PATCH_DWNLD = 0x1,
> BTMTK_WMT_TEST = 0x2,
> @@ -76,6 +80,22 @@ struct btmtk_wakeon {
> __le16 wakeup_delay;
> } __packed;
>
> +struct btmtk_sco {
> + u8 clock_config;
> + u8 transmit_format_config;
> + u8 channel_format_config;
> + u8 channel_select_config;
> +} __packed;
> +
> +struct reg_write_cmd {
> + u8 type;
> + u8 rsv;
> + u8 num;
> + __le32 addr;
> + __le32 data;
> + __le32 mask;
> +} __packed;
> +
> struct btmtk_hci_wmt_params {
> u8 op;
> u8 flag;
> diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
> index 771733ce362b..8e4d8c2da824 100644
> --- a/drivers/bluetooth/btmtksdio.c
> +++ b/drivers/bluetooth/btmtksdio.c
> @@ -830,6 +830,74 @@ static int btsdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
> return err;
> }
>
> +static int btsdio_mtk_reg_write(struct hci_dev *hdev, u32 reg, u32 val, u32 mask)
> +{
> + struct btmtk_hci_wmt_params wmt_params;
> + struct reg_write_cmd reg_write = {
> + .type = 1,
> + .num = 1,
> + .addr = cpu_to_le32(reg),
> + .data = cpu_to_le32(val),
> + .mask = cpu_to_le32(mask),
> + };
> + int err, status;
> +
> + wmt_params.op = BTMTK_WMT_REGISTER;
> + wmt_params.flag = BTMTK_WMT_REG_WRITE;
> + wmt_params.dlen = sizeof(reg_write);
> + wmt_params.data = &reg_write;
> + wmt_params.status = &status;
> +
> + err = mtk_hci_wmt_sync(hdev, &wmt_params);
> + if (err < 0)
> + bt_dev_err(hdev, "Failed to write reg(%d)", err);
> +
> + return err;
> +}
> +
> +static int btsdio_mtk_sco_setting(struct hci_dev *hdev)
> +{
> + struct btmtk_sco sco_setting = {
> + .clock_config = 0x49,
> + .channel_format_config = 0x80,
> + };
> + struct sk_buff *skb;
> + u32 val;
> + int err;
> +
> + /* Enable SCO over i2s/pcm for Mediatek Chipset */

s/Chipset/chipset/

> + skb = __hci_cmd_sync(hdev, 0xfc72, sizeof(sco_setting),
> + &sco_setting, HCI_CMD_TIMEOUT);
> + if (IS_ERR(skb))
> + return PTR_ERR(skb);
> +
> + err = btsdio_mtk_reg_read(hdev, MT7921_PINMUX_0, &val);
> + if (err < 0) {
> + bt_dev_err(hdev, "Failed to read register (%d)", err);
> + return err;
> + }
> +
> + val |= 0x11000000;
> + err = btsdio_mtk_reg_write(hdev, MT7921_PINMUX_0, val, ~0);
> + if (err < 0) {
> + bt_dev_err(hdev, "Failed to write register (%d)", err);
> + return err;
> + }
> +
> + err = btsdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val);
> + if (err < 0) {
> + bt_dev_err(hdev, "Failed to read register (%d)", err);
> + return err;
> + }
> +
> + val |= 0x00000101;
> + err = btsdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0);
> + if (err < 0)
> + bt_dev_err(hdev, "Failed to write register (%d)", err);
> +
> + return err;
> +}
> +
> static int btmtksdio_setup(struct hci_dev *hdev)
> {
> struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
> @@ -862,6 +930,14 @@ static int btmtksdio_setup(struct hci_dev *hdev)
> err = mt79xx_setup(hdev, fwname);
> if (err < 0)
> return err;
> +
> + /* Enable sco over i2s/pcm */

s/sco/SCO/

> + err = btsdio_mtk_sco_setting(hdev);
> + if (err < 0) {
> + bt_dev_err(hdev, "Failed to enable sco setting (%d)", err);

s/sco/SCO/

> + return err;
> + }
> +
> break;
> case 0x7663:
> case 0x7668:


Kind regards,

Paul

2021-12-20 17:52:39

by Sean Wang

[permalink] [raw]
Subject: Re: [PATCH 2/3] Bluetooth: btmtksdio: Enable SCO over I2S function

From: Sean Wang <[email protected]>

>Dear Sean, dear Mark,
>
>
>Am 18.12.21 um 02:08 schrieb [email protected]:
>> From: Mark Chen <[email protected]>
>>
>> For MediaTek chipset, the driver has to issue the specific command to
>> enable Bluetooth SCO support over the I2S/PCM interface.
>
>Please document the datasheet name, revision and section, where this is described.

the datasheet is not released in public so Mark and I cannot provide the detail here, but we will make the patch easy to review and understand.

>
>Please add how SCO support can be tested. Are all Mediatek chipsets supported?

the SCO profile was tested by setting up a VOIP application, connected to HFP device, checked telephony function can work normally.

currently, SCO is only supported by mt7921, we will change the subject to "Bluetooth: mt7921s: Enable SCO over I2S function" to avoid any misunderstanding.

>
>> Co-developed-by: Sean Wang <[email protected]>
>> Signed-off-by: Sean Wang <[email protected]>
>> Signed-off-by: Mark Chen <[email protected]>
>> ---
>> drivers/bluetooth/btmtk.h | 20 +++++++++
>> drivers/bluetooth/btmtksdio.c | 76 +++++++++++++++++++++++++++++++++++
>> 2 files changed, 96 insertions(+)
>>
>> diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
>> index 2be1d2680ad8..fc57ef09d132 100644
>> --- a/drivers/bluetooth/btmtk.h
>> +++ b/drivers/bluetooth/btmtk.h
>> @@ -7,8 +7,12 @@
>>
>> #define HCI_WMT_MAX_EVENT_SIZE 64
>>
>> +#define BTMTK_WMT_REG_WRITE 0x1
>> #define BTMTK_WMT_REG_READ 0x2
>>
>> +#define MT7921_PINMUX_0 0x70005050
>> +#define MT7921_PINMUX_1 0x70005054
>> +
>> enum {
>> BTMTK_WMT_PATCH_DWNLD = 0x1,
>> BTMTK_WMT_TEST = 0x2,
>> @@ -76,6 +80,22 @@ struct btmtk_wakeon {
>> __le16 wakeup_delay;
>> } __packed;
>>
>> +struct btmtk_sco {
>> + u8 clock_config;
>> + u8 transmit_format_config;
>> + u8 channel_format_config;
>> + u8 channel_select_config;
>> +} __packed;
>> +
>> +struct reg_write_cmd {
>> + u8 type;
>> + u8 rsv;
>> + u8 num;
>> + __le32 addr;
>> + __le32 data;
>> + __le32 mask;
>> +} __packed;
>> +
>> struct btmtk_hci_wmt_params {
>> u8 op;
>> u8 flag;
>> diff --git a/drivers/bluetooth/btmtksdio.c
>> b/drivers/bluetooth/btmtksdio.c index 771733ce362b..8e4d8c2da824
>> 100644
>> --- a/drivers/bluetooth/btmtksdio.c
>> +++ b/drivers/bluetooth/btmtksdio.c
>> @@ -830,6 +830,74 @@ static int btsdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
>> return err;
>> }
>>
>> +static int btsdio_mtk_reg_write(struct hci_dev *hdev, u32 reg, u32
>> +val, u32 mask) {
>> + struct btmtk_hci_wmt_params wmt_params;
>> + struct reg_write_cmd reg_write = {
>> + .type = 1,
>> + .num = 1,
>> + .addr = cpu_to_le32(reg),
>> + .data = cpu_to_le32(val),
>> + .mask = cpu_to_le32(mask),
>> + };
>> + int err, status;
>> +
>> + wmt_params.op = BTMTK_WMT_REGISTER;
>> + wmt_params.flag = BTMTK_WMT_REG_WRITE;
>> + wmt_params.dlen = sizeof(reg_write);
>> + wmt_params.data = &reg_write;
>> + wmt_params.status = &status;
>> +
>> + err = mtk_hci_wmt_sync(hdev, &wmt_params);
>> + if (err < 0)
>> + bt_dev_err(hdev, "Failed to write reg(%d)", err);
>> +
>> + return err;
>> +}
>> +
>> +static int btsdio_mtk_sco_setting(struct hci_dev *hdev) {
>> + struct btmtk_sco sco_setting = {
>> + .clock_config = 0x49,
>> + .channel_format_config = 0x80,
>> + };
>> + struct sk_buff *skb;
>> + u32 val;
>> + int err;
>> +
>> + /* Enable SCO over i2s/pcm for Mediatek Chipset */
>
>s/Chipset/chipset/

will do in the next version

>
>> + skb = __hci_cmd_sync(hdev, 0xfc72, sizeof(sco_setting),
>> + &sco_setting, HCI_CMD_TIMEOUT);
>> + if (IS_ERR(skb))
>> + return PTR_ERR(skb);
>> +
>> + err = btsdio_mtk_reg_read(hdev, MT7921_PINMUX_0, &val);
>> + if (err < 0) {
>> + bt_dev_err(hdev, "Failed to read register (%d)", err);
>> + return err;
>> + }
>> +
>> + val |= 0x11000000;
>> + err = btsdio_mtk_reg_write(hdev, MT7921_PINMUX_0, val, ~0);
>> + if (err < 0) {
>> + bt_dev_err(hdev, "Failed to write register (%d)", err);
>> + return err;
>> + }
>> +
>> + err = btsdio_mtk_reg_read(hdev, MT7921_PINMUX_1, &val);
>> + if (err < 0) {
>> + bt_dev_err(hdev, "Failed to read register (%d)", err);
>> + return err;
>> + }
>> +
>> + val |= 0x00000101;
>> + err = btsdio_mtk_reg_write(hdev, MT7921_PINMUX_1, val, ~0);
>> + if (err < 0)
>> + bt_dev_err(hdev, "Failed to write register (%d)", err);
>> +
>> + return err;
>> +}
>> +
>> static int btmtksdio_setup(struct hci_dev *hdev)
>> {
>> struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); @@ -862,6
>> +930,14 @@ static int btmtksdio_setup(struct hci_dev *hdev)
>> err = mt79xx_setup(hdev, fwname);
>> if (err < 0)
>> return err;
>> +
>> + /* Enable sco over i2s/pcm */
>
>s/sco/SCO/

ditto

>
>> + err = btsdio_mtk_sco_setting(hdev);
>> + if (err < 0) {
>> + bt_dev_err(hdev, "Failed to enable sco setting (%d)", err);
>
>s/sco/SCO/

ditto

>
>> + return err;
>> + }
>> +
>> break;
>> case 0x7663:
>> case 0x7668:
>
>
>Kind regards,
>
>Paul
>

2021-12-20 18:34:31

by Sean Wang

[permalink] [raw]
Subject: Re: [PATCH RESEND 1/3] Bluetooth: btmtksdio: add the support of wake on bluetooth

From: Sean Wang <[email protected]>


>Dear Sean, dear Mark,
>
>
>Am 18.12.21 um 02:08 schrieb [email protected]:
>> From: Mark Chen <[email protected]>
>
>Shorter summary: Bluetooth: btmtksdio: Support wake on bluetooth

seemed nice to me, will do in the next version

>
>> Add the support to enable wake on bluetooth
>
>Can you please list the datasheet name and revision used for the implementation.

the datasheet is not released in public so Mark and I cannot provide the detail here, but we will make the patch easy to review and understand.

>Please document how you tested this.

It was tested by setting up an HID or HOGP profile to connect a Bluetooth keyboard and mouse, then putting the system to suspend, then trying to wake up the system by moving the Bluetooth keyboard or mouse, and then checking if the system can be waken up and be brought back to the normal state.

>
>> Co-developed-by: Sean Wang <[email protected]>
>> Signed-off-by: Sean Wang <[email protected]>
>> Signed-off-by: Mark Chen <[email protected]>
>> ---
>> drivers/bluetooth/btmtk.h | 8 ++++++++
>> drivers/bluetooth/btmtksdio.c | 31 ++++++++++++++++++++++++++++++-
>> 2 files changed, 38 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
>> index 6e7b0c7567c0..2be1d2680ad8 100644
>> --- a/drivers/bluetooth/btmtk.h
>> +++ b/drivers/bluetooth/btmtk.h
>> @@ -68,6 +68,14 @@ struct btmtk_tci_sleep {
>> u8 time_compensation;
>> } __packed;
>>
>> +struct btmtk_wakeon {
>> + u8 mode;
>> + u8 gpo;
>> + u8 active_high;
>> + __le16 enable_delay;
>> + __le16 wakeup_delay;
>> +} __packed;
>> +
>> struct btmtk_hci_wmt_params {
>> u8 op;
>> u8 flag;
>> diff --git a/drivers/bluetooth/btmtksdio.c
>> b/drivers/bluetooth/btmtksdio.c index b5ea8d3bffaa..771733ce362b
>> 100644
>> --- a/drivers/bluetooth/btmtksdio.c
>> +++ b/drivers/bluetooth/btmtksdio.c
>> @@ -958,6 +958,30 @@ static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
>> return 0;
>> }
>>
>> +static bool btmtk_sdio_wakeup(struct hci_dev *hdev) {
>> + struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
>> + bool may_wakeup = device_may_wakeup(bdev->dev);
>> + struct btmtk_wakeon bt_awake = {
>> + .mode = 0x1,
>> + .gpo = 0,
>> + .active_high = 0x1,
>> + .enable_delay = cpu_to_le16(0xc80),
>> + .wakeup_delay = cpu_to_le16(0x20)
>> + };
>> + struct sk_buff *skb;
>> +
>> + if (may_wakeup &&
>> + bdev->data->chipid == 0x7921) {
>
>Why the check for 0x7921? Is that device only supported? The commit message does not say anything about it.

currently, wake on bt is only supported by mt7921, we will change the subject to "Bluetooth: mt7921s: Support wake on bluetooth"
and refine the message body to reflect the fact.

>
>> + skb = __hci_cmd_sync(hdev, 0xfc27, sizeof(bt_awake),
>> + &bt_awake, HCI_CMD_TIMEOUT);
>> + if (IS_ERR(skb))
>> + may_wakeup = false;
>> + }
>> +
>> + return may_wakeup;
>> +}
>> +
>> static int btmtksdio_probe(struct sdio_func *func,
>> const struct sdio_device_id *id)
>> {
>> @@ -998,6 +1022,7 @@ static int btmtksdio_probe(struct sdio_func *func,
>> hdev->shutdown = btmtksdio_shutdown;
>> hdev->send = btmtksdio_send_frame;
>> hdev->set_bdaddr = btmtk_set_bdaddr;
>> + hdev->wakeup = btmtk_sdio_wakeup;
>>
>> SET_HCIDEV_DEV(hdev, &func->dev);
>>
>> @@ -1032,7 +1057,11 @@ static int btmtksdio_probe(struct sdio_func *func,
>> */
>> pm_runtime_put_noidle(bdev->dev);
>>
>> - return 0;
>> + err = device_init_wakeup(bdev->dev, true);
>> + if (err)
>> + bt_dev_err(hdev, "%s: failed to init_wakeup", __func__);
>
>Could the error message be extended, so normal users know what to do?
>Currently it’s only useful for developers.

That is done by referring to btusb.c. I have willing to enhance the part along with btusb.c if Marcel has any idea about that.

>
>> +
>> + return err;
>> }
>>
>> static void btmtksdio_remove(struct sdio_func *func)
>
>
>Kind regards,
>
>Paul
>
>

2021-12-20 18:47:19

by Paul Menzel

[permalink] [raw]
Subject: Re: [PATCH 2/3] Bluetooth: btmtksdio: Enable SCO over I2S function

Dear Sean,


Am 20.12.21 um 18:52 schrieb [email protected]:
> From: Sean Wang <[email protected]>

>> Am 18.12.21 um 02:08 schrieb [email protected]:
>>> From: Mark Chen <[email protected]>
>>>
>>> For MediaTek chipset, the driver has to issue the specific
>>> command to enable Bluetooth SCO support over the I2S/PCM
>>> interface.
>>
>> Please document the datasheet name, revision and section, where
>> this is described.
>
> the datasheet is not released in public so Mark and I cannot provide
> the detail here, but we will make the patch easy to review and
> understand.

Too bad. The name and revision of the datasheet would still be good to
have documented.

>> Please add how SCO support can be tested. Are all Mediatek chipsets
>> supported?
>
> the SCO profile was tested by setting up a VOIP application,
> connected to HFP device, checked telephony function can work
> normally.
>
> currently, SCO is only supported by mt7921, we will change the
> subject to "Bluetooth: mt7921s: Enable SCO over I2S function" to
> avoid any misunderstanding.

Thank you.

I also saw a linux-firmare patch updating the firmware. If a specific
firmware version is required, please mention it too.

[…]


Kind regards,

Paul