source: trunk/target/linux/generic/patches-2.6.35/700-rtc7301.patch @ 21952

Last change on this file since 21952 was 21952, checked in by nbd, 6 years ago

rename target/linux/generic-2.6 to generic

File size: 6.2 KB
  • drivers/rtc/Kconfig

    a b config RTC_DRV_NUC900 
    618618          If you say yes here you get support for the RTC subsystem of the 
    619619          NUC910/NUC920 used in embedded systems. 
    620620 
     621config RTC_DRV_RTC7301 
     622        tristate "Epson RTC-7301 SF/DG" 
     623        help 
     624          If you say Y here you will get support for the 
     625          Epson RTC-7301 SF/DG RTC chips. 
     626 
     627          This driver can also be built as a module. If so, the module 
     628          will be called rtc-7301. 
     629 
    621630comment "on-CPU RTC drivers" 
    622631 
    623632config RTC_DRV_OMAP 
  • drivers/rtc/Makefile

    a b obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c 
    7474obj-$(CONFIG_RTC_DRV_RS5C313)   += rtc-rs5c313.o 
    7575obj-$(CONFIG_RTC_DRV_RS5C348)   += rtc-rs5c348.o 
    7676obj-$(CONFIG_RTC_DRV_RS5C372)   += rtc-rs5c372.o 
     77obj-$(CONFIG_RTC_DRV_RTC7301)   += rtc-rtc7301.o 
    7778obj-$(CONFIG_RTC_DRV_RX8025)    += rtc-rx8025.o 
    7879obj-$(CONFIG_RTC_DRV_RX8581)    += rtc-rx8581.o 
    7980obj-$(CONFIG_RTC_DRV_S35390A)   += rtc-s35390a.o 
  • new file drivers/rtc/rtc-rtc7301.c

    - +  
     1/* 
     2 * Driver for Epson RTC-7301SF/DG 
     3 * 
     4 * Copyright (C) 2009 Jose Vasconcellos 
     5 * 
     6 * This program is free software; you can redistribute it and/or modify 
     7 * it under the terms of the GNU General Public License version 2 as 
     8 * published by the Free Software Foundation. 
     9 */ 
     10 
     11#include <linux/module.h> 
     12#include <linux/rtc.h> 
     13#include <linux/platform_device.h> 
     14#include <linux/io.h> 
     15#include <linux/delay.h> 
     16#include <linux/bcd.h> 
     17 
     18#define RTC_NAME "rtc7301" 
     19#define RTC_VERSION "0.1" 
     20 
     21/* Epson RTC-7301 register addresses */ 
     22#define RTC7301_SEC             0x00 
     23#define RTC7301_SEC10           0x01 
     24#define RTC7301_MIN             0x02 
     25#define RTC7301_MIN10           0x03 
     26#define RTC7301_HOUR            0x04 
     27#define RTC7301_HOUR10          0x05 
     28#define RTC7301_WEEKDAY         0x06 
     29#define RTC7301_DAY             0x07 
     30#define RTC7301_DAY10           0x08 
     31#define RTC7301_MON             0x09 
     32#define RTC7301_MON10           0x0A 
     33#define RTC7301_YEAR            0x0B 
     34#define RTC7301_YEAR10          0x0C 
     35#define RTC7301_YEAR100         0x0D 
     36#define RTC7301_YEAR1000        0x0E 
     37#define RTC7301_CTRLREG         0x0F 
     38 
     39static uint8_t __iomem *rtc7301_base; 
     40 
     41#define read_reg(offset) (readb(rtc7301_base + offset) & 0xf) 
     42#define write_reg(offset, data) writeb(data, rtc7301_base + (offset)) 
     43 
     44#define rtc7301_isbusy() (read_reg(RTC7301_CTRLREG) & 1) 
     45 
     46static void rtc7301_init_settings(void) 
     47{ 
     48        int i; 
     49 
     50        write_reg(RTC7301_CTRLREG, 2); 
     51        write_reg(RTC7301_YEAR1000, 2); 
     52        udelay(122); 
     53 
     54        /* bank 1 */ 
     55        write_reg(RTC7301_CTRLREG, 6); 
     56        for (i=0; i<15; i++) 
     57                write_reg(i, 0); 
     58 
     59        /* bank 2 */ 
     60        write_reg(RTC7301_CTRLREG, 14); 
     61        for (i=0; i<15; i++) 
     62                write_reg(i, 0); 
     63        write_reg(RTC7301_CTRLREG, 0); 
     64} 
     65 
     66static int rtc7301_get_datetime(struct device *dev, struct rtc_time *dt) 
     67{ 
     68        int cnt; 
     69        uint8_t buf[16]; 
     70 
     71        cnt = 0; 
     72        while (rtc7301_isbusy()) { 
     73                udelay(244); 
     74                if (cnt++ > 100) { 
     75                        dev_err(dev, "%s: timeout error %x\n", __func__, rtc7301_base[RTC7301_CTRLREG]); 
     76                        return -EIO; 
     77                } 
     78        } 
     79 
     80        for (cnt=0; cnt<16; cnt++) 
     81                buf[cnt] = read_reg(cnt); 
     82 
     83        if (buf[RTC7301_SEC10] & 8) { 
     84                dev_err(dev, "%s: RTC not set\n", __func__); 
     85                return -EINVAL; 
     86        } 
     87 
     88        memset(dt, 0, sizeof(*dt)); 
     89 
     90        dt->tm_sec =  buf[RTC7301_SEC] + buf[RTC7301_SEC10]*10; 
     91        dt->tm_min =  buf[RTC7301_MIN] + buf[RTC7301_MIN10]*10; 
     92        dt->tm_hour = buf[RTC7301_HOUR] + buf[RTC7301_HOUR10]*10; 
     93 
     94        dt->tm_mday = buf[RTC7301_DAY] + buf[RTC7301_DAY10]*10; 
     95        dt->tm_mon =  buf[RTC7301_MON] + buf[RTC7301_MON10]*10 - 1; 
     96        dt->tm_year = buf[RTC7301_YEAR] + buf[RTC7301_YEAR10]*10 + 
     97                      buf[RTC7301_YEAR100]*100 + 
     98                      ((buf[RTC7301_YEAR1000] & 3)*1000) - 1900; 
     99 
     100        /* the rtc device may contain illegal values on power up 
     101         * according to the data sheet. make sure they are valid. 
     102         */ 
     103 
     104        return rtc_valid_tm(dt); 
     105} 
     106 
     107static int rtc7301_set_datetime(struct device *dev, struct rtc_time *dt) 
     108{ 
     109        int data; 
     110 
     111        data = dt->tm_year + 1900; 
     112        if (data >= 2100 || data < 1900) 
     113                return -EINVAL; 
     114 
     115        write_reg(RTC7301_CTRLREG, 2); 
     116        udelay(122); 
     117 
     118        data = bin2bcd(dt->tm_sec); 
     119        write_reg(RTC7301_SEC, data); 
     120        write_reg(RTC7301_SEC10, (data >> 4)); 
     121 
     122        data = bin2bcd(dt->tm_min); 
     123        write_reg(RTC7301_MIN, data ); 
     124        write_reg(RTC7301_MIN10, (data >> 4)); 
     125 
     126        data = bin2bcd(dt->tm_hour); 
     127        write_reg(RTC7301_HOUR, data); 
     128        write_reg(RTC7301_HOUR10, (data >> 4)); 
     129 
     130        data = bin2bcd(dt->tm_mday); 
     131        write_reg(RTC7301_DAY, data); 
     132        write_reg(RTC7301_DAY10, (data>> 4)); 
     133 
     134        data = bin2bcd(dt->tm_mon + 1); 
     135        write_reg(RTC7301_MON, data); 
     136        write_reg(RTC7301_MON10, (data >> 4)); 
     137 
     138        data = bin2bcd(dt->tm_year % 100); 
     139        write_reg(RTC7301_YEAR, data); 
     140        write_reg(RTC7301_YEAR10, (data >> 4)); 
     141        data = bin2bcd((1900 + dt->tm_year) / 100); 
     142        write_reg(RTC7301_YEAR100, data); 
     143 
     144        data = bin2bcd(dt->tm_wday); 
     145        write_reg(RTC7301_WEEKDAY, data); 
     146 
     147        write_reg(RTC7301_CTRLREG, 0); 
     148 
     149        return 0; 
     150} 
     151 
     152static const struct rtc_class_ops rtc7301_rtc_ops = { 
     153        .read_time      = rtc7301_get_datetime, 
     154        .set_time       = rtc7301_set_datetime, 
     155}; 
     156 
     157static int __devinit rtc7301_probe(struct platform_device *pdev) 
     158{ 
     159        struct rtc_device *rtc; 
     160        struct resource *res; 
     161 
     162        res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 
     163        if (!res) 
     164                return -ENOENT; 
     165 
     166        rtc7301_base = ioremap_nocache(res->start, 0x1000 /*res->end - res->start + 1*/); 
     167        if (!rtc7301_base) 
     168                return -EINVAL; 
     169 
     170        rtc = rtc_device_register(RTC_NAME, &pdev->dev, 
     171                                &rtc7301_rtc_ops, THIS_MODULE); 
     172        if (IS_ERR(rtc)) { 
     173                iounmap(rtc7301_base); 
     174                return PTR_ERR(rtc); 
     175        } 
     176 
     177        platform_set_drvdata(pdev, rtc); 
     178 
     179        rtc7301_init_settings(); 
     180        return 0; 
     181} 
     182 
     183static int __devexit rtc7301_remove(struct platform_device *pdev) 
     184{ 
     185        struct rtc_device *rtc = platform_get_drvdata(pdev); 
     186 
     187        if (rtc) 
     188                rtc_device_unregister(rtc); 
     189        if (rtc7301_base) 
     190                iounmap(rtc7301_base); 
     191        return 0; 
     192} 
     193 
     194static struct platform_driver rtc7301_driver = { 
     195        .driver = { 
     196                .name   = RTC_NAME, 
     197                .owner  = THIS_MODULE, 
     198        }, 
     199        .probe  = rtc7301_probe, 
     200        .remove = __devexit_p(rtc7301_remove), 
     201}; 
     202 
     203static __init int rtc7301_init(void) 
     204{ 
     205        return platform_driver_register(&rtc7301_driver); 
     206} 
     207module_init(rtc7301_init); 
     208 
     209static __exit void rtc7301_exit(void) 
     210{ 
     211        platform_driver_unregister(&rtc7301_driver); 
     212} 
     213module_exit(rtc7301_exit); 
     214 
     215MODULE_DESCRIPTION("Epson 7301 RTC driver"); 
     216MODULE_AUTHOR("Jose Vasconcellos <jvasco@verizon.net>"); 
     217MODULE_LICENSE("GPL"); 
     218MODULE_ALIAS("platform:" RTC_NAME); 
     219MODULE_VERSION(RTC_VERSION); 
Note: See TracBrowser for help on using the repository browser.