示例#1
0
static ssize_t proximity_thresh_diff_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t size)
{
	struct gp2a_data *gp2a = dev_get_drvdata(dev);
	struct gp2a_platform_data *pdata = gp2a->pdata;
	u8 threshold_diff = 0;
	int err;

	err = kstrtou8(buf, 10, &threshold_diff);
	if (err) {
		pr_err("%s, conversion %s to number.\n",
			__func__, buf);
		return err;
	}

	if ((threshold_diff > 0) && (threshold_diff < 5)) { /* update diff */
		gp2a->thresh_diff = threshold_diff;
	} else if (threshold_diff == 0) { /* reset to default */
		pdata->gp2a_get_threshold(&gp2a->thresh_diff);
	} else {
		pr_err("%s: invalid value %d\n", __func__, *buf);
		return -EINVAL;
	}

	gp2a_update_threshold(gp2a, is_gp2a030a() ?
			gp2a_original_image_030a : gp2a_original_image,
			(is_gp2a030a() ?
			gp2a_original_image_030a[3][1] :
			gp2a_original_image[3][1]), true);

	return size;
}
示例#2
0
static int proximity_store_calibration(struct device *dev, bool do_calib)
{
	struct gp2a_data *gp2a = dev_get_drvdata(dev);
	struct file *cancel_filp = NULL;
	mm_segment_t old_fs;
	int err = 0;

	if (do_calib) {
		gp2a->cal_data = proximity_adc_read(gp2a);
		if (is_gp2a030a())
			gp2a_original_image_030a[3][1] += gp2a->cal_data;
		else
			gp2a_original_image[3][1] += gp2a->cal_data;
	} else { /* reset */
		gp2a->cal_data = 0;
		if (is_gp2a030a())
			gp2a_original_image_030a[3][1] =
				gp2a->default_threshold;
		else
			gp2a_original_image[3][1] = gp2a->default_threshold;
	}

	/* Update cal data. */
	gp2a_update_threshold(gp2a, is_gp2a030a() ?
			gp2a_original_image_030a : gp2a_original_image,
			(is_gp2a030a() ?
			gp2a_original_image_030a[3][1] :
			gp2a_original_image[3][1]), true);

	pr_info("%s: prox_cal = %d, prox_thresh = 0x%x\n",
		__func__, gp2a->cal_data, (is_gp2a030a() ?
			gp2a_original_image_030a[3][1] :
			gp2a_original_image[3][1]));

	old_fs = get_fs();
	set_fs(KERNEL_DS);

	cancel_filp = filp_open(CALIBRATION_FILE_PATH,
			O_CREAT | O_TRUNC | O_WRONLY | O_SYNC, 0666);
	if (IS_ERR(cancel_filp)) {
		pr_err("%s: Can't open cancelation file\n", __func__);
		set_fs(old_fs);
		err = PTR_ERR(cancel_filp);
		return err;
	}

	err = cancel_filp->f_op->write(cancel_filp,
		(char *)&gp2a->cal_data, sizeof(u8), &cancel_filp->f_pos);
	if (err != sizeof(u8)) {
		pr_err("%s: Can't write the cancel data to file\n", __func__);
		err = -EIO;
	}

	filp_close(cancel_filp, current->files);
	set_fs(old_fs);

	return err;
}
示例#3
0
static int proximity_open_calibration(struct gp2a_data *data)
{
	struct file *cancel_filp = NULL;
	int err = 0;
	mm_segment_t old_fs;

	old_fs = get_fs();
	set_fs(KERNEL_DS);

	cancel_filp = filp_open(CALIBRATION_FILE_PATH, O_RDONLY, 0666);
	if (IS_ERR(cancel_filp)) {
		err = PTR_ERR(cancel_filp);
		if (err != -ENOENT)
			pr_err("%s: Can't open cancelation file\n", __func__);
		set_fs(old_fs);
		return err;
	}

	err = cancel_filp->f_op->read(cancel_filp,
		(char *)&data->cal_data, sizeof(u8), &cancel_filp->f_pos);
	if (err != sizeof(u8)) {
		pr_err("%s: Can't read the cancel data from file\n", __func__);
		err = -EIO;
	}

	if (data->cal_data != 0) {/*If there is an offset cal data. */
#if defined(CONFIG_MACH_KONA_SENSOR)
		if (is_gp2a030a()) {
			gp2a_original_image_030a[5][1] =
				data->default_threshold + data->cal_data;
			gp2a_original_image_030a[3][1] =
				data->default_threshold
				+ data->cal_data - DEFAULT_THRESHOLD_DIFF;
			}
#else
		if (is_gp2a030a())
			gp2a_original_image_030a[3][1] =
				data->default_threshold + data->cal_data;

#endif
		else
			gp2a_original_image[3][1] =
				data->default_threshold + data->cal_data;

		pr_info("%s: prox_cal = %d, prox_thresh = 0x%x\n",
			__func__, data->cal_data, (is_gp2a030a() ?
				gp2a_original_image_030a[3][1] :
				gp2a_original_image[3][1]));
	}

	filp_close(cancel_filp, current->files);
	set_fs(old_fs);

	return err;
}
static ssize_t proximity_name_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{

	return is_gp2a030a() ? sprintf(buf, "%s030\n", CHIP_ID)
		: sprintf(buf, "%s020\n", CHIP_ID);
}
static ssize_t proximity_thresh_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t size)
{
	unsigned long threshold;
	int err = 0;

	err = strict_strtoul(buf, 10, &threshold);

	if (err) {
		pr_err("%s, conversion %s to number.\n",
			__func__, buf);
		return err;
	}

	err = gp2a_update_threshold(is_gp2a030a() ?
			gp2a_original_image_030a : gp2a_original_image,
			threshold, true);

	if (err) {
		pr_err("gp2a threshold(with register) update fail.\n");
		return err;
	}

	return size;
}
示例#6
0
static ssize_t proximity_thresh_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t size)
{
	struct gp2a_data *data = dev_get_drvdata(dev);
	u8 threshold = 0;
	int err = 0;

	err = kstrtou8(buf, 10, &threshold);

	if (err) {
		pr_err("%s, conversion %s to number.\n",
			__func__, buf);
		return err;
	}

	err = gp2a_update_threshold(data, is_gp2a030a() ?
			gp2a_original_image_030a : gp2a_original_image,
			threshold, true);

	if (err) {
		pr_err("gp2a threshold(with register) update fail.\n");
		return err;
	}

	return size;
}
示例#7
0
static void gp2a_work_func_light(struct work_struct *work)
{
	struct sensor_data *data = container_of((struct delayed_work *)work,
						struct sensor_data, work);
	int i;
	int adc = 0;

	adc = lightsensor_get_adcvalue();

	if (is_gp2a030a()) {
		for (i = 0; ARRAY_SIZE(adc_table_030a); i++)
			if (adc <= adc_table_030a[i])
				break;
	} else {
		for (i = 0; ARRAY_SIZE(adc_table); i++)
			if (adc <= adc_table[i])
				break;
	}

	if (data->light_buffer == i) {
		if (data->light_count++ == LIGHT_BUFFER_NUM) {
			input_report_rel(data->input_dev, REL_MISC, adc);
			input_sync(data->input_dev);
			data->light_count = 0;
		}
	} else {
		data->light_buffer = i;
		data->light_count = 0;
	}

	if (data->enabled)
		queue_delayed_work(data->wq, &data->work,
				   msecs_to_jiffies(data->delay));
}
示例#8
0
static ssize_t proximity_cal_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	struct gp2a_data *data = dev_get_drvdata(dev);

	return sprintf(buf, "%d,%d\n", data->cal_data, (is_gp2a030a() ?
			gp2a_original_image_030a[3][1] :
			gp2a_original_image[3][1]));
}
示例#9
0
static ssize_t proximity_cal_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	struct gp2a_data *data = dev_get_drvdata(dev);
#if defined(CONFIG_MACH_KONA_SENSOR)
	return sprintf(buf, "%d,%d\n", data->cal_data,
			gp2a_original_image_030a[5][1]);
#else
	return sprintf(buf, "%d,%d\n", data->cal_data, (is_gp2a030a() ?
			gp2a_original_image_030a[5][1] :
			gp2a_original_image[5][1]));
#endif
}
static ssize_t proximity_thresh_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	int i;
	int threshold = 0;
	u8 (*selected_image)[2] = (is_gp2a030a() ?
			gp2a_original_image_030a : gp2a_original_image);

	for (i = 0; i < COL; i++) {
		if (selected_image[i][0] == 0x08)
			/*PS mode LTH(Loff) */
			threshold = selected_image[i][1];
		else if (selected_image[i][0] == 0x09)
			/*PS mode LTH(Loff) */
			threshold |= selected_image[i][1]<<8;
	}

	return sprintf(buf, "prox_threshold = %d\n", threshold);
}
static int proximity_onoff(u8 onoff)
{
	u8 value;
	int i;
	int err = 0;

#ifdef DEBUG
	gprintk("proximity turn on/off = %d\n", onoff);
#endif

	/* already on light sensor, so must simultaneously
	   turn on light sensor and proximity sensor */
	if (onoff) {
		for (i = 0; i < COL; i++) {
			if (is_gp2a030a())
				err =
				    opt_i2c_write(gp2a_original_image_030a[i][0]
					, &gp2a_original_image_030a[i][1]);
			else
				err =
				    opt_i2c_write(gp2a_original_image[i][0],
						  &gp2a_original_image[i][1]);
			if (err < 0)
				printk(KERN_ERR
				      "%s : turnning on error i = %d, err=%d\n",
				       __func__, i, err);
			lightsensor_mode = 0;
		}
	} else { /* light sensor turn on and proximity turn off */
		if (lightsensor_mode)
			value = 0x67; /*resolution :16bit, range: *8(HIGH) */
		else
			value = 0x63; /* resolution :16bit, range: *128(LOW) */
		opt_i2c_write(COMMAND2, &value);
		/* OP3 : 1(operating mode)
		   OP2 :1(coutinuous operating mode) OP1 : 01(ALS mode) */
		value = 0xD0;
		opt_i2c_write(COMMAND1, &value);
	}

	return 0;
}
static int gp2a_opt_probe(struct platform_device *pdev)
{
	struct gp2a_data *gp2a;
	struct gp2a_platform_data *pdata = pdev->dev.platform_data;
	u8 value = 0;
	int err = 0;

	gprintk("probe start!\n");

	if (!pdata) {
		pr_err("%s: missing pdata!\n", __func__);
		return err;
	}

	if (!pdata->gp2a_led_on) {
		pr_err("%s: incomplete pdata!\n", __func__);
		return err;
	}
	/* gp2a power on */
	pdata->gp2a_led_on(true);

	if (pdata->gp2a_get_threshold) {
		gp2a_update_threshold(is_gp2a030a() ?
			gp2a_original_image_030a : gp2a_original_image,
			pdata->gp2a_get_threshold(), false);
	}

	/* allocate driver_data */
	gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
	if (!gp2a) {
		pr_err("kzalloc error\n");
		return -ENOMEM;
	}

	proximity_enable = 0;
	proximity_sensor_detection = 0;
	proximity_avg_on = 0;
	gp2a->enabled = 0;
	gp2a->pdata = pdata;

	/* prox_timer settings. we poll for prox_avg values using a timer. */
	hrtimer_init(&gp2a->prox_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	gp2a->prox_poll_delay = ns_to_ktime(2000 * NSEC_PER_MSEC);
	gp2a->prox_timer.function = gp2a_prox_timer_func;

	gp2a->prox_wq = create_singlethread_workqueue("gp2a_prox_wq");
	if (!gp2a->prox_wq) {
		err = -ENOMEM;
		pr_err("%s: could not create prox workqueue\n", __func__);
		goto err_create_prox_workqueue;
	}

	INIT_WORK(&gp2a->work_prox, gp2a_work_func_prox_avg);
	INIT_WORK(&gp2a->work, gp2a_work_func_prox);

	err = proximity_input_init(gp2a);
	if (err < 0)
		goto error_setup_reg;

	err = sysfs_create_group(&gp2a->input_dev->dev.kobj,
				 &proximity_attribute_group);
	if (err < 0)
		goto err_sysfs_create_group_proximity;

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

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

	/* init i2c */
	opt_i2c_init();

	if (opt_i2c_client == NULL) {
		pr_err("opt_probe failed : i2c_client is NULL\n");
		goto err_no_device;
	} else
		printk(KERN_INFO "opt_i2c_client : (0x%p), address = %x\n",
		       opt_i2c_client, opt_i2c_client->addr);

	/* GP2A Regs INIT SETTINGS  and Check I2C communication */
	value = 0x00;
	/* shutdown mode op[3]=0 */
	err = opt_i2c_write((u8) (COMMAND1), &value);

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

	/* Setup irq */
	err = gp2a_setup_irq(gp2a);
	if (err) {
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}

	/* set sysfs for proximity sensor */
	gp2a->proximity_dev = sensors_classdev_register("proximity_sensor");
	if (IS_ERR(gp2a->proximity_dev)) {
		pr_err("%s: could not create proximity_dev\n", __func__);
		goto err_proximity_device_create;
	}

	if (device_create_file(gp2a->proximity_dev, &dev_attr_state) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_state.attr.name);
		goto err_proximity_device_create_file1;
	}

	if (device_create_file(gp2a->proximity_dev, &dev_attr_prox_avg) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_prox_avg.attr.name);
		goto err_proximity_device_create_file2;
	}

	if (device_create_file(gp2a->proximity_dev,
						&dev_attr_prox_thresh) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_prox_thresh.attr.name);
		goto err_proximity_device_create_file3;
	}

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

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

	if (device_create_file(gp2a->proximity_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_proximity_device_create_file6;
	}

#ifdef CONFIG_SLP
	device_init_wakeup(gp2a->proximity_dev, true);
#endif
	dev_set_drvdata(gp2a->proximity_dev, gp2a);

	device_init_wakeup(&pdev->dev, 1);

	gprintk("probe success!\n");

	return 0;

err_proximity_device_create_file6:
	device_remove_file(gp2a->proximity_dev, &dev_attr_raw_data);
err_proximity_device_create_file5:
	device_remove_file(gp2a->proximity_dev, &dev_attr_name);
err_proximity_device_create_file4:
	device_remove_file(gp2a->proximity_dev, &dev_attr_vendor);
err_proximity_device_create_file3:
	device_remove_file(gp2a->proximity_dev, &dev_attr_prox_avg);
err_proximity_device_create_file2:
	device_remove_file(gp2a->proximity_dev, &dev_attr_state);
err_proximity_device_create_file1:
	sensors_classdev_unregister(gp2a->proximity_dev);
err_proximity_device_create:
	gpio_free(pdata->p_out);
err_setup_irq:
err_no_device:
	sysfs_remove_group(&gp2a->input_dev->dev.kobj,
			   &proximity_attribute_group);
	wake_lock_destroy(&gp2a->prx_wake_lock);
err_sysfs_create_group_proximity:
	input_unregister_device(gp2a->input_dev);
error_setup_reg:
	destroy_workqueue(gp2a->prox_wq);
err_create_prox_workqueue:
	kfree(gp2a);
	return err;
}
示例#13
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;
}
示例#14
0
static void gp2a_work_func_light(struct work_struct *work)
{
	struct sensor_data *data = container_of((struct delayed_work *)work,
						struct sensor_data, work);
	int i;
	int adc = 0;
#ifdef CONFIG_MACH_BAFFIN
	int count = 0;
#endif

#ifdef CONFIG_MACH_BAFFIN
	while (adc == 0 && count < 5) {
		adc = lightsensor_get_adcvalue(data);
		count++;
	}
#else
	adc = lightsensor_get_adcvalue(data);
#endif

	if (is_gp2a030a()) {
		for (i = 0; ARRAY_SIZE(adc_table_030a); i++)
			if (adc <= adc_table_030a[i])
				break;
	} else {
		for (i = 0; ARRAY_SIZE(adc_table); i++)
			if (adc <= adc_table[i])
				break;
	}

	if (data->light_buffer == i) {
		if (data->light_count++ == LIGHT_BUFFER_NUM) {
			input_report_rel(data->input_dev, REL_MISC,
			(adc ? adc : 1));
			input_sync(data->input_dev);
			data->light_count = 0;
		}
	} else {
		data->light_buffer = i;
		data->light_count = 0;
	}

#if defined(CONFIG_MACH_M3_USA_TMO)
	if (adc == 0) {
		if (data->zero_cnt++ > 25) {
			data->zero_cnt = 0;
			if (data->reset_cnt++ <= LIMIT_RESET_COUNT) {
				lightsensor_onoff(0);
				lightsensor_onoff(1);
				pr_info("%s : lightsensor reset done.\n",
					__func__);
			} else {
				data->reset_cnt = LIMIT_RESET_COUNT + 1;
			}
		}
	} else {
		data->reset_cnt = 0;
		data->zero_cnt = 0;
	}
#endif

	if (data->enabled)
		queue_delayed_work(data->wq, &data->work,
				   msecs_to_jiffies(data->delay));
}