All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/5] [input] add mc13783 touchscreen driver
       [not found] <1249981166-4210-1-git-send-email-s.hauer@pengutronix.de>
@ 2009-08-11  8:59   ` Sascha Hauer
  0 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2009-08-11  8:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-arm-kernel, Sascha Hauer, Dmitry Torokhov, Mark Brown, linux-input

This driver provides support for the touchscreen interface
integrated into the Freescale MC13783.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: linux-input@vger.kernel.org
---
 drivers/input/touchscreen/Kconfig      |   12 ++
 drivers/input/touchscreen/Makefile     |    1 +
 drivers/input/touchscreen/mc13783_ts.c |  228 ++++++++++++++++++++++++++++++++
 3 files changed, 241 insertions(+), 0 deletions(-)
 create mode 100644 drivers/input/touchscreen/mc13783_ts.c

diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 72e2712..7451cf0 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -413,6 +413,18 @@ config TOUCHSCREEN_USB_COMPOSITE
 	  To compile this driver as a module, choose M here: the
 	  module will be called usbtouchscreen.
 
+config TOUCHSCREEN_MC13783
+	tristate "Freescale MC13783 touchscreen input driver"
+	depends on MFD_MC13783
+	help
+	  Say Y here if you have an Freescale MC13783 PMIC on your
+	  board and want to use its touchscreen
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mxc_ts.
+
 config TOUCHSCREEN_USB_EGALAX
 	default y
 	bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 3e1c5e0..7b79598 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
 obj-$(CONFIG_TOUCHSCREEN_MIGOR)		+= migor_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MTOUCH)	+= mtouch.o
 obj-$(CONFIG_TOUCHSCREEN_MK712)		+= mk712.o
+obj-$(CONFIG_TOUCHSCREEN_MC13783)	+= mc13783_ts.o
 obj-$(CONFIG_TOUCHSCREEN_HP600)		+= hp680_ts_input.o
 obj-$(CONFIG_TOUCHSCREEN_HP7XX)		+= jornada720_ts.o
 obj-$(CONFIG_TOUCHSCREEN_HTCPEN)	+= htcpen.o
diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c
new file mode 100644
index 0000000..9dfe280
--- /dev/null
+++ b/drivers/input/touchscreen/mc13783_ts.c
@@ -0,0 +1,228 @@
+/*
+ * Driver for the Freescale Semiconductor MC13783 touchscreen.
+ *
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Sascha Hauer, Pengutronix
+ *
+ * Initial development of this code was funded by
+ * Phytec Messtechnik GmbH, http://www.phytec.de
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <linux/mfd/mc13783-private.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#define MC13783_TS_NAME	"mc13783-ts"
+
+struct mc13783_ts_priv {
+	struct input_dev *idev;
+	struct mc13783 *mc13783;
+	struct delayed_work work;
+	struct workqueue_struct *workq;
+	unsigned int sample[4];
+};
+
+static inline void mc13783_ts_start_conversion(struct mc13783_ts_priv *priv)
+{
+	unsigned int reg_adc0, reg_adc1;
+
+	reg_adc0 = MC13783_ADC0_ADREFEN | MC13783_ADC0_ADREFMODE
+			| MC13783_ADC0_TSMOD0 | MC13783_ADC0_TSMOD1
+			| MC13783_ADC0_ADINC1 | MC13783_ADC0_ADINC2;
+	reg_adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADSEL | MC13783_ADC1_ADA22
+			| MC13783_ADC1_ASC | MC13783_ADC1_ADTRIGIGN;
+
+	mc13783_reg_write(priv->mc13783, MC13783_REG_ADC_0, reg_adc0);
+	mc13783_reg_write(priv->mc13783, MC13783_REG_ADC_1, reg_adc1);
+}
+
+static inline void mc13783_ts_set_irq_mode(struct mc13783_ts_priv *priv)
+{
+	unsigned int reg_adc0, reg_adc1;
+
+	reg_adc0 = MC13783_ADC0_ADREFEN | MC13783_ADC0_ADREFMODE
+			| MC13783_ADC0_TSMOD0;
+	reg_adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN;
+
+	mc13783_reg_write(priv->mc13783, MC13783_REG_ADC_0, reg_adc0);
+	mc13783_reg_write(priv->mc13783, MC13783_REG_ADC_1, reg_adc1);
+}
+
+#define TS_MIN 1
+#define TS_MAX 1000
+
+static void mc13783_ts_handler(int irq, void *data)
+{
+	struct mc13783_ts_priv *priv = data;
+	unsigned int sts;
+
+	mc13783_reg_read(priv->mc13783, MC13783_REG_INTERRUPT_STATUS_0, &sts);
+	mc13783_reg_write(priv->mc13783, MC13783_REG_INTERRUPT_STATUS_0,
+			sts & MC13783_INT_STAT_TSI);
+
+	if (sts & MC13783_INT_STAT_TSI)
+		queue_work(priv->workq, &priv->work.work);
+}
+
+static void mc13783_ts_report_sample(struct mc13783_ts_priv *priv)
+{
+	int x, y, press = 0;
+
+	x = (priv->sample[2] >> 2) & 0x3ff;
+	y = (priv->sample[3] >> 2) & 0x3ff;
+
+	pr_debug("mc13783_ts: x: %d y: %d\n", x, y);
+
+	if (x > TS_MIN && x < TS_MAX && y > TS_MIN && y < TS_MAX) {
+		press = 1;
+		input_report_abs(priv->idev, ABS_X, x);
+		input_report_abs(priv->idev, ABS_Y, y);
+
+		queue_delayed_work(priv->workq, &priv->work, HZ / 50);
+	}
+
+	input_report_abs(priv->idev, ABS_PRESSURE, press);
+	input_sync(priv->idev);
+}
+
+static void mc13783_ts_work(struct work_struct *work)
+{
+	struct mc13783_ts_priv *priv =
+		container_of(work, struct mc13783_ts_priv, work.work);
+	unsigned int mode = MC13783_ADC_MODE_TS;
+	unsigned int channel = 12;
+	int ret;
+
+	ret = mc13783_adc_do_conversion
+		(priv->mc13783, mode, channel, priv->sample);
+
+	if (!ret)
+		mc13783_ts_report_sample(priv);
+}
+
+static int __init mc13783_ts_probe(struct platform_device *pdev)
+{
+	struct mc13783_ts_priv *priv;
+	struct input_dev *idev;
+	int ret;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mc13783 = pdev->dev.platform_data;
+
+	idev = input_allocate_device();
+	if (!idev) {
+		ret = -ENOMEM;
+		goto err_input_alloc;
+	}
+
+	priv->idev = idev;
+	idev->name = MC13783_TS_NAME;
+	idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	idev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+					BIT_MASK(ABS_PRESSURE);
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = mc13783_register_irq(priv->mc13783, MC13783_IRQ_TS,
+		mc13783_ts_handler, priv);
+	if (ret)
+		goto err_failed_irq;
+
+	ret = input_register_device(priv->idev);
+	if (ret) {
+		dev_err(&pdev->dev,
+				"register input device failed with %d\n", ret);
+		goto err_failed_register;
+	}
+
+	/* unmask the ts wakeup interrupt */
+	mc13783_set_bits(priv->mc13783, MC13783_REG_INTERRUPT_MASK_0,
+			MC13783_INT_MASK_TSM, 0);
+
+	mc13783_adc_set_ts_status(priv->mc13783, 1);
+
+	INIT_DELAYED_WORK(&priv->work, mc13783_ts_work);
+
+	priv->workq = create_singlethread_workqueue("mc13783_ts");
+	queue_delayed_work(priv->workq, &priv->work, HZ / 20);
+
+	return 0;
+
+err_failed_register:
+	mc13783_free_irq(priv->mc13783, MC13783_IRQ_TS);
+err_failed_irq:
+	input_free_device(priv->idev);
+err_input_alloc:
+	kfree(priv);
+
+	return ret;
+}
+
+static int __devexit mc13783_ts_remove(struct platform_device *pdev)
+{
+	struct mc13783_ts_priv *priv = platform_get_drvdata(pdev);
+
+	mc13783_adc_set_ts_status(priv->mc13783, 0);
+
+	mc13783_free_irq(priv->mc13783, MC13783_IRQ_TS);
+
+	cancel_delayed_work(&priv->work);
+	destroy_workqueue(priv->workq);
+
+	input_unregister_device(priv->idev);
+	input_free_device(priv->idev);
+
+	kfree(priv);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_ts_driver = {
+	.probe		= mc13783_ts_probe,
+	.remove 	= __devexit_p(mc13783_ts_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= MC13783_TS_NAME,
+	},
+};
+
+static int __init mc13783_ts_init(void)
+{
+	return platform_driver_register(&mc13783_ts_driver);
+}
+
+static void __exit mc13783_ts_exit(void)
+{
+	platform_driver_unregister(&mc13783_ts_driver);
+}
+
+module_init(mc13783_ts_init);
+module_exit(mc13783_ts_exit);
+
+MODULE_DESCRIPTION("MC13783 input touchscreen driver");
+MODULE_AUTHOR("Sascha Hauer, <s.hauer@pengutronix.de>");
+MODULE_LICENSE("GPL");
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/5] [input] add mc13783 touchscreen driver
@ 2009-08-11  8:59   ` Sascha Hauer
  0 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2009-08-11  8:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-arm-kernel, Sascha Hauer, Dmitry Torokhov, Mark Brown, linux-input

This driver provides support for the touchscreen interface
integrated into the Freescale MC13783.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: linux-input@vger.kernel.org
---
 drivers/input/touchscreen/Kconfig      |   12 ++
 drivers/input/touchscreen/Makefile     |    1 +
 drivers/input/touchscreen/mc13783_ts.c |  228 ++++++++++++++++++++++++++++++++
 3 files changed, 241 insertions(+), 0 deletions(-)
 create mode 100644 drivers/input/touchscreen/mc13783_ts.c

diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 72e2712..7451cf0 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -413,6 +413,18 @@ config TOUCHSCREEN_USB_COMPOSITE
 	  To compile this driver as a module, choose M here: the
 	  module will be called usbtouchscreen.
 
+config TOUCHSCREEN_MC13783
+	tristate "Freescale MC13783 touchscreen input driver"
+	depends on MFD_MC13783
+	help
+	  Say Y here if you have an Freescale MC13783 PMIC on your
+	  board and want to use its touchscreen
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mxc_ts.
+
 config TOUCHSCREEN_USB_EGALAX
 	default y
 	bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 3e1c5e0..7b79598 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
 obj-$(CONFIG_TOUCHSCREEN_MIGOR)		+= migor_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MTOUCH)	+= mtouch.o
 obj-$(CONFIG_TOUCHSCREEN_MK712)		+= mk712.o
+obj-$(CONFIG_TOUCHSCREEN_MC13783)	+= mc13783_ts.o
 obj-$(CONFIG_TOUCHSCREEN_HP600)		+= hp680_ts_input.o
 obj-$(CONFIG_TOUCHSCREEN_HP7XX)		+= jornada720_ts.o
 obj-$(CONFIG_TOUCHSCREEN_HTCPEN)	+= htcpen.o
diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c
new file mode 100644
index 0000000..9dfe280
--- /dev/null
+++ b/drivers/input/touchscreen/mc13783_ts.c
@@ -0,0 +1,228 @@
+/*
+ * Driver for the Freescale Semiconductor MC13783 touchscreen.
+ *
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Sascha Hauer, Pengutronix
+ *
+ * Initial development of this code was funded by
+ * Phytec Messtechnik GmbH, http://www.phytec.de
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <linux/mfd/mc13783-private.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#define MC13783_TS_NAME	"mc13783-ts"
+
+struct mc13783_ts_priv {
+	struct input_dev *idev;
+	struct mc13783 *mc13783;
+	struct delayed_work work;
+	struct workqueue_struct *workq;
+	unsigned int sample[4];
+};
+
+static inline void mc13783_ts_start_conversion(struct mc13783_ts_priv *priv)
+{
+	unsigned int reg_adc0, reg_adc1;
+
+	reg_adc0 = MC13783_ADC0_ADREFEN | MC13783_ADC0_ADREFMODE
+			| MC13783_ADC0_TSMOD0 | MC13783_ADC0_TSMOD1
+			| MC13783_ADC0_ADINC1 | MC13783_ADC0_ADINC2;
+	reg_adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADSEL | MC13783_ADC1_ADA22
+			| MC13783_ADC1_ASC | MC13783_ADC1_ADTRIGIGN;
+
+	mc13783_reg_write(priv->mc13783, MC13783_REG_ADC_0, reg_adc0);
+	mc13783_reg_write(priv->mc13783, MC13783_REG_ADC_1, reg_adc1);
+}
+
+static inline void mc13783_ts_set_irq_mode(struct mc13783_ts_priv *priv)
+{
+	unsigned int reg_adc0, reg_adc1;
+
+	reg_adc0 = MC13783_ADC0_ADREFEN | MC13783_ADC0_ADREFMODE
+			| MC13783_ADC0_TSMOD0;
+	reg_adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN;
+
+	mc13783_reg_write(priv->mc13783, MC13783_REG_ADC_0, reg_adc0);
+	mc13783_reg_write(priv->mc13783, MC13783_REG_ADC_1, reg_adc1);
+}
+
+#define TS_MIN 1
+#define TS_MAX 1000
+
+static void mc13783_ts_handler(int irq, void *data)
+{
+	struct mc13783_ts_priv *priv = data;
+	unsigned int sts;
+
+	mc13783_reg_read(priv->mc13783, MC13783_REG_INTERRUPT_STATUS_0, &sts);
+	mc13783_reg_write(priv->mc13783, MC13783_REG_INTERRUPT_STATUS_0,
+			sts & MC13783_INT_STAT_TSI);
+
+	if (sts & MC13783_INT_STAT_TSI)
+		queue_work(priv->workq, &priv->work.work);
+}
+
+static void mc13783_ts_report_sample(struct mc13783_ts_priv *priv)
+{
+	int x, y, press = 0;
+
+	x = (priv->sample[2] >> 2) & 0x3ff;
+	y = (priv->sample[3] >> 2) & 0x3ff;
+
+	pr_debug("mc13783_ts: x: %d y: %d\n", x, y);
+
+	if (x > TS_MIN && x < TS_MAX && y > TS_MIN && y < TS_MAX) {
+		press = 1;
+		input_report_abs(priv->idev, ABS_X, x);
+		input_report_abs(priv->idev, ABS_Y, y);
+
+		queue_delayed_work(priv->workq, &priv->work, HZ / 50);
+	}
+
+	input_report_abs(priv->idev, ABS_PRESSURE, press);
+	input_sync(priv->idev);
+}
+
+static void mc13783_ts_work(struct work_struct *work)
+{
+	struct mc13783_ts_priv *priv =
+		container_of(work, struct mc13783_ts_priv, work.work);
+	unsigned int mode = MC13783_ADC_MODE_TS;
+	unsigned int channel = 12;
+	int ret;
+
+	ret = mc13783_adc_do_conversion
+		(priv->mc13783, mode, channel, priv->sample);
+
+	if (!ret)
+		mc13783_ts_report_sample(priv);
+}
+
+static int __init mc13783_ts_probe(struct platform_device *pdev)
+{
+	struct mc13783_ts_priv *priv;
+	struct input_dev *idev;
+	int ret;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mc13783 = pdev->dev.platform_data;
+
+	idev = input_allocate_device();
+	if (!idev) {
+		ret = -ENOMEM;
+		goto err_input_alloc;
+	}
+
+	priv->idev = idev;
+	idev->name = MC13783_TS_NAME;
+	idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	idev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+					BIT_MASK(ABS_PRESSURE);
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = mc13783_register_irq(priv->mc13783, MC13783_IRQ_TS,
+		mc13783_ts_handler, priv);
+	if (ret)
+		goto err_failed_irq;
+
+	ret = input_register_device(priv->idev);
+	if (ret) {
+		dev_err(&pdev->dev,
+				"register input device failed with %d\n", ret);
+		goto err_failed_register;
+	}
+
+	/* unmask the ts wakeup interrupt */
+	mc13783_set_bits(priv->mc13783, MC13783_REG_INTERRUPT_MASK_0,
+			MC13783_INT_MASK_TSM, 0);
+
+	mc13783_adc_set_ts_status(priv->mc13783, 1);
+
+	INIT_DELAYED_WORK(&priv->work, mc13783_ts_work);
+
+	priv->workq = create_singlethread_workqueue("mc13783_ts");
+	queue_delayed_work(priv->workq, &priv->work, HZ / 20);
+
+	return 0;
+
+err_failed_register:
+	mc13783_free_irq(priv->mc13783, MC13783_IRQ_TS);
+err_failed_irq:
+	input_free_device(priv->idev);
+err_input_alloc:
+	kfree(priv);
+
+	return ret;
+}
+
+static int __devexit mc13783_ts_remove(struct platform_device *pdev)
+{
+	struct mc13783_ts_priv *priv = platform_get_drvdata(pdev);
+
+	mc13783_adc_set_ts_status(priv->mc13783, 0);
+
+	mc13783_free_irq(priv->mc13783, MC13783_IRQ_TS);
+
+	cancel_delayed_work(&priv->work);
+	destroy_workqueue(priv->workq);
+
+	input_unregister_device(priv->idev);
+	input_free_device(priv->idev);
+
+	kfree(priv);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_ts_driver = {
+	.probe		= mc13783_ts_probe,
+	.remove 	= __devexit_p(mc13783_ts_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= MC13783_TS_NAME,
+	},
+};
+
+static int __init mc13783_ts_init(void)
+{
+	return platform_driver_register(&mc13783_ts_driver);
+}
+
+static void __exit mc13783_ts_exit(void)
+{
+	platform_driver_unregister(&mc13783_ts_driver);
+}
+
+module_init(mc13783_ts_init);
+module_exit(mc13783_ts_exit);
+
+MODULE_DESCRIPTION("MC13783 input touchscreen driver");
+MODULE_AUTHOR("Sascha Hauer, <s.hauer@pengutronix.de>");
+MODULE_LICENSE("GPL");
-- 
1.6.3.3


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ:        http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette:  http://www.arm.linux.org.uk/mailinglists/etiquette.php

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/5] [hwmon] add Freescale MC13783 adc driver
  2009-08-11  8:59   ` Sascha Hauer
@ 2009-08-11  8:59     ` Sascha Hauer
  -1 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2009-08-11  8:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-arm-kernel, Sascha Hauer, Luotao Fu, Hans de Goede,
	Andrew Morton, Eric Piel, lm-sensors

From: Luotao Fu <l.fu@pengutronix.de>

This driver provides support for the ADC integrated into the
Freescale MC13783 PMIC.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Eric Piel <eric.piel@tremplin-utc.net>
Cc: lm-sensors@lm-sensors.org
---
 drivers/hwmon/Kconfig       |    6 ++
 drivers/hwmon/Makefile      |    1 +
 drivers/hwmon/mc13783-adc.c |  181 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 188 insertions(+), 0 deletions(-)
 create mode 100644 drivers/hwmon/mc13783-adc.c

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 2d50166..a7e34fd 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1017,6 +1017,12 @@ config SENSORS_APPLESMC
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of applesmc.
 
+config SENSORS_MC13783_ADC
+        tristate "Freescale MC13783 ADC"
+        depends on MFD_MC13783
+        help
+          Support for the ad converter on mc13783 pmic.
+
 config HWMON_DEBUG_CHIP
 	bool "Hardware Monitoring Chip debugging messages"
 	default n
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index b793dce..9b4e131 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -89,6 +89,7 @@ obj-$(CONFIG_SENSORS_VT8231)	+= vt8231.o
 obj-$(CONFIG_SENSORS_W83627EHF)	+= w83627ehf.o
 obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
 obj-$(CONFIG_SENSORS_W83L786NG)	+= w83l786ng.o
+obj-$(CONFIG_SENSORS_MC13783_ADC)       += mc13783-adc.o
 
 ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c
new file mode 100644
index 0000000..885c009
--- /dev/null
+++ b/drivers/hwmon/mc13783-adc.c
@@ -0,0 +1,181 @@
+/*
+ * Driver for the Freescale Semiconductor MC13783 adc.
+ *
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Sascha Hauer, Pengutronix
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/mfd/mc13783-private.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/hwmon.h>
+#include <linux/input.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#define MC13783_ADC_NAME	"mc13783-adc"
+
+struct mc13783_adc_priv {
+	struct mc13783 *mc13783;
+	struct device *hwmon_dev;
+};
+
+static ssize_t mc13783_adc_show_name(struct device *dev, struct device_attribute
+			      *devattr, char *buf)
+{
+	return sprintf(buf, "mc13783_adc\n");
+}
+
+static ssize_t mc13783_adc_read(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	unsigned int channel = attr->index;
+	unsigned int res;
+	unsigned int sample[4];
+
+	mc13783_adc_do_conversion(priv->mc13783, MC13783_ADC_MODE_MULT_CHAN,
+			channel, sample);
+
+	channel &= 0x7;
+
+	res = (sample[channel % 4] >> (channel > 3 ? 14 : 2)) & 0x3ff;
+
+	return sprintf(buf, "%u\n", res);
+}
+
+static struct sensor_device_attribute mc13783_adc_ctl[] = {
+	SENSOR_ATTR(name, S_IRUGO, mc13783_adc_show_name, NULL, 0),
+	SENSOR_ATTR(in0_input, S_IRUGO, mc13783_adc_read, NULL, 0),
+	SENSOR_ATTR(in1_input, S_IRUGO, mc13783_adc_read, NULL, 1),
+	SENSOR_ATTR(in2_input, S_IRUGO, mc13783_adc_read, NULL, 2),
+	SENSOR_ATTR(in3_input, S_IRUGO, mc13783_adc_read, NULL, 3),
+	SENSOR_ATTR(in4_input, S_IRUGO, mc13783_adc_read, NULL, 4),
+	SENSOR_ATTR(in5_input, S_IRUGO, mc13783_adc_read, NULL, 5),
+	SENSOR_ATTR(in6_input, S_IRUGO, mc13783_adc_read, NULL, 6),
+	SENSOR_ATTR(in7_input, S_IRUGO, mc13783_adc_read, NULL, 7),
+	SENSOR_ATTR(in8_input, S_IRUGO, mc13783_adc_read, NULL, 8),
+	SENSOR_ATTR(in9_input, S_IRUGO, mc13783_adc_read, NULL, 9),
+	SENSOR_ATTR(in10_input, S_IRUGO, mc13783_adc_read, NULL, 10),
+	SENSOR_ATTR(in11_input, S_IRUGO, mc13783_adc_read, NULL, 11),
+	SENSOR_ATTR(in12_input, S_IRUGO, mc13783_adc_read, NULL, 12),
+	SENSOR_ATTR(in13_input, S_IRUGO, mc13783_adc_read, NULL, 13),
+	SENSOR_ATTR(in14_input, S_IRUGO, mc13783_adc_read, NULL, 14),
+	SENSOR_ATTR(in15_input, S_IRUGO, mc13783_adc_read, NULL, 15),
+};
+
+static int __init mc13783_adc_probe(struct platform_device *pdev)
+{
+	struct mc13783_adc_priv *priv;
+	int ret, i;
+	int entries;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mc13783 = pdev->dev.platform_data;
+
+	entries = ARRAY_SIZE(mc13783_adc_ctl);
+
+	/* last four channels may be occupied by the touchscreen */
+	if (priv->mc13783->flags & MC13783_USE_TOUCHSCREEN)
+		entries -= 4;
+
+	for (i = 0; i < entries; i++) {
+		ret = device_create_file(&pdev->dev,
+				&mc13783_adc_ctl[i].dev_attr);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"device_create_file failed with %d.\n", ret);
+			goto out_err;
+		}
+	}
+
+	priv->hwmon_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(priv->hwmon_dev)) {
+		ret = PTR_ERR(priv->hwmon_dev);
+		dev_err(&pdev->dev,
+				"hwmon_device_register failed with %d.\n", ret);
+		goto out_err;
+	}
+
+	platform_set_drvdata(pdev, priv);
+
+	return 0;
+
+out_err:
+	for (i--; i >= 0; i--)
+		device_remove_file(&pdev->dev, &mc13783_adc_ctl[i].dev_attr);
+
+	kfree(priv);
+
+	return ret;
+}
+
+static int __devexit mc13783_adc_remove(struct platform_device *pdev)
+{
+	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+	int entries;
+	int i;
+
+	hwmon_device_unregister(&pdev->dev);
+
+	entries = ARRAY_SIZE(mc13783_adc_ctl);
+
+	if (priv->mc13783->flags & MC13783_USE_TOUCHSCREEN)
+		entries -= 4;
+
+	for (i = 0; i < entries; i++)
+		device_remove_file(&pdev->dev, &mc13783_adc_ctl[i].dev_attr);
+
+	kfree(priv);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_adc_driver = {
+	.probe		= mc13783_adc_probe,
+	.remove 	= __devexit_p(mc13783_adc_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= MC13783_ADC_NAME,
+	},
+};
+
+static int __init mc13783_adc_init(void)
+{
+	return platform_driver_register(&mc13783_adc_driver);
+}
+
+static void __exit mc13783_adc_exit(void)
+{
+	platform_driver_unregister(&mc13783_adc_driver);
+}
+
+module_init(mc13783_adc_init);
+module_exit(mc13783_adc_exit);
+
+MODULE_DESCRIPTION("MC13783 input touchscreen driver");
+MODULE_AUTHOR("Luotao Fu, <l.fu@pengutronix.de>");
+MODULE_LICENSE("GPL");
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [lm-sensors] [PATCH 3/5] [hwmon] add Freescale MC13783 adc driver
@ 2009-08-11  8:59     ` Sascha Hauer
  0 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2009-08-11  8:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-arm-kernel, Sascha Hauer, Luotao Fu, Hans de Goede,
	Andrew Morton, Eric Piel, lm-sensors

From: Luotao Fu <l.fu@pengutronix.de>

This driver provides support for the ADC integrated into the
Freescale MC13783 PMIC.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Eric Piel <eric.piel@tremplin-utc.net>
Cc: lm-sensors@lm-sensors.org
---
 drivers/hwmon/Kconfig       |    6 ++
 drivers/hwmon/Makefile      |    1 +
 drivers/hwmon/mc13783-adc.c |  181 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 188 insertions(+), 0 deletions(-)
 create mode 100644 drivers/hwmon/mc13783-adc.c

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 2d50166..a7e34fd 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1017,6 +1017,12 @@ config SENSORS_APPLESMC
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of applesmc.
 
+config SENSORS_MC13783_ADC
+        tristate "Freescale MC13783 ADC"
+        depends on MFD_MC13783
+        help
+          Support for the ad converter on mc13783 pmic.
+
 config HWMON_DEBUG_CHIP
 	bool "Hardware Monitoring Chip debugging messages"
 	default n
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index b793dce..9b4e131 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -89,6 +89,7 @@ obj-$(CONFIG_SENSORS_VT8231)	+= vt8231.o
 obj-$(CONFIG_SENSORS_W83627EHF)	+= w83627ehf.o
 obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
 obj-$(CONFIG_SENSORS_W83L786NG)	+= w83l786ng.o
+obj-$(CONFIG_SENSORS_MC13783_ADC)       += mc13783-adc.o
 
 ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c
new file mode 100644
index 0000000..885c009
--- /dev/null
+++ b/drivers/hwmon/mc13783-adc.c
@@ -0,0 +1,181 @@
+/*
+ * Driver for the Freescale Semiconductor MC13783 adc.
+ *
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Sascha Hauer, Pengutronix
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/mfd/mc13783-private.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/hwmon.h>
+#include <linux/input.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#define MC13783_ADC_NAME	"mc13783-adc"
+
+struct mc13783_adc_priv {
+	struct mc13783 *mc13783;
+	struct device *hwmon_dev;
+};
+
+static ssize_t mc13783_adc_show_name(struct device *dev, struct device_attribute
+			      *devattr, char *buf)
+{
+	return sprintf(buf, "mc13783_adc\n");
+}
+
+static ssize_t mc13783_adc_read(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	unsigned int channel = attr->index;
+	unsigned int res;
+	unsigned int sample[4];
+
+	mc13783_adc_do_conversion(priv->mc13783, MC13783_ADC_MODE_MULT_CHAN,
+			channel, sample);
+
+	channel &= 0x7;
+
+	res = (sample[channel % 4] >> (channel > 3 ? 14 : 2)) & 0x3ff;
+
+	return sprintf(buf, "%u\n", res);
+}
+
+static struct sensor_device_attribute mc13783_adc_ctl[] = {
+	SENSOR_ATTR(name, S_IRUGO, mc13783_adc_show_name, NULL, 0),
+	SENSOR_ATTR(in0_input, S_IRUGO, mc13783_adc_read, NULL, 0),
+	SENSOR_ATTR(in1_input, S_IRUGO, mc13783_adc_read, NULL, 1),
+	SENSOR_ATTR(in2_input, S_IRUGO, mc13783_adc_read, NULL, 2),
+	SENSOR_ATTR(in3_input, S_IRUGO, mc13783_adc_read, NULL, 3),
+	SENSOR_ATTR(in4_input, S_IRUGO, mc13783_adc_read, NULL, 4),
+	SENSOR_ATTR(in5_input, S_IRUGO, mc13783_adc_read, NULL, 5),
+	SENSOR_ATTR(in6_input, S_IRUGO, mc13783_adc_read, NULL, 6),
+	SENSOR_ATTR(in7_input, S_IRUGO, mc13783_adc_read, NULL, 7),
+	SENSOR_ATTR(in8_input, S_IRUGO, mc13783_adc_read, NULL, 8),
+	SENSOR_ATTR(in9_input, S_IRUGO, mc13783_adc_read, NULL, 9),
+	SENSOR_ATTR(in10_input, S_IRUGO, mc13783_adc_read, NULL, 10),
+	SENSOR_ATTR(in11_input, S_IRUGO, mc13783_adc_read, NULL, 11),
+	SENSOR_ATTR(in12_input, S_IRUGO, mc13783_adc_read, NULL, 12),
+	SENSOR_ATTR(in13_input, S_IRUGO, mc13783_adc_read, NULL, 13),
+	SENSOR_ATTR(in14_input, S_IRUGO, mc13783_adc_read, NULL, 14),
+	SENSOR_ATTR(in15_input, S_IRUGO, mc13783_adc_read, NULL, 15),
+};
+
+static int __init mc13783_adc_probe(struct platform_device *pdev)
+{
+	struct mc13783_adc_priv *priv;
+	int ret, i;
+	int entries;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mc13783 = pdev->dev.platform_data;
+
+	entries = ARRAY_SIZE(mc13783_adc_ctl);
+
+	/* last four channels may be occupied by the touchscreen */
+	if (priv->mc13783->flags & MC13783_USE_TOUCHSCREEN)
+		entries -= 4;
+
+	for (i = 0; i < entries; i++) {
+		ret = device_create_file(&pdev->dev,
+				&mc13783_adc_ctl[i].dev_attr);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"device_create_file failed with %d.\n", ret);
+			goto out_err;
+		}
+	}
+
+	priv->hwmon_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(priv->hwmon_dev)) {
+		ret = PTR_ERR(priv->hwmon_dev);
+		dev_err(&pdev->dev,
+				"hwmon_device_register failed with %d.\n", ret);
+		goto out_err;
+	}
+
+	platform_set_drvdata(pdev, priv);
+
+	return 0;
+
+out_err:
+	for (i--; i >= 0; i--)
+		device_remove_file(&pdev->dev, &mc13783_adc_ctl[i].dev_attr);
+
+	kfree(priv);
+
+	return ret;
+}
+
+static int __devexit mc13783_adc_remove(struct platform_device *pdev)
+{
+	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+	int entries;
+	int i;
+
+	hwmon_device_unregister(&pdev->dev);
+
+	entries = ARRAY_SIZE(mc13783_adc_ctl);
+
+	if (priv->mc13783->flags & MC13783_USE_TOUCHSCREEN)
+		entries -= 4;
+
+	for (i = 0; i < entries; i++)
+		device_remove_file(&pdev->dev, &mc13783_adc_ctl[i].dev_attr);
+
+	kfree(priv);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_adc_driver = {
+	.probe		= mc13783_adc_probe,
+	.remove 	= __devexit_p(mc13783_adc_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= MC13783_ADC_NAME,
+	},
+};
+
+static int __init mc13783_adc_init(void)
+{
+	return platform_driver_register(&mc13783_adc_driver);
+}
+
+static void __exit mc13783_adc_exit(void)
+{
+	platform_driver_unregister(&mc13783_adc_driver);
+}
+
+module_init(mc13783_adc_init);
+module_exit(mc13783_adc_exit);
+
+MODULE_DESCRIPTION("MC13783 input touchscreen driver");
+MODULE_AUTHOR("Luotao Fu, <l.fu@pengutronix.de>");
+MODULE_LICENSE("GPL");
-- 
1.6.3.3


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver
  2009-08-11  8:59     ` [lm-sensors] " Sascha Hauer
  (?)
@ 2009-08-11  8:59     ` Sascha Hauer
  2009-08-11  8:59       ` [PATCH 5/5] [regulator] Add a Freescale MC13783 regulator driver Sascha Hauer
  2009-08-12  9:41       ` [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver Alessandro Zummo
  -1 siblings, 2 replies; 10+ messages in thread
From: Sascha Hauer @ 2009-08-11  8:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-arm-kernel, Sascha Hauer, Paul Gortmaker, Alessandro Zummo,
	rtc-linux

This driver provides support for the RTC part integrated into
the Freescale MC13783 PMIC.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Paul Gortmaker <p_gortmaker@yahoo.com>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: rtc-linux@googlegroups.com
---
 drivers/rtc/Kconfig       |    6 ++
 drivers/rtc/Makefile      |    1 +
 drivers/rtc/rtc-mc13783.c |  141 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 148 insertions(+), 0 deletions(-)
 create mode 100644 drivers/rtc/rtc-mc13783.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 81adbdb..e4a242f 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -759,4 +759,10 @@ config RTC_DRV_PS3
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-ps3.
 
+config RTC_DRV_MC13783
+	depends on MFD_MC13783
+	tristate "Freescale MC13783 RTC"
+	help
+	  This enables support for the Freescale MC13783 PMIC RTC
+
 endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 3c0f2b2..00bf66d 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -78,3 +78,4 @@ obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o
 obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
 obj-$(CONFIG_RTC_DRV_PCF50633)	+= rtc-pcf50633.o
 obj-$(CONFIG_RTC_DRV_PS3)	+= rtc-ps3.o
+obj-$(CONFIG_RTC_DRV_MC13783)	+= rtc-mc13783.o
diff --git a/drivers/rtc/rtc-mc13783.c b/drivers/rtc/rtc-mc13783.c
new file mode 100644
index 0000000..d1f1192
--- /dev/null
+++ b/drivers/rtc/rtc-mc13783.c
@@ -0,0 +1,141 @@
+/*
+ * Real Time Clock driver for Freescale MC13783 PMIC
+ *
+ * (C) 2009 Sascha Hauer, Pengutronix
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/mfd/mc13783-private.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/ioctl.h>
+#include <linux/time.h>
+#include <linux/rtc.h>
+
+struct mc13783_rtc {
+	struct rtc_device *rtc;
+	struct mc13783 *mc13783;
+};
+
+static int mc13783_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct mc13783_rtc *priv = dev_get_drvdata(dev);
+	unsigned int seconds, days;
+	unsigned long s1970;
+
+	rtc_tm_to_time(tm, &s1970);
+
+	seconds = s1970 % 86400;
+	days = s1970 / 86400;
+
+	mc13783_reg_write(priv->mc13783, MC13783_REG_RTC_TIME, seconds);
+	mc13783_reg_write(priv->mc13783, MC13783_REG_RTC_DAY, days);
+
+	return 0;
+}
+
+static int mc13783_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct mc13783_rtc *priv = dev_get_drvdata(dev);
+	unsigned int seconds, days1, days2;
+	unsigned long s1970;
+
+	rtc_tm_to_time(tm, &s1970);
+
+	do {
+		mc13783_reg_read(priv->mc13783, MC13783_REG_RTC_TIME, &seconds);
+		mc13783_reg_read(priv->mc13783, MC13783_REG_RTC_DAY, &days1);
+		mc13783_reg_read(priv->mc13783, MC13783_REG_RTC_DAY, &days2);
+	} while (days1 != days2);
+
+	s1970 = days1 * 86400 + seconds;
+
+	rtc_time_to_tm(s1970, tm);
+
+	return 0;
+}
+
+static const struct rtc_class_ops mc13783_rtc_ops = {
+	.read_time	= mc13783_rtc_read_time,
+	.set_time	= mc13783_rtc_set_time,
+};
+
+static int mc13783_rtc_probe(struct platform_device *pdev)
+{
+	int err;
+	struct mc13783_rtc *priv;
+
+	priv = kzalloc(sizeof *priv, GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mc13783 = pdev->dev.platform_data;
+	platform_set_drvdata(pdev, priv);
+
+	priv->rtc = rtc_device_register(pdev->name,
+			&pdev->dev, &mc13783_rtc_ops, THIS_MODULE);
+
+	if (IS_ERR(priv->rtc)) {
+		err = PTR_ERR(priv->rtc);
+		goto exit_kfree;
+	}
+
+	return 0;
+
+exit_kfree:
+	kfree(priv);
+	return err;
+}
+
+static int __exit mc13783_rtc_remove(struct platform_device *pdev)
+{
+	struct mc13783_rtc *priv = platform_get_drvdata(pdev);
+
+	rtc_device_unregister(priv->rtc);
+	platform_set_drvdata(pdev, NULL);
+
+	kfree(priv);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_rtc_driver = {
+	.probe		 = mc13783_rtc_probe,
+	.remove		= __exit_p(mc13783_rtc_remove),
+	.driver = {
+		.name	= "mc13783-rtc",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init mc13783_rtc_init(void)
+{
+	return platform_driver_register(&mc13783_rtc_driver);
+}
+module_init(mc13783_rtc_init);
+
+static void __exit mc13783_rtc_exit(void)
+{
+	platform_driver_unregister(&mc13783_rtc_driver);
+}
+module_exit(mc13783_rtc_exit);
+
+
+MODULE_AUTHOR("Sascha Hauer");
+MODULE_DESCRIPTION("RTC driver for Freescale MC13783 PMIC");
+MODULE_LICENSE("GPL");
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/5] [regulator] Add a Freescale MC13783 regulator driver
  2009-08-11  8:59     ` [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver Sascha Hauer
@ 2009-08-11  8:59       ` Sascha Hauer
  2009-08-12  9:41       ` [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver Alessandro Zummo
  1 sibling, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2009-08-11  8:59 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-arm-kernel, Sascha Hauer, Mark Brown, Liam Girdwood

This driver provides basic support for the voltage regulators
integrated into the Freescale MC13783 PMIC. It is currently
only possible to enable/disable outputs, not to actually
set the voltage.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Liam Girdwood <lrg@slimlogic.co.uk>
---
 drivers/regulator/Kconfig   |    8 +
 drivers/regulator/Makefile  |    1 +
 drivers/regulator/mc13783.c |  410 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 419 insertions(+), 0 deletions(-)
 create mode 100644 drivers/regulator/mc13783.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index f431779..69197e9 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -117,4 +117,12 @@ config REGULATOR_LP3971
 	 Say Y here to support the voltage regulators and convertors
 	 on National Semiconductors LP3971 PMIC
 
+config REGULATOR_MC13783
+	tristate "Support regulators on Freescale MC13783 PMIC"
+	depends on MFD_MC13783
+	help
+	  Say y here to support the regulators found on the Freescale MC13783
+	  PMIC.
+
 endif
+
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 4d762c4..6d45846 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -16,5 +16,6 @@ obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
 obj-$(CONFIG_REGULATOR_DA903X)	+= da903x.o
 obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
+obj-$(CONFIG_REGULATOR_MC13783) += mc13783.o
 
 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/mc13783.c b/drivers/regulator/mc13783.c
new file mode 100644
index 0000000..2bf8e6a
--- /dev/null
+++ b/drivers/regulator/mc13783.c
@@ -0,0 +1,410 @@
+/*
+ * Regulator Driver for Freescale MC13783 PMIC
+ *
+ * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * 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/mfd/mc13783-private.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+
+struct mc13783_regulator {
+	struct regulator_desc desc;
+	int reg;
+	int enable_bit;
+};
+
+static struct regulator_ops mc13783_regulator_ops;
+
+static struct mc13783_regulator mc13783_regulators[] = {
+	[SW_SW3] = {
+		.desc = {
+			.name	= "SW_SW3",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VMMC1,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_SWITCHERS_5,
+		.enable_bit = MC13783_SWCTRL_SW3_EN,
+	},
+	[SW_PLL] = {
+		.desc = {
+			.name	= "SW_PLL",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= SW_PLL,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_SWITCHERS_4,
+		.enable_bit = MC13783_SWCTRL_PLL_EN,
+	},
+	[REGU_VAUDIO] = {
+		.desc = {
+			.name	= "REGU_VAUDIO",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VAUDIO,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VAUDIO_EN,
+	},
+	[REGU_VIOHI] = {
+		.desc = {
+			.name	= "REGU_VIOHI",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VIOHI,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VIOHI_EN,
+	},
+	[REGU_VIOLO] = {
+		.desc = {
+			.name	= "REGU_VIOLO",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VIOLO,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VIOLO_EN,
+	},
+	[REGU_VDIG] = {
+		.desc = {
+			.name	= "REGU_VDIG",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VDIG,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VDIG_EN,
+	},
+	[REGU_VGEN] = {
+		.desc = {
+			.name	= "REGU_VGEN",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VGEN,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VGEN_EN,
+	},
+	[REGU_VRFDIG] = {
+		.desc = {
+			.name	= "REGU_VRFDIG",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VRFDIG,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VRFDIG_EN,
+	},
+	[REGU_VRFREF] = {
+		.desc = {
+			.name	= "REGU_VRFREF",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VRFDIG,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VRFREF_EN,
+	},
+	[REGU_VRFCP] = {
+		.desc = {
+			.name	= "REGU_VRFCP",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VRFCP,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VRFCP_EN,
+	},
+	[REGU_VSIM] = {
+		.desc = {
+			.name	= "REGU_VSIM",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VSIM,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VSIM_EN,
+	},
+	[REGU_VESIM] = {
+		.desc = {
+			.name	= "REGU_VESIM",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VESIM,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VESIM_EN,
+	},
+	[REGU_VCAM] = {
+		.desc = {
+			.name	= "REGU_VCAM",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VCAM,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VCAM_EN,
+	},
+	[REGU_VRFBG] = {
+		.desc = {
+			.name	= "REGU_VRFBG",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VRFBG,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VRFBG_EN,
+	},
+	[REGU_VVIB] = {
+		.desc = {
+			.name	= "REGU_VVIB",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VVIB,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VVIB_EN,
+	},
+	[REGU_VRF1] = {
+		.desc = {
+			.name	= "REGU_VRF1",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VRF1,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VRF1_EN,
+	},
+	[REGU_VRF2] = {
+		.desc = {
+			.name	= "REGU_VRF2",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VRF1,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VRF2_EN,
+	},
+	[REGU_VMMC1] = {
+		.desc = {
+			.name	= "REGU_VMMC1",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VMMC1,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VMMC1_EN,
+	},
+	[REGU_VMMC2] = {
+		.desc = {
+			.name	= "REGU_VMMC2",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_VMMC2,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VMMC2_EN,
+	},
+	[REGU_GPO1] = {
+		.desc = {
+			.name	= "REGU_GPO1",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_GPO1,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_POWER_MISCELLANEOUS,
+		.enable_bit = MC13783_REGCTRL_GPO1_EN,
+	},
+	[REGU_GPO2] = {
+		.desc = {
+			.name	= "REGU_GPO2",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_GPO2,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_POWER_MISCELLANEOUS,
+		.enable_bit = MC13783_REGCTRL_GPO2_EN,
+	},
+	[REGU_GPO3] = {
+		.desc = {
+			.name	= "REGU_GPO3",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_GPO3,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_POWER_MISCELLANEOUS,
+		.enable_bit = MC13783_REGCTRL_GPO3_EN,
+	},
+	[REGU_GPO4] = {
+		.desc = {
+			.name	= "REGU_GPO4",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= REGU_GPO4,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_POWER_MISCELLANEOUS,
+		.enable_bit = MC13783_REGCTRL_GPO4_EN,
+	},
+};
+
+struct mc13783_priv {
+	struct regulator_desc desc[ARRAY_SIZE(mc13783_regulators)];
+	struct mc13783 *mc13783;
+	struct regulator_dev *regulators[0];
+};
+
+static int mc13783_enable(struct regulator_dev *rdev)
+{
+	struct mc13783_priv *priv = rdev_get_drvdata(rdev);
+	int id = rdev_get_id(rdev);
+
+	dev_info(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+	return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg,
+			mc13783_regulators[id].enable_bit,
+			mc13783_regulators[id].enable_bit);
+}
+
+static int mc13783_disable(struct regulator_dev *rdev)
+{
+	struct mc13783_priv *priv = rdev_get_drvdata(rdev);
+	int id = rdev_get_id(rdev);
+
+	dev_info(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+	return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg,
+			mc13783_regulators[id].enable_bit, 0);
+}
+
+static int mc13783_is_enabled(struct regulator_dev *rdev)
+{
+	struct mc13783_priv *priv = rdev_get_drvdata(rdev);
+	int ret, id = rdev_get_id(rdev);
+	unsigned int val;
+
+	ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val);
+	if (ret)
+		return ret;
+
+	return (val & mc13783_regulators[id].enable_bit) != 0;
+}
+
+static struct regulator_ops mc13783_regulator_ops = {
+	.enable		= mc13783_enable,
+	.disable	= mc13783_disable,
+	.is_enabled	= mc13783_is_enabled,
+};
+
+static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
+{
+	struct mc13783_priv *priv;
+	struct mc13783 *mc13783 = pdev->dev.platform_data;
+	struct mc13783_regulator_init_data *init_data;
+	int i, ret;
+
+	dev_info(&pdev->dev, "mc13783_regulator_probe id %d\n", pdev->id);
+
+	priv = kzalloc(sizeof(*priv) + mc13783->num_regulators * sizeof(void *),
+			GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mc13783 = mc13783;
+
+	for (i = 0; i < mc13783->num_regulators; i++) {
+		init_data = &mc13783->regulators[i];
+		priv->regulators[i] = regulator_register(
+				&mc13783_regulators[init_data->id].desc,
+				&pdev->dev, init_data->init_data, priv);
+
+		if (IS_ERR(priv->regulators[i])) {
+			dev_err(&pdev->dev, "failed to register regulator %s\n",
+				mc13783_regulators[i].desc.name);
+			ret = PTR_ERR(priv->regulators[i]);
+			goto err;
+		}
+	}
+
+	platform_set_drvdata(pdev, priv);
+
+	return 0;
+err:
+	while (--i >= 0)
+		regulator_unregister(priv->regulators[i]);
+
+	kfree(priv);
+
+	return ret;
+}
+
+static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
+{
+	struct mc13783_priv *priv = platform_get_drvdata(pdev);
+	struct mc13783 *mc13783 = priv->mc13783;
+	int i;
+
+	for (i = 0; i < mc13783->num_regulators; i++)
+		regulator_unregister(priv->regulators[i]);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_regulator_driver = {
+	.driver	= {
+		.name	= "mc13783-regulator",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= mc13783_regulator_probe,
+	.remove		= mc13783_regulator_remove,
+};
+
+static int __init mc13783_regulator_init(void)
+{
+	return platform_driver_register(&mc13783_regulator_driver);
+}
+module_init(mc13783_regulator_init);
+
+static void __exit mc13783_regulator_exit(void)
+{
+	platform_driver_unregister(&mc13783_regulator_driver);
+}
+module_exit(mc13783_regulator_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
+MODULE_DESCRIPTION("Regulator Driver for Freescale MC13783 PMIC");
+MODULE_ALIAS("platform:mc13783-regulator");
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver
  2009-08-11  8:59     ` [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver Sascha Hauer
  2009-08-11  8:59       ` [PATCH 5/5] [regulator] Add a Freescale MC13783 regulator driver Sascha Hauer
@ 2009-08-12  9:41       ` Alessandro Zummo
  2009-08-12 11:39         ` Sascha Hauer
  1 sibling, 1 reply; 10+ messages in thread
From: Alessandro Zummo @ 2009-08-12  9:41 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: linux-kernel, linux-arm-kernel, Sascha Hauer, Paul Gortmaker, rtc-linux

On Tue, 11 Aug 2009 10:59:25 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> This driver provides support for the RTC part integrated into
> the Freescale MC13783 PMIC.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Paul Gortmaker <p_gortmaker@yahoo.com>
> Cc: Alessandro Zummo <a.zummo@towertech.it>
> Cc: rtc-linux@googlegroups.com


 thanks for your submission, comments below

> ---
>  drivers/rtc/Kconfig       |    6 ++
>  drivers/rtc/Makefile      |    1 +
>  drivers/rtc/rtc-mc13783.c |  141 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 148 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/rtc/rtc-mc13783.c
> 
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 81adbdb..e4a242f 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -759,4 +759,10 @@ config RTC_DRV_PS3
>  	  This driver can also be built as a module. If so, the module
>  	  will be called rtc-ps3.
>  
> +config RTC_DRV_MC13783
> +	depends on MFD_MC13783
> +	tristate "Freescale MC13783 RTC"
> +	help
> +	  This enables support for the Freescale MC13783 PMIC RTC
> +
>  endif # RTC_CLASS
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index 3c0f2b2..00bf66d 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -78,3 +78,4 @@ obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o
>  obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
>  obj-$(CONFIG_RTC_DRV_PCF50633)	+= rtc-pcf50633.o
>  obj-$(CONFIG_RTC_DRV_PS3)	+= rtc-ps3.o
> +obj-$(CONFIG_RTC_DRV_MC13783)	+= rtc-mc13783.o

 keep in in alphabetic order.

> diff --git a/drivers/rtc/rtc-mc13783.c b/drivers/rtc/rtc-mc13783.c
> new file mode 100644
> index 0000000..d1f1192
> --- /dev/null
> +++ b/drivers/rtc/rtc-mc13783.c
> @@ -0,0 +1,141 @@
> +/*
> + * Real Time Clock driver for Freescale MC13783 PMIC
> + *
> + * (C) 2009 Sascha Hauer, Pengutronix
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#include <linux/mfd/mc13783-private.h>
> +#include <linux/platform_device.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/ioctl.h>
> +#include <linux/time.h>
> +#include <linux/rtc.h>

 too many includes?

> +
> +struct mc13783_rtc {
> +	struct rtc_device *rtc;
> +	struct mc13783 *mc13783;
> +};
> +
> +static int mc13783_rtc_set_time(struct device *dev, struct rtc_time *tm)

 please implement set_mmss instad of set_time

> +	struct mc13783_rtc *priv = dev_get_drvdata(dev);
> +	unsigned int seconds, days;
> +	unsigned long s1970;
> +
> +	rtc_tm_to_time(tm, &s1970);
> +
> +	seconds = s1970 % 86400;
> +	days = s1970 / 86400;
> +
> +	mc13783_reg_write(priv->mc13783, MC13783_REG_RTC_TIME, seconds);
> +	mc13783_reg_write(priv->mc13783, MC13783_REG_RTC_DAY, days);
> +
> +	return 0;
> +}
> +
> +static int mc13783_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct mc13783_rtc *priv = dev_get_drvdata(dev);
> +	unsigned int seconds, days1, days2;
> +	unsigned long s1970;
> +
> +	rtc_tm_to_time(tm, &s1970);
> +
> +	do {
> +		mc13783_reg_read(priv->mc13783, MC13783_REG_RTC_TIME, &seconds);
> +		mc13783_reg_read(priv->mc13783, MC13783_REG_RTC_DAY, &days1);
> +		mc13783_reg_read(priv->mc13783, MC13783_REG_RTC_DAY, &days2);
> +	} while (days1 != days2);
> +
> +	s1970 = days1 * 86400 + seconds;
> +
> +	rtc_time_to_tm(s1970, tm);
> +
> +	return 0;

 use rtc_valid_tm

> +}
> +
> +static const struct rtc_class_ops mc13783_rtc_ops = {
> +	.read_time	= mc13783_rtc_read_time,
> +	.set_time	= mc13783_rtc_set_time,
> +};
> +
> +static int mc13783_rtc_probe(struct platform_device *pdev)
> +{
> +	int err;
> +	struct mc13783_rtc *priv;
> +
> +	priv = kzalloc(sizeof *priv, GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->mc13783 = pdev->dev.platform_data;
> +	platform_set_drvdata(pdev, priv);
> +
> +	priv->rtc = rtc_device_register(pdev->name,
> +			&pdev->dev, &mc13783_rtc_ops, THIS_MODULE);
> +
> +	if (IS_ERR(priv->rtc)) {
> +		err = PTR_ERR(priv->rtc);
> +		goto exit_kfree;
> +	}
> +
> +	return 0;
> +
> +exit_kfree:
> +	kfree(priv);
> +	return err;
> +}
> +
> +static int __exit mc13783_rtc_remove(struct platform_device *pdev)
> +{
> +	struct mc13783_rtc *priv = platform_get_drvdata(pdev);
> +
> +	rtc_device_unregister(priv->rtc);
> +	platform_set_drvdata(pdev, NULL);
> +
> +	kfree(priv);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver mc13783_rtc_driver = {
> +	.probe		 = mc13783_rtc_probe,
> +	.remove		= __exit_p(mc13783_rtc_remove),
> +	.driver = {
> +		.name	= "mc13783-rtc",
> +		.owner	= THIS_MODULE,
> +	},
> +};
> +
> +static int __init mc13783_rtc_init(void)
> +{
> +	return platform_driver_register(&mc13783_rtc_driver);

 can you use platform_driver_probe?

> +}
> +module_init(mc13783_rtc_init);
> +
> +static void __exit mc13783_rtc_exit(void)
> +{
> +	platform_driver_unregister(&mc13783_rtc_driver);
> +}
> +module_exit(mc13783_rtc_exit);
> +
> +
> +MODULE_AUTHOR("Sascha Hauer");

 email here please.

> +MODULE_DESCRIPTION("RTC driver for Freescale MC13783 PMIC");
> +MODULE_LICENSE("GPL");
> -- 
> 1.6.3.3
> 


-- 

 Best regards,

 Alessandro Zummo,
  Tower Technologies - Torino, Italy

  http://www.towertech.it


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver
  2009-08-12  9:41       ` [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver Alessandro Zummo
@ 2009-08-12 11:39         ` Sascha Hauer
  0 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2009-08-12 11:39 UTC (permalink / raw)
  To: Alessandro Zummo
  Cc: linux-kernel, linux-arm-kernel, Paul Gortmaker, rtc-linux

Hi Allessandro,

I addressed your comments. Will be fixed next round.

Thanks for reviewing,

 Sascha

On Wed, Aug 12, 2009 at 11:41:34AM +0200, Alessandro Zummo wrote:
> On Tue, 11 Aug 2009 10:59:25 +0200
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > This driver provides support for the RTC part integrated into
> > the Freescale MC13783 PMIC.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > Cc: Paul Gortmaker <p_gortmaker@yahoo.com>
> > Cc: Alessandro Zummo <a.zummo@towertech.it>
> > Cc: rtc-linux@googlegroups.com
> 
> 
>  thanks for your submission, comments below
> 
> > ---
> >  drivers/rtc/Kconfig       |    6 ++
> >  drivers/rtc/Makefile      |    1 +
> >  drivers/rtc/rtc-mc13783.c |  141 +++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 148 insertions(+), 0 deletions(-)
> >  create mode 100644 drivers/rtc/rtc-mc13783.c
> > 
> > diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> > index 81adbdb..e4a242f 100644
> > --- a/drivers/rtc/Kconfig
> > +++ b/drivers/rtc/Kconfig
> > @@ -759,4 +759,10 @@ config RTC_DRV_PS3
> >  	  This driver can also be built as a module. If so, the module
> >  	  will be called rtc-ps3.
> >  
> > +config RTC_DRV_MC13783
> > +	depends on MFD_MC13783
> > +	tristate "Freescale MC13783 RTC"
> > +	help
> > +	  This enables support for the Freescale MC13783 PMIC RTC
> > +
> >  endif # RTC_CLASS
> > diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> > index 3c0f2b2..00bf66d 100644
> > --- a/drivers/rtc/Makefile
> > +++ b/drivers/rtc/Makefile
> > @@ -78,3 +78,4 @@ obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o
> >  obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
> >  obj-$(CONFIG_RTC_DRV_PCF50633)	+= rtc-pcf50633.o
> >  obj-$(CONFIG_RTC_DRV_PS3)	+= rtc-ps3.o
> > +obj-$(CONFIG_RTC_DRV_MC13783)	+= rtc-mc13783.o
> 
>  keep in in alphabetic order.
> 
> > diff --git a/drivers/rtc/rtc-mc13783.c b/drivers/rtc/rtc-mc13783.c
> > new file mode 100644
> > index 0000000..d1f1192
> > --- /dev/null
> > +++ b/drivers/rtc/rtc-mc13783.c
> > @@ -0,0 +1,141 @@
> > +/*
> > + * Real Time Clock driver for Freescale MC13783 PMIC
> > + *
> > + * (C) 2009 Sascha Hauer, Pengutronix
> > + *
> > + * 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.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write to the Free Software
> > + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> > + */
> > +
> > +#include <linux/mfd/mc13783-private.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/ioctl.h>
> > +#include <linux/time.h>
> > +#include <linux/rtc.h>
> 
>  too many includes?
> 
> > +
> > +struct mc13783_rtc {
> > +	struct rtc_device *rtc;
> > +	struct mc13783 *mc13783;
> > +};
> > +
> > +static int mc13783_rtc_set_time(struct device *dev, struct rtc_time *tm)
> 
>  please implement set_mmss instad of set_time
> 
> > +	struct mc13783_rtc *priv = dev_get_drvdata(dev);
> > +	unsigned int seconds, days;
> > +	unsigned long s1970;
> > +
> > +	rtc_tm_to_time(tm, &s1970);
> > +
> > +	seconds = s1970 % 86400;
> > +	days = s1970 / 86400;
> > +
> > +	mc13783_reg_write(priv->mc13783, MC13783_REG_RTC_TIME, seconds);
> > +	mc13783_reg_write(priv->mc13783, MC13783_REG_RTC_DAY, days);
> > +
> > +	return 0;
> > +}
> > +
> > +static int mc13783_rtc_read_time(struct device *dev, struct rtc_time *tm)
> > +{
> > +	struct mc13783_rtc *priv = dev_get_drvdata(dev);
> > +	unsigned int seconds, days1, days2;
> > +	unsigned long s1970;
> > +
> > +	rtc_tm_to_time(tm, &s1970);
> > +
> > +	do {
> > +		mc13783_reg_read(priv->mc13783, MC13783_REG_RTC_TIME, &seconds);
> > +		mc13783_reg_read(priv->mc13783, MC13783_REG_RTC_DAY, &days1);
> > +		mc13783_reg_read(priv->mc13783, MC13783_REG_RTC_DAY, &days2);
> > +	} while (days1 != days2);
> > +
> > +	s1970 = days1 * 86400 + seconds;
> > +
> > +	rtc_time_to_tm(s1970, tm);
> > +
> > +	return 0;
> 
>  use rtc_valid_tm
> 
> > +}
> > +
> > +static const struct rtc_class_ops mc13783_rtc_ops = {
> > +	.read_time	= mc13783_rtc_read_time,
> > +	.set_time	= mc13783_rtc_set_time,
> > +};
> > +
> > +static int mc13783_rtc_probe(struct platform_device *pdev)
> > +{
> > +	int err;
> > +	struct mc13783_rtc *priv;
> > +
> > +	priv = kzalloc(sizeof *priv, GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	priv->mc13783 = pdev->dev.platform_data;
> > +	platform_set_drvdata(pdev, priv);
> > +
> > +	priv->rtc = rtc_device_register(pdev->name,
> > +			&pdev->dev, &mc13783_rtc_ops, THIS_MODULE);
> > +
> > +	if (IS_ERR(priv->rtc)) {
> > +		err = PTR_ERR(priv->rtc);
> > +		goto exit_kfree;
> > +	}
> > +
> > +	return 0;
> > +
> > +exit_kfree:
> > +	kfree(priv);
> > +	return err;
> > +}
> > +
> > +static int __exit mc13783_rtc_remove(struct platform_device *pdev)
> > +{
> > +	struct mc13783_rtc *priv = platform_get_drvdata(pdev);
> > +
> > +	rtc_device_unregister(priv->rtc);
> > +	platform_set_drvdata(pdev, NULL);
> > +
> > +	kfree(priv);
> > +
> > +	return 0;
> > +}
> > +
> > +static struct platform_driver mc13783_rtc_driver = {
> > +	.probe		 = mc13783_rtc_probe,
> > +	.remove		= __exit_p(mc13783_rtc_remove),
> > +	.driver = {
> > +		.name	= "mc13783-rtc",
> > +		.owner	= THIS_MODULE,
> > +	},
> > +};
> > +
> > +static int __init mc13783_rtc_init(void)
> > +{
> > +	return platform_driver_register(&mc13783_rtc_driver);
> 
>  can you use platform_driver_probe?
> 
> > +}
> > +module_init(mc13783_rtc_init);
> > +
> > +static void __exit mc13783_rtc_exit(void)
> > +{
> > +	platform_driver_unregister(&mc13783_rtc_driver);
> > +}
> > +module_exit(mc13783_rtc_exit);
> > +
> > +
> > +MODULE_AUTHOR("Sascha Hauer");
> 
>  email here please.
> 
> > +MODULE_DESCRIPTION("RTC driver for Freescale MC13783 PMIC");
> > +MODULE_LICENSE("GPL");
> > -- 
> > 1.6.3.3
> > 
> 
> 
> -- 
> 
>  Best regards,
> 
>  Alessandro Zummo,
>   Tower Technologies - Torino, Italy
> 
>   http://www.towertech.it
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 3/5] [hwmon] add Freescale MC13783 adc driver
  2009-08-12 15:05   ` [PATCH 2/5] [input] add mc13783 touchscreen driver Sascha Hauer
@ 2009-08-12 15:05     ` Sascha Hauer
  0 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2009-08-12 15:05 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-arm-kernel, Sascha Hauer, Luotao Fu, Hans de Goede,
	Andrew Morton, Eric Piel, lm-sensors

From: Luotao Fu <l.fu@pengutronix.de>

This driver provides support for the ADC integrated into the
Freescale MC13783 PMIC.

Changes since v1:

- add MODULE_ALIAS
- __init -> __devinit in probe function
- use platform_driver_probe instead of platform_driver_register

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Eric Piel <eric.piel@tremplin-utc.net>
Cc: lm-sensors@lm-sensors.org
---
 drivers/hwmon/Kconfig       |    6 ++
 drivers/hwmon/Makefile      |    1 +
 drivers/hwmon/mc13783-adc.c |  181 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 188 insertions(+), 0 deletions(-)
 create mode 100644 drivers/hwmon/mc13783-adc.c

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 2d50166..a7e34fd 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1017,6 +1017,12 @@ config SENSORS_APPLESMC
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of applesmc.
 
+config SENSORS_MC13783_ADC
+        tristate "Freescale MC13783 ADC"
+        depends on MFD_MC13783
+        help
+          Support for the ad converter on mc13783 pmic.
+
 config HWMON_DEBUG_CHIP
 	bool "Hardware Monitoring Chip debugging messages"
 	default n
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index b793dce..9b4e131 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -89,6 +89,7 @@ obj-$(CONFIG_SENSORS_VT8231)	+= vt8231.o
 obj-$(CONFIG_SENSORS_W83627EHF)	+= w83627ehf.o
 obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
 obj-$(CONFIG_SENSORS_W83L786NG)	+= w83l786ng.o
+obj-$(CONFIG_SENSORS_MC13783_ADC)       += mc13783-adc.o
 
 ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c
new file mode 100644
index 0000000..87168f9
--- /dev/null
+++ b/drivers/hwmon/mc13783-adc.c
@@ -0,0 +1,181 @@
+/*
+ * Driver for the Freescale Semiconductor MC13783 adc.
+ *
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Sascha Hauer, Pengutronix
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/mfd/mc13783-private.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/hwmon.h>
+#include <linux/input.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#define MC13783_ADC_NAME	"mc13783-adc"
+
+struct mc13783_adc_priv {
+	struct mc13783 *mc13783;
+	struct device *hwmon_dev;
+};
+
+static ssize_t mc13783_adc_show_name(struct device *dev, struct device_attribute
+			      *devattr, char *buf)
+{
+	return sprintf(buf, "mc13783_adc\n");
+}
+
+static ssize_t mc13783_adc_read(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	unsigned int channel = attr->index;
+	unsigned int res;
+	unsigned int sample[4];
+
+	mc13783_adc_do_conversion(priv->mc13783, MC13783_ADC_MODE_MULT_CHAN,
+			channel, sample);
+
+	channel &= 0x7;
+
+	res = (sample[channel % 4] >> (channel > 3 ? 14 : 2)) & 0x3ff;
+
+	return sprintf(buf, "%u\n", res);
+}
+
+static struct sensor_device_attribute mc13783_adc_ctl[] = {
+	SENSOR_ATTR(name, S_IRUGO, mc13783_adc_show_name, NULL, 0),
+	SENSOR_ATTR(in0_input, S_IRUGO, mc13783_adc_read, NULL, 0),
+	SENSOR_ATTR(in1_input, S_IRUGO, mc13783_adc_read, NULL, 1),
+	SENSOR_ATTR(in2_input, S_IRUGO, mc13783_adc_read, NULL, 2),
+	SENSOR_ATTR(in3_input, S_IRUGO, mc13783_adc_read, NULL, 3),
+	SENSOR_ATTR(in4_input, S_IRUGO, mc13783_adc_read, NULL, 4),
+	SENSOR_ATTR(in5_input, S_IRUGO, mc13783_adc_read, NULL, 5),
+	SENSOR_ATTR(in6_input, S_IRUGO, mc13783_adc_read, NULL, 6),
+	SENSOR_ATTR(in7_input, S_IRUGO, mc13783_adc_read, NULL, 7),
+	SENSOR_ATTR(in8_input, S_IRUGO, mc13783_adc_read, NULL, 8),
+	SENSOR_ATTR(in9_input, S_IRUGO, mc13783_adc_read, NULL, 9),
+	SENSOR_ATTR(in10_input, S_IRUGO, mc13783_adc_read, NULL, 10),
+	SENSOR_ATTR(in11_input, S_IRUGO, mc13783_adc_read, NULL, 11),
+	SENSOR_ATTR(in12_input, S_IRUGO, mc13783_adc_read, NULL, 12),
+	SENSOR_ATTR(in13_input, S_IRUGO, mc13783_adc_read, NULL, 13),
+	SENSOR_ATTR(in14_input, S_IRUGO, mc13783_adc_read, NULL, 14),
+	SENSOR_ATTR(in15_input, S_IRUGO, mc13783_adc_read, NULL, 15),
+};
+
+static int __devinit mc13783_adc_probe(struct platform_device *pdev)
+{
+	struct mc13783_adc_priv *priv;
+	int ret, i;
+	int entries;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mc13783 = dev_get_drvdata(pdev->dev.parent);
+
+	entries = ARRAY_SIZE(mc13783_adc_ctl);
+
+	/* last four channels may be occupied by the touchscreen */
+	if (priv->mc13783->flags & MC13783_USE_TOUCHSCREEN)
+		entries -= 4;
+
+	for (i = 0; i < entries; i++) {
+		ret = device_create_file(&pdev->dev,
+				&mc13783_adc_ctl[i].dev_attr);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"device_create_file failed with %d.\n", ret);
+			goto out_err;
+		}
+	}
+
+	priv->hwmon_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(priv->hwmon_dev)) {
+		ret = PTR_ERR(priv->hwmon_dev);
+		dev_err(&pdev->dev,
+				"hwmon_device_register failed with %d.\n", ret);
+		goto out_err;
+	}
+
+	platform_set_drvdata(pdev, priv);
+
+	return 0;
+
+out_err:
+	for (i--; i >= 0; i--)
+		device_remove_file(&pdev->dev, &mc13783_adc_ctl[i].dev_attr);
+
+	kfree(priv);
+
+	return ret;
+}
+
+static int __devexit mc13783_adc_remove(struct platform_device *pdev)
+{
+	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+	int entries;
+	int i;
+
+	hwmon_device_unregister(&pdev->dev);
+
+	entries = ARRAY_SIZE(mc13783_adc_ctl);
+
+	if (priv->mc13783->flags & MC13783_USE_TOUCHSCREEN)
+		entries -= 4;
+
+	for (i = 0; i < entries; i++)
+		device_remove_file(&pdev->dev, &mc13783_adc_ctl[i].dev_attr);
+
+	kfree(priv);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_adc_driver = {
+	.remove 	= __devexit_p(mc13783_adc_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= MC13783_ADC_NAME,
+	},
+};
+
+static int __init mc13783_adc_init(void)
+{
+	return platform_driver_probe(&mc13783_adc_driver, &mc13783_adc_probe);
+}
+
+static void __exit mc13783_adc_exit(void)
+{
+	platform_driver_unregister(&mc13783_adc_driver);
+}
+
+module_init(mc13783_adc_init);
+module_exit(mc13783_adc_exit);
+
+MODULE_DESCRIPTION("MC13783 input touchscreen driver");
+MODULE_AUTHOR("Luotao Fu, <l.fu@pengutronix.de>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mc13783-adc");
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/5] [hwmon] add Freescale MC13783 adc driver
  2009-08-11  9:07   ` [PATCH 2/5] [input] add mc13783 touchscreen driver Sascha Hauer
@ 2009-08-11  9:07     ` Sascha Hauer
  0 siblings, 0 replies; 10+ messages in thread
From: Sascha Hauer @ 2009-08-11  9:07 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-arm-kernel, Sascha Hauer, Luotao Fu, Hans de Goede,
	Andrew Morton, Eric Piel, lm-sensors

From: Luotao Fu <l.fu@pengutronix.de>

This driver provides support for the ADC integrated into the
Freescale MC13783 PMIC.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Hans de Goede <hdegoede@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Eric Piel <eric.piel@tremplin-utc.net>
Cc: lm-sensors@lm-sensors.org
---
 drivers/hwmon/Kconfig       |    6 ++
 drivers/hwmon/Makefile      |    1 +
 drivers/hwmon/mc13783-adc.c |  181 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 188 insertions(+), 0 deletions(-)
 create mode 100644 drivers/hwmon/mc13783-adc.c

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 2d50166..a7e34fd 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1017,6 +1017,12 @@ config SENSORS_APPLESMC
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of applesmc.
 
+config SENSORS_MC13783_ADC
+        tristate "Freescale MC13783 ADC"
+        depends on MFD_MC13783
+        help
+          Support for the ad converter on mc13783 pmic.
+
 config HWMON_DEBUG_CHIP
 	bool "Hardware Monitoring Chip debugging messages"
 	default n
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index b793dce..9b4e131 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -89,6 +89,7 @@ obj-$(CONFIG_SENSORS_VT8231)	+= vt8231.o
 obj-$(CONFIG_SENSORS_W83627EHF)	+= w83627ehf.o
 obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
 obj-$(CONFIG_SENSORS_W83L786NG)	+= w83l786ng.o
+obj-$(CONFIG_SENSORS_MC13783_ADC)       += mc13783-adc.o
 
 ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c
new file mode 100644
index 0000000..885c009
--- /dev/null
+++ b/drivers/hwmon/mc13783-adc.c
@@ -0,0 +1,181 @@
+/*
+ * Driver for the Freescale Semiconductor MC13783 adc.
+ *
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Sascha Hauer, Pengutronix
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/mfd/mc13783-private.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/hwmon.h>
+#include <linux/input.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#define MC13783_ADC_NAME	"mc13783-adc"
+
+struct mc13783_adc_priv {
+	struct mc13783 *mc13783;
+	struct device *hwmon_dev;
+};
+
+static ssize_t mc13783_adc_show_name(struct device *dev, struct device_attribute
+			      *devattr, char *buf)
+{
+	return sprintf(buf, "mc13783_adc\n");
+}
+
+static ssize_t mc13783_adc_read(struct device *dev,
+		struct device_attribute *devattr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	unsigned int channel = attr->index;
+	unsigned int res;
+	unsigned int sample[4];
+
+	mc13783_adc_do_conversion(priv->mc13783, MC13783_ADC_MODE_MULT_CHAN,
+			channel, sample);
+
+	channel &= 0x7;
+
+	res = (sample[channel % 4] >> (channel > 3 ? 14 : 2)) & 0x3ff;
+
+	return sprintf(buf, "%u\n", res);
+}
+
+static struct sensor_device_attribute mc13783_adc_ctl[] = {
+	SENSOR_ATTR(name, S_IRUGO, mc13783_adc_show_name, NULL, 0),
+	SENSOR_ATTR(in0_input, S_IRUGO, mc13783_adc_read, NULL, 0),
+	SENSOR_ATTR(in1_input, S_IRUGO, mc13783_adc_read, NULL, 1),
+	SENSOR_ATTR(in2_input, S_IRUGO, mc13783_adc_read, NULL, 2),
+	SENSOR_ATTR(in3_input, S_IRUGO, mc13783_adc_read, NULL, 3),
+	SENSOR_ATTR(in4_input, S_IRUGO, mc13783_adc_read, NULL, 4),
+	SENSOR_ATTR(in5_input, S_IRUGO, mc13783_adc_read, NULL, 5),
+	SENSOR_ATTR(in6_input, S_IRUGO, mc13783_adc_read, NULL, 6),
+	SENSOR_ATTR(in7_input, S_IRUGO, mc13783_adc_read, NULL, 7),
+	SENSOR_ATTR(in8_input, S_IRUGO, mc13783_adc_read, NULL, 8),
+	SENSOR_ATTR(in9_input, S_IRUGO, mc13783_adc_read, NULL, 9),
+	SENSOR_ATTR(in10_input, S_IRUGO, mc13783_adc_read, NULL, 10),
+	SENSOR_ATTR(in11_input, S_IRUGO, mc13783_adc_read, NULL, 11),
+	SENSOR_ATTR(in12_input, S_IRUGO, mc13783_adc_read, NULL, 12),
+	SENSOR_ATTR(in13_input, S_IRUGO, mc13783_adc_read, NULL, 13),
+	SENSOR_ATTR(in14_input, S_IRUGO, mc13783_adc_read, NULL, 14),
+	SENSOR_ATTR(in15_input, S_IRUGO, mc13783_adc_read, NULL, 15),
+};
+
+static int __init mc13783_adc_probe(struct platform_device *pdev)
+{
+	struct mc13783_adc_priv *priv;
+	int ret, i;
+	int entries;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mc13783 = pdev->dev.platform_data;
+
+	entries = ARRAY_SIZE(mc13783_adc_ctl);
+
+	/* last four channels may be occupied by the touchscreen */
+	if (priv->mc13783->flags & MC13783_USE_TOUCHSCREEN)
+		entries -= 4;
+
+	for (i = 0; i < entries; i++) {
+		ret = device_create_file(&pdev->dev,
+				&mc13783_adc_ctl[i].dev_attr);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"device_create_file failed with %d.\n", ret);
+			goto out_err;
+		}
+	}
+
+	priv->hwmon_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(priv->hwmon_dev)) {
+		ret = PTR_ERR(priv->hwmon_dev);
+		dev_err(&pdev->dev,
+				"hwmon_device_register failed with %d.\n", ret);
+		goto out_err;
+	}
+
+	platform_set_drvdata(pdev, priv);
+
+	return 0;
+
+out_err:
+	for (i--; i >= 0; i--)
+		device_remove_file(&pdev->dev, &mc13783_adc_ctl[i].dev_attr);
+
+	kfree(priv);
+
+	return ret;
+}
+
+static int __devexit mc13783_adc_remove(struct platform_device *pdev)
+{
+	struct mc13783_adc_priv *priv = platform_get_drvdata(pdev);
+	int entries;
+	int i;
+
+	hwmon_device_unregister(&pdev->dev);
+
+	entries = ARRAY_SIZE(mc13783_adc_ctl);
+
+	if (priv->mc13783->flags & MC13783_USE_TOUCHSCREEN)
+		entries -= 4;
+
+	for (i = 0; i < entries; i++)
+		device_remove_file(&pdev->dev, &mc13783_adc_ctl[i].dev_attr);
+
+	kfree(priv);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_adc_driver = {
+	.probe		= mc13783_adc_probe,
+	.remove 	= __devexit_p(mc13783_adc_remove),
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= MC13783_ADC_NAME,
+	},
+};
+
+static int __init mc13783_adc_init(void)
+{
+	return platform_driver_register(&mc13783_adc_driver);
+}
+
+static void __exit mc13783_adc_exit(void)
+{
+	platform_driver_unregister(&mc13783_adc_driver);
+}
+
+module_init(mc13783_adc_init);
+module_exit(mc13783_adc_exit);
+
+MODULE_DESCRIPTION("MC13783 input touchscreen driver");
+MODULE_AUTHOR("Luotao Fu, <l.fu@pengutronix.de>");
+MODULE_LICENSE("GPL");
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-08-12 15:07 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1249981166-4210-1-git-send-email-s.hauer@pengutronix.de>
2009-08-11  8:59 ` [PATCH 2/5] [input] add mc13783 touchscreen driver Sascha Hauer
2009-08-11  8:59   ` Sascha Hauer
2009-08-11  8:59   ` [PATCH 3/5] [hwmon] add Freescale MC13783 adc driver Sascha Hauer
2009-08-11  8:59     ` [lm-sensors] " Sascha Hauer
2009-08-11  8:59     ` [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver Sascha Hauer
2009-08-11  8:59       ` [PATCH 5/5] [regulator] Add a Freescale MC13783 regulator driver Sascha Hauer
2009-08-12  9:41       ` [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver Alessandro Zummo
2009-08-12 11:39         ` Sascha Hauer
2009-08-11  9:07 [RFC] Freescale MC13783 PMIC support Sascha Hauer
2009-08-11  9:07 ` [PATCH 1/5] drivers/mfd: Add Freescale MC13783 driver Sascha Hauer
2009-08-11  9:07   ` [PATCH 2/5] [input] add mc13783 touchscreen driver Sascha Hauer
2009-08-11  9:07     ` [PATCH 3/5] [hwmon] add Freescale MC13783 adc driver Sascha Hauer
2009-08-12 15:05 [PATCH V2] Freescale MC13783 PMIC support Sascha Hauer
2009-08-12 15:05 ` [PATCH 1/5] drivers/mfd: Add Freescale MC13783 driver Sascha Hauer
2009-08-12 15:05   ` [PATCH 2/5] [input] add mc13783 touchscreen driver Sascha Hauer
2009-08-12 15:05     ` [PATCH 3/5] [hwmon] add Freescale MC13783 adc driver Sascha Hauer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.