Ejemplo n.º 1
0
DRIVER_API_RC qrk_cxxxx_rtc_set_alarm(struct qrk_cxxxx_rtc_alarm *alarm){

    MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CCR) &= ~QRK_RTC_INTERRUPT_ENABLE;

    if(false != alarm->alarm_enable)
    {
        if(alarm->callback_fn)
        {
            callback_fn = alarm->callback_fn;
            callback_param = alarm->callback_param;
        }
        MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_EOI);
        MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CMR) = alarm->alarm_rtc_val;

        SET_INTERRUPT_HANDLER(SOC_RTC_INTERRUPT, rtc_isr);

         /* unmask RTC interrupts to qrk  */
        MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_INT_RTC_MASK_OFFSET) =
        QRK_INT_RTC_UNMASK_QRK;

        MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CCR) |= QRK_RTC_INTERRUPT_ENABLE;
        MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CCR) &= ~QRK_RTC_INTERRUPT_MASK;
    }
    else
    {
        MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_INT_RTC_MASK_OFFSET) = ~(0);
    }
    pm_wakelock_release(&rtc_wakelock);
    pm_wakelock_acquire(&rtc_wakelock, RTC_WAKELOCK_TIMEOUT);
    return DRV_RC_OK;
}
Ejemplo n.º 2
0
/*! \fn     int qrk_cxxxx_rtc_set_alarm(struct device *rtc_dev, const uint32_t alarm_val)
 *
 *  \brief  Function to set an RTC alarm
 *
 *  \param  alarm_val Alarm value
 *
 *  \return DEV_OK on success
 *          DEV_USED otherwise
 */
int qrk_cxxxx_rtc_set_alarm(struct device *rtc_dev, const uint32_t alarm_val)
{
	OS_ERR_TYPE err;

	MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR,
			       QRK_RTC_CCR) &= ~QRK_RTC_INTERRUPT_ENABLE;

	MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_EOI);
	MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CMR) = alarm_val;

	irq_enable(SOC_RTC_INTERRUPT);

	/* unmask RTC interrupts to quark  */
	MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_INT_RTC_MASK_OFFSET) =
		QRK_INT_RTC_UNMASK_QRK;

	MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR,
			       QRK_RTC_CCR) |= QRK_RTC_INTERRUPT_ENABLE;
	MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR,
			       QRK_RTC_CCR) &= ~QRK_RTC_INTERRUPT_MASK;

	pm_wakelock_acquire(&rtc_wakelock);
	timer_start(rtc_wakelock_timer, RTC_WAKELOCK_DELAY, &err);
	if (err != E_OS_OK) {
		pm_wakelock_release(&rtc_wakelock);
		return DEV_USED;
	}
	return DEV_OK;
}
Ejemplo n.º 3
0
/*! \fn     DRIVER_API_RC qrk_cxxxx_rtc_set_config(struct qrk_cxxxx_rtc_config *config)
*
*  \brief   Function to configure the RTC
*
*  \param   config   : pointer to a RTC configuration structure
*
*  \return  DRV_RC_OK on success\n
*           DRV_RC_FAIL otherwise
*/
DRIVER_API_RC qrk_cxxxx_rtc_set_config(struct qrk_cxxxx_rtc_config *config)
{
    OS_ERR_TYPE err;
    /*  Set RTC divider - 32.768khz / 32768 = 1 second.
    *   Note: Divider not implemented in standard emulation image.
    */
    qrk_cxxxx_rtc_clock_frequency(SCSS_RTC_CLK_DIV_1_HZ);

    MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CCR) |= QRK_RTC_INTERRUPT_MASK;

    /* set initial RTC value */
    while (config->initial_rtc_val != MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CCVR)) {
        MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CLR) = config->initial_rtc_val;
    }

    pm_wakelock_acquire(&rtc_wakelock);
    timer_start(rtc_wakelock_timer, RTC_WAKELOCK_DELAY, &err);
    if(err != E_OS_OK) {
        pm_wakelock_release(&rtc_wakelock);
        return DRV_RC_BUSY;
    }
    MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CCR) &= ~QRK_RTC_INTERRUPT_MASK;

    return DRV_RC_OK;
}
Ejemplo n.º 4
0
/*! \fn     int qrk_cxxxx_rtc_set_config(struct device *dev, struct rtc_config *config)
 *
 *  \brief   Function to configure the RTC
 *
 *  \param   config   : pointer to a RTC configuration structure
 *
 *  \return  DEV_OK on success\n
 *           DEV_USED otherwise
 */
static int qrk_cxxxx_rtc_set_config(struct device *	rtc_dev,
				    struct rtc_config * config)
{
	OS_ERR_TYPE err;

	/*  Set RTC divider - 32.768khz / 32768 = 1 second.
	 *   Note: Divider not implemented in standard emulation image.
	 */
	if (!is_rtc_init_done) {
		qrk_cxxxx_rtc_one_time_setup(rtc_dev);
		is_rtc_init_done = true;
	}
	/* Set RTC divider 1HZ */
	qrk_cxxxx_rtc_clock_frequency(SCSS_RTC_CLK_DIV_1_HZ);
	MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR,
			       QRK_RTC_CCR) |= QRK_RTC_INTERRUPT_MASK;

	if (false != config->alarm_enable) {
		if (config->cb_fn)
			callback_fn = config->cb_fn;
	} else {
		/* set initial RTC value */
		while (config->init_val !=
		       MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR,
					      QRK_RTC_CCVR)) {
			MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR,
					       QRK_RTC_CLR) = config->init_val;
		}
		MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE,
				       SCSS_INT_RTC_MASK_OFFSET) = ~(0);
	}
	pm_wakelock_acquire(&rtc_wakelock);
	timer_start(rtc_wakelock_timer, RTC_WAKELOCK_DELAY, &err);
	if (err != E_OS_OK) {
		pm_wakelock_release(&rtc_wakelock);
		return DEV_USED;
	}
	MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR,
			       QRK_RTC_CCR) &= ~QRK_RTC_INTERRUPT_MASK;
	return DEV_OK;
}
Ejemplo n.º 5
0
static void qrk_cxxxx_rtc_wakelock_timer_callback(void* data)
{
    pm_wakelock_release(&rtc_wakelock);
}