//PS enable function int pa12201001_enable_ps(struct i2c_client *client, int enable) { int res; u8 regdata=0; u8 sendvalue=0; if(enable == 1) //PS ON { printk("pa12201001 enable ps sensor\n"); res=i2c_read_reg(client,REG_CFG0,®data); //Read Status if(res<0){ APS_ERR("i2c_read function err\n"); return res; }else{ //sendvalue=regdata & 0xFD; //clear bit //sendvalue=sendvalue | 0x02; //0x02 PS Flag sendvalue=regdata & 0xFC; //clear bit-0 & bit-1 sendvalue=sendvalue | 0x02; //0x02 PS On res=i2c_write_reg(client,REG_CFG0,sendvalue); //Write PS enable if(res<0){ APS_ERR("i2c_write function err\n"); return res; } res=i2c_read_reg(client,REG_CFG0,®data); //Read Status APS_LOG("CFG0 Status: %d\n",regdata); } }else{ //PS OFF printk("pa12201001 disable ps sensor\n"); res=i2c_read_reg(client,REG_CFG0,®data); //Read Status if(res<0){ APS_ERR("i2c_read function err\n"); return res; }else{ APS_LOG("CFG0 Status: %d\n",regdata); //sendvalue=regdata & 0xFD; //clear bit sendvalue=regdata & 0xFC; //clear bit-0 & bit-1 res=i2c_write_reg(client,REG_CFG0,sendvalue); //Write PS disable if(res<0){ APS_ERR("i2c_write function err\n"); return res; } } } return 0; }
/*----------------------------------------------------------------------------*/ static int touch_probe(struct platform_device *pdev) { struct hwmsen_object obj_ps; int err = 0; if(!(touch_obj = kzalloc(sizeof(touch_obj), GFP_KERNEL))) { err = -ENOMEM; } memset(touch_obj, 0, sizeof(touch_obj)); if((err = misc_register(&touch_device))) { APS_ERR("touch_device register failed\n"); } obj_ps.self = touch_obj; obj_ps.polling = 0; obj_ps.sensor_operate = touch_ps_operate; if((err = hwmsen_attach(ID_PROXIMITY, &obj_ps))) { APS_ERR("attach fail = %d\n", err); } touch_create_attr(&touch_alsps_driver.driver); APS_LOG("%s: OK\n", __func__); return 0; }
static int pa122_run_calibration(struct txc_data *data) { struct i2c_client *client = data->client; int i, j; int ret; u16 sum_of_pdata = 0; u8 temp_pdata[20],buftemp[1],cfg0data=0,cfg2data=0; unsigned int ArySize = 20; unsigned int cal_check_flag = 0; u8 value=0; int calibvalue; printk("%s: START proximity sensor calibration\n", __func__); i2c_write_reg(client, REG_PS_TH, 0xFF); i2c_write_reg(client, REG_PS_TL, 0); RECALIBRATION: sum_of_pdata = 0; ret = i2c_read_reg(client, REG_CFG0, &cfg0data); ret = i2c_read_reg(client, REG_CFG2, &cfg2data); /*Set to offset mode & disable interrupt from ps*/ ret = i2c_write_reg(client, REG_CFG2, cfg2data & 0x33); /*Set crosstalk = 0*/ ret = i2c_write_reg(client, REG_PS_OFFSET, 0x00); if (ret < 0) { pr_err("%s: txc_write error\n", __func__); /* Restore CFG2 (Normal mode) and Measure base x-talk */ ret = i2c_write_reg(client, REG_CFG0, cfg0data); ret = i2c_write_reg(client, REG_CFG2, cfg2data | 0xC0); return ret; } /*PS On*/ ret = i2c_write_reg(client, REG_CFG0, cfg0data | 0x02); mdelay(50); for(i = 0; i < 20; i++) { mdelay(15); ret = i2c_read_reg(client,REG_PS_DATA,temp_pdata+i); APS_LOG("temp_data = %d\n", temp_pdata[i]); } /* pdata sorting */ for (i = 0; i < ArySize - 1; i++) for (j = i+1; j < ArySize; j++) if (temp_pdata[i] > temp_pdata[j]) pa12_swap(temp_pdata + i, temp_pdata + j); /* calculate the cross-talk using central 10 data */ for (i = 5; i < 15; i++) { APS_LOG("%s: temp_pdata = %d\n", __func__, temp_pdata[i]); sum_of_pdata = sum_of_pdata + temp_pdata[i]; } calibvalue = sum_of_pdata/10; /* Restore CFG2 (Normal mode) and Measure base x-talk */ ret = i2c_write_reg(client, REG_CFG0, cfg0data); ret = i2c_write_reg(client, REG_CFG2, cfg2data | 0xC0); i2c_write_reg(client, REG_PS_TH, PA12_PS_FAR_TH_HIGH); i2c_write_reg(client, REG_PS_TL, PA12_PS_NEAR_TH_LOW); if (calibvalue < PA12_PS_OFFSET_MAX) { data->ps_calibvalue = calibvalue + PA12_PS_OFFSET_EXTRA; } else { printk("%s: invalid calibrated data, calibvalue %d\n", __func__, calibvalue); if(cal_check_flag == 0) { APS_LOG("%s: RECALIBRATION start\n", __func__); cal_check_flag = 1; goto RECALIBRATION; } else { APS_LOG("%s: CALIBRATION FAIL -> " "cross_talk is set to DEFAULT\n", __func__); ret = i2c_write_reg(client, REG_PS_OFFSET, data->factory_calibvalue); data->pa122_sys_run_cal = 0; return -EINVAL; } } CROSSTALKBASE_RECALIBRATION: /*PS On*/ ret = i2c_write_reg(client, REG_CFG0, cfg0data | 0x02); /*Write offset value to register 0x10*/ ret = i2c_write_reg(client, REG_PS_OFFSET, data->ps_calibvalue); for(i = 0; i < 10; i++) { mdelay(15); ret = i2c_read_reg(client,REG_PS_DATA,temp_pdata+i); APS_LOG("temp_data = %d\n", temp_pdata[i]); } /* pdata sorting */ for (i = 0; i < 9; i++) { for (j = i+1; j < 10; j++) { if (temp_pdata[i] > temp_pdata[j]) pa12_swap(temp_pdata + i, temp_pdata + j); } } /* calculate the cross-talk_base using central 5 data */ sum_of_pdata = 0; for (i = 3; i < 8; i++) { APS_LOG("%s: temp_pdata = %d\n", __func__, temp_pdata[i]); sum_of_pdata = sum_of_pdata + temp_pdata[i]; } data->calibvalue_base = sum_of_pdata/5; if(data->calibvalue_base > 0) { if (data->calibvalue_base >= 8) data->ps_calibvalue += data->calibvalue_base/8; else data->ps_calibvalue += 1; goto CROSSTALKBASE_RECALIBRATION; } else if (data->calibvalue_base == 0) { data->factory_calibvalue = data->ps_calibvalue; data->pa122_sys_run_cal = 1; } /* Restore CFG0 */ ret = i2c_write_reg(client, REG_CFG0, cfg0data); printk("%s: FINISH proximity sensor calibration, %d\n", __func__, data->ps_calibvalue); }
static int pa122_run_fast_calibration(struct i2c_client *client) { struct txc_data *data = i2c_get_clientdata(client); int i = 0; int j = 0; u16 sum_of_pdata = 0; u8 xtalk_temp = 0; u8 temp_pdata[4], cfg0data = 0,cfg2data = 0,cfg3data = 0; unsigned int ArySize = 4; APS_LOG("START proximity sensor calibration\n"); i2c_write_reg(client, REG_PS_TH, 0xFF); i2c_write_reg(client, REG_PS_TL, 0); i2c_read_reg(client, REG_CFG0, &cfg0data); i2c_read_reg(client, REG_CFG2, &cfg2data); i2c_read_reg(client, REG_CFG3, &cfg3data); /*Offset mode & disable intr from ps*/ i2c_write_reg(client, REG_CFG2, cfg2data & 0x33); /*PS sleep time 6.5ms */ i2c_write_reg(client, REG_CFG3, cfg3data & 0xC7); /*Set crosstalk = 0*/ i2c_write_reg(client, REG_PS_OFFSET, 0x00); /*PS On*/ i2c_write_reg(client, REG_CFG0, cfg0data | 0x02); mdelay(50); for(i = 0; i < 4; i++) { mdelay(7); i2c_read_reg(client,REG_PS_DATA,temp_pdata+i); APS_LOG("temp_data = %d\n", temp_pdata[i]); } /* pdata sorting */ for (i = 0; i < ArySize - 1; i++) for (j = i+1; j < ArySize; j++) if (temp_pdata[i] > temp_pdata[j]) pa12_swap(temp_pdata + i, temp_pdata + j); /* calculate the cross-talk using central 2 data */ for (i = 1; i < 3; i++) { APS_LOG("%s: temp_pdata = %d\n", __func__, temp_pdata[i]); sum_of_pdata = sum_of_pdata + temp_pdata[i]; } xtalk_temp = sum_of_pdata/2; APS_LOG("%s: sum_of_pdata = %d calibvalue = %d\n", __func__, sum_of_pdata, xtalk_temp); /* Restore Data */ i2c_write_reg(client, REG_CFG0, cfg0data); i2c_write_reg(client, REG_CFG2, cfg2data | 0xC0); //make sure return normal mode i2c_write_reg(client, REG_CFG3, cfg3data); i2c_write_reg(client, REG_PS_TH, PA12_PS_FAR_TH_HIGH); i2c_write_reg(client, REG_PS_TL, PA12_PS_NEAR_TH_LOW); if (((xtalk_temp + PA12_PS_OFFSET_EXTRA) > data->factory_calibvalue) && (xtalk_temp < PA12_PS_OFFSET_MAX)) { printk("Fast calibrated data=%d\n",xtalk_temp); data->fast_calib_flag = 1; data->fast_calibvalue = xtalk_temp + PA12_PS_OFFSET_EXTRA; /* Write offset value to 0x10 */ i2c_write_reg(client, REG_PS_OFFSET, xtalk_temp + PA12_PS_OFFSET_EXTRA); return xtalk_temp + PA12_PS_OFFSET_EXTRA; } else { printk("Fast calibration fail, calibvalue=%d, use factory_calibvalue %d\n",xtalk_temp, data->factory_calibvalue); data->fast_calib_flag = 0; i2c_write_reg(client, REG_PS_OFFSET, data->factory_calibvalue); xtalk_temp = data->factory_calibvalue; return xtalk_temp; } }
static int rpr400_enable_ps(struct i2c_client *client, int enable) { struct PS_ALS_DATA *obj = i2c_get_clientdata(client); u8 databuf[2]; int res = 0; u8 buffer[1]; u8 reg_value[1]; u8 power_state, power_set; PWR_ST pwr_st; if(client == NULL) { APS_DBG("CLIENT CANN'T EQUL NULL\n"); return -1; } buffer[0]= REG_MODECONTROL; res = i2c_master_send(client, buffer, 0x1); if(res <= 0){ goto EXIT_ERR; } res = i2c_master_recv(client, reg_value, 0x1); if(res <= 0){ goto EXIT_ERR; } power_state = reg_value[0] & 0xF; if(MCTL_TABLE[power_state].ALS == 0){ pwr_st.als_state = CTL_STANDBY; }else{ pwr_st.als_state = CTL_STANDALONE; } if(enable){ if (pwr_st.als_state == CTL_STANDALONE){ power_set = PWRON_PS_ALS; databuf[0] = REG_MODECONTROL; databuf[1] = power_set | (reg_value[0] & CLR_LOW4BIT); res = i2c_master_send(client, databuf, 0x2); if(res <= 0){ goto EXIT_ERR; } }else if(pwr_st.als_state == CTL_STANDBY){ power_set = PWRON_ONLY_PS; databuf[0] = REG_MODECONTROL; databuf[1] = power_set | (reg_value[0] & CLR_LOW4BIT); res = i2c_master_send(client, databuf, 0x2); if(res <= 0){ goto EXIT_ERR; } } atomic_set(&obj->ps_deb_on, 1); atomic_set(&obj->ps_deb_end, jiffies+atomic_read(&obj->ps_debounce)/(1000/HZ)); if(0 == obj->polling_mode_ps) { databuf[0] = REG_PSTL_LSB; databuf[1] = (u8)(PS_ALS_SET_PS_TL & 0x00FF); res = i2c_master_send(client, databuf, 0x2); if(res <= 0){ goto EXIT_ERR; } databuf[0] = REG_PSTL_MBS; databuf[1] = (u8)((PS_ALS_SET_PS_TL & 0xFF00) >> 8); res = i2c_master_send(client, databuf, 0x2); if(res <= 0){ goto EXIT_ERR; } databuf[0] = REG_PSTH_LSB; databuf[1] = (u8)(PS_ALS_SET_ALS_TH & 0x00FF); res = i2c_master_send(client, databuf, 0x2); if(res <= 0){ goto EXIT_ERR; } databuf[0] = REG_PSTH_MBS; databuf[1] = (u8)((PS_ALS_SET_ALS_TH & 0xFF00) >> 8); res = i2c_master_send(client, databuf, 0x2); if(res <= 0){ goto EXIT_ERR; } buffer[0]= REG_INTERRUPT; res = i2c_master_send(client, buffer, 0x1); if(res <= 0){ goto EXIT_ERR; } res = i2c_master_recv(client, reg_value, 0x1); if(res <= 0){ goto EXIT_ERR; } databuf[0] = REG_INTERRUPT; databuf[1] = reg_value[0]|MODE_PROXIMITY; res = i2c_master_send(client, databuf, 0x2); if(res <= 0){ goto EXIT_ERR; } APS_LOG("rpr400_enable_ps: ps enabled."); } }else{
/*----------------------------------------------------------------------------*/ static ssize_t TGesture_show_state(struct device_driver *ddri, char *buf) { APS_LOG("tgesture_state = %d\n", tgesture_state); return snprintf(buf, PAGE_SIZE, "%d\n", tgesture_state); }