rtc: PCF50633 rtc driver
[safe/jmp/linux-2.6] / drivers / rtc / rtc-m48t59.c
index 50f9f10..33921a6 100644 (file)
@@ -76,21 +76,26 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm)
        /* Issue the READ command */
        M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL);
 
-       tm->tm_year     = BCD2BIN(M48T59_READ(M48T59_YEAR));
+       tm->tm_year     = bcd2bin(M48T59_READ(M48T59_YEAR));
        /* tm_mon is 0-11 */
-       tm->tm_mon      = BCD2BIN(M48T59_READ(M48T59_MONTH)) - 1;
-       tm->tm_mday     = BCD2BIN(M48T59_READ(M48T59_MDAY));
+       tm->tm_mon      = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1;
+       tm->tm_mday     = bcd2bin(M48T59_READ(M48T59_MDAY));
 
        val = M48T59_READ(M48T59_WDAY);
-       if ((val & M48T59_WDAY_CEB) && (val & M48T59_WDAY_CB)) {
+       if ((pdata->type == M48T59RTC_TYPE_M48T59) &&
+           (val & M48T59_WDAY_CEB) && (val & M48T59_WDAY_CB)) {
                dev_dbg(dev, "Century bit is enabled\n");
                tm->tm_year += 100;     /* one century */
        }
+#ifdef CONFIG_SPARC
+       /* Sun SPARC machines count years since 1968 */
+       tm->tm_year += 68;
+#endif
 
-       tm->tm_wday     = BCD2BIN(val & 0x07);
-       tm->tm_hour     = BCD2BIN(M48T59_READ(M48T59_HOUR) & 0x3F);
-       tm->tm_min      = BCD2BIN(M48T59_READ(M48T59_MIN) & 0x7F);
-       tm->tm_sec      = BCD2BIN(M48T59_READ(M48T59_SEC) & 0x7F);
+       tm->tm_wday     = bcd2bin(val & 0x07);
+       tm->tm_hour     = bcd2bin(M48T59_READ(M48T59_HOUR) & 0x3F);
+       tm->tm_min      = bcd2bin(M48T59_READ(M48T59_MIN) & 0x7F);
+       tm->tm_sec      = bcd2bin(M48T59_READ(M48T59_SEC) & 0x7F);
 
        /* Clear the READ bit */
        M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
@@ -109,26 +114,35 @@ static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm)
        struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
        unsigned long flags;
        u8 val = 0;
+       int year = tm->tm_year;
+
+#ifdef CONFIG_SPARC
+       /* Sun SPARC machines count years since 1968 */
+       year -= 68;
+#endif
 
        dev_dbg(dev, "RTC set time %04d-%02d-%02d %02d/%02d/%02d\n",
-               tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
+               year + 1900, tm->tm_mon, tm->tm_mday,
                tm->tm_hour, tm->tm_min, tm->tm_sec);
 
+       if (year < 0)
+               return -EINVAL;
+
        spin_lock_irqsave(&m48t59->lock, flags);
        /* Issue the WRITE command */
        M48T59_SET_BITS(M48T59_CNTL_WRITE, M48T59_CNTL);
 
-       M48T59_WRITE((BIN2BCD(tm->tm_sec) & 0x7F), M48T59_SEC);
-       M48T59_WRITE((BIN2BCD(tm->tm_min) & 0x7F), M48T59_MIN);
-       M48T59_WRITE((BIN2BCD(tm->tm_hour) & 0x3F), M48T59_HOUR);
-       M48T59_WRITE((BIN2BCD(tm->tm_mday) & 0x3F), M48T59_MDAY);
+       M48T59_WRITE((bin2bcd(tm->tm_sec) & 0x7F), M48T59_SEC);
+       M48T59_WRITE((bin2bcd(tm->tm_min) & 0x7F), M48T59_MIN);
+       M48T59_WRITE((bin2bcd(tm->tm_hour) & 0x3F), M48T59_HOUR);
+       M48T59_WRITE((bin2bcd(tm->tm_mday) & 0x3F), M48T59_MDAY);
        /* tm_mon is 0-11 */
-       M48T59_WRITE((BIN2BCD(tm->tm_mon + 1) & 0x1F), M48T59_MONTH);
-       M48T59_WRITE(BIN2BCD(tm->tm_year % 100), M48T59_YEAR);
+       M48T59_WRITE((bin2bcd(tm->tm_mon + 1) & 0x1F), M48T59_MONTH);
+       M48T59_WRITE(bin2bcd(year % 100), M48T59_YEAR);
 
-       if (tm->tm_year/100)
+       if (pdata->type == M48T59RTC_TYPE_M48T59 && (year / 100))
                val = (M48T59_WDAY_CEB | M48T59_WDAY_CB);
-       val |= (BIN2BCD(tm->tm_wday) & 0x07);
+       val |= (bin2bcd(tm->tm_wday) & 0x07);
        M48T59_WRITE(val, M48T59_WDAY);
 
        /* Clear the WRITE bit */
@@ -157,18 +171,22 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
        /* Issue the READ command */
        M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL);
 
-       tm->tm_year = BCD2BIN(M48T59_READ(M48T59_YEAR));
+       tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR));
+#ifdef CONFIG_SPARC
+       /* Sun SPARC machines count years since 1968 */
+       tm->tm_year += 68;
+#endif
        /* tm_mon is 0-11 */
-       tm->tm_mon = BCD2BIN(M48T59_READ(M48T59_MONTH)) - 1;
+       tm->tm_mon = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1;
 
        val = M48T59_READ(M48T59_WDAY);
        if ((val & M48T59_WDAY_CEB) && (val & M48T59_WDAY_CB))
                tm->tm_year += 100;     /* one century */
 
-       tm->tm_mday = BCD2BIN(M48T59_READ(M48T59_ALARM_DATE));
-       tm->tm_hour = BCD2BIN(M48T59_READ(M48T59_ALARM_HOUR));
-       tm->tm_min = BCD2BIN(M48T59_READ(M48T59_ALARM_MIN));
-       tm->tm_sec = BCD2BIN(M48T59_READ(M48T59_ALARM_SEC));
+       tm->tm_mday = bcd2bin(M48T59_READ(M48T59_ALARM_DATE));
+       tm->tm_hour = bcd2bin(M48T59_READ(M48T59_ALARM_HOUR));
+       tm->tm_min = bcd2bin(M48T59_READ(M48T59_ALARM_MIN));
+       tm->tm_sec = bcd2bin(M48T59_READ(M48T59_ALARM_SEC));
 
        /* Clear the READ bit */
        M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
@@ -191,27 +209,36 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
        struct rtc_time *tm = &alrm->time;
        u8 mday, hour, min, sec;
        unsigned long flags;
+       int year = tm->tm_year;
+
+#ifdef CONFIG_SPARC
+       /* Sun SPARC machines count years since 1968 */
+       year -= 68;
+#endif
 
        /* If no irq, we don't support ALARM */
        if (m48t59->irq == NO_IRQ)
                return -EIO;
 
+       if (year < 0)
+               return -EINVAL;
+
        /*
         * 0xff means "always match"
         */
        mday = tm->tm_mday;
-       mday = (mday >= 1 && mday <= 31) ? BIN2BCD(mday) : 0xff;
+       mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff;
        if (mday == 0xff)
                mday = M48T59_READ(M48T59_MDAY);
 
        hour = tm->tm_hour;
-       hour = (hour < 24) ? BIN2BCD(hour) : 0x00;
+       hour = (hour < 24) ? bin2bcd(hour) : 0x00;
 
        min = tm->tm_min;
-       min = (min < 60) ? BIN2BCD(min) : 0x00;
+       min = (min < 60) ? bin2bcd(min) : 0x00;
 
        sec = tm->tm_sec;
-       sec = (sec < 60) ? BIN2BCD(sec) : 0x00;
+       sec = (sec < 60) ? bin2bcd(sec) : 0x00;
 
        spin_lock_irqsave(&m48t59->lock, flags);
        /* Issue the WRITE command */
@@ -227,7 +254,7 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
        spin_unlock_irqrestore(&m48t59->lock, flags);
 
        dev_dbg(dev, "RTC set alarm time %04d-%02d-%02d %02d/%02d/%02d\n",
-               tm->tm_year + 1900, tm->tm_mon, tm->tm_mday,
+               year + 1900, tm->tm_mon, tm->tm_mday,
                tm->tm_hour, tm->tm_min, tm->tm_sec);
        return 0;
 }
@@ -359,7 +386,6 @@ static struct bin_attribute m48t59_nvram_attr = {
        .attr = {
                .name = "nvram",
                .mode = S_IRUGO | S_IWUSR,
-               .owner = THIS_MODULE,
        },
        .read = m48t59_nvram_read,
        .write = m48t59_nvram_write,
@@ -411,15 +437,20 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev)
        if (!m48t59)
                return -ENOMEM;
 
-       m48t59->ioaddr = ioremap(res->start, res->end - res->start + 1);
-       if (!m48t59->ioaddr)
-               goto out;
+       m48t59->ioaddr = pdata->ioaddr;
+
+       if (!m48t59->ioaddr) {
+               /* ioaddr not mapped externally */
+               m48t59->ioaddr = ioremap(res->start, res->end - res->start + 1);
+               if (!m48t59->ioaddr)
+                       goto out;
+       }
 
        /* Try to get irq number. We also can work in
         * the mode without IRQ.
         */
        m48t59->irq = platform_get_irq(pdev, 0);
-       if (m48t59->irq < 0)
+       if (m48t59->irq <= 0)
                m48t59->irq = NO_IRQ;
 
        if (m48t59->irq != NO_IRQ) {
@@ -481,11 +512,12 @@ out:
 static int __devexit m48t59_rtc_remove(struct platform_device *pdev)
 {
        struct m48t59_private *m48t59 = platform_get_drvdata(pdev);
+       struct m48t59_plat_data *pdata = pdev->dev.platform_data;
 
        sysfs_remove_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr);
        if (!IS_ERR(m48t59->rtc))
                rtc_device_unregister(m48t59->rtc);
-       if (m48t59->ioaddr)
+       if (m48t59->ioaddr && !pdata->ioaddr)
                iounmap(m48t59->ioaddr);
        if (m48t59->irq != NO_IRQ)
                free_irq(m48t59->irq, &pdev->dev);