From 90550d1903da8dac851d220b794e44c90a11c6ce Mon Sep 17 00:00:00 2001
From: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
Date: Mon, 14 Feb 2011 11:17:12 +0100
Subject: mfd: AB8500 system control driver

This adds a pretty straight-forward system control driver for the
AB8500. This driver will be used from the core platform, e.g the
clock tree implementation in the machine code, and is by nature
singleton.

There are a few simple functions to read, write, set and clear
registers so that the machine code can control its own foundation.

Cc: Mattias Wallin <mattias.wallin@stericsson.com>
Signed-off-by: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
 drivers/mfd/Makefile         |  2 +-
 drivers/mfd/ab8500-sysctrl.c | 80 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mfd/ab8500-sysctrl.c

(limited to 'drivers/mfd')

diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index f0e25cad762..61a0b0f901a 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -71,7 +71,7 @@ obj-$(CONFIG_ABX500_CORE)	+= abx500-core.o
 obj-$(CONFIG_AB3100_CORE)	+= ab3100-core.o
 obj-$(CONFIG_AB3100_OTP)	+= ab3100-otp.o
 obj-$(CONFIG_AB3550_CORE)	+= ab3550-core.o
-obj-$(CONFIG_AB8500_CORE)	+= ab8500-core.o
+obj-$(CONFIG_AB8500_CORE)	+= ab8500-core.o ab8500-sysctrl.o
 obj-$(CONFIG_AB8500_I2C_CORE)	+= ab8500-i2c.o
 obj-$(CONFIG_AB8500_DEBUG)	+= ab8500-debugfs.o
 obj-$(CONFIG_MFD_TIMBERDALE)    += timberdale.o
diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c
new file mode 100644
index 00000000000..392185965b3
--- /dev/null
+++ b/drivers/mfd/ab8500-sysctrl.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> for ST Ericsson.
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/ab8500.h>
+#include <linux/mfd/abx500.h>
+#include <linux/mfd/ab8500/sysctrl.h>
+
+static struct device *sysctrl_dev;
+
+static inline bool valid_bank(u8 bank)
+{
+	return ((bank == AB8500_SYS_CTRL1_BLOCK) ||
+		(bank == AB8500_SYS_CTRL2_BLOCK));
+}
+
+int ab8500_sysctrl_read(u16 reg, u8 *value)
+{
+	u8 bank;
+
+	if (sysctrl_dev == NULL)
+		return -EAGAIN;
+
+	bank = (reg >> 8);
+	if (!valid_bank(bank))
+		return -EINVAL;
+
+	return abx500_get_register_interruptible(sysctrl_dev, bank,
+		(u8)(reg & 0xFF), value);
+}
+
+int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value)
+{
+	u8 bank;
+
+	if (sysctrl_dev == NULL)
+		return -EAGAIN;
+
+	bank = (reg >> 8);
+	if (!valid_bank(bank))
+		return -EINVAL;
+
+	return abx500_mask_and_set_register_interruptible(sysctrl_dev, bank,
+		(u8)(reg & 0xFF), mask, value);
+}
+
+static int __devinit ab8500_sysctrl_probe(struct platform_device *pdev)
+{
+	sysctrl_dev = &pdev->dev;
+	return 0;
+}
+
+static int __devexit ab8500_sysctrl_remove(struct platform_device *pdev)
+{
+	sysctrl_dev = NULL;
+	return 0;
+}
+
+static struct platform_driver ab8500_sysctrl_driver = {
+	.driver = {
+		.name = "ab8500-sysctrl",
+		.owner = THIS_MODULE,
+	},
+	.probe = ab8500_sysctrl_probe,
+	.remove = __devexit_p(ab8500_sysctrl_remove),
+};
+
+static int __init ab8500_sysctrl_init(void)
+{
+	return platform_driver_register(&ab8500_sysctrl_driver);
+}
+subsys_initcall(ab8500_sysctrl_init);
+
+MODULE_AUTHOR("Mattias Nilsson <mattias.i.nilsson@stericsson.com");
+MODULE_DESCRIPTION("AB8500 system control driver");
+MODULE_LICENSE("GPL v2");
-- 
cgit v1.2.3-70-g09d2