15c4e6f13SPierre Ossman /* 25c4e6f13SPierre Ossman * linux/drivers/mmc/sdio.c 35c4e6f13SPierre Ossman * 45c4e6f13SPierre Ossman * Copyright 2006-2007 Pierre Ossman 55c4e6f13SPierre Ossman * 65c4e6f13SPierre Ossman * This program is free software; you can redistribute it and/or modify 75c4e6f13SPierre Ossman * it under the terms of the GNU General Public License as published by 85c4e6f13SPierre Ossman * the Free Software Foundation; either version 2 of the License, or (at 95c4e6f13SPierre Ossman * your option) any later version. 105c4e6f13SPierre Ossman */ 115c4e6f13SPierre Ossman 125c4e6f13SPierre Ossman #include <linux/err.h> 135c4e6f13SPierre Ossman 145c4e6f13SPierre Ossman #include <linux/mmc/host.h> 155c4e6f13SPierre Ossman #include <linux/mmc/card.h> 1635c66c19SPierre Ossman #include <linux/mmc/sdio.h> 17e29a7d73SPierre Ossman #include <linux/mmc/sdio_func.h> 185c4e6f13SPierre Ossman 195c4e6f13SPierre Ossman #include "core.h" 205c4e6f13SPierre Ossman #include "bus.h" 2171578a1eSMichal Miroslaw #include "sd.h" 22e29a7d73SPierre Ossman #include "sdio_bus.h" 235c4e6f13SPierre Ossman #include "mmc_ops.h" 245c4e6f13SPierre Ossman #include "sd_ops.h" 255c4e6f13SPierre Ossman #include "sdio_ops.h" 26b7261261SNicolas Pitre #include "sdio_cis.h" 275c4e6f13SPierre Ossman 280597007fSPierre Ossman static int sdio_read_fbr(struct sdio_func *func) 290597007fSPierre Ossman { 300597007fSPierre Ossman int ret; 310597007fSPierre Ossman unsigned char data; 320597007fSPierre Ossman 330597007fSPierre Ossman ret = mmc_io_rw_direct(func->card, 0, 0, 347616ee95SDavid Vrabel SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF, 0, &data); 350597007fSPierre Ossman if (ret) 360597007fSPierre Ossman goto out; 370597007fSPierre Ossman 380597007fSPierre Ossman data &= 0x0f; 390597007fSPierre Ossman 400597007fSPierre Ossman if (data == 0x0f) { 410597007fSPierre Ossman ret = mmc_io_rw_direct(func->card, 0, 0, 427616ee95SDavid Vrabel SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF_EXT, 0, &data); 430597007fSPierre Ossman if (ret) 440597007fSPierre Ossman goto out; 450597007fSPierre Ossman } 460597007fSPierre Ossman 470597007fSPierre Ossman func->class = data; 480597007fSPierre Ossman 490597007fSPierre Ossman out: 500597007fSPierre Ossman return ret; 510597007fSPierre Ossman } 520597007fSPierre Ossman 53e29a7d73SPierre Ossman static int sdio_init_func(struct mmc_card *card, unsigned int fn) 54e29a7d73SPierre Ossman { 550597007fSPierre Ossman int ret; 56e29a7d73SPierre Ossman struct sdio_func *func; 57e29a7d73SPierre Ossman 58e29a7d73SPierre Ossman BUG_ON(fn > SDIO_MAX_FUNCS); 59e29a7d73SPierre Ossman 60e29a7d73SPierre Ossman func = sdio_alloc_func(card); 61e29a7d73SPierre Ossman if (IS_ERR(func)) 62e29a7d73SPierre Ossman return PTR_ERR(func); 63e29a7d73SPierre Ossman 64e29a7d73SPierre Ossman func->num = fn; 65e29a7d73SPierre Ossman 66*6f51be3dSGrazvydas Ignotas if (!(card->quirks & MMC_QUIRK_NONSTD_SDIO)) { 670597007fSPierre Ossman ret = sdio_read_fbr(func); 680597007fSPierre Ossman if (ret) 690597007fSPierre Ossman goto fail; 700597007fSPierre Ossman 711a632f8cSPierre Ossman ret = sdio_read_func_cis(func); 72b7261261SNicolas Pitre if (ret) 73b7261261SNicolas Pitre goto fail; 74*6f51be3dSGrazvydas Ignotas } else { 75*6f51be3dSGrazvydas Ignotas func->vendor = func->card->cis.vendor; 76*6f51be3dSGrazvydas Ignotas func->device = func->card->cis.device; 77*6f51be3dSGrazvydas Ignotas func->max_blksize = func->card->cis.blksize; 78*6f51be3dSGrazvydas Ignotas } 79b7261261SNicolas Pitre 80e29a7d73SPierre Ossman card->sdio_func[fn - 1] = func; 81e29a7d73SPierre Ossman 82e29a7d73SPierre Ossman return 0; 830597007fSPierre Ossman 840597007fSPierre Ossman fail: 850597007fSPierre Ossman /* 860597007fSPierre Ossman * It is okay to remove the function here even though we hold 870597007fSPierre Ossman * the host lock as we haven't registered the device yet. 880597007fSPierre Ossman */ 890597007fSPierre Ossman sdio_remove_func(func); 900597007fSPierre Ossman return ret; 91e29a7d73SPierre Ossman } 92e29a7d73SPierre Ossman 9335c66c19SPierre Ossman static int sdio_read_cccr(struct mmc_card *card) 9435c66c19SPierre Ossman { 9535c66c19SPierre Ossman int ret; 9635c66c19SPierre Ossman int cccr_vsn; 9735c66c19SPierre Ossman unsigned char data; 9835c66c19SPierre Ossman 9935c66c19SPierre Ossman memset(&card->cccr, 0, sizeof(struct sdio_cccr)); 10035c66c19SPierre Ossman 10135c66c19SPierre Ossman ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CCCR, 0, &data); 10235c66c19SPierre Ossman if (ret) 10335c66c19SPierre Ossman goto out; 10435c66c19SPierre Ossman 10535c66c19SPierre Ossman cccr_vsn = data & 0x0f; 10635c66c19SPierre Ossman 10735c66c19SPierre Ossman if (cccr_vsn > SDIO_CCCR_REV_1_20) { 10835c66c19SPierre Ossman printk(KERN_ERR "%s: unrecognised CCCR structure version %d\n", 10935c66c19SPierre Ossman mmc_hostname(card->host), cccr_vsn); 11035c66c19SPierre Ossman return -EINVAL; 11135c66c19SPierre Ossman } 11235c66c19SPierre Ossman 11335c66c19SPierre Ossman card->cccr.sdio_vsn = (data & 0xf0) >> 4; 11435c66c19SPierre Ossman 11535c66c19SPierre Ossman ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CAPS, 0, &data); 11635c66c19SPierre Ossman if (ret) 11735c66c19SPierre Ossman goto out; 11835c66c19SPierre Ossman 11935c66c19SPierre Ossman if (data & SDIO_CCCR_CAP_SMB) 12035c66c19SPierre Ossman card->cccr.multi_block = 1; 12135c66c19SPierre Ossman if (data & SDIO_CCCR_CAP_LSC) 12235c66c19SPierre Ossman card->cccr.low_speed = 1; 12335c66c19SPierre Ossman if (data & SDIO_CCCR_CAP_4BLS) 12435c66c19SPierre Ossman card->cccr.wide_bus = 1; 12535c66c19SPierre Ossman 12635c66c19SPierre Ossman if (cccr_vsn >= SDIO_CCCR_REV_1_10) { 12735c66c19SPierre Ossman ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_POWER, 0, &data); 12835c66c19SPierre Ossman if (ret) 12935c66c19SPierre Ossman goto out; 13035c66c19SPierre Ossman 13135c66c19SPierre Ossman if (data & SDIO_POWER_SMPC) 13235c66c19SPierre Ossman card->cccr.high_power = 1; 13335c66c19SPierre Ossman } 13435c66c19SPierre Ossman 13535c66c19SPierre Ossman if (cccr_vsn >= SDIO_CCCR_REV_1_20) { 13635c66c19SPierre Ossman ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &data); 13735c66c19SPierre Ossman if (ret) 13835c66c19SPierre Ossman goto out; 13935c66c19SPierre Ossman 14035c66c19SPierre Ossman if (data & SDIO_SPEED_SHS) 14135c66c19SPierre Ossman card->cccr.high_speed = 1; 14235c66c19SPierre Ossman } 14335c66c19SPierre Ossman 14435c66c19SPierre Ossman out: 14535c66c19SPierre Ossman return ret; 14635c66c19SPierre Ossman } 14735c66c19SPierre Ossman 1484ff6471cSPierre Ossman static int sdio_enable_wide(struct mmc_card *card) 1494ff6471cSPierre Ossman { 1504ff6471cSPierre Ossman int ret; 1514ff6471cSPierre Ossman u8 ctrl; 1524ff6471cSPierre Ossman 1534ff6471cSPierre Ossman if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) 1544ff6471cSPierre Ossman return 0; 1554ff6471cSPierre Ossman 1564ff6471cSPierre Ossman if (card->cccr.low_speed && !card->cccr.wide_bus) 1574ff6471cSPierre Ossman return 0; 1584ff6471cSPierre Ossman 1594ff6471cSPierre Ossman ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); 1604ff6471cSPierre Ossman if (ret) 1614ff6471cSPierre Ossman return ret; 1624ff6471cSPierre Ossman 1634ff6471cSPierre Ossman ctrl |= SDIO_BUS_WIDTH_4BIT; 1644ff6471cSPierre Ossman 1654ff6471cSPierre Ossman ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); 1664ff6471cSPierre Ossman if (ret) 1674ff6471cSPierre Ossman return ret; 1684ff6471cSPierre Ossman 1697310ece8SMichal Miroslaw return 1; 1704ff6471cSPierre Ossman } 1714ff6471cSPierre Ossman 1725c4e6f13SPierre Ossman /* 173006ebd5dSOhad Ben-Cohen * If desired, disconnect the pull-up resistor on CD/DAT[3] (pin 1) 174006ebd5dSOhad Ben-Cohen * of the card. This may be required on certain setups of boards, 175006ebd5dSOhad Ben-Cohen * controllers and embedded sdio device which do not need the card's 176006ebd5dSOhad Ben-Cohen * pull-up. As a result, card detection is disabled and power is saved. 177006ebd5dSOhad Ben-Cohen */ 178006ebd5dSOhad Ben-Cohen static int sdio_disable_cd(struct mmc_card *card) 179006ebd5dSOhad Ben-Cohen { 180006ebd5dSOhad Ben-Cohen int ret; 181006ebd5dSOhad Ben-Cohen u8 ctrl; 182006ebd5dSOhad Ben-Cohen 183006ebd5dSOhad Ben-Cohen if (!card->cccr.disable_cd) 184006ebd5dSOhad Ben-Cohen return 0; 185006ebd5dSOhad Ben-Cohen 186006ebd5dSOhad Ben-Cohen ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); 187006ebd5dSOhad Ben-Cohen if (ret) 188006ebd5dSOhad Ben-Cohen return ret; 189006ebd5dSOhad Ben-Cohen 190006ebd5dSOhad Ben-Cohen ctrl |= SDIO_BUS_CD_DISABLE; 191006ebd5dSOhad Ben-Cohen 192006ebd5dSOhad Ben-Cohen return mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); 193006ebd5dSOhad Ben-Cohen } 194006ebd5dSOhad Ben-Cohen 195006ebd5dSOhad Ben-Cohen /* 1966b5eda36SDaniel Drake * Devices that remain active during a system suspend are 1976b5eda36SDaniel Drake * put back into 1-bit mode. 1986b5eda36SDaniel Drake */ 1996b5eda36SDaniel Drake static int sdio_disable_wide(struct mmc_card *card) 2006b5eda36SDaniel Drake { 2016b5eda36SDaniel Drake int ret; 2026b5eda36SDaniel Drake u8 ctrl; 2036b5eda36SDaniel Drake 2046b5eda36SDaniel Drake if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) 2056b5eda36SDaniel Drake return 0; 2066b5eda36SDaniel Drake 2076b5eda36SDaniel Drake if (card->cccr.low_speed && !card->cccr.wide_bus) 2086b5eda36SDaniel Drake return 0; 2096b5eda36SDaniel Drake 2106b5eda36SDaniel Drake ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); 2116b5eda36SDaniel Drake if (ret) 2126b5eda36SDaniel Drake return ret; 2136b5eda36SDaniel Drake 2146b5eda36SDaniel Drake if (!(ctrl & SDIO_BUS_WIDTH_4BIT)) 2156b5eda36SDaniel Drake return 0; 2166b5eda36SDaniel Drake 2176b5eda36SDaniel Drake ctrl &= ~SDIO_BUS_WIDTH_4BIT; 2186b5eda36SDaniel Drake ctrl |= SDIO_BUS_ASYNC_INT; 2196b5eda36SDaniel Drake 2206b5eda36SDaniel Drake ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); 2216b5eda36SDaniel Drake if (ret) 2226b5eda36SDaniel Drake return ret; 2236b5eda36SDaniel Drake 2246b5eda36SDaniel Drake mmc_set_bus_width(card->host, MMC_BUS_WIDTH_1); 2256b5eda36SDaniel Drake 2266b5eda36SDaniel Drake return 0; 2276b5eda36SDaniel Drake } 2286b5eda36SDaniel Drake 2297310ece8SMichal Miroslaw 2307310ece8SMichal Miroslaw static int sdio_enable_4bit_bus(struct mmc_card *card) 2317310ece8SMichal Miroslaw { 2327310ece8SMichal Miroslaw int err; 2337310ece8SMichal Miroslaw 2347310ece8SMichal Miroslaw if (card->type == MMC_TYPE_SDIO) 2357310ece8SMichal Miroslaw return sdio_enable_wide(card); 2367310ece8SMichal Miroslaw 2377310ece8SMichal Miroslaw if ((card->host->caps & MMC_CAP_4_BIT_DATA) && 2387310ece8SMichal Miroslaw (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { 2397310ece8SMichal Miroslaw err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); 2407310ece8SMichal Miroslaw if (err) 2417310ece8SMichal Miroslaw return err; 2427310ece8SMichal Miroslaw } else 2437310ece8SMichal Miroslaw return 0; 2447310ece8SMichal Miroslaw 2457310ece8SMichal Miroslaw err = sdio_enable_wide(card); 2467310ece8SMichal Miroslaw if (err <= 0) 2477310ece8SMichal Miroslaw mmc_app_set_bus_width(card, MMC_BUS_WIDTH_1); 2487310ece8SMichal Miroslaw 2497310ece8SMichal Miroslaw return err; 2507310ece8SMichal Miroslaw } 2517310ece8SMichal Miroslaw 2527310ece8SMichal Miroslaw 2536b5eda36SDaniel Drake /* 254d16f5770SPierre Ossman * Test if the card supports high-speed mode and, if so, switch to it. 255d16f5770SPierre Ossman */ 2567310ece8SMichal Miroslaw static int mmc_sdio_switch_hs(struct mmc_card *card, int enable) 257d16f5770SPierre Ossman { 258d16f5770SPierre Ossman int ret; 259d16f5770SPierre Ossman u8 speed; 260d16f5770SPierre Ossman 261d16f5770SPierre Ossman if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) 262d16f5770SPierre Ossman return 0; 263d16f5770SPierre Ossman 264d16f5770SPierre Ossman if (!card->cccr.high_speed) 265d16f5770SPierre Ossman return 0; 266d16f5770SPierre Ossman 267d16f5770SPierre Ossman ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); 268d16f5770SPierre Ossman if (ret) 269d16f5770SPierre Ossman return ret; 270d16f5770SPierre Ossman 2717310ece8SMichal Miroslaw if (enable) 272d16f5770SPierre Ossman speed |= SDIO_SPEED_EHS; 2737310ece8SMichal Miroslaw else 2747310ece8SMichal Miroslaw speed &= ~SDIO_SPEED_EHS; 275d16f5770SPierre Ossman 276d16f5770SPierre Ossman ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); 277d16f5770SPierre Ossman if (ret) 278d16f5770SPierre Ossman return ret; 279d16f5770SPierre Ossman 28071578a1eSMichal Miroslaw return 1; 28171578a1eSMichal Miroslaw } 282d16f5770SPierre Ossman 2837310ece8SMichal Miroslaw /* 2847310ece8SMichal Miroslaw * Enable SDIO/combo card's high-speed mode. Return 0/1 if [not]supported. 2857310ece8SMichal Miroslaw */ 2867310ece8SMichal Miroslaw static int sdio_enable_hs(struct mmc_card *card) 2877310ece8SMichal Miroslaw { 2887310ece8SMichal Miroslaw int ret; 2897310ece8SMichal Miroslaw 2907310ece8SMichal Miroslaw ret = mmc_sdio_switch_hs(card, true); 2917310ece8SMichal Miroslaw if (ret <= 0 || card->type == MMC_TYPE_SDIO) 2927310ece8SMichal Miroslaw return ret; 2937310ece8SMichal Miroslaw 2947310ece8SMichal Miroslaw ret = mmc_sd_switch_hs(card); 2957310ece8SMichal Miroslaw if (ret <= 0) 2967310ece8SMichal Miroslaw mmc_sdio_switch_hs(card, false); 2977310ece8SMichal Miroslaw 2987310ece8SMichal Miroslaw return ret; 2997310ece8SMichal Miroslaw } 3007310ece8SMichal Miroslaw 30171578a1eSMichal Miroslaw static unsigned mmc_sdio_get_max_clock(struct mmc_card *card) 30271578a1eSMichal Miroslaw { 30371578a1eSMichal Miroslaw unsigned max_dtr; 30471578a1eSMichal Miroslaw 30571578a1eSMichal Miroslaw if (mmc_card_highspeed(card)) { 30671578a1eSMichal Miroslaw /* 30771578a1eSMichal Miroslaw * The SDIO specification doesn't mention how 30871578a1eSMichal Miroslaw * the CIS transfer speed register relates to 30971578a1eSMichal Miroslaw * high-speed, but it seems that 50 MHz is 31071578a1eSMichal Miroslaw * mandatory. 31171578a1eSMichal Miroslaw */ 31271578a1eSMichal Miroslaw max_dtr = 50000000; 31371578a1eSMichal Miroslaw } else { 31471578a1eSMichal Miroslaw max_dtr = card->cis.max_dtr; 31571578a1eSMichal Miroslaw } 31671578a1eSMichal Miroslaw 3177310ece8SMichal Miroslaw if (card->type == MMC_TYPE_SD_COMBO) 3187310ece8SMichal Miroslaw max_dtr = min(max_dtr, mmc_sd_get_max_clock(card)); 3197310ece8SMichal Miroslaw 32071578a1eSMichal Miroslaw return max_dtr; 321d16f5770SPierre Ossman } 322d16f5770SPierre Ossman 323d16f5770SPierre Ossman /* 32417d33e14SNicolas Pitre * Handle the detection and initialisation of a card. 32517d33e14SNicolas Pitre * 32617d33e14SNicolas Pitre * In the case of a resume, "oldcard" will contain the card 32717d33e14SNicolas Pitre * we're trying to reinitialise. 32817d33e14SNicolas Pitre */ 32917d33e14SNicolas Pitre static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, 3303bca4cf7SChris Ball struct mmc_card *oldcard, int powered_resume) 33117d33e14SNicolas Pitre { 33217d33e14SNicolas Pitre struct mmc_card *card; 33317d33e14SNicolas Pitre int err; 33417d33e14SNicolas Pitre 33517d33e14SNicolas Pitre BUG_ON(!host); 33617d33e14SNicolas Pitre WARN_ON(!host->claimed); 33717d33e14SNicolas Pitre 33817d33e14SNicolas Pitre /* 33917d33e14SNicolas Pitre * Inform the card of the voltage 34017d33e14SNicolas Pitre */ 3413bca4cf7SChris Ball if (!powered_resume) { 34217d33e14SNicolas Pitre err = mmc_send_io_op_cond(host, host->ocr, &ocr); 34317d33e14SNicolas Pitre if (err) 34417d33e14SNicolas Pitre goto err; 3453bca4cf7SChris Ball } 34617d33e14SNicolas Pitre 34717d33e14SNicolas Pitre /* 34817d33e14SNicolas Pitre * For SPI, enable CRC as appropriate. 34917d33e14SNicolas Pitre */ 35017d33e14SNicolas Pitre if (mmc_host_is_spi(host)) { 35117d33e14SNicolas Pitre err = mmc_spi_set_crc(host, use_spi_crc); 35217d33e14SNicolas Pitre if (err) 35317d33e14SNicolas Pitre goto err; 35417d33e14SNicolas Pitre } 35517d33e14SNicolas Pitre 35617d33e14SNicolas Pitre /* 35717d33e14SNicolas Pitre * Allocate card structure. 35817d33e14SNicolas Pitre */ 35917d33e14SNicolas Pitre card = mmc_alloc_card(host, NULL); 36017d33e14SNicolas Pitre if (IS_ERR(card)) { 36117d33e14SNicolas Pitre err = PTR_ERR(card); 36217d33e14SNicolas Pitre goto err; 36317d33e14SNicolas Pitre } 36417d33e14SNicolas Pitre 3657310ece8SMichal Miroslaw err = mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid); 3667310ece8SMichal Miroslaw 3677310ece8SMichal Miroslaw if (!err) { 3687310ece8SMichal Miroslaw card->type = MMC_TYPE_SD_COMBO; 3697310ece8SMichal Miroslaw 3707310ece8SMichal Miroslaw if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO || 3717310ece8SMichal Miroslaw memcmp(card->raw_cid, oldcard->raw_cid, sizeof(card->raw_cid)) != 0)) { 3727310ece8SMichal Miroslaw mmc_remove_card(card); 3737310ece8SMichal Miroslaw return -ENOENT; 3747310ece8SMichal Miroslaw } 3757310ece8SMichal Miroslaw } else { 37617d33e14SNicolas Pitre card->type = MMC_TYPE_SDIO; 37717d33e14SNicolas Pitre 3787310ece8SMichal Miroslaw if (oldcard && oldcard->type != MMC_TYPE_SDIO) { 3797310ece8SMichal Miroslaw mmc_remove_card(card); 3807310ece8SMichal Miroslaw return -ENOENT; 3817310ece8SMichal Miroslaw } 3827310ece8SMichal Miroslaw } 3837310ece8SMichal Miroslaw 38417d33e14SNicolas Pitre /* 3853fcb027dSDaniel Mack * Call the optional HC's init_card function to handle quirks. 3863fcb027dSDaniel Mack */ 3873fcb027dSDaniel Mack if (host->ops->init_card) 3883fcb027dSDaniel Mack host->ops->init_card(host, card); 3893fcb027dSDaniel Mack 3903fcb027dSDaniel Mack /* 39117d33e14SNicolas Pitre * For native busses: set card RCA and quit open drain mode. 39217d33e14SNicolas Pitre */ 3933bca4cf7SChris Ball if (!powered_resume && !mmc_host_is_spi(host)) { 39417d33e14SNicolas Pitre err = mmc_send_relative_addr(host, &card->rca); 39517d33e14SNicolas Pitre if (err) 39617d33e14SNicolas Pitre goto remove; 39717d33e14SNicolas Pitre 39817d33e14SNicolas Pitre mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); 39917d33e14SNicolas Pitre } 40017d33e14SNicolas Pitre 40117d33e14SNicolas Pitre /* 4027310ece8SMichal Miroslaw * Read CSD, before selecting the card 4037310ece8SMichal Miroslaw */ 4047310ece8SMichal Miroslaw if (!oldcard && card->type == MMC_TYPE_SD_COMBO) { 4057310ece8SMichal Miroslaw err = mmc_sd_get_csd(host, card); 4067310ece8SMichal Miroslaw if (err) 4077310ece8SMichal Miroslaw return err; 4087310ece8SMichal Miroslaw 4097310ece8SMichal Miroslaw mmc_decode_cid(card); 4107310ece8SMichal Miroslaw } 4117310ece8SMichal Miroslaw 4127310ece8SMichal Miroslaw /* 41317d33e14SNicolas Pitre * Select card, as all following commands rely on that. 41417d33e14SNicolas Pitre */ 4153bca4cf7SChris Ball if (!powered_resume && !mmc_host_is_spi(host)) { 41617d33e14SNicolas Pitre err = mmc_select_card(card); 41717d33e14SNicolas Pitre if (err) 41817d33e14SNicolas Pitre goto remove; 41917d33e14SNicolas Pitre } 42017d33e14SNicolas Pitre 421*6f51be3dSGrazvydas Ignotas if (card->quirks & MMC_QUIRK_NONSTD_SDIO) { 422*6f51be3dSGrazvydas Ignotas /* 423*6f51be3dSGrazvydas Ignotas * This is non-standard SDIO device, meaning it doesn't 424*6f51be3dSGrazvydas Ignotas * have any CIA (Common I/O area) registers present. 425*6f51be3dSGrazvydas Ignotas * It's host's responsibility to fill cccr and cis 426*6f51be3dSGrazvydas Ignotas * structures in init_card(). 427*6f51be3dSGrazvydas Ignotas */ 428*6f51be3dSGrazvydas Ignotas mmc_set_clock(host, card->cis.max_dtr); 429*6f51be3dSGrazvydas Ignotas 430*6f51be3dSGrazvydas Ignotas if (card->cccr.high_speed) { 431*6f51be3dSGrazvydas Ignotas mmc_card_set_highspeed(card); 432*6f51be3dSGrazvydas Ignotas mmc_set_timing(card->host, MMC_TIMING_SD_HS); 433*6f51be3dSGrazvydas Ignotas } 434*6f51be3dSGrazvydas Ignotas 435*6f51be3dSGrazvydas Ignotas goto finish; 436*6f51be3dSGrazvydas Ignotas } 437*6f51be3dSGrazvydas Ignotas 43817d33e14SNicolas Pitre /* 43917d33e14SNicolas Pitre * Read the common registers. 44017d33e14SNicolas Pitre */ 44117d33e14SNicolas Pitre err = sdio_read_cccr(card); 44217d33e14SNicolas Pitre if (err) 44317d33e14SNicolas Pitre goto remove; 44417d33e14SNicolas Pitre 44517d33e14SNicolas Pitre /* 44617d33e14SNicolas Pitre * Read the common CIS tuples. 44717d33e14SNicolas Pitre */ 44817d33e14SNicolas Pitre err = sdio_read_common_cis(card); 44917d33e14SNicolas Pitre if (err) 45017d33e14SNicolas Pitre goto remove; 45117d33e14SNicolas Pitre 45217d33e14SNicolas Pitre if (oldcard) { 45317d33e14SNicolas Pitre int same = (card->cis.vendor == oldcard->cis.vendor && 45417d33e14SNicolas Pitre card->cis.device == oldcard->cis.device); 45517d33e14SNicolas Pitre mmc_remove_card(card); 4567310ece8SMichal Miroslaw if (!same) 4577310ece8SMichal Miroslaw return -ENOENT; 4587310ece8SMichal Miroslaw 45917d33e14SNicolas Pitre card = oldcard; 46095cdfb72SNicolas Pitre return 0; 46117d33e14SNicolas Pitre } 46217d33e14SNicolas Pitre 4637310ece8SMichal Miroslaw if (card->type == MMC_TYPE_SD_COMBO) { 4647310ece8SMichal Miroslaw err = mmc_sd_setup_card(host, card, oldcard != NULL); 4657310ece8SMichal Miroslaw /* handle as SDIO-only card if memory init failed */ 4667310ece8SMichal Miroslaw if (err) { 4677310ece8SMichal Miroslaw mmc_go_idle(host); 4687310ece8SMichal Miroslaw if (mmc_host_is_spi(host)) 4697310ece8SMichal Miroslaw /* should not fail, as it worked previously */ 4707310ece8SMichal Miroslaw mmc_spi_set_crc(host, use_spi_crc); 4717310ece8SMichal Miroslaw card->type = MMC_TYPE_SDIO; 4727310ece8SMichal Miroslaw } else 4737310ece8SMichal Miroslaw card->dev.type = &sd_type; 4747310ece8SMichal Miroslaw } 4757310ece8SMichal Miroslaw 4767310ece8SMichal Miroslaw /* 4777310ece8SMichal Miroslaw * If needed, disconnect card detection pull-up resistor. 4787310ece8SMichal Miroslaw */ 4797310ece8SMichal Miroslaw err = sdio_disable_cd(card); 4807310ece8SMichal Miroslaw if (err) 4817310ece8SMichal Miroslaw goto remove; 4827310ece8SMichal Miroslaw 48317d33e14SNicolas Pitre /* 48417d33e14SNicolas Pitre * Switch to high-speed (if supported). 48517d33e14SNicolas Pitre */ 48617d33e14SNicolas Pitre err = sdio_enable_hs(card); 48771578a1eSMichal Miroslaw if (err > 0) 48871578a1eSMichal Miroslaw mmc_sd_go_highspeed(card); 48971578a1eSMichal Miroslaw else if (err) 49017d33e14SNicolas Pitre goto remove; 49117d33e14SNicolas Pitre 49217d33e14SNicolas Pitre /* 49317d33e14SNicolas Pitre * Change to the card's maximum speed. 49417d33e14SNicolas Pitre */ 49571578a1eSMichal Miroslaw mmc_set_clock(host, mmc_sdio_get_max_clock(card)); 49617d33e14SNicolas Pitre 49717d33e14SNicolas Pitre /* 49817d33e14SNicolas Pitre * Switch to wider bus (if supported). 49917d33e14SNicolas Pitre */ 5007310ece8SMichal Miroslaw err = sdio_enable_4bit_bus(card); 5017310ece8SMichal Miroslaw if (err > 0) 5027310ece8SMichal Miroslaw mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); 5037310ece8SMichal Miroslaw else if (err) 50417d33e14SNicolas Pitre goto remove; 50517d33e14SNicolas Pitre 506*6f51be3dSGrazvydas Ignotas finish: 50717d33e14SNicolas Pitre if (!oldcard) 50817d33e14SNicolas Pitre host->card = card; 50917d33e14SNicolas Pitre return 0; 51017d33e14SNicolas Pitre 51117d33e14SNicolas Pitre remove: 51217d33e14SNicolas Pitre if (!oldcard) 51317d33e14SNicolas Pitre mmc_remove_card(card); 51417d33e14SNicolas Pitre 51517d33e14SNicolas Pitre err: 51617d33e14SNicolas Pitre return err; 51717d33e14SNicolas Pitre } 51817d33e14SNicolas Pitre 51917d33e14SNicolas Pitre /* 5205c4e6f13SPierre Ossman * Host is being removed. Free up the current card. 5215c4e6f13SPierre Ossman */ 5225c4e6f13SPierre Ossman static void mmc_sdio_remove(struct mmc_host *host) 5235c4e6f13SPierre Ossman { 524e29a7d73SPierre Ossman int i; 525e29a7d73SPierre Ossman 5265c4e6f13SPierre Ossman BUG_ON(!host); 5275c4e6f13SPierre Ossman BUG_ON(!host->card); 5285c4e6f13SPierre Ossman 529e29a7d73SPierre Ossman for (i = 0;i < host->card->sdio_funcs;i++) { 530e29a7d73SPierre Ossman if (host->card->sdio_func[i]) { 531e29a7d73SPierre Ossman sdio_remove_func(host->card->sdio_func[i]); 532e29a7d73SPierre Ossman host->card->sdio_func[i] = NULL; 533e29a7d73SPierre Ossman } 534e29a7d73SPierre Ossman } 535e29a7d73SPierre Ossman 5365c4e6f13SPierre Ossman mmc_remove_card(host->card); 5375c4e6f13SPierre Ossman host->card = NULL; 5385c4e6f13SPierre Ossman } 5395c4e6f13SPierre Ossman 5405c4e6f13SPierre Ossman /* 5415c4e6f13SPierre Ossman * Card detection callback from host. 5425c4e6f13SPierre Ossman */ 5435c4e6f13SPierre Ossman static void mmc_sdio_detect(struct mmc_host *host) 5445c4e6f13SPierre Ossman { 5455c4e6f13SPierre Ossman int err; 5465c4e6f13SPierre Ossman 5475c4e6f13SPierre Ossman BUG_ON(!host); 5485c4e6f13SPierre Ossman BUG_ON(!host->card); 5495c4e6f13SPierre Ossman 5505c4e6f13SPierre Ossman mmc_claim_host(host); 5515c4e6f13SPierre Ossman 5525c4e6f13SPierre Ossman /* 5535c4e6f13SPierre Ossman * Just check if our card has been removed. 5545c4e6f13SPierre Ossman */ 5555c4e6f13SPierre Ossman err = mmc_select_card(host->card); 5565c4e6f13SPierre Ossman 5575c4e6f13SPierre Ossman mmc_release_host(host); 5585c4e6f13SPierre Ossman 5595c4e6f13SPierre Ossman if (err) { 5605c4e6f13SPierre Ossman mmc_sdio_remove(host); 5615c4e6f13SPierre Ossman 5625c4e6f13SPierre Ossman mmc_claim_host(host); 5635c4e6f13SPierre Ossman mmc_detach_bus(host); 5645c4e6f13SPierre Ossman mmc_release_host(host); 5655c4e6f13SPierre Ossman } 5665c4e6f13SPierre Ossman } 5675c4e6f13SPierre Ossman 56817d33e14SNicolas Pitre /* 56917d33e14SNicolas Pitre * SDIO suspend. We need to suspend all functions separately. 57017d33e14SNicolas Pitre * Therefore all registered functions must have drivers with suspend 57117d33e14SNicolas Pitre * and resume methods. Failing that we simply remove the whole card. 57217d33e14SNicolas Pitre */ 57395cdfb72SNicolas Pitre static int mmc_sdio_suspend(struct mmc_host *host) 57417d33e14SNicolas Pitre { 57595cdfb72SNicolas Pitre int i, err = 0; 57617d33e14SNicolas Pitre 57717d33e14SNicolas Pitre for (i = 0; i < host->card->sdio_funcs; i++) { 57817d33e14SNicolas Pitre struct sdio_func *func = host->card->sdio_func[i]; 57917d33e14SNicolas Pitre if (func && sdio_func_present(func) && func->dev.driver) { 58017d33e14SNicolas Pitre const struct dev_pm_ops *pmops = func->dev.driver->pm; 58117d33e14SNicolas Pitre if (!pmops || !pmops->suspend || !pmops->resume) { 58295cdfb72SNicolas Pitre /* force removal of entire card in that case */ 58395cdfb72SNicolas Pitre err = -ENOSYS; 58495cdfb72SNicolas Pitre } else 58595cdfb72SNicolas Pitre err = pmops->suspend(&func->dev); 58695cdfb72SNicolas Pitre if (err) 58795cdfb72SNicolas Pitre break; 58817d33e14SNicolas Pitre } 58917d33e14SNicolas Pitre } 59095cdfb72SNicolas Pitre while (err && --i >= 0) { 59117d33e14SNicolas Pitre struct sdio_func *func = host->card->sdio_func[i]; 59217d33e14SNicolas Pitre if (func && sdio_func_present(func) && func->dev.driver) { 59317d33e14SNicolas Pitre const struct dev_pm_ops *pmops = func->dev.driver->pm; 59417d33e14SNicolas Pitre pmops->resume(&func->dev); 59517d33e14SNicolas Pitre } 59617d33e14SNicolas Pitre } 59795cdfb72SNicolas Pitre 5986b5eda36SDaniel Drake if (!err && host->pm_flags & MMC_PM_KEEP_POWER) { 5996b5eda36SDaniel Drake mmc_claim_host(host); 6006b5eda36SDaniel Drake sdio_disable_wide(host->card); 6016b5eda36SDaniel Drake mmc_release_host(host); 6026b5eda36SDaniel Drake } 6036b5eda36SDaniel Drake 60495cdfb72SNicolas Pitre return err; 60595cdfb72SNicolas Pitre } 60695cdfb72SNicolas Pitre 60795cdfb72SNicolas Pitre static int mmc_sdio_resume(struct mmc_host *host) 60895cdfb72SNicolas Pitre { 60995cdfb72SNicolas Pitre int i, err; 61095cdfb72SNicolas Pitre 61195cdfb72SNicolas Pitre BUG_ON(!host); 61295cdfb72SNicolas Pitre BUG_ON(!host->card); 61395cdfb72SNicolas Pitre 61495cdfb72SNicolas Pitre /* Basic card reinitialization. */ 61595cdfb72SNicolas Pitre mmc_claim_host(host); 6163bca4cf7SChris Ball err = mmc_sdio_init_card(host, host->ocr, host->card, 6173bca4cf7SChris Ball (host->pm_flags & MMC_PM_KEEP_POWER)); 6187310ece8SMichal Miroslaw if (!err) { 6196b5eda36SDaniel Drake /* We may have switched to 1-bit mode during suspend. */ 6207310ece8SMichal Miroslaw err = sdio_enable_4bit_bus(host->card); 6217310ece8SMichal Miroslaw if (err > 0) { 6227310ece8SMichal Miroslaw mmc_set_bus_width(host, MMC_BUS_WIDTH_4); 6237310ece8SMichal Miroslaw err = 0; 6247310ece8SMichal Miroslaw } 6257310ece8SMichal Miroslaw } 62640216842SNicolas Pitre if (!err && host->sdio_irqs) 62740216842SNicolas Pitre mmc_signal_sdio_irq(host); 62895cdfb72SNicolas Pitre mmc_release_host(host); 62995cdfb72SNicolas Pitre 63095cdfb72SNicolas Pitre /* 63195cdfb72SNicolas Pitre * If the card looked to be the same as before suspending, then 63295cdfb72SNicolas Pitre * we proceed to resume all card functions. If one of them returns 63395cdfb72SNicolas Pitre * an error then we simply return that error to the core and the 63495cdfb72SNicolas Pitre * card will be redetected as new. It is the responsibility of 63595cdfb72SNicolas Pitre * the function driver to perform further tests with the extra 63695cdfb72SNicolas Pitre * knowledge it has of the card to confirm the card is indeed the 63795cdfb72SNicolas Pitre * same as before suspending (same MAC address for network cards, 63895cdfb72SNicolas Pitre * etc.) and return an error otherwise. 63995cdfb72SNicolas Pitre */ 64095cdfb72SNicolas Pitre for (i = 0; !err && i < host->card->sdio_funcs; i++) { 64195cdfb72SNicolas Pitre struct sdio_func *func = host->card->sdio_func[i]; 64295cdfb72SNicolas Pitre if (func && sdio_func_present(func) && func->dev.driver) { 64395cdfb72SNicolas Pitre const struct dev_pm_ops *pmops = func->dev.driver->pm; 64495cdfb72SNicolas Pitre err = pmops->resume(&func->dev); 64595cdfb72SNicolas Pitre } 64695cdfb72SNicolas Pitre } 64795cdfb72SNicolas Pitre 64895cdfb72SNicolas Pitre return err; 64917d33e14SNicolas Pitre } 6505c4e6f13SPierre Ossman 6515c4e6f13SPierre Ossman static const struct mmc_bus_ops mmc_sdio_ops = { 6525c4e6f13SPierre Ossman .remove = mmc_sdio_remove, 6535c4e6f13SPierre Ossman .detect = mmc_sdio_detect, 65417d33e14SNicolas Pitre .suspend = mmc_sdio_suspend, 65517d33e14SNicolas Pitre .resume = mmc_sdio_resume, 6565c4e6f13SPierre Ossman }; 6575c4e6f13SPierre Ossman 6585c4e6f13SPierre Ossman 6595c4e6f13SPierre Ossman /* 6605c4e6f13SPierre Ossman * Starting point for SDIO card init. 6615c4e6f13SPierre Ossman */ 6625c4e6f13SPierre Ossman int mmc_attach_sdio(struct mmc_host *host, u32 ocr) 6635c4e6f13SPierre Ossman { 6645c4e6f13SPierre Ossman int err; 665e29a7d73SPierre Ossman int i, funcs; 6665c4e6f13SPierre Ossman struct mmc_card *card; 6675c4e6f13SPierre Ossman 6685c4e6f13SPierre Ossman BUG_ON(!host); 669d84075c8SPierre Ossman WARN_ON(!host->claimed); 6705c4e6f13SPierre Ossman 6715c4e6f13SPierre Ossman mmc_attach_bus(host, &mmc_sdio_ops); 6725c4e6f13SPierre Ossman 6735c4e6f13SPierre Ossman /* 6745c4e6f13SPierre Ossman * Sanity check the voltages that the card claims to 6755c4e6f13SPierre Ossman * support. 6765c4e6f13SPierre Ossman */ 6775c4e6f13SPierre Ossman if (ocr & 0x7F) { 6785c4e6f13SPierre Ossman printk(KERN_WARNING "%s: card claims to support voltages " 6795c4e6f13SPierre Ossman "below the defined range. These will be ignored.\n", 6805c4e6f13SPierre Ossman mmc_hostname(host)); 6815c4e6f13SPierre Ossman ocr &= ~0x7F; 6825c4e6f13SPierre Ossman } 6835c4e6f13SPierre Ossman 6845c4e6f13SPierre Ossman host->ocr = mmc_select_voltage(host, ocr); 6855c4e6f13SPierre Ossman 6865c4e6f13SPierre Ossman /* 6875c4e6f13SPierre Ossman * Can we support the voltage(s) of the card(s)? 6885c4e6f13SPierre Ossman */ 6895c4e6f13SPierre Ossman if (!host->ocr) { 6905c4e6f13SPierre Ossman err = -EINVAL; 6915c4e6f13SPierre Ossman goto err; 6925c4e6f13SPierre Ossman } 6935c4e6f13SPierre Ossman 6945c4e6f13SPierre Ossman /* 69517d33e14SNicolas Pitre * Detect and init the card. 6965c4e6f13SPierre Ossman */ 6973bca4cf7SChris Ball err = mmc_sdio_init_card(host, host->ocr, NULL, 0); 6985c4e6f13SPierre Ossman if (err) 6995c4e6f13SPierre Ossman goto err; 70017d33e14SNicolas Pitre card = host->card; 701af517150SDavid Brownell 702af517150SDavid Brownell /* 7035c4e6f13SPierre Ossman * The number of functions on the card is encoded inside 7045c4e6f13SPierre Ossman * the ocr. 7055c4e6f13SPierre Ossman */ 706e8812793SMatt Fleming funcs = (ocr & 0x70000000) >> 28; 707e8812793SMatt Fleming card->sdio_funcs = 0; 7084ff6471cSPierre Ossman 7094ff6471cSPierre Ossman /* 710e29a7d73SPierre Ossman * Initialize (but don't add) all present functions. 711e29a7d73SPierre Ossman */ 712e8812793SMatt Fleming for (i = 0; i < funcs; i++, card->sdio_funcs++) { 713e29a7d73SPierre Ossman err = sdio_init_func(host->card, i + 1); 714e29a7d73SPierre Ossman if (err) 715e29a7d73SPierre Ossman goto remove; 716e29a7d73SPierre Ossman } 7175c4e6f13SPierre Ossman 7185c4e6f13SPierre Ossman mmc_release_host(host); 7195c4e6f13SPierre Ossman 720e29a7d73SPierre Ossman /* 721e29a7d73SPierre Ossman * First add the card to the driver model... 722e29a7d73SPierre Ossman */ 7235c4e6f13SPierre Ossman err = mmc_add_card(host->card); 7245c4e6f13SPierre Ossman if (err) 725e29a7d73SPierre Ossman goto remove_added; 726e29a7d73SPierre Ossman 727e29a7d73SPierre Ossman /* 728e29a7d73SPierre Ossman * ...then the SDIO functions. 729e29a7d73SPierre Ossman */ 730e29a7d73SPierre Ossman for (i = 0;i < funcs;i++) { 731e29a7d73SPierre Ossman err = sdio_add_func(host->card->sdio_func[i]); 732e29a7d73SPierre Ossman if (err) 733e29a7d73SPierre Ossman goto remove_added; 734e29a7d73SPierre Ossman } 7355c4e6f13SPierre Ossman 7365c4e6f13SPierre Ossman return 0; 7375c4e6f13SPierre Ossman 738e29a7d73SPierre Ossman 739e29a7d73SPierre Ossman remove_added: 740e29a7d73SPierre Ossman /* Remove without lock if the device has been added. */ 741e29a7d73SPierre Ossman mmc_sdio_remove(host); 7425c4e6f13SPierre Ossman mmc_claim_host(host); 743e29a7d73SPierre Ossman remove: 744e29a7d73SPierre Ossman /* And with lock if it hasn't been added. */ 745e29a7d73SPierre Ossman if (host->card) 746e29a7d73SPierre Ossman mmc_sdio_remove(host); 7475c4e6f13SPierre Ossman err: 7485c4e6f13SPierre Ossman mmc_detach_bus(host); 7495c4e6f13SPierre Ossman mmc_release_host(host); 7505c4e6f13SPierre Ossman 7515c4e6f13SPierre Ossman printk(KERN_ERR "%s: error %d whilst initialising SDIO card\n", 7525c4e6f13SPierre Ossman mmc_hostname(host), err); 7535c4e6f13SPierre Ossman 7545c4e6f13SPierre Ossman return err; 7555c4e6f13SPierre Ossman } 7565c4e6f13SPierre Ossman 757