[ep93xx] add support for the Simplemachines Sim.One board
[openwrt/svn-archive/archive.git] / target / linux / ep93xx / patches-2.6.30 / 004-simone-rtc.patch
diff --git a/target/linux/ep93xx/patches-2.6.30/004-simone-rtc.patch b/target/linux/ep93xx/patches-2.6.30/004-simone-rtc.patch
new file mode 100644 (file)
index 0000000..69f2c5a
--- /dev/null
@@ -0,0 +1,78 @@
+--- a/drivers/rtc/rtc-ds1307.c
++++ b/drivers/rtc/rtc-ds1307.c
+@@ -661,6 +661,13 @@ static int __devinit ds1307_probe(struct
+                       goto exit_free;
+               }
++#if (defined(CONFIG_MACH_SIM_ONE))
++              /* SIM.ONE board needs 32khz clock on SQW/INTB pin */
++              i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
++                                      ds1307->regs[0] & ~DS1337_BIT_INTCN);
++              i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
++                                      ds1307->regs[0] | (DS1337_BIT_RS1 | DS1337_BIT_RS2));
++#endif
+               /* oscillator off?  turn it on, so clock can tick. */
+               if (ds1307->regs[0] & DS1337_BIT_nEOSC)
+                       ds1307->regs[0] &= ~DS1337_BIT_nEOSC;
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -570,6 +570,14 @@ config RTC_DRV_EP93XX
+         This driver can also be built as a module. If so, the module
+         will be called rtc-ep93xx.
++config RTC_DRV_EP93XX_DS1337
++      bool "Cirrus Logic EP93XX using DS1337 chip"
++      depends on RTC_DRV_EP93XX && I2C && MACH_SIM_ONE
++      help
++        If you say yes here, the EP93XX driver will use the
++        battery-backed-up DS1337 RTC chip on the SIM.ONE board.
++        You almost certainly want this.
++
+ config RTC_DRV_SA1100
+       tristate "SA11x0/PXA2xx"
+       depends on ARCH_SA1100 || ARCH_PXA
+--- a/drivers/rtc/rtc-ep93xx.c
++++ b/drivers/rtc/rtc-ep93xx.c
+@@ -13,6 +13,13 @@
+ #include <linux/rtc.h>
+ #include <linux/platform_device.h>
+ #include <mach/hardware.h>
++#include <asm/io.h>
++
++#if defined(CONFIG_RTC_DRV_EP93XX_DS1337)
++extern int ds1337_do_command(int id, int cmd, void *arg);
++#define DS1337_GET_DATE         0
++#define DS1337_SET_DATE         1
++#endif
+ #define EP93XX_RTC_REG(x)     (EP93XX_RTC_BASE + (x))
+ #define EP93XX_RTC_DATA               EP93XX_RTC_REG(0x0000)
+@@ -37,16 +44,28 @@ static int ep93xx_get_swcomp(struct devi
+ static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm)
+ {
++#if defined(CONFIG_RTC_DRV_EP93XX_DS1337)
++      /* Reroute the internal device to the DS1337 */
++      return ds1337_do_command(0, DS1337_GET_DATE, (void *)tm);
++#else
+       unsigned long time = __raw_readl(EP93XX_RTC_DATA);
+       rtc_time_to_tm(time, tm);
+       return 0;
++#endif
+ }
+ static int ep93xx_rtc_set_mmss(struct device *dev, unsigned long secs)
+ {
++#if defined(CONFIG_RTC_DRV_EP93XX_DS1337)
++      struct rtc_time tm;
++
++      rtc_time_to_tm(secs, &tm);
++      return ds1337_do_command(0, DS1337_SET_DATE, (void *)&tm);
++#else
+       __raw_writel(secs + 1, EP93XX_RTC_LOAD);
+       return 0;
++#endif
+ }
+ static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq)