#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/mfd/tps65910.h>
+#include <linux/wakelock.h>
+#include <linux/kthread.h>
static inline int irq_to_tps65910_irq(struct tps65910 *tps65910,
int irq)
u8 reg;
int i;
+ wake_lock(&tps65910->irq_wake);
tps65910->read(tps65910, TPS65910_INT_STS, 1, ®);
irq_sts = reg;
tps65910->read(tps65910, TPS65910_INT_STS2, 1, ®);
irq_sts &= ~irq_mask;
if (!irq_sts)
+ {
+ wake_unlock(&tps65910->irq_wake);
return IRQ_NONE;
+ }
for (i = 0; i < tps65910->irq_num; i++) {
reg = irq_sts >> 8;
tps65910->write(tps65910, TPS65910_INT_STS3, 1, ®);
}
-
+ wake_unlock(&tps65910->irq_wake);
return IRQ_HANDLED;
}
tps65910->write(tps65910, TPS65910_INT_STS2, 1, ®);
tps65910->read(tps65910, TPS65910_INT_STS3, 1, ®);
tps65910->write(tps65910, TPS65910_INT_STS3, 1, ®);
+ tps65910->read(tps65910, TPS65910_RTC_STATUS, 1, ®);
+ tps65910->write(tps65910, TPS65910_RTC_STATUS, 1, ®);//clear alarm and timer interrupt
/* Mask top level interrupts */
tps65910->irq_mask = 0xFFFFFF;
- mutex_init(&tps65910->irq_lock);
+ mutex_init(&tps65910->irq_lock);
+ wake_lock_init(&tps65910->irq_wake, WAKE_LOCK_SUSPEND, "tps65910_irq_wake");
tps65910->chip_irq = irq;
tps65910->irq_base = pdata->irq_base;
-
+
switch (tps65910_chip_id(tps65910)) {
case TPS65910:
tps65910->irq_num = TPS65910_NUM_IRQ;
return ret;
}
-
-
static irqreturn_t tps65910_alm_irq(int irq, void *data)
{
struct tps65910_rtc *tps65910_rtc = data;
+ int ret;
+ u8 rtc_ctl;
+ /*Dummy read -- mandatory for status register*/
+ ret = tps65910_reg_read(tps65910_rtc->tps65910, TPS65910_RTC_STATUS);
+ if (ret < 0) {
+ printk("%s:Failed to read RTC status: %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = tps65910_reg_read(tps65910_rtc->tps65910, TPS65910_RTC_STATUS);
+ if (ret < 0) {
+ printk("%s:Failed to read RTC status: %d\n", __func__, ret);
+ return ret;
+ }
+ rtc_ctl = ret&0xff;
+
+ //The alarm interrupt keeps its low level, until the micro-controller write 1 in the ALARM bit of the RTC_STATUS_REG register.
+ ret = tps65910_reg_write(tps65910_rtc->tps65910, TPS65910_RTC_STATUS,rtc_ctl);
+ if (ret < 0) {
+ printk("%s:Failed to read RTC status: %d\n", __func__, ret);
+ return ret;
+ }
+
rtc_update_irq(tps65910_rtc->rtc, 1, RTC_IRQF | RTC_AF);
+ printk("%s:irq=%d,rtc_ctl=0x%x\n",__func__,irq,rtc_ctl);
return IRQ_HANDLED;
}
static irqreturn_t tps65910_per_irq(int irq, void *data)
{
struct tps65910_rtc *tps65910_rtc = data;
-
+
rtc_update_irq(tps65910_rtc->rtc, 1, RTC_IRQF | RTC_UF);
//printk("%s:irq=%d\n",__func__,irq);
//tps65910_set_bits(tps65910_rtc->tps65910, TPS65910_RTC_INTERRUPTS,
// BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+ enable_irq_wake(alm_irq); // so tps65910 alarm irq can wake up system
g_pdev = pdev;
printk("%s:ok\n",__func__);
int nr = 0, ret;
struct platform_device *pdev;
struct rtc_time tm;
+ struct rtc_wkalrm alrm;
+ struct tps65910_rtc *tps65910_rtc;
if(count > 3)
return -EFAULT;
return -EFAULT;
sscanf(nr_buf, "%d", &nr);
- if(nr >= 2 || nr < 0)
+ if(nr > 5 || nr < 0)
{
printk("%s:data is error\n",__func__);
return -EFAULT;
else
pdev = g_pdev;
+
+ tps65910_rtc = dev_get_drvdata(&pdev->dev);
+
+ //test rtc time
if(nr == 0)
{
tm.tm_wday = 6;
else
printk("%s:error\n",__func__);
+
+ //test rtc alarm
+ if(nr == 2)
+ {
+ //2000-01-01 00:00:30
+ if(tm.tm_sec < 30)
+ {
+ alrm.time.tm_sec = tm.tm_sec+30;
+ alrm.time.tm_min = tm.tm_min;
+ }
+ else
+ {
+ alrm.time.tm_sec = tm.tm_sec-30;
+ alrm.time.tm_min = tm.tm_min+1;
+ }
+ alrm.time.tm_hour = tm.tm_hour;
+ alrm.time.tm_mday = tm.tm_mday;
+ alrm.time.tm_mon = tm.tm_mon;
+ alrm.time.tm_year = tm.tm_year;
+ tps65910_rtc_alarm_irq_enable(&pdev->dev, 1);
+ tps65910_rtc_setalarm(&pdev->dev, &alrm);
+
+ dev_info(&pdev->dev, "Set alarm %4d-%02d-%02d(%d) %02d:%02d:%02d\n",
+ 1900 + alrm.time.tm_year, alrm.time.tm_mon + 1, alrm.time.tm_mday, alrm.time.tm_wday,
+ alrm.time.tm_hour, alrm.time.tm_min, alrm.time.tm_sec);
+ }
+
+
+ if(nr == 3)
+ {
+ ret = tps65910_reg_read(tps65910_rtc->tps65910, TPS65910_RTC_STATUS);
+ if (ret < 0) {
+ printk("%s:Failed to read RTC status: %d\n", __func__, ret);
+ return ret;
+ }
+ printk("%s:ret=0x%x\n",__func__,ret&0xff);
+
+ ret = tps65910_reg_write(tps65910_rtc->tps65910, TPS65910_RTC_STATUS, ret&0xff);
+ if (ret < 0) {
+ printk("%s:Failed to read RTC status: %d\n", __func__, ret);
+ return ret;
+ }
+ }
+
+ if(nr == 4)
+ tps65910_rtc_update_irq_enable(&pdev->dev, 1);
+
+ if(nr == 5)
+ tps65910_rtc_update_irq_enable(&pdev->dev, 0);
+
return count;
}