Linux-mediatek Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Chris Lu (陸稚泓)" <Chris.Lu@mediatek.com>
To: "pmenzel@molgen.mpg.de" <pmenzel@molgen.mpg.de>
Cc: "Will-CY Lee (李政穎)" <Will-CY.Lee@mediatek.com>,
	"Steve Lee (李視誠)" <steve.lee@mediatek.com>,
	"luiz.dentz@gmail.com" <luiz.dentz@gmail.com>,
	"marcel@holtmann.org" <marcel@holtmann.org>,
	"SS Wu (巫憲欣)" <ss.wu@mediatek.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"johan.hedberg@gmail.com" <johan.hedberg@gmail.com>,
	"Sean Wang" <Sean.Wang@mediatek.com>,
	"linux-bluetooth@vger.kernel.org"
	<linux-bluetooth@vger.kernel.org>,
	"linux-mediatek@lists.infradead.org"
	<linux-mediatek@lists.infradead.org>
Subject: Re: [PATCH v1] Bluetooth: btmtk: Add MT7928 support
Date: Wed, 17 Jun 2026 02:16:55 +0000	[thread overview]
Message-ID: <03e0a6787272a445448a3189b4b575aa85396fb0.camel@mediatek.com> (raw)
In-Reply-To: <6b29b553-d703-448d-9275-62912a62e356@molgen.mpg.de>

Hi Paul,

On Tue, 2026-06-16 at 12:24 +0200, Paul Menzel wrote:
> 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> 
> 
> Dear Chris,
> 
> 
> Thank you for your patch.
> 
> Am 16.06.26 um 05:01 schrieb Chris Lu:
> > Add support for MT7928 (device ID 0x7935) which requires additional
> > firmware (CBMCU firmware) loading before Bluetooth firmware.
> 
> Please detail what CBMCU firmware is.

CBMCU is a new component on MT7928 to handle common part shared across
the combo chip (Wi-Fi/Bluetooth's subsystem), providing a better user
experience through improved coordination between subsystems.

> 
> > Implement two-phase CBMCU firmware download: Phase 1 loads
> > section with type 0x5 containing global descriptor,
> > section maps and signature data; Phase 2 loads remaining
> > firmware sections. Add retry mechanism for concurrent download
> > protection.
> 
> What is type 0x5? How big is the firmware, and how long does it take?
> 
> > After CBMCU firmware loads successfully, the driver continues
> > to load corresponding BT firmware based on device ID through
> > fallthrough to case 0x7922/0x7925.
> 
> Please add the new log message to the commit message.
> 
> > Signed-off-by: Chris Lu <chris.lu@mediatek.com>
> > ---
> >   drivers/bluetooth/btmtk.c | 342
> > +++++++++++++++++++++++++++++++++++++-
> >   drivers/bluetooth/btmtk.h |   3 +
> >   2 files changed, 344 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
> > index 02a96342e964..a68c67d1df4b 100644
> > --- a/drivers/bluetooth/btmtk.c
> > +++ b/drivers/bluetooth/btmtk.c
> > @@ -21,6 +21,7 @@
> >   #define MTK_FW_ROM_PATCH_SEC_MAP_SIZE       64
> >   #define MTK_SEC_MAP_COMMON_SIZE     12
> >   #define MTK_SEC_MAP_NEED_SEND_SIZE  52
> > +#define MTK_SEC_MAP_LENGTH_SIZE      4
> > 
> >   /* It is for mt79xx iso data transmission setting */
> >   #define MTK_ISO_THRESHOLD   264
> > @@ -120,6 +121,10 @@ void btmtk_fw_get_filename(char *buf, size_t
> > size, u32 dev_id, u32 fw_ver,
> >               snprintf(buf, size,
> >                       
> > "mediatek/mt%04x/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",
> >                        dev_id & 0xffff, dev_id & 0xffff, (fw_ver &
> > 0xff) + 1);
> > +     else if (dev_id == 0x7935)
> > +             snprintf(buf, size,
> > +                     
> > "mediatek/mt7928/BT_RAM_CODE_MT%04x_1_1_hdr.bin",
> > +                      dev_id & 0xffff);
> >       else if (dev_id == 0x7961 && fw_flavor)
> >               snprintf(buf, size,
> >                        "mediatek/BT_RAM_CODE_MT%04x_1a_%x_hdr.bin",
> > @@ -734,6 +739,7 @@ static int btmtk_usb_hci_wmt_sync(struct
> > hci_dev *hdev,
> >                       status = BTMTK_WMT_ON_UNDONE;
> >               break;
> >       case BTMTK_WMT_PATCH_DWNLD:
> > +     case BTMTK_WMT_CBMCU_DWNLD:
> >               if (wmt_evt->whdr.flag == 2)
> >                       status = BTMTK_WMT_PATCH_DONE;
> >               else if (wmt_evt->whdr.flag == 1)
> > @@ -870,6 +876,329 @@ static u32 btmtk_usb_reset_done(struct
> > hci_dev *hdev)
> >       return val & MTK_BT_RST_DONE;
> >   }
> > 
> > +static int btmtk_cbmcu_patch_status(struct hci_dev *hdev,
> > +                                 wmt_cmd_sync_func_t wmt_cmd_sync,
> > +                                 u8 *patch_status)
> > +{
> > +     struct btmtk_hci_wmt_params wmt_params;
> > +     int status, err, retry = 20;
> > +
> > +     do {
> > +             wmt_params.op = BTMTK_WMT_CBMCU_DWNLD;
> > +             wmt_params.flag = 0xF0;
> > +             wmt_params.dlen = 0;
> > +             wmt_params.data = NULL;
> > +             wmt_params.status = &status;
> > +
> > +             err = wmt_cmd_sync(hdev, &wmt_params);
> > +             if (err < 0) {
> > +                     bt_dev_err(hdev, "Failed to query CBMCU patch
> > status (%d)", err);
> > +                     return err;
> > +             }
> > +
> > +             *patch_status = (u8)status;
> > +
> > +             if (*patch_status == BTMTK_WMT_PATCH_PROGRESS) {
> > +                     msleep(100);
> > +                     retry--;
> > +             } else {
> > +                     break;
> > +             }
> > +     } while (retry > 0);
> > +
> > +     return 0;
> > +}
> > +
> > +static int btmtk_query_cbmcu_section(struct hci_dev *hdev,
> > +                                  wmt_cmd_sync_func_t
> > wmt_cmd_sync,
> > +                                  u8 cbmcu_type,
> > +                                  const u8 *section_map,
> > +                                  u32 cert_len)
> > +{
> > +     struct btmtk_hci_wmt_params wmt_params;
> > +     u8 cmd[64];
> > +     int status, err;
> > +
> > +     cmd[0] = 0;
> > +     cmd[1] = cbmcu_type;
> > +
> > +     if (cbmcu_type == 0)
> > +             put_unaligned_le32(cert_len, &cmd[2]);
> > +     else
> > +             memcpy(&cmd[2], section_map,
> > MTK_SEC_MAP_NEED_SEND_SIZE);
> > +
> > +     wmt_params.op = BTMTK_WMT_CBMCU_DWNLD;
> > +     wmt_params.flag = 0;
> > +     wmt_params.dlen = cbmcu_type ?
> > +             MTK_SEC_MAP_NEED_SEND_SIZE + 2 :
> > +             MTK_SEC_MAP_LENGTH_SIZE + 2;
> > +     wmt_params.data = cmd;
> > +     wmt_params.status = &status;
> > +
> > +     err = wmt_cmd_sync(hdev, &wmt_params);
> > +     if (err < 0) {
> > +             bt_dev_err(hdev, "Failed to query CBMCU section
> > (%d)", err);
> > +             return err;
> > +     }
> > +
> > +     /* Query should return UNDONE status for successful section
> > query */
> > +     if (status != BTMTK_WMT_PATCH_UNDONE) {
> > +             bt_dev_err(hdev, "CBMCU section query status error
> > (%d)", status);
> > +             return -EIO;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int btmtk_download_cbmcu_section(struct hci_dev *hdev,
> > +                                     wmt_cmd_sync_func_t
> > wmt_cmd_sync,
> > +                                     const u8 *fw_data,
> > +                                     u32 dl_size)
> > +{
> > +     struct btmtk_hci_wmt_params wmt_params;
> > +     u32 sent_len, total_size = dl_size;
> > +     int err;
> > +
> > +     wmt_params.op = BTMTK_WMT_CBMCU_DWNLD;
> > +     wmt_params.status = NULL;
> > +
> > +     while (dl_size > 0) {
> > +             sent_len = min_t(u32, 250, dl_size);
> > +
> > +             if (dl_size == total_size)
> > +                     wmt_params.flag = 1;
> > +             else if (dl_size == sent_len)
> > +                     wmt_params.flag = 3;
> > +             else
> > +                     wmt_params.flag = 2;
> > +
> > +             wmt_params.dlen = sent_len;
> > +             wmt_params.data = fw_data;
> > +
> > +             err = wmt_cmd_sync(hdev, &wmt_params);
> > +             if (err < 0) {
> > +                     bt_dev_err(hdev, "Failed to send CBMCU
> > section data (%d)", err);
> > +                     return err;
> > +             }
> > +
> > +             dl_size -= sent_len;
> > +             fw_data += sent_len;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int btmtk_enable_cbmcu_patch(struct hci_dev *hdev,
> > +                                 wmt_cmd_sync_func_t wmt_cmd_sync)
> > +{
> > +     struct btmtk_hci_wmt_params wmt_params;
> > +     int err;
> > +
> > +     wmt_params.op = BTMTK_WMT_CBMCU_DWNLD;
> > +     wmt_params.flag = 0xF1;
> > +     wmt_params.dlen = 0;
> > +     wmt_params.data = NULL;
> > +     wmt_params.status = NULL;
> > +
> > +     err = wmt_cmd_sync(hdev, &wmt_params);
> > +     if (err < 0) {
> > +             bt_dev_err(hdev, "Failed to enable CBMCU patch (%d)",
> > err);
> > +             return err;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static int btmtk_load_cbmcu_firmware(struct hci_dev *hdev,
> > +                                  const char *fwname,
> > +                                  wmt_cmd_sync_func_t
> > wmt_cmd_sync)
> > +{
> > +     struct btmtk_patch_header *hdr;
> > +     struct btmtk_global_desc *globaldesc;
> > +     struct btmtk_section_map *sectionmap;
> > +     const struct firmware *fw;
> > +     const u8 *fw_ptr;
> > +     u8 *cert_buf = NULL;
> > +     u32 section_num, section_offset, dl_size, cert_len;
> > +     int i, err;
> > +
> > +     err = request_firmware(&fw, fwname, &hdev->dev);
> > +     if (err < 0) {
> > +             bt_dev_err(hdev, "Failed to load CBMCU firmware file
> > (%d)", err);
> 
> Please add fwname to the error message.
> 
> > +             return err;
> > +     }
> > +
> > +     if (fw->size < MTK_FW_ROM_PATCH_HEADER_SIZE +
> > MTK_FW_ROM_PATCH_GD_SIZE) {
> > +             bt_dev_err(hdev, "CBMCU firmware too small (%zu
> > bytes)", fw->size);
> 
> Please add the limit to the error message.
> 
> > +             err = -EINVAL;
> > +             goto err_release_fw;
> > +     }
> > +
> > +     fw_ptr = fw->data;
> > +     hdr = (struct btmtk_patch_header *)fw_ptr;
> > +     globaldesc = (struct btmtk_global_desc *)(fw_ptr +
> > MTK_FW_ROM_PATCH_HEADER_SIZE);
> > +     section_num = le32_to_cpu(globaldesc->section_num);
> > +
> > +     if (fw->size < MTK_FW_ROM_PATCH_HEADER_SIZE +
> > MTK_FW_ROM_PATCH_GD_SIZE +
> > +                    (size_t)MTK_FW_ROM_PATCH_SEC_MAP_SIZE *
> > section_num) {
> > +             bt_dev_err(hdev, "CBMCU firmware truncated
> > (section_num=%u)", section_num);
> 
> Please log the values from the if condition.
> 
> > +             err = -EINVAL;
> > +             goto err_release_fw;
> > +     }
> > +
> > +     bt_dev_info(hdev, "CBMCU Version: 0x%04x%04x, Build Time:
> > %s",
> > +                 le16_to_cpu(hdr->hwver), le16_to_cpu(hdr->swver),
> > hdr->datetime);
> > +
> > +     /* Phase 1: Download section type 0x5 */
> 
> Please define a macro or enum for 0x5.
> 
> > +     for (i = 0; i < section_num; i++) {
> > +             sectionmap = (struct btmtk_section_map *)
> > +                     (fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
> > +                      MTK_FW_ROM_PATCH_GD_SIZE +
> > +                      MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
> > +
> > +             /* Only process type 0x5 section in Phase 1 */
> > +             if ((le32_to_cpu(sectionmap->sectype) & 0xFFFF) !=
> > 0x5)
> > +                     continue;
> > +
> > +             section_offset = le32_to_cpu(sectionmap->secoffset);
> > +             dl_size = le32_to_cpu(sectionmap->secsize);
> > +
> > +             if (dl_size == 0)
> > +                     continue;
> > +
> > +             if (section_offset > fw->size ||
> > +                 dl_size > fw->size - section_offset) {
> > +                     bt_dev_err(hdev, "CBMCU Phase 1 section out
> > of bounds");
> > +                     err = -EINVAL;
> > +                     goto err_release_fw;
> > +             }
> > +
> > +             cert_len = MTK_FW_ROM_PATCH_GD_SIZE +
> > +                        MTK_FW_ROM_PATCH_SEC_MAP_SIZE *
> > section_num +
> > +                        dl_size;
> > +
> > +             /* Query cbmcu section */
> > +             err = btmtk_query_cbmcu_section(hdev, wmt_cmd_sync,
> > 0, NULL,
> > +                                             cert_len);
> > +             if (err < 0)
> > +                     goto err_release_fw;
> > +
> > +             cert_buf = kmalloc(cert_len, GFP_KERNEL);
> > +             if (!cert_buf) {
> > +                     err = -ENOMEM;
> > +                     goto err_release_fw;
> > +             }
> > +
> > +             /* Copy Global Descriptor + All Section Maps */
> > +             memcpy(cert_buf,
> > +                    fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE,
> > +                    MTK_FW_ROM_PATCH_GD_SIZE +
> > MTK_FW_ROM_PATCH_SEC_MAP_SIZE * section_num);
> > +
> > +             /* Copy Phase 1 section data */
> > +             memcpy(cert_buf + MTK_FW_ROM_PATCH_GD_SIZE +
> > +                    MTK_FW_ROM_PATCH_SEC_MAP_SIZE * section_num,
> > +                    fw_ptr + section_offset,
> > +                    dl_size);
> > +
> > +             /* Download Phase 1 section */
> > +             err = btmtk_download_cbmcu_section(hdev,
> > wmt_cmd_sync,
> > +                                                cert_buf,
> > cert_len);
> > +             kfree(cert_buf);
> > +             cert_buf = NULL;
> > +
> > +             if (err < 0) {
> > +                     bt_dev_err(hdev, "Failed to download CBMCU
> > Phase 1 section (%d)", err);
> > +                     goto err_release_fw;
> > +             }
> > +
> > +             break;
> > +     }
> > +
> > +     /* Phase 2: Download other sections (type != 0x5) */
> > +     for (i = 0; i < section_num; i++) {
> > +             sectionmap = (struct btmtk_section_map *)
> > +                     (fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
> > +                      MTK_FW_ROM_PATCH_GD_SIZE +
> > +                      MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
> > +
> > +             /* Skip type 0x5 section in Phase 2 */
> > +             if ((le32_to_cpu(sectionmap->sectype) & 0xFFFF) ==
> > 0x5)
> > +                     continue;
> > +
> > +             section_offset = le32_to_cpu(sectionmap->secoffset);
> > +             dl_size = le32_to_cpu(sectionmap-
> > >bin_info_spec.dlsize);
> > +
> > +             if (dl_size == 0)
> > +                     continue;
> > +
> > +             if (section_offset > fw->size ||
> > +                 dl_size > fw->size - section_offset) {
> > +                     bt_dev_err(hdev, "CBMCU Phase 2 section %d
> > out of bounds", i);
> > +                     err = -EINVAL;
> > +                     goto err_release_fw;
> > +             }
> > +
> > +             /* Query cbmcu section */
> > +             err = btmtk_query_cbmcu_section(hdev, wmt_cmd_sync,
> > 1,
> > +                                             (u8 *)&sectionmap-
> > >bin_info_spec,
> > +                                             0);
> > +             if (err < 0)
> > +                     goto err_release_fw;
> > +
> > +             /* Download section data */
> > +             err = btmtk_download_cbmcu_section(hdev,
> > wmt_cmd_sync,
> > +                                                fw_ptr +
> > section_offset,
> > +                                                dl_size);
> > +             if (err < 0) {
> > +                     bt_dev_err(hdev, "Failed to download CBMCU
> > section %d (%d)", i, err);
> > +                     goto err_release_fw;
> > +             }
> > +     }
> > +
> > +     /* Wait for firmware activation */
> > +     usleep_range(100000, 120000);
> > +
> > +     bt_dev_info(hdev, "CBMCU firmware download completed");
> > +
> > +err_release_fw:
> > +     release_firmware(fw);
> > +     return err;
> > +}
> > +
> > +static int btmtk_setup_cbmcu_firmware(struct hci_dev *hdev,
> > +                                   wmt_cmd_sync_func_t
> > wmt_cmd_sync,
> > +                                   u32 dev_id)
> > +{
> > +     char cbmcu_fwname[64];
> > +     u8 patch_status;
> > +     int err;
> > +
> > +     err = btmtk_cbmcu_patch_status(hdev, wmt_cmd_sync,
> > &patch_status);
> > +     if (err < 0)
> > +             return err;
> > +
> > +     bt_dev_dbg(hdev, "CBMCU patch status: 0x%02x", patch_status);
> > +
> > +     if (patch_status != BTMTK_WMT_PATCH_UNDONE)
> > +             return 0;
> > +
> > +     snprintf(cbmcu_fwname, sizeof(cbmcu_fwname),
> > +              "mediatek/mt7928/CBMCU_CODE_MT%04x_1_1.bin",
> > +              dev_id & 0xffff);
> > +
> > +     err = btmtk_load_cbmcu_firmware(hdev, cbmcu_fwname,
> > wmt_cmd_sync);
> > +     if (err < 0) {
> > +             bt_dev_err(hdev, "Failed to download CBMCU firmware
> > (%d)", err);
> > +             return err;
> > +     }
> > +
> > +     err = btmtk_enable_cbmcu_patch(hdev, wmt_cmd_sync);
> > +     if (err < 0)
> > +             return err;
> > +
> > +     return 0;
> > +}
> > +
> >   int btmtk_usb_subsys_reset(struct hci_dev *hdev, u32 dev_id)
> >   {
> >       u32 val;
> > @@ -894,7 +1223,7 @@ int btmtk_usb_subsys_reset(struct hci_dev
> > *hdev, u32 dev_id)
> >               if (err < 0)
> >                       return err;
> >               msleep(100);
> > -     } else if (dev_id == 0x7925 || dev_id == 0x6639) {
> > +     } else if (dev_id == 0x7925 || dev_id == 0x6639 || dev_id ==
> > 0x7935) {
> >               err = btmtk_usb_uhw_reg_read(hdev,
> > MTK_BT_RESET_REG_CONNV3, &val);
> >               if (err < 0)
> >                       return err;
> > @@ -1379,6 +1708,15 @@ int btmtk_usb_setup(struct hci_dev *hdev)
> >       case 0x7668:
> >               fwname = FIRMWARE_MT7668;
> >               break;
> > +     case 0x7935:
> > +             /* Requires CBMCU firmware before BT firmware */
> > +             err = btmtk_setup_cbmcu_firmware(hdev,
> > btmtk_usb_hci_wmt_sync,
> > +                                              dev_id);
> > +             if (err < 0) {
> > +                     bt_dev_err(hdev, "Failed to set up CBMCU
> > firmware (%d)", err);
> > +                     return err;
> > +             }
> > +             fallthrough;
> >       case 0x7922:
> >       case 0x7925:
> >               /*
> > @@ -1596,3 +1934,5 @@ MODULE_FIRMWARE(FIRMWARE_MT7922);
> >   MODULE_FIRMWARE(FIRMWARE_MT7961);
> >   MODULE_FIRMWARE(FIRMWARE_MT7925);
> >   MODULE_FIRMWARE(FIRMWARE_MT7927);
> > +MODULE_FIRMWARE(FIRMWARE_MT7928);
> > +MODULE_FIRMWARE(FIRMWARE_MT7928_CBMCU);
> > diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
> > index c83c24897c95..6d3bf6b74a1d 100644
> > --- a/drivers/bluetooth/btmtk.h
> > +++ b/drivers/bluetooth/btmtk.h
> > @@ -9,6 +9,8 @@
> >   #define FIRMWARE_MT7961            
> > "mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
> >   #define FIRMWARE_MT7925            
> > "mediatek/mt7925/BT_RAM_CODE_MT7925_1_1_hdr.bin"
> >   #define FIRMWARE_MT7927            
> > "mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin"
> > +#define FIRMWARE_MT7928             
> > "mediatek/mt7928/BT_RAM_CODE_MT7935_1_1_hdr.bin"
> > +#define FIRMWARE_MT7928_CBMCU       
> > "mediatek/mt7928/CBMCU_CODE_MT7935_1_1.bin"
> > 
> >   #define HCI_EV_WMT 0xe4
> >   #define HCI_WMT_MAX_EVENT_SIZE              64
> > @@ -54,6 +56,7 @@ enum {
> >       BTMTK_WMT_RST = 0x7,
> >       BTMTK_WMT_REGISTER = 0x8,
> >       BTMTK_WMT_SEMAPHORE = 0x17,
> > +     BTMTK_WMT_CBMCU_DWNLD = 0x58,
> >   };
> > 
> >   enum {
> 
> 
> Kind regards,
> 
> Paul

Thanks for the review, I'll revise the error message to be more
informative and replace the magic number with proper macro. A v2 will
be sent out shortly.

Chris Lu


  reply	other threads:[~2026-06-17  2:17 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-16  3:01 [PATCH v1] Bluetooth: btmtk: Add MT7928 support Chris Lu
2026-06-16 10:24 ` Paul Menzel
2026-06-17  2:16   ` Chris Lu (陸稚泓) [this message]
2026-06-17  6:53     ` Paul Menzel
2026-06-17  8:34       ` Chris Lu (陸稚泓)
2026-06-17  8:49         ` Paul Menzel
2026-06-16 14:38 ` Pauli Virtanen
2026-06-17  1:53   ` Chris Lu (陸稚泓)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=03e0a6787272a445448a3189b4b575aa85396fb0.camel@mediatek.com \
    --to=chris.lu@mediatek.com \
    --cc=Sean.Wang@mediatek.com \
    --cc=Will-CY.Lee@mediatek.com \
    --cc=johan.hedberg@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=luiz.dentz@gmail.com \
    --cc=marcel@holtmann.org \
    --cc=pmenzel@molgen.mpg.de \
    --cc=ss.wu@mediatek.com \
    --cc=steve.lee@mediatek.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox