1// SPDX-License-Identifier: GPL-2.0 2/* 3 * TX4939 internal RTC driver 4 * Based on RBTX49xx patch from CELF patch archive. 5 * 6 * (C) Copyright TOSHIBA CORPORATION 2005-2007 7 */ 8#include <linux/rtc.h> 9#include <linux/platform_device.h> 10#include <linux/interrupt.h> 11#include <linux/module.h> 12#include <linux/io.h> 13#include <linux/gfp.h> 14 15#define TX4939_RTCCTL_ALME 0x00000080 16#define TX4939_RTCCTL_ALMD 0x00000040 17#define TX4939_RTCCTL_BUSY 0x00000020 18 19#define TX4939_RTCCTL_COMMAND 0x00000007 20#define TX4939_RTCCTL_COMMAND_NOP 0x00000000 21#define TX4939_RTCCTL_COMMAND_GETTIME 0x00000001 22#define TX4939_RTCCTL_COMMAND_SETTIME 0x00000002 23#define TX4939_RTCCTL_COMMAND_GETALARM 0x00000003 24#define TX4939_RTCCTL_COMMAND_SETALARM 0x00000004 25 26#define TX4939_RTCTBC_PM 0x00000080 27#define TX4939_RTCTBC_COMP 0x0000007f 28 29#define TX4939_RTC_REG_RAMSIZE 0x00000100 30#define TX4939_RTC_REG_RWBSIZE 0x00000006 31 32struct tx4939_rtc_reg { 33 __u32 ctl; 34 __u32 adr; 35 __u32 dat; 36 __u32 tbc; 37}; 38 39struct tx4939rtc_plat_data { 40 struct rtc_device *rtc; 41 struct tx4939_rtc_reg __iomem *rtcreg; 42 spinlock_t lock; 43}; 44 45static int tx4939_rtc_cmd(struct tx4939_rtc_reg __iomem *rtcreg, int cmd) 46{ 47 int i = 0; 48 49 __raw_writel(cmd, &rtcreg->ctl); 50 /* This might take 30us (next 32.768KHz clock) */ 51 while (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_BUSY) { 52 /* timeout on approx. 100us (@ GBUS200MHz) */ 53 if (i++ > 200 * 100) 54 return -EBUSY; 55 cpu_relax(); 56 } 57 return 0; 58} 59 60static int tx4939_rtc_set_time(struct device *dev, struct rtc_time *tm) 61{ 62 struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev); 63 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 64 unsigned long secs = rtc_tm_to_time64(tm); 65 int i, ret; 66 unsigned char buf[6]; 67 68 buf[0] = 0; 69 buf[1] = 0; 70 buf[2] = secs; 71 buf[3] = secs >> 8; 72 buf[4] = secs >> 16; 73 buf[5] = secs >> 24; 74 spin_lock_irq(&pdata->lock); 75 __raw_writel(0, &rtcreg->adr); 76 for (i = 0; i < 6; i++) 77 __raw_writel(buf[i], &rtcreg->dat); 78 ret = tx4939_rtc_cmd(rtcreg, 79 TX4939_RTCCTL_COMMAND_SETTIME | 80 (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); 81 spin_unlock_irq(&pdata->lock); 82 return ret; 83} 84 85static int tx4939_rtc_read_time(struct device *dev, struct rtc_time *tm) 86{ 87 struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev); 88 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 89 int i, ret; 90 unsigned long sec; 91 unsigned char buf[6]; 92 93 spin_lock_irq(&pdata->lock); 94 ret = tx4939_rtc_cmd(rtcreg, 95 TX4939_RTCCTL_COMMAND_GETTIME | 96 (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); 97 if (ret) { 98 spin_unlock_irq(&pdata->lock); 99 return ret; 100 } 101 __raw_writel(2, &rtcreg->adr); 102 for (i = 2; i < 6; i++) 103 buf[i] = __raw_readl(&rtcreg->dat); 104 spin_unlock_irq(&pdata->lock); 105 sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) | 106 (buf[3] << 8) | buf[2]; 107 rtc_time64_to_tm(sec, tm); 108 return 0; 109} 110 111static int tx4939_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 112{ 113 struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev); 114 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 115 int i, ret; 116 unsigned long sec; 117 unsigned char buf[6]; 118 119 sec = rtc_tm_to_time64(&alrm->time); 120 buf[0] = 0; 121 buf[1] = 0; 122 buf[2] = sec; 123 buf[3] = sec >> 8; 124 buf[4] = sec >> 16; 125 buf[5] = sec >> 24; 126 spin_lock_irq(&pdata->lock); 127 __raw_writel(0, &rtcreg->adr); 128 for (i = 0; i < 6; i++) 129 __raw_writel(buf[i], &rtcreg->dat); 130 ret = tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_SETALARM | 131 (alrm->enabled ? TX4939_RTCCTL_ALME : 0)); 132 spin_unlock_irq(&pdata->lock); 133 return ret; 134} 135 136static int tx4939_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 137{ 138 struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev); 139 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 140 int i, ret; 141 unsigned long sec; 142 unsigned char buf[6]; 143 u32 ctl; 144 145 spin_lock_irq(&pdata->lock); 146 ret = tx4939_rtc_cmd(rtcreg, 147 TX4939_RTCCTL_COMMAND_GETALARM | 148 (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); 149 if (ret) { 150 spin_unlock_irq(&pdata->lock); 151 return ret; 152 } 153 __raw_writel(2, &rtcreg->adr); 154 for (i = 2; i < 6; i++) 155 buf[i] = __raw_readl(&rtcreg->dat); 156 ctl = __raw_readl(&rtcreg->ctl); 157 alrm->enabled = (ctl & TX4939_RTCCTL_ALME) ? 1 : 0; 158 alrm->pending = (ctl & TX4939_RTCCTL_ALMD) ? 1 : 0; 159 spin_unlock_irq(&pdata->lock); 160 sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) | 161 (buf[3] << 8) | buf[2]; 162 rtc_time64_to_tm(sec, &alrm->time); 163 return rtc_valid_tm(&alrm->time); 164} 165 166static int tx4939_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 167{ 168 struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev); 169 170 spin_lock_irq(&pdata->lock); 171 tx4939_rtc_cmd(pdata->rtcreg, 172 TX4939_RTCCTL_COMMAND_NOP | 173 (enabled ? TX4939_RTCCTL_ALME : 0)); 174 spin_unlock_irq(&pdata->lock); 175 return 0; 176} 177 178static irqreturn_t tx4939_rtc_interrupt(int irq, void *dev_id) 179{ 180 struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev_id); 181 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 182 unsigned long events = RTC_IRQF; 183 184 spin_lock(&pdata->lock); 185 if (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALMD) { 186 events |= RTC_AF; 187 tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_NOP); 188 } 189 spin_unlock(&pdata->lock); 190 rtc_update_irq(pdata->rtc, 1, events); 191 192 return IRQ_HANDLED; 193} 194 195static const struct rtc_class_ops tx4939_rtc_ops = { 196 .read_time = tx4939_rtc_read_time, 197 .read_alarm = tx4939_rtc_read_alarm, 198 .set_alarm = tx4939_rtc_set_alarm, 199 .set_time = tx4939_rtc_set_time, 200 .alarm_irq_enable = tx4939_rtc_alarm_irq_enable, 201}; 202 203static int tx4939_nvram_read(void *priv, unsigned int pos, void *val, 204 size_t bytes) 205{ 206 struct tx4939rtc_plat_data *pdata = priv; 207 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 208 u8 *buf = val; 209 210 spin_lock_irq(&pdata->lock); 211 for (; bytes; bytes--) { 212 __raw_writel(pos++, &rtcreg->adr); 213 *buf++ = __raw_readl(&rtcreg->dat); 214 } 215 spin_unlock_irq(&pdata->lock); 216 return 0; 217} 218 219static int tx4939_nvram_write(void *priv, unsigned int pos, void *val, 220 size_t bytes) 221{ 222 struct tx4939rtc_plat_data *pdata = priv; 223 struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; 224 u8 *buf = val; 225 226 spin_lock_irq(&pdata->lock); 227 for (; bytes; bytes--) { 228 __raw_writel(pos++, &rtcreg->adr); 229 __raw_writel(*buf++, &rtcreg->dat); 230 } 231 spin_unlock_irq(&pdata->lock); 232 return 0; 233} 234 235static int __init tx4939_rtc_probe(struct platform_device *pdev) 236{ 237 struct rtc_device *rtc; 238 struct tx4939rtc_plat_data *pdata; 239 int irq, ret; 240 struct nvmem_config nvmem_cfg = { 241 .name = "tx4939_nvram", 242 .size = TX4939_RTC_REG_RAMSIZE, 243 .reg_read = tx4939_nvram_read, 244 .reg_write = tx4939_nvram_write, 245 }; 246 247 irq = platform_get_irq(pdev, 0); 248 if (irq < 0) 249 return -ENODEV; 250 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 251 if (!pdata) 252 return -ENOMEM; 253 platform_set_drvdata(pdev, pdata); 254 255 pdata->rtcreg = devm_platform_ioremap_resource(pdev, 0); 256 if (IS_ERR(pdata->rtcreg)) 257 return PTR_ERR(pdata->rtcreg); 258 259 spin_lock_init(&pdata->lock); 260 tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); 261 if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt, 262 0, pdev->name, &pdev->dev) < 0) 263 return -EBUSY; 264 rtc = devm_rtc_allocate_device(&pdev->dev); 265 if (IS_ERR(rtc)) 266 return PTR_ERR(rtc); 267 268 rtc->ops = &tx4939_rtc_ops; 269 rtc->nvram_old_abi = true; 270 rtc->range_max = U32_MAX; 271 272 pdata->rtc = rtc; 273 274 nvmem_cfg.priv = pdata; 275 ret = rtc_nvmem_register(rtc, &nvmem_cfg); 276 if (ret) 277 return ret; 278 279 return rtc_register_device(rtc); 280} 281 282static int __exit tx4939_rtc_remove(struct platform_device *pdev) 283{ 284 struct tx4939rtc_plat_data *pdata = platform_get_drvdata(pdev); 285 286 spin_lock_irq(&pdata->lock); 287 tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); 288 spin_unlock_irq(&pdata->lock); 289 return 0; 290} 291 292static struct platform_driver tx4939_rtc_driver = { 293 .remove = __exit_p(tx4939_rtc_remove), 294 .driver = { 295 .name = "tx4939rtc", 296 }, 297}; 298 299module_platform_driver_probe(tx4939_rtc_driver, tx4939_rtc_probe); 300 301MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); 302MODULE_DESCRIPTION("TX4939 internal RTC driver"); 303MODULE_LICENSE("GPL v2"); 304MODULE_ALIAS("platform:tx4939rtc"); 305