Exemplo n.º 1
0
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;
}
Exemplo n.º 3
0
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, &reg);
    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, &reg);
    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, &reg);
    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, &reg);
    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;
}