* [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
2009-08-11 8:59 ` [PATCH 3/5] [hwmon] add Freescale MC13783 adc driver Sascha Hauer
0 siblings, 1 reply; 8+ 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 [flat|nested] 8+ messages in thread
* [PATCH 3/5] [hwmon] add Freescale MC13783 adc driver
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 4/5] [RTC] Add Freescale MC13783 RTC driver Sascha Hauer
0 siblings, 1 reply; 8+ 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 [flat|nested] 8+ messages in thread
* [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver
2009-08-11 8:59 ` [PATCH 3/5] [hwmon] add Freescale MC13783 adc driver 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
0 siblings, 2 replies; 8+ 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 [flat|nested] 8+ 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; 8+ 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 [flat|nested] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ messages in thread
* [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver
2009-08-12 15:05 ` [PATCH 3/5] [hwmon] add Freescale MC13783 adc driver Sascha Hauer
@ 2009-08-12 15:05 ` Sascha Hauer
0 siblings, 0 replies; 8+ messages in thread
From: Sascha Hauer @ 2009-08-12 15:05 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.
changes since v1:
- use set_mmss instead of set_time
- fix __devinit / __devexit usage
- use platform_driver_probe instead of platform_driver_register
- add MODULE_ALIAS
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 | 135 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 142 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..0c2cea6 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o
obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o
obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
+obj-$(CONFIG_RTC_DRV_MC13783) += rtc-mc13783.o
obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o
obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
diff --git a/drivers/rtc/rtc-mc13783.c b/drivers/rtc/rtc-mc13783.c
new file mode 100644
index 0000000..dfa4702
--- /dev/null
+++ b/drivers/rtc/rtc-mc13783.c
@@ -0,0 +1,135 @@
+/*
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/rtc.h>
+
+struct mc13783_rtc {
+ struct rtc_device *rtc;
+ struct mc13783 *mc13783;
+};
+
+static int mc13783_rtc_set_mmss(struct device *dev, unsigned long secs)
+{
+ struct mc13783_rtc *priv = dev_get_drvdata(dev);
+ unsigned int seconds, days;
+
+ seconds = secs % 86400;
+ days = secs / 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 rtc_valid_tm(tm);
+}
+
+static const struct rtc_class_ops mc13783_rtc_ops = {
+ .read_time = mc13783_rtc_read_time,
+ .set_mmss = mc13783_rtc_set_mmss,
+};
+
+static int __devinit 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 = dev_get_drvdata(pdev->dev.parent);
+ 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 __devexit 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 = {
+ .remove = __devexit_p(mc13783_rtc_remove),
+ .driver = {
+ .name = "mc13783-rtc",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init mc13783_rtc_init(void)
+{
+ return platform_driver_probe(&mc13783_rtc_driver, &mc13783_rtc_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 <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION("RTC driver for Freescale MC13783 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mc13783-rtc");
--
1.6.3.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver
2009-08-11 9:07 ` [PATCH 3/5] [hwmon] add Freescale MC13783 adc driver Sascha Hauer
@ 2009-08-11 9:07 ` Sascha Hauer
0 siblings, 0 replies; 8+ messages in thread
From: Sascha Hauer @ 2009-08-11 9:07 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 [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-08-12 15:10 UTC | newest]
Thread overview: 8+ 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 ` [PATCH 3/5] [hwmon] add Freescale MC13783 adc driver 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-11 9:07 ` [PATCH 4/5] [RTC] Add Freescale MC13783 RTC 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
2009-08-12 15:05 ` [PATCH 4/5] [RTC] Add Freescale MC13783 RTC driver Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®