static void proxsensor_get_avgvalue(struct gp2a_data *data)
{
	int min = 0, max = 0, avg = 0;
	int i;
	u8 proximity_value = 0;
	unsigned char get_D2_data[2] = { 0, };

	for (i = 0; i < PROX_READ_NUM; i++) {
		msleep(20);
		opt_i2c_read(0x10, get_D2_data, sizeof(get_D2_data));
		proximity_value = (get_D2_data[1] << 8) | get_D2_data[0];
		avg += proximity_value;

		if (!i)
			min = proximity_value;
		else if (proximity_value < min)
			min = proximity_value;

		if (proximity_value > max)
			max = proximity_value;
	}
	avg /= PROX_READ_NUM;

	data->average[0] = min;
	data->average[1] = avg;
	data->average[2] = max;
}
Esempio n. 2
0
static u8 proximity_adc_read(struct gp2a_data *gp2a)
{
	int adc_arr[OFFSET_ARRAY_LENGTH];
	int total = 0, min = 0, max = 0;
	u8 avg = 0;
	int D2_data = 0;
	unsigned char get_D2_data[2] = {0,};
	int i;

	for (i = 0; i < OFFSET_ARRAY_LENGTH; i++) {
		mdelay(50);
		mutex_lock(&gp2a->data_mutex);
		opt_i2c_read(0x10, get_D2_data, sizeof(get_D2_data));
		mutex_unlock(&gp2a->data_mutex);
		D2_data = (get_D2_data[1] << 8) | get_D2_data[0];
		adc_arr[i] = D2_data;
		if (i == 0) {
			min = adc_arr[i];
			max = adc_arr[i];
		} else {
			if (adc_arr[i] < min)
				min = adc_arr[i];
			else if (adc_arr[i] > max)
				max = adc_arr[i];
		}
		total += adc_arr[i];
	}

	total -= (min + max);
	avg = (u8)(total / (OFFSET_ARRAY_LENGTH - 2));
	pr_info("%s: offset = %d\n", __func__, avg);

	return avg;
}
static ssize_t proximity_raw_data_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	int D2_data = 0;
	unsigned char get_D2_data[2] = { 0, };

	msleep(20);
	opt_i2c_read(0x10, get_D2_data, sizeof(get_D2_data));
	D2_data = (get_D2_data[1] << 8) | get_D2_data[0];

	return sprintf(buf, "%d\n", D2_data);
}
Esempio n. 4
0
static ssize_t proximity_raw_data_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	int D2_data = 0;
	unsigned char get_D2_data[2] = { 0, };
	struct gp2a_data *data = dev_get_drvdata(dev);

	mutex_lock(&data->data_mutex);
	opt_i2c_read(0x10, get_D2_data, sizeof(get_D2_data));
	mutex_unlock(&data->data_mutex);
	D2_data = (get_D2_data[1] << 8) | get_D2_data[0];

	return sprintf(buf, "%d\n", D2_data);
}
Esempio n. 5
0
static char get_ps_vout_value(void)
{
  char value = 0;


#ifdef PROX_MODE_A
  value = gpio_get_value_cansleep(GPIO_PS_VOUT);
#else //PROX_MODE_A
  opt_i2c_read(0x00, &value, 2);
  value &= 0x01;
  value ^= 0x01;
#endif //PROX_MODE_A

  return value;
}
static ssize_t proximity_cal_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct gp2a_data *gp2a = dev_get_drvdata(dev);
	int thresh_hi = 0;
	unsigned char get_D2_data[2]={0,};

	msleep(20);
	opt_i2c_read(PS_HT_LSB, get_D2_data, sizeof(get_D2_data));
	thresh_hi =(get_D2_data[1] << 8) | get_D2_data[0];
	gp2a->threshold_high = thresh_hi;

        printk(KERN_INFO "[GP2A] %s : %d, %d\n",__func__, gp2a->offset_value, gp2a->threshold_high);
	return sprintf(buf, "%d,%d\n", gp2a->offset_value, gp2a->threshold_high);
}
Esempio n. 7
0
static char get_ps_vout_value(void)
{
  char value = 0;


#ifdef PROX_MODE_A
#if 1 //defined (CONFIG_MACH_STEALTH)
  value = gpio_get_value_cansleep(GPIO_PS_VOUT);
#else
  value = gpio_get_value(GPIO_PS_VOUT);
#endif
#else //PROX_MODE_A
  opt_i2c_read(0x00, &value, 2);
  value &= 0x01;
  value ^= 0x01;
#endif //PROX_MODE_A

  return value;
}
Esempio n. 8
0
irqreturn_t gp2a_irq_handler(int irq, void *ptr)
{
    struct gp2a_data *gp2a = ptr;
    char value;
#ifdef PROX_MODE_B
    u8 reg = 0;
#endif

#ifdef PROX_MODE_A
    value = gpio_get_value_cansleep(gp2a->ps_status);
#else
    opt_i2c_read(0x00, &value, 2);
    value &= 0x01;
    value ^= 0x01;
#endif

    input_report_abs(gp2a->input_dev, ABS_DISTANCE,  value);
    input_sync(gp2a->input_dev);

    gp2a->prox_data = value;

#ifdef PROX_MODE_B
    if (value == 1) {
        reg = 0x40;
        opt_i2c_write(NOT_INT_CLR(REGS_HYS), &reg);
    } else{
        reg = 0x27;
        opt_i2c_write(NOT_INT_CLR(REGS_HYS), &reg);
    }

    reg = 0x18;
    opt_i2c_write(NOT_INT_CLR(REGS_CON), &reg);
#endif

#ifdef PROX_MODE_B
    reg = 0x00;
    opt_i2c_write(INT_CLR(REGS_CON), &reg);
#endif


    return IRQ_HANDLED;
}
static ssize_t lightsensor_raw_show(struct device *dev,
					   struct device_attribute *attr,
					   char *buf)
{
	struct gp2a_data *data = dev_get_drvdata(dev);

	unsigned char get_data[4] = { 0, };
	int D0_raw_data;
	int D1_raw_data;
	int ret = 0;

	mutex_lock(&data->data_mutex);
	ret = opt_i2c_read(DATA0_LSB, get_data, sizeof(get_data));
	mutex_unlock(&data->data_mutex);
	if (ret < 0)
		pr_err("%s i2c err: %d\n", __func__, ret) ;
	D0_raw_data = (get_data[1] << 8) | get_data[0];	/* clear */
	D1_raw_data = (get_data[3] << 8) | get_data[2];	/* IR */

	return snprintf(buf, PAGE_SIZE, "%d,%d\n", D0_raw_data, D1_raw_data);
}
Esempio n. 10
0
static ssize_t proximity_state_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
{

	struct gp2a_data *data = dev_get_drvdata(dev);
	static int count;		/*count for proximity average */

	int D2_data = 0;
	unsigned char get_D2_data[2] = { 0, };

	mutex_lock(&data->data_mutex);
	opt_i2c_read(0x10, get_D2_data, sizeof(get_D2_data),
		data->pdata->addr, data->pdata->adapt_num);
	mutex_unlock(&data->data_mutex);
	D2_data = (get_D2_data[1] << 8) | get_D2_data[0];

	data->average[count] = D2_data;
	count++;
	if (count == PROX_READ_NUM)
		count = 0;

	return snprintf(buf, PAGE_SIZE, "%d\n", D2_data);
}
static int proximity_adc_read(struct gp2a_data *gp2a)
{
	int sum[OFFSET_ARRAY_LENGTH];
	int i = 0;
	int avg = 0;
	int min = 0;
	int max = 0;
	int total = 0;
	int D2_data = 0;
	unsigned char get_D2_data[2]={0,};//test

	mutex_lock(&gp2a->data_mutex);
	for (i = 0; i < OFFSET_ARRAY_LENGTH; i++) {
		mdelay(50);
		opt_i2c_read(0x10, get_D2_data, sizeof(get_D2_data));
		D2_data =(get_D2_data[1] << 8) | get_D2_data[0];
		sum[i] = D2_data;
		if (i == 0) {
			min = sum[i];
			max = sum[i];
		} else {
			if (sum[i] < min)
				min = sum[i];
			else if (sum[i] > max)
				max = sum[i];
		}
		total += sum[i];
	}
	mutex_unlock(&gp2a->data_mutex);

	total -= (min + max);
	avg = (int)(total / (OFFSET_ARRAY_LENGTH - 2));
	printk(KERN_INFO "[GP2A] %s: avg = %d\n", __func__, avg);

	return avg;
}
Esempio n. 12
0
static void gp2a_work_func_prox(struct work_struct *work)
{
	struct gp2a_data *gp2a = container_of(work, struct gp2a_data, work_prox);
	
	unsigned char value;
	unsigned char int_val=REGS_PROX;
	unsigned char vout=0;

	/* Read VO & INT Clear */
	
	gprintk("[PROXIMITY] %s : \n",__func__);

	if(INT_CLEAR)
	{
		//int_val = REGS_PROX | (1 <<7);
	}
	opt_i2c_read((u8)(int_val),&value,1);
	vout = value & 0x01;
	printk(KERN_INFO "[PROXIMITY] value = %d \n",vout);



	/* Report proximity information */
	proximity_value = vout;

	
	if(proximity_value ==0)
	{
		timeB = ktime_get();
		
		timeSub = ktime_sub(timeB,timeA);
		printk(KERN_INFO "[PROXIMITY] timeSub sec = %d, timeSub nsec = %d \n",timeSub.tv.sec,timeSub.tv.nsec);
		
		if (timeSub.tv.sec>=3 )
		{
		    wake_lock_timeout(&prx_wake_lock,HZ/2);
			printk(KERN_INFO "[PROXIMITY] wake_lock_timeout : HZ/2 \n");
		}
		else
			printk(KERN_INFO "[PROXIMITY] wake_lock is already set \n");

	}

	if(USE_INPUT_DEVICE)
	{
		input_report_abs(gp2a->input_dev,ABS_DISTANCE,(int)vout);
		input_sync(gp2a->input_dev);
		mdelay(1);
	}

	/* Write HYS Register */

#if (SENSOR_MODE == SENSOR_MODE_B1)
	if(!vout)
	{
		value = 0x40;


	}
	else
	{
		value = 0x20;

	}
#elif (SENSOR_MODE == SENSOR_MODE_B15)
	if(!vout)
	{
		value = 0x2F;


	}
	else
	{
		value = 0x0F;

	}
#elif (SENSOR_MODE == SENSOR_MODE_B2)
	if(!vout)
	{
		value = 0x20;


	}
	else
	{
		value = 0x00;

	}
#endif
    
	
	opt_i2c_write((u8)(REGS_HYS),&value);

	/* Forcing vout terminal to go high */

	value = 0x18;
	opt_i2c_write((u8)(REGS_CON),&value);


	/* enabling VOUT terminal in nomal operation */

	value = 0x00;

	opt_i2c_write((u8)(REGS_CON),&value);

	
	/* enable INT */

	enable_irq(gp2a->irq);
}
Esempio n. 13
0
static void gp2a_work_func_prox(struct work_struct *work)
{
	struct gp2a_data *gp2a = container_of(work, struct gp2a_data, work_prox);
	
	unsigned char value;
	unsigned char int_val=REGS_PROX;
	unsigned char vout=0;
#if defined(CONFIG_MACH_RANT3)
	int err;
	static int retry = 0;
#endif

	/* Read VO & INT Clear */
	
	printk("[PROXIMITY] %s \n",__func__);

	if(INT_CLEAR)
	{
//		int_val = REGS_PROX | (1 <<7);
	}
#if defined(CONFIG_MACH_RANT3)
	err = opt_i2c_read((u8)(int_val),&value,1);

	if(err < 0 && retry == 0)
	{
	    printk("[PROXIMITY] I2C read error, try again==============================!!! \n");
	    retry++;
	    schedule_delayed_work(&gp2a->work_prox, 10);
	    return;
	}
	else
	    retry = 0;
#else
	opt_i2c_read((u8)(int_val),&value,1);
#endif
	
	vout = value & 0x01;
	printk(KERN_INFO "[PROXIMITY] value = %d \n",vout);

	/* Report proximity information */
	proximity_value = vout;

	
	if(proximity_value ==0)
	{
	/*
		timeB = ktime_get();
		
		timeSub = ktime_sub(timeB,timeA);
		printk(KERN_INFO "[PROXIMITY] timeB = %d sec, timeA = %d sec \n",timeB.tv.sec,timeA.tv.sec);
		printk(KERN_INFO "[PROXIMITY] timeSub sec = %d, timeSub nsec = %d \n",timeSub.tv.sec,timeSub.tv.nsec);
		
		if (timeSub.tv.sec>=3 )
		{
		    wake_lock_timeout(&prx_wake_lock,3*HZ);
			printk(KERN_INFO "[PROXIMITY] wake_lock_timeout : 3sec \n");
		}
		else
			printk(KERN_INFO "[PROXIMITY] wake_lock is already set \n");
	*/
	}

	if(USE_INPUT_DEVICE)
	{
		input_report_abs(gp2a->input_dev,ABS_DISTANCE,(int)vout);
		input_sync(gp2a->input_dev);
		mdelay(1);
	}

	/* Write HYS Register */
	if(!vout)
	{
#if defined(CONFIG_MACH_RANT3)
		value = 0x2F;
#else
		value = 0x40;
#endif
	}
	else
	{
#if defined(CONFIG_MACH_RANT3)
		value = 0x0F;
#else
		value = 0x20;
#endif
	}
	
	opt_i2c_write((u8)(REGS_HYS),&value);

	/* Forcing vout terminal to go high */

	value = 0x18;
	opt_i2c_write((u8)(REGS_CON),&value);

	/* enable INT */

	enable_irq(gp2a->irq);

	/* enabling VOUT terminal in nomal operation */

	value = 0x00;

	opt_i2c_write((u8)(REGS_CON),&value);
	
	printk("[PROXIMITY] end %s \n",__func__);
}
Esempio n. 14
0
/*****************************************************************************************
 *  
 *  function    : gp2a_work_func_prox 
 *  description : This function is for proximity sensor (using B-1 Mode ). 
 *                when INT signal is occured , it gets value from VO register.   
 */
void gp2a_work_func_prox(struct work_struct *work) {
	struct gp2a_data *gp2a = container_of(work, struct gp2a_data, work_prox);
	
	unsigned char value;
	unsigned char vout = 0;

	if (proximity_enable == OFF) {
		gprintk("proximity is not enable\n");
		return;
	}

	//20111001 [email protected] : change disable step for Mode B1
	disable_irq_nosync(gp2a->irq);
	
	//20111001 [email protected] : Set Operation mode B1 for X2 New HW Revision [S]
	/* Procedure 5 - Read VO & INT Clear */
	value = opt_i2c_read(gp2a, REGS_PROX);
	
	//Report Data toward HAL [S]
	vout = (value & 0x01)?0:1;
	//20110706 [email protected] : for diag test mode. 250.49 [S]
	if(vout)
		proximity_status = 0;
	else proximity_status = 1;
	//20110706 [email protected] : for diag test mode. 250.49 [E]
	gprintk("value = %x, vout = %d\n",value, vout);

	wake_lock_timeout(&gp2a_wake_lock, 3 * HZ);
	input_report_abs(gp2a->input_dev,ABS_DISTANCE,(int)vout);
	input_sync(gp2a->input_dev);
	mdelay(1);
	//Reposrt Data toward HAL [E]
	
	/* Procedure 6 - Write HYS Register */
//20111110 - [email protected] - Revision 처리 추가! - HW Tuning for Touch Window[S]	
#if defined(CONFIG_KS1103)
	if(get_lge_pcb_revision() > REV_C) {
		if(vout) 
			value = 0x00;
		else 
			value = 0xC3;
	} else {
		if(vout)
			value = 0x40;
		else
			value = 0x23;
	}
#else
	if(vout)
		value = 0x40;
	else
		value = 0x23;
#endif
//20111110 - [email protected] - Revision 처리 추가! - HW Tuning for Touch Window[E]
	opt_i2c_write(gp2a, (u8)(REGS_HYS), value);

	/* Procedure 7 - Forcing vout terminal to go high */
	opt_i2c_write(gp2a, (u8)(REGS_CON), 0x18);

	/* Procedure 8 - enable INT */
	enable_irq(gp2a->irq);
	mdelay(2);

	/* Procedure 9 - enabling VOUT terminal in nomal operation */
	opt_i2c_write(gp2a, (u8)(REGS_CON), 0x00);
	//20111001 [email protected] : Set Operation mode B1 for X2 New HW Revision [E]
}
Esempio n. 15
0
int lightsensor_get_adc(struct sensor_data *data)
{
	unsigned char get_data[4] = { 0, };
	int D0_raw_data;
	int D1_raw_data;
	int D0_data;
	int D1_data;
	int lx = 0;
	u8 value;
	int light_alpha;
	int light_beta;
	static int lx_prev;
	int ret = 0;
#if defined(CONFIG_MACH_BAFFIN_KOR_SKT) || \
	defined(CONFIG_MACH_BAFFIN_KOR_KT) || \
	defined(CONFIG_MACH_BAFFIN_KOR_LGT)
	int d0_boundary = 91;
#elif defined(CONFIG_MACH_KONA)
	int d0_boundary = 93;
#else
	int d0_boundary = 93;
#endif

	mutex_lock(&data->light_mutex);
	ret = opt_i2c_read(DATA0_LSB, get_data, sizeof(get_data));
	mutex_unlock(&data->light_mutex);

	if (ret < 0)
		return lx_prev;
	D0_raw_data = (get_data[1] << 8) | get_data[0];	/* clear */
	D1_raw_data = (get_data[3] << 8) | get_data[2];	/* IR */
	if (is_gp2a030a()) {
		#if defined(CONFIG_MACH_GRANDE)
			if (100 * D1_raw_data <= 41 * D0_raw_data) {
				light_alpha = 1186;
				light_beta = 0;
			} else if (100 * D1_raw_data <= 62 * D0_raw_data) {
				light_alpha = 2930;
				light_beta = 4252;
			} else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) {
				light_alpha = 924;
				light_beta = 1015;
			} else {
				light_alpha = 0;
				light_beta = 0;
			}
		#elif defined(CONFIG_MACH_BAFFIN_KOR_SKT) || \
			defined(CONFIG_MACH_BAFFIN_KOR_KT) || \
			defined(CONFIG_MACH_BAFFIN_KOR_LGT)
			if (100 * D1_raw_data <= 41 * D0_raw_data) {
				light_alpha = 868;
				light_beta = 0;
			} else if (100 * D1_raw_data <= 62 * D0_raw_data) {
				light_alpha = 2308;
				light_beta = 3509;
			} else if (100 * D1_raw_data
						<= d0_boundary * D0_raw_data) {
				light_alpha = 404;
				light_beta = 440;
			} else {
				light_alpha = 0;
				light_beta = 0;
			}
		#elif defined(CONFIG_MACH_KONA)
			if (100 * D1_raw_data <= 40 * D0_raw_data) {
				light_alpha = 834;
				light_beta = 0;
			} else if (100 * D1_raw_data <= 62 * D0_raw_data) {
				light_alpha = 2050;
				light_beta = 3036;
			} else if (100 * D1_raw_data
					<= d0_boundary * D0_raw_data) {
				if (D0_raw_data < 3000
					&& lightsensor_mode == 0) {
					/* Incandescent Low lux */
					light_alpha = 242;
					light_beta = 257;
				} else {
					/* Incandescent High lux */
					light_alpha = 497;
					light_beta = 534;
				}
			} else {
				light_alpha = 0;
				light_beta = 0;
			}
		#else
			if (100 * D1_raw_data <= 41 * D0_raw_data) {
				light_alpha = 736;
				light_beta = 0;
			} else if (100 * D1_raw_data <= 62 * D0_raw_data) {
				light_alpha = 1855;
				light_beta = 2693;
			} else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) {
				light_alpha = 544;
				light_beta = 595;
			} else {
				light_alpha = 0;
				light_beta = 0;
			}
		#endif
	} else {
		if (lightsensor_mode) {	/* HIGH_MODE */
			if (100 * D1_raw_data <= 32 * D0_raw_data) {
				light_alpha = 800;
				light_beta = 0;
			} else if (100 * D1_raw_data <= 67 * D0_raw_data) {
				light_alpha = 2015;
				light_beta = 2925;
			} else if (100 * D1_raw_data <=
				   d0_boundary * D0_raw_data) {
				light_alpha = 56;
				light_beta = 12;
			} else {
				light_alpha = 0;
				light_beta = 0;
			}
		} else {	/* LOW_MODE */
			if (100 * D1_raw_data <= 32 * D0_raw_data) {
				light_alpha = 800;
				light_beta = 0;
			} else if (100 * D1_raw_data <= 67 * D0_raw_data) {
				light_alpha = 2015;
				light_beta = 2925;
			} else if (100 * D1_raw_data <=
				   d0_boundary * D0_raw_data) {
				light_alpha = 547;
				light_beta = 599;
			} else {
				light_alpha = 0;
				light_beta = 0;
			}
		}
	}

	if (lightsensor_mode) {	/* HIGH_MODE */
		D0_data = D0_raw_data * 16;
		D1_data = D1_raw_data * 16;
	} else {		/* LOW_MODE */
		D0_data = D0_raw_data;
		D1_data = D1_raw_data;
	}
	if (is_gp2a030a()) {
		if (D0_data < 3) {
			lx = 0;
#ifdef DEBUG
			gprintk("lx is 0 : D0=%d, D1=%d\n", D0_raw_data,
				D1_raw_data);
#endif
		} else if (lightsensor_mode == 0
			   && (D0_raw_data >= 16000 || D1_raw_data >= 16000)
			   && (D0_raw_data <= 16383 && D1_raw_data <= 16383)) {
#ifdef DEBUG
			gprintk("need to changed HIGH_MODE D0=%d, D1=%d\n",
				D0_raw_data, D1_raw_data);
#endif
			lx = lx_prev;
		} else if (100 * D1_data > d0_boundary * D0_data) {
			lx = lx_prev;
#ifdef DEBUG
gprintk
	("Data range over so ues prev_lx value=%d D0=%d, D1=%d mode=%d\n",
	 lx, D0_data, D1_data, lightsensor_mode);
#endif
			return lx;
		} else {
			lx = (int)((light_alpha / 10 * D0_data * 33)
				   - (light_beta / 10 * D1_data * 33)) / 1000;
#ifdef DEBUG
	gprintk
	    ("D0=%d, D1=%d, lx=%d mode=%d a=%d, b=%d prev_lx=%d\n",
	     D0_raw_data, D1_raw_data, lx, lightsensor_mode,
	     light_alpha, light_beta, lx_prev);
#endif
		}
	} else {
		if ((D0_data == 0 || D1_data == 0)
		    && (D0_data < 300 && D1_data < 300)) {
			lx = 0;
#ifdef DEBUG
			gprintk("lx is 0 : D0=%d, D1=%d\n", D0_raw_data,
				D1_raw_data);
#endif
		} else if ((lightsensor_mode == 0)
			   && (D0_raw_data >= 16000 || D1_raw_data >= 16000)
			   && (D0_raw_data <= 16383 && D1_raw_data <= 16383)) {
#ifdef DEBUG
			gprintk("need to changed HIGH_MODE D0=%d, D1=%d\n",
				D0_raw_data, D1_raw_data);
#endif
			lx = lx_prev;
		} else if ((100 * D1_data > d0_boundary * D0_data)
			   || (100 * D1_data < 15 * D0_data)) {
			lx = lx_prev;
#ifdef DEBUG
	gprintk
	    ("Data range over so ues prev_lx value=%d D0=%d, D1=%d mode=%d\n",
	     lx, D0_data, D1_data, lightsensor_mode);
#endif
			return lx;
		} else {
			lx = (int)((light_alpha / 10 * D0_data * 33)
				   - (light_beta / 10 * D1_data * 33)) / 1000;
#ifdef DEBUG
	gprintk
	    ("D0=%d, D1=%d, lx=%d mode=%d a=%d, b=%d prev_lx=%d\n",
	     D0_raw_data, D1_raw_data, lx, lightsensor_mode,
	     light_alpha, light_beta, lx_prev);
#endif
		}
	}

	lx_prev = lx;

	if (lightsensor_mode) {	/* HIGH MODE */
		if (D0_raw_data < 1000) {
#ifdef DEBUG
			gprintk("change to LOW_MODE detection=%d\n",
				proximity_sensor_detection);
#endif
			lightsensor_mode = 0;	/* change to LOW MODE */

			value = 0x0C;
			opt_i2c_write(COMMAND1, &value);

			if (proximity_sensor_detection)
				value = 0x23;
			else
				value = 0x63;
			opt_i2c_write(COMMAND2, &value);

			if (proximity_enable)
				value = 0xCC;
			else
				value = 0xDC;
			opt_i2c_write(COMMAND1, &value);
		}
	} else {		/* LOW MODE */
		if (D0_raw_data > 16000 || D1_raw_data > 16000) {
#ifdef DEBUG
			gprintk("change to HIGH_MODE detection=%d\n",
				proximity_sensor_detection);
#endif
			lightsensor_mode = 1;	/* change to HIGH MODE */

			value = 0x0C;
			opt_i2c_write(COMMAND1, &value);

			if (proximity_sensor_detection)
				value = 0x27;
			else
				value = 0x67;
			opt_i2c_write(COMMAND2, &value);

			if (proximity_enable)
				value = 0xCC;
			else
				value = 0xDC;
			opt_i2c_write(COMMAND1, &value);
		}
	}

	return lx;
}
Esempio n. 16
0
static int lightsensor_probe(struct platform_device *pdev)
{
	struct sensor_data *data = NULL;
	int rt = -ENXIO;
	unsigned char get_data = 0;

	pr_info("%s, is called\n", __func__);
	/* Check I2C communication */
	rt = opt_i2c_read(DATA0_LSB, &get_data, sizeof(get_data));

	if (rt < 0) {
		pr_err("%s failed : threre is no such device.\n", __func__);
		return rt;
	}

	gprintk("probe start!\n");

	data = kzalloc(sizeof(struct sensor_data), GFP_KERNEL);
	if (!data) {
		pr_err("%s: failed to alloc memory for module data\n",
		       __func__);
		return -ENOMEM;
	}

	data->enabled = 0;
	data->delay = SENSOR_DEFAULT_DELAY;

	data->input_dev = input_allocate_device();
	if (!data->input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		rt = -ENOMEM;
		goto err_input_allocate_device_light;
	}

	input_set_capability(data->input_dev, EV_REL, REL_MISC);
	data->input_dev->name = SENSOR_NAME;

	rt = input_register_device(data->input_dev);
	if (rt) {
		pr_err("%s: could not register input device\n", __func__);
		input_free_device(data->input_dev);
		goto err_input_register_device_light;
	}
	input_set_drvdata(data->input_dev, data);

	rt = sysfs_create_group(&data->input_dev->dev.kobj,
				&lightsensor_attribute_group);
	if (rt) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_light;
	}
	mutex_init(&data->mutex);
	mutex_init(&data->light_mutex);

	data->light_dev = sensors_classdev_register("light_sensor");
	if (IS_ERR(data->light_dev)) {
		pr_err("%s: could not create light_dev\n", __func__);
		goto err_light_device_create;
	}

	if (device_create_file(data->light_dev, &dev_attr_lux) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_lux.attr.name);
		goto err_light_device_create_file;
	}

	if (device_create_file(data->light_dev, &dev_attr_vendor) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_vendor.attr.name);
		goto err_light_device_create_file1;
	}

	if (device_create_file(data->light_dev, &dev_attr_name) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_name.attr.name);
		goto err_light_device_create_file2;
	}

	if (device_create_file(data->light_dev, &dev_attr_raw_data) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_raw_data.attr.name);
		goto err_light_device_create_file3;
	}

	dev_set_drvdata(data->light_dev, data);

	data->wq = create_singlethread_workqueue("gp2a_wq");
	if (!data->wq) {
		rt = -ENOMEM;
		pr_err("%s: could not create workqueue\n", __func__);
		goto err_create_workqueue;
	}

	/* this is the thread function we run on the work queue */
	INIT_DELAYED_WORK(&data->work, gp2a_work_func_light);

	/* set platdata */
	platform_set_drvdata(pdev, data);

	gprintk("probe success!\n");

	goto done;

/* error, unwind it all */
err_light_device_create_file3:
	device_remove_file(data->light_dev, &dev_attr_raw_data);
err_light_device_create_file2:
	device_remove_file(data->light_dev, &dev_attr_name);
err_light_device_create_file1:
	device_remove_file(data->light_dev, &dev_attr_vendor);
err_create_workqueue:
	device_remove_file(data->light_dev, &dev_attr_lux);
err_light_device_create_file:
	sensors_classdev_unregister(data->light_dev);
err_light_device_create:
	mutex_destroy(&data->mutex);
	sysfs_remove_group(&data->input_dev->dev.kobj,
			   &lightsensor_attribute_group);
err_sysfs_create_group_light:
	input_unregister_device(data->input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	kfree(data);

done:
	return rt;
}
int lightsensor_get_adc(struct gp2a_data *data)
{
	unsigned char get_data[4] = { 0, };
	int D0_raw_data;
	int D1_raw_data;
	int D0_data;
	int D1_data;
	int lx = 0;
	u8 value;
	int light_alpha;
	int light_beta;
	static int lx_prev;
	int ret = 0;
	int d0_boundary = 91;
	mutex_lock(&data->data_mutex);
	ret = opt_i2c_read(DATA0_LSB, get_data, sizeof(get_data));
	mutex_unlock(&data->data_mutex);
	if (ret < 0)
		return lx_prev;
	D0_raw_data = (get_data[1] << 8) | get_data[0];	/* clear */
	D1_raw_data = (get_data[3] << 8) | get_data[2];	/* IR */

	// Result of baffin tunning
	if (100 * D1_raw_data <= 41 * D0_raw_data) {
		light_alpha = 830;
		light_beta = 0;
	} else if (100 * D1_raw_data <= 62 * D0_raw_data) {
		light_alpha = 2039;
		light_beta = 2949;
	} else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) {
		light_alpha = 649;
		light_beta = 708;
	} else {
		light_alpha = 0;
		light_beta = 0;
	}


	if (data->lightsensor_mode) {	/* HIGH_MODE */
		D0_data = D0_raw_data * 16;
		D1_data = D1_raw_data * 16;
	} else {		/* LOW_MODE */
		D0_data = D0_raw_data;
		D1_data = D1_raw_data;
	}

	if (D0_data < 3) {
		lx = 0;
	} else if (data->lightsensor_mode == 0
		   && (D0_raw_data >= 16000 || D1_raw_data >= 16000)
		   && (D0_raw_data <= 16383 && D1_raw_data <= 16383)) {
		lx = lx_prev;
	} else if (100 * D1_data > d0_boundary * D0_data) {

		lx = lx_prev;
		return lx;
	} else {
		lx = (int)((light_alpha / 10 * D0_data * 33)
			- (light_beta / 10 * D1_data * 33)) / 1000;
	}

	lx_prev = lx;

	if (data->lightsensor_mode) {	/* HIGH MODE */
		if (D0_raw_data < 1000) {
			pr_info("%s: change to LOW_MODE detection=%d\n",
			       __func__, data->proximity_detection);
			data->lightsensor_mode = 0;	/* change to LOW MODE */

			value = 0x0C;
			opt_i2c_write(COMMAND1, &value);

			if (data->proximity_detection)
				value = 0x23;
			else
				value = 0x63;
			
			opt_i2c_write(COMMAND2, &value);

			if (data->proximity_enabled)
				value = 0xCC;
			else
				value = 0xDC;
			
			opt_i2c_write(COMMAND1, &value);
		}
	} else {		/* LOW MODE */
		if (D0_raw_data > 16000 || D1_raw_data > 16000) {
			pr_info("%s: change to HIGH_MODE detection=%d\n",
			       __func__, data->proximity_detection);
			/* change to HIGH MODE */
			data->lightsensor_mode = 1;

			value = 0x0C;
			opt_i2c_write(COMMAND1, &value);

			if (data->proximity_detection)
				value = 0x27;
			else
				value = 0x67;
			opt_i2c_write(COMMAND2, &value);

			if (data->proximity_enabled)
				value = 0xCC;
			else
				value = 0xDC;
			opt_i2c_write(COMMAND1, &value);
		}
	}

	return lx;
}
Esempio n. 18
0
int lightsensor_get_adc(struct gp2a_data *data)
{
	unsigned char get_data[4] = { 0, };
	int D0_raw_data;
	int D1_raw_data;
	int D0_data;
	int D1_data;
	int lx = 0;
	u8 value;
	int light_alpha;
	int light_beta;
	static int lx_prev;
	int ret = 0;
	int d0_boundary = 92;
	mutex_lock(&data->data_mutex);
	ret = opt_i2c_read(DATA0_LSB, get_data, sizeof(get_data),
		data->pdata->addr, data->pdata->adapt_num);
	mutex_unlock(&data->data_mutex);
	if (ret < 0)
		return lx_prev;
	D0_raw_data = (get_data[1] << 8) | get_data[0];	/* clear */
	D1_raw_data = (get_data[3] << 8) | get_data[2];	/* IR */
	if (data->pdata->version) {  /* GP2AP 030 */
		if (100 * D1_raw_data <= 40 * D0_raw_data) {
			light_alpha = 935;
			light_beta = 0;
		} else if (100 * D1_raw_data <= 54 * D0_raw_data) {
			light_alpha = 3039;
			light_beta = 5176;
		} else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) {
			light_alpha = 494;
			light_beta = 533;
		} else {
			light_alpha = 0;
			light_beta = 0;
		}
	} else {   /* GP2AP 020 */
		if (data->lightsensor_mode) {	/* HIGH_MODE */
			if (100 * D1_raw_data <= 32 * D0_raw_data) {
				light_alpha = 800;
				light_beta = 0;
			} else if (100 * D1_raw_data <= 67 * D0_raw_data) {
				light_alpha = 2015;
				light_beta = 2925;
			} else if (100 * D1_raw_data <=
				d0_boundary * D0_raw_data) {
				light_alpha = 56;
				light_beta = 12;
			} else {
				light_alpha = 0;
				light_beta = 0;
			}
		} else {		/* LOW_MODE */
			if (100 * D1_raw_data <= 32 * D0_raw_data) {
				light_alpha = 800;
				light_beta = 0;
			} else if (100 * D1_raw_data <= 67 * D0_raw_data) {
				light_alpha = 2015;
				light_beta = 2925;
			} else if (100 * D1_raw_data <=
				d0_boundary * D0_raw_data) {
				light_alpha = 547;
				light_beta = 599;
			} else {
				light_alpha = 0;
				light_beta = 0;
			}
		}
	}

	if (data->lightsensor_mode) {	/* HIGH_MODE */
		D0_data = D0_raw_data * 16;
		D1_data = D1_raw_data * 16;
	} else {		/* LOW_MODE */
		D0_data = D0_raw_data;
		D1_data = D1_raw_data;
	}
	if (data->pdata->version) {  /* GP2AP 030 */

		if (D0_data < 3) {

			lx = 0;
		} else if (data->lightsensor_mode == 0
			   && (D0_raw_data >= 16000 || D1_raw_data >= 16000)
			   && (D0_raw_data <= 16383 && D1_raw_data <= 16383)) {
			lx = lx_prev;
		} else if (100 * D1_data > d0_boundary * D0_data) {

			lx = lx_prev;
			return lx;
		} else {
			lx = (int)((light_alpha / 10 * D0_data * 33)
				- (light_beta / 10 * D1_data * 33)) / 1000;
		}
	} else {   /* GP2AP 020 */
		if ((D0_data == 0 || D1_data == 0)\
			&& (D0_data < 300 && D1_data < 300)) {
			lx = 0;
		} else if (data->lightsensor_mode == 0
			   && (D0_raw_data >= 16000 || D1_raw_data >= 16000)
			   && (D0_raw_data <= 16383 && D1_raw_data <= 16383)) {
			lx = lx_prev;

		} else if ((100 * D1_data > d0_boundary * D0_data)
			   || (100 * D1_data < 15 * D0_data)) {
			lx = lx_prev;
			return lx;
		} else {
			lx = (int)((light_alpha / 10 * D0_data * 33)
				- (light_beta / 10 * D1_data * 33)) / 1000;
		}
	}

	lx_prev = lx;

	if (data->lightsensor_mode) {	/* HIGH MODE */
		if (D0_raw_data < 1000) {
			pr_info("%s: change to LOW_MODE detection=%d\n",
			       __func__, data->proximity_detection);
			data->lightsensor_mode = 0;	/* change to LOW MODE */

			value = 0x0C;
			opt_i2c_write(COMMAND1, &value, data->pdata->addr,
				data->pdata->adapt_num);

			if (data->proximity_detection)
				value = 0x23;
			else
				value = 0x63;
			opt_i2c_write(COMMAND2, &value, data->pdata->addr,
				data->pdata->adapt_num);

			if (data->proximity_enabled)
				value = 0xCC;
			else
				value = 0xDC;
			opt_i2c_write(COMMAND1, &value, data->pdata->addr,
				data->pdata->adapt_num);
		}
	} else {		/* LOW MODE */
		if (D0_raw_data > 16000 || D1_raw_data > 16000) {
			pr_info("%s: change to HIGH_MODE detection=%d\n",
			       __func__, data->proximity_detection);
			/* change to HIGH MODE */
			data->lightsensor_mode = 1;

			value = 0x0C;
			opt_i2c_write(COMMAND1, &value, data->pdata->addr,
				data->pdata->adapt_num);

			if (data->proximity_detection)
				value = 0x27;
			else
				value = 0x67;
			opt_i2c_write(COMMAND2, &value, data->pdata->addr,
				data->pdata->adapt_num);

			if (data->proximity_enabled)
				value = 0xCC;
			else
				value = 0xDC;
			opt_i2c_write(COMMAND1, &value, data->pdata->addr,
				data->pdata->adapt_num);
		}
	}

	return lx;
}