Пример #1
0
void hal_rtc_set_gpio_32k_status(u16 user, bool enable)
{
	u16 con, pdn1;

	if (enable) {
		pdn1 = rtc_read(RTC_PDN1);
	} else {
		pdn1 = rtc_read(RTC_PDN1) & ~(1U << user);
		rtc_write(RTC_PDN1, pdn1);
		rtc_write_trigger();
	}

	con = rtc_read(RTC_CON);
	if (enable) {
		con &= ~RTC_CON_F32KOB;
	} else {
		if (!(pdn1 & RTC_GPIO_USER_MASK)) {	/* no users */
			con |= RTC_CON_F32KOB;
		}
	}
	rtc_write(RTC_CON, con);
	rtc_write_trigger();


	if (enable) {
		pdn1 |= (1U << user);
		rtc_write(RTC_PDN1, pdn1);
		rtc_write_trigger();
	}
	hal_rtc_xinfo("RTC_GPIO user %d enable = %d 32k (0x%x)\n", user, enable, pdn1);
}
Пример #2
0
void rtc_gpio_disable_32k(rtc_gpio_user_t user)
{
	u16 con, pdn1;
	unsigned long flags;

	if (user < RTC_GPIO_USER_WIFI || user > RTC_GPIO_USER_FM)
		return;

	spin_lock_irqsave(&rtc_lock, flags);
	pdn1 = rtc_read(RTC_PDN1) & ~(1U << user);
	rtc_write(RTC_PDN1, pdn1);
	rtc_write_trigger();

	if (!(pdn1 & RTC_GPIO_USER_MASK)) {	/* no users */
		if (get_chip_eco_ver() == CHIP_E1) {
			/* keep exporting 32K to avoid f32k_ck drift */
		} else {
			con = rtc_read(RTC_CON) | RTC_CON_F32KOB;
			rtc_write(RTC_CON, con);
			rtc_write_trigger();

			con = rtc_read(RTC_OSC32CON) & ~RTC_OSC32CON_GPIOCKEN;
			rtc_xosc_write(con, true);
		}
	}
	spin_unlock_irqrestore(&rtc_lock, flags);

	printk(RTC_SAY "RTC_GPIO user %d disables 32k (0x%x)\n", user, pdn1);
}
Пример #3
0
void rtc_gpio_enable_32k(rtc_gpio_user_t user)
{
	u16 con, pdn1;
	unsigned long flags;

	if (user < RTC_GPIO_USER_WIFI || user > RTC_GPIO_USER_FM)
		return;

	spin_lock_irqsave(&rtc_lock, flags);
	pdn1 = rtc_read(RTC_PDN1);
	if (!(pdn1 & RTC_GPIO_USER_MASK)) {	/* first user */
		con = rtc_read(RTC_OSC32CON) | RTC_OSC32CON_GPIOCKEN;
		rtc_xosc_write(con, true);

		con = rtc_read(RTC_CON) & ~RTC_CON_F32KOB;
		rtc_write(RTC_CON, con);
		rtc_write_trigger();
	}

	pdn1 |= (1U << user);
	rtc_write(RTC_PDN1, pdn1);
	rtc_write_trigger();
	spin_unlock_irqrestore(&rtc_lock, flags);

	printk(RTC_SAY "RTC_GPIO user %d enables 32k (0x%x)\n", user, pdn1);
}
Пример #4
0
/* initialize rtc setting of using dcxo clock */
static int rtc_enable_dcxo(void)
{
	u16 bbpu, con, osc32con, sec;

	rtc_read(RTC_BBPU, &bbpu);
	rtc_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
	rtc_write_trigger();

	mdelay(1);
	if (!rtc_writeif_unlock()) { /* Unlock for reload */
		rtc_info("rtc_writeif_unlock() fail\n");
		return 0;
	}

	rtc_read(RTC_OSC32CON, &osc32con);
	osc32con &= ~RTC_EMBCK_SRC_SEL;
	osc32con |= RTC_XOSC32_ENB | RTC_REG_XOSC32_ENB;
	if (!rtc_xosc_write(osc32con)) {
		rtc_info("rtc_xosc_write() fail\n");
		return 0;
	}
	rtc_read(RTC_BBPU, &bbpu);
	rtc_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
	rtc_write_trigger();

	rtc_read(RTC_CON, &con);
	rtc_read(RTC_OSC32CON, &osc32con);
	rtc_read(RTC_AL_SEC, &sec);
	rtc_info("con=0x%x, osc32con=0x%x, sec=0x%x\n", con, osc32con, sec);

	return 1;
}
Пример #5
0
static void rtc_writeif_unlock(void)
{
	rtc_write(RTC_PROT, 0x586a);
	rtc_write_trigger();
	rtc_write(RTC_PROT, 0x9136);
	rtc_write_trigger();
}
Пример #6
0
void rtc_enable_writeif(void)
{
	unsigned long flags;

	spin_lock_irqsave(&rtc_lock, flags);
	rtc_write(RTC_PROT, 0x586a);
	rtc_write_trigger();
	rtc_write(RTC_PROT, 0x9136);
	rtc_write_trigger();
	spin_unlock_irqrestore(&rtc_lock, flags);
}
Пример #7
0
void hal_rtc_bbpu_pwdn(void)
{
	u16 ret_val, con;

	/* disable 32K export if there are no RTC_GPIO users */
	if (!(rtc_read(RTC_PDN1) & RTC_GPIO_USER_MASK)) {
		con = rtc_read(RTC_CON) | RTC_CON_F32KOB;
		rtc_write(RTC_CON, con);
		rtc_write_trigger();
	}
	ret_val = hal_rtc_get_spare_register(RTC_32K_LESS);
#if !defined(CONFIG_MTK_FPGA)
	if (!ret_val && pmic_chrdet_status() == KAL_FALSE) {
		/* 1.   Set SRCLKENAs GPIO GPIO as Output Mode, Output Low */
		mt_set_gpio_dir(GPIO_SRCLKEN_PIN, GPIO_DIR_OUT);
		mt_set_gpio_out(GPIO_SRCLKEN_PIN, GPIO_OUT_ZERO);
		/* 2. pull PWRBB low */
		rtc_bbpu_pwrdown(true);

		/* 3.   Switch SRCLKENAs GPIO MUX function to GPIO Mode */
		mt_set_gpio_mode(GPIO_SRCLKEN_PIN, GPIO_MODE_GPIO);
	} else
#endif
	{
		rtc_bbpu_pwrdown(true);
	}
}
Пример #8
0
void hal_rtc_set_alarm(struct rtc_time *tm)
{
	u16 irqen;

	hal_rtc_set_alarm_time(tm);

	irqen = rtc_read(RTC_IRQ_EN) | RTC_IRQ_EN_ONESHOT_AL;
	rtc_write(RTC_IRQ_EN, irqen);
	rtc_write_trigger();
}
Пример #9
0
/* enable lpd subroutine */
static int rtc_lpen(u16 con)
{
	con &= ~RTC_CON_LPRST;
	rtc_write(RTC_CON, con);
	if (!rtc_write_trigger())
		return 0;

	con |= RTC_CON_LPRST;
	rtc_write(RTC_CON, con);
	if (!rtc_write_trigger())
		return 0;

	con &= ~RTC_CON_LPRST;
	rtc_write(RTC_CON, con);
	if (!rtc_write_trigger())
		return 0;

	return 1;
}
Пример #10
0
void rtc_mark_swreset(void)
{
	u16 pdn1;
	unsigned long flags;

	spin_lock_irqsave(&rtc_lock, flags);
	pdn1 = rtc_read(RTC_PDN1) & ~0x0030;
	rtc_write(RTC_PDN1, pdn1 | 0x0020);
	rtc_write_trigger();
	spin_unlock_irqrestore(&rtc_lock, flags);
}
Пример #11
0
void hal_rtc_set_lp_irq(void)
{
	u16 irqen;

#ifndef USER_BUILD_KERNEL
	irqen = rtc_read(RTC_IRQ_EN) | RTC_IRQ_EN_LP;
#else
	irqen = rtc_read(RTC_IRQ_EN) & ~RTC_IRQ_EN_LP;
#endif
	rtc_write(RTC_IRQ_EN, irqen);
	rtc_write_trigger();
}
Пример #12
0
void hal_rtc_clear_alarm(struct rtc_time *tm)
{
	u16 irqsta, irqen, pdn2;

	irqen = rtc_read(RTC_IRQ_EN) & ~RTC_IRQ_EN_AL;
	pdn2 = rtc_read(RTC_PDN2) & ~RTC_PDN2_PWRON_ALARM;
	rtc_write(RTC_IRQ_EN, irqen);
	rtc_write(RTC_PDN2, pdn2);
	rtc_write_trigger();
	irqsta = rtc_read(RTC_IRQ_STA);	/* read clear */

	hal_rtc_set_alarm_time(tm);
}
Пример #13
0
static bool rtc_hw_init(void)
{
	u16 bbpu;

	rtc_read(RTC_BBPU, &bbpu);
	rtc_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_INIT);
	rtc_write_trigger();

	udelay(500);

	rtc_read(RTC_BBPU, &bbpu);
	rtc_write(RTC_BBPU, bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD);
	rtc_write_trigger();

	rtc_read(RTC_BBPU, &bbpu);
	if (bbpu & RTC_BBPU_INIT) {
		rtc_info("timeout\n");
		return false;
	}

	return true;
}
Пример #14
0
/* low power detect setting */
static int rtc_lpd_init(void)
{
	u16 con, sec;

	/* set RTC_LPD_OPT */
	rtc_read(RTC_AL_SEC, &sec);
	sec |= RTC_LPD_OPT_F32K_CK_ALIVE;
	rtc_write(RTC_AL_SEC, sec);
	if (!rtc_write_trigger())
		return 0;

	/* init XOSC32 to detect 32k clock stop */
	rtc_read(RTC_CON, &con);
	con |= RTC_CON_XOSC32_LPEN;
	if (!rtc_lpen(con))
		return 0;

	/* init EOSC32 to detect rtc low power */
	rtc_read(RTC_CON, &con);
	con |= RTC_CON_EOSC32_LPEN;
	if (!rtc_lpen(con))
		return 0;

	rtc_read(RTC_CON, &con);
	con &= ~RTC_CON_XOSC32_LPEN;
	rtc_write(RTC_CON, con);

	/* set RTC_LPD_OPT */
	rtc_read(RTC_AL_SEC, &sec);
	sec &= ~RTC_LPD_OPT_MASK;
	sec |= RTC_LPD_OPT_EOSC_LPD;
	rtc_write(RTC_AL_SEC, sec);
	if (!rtc_write_trigger())
		return 0;

	return 1;
}
Пример #15
0
void rtc_bbpu_power_down(void)
{
	u16 bbpu, con;
	unsigned long flags;

	spin_lock_irqsave(&rtc_lock, flags);
	rtc_writeif_unlock();

	/* disable 32K export if there are no RTC_GPIO users */
	if (!(rtc_read(RTC_PDN1) & RTC_GPIO_USER_MASK)) {
		con = rtc_read(RTC_CON) | RTC_CON_F32KOB;
		rtc_write(RTC_CON, con);
		rtc_write_trigger();

		con = rtc_read(RTC_OSC32CON) & ~RTC_OSC32CON_GPIOCKEN;
		rtc_xosc_write(con, false);
	}

	/* pull PWRBB low */
	bbpu = RTC_BBPU_KEY | RTC_BBPU_AUTO | RTC_BBPU_PWREN;
	rtc_write(RTC_BBPU, bbpu);
	rtc_write_trigger();
	spin_unlock_irqrestore(&rtc_lock, flags);
}
Пример #16
0
u16 rtc_rdwr_uart_bits(u16 *val)
{
	u16 pdn2;
	unsigned long flags;

	spin_lock_irqsave(&rtc_lock, flags);
	if (val) {
		pdn2 = rtc_read(RTC_PDN2) & ~0x0060;
		pdn2 |= (*val & 0x0003) << 5;
		rtc_write(RTC_PDN2, pdn2);
		rtc_write_trigger();
	}
	pdn2 = rtc_read(RTC_PDN2);
	spin_unlock_irqrestore(&rtc_lock, flags);

	return (pdn2 & 0x0060) >> 5;
}
Пример #17
0
/* enable rtc bbpu */
void rtc_bbpu_power_on(void)
{
	u16 bbpu;
	int ret;

	/* pull powerhold high, control by pmic */
	pmic_set_power_hold(true);

	/* pull PWRBB high */
	bbpu = RTC_BBPU_KEY | RTC_BBPU_AUTO | RTC_BBPU_RELOAD | RTC_BBPU_PWREN;
	rtc_write(RTC_BBPU, bbpu);
	ret = rtc_write_trigger();
	rtc_info("rtc_write_trigger=%d\n", ret);

	rtc_read(RTC_BBPU, &bbpu);
	rtc_info("done BBPU=%#x\n", bbpu);
}
Пример #18
0
static void rtc_xosc_write(u16 val, bool reload)
{
	u16 bbpu;

	rtc_write(RTC_OSC32CON, 0x1a57);
	rtc_busy_wait();
	rtc_write(RTC_OSC32CON, 0x2b68);
	rtc_busy_wait();

	rtc_write(RTC_OSC32CON, val);
	rtc_busy_wait();

	if (reload) {
		bbpu = rtc_read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD;
		rtc_write(RTC_BBPU, bbpu);
		rtc_write_trigger();
	}
}
Пример #19
0
void hal_rtc_save_pwron_time(bool enable, struct rtc_time *tm, bool logo)
{
	u16 pdn1, pdn2;

	hal_rtc_set_pwron_alarm_time(tm);

	if (logo)
		pdn2 = rtc_read(RTC_PDN2) | RTC_PDN2_PWRON_LOGO;
	else
		pdn2 = rtc_read(RTC_PDN2) & ~RTC_PDN2_PWRON_LOGO;

	rtc_write(RTC_PDN2, pdn2);

	if (enable)
		pdn1 = rtc_read(RTC_PDN1) | RTC_PDN1_PWRON_TIME;
	else
		pdn1 = rtc_read(RTC_PDN1) & ~RTC_PDN1_PWRON_TIME;
	rtc_write(RTC_PDN1, pdn1);
	rtc_write_trigger();
}
Пример #20
0
/* initialize rtc related gpio */
static int rtc_gpio_init(void)
{
	u16 con;

	/* RTC_32K1V8 clock change from 128k div 4 source
	 * to RTC 32k source
	 */
	pwrap_write_field(PMIC_RG_TOP_CKSEL_CON0_SET, 0x1, 0x1, 3);

	/* Export 32K clock RTC_32K1V8_1 */
	pwrap_write_field(PMIC_RG_TOP_CKPDN_CON1_CLR, 0x1, 0x1, 1);

	/* Export 32K clock RTC_32K2V8 */
	rtc_read(RTC_CON, &con);
	con &= (RTC_CON_LPSTA_RAW | RTC_CON_LPRST | RTC_CON_EOSC32_LPEN
		| RTC_CON_XOSC32_LPEN);
	con |= (RTC_CON_GPEN | RTC_CON_GOE);
	con &= ~(RTC_CON_F32KOB);
	rtc_write(RTC_CON, con);

	return rtc_write_trigger();
}
Пример #21
0
/* write powerkeys to enable rtc functions */
static int rtc_powerkey_init(void)
{
	rtc_write(RTC_POWERKEY1, RTC_POWERKEY1_KEY);
	rtc_write(RTC_POWERKEY2, RTC_POWERKEY2_KEY);
	return rtc_write_trigger();
}
Пример #22
0
static void rtc_tasklet_handler(unsigned long data)
{
	u16 irqsta, pdn1, pdn2, spar1;
	bool pwron_alm = false;

	spin_lock(&rtc_lock);
	irqsta = rtc_read(RTC_IRQ_STA);		/* read clear */
	if (unlikely(!(irqsta & RTC_IRQ_STA_AL))) {
#ifndef USER_BUILD_KERNEL
		if (irqsta & RTC_IRQ_STA_LP)
			rtc_lp_exception();
#endif
		spin_unlock(&rtc_lock);
		enable_irq(MT6573_RTC_IRQ_LINE);
		return;
	}

#if RTC_RELPWR_WHEN_XRST
{
	/* set AUTO bit because AUTO = 0 when PWREN = 1 and alarm occurs */
	u16 bbpu = rtc_read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_AUTO;
	rtc_write(RTC_BBPU, bbpu);
	rtc_write_trigger();
}
#endif

	pdn1 = rtc_read(RTC_PDN1);
	pdn2 = rtc_read(RTC_PDN2);
	spar1 = rtc_read(RTC_SPAR1);
	if (pdn1 & 0x0080) {	/* power-on time is available */
		u16 now_sec, now_min, now_hou, now_dom, now_mth;
		u16 irqen, min, hou, dom, mth;

		now_sec = rtc_read(RTC_TC_SEC);
		now_min = rtc_read(RTC_TC_MIN);
		now_hou = rtc_read(RTC_TC_HOU);
		now_dom = rtc_read(RTC_TC_DOM);
		now_mth = rtc_read(RTC_TC_MTH);
		if (rtc_read(RTC_TC_SEC) < now_sec) {	/* SEC has carried */
			now_sec = rtc_read(RTC_TC_SEC);
			now_min = rtc_read(RTC_TC_MIN);
			now_hou = rtc_read(RTC_TC_HOU);
			now_dom = rtc_read(RTC_TC_DOM);
			now_mth = rtc_read(RTC_TC_MTH);
		}

		min = spar1 & 0x003f;
		hou = (spar1 & 0x07c0) >> 6;
		dom = (spar1 & 0xf800) >> 11;
		mth = pdn2 & 0x000f;

		if (now_mth == mth && now_dom == dom &&
		    now_hou == hou && now_min == min &&
		    now_sec >= (RTC_PWRON_SEC - 1) && now_sec <= (RTC_PWRON_SEC + 4)) {
			rtc_write(RTC_PDN1, pdn1 & ~0x0080);
			rtc_write(RTC_PDN2, pdn2 | 0x0010);
			rtc_write_trigger();
			pwron_alm = true;
		} else {
			/* set power-on alarm when power-on time is available */
			rtc_write(RTC_AL_MTH, mth);
			rtc_write(RTC_AL_DOM, dom);
			rtc_write(RTC_AL_HOU, hou);
			rtc_write(RTC_AL_MIN, min);
			rtc_write(RTC_AL_SEC, RTC_PWRON_SEC);
			rtc_write(RTC_AL_MASK, 0x0050);		/* mask YEA and DOW */
			rtc_write_trigger();
			irqen = rtc_read(RTC_IRQ_EN) | RTC_IRQ_EN_ONESHOT_AL;
			rtc_write(RTC_IRQ_EN, irqen);
			rtc_write_trigger();
		}
	}