Exemplo n.º 1
0
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, &reg);
        if (err)
            return err;
        reg |= 0x8;
        err = tps6591x_write_regs(dev, RTC_INT, 1, &reg);
        if (err)
            return err;
        rtc->irq_en = true;
    } else {
        if (rtc->irq_en == false)
            return 0;
        err = tps6591x_read_regs(dev, RTC_INT, 1, &reg);
        if (err)
            return err;
        reg &= ~0x8;
        err = tps6591x_write_regs(dev, RTC_INT, 1, &reg);
        if (err)
            return err;
        rtc->irq_en = false;
    }
    return 0;
}
Exemplo n.º 2
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, &reg);
        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, &reg);
        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, &reg);
        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;
}
Exemplo n.º 3
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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
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, &reg);
    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, &reg);
    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);
}
Exemplo n.º 7
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;
}