From patchwork Thu Apr 21 12:27:53 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Ospite X-Patchwork-Id: 724651 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p3LCQfXo019375 for ; Thu, 21 Apr 2011 12:28:05 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753416Ab1DUM2E (ORCPT ); Thu, 21 Apr 2011 08:28:04 -0400 Received: from smtp204.alice.it ([82.57.200.100]:58234 "EHLO smtp204.alice.it" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752121Ab1DUM2D (ORCPT ); Thu, 21 Apr 2011 08:28:03 -0400 Received: from jcn (87.3.13.82) by smtp204.alice.it (8.5.124.08) id 4D7E0F64034F733A; Thu, 21 Apr 2011 14:28:01 +0200 Received: from ao2 by jcn with local (Exim 4.75) (envelope-from ) id 1QCszH-00042E-Tt; Thu, 21 Apr 2011 14:27:59 +0200 From: Antonio Ospite To: linux-mmc@vger.kernel.org Cc: Antonio Ospite , Chris Ball , Grant Likely , Mark Brown , openezx-devel@lists.openezx.org, spi-devel-general@lists.sourceforge.net Subject: [RESEND PATCH 4/4] mmc_spi.c: add support for the regulator framework Date: Thu, 21 Apr 2011 14:27:53 +0200 Message-Id: <1303388873-15467-5-git-send-email-ospite@studenti.unina.it> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1303388873-15467-1-git-send-email-ospite@studenti.unina.it> References: <1300733202-27316-1-git-send-email-ospite@studenti.unina.it> <1303388873-15467-1-git-send-email-ospite@studenti.unina.it> X-Face: z*RaLf`X<@C75u6Ig9}{oW$H; 1_\2t5)({*|jhM/Vb; ]yA5\I~93>J<_`<4)A{':UrE Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 21 Apr 2011 12:28:05 +0000 (UTC) Add support for powering up SD cards driven by regulators. This makes the mmc_spi driver work also with the Motorola A910 phone. Signed-off-by: Antonio Ospite --- drivers/mmc/host/mmc_spi.c | 61 +++++++++++++++++++++++++++++++++++-------- 1 files changed, 49 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 0f3672d..acc2ec8 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -150,11 +151,13 @@ struct mmc_spi_host { */ void *ones; dma_addr_t ones_dma; + + struct regulator *vcc; }; static inline int mmc_spi_canpower(struct mmc_spi_host *host) { - return host->pdata && host->pdata->setpower; + return (host->pdata && host->pdata->setpower) || host->vcc; } /****************************************************************************/ @@ -1225,17 +1228,35 @@ static inline int mmc_spi_setpower(struct mmc_spi_host *host, unsigned char power_mode, unsigned int vdd) { + if (!mmc_spi_canpower(host)) + return -ENOSYS; + /* switch power on/off if possible, accounting for * max 250msec powerup time if needed. */ - if (mmc_spi_canpower(host)) { - switch (power_mode) { - case MMC_POWER_OFF: - case MMC_POWER_UP: + switch (power_mode) { + case MMC_POWER_OFF: + if (host->vcc) { + int ret = mmc_regulator_set_ocr(host->mmc, + host->vcc, 0); + if (ret) + return ret; + } else { + host->pdata->setpower(&host->spi->dev, vdd); + } + break; + + case MMC_POWER_UP: + if (host->vcc) { + int ret = mmc_regulator_set_ocr(host->mmc, + host->vcc, vdd); + if (ret) + return ret; + } else { host->pdata->setpower(&host->spi->dev, vdd); - if (power_mode == MMC_POWER_UP) - msleep(host->powerup_msecs); } + msleep(host->powerup_msecs); + break; } return 0; @@ -1420,12 +1441,28 @@ static int mmc_spi_probe(struct spi_device *spi) * and power switching gpios. */ host->pdata = mmc_spi_get_pdata(spi); - if (host->pdata) - mmc->ocr_avail = host->pdata->ocr_mask; - if (!mmc->ocr_avail) { - dev_warn(&spi->dev, "ASSUMING 3.2-3.4 V slot power\n"); - mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; +#ifdef CONFIG_REGULATOR + host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc"); + + if (IS_ERR(host->vcc)) { + host->vcc = NULL; + } else { + host->mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vcc); + if (host->pdata && host->pdata->ocr_mask) + dev_warn(mmc_dev(host->mmc), + "ocr_mask/setpower will not be used\n"); } +#endif + if (host->vcc == NULL) { + /* fall-back to platform data */ + if (host->pdata) + mmc->ocr_avail = host->pdata->ocr_mask; + if (!mmc->ocr_avail) { + dev_warn(&spi->dev, "ASSUMING 3.2-3.4 V slot power\n"); + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + } + } + if (mmc_spi_canpower(host)) { host->powerup_msecs = host->pdata->powerup_msecs; if (!host->powerup_msecs || host->powerup_msecs > 250)