Пример #1
0
static void gp2a_work_func_prox(struct work_struct *work)
{
	struct gp2a_data *data = container_of((struct work_struct *)work,
					struct gp2a_data, proximity_work);

	unsigned char value;
	int ret;

	ret = gp2a_i2c_read(data, COMMAND1, &value, sizeof(value));
	if (ret < 0) {
		pr_info("%s, read data error\n", __func__);
	} else {
		pr_info("%s, read data %d, %d\n", __func__, value & 0x08, !(value & 0x08));
		data->proximity_detection = !(value & 0x08);
	}

	if (!(value & 0x08)) {
		if (data->lightsensor_mode == 0)
			value = 0x63;
		else
			value = 0x67;
		gp2a_i2c_write(data, COMMAND2, &value);
	} else {
		if (data->lightsensor_mode == 0)
			value = 0x23;
		else
			value = 0x27;
		gp2a_i2c_write(data, COMMAND2, &value);
	}

	value = 0xCC;
	gp2a_i2c_write(data, COMMAND1, &value);

	ret = gp2a_i2c_read(data, COMMAND1, &value, sizeof(value));
	if (ret < 0)
		pr_info("%s, read data error\n", __func__);

	pr_info("%s, detection=%d, mode=%d, rev=%d\n", __func__,
		data->proximity_detection, data->lightsensor_mode, system_rev);

	if (system_rev < 12) {
		input_report_abs(data->prox_input_dev, ABS_DISTANCE, data->proximity_detection);
	} else {
		if (!gpio_get_value(data->con_gpio)) {
			input_report_abs(data->prox_input_dev, ABS_DISTANCE, data->proximity_detection);
		} else {
			if (!data->proximity_detection) {
				pr_err("%s, Conducntion is Connect\n", __func__);
				input_report_abs(data->prox_input_dev, ABS_DISTANCE, 1);
			} else {
				input_report_abs(data->prox_input_dev, ABS_DISTANCE, data->proximity_detection);
			}
		}
	}
	input_sync(data->prox_input_dev);
}
Пример #2
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);
	msleep(10);
	gp2a_i2c_read(DATA2_LSB, get_D2_data, sizeof(get_D2_data));
	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;

	//D2_data = D2_data - (data->offset_value); // for ADC compensation
	
	//printk(KERN_INFO "[GP2A] %s: D2_data = %d\n", __func__, D2_data);

        if(D2_data >=0 && D2_data <1024)
            D2_data_val = D2_data;
        else
            D2_data = D2_data_val;
    
	return snprintf(buf, PAGE_SIZE, "%d\n", D2_data);
}
static ssize_t gp2a_light_raw_data_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 = 0;
	int d1_raw_data = 0;
	int ret = 0;

	if (bShutdown == true) {
		pr_err("%s bShutdown true.", __func__);
		goto done;
	}

	mutex_lock(&data->data_mutex);
	ret = gp2a_i2c_read(data, 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 */
done:
	return snprintf(buf, PAGE_SIZE, "%d,%d\n", d0_raw_data, d1_raw_data);
}
static void gp2a_prox_work_func(struct work_struct *work)
{
	struct gp2a_data *gp2a = container_of(work,
		struct gp2a_data, work_prox);
	u8 vo, value;

	gp2a_i2c_read(gp2a, REGS_PROX, &vo);
	vo = 0x01 & vo;

	value = 0x18;
	gp2a_i2c_write(gp2a, REGS_CON, value);

	if (!vo) {
		gp2a->val_state = 0x01;
		value = gp2a->nondetect;
	} else {
		gp2a->val_state = 0x00;
		value = gp2a->detect;
	}
	gp2a_i2c_write(gp2a, REGS_HYS, value);

	pr_info("%s,%d\n", __func__, gp2a->val_state);

	input_report_abs(gp2a->input, ABS_DISTANCE, gp2a->val_state);
	input_sync(gp2a->input);
	msleep(20);

	value = 0x00;
	gp2a_i2c_write(gp2a, REGS_CON, value);
}
void gp2a_panic_display(struct i2c_adapter *pAdap)
{
	u8 value;
	int ret;

	/*
	 * Check driver has been started.
	*/
	if ( !(gp2a && gp2a->client && gp2a->client->adapter))
		return;

	/*
	 * If there is an associated LDO check to make sure it is powered, if
	 * not then we can exit as it wasn't powered when panic occurred.
	*/
	if (gp2a->power_state != GP2A_POWER_ON){
		pr_emerg("\n\n[GP2A Powered off at this time]\n");
		return;
	}

	/*
	 * If pAdap is NULL then exit with message.
	*/
	if ( !pAdap ){
		pr_emerg("\n\n%s Passed NULL pointer!\n",__func__);
		
		return;
	}

	/*
	 * If pAdap->algo_data is not NULL then this driver is using HW I2C,
	 *  then change adapter to use GPIO I2C panic driver.
	 * NB!Will "probably" not work on systems with dedicated I2C pins.
	*/
	if ( pAdap->algo_data ){
		gp2a->client->adapter = pAdap;
	}
	else{
		/*
		 * Otherwise use panic safe SW I2C algo,
		*/
		gp2a->client->adapter->algo = pAdap->algo;
	}

	pr_emerg("\n\n[Display of GP2A registers]\n");

	/* Can only read Proximity reg, all others are write only! */
	ret = gp2a_i2c_read(gp2a->client, GP2A_REG_PROX, &value, 1);

	if (ret < 0) 
	{
		pr_emerg("\t[%02d]: Failed to get value\n", GP2A_REG_PROX);
	} 
	else 
	{
		pr_emerg("\t[%02d]: 0x%02x\n", GP2A_REG_PROX, value);
	}
}
Пример #6
0
static void gp2a_prox_work_func(struct work_struct *work)
{
	struct gp2a_data *gp2a = container_of(work,
		struct gp2a_data, work_prox);
	u8 vo, value;
	if (gp2a->irq != 0) {
		#if defined(CONFIG_MACH_GEIM)
			disable_irq_wake(gp2a->irq);
		#else
			disable_irq_wake(gp2a->irq);
		#endif
		disable_irq(gp2a->irq);
	} else {
		return ;
	}

	gp2a_i2c_read(gp2a, REGS_PROX, &vo);
	vo = 0x01 & vo;
	if (vo == gp2a->val_state) {
		if (!vo) {
			vo = 0x01;
			value = nondetect;
		} else {
			vo = 0x00;
			value = detect;
		}
#ifdef ALPS_DEBUG
		pr_info("%s: %d\n", __func__, gp2a->val_state);
#endif
		gp2a_i2c_write(gp2a, REGS_HYS, &value);
		gp2a->val_state = vo;
	}


	input_report_abs(gp2a->proximity_input_dev,
		ABS_DISTANCE,
		gp2a->val_state);
	input_sync(gp2a->proximity_input_dev);
	msleep(20);

	value = 0x18;
	gp2a_i2c_write(gp2a, REGS_CON, &value);
	if (gp2a->irq != 0) {
		enable_irq(gp2a->irq);
		#if defined(CONFIG_MACH_GEIM)
			enable_irq_wake(gp2a->irq);
		#else
			enable_irq_wake(gp2a->irq);
		#endif
	}
	value = 0x00;
	gp2a_i2c_write(gp2a, REGS_CON, &value);
}
static ssize_t proximity_cal_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct gp2a_data *data = dev_get_drvdata(dev);
	int thresh_hi;
	unsigned char get_D2_data[2];
	msleep(20);
	gp2a_i2c_read(data, PS_HT_LSB, get_D2_data,
		sizeof(get_D2_data));
	thresh_hi = (get_D2_data[1] << 8) | get_D2_data[0];
	data->threshold_high = thresh_hi;
	return sprintf(buf, "%d,%d\n",
			data->offset_value, data->threshold_high);
}
Пример #8
0
static void gp2a_prox_work_func(struct work_struct *work)
{
	unsigned char value;
	unsigned char int_val = GP2A_REG_PROX;
	unsigned char vout = 0;
        int ret=0;

	/* Read VO & INT Clear */	
	debug("[PROXIMITY] %s : \n",__func__);
    
	if((ret=gp2a_i2c_read((u8)(int_val), &value))<0)
	{
            error("gp2a_i2c_read  failed\n");            
            gp2a_prox_reset();
            
            if(proximity_enable == 1)
                gp2a_prox_mode(1);
            else
                gp2a_prox_mode(0);
            
            return;
	}
    
	vout = value & 0x01;
	printk(KERN_INFO "[GP2A] vout = %d \n",vout);

	/* Report proximity information */ 
	proximity_value = vout;

        input_report_abs(gp2a_data->prox_input_dev, ABS_DISTANCE,((vout == 1)? 0:1));
        input_sync(gp2a_data->prox_input_dev);
        mdelay(1);

	/* Write HYS Register */
        gp2a_prox_offset(vout);

	/* Forcing vout terminal to go high */
	value = 0x18;
	gp2a_i2c_write((u8)(GP2A_REG_CON),&value);

	/* enable INT */
	enable_irq(gp2a_data->irq);
	printk(KERN_INFO "[GP2A] enable_irq IRQ_NO:%d\n",gp2a_data->irq);

	/* enabling VOUT terminal in nomal operation */
	value = 0x00;
	gp2a_i2c_write((u8)(GP2A_REG_CON),&value);
	
}
static ssize_t proximity_thresh_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct gp2a_data *data = dev_get_drvdata(dev);
	int thresh_hi = 0;
	unsigned char get_D2_data[2];

	msleep(20);
	gp2a_i2c_read(data, PS_HT_LSB, get_D2_data,
		sizeof(get_D2_data));
	thresh_hi = (get_D2_data[1] << 8) | get_D2_data[0];
	pr_info("%s: THRESHOLD = %d\n", __func__, thresh_hi);

	return sprintf(buf, "prox_threshold = %d\n", thresh_hi);
}
Пример #10
0
/*
 * get_gp2a_proximity_value() is called by magnetic sensor driver(ak8973)
 * for reading proximity value.
 */
int get_gp2a_proximity_value(void)
{
	debug("%s called",__func__); 
#if 0
	int ret =0;
	u8 prox_value;
	if((ret=gp2a_i2c_read(&prox_value))<0)
	{
		error("gp2a_i2c_read failed");
		return -1;
	}
	else
		return (!prox_value);
#else	
	return gpio_get_value(GPIO_PS_OUT);
#endif
}
static ssize_t gp2a_prox_raw_data_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	struct gp2a_data *data = dev_get_drvdata(dev);
	int d2_data = 0;
	unsigned char raw_data[2] = { 0, };

	if (bShutdown == true) {
		pr_err("%s bShutdown true.", __func__);
		goto done;
	}

	mutex_lock(&data->data_mutex);
	gp2a_i2c_read(data, 0x10, raw_data, sizeof(raw_data));
	mutex_unlock(&data->data_mutex);
	d2_data = (raw_data[1] << 8) | raw_data[0];
done:
	return snprintf(buf, PAGE_SIZE, "%d\n", d2_data);
}
static void gp2a_prox_work_func(struct work_struct *work)
{
    struct gp2a_data *gp2a = container_of(work,
                                          struct gp2a_data, work_prox);
    u8 vo, value;
    if (gp2a->irq != 0) {
        disable_irq_wake(gp2a->irq);
        disable_irq(gp2a->irq);
    } else {
        return ;
    }

    gp2a_i2c_read(gp2a, REGS_PROX, &vo);
    vo = 0x01 & vo;
    if (vo == gp2a->val_state) {
        if (!vo) {	/* close */
            vo = 0x01;
            value = nondetect;
        } else {	/* far */
            vo = 0x00;
            value = detect;
        }
        gp2a_i2c_write(gp2a, REGS_HYS, &value);
        gp2a->val_state = vo;
    }

    input_report_abs(gp2a->proximity_input_dev,
                     ABS_DISTANCE,
                     gp2a->val_state);
    input_sync(gp2a->proximity_input_dev);
    /* 1 : far, 0 : close */
    pr_info("%s: %d(1:far/0:close)\n", __func__, gp2a->val_state);
    msleep(20);

    value = 0x18;
    gp2a_i2c_write(gp2a, REGS_CON, &value);
    if (gp2a->irq != 0) {
        enable_irq(gp2a->irq);
        enable_irq_wake(gp2a->irq);
    }
    value = 0x00;
    gp2a_i2c_write(gp2a, REGS_CON, &value);
}
static int gp2a_prox_adc_read(struct gp2a_data *data)
{
	int sum[OFFSET_ARRAY_LENGTH];
	int i = OFFSET_ARRAY_LENGTH-1;
	int avg = 0;
	int min = 0;
	int max = 0;
	int total = 0;

	if (bShutdown == true) {
		pr_err("%s bShutdown true.", __func__);
		goto done;
	}

	mutex_lock(&data->data_mutex);
	do {
		unsigned char get_D2_data[2] = {0,};
		int D2_data;
		msleep(50);
		gp2a_i2c_read(data, DATA2_LSB, get_D2_data,
			sizeof(get_D2_data));
		D2_data = (get_D2_data[1] << 8) | get_D2_data[0];
		sum[i] = D2_data;
		if (i == OFFSET_ARRAY_LENGTH - 1) {
			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];
	} while (i--);
	mutex_unlock(&data->data_mutex);

	total -= (min + max);
	avg = (int)(total / (OFFSET_ARRAY_LENGTH - 2));
	pr_info("%s offset = %d\n", __func__, avg);
done:
	return avg;
}
/* Light Sysfs interface */
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 = gp2a_i2c_read(data, 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);
}
static ssize_t gp2a_prox_thresh_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	struct gp2a_data *data = dev_get_drvdata(dev);
	int thresh_hi = 0, thresh_low = 0;
	unsigned char get_D2_data[4];

	if (bShutdown == true) {
		pr_err("%s bShutdown true.", __func__);
		goto done;
	}

	msleep(20);
	gp2a_i2c_read(data, PS_LT_LSB, get_D2_data,
		sizeof(get_D2_data));
	thresh_hi = (get_D2_data[3] << 8) | get_D2_data[2];
	thresh_low = (get_D2_data[1] << 8) | get_D2_data[0];
	pr_info("%s THRESHOLD = %d\n", __func__, thresh_hi);
done:
	return snprintf(buf, PAGE_SIZE, "%d,%d\n", thresh_hi, thresh_low);
}
static void gp2a_work_avg_prox(struct work_struct *work)
{
	struct gp2a_data *data = container_of((struct delayed_work *)work,
		struct gp2a_data, prox_avg_work);

	int min = 0, max = 0, avg = 0;
	int i = 0;
	unsigned char raw_data[2] = { 0, };

	for (i = 0; i < PROX_READ_NUM; i++) {
		int gp2a_prox_value;
	    mutex_lock(&data->data_mutex);
		gp2a_i2c_read(data, 0x10, raw_data, sizeof(raw_data));
		mutex_unlock(&data->data_mutex);
		gp2a_prox_value = (raw_data[1] << 8) | raw_data[0];

		if (gp2a_prox_value > GP2A_PROX_MAX)
			gp2a_prox_value = GP2A_PROX_MAX;
		if (gp2a_prox_value > GP2A_PROX_MIN) {
			avg += gp2a_prox_value;
			if (!i)
				min = gp2a_prox_value;
			else if (gp2a_prox_value < min)
				min = gp2a_prox_value;
			if (gp2a_prox_value > max)
				max = gp2a_prox_value;
		} else {
			gp2a_prox_value = GP2A_PROX_MIN;
		}
		msleep(40);
	}
	avg /= i;
	data->avg[0] = min;
	data->avg[1] = avg;
	data->avg[2] = max;

	if (data->prox_enabled)
		schedule_delayed_work(&data->prox_avg_work,
				msecs_to_jiffies(data->prox_delay));
}
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);
	gp2a_i2c_read(data, 0x10, get_D2_data, sizeof(get_D2_data));
	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;
	pr_debug("%s: D2_data = %d\n", __func__, D2_data);
	return snprintf(buf, PAGE_SIZE, "%d\n", D2_data);
}
Пример #18
0
static ssize_t gp2a_prox_cal_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct gp2a_data *data = dev_get_drvdata(dev);
	int thresh_hi, thresh_low;
	unsigned char get_D2_data[4];

	if (bShutdown == true){
		pr_err("%s bShutdown true.", __func__);
		goto done;
	}

    msleep(20);
	gp2a_i2c_read(data, PS_LT_LSB, get_D2_data,
		sizeof(get_D2_data));
	thresh_hi = (get_D2_data[3] << 8) | get_D2_data[2];
	thresh_low = (get_D2_data[1] << 8) | get_D2_data[0];
	data->threshold_high = thresh_hi;
done:
	return sprintf(buf, "%d,%d,%d\n",
			data->offset_value, thresh_hi, thresh_low);
}
Пример #19
0
static int proximity_adc_read(struct gp2a_data *data)
{
	int sum[OFFSET_ARRAY_LENGTH];
	int i = OFFSET_ARRAY_LENGTH-1;
	int avg;
	int min = 0;
	int max = 0;
	int total = 0;
	int D2_data;
	unsigned char get_D2_data[2]={0,};

	mutex_lock(&data->data_mutex);
	do {
		msleep(50);
		gp2a_i2c_read(DATA2_LSB, get_D2_data,
			sizeof(get_D2_data));
		D2_data = (get_D2_data[1] << 8) | get_D2_data[0];
		sum[i] = D2_data;
		if (i == OFFSET_ARRAY_LENGTH - 1) {
			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];
	} while (i--);
	mutex_unlock(&data->data_mutex);

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

	return avg;
}
static void gp2a_prox_work_func(struct work_struct *work)
{
	struct gp2a_data *gp2a = container_of(work,
		struct gp2a_data, work_prox);
	u8 vo, value;
	pr_info("%s : irq = %d\n", __func__, gp2a->pdata->irq);

	gp2a_i2c_read(gp2a, REGS_PROX, &vo);
	vo = 0x01 & vo;
	if (vo == gp2a->val_state) {
		if (!vo) {
			vo = 0x01;
			value = nondetect;
		} else {
			vo = 0x00;
			value = detect;
		}
#ifdef ALPS_DEBUG
		pr_info("%s: %d\n", __func__, gp2a->val_state);
#endif
		gp2a_i2c_write(gp2a, REGS_HYS, &value);
		gp2a->val_state = vo;
	}


	input_report_abs(gp2a->proximity_input_dev,
		ABS_DISTANCE,
		gp2a->val_state);
	input_sync(gp2a->proximity_input_dev);
	msleep(20);

	value = 0x18;
	gp2a_i2c_write(gp2a, REGS_CON, &value);
	value = 0x00;
	gp2a_i2c_write(gp2a, REGS_CON, &value);
}
static int gp2a_i2c_probe(struct i2c_client *client,
                          const struct i2c_device_id *id)
{
    struct input_dev *input_dev;
    struct gp2a_data *gp2a;
    struct gp2a_platform_data *pdata = client->dev.platform_data;

    int err = 0;
    u8 vo;
    pr_info("%s: is starting!(%d)\n", __func__, __LINE__);

    nondetect = PROX_NONDETECT;
    detect = PROX_DETECT;

    if (!pdata) {
        pr_err("%s: missing pdata!\n", __func__);
        err = -ENODEV;
        goto done;
    }

    if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
        pr_err("%s: i2c functionality check failed!\n", __func__);
        err = -ENODEV;
        goto done;
    }

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

    gp2a->pdata = pdata;
    gp2a->i2c_client = client;
    i2c_set_clientdata(client, gp2a);

    if (pdata->hw_setup)
        err = pdata->hw_setup(&client->dev);
    if (err < 0) {
        pr_err("%s: hw_setup failed(%d)!\n", __func__, err);
        err = -ENODEV;
        goto done;
    }
    if (pdata->hw_pwr) {
        pdata->hw_pwr(1);
        msleep(15);
    }

    err = gp2a_i2c_read(gp2a, REGS_PROX, &vo);
    if (err < 0) {
        pr_err("%s: fail to read i2c data.\n", __func__);
        goto err_i2c_read;
    }

    /* wake lock init */
    wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND,
                   "prx_wake_lock");
    mutex_init(&gp2a->power_lock);

    /* allocate proximity input_device */
    input_dev = input_allocate_device();
    if (!input_dev) {
        pr_err("%s: could not allocate input device\n", __func__);
        goto err_input_allocate_device_proximity;
    }

    err = input_register_device(input_dev);
    if (err < 0) {
        pr_err("%s: could not register input device\n",
               __func__);
        input_free_device(input_dev);
        goto err_input_allocate_device_proximity;
    }

    gp2a->proximity_input_dev = input_dev;
    input_set_drvdata(input_dev, gp2a);
    input_dev->name = "proximity_sensor";
    input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
    input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);

    err = sysfs_create_group(&input_dev->dev.kobj,
                             &proximity_attribute_group);

    if (err) {
        pr_err("%s: could not create sysfs group\n", __func__);
        goto err_sysfs_create_group_proximity;
    }

    /* the timer just fires off a work queue request.  we need a thread
       to read the i2c (can be slow and blocking). */
    INIT_WORK(&gp2a->work_prox, gp2a_prox_work_func);
    err = gp2a_setup_irq(gp2a);

    if (err) {
        pr_err("%s: could not setup irq\n", __func__);
        goto err_setup_irq;
    }

    err = sensors_register(gp2a->proximity_dev, gp2a,
                           proxi_attrs, "proximity_sensor");
    if (err < 0) {
        pr_info("%s: could not sensors_register\n", __func__);
        goto exit_gp2a_sensors_register;
    }

    /* set initial proximity value as 1 */
    input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1);
    input_sync(gp2a->proximity_input_dev);

    pr_info("%s: is successful!(%d)\n", __func__, __LINE__);
    return 0;

    /* error, unwind it all */
exit_gp2a_sensors_register:
    free_irq(gp2a->irq, gp2a);
    gpio_free(gp2a->pdata->ps_vout_gpio);
err_setup_irq:
    sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
                       &proximity_attribute_group);
err_sysfs_create_group_proximity:
    input_unregister_device(gp2a->proximity_input_dev);
err_input_allocate_device_proximity:
    mutex_destroy(&gp2a->power_lock);
    wake_lock_destroy(&gp2a->prx_wake_lock);
err_i2c_read:
    if (pdata->hw_teardown())
        pdata->hw_teardown();
    kfree(gp2a);
done:
    pr_info("%s: done(%d)\n", __func__, __LINE__);
    return err;
}
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 = 0;
	int light_beta = 0;
	static int lx_prev;
	int ret ;
	int d0_boundary = 92;
#ifndef  CONFIG_MACH_LT02
	int d0_custom[9] = { 0, };
	int i = 0;
#endif
	mutex_lock(&data->data_mutex);
	ret = gp2a_i2c_read(data, 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 */
	if (data->pdata->version) { /* GP2AP 030 */
#ifdef  CONFIG_MACH_LT02
		d0_boundary = 91;
		if (100 * D1_raw_data <= 40 * D0_raw_data) {
			light_alpha = 861;
			light_beta = 0;
		} else if (100 * D1_raw_data <= 62 * D0_raw_data) {
			light_alpha = 2269;
			light_beta = 3521;
		} else if (100 * D1_raw_data <=d0_boundary * D0_raw_data) {
			if( (D0_raw_data < 400) && (data->lightsensor_mode == 0 ) ) {
				light_alpha = 421;
				light_beta = 455;
			}else if( (D0_raw_data < 600) && (data->lightsensor_mode == 0 ) ) {
				light_alpha = 463;
				light_beta = 500;
			}else if( (D0_raw_data < 1700) && (data->lightsensor_mode == 0 ) ) {
				light_alpha = 526;
				light_beta = 568;
			}else if( (D0_raw_data < 2200) && (data->lightsensor_mode == 0 ) ) {
				light_alpha = 568;
				light_beta = 614;
			}else if( (D0_raw_data < 3500) && (data->lightsensor_mode == 0 ) ) {
				light_alpha = 652;
				light_beta = 705;
			} else {		/* Incandescent High lux */
				light_alpha = 715;
				light_beta = 773;
			}
		} else {
			light_alpha = 0;
			light_beta = 0;
		}
#else
		if (data->pdata->d0_value[0]) {
			do {
				d0_custom[i] = data->pdata->d0_value[i];
			} while (i++ < 8);
			d0_boundary = d0_custom[D0_BND];
			if (100 * D1_raw_data <=
				d0_custom[D0_COND1] * D0_raw_data) {
				light_alpha = d0_custom[D0_COND1_A];
				light_beta = 0;
			} else if (100 * D1_raw_data <=
				d0_custom[D0_COND2] * D0_raw_data) {
				light_alpha = d0_custom[D0_COND2_A];
				light_beta = d0_custom[D0_COND2_B];
			} else if (100 * D1_raw_data <=
				d0_boundary * D0_raw_data) {
				light_alpha = d0_custom[D0_COND3_A];
				light_beta = d0_custom[D0_COND3_B];
			} else {
				light_alpha = 0;
				light_beta = 0;
			}
		} else {
			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;
			}
		}
#endif
	} 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;
			gp2a_i2c_write(data, COMMAND1, &value);

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

			if (data->proximity_enabled)
				value = 0xCC;
			else
				value = 0xDC;
			gp2a_i2c_write(data, 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;
			gp2a_i2c_write(data, COMMAND1, &value);

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

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

	return lx;
}
Пример #23
0
static void gp2a_dev_work_func(struct work_struct* work_prox)
{
	int	ret = 0;
	unsigned char value;
	//	printk(" %s, %d\n", __func__, __LINE__);
	if (!gp2a) 
	{
		printk(KERN_ERR "[PROXIMITY][%s] Pointer is NULL!\n", __func__);
	} 
	else if (gp2a->power_state == GP2A_POWER_ON) 
	{
		//		disable_irq(gp2a->irq);

		/* GP2A initialized and powered on => do the job */
		ret = gp2a_i2c_read(gp2a->client, GP2A_REG_PROX, &value, 1);
		//		printk(" %s, %d\n", __func__, __LINE__);
		if (ret < 0) 
		{
			printk(KERN_WARNING "[PROXIMITY][%s] Failed to get GP2A proximity value " "[errno=%d]; ignored", __func__, ret);
		} 
		else 
		{
			gp2a->proximity_state = (value & 0x01);
			//			printk(" %s, %d\n", __func__, __LINE__);
			if (GP2A_BIT_PROX_VO_DETECTION == gp2a->proximity_state) 
			{
				ret = GP2A_INPUT_RANGE_MIN;
				//				printk(" %s, %d\n", __func__, __LINE__);
			}
			else 
			{
				ret = GP2A_INPUT_RANGE_MAX;
				//				printk(" %s, %d\n", __func__, __LINE__);
			}
			input_report_abs(gp2a->prox_input, ABS_DISTANCE, ret);
			input_sync(gp2a->prox_input);
			//			printk(" %s, %d\n", __func__, __LINE__);
		}
	}

	if(!gp2a->proximity_state)	// far
	{
		value = 0x40;
		//		printk(" %s, %d\n", __func__, __LINE__);
	}
	else						// near
	{
		value = 0x20;
		//		printk(" %s, %d\n", __func__, __LINE__);
	}

	/* reset hysteresis */
	gp2a_i2c_write(gp2a->client, (u8)(GP2A_REG_HYS), value);
	//	printk(" %s, %d\n", __func__, __LINE__);
	enable_irq(gp2a->irq);

	/* enabling VOUT terminal in nomal operation */
	value = 0x00;
	gp2a_i2c_write(gp2a->client, (u8)(GP2A_REG_CON), value);
	//	printk(" %s, %d\n", __func__, __LINE__);

}
static void gp2a_prox_work_func(struct work_struct *work)
{	
	unsigned char value;
	unsigned char int_val = GP2A_REG_PROX;
	unsigned char vout = 0;
        int ret=0;

	/* Read VO & INT Clear */	
	debug("[PROXIMITY] %s : \n",__func__);
	if(INT_CLEAR)
	{
		//int_val = GP2A_REG_PROX | (1 <<7);
	}
	
	if((ret=gp2a_i2c_read((u8)(int_val), &value))<0)
	{
            error("gp2a_i2c_read  failed\n");            
            gp2a_prox_reset();
            
            if(proximity_enable == 1)
                gp2a_prox_mode(1);
            else
                gp2a_prox_mode(0);
            
            return;
	}
    
	vout = value & 0x01;
	printk(KERN_INFO "[GP2A] vout = %d \n",vout);

	/* Report proximity information */
	proximity_value = vout;
		
	if(proximity_value ==0)
	{
		timeB = ktime_get();
		
		timeSub = ktime_sub(timeB,timeA);
		debug("[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);
			debug("[PROXIMITY] wake_lock_timeout : HZ/2 \n");
		}
		else
			error("[PROXIMITY] wake_lock is already set \n");
	}

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

	/* Write HYS Register */
	if(!vout)
	{
		value = 0x40;
	}
	else
	{
		value = 0x20;
	}
	
	gp2a_i2c_write((u8)(GP2A_REG_HYS),&value);

	/* Forcing vout terminal to go high */
	value = 0x18;
	gp2a_i2c_write((u8)(GP2A_REG_CON),&value);

	/* enable INT */
	enable_irq(gp2a_data->irq);
	printk(KERN_INFO "[GP2A] enable_irq IRQ_NO:%d\n",gp2a_data->irq);

	/* enabling VOUT terminal in nomal operation */
	value = 0x00;
	gp2a_i2c_write((u8)(GP2A_REG_CON),&value);
	
}
int gp2a_get_lux(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 = 0;
	int light_beta = 0;
	static int lx_prev;
	int ret;

	mutex_lock(&data->data_mutex);
	ret = gp2a_i2c_read(data, 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 */

	if (100 * d1_raw_data <= 55 * d0_raw_data) {
		light_alpha = 746;
		light_beta = 0;
	} else if (100 * d1_raw_data <= 75 * d0_raw_data) {
		light_alpha = 2535;
		light_beta = 3252;
	} else if (100 * d1_raw_data <= 91 * d0_raw_data) {
		if (d0_raw_data < 240) {
			light_alpha = 274;
			light_beta = 298;
		} else if (d0_raw_data < 400) {
			light_alpha = 531;
			light_beta = 577;
		} else if (d0_raw_data < 1600) {
			light_alpha = 295;
			light_beta = 320;
		} else if (d0_raw_data < 2800) {
			light_alpha = 338;
			light_beta = 368;
		} else {
			light_alpha = 516;
			light_beta = 562;
		}
	} 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 < 2) {
		lx = 0;
	} else if (data->lightsensor_mode == 0
		&& (d0_raw_data >= RAWDATA_THRESHOLD ||
		d1_raw_data >= RAWDATA_THRESHOLD)) {
		lx = LUX_MAX_VALUE;
	} else if (100 * d1_data > 95 * d0_data) {
		if (d0_raw_data >= RAWDATA_THRESHOLD ||
			d1_raw_data >= RAWDATA_THRESHOLD)
			lx_prev = LUX_MAX_VALUE;
		lx = lx_prev;
		return lx;
	} else {
		lx = (int)((light_alpha * d0_data)
			- (light_beta * d1_data)) * 33 / 10000;
	}
	if (lx >= LUX_MAX_VALUE)
		lx = LUX_MAX_VALUE;
	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;
			gp2a_i2c_write(data, COMMAND1, &value);

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

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

			value = 0x0C;
			gp2a_i2c_write(data, COMMAND1, &value);

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

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

	return lx;
}
Пример #26
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 = 91;

	mutex_lock(&data->data_mutex);
	ret = gp2a_i2c_read(data, 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 */

	if (data->pdata->version) {  /* GP2AP 030 */
		if (100 * D1_raw_data <= 40 * D0_raw_data) {
			light_alpha = 861;
			light_beta = 0;
		} else if (100 * D1_raw_data <= 62 * D0_raw_data) {
			light_alpha = 2668;
			light_beta = 4027;
		} else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) {
			if( (D0_raw_data < 3000) && (data->lightsensor_mode == 0 ) ) {
				light_alpha = 292;
				light_beta = 316;
			} else {  /* Incandescent High lux */
				light_alpha = 737;
				light_beta = 810;
			}
		} 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;
			gp2a_i2c_write(data, COMMAND1, &value);

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

			if (data->proximity_enabled)
				value = 0xCC;
			else
				value = 0xDC;
			gp2a_i2c_write(data, 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;
			gp2a_i2c_write(data, COMMAND1, &value);

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

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

	return lx;
}
Пример #27
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 = 91;
	int d0_custom[9] = { 0, };
	int i = 0;
	mutex_lock(&data->data_mutex);
	ret = gp2a_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 */
	if (data->pdata->version) {  /* GP2AP 030 */
		if (data->pdata->d0_value[0]) {
			do {
				d0_custom[i] = data->pdata->d0_value[i];
			} while (i++ < 8);
			d0_boundary = d0_custom[D0_BND];
			if (100 * D1_raw_data <=
				d0_custom[D0_COND1] * D0_raw_data) {
				light_alpha = d0_custom[D0_COND1_A];
				light_beta = 0;
			} else if (100 * D1_raw_data <=
				d0_custom[D0_COND2] * D0_raw_data) {
				light_alpha = d0_custom[D0_COND2_A];
				light_beta = d0_custom[D0_COND2_B];
			} else if (100 * D1_raw_data <=
				d0_boundary * D0_raw_data) {
				light_alpha = d0_custom[D0_COND3_A];
				light_beta = d0_custom[D0_COND3_B];
			} else {
				light_alpha = 0;
				light_beta = 0;
			}
		} else {
			if (100 * D1_raw_data <= 40 * D0_raw_data) {
				light_alpha = 978;
				light_beta = 0;
			} else if (100 * D1_raw_data <= 62 * D0_raw_data) {
				light_alpha = 2333;
				light_beta = 3385;
			} else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) {
				light_alpha = 734;
				light_beta = 806;
			} 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) {
			printk(KERN_INFO "[GP2A] %s: change to LOW_MODE detection=%d\n",
				__func__, data->proximity_detection);
			data->lightsensor_mode = 0;	/* change to LOW MODE */

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

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

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

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

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

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

	return lx;
}