From patchwork Mon Jul 18 17:35:19 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tero Kristo X-Patchwork-Id: 987322 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p6IHaCbB013507 for ; Mon, 18 Jul 2011 17:36:12 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754535Ab1GRRgK (ORCPT ); Mon, 18 Jul 2011 13:36:10 -0400 Received: from bear.ext.ti.com ([192.94.94.41]:51152 "EHLO bear.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754495Ab1GRRgH convert rfc822-to-8bit (ORCPT ); Mon, 18 Jul 2011 13:36:07 -0400 Received: from dlep34.itg.ti.com ([157.170.170.115]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id p6IHa347003660 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 18 Jul 2011 12:36:03 -0500 Received: from dlep26.itg.ti.com (smtp-le.itg.ti.com [157.170.170.27]) by dlep34.itg.ti.com (8.13.7/8.13.8) with ESMTP id p6IHa2Bc022128; Mon, 18 Jul 2011 12:36:02 -0500 (CDT) Received: from dnce72.ent.ti.com (localhost [127.0.0.1]) by dlep26.itg.ti.com (8.13.8/8.13.8) with ESMTP id p6IHa2u2010548; Mon, 18 Jul 2011 12:36:02 -0500 (CDT) thread-index: AcxFcSmYOfqzqk50Q2i1jR3E3ynokg== Content-Class: urn:content-classes:message Importance: normal X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.4657 Received: from localhost.localdomain (172.24.88.4) by dnce72.ent.ti.com (137.167.131.87) with Microsoft SMTP Server (TLS) id 8.3.106.1; Mon, 18 Jul 2011 19:36:01 +0200 From: Tero Kristo To: CC: , , , , Subject: [PATCHv3 3/6] regulator: omap smps regulator driver Date: Mon, 18 Jul 2011 20:35:19 +0300 Message-ID: <1311010522-5868-4-git-send-email-t-kristo@ti.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1311010522-5868-1-git-send-email-t-kristo@ti.com> References: <1311010522-5868-1-git-send-email-t-kristo@ti.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@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]); Mon, 18 Jul 2011 17:36:13 +0000 (UTC) OMAP SMPS regulator driver provides access to OMAP voltage processor controlled regulators. These include VDD_MPU and VDD_CORE for OMAP3 and additionally VDD_IVA for OMAP4. SMPS regulators use the OMAP voltage layer for the actual voltage regulation operations. Signed-off-by: Tero Kristo Cc: Kevin Hilman Cc: Tony Lindgren Cc: Todd Poynor Cc: Mark Brown Cc: Liam Girdwood Acked-by: Graeme Gregory --- drivers/regulator/Kconfig | 9 ++ drivers/regulator/Makefile | 1 + drivers/regulator/omap-smps-regulator.c | 180 +++++++++++++++++++++++++++++++ include/linux/regulator/omap-smps.h | 20 ++++ 4 files changed, 210 insertions(+), 0 deletions(-) create mode 100644 drivers/regulator/omap-smps-regulator.c create mode 100644 include/linux/regulator/omap-smps.h diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index d7ed20f..bb18ff2 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -303,5 +303,14 @@ config REGULATOR_TPS65910 help This driver supports TPS65910 voltage regulator chips. +config REGULATOR_OMAP_SMPS + tristate "TI OMAP SMPS Power Regulators" + depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM && TWL4030_CORE + help + This driver supports the OMAP3 / OMAP4 SMPS regulators for VDD1, + VDD2 and VDD3. These regulators reside inside the TWL4030 / + TWL6030 chip but are accessed using the voltage processor + interface of OMAP. + endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 3932d2e..191e3d5 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -43,5 +43,6 @@ obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o +obj-$(CONFIG_REGULATOR_OMAP_SMPS) += omap-smps-regulator.o ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG diff --git a/drivers/regulator/omap-smps-regulator.c b/drivers/regulator/omap-smps-regulator.c new file mode 100644 index 0000000..8b56e4f --- /dev/null +++ b/drivers/regulator/omap-smps-regulator.c @@ -0,0 +1,179 @@ +/* + * omap-vp-regulator.c -- support SMPS regulators for OMAP chips + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "omap-smps" + +struct omap_smps_reg_info { + const char *vdd_name; + struct regulator_dev *rdev; + struct voltagedomain *voltdm; + struct regulator_desc desc; +}; + +static int omap_smps_set_voltage(struct regulator_dev *rdev, int min_uV, + int max_uV, unsigned *selector) +{ + struct omap_smps_reg_info *info = rdev_get_drvdata(rdev); + return voltdm_scale(info->voltdm, min_uV); +} + +static int omap_smps_get_voltage(struct regulator_dev *rdev) +{ + struct omap_smps_reg_info *info = rdev_get_drvdata(rdev); + return omap_vp_get_curr_volt(info->voltdm); +} + +static struct regulator_ops omap_smps_ops = { + .set_voltage = omap_smps_set_voltage, + .get_voltage = omap_smps_get_voltage, +}; + +#define SMPS_REG(name) { \ + .vdd_name = #name, \ + .desc = { \ + .ops = &omap_smps_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + }, \ + } + +static struct omap_smps_reg_info omap_smps_regs[] = { + SMPS_REG(mpu), + SMPS_REG(mpu_iva), + SMPS_REG(iva), + SMPS_REG(core), +}; + +static void omap_smps_reg_cleanup(void) +{ + int i; + struct omap_smps_reg_info *info; + + for (i = 0; i < ARRAY_SIZE(omap_smps_regs); i++) { + info = &omap_smps_regs[i]; + if (info->rdev) { + regulator_unregister(info->rdev); + info->rdev = NULL; + } + + kfree(info->desc.name); + info->desc.name = NULL; + } +} + +static struct regulator_init_data dummy_initdata __initdata; + +static int __devinit omap_smps_reg_probe(struct platform_device *pdev) +{ + int i, j, ret; + struct omap_smps_reg_info *info; + struct omap_smps_platform_data *pdata; + struct regulator_dev *rdev; + struct regulator_init_data *initdata; + struct voltagedomain *voltdm; + char *name; + + pdata = pdev->dev.platform_data; + + for (i = 0; i < ARRAY_SIZE(omap_smps_regs); i++) { + initdata = &dummy_initdata; + info = &omap_smps_regs[i]; + + for (j = 0; j < pdata->num_regulators; j++) + if (!strcmp(info->vdd_name, + pdata->regulators[j]->consumer_supplies[0]. + dev_name)) { + initdata = pdata->regulators[j]; + break; + } + + voltdm = voltdm_lookup(info->vdd_name); + + if (!voltdm) + continue; + + info->voltdm = voltdm; + + name = kmalloc(strlen(info->vdd_name) + 5, GFP_KERNEL); + + if (!name) { + ret = -ENOMEM; + goto err; + } + + sprintf(name, "VDD_%s", info->vdd_name); + + for (j = 0; j < strlen(name); j++) + name[j] = toupper(name[j]); + + info->desc.name = name; + + rdev = regulator_register(&info->desc, &pdev->dev, initdata, + info); + + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, "can't register %s, %ld\n", + info->desc.name, PTR_ERR(rdev)); + ret = PTR_ERR(rdev); + goto err; + } + + info->rdev = rdev; + } + + return 0; +err: + omap_smps_reg_cleanup(); + return ret; +} + +static int omap_smps_reg_remove(struct platform_device *pdev) +{ + omap_smps_reg_cleanup(); + return 0; +} + +static struct platform_driver omap_smps_reg_driver = { + .probe = omap_smps_reg_probe, + .remove = __devexit_p(omap_smps_reg_remove), + .driver.name = DRIVER_NAME, + .driver.owner = THIS_MODULE, +}; + +static int __init omap_smps_reg_init(void) +{ + return platform_driver_register(&omap_smps_reg_driver); +} +subsys_initcall(omap_smps_reg_init); + +static void __exit omap_smps_reg_exit(void) +{ + platform_driver_unregister(&omap_smps_reg_driver); +} +module_exit(omap_smps_reg_exit); + +MODULE_ALIAS("platform:"DRIVER_NAME); +MODULE_AUTHOR("Tero Kristo "); +MODULE_DESCRIPTION("OMAP SMPS regulator driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/regulator/omap-smps.h b/include/linux/regulator/omap-smps.h new file mode 100644 index 0000000..1d5f940 --- /dev/null +++ b/include/linux/regulator/omap-smps.h @@ -0,0 +1,20 @@ +/* + * omap-smps.h - header for OMAP SMPS regulator support + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __OMAP_SMPS_H__ +#define __OMAP_SMPS_H__ + +struct omap_smps_platform_data { + struct regulator_init_data **regulators; + int num_regulators; +}; + +#endif /* End of __OMAP_SMPS_H__ */