Example #1
0
static int sprd_rtc_set_aux_alarm_sec(unsigned long secs)
{
	unsigned sec, min, hour, day;
	unsigned long temp;

	sec = secs % 60;
	temp = (secs - sec)/60;
	min = temp%60;
	temp = (temp - min)/60;
	hour = temp%24;
	temp = (temp - hour)/24;
	day = temp;

	sci_adi_set(ANA_RTC_INT_CLR, RTC_AUXALM_BIT);

	sci_adi_raw_write(ANA_RTC_AUX_SEC_ALM, sec);

	sci_adi_raw_write(ANA_RTC_AUX_MIN_ALM, min);

	sci_adi_raw_write(ANA_RTC_AUX_HOUR_ALM, hour);

	sci_adi_raw_write(ANA_RTC_AUX_DAY_ALM, day);

	return 0;
}
Example #2
0
static int sprd_rtc_set_alarm(struct device *dev,
		struct rtc_wkalrm *alrm)
{
	unsigned long secs;
	unsigned temp;

	sci_adi_raw_write(ANA_RTC_INT_CLR, RTC_ALARM_BIT);

	if(alrm->enabled){
		rtc_tm_to_time(&alrm->time, &secs);
		if(secs < secs_start_year_to_1970)
			return -1;

		
		temp = sci_adi_read(ANA_RTC_INT_EN);
		temp |= RTC_ALARM_BIT;
		sci_adi_raw_write(ANA_RTC_INT_EN, temp);

		secs = secs - secs_start_year_to_1970;
		wake_lock(&rtc_wake_lock);

		sprd_rtc_set_alarm_sec(secs);

		
		sci_adi_raw_write(ANA_RTC_SPG_UPD, SPRD_RTC_UNLOCK);
		wake_unlock(&rtc_wake_lock);
	}else{
		sci_adi_clr(ANA_RTC_INT_EN, RTC_ALARM_BIT);
		sci_adi_raw_write(ANA_RTC_SPG_UPD, SPRD_RTC_LOCK);
		msleep(150);
	}

	return 0;
}
Example #3
0
static u32 adie_efuse_read(int blk_index)
{
    u32 val = 0;

    pr_debug("adie efuse read %d\n", blk_index);
    adie_efuse_lock();
    __adie_efuse_power_on();
    /* enable adie_efuse module clk and power before */

    /* FIXME: set read timing, why 0x20 (default value)
       sci_adi_raw_write(ANA_REG_EFUSE_RD_TIMING_CTRL,
       BITS_EFUSE_RD_TIMING(0x20));
     */

    sci_adi_raw_write(ANA_REG_EFUSE_BLOCK_INDEX,
                      BITS_READ_WRITE_INDEX(blk_index));
    sci_adi_raw_write(ANA_REG_EFUSE_MODE_CTRL, BIT_RD_START);

    if (IS_ERR_VALUE(__adie_efuse_wait_clear(BIT_READ_BUSY)))
        goto out;

    val = sci_adi_read(ANA_REG_EFUSE_DATA_RD);

    /* FIXME: reverse the otp value */
    val = BITS_EFUSE_DATA_RD(~val);

out:
    __adie_efuse_power_off();
    adie_efuse_unlock();
    return val;
}
Example #4
0
/* use ana watchdog to wake up */
void pm_debug_set_apwdt(void)
{
	uint32_t cnt = 0;
	uint32_t ms = 5000;
	cnt = (ms * WDG_CLK) / 1000;

	sci_glb_set(INT_IRQ_ENB, BIT(11));
	/*enable interface clk*/
	sci_adi_set(ANA_AGEN, AGEN_WDG_EN);
	/*enable work clk*/
	sci_adi_set(ANA_RTC_CLK_EN, AGEN_RTC_WDG_EN);
	sci_adi_raw_write(WDG_LOCK, WDG_UNLOCK_KEY);
	sci_adi_set(WDG_CTRL, WDG_NEW_VER_EN);
	WDG_LOAD_TIMER_VALUE(0x80000);
	WDG_LOAD_TIMER_INT_VALUE(0x40000);
	sci_adi_set(WDG_CTRL, WDG_CNT_EN_BIT | WDG_INT_EN_BIT| WDG_RST_EN_BIT);
	sci_adi_raw_write(WDG_LOCK, (uint16_t) (~WDG_UNLOCK_KEY));
	sci_adi_set(ANA_REG_INT_EN, BIT(3));
#if 0
	do{
		udelay(1000);
		printk("INTC1 mask:0x%08x raw:0x%08x en:0x%08x\n", __raw_readl(INTCV1_IRQ_MSKSTS),__raw_readl(INTCV1_IRQ_RAW), __raw_readl(INTCV1_IRQ_EN));
		printk("INT mask:0x%08x raw:0x%08x en:0x%08x ana 0x%08x\n", __raw_readl(INT_IRQ_STS),__raw_readl(INT_IRQ_RAW), __raw_readl(INT_IRQ_ENB), sci_adi_read(ANA_REG_INT_MASK_STATUS));
		printk("ANA mask:0x%08x raw:0x%08x en:0x%08x\n", sci_adi_read(ANA_REG_INT_MASK_STATUS), sci_adi_read(ANA_REG_INT_RAW_STATUS), sci_adi_read(ANA_REG_INT_EN));
		printk("wdg cnt low 0x%08x high 0x%08x\n", sci_adi_read(WDG_CNT_LOW), sci_adi_read(WDG_CNT_HIGH));
	}while(0);
#endif
}
static int sprd_rtc_set_sec(unsigned long secs)
{
	unsigned sec, min, hour, day;
	unsigned set_mask = 0, int_rsts;
	unsigned long temp;
	int i = 0;

	sec = secs % 60;
	temp = (secs - sec)/60;
	min = temp%60;
	temp = (temp - min)/60;
	hour = temp%24;
	temp = (temp - hour)/24;
	day = temp;


	sci_adi_set(ANA_RTC_INT_CLR, RTC_UPD_TIME_MASK);

	if(sec != get_sec()){
		sci_adi_raw_write(ANA_RTC_SEC_UPDATE, sec);
		set_mask |= RTC_SEC_ACK_BIT;
	}
	if(min != get_min()){
		sci_adi_raw_write(ANA_RTC_MIN_UPDATE, min);
		set_mask |= RTC_MIN_ACK_BIT;
	}
	if(hour != get_hour()){
		sci_adi_raw_write(ANA_RTC_HOUR_UPDATE, hour);
		set_mask |= RTC_HOUR_ACK_BIT;
	}
	if(day != get_day()){
		sci_adi_raw_write(ANA_RTC_DAY_UPDATE, day);
		set_mask |= RTC_DAY_ACK_BIT;
	}

	/*
	 * wait till all update done
	 */

	do{
		int_rsts = sci_adi_read(ANA_RTC_INT_RSTS) & RTC_UPD_TIME_MASK;

		if(set_mask == int_rsts)
			break;

		if(i < SPRD_RTC_SET_MAX){
			msleep(1);
			i++;
		}else{
			return 1;
		}
	}while(1);
	sci_adi_set(ANA_RTC_INT_CLR, RTC_UPD_TIME_MASK);

	return 0;
}
static void sc8825_power_off(void)
{

	/*ture off all modules ldo*/
	sci_adi_raw_write(ANA_REG_GLB_LDO_PD_CTRL1,   0x5555);
	sci_adi_raw_write(ANA_REG_GLB_LDO_PD_CTRL0,   0x5555);

	/*ture off all system cores ldo*/
	sci_adi_clr(ANA_REG_GLB_LDO_PD_RST, 0x3ff);
	sci_adi_set(ANA_REG_GLB_LDO_PD_SET, 0x3ff);
}
static int sprd_rtc_set_alarm_sec(unsigned long secs)
{
	unsigned sec, min, hour, day;
	unsigned long temp;
	unsigned set_mask = 0, int_rsts;
	int i = 0;

	sec = secs % 60;
	temp = (secs - sec)/60;
	min = temp%60;
	temp = (temp - min)/60;
	hour = temp%24;
	temp = (temp - hour)/24;
	day = temp;

	sci_adi_set(ANA_RTC_INT_CLR, RTC_ALM_TIME_MASK);


	sci_adi_raw_write(ANA_RTC_SEC_ALM, sec);
	set_mask |= RTC_SEC_ALM_ACK_BIT;

	sci_adi_raw_write(ANA_RTC_MIN_ALM, min);
	set_mask |= RTC_MIN_ALM_ACK_BIT;

	sci_adi_raw_write(ANA_RTC_HOUR_ALM, hour);
	set_mask |= RTC_HOUR_ALM_ACK_BIT;

	sci_adi_raw_write(ANA_RTC_DAY_ALM, day);

	set_mask |= RTC_DAY_ALM_ACK_BIT;

	/*
	 * wait till all update done
	 */

	do{
		int_rsts = sci_adi_read(ANA_RTC_INT_RSTS) & RTC_ALM_TIME_MASK;

		if(set_mask == int_rsts)
			break;

		if(i < SPRD_RTC_SET_MAX){
			msleep(1);
			i++;
		}else{
			return 1;
		}
	}while(1);
	sci_adi_set(ANA_RTC_INT_CLR, RTC_ALM_TIME_MASK);
	#if defined(CONFIG_RTC_CHN_ALARM_BOOT)
		sprd_rtc_set_bit_spg_counter(SPG_CNT_ALARM_BOOT, 0);
	#endif
	return 0;
}
static int sprd_rtc_open(struct device *dev)
{
	int temp = 0;
	/* enable rtc interrupt */
	temp = sci_adi_read(ANA_RTC_INT_EN);
	temp |= RTC_ALARM_BIT;
	sci_adi_raw_write(ANA_RTC_INT_EN, temp);

	//add by wbl
	sci_adi_raw_write(ANA_RTC_SPG_UPD, SPRD_RTC_UNLOCK);
	printk(KERN_EMERG "sprd_rtc_open is calling!\n");
	return 0;
}
void sprd_rtc_set_spg_counter(u16 value)
{
	u16 spg_cnt = 0;
	u32 int_sts = 0;
	int timeout = SPRD_RTC_SET_MAX;

	spg_cnt = sci_adi_read(ANA_RTC_SPG_CNT)&RTC_SPG_CNT_MASK;
	if (spg_cnt == value)
		return;

	sci_adi_set(ANA_RTC_INT_CLR, RTC_SPG_CNT_ACK_BIT);
	sci_adi_raw_write(ANA_RTC_SPG_CNT_UPD, (value&RTC_SPG_CNT_MASK));

	for(;;) {
		if (timeout && int_sts != RTC_SPG_CNT_ACK_BIT) {
			int_sts = sci_adi_read(ANA_RTC_INT_RSTS)&RTC_SPG_CNT_ACK_BIT;
			msleep(1);
			timeout--;
		}
		else
			break;
	}

	sci_adi_set(ANA_RTC_INT_CLR, RTC_SPG_CNT_ACK_BIT);
}
static int sprd_rtc_set_alarm(struct device *dev,
		struct rtc_wkalrm *alrm)
{
	unsigned long secs;
	unsigned temp;
	unsigned long read_secs;
	int i = 0,n;

	rtc_tm_to_time(&alrm->time, &secs);

	sci_adi_raw_write(ANA_RTC_INT_CLR, RTC_ALARM_BIT);

//	printk("sprd_rtc_set_alarm enable : %d,  : %lu, secs : %lu\n", alrm->enabled, secs_start_year_to_1970, secs);
//	printk("sprd_rtc_set_alarm - day [%d] hour [%d] min [%d] sec [%d]\n", alrm->time.tm_mday, alrm->time.tm_hour, alrm->time.tm_min, alrm->time.tm_sec);
	
	if(alrm->enabled){
		if(secs < secs_start_year_to_1970)
			return -1;
		temp = sci_adi_read(ANA_RTC_INT_EN);
		temp |= RTC_ALARM_BIT;
		sci_adi_raw_write(ANA_RTC_INT_EN, temp);

		secs = secs - secs_start_year_to_1970;
		wake_lock(&rtc_wake_lock);
		n = 2;
		while(sprd_rtc_set_alarm_sec(secs)!=0&&(n--)>0);
		do {
			if(i!=0){
				n = 2;
				while(sprd_rtc_set_alarm_sec(secs)!=0&&(n--)>0);
			}
			read_secs = sprd_rtc_get_alarm_sec();
			msleep(1);
			i++;
		}while(read_secs != secs && i < SPRD_RTC_SET_MAX);
		//sci_adi_raw_write(ANA_RTC_SPG_UPD, SPRD_RTC_UNLOCK);
		wake_unlock(&rtc_wake_lock);
	}else{
		sci_adi_clr(ANA_RTC_INT_EN, RTC_ALARM_BIT);
		//sci_adi_raw_write(ANA_RTC_SPG_UPD, SPRD_RTC_LOCK);
		msleep(150);
	}

	return 0;
}
static int sprd_rtc_open(struct device *dev)
{
	int temp = 0;
	/* enable rtc interrupt */
	temp = sci_adi_read(ANA_RTC_INT_EN);
	temp |= RTC_ALARM_BIT;
	sci_adi_raw_write(ANA_RTC_INT_EN, temp);
	return 0;
}
Example #12
0
static int sprd_rtc_set_alarm_sec(unsigned long secs)
{
	unsigned sec, min, hour, day;
	unsigned long temp;
	u32 timeout = 0;
	static bool rtc_alarm_in_update = false;

	sec = secs % 60;
	temp = (secs - sec)/60;
	min = temp%60;
	temp = (temp - min)/60;
	hour = temp%24;
	temp = (temp - hour)/24;
	day = temp;

	if (rtc_alarm_in_update) {
		while ((sci_adi_read(ANA_RTC_INT_RSTS) & RTC_ALM_TIME_MASK) !=
			RTC_ALM_TIME_MASK)
		{
			msleep(10);
			if (timeout++ > SPRD_RTC_SET_MAX) {
				printk("rtc set alarm timeout!\n");
				
				break;
			}
		}
	}

	printk("++++++rtc set alarm and delay is %d !++++++\n", timeout * 10);

	sci_adi_set(ANA_RTC_INT_CLR, RTC_ALM_TIME_MASK);

	sci_adi_raw_write(ANA_RTC_SEC_ALM, sec);

	sci_adi_raw_write(ANA_RTC_MIN_ALM, min);

	sci_adi_raw_write(ANA_RTC_HOUR_ALM, hour);

	sci_adi_raw_write(ANA_RTC_DAY_ALM, day);

	rtc_alarm_in_update = true;

	return 0;
}
static int sci_open(struct inode *inode, struct file *file)
{
	if (test_and_set_bit(1, &wdt_users))
		return -EBUSY;

	/* started the watchdog when it's openned for the 1st time */
	if (wdt_state == 0) {
		/* start the watchdog */
		sci_adi_set(ANA_AGEN, AGEN_WDG_EN | AGEN_RTC_ARCH_EN | AGEN_RTC_WDG_EN);
		sci_adi_raw_write (WDG_LOCK, WDG_UNLOCK_KEY);
		sci_adi_clr (WDG_CTRL, WDG_INT_EN_BIT);
		WDG_LOAD_TIMER_VALUE(margin * WDT_FREQ);
#ifdef CONFIG_ARCH_SC8825
		sci_adi_set(WDG_CTRL, WDG_CNT_EN_BIT | WDG_RST_EN_BIT);
#else
		sci_adi_set(WDG_CTRL, WDG_CNT_EN_BIT);
#endif
		mod_timer(&feeder_timer, jiffies + (feed_period * HZ));
		wdt_state = 1;
	}

	return nonseekable_open(inode, file);
}
static void a_write_reg(uint32_t value, uint32_t addr)
{
	sci_adi_raw_write(addr, value);
}
int dcdc_calibrate(int adc_chan, int def_vol, int to_vol)
{
	int i;
	u32 val[MEASURE_TIMES], sum = 0, adc_vol, ctl_vol, cal_vol;
	for (i = 0; i < ARRAY_SIZE(val); i++) {
		sum += val[i] = sci_adc_get_value(adc_chan, true);
	}
	sum /= ARRAY_SIZE(val);	/* get average value */
	info("adc chan %d, value %d\n", adc_chan, sum);
	adc_vol = sprd_get_adc_to_vol(sum) * (8 * 5) / (30 * 4);
	if (!def_vol) {
		switch (adc_chan) {
		case ADC_CHANNEL_DCDC:
			def_vol = 1100;
			cal_vol = sci_adi_read(ANA_DCDC_CTRL_CAL) & 0x1f;
			i = sci_adi_read(ANA_DCDC_CTRL) & 0x07;
			break;
		case ADC_CHANNEL_DCDCARM:
			def_vol = 1200;
			cal_vol = sci_adi_read(ANA_DCDCARM_CTRL_CAL) & 0x1f;
			i = sci_adi_read(ANA_DCDCARM_CTRL) & 0x07;
			break;
		default:
			goto exit;
		}
		if (0 != i /* + cal_vol */ )
			def_vol = dcdc_ctl_vol[i];
		def_vol += cal_vol * 100 / 32;
#if 0
		if (0 != i + cal_vol) {	/* dcdc had been adjusted in uboot-spl */
			debug("%s default %dmv, from %dmv to %dmv\n",
			     __FUNCTION__, def_vol, adc_vol, to_vol);
			goto exit;
		}
#endif
	}
	info("%s default %dmv, from %dmv to %dmv\n", __FUNCTION__, def_vol,
	     adc_vol, to_vol);

	cal_vol = abs(adc_vol - to_vol);
	if (cal_vol > 200 /* mv */ )
		goto exit;
	else if (cal_vol < to_vol / 100) {
		info("%s is ok\n", __FUNCTION__);
		return 0;
	}

	ctl_vol = def_vol * to_vol / adc_vol;
	for (i = 0; i < ARRAY_SIZE(dcdc_ctl_vol) - 1; i++) {
		if (ctl_vol < dcdc_ctl_vol[i + 1])
			break;
	}
	if (i >= ARRAY_SIZE(dcdc_ctl_vol) - 1)
		goto exit;

	cal_vol = ((ctl_vol - dcdc_ctl_vol[i]) * 32 / 100) % 32;
	debug("%s cal_vol %dmv: %d, 0x%02x\n", __FUNCTION__,
	      dcdc_ctl_vol[i] + cal_vol * 100 / 32, i, cal_vol);
	switch (adc_chan) {
	case ADC_CHANNEL_DCDC:
		sci_adi_raw_write(ANA_DCDC_CTRL_CAL,
				  cal_vol | (0x1f - cal_vol) << 8);
		sci_adi_raw_write(ANA_DCDC_CTRL, i | (0x07 - i) << 4);
		break;
	case ADC_CHANNEL_DCDCARM:
		sci_adi_raw_write(ANA_DCDCARM_CTRL_CAL,
				  cal_vol | (0x1f - cal_vol) << 8);
		sci_adi_raw_write(ANA_DCDCARM_CTRL, i | (0x07 - i) << 4);
		break;
	default:
		break;
	}

	return dcdc_ctl_vol[i] + cal_vol * 100 / 32;
      exit:
	info("%s failure\n", __FUNCTION__);
	return -1;
}
static int sprd_rtc_probe(struct platform_device *plat_dev)
{
	int err = -ENODEV;
	struct resource *irq;

	rtc_data = kzalloc(sizeof(*rtc_data), GFP_KERNEL);
	if(IS_ERR(rtc_data)){
		err = PTR_ERR(rtc_data);
		return err;
	};

	/*ensure the rtc interrupt don't be send to Adie when there's no
	  *rtc alarm int occur.
	  */
	sci_adi_raw_write(ANA_RTC_SPG_UPD, SPRD_RTC_LOCK);
	/* disable all interrupt */
	sci_adi_clr(ANA_RTC_INT_EN, RTC_INT_ALL_MSK);
	/* enable rtc device */
	rtc_data->clk = clk_get(&plat_dev->dev, "ext_32k");
	if (IS_ERR(rtc_data->clk)) {
		err = PTR_ERR(rtc_data->clk);
		goto kfree_data;
	}

	err = clk_enable(rtc_data->clk);
	if (err < 0)
		goto put_clk;

	CLEAR_RTC_INT(RTC_INT_ALL_MSK);
	rtc_data->rtc = rtc_device_register("sprd_rtc", &plat_dev->dev,
			&sprd_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc_data->rtc)) {
		err = PTR_ERR(rtc_data->rtc);
		goto disable_clk;
	}

	irq = platform_get_resource(plat_dev, IORESOURCE_IRQ, 0);
	if(unlikely(!irq)) {
		dev_err(&plat_dev->dev, "no irq resource specified\n");
		goto unregister_rtc;
	}
	rtc_data->irq_no = irq->start;
	platform_set_drvdata(plat_dev, rtc_data);

	err = request_irq(rtc_data->irq_no, rtc_interrupt_handler, 0, "sprd_rtc", rtc_data->rtc);
	if(err){
		printk(KERN_ERR "RTC regist irq error\n");
		goto unregister_rtc;
	}
	sprd_creat_caliberate_attr(rtc_data->rtc->dev);

	sprd_rtc_hwrst_set(1);
	sprd_rtc_set_bit_spg_counter(SPG_CNT_8SECS_RESET, 1);

	sprd_rtc_check_power_down(&plat_dev->dev);

	sprd_rtc_open(&plat_dev->dev);//test

	return 0;

unregister_rtc:
	rtc_device_unregister(rtc_data->rtc);
disable_clk:
	clk_disable(rtc_data->clk);
put_clk:
	clk_put(rtc_data->clk);
kfree_data:
	kfree(rtc_data);
	return err;
}