Blame view
drivers/rtc/rtc-m41t94.c
3.88 KB
8fc2c767b rtc: add support ... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
/* * Driver for ST M41T94 SPI RTC * * Copyright (C) 2008 Kim B. Heino * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/rtc.h> #include <linux/spi/spi.h> #include <linux/bcd.h> #define M41T94_REG_SECONDS 0x01 #define M41T94_REG_MINUTES 0x02 #define M41T94_REG_HOURS 0x03 #define M41T94_REG_WDAY 0x04 #define M41T94_REG_DAY 0x05 #define M41T94_REG_MONTH 0x06 #define M41T94_REG_YEAR 0x07 #define M41T94_REG_HT 0x0c #define M41T94_BIT_HALT 0x40 #define M41T94_BIT_STOP 0x80 #define M41T94_BIT_CB 0x40 #define M41T94_BIT_CEB 0x80 static int m41t94_set_time(struct device *dev, struct rtc_time *tm) { struct spi_device *spi = to_spi_device(dev); u8 buf[8]; /* write cmd + 7 registers */ dev_dbg(dev, "%s secs=%d, mins=%d, " "hours=%d, mday=%d, mon=%d, year=%d, wday=%d ", "write", tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); buf[0] = 0x80 | M41T94_REG_SECONDS; /* write time + date */ |
fe20ba70a drivers/rtc/: use... |
45 46 47 48 49 50 |
buf[M41T94_REG_SECONDS] = bin2bcd(tm->tm_sec); buf[M41T94_REG_MINUTES] = bin2bcd(tm->tm_min); buf[M41T94_REG_HOURS] = bin2bcd(tm->tm_hour); buf[M41T94_REG_WDAY] = bin2bcd(tm->tm_wday + 1); buf[M41T94_REG_DAY] = bin2bcd(tm->tm_mday); buf[M41T94_REG_MONTH] = bin2bcd(tm->tm_mon + 1); |
8fc2c767b rtc: add support ... |
51 52 53 54 |
buf[M41T94_REG_HOURS] |= M41T94_BIT_CEB; if (tm->tm_year >= 100) buf[M41T94_REG_HOURS] |= M41T94_BIT_CB; |
fe20ba70a drivers/rtc/: use... |
55 |
buf[M41T94_REG_YEAR] = bin2bcd(tm->tm_year % 100); |
8fc2c767b rtc: add support ... |
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
return spi_write(spi, buf, 8); } static int m41t94_read_time(struct device *dev, struct rtc_time *tm) { struct spi_device *spi = to_spi_device(dev); u8 buf[2]; int ret, hour; /* clear halt update bit */ ret = spi_w8r8(spi, M41T94_REG_HT); if (ret < 0) return ret; if (ret & M41T94_BIT_HALT) { buf[0] = 0x80 | M41T94_REG_HT; buf[1] = ret & ~M41T94_BIT_HALT; spi_write(spi, buf, 2); } /* clear stop bit */ ret = spi_w8r8(spi, M41T94_REG_SECONDS); if (ret < 0) return ret; if (ret & M41T94_BIT_STOP) { buf[0] = 0x80 | M41T94_REG_SECONDS; buf[1] = ret & ~M41T94_BIT_STOP; spi_write(spi, buf, 2); } |
fe20ba70a drivers/rtc/: use... |
85 86 |
tm->tm_sec = bcd2bin(spi_w8r8(spi, M41T94_REG_SECONDS)); tm->tm_min = bcd2bin(spi_w8r8(spi, M41T94_REG_MINUTES)); |
8fc2c767b rtc: add support ... |
87 |
hour = spi_w8r8(spi, M41T94_REG_HOURS); |
fe20ba70a drivers/rtc/: use... |
88 89 90 91 92 |
tm->tm_hour = bcd2bin(hour & 0x3f); tm->tm_wday = bcd2bin(spi_w8r8(spi, M41T94_REG_WDAY)) - 1; tm->tm_mday = bcd2bin(spi_w8r8(spi, M41T94_REG_DAY)); tm->tm_mon = bcd2bin(spi_w8r8(spi, M41T94_REG_MONTH)) - 1; tm->tm_year = bcd2bin(spi_w8r8(spi, M41T94_REG_YEAR)); |
8fc2c767b rtc: add support ... |
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
if ((hour & M41T94_BIT_CB) || !(hour & M41T94_BIT_CEB)) tm->tm_year += 100; dev_dbg(dev, "%s secs=%d, mins=%d, " "hours=%d, mday=%d, mon=%d, year=%d, wday=%d ", "read", tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); /* initial clock setting can be undefined */ return rtc_valid_tm(tm); } static const struct rtc_class_ops m41t94_rtc_ops = { .read_time = m41t94_read_time, .set_time = m41t94_set_time, }; static struct spi_driver m41t94_driver; |
5a167f454 Drivers: rtc: rem... |
113 |
static int m41t94_probe(struct spi_device *spi) |
8fc2c767b rtc: add support ... |
114 115 116 117 118 119 120 121 122 123 124 125 126 |
{ struct rtc_device *rtc; int res; spi->bits_per_word = 8; spi_setup(spi); res = spi_w8r8(spi, M41T94_REG_SECONDS); if (res < 0) { dev_err(&spi->dev, "not found. "); return res; } |
fb320d0a5 rtc: rtc-m41t94: ... |
127 128 |
rtc = devm_rtc_device_register(&spi->dev, m41t94_driver.driver.name, &m41t94_rtc_ops, THIS_MODULE); |
8fc2c767b rtc: add support ... |
129 130 |
if (IS_ERR(rtc)) return PTR_ERR(rtc); |
ee62474d5 rtc: rtc-m41t94: ... |
131 |
spi_set_drvdata(spi, rtc); |
8fc2c767b rtc: add support ... |
132 133 134 |
return 0; } |
8fc2c767b rtc: add support ... |
135 136 137 |
static struct spi_driver m41t94_driver = { .driver = { .name = "rtc-m41t94", |
8fc2c767b rtc: add support ... |
138 139 |
}, .probe = m41t94_probe, |
8fc2c767b rtc: add support ... |
140 |
}; |
109e94184 rtc: convert rtc ... |
141 |
module_spi_driver(m41t94_driver); |
8fc2c767b rtc: add support ... |
142 143 144 145 |
MODULE_AUTHOR("Kim B. Heino <Kim.Heino@bluegiga.com>"); MODULE_DESCRIPTION("Driver for ST M41T94 SPI RTC"); MODULE_LICENSE("GPL"); |
e0626e384 spi: prefix modal... |
146 |
MODULE_ALIAS("spi:rtc-m41t94"); |