Merge branch 'for-linus' of git://git.infradead.org/users/sameo/mfd-2.6
[linux-btrfs-devel.git] / drivers / staging / brcm80211 / brcmfmac / bcmsdh.c
blobf4e72ed126b08a0c775eef1d04227b86172fd547
1 /*
2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 /* ****************** SDIO CARD Interface Functions **************************/
18 #include <linux/types.h>
19 #include <linux/netdevice.h>
20 #include <linux/pci.h>
21 #include <linux/pci_ids.h>
22 #include <linux/sched.h>
23 #include <linux/completion.h>
25 #include <defs.h>
26 #include <brcm_hw_ids.h>
27 #include <brcmu_utils.h>
28 #include <brcmu_wifi.h>
29 #include <soc.h>
30 #include "dhd.h"
31 #include "dhd_bus.h"
32 #include "sdio_host.h"
34 #define SDIOH_API_ACCESS_RETRY_LIMIT 2
36 #define BRCMF_SD_ERROR_VAL 0x0001 /* Error */
37 #define BRCMF_SD_INFO_VAL 0x0002 /* Info */
40 #ifdef BCMDBG
41 #define BRCMF_SD_ERROR(x) \
42 do { \
43 if ((brcmf_sdio_msglevel & BRCMF_SD_ERROR_VAL) && \
44 net_ratelimit()) \
45 printk x; \
46 } while (0)
47 #define BRCMF_SD_INFO(x) \
48 do { \
49 if ((brcmf_sdio_msglevel & BRCMF_SD_INFO_VAL) && \
50 net_ratelimit()) \
51 printk x; \
52 } while (0)
53 #else /* BCMDBG */
54 #define BRCMF_SD_ERROR(x)
55 #define BRCMF_SD_INFO(x)
56 #endif /* BCMDBG */
58 /* debugging macros */
59 #define SDLX_MSG(x)
61 #define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */
62 #define SDIOH_CMD_TYPE_APPEND 1 /* Append command */
63 #define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */
65 #define SDIOH_DATA_PIO 0 /* PIO mode */
66 #define SDIOH_DATA_DMA 1 /* DMA mode */
68 struct brcmf_sdio_card {
69 bool init_success; /* underlying driver successfully attached */
70 void *sdioh; /* handler for sdioh */
71 u32 vendevid; /* Target Vendor and Device ID on SD bus */
72 bool regfail; /* Save status of last
73 reg_read/reg_write call */
74 u32 sbwad; /* Save backplane window address */
77 /**
78 * SDIO Host Controller info
80 struct sdio_hc {
81 struct sdio_hc *next;
82 struct device *dev; /* platform device handle */
83 void *regs; /* SDIO Host Controller address */
84 struct brcmf_sdio_card *card;
85 void *ch;
86 unsigned int oob_irq;
87 unsigned long oob_flags; /* OOB Host specifiction
88 as edge and etc */
89 bool oob_irq_registered;
92 /* local copy of bcm sd handler */
93 static struct brcmf_sdio_card *l_card;
95 const uint brcmf_sdio_msglevel = BRCMF_SD_ERROR_VAL;
97 static struct sdio_hc *sdhcinfo;
99 /* driver info, initialized when brcmf_sdio_register is called */
100 static struct brcmf_sdioh_driver drvinfo = { NULL, NULL };
102 /* Module parameters specific to each host-controller driver */
104 module_param(sd_msglevel, uint, 0);
106 extern uint sd_f2_blocksize;
107 module_param(sd_f2_blocksize, int, 0);
109 /* forward declarations */
110 int brcmf_sdio_probe(struct device *dev);
111 EXPORT_SYMBOL(brcmf_sdio_probe);
113 int brcmf_sdio_remove(struct device *dev);
114 EXPORT_SYMBOL(brcmf_sdio_remove);
116 struct brcmf_sdio_card*
117 brcmf_sdcard_attach(void *cfghdl, u32 *regsva, uint irq)
119 struct brcmf_sdio_card *card;
121 card = kzalloc(sizeof(struct brcmf_sdio_card), GFP_ATOMIC);
122 if (card == NULL) {
123 BRCMF_SD_ERROR(("sdcard_attach: out of memory"));
124 return NULL;
127 /* save the handler locally */
128 l_card = card;
130 card->sdioh = brcmf_sdioh_attach(cfghdl, irq);
131 if (!card->sdioh) {
132 brcmf_sdcard_detach(card);
133 return NULL;
136 card->init_success = true;
138 *regsva = SI_ENUM_BASE;
140 /* Report the BAR, to fix if needed */
141 card->sbwad = SI_ENUM_BASE;
142 return card;
145 int brcmf_sdcard_detach(struct brcmf_sdio_card *card)
147 if (card != NULL) {
148 if (card->sdioh) {
149 brcmf_sdioh_detach(card->sdioh);
150 card->sdioh = NULL;
152 kfree(card);
155 l_card = NULL;
156 return 0;
160 brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name,
161 void *params, int plen, void *arg, int len, bool set)
163 return brcmf_sdioh_iovar_op(card->sdioh, name, params, plen, arg,
164 len, set);
167 int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card)
169 return brcmf_sdioh_interrupt_set(card->sdioh, true);
172 int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card)
174 return brcmf_sdioh_interrupt_set(card->sdioh, false);
177 int brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card,
178 void (*fn)(void *), void *argh)
180 return brcmf_sdioh_interrupt_register(card->sdioh, fn, argh);
183 int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card)
185 return brcmf_sdioh_interrupt_deregister(card->sdioh);
188 u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
189 int *err)
191 int status;
192 s32 retry = 0;
193 u8 data = 0;
195 if (!card)
196 card = l_card;
198 do {
199 if (retry) /* wait for 1 ms till bus get settled down */
200 udelay(1000);
201 status =
202 brcmf_sdioh_cfg_read(card->sdioh, fnc_num, addr,
203 (u8 *) &data);
204 } while (status != 0
205 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
206 if (err)
207 *err = status;
209 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
210 __func__, fnc_num, addr, data));
212 return data;
215 void
216 brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint fnc_num, u32 addr,
217 u8 data, int *err)
219 int status;
220 s32 retry = 0;
222 if (!card)
223 card = l_card;
225 do {
226 if (retry) /* wait for 1 ms till bus get settled down */
227 udelay(1000);
228 status =
229 brcmf_sdioh_cfg_write(card->sdioh, fnc_num, addr,
230 (u8 *) &data);
231 } while (status != 0
232 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
233 if (err)
234 *err = status;
236 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
237 __func__, fnc_num, addr, data));
240 u32 brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num,
241 u32 addr, int *err)
243 int status;
244 u32 data = 0;
246 if (!card)
247 card = l_card;
249 status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
250 SDIOH_READ, fnc_num, addr, &data, 4);
252 if (err)
253 *err = status;
255 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
256 __func__, fnc_num, addr, data));
258 return data;
261 void
262 brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card, uint fnc_num,
263 u32 addr, u32 data, int *err)
265 int status;
267 if (!card)
268 card = l_card;
270 status =
271 brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
272 SDIOH_WRITE, fnc_num, addr, &data, 4);
274 if (err)
275 *err = status;
277 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
278 __func__, fnc_num, addr, data));
281 int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, u8 * cis,
282 uint length)
284 int status;
286 u8 *tmp_buf, *tmp_ptr;
287 u8 *ptr;
288 bool ascii = func & ~0xf;
289 func &= 0x7;
291 if (!card)
292 card = l_card;
294 status = brcmf_sdioh_cis_read(card->sdioh, func, cis, length);
296 if (ascii) {
297 /* Move binary bits to tmp and format them
298 into the provided buffer. */
299 tmp_buf = kmalloc(length, GFP_ATOMIC);
300 if (tmp_buf == NULL) {
301 BRCMF_SD_ERROR(("%s: out of memory\n", __func__));
302 return -ENOMEM;
304 memcpy(tmp_buf, cis, length);
305 for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4);
306 tmp_ptr++) {
307 ptr += sprintf((char *)ptr, "%.2x ", *tmp_ptr & 0xff);
308 if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0)
309 ptr += sprintf((char *)ptr, "\n");
311 kfree(tmp_buf);
314 return status;
317 static int
318 brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_card *card, u32 address)
320 int err = 0;
321 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
322 (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
323 if (!err)
324 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
325 SBSDIO_FUNC1_SBADDRMID,
326 (address >> 16) & SBSDIO_SBADDRMID_MASK,
327 &err);
328 if (!err)
329 brcmf_sdcard_cfg_write(card, SDIO_FUNC_1,
330 SBSDIO_FUNC1_SBADDRHIGH,
331 (address >> 24) & SBSDIO_SBADDRHIGH_MASK,
332 &err);
334 return err;
337 u32 brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size)
339 int status;
340 u32 word = 0;
341 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
343 BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr));
345 if (!card)
346 card = l_card;
348 if (bar0 != card->sbwad) {
349 if (brcmf_sdcard_set_sbaddr_window(card, bar0))
350 return 0xFFFFFFFF;
352 card->sbwad = bar0;
355 addr &= SBSDIO_SB_OFT_ADDR_MASK;
356 if (size == 4)
357 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
359 status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
360 SDIOH_READ, SDIO_FUNC_1, addr, &word, size);
362 card->regfail = (status != 0);
364 BRCMF_SD_INFO(("u32data = 0x%x\n", word));
366 /* if ok, return appropriately masked word */
367 if (status == 0) {
368 switch (size) {
369 case sizeof(u8):
370 return word & 0xff;
371 case sizeof(u16):
372 return word & 0xffff;
373 case sizeof(u32):
374 return word;
375 default:
376 card->regfail = true;
381 /* otherwise, bad sdio access or invalid size */
382 BRCMF_SD_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__,
383 addr, size));
384 return 0xFFFFFFFF;
387 u32 brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size,
388 u32 data)
390 int status;
391 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
392 int err = 0;
394 BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
395 __func__, addr, size * 8, data));
397 if (!card)
398 card = l_card;
400 if (bar0 != card->sbwad) {
401 err = brcmf_sdcard_set_sbaddr_window(card, bar0);
402 if (err)
403 return err;
405 card->sbwad = bar0;
408 addr &= SBSDIO_SB_OFT_ADDR_MASK;
409 if (size == 4)
410 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
411 status =
412 brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL,
413 SDIOH_WRITE, SDIO_FUNC_1, addr, &data, size);
414 card->regfail = (status != 0);
416 if (status == 0)
417 return 0;
419 BRCMF_SD_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
420 __func__, data, addr, size));
421 return 0xFFFFFFFF;
424 bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card)
426 return card->regfail;
430 brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
431 uint flags,
432 u8 *buf, uint nbytes, struct sk_buff *pkt,
433 void (*complete)(void *handle, int status,
434 bool sync_waiting),
435 void *handle)
437 int status;
438 uint incr_fix;
439 uint width;
440 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
441 int err = 0;
443 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
444 __func__, fn, addr, nbytes));
446 /* Async not implemented yet */
447 if (flags & SDIO_REQ_ASYNC)
448 return -ENOTSUPP;
450 if (bar0 != card->sbwad) {
451 err = brcmf_sdcard_set_sbaddr_window(card, bar0);
452 if (err)
453 return err;
455 card->sbwad = bar0;
458 addr &= SBSDIO_SB_OFT_ADDR_MASK;
460 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
461 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
462 if (width == 4)
463 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
465 status = brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
466 incr_fix, SDIOH_READ, fn, addr, width, nbytes, buf, pkt);
468 return status;
472 brcmf_sdcard_send_buf(struct brcmf_sdio_card *card, u32 addr, uint fn,
473 uint flags, u8 *buf, uint nbytes, void *pkt,
474 void (*complete)(void *handle, int status,
475 bool sync_waiting),
476 void *handle)
478 uint incr_fix;
479 uint width;
480 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
481 int err = 0;
483 BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
484 __func__, fn, addr, nbytes));
486 /* Async not implemented yet */
487 if (flags & SDIO_REQ_ASYNC)
488 return -ENOTSUPP;
490 if (bar0 != card->sbwad) {
491 err = brcmf_sdcard_set_sbaddr_window(card, bar0);
492 if (err)
493 return err;
495 card->sbwad = bar0;
498 addr &= SBSDIO_SB_OFT_ADDR_MASK;
500 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
501 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
502 if (width == 4)
503 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
505 return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
506 incr_fix, SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt);
509 int brcmf_sdcard_rwdata(struct brcmf_sdio_card *card, uint rw, u32 addr,
510 u8 *buf, uint nbytes)
512 addr &= SBSDIO_SB_OFT_ADDR_MASK;
513 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
515 return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO,
516 SDIOH_DATA_INC, (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
517 addr, 4, nbytes, buf, NULL);
520 int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn)
522 return brcmf_sdioh_abort(card->sdioh, fn);
525 int brcmf_sdcard_query_device(struct brcmf_sdio_card *card)
527 card->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0;
528 return card->vendevid;
531 u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card)
533 if (!card)
534 card = l_card;
536 return card->sbwad;
539 int brcmf_sdio_probe(struct device *dev)
541 struct sdio_hc *sdhc = NULL;
542 u32 regs = 0;
543 struct brcmf_sdio_card *card = NULL;
544 int irq = 0;
545 u32 vendevid;
546 unsigned long irq_flags = 0;
548 /* allocate SDIO Host Controller state info */
549 sdhc = kzalloc(sizeof(struct sdio_hc), GFP_ATOMIC);
550 if (!sdhc) {
551 SDLX_MSG(("%s: out of memory\n", __func__));
552 goto err;
554 sdhc->dev = (void *)dev;
556 card = brcmf_sdcard_attach((void *)0, &regs, irq);
557 if (!card) {
558 SDLX_MSG(("%s: attach failed\n", __func__));
559 goto err;
562 sdhc->card = card;
563 sdhc->oob_irq = irq;
564 sdhc->oob_flags = irq_flags;
565 sdhc->oob_irq_registered = false; /* to make sure.. */
567 /* chain SDIO Host Controller info together */
568 sdhc->next = sdhcinfo;
569 sdhcinfo = sdhc;
570 /* Read the vendor/device ID from the CIS */
571 vendevid = brcmf_sdcard_query_device(card);
573 /* try to attach to the target device */
574 sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF),
575 0, 0, 0, 0, regs, card);
576 if (!sdhc->ch) {
577 SDLX_MSG(("%s: device attach failed\n", __func__));
578 goto err;
581 return 0;
583 /* error handling */
584 err:
585 if (sdhc) {
586 if (sdhc->card)
587 brcmf_sdcard_detach(sdhc->card);
588 kfree(sdhc);
591 return -ENODEV;
594 int brcmf_sdio_remove(struct device *dev)
596 struct sdio_hc *sdhc, *prev;
598 sdhc = sdhcinfo;
599 drvinfo.detach(sdhc->ch);
600 brcmf_sdcard_detach(sdhc->card);
601 /* find the SDIO Host Controller state for this pdev
602 and take it out from the list */
603 for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) {
604 if (sdhc->dev == (void *)dev) {
605 if (prev)
606 prev->next = sdhc->next;
607 else
608 sdhcinfo = NULL;
609 break;
611 prev = sdhc;
613 if (!sdhc) {
614 SDLX_MSG(("%s: failed\n", __func__));
615 return 0;
618 /* release SDIO Host Controller info */
619 kfree(sdhc);
620 return 0;
623 int brcmf_sdio_register(struct brcmf_sdioh_driver *driver)
625 drvinfo = *driver;
627 SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n"));
628 return brcmf_sdio_function_init();
631 void brcmf_sdio_unregister(void)
633 brcmf_sdio_function_cleanup();
636 void brcmf_sdio_wdtmr_enable(bool enable)
638 if (enable)
639 brcmf_sdbrcm_wd_timer(sdhcinfo->ch, brcmf_watchdog_ms);
640 else
641 brcmf_sdbrcm_wd_timer(sdhcinfo->ch, 0);