From patchwork Fri Feb 15 15:14:00 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 2148421 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id EE6C73FE80 for ; Fri, 15 Feb 2013 15:14:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933005Ab3BOPOU (ORCPT ); Fri, 15 Feb 2013 10:14:20 -0500 Received: from moutng.kundenserver.de ([212.227.126.171]:54855 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759267Ab3BOPOS (ORCPT ); Fri, 15 Feb 2013 10:14:18 -0500 Received: from axis700.grange (dslb-188-109-033-039.pools.arcor-ip.net [188.109.33.39]) by mrelayeu.kundenserver.de (node=mrbap1) with ESMTP (Nemesis) id 0MLR0k-1U5p1a2lko-000lCJ; Fri, 15 Feb 2013 16:14:13 +0100 Received: from 6a.grange (6a.grange [192.168.1.11]) by axis700.grange (Postfix) with ESMTPS id 65EA540BC7; Fri, 15 Feb 2013 16:14:10 +0100 (CET) Received: from lyakh by 6a.grange with local (Exim 4.72) (envelope-from ) id 1U6MzK-0004k3-6h; Fri, 15 Feb 2013 16:14:10 +0100 From: Guennadi Liakhovetski To: linux-mmc@vger.kernel.org Cc: devicetree-discuss@lists.ozlabs.org, linux-sh@vger.kernel.org, Magnus Damm , Simon Horman , Arnd Bergmann , Guennadi Liakhovetski Subject: [PATCH v4 11/13] mmc: tmio: add support for the VccQ regulator Date: Fri, 15 Feb 2013 16:14:00 +0100 Message-Id: <1360941242-18153-12-git-send-email-g.liakhovetski@gmx.de> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1360941242-18153-1-git-send-email-g.liakhovetski@gmx.de> References: <1360941242-18153-1-git-send-email-g.liakhovetski@gmx.de> X-Provags-ID: V02:K0:9pr8glwTY4d+nCrJZ4Lv6mXGKDQ+4tw9WQxRbIx3+zl NAVYNJ1igbN5Pc09CsjD03qnTk/85BHevEPFc4h0qUM9urWxSw DjcwJKNf30HPoaX/R5Si9mX4BcxRbFSEivjWeguLF23z6MzOZ3 k85OA/2BBe90eWgxZ3W1IrdTtRnGcWtnO30jqflenHDE40C+G3 HGV2e27t14TjnAOa6/Z09xu4IWLSzH9yC+0B5UJG97yw8uMP52 MeW19RH5OawY9QEam/fNwg2ot3qnq7maSfpG7yu8dJ1zZMSjvM iq7gp9ucJAfItROZ/5ZDZtOVQSzCOxMlKq3HKBillsqrTCgUQP xdu6flcVLXoSpMEvrqEND9uUEOY4Wgxv/nMPG5T2pl9x7Yig3D 1Ckc16qQXJIRygser2821ar1UwfVh2/2EI= Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Some SD/MMC interfaces use 2 power regulators: one to power the card itself (Vcc) and another one to pull signal lines up (VccQ). In case of eMMC and UHS SD cards the regulators also have to be configured to supply different voltages. The preferred order of turning supply power on and off is to turn Vcc first on and last off. Signed-off-by: Guennadi Liakhovetski --- drivers/mmc/host/tmio_mmc_pio.c | 56 ++++++++++++++++++++++++++++++++------- 1 files changed, 46 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index e5b3fcf..f508ecb 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -155,6 +156,7 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock) host->set_clk_div(host->pdev, (clk>>22) & 1); sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff); + msleep(10); } static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) @@ -768,16 +770,48 @@ static int tmio_mmc_clk_update(struct mmc_host *mmc) return ret; } -static void tmio_mmc_set_power(struct tmio_mmc_host *host, struct mmc_ios *ios) +static void tmio_mmc_power_on(struct tmio_mmc_host *host, unsigned short vdd) { struct mmc_host *mmc = host->mmc; + int ret = 0; + + /* .set_ios() is returning void, so, no chance to report an error */ if (host->set_pwr) - host->set_pwr(host->pdev, ios->power_mode != MMC_POWER_OFF); + host->set_pwr(host->pdev, 1); + + if (!IS_ERR(mmc->supply.vmmc)) { + ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); + /* + * Attention: empiric value. With a b43 WiFi SDIO card this + * delay proved necessary for reliable card-insertion probing. + * 100us were not enough. Is this the same 140us delay, as in + * tmio_mmc_set_ios()? + */ + udelay(200); + } + /* + * It seems, VccQ should be switched on after Vcc, this is also what the + * omap_hsmmc.c driver does. + */ + if (!IS_ERR(mmc->supply.vqmmc) && !ret) { + regulator_enable(mmc->supply.vqmmc); + udelay(200); + } +} + +static void tmio_mmc_power_off(struct tmio_mmc_host *host) +{ + struct mmc_host *mmc = host->mmc; + + if (!IS_ERR(mmc->supply.vqmmc)) + regulator_disable(mmc->supply.vqmmc); + if (!IS_ERR(mmc->supply.vmmc)) - /* Errors ignored... */ - mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, - ios->power_mode ? ios->vdd : 0); + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); + + if (host->set_pwr) + host->set_pwr(host->pdev, 0); } /* Set MMC clock / power. @@ -828,18 +862,20 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (!host->power) { tmio_mmc_clk_update(mmc); pm_runtime_get_sync(dev); - host->power = true; } tmio_mmc_set_clock(host, ios->clock); - /* power up SD bus */ - tmio_mmc_set_power(host, ios); + if (!host->power) { + /* power up SD card and the bus */ + tmio_mmc_power_on(host, ios->vdd); + host->power = true; + } /* start bus clock */ tmio_mmc_clk_start(host); } else if (ios->power_mode != MMC_POWER_UP) { - if (ios->power_mode == MMC_POWER_OFF) - tmio_mmc_set_power(host, ios); if (host->power) { struct tmio_mmc_data *pdata = host->pdata; + if (ios->power_mode == MMC_POWER_OFF) + tmio_mmc_power_off(host); tmio_mmc_clk_stop(host); host->power = false; pm_runtime_put(dev);