{"id":816933,"url":"http://patchwork.ozlabs.org/api/patches/816933/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/patch/1506006190-9498-3-git-send-email-jjhiblot@ti.com/","project":{"id":18,"url":"http://patchwork.ozlabs.org/api/projects/18/?format=json","name":"U-Boot","link_name":"uboot","list_id":"u-boot.lists.denx.de","list_email":"u-boot@lists.denx.de","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<1506006190-9498-3-git-send-email-jjhiblot@ti.com>","list_archive_url":null,"date":"2017-09-21T15:03:10","name":"[U-Boot,v3,2/2] regulator: pbias: Add PBIAS regulator for proper voltage switching on MMC1","commit_ref":"8ff7763d62d09c541e398239b7e4e3a5e732d273","pull_url":null,"state":"accepted","archived":false,"hash":"3ff3d11f8b625ad1523effd486a220685b69e546","submitter":{"id":70508,"url":"http://patchwork.ozlabs.org/api/people/70508/?format=json","name":"Jean-Jacques Hiblot","email":"jjhiblot@ti.com"},"delegate":{"id":12423,"url":"http://patchwork.ozlabs.org/api/users/12423/?format=json","username":"Jaehoon","first_name":"Jaehoon","last_name":"Chung","email":"jh80.chung@samsung.com"},"mbox":"http://patchwork.ozlabs.org/project/uboot/patch/1506006190-9498-3-git-send-email-jjhiblot@ti.com/mbox/","series":[{"id":4408,"url":"http://patchwork.ozlabs.org/api/series/4408/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/list/?series=4408","date":"2017-09-21T15:03:09","name":"power: Add a driver to handle the PBIAS cell of the TI SOCs","version":3,"mbox":"http://patchwork.ozlabs.org/series/4408/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/816933/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/816933/checks/","tags":{},"related":[],"headers":{"Return-Path":"<u-boot-bounces@lists.denx.de>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=lists.denx.de\n\t(client-ip=81.169.180.215; helo=lists.denx.de;\n\tenvelope-from=u-boot-bounces@lists.denx.de;\n\treceiver=<UNKNOWN>)","ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ti.com header.i=@ti.com header.b=\"y0QULPfb\";\n\tdkim-atps=neutral"],"Received":["from lists.denx.de (dione.denx.de [81.169.180.215])\n\tby ozlabs.org (Postfix) with ESMTP id 3xyfyd3FD5z9t3v\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 22 Sep 2017 01:04:09 +1000 (AEST)","by lists.denx.de (Postfix, from userid 105)\n\tid 34E57C22081; Thu, 21 Sep 2017 15:03:42 +0000 (UTC)","from lists.denx.de (localhost [IPv6:::1])\n\tby lists.denx.de (Postfix) with ESMTP id 844D8C21FFE;\n\tThu, 21 Sep 2017 15:03:20 +0000 (UTC)","by lists.denx.de (Postfix, from userid 105)\n\tid 19359C21FFE; Thu, 21 Sep 2017 15:03:18 +0000 (UTC)","from lelnx194.ext.ti.com (lelnx194.ext.ti.com [198.47.27.80])\n\tby lists.denx.de (Postfix) with ESMTPS id CF184C21C4E\n\tfor <u-boot@lists.denx.de>; Thu, 21 Sep 2017 15:03:16 +0000 (UTC)","from dlelxv90.itg.ti.com ([172.17.2.17])\n\tby lelnx194.ext.ti.com (8.15.1/8.15.1) with ESMTP id v8LF3E8C010399; \n\tThu, 21 Sep 2017 10:03:14 -0500","from DLEE101.ent.ti.com (dlee101.ent.ti.com [157.170.170.31])\n\tby dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id v8LF3Eef004641; \n\tThu, 21 Sep 2017 10:03:14 -0500","from DLEE103.ent.ti.com (157.170.170.33) by DLEE101.ent.ti.com\n\t(157.170.170.31) with Microsoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.1.845.34;\n\tThu, 21 Sep 2017 10:03:15 -0500","from dflp32.itg.ti.com (10.64.6.15) by DLEE103.ent.ti.com\n\t(157.170.170.33) with Microsoft SMTP Server (version=TLS1_0,\n\tcipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.845.34 via Frontend\n\tTransport; Thu, 21 Sep 2017 10:03:14 -0500","from localhost (ileax41-snat.itg.ti.com [10.172.224.153])\n\tby dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id v8LF3DMF026584;\n\tThu, 21 Sep 2017 10:03:14 -0500"],"X-Spam-Checker-Version":"SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de","X-Spam-Level":"","X-Spam-Status":"No, score=0.0 required=5.0 tests=RCVD_IN_DNSWL_NONE,\n\tT_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ti.com;\n\ts=ti-com-17Q1; t=1506006194;\n\tbh=/FawNG66+L9zzrUMeTzw1O9/0kpxlHFgwcmZyEp4FJA=;\n\th=From:To:CC:Subject:Date:In-Reply-To:References;\n\tb=y0QULPfboe7Nvjt4JXAMnTipsubEwJJNMBD6+MxE3ZIfEE9CagRn1Co+BTkmTDOZ8\n\tJCBAVAZQSu37lNwwLpK7Fp1qmMiDOVsdTbnulJEdr1xOdMD8RNKsx9FiOGpCJKEuyA\n\tmvfgJ2ykfFudAV7s3iXXwI3HnqbxveW55fDEr1Ao=","From":"Jean-Jacques Hiblot <jjhiblot@ti.com>","To":"<jh80.chung@samsung.com>, <trini@konsulko.com>, <kishon@ti.com>,\n\t<sjg@chromium.org>","Date":"Thu, 21 Sep 2017 17:03:10 +0200","Message-ID":"<1506006190-9498-3-git-send-email-jjhiblot@ti.com>","X-Mailer":"git-send-email 1.9.1","In-Reply-To":"<1506006190-9498-1-git-send-email-jjhiblot@ti.com>","References":"<1506006190-9498-1-git-send-email-jjhiblot@ti.com>","MIME-Version":"1.0","X-EXCLAIMER-MD-CONFIG":"e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180","Cc":"u-boot@lists.denx.de","Subject":"[U-Boot] [PATCH v3 2/2] regulator: pbias: Add PBIAS regulator for\n\tproper voltage switching on MMC1","X-BeenThere":"u-boot@lists.denx.de","X-Mailman-Version":"2.1.18","Precedence":"list","List-Id":"U-Boot discussion <u-boot.lists.denx.de>","List-Unsubscribe":"<https://lists.denx.de/options/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=unsubscribe>","List-Archive":"<http://lists.denx.de/pipermail/u-boot/>","List-Post":"<mailto:u-boot@lists.denx.de>","List-Help":"<mailto:u-boot-request@lists.denx.de?subject=help>","List-Subscribe":"<https://lists.denx.de/listinfo/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=subscribe>","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","Errors-To":"u-boot-bounces@lists.denx.de","Sender":"\"U-Boot\" <u-boot-bounces@lists.denx.de>"},"content":"In the TI SOCs a PBIAS cell exists to provide a bias voltage to the MMC1\nIO cells. Without this bias voltage these I/O cells can not function\nproperly. The PBIAS cell is controlled by software.\n\nSigned-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>\nReviewed-by: Tom Rini <trini@konsulko.com>\nReviewed-by: Simon Glass <sjg@chromium.org>\n---\n drivers/mmc/Kconfig                       |   1 +\n drivers/power/regulator/Kconfig           |  13 ++\n drivers/power/regulator/Makefile          |   1 +\n drivers/power/regulator/pbias_regulator.c | 301 ++++++++++++++++++++++++++++++\n 4 files changed, 316 insertions(+)\n create mode 100644 drivers/power/regulator/pbias_regulator.c","diff":"diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig\nindex 78e58d4..4b9bee0 100644\n--- a/drivers/mmc/Kconfig\n+++ b/drivers/mmc/Kconfig\n@@ -159,6 +159,7 @@ config MMC_PCI\n config MMC_OMAP_HS\n \tbool \"TI OMAP High Speed Multimedia Card Interface support\"\n \tselect DM_REGULATOR_PBIAS if DM_MMC && DM_REGULATOR\n+\tselect DM_REGULATOR_PBIAS if DM_MMC && DM_REGULATOR\n \thelp\n \t  This selects the TI OMAP High Speed Multimedia card Interface.\n \t  If you have an omap2plus board with a Multimedia Card slot,\ndiff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig\nindex c82a936..2cfade1 100644\n--- a/drivers/power/regulator/Kconfig\n+++ b/drivers/power/regulator/Kconfig\n@@ -151,6 +151,19 @@ config DM_REGULATOR_PALMAS\n \tfeatures for REGULATOR PALMAS and the family of PALMAS PMICs.\n \tThe driver implements get/set api for: value and enable.\n \n+config DM_REGULATOR_PBIAS\n+\tbool \"Enable driver for PBIAS regulator\"\n+\tdepends on DM_REGULATOR\n+\tselect REGMAP\n+\tselect SYSCON\n+\t---help---\n+\tThis enables implementation of driver-model regulator uclass\n+\tfeatures for pseudo-regulator PBIAS found in the OMAP SOCs.\n+\tThis pseudo-regulator is used to provide a BIAS voltage to MMC1\n+\tsignal pads and must be configured properly during a voltage switch.\n+\tVoltage switching is required by some operating modes of SDcards and\n+\teMMC.\n+\n config DM_REGULATOR_LP873X\n \tbool \"Enable driver for LP873X PMIC regulators\"\n         depends on PMIC_LP873X\ndiff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile\nindex 18fb870..6c149a9 100644\n--- a/drivers/power/regulator/Makefile\n+++ b/drivers/power/regulator/Makefile\n@@ -18,5 +18,6 @@ obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o\n obj-$(CONFIG_DM_REGULATOR_SANDBOX) += sandbox.o\n obj-$(CONFIG_REGULATOR_TPS65090) += tps65090_regulator.o\n obj-$(CONFIG_$(SPL_)DM_REGULATOR_PALMAS) += palmas_regulator.o\n+obj-$(CONFIG_$(SPL_)DM_REGULATOR_PBIAS) += pbias_regulator.o\n obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o\n obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP87565) += lp87565_regulator.o\ndiff --git a/drivers/power/regulator/pbias_regulator.c b/drivers/power/regulator/pbias_regulator.c\nnew file mode 100644\nindex 0000000..914500b\n--- /dev/null\n+++ b/drivers/power/regulator/pbias_regulator.c\n@@ -0,0 +1,301 @@\n+/*\n+ * (C) Copyright 2016 Texas Instruments Incorporated, <www.ti.com>\n+ * Jean-Jacques Hiblot <jjhiblot@ti.com>\n+ *\n+ * SPDX-License-Identifier:\tGPL-2.0+\n+ */\n+\n+#include <common.h>\n+#include <errno.h>\n+#include <dm.h>\n+#include <power/pmic.h>\n+#include <power/regulator.h>\n+#include <regmap.h>\n+#include <syscon.h>\n+#include <linux/bitops.h>\n+#include <linux/ioport.h>\n+#include <dm/read.h>\n+\n+DECLARE_GLOBAL_DATA_PTR;\n+\n+struct pbias_reg_info {\n+\tu32 enable;\n+\tu32 enable_mask;\n+\tu32 disable_val;\n+\tu32 vmode;\n+\tunsigned int enable_time;\n+\tchar *name;\n+};\n+\n+struct pbias_priv {\n+\tstruct regmap *regmap;\n+\tint offset;\n+};\n+\n+static const struct pmic_child_info pmic_children_info[] = {\n+\t{ .prefix = \"pbias\", .driver = \"pbias_regulator\"},\n+\t{ },\n+};\n+\n+static int pbias_write(struct udevice *dev, uint reg, const uint8_t *buff,\n+\t\t       int len)\n+{\n+\tstruct pbias_priv *priv = dev_get_priv(dev);\n+\tu32 val = *(u32 *)buff;\n+\n+\tif (len != 4)\n+\t\treturn -EINVAL;\n+\n+\treturn regmap_write(priv->regmap, priv->offset, val);\n+}\n+\n+static int pbias_read(struct udevice *dev, uint reg, uint8_t *buff, int len)\n+{\n+\tstruct pbias_priv *priv = dev_get_priv(dev);\n+\n+\tif (len != 4)\n+\t\treturn -EINVAL;\n+\n+\treturn regmap_read(priv->regmap, priv->offset, (u32 *)buff);\n+}\n+\n+static int pbias_ofdata_to_platdata(struct udevice *dev)\n+{\n+\tstruct pbias_priv *priv = dev_get_priv(dev);\n+\tstruct udevice *syscon;\n+\tstruct regmap *regmap;\n+\tstruct resource res;\n+\tint err;\n+\n+\terr = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,\n+\t\t\t\t\t   \"syscon\", &syscon);\n+\tif (err) {\n+\t\terror(\"%s: unable to find syscon device (%d)\\n\", __func__,\n+\t\t      err);\n+\t\treturn err;\n+\t}\n+\n+\tregmap = syscon_get_regmap(syscon);\n+\tif (IS_ERR(regmap)) {\n+\t\terror(\"%s: unable to find regmap (%ld)\\n\", __func__,\n+\t\t      PTR_ERR(regmap));\n+\t\treturn PTR_ERR(regmap);\n+\t}\n+\tpriv->regmap = regmap;\n+\n+\terr = dev_read_resource(dev, 0, &res);\n+\tif (err) {\n+\t\terror(\"%s: unable to find offset (%d)\\n\", __func__, err);\n+\t\treturn err;\n+\t}\n+\tpriv->offset = res.start;\n+\n+\treturn 0;\n+}\n+\n+static int pbias_bind(struct udevice *dev)\n+{\n+\tint children;\n+\n+\tchildren = pmic_bind_children(dev, dev->node, pmic_children_info);\n+\tif (!children)\n+\t\tdebug(\"%s: %s - no child found\\n\", __func__, dev->name);\n+\n+\treturn 0;\n+}\n+\n+static struct dm_pmic_ops pbias_ops = {\n+\t.read = pbias_read,\n+\t.write = pbias_write,\n+};\n+\n+static const struct udevice_id pbias_ids[] = {\n+\t{ .compatible = \"ti,pbias-dra7\" },\n+\t{ }\n+};\n+\n+U_BOOT_DRIVER(pbias_pmic) = {\n+\t.name = \"pbias_pmic\",\n+\t.id = UCLASS_PMIC,\n+\t.of_match = pbias_ids,\n+\t.bind = pbias_bind,\n+\t.ops = &pbias_ops,\n+\t.ofdata_to_platdata = pbias_ofdata_to_platdata,\n+\t.priv_auto_alloc_size = sizeof(struct pbias_priv),\n+};\n+\n+static const struct pbias_reg_info pbias_mmc_omap2430 = {\n+\t.enable = BIT(1),\n+\t.enable_mask = BIT(1),\n+\t.vmode = BIT(0),\n+\t.disable_val = 0,\n+\t.enable_time = 100,\n+\t.name = \"pbias_mmc_omap2430\"\n+};\n+\n+static const struct pbias_reg_info pbias_sim_omap3 = {\n+\t.enable = BIT(9),\n+\t.enable_mask = BIT(9),\n+\t.vmode = BIT(8),\n+\t.enable_time = 100,\n+\t.name = \"pbias_sim_omap3\"\n+};\n+\n+static const struct pbias_reg_info pbias_mmc_omap4 = {\n+\t.enable = BIT(26) | BIT(22),\n+\t.enable_mask = BIT(26) | BIT(25) | BIT(22),\n+\t.disable_val = BIT(25),\n+\t.vmode = BIT(21),\n+\t.enable_time = 100,\n+\t.name = \"pbias_mmc_omap4\"\n+};\n+\n+static const struct pbias_reg_info pbias_mmc_omap5 = {\n+\t.enable = BIT(27) | BIT(26),\n+\t.enable_mask = BIT(27) | BIT(25) | BIT(26),\n+\t.disable_val = BIT(25),\n+\t.vmode = BIT(21),\n+\t.enable_time = 100,\n+\t.name = \"pbias_mmc_omap5\"\n+};\n+\n+static const struct pbias_reg_info *pbias_reg_infos[] = {\n+\t&pbias_mmc_omap5,\n+\t&pbias_mmc_omap4,\n+\t&pbias_sim_omap3,\n+\t&pbias_mmc_omap2430,\n+\tNULL\n+};\n+\n+static int pbias_regulator_probe(struct udevice *dev)\n+{\n+\tconst struct pbias_reg_info **p = pbias_reg_infos;\n+\tstruct dm_regulator_uclass_platdata *uc_pdata;\n+\n+\tuc_pdata = dev_get_uclass_platdata(dev);\n+\n+\twhile (*p) {\n+\t\tint rc;\n+\n+\t\trc = dev_read_stringlist_search(dev, \"regulator-name\",\n+\t\t\t\t\t\t(*p)->name);\n+\t\tif (rc >= 0) {\n+\t\t\tdebug(\"found regulator %s\\n\", (*p)->name);\n+\t\t\tbreak;\n+\t\t} else if (rc != -ENODATA) {\n+\t\t\treturn rc;\n+\t\t}\n+\t\tp++;\n+\t}\n+\tif (!*p) {\n+\t\tint i = 0;\n+\t\tconst char *s;\n+\n+\t\tdebug(\"regulator \");\n+\t\twhile (dev_read_string_index(dev, \"regulator-name\", i++, &s) >= 0)\n+\t\t\tdebug(\"%s'%s' \", (i > 1) ? \", \" : \"\", s);\n+\t\tdebug(\"%s not supported\\n\", (i > 2) ? \"are\" : \"is\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tuc_pdata->type = REGULATOR_TYPE_OTHER;\n+\tdev->priv = (void *)*p;\n+\n+\treturn 0;\n+}\n+\n+static int pbias_regulator_get_value(struct udevice *dev)\n+{\n+\tconst struct pbias_reg_info *p = dev_get_priv(dev);\n+\tint rc;\n+\tu32 reg;\n+\n+\trc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tdebug(\"%s voltage id %s\\n\", p->name,\n+\t      (reg & p->vmode) ? \"3.0v\" : \"1.8v\");\n+\treturn (reg & p->vmode) ? 3000000 : 1800000;\n+}\n+\n+static int pbias_regulator_set_value(struct udevice *dev, int uV)\n+{\n+\tconst struct pbias_reg_info *p = dev_get_priv(dev);\n+\tint rc;\n+\tu32 reg;\n+\n+\tdebug(\"Setting %s voltage to %s\\n\", p->name,\n+\t      (reg & p->vmode) ? \"3.0v\" : \"1.8v\");\n+\n+\trc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tif (uV == 3000000)\n+\t\treg |= p->vmode;\n+\telse if (uV == 1800000)\n+\t\treg &= ~p->vmode;\n+\telse\n+\t\treturn -EINVAL;\n+\n+\treturn pmic_write(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));\n+}\n+\n+static int pbias_regulator_get_enable(struct udevice *dev)\n+{\n+\tconst struct pbias_reg_info *p = dev_get_priv(dev);\n+\tint rc;\n+\tu32 reg;\n+\n+\trc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tdebug(\"%s id %s\\n\", p->name,\n+\t      (reg & p->enable_mask) == (p->disable_val) ? \"on\" : \"off\");\n+\n+\treturn (reg & p->enable_mask) == (p->disable_val);\n+}\n+\n+static int pbias_regulator_set_enable(struct udevice *dev, bool enable)\n+{\n+\tconst struct pbias_reg_info *p = dev_get_priv(dev);\n+\tint rc;\n+\tu32 reg;\n+\n+\tdebug(\"Turning %s %s\\n\", enable ? \"on\" : \"off\", p->name);\n+\n+\trc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));\n+\tif (rc)\n+\t\treturn rc;\n+\n+\treg &= ~p->enable_mask;\n+\tif (enable)\n+\t\treg |= p->enable;\n+\telse\n+\t\treg |= p->disable_val;\n+\n+\trc = pmic_write(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));\n+\tif (rc)\n+\t\treturn rc;\n+\n+\tif (enable)\n+\t\tudelay(p->enable_time);\n+\n+\treturn 0;\n+}\n+\n+static const struct dm_regulator_ops pbias_regulator_ops = {\n+\t.get_value  = pbias_regulator_get_value,\n+\t.set_value  = pbias_regulator_set_value,\n+\t.get_enable = pbias_regulator_get_enable,\n+\t.set_enable = pbias_regulator_set_enable,\n+};\n+\n+U_BOOT_DRIVER(pbias_regulator) = {\n+\t.name = \"pbias_regulator\",\n+\t.id = UCLASS_REGULATOR,\n+\t.ops = &pbias_regulator_ops,\n+\t.probe = pbias_regulator_probe,\n+};\n","prefixes":["U-Boot","v3","2/2"]}