예제 #1
0
/*******************************************
function:enable P-sensor
parameter: 
	@gainrange: select the gain range
return:
	This executes the SMBus "write byte" protocol, returning
	negative errno else zero on success.
inportant:
	Other settings like timing and threshold to be set BEFORE here, 
	if required. Not set and kept as device default for now.
********************************************/
static int ltr558_ps_enable(int gainrange){
	int error;
	int setgain;

	switch (gainrange) {
		case PS_RANGE1:
			setgain = MODE_PS_ON_Gain1;
			break;

		case PS_RANGE4:
			setgain = MODE_PS_ON_Gain4;
			break;

		case PS_RANGE8:
			setgain = MODE_PS_ON_Gain8;
			break;

		case PS_RANGE16:
			setgain = MODE_PS_ON_Gain16;
			break;

		default:
			setgain = MODE_PS_ON_Gain1;
			break;
	}

	error = ltr558_i2c_write_reg(LTR558_PS_CONTR, setgain); 
	ltr558_i2c_read_reg(0x81);
	LTRDBG("0x81 = [%x]\n", ltr558_i2c_read_reg(0x81));
	mdelay(WAKEUP_DELAY);
	
	return error;
}
예제 #2
0
static bool ltr558_read_id(void){
	if ((0x80 == ltr558_i2c_read_reg(LTR558_PART_ID)) &&
		(0x05 == ltr558_i2c_read_reg(LTR558_MANUFACTURER_ID))){
		ltr558_is_good = true;
	}

	return ltr558_is_good;
}
static int get_lsensor_value(struct ltr558_info *lpi,uint8_t *data)
{
        int ret = 0;
        int alsval_ch0_lo, alsval_ch0_hi, alsval_ch0;
        int alsval_ch1_lo, alsval_ch1_hi, alsval_ch1;
        int luxdata_int;
        int ratio = 0;
        long luxdata_flt = 0;
        if (data == NULL)
            return -EFAULT;

        alsval_ch0_lo = ltr558_i2c_read_reg(LTR558_ALS_DATA_CH0_0);
        alsval_ch0_hi = ltr558_i2c_read_reg(LTR558_ALS_DATA_CH0_1);
        alsval_ch0 = (alsval_ch0_hi * 256) + alsval_ch0_lo;

        alsval_ch1_lo = ltr558_i2c_read_reg(LTR558_ALS_DATA_CH1_0);
        alsval_ch1_hi = ltr558_i2c_read_reg(LTR558_ALS_DATA_CH1_1);
        alsval_ch1 = (alsval_ch1_hi * 256) + alsval_ch1_lo;


        ratio = alsval_ch1*100-alsval_ch0*69;

        // Compute Lux data from ALS data (ch0 and ch1)
        // For Ratio < 0.69:
        // 1.3618*CH0 a<80>???¡ã.5*CH1
        // For 0.69 <= Ratio < 1:
        // 0.57*CH0 a<80>???¡ã.345*CH1
        // For high gain, divide the calculated lux by 150.

        if (ratio < 0){
                luxdata_flt = (13618 * alsval_ch0) - (15000 * alsval_ch1);
        }
        else if ((ratio >= 0) && (alsval_ch1<alsval_ch0)){
                luxdata_flt = (5700 * alsval_ch0) - (3450 * alsval_ch1);
        }
        else {
                luxdata_flt = 0;
        }

        // For Range1
        if (lpi->gainrange == ALS_RANGE1_320)
                luxdata_flt = luxdata_flt / 1500000;

        // convert float to integer;
        luxdata_int = luxdata_flt;
        if ((luxdata_flt - luxdata_int)*2 > 1){
                luxdata_int = luxdata_int + 1;
        }
        else {
                luxdata_int = luxdata_flt/10000;
        }
        *data = luxdata_int;
        return ret;
}
예제 #4
0
/*******************************************
function:choose the range for L-sensor to detect interrupt
parameter: 
	@l_range:the range we want to set.
		L_RANGE_1: detect ch0 range 0~3000
		L_RANGE_NULL: do not detect
return:
	-1:wrong parameter
********************************************/
static int ltr558_set_l_range(int l_range){
	int result =0;

	switch(l_range){
		case L_RANGE_1:
			result = ltr558_i2c_write_reg(LTR558_ALS_THRES_UP_0, 0xB8);		
			result = ltr558_i2c_write_reg(LTR558_ALS_THRES_UP_1, 0x0B);
			LTRDBG("0x97 = [%x], 0x98 = [%x]\n", 
				ltr558_i2c_read_reg(LTR558_ALS_THRES_UP_0), 
				ltr558_i2c_read_reg(LTR558_ALS_THRES_UP_1));
			result = ltr558_i2c_write_reg(LTR558_ALS_THRES_LOW_0, 0xff);
			result = ltr558_i2c_write_reg(LTR558_ALS_THRES_LOW_1, 0xff);
			LTRDBG("0x99 = [%x], 0x9a = [%x]\n", 
				ltr558_i2c_read_reg(LTR558_ALS_THRES_LOW_0), 
				ltr558_i2c_read_reg(LTR558_ALS_THRES_LOW_1));
			break;
		case L_RANGE_NULL:
			result = ltr558_i2c_write_reg(LTR558_ALS_THRES_UP_0, 0xff);		
			result = ltr558_i2c_write_reg(LTR558_ALS_THRES_UP_1, 0xff);
			LTRDBG("0x97 = [%x], 0x98 = [%x]\n", 
				ltr558_i2c_read_reg(LTR558_ALS_THRES_UP_0), 
				ltr558_i2c_read_reg(LTR558_ALS_THRES_UP_1));

			result = ltr558_i2c_write_reg(LTR558_ALS_THRES_LOW_0, 0x00);
			result = ltr558_i2c_write_reg(LTR558_ALS_THRES_LOW_1, 0x00);
			LTRDBG("0x99 = [%x], 0x9a = [%x]\n", 
				ltr558_i2c_read_reg(LTR558_ALS_THRES_LOW_0), 
				ltr558_i2c_read_reg(LTR558_ALS_THRES_LOW_1));
			break;
		default:
			return -1;
	}
	return result;
}
예제 #5
0
/*******************************************
function:enable L-sensor
parameter: 
	@gainrange: select the gain range
return:
	This executes the SMBus "write byte" protocol, returning
	negative errno else zero on success.
inportant:
	Other settings like timing and threshold to be set BEFORE here, 
	if required. Not set and kept as device default for now.
********************************************/
static int ltr558_als_enable(int gainrange){
	int error;

	if (gainrange == ALS_RANGE1_320)
		error = ltr558_i2c_write_reg(LTR558_ALS_CONTR, MODE_ALS_ON_Range1);
	else if (gainrange == ALS_RANGE2_64K)
		error = ltr558_i2c_write_reg(LTR558_ALS_CONTR, MODE_ALS_ON_Range2);
	else
		error = -1;

	ltr558_i2c_read_reg(0x80);
	LTRDBG("0x80 = [%x]\n", ltr558_i2c_read_reg(0x80));
	mdelay(WAKEUP_DELAY);

	return error;
}
예제 #6
0
/*******************************************
function:Put L-sensor into Standby mode
parameter: 
	none
return:
	This executes the SMBus "write byte" protocol, returning
	negative errno else zero on success.
********************************************/
static int ltr558_als_disable(void){
	int error;
	
	error = ltr558_i2c_write_reg(LTR558_ALS_CONTR, MODE_ALS_StdBy); 
	LTRDBG("0x80 = [%x]\n", ltr558_i2c_read_reg(0x80));
	
	return error;
}
예제 #7
0
static int ltr558_als_read(struct i2c_client *client)
{
	int alsval_ch0_lo, alsval_ch0_hi;
	int alsval_ch1_lo, alsval_ch1_hi;
	unsigned int alsval_ch0 = 0, alsval_ch1 = 0;
	int luxdata = 0, ratio = 0;
	long ch0_coeff = 0, ch1_coeff = 0;

	alsval_ch1_lo = ltr558_i2c_read_reg(client, LTR558_ALS_DATA_CH1_0);
	alsval_ch1_hi = ltr558_i2c_read_reg(client, LTR558_ALS_DATA_CH1_1);
	alsval_ch1 = (alsval_ch1_hi * 256) + alsval_ch1_lo;

	alsval_ch0_lo = ltr558_i2c_read_reg(client, LTR558_ALS_DATA_CH0_0);
	alsval_ch0_hi = ltr558_i2c_read_reg(client, LTR558_ALS_DATA_CH0_1);
	alsval_ch0 = (alsval_ch0_hi * 256) + alsval_ch0_lo;

	if (alsval_ch0 == 0 && alsval_ch1 == 0)
		return 0;

	/* lux formula */
	ratio = (100 * alsval_ch1)/(alsval_ch1 + alsval_ch0);

	if (ratio < 45) {
		ch0_coeff = 17743;
		ch1_coeff = -11059;
	}
	else if ((ratio >= 45) && (ratio < 64)) {
		ch0_coeff = 37725;
		ch1_coeff = 13363;
	}
	else if ((ratio >= 64) && (ratio < 85)) {
		ch0_coeff = 16900;
		ch1_coeff = 1690;
	}
	else if (ratio >= 85) {
		ch0_coeff = 0;
		ch1_coeff = 0;
	}

	luxdata = ((alsval_ch0 * ch0_coeff) - (alsval_ch1 * ch1_coeff))/10000;
	return luxdata;
}
static void sensor_irq_do_work(struct work_struct *work)
{
    struct ltr558_info *lpi = lp_info;

    uint8_t status = 0;
    int als_ps_status;
    int interrupt, newdata;

    als_ps_status = ltr558_i2c_read_reg(LTR558_ALS_PS_STATUS);
    interrupt = als_ps_status & 10;
    newdata = als_ps_status & 5;

    switch (interrupt){
                case 2:
                        // PS interrupt
                        if ((newdata == 1) | (newdata == 5)){
                          
                         //wake_up_interruptible(&ps_waitqueue);
                            report_psensor_input_event(lpi);
                        }
                        break;

                case 8:
                        // ALS interrupt
                        if ((newdata == 4) | (newdata == 5)){
                        //wake_up_interruptible(&als_waitqueue);
                            report_lsensor_input_event(lpi);
                        }
                        break;

                case 10:
                        // Both interrupt
                        if ((newdata == 1) | (newdata == 5)){
                            report_psensor_input_event(lpi);
                        }
                        //wake_up_interruptible(&als_waitqueue);
                        if((newdata == 4) | (newdata == 5)){
                            report_lsensor_input_event(lpi);
                        }
                        break;
        }
#if 0
    /*check ALS or PS*/
    ltr558_i2c_read(LTR558_ALS_PS_STATUS,&status);

    D("[ltr558] intr status[0x%x]\n",status);
    if(status & 0x02)/*ps trigger interrupt*/
    {
        report_psensor_input_event(lpi);
    }
#endif

}
static int ltr558_ps_read(void)
{
        int psval_lo, psval_hi, psdata;

        psval_lo = ltr558_i2c_read_reg(LTR558_PS_DATA_0);
        if (psval_lo < 0){
                psdata = psval_lo;
                goto out;
        }

        psval_hi = ltr558_i2c_read_reg(LTR558_PS_DATA_1);
        if (psval_hi < 0){
                psdata = psval_hi;
                goto out;
        }

        psdata = ((psval_hi & 7)* 256) + psval_lo;


        out:
        final_prox_val = psdata;
        return psdata;
}
예제 #10
0
/*******************************************
function:read P-sensor data
parameter: 
	none
return:
	This executes the SMBus "read byte" protocol, returning 
	negative errno, else return the P-sensor data .
********************************************/
static int ltr558_ps_read(void){
	int psval_lo, psval_hi, psdata;

	psval_lo = ltr558_i2c_read_reg(LTR558_PS_DATA_0);
	if (psval_lo < 0){
		LTRERR("read LTR558_PS_DATA_0 fail\n");
		psdata = psval_lo;
		goto out;
	}
		
	psval_hi = ltr558_i2c_read_reg(LTR558_PS_DATA_1);
	if (psval_hi < 0){
		LTRERR("read LTR558_PS_DATA_1 fail\n");
		psdata = psval_hi;
		goto out;
	}

	//printk("data_lo == %d data_hi == %d \n",psval_lo,psval_hi);
	psdata = ((psval_hi & 7) << 8) + psval_lo;

	out:
	return psdata;
}
예제 #11
0
static int ltr558_ps_read(struct i2c_client *client)
{
	int psval_lo = 0, psval_hi = 0, psdata = 0;
	psval_lo = ltr558_i2c_read_reg(client, LTR558_PS_DATA_0);
	if (psval_lo < 0){
		psdata = psval_lo;
		goto out;
	}

	psval_hi = ltr558_i2c_read_reg(client, LTR558_PS_DATA_1);
	if (psval_hi < 0){
		psdata = psval_hi;
		goto out;
	}

	/* PS should never saturate */
	/* FIX ME: enable WARN_ON once sensor is calibrated */
	/* WARN_ON(psval_hi & BIT(7)); */

	psdata = ((psval_hi & 0x07) * 256) + psval_lo;
out:
	return psdata;
}
예제 #12
0
static void ltr558_schedwork(struct work_struct *work){
	int als_ps_status;
	int interrupt, newdata;
	int final_prox_val;
	int final_lux_val;

	als_ps_status = ltr558_i2c_read_reg(LTR558_ALS_PS_STATUS);
	interrupt = als_ps_status & 10;
	newdata   = als_ps_status & 5 ;
	LTRDBG("interrupt [%d]  newdata  [%d]\n", interrupt, newdata);
	switch (interrupt){
		case 2:
			// PS interrupt
			if ((newdata == 1) | (newdata == 5)){
				
				final_prox_val = ltr558_ps_read();
				if(final_prox_val < 0){
					LTRERR("read P-sensor data fail\n");
					goto out;
				}
				
				LTRDBG("final_prox_val [%d]\n", final_prox_val);
				if (final_prox_val >= 0x214){
					P_L_printk("ltr558 OBJECT_IS_DETECTED\n");
					input_report_abs(ltr558_data->ltr558_input,
									ABS_DISTANCE, OBJECT_IS_DETECTED);
					if (ltr558_set_p_range(P_RANGE_2)){
						LTRERR("set P-sensor to range 2 fail\n");
					}	
				}else if (final_prox_val < 0x214){
					P_L_printk("ltr558 OBJECT_IS_NOT_DETECTED\n");
					input_report_abs(ltr558_data->ltr558_input,
									ABS_DISTANCE, OBJECT_IS_NOT_DETECTED);
					if (ltr558_set_p_range(P_RANGE_1)){
						LTRERR("set P-sensor to range 1 fail\n");
					}	
				}
			}
			break;

		case 8:
			// ALS interrupt
			if ((newdata == 4) | (newdata == 5)){
				
				final_lux_val = ltr558_als_read();
				if(final_lux_val < 0){
					LTRERR("read L-sensor data fail\n");
					goto out;
				}
				
				input_report_abs(ltr558_data->ltr558_input, ABS_MISC, final_lux_val);
				LTRDBG("final_lux_val [%d]\n", final_lux_val);
			}
			break;

		case 10:
			// Both interrupt
			if ((newdata == 1) | (newdata == 5)){
				
				final_prox_val = ltr558_ps_read();
				if(final_prox_val < 0){
					LTRERR("read P-sensor data fail\n");
					goto read_als;
				}
				
				LTRDBG("final_prox_val [%d]\n", final_prox_val);
				if (final_prox_val >= 0x214){
					input_report_abs(ltr558_data->ltr558_input,
									ABS_DISTANCE, OBJECT_IS_DETECTED);
					if (ltr558_set_p_range(P_RANGE_2)){
						LTRERR("set P-sensor to range 2 fail\n");
					}	
				}else if (final_prox_val <0x214){
					input_report_abs(ltr558_data->ltr558_input,
									ABS_DISTANCE, OBJECT_IS_NOT_DETECTED);
					if (ltr558_set_p_range(P_RANGE_1)){
						LTRERR("set P-sensor to range 2 fail\n");
					}	
				}
			}
read_als:
			if ((newdata == 4) | (newdata == 5)){
				
				final_lux_val = ltr558_als_read();
				if(final_lux_val < 0){
					LTRERR("read L-sensor data fail\n");
					goto out;
				}
				
				input_report_abs(ltr558_data->ltr558_input, ABS_MISC, final_lux_val);
				LTRDBG("final_lux_val [%d]\n", final_lux_val);
			}
			break;
	}
out:
	input_sync(ltr558_data->ltr558_input);	
	enable_irq(ltr558_data->ltr558_irq);

}
예제 #13
0
/*******************************************
function:choose the range for P-sensor to detect interrupt
parameter: 
	@p_range:the range we want to set.
		P_RANGE_1: detect range 200~max
		P_RANGE_2: detect range 0~128
		P_RANGE_NULL: do not detect
return:
	-1:wrong parameter
********************************************/
static int ltr558_set_p_range(int p_range){
	int result = 0;
	
	switch(p_range){
		case P_RANGE_1:
			result = ltr558_i2c_write_reg(LTR558_PS_THRES_UP_0, 0x14); ///d4		//0x2C		
			result = ltr558_i2c_write_reg(LTR558_PS_THRES_UP_1, 0x02);		//0x01
			LTRDBG("0x90 = [%x], 0x91 = [%x]\n", 
			ltr558_i2c_read_reg(LTR558_PS_THRES_UP_0), 
				ltr558_i2c_read_reg(LTR558_PS_THRES_UP_1));

			result = ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_0, 0x00);
			result = ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_1, 0x00);
			LTRDBG("0x92 = [%x], 0x93 = [%x]\n", 
				ltr558_i2c_read_reg(LTR558_PS_THRES_LOW_0),
				ltr558_i2c_read_reg(LTR558_PS_THRES_LOW_1));
			break;
		case P_RANGE_2:
			result = ltr558_i2c_write_reg(LTR558_PS_THRES_UP_0, 0xff);
			result = ltr558_i2c_write_reg(LTR558_PS_THRES_UP_1, 0x07);
			LTRDBG("0x90 = [%x], 0x91 = [%x]\n", 
				ltr558_i2c_read_reg(LTR558_PS_THRES_UP_0), 
				ltr558_i2c_read_reg(LTR558_PS_THRES_UP_1));

			result = ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_0, 0x14);
			result = ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_1, 0x02);
			LTRDBG("0x92 = [%x], 0x93 = [%x]\n", 
				ltr558_i2c_read_reg(LTR558_PS_THRES_LOW_0), 
				ltr558_i2c_read_reg(LTR558_PS_THRES_LOW_1));
			break;
		case P_RANGE_NULL:
			result = ltr558_i2c_write_reg(LTR558_PS_THRES_UP_0, 0xff);		
			result = ltr558_i2c_write_reg(LTR558_PS_THRES_UP_1, 0x07);
			LTRDBG("0x90 = [%x], 0x91 = [%x]\n", 
				ltr558_i2c_read_reg(LTR558_PS_THRES_UP_0), 
				ltr558_i2c_read_reg(LTR558_PS_THRES_UP_1));

			result = ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_0, 0x00);
			result = ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_1, 0x00);
			LTRDBG("0x92 = [%x], 0x93 = [%x]\n", 
				ltr558_i2c_read_reg(LTR558_PS_THRES_LOW_0), 
				ltr558_i2c_read_reg(LTR558_PS_THRES_LOW_1));
			break;
		default:
			return -1;
	}
	return result;
}
예제 #14
0
/*******************************************
function:read L-sensor data
parameter: 
	none
return:
	This executes the SMBus "read byte" protocol, returning 
	negative errno, else return the P-sensor data .
inportant:
	must read by sequence 0x88->0x89->0x8A->0x8C
********************************************/
static int ltr558_als_read(void){
	int alsval_ch0_lo, alsval_ch0_hi;
	int alsval_ch1_lo, alsval_ch1_hi;
	int luxdata;
	int ratio;
	int alsval_ch0, alsval_ch1;
	int ch0_coeff, ch1_coeff;
	static int old_luxdata = 1;
	static int time_num1 = 0;
	static int time_num2 = 0;
	int light_value = 0;
	int report_flag = false;
	static int luxdata_out = 200;
#ifdef 	CONFIG_SENSORS_LTR501ALS_FUNCTION_CONTROL
	int differ_tp_light = 0;
#endif
	static int old_range_count = -1;
	static int variable1 = 3;
	static int array[4]  = {0};
	int range_count, i;

	alsval_ch1_lo = ltr558_i2c_read_reg(LTR558_ALS_DATA_CH1_0);
	if (alsval_ch1_lo < 0){
		LTRERR("read LTR558_ALS_DATA_CH1_0 fail\n");
		luxdata = alsval_ch1_lo;
		goto out;
	}
	alsval_ch1_hi = ltr558_i2c_read_reg(LTR558_ALS_DATA_CH1_1);
	if (alsval_ch1_hi < 0){
		LTRERR("read LTR558_ALS_DATA_CH1_1 fail\n");
		luxdata = alsval_ch1_hi;
		goto out;
	}
	alsval_ch1 = (alsval_ch1_hi * 256) + alsval_ch1_lo;

	alsval_ch0_lo = ltr558_i2c_read_reg(LTR558_ALS_DATA_CH0_0);
	if (alsval_ch0_lo < 0){
		LTRERR("read LTR501_ALS_DATA_CH0_0 fail\n");
		luxdata = alsval_ch0_lo;
		goto out;
	}
	alsval_ch0_hi = ltr558_i2c_read_reg(LTR558_ALS_DATA_CH0_1);
	if (alsval_ch0_hi < 0){
		LTRERR("read LTR558_ALS_DATA_CH0_1 fail\n");
		luxdata = alsval_ch0_hi;
		goto out;
	}
	alsval_ch0 = (alsval_ch0_hi * 256) + alsval_ch0_lo;
//	printk("alsval_ch0_hi[%d],  alsval_ch0_lo[%d]\n", alsval_ch0_hi, alsval_ch0_lo);
//	printk("alsval_ch1_hi[%d],  alsval_ch1_lo[%d]\n", alsval_ch1_hi, alsval_ch1_lo);
//	printk("alsval_ch0[%d],  alsval_ch1[%d]\n", alsval_ch0, alsval_ch1);
	
	LTRDBG("alsval_ch0[%d],  alsval_ch1[%d]\n", alsval_ch0, alsval_ch1);

	if ((0 == alsval_ch0) && ( 0 == alsval_ch1)){
		luxdata = 0;
		goto out;
	}
	
	ratio = (100 * alsval_ch1)/(alsval_ch1 + alsval_ch0);
//	printk("ratio[%d]\n", ratio);
	if (ratio < 45)
	{
		ch0_coeff = 17743;
		ch1_coeff = -11059;
	}
	else if ((ratio >= 45) && (ratio < 64))
	{
		ch0_coeff = 37725;
		ch1_coeff = 13363;
	}
	else if ((ratio >= 64) && (ratio < 85))
	{
		ch0_coeff = 16900;
		ch1_coeff = 1690;
	}
	else if ((ratio >= 85) && (ratio < 99))
	{
		ch0_coeff = 0;
		ch1_coeff = 0;
	}
	else if(ratio == 100)
	{
		if(alsval_ch1 < 1000)
		{
			ch0_coeff = 0;
			ch1_coeff = 0;
		}
		else
		{
//			ch0_coeff = 0;
//			ch1_coeff = 100000;
			luxdata = 100000;
			goto out;
			
		}
	}
	luxdata = ((alsval_ch0 * ch0_coeff) - (alsval_ch1 * ch1_coeff))/10000;
	///luxdata = ((alsval_ch0 * ch0_coeff) - (alsval_ch1 * ch1_coeff))/900000;///600000; //crystal changed ,ehanced Sensitivity,2012-10-23
out:
/*	if (0 == luxdata)
	{
		luxdata = 1;
	}
*/	
//	printk("luxdata[%d]\n", luxdata);
#ifdef CONFIG_SENSORS_LTR501ALS_FUNCTION_CONTROL	
	if ( (tp_class == B_Y_TOUCH) && (luxdata > 1) )		//compatible different Tp light value
	{

		if ( luxdata > (LEVEL_1_LUXDATA_DIV + 2 ) && luxdata < (LEVEL_2_LUXDATA_DIV + 2) ){
			differ_tp_light = DIFFER_TP_LIGHT_1 ;
		}
		else if ( luxdata >= (LEVEL_2_LUXDATA_DIV + 2) && luxdata < (LEVEL_3_LUXDATA_DIV + 2) ){
			differ_tp_light = DIFFER_TP_LIGHT_2 ;
		}
		else if ( luxdata >= (LEVEL_3_LUXDATA_DIV + 2) && luxdata < (LEVEL_4_LUXDATA_DIV + 5) ){
			differ_tp_light = DIFFER_TP_LIGHT_3 ;
		}
		else if ( luxdata >= (LEVEL_4_LUXDATA_DIV + 5) ){
			differ_tp_light = DIFFER_TP_LIGHT_4 ;
		}
	
		if ( POLARITY_FLAG )
		{
			luxdata += differ_tp_light ;
		}
		else
		{
			if( luxdata > differ_tp_light )
			{
				luxdata -= differ_tp_light ;
			}
		}
	}

	if ( luxdata > (LEVEL_4_LUXDATA_DIV + 5) ){
		return luxdata * MULTIPLE_VALUE;			//LEVEL5 -> LEVEL1,2,3,4  immediately return
	}

	
	if (luxdata == 1)		//counter for "avoid level changed too quickly"
	{
		time_num1++;
		time_num2 = 0;
	}
	else
	{
		time_num1 = 0;
		if (luxdata >= (LEVEL_2_LUXDATA_DIV + 2) && luxdata < (LEVEL_3_LUXDATA_DIV - 2))
		{
			time_num2++;
		}
		else
		{
			time_num2 = 0;
		}
	}

	if ((time_num1 < 3 && luxdata < 2) || 
		(luxdata > (LEVEL_1_LUXDATA_DIV - 2) && luxdata < (LEVEL_1_LUXDATA_DIV + 2)) ||
		(luxdata > (LEVEL_2_LUXDATA_DIV - 3) && luxdata < (LEVEL_2_LUXDATA_DIV + 3)) || 
		(luxdata > (LEVEL_3_LUXDATA_DIV - 2) && luxdata < (LEVEL_3_LUXDATA_DIV + 2)) || 
		(time_num2 < 3 && (luxdata > (LEVEL_2_LUXDATA_DIV + 2) && luxdata < (LEVEL_3_LUXDATA_DIV -2))) ||
		(luxdata > (LEVEL_4_LUXDATA_DIV - 5) && luxdata < (LEVEL_4_LUXDATA_DIV + 5)))
		
	{
		luxdata = old_luxdata ;
	}else{
		old_luxdata = luxdata ;
	}

	luxdata =  luxdata * MULTIPLE_VALUE;
#else
	if(luxdata >= 0 && luxdata < variable1)
		range_count = 0;
	else if(luxdata >= variable1 && luxdata < 150)
		range_count = 1;
	else if(luxdata >= 150 && luxdata < 3000)
		range_count = 2;
	else if(luxdata >= 3000)
		range_count = 3;

	if(range_count == old_range_count)
	{
		array[range_count] ++;
		if(array[range_count] == 3)
		{
			for(i = 0; i <= 3; i ++)
			{
				array[i] = 0;
			}
			light_value = range_count;
			report_flag = true;
		}
	}
	else
	{
		for(i = 0; i <= 3; i ++)
		{
			array[i] = 0;
		}
		array[range_count] ++;
	}
	old_range_count = range_count;

	if(report_flag == true)
	{
		switch(light_value)
			{
			case 0 :
				luxdata_out = (luxdata - 3 < 0) ? luxdata : 2;//10;
				variable1 = 7;
				break;
			case 1:
				luxdata_out = luxdata;//200;
				variable1 = 3;
				break;
			case 2:
				luxdata_out = luxdata;//400;
				variable1 = 3;
				break;
			case 3:
				luxdata_out = luxdata;//1000;
				variable1 = 3;
				break;
			default:
				break;
			}
		report_flag = false;
	}
/*	if (luxdata == 1)
	{
		time_num1++;
		time_num2 = 0;
	}
	else
	{
		time_num1 = 0;
		if (luxdata >= 9)
		{
			time_num2++;
		}
		else
		{
			time_num2 = 0;
		}
	}


	if ((luxdata < 0) || 
		(old_luxdata < 2 && ((time_num2 < 2) || luxdata < 9)) || 
		((old_luxdata >= 2) && ((time_num1 < 2 && luxdata < 2) || (luxdata > 80 && luxdata < 90)))) 
	{
		luxdata = old_luxdata;
	}
	else
	{
		old_luxdata = luxdata;
	}
	
	if (time_num1 > 100)
	{
		time_num1 = 0;
	}
	if (time_num2 > 100)
	{
		time_num2 = 0;
	}
	
	luxdata =  luxdata * 7;

	if (luxdata > 7 && luxdata <= 1000)
		luxdata = (luxdata / 100) * 100 + 50;
	else if (luxdata > 1000)
		luxdata = (luxdata / 1000) * 1000 + 50; ///?500
*/		
#endif	

	return luxdata_out;
}
예제 #15
0
static int ltr558_devinit(void){
	int error;	
	int ret=0;

	//mdelay(PON_DELAY);
	ltr558_read_id();
	if (false == ltr558_read_id()){
		LTRERR("ltr558 id is wrong\n");
		return -1;
	}
	P_L_printk("%s: Can read ltr558 id successfully.\n",__func__);

	error = ltr558_als_disable();
	if (error < 0)
		goto exit_disable_sensor_fail;
	error = ltr558_ps_disable();
	if (error < 0)
		goto exit_disable_sensor_fail;

	error = ltr558_config();
	if (error < 0)
		goto exit_config_sensor_fail;

	error = ltr558_set_p_range(P_RANGE_1);
	if (error < 0)
		goto exit_set_sensor_range_fail;
	
	error = ltr558_set_l_range(L_RANGE_1);
	if (error < 0)
		goto exit_set_sensor_range_fail;

	mdelay(WAKEUP_DELAY); 	
	
#if 0
	LTRDBG("0x80 = [%x]\n", ltr558_i2c_read_reg(0x80));
	LTRDBG("0x81 = [%x]\n", ltr558_i2c_read_reg(0x81));
	LTRDBG("0x82 = [%x]\n", ltr558_i2c_read_reg(0x82));
	LTRDBG("0x83 = [%x]\n", ltr558_i2c_read_reg(0x83));
	LTRDBG("0x84 = [%x]\n", ltr558_i2c_read_reg(0x84));
	LTRDBG("0x85 = [%x]\n", ltr558_i2c_read_reg(0x85));
	LTRDBG("0x86 = [%x]\n", ltr558_i2c_read_reg(0x86));
	LTRDBG("0x87 = [%x]\n", ltr558_i2c_read_reg(0x87));
	LTRDBG("0x88 = [%x]\n", ltr558_i2c_read_reg(0x88));
	LTRDBG("0x89 = [%x]\n", ltr558_i2c_read_reg(0x89));
	LTRDBG("0x8a = [%x]\n", ltr558_i2c_read_reg(0x8a));
	LTRDBG("0x8b = [%x]\n", ltr558_i2c_read_reg(0x8b));
	LTRDBG("0x8c = [%x]\n", ltr558_i2c_read_reg(0x8c));
	LTRDBG("0x8d = [%x]\n", ltr558_i2c_read_reg(0x8d));
	LTRDBG("0x8e = [%x]\n", ltr558_i2c_read_reg(0x8e));
	LTRDBG("0x8f  = [%x]\n",ltr558_i2c_read_reg(0x8f));
	LTRDBG("0x90 = [%x]\n", ltr558_i2c_read_reg(0x90));
	LTRDBG("0x91 = [%x]\n", ltr558_i2c_read_reg(0x91));
	LTRDBG("0x92 = [%x]\n", ltr558_i2c_read_reg(0x92));
	LTRDBG("0x93 = [%x]\n", ltr558_i2c_read_reg(0x93));
	LTRDBG("0x97 = [%x]\n", ltr558_i2c_read_reg(0x97));
	LTRDBG("0x98 = [%x]\n", ltr558_i2c_read_reg(0x98));
	LTRDBG("0x99 = [%x]\n", ltr558_i2c_read_reg(0x99));
	LTRDBG("0x9a = [%x]\n", ltr558_i2c_read_reg(0x9a));
	LTRDBG("0x9e = [%x]\n", ltr558_i2c_read_reg(0x9e));
#endif

	error = 0;

exit_set_sensor_range_fail:
exit_config_sensor_fail:
exit_disable_sensor_fail:
	return error;
}