^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * An rtc/i2c driver for the EM Microelectronic EM3027
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright 2011 CompuLab, Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Mike Rapoport <mike@compulab.co.il>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Based on rtc-ds1672.c by Alessandro Zummo <a.zummo@towertech.it>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/rtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/bcd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define EM3027_REG_ON_OFF_CTRL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define EM3027_REG_IRQ_CTRL 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define EM3027_REG_IRQ_FLAGS 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define EM3027_REG_STATUS 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define EM3027_REG_RST_CTRL 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define EM3027_REG_WATCH_SEC 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define EM3027_REG_WATCH_MIN 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define EM3027_REG_WATCH_HOUR 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define EM3027_REG_WATCH_DATE 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define EM3027_REG_WATCH_DAY 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define EM3027_REG_WATCH_MON 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define EM3027_REG_WATCH_YEAR 0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define EM3027_REG_ALARM_SEC 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define EM3027_REG_ALARM_MIN 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define EM3027_REG_ALARM_HOUR 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define EM3027_REG_ALARM_DATE 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define EM3027_REG_ALARM_DAY 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define EM3027_REG_ALARM_MON 0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define EM3027_REG_ALARM_YEAR 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static struct i2c_driver em3027_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int em3027_get_time(struct device *dev, struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned char addr = EM3027_REG_WATCH_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) unsigned char buf[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct i2c_msg msgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {/* setup read addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .addr = client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .len = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .buf = &addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {/* read time/date */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .addr = client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .len = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .buf = buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* read time/date registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) dev_err(&client->dev, "%s: read error\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) tm->tm_sec = bcd2bin(buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) tm->tm_min = bcd2bin(buf[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) tm->tm_hour = bcd2bin(buf[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) tm->tm_mday = bcd2bin(buf[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) tm->tm_wday = bcd2bin(buf[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) tm->tm_mon = bcd2bin(buf[5]) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) tm->tm_year = bcd2bin(buf[6]) + 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static int em3027_set_time(struct device *dev, struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned char buf[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct i2c_msg msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .addr = client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .len = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .buf = buf, /* write time/date */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) buf[0] = EM3027_REG_WATCH_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) buf[1] = bin2bcd(tm->tm_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) buf[2] = bin2bcd(tm->tm_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) buf[3] = bin2bcd(tm->tm_hour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) buf[4] = bin2bcd(tm->tm_mday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) buf[5] = bin2bcd(tm->tm_wday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) buf[6] = bin2bcd(tm->tm_mon + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) buf[7] = bin2bcd(tm->tm_year % 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* write time/date registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if ((i2c_transfer(client->adapter, &msg, 1)) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) dev_err(&client->dev, "%s: write error\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static const struct rtc_class_ops em3027_rtc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .read_time = em3027_get_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .set_time = em3027_set_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static int em3027_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct rtc_device *rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) rtc = devm_rtc_device_register(&client->dev, em3027_driver.driver.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) &em3027_rtc_ops, THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (IS_ERR(rtc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return PTR_ERR(rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) i2c_set_clientdata(client, rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static const struct i2c_device_id em3027_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) { "em3027", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) MODULE_DEVICE_TABLE(i2c, em3027_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static const struct of_device_id em3027_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) { .compatible = "emmicro,em3027", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) MODULE_DEVICE_TABLE(of, em3027_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static struct i2c_driver em3027_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .name = "rtc-em3027",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .of_match_table = of_match_ptr(em3027_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .probe = &em3027_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .id_table = em3027_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) module_i2c_driver(em3027_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) MODULE_DESCRIPTION("EM Microelectronic EM3027 RTC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) MODULE_LICENSE("GPL");