Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * An SPI driver for the Philips PCF2123 RTC
0004  * Copyright 2009 Cyber Switching, Inc.
0005  *
0006  * Author: Chris Verges <chrisv@cyberswitching.com>
0007  * Maintainers: http://www.cyberswitching.com
0008  *
0009  * based on the RS5C348 driver in this same directory.
0010  *
0011  * Thanks to Christian Pellegrin <chripell@fsfe.org> for
0012  * the sysfs contributions to this driver.
0013  *
0014  * Please note that the CS is active high, so platform data
0015  * should look something like:
0016  *
0017  * static struct spi_board_info ek_spi_devices[] = {
0018  *  ...
0019  *  {
0020  *      .modalias       = "rtc-pcf2123",
0021  *      .chip_select        = 1,
0022  *      .controller_data    = (void *)AT91_PIN_PA10,
0023  *      .max_speed_hz       = 1000 * 1000,
0024  *      .mode           = SPI_CS_HIGH,
0025  *      .bus_num        = 0,
0026  *  },
0027  *  ...
0028  *};
0029  */
0030 
0031 #include <linux/bcd.h>
0032 #include <linux/delay.h>
0033 #include <linux/device.h>
0034 #include <linux/errno.h>
0035 #include <linux/init.h>
0036 #include <linux/kernel.h>
0037 #include <linux/of.h>
0038 #include <linux/string.h>
0039 #include <linux/slab.h>
0040 #include <linux/rtc.h>
0041 #include <linux/spi/spi.h>
0042 #include <linux/module.h>
0043 #include <linux/regmap.h>
0044 
0045 /* REGISTERS */
0046 #define PCF2123_REG_CTRL1   (0x00)  /* Control Register 1 */
0047 #define PCF2123_REG_CTRL2   (0x01)  /* Control Register 2 */
0048 #define PCF2123_REG_SC      (0x02)  /* datetime */
0049 #define PCF2123_REG_MN      (0x03)
0050 #define PCF2123_REG_HR      (0x04)
0051 #define PCF2123_REG_DM      (0x05)
0052 #define PCF2123_REG_DW      (0x06)
0053 #define PCF2123_REG_MO      (0x07)
0054 #define PCF2123_REG_YR      (0x08)
0055 #define PCF2123_REG_ALRM_MN (0x09)  /* Alarm Registers */
0056 #define PCF2123_REG_ALRM_HR (0x0a)
0057 #define PCF2123_REG_ALRM_DM (0x0b)
0058 #define PCF2123_REG_ALRM_DW (0x0c)
0059 #define PCF2123_REG_OFFSET  (0x0d)  /* Clock Rate Offset Register */
0060 #define PCF2123_REG_TMR_CLKOUT  (0x0e)  /* Timer Registers */
0061 #define PCF2123_REG_CTDWN_TMR   (0x0f)
0062 
0063 /* PCF2123_REG_CTRL1 BITS */
0064 #define CTRL1_CLEAR     (0) /* Clear */
0065 #define CTRL1_CORR_INT      BIT(1)  /* Correction irq enable */
0066 #define CTRL1_12_HOUR       BIT(2)  /* 12 hour time */
0067 #define CTRL1_SW_RESET  (BIT(3) | BIT(4) | BIT(6))  /* Software reset */
0068 #define CTRL1_STOP      BIT(5)  /* Stop the clock */
0069 #define CTRL1_EXT_TEST      BIT(7)  /* External clock test mode */
0070 
0071 /* PCF2123_REG_CTRL2 BITS */
0072 #define CTRL2_TIE       BIT(0)  /* Countdown timer irq enable */
0073 #define CTRL2_AIE       BIT(1)  /* Alarm irq enable */
0074 #define CTRL2_TF        BIT(2)  /* Countdown timer flag */
0075 #define CTRL2_AF        BIT(3)  /* Alarm flag */
0076 #define CTRL2_TI_TP     BIT(4)  /* Irq pin generates pulse */
0077 #define CTRL2_MSF       BIT(5)  /* Minute or second irq flag */
0078 #define CTRL2_SI        BIT(6)  /* Second irq enable */
0079 #define CTRL2_MI        BIT(7)  /* Minute irq enable */
0080 
0081 /* PCF2123_REG_SC BITS */
0082 #define OSC_HAS_STOPPED     BIT(7)  /* Clock has been stopped */
0083 
0084 /* PCF2123_REG_ALRM_XX BITS */
0085 #define ALRM_DISABLE        BIT(7)  /* MN, HR, DM, or DW alarm matching */
0086 
0087 /* PCF2123_REG_TMR_CLKOUT BITS */
0088 #define CD_TMR_4096KHZ      (0) /* 4096 KHz countdown timer */
0089 #define CD_TMR_64HZ     (1) /* 64 Hz countdown timer */
0090 #define CD_TMR_1HZ      (2) /* 1 Hz countdown timer */
0091 #define CD_TMR_60th_HZ      (3) /* 60th Hz countdown timer */
0092 #define CD_TMR_TE       BIT(3)  /* Countdown timer enable */
0093 
0094 /* PCF2123_REG_OFFSET BITS */
0095 #define OFFSET_SIGN_BIT     6   /* 2's complement sign bit */
0096 #define OFFSET_COARSE       BIT(7)  /* Coarse mode offset */
0097 #define OFFSET_STEP     (2170)  /* Offset step in parts per billion */
0098 #define OFFSET_MASK     GENMASK(6, 0)   /* Offset value */
0099 
0100 /* READ/WRITE ADDRESS BITS */
0101 #define PCF2123_WRITE       BIT(4)
0102 #define PCF2123_READ        (BIT(4) | BIT(7))
0103 
0104 
0105 static struct spi_driver pcf2123_driver;
0106 
0107 struct pcf2123_data {
0108     struct rtc_device *rtc;
0109     struct regmap *map;
0110 };
0111 
0112 static const struct regmap_config pcf2123_regmap_config = {
0113     .reg_bits = 8,
0114     .val_bits = 8,
0115     .read_flag_mask = PCF2123_READ,
0116     .write_flag_mask = PCF2123_WRITE,
0117     .max_register = PCF2123_REG_CTDWN_TMR,
0118 };
0119 
0120 static int pcf2123_read_offset(struct device *dev, long *offset)
0121 {
0122     struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
0123     int ret, val;
0124     unsigned int reg;
0125 
0126     ret = regmap_read(pcf2123->map, PCF2123_REG_OFFSET, &reg);
0127     if (ret)
0128         return ret;
0129 
0130     val = sign_extend32((reg & OFFSET_MASK), OFFSET_SIGN_BIT);
0131 
0132     if (reg & OFFSET_COARSE)
0133         val *= 2;
0134 
0135     *offset = ((long)val) * OFFSET_STEP;
0136 
0137     return 0;
0138 }
0139 
0140 /*
0141  * The offset register is a 7 bit signed value with a coarse bit in bit 7.
0142  * The main difference between the two is normal offset adjusts the first
0143  * second of n minutes every other hour, with 61, 62 and 63 being shoved
0144  * into the 60th minute.
0145  * The coarse adjustment does the same, but every hour.
0146  * the two overlap, with every even normal offset value corresponding
0147  * to a coarse offset. Based on this algorithm, it seems that despite the
0148  * name, coarse offset is a better fit for overlapping values.
0149  */
0150 static int pcf2123_set_offset(struct device *dev, long offset)
0151 {
0152     struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
0153     s8 reg;
0154 
0155     if (offset > OFFSET_STEP * 127)
0156         reg = 127;
0157     else if (offset < OFFSET_STEP * -128)
0158         reg = -128;
0159     else
0160         reg = DIV_ROUND_CLOSEST(offset, OFFSET_STEP);
0161 
0162     /* choose fine offset only for odd values in the normal range */
0163     if (reg & 1 && reg <= 63 && reg >= -64) {
0164         /* Normal offset. Clear the coarse bit */
0165         reg &= ~OFFSET_COARSE;
0166     } else {
0167         /* Coarse offset. Divide by 2 and set the coarse bit */
0168         reg >>= 1;
0169         reg |= OFFSET_COARSE;
0170     }
0171 
0172     return regmap_write(pcf2123->map, PCF2123_REG_OFFSET, (unsigned int)reg);
0173 }
0174 
0175 static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm)
0176 {
0177     struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
0178     u8 rxbuf[7];
0179     int ret;
0180 
0181     ret = regmap_bulk_read(pcf2123->map, PCF2123_REG_SC, rxbuf,
0182                 sizeof(rxbuf));
0183     if (ret)
0184         return ret;
0185 
0186     if (rxbuf[0] & OSC_HAS_STOPPED) {
0187         dev_info(dev, "clock was stopped. Time is not valid\n");
0188         return -EINVAL;
0189     }
0190 
0191     tm->tm_sec = bcd2bin(rxbuf[0] & 0x7F);
0192     tm->tm_min = bcd2bin(rxbuf[1] & 0x7F);
0193     tm->tm_hour = bcd2bin(rxbuf[2] & 0x3F); /* rtc hr 0-23 */
0194     tm->tm_mday = bcd2bin(rxbuf[3] & 0x3F);
0195     tm->tm_wday = rxbuf[4] & 0x07;
0196     tm->tm_mon = bcd2bin(rxbuf[5] & 0x1F) - 1; /* rtc mn 1-12 */
0197     tm->tm_year = bcd2bin(rxbuf[6]) + 100;
0198 
0199     dev_dbg(dev, "%s: tm is %ptR\n", __func__, tm);
0200 
0201     return 0;
0202 }
0203 
0204 static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm)
0205 {
0206     struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
0207     u8 txbuf[7];
0208     int ret;
0209 
0210     dev_dbg(dev, "%s: tm is %ptR\n", __func__, tm);
0211 
0212     /* Stop the counter first */
0213     ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_STOP);
0214     if (ret)
0215         return ret;
0216 
0217     /* Set the new time */
0218     txbuf[0] = bin2bcd(tm->tm_sec & 0x7F);
0219     txbuf[1] = bin2bcd(tm->tm_min & 0x7F);
0220     txbuf[2] = bin2bcd(tm->tm_hour & 0x3F);
0221     txbuf[3] = bin2bcd(tm->tm_mday & 0x3F);
0222     txbuf[4] = tm->tm_wday & 0x07;
0223     txbuf[5] = bin2bcd((tm->tm_mon + 1) & 0x1F); /* rtc mn 1-12 */
0224     txbuf[6] = bin2bcd(tm->tm_year - 100);
0225 
0226     ret = regmap_bulk_write(pcf2123->map, PCF2123_REG_SC, txbuf,
0227                 sizeof(txbuf));
0228     if (ret)
0229         return ret;
0230 
0231     /* Start the counter */
0232     ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_CLEAR);
0233     if (ret)
0234         return ret;
0235 
0236     return 0;
0237 }
0238 
0239 static int pcf2123_rtc_alarm_irq_enable(struct device *dev, unsigned int en)
0240 {
0241     struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
0242 
0243     return regmap_update_bits(pcf2123->map, PCF2123_REG_CTRL2, CTRL2_AIE,
0244                   en ? CTRL2_AIE : 0);
0245 }
0246 
0247 static int pcf2123_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
0248 {
0249     struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
0250     u8 rxbuf[4];
0251     int ret;
0252     unsigned int val = 0;
0253 
0254     ret = regmap_bulk_read(pcf2123->map, PCF2123_REG_ALRM_MN, rxbuf,
0255                 sizeof(rxbuf));
0256     if (ret)
0257         return ret;
0258 
0259     alm->time.tm_min = bcd2bin(rxbuf[0] & 0x7F);
0260     alm->time.tm_hour = bcd2bin(rxbuf[1] & 0x3F);
0261     alm->time.tm_mday = bcd2bin(rxbuf[2] & 0x3F);
0262     alm->time.tm_wday = bcd2bin(rxbuf[3] & 0x07);
0263 
0264     dev_dbg(dev, "%s: alm is %ptR\n", __func__, &alm->time);
0265 
0266     ret = regmap_read(pcf2123->map, PCF2123_REG_CTRL2, &val);
0267     if (ret)
0268         return ret;
0269 
0270     alm->enabled = !!(val & CTRL2_AIE);
0271 
0272     return 0;
0273 }
0274 
0275 static int pcf2123_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
0276 {
0277     struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
0278     u8 txbuf[4];
0279     int ret;
0280 
0281     dev_dbg(dev, "%s: alm is %ptR\n", __func__, &alm->time);
0282 
0283     /* Disable alarm interrupt */
0284     ret = regmap_update_bits(pcf2123->map, PCF2123_REG_CTRL2, CTRL2_AIE, 0);
0285     if (ret)
0286         return ret;
0287 
0288     /* Ensure alarm flag is clear */
0289     ret = regmap_update_bits(pcf2123->map, PCF2123_REG_CTRL2, CTRL2_AF, 0);
0290     if (ret)
0291         return ret;
0292 
0293     /* Set new alarm */
0294     txbuf[0] = bin2bcd(alm->time.tm_min & 0x7F);
0295     txbuf[1] = bin2bcd(alm->time.tm_hour & 0x3F);
0296     txbuf[2] = bin2bcd(alm->time.tm_mday & 0x3F);
0297     txbuf[3] = ALRM_DISABLE;
0298 
0299     ret = regmap_bulk_write(pcf2123->map, PCF2123_REG_ALRM_MN, txbuf,
0300                 sizeof(txbuf));
0301     if (ret)
0302         return ret;
0303 
0304     return pcf2123_rtc_alarm_irq_enable(dev, alm->enabled);
0305 }
0306 
0307 static irqreturn_t pcf2123_rtc_irq(int irq, void *dev)
0308 {
0309     struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
0310     unsigned int val = 0;
0311     int ret = IRQ_NONE;
0312 
0313     rtc_lock(pcf2123->rtc);
0314     regmap_read(pcf2123->map, PCF2123_REG_CTRL2, &val);
0315 
0316     /* Alarm? */
0317     if (val & CTRL2_AF) {
0318         ret = IRQ_HANDLED;
0319 
0320         /* Clear alarm flag */
0321         regmap_update_bits(pcf2123->map, PCF2123_REG_CTRL2, CTRL2_AF, 0);
0322 
0323         rtc_update_irq(pcf2123->rtc, 1, RTC_IRQF | RTC_AF);
0324     }
0325 
0326     rtc_unlock(pcf2123->rtc);
0327 
0328     return ret;
0329 }
0330 
0331 static int pcf2123_reset(struct device *dev)
0332 {
0333     struct pcf2123_data *pcf2123 = dev_get_drvdata(dev);
0334     int ret;
0335     unsigned int val = 0;
0336 
0337     ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_SW_RESET);
0338     if (ret)
0339         return ret;
0340 
0341     /* Stop the counter */
0342     dev_dbg(dev, "stopping RTC\n");
0343     ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_STOP);
0344     if (ret)
0345         return ret;
0346 
0347     /* See if the counter was actually stopped */
0348     dev_dbg(dev, "checking for presence of RTC\n");
0349     ret = regmap_read(pcf2123->map, PCF2123_REG_CTRL1, &val);
0350     if (ret)
0351         return ret;
0352 
0353     dev_dbg(dev, "received data from RTC (0x%08X)\n", val);
0354     if (!(val & CTRL1_STOP))
0355         return -ENODEV;
0356 
0357     /* Start the counter */
0358     ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_CLEAR);
0359     if (ret)
0360         return ret;
0361 
0362     return 0;
0363 }
0364 
0365 static const struct rtc_class_ops pcf2123_rtc_ops = {
0366     .read_time  = pcf2123_rtc_read_time,
0367     .set_time   = pcf2123_rtc_set_time,
0368     .read_offset    = pcf2123_read_offset,
0369     .set_offset = pcf2123_set_offset,
0370     .read_alarm = pcf2123_rtc_read_alarm,
0371     .set_alarm  = pcf2123_rtc_set_alarm,
0372     .alarm_irq_enable = pcf2123_rtc_alarm_irq_enable,
0373 };
0374 
0375 static int pcf2123_probe(struct spi_device *spi)
0376 {
0377     struct rtc_device *rtc;
0378     struct rtc_time tm;
0379     struct pcf2123_data *pcf2123;
0380     int ret = 0;
0381 
0382     pcf2123 = devm_kzalloc(&spi->dev, sizeof(struct pcf2123_data),
0383                 GFP_KERNEL);
0384     if (!pcf2123)
0385         return -ENOMEM;
0386 
0387     dev_set_drvdata(&spi->dev, pcf2123);
0388 
0389     pcf2123->map = devm_regmap_init_spi(spi, &pcf2123_regmap_config);
0390     if (IS_ERR(pcf2123->map)) {
0391         dev_err(&spi->dev, "regmap init failed.\n");
0392         return PTR_ERR(pcf2123->map);
0393     }
0394 
0395     ret = pcf2123_rtc_read_time(&spi->dev, &tm);
0396     if (ret < 0) {
0397         ret = pcf2123_reset(&spi->dev);
0398         if (ret < 0) {
0399             dev_err(&spi->dev, "chip not found\n");
0400             return ret;
0401         }
0402     }
0403 
0404     dev_info(&spi->dev, "spiclk %u KHz.\n",
0405             (spi->max_speed_hz + 500) / 1000);
0406 
0407     /* Finalize the initialization */
0408     rtc = devm_rtc_allocate_device(&spi->dev);
0409     if (IS_ERR(rtc))
0410         return PTR_ERR(rtc);
0411 
0412     pcf2123->rtc = rtc;
0413 
0414     /* Register alarm irq */
0415     if (spi->irq > 0) {
0416         ret = devm_request_threaded_irq(&spi->dev, spi->irq, NULL,
0417                 pcf2123_rtc_irq,
0418                 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
0419                 pcf2123_driver.driver.name, &spi->dev);
0420         if (!ret)
0421             device_init_wakeup(&spi->dev, true);
0422         else
0423             dev_err(&spi->dev, "could not request irq.\n");
0424     }
0425 
0426     /* The PCF2123's alarm only has minute accuracy. Must add timer
0427      * support to this driver to generate interrupts more than once
0428      * per minute.
0429      */
0430     set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->features);
0431     clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);
0432     rtc->ops = &pcf2123_rtc_ops;
0433     rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
0434     rtc->range_max = RTC_TIMESTAMP_END_2099;
0435     rtc->set_start_time = true;
0436 
0437     ret = devm_rtc_register_device(rtc);
0438     if (ret)
0439         return ret;
0440 
0441     return 0;
0442 }
0443 
0444 #ifdef CONFIG_OF
0445 static const struct of_device_id pcf2123_dt_ids[] = {
0446     { .compatible = "nxp,pcf2123", },
0447     { .compatible = "microcrystal,rv2123", },
0448     /* Deprecated, do not use */
0449     { .compatible = "nxp,rtc-pcf2123", },
0450     { /* sentinel */ }
0451 };
0452 MODULE_DEVICE_TABLE(of, pcf2123_dt_ids);
0453 #endif
0454 
0455 static const struct spi_device_id pcf2123_spi_ids[] = {
0456     { .name = "pcf2123", },
0457     { .name = "rv2123", },
0458     { .name = "rtc-pcf2123", },
0459     { /* sentinel */ }
0460 };
0461 MODULE_DEVICE_TABLE(spi, pcf2123_spi_ids);
0462 
0463 static struct spi_driver pcf2123_driver = {
0464     .driver = {
0465             .name   = "rtc-pcf2123",
0466             .of_match_table = of_match_ptr(pcf2123_dt_ids),
0467     },
0468     .probe  = pcf2123_probe,
0469     .id_table = pcf2123_spi_ids,
0470 };
0471 
0472 module_spi_driver(pcf2123_driver);
0473 
0474 MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>");
0475 MODULE_DESCRIPTION("NXP PCF2123 RTC driver");
0476 MODULE_LICENSE("GPL");