rtc-sd3078.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Real Time Clock (RTC) Driver for sd3078
  4. * Copyright (C) 2018 Zoro Li
  5. */
  6. #include <linux/bcd.h>
  7. #include <linux/i2c.h>
  8. #include <linux/module.h>
  9. #include <linux/regmap.h>
  10. #include <linux/rtc.h>
  11. #include <linux/slab.h>
  12. #define SD3078_REG_SC 0x00
  13. #define SD3078_REG_MN 0x01
  14. #define SD3078_REG_HR 0x02
  15. #define SD3078_REG_DW 0x03
  16. #define SD3078_REG_DM 0x04
  17. #define SD3078_REG_MO 0x05
  18. #define SD3078_REG_YR 0x06
  19. #define SD3078_REG_CTRL1 0x0f
  20. #define SD3078_REG_CTRL2 0x10
  21. #define SD3078_REG_CTRL3 0x11
  22. #define KEY_WRITE1 0x80
  23. #define KEY_WRITE2 0x04
  24. #define KEY_WRITE3 0x80
  25. #define NUM_TIME_REGS (SD3078_REG_YR - SD3078_REG_SC + 1)
  26. /*
  27. * The sd3078 has write protection
  28. * and we can choose whether or not to use it.
  29. * Write protection is turned off by default.
  30. */
  31. #define WRITE_PROTECT_EN 0
  32. /*
  33. * In order to prevent arbitrary modification of the time register,
  34. * when modification of the register,
  35. * the "write" bit needs to be written in a certain order.
  36. * 1. set WRITE1 bit
  37. * 2. set WRITE2 bit
  38. * 3. set WRITE3 bit
  39. */
  40. static void sd3078_enable_reg_write(struct regmap *regmap)
  41. {
  42. regmap_update_bits(regmap, SD3078_REG_CTRL2, KEY_WRITE1, KEY_WRITE1);
  43. regmap_update_bits(regmap, SD3078_REG_CTRL1, KEY_WRITE2, KEY_WRITE2);
  44. regmap_update_bits(regmap, SD3078_REG_CTRL1, KEY_WRITE3, KEY_WRITE3);
  45. }
  46. #if WRITE_PROTECT_EN
  47. /*
  48. * In order to prevent arbitrary modification of the time register,
  49. * we should disable the write function.
  50. * when disable write,
  51. * the "write" bit needs to be clear in a certain order.
  52. * 1. clear WRITE2 bit
  53. * 2. clear WRITE3 bit
  54. * 3. clear WRITE1 bit
  55. */
  56. static void sd3078_disable_reg_write(struct regmap *regmap)
  57. {
  58. regmap_update_bits(regmap, SD3078_REG_CTRL1, KEY_WRITE2, 0);
  59. regmap_update_bits(regmap, SD3078_REG_CTRL1, KEY_WRITE3, 0);
  60. regmap_update_bits(regmap, SD3078_REG_CTRL2, KEY_WRITE1, 0);
  61. }
  62. #endif
  63. static int sd3078_rtc_read_time(struct device *dev, struct rtc_time *tm)
  64. {
  65. unsigned char hour;
  66. unsigned char rtc_data[NUM_TIME_REGS] = {0};
  67. struct i2c_client *client = to_i2c_client(dev);
  68. struct regmap *regmap = i2c_get_clientdata(client);
  69. int ret;
  70. ret = regmap_bulk_read(regmap, SD3078_REG_SC, rtc_data, NUM_TIME_REGS);
  71. if (ret < 0) {
  72. dev_err(dev, "reading from RTC failed with err:%d\n", ret);
  73. return ret;
  74. }
  75. tm->tm_sec = bcd2bin(rtc_data[SD3078_REG_SC] & 0x7F);
  76. tm->tm_min = bcd2bin(rtc_data[SD3078_REG_MN] & 0x7F);
  77. /*
  78. * The sd3078 supports 12/24 hour mode.
  79. * When getting time,
  80. * we need to convert the 12 hour mode to the 24 hour mode.
  81. */
  82. hour = rtc_data[SD3078_REG_HR];
  83. if (hour & 0x80) /* 24H MODE */
  84. tm->tm_hour = bcd2bin(rtc_data[SD3078_REG_HR] & 0x3F);
  85. else if (hour & 0x20) /* 12H MODE PM */
  86. tm->tm_hour = bcd2bin(rtc_data[SD3078_REG_HR] & 0x1F) + 12;
  87. else /* 12H MODE AM */
  88. tm->tm_hour = bcd2bin(rtc_data[SD3078_REG_HR] & 0x1F);
  89. tm->tm_mday = bcd2bin(rtc_data[SD3078_REG_DM] & 0x3F);
  90. tm->tm_wday = rtc_data[SD3078_REG_DW] & 0x07;
  91. tm->tm_mon = bcd2bin(rtc_data[SD3078_REG_MO] & 0x1F) - 1;
  92. tm->tm_year = bcd2bin(rtc_data[SD3078_REG_YR]) + 100;
  93. return 0;
  94. }
  95. static int sd3078_rtc_set_time(struct device *dev, struct rtc_time *tm)
  96. {
  97. unsigned char rtc_data[NUM_TIME_REGS];
  98. struct i2c_client *client = to_i2c_client(dev);
  99. struct regmap *regmap = i2c_get_clientdata(client);
  100. int ret;
  101. rtc_data[SD3078_REG_SC] = bin2bcd(tm->tm_sec);
  102. rtc_data[SD3078_REG_MN] = bin2bcd(tm->tm_min);
  103. rtc_data[SD3078_REG_HR] = bin2bcd(tm->tm_hour) | 0x80;
  104. rtc_data[SD3078_REG_DM] = bin2bcd(tm->tm_mday);
  105. rtc_data[SD3078_REG_DW] = tm->tm_wday & 0x07;
  106. rtc_data[SD3078_REG_MO] = bin2bcd(tm->tm_mon) + 1;
  107. rtc_data[SD3078_REG_YR] = bin2bcd(tm->tm_year - 100);
  108. #if WRITE_PROTECT_EN
  109. sd3078_enable_reg_write(regmap);
  110. #endif
  111. ret = regmap_bulk_write(regmap, SD3078_REG_SC, rtc_data,
  112. NUM_TIME_REGS);
  113. if (ret < 0) {
  114. dev_err(dev, "writing to RTC failed with err:%d\n", ret);
  115. return ret;
  116. }
  117. #if WRITE_PROTECT_EN
  118. sd3078_disable_reg_write(regmap);
  119. #endif
  120. return 0;
  121. }
  122. static const struct rtc_class_ops sd3078_rtc_ops = {
  123. .read_time = sd3078_rtc_read_time,
  124. .set_time = sd3078_rtc_set_time,
  125. };
  126. static const struct regmap_config regmap_config = {
  127. .reg_bits = 8,
  128. .val_bits = 8,
  129. .max_register = 0x11,
  130. };
  131. static int sd3078_probe(struct i2c_client *client)
  132. {
  133. int ret;
  134. struct regmap *regmap;
  135. struct rtc_device *rtc;
  136. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
  137. return -ENODEV;
  138. regmap = devm_regmap_init_i2c(client, &regmap_config);
  139. if (IS_ERR(regmap)) {
  140. dev_err(&client->dev, "regmap allocation failed\n");
  141. return PTR_ERR(regmap);
  142. }
  143. i2c_set_clientdata(client, regmap);
  144. rtc = devm_rtc_allocate_device(&client->dev);
  145. if (IS_ERR(rtc))
  146. return PTR_ERR(rtc);
  147. rtc->ops = &sd3078_rtc_ops;
  148. rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
  149. rtc->range_max = RTC_TIMESTAMP_END_2099;
  150. ret = devm_rtc_register_device(rtc);
  151. if (ret)
  152. return ret;
  153. sd3078_enable_reg_write(regmap);
  154. return 0;
  155. }
  156. static const struct i2c_device_id sd3078_id[] = {
  157. { "sd3078" },
  158. { }
  159. };
  160. MODULE_DEVICE_TABLE(i2c, sd3078_id);
  161. static const __maybe_unused struct of_device_id rtc_dt_match[] = {
  162. { .compatible = "whwave,sd3078" },
  163. {},
  164. };
  165. MODULE_DEVICE_TABLE(of, rtc_dt_match);
  166. static struct i2c_driver sd3078_driver = {
  167. .driver = {
  168. .name = "sd3078",
  169. .of_match_table = of_match_ptr(rtc_dt_match),
  170. },
  171. .probe = sd3078_probe,
  172. .id_table = sd3078_id,
  173. };
  174. module_i2c_driver(sd3078_driver);
  175. MODULE_AUTHOR("Dianlong Li <long17.cool@163.com>");
  176. MODULE_DESCRIPTION("SD3078 RTC driver");
  177. MODULE_LICENSE("GPL v2");