Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

RTC: RK808: add RTC driver for RK808

This is the initial version of the RK808 PMIC. This is a power management
IC for multimedia products. It provides regulators that are able to
supply power to processor cores and other components. The chip provides
other modules including RTC, Clockout.

Add RTC driver for supporting RTC device present inside RK808 PMIC.

[akpm@linux-foundation.org: make tm_def static]
Signed-off-by: Chris Zhong <zyw@rock-chips.com>
Signed-off-by: Zhang Qing <zhangqing@rock-chips.com>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Doug Anderson <dianders@chromium.org>
Tested-by: Doug Anderson <dianders@chromium.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Ian Campbell <ijc+devicetree@hellion.org.uk>
Cc: Samuel Ortiz <sameo@linux.intel.com> says:
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Olof Johansson <olof@lixom.net>
Cc: Dmitry Torokhov <dtor@chromium.org>
Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Cc: Kever Yang <kever.yang@rock-chips.com>
Cc: Li Zhong <zhong@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Chris Zhong and committed by
Linus Torvalds
3ca1e326 a28885bc

+425
+10
drivers/rtc/Kconfig
··· 288 288 This driver can also be built as a module. If so, the module 289 289 will be called rtc-max77686. 290 290 291 + config RTC_DRV_RK808 292 + tristate "Rockchip RK808 RTC" 293 + depends on MFD_RK808 294 + help 295 + If you say yes here you will get support for the 296 + RTC of RK808 PMIC. 297 + 298 + This driver can also be built as a module. If so, the module 299 + will be called rk808-rtc. 300 + 291 301 config RTC_DRV_RS5C372 292 302 tristate "Ricoh R2025S/D, RS5C372A/B, RV5C386, RV5C387A" 293 303 help
+1
drivers/rtc/Makefile
··· 109 109 obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o 110 110 obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o 111 111 obj-$(CONFIG_RTC_DRV_RC5T583) += rtc-rc5t583.o 112 + obj-$(CONFIG_RTC_DRV_RK808) += rtc-rk808.o 112 113 obj-$(CONFIG_RTC_DRV_RP5C01) += rtc-rp5c01.o 113 114 obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o 114 115 obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
+414
drivers/rtc/rtc-rk808.c
··· 1 + /* 2 + * RTC driver for Rockchip RK808 3 + * 4 + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd 5 + * 6 + * Author: Chris Zhong <zyw@rock-chips.com> 7 + * Author: Zhang Qing <zhangqing@rock-chips.com> 8 + * 9 + * This program is free software; you can redistribute it and/or modify it 10 + * under the terms and conditions of the GNU General Public License, 11 + * version 2, as published by the Free Software Foundation. 12 + * 13 + * This program is distributed in the hope it will be useful, but WITHOUT 14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 16 + * more details. 17 + */ 18 + 19 + #include <linux/module.h> 20 + #include <linux/kernel.h> 21 + #include <linux/rtc.h> 22 + #include <linux/bcd.h> 23 + #include <linux/mfd/rk808.h> 24 + #include <linux/platform_device.h> 25 + #include <linux/i2c.h> 26 + 27 + /* RTC_CTRL_REG bitfields */ 28 + #define BIT_RTC_CTRL_REG_STOP_RTC_M BIT(0) 29 + 30 + /* RK808 has a shadowed register for saving a "frozen" RTC time. 31 + * When user setting "GET_TIME" to 1, the time will save in this shadowed 32 + * register. If set "READSEL" to 1, user read rtc time register, actually 33 + * get the time of that moment. If we need the real time, clr this bit. 34 + */ 35 + #define BIT_RTC_CTRL_REG_RTC_GET_TIME BIT(6) 36 + #define BIT_RTC_CTRL_REG_RTC_READSEL_M BIT(7) 37 + #define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M BIT(3) 38 + #define RTC_STATUS_MASK 0xFE 39 + 40 + #define SECONDS_REG_MSK 0x7F 41 + #define MINUTES_REG_MAK 0x7F 42 + #define HOURS_REG_MSK 0x3F 43 + #define DAYS_REG_MSK 0x3F 44 + #define MONTHS_REG_MSK 0x1F 45 + #define YEARS_REG_MSK 0xFF 46 + #define WEEKS_REG_MSK 0x7 47 + 48 + /* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */ 49 + 50 + #define NUM_TIME_REGS (RK808_WEEKS_REG - RK808_SECONDS_REG + 1) 51 + #define NUM_ALARM_REGS (RK808_ALARM_YEARS_REG - RK808_ALARM_SECONDS_REG + 1) 52 + 53 + struct rk808_rtc { 54 + struct rk808 *rk808; 55 + struct rtc_device *rtc; 56 + int irq; 57 + }; 58 + 59 + /* Read current time and date in RTC */ 60 + static int rk808_rtc_readtime(struct device *dev, struct rtc_time *tm) 61 + { 62 + struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); 63 + struct rk808 *rk808 = rk808_rtc->rk808; 64 + u8 rtc_data[NUM_TIME_REGS]; 65 + int ret; 66 + 67 + /* Force an update of the shadowed registers right now */ 68 + ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, 69 + BIT_RTC_CTRL_REG_RTC_GET_TIME, 70 + 0); 71 + if (ret) { 72 + dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret); 73 + return ret; 74 + } 75 + 76 + ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, 77 + BIT_RTC_CTRL_REG_RTC_GET_TIME, 78 + BIT_RTC_CTRL_REG_RTC_GET_TIME); 79 + if (ret) { 80 + dev_err(dev, "Failed to update bits rtc_ctrl: %d\n", ret); 81 + return ret; 82 + } 83 + 84 + ret = regmap_bulk_read(rk808->regmap, RK808_SECONDS_REG, 85 + rtc_data, NUM_TIME_REGS); 86 + if (ret) { 87 + dev_err(dev, "Failed to bulk read rtc_data: %d\n", ret); 88 + return ret; 89 + } 90 + 91 + tm->tm_sec = bcd2bin(rtc_data[0] & SECONDS_REG_MSK); 92 + tm->tm_min = bcd2bin(rtc_data[1] & MINUTES_REG_MAK); 93 + tm->tm_hour = bcd2bin(rtc_data[2] & HOURS_REG_MSK); 94 + tm->tm_mday = bcd2bin(rtc_data[3] & DAYS_REG_MSK); 95 + tm->tm_mon = (bcd2bin(rtc_data[4] & MONTHS_REG_MSK)) - 1; 96 + tm->tm_year = (bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 100; 97 + tm->tm_wday = bcd2bin(rtc_data[6] & WEEKS_REG_MSK); 98 + dev_dbg(dev, "RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", 99 + 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, 100 + tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec); 101 + 102 + return ret; 103 + } 104 + 105 + /* Set current time and date in RTC */ 106 + static int rk808_rtc_set_time(struct device *dev, struct rtc_time *tm) 107 + { 108 + struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); 109 + struct rk808 *rk808 = rk808_rtc->rk808; 110 + u8 rtc_data[NUM_TIME_REGS]; 111 + int ret; 112 + 113 + rtc_data[0] = bin2bcd(tm->tm_sec); 114 + rtc_data[1] = bin2bcd(tm->tm_min); 115 + rtc_data[2] = bin2bcd(tm->tm_hour); 116 + rtc_data[3] = bin2bcd(tm->tm_mday); 117 + rtc_data[4] = bin2bcd(tm->tm_mon + 1); 118 + rtc_data[5] = bin2bcd(tm->tm_year - 100); 119 + rtc_data[6] = bin2bcd(tm->tm_wday); 120 + dev_dbg(dev, "set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", 121 + 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, 122 + tm->tm_wday, tm->tm_hour , tm->tm_min, tm->tm_sec); 123 + 124 + /* Stop RTC while updating the RTC registers */ 125 + ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, 126 + BIT_RTC_CTRL_REG_STOP_RTC_M, 127 + BIT_RTC_CTRL_REG_STOP_RTC_M); 128 + if (ret) { 129 + dev_err(dev, "Failed to update RTC control: %d\n", ret); 130 + return ret; 131 + } 132 + 133 + ret = regmap_bulk_write(rk808->regmap, RK808_SECONDS_REG, 134 + rtc_data, NUM_TIME_REGS); 135 + if (ret) { 136 + dev_err(dev, "Failed to bull write rtc_data: %d\n", ret); 137 + return ret; 138 + } 139 + /* Start RTC again */ 140 + ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, 141 + BIT_RTC_CTRL_REG_STOP_RTC_M, 0); 142 + if (ret) { 143 + dev_err(dev, "Failed to update RTC control: %d\n", ret); 144 + return ret; 145 + } 146 + return 0; 147 + } 148 + 149 + /* Read alarm time and date in RTC */ 150 + static int rk808_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) 151 + { 152 + struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); 153 + struct rk808 *rk808 = rk808_rtc->rk808; 154 + u8 alrm_data[NUM_ALARM_REGS]; 155 + uint32_t int_reg; 156 + int ret; 157 + 158 + ret = regmap_bulk_read(rk808->regmap, RK808_ALARM_SECONDS_REG, 159 + alrm_data, NUM_ALARM_REGS); 160 + 161 + alrm->time.tm_sec = bcd2bin(alrm_data[0] & SECONDS_REG_MSK); 162 + alrm->time.tm_min = bcd2bin(alrm_data[1] & MINUTES_REG_MAK); 163 + alrm->time.tm_hour = bcd2bin(alrm_data[2] & HOURS_REG_MSK); 164 + alrm->time.tm_mday = bcd2bin(alrm_data[3] & DAYS_REG_MSK); 165 + alrm->time.tm_mon = (bcd2bin(alrm_data[4] & MONTHS_REG_MSK)) - 1; 166 + alrm->time.tm_year = (bcd2bin(alrm_data[5] & YEARS_REG_MSK)) + 100; 167 + 168 + ret = regmap_read(rk808->regmap, RK808_RTC_INT_REG, &int_reg); 169 + if (ret) { 170 + dev_err(dev, "Failed to read RTC INT REG: %d\n", ret); 171 + return ret; 172 + } 173 + 174 + dev_dbg(dev, "alrm read RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", 175 + 1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, 176 + alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, 177 + alrm->time.tm_min, alrm->time.tm_sec); 178 + 179 + alrm->enabled = (int_reg & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M) ? 1 : 0; 180 + 181 + return 0; 182 + } 183 + 184 + static int rk808_rtc_stop_alarm(struct rk808_rtc *rk808_rtc) 185 + { 186 + struct rk808 *rk808 = rk808_rtc->rk808; 187 + int ret; 188 + 189 + ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG, 190 + BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0); 191 + 192 + return ret; 193 + } 194 + 195 + static int rk808_rtc_start_alarm(struct rk808_rtc *rk808_rtc) 196 + { 197 + struct rk808 *rk808 = rk808_rtc->rk808; 198 + int ret; 199 + 200 + ret = regmap_update_bits(rk808->regmap, RK808_RTC_INT_REG, 201 + BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 202 + BIT_RTC_INTERRUPTS_REG_IT_ALARM_M); 203 + 204 + return ret; 205 + } 206 + 207 + static int rk808_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) 208 + { 209 + struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); 210 + struct rk808 *rk808 = rk808_rtc->rk808; 211 + u8 alrm_data[NUM_ALARM_REGS]; 212 + int ret; 213 + 214 + ret = rk808_rtc_stop_alarm(rk808_rtc); 215 + if (ret) { 216 + dev_err(dev, "Failed to stop alarm: %d\n", ret); 217 + return ret; 218 + } 219 + dev_dbg(dev, "alrm set RTC date/time %4d-%02d-%02d(%d) %02d:%02d:%02d\n", 220 + 1900 + alrm->time.tm_year, alrm->time.tm_mon + 1, 221 + alrm->time.tm_mday, alrm->time.tm_wday, alrm->time.tm_hour, 222 + alrm->time.tm_min, alrm->time.tm_sec); 223 + 224 + alrm_data[0] = bin2bcd(alrm->time.tm_sec); 225 + alrm_data[1] = bin2bcd(alrm->time.tm_min); 226 + alrm_data[2] = bin2bcd(alrm->time.tm_hour); 227 + alrm_data[3] = bin2bcd(alrm->time.tm_mday); 228 + alrm_data[4] = bin2bcd(alrm->time.tm_mon + 1); 229 + alrm_data[5] = bin2bcd(alrm->time.tm_year - 100); 230 + 231 + ret = regmap_bulk_write(rk808->regmap, RK808_ALARM_SECONDS_REG, 232 + alrm_data, NUM_ALARM_REGS); 233 + if (ret) { 234 + dev_err(dev, "Failed to bulk write: %d\n", ret); 235 + return ret; 236 + } 237 + if (alrm->enabled) { 238 + ret = rk808_rtc_start_alarm(rk808_rtc); 239 + if (ret) { 240 + dev_err(dev, "Failed to start alarm: %d\n", ret); 241 + return ret; 242 + } 243 + } 244 + return 0; 245 + } 246 + 247 + static int rk808_rtc_alarm_irq_enable(struct device *dev, 248 + unsigned int enabled) 249 + { 250 + struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); 251 + 252 + if (enabled) 253 + return rk808_rtc_start_alarm(rk808_rtc); 254 + 255 + return rk808_rtc_stop_alarm(rk808_rtc); 256 + } 257 + 258 + /* 259 + * We will just handle setting the frequency and make use the framework for 260 + * reading the periodic interupts. 261 + * 262 + * @freq: Current periodic IRQ freq: 263 + * bit 0: every second 264 + * bit 1: every minute 265 + * bit 2: every hour 266 + * bit 3: every day 267 + */ 268 + static irqreturn_t rk808_alarm_irq(int irq, void *data) 269 + { 270 + struct rk808_rtc *rk808_rtc = data; 271 + struct rk808 *rk808 = rk808_rtc->rk808; 272 + struct i2c_client *client = rk808->i2c; 273 + int ret; 274 + 275 + ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG, 276 + RTC_STATUS_MASK); 277 + if (ret) { 278 + dev_err(&client->dev, 279 + "%s:Failed to update RTC status: %d\n", __func__, ret); 280 + return ret; 281 + } 282 + 283 + rtc_update_irq(rk808_rtc->rtc, 1, RTC_IRQF | RTC_AF); 284 + dev_dbg(&client->dev, 285 + "%s:irq=%d\n", __func__, irq); 286 + return IRQ_HANDLED; 287 + } 288 + 289 + static const struct rtc_class_ops rk808_rtc_ops = { 290 + .read_time = rk808_rtc_readtime, 291 + .set_time = rk808_rtc_set_time, 292 + .read_alarm = rk808_rtc_readalarm, 293 + .set_alarm = rk808_rtc_setalarm, 294 + .alarm_irq_enable = rk808_rtc_alarm_irq_enable, 295 + }; 296 + 297 + #ifdef CONFIG_PM_SLEEP 298 + /* Turn off the alarm if it should not be a wake source. */ 299 + static int rk808_rtc_suspend(struct device *dev) 300 + { 301 + struct platform_device *pdev = to_platform_device(dev); 302 + struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev); 303 + 304 + if (device_may_wakeup(dev)) 305 + enable_irq_wake(rk808_rtc->irq); 306 + 307 + return 0; 308 + } 309 + 310 + /* Enable the alarm if it should be enabled (in case it was disabled to 311 + * prevent use as a wake source). 312 + */ 313 + static int rk808_rtc_resume(struct device *dev) 314 + { 315 + struct platform_device *pdev = to_platform_device(dev); 316 + struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev); 317 + 318 + if (device_may_wakeup(dev)) 319 + disable_irq_wake(rk808_rtc->irq); 320 + 321 + return 0; 322 + } 323 + #endif 324 + 325 + static SIMPLE_DEV_PM_OPS(rk808_rtc_pm_ops, 326 + rk808_rtc_suspend, rk808_rtc_resume); 327 + 328 + static int rk808_rtc_probe(struct platform_device *pdev) 329 + { 330 + struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); 331 + struct rk808_rtc *rk808_rtc; 332 + struct rtc_time tm; 333 + int ret; 334 + 335 + rk808_rtc = devm_kzalloc(&pdev->dev, sizeof(*rk808_rtc), GFP_KERNEL); 336 + if (rk808_rtc == NULL) 337 + return -ENOMEM; 338 + 339 + platform_set_drvdata(pdev, rk808_rtc); 340 + rk808_rtc->rk808 = rk808; 341 + 342 + /* start rtc running by default, and use shadowed timer. */ 343 + ret = regmap_update_bits(rk808->regmap, RK808_RTC_CTRL_REG, 344 + BIT_RTC_CTRL_REG_STOP_RTC_M | 345 + BIT_RTC_CTRL_REG_RTC_READSEL_M, 346 + BIT_RTC_CTRL_REG_RTC_READSEL_M); 347 + if (ret) { 348 + dev_err(&pdev->dev, 349 + "Failed to update RTC control: %d\n", ret); 350 + return ret; 351 + } 352 + 353 + ret = regmap_write(rk808->regmap, RK808_RTC_STATUS_REG, 354 + RTC_STATUS_MASK); 355 + if (ret) { 356 + dev_err(&pdev->dev, 357 + "Failed to write RTC status: %d\n", ret); 358 + return ret; 359 + } 360 + 361 + /* set init time */ 362 + ret = rk808_rtc_readtime(&pdev->dev, &tm); 363 + if (ret) { 364 + dev_err(&pdev->dev, "Failed to read RTC time\n"); 365 + return ret; 366 + } 367 + ret = rtc_valid_tm(&tm); 368 + if (ret) 369 + dev_warn(&pdev->dev, "invalid date/time\n"); 370 + 371 + device_init_wakeup(&pdev->dev, 1); 372 + 373 + rk808_rtc->rtc = devm_rtc_device_register(&pdev->dev, "rk808-rtc", 374 + &rk808_rtc_ops, THIS_MODULE); 375 + if (IS_ERR(rk808_rtc->rtc)) { 376 + ret = PTR_ERR(rk808_rtc->rtc); 377 + return ret; 378 + } 379 + 380 + rk808_rtc->irq = platform_get_irq(pdev, 0); 381 + if (rk808_rtc->irq < 0) { 382 + if (rk808_rtc->irq != -EPROBE_DEFER) 383 + dev_err(&pdev->dev, "Wake up is not possible as irq = %d\n", 384 + rk808_rtc->irq); 385 + return rk808_rtc->irq; 386 + } 387 + 388 + /* request alarm irq of rk808 */ 389 + ret = devm_request_threaded_irq(&pdev->dev, rk808_rtc->irq, NULL, 390 + rk808_alarm_irq, 0, 391 + "RTC alarm", rk808_rtc); 392 + if (ret) { 393 + dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", 394 + rk808_rtc->irq, ret); 395 + } 396 + 397 + return ret; 398 + } 399 + 400 + static struct platform_driver rk808_rtc_driver = { 401 + .probe = rk808_rtc_probe, 402 + .driver = { 403 + .name = "rk808-rtc", 404 + .pm = &rk808_rtc_pm_ops, 405 + }, 406 + }; 407 + 408 + module_platform_driver(rk808_rtc_driver); 409 + 410 + MODULE_DESCRIPTION("RTC driver for the rk808 series PMICs"); 411 + MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); 412 + MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); 413 + MODULE_LICENSE("GPL"); 414 + MODULE_ALIAS("platform:rk808-rtc");