Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* rtc-max6916.c
0003  *
0004  * Driver for MAXIM  max6916 Low Current, SPI Compatible
0005  * Real Time Clock
0006  *
0007  * Author : Venkat Prashanth B U <venkat.prashanth2498@gmail.com>
0008  */
0009 
0010 #include <linux/init.h>
0011 #include <linux/module.h>
0012 #include <linux/device.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/rtc.h>
0015 #include <linux/spi/spi.h>
0016 #include <linux/bcd.h>
0017 
0018 /* Registers in max6916 rtc */
0019 
0020 #define MAX6916_SECONDS_REG 0x01
0021 #define MAX6916_MINUTES_REG 0x02
0022 #define MAX6916_HOURS_REG   0x03
0023 #define MAX6916_DATE_REG    0x04
0024 #define MAX6916_MONTH_REG   0x05
0025 #define MAX6916_DAY_REG 0x06
0026 #define MAX6916_YEAR_REG    0x07
0027 #define MAX6916_CONTROL_REG 0x08
0028 #define MAX6916_STATUS_REG  0x0C
0029 #define MAX6916_CLOCK_BURST 0x3F
0030 
0031 static int max6916_read_reg(struct device *dev, unsigned char address,
0032                 unsigned char *data)
0033 {
0034     struct spi_device *spi = to_spi_device(dev);
0035 
0036     *data = address | 0x80;
0037 
0038     return spi_write_then_read(spi, data, 1, data, 1);
0039 }
0040 
0041 static int max6916_write_reg(struct device *dev, unsigned char address,
0042                  unsigned char data)
0043 {
0044     struct spi_device *spi = to_spi_device(dev);
0045     unsigned char buf[2];
0046 
0047     buf[0] = address & 0x7F;
0048     buf[1] = data;
0049 
0050     return spi_write_then_read(spi, buf, 2, NULL, 0);
0051 }
0052 
0053 static int max6916_read_time(struct device *dev, struct rtc_time *dt)
0054 {
0055     struct spi_device *spi = to_spi_device(dev);
0056     int err;
0057     unsigned char buf[8];
0058 
0059     buf[0] = MAX6916_CLOCK_BURST | 0x80;
0060 
0061     err = spi_write_then_read(spi, buf, 1, buf, 8);
0062 
0063     if (err)
0064         return err;
0065 
0066     dt->tm_sec = bcd2bin(buf[0]);
0067     dt->tm_min = bcd2bin(buf[1]);
0068     dt->tm_hour = bcd2bin(buf[2] & 0x3F);
0069     dt->tm_mday = bcd2bin(buf[3]);
0070     dt->tm_mon = bcd2bin(buf[4]) - 1;
0071     dt->tm_wday = bcd2bin(buf[5]) - 1;
0072     dt->tm_year = bcd2bin(buf[6]) + 100;
0073 
0074     return 0;
0075 }
0076 
0077 static int max6916_set_time(struct device *dev, struct rtc_time *dt)
0078 {
0079     struct spi_device *spi = to_spi_device(dev);
0080     unsigned char buf[9];
0081 
0082     if (dt->tm_year < 100 || dt->tm_year > 199) {
0083         dev_err(&spi->dev, "Year must be between 2000 and 2099. It's %d.\n",
0084             dt->tm_year + 1900);
0085         return -EINVAL;
0086     }
0087 
0088     buf[0] = MAX6916_CLOCK_BURST & 0x7F;
0089     buf[1] = bin2bcd(dt->tm_sec);
0090     buf[2] = bin2bcd(dt->tm_min);
0091     buf[3] = (bin2bcd(dt->tm_hour) & 0X3F);
0092     buf[4] = bin2bcd(dt->tm_mday);
0093     buf[5] = bin2bcd(dt->tm_mon + 1);
0094     buf[6] = bin2bcd(dt->tm_wday + 1);
0095     buf[7] = bin2bcd(dt->tm_year % 100);
0096     buf[8] = bin2bcd(0x00);
0097 
0098     /* write the rtc settings */
0099     return spi_write_then_read(spi, buf, 9, NULL, 0);
0100 }
0101 
0102 static const struct rtc_class_ops max6916_rtc_ops = {
0103     .read_time = max6916_read_time,
0104     .set_time = max6916_set_time,
0105 };
0106 
0107 static int max6916_probe(struct spi_device *spi)
0108 {
0109     struct rtc_device *rtc;
0110     unsigned char data;
0111     int res;
0112 
0113     /* spi setup with max6916 in mode 3 and bits per word as 8 */
0114     spi->mode = SPI_MODE_3;
0115     spi->bits_per_word = 8;
0116     spi_setup(spi);
0117 
0118     /* RTC Settings */
0119     res = max6916_read_reg(&spi->dev, MAX6916_SECONDS_REG, &data);
0120     if (res)
0121         return res;
0122 
0123     /* Disable the write protect of rtc */
0124     max6916_read_reg(&spi->dev, MAX6916_CONTROL_REG, &data);
0125     data = data & ~(1 << 7);
0126     max6916_write_reg(&spi->dev, MAX6916_CONTROL_REG, data);
0127 
0128     /*Enable oscillator,disable oscillator stop flag, glitch filter*/
0129     max6916_read_reg(&spi->dev, MAX6916_STATUS_REG, &data);
0130     data = data & 0x1B;
0131     max6916_write_reg(&spi->dev, MAX6916_STATUS_REG, data);
0132 
0133     /* display the settings */
0134     max6916_read_reg(&spi->dev, MAX6916_CONTROL_REG, &data);
0135     dev_info(&spi->dev, "MAX6916 RTC CTRL Reg = 0x%02x\n", data);
0136 
0137     max6916_read_reg(&spi->dev, MAX6916_STATUS_REG, &data);
0138     dev_info(&spi->dev, "MAX6916 RTC Status Reg = 0x%02x\n", data);
0139 
0140     rtc = devm_rtc_device_register(&spi->dev, "max6916",
0141                        &max6916_rtc_ops, THIS_MODULE);
0142     if (IS_ERR(rtc))
0143         return PTR_ERR(rtc);
0144 
0145     spi_set_drvdata(spi, rtc);
0146 
0147     return 0;
0148 }
0149 
0150 static struct spi_driver max6916_driver = {
0151     .driver = {
0152         .name = "max6916",
0153     },
0154     .probe = max6916_probe,
0155 };
0156 module_spi_driver(max6916_driver);
0157 
0158 MODULE_DESCRIPTION("MAX6916 SPI RTC DRIVER");
0159 MODULE_AUTHOR("Venkat Prashanth B U <venkat.prashanth2498@gmail.com>");
0160 MODULE_LICENSE("GPL v2");