[PATCH] regulator: Add support samsung power domain

From: Kukjin Kim
Date: Fri Sep 17 2010 - 06:19:06 EST


From: Changhwan Youn <chaos.youn@xxxxxxxxxxx>

This patch adds common regulator driver for samsung power domain.
A consumer of controlling power domain uses regulator framework API,
So new samsung pd driver is inserted into regulator directory.

Signed-off-by: Changhwan Youn <chaos.youn@xxxxxxxxxxx>
Signed-off-by: Jeongbae Seo <jeongbae.seo@xxxxxxxxxxx>
Signed-off-by: Kukjin Kim <kgene.kim@xxxxxxxxxxx>
---
drivers/regulator/Kconfig | 5 +
drivers/regulator/Makefile | 1 +
drivers/regulator/samsung_pd.c | 169 ++++++++++++++++++++++++++++++++++
include/linux/regulator/samsung_pd.h | 46 +++++++++
4 files changed, 221 insertions(+), 0 deletions(-)
create mode 100644 drivers/regulator/samsung_pd.c
create mode 100644 include/linux/regulator/samsung_pd.h

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 172951b..1ef8efe 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -235,5 +235,10 @@ config REGULATOR_TPS6586X
help
This driver supports TPS6586X voltage regulator chips.

+config REGULATOR_SAMSUNG_POWER_DOMAIN
+ tristate "Samsung power domain support"
+ help
+ This driver provides support for samsung power domain.
+
endif

diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 8285fd8..30ae640 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -36,5 +36,6 @@ obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o
+obj-$(CONFIG_REGULATOR_SAMSUNG_POWER_DOMAIN) += samsung_pd.o

ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/samsung_pd.c b/drivers/regulator/samsung_pd.c
new file mode 100644
index 0000000..ef48f16
--- /dev/null
+++ b/drivers/regulator/samsung_pd.c
@@ -0,0 +1,169 @@
+/* linux/driver/regulator/samsung_pd.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Based on linux/driver/regulator/fixed.c
+ *
+ * Samsung power domain support
+ *
+ * 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.
+*/
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/samsung_pd.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+
+struct samsung_pd_data {
+ struct regulator_desc desc;
+ struct regulator_dev *dev;
+ unsigned startup_delay;
+ bool is_enabled;
+ int (*enable)(void);
+ int (*disable)(void);
+};
+
+static int samsung_pd_is_enabled(struct regulator_dev *dev)
+{
+ struct samsung_pd_data *data = rdev_get_drvdata(dev);
+
+ return data->is_enabled;
+}
+
+static int samsung_pd_enable(struct regulator_dev *dev)
+{
+ struct samsung_pd_data *data = rdev_get_drvdata(dev);
+ int ret;
+
+ ret = data->enable();
+ if (!ret)
+ data->is_enabled = true;
+
+ return ret;
+}
+
+static int samsung_pd_disable(struct regulator_dev *dev)
+{
+ struct samsung_pd_data *data = rdev_get_drvdata(dev);
+ int ret;
+
+ ret = data->disable();
+ if (!ret)
+ data->is_enabled = false;
+
+ return ret;
+}
+
+static int samsung_pd_enable_time(struct regulator_dev *dev)
+{
+ struct samsung_pd_data *data = rdev_get_drvdata(dev);
+
+ return data->startup_delay;
+}
+
+static struct regulator_ops samsung_pd_ops = {
+ .is_enabled = samsung_pd_is_enabled,
+ .enable = samsung_pd_enable,
+ .disable = samsung_pd_disable,
+ .enable_time = samsung_pd_enable_time,
+};
+
+static int __devinit reg_samsung_pd_probe(struct platform_device *pdev)
+{
+ struct samsung_pd_config *config = pdev->dev.platform_data;
+ struct samsung_pd_data *drvdata;
+ int ret;
+
+ drvdata = kzalloc(sizeof(struct samsung_pd_data), GFP_KERNEL);
+ if (drvdata == NULL) {
+ dev_err(&pdev->dev, "Failed to allocate device data\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL);
+ if (drvdata->desc.name == NULL) {
+ dev_err(&pdev->dev, "Failed to allocate supply name\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ drvdata->desc.type = REGULATOR_VOLTAGE;
+ drvdata->desc.owner = THIS_MODULE;
+ drvdata->desc.ops = &samsung_pd_ops;
+ drvdata->desc.n_voltages = 1;
+
+ drvdata->startup_delay = config->startup_delay;
+ drvdata->is_enabled = config->enabled_at_boot;
+ drvdata->enable = config->enable;
+ drvdata->disable = config->disable;
+
+ if (drvdata->is_enabled)
+ drvdata->enable();
+
+ drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
+ config->init_data, drvdata);
+ if (IS_ERR(drvdata->dev)) {
+ ret = PTR_ERR(drvdata->dev);
+ dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret);
+ goto err_name;
+ }
+
+ platform_set_drvdata(pdev, drvdata);
+
+ dev_dbg(&pdev->dev, "%s registerd\n", drvdata->desc.name);
+
+ return 0;
+
+err_name:
+ kfree(drvdata->desc.name);
+err:
+ kfree(drvdata);
+ return ret;
+}
+
+static int __devexit reg_samsung_pd_remove(struct platform_device *pdev)
+{
+ struct samsung_pd_data *drvdata = platform_get_drvdata(pdev);
+
+ regulator_unregister(drvdata->dev);
+ kfree(drvdata->desc.name);
+ kfree(drvdata);
+
+ return 0;
+}
+
+static struct platform_driver regulator_samsung_pd_driver = {
+ .probe = reg_samsung_pd_probe,
+ .remove = __devexit_p(reg_samsung_pd_remove),
+ .driver = {
+ .name = "reg-samsung-pd",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init regulator_samsung_pd_init(void)
+{
+ return platform_driver_register(&regulator_samsung_pd_driver);
+}
+subsys_initcall(regulator_samsung_pd_init);
+
+static void __exit regulator_samsung_pd_exit(void)
+{
+ platform_driver_unregister(&regulator_samsung_pd_driver);
+}
+module_exit(regulator_samsung_pd_exit);
+
+MODULE_AUTHOR("Changhwan Youn <chaos@xxxxxxxxxxx>");
+MODULE_AUTHOR("Jeongbae Seo <jeongbae.seo@xxxxxxxxxxx>");
+MODULE_DESCRIPTION("Samsung power domain regulator");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:reg-samsung-pd");
diff --git a/include/linux/regulator/samsung_pd.h b/include/linux/regulator/samsung_pd.h
new file mode 100644
index 0000000..505b458
--- /dev/null
+++ b/include/linux/regulator/samsung_pd.h
@@ -0,0 +1,46 @@
+/* linux/include/linux/regulator/samsung_pd.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Based on linux/include/linux/regulator/fixed.h
+ *
+ * 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 __REGULATOR_SAMSUNG_PD_H
+#define __REGULATOR_SAMSUNG_PD_H __FILE__
+
+struct regulator_init_data;
+
+/*
+ * struct samsung_pd_config - samsung_pd_config structure
+ * @supply_name: Name of the regulator supply
+ * @microvolts: Output voltage of regulator
+ * @startup_delay: Start-up time in microseconds
+ * @enabled_at_boot: Whether regulator has been enabled at
+ * boot or not. 1 = Yes, 0 = No
+ * This is used to keep the regulator at
+ * the default state
+ * @init_data: regulator_init_data
+ * @enable: regulator enable function
+ * @disable: regulator disable function
+ *
+ * This structure contains samsung power domain regulator configuration
+ * information that must be passed by platform code to the samsung
+ * power domain regulator driver.
+ */
+
+struct samsung_pd_config {
+ const char *supply_name;
+ int microvolts;
+ unsigned startup_delay;
+ unsigned enabled_at_boot:1;
+ struct regulator_init_data *init_data;
+ int (*enable)(void);
+ int (*disable)(void);
+};
+
+#endif /* __REGULATOR_SAMSUNG_PD_H */
--
1.6.2.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/