Exemplo n.º 1
0
/* 
 * Setting GP2AP002S00F proximity sensor operation mode, 
 * enable=1-->Normal Operation Mode
 * enable=0-->Shutdown Mode 
 */
static int gp2a_prox_mode(int enable)
{	
	u8 reg_value;
	int ret=0;
	debug("%s called",__func__); 
	if(1==enable)
	{
		
		reg_value = 0x01;
		if((ret=gp2a_i2c_write(GP2A_REG_OPMOD,&reg_value))<0)
			error("gp2a_i2c_write 1 failed");
		
		reg_value = 0x00;
		if((ret=gp2a_i2c_write(GP2A_REG_CON,&reg_value))<0)
			error("gp2a_i2c_write 2 failed");
		
		proximity_enable=1;
	}
	else 
	{
		reg_value = 0x00;
		if((ret=gp2a_i2c_write(GP2A_REG_OPMOD,&reg_value))<0)
			error("gp2a_i2c_write 3 failed");
		
		reg_value = 0x18;
		if((ret=gp2a_i2c_write(GP2A_REG_CON,&reg_value))<0)
			error("gp2a_i2c_write 4 failed");
		
		proximity_enable=0;
	}   
	
	return ret;
}
static int gp2a_proximity_poweroff(void)
{
	u8 val = 0;
	int ret = 0;

#if defined(CONFIG_GP2A_MODE_B)
	disable_irq_nosync(gp2a->irq);
#else
	disable_irq(gp2a->irq);
#endif

#if defined(CONFIG_GP2A_MODE_B)
	// SSD : Software shutdown function ( 0:shutdown mode, 1:opteration mode )
	val = 0x02;	// VCON enable, SSD disable
	ret = gp2a_i2c_write(gp2a->client, GP2A_REG_OPMOD, val);
	//		printk(" %s, %d\n", __func__, __LINE__);
#else		
	val = 0x00;
	ret = gp2a_i2c_write(gp2a->client, GP2A_REG_OPMOD, val);
	//		printk(" %s, %d\n", __func__, __LINE__);
#endif		
	proximity_enable = 0;
	//		printk("OXOXOXOXOX %s, %d\n", __func__, __LINE__);

	return ret;

}
static int lightsensor_onoff(u8 onoff, struct gp2a_data *data)
{
	u8 value;

	pr_debug("%s : light_sensor onoff = %d\n", __func__, onoff);

	if (onoff) {
		/*in calling, must turn on proximity sensor */
		if (data->proximity_enabled == 0) {
			value = 0x01;
			gp2a_i2c_write(data, COMMAND4, &value);
			value = 0x63;
			gp2a_i2c_write(data, COMMAND2, &value);
			/*OP3 : 1(operating mode) OP2 :1
				(coutinuous operating mode)
				OP1 : 01(ALS mode) TYPE=0(auto) */
			value = 0xD0;
			gp2a_i2c_write(data, COMMAND1, &value);
			/* other setting have defualt value. */
		}
	} else {
		/*in calling, must turn on proximity sensor */
		if (data->proximity_enabled == 0) {
			value = 0x00;	/*shutdown mode */
			gp2a_i2c_write(data, (u8) (COMMAND1), &value);
		}
	}

	return 0;
}
static int proximity_onoff(u8 onoff, struct gp2a_data  *data)
{
	u8 value;
	int i;
	int err = 0;

	pr_info("%s : proximity turn on/off = %d\n", __func__, onoff);

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

	return 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;

	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);
}
Exemplo n.º 6
0
static int lightsensor_reset(struct gp2a_data *data)
{
	u8 value;
	int i;
	pr_info("%s\n", __func__);

	if (data->light_enabled) {
		mutex_lock(&data->light_mutex);

		value = 0x01;
		gp2a_i2c_write(data, COMMAND4, &value);
		if (data->lightsensor_mode)
			value = 0x67; /*resolution :16bit, range: *8(HIGH) */
		else
			value = 0x63; /* resolution :16bit, range: *128(LOW) */
		gp2a_i2c_write(data, COMMAND2, &value);

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

		for (i = 0; i < COL; i++) {
			gp2a_i2c_write(data, gp2a_reg[i][0],
				&gp2a_reg[i][1]);
		}

		mutex_unlock(&data->light_mutex);
	}

	return 0;
}
Exemplo n.º 7
0
static ssize_t
proximity_enable_store(struct device *dev,
			struct device_attribute *attr,
			const char *buf, size_t count)
{
	struct gp2a_data *data = dev_get_drvdata(dev);

	int value = 0;
	int err = 0;
	int16_t thrd;
	u8 reg;

	err = kstrtoint(buf, 10, &value);

	if (err) {
		pr_err("%s, kstrtoint failed.", __func__);
		goto done;
	}
	if (value != 0 && value != 1)
		goto done;

        printk(KERN_INFO "[GP2A] proximity_enable_store : value=%d, offset=%d\n", value, data->offset_value);

	if (data->proximity_enabled && !value) {	/* Prox power off */
		data->proximity_enabled = value;
		disable_irq(data->irq);

		proximity_onoff(0, data);
		if (data->pdata->led_on)
			data->pdata->led_on(0);
	}
	if (!data->proximity_enabled && value) {	/* prox power on */
		data->proximity_enabled = value;
		if (data->pdata->led_on)
			data->pdata->led_on(1);
		msleep(5);
		proximity_onoff(1, data);

		thrd = gp2a_reg[3][1]+(data->offset_value);
		THR_REG_LSB(thrd, reg);
		gp2a_i2c_write(gp2a_reg[3][0], &reg);
		THR_REG_MSB(thrd, reg);
		gp2a_i2c_write(gp2a_reg[4][0], &reg);

		thrd = gp2a_reg[5][1]+(data->offset_value);
		THR_REG_LSB(thrd, reg);
		gp2a_i2c_write(gp2a_reg[5][0], &reg);
		THR_REG_MSB(thrd, reg);
		gp2a_i2c_write(gp2a_reg[6][0], &reg);

		input_report_abs(data->proximity_input_dev, ABS_DISTANCE, 1);
		input_sync(data->proximity_input_dev);

		enable_irq(data->irq);
	}
done:
	return count;
}
Exemplo n.º 8
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);
}
Exemplo n.º 9
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);
}
Exemplo n.º 10
0
static int gp2a_proximity_poweron(void)
{
	u8	val;
	int	ret = 0;

	printk(KERN_INFO "[PROXIMITY][%s] start!\n", __func__);

#if !defined(CONFIG_GP2A_MODE_B) 	
	int i;
#endif


#if defined(CONFIG_GP2A_MODE_B)
	// ASD : Select switch for analog sleep function ( 0:ineffective, 1:effective )
	// OCON[1:0] : Select switches for enabling/disabling VOUT terminal 
	//             ( 00:enable, 11:force to go High, 10:forcr to go Low )
	val = 0x18;	// 11:force to go High
	ret = gp2a_i2c_write(gp2a->client, GP2A_REG_CON, val);
	//	printk(" %s, %d\n", __func__, __LINE__);

	val = 0x40;	// HYSD enable
	ret = gp2a_i2c_write(gp2a->client, GP2A_REG_HYS, val);
	//	printk(" %s, %d\n", __func__, __LINE__);


	val = 0x03;	// VCON enable, SSD enable
	ret = gp2a_i2c_write(gp2a->client, GP2A_REG_OPMOD, val);
	//	printk(" %s, %d\n", __func__, __LINE__);

#else
	for(i=1;i<5;i++)
	{
		//opt_i2c_write((u8)(i),&gp2a_original_image[i]);
		gp2a_i2c_write(gp2a->client,i, gp2a_original_image[i]);
	}
#endif		
	proximity_enable = 1;
	enable_irq(gp2a->irq);

#if defined(CONFIG_GP2A_MODE_B)
	val = 0x00;	// 00:enable
	ret = gp2a_i2c_write(gp2a->client, GP2A_REG_CON, val);
#endif	


	input_report_abs(gp2a->prox_input, ABS_DISTANCE, 1);
	input_sync(gp2a->prox_input);



	printk(KERN_INFO "[PROXIMITY][%s] end!\n", __func__);
	return ret;
}
Exemplo n.º 11
0
static int gp2a_prox_manual_offset(struct gp2a_data  *data, u8 change_on)
{
	struct file *cal_filp;
	int err;
	int16_t thrd;
	u8 reg;
	mm_segment_t old_fs;

	data->offset_value = change_on;
	/* update threshold */
	thrd = gp2a_reg[3][1]+(data->offset_value);
	THR_REG_LSB(thrd, reg);
	gp2a_i2c_write(data, gp2a_reg[3][0], &reg);
	THR_REG_MSB(thrd, reg);
	gp2a_i2c_write(data, gp2a_reg[4][0], &reg);

	thrd = gp2a_reg[5][1]+(data->offset_value);
	THR_REG_LSB(thrd, reg);
	gp2a_i2c_write(data, gp2a_reg[5][0], &reg);
	THR_REG_MSB(thrd, reg);
	gp2a_i2c_write(data, gp2a_reg[6][0], &reg);

	/* calibration result */
	data->cal_result = 1;

	old_fs = get_fs();
	set_fs(KERNEL_DS);

	cal_filp = filp_open(CAL_PATH,
			O_CREAT | O_TRUNC | O_WRONLY,
			S_IRUGO | S_IWUSR | S_IWGRP);
	if (IS_ERR(cal_filp)) {
		pr_err("%s Can't open calibration file\n", __func__);
		set_fs(old_fs);
		err = PTR_ERR(cal_filp);
		goto done;
	}

	err = cal_filp->f_op->write(cal_filp,
		(char *)&data->offset_value, sizeof(int),
			&cal_filp->f_pos);
	if (err != sizeof(int)) {
		pr_err("%s Can't write the cal data to file\n",
			__func__);
		err = -EIO;
	}

	filp_close(cal_filp, current->files);
done:
	set_fs(old_fs);
	return err;
}
Exemplo n.º 12
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);
	
}
Exemplo n.º 13
0
static long gp2a_opt_ioctl(struct file *file, unsigned int cmd,  unsigned long arg)
{	
	int ret = 0;
	short data = 0;
	u8 thrd = 0;
	u8 reg;

	switch (cmd)
	{
		case PROX_IOC_SET_CALIBRATION:
		{
			printk(KERN_INFO "[GP2A] PROX_IOC_SET_CALIBRATION\n");                
			if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
				return -EFAULT;

			ret = proximity_open_calibration(gp2a_opt_data);
			if (ret < 0 && ret != -ENOENT)
			{
				printk(KERN_INFO "[GP2A] proximity_open_offset() failed\n");
			}else {
				thrd = gp2a_reg[3][1]+(gp2a_opt_data->offset_value);
				THR_REG_LSB(thrd, reg);
				gp2a_i2c_write(gp2a_reg[3][0], &reg);
				THR_REG_MSB(thrd, reg);
				gp2a_i2c_write(gp2a_reg[4][0], &reg);

				thrd = gp2a_reg[5][1]+(gp2a_opt_data->offset_value);
				THR_REG_LSB(thrd, reg);
				gp2a_i2c_write(gp2a_reg[5][0], &reg);
				THR_REG_MSB(thrd, reg);
				gp2a_i2c_write(gp2a_reg[6][0], &reg);
			}
			break;
		}
		case PROX_IOC_GET_CALIBRATION:
		{
			printk(KERN_INFO "[GP2A] PROX_IOC_GET_CALIBRATION\n");      
			data = gp2a_opt_data->offset_value;
			if (copy_to_user((void __user *)arg, &data, sizeof(data)))
				return -EFAULT;
			break;
		}
		default:
			printk(KERN_ERR "Unknown IOCTL command");
			ret = -ENOTTY;
			break;
	}
	return ret;
}
static int gp2a_setup_irq(struct gp2a_data *gp2a)
{
	int rc;
	struct gp2a_platform_data *pdata = gp2a->pdata;
	int irq = -1;
	u8 value;

	rc = gpio_request(pdata->p_out, "gpio_proximity_out");
	if (rc < 0) {
		pr_err("%s,gpio %d request failed (%d)\n",
			__func__, pdata->p_out, rc);
		return rc;
	}

	rc = gpio_direction_input(pdata->p_out);
	if (rc < 0) {
		pr_err("%s,failed gpio %d as input (%d)\n",
			__func__, pdata->p_out, rc);
		goto err_gpio_direction_input;
	}

	value = 0x18;
	gp2a_i2c_write(gp2a, REGS_CON, value);
	irq = gpio_to_irq(pdata->p_out);
	rc = request_irq(irq, gp2a_irq_handler, IRQF_TRIGGER_FALLING,
					"proximity_int", gp2a);

	if (rc < 0) {
		pr_err("%s,request_irq(%d) failed for gpio %d (%d)\n",
			__func__, irq,
			pdata->p_out, rc);
		goto err_request_irq;
	} else{
		pr_info("%s,request_irq(%d) success for gpio %d\n",
			__func__, irq, pdata->p_out);
	}
	disable_irq(irq);
	gp2a->irq = irq;

	value = 0x02;
	gp2a_i2c_write(gp2a, REGS_OPMOD, value);
	goto done;

err_request_irq:
err_gpio_direction_input:
	gpio_free(pdata->p_out);
done:
	return rc;
}
Exemplo n.º 15
0
static ssize_t prox_cal_write(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t size)
{
	struct gp2a_data *gp2a = dev_get_drvdata(dev);
	u8 value;
	int err;

	if (sysfs_streq(buf, "1")) {
		gp2a->cal_mode = 1;
		nondetect = PROX_NONDETECT_MODE1;
		detect = PROX_DETECT_MODE1;
	} else if (sysfs_streq(buf, "2")) {
		gp2a->cal_mode = 2;
		nondetect = PROX_NONDETECT_MODE2;
		detect = PROX_DETECT_MODE2;
	} else if (sysfs_streq(buf, "0")) {
		gp2a->cal_mode = 0;
		nondetect = PROX_NONDETECT;
		detect = PROX_DETECT;
	} else {
		pr_err("%s: invalid value %d\n", __func__, *buf);
		return -EINVAL;
	}

#if defined(CONFIG_MACH_KYLE)
	value = 0x00;
#else
	value = 0x08;
#endif
	gp2a_i2c_write(gp2a, REGS_GAIN, &value);
	value = nondetect;
	gp2a_i2c_write(gp2a, REGS_HYS, &value);
	value = 0x04;
	gp2a_i2c_write(gp2a, REGS_CYCLE, &value);
	value = 0x03;
	gp2a_i2c_write(gp2a, REGS_OPMOD, &value);
	value = 0x00;
	gp2a_i2c_write(gp2a, REGS_CON, &value);

	err = gp2a_cal_mode_save_file(gp2a->cal_mode);

	if (err < 0) {
		pr_err("%s: prox_cal_write() failed\n", __func__);
		return err;
	}

	return size;
}
Exemplo n.º 16
0
/* interrupt happened due to transition/change of near/far proximity state */
irqreturn_t gp2a_irq_handler(int irq, void *data)
{
	struct gp2a_data *ip = data;

#ifdef GP2A_MODE_B
/* GP2A MODE B */
	queue_work(ip->wq, &ip->work_proximity);
#else
/* GP2A MODE A */
	u8 setting;
	int val = gpio_get_value(ip->pdata->p_out);
	if (val < 0) {
		pr_err("%s: gpio_get_value error %d\n", __func__, val);
		return IRQ_HANDLED;
	}

	if (val != ip->prox_value) {
		if (val)
			setting = VO_0;
		else
			setting = VO_1;
		gp2a_i2c_write(ip, REGS_HYS, &setting);
	}

	ip->prox_value = val;
	pr_err("gp2a: proximity val = %d\n", val);

	/* 0 is close, 1 is far */
	input_report_abs(ip->proximity_input_dev, ABS_DISTANCE, val);
	input_sync(ip->proximity_input_dev);
	wake_lock_timeout(&ip->prx_wake_lock, 3*HZ);
#endif
	return IRQ_HANDLED;
}
Exemplo n.º 17
0
static int gp2a_i2c_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct gp2a_data *gp2a = i2c_get_clientdata(client);
	u8 value;

	mutex_lock(&gp2a->light_mutex);
	if (gp2a->light_enabled)
		cancel_delayed_work_sync(&gp2a->light_work);

	mutex_unlock(&gp2a->light_mutex);
	if (gp2a->proximity_enabled) {
			/*enable_irq_wake(gp2a->irq); already wake irq enabled */
	} else {
		value = 0x00;	/*shutdown mode */
		gp2a_i2c_write(gp2a, (u8) (COMMAND1), &value);

		gpio_free(gp2a->pdata->p_out);
		sensor_power_on_vdd(gp2a,0);
		//if (gp2a->pdata->power_on)
		//	gp2a->pdata->power_on(0);
	}

	return 0;
}
Exemplo n.º 18
0
/* interrupt happened due to transition/change of near/far proximity state */
irqreturn_t gp2a_irq_handler(int irq, void *data)
{
	struct gp2a_data *ip = data;
	u8 setting;
	int val = gpio_get_value(ip->pdata->p_out);
	if (val < 0) {
		pr_err("%s: gpio_get_value error %d\n", __func__, val);
		return IRQ_HANDLED;
	}

	if (val != ip->val_state) {
		if (val)
			setting = 0x40;
		else
			setting = 0x20;
		gp2a_i2c_write(ip, REGS_HYS, &setting);
	}

	ip->val_state = val;
	pr_err("gp2a: proximity val = %d\n", val);

	/* 0 is close, 1 is far */
	input_report_abs(ip->proximity_input_dev, ABS_DISTANCE, val);
	input_sync(ip->proximity_input_dev);
	wake_lock_timeout(&ip->prx_wake_lock, 3*HZ);

	return IRQ_HANDLED;
}
Exemplo n.º 19
0
static void gp2a_work_func_proximity(struct work_struct *work)
{
	int	ret;
	u8 value;
	u8 vout = 0;

	struct gp2a_data *gp2a = container_of(work, struct gp2a_data,
					work_proximity);
	pr_info("%s : gp2a mode b", __func__);

	mutex_lock(&gp2a->power_mutex);
	/* GP2A initialized and powered on => do the job */
	ret = gpio_get_value(gp2a->pdata->p_out);

	if (ret < 0) {
		pr_info("Failed to get GP2A proximity value "
				"[errno=%d]; ignored", ret);
	} else {
		gp2a->prox_value = ret;

		if (GP2A_BIT_PROX_VO_DETECTION == gp2a->prox_value) {
			ret = GP2A_INPUT_RANGE_MIN;
			pr_info("GP2A_INPUT_RANGE_MIN");
		} else {
			ret = GP2A_INPUT_RANGE_MAX;
			pr_info("GP2A_INPUT_RANGE_MAX");
		}
		input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, ret);
		input_sync(gp2a->proximity_input_dev);
		pr_info("input_report_abs proximity_input_dev");
	}

	if (ret)
		value = VO_0;
	else
		value = VO_1;

	pr_info("value = 0x%x\n", value);

	gp2a_i2c_write(gp2a, REGS_HYS, &value);

	/* enabling VOUT terminal in nomal operation */
	value = 0x00;
	gp2a_i2c_write(gp2a, REGS_CON, &value);

	mutex_unlock(&gp2a->power_mutex);
}
static void gp2a_work_func_prox(struct work_struct *work)
{
	struct gp2a_data *gp2a = container_of((struct work_struct *)work,
					struct gp2a_data, proximity_work);

	unsigned char value;
	char result;
	int ret;

	/* 0 : proximity, 1 : away */
	result = gpio_get_value_cansleep(gp2a->pdata->p_out);
	gp2a->proximity_detection = !result;

	input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, result);
	pr_info("%s Proximity values = %d\n", __func__, result);
	input_sync(gp2a->proximity_input_dev);

	disable_irq(gp2a->irq);

	/*Software reset */
	value = 0x0C;
	ret = gp2a_i2c_write(gp2a, COMMAND1, &value);

	if (result == 0) {	/* detection = Falling Edge */
		if (gp2a->lightsensor_mode == 0)	/* Low mode */
			value = 0x23;
		else		/* High mode */
			value = 0x27;
		ret = gp2a_i2c_write(gp2a, COMMAND2, &value);
	} else {		/* none Detection */
		if (gp2a->lightsensor_mode == 0)	/* Low mode */
			value = 0x63;
		else		/* High mode */
			value = 0x67;
		ret = gp2a_i2c_write(gp2a, COMMAND2, &value);
	}

	enable_irq(gp2a->irq);

	value = 0xCC;
	ret = gp2a_i2c_write(gp2a, COMMAND1, &value);

	gp2a->prox_data = result;
	pr_debug("proximity = %d, lightsensor_mode=%d\n",
		result, gp2a->lightsensor_mode);
}
static int gp2a_power_onoff(struct gp2a_data *gp2a, int power)
{
	u8 value;
	pr_info("%s,status(%d)\n", __func__, power);

	if (power) {
		gp2a_leda_onoff(gp2a, power);
		value = 0x18;
		gp2a_i2c_write(gp2a, REGS_CON, value);
		value = 0x08;
		gp2a_i2c_write(gp2a, REGS_GAIN, value);
		value = gp2a->nondetect;
		gp2a_i2c_write(gp2a, REGS_HYS, value);
		value = 0x04;
		gp2a_i2c_write(gp2a, REGS_CYCLE, value);
		value = 0x03;
		gp2a_i2c_write(gp2a, REGS_OPMOD, value);

		enable_irq_wake(gp2a->irq);
		enable_irq(gp2a->irq);

		value = 0x00;
		gp2a_i2c_write(gp2a, REGS_CON, value);
	} else {
		disable_irq_wake(gp2a->irq);
		disable_irq(gp2a->irq);

		value = 0x02;
		gp2a_i2c_write(gp2a, REGS_OPMOD, value);
		gp2a_leda_onoff(gp2a, power);
	}
	return 0;
}
Exemplo n.º 22
0
static int gp2a_prox_onoff(u8 onoff, struct gp2a_data  *data)
{
	u8 value;

	pr_info("%s : proximity turn on/off = %d\n", __func__, onoff);

	/* already on light sensor, so must simultaneously
		turn on light sensor and proximity sensor */
	if (onoff) {
		int i;
#ifndef CONFIG_SEC_BERLUTI_PROJECT
		gpio_set_value(data->vled_gpio, 1);
#endif

		for (i = 0; i < COL; i++) {
			int err = gp2a_i2c_write(data, gp2a_reg[i][0],
				&gp2a_reg[i][1]);
			if (err < 0)
				pr_err("%s : turnning on error i = %d, err=%d\n",
					__func__, i, err);
			data->lightsensor_mode = 0;
		}
	} else {
		if (data->light_enabled) {
			if (data->lightsensor_mode)
				value = 0x67; /*resolution :16bit, range: *8(HIGH) */
			else
				value = 0x63; /* resolution :16bit, range: *128(LOW) */
			gp2a_i2c_write(data, COMMAND2, &value);
			/* OP3 : 1(operating mode)
			   OP2 : 1(coutinuous operating mode) OP1 : 01(ALS mode) */
			value = 0xD0;
			gp2a_i2c_write(data, COMMAND1, &value);
		} else {
			value = 0x00;	/*shutdown mode */
			gp2a_i2c_write(data, (u8) (COMMAND1), &value);
		}
#ifndef CONFIG_SEC_BERLUTI_PROJECT
		gpio_set_value(data->vled_gpio, 0);
#endif
	}

	return 0;
}
Exemplo n.º 23
0
static ssize_t proximity_enable_store(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t size)
{
	struct gp2a_data *gp2a = dev_get_drvdata(dev);
	bool new_value;

	if (sysfs_streq(buf, "1"))
		new_value = true;
	else if (sysfs_streq(buf, "0"))
		new_value = false;
	else {
		pr_err("%s: invalid value %d\n", __func__, *buf);
		return -EINVAL;
	}
#ifdef CONFIG_TOUCH_WAKE
	if (!new_value)
	  proximity_off();
#endif
	mutex_lock(&gp2a->power_lock);
	gp2a_dbgmsg("new_value = %d, old state = %d\n",
		    new_value, (gp2a->power_state & PROXIMITY_ENABLED) ? 1 : 0);
	if (new_value && !(gp2a->power_state & PROXIMITY_ENABLED)) {
		if (!gp2a->power_state)
			gp2a->pdata->power(true);
		gp2a->power_state |= PROXIMITY_ENABLED;
		enable_irq(gp2a->irq);
		enable_irq_wake(gp2a->irq);
		gp2a_i2c_write(gp2a, REGS_GAIN, &reg_defaults[1]);
		gp2a_i2c_write(gp2a, REGS_HYS, &reg_defaults[2]);
		gp2a_i2c_write(gp2a, REGS_CYCLE, &reg_defaults[3]);
		gp2a_i2c_write(gp2a, REGS_OPMOD, &reg_defaults[4]);
	} else if (!new_value && (gp2a->power_state & PROXIMITY_ENABLED)) {
		disable_irq_wake(gp2a->irq);
		disable_irq(gp2a->irq);
		gp2a_i2c_write(gp2a, REGS_OPMOD, &reg_defaults[0]);
		gp2a->power_state &= ~PROXIMITY_ENABLED;
		if (!gp2a->power_state)
			gp2a->pdata->power(false);
	}
	mutex_unlock(&gp2a->power_lock);
	return size;
}
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);
}
Exemplo n.º 25
0
static int gp2a_prox_cal_mode(char mode)
{
	int ret=0;
	u8 reg_value;

	if (mode == 1) 
        {
		nondetect = PROX_NONDETECT_MODE1;
		detect = PROX_DETECT_MODE1;
	} 
        else if (mode == 2) 
        {
		nondetect = PROX_NONDETECT_MODE2;
		detect = PROX_DETECT_MODE2;
	} 
        else
        {
		nondetect = PROX_NONDETECT;
		detect = PROX_DETECT;
	} 
    
	reg_value = 0x08;
	if((ret=gp2a_i2c_write(GP2A_REG_GAIN/*0x01*/,&reg_value))<0)
			error("gp2a_i2c_write 1 failed\n");

        gp2a_prox_offset(0);
        
	reg_value = 0x04;
	if((ret=gp2a_i2c_write(GP2A_REG_CYCLE/*0x03*/,&reg_value))<0)
			error("gp2a_i2c_write 3 failed\n");

	reg_value = 0x03;
	if((ret=gp2a_i2c_write(GP2A_REG_OPMOD,&reg_value))<0)
		error("gp2a_i2c_write 3 failed");

	reg_value = 0x00;
	if((ret=gp2a_i2c_write(GP2A_REG_CON,&reg_value))<0)
		error("gp2a_i2c_write 4 failed");

        return ret;

}
/* 
* Operation Mode B
* Initiate operation
*/
static int gp2a_prox_reset(void)
{
    	u8 reg_value;
	int ret=0;
	debug("[GP2A] %s called\n",__func__); 
/* 
        Procedure 1: After Power Supply is turned on, setup the following register
        01H GAIN - 0x08
        02H HYS - 0x40
        03H CYCLE - 0x04
        04H OPMOD - 0x03
        Procedure 2: Permit host's interrupt input
        Procedure 3 : VOUT terminal changes from "H" to "L"
        Procedure 4 : Forbit host's interrupt input
        Procedure 5 : Read VO value through I2C bus interface, VO=0 : no detection, VO=1 : detection
        Procedure 6 : Write HYS register through I2C bus interface
        Procedure 7 : Set 06H CON register as follows, forcing VOUT terminal to go H.
        06H CON - 0x18
        Procedure 8 : Permit host's interrupt input
        Prodecure 9 : Set 06H CON register as follows, enabling VOUT terminal in normal operation
        06H CON - 0x00
        Prodecure 10 : Repeat procedures from 3 to 9
*/
	reg_value = 0x18;
	if((ret=gp2a_i2c_write(GP2A_REG_CON/*0x06*/,&reg_value))<0)
			error("gp2a_i2c_write 4 failed\n");	
    
	reg_value = 0x08;
	if((ret=gp2a_i2c_write(GP2A_REG_GAIN/*0x01*/,&reg_value))<0)
			error("gp2a_i2c_write 1 failed\n");

	reg_value = 0x40;
	if((ret=gp2a_i2c_write(GP2A_REG_HYS/*0x02*/,&reg_value))<0)
			error("gp2a_i2c_write 2 failed\n");

	reg_value = 0x04;
	if((ret=gp2a_i2c_write(GP2A_REG_CYCLE/*0x03*/,&reg_value))<0)
			error("gp2a_i2c_write 3 failed\n");
	
	return ret;
}
Exemplo n.º 27
0
static int gp2a_prox_mode(int enable)
{	
	u8 reg_value;
	int ret=0;
	debug("%s called\n",__func__); 
    
	if(1==enable)
	{
		reg_value = 0x18;
		if((ret=gp2a_i2c_write(GP2A_REG_CON,&reg_value))<0)
			error("gp2a_i2c_write 1 failed");
		
                gp2a_prox_offset(0);
        
		reg_value = 0x03;
		if((ret=gp2a_i2c_write(GP2A_REG_OPMOD,&reg_value))<0)
			error("gp2a_i2c_write 3 failed");

		enable_irq(gp2a_data->irq);
		
		reg_value = 0x00;
		if((ret=gp2a_i2c_write(GP2A_REG_CON,&reg_value))<0)
			error("gp2a_i2c_write 4 failed");
		
		proximity_enable=1;
	}
	else 
	{
		disable_irq_nosync(gp2a_data->irq);

		reg_value = 0x02;
		if((ret=gp2a_i2c_write(GP2A_REG_OPMOD,&reg_value))<0)
			error("gp2a_i2c_write 3 failed");
		
		proximity_enable=0;
                proximity_value = 0;
	}   
	
	return ret;
}
Exemplo n.º 28
0
static int gp2a_prox_reset(void)
{
    	u8 reg_value;
	int ret=0;
	debug("[GP2A] %s called\n",__func__); 

	reg_value = 0x18;
	if((ret=gp2a_i2c_write(GP2A_REG_CON/*0x06*/,&reg_value))<0)
			error("gp2a_i2c_write 4 failed\n");	
    
	reg_value = 0x08;
	if((ret=gp2a_i2c_write(GP2A_REG_GAIN/*0x01*/,&reg_value))<0)
			error("gp2a_i2c_write 1 failed\n");

        gp2a_prox_offset(0);
        
	reg_value = 0x04;
	if((ret=gp2a_i2c_write(GP2A_REG_CYCLE/*0x03*/,&reg_value))<0)
			error("gp2a_i2c_write 3 failed\n");
	
	return ret;
}
Exemplo n.º 29
0
static ssize_t proximity_enable_store(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf, size_t size)
{
	struct gp2a_data *gp2a = dev_get_drvdata(dev);
	bool new_value;

	if (sysfs_streq(buf, "1"))
		new_value = true;
	else if (sysfs_streq(buf, "0"))
		new_value = false;
	else {
		pr_err("%s: invalid value %d\n", __func__, *buf);
		return -EINVAL;
	}

	mutex_lock(&gp2a->power_lock);
	gp2a_dbgmsg("new_value = %d, old state = %d\n", new_value, gp2a->on);
	if (new_value && !gp2a->on) {
		gp2a->pdata->power(true);
		gp2a->on = true;
		enable_irq(gp2a->irq);
		enable_irq_wake(gp2a->irq);
		gp2a_i2c_write(gp2a, REGS_GAIN, &reg_defaults[1]);
		gp2a_i2c_write(gp2a, REGS_HYS, &reg_defaults[2]);
		gp2a_i2c_write(gp2a, REGS_CYCLE, &reg_defaults[3]);
		gp2a_i2c_write(gp2a, REGS_OPMOD, &reg_defaults[4]);
	} else if (!new_value && gp2a->on) {
		disable_irq_wake(gp2a->irq);
		disable_irq(gp2a->irq);
		gp2a_i2c_write(gp2a, REGS_OPMOD, &reg_defaults[0]);
		gp2a->on = false;
		gp2a->pdata->power(false);
	}
	mutex_unlock(&gp2a->power_lock);
	return size;
}
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);
}