rtc-ds1347.c (4322B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* rtc-ds1347.c 3 * 4 * Driver for Dallas Semiconductor DS1347 Low Current, SPI Compatible 5 * Real Time Clock 6 * 7 * Author : Raghavendra Chandra Ganiga <ravi23ganiga@gmail.com> 8 */ 9 10#include <linux/init.h> 11#include <linux/module.h> 12#include <linux/device.h> 13#include <linux/platform_device.h> 14#include <linux/rtc.h> 15#include <linux/spi/spi.h> 16#include <linux/bcd.h> 17#include <linux/regmap.h> 18 19/* Registers in ds1347 rtc */ 20 21#define DS1347_SECONDS_REG 0x01 22#define DS1347_MINUTES_REG 0x03 23#define DS1347_HOURS_REG 0x05 24#define DS1347_DATE_REG 0x07 25#define DS1347_MONTH_REG 0x09 26#define DS1347_DAY_REG 0x0B 27#define DS1347_YEAR_REG 0x0D 28#define DS1347_CONTROL_REG 0x0F 29#define DS1347_CENTURY_REG 0x13 30#define DS1347_STATUS_REG 0x17 31#define DS1347_CLOCK_BURST 0x3F 32 33#define DS1347_WP_BIT BIT(7) 34 35#define DS1347_NEOSC_BIT BIT(7) 36#define DS1347_OSF_BIT BIT(2) 37 38static const struct regmap_range ds1347_ranges[] = { 39 { 40 .range_min = DS1347_SECONDS_REG, 41 .range_max = DS1347_STATUS_REG, 42 }, 43}; 44 45static const struct regmap_access_table ds1347_access_table = { 46 .yes_ranges = ds1347_ranges, 47 .n_yes_ranges = ARRAY_SIZE(ds1347_ranges), 48}; 49 50static int ds1347_read_time(struct device *dev, struct rtc_time *dt) 51{ 52 struct regmap *map = dev_get_drvdata(dev); 53 unsigned int status, century, secs; 54 unsigned char buf[8]; 55 int err; 56 57 err = regmap_read(map, DS1347_STATUS_REG, &status); 58 if (err) 59 return err; 60 61 if (status & DS1347_OSF_BIT) 62 return -EINVAL; 63 64 do { 65 err = regmap_bulk_read(map, DS1347_CLOCK_BURST, buf, 8); 66 if (err) 67 return err; 68 69 err = regmap_read(map, DS1347_CENTURY_REG, ¢ury); 70 if (err) 71 return err; 72 73 err = regmap_read(map, DS1347_SECONDS_REG, &secs); 74 if (err) 75 return err; 76 } while (buf[0] != secs); 77 78 dt->tm_sec = bcd2bin(buf[0]); 79 dt->tm_min = bcd2bin(buf[1] & 0x7f); 80 dt->tm_hour = bcd2bin(buf[2] & 0x3F); 81 dt->tm_mday = bcd2bin(buf[3]); 82 dt->tm_mon = bcd2bin(buf[4]) - 1; 83 dt->tm_wday = bcd2bin(buf[5]) - 1; 84 dt->tm_year = (bcd2bin(century) * 100) + bcd2bin(buf[6]) - 1900; 85 86 return 0; 87} 88 89static int ds1347_set_time(struct device *dev, struct rtc_time *dt) 90{ 91 struct regmap *map = dev_get_drvdata(dev); 92 unsigned int century; 93 unsigned char buf[8]; 94 int err; 95 96 err = regmap_update_bits(map, DS1347_STATUS_REG, 97 DS1347_NEOSC_BIT, DS1347_NEOSC_BIT); 98 if (err) 99 return err; 100 101 buf[0] = bin2bcd(dt->tm_sec); 102 buf[1] = bin2bcd(dt->tm_min); 103 buf[2] = (bin2bcd(dt->tm_hour) & 0x3F); 104 buf[3] = bin2bcd(dt->tm_mday); 105 buf[4] = bin2bcd(dt->tm_mon + 1); 106 buf[5] = bin2bcd(dt->tm_wday + 1); 107 buf[6] = bin2bcd(dt->tm_year % 100); 108 buf[7] = bin2bcd(0x00); 109 110 err = regmap_bulk_write(map, DS1347_CLOCK_BURST, buf, 8); 111 if (err) 112 return err; 113 114 century = (dt->tm_year / 100) + 19; 115 err = regmap_write(map, DS1347_CENTURY_REG, century); 116 if (err) 117 return err; 118 119 return regmap_update_bits(map, DS1347_STATUS_REG, 120 DS1347_NEOSC_BIT | DS1347_OSF_BIT, 0); 121} 122 123static const struct rtc_class_ops ds1347_rtc_ops = { 124 .read_time = ds1347_read_time, 125 .set_time = ds1347_set_time, 126}; 127 128static int ds1347_probe(struct spi_device *spi) 129{ 130 struct rtc_device *rtc; 131 struct regmap_config config; 132 struct regmap *map; 133 int err; 134 135 memset(&config, 0, sizeof(config)); 136 config.reg_bits = 8; 137 config.val_bits = 8; 138 config.read_flag_mask = 0x80; 139 config.max_register = 0x3F; 140 config.wr_table = &ds1347_access_table; 141 142 /* spi setup with ds1347 in mode 3 and bits per word as 8 */ 143 spi->mode = SPI_MODE_3; 144 spi->bits_per_word = 8; 145 spi_setup(spi); 146 147 map = devm_regmap_init_spi(spi, &config); 148 149 if (IS_ERR(map)) { 150 dev_err(&spi->dev, "ds1347 regmap init spi failed\n"); 151 return PTR_ERR(map); 152 } 153 154 spi_set_drvdata(spi, map); 155 156 /* Disable the write protect of rtc */ 157 err = regmap_update_bits(map, DS1347_CONTROL_REG, DS1347_WP_BIT, 0); 158 if (err) 159 return err; 160 161 rtc = devm_rtc_allocate_device(&spi->dev); 162 if (IS_ERR(rtc)) 163 return PTR_ERR(rtc); 164 165 rtc->ops = &ds1347_rtc_ops; 166 rtc->range_min = RTC_TIMESTAMP_BEGIN_0000; 167 rtc->range_max = RTC_TIMESTAMP_END_9999; 168 169 return devm_rtc_register_device(rtc); 170} 171 172static struct spi_driver ds1347_driver = { 173 .driver = { 174 .name = "ds1347", 175 }, 176 .probe = ds1347_probe, 177}; 178 179module_spi_driver(ds1347_driver); 180 181MODULE_DESCRIPTION("DS1347 SPI RTC DRIVER"); 182MODULE_AUTHOR("Raghavendra C Ganiga <ravi23ganiga@gmail.com>"); 183MODULE_LICENSE("GPL v2");