static int tps6591x_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
	u8 buff[7];
	int err;

	buff[0] = tm->tm_sec;
	buff[1] = tm->tm_min;
	buff[2] = tm->tm_hour;
	buff[3] = tm->tm_mday;
	buff[4] = tm->tm_mon;
	buff[5] = tm->tm_year;
	buff[6] = tm->tm_wday;
	buff[4] = tm->tm_mon+1;
	print_time(dev, tm);
	convert_decimal_to_bcd(buff, sizeof(buff));
	err = tps6591x_rtc_stop(dev);
	if (err < 0) {
		dev_err(dev->parent, "\n failed to clear RTC_ENABLE\n");
		return err;
	}

	err = tps6591x_write_regs(dev, RTC_SECONDS_REG, sizeof(buff), buff);
	if (err < 0) {
		dev_err(dev->parent, "\n failed to program new time\n");
		return err;
	}

	err = tps6591x_rtc_start(dev);
	if (err < 0) {
		dev_err(dev->parent, "\n failed to set RTC_ENABLE\n");
		return err;
	}

	return 0;
}
Esempio n. 2
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;
}