Beispiel #1
0
static int comp_init(struct td_device *dev)
{
	int i;
	struct cmp_cb *cmp_cb_tmp = (struct cmp_cb *)dev->priv;

	for (i = 0; i < CMP_COUNT; i++) {
		cmp_cb_tmp[i].cb = NULL;
		cmp_cb_tmp[i].cb_data = NULL;
	}
	dev->priv = cmp_cb_tmp;
#ifdef CONFIG_QUARK
	MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE,
			       INT_COMPARATORS_HOST_MASK) |=
		INT_COMPARATORS_MASK;
#elif CONFIG_ARC
	MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, INT_COMPARATORS_SS_MASK) |=
		INT_COMPARATORS_MASK;
#endif
	MMIO_REG_VAL(CMP_STAT_CLR) |= INT_COMPARATORS_MASK;
	MMIO_REG_VAL(CMP_EN) &= ~(INT_COMPARATORS_MASK);
	MMIO_REG_VAL(CMP_PWR) &= ~(INT_COMPARATORS_MASK);

	/* enable interrupt trap for comparator driver */
	IRQ_CONNECT(SOC_CMP_INTERRUPT, ISR_DEFAULT_PRIO, comp_isr, NULL, 0);
	irq_enable(SOC_CMP_INTERRUPT);
	return 0;
}
Beispiel #2
0
static void qrk_cxxxx_rtc_clock_frequency(uint32_t frequency)
{
    MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_CCU_SYS_CLK_CTL_OFFSET) &= ~SCSS_CCU_RTC_CLK_DIV_EN;
    MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_CCU_SYS_CLK_CTL_OFFSET) &= ~SCSS_RTC_CLK_DIV_MASK;
    MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_CCU_SYS_CLK_CTL_OFFSET) |= frequency;
    MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_CCU_SYS_CLK_CTL_OFFSET) |= SCSS_CCU_RTC_CLK_DIV_EN;
}
/*! \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;
}
Beispiel #4
0
static void i2s_dma_cb_done(void *num)
{
	uint8_t channel = (uint32_t)num;
 	uint32_t reg;
  
	if(channel == I2S_CHANNEL_TX)
	{
		if((0x00200000 & MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_CTRL))
        	&& !(0x18000000 & MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_CTRL)))
		{	
			for(int i = 0; i < 4; ++i)
				MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_DATA_REG) = 0x0;
		}

		do
		{
			reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].fifo_stat);
		} while(reg & 0x000000FF);
	}
  
	if (i2s_info->cfg[channel].cb_done) 
	{
		i2s_info->cfg[channel].cb_done(i2s_info->cfg[channel].cb_done_arg);
	}
 
	i2s_disable(channel);
 
	return;
}
void qrk_aonpt_start(void)
{
	MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_AONPT_CTRL) =
		(AONPT_CLR | AONPT_RST);
	volatile uint32_t time = get_uptime_32k();
	while(get_uptime_32k() - time < 5);
	MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_AONPT_STAT);
}
void qrk_aonpt_stop(void)
{
	uint32_t flags = interrupt_lock();
	MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_AONPT_CFG) = 0;
	MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_AONPT_CTRL) = (AONPT_CLR | AONPT_RST);
	volatile uint32_t time = get_uptime_32k();
	while(get_uptime_32k() - time < 5);
	interrupt_unlock(flags);
}
void aonpt_ISR(void)
{
	if (!is_oneshot) {
		MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE,SCSS_AONPT_CTRL) = AONPT_CLR;
		MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_AONPT_STAT);
	}

	if (callback_fn != NULL)
		callback_fn();
}
static int qrk_aonpt_resume(struct device *dev)
{
	SET_INTERRUPT_HANDLER(SOC_AONPT_INTERRUPT, aonpt_ISR);
	SOC_UNMASK_INTERRUPTS(SCSS_AON_TIMER_MASK);
	MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_AONPT_STAT);
	return 0;
}
Beispiel #9
0
/* ISR */
static void i2s_isr(void)
{
	uint32_t stat;

	// Determine interrupt source
	stat = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_STAT);

	// Check for errors
	if (stat & (1 << SOC_I2S_STAT_TDATA_UNDERR)) 
	{
		if (i2s_info->cfg[I2S_CHANNEL_TX].cb_err) 
		{
			i2s_info->cfg[I2S_CHANNEL_TX].cb_err_arg=(void *)stat;
			i2s_info->cfg[I2S_CHANNEL_TX].cb_err(i2s_info->cfg[I2S_CHANNEL_TX].cb_err_arg);
		}
		i2s_disable(I2S_CHANNEL_TX);
	}
	if (stat & (1 << SOC_I2S_STAT_RDATA_OVRERR)) 
	{
		if (i2s_info->cfg[I2S_CHANNEL_RX].cb_err) 
		{
			i2s_info->cfg[I2S_CHANNEL_RX].cb_err_arg=(void *)stat;
			i2s_info->cfg[I2S_CHANNEL_RX].cb_err(i2s_info->cfg[I2S_CHANNEL_RX].cb_err_arg);
		}
		i2s_disable(I2S_CHANNEL_RX);
	}

	return;
}
void qrk_aonpt_configure(uint32_t period, void (*on_timeout_cb)(), bool one_shot)
{
	/* stops the previous alarm if any */
	qrk_aonpt_stop();
	callback_fn = on_timeout_cb;
	is_oneshot = one_shot;
	MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_AONPT_CFG) = period;
}
Beispiel #11
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;
}
Beispiel #12
0
/*! \fn     void rtc_isr(void)
 *
 *  \brief   RTC alarm ISR, if specified calls a user defined callback
 */
static void rtc_isr(void *arg)
{
	struct device *dev = arg;

	MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_EOI);

	if (callback_fn)
		(*callback_fn)(dev);
}
Beispiel #13
0
/*! \fn     void rtc_isr(void)
*
*  \brief   RTC alarm ISR, if specified calls a user defined callback
*/
void rtc_isr(void)
{
    MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_EOI);

    if (callback_fn)
    {
        (*callback_fn)(callback_param);
    }
}
void variantPwmInit(void)
{
    /* Enable PWM peripheral clock */
    MMIO_REG_VAL(QRK_CLKGATE_CTRL) |= QRK_CLKGATE_CTRL_PWM_ENABLE;

    /* Select PWM mode, with interrupts masked */
    for (uint8_t i = 0; i < NUM_PWM; i++) {
        uint32_t offset = ((i * QRK_PWM_N_REGS_LEN) + QRK_PWM_N_CONTROL);
        MMIO_REG_VAL_FROM_BASE(QRK_PWM_BASE_ADDR, offset) = QRK_PWM_CONTROL_PWM_OUT | QRK_PWM_CONTROL_INT_MASK | QRK_PWM_CONTROL_MODE_PERIODIC;
    }
}
Beispiel #15
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;
}
Beispiel #16
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;
}
Beispiel #17
0
void set_oscillator(int internal)
{
	if (internal) {
		/* Start internal oscillator (with trim) */
		MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_OSC0_CFG1) |=
			INTERNAL_OSC_TRIM << OSC0_CFG1_INTERNAL_OSC_TRIM_BIT |
			OSC0_CFG1_INTERNAL_OSC_EN_MASK;
		/* Wait internal oscillator ready */
		while (!((MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_OSC0_STAT1) & OSC0_STAT1_LOCK_INTERNAL)))
			;
		/* Trim internal oscillator */
		MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_OSC0_CFG1) =
			INTERNAL_OSC_TRIM << OSC0_CFG1_INTERNAL_OSC_TRIM_BIT |
			OSC0_CFG1_INTERNAL_OSC_EN_MASK;
	} else {
		/* Set clk to 32MHz, external oscillator, 5.5pF load */
		MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_OSC0_CFG1) |=
			OSC0_CFG1_XTAL_OSC_TRIM_5_55_PF |
			OSC0_CFG1_XTAL_OSC_EN_MASK;
		/* Wait internal regulator ready */
		while (!((MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_OSC0_STAT1) & OSC0_STAT1_LOCK_XTAL)))
			;
		/* Switch to external oscillator */
		MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_OSC0_CFG1) =
			OSC0_CFG1_XTAL_OSC_TRIM_5_55_PF |
			(OSC0_CFG1_XTAL_OSC_EN_MASK | OSC0_CFG1_XTAL_OSC_OUT_MASK);
	}
}
Beispiel #18
0
static int qrk_cxxxx_rtc_init(struct device* dev) {
    const uint32_t expected_freq = SCSS_RTC_CLK_DIV_1_HZ | SCSS_CCU_RTC_CLK_DIV_EN;

    qrk_cxxxx_rtc_enable(dev);

    uint32_t curr_freq =
        MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_CCU_SYS_CLK_CTL_OFFSET) &
        (SCSS_CCU_RTC_CLK_DIV_EN | SCSS_RTC_CLK_DIV_MASK);
    pm_wakelock_init(&rtc_wakelock, RTC_WAKELOCK);

    // disable interrupt
    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);

    /* Reset initial value only if RTC wasn't enabled at right frequency at
     * beginning of init
     */
    if (expected_freq != curr_freq) {
        //  Set RTC divider 4096HZ for fast uptade
        qrk_cxxxx_rtc_clock_frequency(SCSS_RTC_CLK_DIV_4096_HZ);

        /* set intial RTC value 0 */
        MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CLR) = 0;
        while (0 != MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CCVR)) {
            MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CLR) = 0;
        }
    }
    //  Set RTC divider 1HZ
    qrk_cxxxx_rtc_clock_frequency(SCSS_RTC_CLK_DIV_1_HZ);
    return 0;
}
Beispiel #19
0
DRIVER_API_RC comp_configure(struct td_device *dev, int index, int polarity,
			     int refsel, void (*cb)(void *), void *param)
{
	struct cmp_cb *cmp_cb_tmp = (struct cmp_cb *)dev->priv;

	if (index >= CMP_COUNT || index < 0) {
		return DRV_RC_INVALID_CONFIG;
	}
	cmp_cb_tmp[index].cb = cb;
	cmp_cb_tmp[index].cb_data = param;

	// Enable comparator <index>
	MMIO_REG_VAL(CMP_PWR) |= (1 << index);

	if (polarity)
		MMIO_REG_VAL(CMP_REF_POL) |= (1 << index);
	else
		MMIO_REG_VAL(CMP_REF_POL) &= ~(1 << index);
	if (refsel)
		MMIO_REG_VAL(CMP_REF_SEL) |= (1 << index);
	else
		MMIO_REG_VAL(CMP_REF_SEL) &= ~(1 << index);

	// Enable power in comparator <index>
	MMIO_REG_VAL(CMP_EN) |= (1 << index);

	/* Enable interrupt to host. */
#ifdef CONFIG_QUARK
	MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE,
			       INT_COMPARATORS_HOST_MASK) &=
		~(1 << index);
#elif CONFIG_ARC
	MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, INT_COMPARATORS_SS_MASK) &=
		~(1 << index);
#else
#error Unknown target for comparator driver
#endif
	return DRV_RC_OK;
}
Beispiel #20
0
/* Driver API */
DRIVER_API_RC soc_i2s_init()
{
	int i;
	uint32_t reg;

	// Prep info struct
	for (i = 0; i < I2S_NUM_CHANNELS; i++) 
	{
		i2s_info->en[i] = 0;
		i2s_info->cfgd[i] = 0;
		i2s_info->cfg[i].cb_done = NULL;
		i2s_info->cfg[i].cb_err = NULL;
	}

	// Enable global clock, use local clock gating per channel instead
	set_clock_gate(i2s_info->clk_gate_info, CLK_GATE_ON);

	// Setup ISR (and enable)
	SET_INTERRUPT_HANDLER(i2s_info->int_vector, i2s_interrupt_handler);
	SOC_UNMASK_INTERRUPTS(i2s_info->int_mask);

	// Set up control register
	reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_CTRL);
	reg |= (1 << SOC_I2S_CTRL_TR_CFG_0);
 	reg &= ~(1 << SOC_I2S_CTRL_TSYNC_LOOP_BACK);
	reg &= ~(1 << SOC_I2S_CTRL_RSYNC_LOOP_BACK);
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_CTRL) = reg;

	// Set the watermark levels
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_TFIFO_CTRL) &= 0xFFFCFFFF;
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_TFIFO_CTRL) |= (I2S_TFIFO_THR << SOC_I2S_TFIFO_CTRL_TAFULL_THRS);

	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_RFIFO_CTRL) &= 0xFFFCFFFF;
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_RFIFO_CTRL) |= (I2S_RFIFO_THR << SOC_I2S_RFIFO_CTRL_RAFULL_THRS);

	// Enable global interrupt mask
	reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_CID_CTRL);
	reg |= (1 << SOC_I2S_CID_CTRL_INTREQ_MASK);
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, SOC_I2S_CID_CTRL) = reg;

	// Initially, have all channels disabled
	for (i = 0; i < I2S_NUM_CHANNELS; i++) 
	{
		i2s_disable(i);
	}

	return DRV_RC_OK;
}
Beispiel #21
0
/* Internal functions */
static void i2s_enable(uint8_t channel)
{
	uint32_t reg;

	// Enable local clock and interrupts
	reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].cid_ctrl);
	reg &= ~(1 << (i2s_reg_map[channel].cid_ctrl_strobe));
	reg &= ~(1 << (i2s_reg_map[channel].cid_ctrl_strobe_sync));
	reg |= (1 << (i2s_reg_map[channel].cid_ctrl_mask));
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].cid_ctrl) = reg;

	// Clear all interrupts
	reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].stat);
	reg &= ~(i2s_reg_map[channel].stat_mask);
	reg |= (1 << SOC_I2S_STAT_TDATA_UNDERR);
	reg |= (1 << SOC_I2S_STAT_RDATA_OVRERR);
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].stat) = reg;

	// Set enabled flag for channel
	i2s_info->en[channel] = 1;

	return;
}
Beispiel #22
0
static void i2s_disable(uint8_t channel)
{
	uint32_t reg;
	uint32_t num_active;
	int i;

	// Release DMA resources
	if (i2s_info->en[channel]) 
	{
		soc_dma_stop_transfer(&(i2s_info->dma_ch[channel]));
		soc_dma_release(&(i2s_info->dma_ch[channel]));
		soc_dma_free_list(&(i2s_info->dma_cfg[channel]));
	}
 	// Clear enabled flag for channel
	i2s_info->en[channel] = 0;

	// Let the processor do whatever power down it wants
	num_active = 0;
	for (i = 0; i < I2S_NUM_CHANNELS; i++) 
	{
		if (i2s_info->en[i]) 
		{
			num_active++;
		}
	}
 
	// Disable channel and hold parts in reset
	reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].ctrl);
	reg &= ~(1 << (i2s_reg_map[channel].ctrl_fifo_rst));
	reg &= ~(1 << (i2s_reg_map[channel].ctrl_sync_rst));
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].ctrl) = reg;

	// Clear all interrupts
	reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].stat);
	reg &= ~(i2s_reg_map[channel].stat_mask);
	reg &= ~(1 << i2s_reg_map[channel].stat_err);
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].stat) = reg;

	// Disable local clock and interrupts
	reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].cid_ctrl);
	reg |= (1 << (i2s_reg_map[channel].cid_ctrl_strobe));
	reg |= (1 << (i2s_reg_map[channel].cid_ctrl_strobe_sync));
	reg &= ~(1 << (i2s_reg_map[channel].cid_ctrl_mask));
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].cid_ctrl) = reg;

	return;

}
Beispiel #23
0
static void i2s_dma_cb_done(void *num)
{
	uint8_t channel = (uint32_t)num;
 	uint32_t reg;
  
	if(channel == I2S_CHANNEL_TX)
	{
		do
		{
			reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].fifo_stat);
		} while(reg & 0x000000FF); 
	}
	
	if (i2s_info->cfg[channel].cb_done) 
	{
		i2s_info->cfg[channel].cb_done(i2s_info->cfg[channel].cb_done_arg);
	}
 
	i2s_disable(channel);
 
	return;
}
Beispiel #24
0
static void qrk_cxxxx_rtc_one_time_setup(struct device *rtc_dev)
{
	OS_ERR_TYPE err;
	const uint32_t expected_freq = SCSS_RTC_CLK_DIV_1_HZ |
				       SCSS_CCU_RTC_CLK_DIV_EN;

	qrk_cxxxx_rtc_enable(rtc_dev);
	rtc_wakelock_timer = timer_create(qrk_cxxxx_rtc_wakelock_timer_callback,
					  NULL,
					  RTC_WAKELOCK_DELAY,
					  false,
					  false,
					  &err);
	if (E_OS_OK != err)
		pr_error(LOG_MODULE_DRV, "rtc_wakelock_timer err");

	uint32_t curr_freq =
		MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE,
				       SCSS_CCU_SYS_CLK_CTL_OFFSET) &
		(SCSS_CCU_RTC_CLK_DIV_EN | SCSS_RTC_CLK_DIV_MASK);
	pm_wakelock_init(&rtc_wakelock);

	/* disable interrupt */
	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);

	/* Reset initial value only if RTC wasn't enabled at right frequency at
	 * beginning of init
	 */
	if (expected_freq != curr_freq) {
		/* Set RTC divider 4096HZ for fast update */
		qrk_cxxxx_rtc_clock_frequency(SCSS_RTC_CLK_DIV_4096_HZ);

		/* set intial RTC value 0 */
		MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CLR) = 0;
		while (0 !=
		       MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR,
					      QRK_RTC_CCVR)) {
			MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR,
					       QRK_RTC_CLR) = 0;
		}
	}
}
Beispiel #25
0
/* External API */
DRIVER_API_RC soc_i2s_config(uint8_t channel, struct soc_i2s_cfg *cfg)
{
	uint32_t reg;
	uint16_t sample_rate;

	// Check channel no in use
	if (channel >= I2S_NUM_CHANNELS) 
	{
		return DRV_RC_FAIL;
	} 
	else if (i2s_info->en[channel]) 
	{
		return DRV_RC_CONTROLLER_IN_USE;
	}

	// Set master/slave
	reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].ctrl);
	reg &= ~(1 << (i2s_reg_map[channel].ctrl_ms));
	reg |= (cfg->master & 0x1) << i2s_reg_map[channel].ctrl_ms;
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].ctrl) = reg;

	// Calculate sample_rate divider (note, acts as if resolution is always 32)
	sample_rate = i2s_info->clk_speed / (cfg->sample_rate * cfg->resolution * 2);

	// Setup resolution and sampling rate
	reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].srr);
	reg &= ~(i2s_reg_map[channel].srr_mask);
	reg |= (sample_rate & 0x7FF) << i2s_reg_map[channel].srr_sample_rate;
	reg |= ((cfg->resolution - 1) & 0x1F) << i2s_reg_map[channel].srr_resolution;
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].srr) = reg;

	// Setup mode
	reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].dev_conf);
	reg &= ~(i2s_reg_map[channel].dev_conf_mask);
	// Use sck_polar as shift amount as its the LSb of the DEV_CONF settings
	reg |= ((cfg->mode & 0x3F) << i2s_reg_map[channel].dev_conf_sck_polar);
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].dev_conf) = reg;

	// Complete configuration (and set flag)
	i2s_info->cfg[channel] = *cfg;
	i2s_info->cfgd[channel] = 1;

	return DRV_RC_OK;
}
uint32_t qrk_aonpt_read(void)
{
	return MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, SCSS_AONPT_CNT);
}
Beispiel #27
0
/*! \fn     uint32_t qrk_cxxxx_rtc_read(void)
*
*  \brief   Function to read the RTC
*
*  \return  uint32_t - epoch time
*/
uint32_t qrk_cxxxx_rtc_read(void)
{
    return MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CCVR);
}
Beispiel #28
0
DRIVER_API_RC soc_i2s_stream(uint32_t *buf, uint32_t len, uint32_t num_bufs)
{
	DRIVER_API_RC ret;
	uint8_t channel = I2S_CHANNEL_TX;
	uint32_t reg;
	uint32_t len_per_buf;
	int i;
	struct soc_dma_xfer_item *dma_list;

	// Check channel no in use and configured
	if (channel >= I2S_NUM_CHANNELS) 
	{
		return DRV_RC_FAIL;
	} 
	else if (i2s_info->en[channel] || !(i2s_info->cfgd[channel])) 
	{
		return DRV_RC_FAIL;
	}

	// Get a DMA channel
	ret = soc_dma_acquire(&(i2s_info->dma_ch[channel]));

	if (ret != DRV_RC_OK) 
	{
		return DRV_RC_FAIL;
	}

	// Enable the channel
	i2s_enable(channel);

	// Determine the length of a single buffer
	if (num_bufs == 0) 
	{
		len_per_buf = len;
	} 
	else 
	{
		len_per_buf = len / num_bufs;
	}

	// Prep some configuration
	i2s_info->dma_cfg[channel].type = SOC_DMA_TYPE_MEM2PER;
	i2s_info->dma_cfg[channel].dest_interface = SOC_DMA_INTERFACE_I2S_TX;
	i2s_info->dma_cfg[channel].dest_step_count = 0;
	i2s_info->dma_cfg[channel].src_step_count = 0;

	i2s_info->dma_cfg[channel].xfer.dest.delta = SOC_DMA_DELTA_NONE;
	i2s_info->dma_cfg[channel].xfer.dest.width = SOC_DMA_WIDTH_32;
	i2s_info->dma_cfg[channel].xfer.dest.addr = (void *)(SOC_I2S_BASE + SOC_I2S_DATA_REG);
	i2s_info->dma_cfg[channel].xfer.src.delta = SOC_DMA_DELTA_INCR;
	i2s_info->dma_cfg[channel].xfer.src.width = SOC_DMA_WIDTH_32;

	if (num_bufs == 0) 
	{
		i2s_info->dma_cfg[channel].cb_done = i2s_dma_cb_done;
		i2s_info->dma_cfg[channel].cb_done_arg = (void *)((uint32_t)channel);
	} 
	else 
	{
		i2s_info->dma_cfg[channel].cb_block = i2s_dma_cb_block;
		i2s_info->dma_cfg[channel].cb_block_arg = (void *)((uint32_t)channel);
	}

	i2s_info->dma_cfg[channel].cb_err = i2s_dma_cb_err;
	i2s_info->dma_cfg[channel].cb_err_arg = (void *)((uint32_t)channel);

	// Setup the linked list
	for (i = 0; i < ((num_bufs == 0) ? 1 : num_bufs); i++) 
	{
		if (i == 0) 
		{
			dma_list = &(i2s_info->dma_cfg[channel].xfer);
		} 
		else 
		{
			ret = soc_dma_alloc_list_item(&dma_list, dma_list);

			if (ret != DRV_RC_OK) 
			{
				goto fail;
			}
		}

		dma_list->src.addr = (void *)(&(buf[i * (len_per_buf / sizeof(uint32_t))]));
		dma_list->size = len_per_buf / sizeof(uint32_t);
	}

	// Create a circular list if we are doing circular buffering
	if (num_bufs != 0) 
	{
		dma_list->next = &(i2s_info->dma_cfg[channel].xfer);
	}

	// Setup and start the DMA engine
	ret = soc_dma_config(&(i2s_info->dma_ch[channel]), &(i2s_info->dma_cfg[channel]));

	if (ret != DRV_RC_OK) 
	{
		goto fail;
	}

	ret = soc_dma_start_transfer(&(i2s_info->dma_ch[channel]));

	if (ret != DRV_RC_OK) 
	{
		goto fail;
	}

	// Enable the channel and let it go!
	reg = MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].ctrl);
	reg |= (1 << (i2s_reg_map[channel].ctrl_en));
	reg |= (1 << (i2s_reg_map[channel].ctrl_sync_rst));
	MMIO_REG_VAL_FROM_BASE(SOC_I2S_BASE, i2s_reg_map[channel].ctrl) = reg;

	return DRV_RC_OK;

fail:
	i2s_disable(channel);
	soc_dma_release(&(i2s_info->dma_ch[channel]));
	return DRV_RC_FAIL;
}
Beispiel #29
0
/*! \fn     void qrk_cxxxx_rtc_clk_disable(void)
*
*  \brief   Function to disable RTC clock
*/
void qrk_cxxxx_rtc_clk_disable(void)
{
    MMIO_REG_VAL_FROM_BASE(QRK_RTC_BASE_ADDR, QRK_RTC_CCR) &= ~QRK_RTC_ENABLE;
}
void run_arc_driver_tests(void)
{
    // Disable all interrupts on QRK core
    MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, INT_SPI_MST_0_MASK) |= ~(QRK_INT_UNMASK_IA);
    MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, INT_SPI_MST_1_MASK) |= ~(QRK_INT_UNMASK_IA);
    MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, INT_I2C_MST_0_MASK) |= ~(QRK_INT_UNMASK_IA);
    MMIO_REG_VAL_FROM_BASE(SCSS_REGISTER_BASE, INT_I2C_MST_1_MASK) |= ~(QRK_INT_UNMASK_IA);

    cu_set_log_backend(&log_backend_os_printk);

#if defined (CONFIG_SS_ADC)
    CU_RUN_TEST(adc_test);
#endif

    CU_RUN_TEST(cbuffer_tst);

    /* TODO: drop when KConfig implemented*/
#if defined (CONFIG_BOARD_CURIE_APP) && defined (CONFIG_SBA) && defined (CONFIG_INTEL_QRK_SPI)
    CU_RUN_TEST(sba_spi_test);          //ARC SBA SOC SPI test
#endif

#if defined (CONFIG_BOARD_CURIE_APP) && defined (CONFIG_SBA) && defined (CONFIG_SPI)
    CU_RUN_TEST(sba_ss_unit_spi);       //ARC SBA SS SPI test
#endif

#if defined (CONFIG_BOARD_CURIE_APP) && defined (CONFIG_SBA) && defined (CONFIG_INTEL_QRK_I2C)
    CU_RUN_TEST(sba_i2c_test);          //ARC SBA SOC I2C test
#endif

#if defined (CONFIG_BOARD_CURIE_APP) && defined (CONFIG_SBA) && defined (CONFIG_I2C)
    CU_RUN_TEST(sba_ss_unit_i2c);
#endif

#if defined (CONFIG_GPIO_DRIVER_TESTS)
#if defined (CONFIG_SOC_GPIO_32)
    CU_RUN_TEST(gpio_test);
#endif

#if defined (CONFIG_SOC_GPIO_AON)
    CU_RUN_TEST(gpio_aon_test);
#endif

#if defined (CONFIG_SS_GPIO)
    CU_RUN_TEST(gpio_ss_test);
#endif
#endif

#ifdef CONFIG_SOC_COMPARATOR
    CU_RUN_TEST(comparator_test);
#endif

    CU_RUN_TEST(wakelock_test);

#if defined (CONFIG_BMI160)
    CU_RUN_TEST(bmi160_unit_test);
#endif

#if defined (CONFIG_BME280)
    CU_RUN_TEST(bme280_unit_test);
#endif

}