static int s35390a_clear_alarm_int(void)
{
	unsigned char sts = 0;
	unsigned char reg = 0x00;
	int ret = 0;

	ret = s35390a_get_reg(EXT_RTC_STS_REG2,&reg,1);
	if(ret != SP_OK)
		return ret;
	
	reg &= 0x0f;
	ret = s35390a_set_reg(EXT_RTC_STS_REG2,&reg,1);
	if(ret != SP_OK)
		return ret;

	ret = s35390a_get_reg(EXT_RTC_STS_REG1,&sts,1);
	if(ret != SP_OK)
		return ret;
	
	if ((sts&0x20)==0x20) {	/*INT1:(sts&0x10)==0x10; INT2:(sts&0x20)==0x20 */
		DEBUG0("External RTC alarm INT clear OK\n ");
		return SP_OK;
	}

	return SP_FAIL;
}
Example #2
0
static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm)
{
	struct s35390a *s35390a = i2c_get_clientdata(client);
	char buf[3], sts;
	int i, err;

	if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)) < 0)
		return -EIO;

	sts = bitrev8(sts);

	s35390a_alarm_irq_enable(client, 1);
	err = s35390a_get_reg(s35390a, S35390A_CMD_INT1_REG1, buf, sizeof(buf));
	if (err < 0)
		return err;

	/* This chip returns the bits of each byte in reverse order */
	for (i = 0; i < 3; ++i) {
		buf[i] = bitrev8(buf[i]);
		buf[i] &= ~0x80;
	}

	alm->time.tm_wday = bcd2bin(buf[S35390A_ALRM_BYTE_WDAY]);
	alm->time.tm_hour = s35390a_reg2hr(s35390a, buf[S35390A_ALRM_BYTE_HOURS]);
	alm->time.tm_min = bcd2bin(buf[S35390A_ALRM_BYTE_MINS]);

	dev_dbg(&client->dev, "%s: alm is mins=%d, hours=%d, wday=%d\n",
			__func__, alm->time.tm_min, alm->time.tm_hour,
			alm->time.tm_wday);

	if (!(sts & BIT(2)))
		s35390a_alarm_irq_enable(client, 0);

	return 0;
}
/**
* @brief Set S35390A Alarm Interrupt settings, using INT2
* @param enable[in] : Alarm Interrupt enable (0 disable/1 enable).
* @param pending[in] : Alarm Interrupt pending (0 not pending/1 pending).
* @param time[in] : Alarm time value.
*/
static int  s35390a_set_alarm(unsigned char enable, unsigned char pending, struct rtc_time *alarm)
{
	unsigned char time[4] = {0};
	unsigned char reg = 0x40; /*use INT2: 0x40     use INT1:  0x04;*/
	unsigned char tmp = 0;
	unsigned char weekDayEn = 0x80;
	int ret = 0;

	if(alarm->tm_hour >= 12){
		tmp = 0x40;
	}
	DEBUG0("Set alarm %d-%d-%d-%d-%d-%d\n", alarm->tm_year+1900, alarm->tm_mon, alarm->tm_mday, alarm->tm_hour, alarm->tm_min, alarm->tm_sec);

	alarm->tm_wday = day_of_week(alarm->tm_year+1900, alarm->tm_mon, alarm->tm_mday);
	time[0] = bin2bcd(alarm->tm_wday) | weekDayEn;/*0x80 will make weekDay enable*/
	time[1] = bin2bcd(alarm->tm_hour) | 0x80;
	time[1] = time[1] |tmp;/*must set am/pm whether 12 or 24*/
	time[2] = bin2bcd(alarm->tm_min) | 0x80;
	
	
	//DEBUG0("Set alarm[0x%x][0x%x][0x%x]\n", time[0], time[1], time[2]);
	
	/**/
	ret = s35390a_get_reg(EXT_RTC_STS_REG2, &reg, 1);
	if(ret != SP_OK)
		return ret;
	
	if(enable == 1){
		reg &= 0x0f;
		reg |= 0x40;
		ret = s35390a_set_reg(EXT_RTC_STS_REG2, &reg, 1);
	}else{
		reg &= 0x0f;
		ret = s35390a_set_reg(EXT_RTC_STS_REG2, &reg, 1);
	}
	if(ret != SP_OK)
		return ret;

	ret = s35390a_set_reg(EXT_RTC_INT_REG2, time, 3);
	if(ret != SP_OK)
		return ret;
	
	ret = s35390a_get_reg(EXT_RTC_STS_REG2, &reg, 1);
	if(ret != SP_OK)
		return ret;
	//DEBUG0("enable = %d, REG = 0x%x \n", enable, reg);

	return ret;

}
Example #4
0
static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm)
{
	struct s35390a *s35390a = i2c_get_clientdata(client);
	char buf[7];
	int i, err;

	err = s35390a_get_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf));
	if (err < 0)
		return err;

	/* This chip returns the bits of each byte in reverse order */
	for (i = 0; i < 7; ++i)
		buf[i] = bitrev8(buf[i]);

	tm->tm_sec = bcd2bin(buf[S35390A_BYTE_SECS]);
	tm->tm_min = bcd2bin(buf[S35390A_BYTE_MINS]);
	tm->tm_hour = s35390a_reg2hr(s35390a, buf[S35390A_BYTE_HOURS]);
	tm->tm_wday = bcd2bin(buf[S35390A_BYTE_WDAY]);
	tm->tm_mday = bcd2bin(buf[S35390A_BYTE_DAY]);
	tm->tm_mon = bcd2bin(buf[S35390A_BYTE_MONTH]) - 1;
	tm->tm_year = bcd2bin(buf[S35390A_BYTE_YEAR]) + 100;

	dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, "
		"mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec,
		tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year,
		tm->tm_wday);

	return rtc_valid_tm(tm);
}
static int s35390a_set_adjust(unsigned char adj_data)
{
	unsigned char reg1, reg2 = 0;
	int retryCount = 10;
	int ret;

	/* Set External RTC EXT_RTC_ADJ_REG */
	reg1 = adj_data;

	while ( retryCount-- > 0 ) {
		/* write */
		ret = s35390a_set_reg( EXT_RTC_ADJ_REG, &reg1, 1 );
		if ( SP_OK == ret ) {
			break;
		}
	}
	
	if ( SP_FAIL == ret ) {
		return SP_FAIL;
	}
	
	retryCount = 10;	 
	while ( retryCount-- > 0 ) {
		/* read back */
		s35390a_get_reg(EXT_RTC_ADJ_REG, &reg2, 1);
		if ( reg1 == reg2 ) 
			break;
	}	

	return retryCount == 0 ? SP_FAIL : SP_OK;
}
Example #6
0
static void s35390a_work(struct work_struct *work)
{
	struct s35390a *s35390a;
	struct i2c_client *client;
	char buf[1];

	s35390a = container_of(work, struct s35390a, work);
	if (!s35390a)
		return;
	client = s35390a->client[0];

	if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf)) < 0)
		goto out;

	/* This chip returns the bits of each byte in reverse order */
	buf[0] = bitrev8(buf[0]);

	if (buf[0] & BIT(2)) {
		/* Notify RTC core on event */
		rtc_update_irq(s35390a->rtc, 1, RTC_IRQF | RTC_AF);
		s35390a_alarm_irq_enable(client, 0);
	} else if (buf[0] & BIT(0)) {
		/* Notify RTC core on event */
		rtc_update_irq(s35390a->rtc, 1, RTC_PF | RTC_IRQF);
	} else if (buf[0] & BIT(1)) {
		/* Notify RTC core on event */
		rtc_update_irq(s35390a->rtc, 1, RTC_UF | RTC_IRQF);
	}
	enable_irq(client->irq);
out:
	return;
}
/**
*@brief Check started or not
*/
static int s35390a_check_started(unsigned char *pReg)
{
	unsigned char reg1_sts;
	unsigned char reg2_sts;
	int ret = 0;
	int retry = 10;

	/*unsigned char tmp = 0;*/
	ret = s35390a_get_reg(EXT_RTC_STS_REG1, &reg1_sts,1);
	if( ret != SP_OK ) {
		*pReg = 0;
		return ret;
	}
	
	if(((reg1_sts&0x80)==0x80)||((reg1_sts&0x40)==0x40)){	/*poc or boc is 1*/	
		DIAG_INFO("\nExternal RTC first start up!\n\n");
		while(1)	{
			/*Ïò׎̬ŒÄŽæÆ÷1µÄBIT0ÐŽÈë1œøÐÐreset*/
			reg1_sts = reg1_sts|0x01;
			s35390a_set_reg(EXT_RTC_STS_REG1, &reg1_sts, 1);

			#if 0
			/*×ÔÓɌĎæÆ÷£¬Öµ¿É×ÔÓÉÉ趚£¬¿ÉÓÃΪRTC reliableµÄÅбð*/
			tmp = 0xa5;
			halExtRtcRegWrite(EXT_RTC_FREE_REG,&tmp,1);
			#endif
			
			s35390a_get_reg(EXT_RTC_STS_REG2,&reg2_sts, 1);
			if ((reg2_sts&0x80)==0){/*TEST bit is 0*/	
				ret = SP_OK;
				break;
			}
			if( retry < 0 ) {
				ret = SP_FAIL;
				break;
			}
			else {
				retry--;
			}
		}		
	}
	*pReg = reg1_sts;

	return ret;
}
/**
*@brief Set int1 output frequency
*/
static int s35390a_int1_output_freq(unsigned int frequency)
{	
	unsigned char sts_reg2, int_reg1;
	
	s35390a_get_reg(EXT_RTC_STS_REG2, &sts_reg2, 1);
	sts_reg2 &= 0xf0;
	sts_reg2 |= 0x01;
	s35390a_set_reg(EXT_RTC_STS_REG2, &sts_reg2, 1);
	if(frequency == 16)
		int_reg1 = 0x08;/*Out put 16HZ to INT1*/
	else
		int_reg1 = 0x10;/*Out put 8HZ to INT1*/
	s35390a_set_reg(EXT_RTC_INT_REG1, &int_reg1, 1);

	s35390a_get_reg(EXT_RTC_STS_REG2, &sts_reg2, 1);
	s35390a_set_reg(EXT_RTC_INT_REG1, &int_reg1, 1);
	
	DIAG_VERB("output_frequency: sts_reg2, int_reg1 = 0x%x, 0x%x \n", sts_reg2, int_reg1);
	return SP_OK;
}
static int s35390a_get_adjust(unsigned char *adj_data)
{
	int ret;
	unsigned char reg1;

	/* Get External RTC EXT_RTC_ADJ_REG */
	ret = s35390a_get_reg( EXT_RTC_ADJ_REG, &reg1, 1 );

	*adj_data = reg1;
	
	return ret;
}
Example #10
0
static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm)
{
	struct s35390a *s35390a = i2c_get_clientdata(client);
	char buf[3], sts = 0;
	int err, i;

	dev_dbg(&client->dev, "%s: alm is secs=%d, mins=%d, hours=%d mday=%d, "\
		"mon=%d, year=%d, wday=%d\n", __func__, alm->time.tm_sec,
		alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday,
		alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday);

	/* disable interrupt */
	err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
	if (err < 0)
		return err;

	/* clear pending interrupt, if any */
	err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, &sts, sizeof(sts));
	if (err < 0)
		return err;

	if (alm->enabled)
		sts = S35390A_INT2_MODE_ALARM;
	else
		sts = S35390A_INT2_MODE_NOINTR;

	/* This chip expects the bits of each byte to be in reverse order */
	sts = bitrev8(sts);

	/* set interupt mode*/
	err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
	if (err < 0)
		return err;

	if (alm->time.tm_wday != -1)
		buf[S35390A_ALRM_BYTE_WDAY] = bin2bcd(alm->time.tm_wday) | 0x80;

	buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a,
			alm->time.tm_hour) | 0x80;
	buf[S35390A_ALRM_BYTE_MINS] = bin2bcd(alm->time.tm_min) | 0x80;

	if (alm->time.tm_hour >= 12)
		buf[S35390A_ALRM_BYTE_HOURS] |= 0x40;

	for (i = 0; i < 3; ++i)
		buf[i] = bitrev8(buf[i]);

	err = s35390a_set_reg(s35390a, S35390A_CMD_INT2_REG1, buf,
								sizeof(buf));

	return err;
}
Example #11
0
static int s35390a_disable_test_mode(struct s35390a *s35390a)
{
	char buf[1];

	if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf)) < 0)
		return -EIO;

	if (!(buf[0] & S35390A_FLAG_TEST))
		return 0;

	buf[0] &= ~S35390A_FLAG_TEST;
	return s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf));
}
Example #12
0
static int s35390a_alarm_irq_enable(struct i2c_client *client, unsigned enabled)
{
	struct s35390a *s35390a = i2c_get_clientdata(client);
	struct rtc_wkalrm *alm;
	char buf[3], sts;
	int err, i;

	err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
	if (err) {
		dev_err(&client->dev, "%s: failed to read STS2 reg\n", __func__);
		return err;
	}

	/* This chip returns the bits of each byte in reverse order */
	sts = bitrev8(sts);

	sts &= ~S35390A_INT1_MODE_MASK;

	if (enabled)
		sts |= S35390A_INT1_MODE_ALARM;
	else
		sts |= S35390A_INT1_MODE_NOINTR;

	/* This chip returns the bits of each byte in reverse order */
	sts = bitrev8(sts);

	err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
	if (err) {
		dev_err(&client->dev, "%s: failed to set STS2 reg\n", __func__);
		return err;
	}

	alm = &s35390a->alarm;

	if (alm->time.tm_wday != -1)
		buf[S35390A_ALRM_BYTE_WDAY] = bin2bcd(alm->time.tm_wday) | 0x80;

	buf[S35390A_ALRM_BYTE_HOURS] = s35390a_hr2reg(s35390a,
			alm->time.tm_hour) | 0x80;
	buf[S35390A_ALRM_BYTE_MINS] = bin2bcd(alm->time.tm_min) | 0x80;

	if (alm->time.tm_hour >= 12)
		buf[S35390A_ALRM_BYTE_HOURS] |= 0x40;

	/* This chip expects the bits of each byte to be in reverse order */
	for (i = 0; i < 3; ++i)
		buf[i] = bitrev8(buf[i]);

	return s35390a_set_reg(s35390a, S35390A_CMD_INT1_REG1, buf, sizeof(buf));
}
Example #13
0
static int s35390a_reset(struct s35390a *s35390a)
{
	char buf[1];

	if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)) < 0)
		return -EIO;

	if (!(buf[0] & (S35390A_FLAG_POC | S35390A_FLAG_BLD)))
		return 0;

	buf[0] |= (S35390A_FLAG_RESET | S35390A_FLAG_24H);
	buf[0] &= 0xf0;
	return s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf));
}
/**
* @brief Get S35390A Alarm Interrupt settings.
* @param enable[out] : Alarm Interrupt enable (0 disable/1 enable).
* @param pending[out] : Alarm Interrupt pending (0 not pending/1 pending).
* @param time[out] : Alarm time value.
*/
static int s35390a_get_alarm(unsigned char *enable, unsigned char *pending, struct rtc_time *alarm)
{
	unsigned char sts = 0;
	unsigned char time[4] = {0};
	int ret = 0;
	
	/*check enalbe*/
	ret = s35390a_get_reg(EXT_RTC_STS_REG2, &sts, 1);
	if(ret != SP_OK){
		DEBUG0("[%s] get alarm enable fail!\n", __FUNCTION__);
		return ret;
	}
	*enable = (sts & 0x40)?1:0;
	//DEBUG0("sts = 0x%x, Enable = %d \n", sts, *enable);

	/*read alarm time*/
	ret = s35390a_get_reg(EXT_RTC_INT_REG2, time, 3);
	if(ret != SP_OK){
		DEBUG0("[%s] Get alarm time fail!\n", __FUNCTION__);
		return ret;
	}
	//DEBUG0("Get alarm[0x%x][0x%x][0x%x]\n", time[0], time[1], time[2]);

	alarm->tm_year = 0;
	alarm->tm_mon = 0;
	alarm->tm_mday = 0;
	alarm->tm_wday = bcd2bin(time[0] & 0x7f);
	if((time[0]&0x80)==0x00)
	{
		alarm->tm_wday = 7;/*发现闹钟未使能星期设定,则回传7*/
	}
	alarm->tm_hour = bcd2bin(time[1] & 0x3f);
	alarm->tm_min =  bcd2bin(time[2] & 0x7f);
	alarm->tm_sec = 0;
	
	return ret;
}
/**
*@brief Get S35390A RTC Interrupt source.
*/
static int s35390a_get_int_src(unsigned int *int_src)
{
	unsigned char sts = 0;
	int ret = 0;

	ret = s35390a_get_reg(EXT_RTC_STS_REG1, &sts, 1);
	if(ret != SP_OK){
		*int_src = 0;
		return ret; 
	}

	if(sts & 0x10)
		*int_src= S35390A_INT_FLAG_INT1;	

	if(sts & 0x20)
		*int_src = S35390A_INT_FLAG_INT2;

	return ret;
}
/**
*@brief Set alarm interrupt
*/
static int s35390a_set_alarm_int(unsigned char enable)
{
	unsigned char int_reg2 = 0;
	int ret = 0;

	/*int2 for alarm */
	ret = s35390a_get_reg(EXT_RTC_STS_REG2, &int_reg2, 1);
	if(ret != SP_OK)
		return ret;
	
	if(enable == 1){
		int_reg2 &= 0x0f;
		int_reg2 |= 0x40;
	}
	else{
		int_reg2 &= 0x0f;
	}

	return s35390a_set_reg(EXT_RTC_STS_REG2, &int_reg2, 1); /*set sts_reg2*/
}
Example #17
0
static int s35390a_freq_irq_enable(struct i2c_client *client, unsigned enabled)
{
	struct s35390a *s35390a = i2c_get_clientdata(client);
	char buf[1];
	int err;

	err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf));
	if (err) {
		dev_err(&client->dev, "%s: failed to read STS2 reg\n", __func__);
		return err;
	}

	/* This chip returns the bits of each byte in reverse order */
	buf[0] = bitrev8(buf[0]);

	buf[0] &= ~S35390A_INT1_MODE_MASK;

	if (enabled)
		buf[0] |= S35390A_INT1_MODE_FREQ;
	else
		buf[0] |= S35390A_INT1_MODE_NOINTR;

	/* This chip returns the bits of each byte in reverse order */
	buf[0] = bitrev8(buf[0]);

	err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf));
	if (err) {
		dev_err(&client->dev, "%s: failed to set STS2 reg\n", __func__);
		return err;
	}

	if (enabled) {
		buf[0] = s35390a->rtc->irq_freq;

		buf[0] = bitrev8(buf[0]);
		err = s35390a_set_reg(s35390a, S35390A_CMD_INT1_REG1, buf,
				sizeof(buf));
	}

	return err;
}
/**
*@brief Set time format
*/
static int s35390a_set_12or24_format(unsigned char format)
{
	unsigned char reg1_sts;
	int ret;

	ret = s35390a_get_reg(EXT_RTC_STS_REG1,&reg1_sts,1);
	if( ret != SP_OK ) {
		return ret;
	}
	
	if (format == 0) {
		/* 12 hours */
		reg1_sts = reg1_sts&0xfd;
	} else {
		/* 24 hours */
		reg1_sts = reg1_sts|0x02;		
	}
	
	return  s35390a_set_reg(EXT_RTC_STS_REG1, &reg1_sts, 1); /*set sts_reg1*/	
	
}
static int gp_ext_rtc_get_time(struct device *dev, struct rtc_time *tm)
{
	unsigned char i = 0;
	unsigned char time[7];
	int ret = 0;
	DEBUG0("[%s]:Enter \n", __FUNCTION__);

	if(!gp_ext_rtc_info){
		return (-EPERM);
	}
	spin_lock_irq(&gp_ext_rtc_info->lock);
	
	ret = s35390a_get_reg(EXT_RTC_TIME_REG1, time, 7);	/*read real time*/
	if( ret != SP_OK ) {
		return (-EIO);
	}
	
	for(i=0;i<7;i++){
		if (i==4){
			if (time[4]&0x40){
				time[4] = time[4]&0xbf;
			}
		}
		time[i] = bcd2bin(time[i]);
	}

	tm->tm_year = time[0]+100;/*UI base on 1900,but external base on 2000*/
	tm->tm_mon = time[1] - 1; /*upper layer:0~11; s35390a: 1~12*/
	tm->tm_mday = time[2];
	tm->tm_wday = time[3];
	tm->tm_hour = time[4];
	tm->tm_min = time[5];
	tm->tm_sec = time[6];
	
	spin_unlock_irq(&gp_ext_rtc_info->lock);
          
	//DEBUG0("From Reg:%d %d %d %d %d %d\n",time[0],time[1],time[2],time[4],time[5],time[6]);	

	return 0;
}
Example #20
0
static int s35390a_update_irq_enable(struct i2c_client *client, unsigned enabled)
{
	struct s35390a *s35390a = i2c_get_clientdata(client);
	char buf[1];

	if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf)) < 0)
		return -EIO;

	/* This chip returns the bits of each byte in reverse order */
	buf[0] = bitrev8(buf[0]);

	buf[0] &= ~S35390A_INT1_MODE_MASK;

	if (enabled)
		buf[0] |= S35390A_INT1_MODE_PMIN_EDG;
	else
		buf[0] |= S35390A_INT1_MODE_NOINTR;

	/* This chip returns the bits of each byte in reverse order */
	buf[0] = bitrev8(buf[0]);

	return s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf));
}
Example #21
0
static int s35390a_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	int err;
	unsigned int i;
	struct s35390a *s35390a;
	struct rtc_time tm;
	char buf[1];

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		err = -ENODEV;
		goto exit;
	}

	s35390a = kzalloc(sizeof(struct s35390a), GFP_KERNEL);
	if (!s35390a) {
		err = -ENOMEM;
		goto exit;
	}

	s35390a->client[0] = client;
	i2c_set_clientdata(client, s35390a);

	/* This chip uses multiple addresses, use dummy devices for them */
	for (i = 1; i < 8; ++i) {
		s35390a->client[i] = i2c_new_dummy(client->adapter,
					client->addr + i);
		if (!s35390a->client[i]) {
			dev_err(&client->dev, "Address %02x unavailable\n",
						client->addr + i);
			err = -EBUSY;
			goto exit_dummy;
		}
	}

	err = s35390a_reset(s35390a);
	if (err < 0) {
		dev_err(&client->dev, "error resetting chip\n");
		goto exit_dummy;
	}

	err = s35390a_disable_test_mode(s35390a);
	if (err < 0) {
		dev_err(&client->dev, "error disabling test mode\n");
		goto exit_dummy;
	}

	err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf));
	if (err < 0) {
		dev_err(&client->dev, "error checking 12/24 hour mode\n");
		goto exit_dummy;
	}
	if (buf[0] & S35390A_FLAG_24H)
		s35390a->twentyfourhour = 1;
	else
		s35390a->twentyfourhour = 0;

	if (s35390a_get_datetime(client, &tm) < 0)
		dev_warn(&client->dev, "clock needs to be set\n");

	INIT_WORK(&s35390a->work, s35390a_work);

	if (client->irq > 0) {
		err = request_irq(client->irq, s35390a_irq, IRQF_TRIGGER_LOW,
				client->name, client);
		if (err) {
			dev_err(&client->dev, "unable to request IRQ\n");
			goto exit_dummy;
		}
	}

	s35390a->rtc = rtc_device_register(s35390a_driver.driver.name,
				&client->dev, &s35390a_rtc_ops, THIS_MODULE);

	if (IS_ERR(s35390a->rtc)) {
		err = PTR_ERR(s35390a->rtc);
		goto exit_intr;
	}
	s35390a->rtc->irq_freq = 0;
	s35390a->rtc->max_user_freq = 16;
	return 0;

exit_intr:
	free_irq(client->irq, client);

exit_dummy:
	for (i = 1; i < 8; ++i)
		if (s35390a->client[i])
			i2c_unregister_device(s35390a->client[i]);
	kfree(s35390a);
	i2c_set_clientdata(client, NULL);

exit:
	return err;
}