static int tps6591x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct tps6591x_rtc *rtc = dev_get_drvdata(dev); unsigned long seconds; u8 buff[6]; int err; struct rtc_time tm; if (rtc->shutdown_ongoing) { printk(KERN_WARNING "tps6591x_rtc_set_alarm: Device shutdown on-going, skip alarm setting.\n"); return -ESHUTDOWN; } if (rtc->irq == -1) return -EIO; err = tps6591x_rtc_valid_tm(&alrm->time); if (err < 0) { dev_err(dev->parent, "\n Invalid alarm time\n"); return err; } dev_info(dev->parent, "\n setting alarm to requested time::\n"); print_time(dev->parent, &alrm->time); rtc_tm_to_time(&alrm->time, &seconds); tps6591x_rtc_read_time(dev, &tm); rtc_tm_to_time(&tm, &rtc->epoch_start); if (WARN_ON(alrm->enabled && (seconds < rtc->epoch_start))) { dev_err(dev->parent, "\n can't set alarm to requested time\n"); return -EINVAL; } err = tps6591x_rtc_alarm_irq_enable(dev, alrm->enabled); if(err) { dev_err(dev->parent, "\n can't set alarm irq\n"); return err; } buff[0] = alrm->time.tm_sec; buff[1] = alrm->time.tm_min; buff[2] = alrm->time.tm_hour; buff[3] = alrm->time.tm_mday; buff[4] = alrm->time.tm_mon + 1; buff[5] = alrm->time.tm_year % RTC_YEAR_OFFSET; convert_decimal_to_bcd(buff, sizeof(buff)); err = tps6591x_write_regs(dev, RTC_ALARM, sizeof(buff), buff); if (err) dev_err(dev->parent, "\n unable to program alarm\n"); return err; }
static int tps6591x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct tps6591x_rtc *rtc = dev_get_drvdata(dev); unsigned long seconds; u8 buff[6]; int err; struct rtc_time tm; if (rtc->irq == -1) return -EIO; dev_info(dev->parent, "\n setting alarm to requested time::\n"); print_time(dev->parent, &alrm->time); rtc_tm_to_time(&alrm->time, &seconds); tps6591x_rtc_read_time(dev, &tm); rtc_tm_to_time(&tm, &rtc->epoch_start); if (WARN_ON(alrm->enabled && (seconds < rtc->epoch_start))) { dev_err(dev->parent, "\n can't set alarm to requested time\n"); return -EINVAL; } if (alrm->enabled && !rtc->irq_en) { rtc->irq_en = true; } else if (!alrm->enabled && rtc->irq_en) { rtc->irq_en = false; } buff[0] = alrm->time.tm_sec; buff[1] = alrm->time.tm_min; buff[2] = alrm->time.tm_hour; buff[3] = alrm->time.tm_mday; buff[4] = alrm->time.tm_mon+1; buff[5] = alrm->time.tm_year; convert_decimal_to_bcd(buff, sizeof(buff)); err = tps6591x_write_regs(dev, RTC_ALARM, sizeof(buff), buff); if (err) dev_err(dev->parent, "\n unable to program alarm\n"); return err; }
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; }