예제 #1
0
int pcf50633_irq_suspend(struct pcf50633 *pcf)
{
    int ret;
    int i;
    u8 res[5];

    /* Make sure our interrupt handlers are not called
     * henceforth */
    disable_irq(pcf->irq);

    /* Save the masks */
    ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M,
                              ARRAY_SIZE(pcf->suspend_irq_masks),
                              pcf->suspend_irq_masks);
    if (ret < 0) {
        dev_err(pcf->dev, "error saving irq masks\n");
        goto out;
    }

    /* Write wakeup irq masks */
    for (i = 0; i < ARRAY_SIZE(res); i++)
        res[i] = ~pcf->pdata->resumers[i];

    ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
                               ARRAY_SIZE(res), &res[0]);
    if (ret < 0) {
        dev_err(pcf->dev, "error writing wakeup irq masks\n");
        goto out;
    }

    pcf->is_suspended = 1;

out:
    return ret;
}
예제 #2
0
static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct pcf50633_rtc *rtc;
	struct pcf50633_time pcf_tm;
	int alarm_masked, ret = 0;

	rtc = dev_get_drvdata(dev);

	rtc2pcf_time(&pcf_tm, &alrm->time);

	/* do like mktime does and ignore tm_wday */
	pcf_tm.time[PCF50633_TI_WKDAY] = 7;

	alarm_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_ALARM);

	/* disable alarm interrupt */
	if (!alarm_masked)
		pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM);

	/* Returns 0 on success */
	ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSCA,
				PCF50633_TI_EXTENT, &pcf_tm.time[0]);
	if (!alrm->enabled)
		rtc->alarm_pending = 0;

	if (!alarm_masked || alrm->enabled)
		pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM);
	rtc->alarm_enabled = alrm->enabled;

	return ret;
}
예제 #3
0
static int pcf50633_resume(struct device *dev)
{
	struct pcf50633 *pcf;
	int ret;

	pcf = dev_get_drvdata(dev);

	/* Write the saved mask registers */
	ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
				ARRAY_SIZE(pcf->suspend_irq_masks),
					pcf->suspend_irq_masks);
	if (ret < 0)
		dev_err(pcf->dev, "Error restoring saved suspend masks\n");

	/* Restore regulators' state */


	get_device(pcf->dev);

	/*
	 * Clear any pending interrupts and set resume reason if any.
	 * This will leave with enable_irq()
	 */
	pcf50633_irq_worker(&pcf->irq_work);

	return 0;
}
예제 #4
0
int pcf50633_irq_resume(struct pcf50633 *pcf)
{
    int ret;

    /* Write the saved mask registers */
    ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
                               ARRAY_SIZE(pcf->suspend_irq_masks),
                               pcf->suspend_irq_masks);
    if (ret < 0)
        dev_err(pcf->dev, "Error restoring saved suspend masks\n");

    enable_irq(pcf->irq);

    return ret;
}
예제 #5
0
static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
	struct pcf50633_rtc *rtc;
	struct pcf50633_time pcf_tm;
	int second_masked, alarm_masked, ret = 0;

	rtc = dev_get_drvdata(dev);

	dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n",
		tm->tm_mday, tm->tm_mon, tm->tm_year,
		tm->tm_hour, tm->tm_min, tm->tm_sec);

	rtc2pcf_time(&pcf_tm, tm);

	dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n",
		pcf_tm.time[PCF50633_TI_DAY],
		pcf_tm.time[PCF50633_TI_MONTH],
		pcf_tm.time[PCF50633_TI_YEAR],
		pcf_tm.time[PCF50633_TI_HOUR],
		pcf_tm.time[PCF50633_TI_MIN],
		pcf_tm.time[PCF50633_TI_SEC]);


	second_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_SECOND);
	alarm_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_ALARM);

	if (!second_masked)
		pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_SECOND);
	if (!alarm_masked)
		pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM);

	/* Returns 0 on success */
	ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSC,
					     PCF50633_TI_EXTENT,
					     &pcf_tm.time[0]);

	if (!second_masked)
		pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_SECOND);
	if (!alarm_masked)
		pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM);

	return ret;
}
예제 #6
0
static int pcf50633_suspend(struct device *dev, pm_message_t state)
{
	struct pcf50633 *pcf;
	int ret = 0, i;
	u8 res[5];

	pcf = dev_get_drvdata(dev);

	/* Make sure our interrupt handlers are not called
	 * henceforth */
	disable_irq(pcf->irq);

	/* Make sure that any running IRQ worker has quit */
	cancel_work_sync(&pcf->irq_work);

	/* Save the masks */
	ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M,
				ARRAY_SIZE(pcf->suspend_irq_masks),
					pcf->suspend_irq_masks);
	if (ret < 0) {
		dev_err(pcf->dev, "error saving irq masks\n");
		goto out;
	}

	/* Write wakeup irq masks */
	for (i = 0; i < ARRAY_SIZE(res); i++)
		res[i] = ~pcf->pdata->resumers[i];

	ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
					ARRAY_SIZE(res), &res[0]);
	if (ret < 0) {
		dev_err(pcf->dev, "error writing wakeup irq masks\n");
		goto out;
	}

	pcf->is_suspended = 1;

out:
	return ret;
}