static int aps_12d_open(struct inode *inode, struct file *file) { PROXIMITY_DEBUG("aps_12d_open enter, timer_count=%d\n", aps_12d_timer_count); /* when the device is open use this if light open report -1 when proximity open then lock it*/ if( light_device_minor == iminor(inode) ){ aps_first_read = 1; PROXIMITY_DEBUG("%s:light sensor open", __func__); } if( proximity_device_minor == iminor(inode) ){ printk("%s:proximity_device_minor == iminor(inode)", __func__); wake_lock( &proximity_wake_lock); /* 0 is close, 1 is far */ input_report_abs(this_aps_data->input_dev, ABS_DISTANCE, 1); input_sync(this_aps_data->input_dev); PROXIMITY_DEBUG("%s:proximity = %d", __func__, 1); } if( 0 == aps_12d_timer_count ) hrtimer_start(&this_aps_data->timer, ktime_set(1, 0), HRTIMER_MODE_REL); aps_12d_timer_count++; return nonseekable_open(inode, file); }
static int aps_12d_resume(struct i2c_client *client) { int ret; struct aps_data *aps = i2c_get_clientdata(client); PROXIMITY_DEBUG("ghj aps_12d_resume enter\n "); /* Command 2 register: 25mA,DC,12bit,Range2 */ /* write reg value for the two device */ if(EVERLIGHT == intersil_flag) { ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ (uint8_t)(APS_12D_IRDR_SEL_50MA << 6 | \ APS_12D_FREQ_SEL_DC << 4 | \ APS_12D_RES_SEL_12 << 2 | \ APS_12D_RANGE_SEL_ALS_1000)); } else { ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ (uint8_t)(APS_12D_IRDR_SEL_INTERSIL_50MA << 4 | \ APS_FREQ_INTERSIL_DC << 6 | \ APS_ADC_12 << 2 | \ APS_INTERSIL_SCHEME_OFF| \ APS_12D_RANGE_SEL_ALS_1000)); } hrtimer_start(&aps->timer, ktime_set(1, 0), HRTIMER_MODE_REL); return 0; }
static int aps_12d_resume(struct i2c_client *client) { int ret; struct aps_data *aps = i2c_get_clientdata(client); PROXIMITY_DEBUG("ghj aps_12d_resume enter\n "); /* Command 2 register: 25mA,DC,12bit,Range2 */ /* < DTS2010081803338 zhangtao 20100818 begin */ /* make the rang smaller can make the ir changge bigger */ ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ /* < DTS2010102103994 zhangtao 20101112 begin */ (uint8_t)(APS_12D_IRDR_SEL_50MA << 6 | \ APS_12D_FREQ_SEL_DC << 4 | \ APS_12D_RES_SEL_12 << 2 | \ APS_12D_RANGE_SEL_ALS_1000)); /* DTS2010102103994 zhangtao 20101112 end > */ /* DTS2010081803338 zhangtao 20100818 end > */ /* < DTS2010072801000 zhangtao 20100728 begin */ /* enable aps_first_read */ /* < DTS2010090300997 zhangtao 20100903 begin */ /* the flag is not used */ /* DTS2010090300997 zhangtao 20100903 end > */ /* DTS2010072801000 zhangtao 20100728 end > */ hrtimer_start(&aps->timer, ktime_set(1, 0), HRTIMER_MODE_REL); return 0; }
static int aps_12d_suspend(struct i2c_client *client, pm_message_t mesg) { int ret; struct aps_data *aps = i2c_get_clientdata(client); PROXIMITY_DEBUG("ghj aps_12d_suspend enter\n "); hrtimer_cancel(&aps->timer); ret = cancel_work_sync(&aps->work); ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_POWER_DOWN); if (aps->power) { ret = aps->power(0); if (ret < 0) /* < DTS2010072801000 zhangtao 20100728 begin */ printk(KERN_ERR "aps_12d_suspend power off failed\n"); } /* enable aps_first_read */ /* < DTS2010090300997 zhangtao 20100903 begin */ /* the flag is not used */ /* DTS2010090300997 zhangtao 20100903 end > */ /* DTS2010072801000 zhangtao 20100728 end > */ return 0; }
static int aps_12d_remove(struct i2c_client *client) { struct aps_data *aps = i2c_get_clientdata(client); PROXIMITY_DEBUG("ghj aps_12d_remove enter\n "); hrtimer_cancel(&aps->timer); misc_deregister(&light_device); misc_deregister(&proximity_device); input_unregister_device(aps->input_dev); kfree(aps); return 0; }
static int aps_12d_release(struct inode *inode, struct file *file) { PROXIMITY_DEBUG("aps_12d_release enter, timer_count=%d\n ", aps_12d_timer_count); aps_12d_timer_count--; if( 0 == aps_12d_timer_count ) { hrtimer_cancel(&this_aps_data->timer); aps_12d_delay = APS_12D_TIMRER; } if( proximity_device_minor == iminor(inode) ){ printk("%s: proximity_device_minor == iminor(inode)", __func__); wake_unlock( &proximity_wake_lock); } return 0; }
static int aps_12d_resume(struct i2c_client *client) { int ret; struct aps_data *aps = i2c_get_clientdata(client); PROXIMITY_DEBUG("aps_12d_resume enter\n "); /* Command 2 register: 25mA,DC,12bit,Range2 */ ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ (uint8_t)(APS_12D_IRDR_SEL_50MA << 6 | \ APS_12D_FREQ_SEL_DC << 4 | \ APS_12D_RES_SEL_12 << 2 | \ APS_12D_RANGE_SEL_ALS_1000)); hrtimer_start(&aps->timer, ktime_set(1, 0), HRTIMER_MODE_REL); return 0; }
static int aps_12d_suspend(struct i2c_client *client, pm_message_t mesg) { int ret; struct aps_data *aps = i2c_get_clientdata(client); PROXIMITY_DEBUG("aps_12d_suspend enter\n "); hrtimer_cancel(&aps->timer); ret = cancel_work_sync(&aps->work); ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_POWER_DOWN); if (aps->power) { ret = aps->power(0); if (ret < 0) printk(KERN_ERR "aps_12d_suspend power off failed\n"); } return 0; }
static int aps_12d_remove(struct i2c_client *client) { struct aps_data *aps = i2c_get_clientdata(client); PROXIMITY_DEBUG("aps_12d_remove enter\n "); hrtimer_cancel(&aps->timer); #ifdef CONFIG_HAS_EARLYSUSPEND unregister_early_suspend(&aps->early_suspend); #endif misc_deregister(&light_device); misc_deregister(&proximity_device); input_unregister_device(aps->input_dev); kfree(aps); return 0; }
static int aps_12d_release(struct inode *inode, struct file *file) { PROXIMITY_DEBUG("aps_12d_release enter, timer_count=%d\n ", aps_12d_timer_count); aps_12d_timer_count--; if( 0 == aps_12d_timer_count ) { hrtimer_cancel(&this_aps_data->timer); aps_12d_delay = APS_12D_TIMRER; } /* < DTS2010090300997 zhangtao 20100903 begin */ /*when proximity is released then unlock it*/ if( proximity_device_minor == iminor(inode) ){ printk("%s: proximity_device_minor == iminor(inode)", __func__); wake_unlock( &proximity_wake_lock); } /* DTS2010090300997 zhangtao 20100903 end > */ return 0; }
static int aps_12d_probe( struct i2c_client *client, const struct i2c_device_id *id) { /* define and initialization the value */ int value_lsb = 0; int value_msb = 0; int ret; struct aps_data *aps; /*the aps_12d sensors ispower on*/ int i; #ifdef CONFIG_ARCH_MSM7X30 struct vreg *vreg_gp4=NULL; int rc; /*delete this line,27A don't have to match the power supply*/ vreg_gp4 = vreg_get(NULL, VREG_GP4_NAME); if (IS_ERR(vreg_gp4)) { pr_err("%s:gp4 power init get failed\n", __func__); } /* set gp4 voltage as 2700mV for all */ rc = vreg_set_level(vreg_gp4,VREG_GP4_VOLTAGE_VALUE_2700); if (rc) { pr_err("%s: vreg_gp4 vreg_set_level failed (%d)\n", __func__, rc); return rc; } rc = vreg_enable(vreg_gp4); if (rc) { pr_err("%s: vreg_gp4 vreg_enable failed (%d)\n", __func__, rc); return rc; } #endif mdelay(5); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { printk(KERN_ERR "aps_12d_probe: need I2C_FUNC_I2C\n"); ret = -ENODEV; goto err_check_functionality_failed; } /* if querry the board is T1 or T2 turn off the proximity */ /* This modification for version A&B of U8800,only */ if((machine_is_msm7x30_u8800())&&((get_hw_sub_board_id() == HW_VER_SUB_VA) || ((get_hw_sub_board_id() == HW_VER_SUB_VB)))) { printk(KERN_ERR "aps_12d_probe: aps is not supported in U8800 and U8800 T1 board!\n"); ret = -ENODEV; goto err_check_functionality_failed; } aps = kzalloc(sizeof(*aps), GFP_KERNEL); if (aps == NULL) { ret = -ENOMEM; goto err_alloc_data_failed; } mutex_init(&aps->mlock); INIT_WORK(&aps->work, aps_12d_work_func); aps->client = client; i2c_set_clientdata(client, aps); PROXIMITY_DEBUG(KERN_INFO "ghj aps_12d_probe send command 2\n "); /* Command 2 register: 25mA,DC,12bit,Range1 */ /*power_down to avoid the iic read error */ aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_POWER_DOWN); /*init the flag,because everlight's 0x06,0x07's register's value low 4 bit is 0*/ value_lsb = aps_i2c_reg_read(aps, APS_INT_HT_LSB); value_msb = aps_i2c_reg_read(aps, APS_INT_HT_MSB); old_lsb = value_lsb; old_msb = value_msb; /* debug--- stare at the value of lsb & msb */ APS_DBG("value_lsb=%d,value_msb=%d\n",value_lsb,value_msb); /* judge the device type */ /* when 06 07 registers don't equal 0x00, we think it's a intersil hardware */ if((0x00 == value_lsb) && (0x00 == value_msb)) { intersil_flag = EVERLIGHT; } else { intersil_flag = INTERSIL; } /* write reg value for the two device */ if(EVERLIGHT == intersil_flag) { ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ (uint8_t)(APS_12D_IRDR_SEL_50MA << 6 | \ APS_12D_FREQ_SEL_DC << 4 | \ APS_12D_RES_SEL_12 << 2 | \ APS_12D_RANGE_SEL_ALS_1000)); } else { /*because Power-up and Power Supply Considerations is not good enough for intersil's datasheet,so avoid it via software*/ ret = aps_i2c_reg_write(aps, APS_TEST, APS_12D_POWER_DOWN); if (ret < 0) { PROXIMITY_DEBUG("APS_TEST error!\n"); } msleep(10); ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_POWER_DOWN); if (ret < 0) { PROXIMITY_DEBUG("APS_12D_POWER_DOWN error!\n"); } msleep(10); ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ (uint8_t)(APS_12D_IRDR_SEL_INTERSIL_50MA << 4 | \ APS_FREQ_INTERSIL_DC << 6 | \ APS_ADC_12 << 2 | \ APS_INTERSIL_SCHEME_OFF| \ APS_12D_RANGE_SEL_ALS_1000)); } err_threshold_value[1] = 50; if (ret < 0) { goto err_detect_failed; } range_index = 0; #ifdef CONFIG_HUAWEI_HW_DEV_DCT /* detect current device successful, set the flag as present */ set_hw_dev_flag(DEV_I2C_APS); #endif for(i = 0; i < TOTAL_RANGE_NUM; i++) { /* NOTE: do NOT use the last one */ /* get the down_range_value */ if(EVERLIGHT == intersil_flag) { up_range_value[i] = MAX_ADC_OUTPUT - high_threshold_value_U8661[i] - RANGE_FIX + 500; } else { up_range_value[i] = MAX_ADC_OUTPUT - high_threshold_value_U8661_I[i] - RANGE_FIX + 500; } } down_range_value[0] = 0; for(i = 1; i < TOTAL_RANGE_NUM; i++) { /* NOTE: do not use the first one */ /* get the down_range_value */ if(EVERLIGHT == intersil_flag) { down_range_value[i] = (MAX_ADC_OUTPUT - high_threshold_value_U8661[i-1] - (MAX_ADC_OUTPUT / ADJUST_GATE)) / 4 - 650; } else { down_range_value[i] = (MAX_ADC_OUTPUT - high_threshold_value_U8661_I[i-1] - (MAX_ADC_OUTPUT / ADJUST_GATE)) / 4 - 650; } } /*we don't use the input device sensors again */ aps->input_dev = input_allocate_device(); if (aps->input_dev == NULL) { ret = -ENOMEM; PROXIMITY_DEBUG(KERN_ERR "aps_12d_probe: Failed to allocate input device\n"); goto err_input_dev_alloc_failed; } aps->input_dev->name = "sensors_aps"; aps->input_dev->id.bustype = BUS_I2C; input_set_drvdata(aps->input_dev, aps); ret = input_register_device(aps->input_dev); if (ret) { printk(KERN_ERR "aps_probe: Unable to register %s input device\n", aps->input_dev->name); goto err_input_register_device_failed; } set_bit(EV_ABS, aps->input_dev->evbit); input_set_abs_params(aps->input_dev, ABS_LIGHT, 0, 10240, 0, 0); input_set_abs_params(aps->input_dev, ABS_DISTANCE, 0, 1, 0, 0); ret = misc_register(&light_device); if (ret) { printk(KERN_ERR "aps_12d_probe: light_device register failed\n"); goto err_light_misc_device_register_failed; } ret = misc_register(&proximity_device); if (ret) { printk(KERN_ERR "aps_12d_probe: proximity_device register failed\n"); goto err_proximity_misc_device_register_failed; } if( light_device.minor != MISC_DYNAMIC_MINOR ){ light_device_minor = light_device.minor; } if( proximity_device.minor != MISC_DYNAMIC_MINOR ){ proximity_device_minor = proximity_device.minor ; } wake_lock_init(&proximity_wake_lock, WAKE_LOCK_SUSPEND, "proximity"); hrtimer_init(&aps->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); aps->timer.function = aps_timer_func; aps_wq = create_singlethread_workqueue("aps_wq"); if (!aps_wq) { ret = -ENOMEM; goto err_create_workqueue_failed; } this_aps_data =aps; ret = set_sensor_input(PS, aps->input_dev->dev.kobj.name); if (ret) { dev_err(&client->dev, "%s set_sensor_input failed\n", __func__); goto err_create_workqueue_failed; } ret = set_sensor_input(ALS, aps->input_dev->dev.kobj.name); if (ret) { dev_err(&client->dev, "%s set_sensor_input failed\n", __func__); goto err_create_workqueue_failed; } /* delete the redundant code */ printk(KERN_INFO "aps_12d_probe: Start Proximity Sensor APS-12D\n"); set_sensors_list(L_SENSOR + P_SENSOR); return 0; err_create_workqueue_failed: misc_deregister(&proximity_device); err_proximity_misc_device_register_failed: misc_deregister(&light_device); err_light_misc_device_register_failed: err_input_register_device_failed: input_free_device(aps->input_dev); err_input_dev_alloc_failed: err_detect_failed: kfree(aps); err_alloc_data_failed: err_check_functionality_failed: #ifdef CONFIG_ARCH_MSM7X30 if(NULL != vreg_gp4) { /* can't use the flag ret here, it will change the return value of probe function */ vreg_disable(vreg_gp4); /* delete a line */ } #endif return ret; }
static void aps_12d_work_func(struct work_struct *work) { int flag = -1; // delete flag_old int ret; int reg_val_lsb; int reg_val_msb; int sesc = aps_12d_delay/1000; int nsesc = (aps_12d_delay%1000)*1000000; uint16_t high_threshold = 0; uint16_t low_threshold = 0; int ir_count = 0; int ps_count = 0; uint16_t als_count = 0; uint8_t als_level = 0; /* del als_level_old */ uint8_t i; struct aps_data *aps = container_of(work, struct aps_data, work); /* add printf infomation at the key point */ if(INTERSIL == intersil_flag) { APS_DBG("intersil!\n"); } else { APS_DBG("everlight!\n"); } if (atomic_read(&p_flag)) { /* Command 1 register: IR once */ adjust_time = 0; re_adjust: /* init the range to the num last time we set */ if(( range_index >=0 ) && ( range_index < TOTAL_RANGE_NUM )) { /* deal with intersil and everlight with diferent valure */ if(EVERLIGHT == intersil_flag) { aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ (uint8_t)(APS_12D_IRDR_SEL_50MA << 6 | \ APS_12D_FREQ_SEL_DC << 4 | \ APS_12D_RES_SEL_12 << 2 | \ range_reg_value[range_index])); high_threshold = high_threshold_value_U8661[range_index]; low_threshold = low_threshold_value_U8661[range_index]; } else { aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ (uint8_t)(APS_12D_IRDR_SEL_INTERSIL_50MA << 4 | \ APS_FREQ_INTERSIL_DC << 6 | \ APS_ADC_12 << 2 | \ APS_INTERSIL_SCHEME_OFF| \ range_reg_value[range_index])); high_threshold = high_threshold_value_U8661_I[range_index]; low_threshold = low_threshold_value_U8661_I[range_index]; } } else { PROXIMITY_DEBUG("BUG: range_index error!!!!\n"); range_index = 0; } er_adjust: /* deal with intersil and everlight with diferent mode */ if(EVERLIGHT == intersil_flag) { ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_IR_ONCE); } else { ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_IR_CONTINUOUS); } msleep(45); reg_val_lsb = aps_i2c_reg_read(aps, APS_12D_DATA_LSB); reg_val_msb = aps_i2c_reg_read(aps, APS_12D_DATA_MSB); ir_count = ((uint16_t)reg_val_msb << 8) + (uint16_t)reg_val_lsb; PROXIMITY_DEBUG("IR once lsb=%d; msb=%d; ir_count=%d \n", reg_val_lsb, reg_val_msb, ir_count); if (ir_count > 0xFFF){ PROXIMITY_DEBUG("get wrong ir value, ir_count=%d \n", ir_count); ir_count = 0xFFF; } if (ir_count < 0){ PROXIMITY_DEBUG("get wrong ir value, ir_count=%d \n", ir_count); ir_count = 0; } /* * auto adjust the range * stratety: * if current adc value >= up_range_value[i] * switch to upper range * if current adc value < down_range_value[i] * switch to lower range */ if(ir_count > up_range_value[range_index]) { if(adjust_time < TOTAL_RANGE_NUM-1) { if(range_index < TOTAL_RANGE_NUM-1) { range_index++; adjust_time++; goto re_adjust; } else { PROXIMITY_DEBUG("infrared ray TOO HIGH?\n"); } } else { PROXIMITY_DEBUG("proximity readjust exceed max retry times.\n"); } } else if((ir_count < down_range_value[range_index])) { if(adjust_time < TOTAL_RANGE_NUM-1) { if(range_index >= TOTAL_RANGE_NUM-1) { range_index--; adjust_time++; goto re_adjust; } else { PROXIMITY_DEBUG("BUG: no exist lux value!!\n"); } } else { PROXIMITY_DEBUG("proximity readjust exceed max retry times.\n"); } } /*all of the intersil's ONCE module has a big risk */ if(EVERLIGHT == intersil_flag) { ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_PROXIMITY_ONCE); } else { ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_PROXIMITY_CONTINUOUS); } msleep(45); reg_val_lsb = aps_i2c_reg_read(aps, APS_12D_DATA_LSB); reg_val_msb = aps_i2c_reg_read(aps, APS_12D_DATA_MSB); ps_count = ((uint16_t)reg_val_msb << 8) + (uint16_t)reg_val_lsb; PROXIMITY_DEBUG("PS once lsb=%d; msb=%d; ps_count=%d \n", reg_val_lsb, reg_val_msb, ps_count); if (ps_count > 0xFFF){ PROXIMITY_DEBUG("get wrong ps value, ps_count=%d \n", ps_count); ps_count = 0xFFF; } if (ps_count < 0){ PROXIMITY_DEBUG("get wrong ps value, ps_count=%d \n", ps_count); ps_count = 0; } /*get value of proximity and light*/ proximity_data_value = ps_count; if (range_index == 1){ light_data_value = ir_count*RANG_VALUE; } else { light_data_value = ir_count; } /* delete this if, because we don't want filtrate the negative value * when the value is negative , we set the status to away */ if( (ps_count - ir_count) < low_threshold ) flag = 1; else if ( (ps_count - ir_count) > err_threshold_value[range_index] ) flag = -1; else if( (ps_count - ir_count) > high_threshold ) flag = 0; else{ PROXIMITY_DEBUG("the value is in the threshold, do not report. \n"); } APS_DBG("the ps -ir is %d,the ps is %d,the ir is %d,the range_index is %d!\n",ps_count - ir_count,ps_count,ir_count,range_index); /* add printf infomation at the key point */ APS_DBG("approch flag is %d ,0 is close,1 is far\n",flag); APS_DBG("lsb = 0x%x,msb = 0x%x\n",old_lsb,old_msb); /* skip invalid event */ if(-1 != flag) { if(1 == flag) { /* report far event immediately */ /* 0 is close, 1 is far */ input_report_abs(aps->input_dev, ABS_DISTANCE, flag); input_sync(aps->input_dev); } else if(last_event != flag) { PROXIMITY_DEBUG("NOTE: skip unstable data: %s !!!\n", flag ? "far" : "close"); last_event = flag; goto er_adjust; } else { PROXIMITY_DEBUG("report distance flag=%d \n", flag); /* 0 is close, 1 is far */ input_report_abs(aps->input_dev, ABS_DISTANCE, flag); input_sync(aps->input_dev); } } /* save the last event */ last_event = flag; /* * reset the sensor range to 1000. */ if(0 != range_index) { /*all of the intersil's ONCE module has a big risk */ if(EVERLIGHT == intersil_flag) { aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ (uint8_t)(APS_12D_IRDR_SEL_50MA << 6 | \ APS_12D_FREQ_SEL_DC << 4 | \ APS_12D_RES_SEL_12 << 2 | \ APS_12D_RANGE_SEL_ALS_1000)); } else { aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ (uint8_t)(APS_12D_IRDR_SEL_INTERSIL_50MA << 4 | \ APS_FREQ_INTERSIL_DC << 6 | \ APS_ADC_12 << 2 | \ APS_INTERSIL_SCHEME_OFF | \ APS_12D_RANGE_SEL_ALS_1000)); } } } if (atomic_read(&l_flag)) { /* deal with intersil and everlight with diferent mode */ if(EVERLIGHT == intersil_flag) { ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_ALS_ONCE); } else { ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_ALS_CONTINUOUS); } msleep(45); reg_val_lsb = aps_i2c_reg_read(aps, APS_12D_DATA_LSB); reg_val_msb = aps_i2c_reg_read(aps, APS_12D_DATA_MSB); als_count = ((uint16_t)reg_val_msb << 8) + (uint16_t)reg_val_lsb; /* add printf infomation at the key point */ APS_DBG("ALS once lsb=%d; msb=%d; als_count=%d \n", reg_val_lsb, reg_val_msb, als_count); if (als_count > 0xFFF){ PROXIMITY_DEBUG("get wrong als value, als_count=%d \n", als_count); als_count = 0xFFF; } als_level = LSENSOR_MAX_LEVEL - 1; /* deal with intersil and everlight lsensor */ for (i = 0; i < ARRAY_SIZE(lsensor_adc_U8661_table); i++) { if(EVERLIGHT == intersil_flag) { if (als_count <= lsensor_adc_U8661_table[i]) { als_level = i; break; } } else { if (als_count <= lsensor_adc_U8661_Inter_table[i]) { als_level = i; break; } } } /* if it's intersil,it shoule be a power_down,because Power-up and Power Supply Considerations is not correct */ APS_DBG("report adc level=%d \n", als_level); if(INTERSIL == intersil_flag) { ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_POWER_DOWN); msleep(10); } if(aps_first_read) { /* report a invalid key first */ aps_first_read = 0; /*changge the report event as -1 so the app will not changge anything*/ input_report_abs(aps->input_dev, ABS_LIGHT, -1); input_sync(aps->input_dev); } else { APS_DBG("report lux value=%d \n", lsensor_adc_table[als_level]); input_report_abs(aps->input_dev, ABS_LIGHT, als_level); input_sync(aps->input_dev); } } if (atomic_read(&p_flag) || atomic_read(&l_flag)) hrtimer_start(&aps->timer, ktime_set(sesc, nsesc), HRTIMER_MODE_REL); }
static void aps_12d_work_func(struct work_struct *work) { int flag = -1; // delete flag_old int ret; int reg_val_lsb; int reg_val_msb; int sesc = aps_12d_delay/1000; int nsesc = (aps_12d_delay%1000)*1000000; int ir_count = 0; int ps_count = 0; uint16_t als_count = 0; uint8_t als_level = 0; /* del als_level_old */ uint8_t i; struct aps_data *aps = container_of(work, struct aps_data, work); PROXIMITY_DEBUG("aps_12d_work_func enter\n "); if (atomic_read(&p_flag)) { /* Command 1 register: IR once */ adjust_time = 0; re_adjust: if( machine_is_msm7x25_u8150() || machine_is_msm7x25_c8150() || machine_is_msm7x25_c8510() \ || machine_is_msm7x25_u8160() || machine_is_msm7x25_u8130() || machine_is_msm7x25_u8159()) { /* init the range to the num last time we set */ if(( range_index >=0 ) && ( range_index < TOTAL_RANGE_NUM )) { aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ (uint8_t)(APS_12D_IRDR_SEL_50MA << 6 | \ APS_12D_FREQ_SEL_DC << 4 | \ APS_12D_RES_SEL_12 << 2 | \ range_reg_value[range_index])); high_threshold = high_threshold_value[range_index]; low_threshold = low_threshold_value[range_index]; #ifdef DEBUG_AUTO_RANGE_ADJUST // del printk #endif } else { printk("BUG: range_index error!!!!\n"); range_index = 0; } } ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_IR_ONCE); msleep(60); reg_val_lsb = aps_i2c_reg_read(aps, APS_12D_DATA_LSB); reg_val_msb = aps_i2c_reg_read(aps, APS_12D_DATA_MSB); ir_count = ((uint16_t)reg_val_msb << 8) + (uint16_t)reg_val_lsb; PROXIMITY_DEBUG("IR once lsb=%d; msb=%d; ir_count=%d \n", reg_val_lsb, reg_val_msb, ir_count); if (ir_count > 0xFFF){ PROXIMITY_DEBUG("get wrong ir value, ir_count=%d \n", ir_count); ir_count = 0xFFF; } if (ir_count < 0){ PROXIMITY_DEBUG("get wrong ir value, ir_count=%d \n", ir_count); ir_count = 0; } /* * auto adjust the range * stratety: * if current adc value >= up_range_value[i] * switch to upper range * if current adc value < down_range_value[i] * switch to lower range */ if( machine_is_msm7x25_u8150() || machine_is_msm7x25_c8150() || machine_is_msm7x25_c8510() \ || machine_is_msm7x25_u8160() || machine_is_msm7x25_u8130() || machine_is_msm7x25_u8159()) { if(ir_count > up_range_value[range_index]) { if(adjust_time < 3) { if(range_index < TOTAL_RANGE_NUM-1) { #ifdef DEBUG_AUTO_RANGE_ADJUST printk("switch to upper range: %d.\n", range_index); #endif range_index++; adjust_time++; goto re_adjust; } else { printk("infrared ray TOO HIGH?\n"); } } else { printk("proximity readjust exceed max retry times.\n"); } } else if((ir_count < down_range_value[range_index])) { if(adjust_time < 3) { if(range_index >=1) { #ifdef DEBUG_AUTO_RANGE_ADJUST printk("switch to lower range: %d.\n", range_index); #endif range_index--; adjust_time++; goto re_adjust; } else { printk("BUG: no exist lux value!!\n"); } } else { printk("proximity readjust exceed max retry times.\n"); } } } msleep(30); ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_PROXIMITY_ONCE); msleep(60); reg_val_lsb = aps_i2c_reg_read(aps, APS_12D_DATA_LSB); reg_val_msb = aps_i2c_reg_read(aps, APS_12D_DATA_MSB); ps_count = ((uint16_t)reg_val_msb << 8) + (uint16_t)reg_val_lsb; PROXIMITY_DEBUG("PS once lsb=%d; msb=%d; ps_count=%d \n", reg_val_lsb, reg_val_msb, ps_count); if (ps_count > 0xFFF){ PROXIMITY_DEBUG("get wrong ps value, ps_count=%d \n", ps_count); ps_count = 0xFFF; } if (ps_count < 0){ PROXIMITY_DEBUG("get wrong ps value, ps_count=%d \n", ps_count); ps_count = 0; } if((ps_count - ir_count) > high_threshold) flag = 0; else if( (ps_count - ir_count) < low_threshold ) flag = 1; else{ PROXIMITY_DEBUG("the value is in the threshold, do not report. \n"); } if( machine_is_msm7x25_u8150() || machine_is_msm7x25_c8150() || machine_is_msm7x25_c8510() \ || machine_is_msm7x25_u8160() || machine_is_msm7x25_u8130() || machine_is_msm7x25_u8159()) { /* skip invalid event */ if(-1 != flag) { if(1 == flag) { /* report far event immediately */ /* 0 is close, 1 is far */ input_report_abs(aps->input_dev, ABS_DISTANCE, flag); input_sync(aps->input_dev); } else if(last_event != flag) { printk("NOTE: skip unstable data: %s !!!\n", flag ? "far" : "close"); } else { PROXIMITY_DEBUG("report distance flag=%d \n", flag); /* 0 is close, 1 is far */ input_report_abs(aps->input_dev, ABS_DISTANCE, flag); input_sync(aps->input_dev); } } /* save the last event */ last_event = flag; /* * reset the sensor range to 1000. */ if(0 != range_index) { aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ (uint8_t)(APS_12D_IRDR_SEL_50MA << 6 | \ APS_12D_FREQ_SEL_DC << 4 | \ APS_12D_RES_SEL_12 << 2 | \ APS_12D_RANGE_SEL_ALS_1000)); #ifdef DEBUG_AUTO_RANGE_ADJUST printk("reset range!!\n"); #endif } } else { PROXIMITY_DEBUG("report distance flag=%d \n", flag); /* 0 is close, 1 is far */ input_report_abs(aps->input_dev, ABS_DISTANCE, flag); input_sync(aps->input_dev); } } if (atomic_read(&p_flag) && atomic_read(&l_flag)) msleep(120); if (atomic_read(&l_flag)) { ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_ALS_ONCE); msleep(60); reg_val_lsb = aps_i2c_reg_read(aps, APS_12D_DATA_LSB); reg_val_msb = aps_i2c_reg_read(aps, APS_12D_DATA_MSB); als_count = ((uint16_t)reg_val_msb << 8) + (uint16_t)reg_val_lsb; PROXIMITY_DEBUG("ALS once lsb=%d; msb=%d; als_count=%d \n", reg_val_lsb, reg_val_msb, als_count); if (als_count > 0xFFF){ PROXIMITY_DEBUG("get wrong als value, als_count=%d \n", als_count); als_count = 0xFFF; } als_level = LSENSOR_MAX_LEVEL - 1; for (i = 0; i < ARRAY_SIZE(lsensor_adc_table); i++){ if (als_count < lsensor_adc_table[i]){ als_level = i; break; } } PROXIMITY_DEBUG("report adc level=%d \n", als_level); if(aps_first_read) { /* report a invalid key first */ aps_first_read = 0; input_report_abs(aps->input_dev, ABS_LIGHT, -1); input_sync(aps->input_dev); } else { PROXIMITY_DEBUG("report lux value=%d \n", lsensor_lux_table[als_level]); input_report_abs(aps->input_dev, ABS_LIGHT, lsensor_lux_table[als_level]); input_sync(aps->input_dev); } } if (atomic_read(&p_flag) || atomic_read(&l_flag)) hrtimer_start(&aps->timer, ktime_set(sesc, nsesc), HRTIMER_MODE_REL); }
/*<BU5D08118 zhangtao 20100419 begin*/ static int aps_12d_probe( struct i2c_client *client, const struct i2c_device_id *id) { int ret; struct aps_data *aps; /*the aps_12d sensors ispower on*/ /* <BU5D07679 zhangtao 20100413 begin */ struct vreg *vreg_gp4=NULL; int rc; /* <DTS2010100800714 liugaofei 20101008 begin */ int i; /* DTS2010100800714 liugaofei 20101008 end */ vreg_gp4 = vreg_get(NULL, VREG_GP4_NAME); /* < DTS2010061200552 zhangtao 20100612 begin */ if (IS_ERR(vreg_gp4)) { pr_err("%s:gp4 power init get failed\n", __func__); } /* DTS2010061200552 zhangtao 20100612 end> */ /* <DTS2011012600839 liliang 20110215 begin */ /* set gp4 voltage as 2700mV for all */ rc = vreg_set_level(vreg_gp4,VREG_GP4_VOLTAGE_VALUE_2700); /* <DTS2011012600839 liliang 20110215 end >*/ if (rc) { PROXIMITY_DEBUG("%s: vreg_gp4 vreg_set_level failed \n", __func__); return rc; } rc = vreg_enable(vreg_gp4); if (rc) { pr_err("%s: vreg_gp4 vreg_enable failed \n", __func__); return rc; } mdelay(5); /* BU5D07679 zhangtao 20100413 end> */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { PROXIMITY_DEBUG(KERN_ERR "aps_12d_probe: need I2C_FUNC_I2C\n"); ret = -ENODEV; goto err_check_functionality_failed; } /* < DTS2010091001474 zhangtao 20100910 begin */ /* if querry the board is T1 or T2 turn off the proximity */ /*< DTS2010092400487 lijianzhao 20100924 begin */ /* This modification for version A&B of U8800,only */ if((machine_is_msm7x30_u8800())&&((get_hw_sub_board_id() == HW_VER_SUB_VA) || ((get_hw_sub_board_id() == HW_VER_SUB_VB)))) { printk(KERN_ERR "aps_12d_probe: aps is not supported in U8800 and U8800 T1 board!\n"); ret = -ENODEV; goto err_check_functionality_failed; } /* DTS2010092400487 lijianzhao 20100924 end >*/ /* DTS2010091001474 zhangtao 20100910 end > */ aps = kzalloc(sizeof(*aps), GFP_KERNEL); if (aps == NULL) { ret = -ENOMEM; goto err_alloc_data_failed; } mutex_init(&aps->mlock); INIT_WORK(&aps->work, aps_12d_work_func); aps->client = client; i2c_set_clientdata(client, aps); PROXIMITY_DEBUG(KERN_INFO "ghj aps_12d_probe send command 2\n "); /* Command 2 register: 25mA,DC,12bit,Range1 */ /* < DTS2010081803338 zhangtao 20100818 begin */ /* make the rang smaller can make the ir changge bigger */ ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ /* < DTS2010102103994 zhangtao 20101112 begin */ (uint8_t)(APS_12D_IRDR_SEL_50MA << 6 | \ APS_12D_FREQ_SEL_DC << 4 | \ APS_12D_RES_SEL_12 << 2 | \ APS_12D_RANGE_SEL_ALS_1000)); /* DTS2010102103994 zhangtao 20101112 end > */ /* DTS2010081803338 zhangtao 20100818 end > */ if(ret < 0) { goto err_detect_failed; } /* <DTS2010100800714 liugaofei 20101008 begin */ range_index = 0; for(i = 0; i < TOTAL_RANGE_NUM; i++) { /* NOTE: do NOT use the last one */ up_range_value[i] = MAX_ADC_OUTPUT - high_threshold_value[i] - RANGE_FIX; } down_range_value[0] = 0; for(i = 1; i < TOTAL_RANGE_NUM; i++) { /* NOTE: do not use the first one */ down_range_value[i] = (MAX_ADC_OUTPUT - high_threshold_value[i-1] - (MAX_ADC_OUTPUT / ADJUST_GATE)) / 4; } /* DTS2010100800714 liugaofei 20101008 end */ /* < DTS2011042705601 zhangtao 20110427 begin */ /*we don't use the input device sensors again */ aps->input_dev = input_allocate_device(); if (aps->input_dev == NULL) { ret = -ENOMEM; PROXIMITY_DEBUG(KERN_ERR "aps_12d_probe: Failed to allocate input device\n"); goto err_input_dev_alloc_failed; } aps->input_dev->name = "sensors_aps"; aps->input_dev->id.bustype = BUS_I2C; input_set_drvdata(aps->input_dev, aps); ret = input_register_device(aps->input_dev); if (ret) { printk(KERN_ERR "aps_probe: Unable to register %s input device\n", aps->input_dev->name); goto err_input_register_device_failed; } /* DTS2011042705601 zhangtao 20110427 end > */ set_bit(EV_ABS, aps->input_dev->evbit); input_set_abs_params(aps->input_dev, ABS_LIGHT, 0, 10240, 0, 0); input_set_abs_params(aps->input_dev, ABS_DISTANCE, 0, 1, 0, 0); ret = misc_register(&light_device); if (ret) { printk(KERN_ERR "aps_12d_probe: light_device register failed\n"); goto err_light_misc_device_register_failed; } ret = misc_register(&proximity_device); if (ret) { printk(KERN_ERR "aps_12d_probe: proximity_device register failed\n"); goto err_proximity_misc_device_register_failed; } /* < DTS2010090300997 zhangtao 20100903 begin */ if( light_device.minor != MISC_DYNAMIC_MINOR ){ light_device_minor = light_device.minor; } if( proximity_device.minor != MISC_DYNAMIC_MINOR ){ proximity_device_minor = proximity_device.minor ; } wake_lock_init(&proximity_wake_lock, WAKE_LOCK_SUSPEND, "proximity"); /* DTS2010090300997 zhangtao 20100903 end > */ hrtimer_init(&aps->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); aps->timer.function = aps_timer_func; aps_wq = create_singlethread_workqueue("aps_wq"); if (!aps_wq) { ret = -ENOMEM; goto err_create_workqueue_failed; } this_aps_data =aps; /* <DTS2011032104626 shenjinming 20110321 begin */ #ifdef CONFIG_HUAWEI_HW_DEV_DCT /* detect current device successful, set the flag as present */ set_hw_dev_flag(DEV_I2C_APS); #endif /* <DTS2011032104626 shenjinming 20110321 end> */ /* < DTS2011052606009 jiaxianghong 20110527 end */ printk(KERN_INFO "aps_12d_probe: Start Proximity Sensor APS-12D\n"); /* DTS2010072801000 zhangtao 20100728 end > */ return 0; err_create_workqueue_failed: misc_deregister(&proximity_device); err_proximity_misc_device_register_failed: misc_deregister(&light_device); err_light_misc_device_register_failed: err_input_register_device_failed: input_free_device(aps->input_dev); err_input_dev_alloc_failed: err_detect_failed: kfree(aps); err_alloc_data_failed: err_check_functionality_failed: /* < DTS2010061200552 zhangtao 20100612 begin */ if(NULL != vreg_gp4) { /* < DTS2011052101089 shenjinming 20110521 begin */ /* can't use the flag ret here, it will change the return value of probe function */ vreg_disable(vreg_gp4); /* delete a line */ /* DTS2011052101089 shenjinming 20110521 end > */ } /* DTS2010061200552 zhangtao 20100612 end > */ return ret; }
static void aps_12d_work_func(struct work_struct *work) { /* < DTS2010072801000 zhangtao 20100728 begin */ /* < DTS2010090300997 zhangtao 20100903 begin */ int flag = -1; /* DTS2010090300997 zhangtao 20100903 end > */ // delete flag_old int ret; int reg_val_lsb; int reg_val_msb; int sesc = aps_12d_delay/1000; int nsesc = (aps_12d_delay%1000)*1000000; /* <DTS2010060100640 zhangtao 20100601 begin*/ /* < DTS2010073101147 zhangtao 20100731 begin */ /* < DTS2010081803338 zhangtao 20100818 begin */ /* < DTS2010102103994 zhangtao 20101112 begin */ uint16_t high_threshold = 0; uint16_t low_threshold = 0; /* DTS2010102103994 zhangtao 20101112 end > */ /* DTS2010081803338 zhangtao 20100818 end > */ /* DTS2010073101147 zhangtao 20100731 end > */ /* DTS2010060100640 zhangtao 20100601 end>*/ int ir_count = 0; int ps_count = 0; uint16_t als_count = 0; uint8_t als_level = 0; /* del als_level_old */ uint8_t i; /* DTS2010072801000 zhangtao 20100728 end > */ struct aps_data *aps = container_of(work, struct aps_data, work); PROXIMITY_DEBUG("ghj aps_12d_work_func enter\n "); if (atomic_read(&p_flag)) { /* Command 1 register: IR once */ /* <DTS2010100800714 liugaofei 20101008 begin */ adjust_time = 0; re_adjust: /* init the range to the num last time we set */ if(( range_index >=0 ) && ( range_index < TOTAL_RANGE_NUM )) { aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ /* < DTS2010102103994 zhangtao 20101112 begin */ (uint8_t)(APS_12D_IRDR_SEL_50MA << 6 | \ APS_12D_FREQ_SEL_DC << 4 | \ APS_12D_RES_SEL_12 << 2 | \ range_reg_value[range_index])); high_threshold = high_threshold_value[range_index]; low_threshold = low_threshold_value[range_index]; /* DTS2010102103994 zhangtao 20101112 end > */ } else { PROXIMITY_DEBUG("BUG: range_index error!!!!\n"); range_index = 0; } er_adjust: /* DTS2010100800714 liugaofei 20101008 end */ ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_IR_ONCE); /* < DTS2010102103994 zhangtao 20101112 begin */ msleep(45); /* DTS2010102103994 zhangtao 20101112 end > */ reg_val_lsb = aps_i2c_reg_read(aps, APS_12D_DATA_LSB); reg_val_msb = aps_i2c_reg_read(aps, APS_12D_DATA_MSB); ir_count = ((uint16_t)reg_val_msb << 8) + (uint16_t)reg_val_lsb; PROXIMITY_DEBUG("IR once lsb=%d; msb=%d; ir_count=%d \n", reg_val_lsb, reg_val_msb, ir_count); /* < DTS2010072801000 zhangtao 20100728 begin */ if (ir_count > 0xFFF){ PROXIMITY_DEBUG("get wrong ir value, ir_count=%d \n", ir_count); ir_count = 0xFFF; } if (ir_count < 0){ PROXIMITY_DEBUG("get wrong ir value, ir_count=%d \n", ir_count); ir_count = 0; } /* <DTS2010100800714 liugaofei 20101008 begin */ /* * auto adjust the range * stratety: * if current adc value >= up_range_value[i] * switch to upper range * if current adc value < down_range_value[i] * switch to lower range */ if(ir_count > up_range_value[range_index]) { if(adjust_time < TOTAL_RANGE_NUM-1) { if(range_index < TOTAL_RANGE_NUM-1) { range_index++; adjust_time++; goto re_adjust; } else { PROXIMITY_DEBUG("infrared ray TOO HIGH?\n"); } } else { PROXIMITY_DEBUG("proximity readjust exceed max retry times.\n"); } } else if((ir_count < down_range_value[range_index])) { if(adjust_time < TOTAL_RANGE_NUM-1) { if(range_index >= TOTAL_RANGE_NUM-1) { range_index--; adjust_time++; goto re_adjust; } else { PROXIMITY_DEBUG("BUG: no exist lux value!!\n"); } } else { PROXIMITY_DEBUG("proximity readjust exceed max retry times.\n"); } } /* DTS2010100800714 liugaofei 20101008 end */ /* DTS2010072801000 zhangtao 20100728 end > */ ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_PROXIMITY_ONCE); /* < DTS2010102103994 zhangtao 20101112 begin */ msleep(45); /* DTS2010102103994 zhangtao 20101112 end > */ reg_val_lsb = aps_i2c_reg_read(aps, APS_12D_DATA_LSB); reg_val_msb = aps_i2c_reg_read(aps, APS_12D_DATA_MSB); ps_count = ((uint16_t)reg_val_msb << 8) + (uint16_t)reg_val_lsb; PROXIMITY_DEBUG("PS once lsb=%d; msb=%d; ps_count=%d \n", reg_val_lsb, reg_val_msb, ps_count); /* < DTS2010072801000 zhangtao 20100728 begin */ if (ps_count > 0xFFF){ PROXIMITY_DEBUG("get wrong ps value, ps_count=%d \n", ps_count); ps_count = 0xFFF; } if (ps_count < 0){ PROXIMITY_DEBUG("get wrong ps value, ps_count=%d \n", ps_count); ps_count = 0; } /* <DTS2010100800714 liugaofei 20101008 begin */ /* < DTS2011071500961 liujinggang 20110715 begin */ /*get value of proximity and light*/ proximity_data_value = ps_count; if (range_index == 1){ light_data_value = ir_count*RANG_VALUE; } else { light_data_value = ir_count; } /* DTS2011071500961 liujinggang 20110715 end > */ if ((ps_count - ir_count) > err_threshold_value[range_index] || (ps_count - ir_count) < 0 ) flag = -1; else if( (ps_count - ir_count) > high_threshold ) /* DTS2010100800714 liugaofei 20101008 end */ flag = 0; else if( (ps_count - ir_count) < low_threshold ) flag = 1; else{ PROXIMITY_DEBUG("the value is in the threshold, do not report. \n"); } /* < DTS2010102103994 zhangtao 20101112 begin */ APS_DBG("the ps -ir is %d,the ps is %d,the ir is %d,the range_index is %d!\n",ps_count - ir_count,ps_count,ir_count,range_index); /* DTS2010102103994 zhangtao 20101112 end > */ /* DTS2010072801000 zhangtao 20100728 end > */ /* <DTS2010100800714 liugaofei 20101008 begin */ /* skip invalid event */ if(-1 != flag) { if(1 == flag) { /* report far event immediately */ /* 0 is close, 1 is far */ input_report_abs(aps->input_dev, ABS_DISTANCE, flag); input_sync(aps->input_dev); } else if(last_event != flag) { PROXIMITY_DEBUG("NOTE: skip unstable data: %s !!!\n", flag ? "far" : "close"); last_event = flag; goto er_adjust; } else { PROXIMITY_DEBUG("report distance flag=%d \n", flag); /* 0 is close, 1 is far */ input_report_abs(aps->input_dev, ABS_DISTANCE, flag); input_sync(aps->input_dev); } } /* save the last event */ last_event = flag; /* * reset the sensor range to 1000. */ if(0 != range_index) { aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ /* < DTS2010102103994 zhangtao 20101112 begin */ (uint8_t)(APS_12D_IRDR_SEL_50MA << 6 | \ APS_12D_FREQ_SEL_DC << 4 | \ APS_12D_RES_SEL_12 << 2 | \ APS_12D_RANGE_SEL_ALS_1000)); /* DTS2010102103994 zhangtao 20101112 end > */ } } /* DTS2010100800714 liugaofei 20101008 end */ if (atomic_read(&l_flag)) { ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_ALS_ONCE); /* < DTS2010102103994 zhangtao 20101112 begin */ msleep(45); /* DTS2010102103994 zhangtao 20101112 end > */ reg_val_lsb = aps_i2c_reg_read(aps, APS_12D_DATA_LSB); reg_val_msb = aps_i2c_reg_read(aps, APS_12D_DATA_MSB); als_count = ((uint16_t)reg_val_msb << 8) + (uint16_t)reg_val_lsb; PROXIMITY_DEBUG("ALS once lsb=%d; msb=%d; als_count=%d \n", reg_val_lsb, reg_val_msb, als_count); /* < DTS2010072801000 zhangtao 20100728 begin */ if (als_count > 0xFFF){ PROXIMITY_DEBUG("get wrong als value, als_count=%d \n", als_count); als_count = 0xFFF; } als_level = LSENSOR_MAX_LEVEL - 1; for (i = 0; i < ARRAY_SIZE(lsensor_adc_table); i++){ if (als_count < lsensor_adc_table[i]){ als_level = i; break; } } PROXIMITY_DEBUG("report adc level=%d \n", als_level); if(aps_first_read) { /* report a invalid key first */ aps_first_read = 0; /* < DTS2011010500959 zhangtao 20110119 begin */ /* < DTS2011030404089 zhangtao 20110314 begin */ /*changge the report event as -1 so the app will not changge anything*/ input_report_abs(aps->input_dev, ABS_LIGHT, -1); /* DTS2011030404089 zhangtao 20110314 end > */ /* DTS2011010500959 zhangtao 20110119 end > */ input_sync(aps->input_dev); } else { /* < DTS2011042705601 zhangtao 20110427 begin */ input_report_abs(aps->input_dev, ABS_LIGHT, als_level); /* DTS2011042705601 zhangtao 20110427 end > */ input_sync(aps->input_dev); /* DTS2010072801000 zhangtao 20100728 end > */ } } if (atomic_read(&p_flag) || atomic_read(&l_flag)) hrtimer_start(&aps->timer, ktime_set(sesc, nsesc), HRTIMER_MODE_REL); }