From patchwork Wed Jan 23 15:32:38 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 2025501 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 802CC3FD86 for ; Wed, 23 Jan 2013 15:40:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756224Ab3AWPkV (ORCPT ); Wed, 23 Jan 2013 10:40:21 -0500 Received: from moutng.kundenserver.de ([212.227.17.10]:59173 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755880Ab3AWPkS (ORCPT ); Wed, 23 Jan 2013 10:40:18 -0500 Received: from axis700.grange (dslb-178-006-250-035.pools.arcor-ip.net [178.6.250.35]) by mrelayeu.kundenserver.de (node=mreu2) with ESMTP (Nemesis) id 0LouSd-1UepNT2bnv-00gRl5; Wed, 23 Jan 2013 16:40:17 +0100 Received: from 6a.grange (6a.grange [192.168.1.11]) by axis700.grange (Postfix) with ESMTPS id E9FB840BC7; Wed, 23 Jan 2013 16:40:14 +0100 (CET) Received: from lyakh by 6a.grange with local (Exim 4.72) (envelope-from ) id 1Ty2Qw-0000Q4-OG; Wed, 23 Jan 2013 16:40:14 +0100 From: Guennadi Liakhovetski To: linux-mmc@vger.kernel.org Cc: linux-sh@vger.kernel.org, Magnus Damm , Chris Ball , Guennadi Liakhovetski Subject: [PATCH v2 11/11] mmc: tmio: add support for the VccQ regulator Date: Wed, 23 Jan 2013 16:32:38 +0100 Message-Id: <1358955158-1510-12-git-send-email-g.liakhovetski@gmx.de> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1358955158-1510-1-git-send-email-g.liakhovetski@gmx.de> References: <1358955158-1510-1-git-send-email-g.liakhovetski@gmx.de> X-Provags-ID: V02:K0:8Ee62YHjPdEXhygnlREhzs5H3M1fNpxVeOOaderz+wp +A61itQewiqs0+7+djYWlw0AwrkxHfiql1ID2MWamqATtLmRQF H9Sh8lwxlqT59E8Ox8eeUiQ+YPtGFBheU3mOJhGDmarL76Vpr3 Z4iH17mpsj8nWB7ejJl3MddSWQ4QOc7eXoEpZDcA14Kq4oG8/3 F0BF7INCws2ur52kQGzPwkQKYBo7XqbiMLLcgBWNIoSy8Pmb97 tJnO3T31RCNIHoLlalOlM5UgfY6C5j4pfdWPkcFCpQzoj2SVSS Oni0THCVOo1rlhmJC3p+Ob98FZFdj9kJUy6Rezy1Tp5KxDcsL3 bBitBU6aiP+FwyCZ4M4NmqeOvG0++kIE/IfFhF/kc1kpP6Rvzp HVQqVpSJj35Qw== 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 --- v2: 1. delays are necessary for reliable SDIO card probing 2. balance calls to tmio_mmc_power_on() and tmio_mmc_power_off() 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 13729b6..cd3b777 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);