blob: cb2edaef75d1f521526c9811d8ae7d3bf3594343 [file] [log] [blame]
Duy Truong790f06d2013-02-13 16:38:12 -08001/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/rtc.h>
16#include <linux/pm.h>
17#include <linux/slab.h>
Stephen Boyd265a3412013-01-17 18:48:20 -080018#include <linux/spinlock.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070019
20#include <linux/mfd/pm8xxx/core.h>
21#include <linux/mfd/pm8xxx/rtc.h>
22
23
24/* RTC Register offsets from RTC CTRL REG */
Stephen Boyd265a3412013-01-17 18:48:20 -080025#define PM8XXX_ALARM_CTRL_OFFSET 0x01
26#define PM8XXX_RTC_WRITE_OFFSET 0x02
27#define PM8XXX_RTC_READ_OFFSET 0x06
28#define PM8XXX_ALARM_RW_OFFSET 0x0A
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029
30/* RTC_CTRL register bit fields */
Stephen Boyd265a3412013-01-17 18:48:20 -080031#define PM8xxx_RTC_ENABLE BIT(7)
32#define PM8xxx_RTC_ALARM_ENABLE BIT(1)
33#define PM8xxx_RTC_ALARM_CLEAR BIT(0)
34#define PM8xxx_RTC_ABORT_ENABLE BIT(0)
Ashay Jaiswald66c9d52011-10-13 17:41:40 +053035
Stephen Boyd265a3412013-01-17 18:48:20 -080036#define NUM_8_BIT_RTC_REGS 0x4
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070037
38/**
Stephen Boyd265a3412013-01-17 18:48:20 -080039 * struct pm8xxx_rtc - rtc driver internal structure
40 * @rtc: rtc device for this driver.
41 * @rtc_alarm_irq: rtc alarm irq number.
42 * @rtc_base: address of rtc control register.
43 * @rtc_read_base: base address of read registers.
44 * @rtc_write_base: base address of write registers.
45 * @alarm_rw_base: base address of alarm registers.
46 * @ctrl_reg: rtc control register.
47 * @rtc_dev: device structure.
48 * @ctrl_reg_lock: spinlock protecting access to ctrl_reg.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070049 */
50struct pm8xxx_rtc {
51 struct rtc_device *rtc;
52 int rtc_alarm_irq;
53 int rtc_base;
54 int rtc_read_base;
55 int rtc_write_base;
56 int alarm_rw_base;
57 u8 ctrl_reg;
58 struct device *rtc_dev;
59 spinlock_t ctrl_reg_lock;
60};
61
62/*
63 * The RTC registers need to be read/written one byte at a time. This is a
64 * hardware limitation.
65 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070066static int pm8xxx_read_wrapper(struct pm8xxx_rtc *rtc_dd, u8 *rtc_val,
Stephen Boyd265a3412013-01-17 18:48:20 -080067 int base, int count)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070068{
69 int i, rc;
70 struct device *parent = rtc_dd->rtc_dev->parent;
71
72 for (i = 0; i < count; i++) {
73 rc = pm8xxx_readb(parent, base + i, &rtc_val[i]);
74 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -080075 dev_err(rtc_dd->rtc_dev, "PMIC read failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070076 return rc;
77 }
78 }
79
80 return 0;
81}
82
83static int pm8xxx_write_wrapper(struct pm8xxx_rtc *rtc_dd, u8 *rtc_val,
Stephen Boyd265a3412013-01-17 18:48:20 -080084 int base, int count)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070085{
86 int i, rc;
87 struct device *parent = rtc_dd->rtc_dev->parent;
88
89 for (i = 0; i < count; i++) {
90 rc = pm8xxx_writeb(parent, base + i, rtc_val[i]);
91 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -080092 dev_err(rtc_dd->rtc_dev, "PMIC write failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070093 return rc;
94 }
95 }
96
97 return 0;
98}
99
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700100/*
101 * Steps to write the RTC registers.
102 * 1. Disable alarm if enabled.
103 * 2. Write 0x00 to LSB.
104 * 3. Write Byte[1], Byte[2], Byte[3] then Byte[0].
105 * 4. Enable alarm if disabled in step 1.
106 */
Stephen Boyd265a3412013-01-17 18:48:20 -0800107static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700108{
Stephen Boyd265a3412013-01-17 18:48:20 -0800109 int rc, i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700110 unsigned long secs, irq_flags;
Stephen Boyd265a3412013-01-17 18:48:20 -0800111 u8 value[NUM_8_BIT_RTC_REGS], reg = 0, alarm_enabled = 0, ctrl_reg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700112 struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
113
114 rtc_tm_to_time(tm, &secs);
115
Stephen Boyd265a3412013-01-17 18:48:20 -0800116 for (i = 0; i < NUM_8_BIT_RTC_REGS; i++) {
117 value[i] = secs & 0xFF;
118 secs >>= 8;
119 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700120
121 dev_dbg(dev, "Seconds value to be written to RTC = %lu\n", secs);
122
123 spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
124 ctrl_reg = rtc_dd->ctrl_reg;
125
126 if (ctrl_reg & PM8xxx_RTC_ALARM_ENABLE) {
127 alarm_enabled = 1;
128 ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE;
129 rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base,
Stephen Boyd265a3412013-01-17 18:48:20 -0800130 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700131 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800132 dev_err(dev, "Write to RTC control register "
133 "failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700134 goto rtc_rw_fail;
135 }
Stephen Boyd265a3412013-01-17 18:48:20 -0800136 rtc_dd->ctrl_reg = ctrl_reg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700137 } else
138 spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
139
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700140 /* Write 0 to Byte[0] */
141 reg = 0;
142 rc = pm8xxx_write_wrapper(rtc_dd, &reg, rtc_dd->rtc_write_base, 1);
143 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800144 dev_err(dev, "Write to RTC write data register failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700145 goto rtc_rw_fail;
146 }
147
148 /* Write Byte[1], Byte[2], Byte[3] */
149 rc = pm8xxx_write_wrapper(rtc_dd, value + 1,
150 rtc_dd->rtc_write_base + 1, 3);
151 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800152 dev_err(dev, "Write to RTC write data register failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700153 goto rtc_rw_fail;
154 }
155
156 /* Write Byte[0] */
157 rc = pm8xxx_write_wrapper(rtc_dd, value, rtc_dd->rtc_write_base, 1);
158 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800159 dev_err(dev, "Write to RTC write data register failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700160 goto rtc_rw_fail;
161 }
162
163 if (alarm_enabled) {
164 ctrl_reg |= PM8xxx_RTC_ALARM_ENABLE;
165 rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base,
166 1);
167 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800168 dev_err(dev, "Write to RTC control register "
169 "failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700170 goto rtc_rw_fail;
171 }
Stephen Boyd265a3412013-01-17 18:48:20 -0800172 rtc_dd->ctrl_reg = ctrl_reg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700173 }
174
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700175rtc_rw_fail:
176 if (alarm_enabled)
177 spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
178
179 return rc;
180}
181
Stephen Boyd265a3412013-01-17 18:48:20 -0800182static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700183{
184 int rc;
Stephen Boyd265a3412013-01-17 18:48:20 -0800185 u8 value[NUM_8_BIT_RTC_REGS], reg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700186 unsigned long secs;
187 struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
188
189 rc = pm8xxx_read_wrapper(rtc_dd, value, rtc_dd->rtc_read_base,
190 NUM_8_BIT_RTC_REGS);
191 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800192 dev_err(dev, "RTC read data register failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700193 return rc;
194 }
195
196 /*
197 * Read the LSB again and check if there has been a carry over.
198 * If there is, redo the read operation.
199 */
200 rc = pm8xxx_read_wrapper(rtc_dd, &reg, rtc_dd->rtc_read_base, 1);
201 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800202 dev_err(dev, "RTC read data register failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700203 return rc;
204 }
205
206 if (unlikely(reg < value[0])) {
207 rc = pm8xxx_read_wrapper(rtc_dd, value,
208 rtc_dd->rtc_read_base, NUM_8_BIT_RTC_REGS);
209 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800210 dev_err(dev, "RTC read data register failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700211 return rc;
212 }
213 }
214
Stephen Boyd265a3412013-01-17 18:48:20 -0800215 secs = value[0] | (value[1] << 8) | (value[2] << 16) | (value[3] << 24);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700216
217 rtc_time_to_tm(secs, tm);
218
219 rc = rtc_valid_tm(tm);
220 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800221 dev_err(dev, "Invalid time read from RTC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700222 return rc;
223 }
224
225 dev_dbg(dev, "secs = %lu, h:m:s == %d:%d:%d, d/m/y = %d/%d/%d\n",
Stephen Boyd265a3412013-01-17 18:48:20 -0800226 secs, tm->tm_hour, tm->tm_min, tm->tm_sec,
227 tm->tm_mday, tm->tm_mon, tm->tm_year);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700228
229 return 0;
230}
231
Stephen Boyd265a3412013-01-17 18:48:20 -0800232static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700233{
Stephen Boyd265a3412013-01-17 18:48:20 -0800234 int rc, i;
235 u8 value[NUM_8_BIT_RTC_REGS], ctrl_reg;
236 unsigned long secs, irq_flags;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700237 struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700238
239 rtc_tm_to_time(&alarm->time, &secs);
240
Stephen Boyd265a3412013-01-17 18:48:20 -0800241 for (i = 0; i < NUM_8_BIT_RTC_REGS; i++) {
242 value[i] = secs & 0xFF;
243 secs >>= 8;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700244 }
245
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700246 spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
247
248 rc = pm8xxx_write_wrapper(rtc_dd, value, rtc_dd->alarm_rw_base,
249 NUM_8_BIT_RTC_REGS);
250 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800251 dev_err(dev, "Write to RTC ALARM register failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700252 goto rtc_rw_fail;
253 }
254
255 ctrl_reg = rtc_dd->ctrl_reg;
Stephen Boyd265a3412013-01-17 18:48:20 -0800256 ctrl_reg = alarm->enabled ? (ctrl_reg | PM8xxx_RTC_ALARM_ENABLE) :
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700257 (ctrl_reg & ~PM8xxx_RTC_ALARM_ENABLE);
258
259 rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1);
260 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800261 dev_err(dev, "Write to RTC control register failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700262 goto rtc_rw_fail;
263 }
264
265 rtc_dd->ctrl_reg = ctrl_reg;
266
267 dev_dbg(dev, "Alarm Set for h:r:s=%d:%d:%d, d/m/y=%d/%d/%d\n",
Stephen Boyd265a3412013-01-17 18:48:20 -0800268 alarm->time.tm_hour, alarm->time.tm_min,
269 alarm->time.tm_sec, alarm->time.tm_mday,
270 alarm->time.tm_mon, alarm->time.tm_year);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700271rtc_rw_fail:
272 spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
273 return rc;
274}
275
Stephen Boyd265a3412013-01-17 18:48:20 -0800276static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700277{
278 int rc;
Stephen Boyd265a3412013-01-17 18:48:20 -0800279 u8 value[NUM_8_BIT_RTC_REGS];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700280 unsigned long secs;
281 struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
282
283 rc = pm8xxx_read_wrapper(rtc_dd, value, rtc_dd->alarm_rw_base,
284 NUM_8_BIT_RTC_REGS);
285 if (rc < 0) {
286 dev_err(dev, "RTC alarm time read failed\n");
287 return rc;
288 }
289
Stephen Boyd265a3412013-01-17 18:48:20 -0800290 secs = value[0] | (value[1] << 8) | (value[2] << 16) | (value[3] << 24);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700291
292 rtc_time_to_tm(secs, &alarm->time);
293
294 rc = rtc_valid_tm(&alarm->time);
295 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800296 dev_err(dev, "Invalid alarm time read from RTC\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700297 return rc;
298 }
299
300 dev_dbg(dev, "Alarm set for - h:r:s=%d:%d:%d, d/m/y=%d/%d/%d\n",
Stephen Boyd265a3412013-01-17 18:48:20 -0800301 alarm->time.tm_hour, alarm->time.tm_min,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700302 alarm->time.tm_sec, alarm->time.tm_mday,
303 alarm->time.tm_mon, alarm->time.tm_year);
304
305 return 0;
306}
307
Stephen Boyd265a3412013-01-17 18:48:20 -0800308static int pm8xxx_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700309{
310 int rc;
311 unsigned long irq_flags;
312 struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
313 u8 ctrl_reg;
314
315 spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
316 ctrl_reg = rtc_dd->ctrl_reg;
Stephen Boyd265a3412013-01-17 18:48:20 -0800317 ctrl_reg = (enable) ? (ctrl_reg | PM8xxx_RTC_ALARM_ENABLE) :
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700318 (ctrl_reg & ~PM8xxx_RTC_ALARM_ENABLE);
319
320 rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1);
321 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800322 dev_err(dev, "Write to RTC control register failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700323 goto rtc_rw_fail;
324 }
325
326 rtc_dd->ctrl_reg = ctrl_reg;
327
328rtc_rw_fail:
329 spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
330 return rc;
331}
332
333static struct rtc_class_ops pm8xxx_rtc_ops = {
334 .read_time = pm8xxx_rtc_read_time,
335 .set_alarm = pm8xxx_rtc_set_alarm,
336 .read_alarm = pm8xxx_rtc_read_alarm,
337 .alarm_irq_enable = pm8xxx_rtc_alarm_irq_enable,
338};
339
340static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id)
341{
342 struct pm8xxx_rtc *rtc_dd = dev_id;
343 u8 ctrl_reg;
344 int rc;
345 unsigned long irq_flags;
346
347 rtc_update_irq(rtc_dd->rtc, 1, RTC_IRQF | RTC_AF);
348
349 spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
350
351 /* Clear the alarm enable bit */
352 ctrl_reg = rtc_dd->ctrl_reg;
353 ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE;
354
355 rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1);
356 if (rc < 0) {
357 spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
Stephen Boyd265a3412013-01-17 18:48:20 -0800358 dev_err(rtc_dd->rtc_dev, "Write to RTC control register "
359 "failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700360 goto rtc_alarm_handled;
361 }
362
363 rtc_dd->ctrl_reg = ctrl_reg;
364 spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
365
366 /* Clear RTC alarm register */
367 rc = pm8xxx_read_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base +
368 PM8XXX_ALARM_CTRL_OFFSET, 1);
369 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800370 dev_err(rtc_dd->rtc_dev, "RTC Alarm control register read "
371 "failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700372 goto rtc_alarm_handled;
373 }
374
375 ctrl_reg &= ~PM8xxx_RTC_ALARM_CLEAR;
376 rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base +
377 PM8XXX_ALARM_CTRL_OFFSET, 1);
378 if (rc < 0)
Stephen Boyd265a3412013-01-17 18:48:20 -0800379 dev_err(rtc_dd->rtc_dev, "Write to RTC Alarm control register"
380 " failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700381
382rtc_alarm_handled:
383 return IRQ_HANDLED;
384}
385
386static int __devinit pm8xxx_rtc_probe(struct platform_device *pdev)
387{
388 int rc;
389 u8 ctrl_reg;
390 bool rtc_write_enable = false;
391 struct pm8xxx_rtc *rtc_dd;
392 struct resource *rtc_resource;
393 const struct pm8xxx_rtc_platform_data *pdata =
Stephen Boyd265a3412013-01-17 18:48:20 -0800394 dev_get_platdata(&pdev->dev);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700395
396 if (pdata != NULL)
397 rtc_write_enable = pdata->rtc_write_enable;
398
399 rtc_dd = kzalloc(sizeof(*rtc_dd), GFP_KERNEL);
400 if (rtc_dd == NULL) {
401 dev_err(&pdev->dev, "Unable to allocate memory!\n");
402 return -ENOMEM;
403 }
404
Stephen Boyd265a3412013-01-17 18:48:20 -0800405 /* Initialise spinlock to protect RTC control register */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700406 spin_lock_init(&rtc_dd->ctrl_reg_lock);
407
408 rtc_dd->rtc_alarm_irq = platform_get_irq(pdev, 0);
409 if (rtc_dd->rtc_alarm_irq < 0) {
410 dev_err(&pdev->dev, "Alarm IRQ resource absent!\n");
411 rc = -ENXIO;
412 goto fail_rtc_enable;
413 }
414
415 rtc_resource = platform_get_resource_byname(pdev, IORESOURCE_IO,
416 "pmic_rtc_base");
417 if (!(rtc_resource && rtc_resource->start)) {
418 dev_err(&pdev->dev, "RTC IO resource absent!\n");
419 rc = -ENXIO;
420 goto fail_rtc_enable;
421 }
422
423 rtc_dd->rtc_base = rtc_resource->start;
424
425 /* Setup RTC register addresses */
426 rtc_dd->rtc_write_base = rtc_dd->rtc_base + PM8XXX_RTC_WRITE_OFFSET;
427 rtc_dd->rtc_read_base = rtc_dd->rtc_base + PM8XXX_RTC_READ_OFFSET;
428 rtc_dd->alarm_rw_base = rtc_dd->rtc_base + PM8XXX_ALARM_RW_OFFSET;
429
Stephen Boyd265a3412013-01-17 18:48:20 -0800430 rtc_dd->rtc_dev = &pdev->dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700431
432 /* Check if the RTC is on, else turn it on */
433 rc = pm8xxx_read_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1);
434 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800435 dev_err(&pdev->dev, "RTC control register read failed!\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700436 goto fail_rtc_enable;
437 }
438
439 if (!(ctrl_reg & PM8xxx_RTC_ENABLE)) {
440 ctrl_reg |= PM8xxx_RTC_ENABLE;
441 rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base,
442 1);
443 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800444 dev_err(&pdev->dev, "Write to RTC control register "
445 "failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700446 goto fail_rtc_enable;
447 }
448 }
449
Ashay Jaiswald66c9d52011-10-13 17:41:40 +0530450 /* Enable abort enable feature */
451 ctrl_reg |= PM8xxx_RTC_ABORT_ENABLE;
452 rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1);
453 if (rc < 0) {
454 dev_err(&pdev->dev, "PM8xxx write failed!\n");
455 goto fail_rtc_enable;
456 }
457
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700458 rtc_dd->ctrl_reg = ctrl_reg;
459 if (rtc_write_enable == true)
460 pm8xxx_rtc_ops.set_time = pm8xxx_rtc_set_time;
461
462 platform_set_drvdata(pdev, rtc_dd);
463
Josh Cartwright05e49d12014-04-03 14:50:14 -0700464 device_init_wakeup(&pdev->dev, 1);
465
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700466 /* Register the RTC device */
467 rtc_dd->rtc = rtc_device_register("pm8xxx_rtc", &pdev->dev,
468 &pm8xxx_rtc_ops, THIS_MODULE);
469 if (IS_ERR(rtc_dd->rtc)) {
470 dev_err(&pdev->dev, "%s: RTC registration failed (%ld)\n",
471 __func__, PTR_ERR(rtc_dd->rtc));
472 rc = PTR_ERR(rtc_dd->rtc);
473 goto fail_rtc_enable;
474 }
475
476 /* Request the alarm IRQ */
477 rc = request_any_context_irq(rtc_dd->rtc_alarm_irq,
478 pm8xxx_alarm_trigger, IRQF_TRIGGER_RISING,
479 "pm8xxx_rtc_alarm", rtc_dd);
480 if (rc < 0) {
481 dev_err(&pdev->dev, "Request IRQ failed (%d)\n", rc);
482 goto fail_req_irq;
483 }
484
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700485 dev_dbg(&pdev->dev, "Probe success !!\n");
486
487 return 0;
488
489fail_req_irq:
490 rtc_device_unregister(rtc_dd->rtc);
491fail_rtc_enable:
492 platform_set_drvdata(pdev, NULL);
493 kfree(rtc_dd);
494 return rc;
495}
496
Stephen Boyd265a3412013-01-17 18:48:20 -0800497static int __devexit pm8xxx_rtc_remove(struct platform_device *pdev)
498{
499 struct pm8xxx_rtc *rtc_dd = platform_get_drvdata(pdev);
500
501 device_init_wakeup(&pdev->dev, 0);
502 free_irq(rtc_dd->rtc_alarm_irq, rtc_dd);
503 rtc_device_unregister(rtc_dd->rtc);
504 platform_set_drvdata(pdev, NULL);
505 kfree(rtc_dd);
506
507 return 0;
508}
509
510#ifdef CONFIG_PM_SLEEP
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700511static int pm8xxx_rtc_resume(struct device *dev)
512{
513 struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
514
515 if (device_may_wakeup(dev))
516 disable_irq_wake(rtc_dd->rtc_alarm_irq);
517
518 return 0;
519}
520
521static int pm8xxx_rtc_suspend(struct device *dev)
522{
523 struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev);
524
525 if (device_may_wakeup(dev))
526 enable_irq_wake(rtc_dd->rtc_alarm_irq);
527
528 return 0;
529}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700530#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700531
Stephen Boyd265a3412013-01-17 18:48:20 -0800532static SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, pm8xxx_rtc_suspend, pm8xxx_rtc_resume);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700533
Ashay Jaiswald66c9d52011-10-13 17:41:40 +0530534static void pm8xxx_rtc_shutdown(struct platform_device *pdev)
535{
536 u8 value[4] = {0, 0, 0, 0};
537 u8 reg;
538 int rc;
539 unsigned long irq_flags;
540 bool rtc_alarm_powerup = false;
541 struct pm8xxx_rtc *rtc_dd = platform_get_drvdata(pdev);
542 struct pm8xxx_rtc_platform_data *pdata = pdev->dev.platform_data;
543
544 if (pdata != NULL)
545 rtc_alarm_powerup = pdata->rtc_alarm_powerup;
546
547 if (!rtc_alarm_powerup) {
548
549 spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags);
550 dev_dbg(&pdev->dev, "Disabling alarm interrupts\n");
551
552 /* Disable RTC alarms */
553 reg = rtc_dd->ctrl_reg;
554 reg &= ~PM8xxx_RTC_ALARM_ENABLE;
555 rc = pm8xxx_write_wrapper(rtc_dd, &reg, rtc_dd->rtc_base, 1);
556 if (rc < 0) {
Stephen Boyd265a3412013-01-17 18:48:20 -0800557 dev_err(rtc_dd->rtc_dev, "Disabling alarm failed\n");
Ashay Jaiswald66c9d52011-10-13 17:41:40 +0530558 goto fail_alarm_disable;
559 }
560
561 /* Clear Alarm register */
562 rc = pm8xxx_write_wrapper(rtc_dd, value,
563 rtc_dd->alarm_rw_base, NUM_8_BIT_RTC_REGS);
564 if (rc < 0)
Stephen Boyd265a3412013-01-17 18:48:20 -0800565 dev_err(rtc_dd->rtc_dev, "Clearing alarm failed\n");
Ashay Jaiswald66c9d52011-10-13 17:41:40 +0530566
567fail_alarm_disable:
568 spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
569 }
570}
571
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700572static struct platform_driver pm8xxx_rtc_driver = {
573 .probe = pm8xxx_rtc_probe,
574 .remove = __devexit_p(pm8xxx_rtc_remove),
Ashay Jaiswald66c9d52011-10-13 17:41:40 +0530575 .shutdown = pm8xxx_rtc_shutdown,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700576 .driver = {
577 .name = PM8XXX_RTC_DEV_NAME,
578 .owner = THIS_MODULE,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700579 .pm = &pm8xxx_rtc_pm_ops,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700580 },
581};
582
Stephen Boyd265a3412013-01-17 18:48:20 -0800583module_platform_driver(pm8xxx_rtc_driver);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700584
585MODULE_ALIAS("platform:rtc-pm8xxx");
586MODULE_DESCRIPTION("PMIC8xxx RTC driver");
587MODULE_LICENSE("GPL v2");
588MODULE_AUTHOR("Anirudh Ghayal <aghayal@codeaurora.org>");