root/drivers/staging/wilc1000/wilc_sdio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wilc_sdio_interrupt
  2. wilc_sdio_cmd52
  3. wilc_sdio_cmd53
  4. wilc_sdio_probe
  5. wilc_sdio_remove
  6. wilc_sdio_reset
  7. wilc_sdio_suspend
  8. wilc_sdio_enable_interrupt
  9. wilc_sdio_disable_interrupt
  10. wilc_sdio_set_func0_csa_address
  11. wilc_sdio_set_func0_block_size
  12. wilc_sdio_set_func1_block_size
  13. wilc_sdio_write_reg
  14. wilc_sdio_write
  15. wilc_sdio_read_reg
  16. wilc_sdio_read
  17. wilc_sdio_deinit
  18. wilc_sdio_init
  19. wilc_sdio_read_size
  20. wilc_sdio_read_int
  21. wilc_sdio_clear_int_ext
  22. wilc_sdio_sync_ext
  23. wilc_sdio_resume

   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/host.h>
  10 
  11 #include "wilc_wfi_netdevice.h"
  12 #include "wilc_wfi_cfgoperations.h"
  13 
  14 #define SDIO_MODALIAS "wilc1000_sdio"
  15 
  16 #define SDIO_VENDOR_ID_WILC 0x0296
  17 #define SDIO_DEVICE_ID_WILC 0x5347
  18 
  19 static const struct sdio_device_id wilc_sdio_ids[] = {
  20         { SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) },
  21         { },
  22 };
  23 
  24 #define WILC_SDIO_BLOCK_SIZE 512
  25 
  26 struct wilc_sdio {
  27         bool irq_gpio;
  28         u32 block_size;
  29         int nint;
  30 /* Max num interrupts allowed in registers 0xf7, 0xf8 */
  31 #define MAX_NUN_INT_THRPT_ENH2 (5)
  32         int has_thrpt_enh3;
  33 };
  34 
  35 struct sdio_cmd52 {
  36         u32 read_write:         1;
  37         u32 function:           3;
  38         u32 raw:                1;
  39         u32 address:            17;
  40         u32 data:               8;
  41 };
  42 
  43 struct sdio_cmd53 {
  44         u32 read_write:         1;
  45         u32 function:           3;
  46         u32 block_mode:         1;
  47         u32 increment:          1;
  48         u32 address:            17;
  49         u32 count:              9;
  50         u8 *buffer;
  51         u32 block_size;
  52 };
  53 
  54 static const struct wilc_hif_func wilc_hif_sdio;
  55 
  56 static void wilc_sdio_interrupt(struct sdio_func *func)
  57 {
  58         sdio_release_host(func);
  59         wilc_handle_isr(sdio_get_drvdata(func));
  60         sdio_claim_host(func);
  61 }
  62 
  63 static int wilc_sdio_cmd52(struct wilc *wilc, struct sdio_cmd52 *cmd)
  64 {
  65         struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
  66         int ret;
  67         u8 data;
  68 
  69         sdio_claim_host(func);
  70 
  71         func->num = cmd->function;
  72         if (cmd->read_write) {  /* write */
  73                 if (cmd->raw) {
  74                         sdio_writeb(func, cmd->data, cmd->address, &ret);
  75                         data = sdio_readb(func, cmd->address, &ret);
  76                         cmd->data = data;
  77                 } else {
  78                         sdio_writeb(func, cmd->data, cmd->address, &ret);
  79                 }
  80         } else {        /* read */
  81                 data = sdio_readb(func, cmd->address, &ret);
  82                 cmd->data = data;
  83         }
  84 
  85         sdio_release_host(func);
  86 
  87         if (ret)
  88                 dev_err(&func->dev, "%s..failed, err(%d)\n", __func__, ret);
  89         return ret;
  90 }
  91 
  92 static int wilc_sdio_cmd53(struct wilc *wilc, struct sdio_cmd53 *cmd)
  93 {
  94         struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
  95         int size, ret;
  96 
  97         sdio_claim_host(func);
  98 
  99         func->num = cmd->function;
 100         func->cur_blksize = cmd->block_size;
 101         if (cmd->block_mode)
 102                 size = cmd->count * cmd->block_size;
 103         else
 104                 size = cmd->count;
 105 
 106         if (cmd->read_write) {  /* write */
 107                 ret = sdio_memcpy_toio(func, cmd->address,
 108                                        (void *)cmd->buffer, size);
 109         } else {        /* read */
 110                 ret = sdio_memcpy_fromio(func, (void *)cmd->buffer,
 111                                          cmd->address,  size);
 112         }
 113 
 114         sdio_release_host(func);
 115 
 116         if (ret)
 117                 dev_err(&func->dev, "%s..failed, err(%d)\n", __func__,  ret);
 118 
 119         return ret;
 120 }
 121 
 122 static int wilc_sdio_probe(struct sdio_func *func,
 123                            const struct sdio_device_id *id)
 124 {
 125         struct wilc *wilc;
 126         int ret;
 127         struct gpio_desc *gpio = NULL;
 128         struct wilc_sdio *sdio_priv;
 129 
 130         sdio_priv = kzalloc(sizeof(*sdio_priv), GFP_KERNEL);
 131         if (!sdio_priv)
 132                 return -ENOMEM;
 133 
 134         if (IS_ENABLED(CONFIG_WILC1000_HW_OOB_INTR)) {
 135                 gpio = gpiod_get(&func->dev, "irq", GPIOD_IN);
 136                 if (IS_ERR(gpio)) {
 137                         /* get the GPIO descriptor from hardcode GPIO number */
 138                         gpio = gpio_to_desc(GPIO_NUM);
 139                         if (!gpio)
 140                                 dev_err(&func->dev, "failed to get irq gpio\n");
 141                 }
 142         }
 143 
 144         ret = wilc_cfg80211_init(&wilc, &func->dev, WILC_HIF_SDIO,
 145                                  &wilc_hif_sdio);
 146         if (ret) {
 147                 kfree(sdio_priv);
 148                 return ret;
 149         }
 150         sdio_set_drvdata(func, wilc);
 151         wilc->bus_data = sdio_priv;
 152         wilc->dev = &func->dev;
 153         wilc->gpio_irq = gpio;
 154 
 155         wilc->rtc_clk = devm_clk_get(&func->card->dev, "rtc_clk");
 156         if (PTR_ERR_OR_ZERO(wilc->rtc_clk) == -EPROBE_DEFER)
 157                 return -EPROBE_DEFER;
 158         else if (!IS_ERR(wilc->rtc_clk))
 159                 clk_prepare_enable(wilc->rtc_clk);
 160 
 161         dev_info(&func->dev, "Driver Initializing success\n");
 162         return 0;
 163 }
 164 
 165 static void wilc_sdio_remove(struct sdio_func *func)
 166 {
 167         struct wilc *wilc = sdio_get_drvdata(func);
 168 
 169         /* free the GPIO in module remove */
 170         if (wilc->gpio_irq)
 171                 gpiod_put(wilc->gpio_irq);
 172 
 173         if (!IS_ERR(wilc->rtc_clk))
 174                 clk_disable_unprepare(wilc->rtc_clk);
 175 
 176         wilc_netdev_cleanup(wilc);
 177 }
 178 
 179 static int wilc_sdio_reset(struct wilc *wilc)
 180 {
 181         struct sdio_cmd52 cmd;
 182         int ret;
 183         struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 184 
 185         cmd.read_write = 1;
 186         cmd.function = 0;
 187         cmd.raw = 0;
 188         cmd.address = 0x6;
 189         cmd.data = 0x8;
 190         ret = wilc_sdio_cmd52(wilc, &cmd);
 191         if (ret) {
 192                 dev_err(&func->dev, "Fail cmd 52, reset cmd ...\n");
 193                 return ret;
 194         }
 195         return 0;
 196 }
 197 
 198 static int wilc_sdio_suspend(struct device *dev)
 199 {
 200         struct sdio_func *func = dev_to_sdio_func(dev);
 201         struct wilc *wilc = sdio_get_drvdata(func);
 202         int ret;
 203 
 204         dev_info(dev, "sdio suspend\n");
 205         chip_wakeup(wilc);
 206 
 207         if (!IS_ERR(wilc->rtc_clk))
 208                 clk_disable_unprepare(wilc->rtc_clk);
 209 
 210         if (wilc->suspend_event) {
 211                 host_sleep_notify(wilc);
 212                 chip_allow_sleep(wilc);
 213         }
 214 
 215         ret = wilc_sdio_reset(wilc);
 216         if (ret) {
 217                 dev_err(&func->dev, "Fail reset sdio\n");
 218                 return ret;
 219         }
 220         sdio_claim_host(func);
 221 
 222         return 0;
 223 }
 224 
 225 static 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 
 241 static 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 
 259 static int wilc_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 
 300 static int wilc_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 
 336 static int wilc_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  ********************************************/
 370 static int wilc_sdio_write_reg(struct wilc *wilc, u32 addr, u32 data)
 371 {
 372         struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 373         struct wilc_sdio *sdio_priv = wilc->bus_data;
 374         int ret;
 375 
 376         cpu_to_le32s(&data);
 377 
 378         if (addr >= 0xf0 && addr <= 0xff) {
 379                 struct sdio_cmd52 cmd;
 380 
 381                 cmd.read_write = 1;
 382                 cmd.function = 0;
 383                 cmd.raw = 0;
 384                 cmd.address = addr;
 385                 cmd.data = data;
 386                 ret = wilc_sdio_cmd52(wilc, &cmd);
 387                 if (ret) {
 388                         dev_err(&func->dev,
 389                                 "Failed cmd 52, read reg (%08x) ...\n", addr);
 390                         goto fail;
 391                 }
 392         } else {
 393                 struct sdio_cmd53 cmd;
 394 
 395                 /**
 396                  *      set the AHB address
 397                  **/
 398                 if (!wilc_sdio_set_func0_csa_address(wilc, addr))
 399                         goto fail;
 400 
 401                 cmd.read_write = 1;
 402                 cmd.function = 0;
 403                 cmd.address = 0x10f;
 404                 cmd.block_mode = 0;
 405                 cmd.increment = 1;
 406                 cmd.count = 4;
 407                 cmd.buffer = (u8 *)&data;
 408                 cmd.block_size = sdio_priv->block_size;
 409                 ret = wilc_sdio_cmd53(wilc, &cmd);
 410                 if (ret) {
 411                         dev_err(&func->dev,
 412                                 "Failed cmd53, write reg (%08x)...\n", addr);
 413                         goto fail;
 414                 }
 415         }
 416 
 417         return 1;
 418 
 419 fail:
 420 
 421         return 0;
 422 }
 423 
 424 static int wilc_sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
 425 {
 426         struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 427         struct wilc_sdio *sdio_priv = wilc->bus_data;
 428         u32 block_size = sdio_priv->block_size;
 429         struct sdio_cmd53 cmd;
 430         int nblk, nleft, ret;
 431 
 432         cmd.read_write = 1;
 433         if (addr > 0) {
 434                 /**
 435                  *      has to be word aligned...
 436                  **/
 437                 if (size & 0x3) {
 438                         size += 4;
 439                         size &= ~0x3;
 440                 }
 441 
 442                 /**
 443                  *      func 0 access
 444                  **/
 445                 cmd.function = 0;
 446                 cmd.address = 0x10f;
 447         } else {
 448                 /**
 449                  *      has to be word aligned...
 450                  **/
 451                 if (size & 0x3) {
 452                         size += 4;
 453                         size &= ~0x3;
 454                 }
 455 
 456                 /**
 457                  *      func 1 access
 458                  **/
 459                 cmd.function = 1;
 460                 cmd.address = 0;
 461         }
 462 
 463         nblk = size / block_size;
 464         nleft = size % block_size;
 465 
 466         if (nblk > 0) {
 467                 cmd.block_mode = 1;
 468                 cmd.increment = 1;
 469                 cmd.count = nblk;
 470                 cmd.buffer = buf;
 471                 cmd.block_size = block_size;
 472                 if (addr > 0) {
 473                         if (!wilc_sdio_set_func0_csa_address(wilc, addr))
 474                                 goto fail;
 475                 }
 476                 ret = wilc_sdio_cmd53(wilc, &cmd);
 477                 if (ret) {
 478                         dev_err(&func->dev,
 479                                 "Failed cmd53 [%x], block send...\n", addr);
 480                         goto fail;
 481                 }
 482                 if (addr > 0)
 483                         addr += nblk * block_size;
 484                 buf += nblk * block_size;
 485         }
 486 
 487         if (nleft > 0) {
 488                 cmd.block_mode = 0;
 489                 cmd.increment = 1;
 490                 cmd.count = nleft;
 491                 cmd.buffer = buf;
 492 
 493                 cmd.block_size = block_size;
 494 
 495                 if (addr > 0) {
 496                         if (!wilc_sdio_set_func0_csa_address(wilc, addr))
 497                                 goto fail;
 498                 }
 499                 ret = wilc_sdio_cmd53(wilc, &cmd);
 500                 if (ret) {
 501                         dev_err(&func->dev,
 502                                 "Failed cmd53 [%x], bytes send...\n", addr);
 503                         goto fail;
 504                 }
 505         }
 506 
 507         return 1;
 508 
 509 fail:
 510 
 511         return 0;
 512 }
 513 
 514 static int wilc_sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data)
 515 {
 516         struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 517         struct wilc_sdio *sdio_priv = wilc->bus_data;
 518         int ret;
 519 
 520         if (addr >= 0xf0 && addr <= 0xff) {
 521                 struct sdio_cmd52 cmd;
 522 
 523                 cmd.read_write = 0;
 524                 cmd.function = 0;
 525                 cmd.raw = 0;
 526                 cmd.address = addr;
 527                 ret = wilc_sdio_cmd52(wilc, &cmd);
 528                 if (ret) {
 529                         dev_err(&func->dev,
 530                                 "Failed cmd 52, read reg (%08x) ...\n", addr);
 531                         goto fail;
 532                 }
 533                 *data = cmd.data;
 534         } else {
 535                 struct sdio_cmd53 cmd;
 536 
 537                 if (!wilc_sdio_set_func0_csa_address(wilc, addr))
 538                         goto fail;
 539 
 540                 cmd.read_write = 0;
 541                 cmd.function = 0;
 542                 cmd.address = 0x10f;
 543                 cmd.block_mode = 0;
 544                 cmd.increment = 1;
 545                 cmd.count = 4;
 546                 cmd.buffer = (u8 *)data;
 547 
 548                 cmd.block_size = sdio_priv->block_size;
 549                 ret = wilc_sdio_cmd53(wilc, &cmd);
 550                 if (ret) {
 551                         dev_err(&func->dev,
 552                                 "Failed cmd53, read reg (%08x)...\n", addr);
 553                         goto fail;
 554                 }
 555         }
 556 
 557         le32_to_cpus(data);
 558 
 559         return 1;
 560 
 561 fail:
 562 
 563         return 0;
 564 }
 565 
 566 static int wilc_sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
 567 {
 568         struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 569         struct wilc_sdio *sdio_priv = wilc->bus_data;
 570         u32 block_size = sdio_priv->block_size;
 571         struct sdio_cmd53 cmd;
 572         int nblk, nleft, ret;
 573 
 574         cmd.read_write = 0;
 575         if (addr > 0) {
 576                 /**
 577                  *      has to be word aligned...
 578                  **/
 579                 if (size & 0x3) {
 580                         size += 4;
 581                         size &= ~0x3;
 582                 }
 583 
 584                 /**
 585                  *      func 0 access
 586                  **/
 587                 cmd.function = 0;
 588                 cmd.address = 0x10f;
 589         } else {
 590                 /**
 591                  *      has to be word aligned...
 592                  **/
 593                 if (size & 0x3) {
 594                         size += 4;
 595                         size &= ~0x3;
 596                 }
 597 
 598                 /**
 599                  *      func 1 access
 600                  **/
 601                 cmd.function = 1;
 602                 cmd.address = 0;
 603         }
 604 
 605         nblk = size / block_size;
 606         nleft = size % block_size;
 607 
 608         if (nblk > 0) {
 609                 cmd.block_mode = 1;
 610                 cmd.increment = 1;
 611                 cmd.count = nblk;
 612                 cmd.buffer = buf;
 613                 cmd.block_size = block_size;
 614                 if (addr > 0) {
 615                         if (!wilc_sdio_set_func0_csa_address(wilc, addr))
 616                                 goto fail;
 617                 }
 618                 ret = wilc_sdio_cmd53(wilc, &cmd);
 619                 if (ret) {
 620                         dev_err(&func->dev,
 621                                 "Failed cmd53 [%x], block read...\n", addr);
 622                         goto fail;
 623                 }
 624                 if (addr > 0)
 625                         addr += nblk * block_size;
 626                 buf += nblk * block_size;
 627         }       /* if (nblk > 0) */
 628 
 629         if (nleft > 0) {
 630                 cmd.block_mode = 0;
 631                 cmd.increment = 1;
 632                 cmd.count = nleft;
 633                 cmd.buffer = buf;
 634 
 635                 cmd.block_size = block_size;
 636 
 637                 if (addr > 0) {
 638                         if (!wilc_sdio_set_func0_csa_address(wilc, addr))
 639                                 goto fail;
 640                 }
 641                 ret = wilc_sdio_cmd53(wilc, &cmd);
 642                 if (ret) {
 643                         dev_err(&func->dev,
 644                                 "Failed cmd53 [%x], bytes read...\n", addr);
 645                         goto fail;
 646                 }
 647         }
 648 
 649         return 1;
 650 
 651 fail:
 652 
 653         return 0;
 654 }
 655 
 656 /********************************************
 657  *
 658  *      Bus interfaces
 659  *
 660  ********************************************/
 661 
 662 static int wilc_sdio_deinit(struct wilc *wilc)
 663 {
 664         return 1;
 665 }
 666 
 667 static int wilc_sdio_init(struct wilc *wilc, bool resume)
 668 {
 669         struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 670         struct wilc_sdio *sdio_priv = wilc->bus_data;
 671         struct sdio_cmd52 cmd;
 672         int loop, ret;
 673         u32 chipid;
 674 
 675         if (!resume)
 676                 sdio_priv->irq_gpio = wilc->dev_irq_num;
 677 
 678         /**
 679          *      function 0 csa enable
 680          **/
 681         cmd.read_write = 1;
 682         cmd.function = 0;
 683         cmd.raw = 1;
 684         cmd.address = 0x100;
 685         cmd.data = 0x80;
 686         ret = wilc_sdio_cmd52(wilc, &cmd);
 687         if (ret) {
 688                 dev_err(&func->dev, "Fail cmd 52, enable csa...\n");
 689                 goto fail;
 690         }
 691 
 692         /**
 693          *      function 0 block size
 694          **/
 695         if (!wilc_sdio_set_func0_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) {
 696                 dev_err(&func->dev, "Fail cmd 52, set func 0 block size...\n");
 697                 goto fail;
 698         }
 699         sdio_priv->block_size = WILC_SDIO_BLOCK_SIZE;
 700 
 701         /**
 702          *      enable func1 IO
 703          **/
 704         cmd.read_write = 1;
 705         cmd.function = 0;
 706         cmd.raw = 1;
 707         cmd.address = 0x2;
 708         cmd.data = 0x2;
 709         ret = wilc_sdio_cmd52(wilc, &cmd);
 710         if (ret) {
 711                 dev_err(&func->dev,
 712                         "Fail cmd 52, set IOE register...\n");
 713                 goto fail;
 714         }
 715 
 716         /**
 717          *      make sure func 1 is up
 718          **/
 719         cmd.read_write = 0;
 720         cmd.function = 0;
 721         cmd.raw = 0;
 722         cmd.address = 0x3;
 723         loop = 3;
 724         do {
 725                 cmd.data = 0;
 726                 ret = wilc_sdio_cmd52(wilc, &cmd);
 727                 if (ret) {
 728                         dev_err(&func->dev,
 729                                 "Fail cmd 52, get IOR register...\n");
 730                         goto fail;
 731                 }
 732                 if (cmd.data == 0x2)
 733                         break;
 734         } while (loop--);
 735 
 736         if (loop <= 0) {
 737                 dev_err(&func->dev, "Fail func 1 is not ready...\n");
 738                 goto fail;
 739         }
 740 
 741         /**
 742          *      func 1 is ready, set func 1 block size
 743          **/
 744         if (!wilc_sdio_set_func1_block_size(wilc, WILC_SDIO_BLOCK_SIZE)) {
 745                 dev_err(&func->dev, "Fail set func 1 block size...\n");
 746                 goto fail;
 747         }
 748 
 749         /**
 750          *      func 1 interrupt enable
 751          **/
 752         cmd.read_write = 1;
 753         cmd.function = 0;
 754         cmd.raw = 1;
 755         cmd.address = 0x4;
 756         cmd.data = 0x3;
 757         ret = wilc_sdio_cmd52(wilc, &cmd);
 758         if (ret) {
 759                 dev_err(&func->dev, "Fail cmd 52, set IEN register...\n");
 760                 goto fail;
 761         }
 762 
 763         /**
 764          *      make sure can read back chip id correctly
 765          **/
 766         if (!resume) {
 767                 if (!wilc_sdio_read_reg(wilc, 0x1000, &chipid)) {
 768                         dev_err(&func->dev, "Fail cmd read chip id...\n");
 769                         goto fail;
 770                 }
 771                 dev_err(&func->dev, "chipid (%08x)\n", chipid);
 772                 if ((chipid & 0xfff) > 0x2a0)
 773                         sdio_priv->has_thrpt_enh3 = 1;
 774                 else
 775                         sdio_priv->has_thrpt_enh3 = 0;
 776                 dev_info(&func->dev, "has_thrpt_enh3 = %d...\n",
 777                          sdio_priv->has_thrpt_enh3);
 778         }
 779 
 780         return 1;
 781 
 782 fail:
 783 
 784         return 0;
 785 }
 786 
 787 static int wilc_sdio_read_size(struct wilc *wilc, u32 *size)
 788 {
 789         u32 tmp;
 790         struct sdio_cmd52 cmd;
 791 
 792         /**
 793          *      Read DMA count in words
 794          **/
 795         cmd.read_write = 0;
 796         cmd.function = 0;
 797         cmd.raw = 0;
 798         cmd.address = 0xf2;
 799         cmd.data = 0;
 800         wilc_sdio_cmd52(wilc, &cmd);
 801         tmp = cmd.data;
 802 
 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 
 812 static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status)
 813 {
 814         struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 815         struct wilc_sdio *sdio_priv = wilc->bus_data;
 816         u32 tmp;
 817         struct sdio_cmd52 cmd;
 818 
 819         wilc_sdio_read_size(wilc, &tmp);
 820 
 821         /**
 822          *      Read IRQ flags
 823          **/
 824         if (!sdio_priv->irq_gpio) {
 825                 int i;
 826 
 827                 cmd.read_write = 0;
 828                 cmd.function = 1;
 829                 cmd.address = 0x04;
 830                 cmd.data = 0;
 831                 wilc_sdio_cmd52(wilc, &cmd);
 832 
 833                 if (cmd.data & BIT(0))
 834                         tmp |= INT_0;
 835                 if (cmd.data & BIT(2))
 836                         tmp |= INT_1;
 837                 if (cmd.data & BIT(3))
 838                         tmp |= INT_2;
 839                 if (cmd.data & BIT(4))
 840                         tmp |= INT_3;
 841                 if (cmd.data & BIT(5))
 842                         tmp |= INT_4;
 843                 if (cmd.data & BIT(6))
 844                         tmp |= INT_5;
 845                 for (i = sdio_priv->nint; i < MAX_NUM_INT; i++) {
 846                         if ((tmp >> (IRG_FLAGS_OFFSET + i)) & 0x1) {
 847                                 dev_err(&func->dev,
 848                                         "Unexpected interrupt (1) : tmp=%x, data=%x\n",
 849                                         tmp, cmd.data);
 850                                 break;
 851                         }
 852                 }
 853         } else {
 854                 u32 irq_flags;
 855 
 856                 cmd.read_write = 0;
 857                 cmd.function = 0;
 858                 cmd.raw = 0;
 859                 cmd.address = 0xf7;
 860                 cmd.data = 0;
 861                 wilc_sdio_cmd52(wilc, &cmd);
 862                 irq_flags = cmd.data & 0x1f;
 863                 tmp |= ((irq_flags >> 0) << IRG_FLAGS_OFFSET);
 864         }
 865 
 866         *int_status = tmp;
 867 
 868         return 1;
 869 }
 870 
 871 static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val)
 872 {
 873         struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 874         struct wilc_sdio *sdio_priv = wilc->bus_data;
 875         int ret;
 876         int vmm_ctl;
 877 
 878         if (sdio_priv->has_thrpt_enh3) {
 879                 u32 reg;
 880 
 881                 if (sdio_priv->irq_gpio) {
 882                         u32 flags;
 883 
 884                         flags = val & (BIT(MAX_NUN_INT_THRPT_ENH2) - 1);
 885                         reg = flags;
 886                 } else {
 887                         reg = 0;
 888                 }
 889                 /* select VMM table 0 */
 890                 if (val & SEL_VMM_TBL0)
 891                         reg |= BIT(5);
 892                 /* select VMM table 1 */
 893                 if (val & SEL_VMM_TBL1)
 894                         reg |= BIT(6);
 895                 /* enable VMM */
 896                 if (val & EN_VMM)
 897                         reg |= BIT(7);
 898                 if (reg) {
 899                         struct sdio_cmd52 cmd;
 900 
 901                         cmd.read_write = 1;
 902                         cmd.function = 0;
 903                         cmd.raw = 0;
 904                         cmd.address = 0xf8;
 905                         cmd.data = reg;
 906 
 907                         ret = wilc_sdio_cmd52(wilc, &cmd);
 908                         if (ret) {
 909                                 dev_err(&func->dev,
 910                                         "Failed cmd52, set 0xf8 data (%d) ...\n",
 911                                         __LINE__);
 912                                 goto fail;
 913                         }
 914                 }
 915                 return 1;
 916         }
 917         if (sdio_priv->irq_gpio) {
 918                 /* has_thrpt_enh2 uses register 0xf8 to clear interrupts. */
 919                 /*
 920                  * Cannot clear multiple interrupts.
 921                  * Must clear each interrupt individually.
 922                  */
 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 < sdio_priv->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                                 if (!ret)
 949                                         break;
 950                                 flags >>= 1;
 951                         }
 952                         if (!ret)
 953                                 goto fail;
 954                         for (i = sdio_priv->nint; i < MAX_NUM_INT; i++) {
 955                                 if (flags & 1)
 956                                         dev_err(&func->dev,
 957                                                 "Unexpected interrupt cleared %d...\n",
 958                                                 i);
 959                                 flags >>= 1;
 960                         }
 961                 }
 962         }
 963 
 964         vmm_ctl = 0;
 965         /* select VMM table 0 */
 966         if (val & SEL_VMM_TBL0)
 967                 vmm_ctl |= BIT(0);
 968         /* select VMM table 1 */
 969         if (val & SEL_VMM_TBL1)
 970                 vmm_ctl |= BIT(1);
 971         /* enable VMM */
 972         if (val & EN_VMM)
 973                 vmm_ctl |= BIT(2);
 974 
 975         if (vmm_ctl) {
 976                 struct sdio_cmd52 cmd;
 977 
 978                 cmd.read_write = 1;
 979                 cmd.function = 0;
 980                 cmd.raw = 0;
 981                 cmd.address = 0xf6;
 982                 cmd.data = vmm_ctl;
 983                 ret = wilc_sdio_cmd52(wilc, &cmd);
 984                 if (ret) {
 985                         dev_err(&func->dev,
 986                                 "Failed cmd52, set 0xf6 data (%d) ...\n",
 987                                 __LINE__);
 988                         goto fail;
 989                 }
 990         }
 991         return 1;
 992 fail:
 993         return 0;
 994 }
 995 
 996 static int wilc_sdio_sync_ext(struct wilc *wilc, int nint)
 997 {
 998         struct sdio_func *func = dev_to_sdio_func(wilc->dev);
 999         struct wilc_sdio *sdio_priv = wilc->bus_data;
1000         u32 reg;
1001 
1002         if (nint > MAX_NUM_INT) {
1003                 dev_err(&func->dev, "Too many interrupts (%d)...\n", nint);
1004                 return 0;
1005         }
1006         if (nint > MAX_NUN_INT_THRPT_ENH2) {
1007                 dev_err(&func->dev,
1008                         "Cannot support more than 5 interrupts when has_thrpt_enh2=1.\n");
1009                 return 0;
1010         }
1011 
1012         sdio_priv->nint = nint;
1013 
1014         /**
1015          *      Disable power sequencer
1016          **/
1017         if (!wilc_sdio_read_reg(wilc, WILC_MISC, &reg)) {
1018                 dev_err(&func->dev, "Failed read misc reg...\n");
1019                 return 0;
1020         }
1021 
1022         reg &= ~BIT(8);
1023         if (!wilc_sdio_write_reg(wilc, WILC_MISC, reg)) {
1024                 dev_err(&func->dev, "Failed write misc reg...\n");
1025                 return 0;
1026         }
1027 
1028         if (sdio_priv->irq_gpio) {
1029                 u32 reg;
1030                 int ret, i;
1031 
1032                 /**
1033                  *      interrupt pin mux select
1034                  **/
1035                 ret = wilc_sdio_read_reg(wilc, WILC_PIN_MUX_0, &reg);
1036                 if (!ret) {
1037                         dev_err(&func->dev, "Failed read reg (%08x)...\n",
1038                                 WILC_PIN_MUX_0);
1039                         return 0;
1040                 }
1041                 reg |= BIT(8);
1042                 ret = wilc_sdio_write_reg(wilc, WILC_PIN_MUX_0, reg);
1043                 if (!ret) {
1044                         dev_err(&func->dev, "Failed write reg (%08x)...\n",
1045                                 WILC_PIN_MUX_0);
1046                         return 0;
1047                 }
1048 
1049                 /**
1050                  *      interrupt enable
1051                  **/
1052                 ret = wilc_sdio_read_reg(wilc, WILC_INTR_ENABLE, &reg);
1053                 if (!ret) {
1054                         dev_err(&func->dev, "Failed read reg (%08x)...\n",
1055                                 WILC_INTR_ENABLE);
1056                         return 0;
1057                 }
1058 
1059                 for (i = 0; (i < 5) && (nint > 0); i++, nint--)
1060                         reg |= BIT((27 + i));
1061                 ret = wilc_sdio_write_reg(wilc, WILC_INTR_ENABLE, reg);
1062                 if (!ret) {
1063                         dev_err(&func->dev, "Failed write reg (%08x)...\n",
1064                                 WILC_INTR_ENABLE);
1065                         return 0;
1066                 }
1067                 if (nint) {
1068                         ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
1069                         if (!ret) {
1070                                 dev_err(&func->dev,
1071                                         "Failed read reg (%08x)...\n",
1072                                         WILC_INTR2_ENABLE);
1073                                 return 0;
1074                         }
1075 
1076                         for (i = 0; (i < 3) && (nint > 0); i++, nint--)
1077                                 reg |= BIT(i);
1078 
1079                         ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
1080                         if (!ret) {
1081                                 dev_err(&func->dev,
1082                                         "Failed write reg (%08x)...\n",
1083                                         WILC_INTR2_ENABLE);
1084                                 return 0;
1085                         }
1086                 }
1087         }
1088         return 1;
1089 }
1090 
1091 /* Global sdio HIF function table */
1092 static const struct wilc_hif_func wilc_hif_sdio = {
1093         .hif_init = wilc_sdio_init,
1094         .hif_deinit = wilc_sdio_deinit,
1095         .hif_read_reg = wilc_sdio_read_reg,
1096         .hif_write_reg = wilc_sdio_write_reg,
1097         .hif_block_rx = wilc_sdio_read,
1098         .hif_block_tx = wilc_sdio_write,
1099         .hif_read_int = wilc_sdio_read_int,
1100         .hif_clear_int_ext = wilc_sdio_clear_int_ext,
1101         .hif_read_size = wilc_sdio_read_size,
1102         .hif_block_tx_ext = wilc_sdio_write,
1103         .hif_block_rx_ext = wilc_sdio_read,
1104         .hif_sync_ext = wilc_sdio_sync_ext,
1105         .enable_interrupt = wilc_sdio_enable_interrupt,
1106         .disable_interrupt = wilc_sdio_disable_interrupt,
1107 };
1108 
1109 static int wilc_sdio_resume(struct device *dev)
1110 {
1111         struct sdio_func *func = dev_to_sdio_func(dev);
1112         struct wilc *wilc = sdio_get_drvdata(func);
1113 
1114         dev_info(dev, "sdio resume\n");
1115         sdio_release_host(func);
1116         chip_wakeup(wilc);
1117         wilc_sdio_init(wilc, true);
1118 
1119         if (wilc->suspend_event)
1120                 host_wakeup_notify(wilc);
1121 
1122         chip_allow_sleep(wilc);
1123 
1124         return 0;
1125 }
1126 
1127 static const struct of_device_id wilc_of_match[] = {
1128         { .compatible = "microchip,wilc1000-sdio", },
1129         { /* sentinel */ }
1130 };
1131 MODULE_DEVICE_TABLE(of, wilc_of_match);
1132 
1133 static const struct dev_pm_ops wilc_sdio_pm_ops = {
1134         .suspend = wilc_sdio_suspend,
1135         .resume = wilc_sdio_resume,
1136 };
1137 
1138 static struct sdio_driver wilc_sdio_driver = {
1139         .name           = SDIO_MODALIAS,
1140         .id_table       = wilc_sdio_ids,
1141         .probe          = wilc_sdio_probe,
1142         .remove         = wilc_sdio_remove,
1143         .drv = {
1144                 .pm = &wilc_sdio_pm_ops,
1145                 .of_match_table = wilc_of_match,
1146         }
1147 };
1148 module_driver(wilc_sdio_driver,
1149               sdio_register_driver,
1150               sdio_unregister_driver);
1151 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */