linux/drivers/staging/wilc1000/wilc_sdio.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) Atmel Corporation.  All rights reserved.
   3 *
   4 * Module Name:  wilc_sdio.c
   5 */
   6
   7#include <linux/string.h>
   8#include "wilc_wlan_if.h"
   9#include "wilc_wlan.h"
  10#include "wilc_wfi_netdevice.h"
  11#include <linux/mmc/sdio_func.h>
  12#include <linux/mmc/card.h>
  13#include <linux/mmc/sdio_ids.h>
  14#include <linux/mmc/sdio.h>
  15#include <linux/mmc/host.h>
  16#include <linux/of_gpio.h>
  17
  18#define SDIO_MODALIAS "wilc1000_sdio"
  19
  20#define SDIO_VENDOR_ID_WILC 0x0296
  21#define SDIO_DEVICE_ID_WILC 0x5347
  22
  23static const struct sdio_device_id wilc_sdio_ids[] = {
  24        { SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) },
  25        { },
  26};
  27
  28#define WILC_SDIO_BLOCK_SIZE 512
  29
  30struct wilc_sdio {
  31        bool irq_gpio;
  32        u32 block_size;
  33        int nint;
  34#define MAX_NUN_INT_THRPT_ENH2 (5) /* Max num interrupts allowed in registers 0xf7, 0xf8 */
  35        int has_thrpt_enh3;
  36};
  37
  38static struct wilc_sdio g_sdio;
  39static const struct wilc_hif_func wilc_hif_sdio;
  40
  41static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data);
  42static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data);
  43static int sdio_init(struct wilc *wilc, bool resume);
  44
  45static void wilc_sdio_interrupt(struct sdio_func *func)
  46{
  47        sdio_release_host(func);
  48        wilc_handle_isr(sdio_get_drvdata(func));
  49        sdio_claim_host(func);
  50}
  51
  52static int wilc_sdio_cmd52(struct wilc *wilc, struct sdio_cmd52 *cmd)
  53{
  54        struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
  55        int ret;
  56        u8 data;
  57
  58        sdio_claim_host(func);
  59
  60        func->num = cmd->function;
  61        if (cmd->read_write) {  /* write */
  62                if (cmd->raw) {
  63                        sdio_writeb(func, cmd->data, cmd->address, &ret);
  64                        data = sdio_readb(func, cmd->address, &ret);
  65                        cmd->data = data;
  66                } else {
  67                        sdio_writeb(func, cmd->data, cmd->address, &ret);
  68                }
  69        } else {        /* read */
  70                data = sdio_readb(func, cmd->address, &ret);
  71                cmd->data = data;
  72        }
  73
  74        sdio_release_host(func);
  75
  76        if (ret)
  77                dev_err(&func->dev, "%s..failed, err(%d)\n", __func__, ret);
  78        return ret;
  79}
  80
  81static int wilc_sdio_cmd53(struct wilc *wilc, struct sdio_cmd53 *cmd)
  82{
  83        struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
  84        int size, ret;
  85
  86        sdio_claim_host(func);
  87
  88        func->num = cmd->function;
  89        func->cur_blksize = cmd->block_size;
  90        if (cmd->block_mode)
  91                size = cmd->count * cmd->block_size;
  92        else
  93                size = cmd->count;
  94
  95        if (cmd->read_write) {  /* write */
  96                ret = sdio_memcpy_toio(func, cmd->address,
  97                                       (void *)cmd->buffer, size);
  98        } else {        /* read */
  99                ret = sdio_memcpy_fromio(func, (void *)cmd->buffer,
 100                                         cmd->address,  size);
 101        }
 102
 103        sdio_release_host(func);
 104
 105        if (ret)
 106                dev_err(&func->dev, "%s..failed, err(%d)\n", __func__,  ret);
 107
 108        return ret;
 109}
 110
 111static int linux_sdio_probe(struct sdio_func *func,
 112                            const struct sdio_device_id *id)
 113{
 114        struct wilc *wilc;
 115        int gpio, ret;
 116
 117        gpio = -1;
 118        if (IS_ENABLED(CONFIG_WILC1000_HW_OOB_INTR)) {
 119                gpio = of_get_gpio(func->dev.of_node, 0);
 120                if (gpio < 0)
 121                        gpio = GPIO_NUM;
 122        }
 123
 124        dev_dbg(&func->dev, "Initializing netdev\n");
 125        ret = wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, gpio,
 126                               &wilc_hif_sdio);
 127        if (ret) {
 128                dev_err(&func->dev, "Couldn't initialize netdev\n");
 129                return ret;
 130        }
 131        sdio_set_drvdata(func, wilc);
 132        wilc->dev = &func->dev;
 133
 134        dev_info(&func->dev, "Driver Initializing success\n");
 135        return 0;
 136}
 137
 138static void linux_sdio_remove(struct sdio_func *func)
 139{
 140        wilc_netdev_cleanup(sdio_get_drvdata(func));
 141}
 142
 143static int sdio_reset(struct wilc *wilc)
 144{
 145        struct sdio_cmd52 cmd;
 146        int ret;
 147        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 148
 149        cmd.read_write = 1;
 150        cmd.function = 0;
 151        cmd.raw = 0;
 152        cmd.address = 0x6;
 153        cmd.data = 0x8;
 154        ret = wilc_sdio_cmd52(wilc, &cmd);
 155        if (ret) {
 156                dev_err(&func->dev, "Fail cmd 52, reset cmd ...\n");
 157                return ret;
 158        }
 159        return 0;
 160}
 161
 162static int wilc_sdio_suspend(struct device *dev)
 163{
 164        struct sdio_func *func = dev_to_sdio_func(dev);
 165        struct wilc *wilc = sdio_get_drvdata(func);
 166        int ret;
 167
 168        dev_info(dev, "sdio suspend\n");
 169        chip_wakeup(wilc);
 170
 171        if (!wilc->suspend_event) {
 172                wilc_chip_sleep_manually(wilc);
 173        } else {
 174                host_sleep_notify(wilc);
 175                chip_allow_sleep(wilc);
 176        }
 177
 178        ret = sdio_reset(wilc);
 179        if (ret) {
 180                dev_err(&func->dev, "Fail reset sdio\n");
 181                return ret;
 182        }
 183        sdio_claim_host(func);
 184
 185        return 0;
 186}
 187
 188static int wilc_sdio_resume(struct device *dev)
 189{
 190        struct sdio_func *func = dev_to_sdio_func(dev);
 191        struct wilc *wilc = sdio_get_drvdata(func);
 192
 193        dev_info(dev, "sdio resume\n");
 194        sdio_release_host(func);
 195        chip_wakeup(wilc);
 196        sdio_init(wilc, true);
 197
 198        if (wilc->suspend_event)
 199                host_wakeup_notify(wilc);
 200
 201        chip_allow_sleep(wilc);
 202
 203        return 0;
 204}
 205
 206static const struct dev_pm_ops wilc_sdio_pm_ops = {
 207        .suspend = wilc_sdio_suspend,
 208        .resume = wilc_sdio_resume,
 209};
 210
 211static struct sdio_driver wilc1000_sdio_driver = {
 212        .name           = SDIO_MODALIAS,
 213        .id_table       = wilc_sdio_ids,
 214        .probe          = linux_sdio_probe,
 215        .remove         = linux_sdio_remove,
 216        .drv = {
 217                .pm = &wilc_sdio_pm_ops,
 218        }
 219};
 220module_driver(wilc1000_sdio_driver,
 221              sdio_register_driver,
 222              sdio_unregister_driver);
 223MODULE_LICENSE("GPL");
 224
 225static int wilc_sdio_enable_interrupt(struct wilc *dev)
 226{
 227        struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev);
 228        int ret = 0;
 229
 230        sdio_claim_host(func);
 231        ret = sdio_claim_irq(func, wilc_sdio_interrupt);
 232        sdio_release_host(func);
 233
 234        if (ret < 0) {
 235                dev_err(&func->dev, "can't claim sdio_irq, err(%d)\n", ret);
 236                ret = -EIO;
 237        }
 238        return ret;
 239}
 240
 241static void wilc_sdio_disable_interrupt(struct wilc *dev)
 242{
 243        struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev);
 244        int ret;
 245
 246        sdio_claim_host(func);
 247        ret = sdio_release_irq(func);
 248        if (ret < 0)
 249                dev_err(&func->dev, "can't release sdio_irq, err(%d)\n", ret);
 250        sdio_release_host(func);
 251}
 252
 253/********************************************
 254 *
 255 *      Function 0
 256 *
 257 ********************************************/
 258
 259static int sdio_set_func0_csa_address(struct wilc *wilc, u32 adr)
 260{
 261        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 262        struct sdio_cmd52 cmd;
 263        int ret;
 264
 265        /**
 266         *      Review: BIG ENDIAN
 267         **/
 268        cmd.read_write = 1;
 269        cmd.function = 0;
 270        cmd.raw = 0;
 271        cmd.address = 0x10c;
 272        cmd.data = (u8)adr;
 273        ret = wilc_sdio_cmd52(wilc, &cmd);
 274        if (ret) {
 275                dev_err(&func->dev, "Failed cmd52, set 0x10c data...\n");
 276                goto _fail_;
 277        }
 278
 279        cmd.address = 0x10d;
 280        cmd.data = (u8)(adr >> 8);
 281        ret = wilc_sdio_cmd52(wilc, &cmd);
 282        if (ret) {
 283                dev_err(&func->dev, "Failed cmd52, set 0x10d data...\n");
 284                goto _fail_;
 285        }
 286
 287        cmd.address = 0x10e;
 288        cmd.data = (u8)(adr >> 16);
 289        ret = wilc_sdio_cmd52(wilc, &cmd);
 290        if (ret) {
 291                dev_err(&func->dev, "Failed cmd52, set 0x10e data...\n");
 292                goto _fail_;
 293        }
 294
 295        return 1;
 296_fail_:
 297        return 0;
 298}
 299
 300static int sdio_set_func0_block_size(struct wilc *wilc, u32 block_size)
 301{
 302        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 303        struct sdio_cmd52 cmd;
 304        int ret;
 305
 306        cmd.read_write = 1;
 307        cmd.function = 0;
 308        cmd.raw = 0;
 309        cmd.address = 0x10;
 310        cmd.data = (u8)block_size;
 311        ret = wilc_sdio_cmd52(wilc, &cmd);
 312        if (ret) {
 313                dev_err(&func->dev, "Failed cmd52, set 0x10 data...\n");
 314                goto _fail_;
 315        }
 316
 317        cmd.address = 0x11;
 318        cmd.data = (u8)(block_size >> 8);
 319        ret = wilc_sdio_cmd52(wilc, &cmd);
 320        if (ret) {
 321                dev_err(&func->dev, "Failed cmd52, set 0x11 data...\n");
 322                goto _fail_;
 323        }
 324
 325        return 1;
 326_fail_:
 327        return 0;
 328}
 329
 330/********************************************
 331 *
 332 *      Function 1
 333 *
 334 ********************************************/
 335
 336static int sdio_set_func1_block_size(struct wilc *wilc, u32 block_size)
 337{
 338        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 339        struct sdio_cmd52 cmd;
 340        int ret;
 341
 342        cmd.read_write = 1;
 343        cmd.function = 0;
 344        cmd.raw = 0;
 345        cmd.address = 0x110;
 346        cmd.data = (u8)block_size;
 347        ret = wilc_sdio_cmd52(wilc, &cmd);
 348        if (ret) {
 349                dev_err(&func->dev, "Failed cmd52, set 0x110 data...\n");
 350                goto _fail_;
 351        }
 352        cmd.address = 0x111;
 353        cmd.data = (u8)(block_size >> 8);
 354        ret = wilc_sdio_cmd52(wilc, &cmd);
 355        if (ret) {
 356                dev_err(&func->dev, "Failed cmd52, set 0x111 data...\n");
 357                goto _fail_;
 358        }
 359
 360        return 1;
 361_fail_:
 362        return 0;
 363}
 364
 365/********************************************
 366 *
 367 *      Sdio interfaces
 368 *
 369 ********************************************/
 370static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data)
 371{
 372        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 373        int ret;
 374
 375        data = cpu_to_le32(data);
 376
 377        if ((addr >= 0xf0) && (addr <= 0xff)) {
 378                struct sdio_cmd52 cmd;
 379
 380                cmd.read_write = 1;
 381                cmd.function = 0;
 382                cmd.raw = 0;
 383                cmd.address = addr;
 384                cmd.data = data;
 385                ret = wilc_sdio_cmd52(wilc, &cmd);
 386                if (ret) {
 387                        dev_err(&func->dev,
 388                                "Failed cmd 52, read reg (%08x) ...\n", addr);
 389                        goto _fail_;
 390                }
 391        } else {
 392                struct sdio_cmd53 cmd;
 393
 394                /**
 395                 *      set the AHB address
 396                 **/
 397                if (!sdio_set_func0_csa_address(wilc, addr))
 398                        goto _fail_;
 399
 400                cmd.read_write = 1;
 401                cmd.function = 0;
 402                cmd.address = 0x10f;
 403                cmd.block_mode = 0;
 404                cmd.increment = 1;
 405                cmd.count = 4;
 406                cmd.buffer = (u8 *)&data;
 407                cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */
 408                ret = wilc_sdio_cmd53(wilc, &cmd);
 409                if (ret) {
 410                        dev_err(&func->dev,
 411                                "Failed cmd53, write reg (%08x)...\n", addr);
 412                        goto _fail_;
 413                }
 414        }
 415
 416        return 1;
 417
 418_fail_:
 419
 420        return 0;
 421}
 422
 423static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
 424{
 425        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 426        u32 block_size = g_sdio.block_size;
 427        struct sdio_cmd53 cmd;
 428        int nblk, nleft, ret;
 429
 430        cmd.read_write = 1;
 431        if (addr > 0) {
 432                /**
 433                 *      has to be word aligned...
 434                 **/
 435                if (size & 0x3) {
 436                        size += 4;
 437                        size &= ~0x3;
 438                }
 439
 440                /**
 441                 *      func 0 access
 442                 **/
 443                cmd.function = 0;
 444                cmd.address = 0x10f;
 445        } else {
 446                /**
 447                 *      has to be word aligned...
 448                 **/
 449                if (size & 0x3) {
 450                        size += 4;
 451                        size &= ~0x3;
 452                }
 453
 454                /**
 455                 *      func 1 access
 456                 **/
 457                cmd.function = 1;
 458                cmd.address = 0;
 459        }
 460
 461        nblk = size / block_size;
 462        nleft = size % block_size;
 463
 464        if (nblk > 0) {
 465                cmd.block_mode = 1;
 466                cmd.increment = 1;
 467                cmd.count = nblk;
 468                cmd.buffer = buf;
 469                cmd.block_size = block_size;
 470                if (addr > 0) {
 471                        if (!sdio_set_func0_csa_address(wilc, addr))
 472                                goto _fail_;
 473                }
 474                ret = wilc_sdio_cmd53(wilc, &cmd);
 475                if (ret) {
 476                        dev_err(&func->dev,
 477                                "Failed cmd53 [%x], block send...\n", addr);
 478                        goto _fail_;
 479                }
 480                if (addr > 0)
 481                        addr += nblk * block_size;
 482                buf += nblk * block_size;
 483        }
 484
 485        if (nleft > 0) {
 486                cmd.block_mode = 0;
 487                cmd.increment = 1;
 488                cmd.count = nleft;
 489                cmd.buffer = buf;
 490
 491                cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */
 492
 493                if (addr > 0) {
 494                        if (!sdio_set_func0_csa_address(wilc, addr))
 495                                goto _fail_;
 496                }
 497                ret = wilc_sdio_cmd53(wilc, &cmd);
 498                if (ret) {
 499                        dev_err(&func->dev,
 500                                "Failed cmd53 [%x], bytes send...\n", addr);
 501                        goto _fail_;
 502                }
 503        }
 504
 505        return 1;
 506
 507_fail_:
 508
 509        return 0;
 510}
 511
 512static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data)
 513{
 514        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 515        int ret;
 516
 517        if ((addr >= 0xf0) && (addr <= 0xff)) {
 518                struct sdio_cmd52 cmd;
 519
 520                cmd.read_write = 0;
 521                cmd.function = 0;
 522                cmd.raw = 0;
 523                cmd.address = addr;
 524                ret = wilc_sdio_cmd52(wilc, &cmd);
 525                if (ret) {
 526                        dev_err(&func->dev,
 527                                "Failed cmd 52, read reg (%08x) ...\n", addr);
 528                        goto _fail_;
 529                }
 530                *data = cmd.data;
 531        } else {
 532                struct sdio_cmd53 cmd;
 533
 534                if (!sdio_set_func0_csa_address(wilc, addr))
 535                        goto _fail_;
 536
 537                cmd.read_write = 0;
 538                cmd.function = 0;
 539                cmd.address = 0x10f;
 540                cmd.block_mode = 0;
 541                cmd.increment = 1;
 542                cmd.count = 4;
 543                cmd.buffer = (u8 *)data;
 544
 545                cmd.block_size = g_sdio.block_size; /* johnny : prevent it from setting unexpected value */
 546                ret = wilc_sdio_cmd53(wilc, &cmd);
 547                if (ret) {
 548                        dev_err(&func->dev,
 549                                "Failed cmd53, read reg (%08x)...\n", addr);
 550                        goto _fail_;
 551                }
 552        }
 553
 554        *data = cpu_to_le32(*data);
 555
 556        return 1;
 557
 558_fail_:
 559
 560        return 0;
 561}
 562
 563static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
 564{
 565        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 566        u32 block_size = g_sdio.block_size;
 567        struct sdio_cmd53 cmd;
 568        int nblk, nleft, ret;
 569
 570        cmd.read_write = 0;
 571        if (addr > 0) {
 572                /**
 573                 *      has to be word aligned...
 574                 **/
 575                if (size & 0x3) {
 576                        size += 4;
 577                        size &= ~0x3;
 578                }
 579
 580                /**
 581                 *      func 0 access
 582                 **/
 583                cmd.function = 0;
 584                cmd.address = 0x10f;
 585        } else {
 586                /**
 587                 *      has to be word aligned...
 588                 **/
 589                if (size & 0x3) {
 590                        size += 4;
 591                        size &= ~0x3;
 592                }
 593
 594                /**
 595                 *      func 1 access
 596                 **/
 597                cmd.function = 1;
 598                cmd.address = 0;
 599        }
 600
 601        nblk = size / block_size;
 602        nleft = size % block_size;
 603
 604        if (nblk > 0) {
 605                cmd.block_mode = 1;
 606                cmd.increment = 1;
 607                cmd.count = nblk;
 608                cmd.buffer = buf;
 609                cmd.block_size = block_size;
 610                if (addr > 0) {
 611                        if (!sdio_set_func0_csa_address(wilc, addr))
 612                                goto _fail_;
 613                }
 614                ret = wilc_sdio_cmd53(wilc, &cmd);
 615                if (ret) {
 616                        dev_err(&func->dev,
 617                                "Failed cmd53 [%x], block read...\n", addr);
 618                        goto _fail_;
 619                }
 620                if (addr > 0)
 621                        addr += nblk * block_size;
 622                buf += nblk * block_size;
 623        }       /* if (nblk > 0) */
 624
 625        if (nleft > 0) {
 626                cmd.block_mode = 0;
 627                cmd.increment = 1;
 628                cmd.count = nleft;
 629                cmd.buffer = buf;
 630
 631                cmd.block_size = block_size; /* johnny : prevent it from setting unexpected value */
 632
 633                if (addr > 0) {
 634                        if (!sdio_set_func0_csa_address(wilc, addr))
 635                                goto _fail_;
 636                }
 637                ret = wilc_sdio_cmd53(wilc, &cmd);
 638                if (ret) {
 639                        dev_err(&func->dev,
 640                                "Failed cmd53 [%x], bytes read...\n", addr);
 641                        goto _fail_;
 642                }
 643        }
 644
 645        return 1;
 646
 647_fail_:
 648
 649        return 0;
 650}
 651
 652/********************************************
 653 *
 654 *      Bus interfaces
 655 *
 656 ********************************************/
 657
 658static int sdio_deinit(struct wilc *wilc)
 659{
 660        return 1;
 661}
 662
 663static int sdio_init(struct wilc *wilc, bool resume)
 664{
 665        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 666        struct sdio_cmd52 cmd;
 667        int loop, ret;
 668        u32 chipid;
 669
 670        if (!resume) {
 671                memset(&g_sdio, 0, sizeof(struct wilc_sdio));
 672                g_sdio.irq_gpio = wilc->dev_irq_num;
 673        }
 674
 675        /**
 676         *      function 0 csa enable
 677         **/
 678        cmd.read_write = 1;
 679        cmd.function = 0;
 680        cmd.raw = 1;
 681        cmd.address = 0x100;
 682        cmd.data = 0x80;
 683        ret = wilc_sdio_cmd52(wilc, &cmd);
 684        if (ret) {
 685                dev_err(&func->dev, "Fail cmd 52, enable csa...\n");
 686                goto _fail_;
 687        }
 688
 689        /**
 690         *      function 0 block size
 691         **/
 692        if (!sdio_set_func0_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) {
 693                dev_err(&func->dev, "Fail cmd 52, set func 0 block size...\n");
 694                goto _fail_;
 695        }
 696        g_sdio.block_size = WILC_SDIO_BLOCK_SIZE;
 697
 698        /**
 699         *      enable func1 IO
 700         **/
 701        cmd.read_write = 1;
 702        cmd.function = 0;
 703        cmd.raw = 1;
 704        cmd.address = 0x2;
 705        cmd.data = 0x2;
 706        ret = wilc_sdio_cmd52(wilc, &cmd);
 707        if (ret) {
 708                dev_err(&func->dev,
 709                        "Fail cmd 52, set IOE register...\n");
 710                goto _fail_;
 711        }
 712
 713        /**
 714         *      make sure func 1 is up
 715         **/
 716        cmd.read_write = 0;
 717        cmd.function = 0;
 718        cmd.raw = 0;
 719        cmd.address = 0x3;
 720        loop = 3;
 721        do {
 722                cmd.data = 0;
 723                ret = wilc_sdio_cmd52(wilc, &cmd);
 724                if (ret) {
 725                        dev_err(&func->dev,
 726                                "Fail cmd 52, get IOR register...\n");
 727                        goto _fail_;
 728                }
 729                if (cmd.data == 0x2)
 730                        break;
 731        } while (loop--);
 732
 733        if (loop <= 0) {
 734                dev_err(&func->dev, "Fail func 1 is not ready...\n");
 735                goto _fail_;
 736        }
 737
 738        /**
 739         *      func 1 is ready, set func 1 block size
 740         **/
 741        if (!sdio_set_func1_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) {
 742                dev_err(&func->dev, "Fail set func 1 block size...\n");
 743                goto _fail_;
 744        }
 745
 746        /**
 747         *      func 1 interrupt enable
 748         **/
 749        cmd.read_write = 1;
 750        cmd.function = 0;
 751        cmd.raw = 1;
 752        cmd.address = 0x4;
 753        cmd.data = 0x3;
 754        ret = wilc_sdio_cmd52(wilc, &cmd);
 755        if (ret) {
 756                dev_err(&func->dev, "Fail cmd 52, set IEN register...\n");
 757                goto _fail_;
 758        }
 759
 760        /**
 761         *      make sure can read back chip id correctly
 762         **/
 763        if (!resume) {
 764                if (!sdio_read_reg(wilc, 0x1000, &chipid)) {
 765                        dev_err(&func->dev, "Fail cmd read chip id...\n");
 766                        goto _fail_;
 767                }
 768                dev_err(&func->dev, "chipid (%08x)\n", chipid);
 769                if ((chipid & 0xfff) > 0x2a0)
 770                        g_sdio.has_thrpt_enh3 = 1;
 771                else
 772                        g_sdio.has_thrpt_enh3 = 0;
 773                dev_info(&func->dev, "has_thrpt_enh3 = %d...\n",
 774                         g_sdio.has_thrpt_enh3);
 775        }
 776
 777        return 1;
 778
 779_fail_:
 780
 781        return 0;
 782}
 783
 784static int sdio_read_size(struct wilc *wilc, u32 *size)
 785{
 786        u32 tmp;
 787        struct sdio_cmd52 cmd;
 788
 789        /**
 790         *      Read DMA count in words
 791         **/
 792        cmd.read_write = 0;
 793        cmd.function = 0;
 794        cmd.raw = 0;
 795        cmd.address = 0xf2;
 796        cmd.data = 0;
 797        wilc_sdio_cmd52(wilc, &cmd);
 798        tmp = cmd.data;
 799
 800        /* cmd.read_write = 0; */
 801        /* cmd.function = 0; */
 802        /* cmd.raw = 0; */
 803        cmd.address = 0xf3;
 804        cmd.data = 0;
 805        wilc_sdio_cmd52(wilc, &cmd);
 806        tmp |= (cmd.data << 8);
 807
 808        *size = tmp;
 809        return 1;
 810}
 811
 812static int sdio_read_int(struct wilc *wilc, u32 *int_status)
 813{
 814        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 815        u32 tmp;
 816        struct sdio_cmd52 cmd;
 817
 818        sdio_read_size(wilc, &tmp);
 819
 820        /**
 821         *      Read IRQ flags
 822         **/
 823        if (!g_sdio.irq_gpio) {
 824                int i;
 825
 826                cmd.function = 1;
 827                cmd.address = 0x04;
 828                cmd.data = 0;
 829                wilc_sdio_cmd52(wilc, &cmd);
 830
 831                if (cmd.data & BIT(0))
 832                        tmp |= INT_0;
 833                if (cmd.data & BIT(2))
 834                        tmp |= INT_1;
 835                if (cmd.data & BIT(3))
 836                        tmp |= INT_2;
 837                if (cmd.data & BIT(4))
 838                        tmp |= INT_3;
 839                if (cmd.data & BIT(5))
 840                        tmp |= INT_4;
 841                if (cmd.data & BIT(6))
 842                        tmp |= INT_5;
 843                for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
 844                        if ((tmp >> (IRG_FLAGS_OFFSET + i)) & 0x1) {
 845                                dev_err(&func->dev,
 846                                        "Unexpected interrupt (1) : tmp=%x, data=%x\n",
 847                                        tmp, cmd.data);
 848                                break;
 849                        }
 850                }
 851        } else {
 852                u32 irq_flags;
 853
 854                cmd.read_write = 0;
 855                cmd.function = 0;
 856                cmd.raw = 0;
 857                cmd.address = 0xf7;
 858                cmd.data = 0;
 859                wilc_sdio_cmd52(wilc, &cmd);
 860                irq_flags = cmd.data & 0x1f;
 861                tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET);
 862        }
 863
 864        *int_status = tmp;
 865
 866        return 1;
 867}
 868
 869static int sdio_clear_int_ext(struct wilc *wilc, u32 val)
 870{
 871        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 872        int ret;
 873
 874        if (g_sdio.has_thrpt_enh3) {
 875                u32 reg;
 876
 877                if (g_sdio.irq_gpio) {
 878                        u32 flags;
 879
 880                        flags = val & (BIT(MAX_NUN_INT_THRPT_ENH2) - 1);
 881                        reg = flags;
 882                } else {
 883                        reg = 0;
 884                }
 885                /* select VMM table 0 */
 886                if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
 887                        reg |= BIT(5);
 888                /* select VMM table 1 */
 889                if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
 890                        reg |= BIT(6);
 891                /* enable VMM */
 892                if ((val & EN_VMM) == EN_VMM)
 893                        reg |= BIT(7);
 894                if (reg) {
 895                        struct sdio_cmd52 cmd;
 896
 897                        cmd.read_write = 1;
 898                        cmd.function = 0;
 899                        cmd.raw = 0;
 900                        cmd.address = 0xf8;
 901                        cmd.data = reg;
 902
 903                        ret = wilc_sdio_cmd52(wilc, &cmd);
 904                        if (ret) {
 905                                dev_err(&func->dev,
 906                                        "Failed cmd52, set 0xf8 data (%d) ...\n",
 907                                        __LINE__);
 908                                goto _fail_;
 909                        }
 910                }
 911        } else {
 912                if (g_sdio.irq_gpio) {
 913                        /* see below. has_thrpt_enh2 uses register 0xf8 to clear interrupts. */
 914                        /* Cannot clear multiple interrupts. Must clear each interrupt individually */
 915                        u32 flags;
 916
 917                        flags = val & (BIT(MAX_NUM_INT) - 1);
 918                        if (flags) {
 919                                int i;
 920
 921                                ret = 1;
 922                                for (i = 0; i < g_sdio.nint; i++) {
 923                                        if (flags & 1) {
 924                                                struct sdio_cmd52 cmd;
 925
 926                                                cmd.read_write = 1;
 927                                                cmd.function = 0;
 928                                                cmd.raw = 0;
 929                                                cmd.address = 0xf8;
 930                                                cmd.data = BIT(i);
 931
 932                                                ret = wilc_sdio_cmd52(wilc, &cmd);
 933                                                if (ret) {
 934                                                        dev_err(&func->dev,
 935                                                                "Failed cmd52, set 0xf8 data (%d) ...\n",
 936                                                                __LINE__);
 937                                                        goto _fail_;
 938                                                }
 939                                        }
 940                                        if (!ret)
 941                                                break;
 942                                        flags >>= 1;
 943                                }
 944                                if (!ret)
 945                                        goto _fail_;
 946                                for (i = g_sdio.nint; i < MAX_NUM_INT; i++) {
 947                                        if (flags & 1)
 948                                                dev_err(&func->dev,
 949                                                        "Unexpected interrupt cleared %d...\n",
 950                                                        i);
 951                                        flags >>= 1;
 952                                }
 953                        }
 954                }
 955
 956                {
 957                        u32 vmm_ctl;
 958
 959                        vmm_ctl = 0;
 960                        /* select VMM table 0 */
 961                        if ((val & SEL_VMM_TBL0) == SEL_VMM_TBL0)
 962                                vmm_ctl |= BIT(0);
 963                        /* select VMM table 1 */
 964                        if ((val & SEL_VMM_TBL1) == SEL_VMM_TBL1)
 965                                vmm_ctl |= BIT(1);
 966                        /* enable VMM */
 967                        if ((val & EN_VMM) == EN_VMM)
 968                                vmm_ctl |= BIT(2);
 969
 970                        if (vmm_ctl) {
 971                                struct sdio_cmd52 cmd;
 972
 973                                cmd.read_write = 1;
 974                                cmd.function = 0;
 975                                cmd.raw = 0;
 976                                cmd.address = 0xf6;
 977                                cmd.data = vmm_ctl;
 978                                ret = wilc_sdio_cmd52(wilc, &cmd);
 979                                if (ret) {
 980                                        dev_err(&func->dev,
 981                                                "Failed cmd52, set 0xf6 data (%d) ...\n",
 982                                                __LINE__);
 983                                        goto _fail_;
 984                                }
 985                        }
 986                }
 987        }
 988
 989        return 1;
 990_fail_:
 991        return 0;
 992}
 993
 994static int sdio_sync_ext(struct wilc *wilc, int nint)
 995{
 996        struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 997        u32 reg;
 998
 999        if (nint > MAX_NUM_INT) {
1000                dev_err(&func->dev, "Too many interrupts (%d)...\n", nint);
1001                return 0;
1002        }
1003        if (nint > MAX_NUN_INT_THRPT_ENH2) {
1004                dev_err(&func->dev,
1005                        "Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n");
1006                return 0;
1007        }
1008
1009        g_sdio.nint = nint;
1010
1011        /**
1012         *      Disable power sequencer
1013         **/
1014        if (!sdio_read_reg(wilc, WILC_MISC, &reg)) {
1015                dev_err(&func->dev, "Failed read misc reg...\n");
1016                return 0;
1017        }
1018
1019        reg &= ~BIT(8);
1020        if (!sdio_write_reg(wilc, WILC_MISC, reg)) {
1021                dev_err(&func->dev, "Failed write misc reg...\n");
1022                return 0;
1023        }
1024
1025        if (g_sdio.irq_gpio) {
1026                u32 reg;
1027                int ret, i;
1028
1029                /**
1030                 *      interrupt pin mux select
1031                 **/
1032                ret = sdio_read_reg(wilc, WILC_PIN_MUX_0, &reg);
1033                if (!ret) {
1034                        dev_err(&func->dev, "Failed read reg (%08x)...\n",
1035                                WILC_PIN_MUX_0);
1036                        return 0;
1037                }
1038                reg |= BIT(8);
1039                ret = sdio_write_reg(wilc, WILC_PIN_MUX_0, reg);
1040                if (!ret) {
1041                        dev_err(&func->dev, "Failed write reg (%08x)...\n",
1042                                WILC_PIN_MUX_0);
1043                        return 0;
1044                }
1045
1046                /**
1047                 *      interrupt enable
1048                 **/
1049                ret = sdio_read_reg(wilc, WILC_INTR_ENABLE, &reg);
1050                if (!ret) {
1051                        dev_err(&func->dev, "Failed read reg (%08x)...\n",
1052                                WILC_INTR_ENABLE);
1053                        return 0;
1054                }
1055
1056                for (i = 0; (i < 5) && (nint > 0); i++, nint--)
1057                        reg |= BIT((27 + i));
1058                ret = sdio_write_reg(wilc, WILC_INTR_ENABLE, reg);
1059                if (!ret) {
1060                        dev_err(&func->dev, "Failed write reg (%08x)...\n",
1061                                WILC_INTR_ENABLE);
1062                        return 0;
1063                }
1064                if (nint) {
1065                        ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
1066                        if (!ret) {
1067                                dev_err(&func->dev,
1068                                        "Failed read reg (%08x)...\n",
1069                                        WILC_INTR2_ENABLE);
1070                                return 0;
1071                        }
1072
1073                        for (i = 0; (i < 3) && (nint > 0); i++, nint--)
1074                                reg |= BIT(i);
1075
1076                        ret = sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
1077                        if (!ret) {
1078                                dev_err(&func->dev,
1079                                        "Failed write reg (%08x)...\n",
1080                                        WILC_INTR2_ENABLE);
1081                                return 0;
1082                        }
1083                }
1084        }
1085        return 1;
1086}
1087
1088/********************************************
1089 *
1090 *      Global sdio HIF function table
1091 *
1092 ********************************************/
1093
1094static const struct wilc_hif_func wilc_hif_sdio = {
1095        .hif_init = sdio_init,
1096        .hif_deinit = sdio_deinit,
1097        .hif_read_reg = sdio_read_reg,
1098        .hif_write_reg = sdio_write_reg,
1099        .hif_block_rx = sdio_read,
1100        .hif_block_tx = sdio_write,
1101        .hif_read_int = sdio_read_int,
1102        .hif_clear_int_ext = sdio_clear_int_ext,
1103        .hif_read_size = sdio_read_size,
1104        .hif_block_tx_ext = sdio_write,
1105        .hif_block_rx_ext = sdio_read,
1106        .hif_sync_ext = sdio_sync_ext,
1107        .enable_interrupt = wilc_sdio_enable_interrupt,
1108        .disable_interrupt = wilc_sdio_disable_interrupt,
1109};
1110
1111