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); }
static ssize_t proximity_state_show(struct device *dev, struct device_attribute *attr, char *buf) { struct gp2a_data *data = dev_get_drvdata(dev); static int count; /*count for proximity average */ int D2_data = 0; unsigned char get_D2_data[2] = { 0, }; mutex_lock(&data->data_mutex); msleep(10); gp2a_i2c_read(DATA2_LSB, get_D2_data, sizeof(get_D2_data)); mutex_unlock(&data->data_mutex); D2_data = (get_D2_data[1] << 8) | get_D2_data[0]; data->average[count] = D2_data; count++; if (count == PROX_READ_NUM) count = 0; //D2_data = D2_data - (data->offset_value); // for ADC compensation //printk(KERN_INFO "[GP2A] %s: D2_data = %d\n", __func__, D2_data); if(D2_data >=0 && D2_data <1024) D2_data_val = D2_data; else D2_data = D2_data_val; return snprintf(buf, PAGE_SIZE, "%d\n", D2_data); }
static ssize_t gp2a_light_raw_data_show(struct device *dev, struct device_attribute *attr, char *buf) { struct gp2a_data *data = dev_get_drvdata(dev); unsigned char get_data[4] = { 0, }; int d0_raw_data = 0; int d1_raw_data = 0; int ret = 0; if (bShutdown == true) { pr_err("%s bShutdown true.", __func__); goto done; } mutex_lock(&data->data_mutex); ret = gp2a_i2c_read(data, DATA0_LSB, get_data, sizeof(get_data)); mutex_unlock(&data->data_mutex); if (ret < 0) pr_err("%s i2c err: %d\n", __func__, ret); d0_raw_data = (get_data[1] << 8) | get_data[0]; /* clear */ d1_raw_data = (get_data[3] << 8) | get_data[2]; /* IR */ done: return snprintf(buf, PAGE_SIZE, "%d,%d\n", d0_raw_data, d1_raw_data); }
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); }
void gp2a_panic_display(struct i2c_adapter *pAdap) { u8 value; int ret; /* * Check driver has been started. */ if ( !(gp2a && gp2a->client && gp2a->client->adapter)) return; /* * If there is an associated LDO check to make sure it is powered, if * not then we can exit as it wasn't powered when panic occurred. */ if (gp2a->power_state != GP2A_POWER_ON){ pr_emerg("\n\n[GP2A Powered off at this time]\n"); return; } /* * If pAdap is NULL then exit with message. */ if ( !pAdap ){ pr_emerg("\n\n%s Passed NULL pointer!\n",__func__); return; } /* * If pAdap->algo_data is not NULL then this driver is using HW I2C, * then change adapter to use GPIO I2C panic driver. * NB!Will "probably" not work on systems with dedicated I2C pins. */ if ( pAdap->algo_data ){ gp2a->client->adapter = pAdap; } else{ /* * Otherwise use panic safe SW I2C algo, */ gp2a->client->adapter->algo = pAdap->algo; } pr_emerg("\n\n[Display of GP2A registers]\n"); /* Can only read Proximity reg, all others are write only! */ ret = gp2a_i2c_read(gp2a->client, GP2A_REG_PROX, &value, 1); if (ret < 0) { pr_emerg("\t[%02d]: Failed to get value\n", GP2A_REG_PROX); } else { pr_emerg("\t[%02d]: 0x%02x\n", GP2A_REG_PROX, value); } }
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); }
static ssize_t proximity_cal_show(struct device *dev, struct device_attribute *attr, char *buf) { struct gp2a_data *data = dev_get_drvdata(dev); int thresh_hi; unsigned char get_D2_data[2]; msleep(20); gp2a_i2c_read(data, PS_HT_LSB, get_D2_data, sizeof(get_D2_data)); thresh_hi = (get_D2_data[1] << 8) | get_D2_data[0]; data->threshold_high = thresh_hi; return sprintf(buf, "%d,%d\n", data->offset_value, data->threshold_high); }
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); }
static ssize_t proximity_thresh_show(struct device *dev, struct device_attribute *attr, char *buf) { struct gp2a_data *data = dev_get_drvdata(dev); int thresh_hi = 0; unsigned char get_D2_data[2]; msleep(20); gp2a_i2c_read(data, PS_HT_LSB, get_D2_data, sizeof(get_D2_data)); thresh_hi = (get_D2_data[1] << 8) | get_D2_data[0]; pr_info("%s: THRESHOLD = %d\n", __func__, thresh_hi); return sprintf(buf, "prox_threshold = %d\n", thresh_hi); }
/* * get_gp2a_proximity_value() is called by magnetic sensor driver(ak8973) * for reading proximity value. */ int get_gp2a_proximity_value(void) { debug("%s called",__func__); #if 0 int ret =0; u8 prox_value; if((ret=gp2a_i2c_read(&prox_value))<0) { error("gp2a_i2c_read failed"); return -1; } else return (!prox_value); #else return gpio_get_value(GPIO_PS_OUT); #endif }
static ssize_t gp2a_prox_raw_data_show(struct device *dev, struct device_attribute *attr, char *buf) { struct gp2a_data *data = dev_get_drvdata(dev); int d2_data = 0; unsigned char raw_data[2] = { 0, }; if (bShutdown == true) { pr_err("%s bShutdown true.", __func__); goto done; } mutex_lock(&data->data_mutex); gp2a_i2c_read(data, 0x10, raw_data, sizeof(raw_data)); mutex_unlock(&data->data_mutex); d2_data = (raw_data[1] << 8) | raw_data[0]; done: return snprintf(buf, PAGE_SIZE, "%d\n", d2_data); }
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); }
static int gp2a_prox_adc_read(struct gp2a_data *data) { int sum[OFFSET_ARRAY_LENGTH]; int i = OFFSET_ARRAY_LENGTH-1; int avg = 0; int min = 0; int max = 0; int total = 0; if (bShutdown == true) { pr_err("%s bShutdown true.", __func__); goto done; } mutex_lock(&data->data_mutex); do { unsigned char get_D2_data[2] = {0,}; int D2_data; msleep(50); gp2a_i2c_read(data, DATA2_LSB, get_D2_data, sizeof(get_D2_data)); D2_data = (get_D2_data[1] << 8) | get_D2_data[0]; sum[i] = D2_data; if (i == OFFSET_ARRAY_LENGTH - 1) { min = sum[i]; max = sum[i]; } else { if (sum[i] < min) min = sum[i]; else if (sum[i] > max) max = sum[i]; } total += sum[i]; } while (i--); mutex_unlock(&data->data_mutex); total -= (min + max); avg = (int)(total / (OFFSET_ARRAY_LENGTH - 2)); pr_info("%s offset = %d\n", __func__, avg); done: return avg; }
/* Light Sysfs interface */ static ssize_t lightsensor_raw_show(struct device *dev, struct device_attribute *attr, char *buf) { struct gp2a_data *data = dev_get_drvdata(dev); unsigned char get_data[4] = { 0, }; int D0_raw_data; int D1_raw_data; int ret = 0; mutex_lock(&data->data_mutex); ret = gp2a_i2c_read(data, DATA0_LSB, get_data, sizeof(get_data)); mutex_unlock(&data->data_mutex); if (ret < 0) pr_err("%s i2c err: %d\n", __func__, ret) ; D0_raw_data = (get_data[1] << 8) | get_data[0]; /* clear */ D1_raw_data = (get_data[3] << 8) | get_data[2]; /* IR */ return snprintf(buf, PAGE_SIZE, "%d,%d\n", D0_raw_data, D1_raw_data); }
static ssize_t gp2a_prox_thresh_show(struct device *dev, struct device_attribute *attr, char *buf) { struct gp2a_data *data = dev_get_drvdata(dev); int thresh_hi = 0, thresh_low = 0; unsigned char get_D2_data[4]; if (bShutdown == true) { pr_err("%s bShutdown true.", __func__); goto done; } msleep(20); gp2a_i2c_read(data, PS_LT_LSB, get_D2_data, sizeof(get_D2_data)); thresh_hi = (get_D2_data[3] << 8) | get_D2_data[2]; thresh_low = (get_D2_data[1] << 8) | get_D2_data[0]; pr_info("%s THRESHOLD = %d\n", __func__, thresh_hi); done: return snprintf(buf, PAGE_SIZE, "%d,%d\n", thresh_hi, thresh_low); }
static void gp2a_work_avg_prox(struct work_struct *work) { struct gp2a_data *data = container_of((struct delayed_work *)work, struct gp2a_data, prox_avg_work); int min = 0, max = 0, avg = 0; int i = 0; unsigned char raw_data[2] = { 0, }; for (i = 0; i < PROX_READ_NUM; i++) { int gp2a_prox_value; mutex_lock(&data->data_mutex); gp2a_i2c_read(data, 0x10, raw_data, sizeof(raw_data)); mutex_unlock(&data->data_mutex); gp2a_prox_value = (raw_data[1] << 8) | raw_data[0]; if (gp2a_prox_value > GP2A_PROX_MAX) gp2a_prox_value = GP2A_PROX_MAX; if (gp2a_prox_value > GP2A_PROX_MIN) { avg += gp2a_prox_value; if (!i) min = gp2a_prox_value; else if (gp2a_prox_value < min) min = gp2a_prox_value; if (gp2a_prox_value > max) max = gp2a_prox_value; } else { gp2a_prox_value = GP2A_PROX_MIN; } msleep(40); } avg /= i; data->avg[0] = min; data->avg[1] = avg; data->avg[2] = max; if (data->prox_enabled) schedule_delayed_work(&data->prox_avg_work, msecs_to_jiffies(data->prox_delay)); }
static ssize_t proximity_state_show(struct device *dev, struct device_attribute *attr, char *buf) { struct gp2a_data *data = dev_get_drvdata(dev); static int count; /*count for proximity average */ int D2_data = 0; unsigned char get_D2_data[2] = { 0, }; mutex_lock(&data->data_mutex); gp2a_i2c_read(data, 0x10, get_D2_data, sizeof(get_D2_data)); mutex_unlock(&data->data_mutex); D2_data = (get_D2_data[1] << 8) | get_D2_data[0]; data->average[count] = D2_data; count++; if (count == PROX_READ_NUM) count = 0; pr_debug("%s: D2_data = %d\n", __func__, D2_data); return snprintf(buf, PAGE_SIZE, "%d\n", D2_data); }
static ssize_t gp2a_prox_cal_show(struct device *dev, struct device_attribute *attr, char *buf) { struct gp2a_data *data = dev_get_drvdata(dev); int thresh_hi, thresh_low; unsigned char get_D2_data[4]; if (bShutdown == true){ pr_err("%s bShutdown true.", __func__); goto done; } msleep(20); gp2a_i2c_read(data, PS_LT_LSB, get_D2_data, sizeof(get_D2_data)); thresh_hi = (get_D2_data[3] << 8) | get_D2_data[2]; thresh_low = (get_D2_data[1] << 8) | get_D2_data[0]; data->threshold_high = thresh_hi; done: return sprintf(buf, "%d,%d,%d\n", data->offset_value, thresh_hi, thresh_low); }
static int proximity_adc_read(struct gp2a_data *data) { int sum[OFFSET_ARRAY_LENGTH]; int i = OFFSET_ARRAY_LENGTH-1; int avg; int min = 0; int max = 0; int total = 0; int D2_data; unsigned char get_D2_data[2]={0,}; mutex_lock(&data->data_mutex); do { msleep(50); gp2a_i2c_read(DATA2_LSB, get_D2_data, sizeof(get_D2_data)); D2_data = (get_D2_data[1] << 8) | get_D2_data[0]; sum[i] = D2_data; if (i == OFFSET_ARRAY_LENGTH - 1) { min = sum[i]; max = sum[i]; } else { if (sum[i] < min) min = sum[i]; else if (sum[i] > max) max = sum[i]; } total += sum[i]; } while (i--); mutex_unlock(&data->data_mutex); total -= (min + max); avg = (int)(total / (OFFSET_ARRAY_LENGTH - 2)); printk(KERN_INFO "[GP2A] %s: offset = %d\n", __func__, avg); return avg; }
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); }
static int gp2a_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct input_dev *input_dev; struct gp2a_data *gp2a; struct gp2a_platform_data *pdata = client->dev.platform_data; int err = 0; u8 vo; pr_info("%s: is starting!(%d)\n", __func__, __LINE__); nondetect = PROX_NONDETECT; detect = PROX_DETECT; if (!pdata) { pr_err("%s: missing pdata!\n", __func__); err = -ENODEV; goto done; } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("%s: i2c functionality check failed!\n", __func__); err = -ENODEV; goto done; } gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL); if (!gp2a) { pr_err("%s: failed to alloc memory for module data\n", __func__); err = -ENOMEM; goto done; } gp2a->pdata = pdata; gp2a->i2c_client = client; i2c_set_clientdata(client, gp2a); if (pdata->hw_setup) err = pdata->hw_setup(&client->dev); if (err < 0) { pr_err("%s: hw_setup failed(%d)!\n", __func__, err); err = -ENODEV; goto done; } if (pdata->hw_pwr) { pdata->hw_pwr(1); msleep(15); } err = gp2a_i2c_read(gp2a, REGS_PROX, &vo); if (err < 0) { pr_err("%s: fail to read i2c data.\n", __func__); goto err_i2c_read; } /* wake lock init */ wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND, "prx_wake_lock"); mutex_init(&gp2a->power_lock); /* allocate proximity input_device */ input_dev = input_allocate_device(); if (!input_dev) { pr_err("%s: could not allocate input device\n", __func__); goto err_input_allocate_device_proximity; } err = input_register_device(input_dev); if (err < 0) { pr_err("%s: could not register input device\n", __func__); input_free_device(input_dev); goto err_input_allocate_device_proximity; } gp2a->proximity_input_dev = input_dev; input_set_drvdata(input_dev, gp2a); input_dev->name = "proximity_sensor"; input_set_capability(input_dev, EV_ABS, ABS_DISTANCE); input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0); err = sysfs_create_group(&input_dev->dev.kobj, &proximity_attribute_group); if (err) { pr_err("%s: could not create sysfs group\n", __func__); goto err_sysfs_create_group_proximity; } /* the timer just fires off a work queue request. we need a thread to read the i2c (can be slow and blocking). */ INIT_WORK(&gp2a->work_prox, gp2a_prox_work_func); err = gp2a_setup_irq(gp2a); if (err) { pr_err("%s: could not setup irq\n", __func__); goto err_setup_irq; } err = sensors_register(gp2a->proximity_dev, gp2a, proxi_attrs, "proximity_sensor"); if (err < 0) { pr_info("%s: could not sensors_register\n", __func__); goto exit_gp2a_sensors_register; } /* set initial proximity value as 1 */ input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1); input_sync(gp2a->proximity_input_dev); pr_info("%s: is successful!(%d)\n", __func__, __LINE__); return 0; /* error, unwind it all */ exit_gp2a_sensors_register: free_irq(gp2a->irq, gp2a); gpio_free(gp2a->pdata->ps_vout_gpio); err_setup_irq: sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj, &proximity_attribute_group); err_sysfs_create_group_proximity: input_unregister_device(gp2a->proximity_input_dev); err_input_allocate_device_proximity: mutex_destroy(&gp2a->power_lock); wake_lock_destroy(&gp2a->prx_wake_lock); err_i2c_read: if (pdata->hw_teardown()) pdata->hw_teardown(); kfree(gp2a); done: pr_info("%s: done(%d)\n", __func__, __LINE__); return err; }
int lightsensor_get_adc(struct gp2a_data *data) { unsigned char get_data[4] = { 0, }; int D0_raw_data; int D1_raw_data; int D0_data; int D1_data; int lx = 0; u8 value; int light_alpha = 0; int light_beta = 0; static int lx_prev; int ret ; int d0_boundary = 92; #ifndef CONFIG_MACH_LT02 int d0_custom[9] = { 0, }; int i = 0; #endif mutex_lock(&data->data_mutex); ret = gp2a_i2c_read(data, DATA0_LSB, get_data, sizeof(get_data)); mutex_unlock(&data->data_mutex); if (ret < 0) return lx_prev; D0_raw_data = (get_data[1] << 8) | get_data[0]; /* clear */ D1_raw_data = (get_data[3] << 8) | get_data[2]; /* IR */ if (data->pdata->version) { /* GP2AP 030 */ #ifdef CONFIG_MACH_LT02 d0_boundary = 91; if (100 * D1_raw_data <= 40 * D0_raw_data) { light_alpha = 861; light_beta = 0; } else if (100 * D1_raw_data <= 62 * D0_raw_data) { light_alpha = 2269; light_beta = 3521; } else if (100 * D1_raw_data <=d0_boundary * D0_raw_data) { if( (D0_raw_data < 400) && (data->lightsensor_mode == 0 ) ) { light_alpha = 421; light_beta = 455; }else if( (D0_raw_data < 600) && (data->lightsensor_mode == 0 ) ) { light_alpha = 463; light_beta = 500; }else if( (D0_raw_data < 1700) && (data->lightsensor_mode == 0 ) ) { light_alpha = 526; light_beta = 568; }else if( (D0_raw_data < 2200) && (data->lightsensor_mode == 0 ) ) { light_alpha = 568; light_beta = 614; }else if( (D0_raw_data < 3500) && (data->lightsensor_mode == 0 ) ) { light_alpha = 652; light_beta = 705; } else { /* Incandescent High lux */ light_alpha = 715; light_beta = 773; } } else { light_alpha = 0; light_beta = 0; } #else if (data->pdata->d0_value[0]) { do { d0_custom[i] = data->pdata->d0_value[i]; } while (i++ < 8); d0_boundary = d0_custom[D0_BND]; if (100 * D1_raw_data <= d0_custom[D0_COND1] * D0_raw_data) { light_alpha = d0_custom[D0_COND1_A]; light_beta = 0; } else if (100 * D1_raw_data <= d0_custom[D0_COND2] * D0_raw_data) { light_alpha = d0_custom[D0_COND2_A]; light_beta = d0_custom[D0_COND2_B]; } else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) { light_alpha = d0_custom[D0_COND3_A]; light_beta = d0_custom[D0_COND3_B]; } else { light_alpha = 0; light_beta = 0; } } else { if (100 * D1_raw_data <= 40 * D0_raw_data) { light_alpha = 935; light_beta = 0; } else if (100 * D1_raw_data <= 54 * D0_raw_data) { light_alpha = 3039; light_beta = 5176; } else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) { light_alpha = 494; light_beta = 533; } else { light_alpha = 0; light_beta = 0; } } #endif } else { /* GP2AP 020 */ if (data->lightsensor_mode) { /* HIGH_MODE */ if (100 * D1_raw_data <= 32 * D0_raw_data) { light_alpha = 800; light_beta = 0; } else if (100 * D1_raw_data <= 67 * D0_raw_data) { light_alpha = 2015; light_beta = 2925; } else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) { light_alpha = 56; light_beta = 12; } else { light_alpha = 0; light_beta = 0; } } else { /* LOW_MODE */ if (100 * D1_raw_data <= 32 * D0_raw_data) { light_alpha = 800; light_beta = 0; } else if (100 * D1_raw_data <= 67 * D0_raw_data) { light_alpha = 2015; light_beta = 2925; } else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) { light_alpha = 547; light_beta = 599; } else { light_alpha = 0; light_beta = 0; } } } if (data->lightsensor_mode) { /* HIGH_MODE */ D0_data = D0_raw_data * 16; D1_data = D1_raw_data * 16; } else { /* LOW_MODE */ D0_data = D0_raw_data; D1_data = D1_raw_data; } if (data->pdata->version) { /* GP2AP 030 */ if (D0_data < 3) { lx = 0; } else if (data->lightsensor_mode == 0 && (D0_raw_data >= 16000 || D1_raw_data >= 16000) && (D0_raw_data <= 16383 && D1_raw_data <= 16383)) { lx = lx_prev; } else if (100 * D1_data > d0_boundary * D0_data) { lx = lx_prev; return lx; } else { lx = (int)((light_alpha / 10 * D0_data * 33) - (light_beta / 10 * D1_data * 33)) / 1000; } } else { /* GP2AP 020 */ if ((D0_data == 0 || D1_data == 0)\ && (D0_data < 300 && D1_data < 300)) { lx = 0; } else if (data->lightsensor_mode == 0 && (D0_raw_data >= 16000 || D1_raw_data >= 16000) && (D0_raw_data <= 16383 && D1_raw_data <= 16383)) { lx = lx_prev; } else if ((100 * D1_data > d0_boundary * D0_data) || (100 * D1_data < 15 * D0_data)) { lx = lx_prev; return lx; } else { lx = (int)((light_alpha / 10 * D0_data * 33) - (light_beta / 10 * D1_data * 33)) / 1000; } } lx_prev = lx; if (data->lightsensor_mode) { /* HIGH MODE */ if (D0_raw_data < 1000) { pr_info("%s: change to LOW_MODE detection=%d\n", __func__, data->proximity_detection); data->lightsensor_mode = 0; /* change to LOW MODE */ value = 0x0C; gp2a_i2c_write(data, COMMAND1, &value); if (data->proximity_detection) value = 0x23; else value = 0x63; gp2a_i2c_write(data, COMMAND2, &value); if (data->proximity_enabled) value = 0xCC; else value = 0xDC; gp2a_i2c_write(data, COMMAND1, &value); } } else { /* LOW MODE */ if (D0_raw_data > 16000 || D1_raw_data > 16000) { pr_info("%s: change to HIGH_MODE detection=%d\n", __func__, data->proximity_detection); /* change to HIGH MODE */ data->lightsensor_mode = 1; value = 0x0C; gp2a_i2c_write(data, COMMAND1, &value); if (data->proximity_detection) value = 0x27; else value = 0x67; gp2a_i2c_write(data, COMMAND2, &value); if (data->proximity_enabled) value = 0xCC; else value = 0xDC; gp2a_i2c_write(data, COMMAND1, &value); } } return lx; }
static void gp2a_dev_work_func(struct work_struct* work_prox) { int ret = 0; unsigned char value; // printk(" %s, %d\n", __func__, __LINE__); if (!gp2a) { printk(KERN_ERR "[PROXIMITY][%s] Pointer is NULL!\n", __func__); } else if (gp2a->power_state == GP2A_POWER_ON) { // disable_irq(gp2a->irq); /* GP2A initialized and powered on => do the job */ ret = gp2a_i2c_read(gp2a->client, GP2A_REG_PROX, &value, 1); // printk(" %s, %d\n", __func__, __LINE__); if (ret < 0) { printk(KERN_WARNING "[PROXIMITY][%s] Failed to get GP2A proximity value " "[errno=%d]; ignored", __func__, ret); } else { gp2a->proximity_state = (value & 0x01); // printk(" %s, %d\n", __func__, __LINE__); if (GP2A_BIT_PROX_VO_DETECTION == gp2a->proximity_state) { ret = GP2A_INPUT_RANGE_MIN; // printk(" %s, %d\n", __func__, __LINE__); } else { ret = GP2A_INPUT_RANGE_MAX; // printk(" %s, %d\n", __func__, __LINE__); } input_report_abs(gp2a->prox_input, ABS_DISTANCE, ret); input_sync(gp2a->prox_input); // printk(" %s, %d\n", __func__, __LINE__); } } if(!gp2a->proximity_state) // far { value = 0x40; // printk(" %s, %d\n", __func__, __LINE__); } else // near { value = 0x20; // printk(" %s, %d\n", __func__, __LINE__); } /* reset hysteresis */ gp2a_i2c_write(gp2a->client, (u8)(GP2A_REG_HYS), value); // printk(" %s, %d\n", __func__, __LINE__); enable_irq(gp2a->irq); /* enabling VOUT terminal in nomal operation */ value = 0x00; gp2a_i2c_write(gp2a->client, (u8)(GP2A_REG_CON), value); // printk(" %s, %d\n", __func__, __LINE__); }
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(INT_CLEAR) { //int_val = GP2A_REG_PROX | (1 <<7); } 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; if(proximity_value ==0) { timeB = ktime_get(); timeSub = ktime_sub(timeB,timeA); debug("[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); debug("[PROXIMITY] wake_lock_timeout : HZ/2 \n"); } else error("[PROXIMITY] wake_lock is already set \n"); } if(USE_INPUT_DEVICE) { input_report_abs(gp2a_data->prox_input_dev, ABS_DISTANCE,(int)vout); input_sync(gp2a_data->prox_input_dev); mdelay(1); } /* Write HYS Register */ if(!vout) { value = 0x40; } else { value = 0x20; } gp2a_i2c_write((u8)(GP2A_REG_HYS),&value); /* 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); }
int gp2a_get_lux(struct gp2a_data *data) { unsigned char get_data[4] = { 0, }; int d0_raw_data; int d1_raw_data; int d0_data; int d1_data; int lx = 0; u8 value; int light_alpha = 0; int light_beta = 0; static int lx_prev; int ret; mutex_lock(&data->data_mutex); ret = gp2a_i2c_read(data, DATA0_LSB, get_data, sizeof(get_data)); mutex_unlock(&data->data_mutex); if (ret < 0) return lx_prev; d0_raw_data = (get_data[1] << 8) | get_data[0]; /* clear */ d1_raw_data = (get_data[3] << 8) | get_data[2]; /* IR */ if (100 * d1_raw_data <= 55 * d0_raw_data) { light_alpha = 746; light_beta = 0; } else if (100 * d1_raw_data <= 75 * d0_raw_data) { light_alpha = 2535; light_beta = 3252; } else if (100 * d1_raw_data <= 91 * d0_raw_data) { if (d0_raw_data < 240) { light_alpha = 274; light_beta = 298; } else if (d0_raw_data < 400) { light_alpha = 531; light_beta = 577; } else if (d0_raw_data < 1600) { light_alpha = 295; light_beta = 320; } else if (d0_raw_data < 2800) { light_alpha = 338; light_beta = 368; } else { light_alpha = 516; light_beta = 562; } } else { light_alpha = 0; light_beta = 0; } if (data->lightsensor_mode) { /* HIGH_MODE */ d0_data = d0_raw_data * 16; d1_data = d1_raw_data * 16; } else { /* LOW_MODE */ d0_data = d0_raw_data; d1_data = d1_raw_data; } if (d0_data < 2) { lx = 0; } else if (data->lightsensor_mode == 0 && (d0_raw_data >= RAWDATA_THRESHOLD || d1_raw_data >= RAWDATA_THRESHOLD)) { lx = LUX_MAX_VALUE; } else if (100 * d1_data > 95 * d0_data) { if (d0_raw_data >= RAWDATA_THRESHOLD || d1_raw_data >= RAWDATA_THRESHOLD) lx_prev = LUX_MAX_VALUE; lx = lx_prev; return lx; } else { lx = (int)((light_alpha * d0_data) - (light_beta * d1_data)) * 33 / 10000; } if (lx >= LUX_MAX_VALUE) lx = LUX_MAX_VALUE; lx_prev = lx; if (data->lightsensor_mode) { /* HIGH MODE */ if (d0_raw_data < 1000) { pr_info("%s: change to LOW_MODE detection=%d\n", __func__, data->proximity_detection); data->lightsensor_mode = 0; /* change to LOW MODE */ value = 0x0C; gp2a_i2c_write(data, COMMAND1, &value); if (data->proximity_detection) value = 0x23; else value = 0x63; gp2a_i2c_write(data, COMMAND2, &value); if (data->prox_enabled) value = 0xCC; else value = 0xDC; gp2a_i2c_write(data, COMMAND1, &value); } } else { /* LOW MODE */ if (d0_raw_data > RAWDATA_THRESHOLD || d1_raw_data > RAWDATA_THRESHOLD) { pr_info("%s: change to HIGH_MODE detection=%d\n", __func__, data->proximity_detection); /* change to HIGH MODE */ data->lightsensor_mode = 1; value = 0x0C; gp2a_i2c_write(data, COMMAND1, &value); if (data->proximity_detection) value = 0x27; else value = 0x67; gp2a_i2c_write(data, COMMAND2, &value); if (data->prox_enabled) value = 0xCC; else value = 0xDC; gp2a_i2c_write(data, COMMAND1, &value); } } return lx; }
int lightsensor_get_adc(struct gp2a_data *data) { unsigned char get_data[4] = { 0, }; int D0_raw_data; int D1_raw_data; int D0_data; int D1_data; int lx = 0; u8 value; int light_alpha; int light_beta; static int lx_prev; int ret = 0; int d0_boundary = 91; mutex_lock(&data->data_mutex); ret = gp2a_i2c_read(data, DATA0_LSB, get_data, sizeof(get_data)); mutex_unlock(&data->data_mutex); if (ret < 0) return lx_prev; D0_raw_data = (get_data[1] << 8) | get_data[0]; /* clear */ D1_raw_data = (get_data[3] << 8) | get_data[2]; /* IR */ if (data->pdata->version) { /* GP2AP 030 */ if (100 * D1_raw_data <= 40 * D0_raw_data) { light_alpha = 861; light_beta = 0; } else if (100 * D1_raw_data <= 62 * D0_raw_data) { light_alpha = 2668; light_beta = 4027; } else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) { if( (D0_raw_data < 3000) && (data->lightsensor_mode == 0 ) ) { light_alpha = 292; light_beta = 316; } else { /* Incandescent High lux */ light_alpha = 737; light_beta = 810; } } else { light_alpha = 0; light_beta = 0; } } else { /* GP2AP 020 */ if (data->lightsensor_mode) { /* HIGH_MODE */ if (100 * D1_raw_data <= 32 * D0_raw_data) { light_alpha = 800; light_beta = 0; } else if (100 * D1_raw_data <= 67 * D0_raw_data) { light_alpha = 2015; light_beta = 2925; } else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) { light_alpha = 56; light_beta = 12; } else { light_alpha = 0; light_beta = 0; } } else { /* LOW_MODE */ if (100 * D1_raw_data <= 32 * D0_raw_data) { light_alpha = 800; light_beta = 0; } else if (100 * D1_raw_data <= 67 * D0_raw_data) { light_alpha = 2015; light_beta = 2925; } else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) { light_alpha = 547; light_beta = 599; } else { light_alpha = 0; light_beta = 0; } } } if (data->lightsensor_mode) { /* HIGH_MODE */ D0_data = D0_raw_data * 16; D1_data = D1_raw_data * 16; } else { /* LOW_MODE */ D0_data = D0_raw_data; D1_data = D1_raw_data; } if (data->pdata->version) { /* GP2AP 030 */ if (D0_data < 3) { lx = 0; } else if (data->lightsensor_mode == 0 && (D0_raw_data >= 16000 || D1_raw_data >= 16000) && (D0_raw_data <= 16383 && D1_raw_data <= 16383)) { lx = lx_prev; } else if (100 * D1_data > d0_boundary * D0_data) { lx = lx_prev; return lx; } else { lx = (int)((light_alpha / 10 * D0_data * 33) - (light_beta / 10 * D1_data * 33)) / 1000; } } else { /* GP2AP 020 */ if ((D0_data == 0 || D1_data == 0)\ && (D0_data < 300 && D1_data < 300)) { lx = 0; } else if (data->lightsensor_mode == 0 && (D0_raw_data >= 16000 || D1_raw_data >= 16000) && (D0_raw_data <= 16383 && D1_raw_data <= 16383)) { lx = lx_prev; } else if ((100 * D1_data > d0_boundary * D0_data) || (100 * D1_data < 15 * D0_data)) { lx = lx_prev; return lx; } else { lx = (int)((light_alpha / 10 * D0_data * 33) - (light_beta / 10 * D1_data * 33)) / 1000; } } lx_prev = lx; if (data->lightsensor_mode) { /* HIGH MODE */ if (D0_raw_data < 1000) { pr_info("%s: change to LOW_MODE detection=%d\n", __func__, data->proximity_detection); data->lightsensor_mode = 0; /* change to LOW MODE */ value = 0x0C; gp2a_i2c_write(data, COMMAND1, &value); if (data->proximity_detection) value = 0x23; else value = 0x63; gp2a_i2c_write(data, COMMAND2, &value); if (data->proximity_enabled) value = 0xCC; else value = 0xDC; gp2a_i2c_write(data, COMMAND1, &value); } } else { /* LOW MODE */ if (D0_raw_data > 16000 || D1_raw_data > 16000) { pr_info("%s: change to HIGH_MODE detection=%d\n", __func__, data->proximity_detection); /* change to HIGH MODE */ data->lightsensor_mode = 1; value = 0x0C; gp2a_i2c_write(data, COMMAND1, &value); if (data->proximity_detection) value = 0x27; else value = 0x67; gp2a_i2c_write(data, COMMAND2, &value); if (data->proximity_enabled) value = 0xCC; else value = 0xDC; gp2a_i2c_write(data, COMMAND1, &value); } } return lx; }
int lightsensor_get_adc(struct gp2a_data *data) { unsigned char get_data[4] = { 0, }; int D0_raw_data; int D1_raw_data; int D0_data; int D1_data; int lx = 0; u8 value; int light_alpha; int light_beta; static int lx_prev; int ret = 0; int d0_boundary = 91; int d0_custom[9] = { 0, }; int i = 0; mutex_lock(&data->data_mutex); ret = gp2a_i2c_read(DATA0_LSB, get_data, sizeof(get_data)); mutex_unlock(&data->data_mutex); if (ret < 0) return lx_prev; D0_raw_data = (get_data[1] << 8) | get_data[0]; /* clear */ D1_raw_data = (get_data[3] << 8) | get_data[2]; /* IR */ if (data->pdata->version) { /* GP2AP 030 */ if (data->pdata->d0_value[0]) { do { d0_custom[i] = data->pdata->d0_value[i]; } while (i++ < 8); d0_boundary = d0_custom[D0_BND]; if (100 * D1_raw_data <= d0_custom[D0_COND1] * D0_raw_data) { light_alpha = d0_custom[D0_COND1_A]; light_beta = 0; } else if (100 * D1_raw_data <= d0_custom[D0_COND2] * D0_raw_data) { light_alpha = d0_custom[D0_COND2_A]; light_beta = d0_custom[D0_COND2_B]; } else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) { light_alpha = d0_custom[D0_COND3_A]; light_beta = d0_custom[D0_COND3_B]; } else { light_alpha = 0; light_beta = 0; } } else { if (100 * D1_raw_data <= 40 * D0_raw_data) { light_alpha = 978; light_beta = 0; } else if (100 * D1_raw_data <= 62 * D0_raw_data) { light_alpha = 2333; light_beta = 3385; } else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) { light_alpha = 734; light_beta = 806; } else { light_alpha = 0; light_beta = 0; } } } else { /* GP2AP 020 */ if (data->lightsensor_mode) { /* HIGH_MODE */ if (100 * D1_raw_data <= 32 * D0_raw_data) { light_alpha = 800; light_beta = 0; } else if (100 * D1_raw_data <= 67 * D0_raw_data) { light_alpha = 2015; light_beta = 2925; } else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) { light_alpha = 56; light_beta = 12; } else { light_alpha = 0; light_beta = 0; } } else { /* LOW_MODE */ if (100 * D1_raw_data <= 32 * D0_raw_data) { light_alpha = 800; light_beta = 0; } else if (100 * D1_raw_data <= 67 * D0_raw_data) { light_alpha = 2015; light_beta = 2925; } else if (100 * D1_raw_data <= d0_boundary * D0_raw_data) { light_alpha = 547; light_beta = 599; } else { light_alpha = 0; light_beta = 0; } } } if (data->lightsensor_mode) { /* HIGH_MODE */ D0_data = D0_raw_data * 16; D1_data = D1_raw_data * 16; } else { /* LOW_MODE */ D0_data = D0_raw_data; D1_data = D1_raw_data; } if (data->pdata->version) { /* GP2AP 030 */ if (D0_data < 3) { lx = 0; } else if (data->lightsensor_mode == 0 && (D0_raw_data >= 16000 || D1_raw_data >= 16000) && (D0_raw_data <= 16383 && D1_raw_data <= 16383)) { lx = lx_prev; } else if (100 * D1_data > d0_boundary * D0_data) { lx = lx_prev; return lx; } else { lx = (int)((light_alpha / 10 * D0_data * 33) - (light_beta / 10 * D1_data * 33)) / 1000; } } else { /* GP2AP 020 */ if ((D0_data == 0 || D1_data == 0)\ && (D0_data < 300 && D1_data < 300)) { lx = 0; } else if (data->lightsensor_mode == 0 && (D0_raw_data >= 16000 || D1_raw_data >= 16000) && (D0_raw_data <= 16383 && D1_raw_data <= 16383)) { lx = lx_prev; } else if ((100 * D1_data > d0_boundary * D0_data) || (100 * D1_data < 15 * D0_data)) { lx = lx_prev; return lx; } else { lx = (int)((light_alpha / 10 * D0_data * 33) - (light_beta / 10 * D1_data * 33)) / 1000; } } lx_prev = lx; if (data->lightsensor_mode) { /* HIGH MODE */ if (D0_raw_data < 1000) { printk(KERN_INFO "[GP2A] %s: change to LOW_MODE detection=%d\n", __func__, data->proximity_detection); data->lightsensor_mode = 0; /* change to LOW MODE */ value = 0x0C; gp2a_i2c_write(COMMAND1, &value); if (data->proximity_detection) value = 0x23; else value = 0x63; gp2a_i2c_write(COMMAND2, &value); if (data->proximity_enabled) value = 0xCC; else value = 0xDC; gp2a_i2c_write(COMMAND1, &value); } } else { /* LOW MODE */ if (D0_raw_data > 16000 || D1_raw_data > 16000) { printk(KERN_INFO "[GP2A] %s: change to HIGH_MODE detection=%d\n", __func__, data->proximity_detection); /* change to HIGH MODE */ data->lightsensor_mode = 1; value = 0x0C; gp2a_i2c_write(COMMAND1, &value); if (data->proximity_detection) value = 0x27; else value = 0x67; gp2a_i2c_write(COMMAND2, &value); if (data->proximity_enabled) value = 0xCC; else value = 0xDC; gp2a_i2c_write(COMMAND1, &value); } } return lx; }