blob: 93c47796ecfd82f0aeaa14192d967e7528f50ae0 [file] [log] [blame]
Sean Wang9aebfd42019-03-08 09:15:44 +08001// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2019 MediaTek Inc.
3
4/*
5 * Bluetooth support for MediaTek SDIO devices
6 *
7 * This file is written based on btsdio.c and btmtkuart.c.
8 *
9 * Author: Sean Wang <sean.wang@mediatek.com>
10 *
11 */
12
13#include <asm/unaligned.h>
14#include <linux/atomic.h>
Sean Wang9aebfd42019-03-08 09:15:44 +080015#include <linux/init.h>
16#include <linux/iopoll.h>
17#include <linux/kernel.h>
18#include <linux/module.h>
Sean Wang7f3c5632019-04-18 17:08:02 +080019#include <linux/pm_runtime.h>
Sean Wang9aebfd42019-03-08 09:15:44 +080020#include <linux/skbuff.h>
21
22#include <linux/mmc/host.h>
23#include <linux/mmc/sdio_ids.h>
24#include <linux/mmc/sdio_func.h>
25
26#include <net/bluetooth/bluetooth.h>
27#include <net/bluetooth/hci_core.h>
28
29#include "h4_recv.h"
Sean Wang3a722042021-10-19 05:30:13 +080030#include "btmtk.h"
Sean Wang9aebfd42019-03-08 09:15:44 +080031
32#define VERSION "0.1"
33
Sean Wang7f3c5632019-04-18 17:08:02 +080034#define MTKBTSDIO_AUTOSUSPEND_DELAY 8000
35
36static bool enable_autosuspend;
37
Sean Wang9aebfd42019-03-08 09:15:44 +080038struct btmtksdio_data {
39 const char *fwname;
Sean Wangc603bf12021-10-19 05:30:21 +080040 u16 chipid;
Sean Wang9aebfd42019-03-08 09:15:44 +080041};
42
43static const struct btmtksdio_data mt7663_data = {
44 .fwname = FIRMWARE_MT7663,
Sean Wangc603bf12021-10-19 05:30:21 +080045 .chipid = 0x7663,
Sean Wang9aebfd42019-03-08 09:15:44 +080046};
47
48static const struct btmtksdio_data mt7668_data = {
49 .fwname = FIRMWARE_MT7668,
Sean Wangc603bf12021-10-19 05:30:21 +080050 .chipid = 0x7668,
51};
52
53static const struct btmtksdio_data mt7921_data = {
54 .fwname = FIRMWARE_MT7961,
55 .chipid = 0x7921,
Sean Wang9aebfd42019-03-08 09:15:44 +080056};
57
58static const struct sdio_device_id btmtksdio_table[] = {
Pali Rohárbaaa1102020-05-22 16:44:06 +020059 {SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7663),
Sean Wang9aebfd42019-03-08 09:15:44 +080060 .driver_data = (kernel_ulong_t)&mt7663_data },
Pali Rohárbaaa1102020-05-22 16:44:06 +020061 {SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7668),
Sean Wang9aebfd42019-03-08 09:15:44 +080062 .driver_data = (kernel_ulong_t)&mt7668_data },
Sean Wangc603bf12021-10-19 05:30:21 +080063 {SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, SDIO_DEVICE_ID_MEDIATEK_MT7961),
64 .driver_data = (kernel_ulong_t)&mt7921_data },
Sean Wang9aebfd42019-03-08 09:15:44 +080065 { } /* Terminating entry */
66};
Bartosz Golaszewski53121a72019-11-07 10:46:10 +010067MODULE_DEVICE_TABLE(sdio, btmtksdio_table);
Sean Wang9aebfd42019-03-08 09:15:44 +080068
69#define MTK_REG_CHLPCR 0x4 /* W1S */
70#define C_INT_EN_SET BIT(0)
71#define C_INT_EN_CLR BIT(1)
Sean Wang2e47cc22019-04-18 17:08:00 +080072#define C_FW_OWN_REQ_SET BIT(8) /* For write */
73#define C_COM_DRV_OWN BIT(8) /* For read */
Sean Wang9aebfd42019-03-08 09:15:44 +080074#define C_FW_OWN_REQ_CLR BIT(9)
75
76#define MTK_REG_CSDIOCSR 0x8
77#define SDIO_RE_INIT_EN BIT(0)
78#define SDIO_INT_CTL BIT(2)
79
80#define MTK_REG_CHCR 0xc
81#define C_INT_CLR_CTRL BIT(1)
82
83/* CHISR have the same bits field definition with CHIER */
84#define MTK_REG_CHISR 0x10
85#define MTK_REG_CHIER 0x14
86#define FW_OWN_BACK_INT BIT(0)
87#define RX_DONE_INT BIT(1)
88#define TX_EMPTY BIT(2)
89#define TX_FIFO_OVERFLOW BIT(8)
90#define RX_PKT_LEN GENMASK(31, 16)
91
92#define MTK_REG_CTDR 0x18
93
94#define MTK_REG_CRDR 0x1c
95
Sean Wang184ea402021-10-19 05:30:18 +080096#define MTK_REG_CRPLR 0x24
97
Sean Wang9aebfd42019-03-08 09:15:44 +080098#define MTK_SDIO_BLOCK_SIZE 256
99
100#define BTMTKSDIO_TX_WAIT_VND_EVT 1
101
Sean Wang9aebfd42019-03-08 09:15:44 +0800102struct mtkbtsdio_hdr {
103 __le16 len;
104 __le16 reserved;
105 u8 bt_type;
106} __packed;
107
Sean Wang9aebfd42019-03-08 09:15:44 +0800108struct btmtksdio_dev {
109 struct hci_dev *hdev;
110 struct sdio_func *func;
Sean Wang7f3c5632019-04-18 17:08:02 +0800111 struct device *dev;
Sean Wang9aebfd42019-03-08 09:15:44 +0800112
Sean Wang26270bc2021-10-19 05:30:16 +0800113 struct work_struct txrx_work;
Sean Wang9aebfd42019-03-08 09:15:44 +0800114 unsigned long tx_state;
115 struct sk_buff_head txq;
Mark-yw Chen10fe40e2021-10-19 05:30:19 +0800116 bool hw_tx_ready;
Sean Wang9aebfd42019-03-08 09:15:44 +0800117
118 struct sk_buff *evt_skb;
119
120 const struct btmtksdio_data *data;
121};
122
123static int mtk_hci_wmt_sync(struct hci_dev *hdev,
124 struct btmtk_hci_wmt_params *wmt_params)
125{
126 struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
127 struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc;
Sean Wangc603bf12021-10-19 05:30:21 +0800128 struct btmtk_hci_wmt_evt_reg *wmt_evt_reg;
Sean Wang9aebfd42019-03-08 09:15:44 +0800129 u32 hlen, status = BTMTK_WMT_INVALID;
130 struct btmtk_hci_wmt_evt *wmt_evt;
Sean Wang3a722042021-10-19 05:30:13 +0800131 struct btmtk_hci_wmt_cmd *wc;
132 struct btmtk_wmt_hdr *hdr;
Sean Wang9aebfd42019-03-08 09:15:44 +0800133 int err;
134
Sean Wang3a722042021-10-19 05:30:13 +0800135 /* Send the WMT command and wait until the WMT event returns */
Sean Wang9aebfd42019-03-08 09:15:44 +0800136 hlen = sizeof(*hdr) + wmt_params->dlen;
137 if (hlen > 255)
138 return -EINVAL;
139
Sean Wang3a722042021-10-19 05:30:13 +0800140 wc = kzalloc(hlen, GFP_KERNEL);
141 if (!wc)
142 return -ENOMEM;
143
144 hdr = &wc->hdr;
Sean Wang9aebfd42019-03-08 09:15:44 +0800145 hdr->dir = 1;
146 hdr->op = wmt_params->op;
147 hdr->dlen = cpu_to_le16(wmt_params->dlen + 1);
148 hdr->flag = wmt_params->flag;
Sean Wang3a722042021-10-19 05:30:13 +0800149 memcpy(wc->data, wmt_params->data, wmt_params->dlen);
Sean Wang9aebfd42019-03-08 09:15:44 +0800150
151 set_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
152
Sean Wang3a722042021-10-19 05:30:13 +0800153 err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc);
Sean Wang9aebfd42019-03-08 09:15:44 +0800154 if (err < 0) {
155 clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
Sean Wang3a722042021-10-19 05:30:13 +0800156 goto err_free_wc;
Sean Wang9aebfd42019-03-08 09:15:44 +0800157 }
158
159 /* The vendor specific WMT commands are all answered by a vendor
160 * specific event and will not have the Command Status or Command
161 * Complete as with usual HCI command flow control.
162 *
163 * After sending the command, wait for BTMTKSDIO_TX_WAIT_VND_EVT
164 * state to be cleared. The driver specific event receive routine
165 * will clear that state and with that indicate completion of the
166 * WMT command.
167 */
168 err = wait_on_bit_timeout(&bdev->tx_state, BTMTKSDIO_TX_WAIT_VND_EVT,
169 TASK_INTERRUPTIBLE, HCI_INIT_TIMEOUT);
170 if (err == -EINTR) {
171 bt_dev_err(hdev, "Execution of wmt command interrupted");
172 clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
Sean Wang3a722042021-10-19 05:30:13 +0800173 goto err_free_wc;
Sean Wang9aebfd42019-03-08 09:15:44 +0800174 }
175
176 if (err) {
177 bt_dev_err(hdev, "Execution of wmt command timed out");
178 clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state);
Sean Wang3a722042021-10-19 05:30:13 +0800179 err = -ETIMEDOUT;
180 goto err_free_wc;
Sean Wang9aebfd42019-03-08 09:15:44 +0800181 }
182
183 /* Parse and handle the return WMT event */
184 wmt_evt = (struct btmtk_hci_wmt_evt *)bdev->evt_skb->data;
185 if (wmt_evt->whdr.op != hdr->op) {
186 bt_dev_err(hdev, "Wrong op received %d expected %d",
187 wmt_evt->whdr.op, hdr->op);
188 err = -EIO;
189 goto err_free_skb;
190 }
191
192 switch (wmt_evt->whdr.op) {
Sean Wang3a722042021-10-19 05:30:13 +0800193 case BTMTK_WMT_SEMAPHORE:
Sean Wang9aebfd42019-03-08 09:15:44 +0800194 if (wmt_evt->whdr.flag == 2)
195 status = BTMTK_WMT_PATCH_UNDONE;
196 else
197 status = BTMTK_WMT_PATCH_DONE;
198 break;
Sean Wang3a722042021-10-19 05:30:13 +0800199 case BTMTK_WMT_FUNC_CTRL:
Sean Wang9aebfd42019-03-08 09:15:44 +0800200 wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
201 if (be16_to_cpu(wmt_evt_funcc->status) == 0x404)
202 status = BTMTK_WMT_ON_DONE;
203 else if (be16_to_cpu(wmt_evt_funcc->status) == 0x420)
204 status = BTMTK_WMT_ON_PROGRESS;
205 else
206 status = BTMTK_WMT_ON_UNDONE;
207 break;
Sean Wangc603bf12021-10-19 05:30:21 +0800208 case BTMTK_WMT_PATCH_DWNLD:
209 if (wmt_evt->whdr.flag == 2)
210 status = BTMTK_WMT_PATCH_DONE;
211 else if (wmt_evt->whdr.flag == 1)
212 status = BTMTK_WMT_PATCH_PROGRESS;
213 else
214 status = BTMTK_WMT_PATCH_UNDONE;
215 break;
216 case BTMTK_WMT_REGISTER:
217 wmt_evt_reg = (struct btmtk_hci_wmt_evt_reg *)wmt_evt;
218 if (le16_to_cpu(wmt_evt->whdr.dlen) == 12)
219 status = le32_to_cpu(wmt_evt_reg->val);
220 break;
Sean Wang9aebfd42019-03-08 09:15:44 +0800221 }
222
223 if (wmt_params->status)
224 *wmt_params->status = status;
225
226err_free_skb:
227 kfree_skb(bdev->evt_skb);
228 bdev->evt_skb = NULL;
Sean Wang3a722042021-10-19 05:30:13 +0800229err_free_wc:
230 kfree(wc);
Sean Wang9aebfd42019-03-08 09:15:44 +0800231
232 return err;
233}
234
235static int btmtksdio_tx_packet(struct btmtksdio_dev *bdev,
236 struct sk_buff *skb)
237{
238 struct mtkbtsdio_hdr *sdio_hdr;
239 int err;
240
241 /* Make sure that there are enough rooms for SDIO header */
242 if (unlikely(skb_headroom(skb) < sizeof(*sdio_hdr))) {
243 err = pskb_expand_head(skb, sizeof(*sdio_hdr), 0,
244 GFP_ATOMIC);
245 if (err < 0)
246 return err;
247 }
248
249 /* Prepend MediaTek SDIO Specific Header */
250 skb_push(skb, sizeof(*sdio_hdr));
251
252 sdio_hdr = (void *)skb->data;
253 sdio_hdr->len = cpu_to_le16(skb->len);
254 sdio_hdr->reserved = cpu_to_le16(0);
255 sdio_hdr->bt_type = hci_skb_pkt_type(skb);
256
Mark-yw Chen10fe40e2021-10-19 05:30:19 +0800257 bdev->hw_tx_ready = false;
Sean Wang9aebfd42019-03-08 09:15:44 +0800258 err = sdio_writesb(bdev->func, MTK_REG_CTDR, skb->data,
259 round_up(skb->len, MTK_SDIO_BLOCK_SIZE));
260 if (err < 0)
261 goto err_skb_pull;
262
263 bdev->hdev->stat.byte_tx += skb->len;
264
265 kfree_skb(skb);
266
267 return 0;
268
269err_skb_pull:
270 skb_pull(skb, sizeof(*sdio_hdr));
271
272 return err;
273}
274
275static u32 btmtksdio_drv_own_query(struct btmtksdio_dev *bdev)
276{
277 return sdio_readl(bdev->func, MTK_REG_CHLPCR, NULL);
278}
279
Sean Wang9aebfd42019-03-08 09:15:44 +0800280static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
281{
282 struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
283 struct hci_event_hdr *hdr = (void *)skb->data;
284 int err;
285
286 /* Fix up the vendor event id with 0xff for vendor specific instead
287 * of 0xe4 so that event send via monitoring socket can be parsed
288 * properly.
289 */
290 if (hdr->evt == 0xe4)
291 hdr->evt = HCI_EV_VENDOR;
292
293 /* When someone waits for the WMT event, the skb is being cloned
294 * and being processed the events from there then.
295 */
296 if (test_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state)) {
297 bdev->evt_skb = skb_clone(skb, GFP_KERNEL);
298 if (!bdev->evt_skb) {
299 err = -ENOMEM;
300 goto err_out;
301 }
302 }
303
304 err = hci_recv_frame(hdev, skb);
305 if (err < 0)
306 goto err_free_skb;
307
308 if (hdr->evt == HCI_EV_VENDOR) {
309 if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT,
310 &bdev->tx_state)) {
311 /* Barrier to sync with other CPUs */
312 smp_mb__after_atomic();
313 wake_up_bit(&bdev->tx_state, BTMTKSDIO_TX_WAIT_VND_EVT);
314 }
315 }
316
317 return 0;
318
319err_free_skb:
320 kfree_skb(bdev->evt_skb);
321 bdev->evt_skb = NULL;
322
323err_out:
324 return err;
325}
326
Sean Wangdb57b622021-11-20 06:25:46 +0800327static int btmtksdio_recv_acl(struct hci_dev *hdev, struct sk_buff *skb)
328{
329 struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
330 u16 handle = le16_to_cpu(hci_acl_hdr(skb)->handle);
331
332 switch (handle) {
333 case 0xfc6f:
334 /* Firmware dump from device: when the firmware hangs, the
335 * device can no longer suspend and thus disable auto-suspend.
336 */
337 pm_runtime_forbid(bdev->dev);
338 fallthrough;
339 case 0x05ff:
340 case 0x05fe:
341 /* Firmware debug logging */
342 return hci_recv_diag(hdev, skb);
343 }
344
345 return hci_recv_frame(hdev, skb);
346}
347
Sean Wang9aebfd42019-03-08 09:15:44 +0800348static const struct h4_recv_pkt mtk_recv_pkts[] = {
Sean Wangdb57b622021-11-20 06:25:46 +0800349 { H4_RECV_ACL, .recv = btmtksdio_recv_acl },
Sean Wang9aebfd42019-03-08 09:15:44 +0800350 { H4_RECV_SCO, .recv = hci_recv_frame },
351 { H4_RECV_EVENT, .recv = btmtksdio_recv_event },
352};
353
354static int btmtksdio_rx_packet(struct btmtksdio_dev *bdev, u16 rx_size)
355{
356 const struct h4_recv_pkt *pkts = mtk_recv_pkts;
357 int pkts_count = ARRAY_SIZE(mtk_recv_pkts);
358 struct mtkbtsdio_hdr *sdio_hdr;
Sean Wang9aebfd42019-03-08 09:15:44 +0800359 int err, i, pad_size;
360 struct sk_buff *skb;
361 u16 dlen;
362
363 if (rx_size < sizeof(*sdio_hdr))
364 return -EILSEQ;
365
366 /* A SDIO packet is exactly containing a Bluetooth packet */
367 skb = bt_skb_alloc(rx_size, GFP_KERNEL);
368 if (!skb)
369 return -ENOMEM;
370
371 skb_put(skb, rx_size);
372
373 err = sdio_readsb(bdev->func, skb->data, MTK_REG_CRDR, rx_size);
374 if (err < 0)
375 goto err_kfree_skb;
376
Sean Wang9aebfd42019-03-08 09:15:44 +0800377 sdio_hdr = (void *)skb->data;
378
379 /* We assume the default error as -EILSEQ simply to make the error path
380 * be cleaner.
381 */
382 err = -EILSEQ;
383
384 if (rx_size != le16_to_cpu(sdio_hdr->len)) {
385 bt_dev_err(bdev->hdev, "Rx size in sdio header is mismatched ");
386 goto err_kfree_skb;
387 }
388
389 hci_skb_pkt_type(skb) = sdio_hdr->bt_type;
390
391 /* Remove MediaTek SDIO header */
392 skb_pull(skb, sizeof(*sdio_hdr));
393
394 /* We have to dig into the packet to get payload size and then know how
395 * many padding bytes at the tail, these padding bytes should be removed
396 * before the packet is indicated to the core layer.
397 */
398 for (i = 0; i < pkts_count; i++) {
399 if (sdio_hdr->bt_type == (&pkts[i])->type)
400 break;
401 }
402
403 if (i >= pkts_count) {
404 bt_dev_err(bdev->hdev, "Invalid bt type 0x%02x",
405 sdio_hdr->bt_type);
406 goto err_kfree_skb;
407 }
408
409 /* Remaining bytes cannot hold a header*/
410 if (skb->len < (&pkts[i])->hlen) {
411 bt_dev_err(bdev->hdev, "The size of bt header is mismatched");
412 goto err_kfree_skb;
413 }
414
415 switch ((&pkts[i])->lsize) {
Jagdish Tirumala1ca2a3942020-12-15 15:17:30 +0530416 case 1:
417 dlen = skb->data[(&pkts[i])->loff];
418 break;
419 case 2:
420 dlen = get_unaligned_le16(skb->data +
Sean Wang9aebfd42019-03-08 09:15:44 +0800421 (&pkts[i])->loff);
Jagdish Tirumala1ca2a3942020-12-15 15:17:30 +0530422 break;
423 default:
424 goto err_kfree_skb;
Sean Wang9aebfd42019-03-08 09:15:44 +0800425 }
426
427 pad_size = skb->len - (&pkts[i])->hlen - dlen;
428
429 /* Remaining bytes cannot hold a payload */
430 if (pad_size < 0) {
431 bt_dev_err(bdev->hdev, "The size of bt payload is mismatched");
432 goto err_kfree_skb;
433 }
434
435 /* Remove padding bytes */
436 skb_trim(skb, skb->len - pad_size);
437
438 /* Complete frame */
439 (&pkts[i])->recv(bdev->hdev, skb);
440
Sean Wangbcaa7d72019-04-18 17:08:01 +0800441 bdev->hdev->stat.byte_rx += rx_size;
442
Sean Wang9aebfd42019-03-08 09:15:44 +0800443 return 0;
444
445err_kfree_skb:
Sean Wang9aebfd42019-03-08 09:15:44 +0800446 kfree_skb(skb);
447
448 return err;
449}
450
Sean Wang26270bc2021-10-19 05:30:16 +0800451static void btmtksdio_txrx_work(struct work_struct *work)
Sean Wang9aebfd42019-03-08 09:15:44 +0800452{
Sean Wang26270bc2021-10-19 05:30:16 +0800453 struct btmtksdio_dev *bdev = container_of(work, struct btmtksdio_dev,
454 txrx_work);
455 unsigned long txrx_timeout;
Sean Wang184ea402021-10-19 05:30:18 +0800456 u32 int_status, rx_size;
Sean Wang26270bc2021-10-19 05:30:16 +0800457 struct sk_buff *skb;
Sean Wang26270bc2021-10-19 05:30:16 +0800458 int err;
Sean Wang7f3c5632019-04-18 17:08:02 +0800459
460 pm_runtime_get_sync(bdev->dev);
461
462 sdio_claim_host(bdev->func);
463
Sean Wang9aebfd42019-03-08 09:15:44 +0800464 /* Disable interrupt */
Sean Wang26270bc2021-10-19 05:30:16 +0800465 sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0);
Sean Wang9aebfd42019-03-08 09:15:44 +0800466
Sean Wang26270bc2021-10-19 05:30:16 +0800467 txrx_timeout = jiffies + 5 * HZ;
468
469 do {
470 int_status = sdio_readl(bdev->func, MTK_REG_CHISR, NULL);
471
472 /* Ack an interrupt as soon as possible before any operation on
473 * hardware.
474 *
475 * Note that we don't ack any status during operations to avoid race
476 * condition between the host and the device such as it's possible to
477 * mistakenly ack RX_DONE for the next packet and then cause interrupts
478 * not be raised again but there is still pending data in the hardware
479 * FIFO.
480 */
481 sdio_writel(bdev->func, int_status, MTK_REG_CHISR, NULL);
482
483 if (int_status & FW_OWN_BACK_INT)
484 bt_dev_dbg(bdev->hdev, "Get fw own back");
485
486 if (int_status & TX_EMPTY)
Mark-yw Chen10fe40e2021-10-19 05:30:19 +0800487 bdev->hw_tx_ready = true;
Sean Wang26270bc2021-10-19 05:30:16 +0800488 else if (unlikely(int_status & TX_FIFO_OVERFLOW))
489 bt_dev_warn(bdev->hdev, "Tx fifo overflow");
490
Mark-yw Chen10fe40e2021-10-19 05:30:19 +0800491 if (bdev->hw_tx_ready) {
492 skb = skb_dequeue(&bdev->txq);
493 if (skb) {
494 err = btmtksdio_tx_packet(bdev, skb);
495 if (err < 0) {
496 bdev->hdev->stat.err_tx++;
497 skb_queue_head(&bdev->txq, skb);
498 }
499 }
500 }
501
Sean Wang26270bc2021-10-19 05:30:16 +0800502 if (int_status & RX_DONE_INT) {
Sean Wang184ea402021-10-19 05:30:18 +0800503 rx_size = sdio_readl(bdev->func, MTK_REG_CRPLR, NULL);
504 rx_size = (rx_size & RX_PKT_LEN) >> 16;
Sean Wang26270bc2021-10-19 05:30:16 +0800505 if (btmtksdio_rx_packet(bdev, rx_size) < 0)
506 bdev->hdev->stat.err_rx++;
507 }
Sean Wang26270bc2021-10-19 05:30:16 +0800508 } while (int_status || time_is_before_jiffies(txrx_timeout));
509
Sean Wang9aebfd42019-03-08 09:15:44 +0800510 /* Enable interrupt */
Sean Wang26270bc2021-10-19 05:30:16 +0800511 sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, 0);
512
513 sdio_release_host(bdev->func);
Sean Wang7f3c5632019-04-18 17:08:02 +0800514
515 pm_runtime_mark_last_busy(bdev->dev);
516 pm_runtime_put_autosuspend(bdev->dev);
Sean Wang9aebfd42019-03-08 09:15:44 +0800517}
518
Sean Wang26270bc2021-10-19 05:30:16 +0800519static void btmtksdio_interrupt(struct sdio_func *func)
520{
521 struct btmtksdio_dev *bdev = sdio_get_drvdata(func);
522
523 /* Disable interrupt */
524 sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, 0);
525
526 schedule_work(&bdev->txrx_work);
527}
528
Sean Wang9aebfd42019-03-08 09:15:44 +0800529static int btmtksdio_open(struct hci_dev *hdev)
530{
531 struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
Sean Wang77b210d2021-10-19 05:30:15 +0800532 u32 status, val;
Sean Wang9aebfd42019-03-08 09:15:44 +0800533 int err;
Sean Wang9aebfd42019-03-08 09:15:44 +0800534
535 sdio_claim_host(bdev->func);
536
537 err = sdio_enable_func(bdev->func);
538 if (err < 0)
539 goto err_release_host;
540
541 /* Get ownership from the device */
542 sdio_writel(bdev->func, C_FW_OWN_REQ_CLR, MTK_REG_CHLPCR, &err);
543 if (err < 0)
544 goto err_disable_func;
545
546 err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
Sean Wang2e47cc22019-04-18 17:08:00 +0800547 status & C_COM_DRV_OWN, 2000, 1000000);
Sean Wang9aebfd42019-03-08 09:15:44 +0800548 if (err < 0) {
549 bt_dev_err(bdev->hdev, "Cannot get ownership from device");
550 goto err_disable_func;
551 }
552
553 /* Disable interrupt & mask out all interrupt sources */
554 sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, &err);
555 if (err < 0)
556 goto err_disable_func;
557
558 sdio_writel(bdev->func, 0, MTK_REG_CHIER, &err);
559 if (err < 0)
560 goto err_disable_func;
561
562 err = sdio_claim_irq(bdev->func, btmtksdio_interrupt);
563 if (err < 0)
564 goto err_disable_func;
565
566 err = sdio_set_block_size(bdev->func, MTK_SDIO_BLOCK_SIZE);
567 if (err < 0)
568 goto err_release_irq;
569
570 /* SDIO CMD 5 allows the SDIO device back to idle state an
571 * synchronous interrupt is supported in SDIO 4-bit mode
572 */
Sean Wang5b23ac12021-10-19 05:30:17 +0800573 val = sdio_readl(bdev->func, MTK_REG_CSDIOCSR, &err);
574 if (err < 0)
575 goto err_release_irq;
576
577 val |= SDIO_INT_CTL;
578 sdio_writel(bdev->func, val, MTK_REG_CSDIOCSR, &err);
Sean Wang9aebfd42019-03-08 09:15:44 +0800579 if (err < 0)
580 goto err_release_irq;
581
Sean Wang77b210d2021-10-19 05:30:15 +0800582 /* Explitly set write-1-clear method */
583 val = sdio_readl(bdev->func, MTK_REG_CHCR, &err);
584 if (err < 0)
585 goto err_release_irq;
586
587 val |= C_INT_CLR_CTRL;
588 sdio_writel(bdev->func, val, MTK_REG_CHCR, &err);
Sean Wang9aebfd42019-03-08 09:15:44 +0800589 if (err < 0)
590 goto err_release_irq;
591
592 /* Setup interrupt sources */
593 sdio_writel(bdev->func, RX_DONE_INT | TX_EMPTY | TX_FIFO_OVERFLOW,
594 MTK_REG_CHIER, &err);
595 if (err < 0)
596 goto err_release_irq;
597
598 /* Enable interrupt */
599 sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, &err);
600 if (err < 0)
601 goto err_release_irq;
602
603 sdio_release_host(bdev->func);
604
605 return 0;
606
607err_release_irq:
608 sdio_release_irq(bdev->func);
609
610err_disable_func:
611 sdio_disable_func(bdev->func);
612
613err_release_host:
614 sdio_release_host(bdev->func);
615
616 return err;
617}
618
619static int btmtksdio_close(struct hci_dev *hdev)
620{
621 struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
622 u32 status;
623 int err;
624
625 sdio_claim_host(bdev->func);
626
627 /* Disable interrupt */
628 sdio_writel(bdev->func, C_INT_EN_CLR, MTK_REG_CHLPCR, NULL);
629
630 sdio_release_irq(bdev->func);
631
Sean Wang26270bc2021-10-19 05:30:16 +0800632 cancel_work_sync(&bdev->txrx_work);
633
Sean Wang9aebfd42019-03-08 09:15:44 +0800634 /* Return ownership to the device */
635 sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, NULL);
636
637 err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
Sean Wang2e47cc22019-04-18 17:08:00 +0800638 !(status & C_COM_DRV_OWN), 2000, 1000000);
Sean Wang9aebfd42019-03-08 09:15:44 +0800639 if (err < 0)
640 bt_dev_err(bdev->hdev, "Cannot return ownership to device");
641
642 sdio_disable_func(bdev->func);
643
644 sdio_release_host(bdev->func);
645
646 return 0;
647}
648
649static int btmtksdio_flush(struct hci_dev *hdev)
650{
651 struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
652
653 skb_queue_purge(&bdev->txq);
654
Sean Wang26270bc2021-10-19 05:30:16 +0800655 cancel_work_sync(&bdev->txrx_work);
Sean Wang9aebfd42019-03-08 09:15:44 +0800656
657 return 0;
658}
659
660static int btmtksdio_func_query(struct hci_dev *hdev)
661{
662 struct btmtk_hci_wmt_params wmt_params;
663 int status, err;
664 u8 param = 0;
665
666 /* Query whether the function is enabled */
Sean Wang3a722042021-10-19 05:30:13 +0800667 wmt_params.op = BTMTK_WMT_FUNC_CTRL;
Sean Wang9aebfd42019-03-08 09:15:44 +0800668 wmt_params.flag = 4;
669 wmt_params.dlen = sizeof(param);
670 wmt_params.data = &param;
671 wmt_params.status = &status;
672
673 err = mtk_hci_wmt_sync(hdev, &wmt_params);
674 if (err < 0) {
675 bt_dev_err(hdev, "Failed to query function status (%d)", err);
676 return err;
677 }
678
679 return status;
680}
681
Sean Wangc603bf12021-10-19 05:30:21 +0800682static int mt76xx_setup(struct hci_dev *hdev, const char *fwname)
Sean Wang9aebfd42019-03-08 09:15:44 +0800683{
Sean Wang9aebfd42019-03-08 09:15:44 +0800684 struct btmtk_hci_wmt_params wmt_params;
Sean Wang9aebfd42019-03-08 09:15:44 +0800685 struct btmtk_tci_sleep tci_sleep;
Sean Wang9aebfd42019-03-08 09:15:44 +0800686 struct sk_buff *skb;
687 int err, status;
688 u8 param = 0x1;
689
Sean Wang9aebfd42019-03-08 09:15:44 +0800690 /* Query whether the firmware is already download */
Sean Wang3a722042021-10-19 05:30:13 +0800691 wmt_params.op = BTMTK_WMT_SEMAPHORE;
Sean Wang9aebfd42019-03-08 09:15:44 +0800692 wmt_params.flag = 1;
693 wmt_params.dlen = 0;
694 wmt_params.data = NULL;
695 wmt_params.status = &status;
696
697 err = mtk_hci_wmt_sync(hdev, &wmt_params);
698 if (err < 0) {
699 bt_dev_err(hdev, "Failed to query firmware status (%d)", err);
700 return err;
701 }
702
703 if (status == BTMTK_WMT_PATCH_DONE) {
704 bt_dev_info(hdev, "Firmware already downloaded");
705 goto ignore_setup_fw;
706 }
707
708 /* Setup a firmware which the device definitely requires */
Sean Wangc603bf12021-10-19 05:30:21 +0800709 err = btmtk_setup_firmware(hdev, fwname, mtk_hci_wmt_sync);
Sean Wang9aebfd42019-03-08 09:15:44 +0800710 if (err < 0)
711 return err;
712
713ignore_setup_fw:
714 /* Query whether the device is already enabled */
715 err = readx_poll_timeout(btmtksdio_func_query, hdev, status,
716 status < 0 || status != BTMTK_WMT_ON_PROGRESS,
717 2000, 5000000);
718 /* -ETIMEDOUT happens */
719 if (err < 0)
720 return err;
721
722 /* The other errors happen in btusb_mtk_func_query */
723 if (status < 0)
724 return status;
725
726 if (status == BTMTK_WMT_ON_DONE) {
727 bt_dev_info(hdev, "function already on");
728 goto ignore_func_on;
729 }
730
731 /* Enable Bluetooth protocol */
Sean Wang3a722042021-10-19 05:30:13 +0800732 wmt_params.op = BTMTK_WMT_FUNC_CTRL;
Sean Wang9aebfd42019-03-08 09:15:44 +0800733 wmt_params.flag = 0;
734 wmt_params.dlen = sizeof(param);
735 wmt_params.data = &param;
736 wmt_params.status = NULL;
737
738 err = mtk_hci_wmt_sync(hdev, &wmt_params);
739 if (err < 0) {
740 bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
741 return err;
742 }
743
744ignore_func_on:
745 /* Apply the low power environment setup */
746 tci_sleep.mode = 0x5;
747 tci_sleep.duration = cpu_to_le16(0x640);
748 tci_sleep.host_duration = cpu_to_le16(0x640);
749 tci_sleep.host_wakeup_pin = 0;
750 tci_sleep.time_compensation = 0;
751
752 skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
753 HCI_INIT_TIMEOUT);
754 if (IS_ERR(skb)) {
755 err = PTR_ERR(skb);
756 bt_dev_err(hdev, "Failed to apply low power setting (%d)", err);
757 return err;
758 }
759 kfree_skb(skb);
760
Sean Wangc603bf12021-10-19 05:30:21 +0800761 return 0;
762}
763
764static int mt79xx_setup(struct hci_dev *hdev, const char *fwname)
765{
766 struct btmtk_hci_wmt_params wmt_params;
767 u8 param = 0x1;
768 int err;
769
770 err = btmtk_setup_firmware_79xx(hdev, fwname, mtk_hci_wmt_sync);
771 if (err < 0) {
772 bt_dev_err(hdev, "Failed to setup 79xx firmware (%d)", err);
773 return err;
774 }
775
776 /* Enable Bluetooth protocol */
777 wmt_params.op = BTMTK_WMT_FUNC_CTRL;
778 wmt_params.flag = 0;
779 wmt_params.dlen = sizeof(param);
780 wmt_params.data = &param;
781 wmt_params.status = NULL;
782
783 err = mtk_hci_wmt_sync(hdev, &wmt_params);
784 if (err < 0) {
785 bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
786 return err;
787 }
788
789 return err;
790}
791
792static int btsdio_mtk_reg_read(struct hci_dev *hdev, u32 reg, u32 *val)
793{
794 struct btmtk_hci_wmt_params wmt_params;
795 struct reg_read_cmd {
796 u8 type;
797 u8 rsv;
798 u8 num;
799 __le32 addr;
800 } __packed reg_read = {
801 .type = 1,
802 .num = 1,
803 };
804 u32 status;
805 int err;
806
807 reg_read.addr = cpu_to_le32(reg);
808 wmt_params.op = BTMTK_WMT_REGISTER;
809 wmt_params.flag = BTMTK_WMT_REG_READ;
810 wmt_params.dlen = sizeof(reg_read);
811 wmt_params.data = &reg_read;
812 wmt_params.status = &status;
813
814 err = mtk_hci_wmt_sync(hdev, &wmt_params);
815 if (err < 0) {
816 bt_dev_err(hdev, "Failed to read reg(%d)", err);
817 return err;
818 }
819
820 *val = status;
821
822 return err;
823}
824
825static int btmtksdio_setup(struct hci_dev *hdev)
826{
827 struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
828 ktime_t calltime, delta, rettime;
829 unsigned long long duration;
830 char fwname[64];
831 int err, dev_id;
832 u32 fw_version = 0;
833
834 calltime = ktime_get();
835 bdev->hw_tx_ready = true;
836
837 switch (bdev->data->chipid) {
838 case 0x7921:
839 err = btsdio_mtk_reg_read(hdev, 0x70010200, &dev_id);
840 if (err < 0) {
841 bt_dev_err(hdev, "Failed to get device id (%d)", err);
842 return err;
843 }
844
845 err = btsdio_mtk_reg_read(hdev, 0x80021004, &fw_version);
846 if (err < 0) {
847 bt_dev_err(hdev, "Failed to get fw version (%d)", err);
848 return err;
849 }
850
851 snprintf(fwname, sizeof(fwname),
852 "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",
853 dev_id & 0xffff, (fw_version & 0xff) + 1);
854 err = mt79xx_setup(hdev, fwname);
855 if (err < 0)
856 return err;
857 break;
858 case 0x7663:
859 case 0x7668:
860 err = mt76xx_setup(hdev, bdev->data->fwname);
861 if (err < 0)
862 return err;
863 break;
864 default:
865 return -ENODEV;
866 }
867
Sean Wang9aebfd42019-03-08 09:15:44 +0800868 rettime = ktime_get();
869 delta = ktime_sub(rettime, calltime);
870 duration = (unsigned long long)ktime_to_ns(delta) >> 10;
871
Sean Wang7f3c5632019-04-18 17:08:02 +0800872 pm_runtime_set_autosuspend_delay(bdev->dev,
873 MTKBTSDIO_AUTOSUSPEND_DELAY);
874 pm_runtime_use_autosuspend(bdev->dev);
875
876 err = pm_runtime_set_active(bdev->dev);
877 if (err < 0)
878 return err;
879
880 /* Default forbid runtime auto suspend, that can be allowed by
881 * enable_autosuspend flag or the PM runtime entry under sysfs.
882 */
883 pm_runtime_forbid(bdev->dev);
884 pm_runtime_enable(bdev->dev);
885
886 if (enable_autosuspend)
887 pm_runtime_allow(bdev->dev);
888
Sean Wang9aebfd42019-03-08 09:15:44 +0800889 bt_dev_info(hdev, "Device setup in %llu usecs", duration);
890
891 return 0;
892}
893
894static int btmtksdio_shutdown(struct hci_dev *hdev)
895{
Sean Wang7f3c5632019-04-18 17:08:02 +0800896 struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
Sean Wang9aebfd42019-03-08 09:15:44 +0800897 struct btmtk_hci_wmt_params wmt_params;
898 u8 param = 0x0;
899 int err;
900
Sean Wang7f3c5632019-04-18 17:08:02 +0800901 /* Get back the state to be consistent with the state
902 * in btmtksdio_setup.
903 */
904 pm_runtime_get_sync(bdev->dev);
905
Sean Wang9aebfd42019-03-08 09:15:44 +0800906 /* Disable the device */
Sean Wang3a722042021-10-19 05:30:13 +0800907 wmt_params.op = BTMTK_WMT_FUNC_CTRL;
Sean Wang9aebfd42019-03-08 09:15:44 +0800908 wmt_params.flag = 0;
909 wmt_params.dlen = sizeof(param);
910 wmt_params.data = &param;
911 wmt_params.status = NULL;
912
913 err = mtk_hci_wmt_sync(hdev, &wmt_params);
914 if (err < 0) {
915 bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
916 return err;
917 }
918
Sean Wang7f3c5632019-04-18 17:08:02 +0800919 pm_runtime_put_noidle(bdev->dev);
920 pm_runtime_disable(bdev->dev);
921
Sean Wang9aebfd42019-03-08 09:15:44 +0800922 return 0;
923}
924
925static int btmtksdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
926{
927 struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
928
929 switch (hci_skb_pkt_type(skb)) {
930 case HCI_COMMAND_PKT:
931 hdev->stat.cmd_tx++;
932 break;
933
934 case HCI_ACLDATA_PKT:
935 hdev->stat.acl_tx++;
936 break;
937
938 case HCI_SCODATA_PKT:
939 hdev->stat.sco_tx++;
940 break;
941
942 default:
943 return -EILSEQ;
944 }
945
946 skb_queue_tail(&bdev->txq, skb);
947
Sean Wang26270bc2021-10-19 05:30:16 +0800948 schedule_work(&bdev->txrx_work);
Sean Wang9aebfd42019-03-08 09:15:44 +0800949
950 return 0;
951}
952
953static int btmtksdio_probe(struct sdio_func *func,
954 const struct sdio_device_id *id)
955{
956 struct btmtksdio_dev *bdev;
957 struct hci_dev *hdev;
958 int err;
959
960 bdev = devm_kzalloc(&func->dev, sizeof(*bdev), GFP_KERNEL);
961 if (!bdev)
962 return -ENOMEM;
963
964 bdev->data = (void *)id->driver_data;
965 if (!bdev->data)
966 return -ENODEV;
967
Sean Wang7f3c5632019-04-18 17:08:02 +0800968 bdev->dev = &func->dev;
Sean Wang9aebfd42019-03-08 09:15:44 +0800969 bdev->func = func;
970
Sean Wang26270bc2021-10-19 05:30:16 +0800971 INIT_WORK(&bdev->txrx_work, btmtksdio_txrx_work);
Sean Wang9aebfd42019-03-08 09:15:44 +0800972 skb_queue_head_init(&bdev->txq);
973
974 /* Initialize and register HCI device */
975 hdev = hci_alloc_dev();
976 if (!hdev) {
977 dev_err(&func->dev, "Can't allocate HCI device\n");
978 return -ENOMEM;
979 }
980
981 bdev->hdev = hdev;
982
983 hdev->bus = HCI_SDIO;
984 hci_set_drvdata(hdev, bdev);
985
986 hdev->open = btmtksdio_open;
987 hdev->close = btmtksdio_close;
988 hdev->flush = btmtksdio_flush;
989 hdev->setup = btmtksdio_setup;
990 hdev->shutdown = btmtksdio_shutdown;
991 hdev->send = btmtksdio_send_frame;
Sean Wang877ec9e2021-10-19 05:30:14 +0800992 hdev->set_bdaddr = btmtk_set_bdaddr;
993
Sean Wang9aebfd42019-03-08 09:15:44 +0800994 SET_HCIDEV_DEV(hdev, &func->dev);
995
996 hdev->manufacturer = 70;
997 set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
998
999 err = hci_register_dev(hdev);
1000 if (err < 0) {
1001 dev_err(&func->dev, "Can't register HCI device\n");
1002 hci_free_dev(hdev);
1003 return err;
1004 }
1005
1006 sdio_set_drvdata(func, bdev);
1007
Sean Wang7f3c5632019-04-18 17:08:02 +08001008 /* pm_runtime_enable would be done after the firmware is being
1009 * downloaded because the core layer probably already enables
1010 * runtime PM for this func such as the case host->caps &
1011 * MMC_CAP_POWER_OFF_CARD.
1012 */
1013 if (pm_runtime_enabled(bdev->dev))
1014 pm_runtime_disable(bdev->dev);
1015
1016 /* As explaination in drivers/mmc/core/sdio_bus.c tells us:
1017 * Unbound SDIO functions are always suspended.
1018 * During probe, the function is set active and the usage count
1019 * is incremented. If the driver supports runtime PM,
1020 * it should call pm_runtime_put_noidle() in its probe routine and
1021 * pm_runtime_get_noresume() in its remove routine.
1022 *
1023 * So, put a pm_runtime_put_noidle here !
1024 */
1025 pm_runtime_put_noidle(bdev->dev);
1026
Sean Wang9aebfd42019-03-08 09:15:44 +08001027 return 0;
1028}
1029
1030static void btmtksdio_remove(struct sdio_func *func)
1031{
1032 struct btmtksdio_dev *bdev = sdio_get_drvdata(func);
1033 struct hci_dev *hdev;
1034
1035 if (!bdev)
1036 return;
1037
Sean Wang7f3c5632019-04-18 17:08:02 +08001038 /* Be consistent the state in btmtksdio_probe */
1039 pm_runtime_get_noresume(bdev->dev);
1040
Sean Wang9aebfd42019-03-08 09:15:44 +08001041 hdev = bdev->hdev;
1042
1043 sdio_set_drvdata(func, NULL);
1044 hci_unregister_dev(hdev);
1045 hci_free_dev(hdev);
1046}
1047
Sean Wang7f3c5632019-04-18 17:08:02 +08001048#ifdef CONFIG_PM
1049static int btmtksdio_runtime_suspend(struct device *dev)
1050{
1051 struct sdio_func *func = dev_to_sdio_func(dev);
1052 struct btmtksdio_dev *bdev;
1053 u32 status;
1054 int err;
1055
1056 bdev = sdio_get_drvdata(func);
1057 if (!bdev)
1058 return 0;
1059
1060 sdio_claim_host(bdev->func);
1061
1062 sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, &err);
1063 if (err < 0)
1064 goto out;
1065
1066 err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
1067 !(status & C_COM_DRV_OWN), 2000, 1000000);
1068out:
1069 bt_dev_info(bdev->hdev, "status (%d) return ownership to device", err);
1070
1071 sdio_release_host(bdev->func);
1072
1073 return err;
1074}
1075
1076static int btmtksdio_runtime_resume(struct device *dev)
1077{
1078 struct sdio_func *func = dev_to_sdio_func(dev);
1079 struct btmtksdio_dev *bdev;
1080 u32 status;
1081 int err;
1082
1083 bdev = sdio_get_drvdata(func);
1084 if (!bdev)
1085 return 0;
1086
1087 sdio_claim_host(bdev->func);
1088
1089 sdio_writel(bdev->func, C_FW_OWN_REQ_CLR, MTK_REG_CHLPCR, &err);
1090 if (err < 0)
1091 goto out;
1092
1093 err = readx_poll_timeout(btmtksdio_drv_own_query, bdev, status,
1094 status & C_COM_DRV_OWN, 2000, 1000000);
1095out:
1096 bt_dev_info(bdev->hdev, "status (%d) get ownership from device", err);
1097
1098 sdio_release_host(bdev->func);
1099
1100 return err;
1101}
1102
1103static UNIVERSAL_DEV_PM_OPS(btmtksdio_pm_ops, btmtksdio_runtime_suspend,
1104 btmtksdio_runtime_resume, NULL);
1105#define BTMTKSDIO_PM_OPS (&btmtksdio_pm_ops)
1106#else /* CONFIG_PM */
1107#define BTMTKSDIO_PM_OPS NULL
1108#endif /* CONFIG_PM */
1109
Sean Wang9aebfd42019-03-08 09:15:44 +08001110static struct sdio_driver btmtksdio_driver = {
1111 .name = "btmtksdio",
1112 .probe = btmtksdio_probe,
1113 .remove = btmtksdio_remove,
1114 .id_table = btmtksdio_table,
Sean Wang7f3c5632019-04-18 17:08:02 +08001115 .drv = {
1116 .owner = THIS_MODULE,
1117 .pm = BTMTKSDIO_PM_OPS,
1118 }
Sean Wang9aebfd42019-03-08 09:15:44 +08001119};
1120
Sean Wanga6094a42019-03-14 05:01:59 +08001121module_sdio_driver(btmtksdio_driver);
Sean Wang9aebfd42019-03-08 09:15:44 +08001122
Sean Wang7f3c5632019-04-18 17:08:02 +08001123module_param(enable_autosuspend, bool, 0644);
1124MODULE_PARM_DESC(enable_autosuspend, "Enable autosuspend by default");
1125
Sean Wang9aebfd42019-03-08 09:15:44 +08001126MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
1127MODULE_DESCRIPTION("MediaTek Bluetooth SDIO driver ver " VERSION);
1128MODULE_VERSION(VERSION);
1129MODULE_LICENSE("GPL");