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