static int tps6591x_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) { struct tps6591x_rtc *rtc = dev_get_drvdata(dev); u8 reg; int err; if (rtc->irq == -1) return -EIO; if (enable) { if (rtc->irq_en == true) return 0; err = tps6591x_read_regs(dev, RTC_INT, 1, ®); if (err) return err; reg |= 0x8; err = tps6591x_write_regs(dev, RTC_INT, 1, ®); if (err) return err; rtc->irq_en = true; } else { if (rtc->irq_en == false) return 0; err = tps6591x_read_regs(dev, RTC_INT, 1, ®); if (err) return err; reg &= ~0x8; err = tps6591x_write_regs(dev, RTC_INT, 1, ®); if (err) return err; rtc->irq_en = false; } return 0; }
static int tps6591x_rtc_start(struct device *dev) { u8 reg = 0; u8 retries = 0; int err; do { err = tps6591x_read_regs(dev, RTC_CTRL, 1, ®); if (err < 0) { dev_err(dev->parent, "\n failed to read RTC_CTRL reg\n"); return err; } /* set STOP bit alone */ reg |= 0x1; err = tps6591x_write_regs(dev, RTC_CTRL, 1, ®); if (err < 0) { dev_err(dev->parent, "\n failed to program RTC_CTRL reg\n"); return err; } err = tps6591x_read_regs(dev, RTC_STATUS, 1, ®); if (err < 0) { dev_err(dev->parent, "\n failed to read RTC_CTRL reg\n"); return err; } /* FixMe: Is allowing up to 5 retries sufficient?? */ if (retries++ == 5) { dev_err(dev->parent, "\n failed to stop RTC\n"); return -EBUSY; } } while (!(reg & 2)); return 0; }
static int tps6591x_rtc_read_time(struct device *dev, struct rtc_time *tm) { u8 buff[7]; int err; err = tps6591x_read_regs(dev, RTC_SECONDS_REG, sizeof(buff), buff); if (err < 0) { dev_err(dev, "\n %s :: failed to read time\n", __FILE__); return err; } convert_bcd_to_decimal(buff, sizeof(buff)); tm->tm_sec = buff[0]; tm->tm_min = buff[1]; tm->tm_hour = buff[2]; tm->tm_mday = buff[3]; tm->tm_mon = buff[4] - 1; tm->tm_year = buff[5] + RTC_YEAR_OFFSET; tm->tm_wday = buff[6]; print_time(dev, tm); return tps6591x_rtc_valid_tm(tm); }
static int tps6591x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { u8 buff[6]; int err; err = tps6591x_read_regs(dev, RTC_ALARM, sizeof(buff), buff); if (err) return err; convert_bcd_to_decimal(buff, sizeof(buff)); alrm->time.tm_sec = buff[0]; alrm->time.tm_min = buff[1]; alrm->time.tm_hour = buff[2]; alrm->time.tm_mday = buff[3]; alrm->time.tm_mon = buff[4] - 1; alrm->time.tm_year = buff[5] + RTC_YEAR_OFFSET; dev_info(dev->parent, "\n getting alarm time::\n"); print_time(dev, &alrm->time); return 0; }
static irqreturn_t tps6591x_rtc_irq(int irq, void *data) { struct device *dev = data; struct tps6591x_rtc *rtc = dev_get_drvdata(dev); u8 reg; int err; /* clear Alarm status bits.*/ err = tps6591x_read_regs(dev, RTC_STATUS, 1, ®); if (err) { dev_err(dev->parent, "unable to read RTC_STATUS reg\n"); return -EBUSY; } reg = ALARM_INT_STATUS; err = tps6591x_write_regs(dev, RTC_STATUS, 1, ®); if (err) { dev_err(dev->parent, "unable to program RTC_STATUS reg\n"); return -EBUSY; } rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); return IRQ_HANDLED; }
static int tps6591x_rtc_read_time(struct device *dev, struct rtc_time *tm) { u8 buff[7]; int err; err = tps6591x_read_regs(dev, RTC_SECONDS_REG, sizeof(buff), buff); if (err < 0) { dev_err(dev, "\n %s :: failed to read time\n", __FILE__); return err; } convert_bcd_to_decimal(buff, sizeof(buff)); tm->tm_sec = buff[0]; tm->tm_min = buff[1]; tm->tm_hour = buff[2]; tm->tm_mday = buff[3]; tm->tm_mon = buff[4]; tm->tm_year = buff[5]; tm->tm_wday = buff[6]; if(tm->tm_mon >= 1) tm->tm_mon -=1; else printk("[Error]tps6591x_rtc_read_time tm->tm_mon=%x! This value should be above 0. \n", tm->tm_mon ); print_time(dev, tm); return tps6591x_rtc_valid_tm(tm); }
static int __devinit tps6591x_rtc_probe(struct platform_device *pdev) { struct tps6591x_rtc_platform_data *pdata = pdev->dev.platform_data; struct tps6591x_rtc *rtc; struct rtc_time tm; int err; u8 reg; rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); if (!rtc) return -ENOMEM; rtc->shutdown_ongoing = false; rtc->irq = -1; if (!pdata) { dev_err(&pdev->dev, "no platform_data specified\n"); return -EINVAL; } if (pdata->irq < 0) dev_err(&pdev->dev, "\n no IRQ specified, wakeup is disabled\n"); dev_set_drvdata(&pdev->dev, rtc); device_init_wakeup(&pdev->dev, 1); rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &tps6591x_rtc_ops, THIS_MODULE); if (IS_ERR(rtc->rtc)) { err = PTR_ERR(rtc->rtc); goto fail; } if ((int)pdev && (int)&pdev->dev) err = tps6591x_read_regs(&pdev->dev, RTC_STATUS, 1, ®); else { dev_err(&pdev->dev, "\n %s Input params incorrect\n", __func__); return -EBUSY; } if (err) { dev_err(&pdev->dev, "\n %s unable to read status\n", __func__); return -EBUSY; } reg = RTC_BBCH_SEL | RTC_BBCH_EN; tps6591x_write_regs(&pdev->dev, RTC_BBCH_REG, 1, ®); if (err) { dev_err(&pdev->dev, "unable to program Charger reg\n"); return -EBUSY; } err = tps6591x_rtc_start(&pdev->dev); if (err) { dev_err(&pdev->dev, "unable to start RTC\n"); return -EBUSY; } tps6591x_rtc_read_time(&pdev->dev, &tm); if (tps6591x_rtc_valid_tm(&tm) < 0) { if (pdata->time.tm_year < 2000 || pdata->time.tm_year >= 2100) { memset(&pdata->time, 0, sizeof(pdata->time)); pdata->time.tm_year = 2000; pdata->time.tm_mday = 1; } pdata->time.tm_year -= OS_REF_YEAR; tps6591x_rtc_set_time(&pdev->dev, &pdata->time); } reg = ALARM_INT_STATUS; err = tps6591x_write_regs(&pdev->dev, RTC_STATUS, 1, ®); if (err) { dev_err(&pdev->dev, "unable to program RTC_STATUS reg\n"); return -EBUSY; } reg = ENABLE_ALARM_INT; tps6591x_write_regs(&pdev->dev, RTC_INT, 1, ®); if (err) { dev_err(&pdev->dev, "unable to program Interrupt Mask reg\n"); return -EBUSY; } if (pdata && (pdata->irq >= 0)) { rtc->irq = pdata->irq; err = request_threaded_irq(pdata->irq, NULL, tps6591x_rtc_irq, IRQF_ONESHOT, "rtc_tps6591x", &pdev->dev); if (err) { dev_err(&pdev->dev, "request IRQ:%d fail\n", rtc->irq); rtc->irq = -1; } else { device_init_wakeup(&pdev->dev, 1); enable_irq_wake(rtc->irq); } } return 0; fail: if (!IS_ERR_OR_NULL(rtc->rtc)) rtc_device_unregister(rtc->rtc); kfree(rtc); return err; }