1041 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.4 * All rights reserved.5 */6 7#include <linux/clk.h>8#include <linux/mmc/sdio_func.h>9#include <linux/mmc/sdio_ids.h>10#include <linux/mmc/host.h>11#include <linux/mmc/sdio.h>12#include <linux/of_irq.h>13 14#include "netdev.h"15#include "cfg80211.h"16 17#define SDIO_MODALIAS "wilc1000_sdio"18 19static const struct sdio_device_id wilc_sdio_ids[] = {20 { SDIO_DEVICE(SDIO_VENDOR_ID_MICROCHIP_WILC, SDIO_DEVICE_ID_MICROCHIP_WILC1000) },21 { },22};23MODULE_DEVICE_TABLE(sdio, wilc_sdio_ids);24 25#define WILC_SDIO_BLOCK_SIZE 51226 27static int wilc_sdio_init(struct wilc *wilc, bool resume);28static int wilc_sdio_deinit(struct wilc *wilc);29 30struct wilc_sdio {31 bool irq_gpio;32 u32 block_size;33 bool isinit;34 u8 *cmd53_buf;35};36 37struct sdio_cmd52 {38 u32 read_write: 1;39 u32 function: 3;40 u32 raw: 1;41 u32 address: 17;42 u32 data: 8;43};44 45struct sdio_cmd53 {46 u32 read_write: 1;47 u32 function: 3;48 u32 block_mode: 1;49 u32 increment: 1;50 u32 address: 17;51 u32 count: 9;52 u8 *buffer;53 u32 block_size;54 bool use_global_buf;55};56 57static const struct wilc_hif_func wilc_hif_sdio;58 59static void wilc_sdio_interrupt(struct sdio_func *func)60{61 sdio_release_host(func);62 wilc_handle_isr(sdio_get_drvdata(func));63 sdio_claim_host(func);64}65 66static int wilc_sdio_cmd52(struct wilc *wilc, struct sdio_cmd52 *cmd)67{68 struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);69 int ret;70 u8 data;71 72 sdio_claim_host(func);73 74 func->num = cmd->function;75 if (cmd->read_write) { /* write */76 if (cmd->raw) {77 sdio_writeb(func, cmd->data, cmd->address, &ret);78 data = sdio_readb(func, cmd->address, &ret);79 cmd->data = data;80 } else {81 sdio_writeb(func, cmd->data, cmd->address, &ret);82 }83 } else { /* read */84 data = sdio_readb(func, cmd->address, &ret);85 cmd->data = data;86 }87 88 sdio_release_host(func);89 90 if (ret)91 dev_err(&func->dev, "%s..failed, err(%d)\n", __func__, ret);92 return ret;93}94 95static int wilc_sdio_cmd53(struct wilc *wilc, struct sdio_cmd53 *cmd)96{97 struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);98 int size, ret;99 struct wilc_sdio *sdio_priv = wilc->bus_data;100 u8 *buf = cmd->buffer;101 102 sdio_claim_host(func);103 104 func->num = cmd->function;105 func->cur_blksize = cmd->block_size;106 if (cmd->block_mode)107 size = cmd->count * cmd->block_size;108 else109 size = cmd->count;110 111 if (cmd->use_global_buf) {112 if (size > sizeof(u32)) {113 ret = -EINVAL;114 goto out;115 }116 buf = sdio_priv->cmd53_buf;117 }118 119 if (cmd->read_write) { /* write */120 if (cmd->use_global_buf)121 memcpy(buf, cmd->buffer, size);122 123 ret = sdio_memcpy_toio(func, cmd->address, buf, size);124 } else { /* read */125 ret = sdio_memcpy_fromio(func, buf, cmd->address, size);126 127 if (cmd->use_global_buf)128 memcpy(cmd->buffer, buf, size);129 }130out:131 sdio_release_host(func);132 133 if (ret)134 dev_err(&func->dev, "%s..failed, err(%d)\n", __func__, ret);135 136 return ret;137}138 139static int wilc_sdio_probe(struct sdio_func *func,140 const struct sdio_device_id *id)141{142 struct wilc_sdio *sdio_priv;143 struct wilc_vif *vif;144 struct wilc *wilc;145 int ret;146 147 148 sdio_priv = kzalloc(sizeof(*sdio_priv), GFP_KERNEL);149 if (!sdio_priv)150 return -ENOMEM;151 152 sdio_priv->cmd53_buf = kzalloc(sizeof(u32), GFP_KERNEL);153 if (!sdio_priv->cmd53_buf) {154 ret = -ENOMEM;155 goto free;156 }157 158 ret = wilc_cfg80211_init(&wilc, &func->dev, WILC_HIF_SDIO,159 &wilc_hif_sdio);160 if (ret)161 goto free;162 163 if (IS_ENABLED(CONFIG_WILC1000_HW_OOB_INTR)) {164 struct device_node *np = func->card->dev.of_node;165 int irq_num = of_irq_get(np, 0);166 167 if (irq_num > 0) {168 wilc->dev_irq_num = irq_num;169 sdio_priv->irq_gpio = true;170 }171 }172 173 sdio_set_drvdata(func, wilc);174 wilc->bus_data = sdio_priv;175 wilc->dev = &func->dev;176 177 wilc->rtc_clk = devm_clk_get_optional_enabled(&func->card->dev, "rtc");178 if (IS_ERR(wilc->rtc_clk)) {179 ret = PTR_ERR(wilc->rtc_clk);180 goto dispose_irq;181 }182 183 wilc_sdio_init(wilc, false);184 185 ret = wilc_load_mac_from_nv(wilc);186 if (ret) {187 pr_err("Can not retrieve MAC address from chip\n");188 goto dispose_irq;189 }190 191 wilc_sdio_deinit(wilc);192 193 vif = wilc_netdev_ifc_init(wilc, "wlan%d", WILC_STATION_MODE,194 NL80211_IFTYPE_STATION, false);195 if (IS_ERR(vif)) {196 ret = PTR_ERR(vif);197 goto dispose_irq;198 }199 200 dev_info(&func->dev, "Driver Initializing success\n");201 return 0;202 203dispose_irq:204 irq_dispose_mapping(wilc->dev_irq_num);205 wilc_netdev_cleanup(wilc);206free:207 kfree(sdio_priv->cmd53_buf);208 kfree(sdio_priv);209 return ret;210}211 212static void wilc_sdio_remove(struct sdio_func *func)213{214 struct wilc *wilc = sdio_get_drvdata(func);215 struct wilc_sdio *sdio_priv = wilc->bus_data;216 217 wilc_netdev_cleanup(wilc);218 kfree(sdio_priv->cmd53_buf);219 kfree(sdio_priv);220}221 222static int wilc_sdio_reset(struct wilc *wilc)223{224 struct sdio_cmd52 cmd;225 int ret;226 struct sdio_func *func = dev_to_sdio_func(wilc->dev);227 228 cmd.read_write = 1;229 cmd.function = 0;230 cmd.raw = 0;231 cmd.address = SDIO_CCCR_ABORT;232 cmd.data = WILC_SDIO_CCCR_ABORT_RESET;233 ret = wilc_sdio_cmd52(wilc, &cmd);234 if (ret) {235 dev_err(&func->dev, "Fail cmd 52, reset cmd ...\n");236 return ret;237 }238 return 0;239}240 241static bool wilc_sdio_is_init(struct wilc *wilc)242{243 struct wilc_sdio *sdio_priv = wilc->bus_data;244 245 return sdio_priv->isinit;246}247 248static int wilc_sdio_enable_interrupt(struct wilc *dev)249{250 struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev);251 int ret = 0;252 253 sdio_claim_host(func);254 ret = sdio_claim_irq(func, wilc_sdio_interrupt);255 sdio_release_host(func);256 257 if (ret < 0) {258 dev_err(&func->dev, "can't claim sdio_irq, err(%d)\n", ret);259 ret = -EIO;260 }261 return ret;262}263 264static void wilc_sdio_disable_interrupt(struct wilc *dev)265{266 struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev);267 int ret;268 269 sdio_claim_host(func);270 ret = sdio_release_irq(func);271 if (ret < 0)272 dev_err(&func->dev, "can't release sdio_irq, err(%d)\n", ret);273 sdio_release_host(func);274}275 276/********************************************277 *278 * Function 0279 *280 ********************************************/281 282static int wilc_sdio_set_func0_csa_address(struct wilc *wilc, u32 adr)283{284 struct sdio_func *func = dev_to_sdio_func(wilc->dev);285 struct sdio_cmd52 cmd;286 int ret;287 288 /**289 * Review: BIG ENDIAN290 **/291 cmd.read_write = 1;292 cmd.function = 0;293 cmd.raw = 0;294 cmd.address = WILC_SDIO_FBR_CSA_REG;295 cmd.data = (u8)adr;296 ret = wilc_sdio_cmd52(wilc, &cmd);297 if (ret) {298 dev_err(&func->dev, "Failed cmd52, set %04x data...\n",299 cmd.address);300 return ret;301 }302 303 cmd.address = WILC_SDIO_FBR_CSA_REG + 1;304 cmd.data = (u8)(adr >> 8);305 ret = wilc_sdio_cmd52(wilc, &cmd);306 if (ret) {307 dev_err(&func->dev, "Failed cmd52, set %04x data...\n",308 cmd.address);309 return ret;310 }311 312 cmd.address = WILC_SDIO_FBR_CSA_REG + 2;313 cmd.data = (u8)(adr >> 16);314 ret = wilc_sdio_cmd52(wilc, &cmd);315 if (ret) {316 dev_err(&func->dev, "Failed cmd52, set %04x data...\n",317 cmd.address);318 return ret;319 }320 321 return 0;322}323 324static int wilc_sdio_set_block_size(struct wilc *wilc, u8 func_num,325 u32 block_size)326{327 struct sdio_func *func = dev_to_sdio_func(wilc->dev);328 struct sdio_cmd52 cmd;329 int ret;330 331 cmd.read_write = 1;332 cmd.function = 0;333 cmd.raw = 0;334 cmd.address = SDIO_FBR_BASE(func_num) + SDIO_CCCR_BLKSIZE;335 cmd.data = (u8)block_size;336 ret = wilc_sdio_cmd52(wilc, &cmd);337 if (ret) {338 dev_err(&func->dev, "Failed cmd52, set %04x data...\n",339 cmd.address);340 return ret;341 }342 343 cmd.address = SDIO_FBR_BASE(func_num) + SDIO_CCCR_BLKSIZE + 1;344 cmd.data = (u8)(block_size >> 8);345 ret = wilc_sdio_cmd52(wilc, &cmd);346 if (ret) {347 dev_err(&func->dev, "Failed cmd52, set %04x data...\n",348 cmd.address);349 return ret;350 }351 352 return 0;353}354 355/********************************************356 *357 * Sdio interfaces358 *359 ********************************************/360static int wilc_sdio_write_reg(struct wilc *wilc, u32 addr, u32 data)361{362 struct sdio_func *func = dev_to_sdio_func(wilc->dev);363 struct wilc_sdio *sdio_priv = wilc->bus_data;364 int ret;365 366 cpu_to_le32s(&data);367 368 if (addr >= 0xf0 && addr <= 0xff) { /* only vendor specific registers */369 struct sdio_cmd52 cmd;370 371 cmd.read_write = 1;372 cmd.function = 0;373 cmd.raw = 0;374 cmd.address = addr;375 cmd.data = data;376 ret = wilc_sdio_cmd52(wilc, &cmd);377 if (ret)378 dev_err(&func->dev,379 "Failed cmd 52, read reg (%08x) ...\n", addr);380 } else {381 struct sdio_cmd53 cmd;382 383 /**384 * set the AHB address385 **/386 ret = wilc_sdio_set_func0_csa_address(wilc, addr);387 if (ret)388 return ret;389 390 cmd.read_write = 1;391 cmd.function = 0;392 cmd.address = WILC_SDIO_FBR_DATA_REG;393 cmd.block_mode = 0;394 cmd.increment = 1;395 cmd.count = sizeof(u32);396 cmd.buffer = (u8 *)&data;397 cmd.use_global_buf = true;398 cmd.block_size = sdio_priv->block_size;399 ret = wilc_sdio_cmd53(wilc, &cmd);400 if (ret)401 dev_err(&func->dev,402 "Failed cmd53, write reg (%08x)...\n", addr);403 }404 405 return ret;406}407 408static int wilc_sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)409{410 struct sdio_func *func = dev_to_sdio_func(wilc->dev);411 struct wilc_sdio *sdio_priv = wilc->bus_data;412 u32 block_size = sdio_priv->block_size;413 struct sdio_cmd53 cmd;414 int nblk, nleft, ret;415 416 cmd.read_write = 1;417 if (addr > 0) {418 /**419 * func 0 access420 **/421 cmd.function = 0;422 cmd.address = WILC_SDIO_FBR_DATA_REG;423 } else {424 /**425 * func 1 access426 **/427 cmd.function = 1;428 cmd.address = WILC_SDIO_F1_DATA_REG;429 }430 431 size = ALIGN(size, 4);432 nblk = size / block_size;433 nleft = size % block_size;434 435 cmd.use_global_buf = false;436 if (nblk > 0) {437 cmd.block_mode = 1;438 cmd.increment = 1;439 cmd.count = nblk;440 cmd.buffer = buf;441 cmd.block_size = block_size;442 if (addr > 0) {443 ret = wilc_sdio_set_func0_csa_address(wilc, addr);444 if (ret)445 return ret;446 }447 ret = wilc_sdio_cmd53(wilc, &cmd);448 if (ret) {449 dev_err(&func->dev,450 "Failed cmd53 [%x], block send...\n", addr);451 return ret;452 }453 if (addr > 0)454 addr += nblk * block_size;455 buf += nblk * block_size;456 }457 458 if (nleft > 0) {459 cmd.block_mode = 0;460 cmd.increment = 1;461 cmd.count = nleft;462 cmd.buffer = buf;463 464 cmd.block_size = block_size;465 466 if (addr > 0) {467 ret = wilc_sdio_set_func0_csa_address(wilc, addr);468 if (ret)469 return ret;470 }471 ret = wilc_sdio_cmd53(wilc, &cmd);472 if (ret) {473 dev_err(&func->dev,474 "Failed cmd53 [%x], bytes send...\n", addr);475 return ret;476 }477 }478 479 return 0;480}481 482static int wilc_sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data)483{484 struct sdio_func *func = dev_to_sdio_func(wilc->dev);485 struct wilc_sdio *sdio_priv = wilc->bus_data;486 int ret;487 488 if (addr >= 0xf0 && addr <= 0xff) { /* only vendor specific registers */489 struct sdio_cmd52 cmd;490 491 cmd.read_write = 0;492 cmd.function = 0;493 cmd.raw = 0;494 cmd.address = addr;495 ret = wilc_sdio_cmd52(wilc, &cmd);496 if (ret) {497 dev_err(&func->dev,498 "Failed cmd 52, read reg (%08x) ...\n", addr);499 return ret;500 }501 *data = cmd.data;502 } else {503 struct sdio_cmd53 cmd;504 505 ret = wilc_sdio_set_func0_csa_address(wilc, addr);506 if (ret)507 return ret;508 509 cmd.read_write = 0;510 cmd.function = 0;511 cmd.address = WILC_SDIO_FBR_DATA_REG;512 cmd.block_mode = 0;513 cmd.increment = 1;514 cmd.count = sizeof(u32);515 cmd.buffer = (u8 *)data;516 cmd.use_global_buf = true;517 518 cmd.block_size = sdio_priv->block_size;519 ret = wilc_sdio_cmd53(wilc, &cmd);520 if (ret) {521 dev_err(&func->dev,522 "Failed cmd53, read reg (%08x)...\n", addr);523 return ret;524 }525 }526 527 le32_to_cpus(data);528 return 0;529}530 531static int wilc_sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)532{533 struct sdio_func *func = dev_to_sdio_func(wilc->dev);534 struct wilc_sdio *sdio_priv = wilc->bus_data;535 u32 block_size = sdio_priv->block_size;536 struct sdio_cmd53 cmd;537 int nblk, nleft, ret;538 539 cmd.read_write = 0;540 if (addr > 0) {541 /**542 * func 0 access543 **/544 cmd.function = 0;545 cmd.address = WILC_SDIO_FBR_DATA_REG;546 } else {547 /**548 * func 1 access549 **/550 cmd.function = 1;551 cmd.address = WILC_SDIO_F1_DATA_REG;552 }553 554 size = ALIGN(size, 4);555 nblk = size / block_size;556 nleft = size % block_size;557 558 cmd.use_global_buf = false;559 if (nblk > 0) {560 cmd.block_mode = 1;561 cmd.increment = 1;562 cmd.count = nblk;563 cmd.buffer = buf;564 cmd.block_size = block_size;565 if (addr > 0) {566 ret = wilc_sdio_set_func0_csa_address(wilc, addr);567 if (ret)568 return ret;569 }570 ret = wilc_sdio_cmd53(wilc, &cmd);571 if (ret) {572 dev_err(&func->dev,573 "Failed cmd53 [%x], block read...\n", addr);574 return ret;575 }576 if (addr > 0)577 addr += nblk * block_size;578 buf += nblk * block_size;579 } /* if (nblk > 0) */580 581 if (nleft > 0) {582 cmd.block_mode = 0;583 cmd.increment = 1;584 cmd.count = nleft;585 cmd.buffer = buf;586 587 cmd.block_size = block_size;588 589 if (addr > 0) {590 ret = wilc_sdio_set_func0_csa_address(wilc, addr);591 if (ret)592 return ret;593 }594 ret = wilc_sdio_cmd53(wilc, &cmd);595 if (ret) {596 dev_err(&func->dev,597 "Failed cmd53 [%x], bytes read...\n", addr);598 return ret;599 }600 }601 602 return 0;603}604 605/********************************************606 *607 * Bus interfaces608 *609 ********************************************/610 611static int wilc_sdio_deinit(struct wilc *wilc)612{613 struct sdio_func *func = dev_to_sdio_func(wilc->dev);614 struct wilc_sdio *sdio_priv = wilc->bus_data;615 struct sdio_cmd52 cmd;616 int ret;617 618 cmd.read_write = 1;619 cmd.function = 0;620 cmd.raw = 1;621 622 /* Disable all functions interrupts */623 cmd.address = SDIO_CCCR_IENx;624 cmd.data = 0;625 ret = wilc_sdio_cmd52(wilc, &cmd);626 if (ret) {627 dev_err(&func->dev, "Failed to disable functions interrupts\n");628 return ret;629 }630 631 /* Disable all functions */632 cmd.address = SDIO_CCCR_IOEx;633 cmd.data = 0;634 ret = wilc_sdio_cmd52(wilc, &cmd);635 if (ret) {636 dev_err(&func->dev,637 "Failed to reset all functions\n");638 return ret;639 }640 641 /* Disable CSA */642 cmd.read_write = 0;643 cmd.address = SDIO_FBR_BASE(1);644 ret = wilc_sdio_cmd52(wilc, &cmd);645 if (ret) {646 dev_err(&func->dev,647 "Failed to read CSA for function 1\n");648 return ret;649 }650 cmd.read_write = 1;651 cmd.address = SDIO_FBR_BASE(1);652 cmd.data &= ~SDIO_FBR_ENABLE_CSA;653 ret = wilc_sdio_cmd52(wilc, &cmd);654 if (ret) {655 dev_err(&func->dev,656 "Failed to disable CSA for function 1\n");657 return ret;658 }659 660 sdio_priv->isinit = false;661 return 0;662}663 664static int wilc_sdio_init(struct wilc *wilc, bool resume)665{666 struct sdio_func *func = dev_to_sdio_func(wilc->dev);667 struct wilc_sdio *sdio_priv = wilc->bus_data;668 struct sdio_cmd52 cmd;669 int loop, ret;670 u32 chipid;671 672 /**673 * function 0 csa enable674 **/675 cmd.read_write = 1;676 cmd.function = 0;677 cmd.raw = 1;678 cmd.address = SDIO_FBR_BASE(1);679 cmd.data = SDIO_FBR_ENABLE_CSA;680 ret = wilc_sdio_cmd52(wilc, &cmd);681 if (ret) {682 dev_err(&func->dev, "Fail cmd 52, enable csa...\n");683 return ret;684 }685 686 /**687 * function 0 block size688 **/689 ret = wilc_sdio_set_block_size(wilc, 0, WILC_SDIO_BLOCK_SIZE);690 if (ret) {691 dev_err(&func->dev, "Fail cmd 52, set func 0 block size...\n");692 return ret;693 }694 sdio_priv->block_size = WILC_SDIO_BLOCK_SIZE;695 696 /**697 * enable func1 IO698 **/699 cmd.read_write = 1;700 cmd.function = 0;701 cmd.raw = 1;702 cmd.address = SDIO_CCCR_IOEx;703 cmd.data = WILC_SDIO_CCCR_IO_EN_FUNC1;704 ret = wilc_sdio_cmd52(wilc, &cmd);705 if (ret) {706 dev_err(&func->dev,707 "Fail cmd 52, set IOE register...\n");708 return ret;709 }710 711 /**712 * make sure func 1 is up713 **/714 cmd.read_write = 0;715 cmd.function = 0;716 cmd.raw = 0;717 cmd.address = SDIO_CCCR_IORx;718 loop = 3;719 do {720 cmd.data = 0;721 ret = wilc_sdio_cmd52(wilc, &cmd);722 if (ret) {723 dev_err(&func->dev,724 "Fail cmd 52, get IOR register...\n");725 return ret;726 }727 if (cmd.data == WILC_SDIO_CCCR_IO_EN_FUNC1)728 break;729 } while (loop--);730 731 if (loop <= 0) {732 dev_err(&func->dev, "Fail func 1 is not ready...\n");733 return -EINVAL;734 }735 736 /**737 * func 1 is ready, set func 1 block size738 **/739 ret = wilc_sdio_set_block_size(wilc, 1, WILC_SDIO_BLOCK_SIZE);740 if (ret) {741 dev_err(&func->dev, "Fail set func 1 block size...\n");742 return ret;743 }744 745 /**746 * func 1 interrupt enable747 **/748 cmd.read_write = 1;749 cmd.function = 0;750 cmd.raw = 1;751 cmd.address = SDIO_CCCR_IENx;752 cmd.data = WILC_SDIO_CCCR_IEN_MASTER | WILC_SDIO_CCCR_IEN_FUNC1;753 ret = wilc_sdio_cmd52(wilc, &cmd);754 if (ret) {755 dev_err(&func->dev, "Fail cmd 52, set IEN register...\n");756 return ret;757 }758 759 /**760 * make sure can read back chip id correctly761 **/762 if (!resume) {763 ret = wilc_sdio_read_reg(wilc, WILC_CHIPID, &chipid);764 if (ret) {765 dev_err(&func->dev, "Fail cmd read chip id...\n");766 return ret;767 }768 dev_err(&func->dev, "chipid (%08x)\n", chipid);769 }770 771 sdio_priv->isinit = true;772 return 0;773}774 775static int wilc_sdio_read_size(struct wilc *wilc, u32 *size)776{777 u32 tmp;778 struct sdio_cmd52 cmd;779 780 /**781 * Read DMA count in words782 **/783 cmd.read_write = 0;784 cmd.function = 0;785 cmd.raw = 0;786 cmd.address = WILC_SDIO_INTERRUPT_DATA_SZ_REG;787 cmd.data = 0;788 wilc_sdio_cmd52(wilc, &cmd);789 tmp = cmd.data;790 791 cmd.address = WILC_SDIO_INTERRUPT_DATA_SZ_REG + 1;792 cmd.data = 0;793 wilc_sdio_cmd52(wilc, &cmd);794 tmp |= (cmd.data << 8);795 796 *size = tmp;797 return 0;798}799 800static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status)801{802 struct sdio_func *func = dev_to_sdio_func(wilc->dev);803 struct wilc_sdio *sdio_priv = wilc->bus_data;804 u32 tmp;805 u8 irq_flags;806 struct sdio_cmd52 cmd;807 808 wilc_sdio_read_size(wilc, &tmp);809 810 /**811 * Read IRQ flags812 **/813 if (!sdio_priv->irq_gpio) {814 cmd.function = 1;815 cmd.address = WILC_SDIO_EXT_IRQ_FLAG_REG;816 } else {817 cmd.function = 0;818 cmd.address = WILC_SDIO_IRQ_FLAG_REG;819 }820 cmd.raw = 0;821 cmd.read_write = 0;822 cmd.data = 0;823 wilc_sdio_cmd52(wilc, &cmd);824 irq_flags = cmd.data;825 tmp |= FIELD_PREP(IRG_FLAGS_MASK, cmd.data);826 827 if (FIELD_GET(UNHANDLED_IRQ_MASK, irq_flags))828 dev_err(&func->dev, "Unexpected interrupt (1) int=%lx\n",829 FIELD_GET(UNHANDLED_IRQ_MASK, irq_flags));830 831 *int_status = tmp;832 833 return 0;834}835 836static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val)837{838 struct sdio_func *func = dev_to_sdio_func(wilc->dev);839 struct wilc_sdio *sdio_priv = wilc->bus_data;840 int ret;841 u32 reg = 0;842 843 if (sdio_priv->irq_gpio)844 reg = val & (BIT(MAX_NUM_INT) - 1);845 846 /* select VMM table 0 */847 if (val & SEL_VMM_TBL0)848 reg |= BIT(5);849 /* select VMM table 1 */850 if (val & SEL_VMM_TBL1)851 reg |= BIT(6);852 /* enable VMM */853 if (val & EN_VMM)854 reg |= BIT(7);855 if (reg) {856 struct sdio_cmd52 cmd;857 858 cmd.read_write = 1;859 cmd.function = 0;860 cmd.raw = 0;861 cmd.address = WILC_SDIO_IRQ_CLEAR_FLAG_REG;862 cmd.data = reg;863 864 ret = wilc_sdio_cmd52(wilc, &cmd);865 if (ret) {866 dev_err(&func->dev,867 "Failed cmd52, set (%02x) data (%d) ...\n",868 cmd.address, __LINE__);869 return ret;870 }871 }872 return 0;873}874 875static int wilc_sdio_sync_ext(struct wilc *wilc, int nint)876{877 struct sdio_func *func = dev_to_sdio_func(wilc->dev);878 struct wilc_sdio *sdio_priv = wilc->bus_data;879 880 if (nint > MAX_NUM_INT) {881 dev_err(&func->dev, "Too many interrupts (%d)...\n", nint);882 return -EINVAL;883 }884 885 if (sdio_priv->irq_gpio) {886 u32 reg;887 int ret, i;888 889 /**890 * interrupt pin mux select891 **/892 ret = wilc_sdio_read_reg(wilc, WILC_PIN_MUX_0, ®);893 if (ret) {894 dev_err(&func->dev, "Failed read reg (%08x)...\n",895 WILC_PIN_MUX_0);896 return ret;897 }898 reg |= BIT(8);899 ret = wilc_sdio_write_reg(wilc, WILC_PIN_MUX_0, reg);900 if (ret) {901 dev_err(&func->dev, "Failed write reg (%08x)...\n",902 WILC_PIN_MUX_0);903 return ret;904 }905 906 /**907 * interrupt enable908 **/909 ret = wilc_sdio_read_reg(wilc, WILC_INTR_ENABLE, ®);910 if (ret) {911 dev_err(&func->dev, "Failed read reg (%08x)...\n",912 WILC_INTR_ENABLE);913 return ret;914 }915 916 for (i = 0; (i < 5) && (nint > 0); i++, nint--)917 reg |= BIT((27 + i));918 ret = wilc_sdio_write_reg(wilc, WILC_INTR_ENABLE, reg);919 if (ret) {920 dev_err(&func->dev, "Failed write reg (%08x)...\n",921 WILC_INTR_ENABLE);922 return ret;923 }924 if (nint) {925 ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, ®);926 if (ret) {927 dev_err(&func->dev,928 "Failed read reg (%08x)...\n",929 WILC_INTR2_ENABLE);930 return ret;931 }932 933 for (i = 0; (i < 3) && (nint > 0); i++, nint--)934 reg |= BIT(i);935 936 ret = wilc_sdio_write_reg(wilc, WILC_INTR2_ENABLE, reg);937 if (ret) {938 dev_err(&func->dev,939 "Failed write reg (%08x)...\n",940 WILC_INTR2_ENABLE);941 return ret;942 }943 }944 }945 return 0;946}947 948/* Global sdio HIF function table */949static const struct wilc_hif_func wilc_hif_sdio = {950 .hif_init = wilc_sdio_init,951 .hif_deinit = wilc_sdio_deinit,952 .hif_read_reg = wilc_sdio_read_reg,953 .hif_write_reg = wilc_sdio_write_reg,954 .hif_block_rx = wilc_sdio_read,955 .hif_block_tx = wilc_sdio_write,956 .hif_read_int = wilc_sdio_read_int,957 .hif_clear_int_ext = wilc_sdio_clear_int_ext,958 .hif_read_size = wilc_sdio_read_size,959 .hif_block_tx_ext = wilc_sdio_write,960 .hif_block_rx_ext = wilc_sdio_read,961 .hif_sync_ext = wilc_sdio_sync_ext,962 .enable_interrupt = wilc_sdio_enable_interrupt,963 .disable_interrupt = wilc_sdio_disable_interrupt,964 .hif_reset = wilc_sdio_reset,965 .hif_is_init = wilc_sdio_is_init,966};967 968static int wilc_sdio_suspend(struct device *dev)969{970 struct sdio_func *func = dev_to_sdio_func(dev);971 struct wilc *wilc = sdio_get_drvdata(func);972 int ret;973 974 dev_info(dev, "sdio suspend\n");975 976 if (!wilc->initialized)977 return 0;978 979 if (!IS_ERR(wilc->rtc_clk))980 clk_disable_unprepare(wilc->rtc_clk);981 982 host_sleep_notify(wilc);983 984 wilc_sdio_disable_interrupt(wilc);985 986 ret = wilc_sdio_reset(wilc);987 if (ret) {988 dev_err(&func->dev, "Fail reset sdio\n");989 return ret;990 }991 992 return 0;993}994 995static int wilc_sdio_resume(struct device *dev)996{997 struct sdio_func *func = dev_to_sdio_func(dev);998 struct wilc *wilc = sdio_get_drvdata(func);999 1000 dev_info(dev, "sdio resume\n");1001 1002 if (!wilc->initialized)1003 return 0;1004 1005 if (!IS_ERR(wilc->rtc_clk))1006 clk_prepare_enable(wilc->rtc_clk);1007 1008 wilc_sdio_init(wilc, true);1009 wilc_sdio_enable_interrupt(wilc);1010 1011 host_wakeup_notify(wilc);1012 1013 return 0;1014}1015 1016static const struct of_device_id wilc_of_match[] = {1017 { .compatible = "microchip,wilc1000", },1018 { /* sentinel */ }1019};1020MODULE_DEVICE_TABLE(of, wilc_of_match);1021 1022static const struct dev_pm_ops wilc_sdio_pm_ops = {1023 .suspend = wilc_sdio_suspend,1024 .resume = wilc_sdio_resume,1025};1026 1027static struct sdio_driver wilc_sdio_driver = {1028 .name = SDIO_MODALIAS,1029 .id_table = wilc_sdio_ids,1030 .probe = wilc_sdio_probe,1031 .remove = wilc_sdio_remove,1032 .drv = {1033 .pm = &wilc_sdio_pm_ops,1034 .of_match_table = wilc_of_match,1035 }1036};1037module_sdio_driver(wilc_sdio_driver);1038 1039MODULE_DESCRIPTION("Atmel WILC1000 SDIO wireless driver");1040MODULE_LICENSE("GPL");1041