From patchwork Wed Jan 16 16:54:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 1991841 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 3D9F0DF2A2 for ; Wed, 16 Jan 2013 16:55:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757905Ab3APQyy (ORCPT ); Wed, 16 Jan 2013 11:54:54 -0500 Received: from moutng.kundenserver.de ([212.227.126.187]:56746 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757949Ab3APQyu (ORCPT ); Wed, 16 Jan 2013 11:54:50 -0500 Received: from axis700.grange (dslb-178-006-255-053.pools.arcor-ip.net [178.6.255.53]) by mrelayeu.kundenserver.de (node=mreu3) with ESMTP (Nemesis) id 0M9AKX-1To7kL2cyT-00CQPc; Wed, 16 Jan 2013 17:54:48 +0100 Received: from 6a.grange (6a.grange [192.168.1.11]) by axis700.grange (Postfix) with ESMTPS id 6B1FF40BC5; Wed, 16 Jan 2013 17:54:47 +0100 (CET) Received: from lyakh by 6a.grange with local (Exim 4.72) (envelope-from ) id 1TvWGF-0006my-6i; Wed, 16 Jan 2013 17:54:47 +0100 From: Guennadi Liakhovetski To: linux-mmc@vger.kernel.org Cc: linux-sh@vger.kernel.org, Magnus Damm Subject: [PATCH 11/11] mmc: tmio: add support for the VccQ regulator Date: Wed, 16 Jan 2013 17:54:46 +0100 Message-Id: <1358355286-26029-12-git-send-email-g.liakhovetski@gmx.de> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1358355286-26029-1-git-send-email-g.liakhovetski@gmx.de> References: <1358355286-26029-1-git-send-email-g.liakhovetski@gmx.de> X-Provags-ID: V02:K0:+d3OFkdONL38oe4Q+rKzVMCSp8CZvRRciKnGhxr08tK T5OaueOGSAiz3nyMA7RvLauAmctprHae7v/0HvyIOGyT2p1y2v 4OdbrRIlHJ3a1Lv15koKWChTzCC3oSU6BrD+6LTVH0ilbHG/Je X04KN51fv+sPG6b/8QEC4a8S8llBkcY3w5823U0c6JirTOpeUT jahxNeQ8leQTLqtQ5NELD9M+xFEFTuP7g8ObxEy9ViwlRSzPCc biezkScarEmbjdmI047gvcjh9WwLtYHkfKLpUgK6FydZrew+n7 mE5Kuvb0OW23s5IHaDOYKzdgbany7BicquU3gBNaUy07RHnvPU 44/a136mdcd3Ce/dg98LLR5DuE+24s9ZoadjUhsh972RXxJl4n 3kIxTTfc0X4Fg== 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 | 40 +++++++++++++++++++++++++++++++------- 1 files changed, 32 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 84582b3..932579c 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 @@ -768,16 +769,39 @@ 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); + + /* + * It seems, VccQ should be switch 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); +} + +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. @@ -831,13 +855,13 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->power = true; } tmio_mmc_set_clock(host, ios->clock); - /* power up SD bus */ - tmio_mmc_set_power(host, ios); + /* power up SD card and the bus */ + tmio_mmc_power_on(host, ios->vdd); /* 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); + tmio_mmc_power_off(host); if (host->power) { struct tmio_mmc_data *pdata = host->pdata; tmio_mmc_clk_stop(host);