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