Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * A SPI driver for the Ricoh RS5C348 RTC
0004  *
0005  * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
0006  *
0007  * The board specific init code should provide characteristics of this
0008  * device:
0009  *     Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS
0010  */
0011 
0012 #include <linux/bcd.h>
0013 #include <linux/delay.h>
0014 #include <linux/device.h>
0015 #include <linux/errno.h>
0016 #include <linux/init.h>
0017 #include <linux/kernel.h>
0018 #include <linux/string.h>
0019 #include <linux/slab.h>
0020 #include <linux/rtc.h>
0021 #include <linux/workqueue.h>
0022 #include <linux/spi/spi.h>
0023 #include <linux/module.h>
0024 
0025 #define RS5C348_REG_SECS    0
0026 #define RS5C348_REG_MINS    1
0027 #define RS5C348_REG_HOURS   2
0028 #define RS5C348_REG_WDAY    3
0029 #define RS5C348_REG_DAY 4
0030 #define RS5C348_REG_MONTH   5
0031 #define RS5C348_REG_YEAR    6
0032 #define RS5C348_REG_CTL1    14
0033 #define RS5C348_REG_CTL2    15
0034 
0035 #define RS5C348_SECS_MASK   0x7f
0036 #define RS5C348_MINS_MASK   0x7f
0037 #define RS5C348_HOURS_MASK  0x3f
0038 #define RS5C348_WDAY_MASK   0x03
0039 #define RS5C348_DAY_MASK    0x3f
0040 #define RS5C348_MONTH_MASK  0x1f
0041 
0042 #define RS5C348_BIT_PM  0x20    /* REG_HOURS */
0043 #define RS5C348_BIT_Y2K 0x80    /* REG_MONTH */
0044 #define RS5C348_BIT_24H 0x20    /* REG_CTL1 */
0045 #define RS5C348_BIT_XSTP    0x10    /* REG_CTL2 */
0046 #define RS5C348_BIT_VDET    0x40    /* REG_CTL2 */
0047 
0048 #define RS5C348_CMD_W(addr) (((addr) << 4) | 0x08)  /* single write */
0049 #define RS5C348_CMD_R(addr) (((addr) << 4) | 0x0c)  /* single read */
0050 #define RS5C348_CMD_MW(addr)    (((addr) << 4) | 0x00)  /* burst write */
0051 #define RS5C348_CMD_MR(addr)    (((addr) << 4) | 0x04)  /* burst read */
0052 
0053 struct rs5c348_plat_data {
0054     struct rtc_device *rtc;
0055     int rtc_24h;
0056 };
0057 
0058 static int
0059 rs5c348_rtc_set_time(struct device *dev, struct rtc_time *tm)
0060 {
0061     struct spi_device *spi = to_spi_device(dev);
0062     struct rs5c348_plat_data *pdata = dev_get_platdata(&spi->dev);
0063     u8 txbuf[5+7], *txp;
0064     int ret;
0065 
0066     ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
0067     if (ret < 0)
0068         return ret;
0069     if (ret & RS5C348_BIT_XSTP) {
0070         txbuf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2);
0071         txbuf[1] = 0;
0072         ret = spi_write_then_read(spi, txbuf, 2, NULL, 0);
0073         if (ret < 0)
0074             return ret;
0075     }
0076 
0077     /* Transfer 5 bytes before writing SEC.  This gives 31us for carry. */
0078     txp = txbuf;
0079     txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
0080     txbuf[1] = 0;   /* dummy */
0081     txbuf[2] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
0082     txbuf[3] = 0;   /* dummy */
0083     txbuf[4] = RS5C348_CMD_MW(RS5C348_REG_SECS); /* cmd, sec, ... */
0084     txp = &txbuf[5];
0085     txp[RS5C348_REG_SECS] = bin2bcd(tm->tm_sec);
0086     txp[RS5C348_REG_MINS] = bin2bcd(tm->tm_min);
0087     if (pdata->rtc_24h) {
0088         txp[RS5C348_REG_HOURS] = bin2bcd(tm->tm_hour);
0089     } else {
0090         /* hour 0 is AM12, noon is PM12 */
0091         txp[RS5C348_REG_HOURS] = bin2bcd((tm->tm_hour + 11) % 12 + 1) |
0092             (tm->tm_hour >= 12 ? RS5C348_BIT_PM : 0);
0093     }
0094     txp[RS5C348_REG_WDAY] = bin2bcd(tm->tm_wday);
0095     txp[RS5C348_REG_DAY] = bin2bcd(tm->tm_mday);
0096     txp[RS5C348_REG_MONTH] = bin2bcd(tm->tm_mon + 1) |
0097         (tm->tm_year >= 100 ? RS5C348_BIT_Y2K : 0);
0098     txp[RS5C348_REG_YEAR] = bin2bcd(tm->tm_year % 100);
0099     /* write in one transfer to avoid data inconsistency */
0100     ret = spi_write_then_read(spi, txbuf, sizeof(txbuf), NULL, 0);
0101     udelay(62); /* Tcsr 62us */
0102     return ret;
0103 }
0104 
0105 static int
0106 rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm)
0107 {
0108     struct spi_device *spi = to_spi_device(dev);
0109     struct rs5c348_plat_data *pdata = dev_get_platdata(&spi->dev);
0110     u8 txbuf[5], rxbuf[7];
0111     int ret;
0112 
0113     ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2));
0114     if (ret < 0)
0115         return ret;
0116     if (ret & RS5C348_BIT_VDET)
0117         dev_warn(&spi->dev, "voltage-low detected.\n");
0118     if (ret & RS5C348_BIT_XSTP) {
0119         dev_warn(&spi->dev, "oscillator-stop detected.\n");
0120         return -EINVAL;
0121     }
0122 
0123     /* Transfer 5 byte befores reading SEC.  This gives 31us for carry. */
0124     txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
0125     txbuf[1] = 0;   /* dummy */
0126     txbuf[2] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */
0127     txbuf[3] = 0;   /* dummy */
0128     txbuf[4] = RS5C348_CMD_MR(RS5C348_REG_SECS); /* cmd, sec, ... */
0129 
0130     /* read in one transfer to avoid data inconsistency */
0131     ret = spi_write_then_read(spi, txbuf, sizeof(txbuf),
0132                   rxbuf, sizeof(rxbuf));
0133     udelay(62); /* Tcsr 62us */
0134     if (ret < 0)
0135         return ret;
0136 
0137     tm->tm_sec = bcd2bin(rxbuf[RS5C348_REG_SECS] & RS5C348_SECS_MASK);
0138     tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK);
0139     tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK);
0140     if (!pdata->rtc_24h) {
0141         if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) {
0142             tm->tm_hour -= 20;
0143             tm->tm_hour %= 12;
0144             tm->tm_hour += 12;
0145         } else
0146             tm->tm_hour %= 12;
0147     }
0148     tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK);
0149     tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK);
0150     tm->tm_mon =
0151         bcd2bin(rxbuf[RS5C348_REG_MONTH] & RS5C348_MONTH_MASK) - 1;
0152     /* year is 1900 + tm->tm_year */
0153     tm->tm_year = bcd2bin(rxbuf[RS5C348_REG_YEAR]) +
0154         ((rxbuf[RS5C348_REG_MONTH] & RS5C348_BIT_Y2K) ? 100 : 0);
0155 
0156     return 0;
0157 }
0158 
0159 static const struct rtc_class_ops rs5c348_rtc_ops = {
0160     .read_time  = rs5c348_rtc_read_time,
0161     .set_time   = rs5c348_rtc_set_time,
0162 };
0163 
0164 static int rs5c348_probe(struct spi_device *spi)
0165 {
0166     int ret;
0167     struct rtc_device *rtc;
0168     struct rs5c348_plat_data *pdata;
0169 
0170     pdata = devm_kzalloc(&spi->dev, sizeof(struct rs5c348_plat_data),
0171                 GFP_KERNEL);
0172     if (!pdata)
0173         return -ENOMEM;
0174     spi->dev.platform_data = pdata;
0175 
0176     /* Check D7 of SECOND register */
0177     ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_SECS));
0178     if (ret < 0 || (ret & 0x80)) {
0179         dev_err(&spi->dev, "not found.\n");
0180         return ret;
0181     }
0182 
0183     dev_info(&spi->dev, "spiclk %u KHz.\n",
0184          (spi->max_speed_hz + 500) / 1000);
0185 
0186     ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL1));
0187     if (ret < 0)
0188         return ret;
0189     if (ret & RS5C348_BIT_24H)
0190         pdata->rtc_24h = 1;
0191 
0192     rtc = devm_rtc_allocate_device(&spi->dev);
0193     if (IS_ERR(rtc))
0194         return PTR_ERR(rtc);
0195 
0196     pdata->rtc = rtc;
0197 
0198     rtc->ops = &rs5c348_rtc_ops;
0199 
0200     return devm_rtc_register_device(rtc);
0201 }
0202 
0203 static struct spi_driver rs5c348_driver = {
0204     .driver = {
0205         .name   = "rtc-rs5c348",
0206     },
0207     .probe  = rs5c348_probe,
0208 };
0209 
0210 module_spi_driver(rs5c348_driver);
0211 
0212 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
0213 MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver");
0214 MODULE_LICENSE("GPL");
0215 MODULE_ALIAS("spi:rtc-rs5c348");