rtc-moxart.c (8827B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * MOXA ART RTC driver. 4 * 5 * Copyright (C) 2013 Jonas Jensen 6 * 7 * Jonas Jensen <jonas.jensen@gmail.com> 8 * 9 * Based on code from 10 * Moxa Technology Co., Ltd. <www.moxa.com> 11 */ 12 13#include <linux/init.h> 14#include <linux/kernel.h> 15#include <linux/delay.h> 16#include <linux/rtc.h> 17#include <linux/platform_device.h> 18#include <linux/module.h> 19#include <linux/gpio.h> 20#include <linux/of_gpio.h> 21 22#define GPIO_RTC_RESERVED 0x0C 23#define GPIO_RTC_DATA_SET 0x10 24#define GPIO_RTC_DATA_CLEAR 0x14 25#define GPIO_RTC_PIN_PULL_ENABLE 0x18 26#define GPIO_RTC_PIN_PULL_TYPE 0x1C 27#define GPIO_RTC_INT_ENABLE 0x20 28#define GPIO_RTC_INT_RAW_STATE 0x24 29#define GPIO_RTC_INT_MASKED_STATE 0x28 30#define GPIO_RTC_INT_MASK 0x2C 31#define GPIO_RTC_INT_CLEAR 0x30 32#define GPIO_RTC_INT_TRIGGER 0x34 33#define GPIO_RTC_INT_BOTH 0x38 34#define GPIO_RTC_INT_RISE_NEG 0x3C 35#define GPIO_RTC_BOUNCE_ENABLE 0x40 36#define GPIO_RTC_BOUNCE_PRE_SCALE 0x44 37#define GPIO_RTC_PROTECT_W 0x8E 38#define GPIO_RTC_PROTECT_R 0x8F 39#define GPIO_RTC_YEAR_W 0x8C 40#define GPIO_RTC_YEAR_R 0x8D 41#define GPIO_RTC_DAY_W 0x8A 42#define GPIO_RTC_DAY_R 0x8B 43#define GPIO_RTC_MONTH_W 0x88 44#define GPIO_RTC_MONTH_R 0x89 45#define GPIO_RTC_DATE_W 0x86 46#define GPIO_RTC_DATE_R 0x87 47#define GPIO_RTC_HOURS_W 0x84 48#define GPIO_RTC_HOURS_R 0x85 49#define GPIO_RTC_MINUTES_W 0x82 50#define GPIO_RTC_MINUTES_R 0x83 51#define GPIO_RTC_SECONDS_W 0x80 52#define GPIO_RTC_SECONDS_R 0x81 53#define GPIO_RTC_DELAY_TIME 8 54 55struct moxart_rtc { 56 struct rtc_device *rtc; 57 spinlock_t rtc_lock; 58 int gpio_data, gpio_sclk, gpio_reset; 59}; 60 61static int day_of_year[12] = { 0, 31, 59, 90, 120, 151, 181, 62 212, 243, 273, 304, 334 }; 63 64static void moxart_rtc_write_byte(struct device *dev, u8 data) 65{ 66 struct moxart_rtc *moxart_rtc = dev_get_drvdata(dev); 67 int i; 68 69 for (i = 0; i < 8; i++, data >>= 1) { 70 gpio_set_value(moxart_rtc->gpio_sclk, 0); 71 gpio_set_value(moxart_rtc->gpio_data, ((data & 1) == 1)); 72 udelay(GPIO_RTC_DELAY_TIME); 73 gpio_set_value(moxart_rtc->gpio_sclk, 1); 74 udelay(GPIO_RTC_DELAY_TIME); 75 } 76} 77 78static u8 moxart_rtc_read_byte(struct device *dev) 79{ 80 struct moxart_rtc *moxart_rtc = dev_get_drvdata(dev); 81 int i; 82 u8 data = 0; 83 84 for (i = 0; i < 8; i++) { 85 gpio_set_value(moxart_rtc->gpio_sclk, 0); 86 udelay(GPIO_RTC_DELAY_TIME); 87 gpio_set_value(moxart_rtc->gpio_sclk, 1); 88 udelay(GPIO_RTC_DELAY_TIME); 89 if (gpio_get_value(moxart_rtc->gpio_data)) 90 data |= (1 << i); 91 udelay(GPIO_RTC_DELAY_TIME); 92 } 93 return data; 94} 95 96static u8 moxart_rtc_read_register(struct device *dev, u8 cmd) 97{ 98 struct moxart_rtc *moxart_rtc = dev_get_drvdata(dev); 99 u8 data; 100 unsigned long flags; 101 102 local_irq_save(flags); 103 104 gpio_direction_output(moxart_rtc->gpio_data, 0); 105 gpio_set_value(moxart_rtc->gpio_reset, 1); 106 udelay(GPIO_RTC_DELAY_TIME); 107 moxart_rtc_write_byte(dev, cmd); 108 gpio_direction_input(moxart_rtc->gpio_data); 109 udelay(GPIO_RTC_DELAY_TIME); 110 data = moxart_rtc_read_byte(dev); 111 gpio_set_value(moxart_rtc->gpio_sclk, 0); 112 gpio_set_value(moxart_rtc->gpio_reset, 0); 113 udelay(GPIO_RTC_DELAY_TIME); 114 115 local_irq_restore(flags); 116 117 return data; 118} 119 120static void moxart_rtc_write_register(struct device *dev, u8 cmd, u8 data) 121{ 122 struct moxart_rtc *moxart_rtc = dev_get_drvdata(dev); 123 unsigned long flags; 124 125 local_irq_save(flags); 126 127 gpio_direction_output(moxart_rtc->gpio_data, 0); 128 gpio_set_value(moxart_rtc->gpio_reset, 1); 129 udelay(GPIO_RTC_DELAY_TIME); 130 moxart_rtc_write_byte(dev, cmd); 131 moxart_rtc_write_byte(dev, data); 132 gpio_set_value(moxart_rtc->gpio_sclk, 0); 133 gpio_set_value(moxart_rtc->gpio_reset, 0); 134 udelay(GPIO_RTC_DELAY_TIME); 135 136 local_irq_restore(flags); 137} 138 139static int moxart_rtc_set_time(struct device *dev, struct rtc_time *tm) 140{ 141 struct moxart_rtc *moxart_rtc = dev_get_drvdata(dev); 142 143 spin_lock_irq(&moxart_rtc->rtc_lock); 144 145 moxart_rtc_write_register(dev, GPIO_RTC_PROTECT_W, 0); 146 moxart_rtc_write_register(dev, GPIO_RTC_YEAR_W, 147 (((tm->tm_year - 100) / 10) << 4) | 148 ((tm->tm_year - 100) % 10)); 149 150 moxart_rtc_write_register(dev, GPIO_RTC_MONTH_W, 151 (((tm->tm_mon + 1) / 10) << 4) | 152 ((tm->tm_mon + 1) % 10)); 153 154 moxart_rtc_write_register(dev, GPIO_RTC_DATE_W, 155 ((tm->tm_mday / 10) << 4) | 156 (tm->tm_mday % 10)); 157 158 moxart_rtc_write_register(dev, GPIO_RTC_HOURS_W, 159 ((tm->tm_hour / 10) << 4) | 160 (tm->tm_hour % 10)); 161 162 moxart_rtc_write_register(dev, GPIO_RTC_MINUTES_W, 163 ((tm->tm_min / 10) << 4) | 164 (tm->tm_min % 10)); 165 166 moxart_rtc_write_register(dev, GPIO_RTC_SECONDS_W, 167 ((tm->tm_sec / 10) << 4) | 168 (tm->tm_sec % 10)); 169 170 moxart_rtc_write_register(dev, GPIO_RTC_PROTECT_W, 0x80); 171 172 spin_unlock_irq(&moxart_rtc->rtc_lock); 173 174 dev_dbg(dev, "%s: success tm_year=%d tm_mon=%d\n" 175 "tm_mday=%d tm_hour=%d tm_min=%d tm_sec=%d\n", 176 __func__, tm->tm_year, tm->tm_mon, tm->tm_mday, 177 tm->tm_hour, tm->tm_min, tm->tm_sec); 178 179 return 0; 180} 181 182static int moxart_rtc_read_time(struct device *dev, struct rtc_time *tm) 183{ 184 struct moxart_rtc *moxart_rtc = dev_get_drvdata(dev); 185 unsigned char v; 186 187 spin_lock_irq(&moxart_rtc->rtc_lock); 188 189 v = moxart_rtc_read_register(dev, GPIO_RTC_SECONDS_R); 190 tm->tm_sec = (((v & 0x70) >> 4) * 10) + (v & 0x0F); 191 192 v = moxart_rtc_read_register(dev, GPIO_RTC_MINUTES_R); 193 tm->tm_min = (((v & 0x70) >> 4) * 10) + (v & 0x0F); 194 195 v = moxart_rtc_read_register(dev, GPIO_RTC_HOURS_R); 196 if (v & 0x80) { /* 12-hour mode */ 197 tm->tm_hour = (((v & 0x10) >> 4) * 10) + (v & 0x0F); 198 if (v & 0x20) { /* PM mode */ 199 tm->tm_hour += 12; 200 if (tm->tm_hour >= 24) 201 tm->tm_hour = 0; 202 } 203 } else { /* 24-hour mode */ 204 tm->tm_hour = (((v & 0x30) >> 4) * 10) + (v & 0x0F); 205 } 206 207 v = moxart_rtc_read_register(dev, GPIO_RTC_DATE_R); 208 tm->tm_mday = (((v & 0x30) >> 4) * 10) + (v & 0x0F); 209 210 v = moxart_rtc_read_register(dev, GPIO_RTC_MONTH_R); 211 tm->tm_mon = (((v & 0x10) >> 4) * 10) + (v & 0x0F); 212 tm->tm_mon--; 213 214 v = moxart_rtc_read_register(dev, GPIO_RTC_YEAR_R); 215 tm->tm_year = (((v & 0xF0) >> 4) * 10) + (v & 0x0F); 216 tm->tm_year += 100; 217 if (tm->tm_year <= 69) 218 tm->tm_year += 100; 219 220 v = moxart_rtc_read_register(dev, GPIO_RTC_DAY_R); 221 tm->tm_wday = (v & 0x0f) - 1; 222 tm->tm_yday = day_of_year[tm->tm_mon]; 223 tm->tm_yday += (tm->tm_mday - 1); 224 if (tm->tm_mon >= 2) { 225 if (!(tm->tm_year % 4) && (tm->tm_year % 100)) 226 tm->tm_yday++; 227 } 228 229 tm->tm_isdst = 0; 230 231 spin_unlock_irq(&moxart_rtc->rtc_lock); 232 233 return 0; 234} 235 236static const struct rtc_class_ops moxart_rtc_ops = { 237 .read_time = moxart_rtc_read_time, 238 .set_time = moxart_rtc_set_time, 239}; 240 241static int moxart_rtc_probe(struct platform_device *pdev) 242{ 243 struct moxart_rtc *moxart_rtc; 244 int ret = 0; 245 246 moxart_rtc = devm_kzalloc(&pdev->dev, sizeof(*moxart_rtc), GFP_KERNEL); 247 if (!moxart_rtc) 248 return -ENOMEM; 249 250 moxart_rtc->gpio_data = of_get_named_gpio(pdev->dev.of_node, 251 "gpio-rtc-data", 0); 252 if (!gpio_is_valid(moxart_rtc->gpio_data)) { 253 dev_err(&pdev->dev, "invalid gpio (data): %d\n", 254 moxart_rtc->gpio_data); 255 return moxart_rtc->gpio_data; 256 } 257 258 moxart_rtc->gpio_sclk = of_get_named_gpio(pdev->dev.of_node, 259 "gpio-rtc-sclk", 0); 260 if (!gpio_is_valid(moxart_rtc->gpio_sclk)) { 261 dev_err(&pdev->dev, "invalid gpio (sclk): %d\n", 262 moxart_rtc->gpio_sclk); 263 return moxart_rtc->gpio_sclk; 264 } 265 266 moxart_rtc->gpio_reset = of_get_named_gpio(pdev->dev.of_node, 267 "gpio-rtc-reset", 0); 268 if (!gpio_is_valid(moxart_rtc->gpio_reset)) { 269 dev_err(&pdev->dev, "invalid gpio (reset): %d\n", 270 moxart_rtc->gpio_reset); 271 return moxart_rtc->gpio_reset; 272 } 273 274 spin_lock_init(&moxart_rtc->rtc_lock); 275 platform_set_drvdata(pdev, moxart_rtc); 276 277 ret = devm_gpio_request(&pdev->dev, moxart_rtc->gpio_data, "rtc_data"); 278 if (ret) { 279 dev_err(&pdev->dev, "can't get rtc_data gpio\n"); 280 return ret; 281 } 282 283 ret = devm_gpio_request_one(&pdev->dev, moxart_rtc->gpio_sclk, 284 GPIOF_DIR_OUT, "rtc_sclk"); 285 if (ret) { 286 dev_err(&pdev->dev, "can't get rtc_sclk gpio\n"); 287 return ret; 288 } 289 290 ret = devm_gpio_request_one(&pdev->dev, moxart_rtc->gpio_reset, 291 GPIOF_DIR_OUT, "rtc_reset"); 292 if (ret) { 293 dev_err(&pdev->dev, "can't get rtc_reset gpio\n"); 294 return ret; 295 } 296 297 moxart_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, 298 &moxart_rtc_ops, 299 THIS_MODULE); 300 if (IS_ERR(moxart_rtc->rtc)) { 301 dev_err(&pdev->dev, "devm_rtc_device_register failed\n"); 302 return PTR_ERR(moxart_rtc->rtc); 303 } 304 305 return 0; 306} 307 308static const struct of_device_id moxart_rtc_match[] = { 309 { .compatible = "moxa,moxart-rtc" }, 310 { }, 311}; 312MODULE_DEVICE_TABLE(of, moxart_rtc_match); 313 314static struct platform_driver moxart_rtc_driver = { 315 .probe = moxart_rtc_probe, 316 .driver = { 317 .name = "moxart-rtc", 318 .of_match_table = moxart_rtc_match, 319 }, 320}; 321module_platform_driver(moxart_rtc_driver); 322 323MODULE_DESCRIPTION("MOXART RTC driver"); 324MODULE_LICENSE("GPL"); 325MODULE_AUTHOR("Jonas Jensen <jonas.jensen@gmail.com>");