コード例 #1
0
static int lightsensor_onoff(u8 onoff)
{
	u8 value = 0;

#ifdef DEBUG
	gprintk("lightsensor_onoff = %d\n", onoff);
	gprintk("proximity_enable onoff = %d\n", proximity_enable);
#endif

	if (onoff) {
		/*in calling, must turn on proximity sensor */
		if (proximity_enable == 0) {
			value = 0x01;
			opt_i2c_write(COMMAND4, &value);

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

	return 0;
}
コード例 #2
0
static int gp2a_opt_resume(struct i2c_client *client) {
	struct gp2a_data *gp2a = i2c_get_clientdata(client);
	int i;

	gprintk("resume, proximity_enable:%d\n", proximity_enable);

//20110702 [email protected] nothing [S]
#if defined(CONFIG_LU6500) || defined(CONFIG_KS1001) || defined(CONFIG_KS1103) || defined (CONFIG_SU880) || defined (CONFIG_KU8800) || defined (CONFIG_LU8800)
	// nothing
#else
	if(!proximity_enable) {

		/* GP2A Regs INIT SETTINGS */
		for(i=1; i<=4; i++) 
			opt_i2c_write(gp2a, (u8)(i), gp2a_original_image[i]);
		
		//20111001 [email protected] : Set Operation mode B1 for X2 New HW Revision [S]
		//Shutdown Mode(0x02) -> Operation Mode(ox03) Procedure 1~5
		opt_i2c_write(gp2a, (u8)(REGS_CON),  0x18);//1
		opt_i2c_write(gp2a, (u8)(REGS_HYS),  0x40);//2
		opt_i2c_write(gp2a, (u8)(REGS_OPMOD),  0x03);//3

		enable_irq(gp2a->irq);//4
		msleep(2);
		opt_i2c_write(gp2a, (u8)(REGS_CON),  0x00);//5
		//20111001 [email protected] : Set Operation mode B1 for X2 New HW Revision [E]	

		proximity_enable = ON;
	}
#endif
//20110702 [email protected] nothing [E]

	return 0;
}
コード例 #3
0
static int lightsensor_onoff(u8 onoff, struct gp2a_data *data)
{
	u8 value;

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

	return 0;
}
コード例 #4
0
static void gp2a_on(struct gp2a_data *gp2a, int type)
{
	u8 value;
	printk(KERN_INFO "[OPTICAL] gp2a_on(%d)\n",type);
	if(type == PROXIMITY)
	{
		gprintk("[PROXIMITY] go nomal mode : power on \n");
		value = 0x18;
		opt_i2c_write((u8)(REGS_CON),&value);

		value = 0x40;
		opt_i2c_write((u8)(REGS_HYS),&value);

		value = 0x03;
		opt_i2c_write((u8)(REGS_OPMOD),&value);

		gprintk("enable irq for proximity\n");
		enable_irq(gp2a ->irq);

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

		proximity_enable =1;
	}
	if(type == LIGHT)
	{
		light_enable = ON;
		printk(KERN_INFO "[LIGHT_SENSOR] timer start for light sensor\n");
	    hrtimer_start(&gp2a->timer,ktime_set(light_init_period/2,0),HRTIMER_MODE_REL);
	}
}
コード例 #5
0
static int gp2a_opt_resume(struct i2c_client *client)
{
	int config = 0;
	int err = 0;

	printk("[HSIL] %s\n", __func__);
	if(!proximity_enable)
	{
#if defined(CONFIG_MACH_TOTORO_CTC) && (CONFIG_BOARD_REVISION >= 0x02) //twkim add proximity sensor driver to totoro_ctc
#else
		config = GPIO_CFG(VIR_LED_EN, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA);
		err = gpio_tlmm_config(config, GPIO_CFG_ENABLE);
		if (err) 
			printk(KERN_ERR "%s: gpio_tlmm_config(%#x)=%d\n", __func__, VIR_LED_EN, err);
#endif
		config = GPIO_CFG(GPIO_SENSE_OUT, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA);
		err = gpio_tlmm_config(config, GPIO_CFG_ENABLE);
		if (err) 
			printk(KERN_ERR "%s: gpio_tlmm_config(%#x)=%d\n", __func__, GPIO_SENSE_OUT, err);
#if defined(CONFIG_MACH_TOTORO_CTC) && (CONFIG_BOARD_REVISION >= 0x02) //twkim add proximity sensor driver to totoro_ctc
#else
		gpio_set_value(VIR_LED_EN, 1);
#endif
	}
#if 0
	/* wake_up source handler */
	if(proximity_enable)
	{
		value = 0x18;
		opt_i2c_write((u8)(REGS_CON),&value);

		value = 0x40;
		opt_i2c_write((u8)(REGS_HYS),&value);
		
		
		value = 0x03;
		opt_i2c_write((u8)(REGS_OPMOD),&value);

		enable_irq(gp2a->irq);
		
		value = 0x00;
		opt_i2c_write((u8)(REGS_CON),&value);

	       wake_lock_timeout(&prx_wake_lock,3 * HZ);
		timeA = ktime_get();
		printk("[%s] : wake_lock_timeout 3 Sec \n",__func__);

		/*
		if(!gpio_get_value(GPIO_PS_VOUT))
		{
			gp2a_irq_handler(gp2a->irq,gp2a);
			

		}
		*/
	}
#endif
	return 0;
}
コード例 #6
0
static ssize_t
proximity_enable_store(struct device *dev,
                       struct device_attribute *attr, const char *buf, size_t count)
{
    struct input_dev *input_data = to_input_dev(dev);
    struct gp2a_data *data = input_get_drvdata(input_data);
    int value = simple_strtoul(buf, NULL, 10);
    char input;
    unsigned long flags;

    if (value != 0 && value != 1)
        return count;

    /* Proximity power off */
    if (data->enabled && !value) {
        disable_irq(data->irq);

        proximity_onoff(0);
        disable_irq_wake(data->irq);
        if (data->gp2a_led_on)
            data->gp2a_led_on(0);
        if (data->power_on)
            data->power_on(0);
    }
    /* proximity power on */
    if (!data->enabled && value) {
        if (data->power_on)
            data->power_on(1);
        if (data->gp2a_led_on)
            data->gp2a_led_on(1);
        msleep(1);
        proximity_onoff(1);

        input = 0x01;
        opt_i2c_write((u8)(REGS_OPMOD), &input);

        msleep(50);
        enable_irq_wake(data->irq);
        input = gpio_get_value_cansleep(data->ps_status);
        input_report_abs(data->input_dev, ABS_DISTANCE,  input);

        input_sync(data->input_dev);
        gprintk("[PROX] Start proximity = %d\n", input);
        spin_lock_irqsave(&data->prox_lock, flags);
        input = 0x03;
        opt_i2c_write((u8)(REGS_OPMOD), &input);

        enable_irq(data->irq);

        spin_unlock_irqrestore(&data->prox_lock, flags);
    }

    data->enabled = value;
    input_report_abs(input_data, ABS_CONTROL_REPORT,
                     (value<<16) | data->delay);
    return count;
}
コード例 #7
0
static int gp2a_opt_resume( struct platform_device* pdev )
{

	struct gp2a_data *gp2a = platform_get_drvdata(pdev);
	u8 value;
	
	printk("[%s] : \n",__func__);
	/* wake_up source handler */
	if(proximity_enable)
	{
		value = 0x18;
		opt_i2c_write((u8)(REGS_CON),&value);

		value = 0x40;
		opt_i2c_write((u8)(REGS_HYS),&value);

		value = 0x03;
		opt_i2c_write((u8)(REGS_OPMOD),&value);


		enable_irq(gp2a->irq);


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

		

	    wake_lock_timeout(&prx_wake_lock,3 * HZ);
		timeA = ktime_get();
		printk("[%s] : wake_lock_timeout 3 Sec \n",__func__);

		/*
		if(!gpio_get_value(GPIO_PS_VOUT))
		{
			printk("[%s] : call irq_handler forcely \n",__func__);
			gp2a_irq_handler(gp2a->irq,gp2a);
			

		}
		*/

	
	}

	cur_state = STATE_INIT;
	light_init_check = false;
	
	if(light_enable)
	{
		gprintk("[%s] : hrtimer_start \n",__func__);
	    hrtimer_start(&gp2a->timer,ktime_set(light_init_period/2,0),HRTIMER_MODE_REL);
	}

	return 0;
}
コード例 #8
0
/*****************************************************************************************
 *  
 *  function    : gp2a_on 
 *  description : This function is power-on function for optical sensor.
 *
 *  int type    : Sensor type. Two values is available (PROXIMITY,LIGHT).
 *                it support power-on function separately.
 *                
 *                 
 */
int gp2a_on(struct gp2a_data *gp2a, int type)
{
	u8 value;
	int err = 0;
#ifdef LIGHT_SENSOR_ENABLED
	ktime_t light_polling_time;
#endif
	gprintk("gp2a_on(%d)\n",type);
	gprintk("gp2a power on voltage up \n");
	if(type == PROXIMITY)
	{
		gprintk("[PROXIMITY] go nomal mode : power on \n");
		// 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 )
		value = 0x18;	// 11:force to go High
		err = opt_i2c_write((u8)(REGS_CON),&value);
		if(err < 0) return err;

#if defined(CONFIG_MACH_RANT3)
	value = 0x2F;	// HYSD enable
#else
		value = 0x40;	// HYSD enable
#endif
		err = opt_i2c_write((u8)(REGS_HYS),&value);
		if(err < 0) return err;

		// VCON : VOUT terminal output method control ( 0:normal mode, 1:interrupt mode )
		// SSD : Software shutdown function ( 0:shutdown mode, 1:opteration mode )
		value = 0x03;	// VCON enable, SSD enable
		err = opt_i2c_write((u8)(REGS_OPMOD),&value);
		if(err < 0) return err;
#if USE_INTERRUPT
		gprintk("enable irq for proximity\n");
		enable_irq(gp2a ->irq);
#if !defined(CONFIG_MACH_RANT3)
		set_irq_wake(gp2a->irq, 1);
#endif
#endif
		// OCON[1:0] : Select switches for enabling/disabling VOUT terminal 
		//             ( 00:enable, 11:force to go High, 10:forcr to go Low )
		value = 0x00;	// 00:enable
		err = opt_i2c_write((u8)(REGS_CON),&value);
		
	}
#ifdef LIGHT_SENSOR_ENABLED
	if(type == LIGHT)
	{
		gprintk(KERN_INFO "[LIGHT_SENSOR] timer start for light sensor\n");
		//hrtimer_start(&gp2a->timer,ktime_set(light_init_period/2,0),HRTIMER_MODE_REL);
		hrtimer_start(&gp2a->timer,ktime_set(0,500000000),HRTIMER_MODE_REL);
		light_enable = ON;
	}
#endif	
       return err;
}
コード例 #9
0
void gp2a_on(struct gp2a_data *gp2a, int type)
{
	u8 value;
	int err = 0;
	
	gprintk("gp2a_on(%d)\n",type);
	gprintk("gp2a power on voltage up \n");

#if defined(CONFIG_MACH_VASTO)
    vreg_enable(vreg_proximity);
#else
	if( board_hw_revision < 3 )
	{
		vreg_enable(vreg_proximity); // voltage 
	}
	else
	{
		gpio_set_value(VIR_LED_EN, 1);
	}
#endif
	//register irq to wakeup source
	printk("[GP2A] register irq = %d\n",gp2a ->irq);
	err = set_irq_wake(gp2a ->irq, 1);  // enable : 1, disable : 0
	printk("[GP2A] register wakeup source = %d\n",err);
	if (err) 
		printk("[GP2A] register wakeup source failed\n");
	
	// 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 )
	value = 0x18;	// 11:force to go High
	opt_i2c_write((u8)(REGS_CON),&value);

	value = 0x40;	// HYSD enable
	opt_i2c_write((u8)(REGS_HYS),&value);

	// VCON : VOUT terminal output method control ( 0:normal mode, 1:interrupt mode )
	// SSD : Software shutdown function ( 0:shutdown mode, 1:opteration mode )
	value = 0x03;	// VCON enable, SSD enable
	opt_i2c_write((u8)(REGS_OPMOD),&value);

	if(type == PROXIMITY)
	{
		gprintk("enable irq for proximity\n");
		enable_irq(gp2a ->irq);
	}

	// OCON[1:0] : Select switches for enabling/disabling VOUT terminal 
	//             ( 00:enable, 11:force to go High, 10:forcr to go Low )
	value = 0x00;	// 00:enable
	opt_i2c_write((u8)(REGS_CON),&value);
}
コード例 #10
0
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;

	if (gp2a->irq != 0) {
		disable_irq_wake(gp2a->irq);
		disable_irq(gp2a->irq);
	}
	/* 0 : proximity, 1 : away */
        result = gpio_get_value(gp2a->pdata->p_out);
	gp2a->proximity_detection = !result;

	input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, result);
	input_sync(gp2a->proximity_input_dev);

        printk(KERN_INFO "[GP2A] proximity value = %d \n",result);

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

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

	if (gp2a->irq != 0) {
	enable_irq(gp2a->irq);
		enable_irq_wake(gp2a->irq);
	}
	value = 0xCC;
	ret = opt_i2c_write(COMMAND1, &value);

	gp2a->prox_data = result;
    
}
コード例 #11
0
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);

	value = 0x0C;
	ret = opt_i2c_write(COMMAND1, &value, gp2a->pdata->addr,
		gp2a->pdata->adapt_num);	/*Software reset */

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

	enable_irq(gp2a->irq);

	value = 0xCC;
	ret = opt_i2c_write(COMMAND1, &value, gp2a->pdata->addr,
		gp2a->pdata->adapt_num);

	gp2a->prox_data = result;
	pr_debug("proximity = %d, lightsensor_mode=%d\n",
		result, gp2a->lightsensor_mode);
}
コード例 #12
0
static void gp2a_off(struct gp2a_data *gp2a, int type)
{
	u8 value;

	printk(KERN_INFO "[OPTICAL] gp2a_off(%d)\n",type);
	if(type == PROXIMITY || type == ALL)
	{
	
		gprintk("[PROXIMITY] go power down mode  \n");
		
		gprintk("disable irq for proximity \n");
		disable_irq(gp2a ->irq);
		
		value = 0x02;
		opt_i2c_write((u8)(REGS_OPMOD),&value);
		
		proximity_enable =0;
		proximity_value = 0;
	}

	if(type ==LIGHT)
	{
		printk("[LIGHT_SENSOR] timer cancel for light sensor\n");
		hrtimer_cancel(&gp2a->timer);
		light_enable = OFF;
		cur_state = STATE_INIT;
		light_init_check = false;
		

	}

	
	

}
コード例 #13
0
int gp2a_off(struct gp2a_data *gp2a, int type)
{
	u8 value;
	int err = 0;

	gprintk("gp2a_off(%d)\n",type);
	if(type == PROXIMITY || type == ALL)
	{
#if USE_INTERRUPT	  
		gprintk("disable irq for proximity \n");
#if !defined(CONFIG_MACH_RANT3)
		set_irq_wake(gp2a->irq, 0);
#endif
		disable_irq_nosync(gp2a ->irq);
#endif
		// SSD : Software shutdown function ( 0:shutdown mode, 1:opteration mode )
		value = 0x02;	// VCON enable, SSD disable
		err = opt_i2c_write((u8)(REGS_OPMOD),&value);
	
	}
#ifdef LIGHT_SENSOR_ENABLED
	if(type ==LIGHT)
	{
		gprintk("[LIGHT_SENSOR] timer cancel for light sensor\n");
		hrtimer_cancel(&gp2a->timer);
		/* In case light sensor is off, set the default backlight level */
		//lcdc_set_backlight_autobrightness(app_bl_level);
		light_enable = OFF;
	}
#endif	
       return err;
}
コード例 #14
0
static int gp2a_opt_suspend(struct i2c_client *client, pm_message_t mesg)
{
	struct gp2a_data *gp2a = i2c_get_clientdata(client);

	int config = 0;
	int err = 0;
	u8 value;
	
	printk("[HSIL] %s\n", __func__);
	if(!proximity_enable)
	{
		config = GPIO_CFG(GPIO_PS_VOUT, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA);
		err = gpio_tlmm_config(config, GPIO_CFG_ENABLE);
		if (err) 
			printk(KERN_ERR "%s: gpio_tlmm_config(%#x)=%d\n", __func__, GPIO_PS_VOUT, err);
	}
	else
	{
#if USE_INTERRUPT	  
		disable_irq_nosync(gp2a ->irq);
#endif
		value = 0x02;
		opt_i2c_write((u8)(REGS_OPMOD),&value);
		printk(KERN_INFO "[%s] GP2A !!suspend mode proximity_enable \n",__FUNCTION__);
	}
	return 0;
}
コード例 #15
0
static int gp2a_update_threshold(struct gp2a_data *data,
	u8 (*selected_image)[2], u8 new_threshold, bool update_reg)
{
	int i, err = 0;
	u8 set_value;

	pr_info("%s, new = 0x%x, thresh_diff = %d\n", __func__,
		new_threshold, data->thresh_diff);
	for (i = 0; i < COL; i++) {
		switch (selected_image[i][0]) {
		case PS_LOW_THD_L:
			/*PS mode LTH(Loff) for low 8bit*/
#if defined(CONFIG_MACH_KONA_SENSOR)
			set_value = (new_threshold-data->thresh_diff) & 0x00FF;
#else
			set_value = new_threshold & 0x00FF;
#endif
			break;

		case PS_LOW_THD_H:
			/*PS mode LTH(Loff) for high 8bit*/
			set_value = (new_threshold & 0xFF00) >> 8;
			break;

		case PS_HIGH_THD_L:
			/*PS mode HTH(Lon) for low 8bit*/
#if defined(CONFIG_MACH_KONA_SENSOR)
			set_value = (new_threshold) & 0x00FF;
#else
			set_value = (new_threshold+data->thresh_diff) & 0x00FF;
#endif
			break;

		case PS_HIGH_THD_H:
			/* PS mode HTH(Lon) for high 8bit*/
			set_value = ((new_threshold
				+data->thresh_diff) & 0xFF00) >> 8;
			break;

		default:
			continue;
		}

		if (update_reg)
			err = opt_i2c_write(selected_image[i][0], &set_value);

		if (err) {
			pr_err("%s : setting error i = %d, err=%d\n",
			 __func__, i, err);
			return err;
		} else {
			selected_image[i][1] = set_value;
		}
	}

	return err;
}
コード例 #16
0
static int proximity_onoff(u8 onoff, struct gp2a_data  *data)
{
	u8 value;
	int i;
	/* unsigned char get_data[1]; */
	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) {
		/*opt_i2c_read(COMMAND1, get_data, sizeof(get_data)); */
		/*if (get_data == 0xC1)
		   return 0; */
		for (i = 0; i < COL; i++) {
			err = opt_i2c_write(gp2a_original_image[i][0],
				&gp2a_original_image[i][1], data->pdata->addr,
				data->pdata->adapt_num);
			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 */
		/*opt_i2c_read(COMMAND1, get_data, sizeof(get_data)); */
		/*if (get_data == 0xD1)
		   return 0; */

		if (data->lightsensor_mode)
			value = 0x67; /*resolution :16bit, range: *8(HIGH) */
		else
			value = 0x63; /* resolution :16bit, range: *128(LOW) */
		opt_i2c_write(COMMAND2, &value, data->pdata->addr,
			data->pdata->adapt_num);
		/* OP3 : 1(operating mode)
		   OP2 :1(coutinuous operating mode) OP1 : 01(ALS mode) */
		value = 0xD0;
		opt_i2c_write(COMMAND1, &value, data->pdata->addr,
			data->pdata->adapt_num);
	}

	return 0;
}
コード例 #17
0
/*****************************************************************************************
 *  
 *  function    : gp2a_work_func_prox 
 *  description : This function is for proximity sensor (using B-1 Mode ). 
 *                when INT signal is occured , it gets value from VO register.   
 *
 *                 
 */
static void gp2a_work_func_prox(struct work_struct *work)
{
	struct gp2a_data *gp2a = container_of((struct work_struct *)work,
							struct gp2a_data, work);
	
	char value;
#ifdef PROX_MODE_B
    u8 reg = 0;
#endif

    disable_irq(IRQ_GP2A_INT);

    value = get_ps_vout_value(); 

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

	gp2a->prox_data= value;
	gprintk("proximity = %d\n",value); //Temp

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

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

    enable_irq(IRQ_GP2A_INT);

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

}
コード例 #18
0
static int proximity_onoff(u8 onoff)
{
    u8 value;
    int i;

    if (onoff) {
        for (i = 1 ; i < 5 ; i++)
            opt_i2c_write((u8)(i), &gp2a_original_image[i]);
    } else {
#ifdef PROX_MODE_A
        value = 0x00;
#else
        value = 0x02;
#endif
        opt_i2c_write((u8)(REGS_OPMOD), &value);
    }

    return 0;
}
コード例 #19
0
static int gp2a_opt_resume(struct i2c_client *client)
{
	struct gp2a_data *gp2a = i2c_get_clientdata(client);

	int config = 0;
	int err = 0;
	u8 value;

	printk("[HSIL] %s\n", __func__);
	if(!proximity_enable)
	{
		config = GPIO_CFG(GPIO_PS_VOUT, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA);
		err = gpio_tlmm_config(config, GPIO_CFG_ENABLE);
		if (err) 
			printk(KERN_ERR "%s: gpio_tlmm_config(%#x)=%d\n", __func__, GPIO_PS_VOUT, err);	
	}
	else
	{
		value = 0x18;
		opt_i2c_write((u8)(REGS_CON),&value);

#if defined(CONFIG_MACH_RANT3)
		value = 0x2F;
#else
		value = 0x40;
#endif
		opt_i2c_write((u8)(REGS_HYS),&value);
		
		
		value = 0x03;
		opt_i2c_write((u8)(REGS_OPMOD),&value);
#if USE_INTERRUPT
		enable_irq(gp2a->irq);
#endif		
		value = 0x00;
		opt_i2c_write((u8)(REGS_CON),&value);

//	       wake_lock_timeout(&prx_wake_lock,3 * HZ);
//		timeA = ktime_get();
//		printk("[%s] : wake_lock_timeout 3 Sec \n",__func__);
	}
	return 0;
}
コード例 #20
0
irqreturn_t gp2a_irq_handler(int irq, void *ptr)
{
    struct gp2a_data *gp2a = ptr;
    char value;
#ifdef PROX_MODE_B
    u8 reg = 0;
#endif

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

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

    gp2a->prox_data = value;

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

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

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


    return IRQ_HANDLED;
}
コード例 #21
0
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;
}
コード例 #22
0
static long gp2a_opt_ioctl(struct file *file, unsigned int cmd,  unsigned long arg)
{	
    int ret = 0;
    short data = 0;
    u8 thrd = 0;

    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_offset(gp2a_opt_data);
		if (ret < 0 && ret != -ENOENT)
		{
			printk(KERN_INFO "[GP2A] proximity_open_offset() failed\n");
		}else {
			thrd = gp2a_original_image[3][1]+(gp2a_opt_data->offset_value);
			opt_i2c_write(gp2a_original_image[3][0], &thrd);
			thrd = gp2a_original_image[5][1]+(gp2a_opt_data->offset_value);
			opt_i2c_write(gp2a_original_image[5][0], &thrd);
		}
		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;
}
コード例 #23
0
static int lightsensor_onoff(u8 onoff, struct gp2a_data *data)
{
	u8 value;

#ifdef DEBUG
	pr_info(KERN_INFO "%s : light_sensor onoff = %d\n", __func__, onoff);
	       data->proximity_enabled);
#endif

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

	return 0;
}
コード例 #24
0
void gp2a_on(struct gp2a_data *gp2a) {
	int i;

	if(proximity_enable == OFF) {
		gprintk("gp2a power on\n");
#if defined(CONFIG_LU6500) || defined(CONFIG_KS1001)
		gp2a_power_control(ON);
		msleep(5);	
#endif
		proximity_enable = ON;
		//20111001 [email protected] : Set Operation mode B1 for X2 New HW Revision [S]
		//Shutdown Mode(0x02) -> Operation Mode(ox03) Procedure 1~5
		opt_i2c_write(gp2a, (u8)(REGS_CON),  0x18);//1
		opt_i2c_write(gp2a, (u8)(REGS_HYS),  0x40);//2
		opt_i2c_write(gp2a, (u8)(REGS_OPMOD),  0x03);//3

		enable_irq(gp2a->irq);//4
		msleep(2);
		opt_i2c_write(gp2a, (u8)(REGS_CON),  0x00);//5
		//20111001 [email protected] : Set Operation mode B1 for X2 New HW Revision [E]
		
		gp2a_read_forcely(gp2a);
	}
}
コード例 #25
0
static int gp2a_update_threshold(u8 (*selected_image)[2],
				unsigned long new_threshold, bool update_reg)
{
	int i, err = 0;
	u8 set_value;

	for (i = 0; i < COL; i++) {
		switch (selected_image[i][0]) {
		case PS_LOW_THD_L:
			/*PS mode LTH(Loff) for low 8bit*/
			set_value = new_threshold & 0x00FF;
			break;

		case PS_LOW_THD_H:
			/*PS mode LTH(Loff) for high 8bit*/
			set_value = (new_threshold & 0xFF00) >> 8;
			break;

		case PS_HIGH_THD_L:
			/*PS mode HTH(Lon) for low 8bit*/
			set_value = (new_threshold+1) & 0x00FF;
			break;

		case PS_HIGH_THD_H:
			/* PS mode HTH(Lon) for high 8bit*/
			set_value = ((new_threshold+1) & 0xFF00) >> 8;
			break;

		default:
			continue;
		}

		if (update_reg)
			err = opt_i2c_write(selected_image[i][0], &set_value);

		if (err) {
			pr_err("%s : setting error i = %d, err=%d\n",
			 __func__, i, err);
			return err;
		} else
			selected_image[i][1] = set_value;
	}

	return err;
}
コード例 #26
0
void gp2a_off(struct gp2a_data *gp2a, int type)
{
	u8 value;
	int err = 0;
#if defined(CONFIG_MACH_TOTORO_CTC) && (CONFIG_BOARD_REVISION >= 0x02) //twkim add proximity sensor driver to totoro_ctc
        vreg_disable(vreg_proximity); // voltage 
#else        
	if( board_hw_revision < 3 )
	{
		vreg_disable(vreg_proximity); // voltage 
	}
	else
	{
		gpio_set_value(VIR_LED_EN, 0);
	}
#endif    

	gprintk("gp2a_off voltage down(%d)\n",type);

	//delete irq from wakeup source
	printk("[GP2A] unregister irq = %d\n",gp2a ->irq);
	err = set_irq_wake(gp2a ->irq, 0); // enable : 1, disable : 0
	printk("[GP2A] register wakeup source = %d\n",err);
	if (err) 
		printk("[GP2A] register wakeup source failed\n");
	
	
	gprintk("gp2a power off \n");
	if(type == PROXIMITY || type==ALL)
	{
		gprintk("disable irq for proximity \n");
		disable_irq_nosync(gp2a ->irq);
	}
	// SSD : Software shutdown function ( 0:shutdown mode, 1:opteration mode )
	value = 0x02;	// VCON enable, SSD disable
	opt_i2c_write((u8)(REGS_OPMOD),&value);
#if defined(CONFIG_MACH_TOTORO_CTC) && (CONFIG_BOARD_REVISION >= 0x02) //twkim add proximity sensor driver to totoro_ctc
       gp2a_gpio_set(DISABLE);
#endif

}
コード例 #27
0
void gp2a_off(struct gp2a_data *gp2a) {

	gprintk("gp2a_off\n");
	if(proximity_enable == ON) {
		gprintk("disable irq for proximity \n");
	
		//20110921 [email protected] : for Phone Call and First Status in Framework[S]
		wake_lock_timeout(&gp2a_wake_lock, 3 * HZ);
		input_report_abs(gp2a->input_dev,ABS_DISTANCE, FAR);
	        input_sync(gp2a->input_dev);
	        mdelay(1);
		//20110921 [email protected] : for Phone Call and First Status in Framework[E]	
		
		//20111001 [email protected] : Set Operation mode B1 for X2 New HW Revision [S]
		//Operation Mode(0x03) -> Shutdown Mode(0x02)
		disable_irq_nosync(gp2a->irq);
		opt_i2c_write(gp2a, (u8)(REGS_OPMOD), 0x02);
		//20111001 [email protected] : Set Operation mode B1 for X2 New HW Revision [E]
		proximity_enable = OFF;
	}
}
コード例 #28
0
static int gp2a_opt_suspend(struct i2c_client *client, pm_message_t state) {
	struct gp2a_data *gp2a = i2c_get_clientdata(client);

	gprintk("suspend, proximity_enable:%d\n", proximity_enable);

//20110702 [email protected] nothing [S]
#if defined(CONFIG_LU6500) || defined(CONFIG_KS1001) || defined(CONFIG_KS1103) || defined (CONFIG_SU880) || defined (CONFIG_KU8800) || defined (CONFIG_LU8800)
	// nothing
#else
	if(proximity_enable) {
		//20111001 [email protected] : Set Operation mode B1 for X2 New HW Revision [S]
		//Operation Mode(0x03) -> Shutdown Mode(0x02)
		disable_irq_nosync(gp2a->irq);
		opt_i2c_write(gp2a, (u8)(REGS_OPMOD), 0x02);
		//20111001 [email protected] : Set Operation mode B1 for X2 New HW Revision [E]
		proximity_enable = OFF;
	}
#endif
//20110702 [email protected] nothing [E]

	return 0;
}
コード例 #29
0
static int gp2a_opt_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	int err = 0;
	int i;
#if USE_INTERRUPT
	int irq;
#endif
	int config;

	struct gp2a_data *gp2a;
#ifdef STM_DEBUG
	printk(KERN_INFO "%s\n",__FUNCTION__);
#endif

#if defined(CONFIG_MACH_TOTORO_CTC) && (CONFIG_BOARD_REVISION >= 0x02) //twkim add proximity sensor driver to totoro_ctc
    {
		vreg_proximity = vreg_get(0, "ldo9"); //twkim fixed pmic set
		if (IS_ERR(vreg_proximity))
		{	
			printk("===== [PROXIMITY] proximity IS_ERR TEST =====\n");
			return PTR_ERR(vreg_proximity);
		}
	
#if defined(CONFIG_MACH_TOTORO_CTC) && (CONFIG_BOARD_REVISION >= 0x02) //twkim add proximity sensor driver to totoro_ctc
             vreg_set_level(vreg_proximity, OUT2800mV); // set to 3.0V voltage twkim 12 -> 10 to set 2.85V -> 2.6v
             gp2a_gpio_set(ENABLE);
#else
	vreg_set_level(vreg_proximity, OUT2850mV); // set to 3.0V voltage twkim 12 -> 10 to set 2.85V
#endif
		vreg_enable(vreg_proximity); // voltage 
	}
#else
	if( board_hw_revision < 3 )
	{
		vreg_proximity = vreg_get(0, "ldo19");
		if (IS_ERR(vreg_proximity))
		{	
			printk("===== [PROXIMITY] proximity IS_ERR TEST =====\n");
			return PTR_ERR(vreg_proximity);
		}
	
	vreg_set_level(vreg_proximity, 12); // set to 3.0V voltage 
		vreg_enable(vreg_proximity); // voltage 
	}
	else
	{
		gpio_set_value(VIR_LED_EN, 1);
	}
#endif    
	
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
	{
		printk(KERN_INFO "[GP2A] i2c_check_functionality error\n");
		err = -ENODEV;
		goto exit;
	}
	if ( !i2c_check_functionality(client->adapter,I2C_FUNC_SMBUS_BYTE_DATA) ) {
		printk(KERN_INFO "[GP2A] byte op is not permited.\n");
		goto exit;
	}

	/* OK. For now, we presume we have a valid client. We now create the
	client structure, even though we cannot fill it completely yet. */
	if (!(gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL)))
	{
		err = -ENOMEM;
		goto exit;
	}
	memset(gp2a, 0, sizeof(struct gp2a_data));
	gp2a->client = client;
	i2c_set_clientdata(client, gp2a);

	opt_i2c_client = client;

	if (i2c_smbus_read_byte(client) < 0)
	{
		printk(KERN_ERR "[GP2A] i2c_smbus_read_byte error!!\n");
		goto exit_kfree;
	}
	else
	{
		printk("GP2A Device detected!\n");
	}

	printk("[%s] slave addr = %x\n", __func__, client->addr);
	
	/* Input device Settings */
	if(USE_INPUT_DEVICE)
	{
		gp2a->input_dev = input_allocate_device();
		if (gp2a->input_dev == NULL) 
		{
			pr_err("Failed to allocate input device\n");
			return -ENOMEM;
		}
		gp2a->input_dev->name = "proximity_sensor";
	
		set_bit(EV_SYN,gp2a->input_dev->evbit);
		set_bit(EV_ABS,gp2a->input_dev->evbit);
		
 	       input_set_abs_params(gp2a->input_dev, ABS_DISTANCE, 0, 1, 0, 0);
		
	
		err = input_register_device(gp2a->input_dev);
		if (err) 
		{
			pr_err("Unable to register %s input device\n", gp2a->input_dev->name);
			input_free_device(gp2a->input_dev);
			kfree(gp2a);
			return -1;
		}

	}

#if USE_INTERRUPT
	/* WORK QUEUE Settings */
	gp2a_wq = create_singlethread_workqueue("gp2a_wq");
	if (!gp2a_wq)
		return -ENOMEM;
	INIT_WORK(&gp2a->work_prox, gp2a_work_func_prox);
	gprintk("Workqueue Settings complete\n");
#endif

	/* misc device Settings */
	err = misc_register(&proximity_device);
	if(err) {
		pr_err(KERN_ERR "misc_register failed - prox \n");
	}

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

	/* set sysfs for light sensor */
	proxsensor_class = class_create(THIS_MODULE, "proxsensor");
	if (IS_ERR(proxsensor_class))
		pr_err("Failed to create class(proxsensor)!\n");

	switch_cmd_dev = device_create(proxsensor_class, NULL, 0, NULL, "switch_cmd");	
	if (device_create_file(switch_cmd_dev, &dev_attr_proxsensor_file_state) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_proxsensor_file_state.attr.name);
	
	dev_set_drvdata(switch_cmd_dev,gp2a);
	
	/* ktime init */

	timeA = ktime_set(0,0);
	timeB = ktime_set(0,0);
	
	/* gpio config */
	config = GPIO_CFG(GPIO_SENSE_OUT, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA);
	err = gpio_tlmm_config(config, GPIO_CFG_ENABLE);
	if (err) 
		printk(KERN_ERR "%s: gpio_tlmm_config(%#x)=%d\n", __func__, GPIO_SENSE_OUT, err);

	/* GP2A Regs INIT SETTINGS */
	for(i=1;i<5;i++)
	{
		opt_i2c_write((u8)(i),&gp2a_original_image[i]);
	}

	mdelay(2);
#if USE_INTERRUPT
	/* INT Settings */	
	irq = gpio_to_irq(GPIO_SENSE_OUT);
	gp2a->irq = -1;
	set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);

	err = request_irq(irq, gp2a_irq_handler, IRQF_DISABLED, "gp2a_int", gp2a);
	if (err)
	{
		printk("[GP2A] request_irq failed for gp2a\n");
		goto exit_kfree;
	}

	printk("[GP2A] register irq = %d\n",irq);
	err = set_irq_wake(irq, 1);
	printk("[GP2A] register wakeup source = %d\n",err);
	if (err) 
		printk("[GP2A] register wakeup source failed\n");
	
	gp2a->irq = irq;
	gprintk("INT Settings complete\n");
#endif
	
	// maintain power-down mode before using sensor
	gp2a_off(gp2a,ALL);
	
//++	// test for sensor 

/*
	printk("[GP2A] curr prox value = %d\n", gpio_get_value(GPIO_SENSE_OUT));
	gp2a_on(gp2a,PROXIMITY);
	printk("[GP2A] curr prox value = %d\n", gpio_get_value(GPIO_SENSE_OUT));
	
//--

	// maintain power-down mode before using sensor
	//ESD test sleep
	gp2a_off(gp2a,ALL);
*/

	printk("gp2a_opt_probe is OK!!\n");
	return 0;
	
exit_kfree:
	kfree(gp2a);
exit:
	return err;
}
コード例 #30
0
static void gp2a_work_func_prox(struct work_struct *work)
{
	struct gp2a_data *gp2a = container_of(work, struct gp2a_data, work_prox);
	
	unsigned char value;
	unsigned char int_val=REGS_PROX;
	unsigned char vout=0;

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

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



	/* Report proximity information */
	proximity_value = vout;

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

	}

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

	/* Write HYS Register */

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


	}
	else
	{
		value = 0x20;

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


	}
	else
	{
		value = 0x0F;

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


	}
	else
	{
		value = 0x00;

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

	/* Forcing vout terminal to go high */

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


	/* enabling VOUT terminal in nomal operation */

	value = 0x00;

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

	
	/* enable INT */

	enable_irq(gp2a->irq);
}