/* * meas_voltage_stable - measures relative stable voltage from spec. input */ static int ab8500_meas_voltage_stable(struct abx500_ad *dd) { int iterations = 2; int v1, v2, dv; v1 = ab8500_gpadc_convert((struct ab8500_gpadc *)dd->gpadc, ACC_DETECT2); do { msleep(1); --iterations; v2 = ab8500_gpadc_convert((struct ab8500_gpadc *)dd->gpadc, ACC_DETECT2); dv = abs(v2 - v1); v1 = v2; } while (iterations > 0 && dv > MAX_VOLT_DIFF); return v1; }
/* * Measures a relative stable voltage from spec. input on spec channel */ static int gpadc_convert_stable(struct ab8500_gpadc *gpadc, u8 channel, int *value) { int i = GPADC_MAX_ITERATIONS; int mv1, mv2, dmv; mv1 = ab8500_gpadc_convert(gpadc, channel); do { i--; usleep_range(GPADC_MIN_DELTA_DELAY, GPADC_MAX_DELTA_DELAY); mv2 = ab8500_gpadc_convert(gpadc, channel); dmv = abs(mv2 - mv1); mv1 = mv2; } while (i > 0 && dmv > GPADC_MAX_VOLT_DIFF); if (mv1 < 0 || dmv > GPADC_MAX_VOLT_DIFF) return -EIO; *value = mv1; return 0; }
static void gp2a_dev_light_work_func(struct work_struct* work) { int i; int adc; int ret = 0; if (!gp2a) { printk(KERN_ERR "[PROXIMITY][%s] Pointer is NULL\n", __func__); } else if (gp2a->power_state == GP2A_POWER_ON) { /* Light sensor values from AB8500 */ gp2a->adc = ab8500_gpadc_convert(gp2a->gpadc, gp2a->alsout); if(gp2a->adc < 0) { printk(KERN_WARNING "[PROXIMITY][%s] Failed to get GP2A light sensor value [errno=%d]; ignored", __func__, gp2a->adc); } else { /* 1350*x/1023 is the formula to convert from RAW GPADC data * to voltage for AdcAux1 and AdcAux2 on the AB8500. */ for (i = 0; ARRAY_SIZE(adc_table); i++) if (gp2a->adc <= adc_table[i]) break; gp2a->lux = gp2a->adc; if (gp2a->light_buffer == i) { if (gp2a->light_count++ == LIGHT_BUFFER_NUM) { input_report_abs(gp2a->light_input, ABS_MISC, gp2a->lux); input_sync(gp2a->light_input); gp2a->light_count = 0; } // printk("@@@@ %s, %d####\n",__func__, gp2a->lux); } else { gp2a->light_buffer = i; gp2a->light_count = 0; } if(ret < 0) { printk(KERN_ERR "[PROXIMITY][%s] Failed to reset timer!!", __func__); } goto out; } out: return; } }
static ssize_t show_input(struct device *dev, struct device_attribute *devattr, char *buf) { int val; struct ab8500_temp *data = dev_get_drvdata(dev); struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); /* hwmon attr index starts at 1, thus "attr->index-1" below */ u8 gpadc_addr = data->gpadc_addr[attr->index - 1]; val = ab8500_gpadc_convert(data->gpadc, gpadc_addr); if (val < 0) dev_err(&data->pdev->dev, "GPADC read failed\n"); return sprintf(buf, "%d\n", val); }
static int ab8500_read_sensor(struct abx500_temp *data, u8 sensor) { int val; /* * Special treatment for the BAT_CTRL node, since this * temperature measurement is more complex than just * an ADC readout * * DIE_TEMP input temperature reading is not supported * in AB8500 */ if (sensor == DIE_TEMP) val = 0; else if (sensor == BAT_CTRL) val = ab8500_btemp_get_batctrl_temp(data->ab8500_btemp); else val = ab8500_gpadc_convert(data->ab8500_gpadc, sensor); return val; }
static int sec_bat_adc_ap_read(unsigned int channel) { int adc; switch (channel) { case SEC_BAT_ADC_CHANNEL_TEMP: case SEC_BAT_ADC_CHANNEL_TEMP_AMBIENT: adc = ab8500_gpadc_read_raw( ab8500_gpadc_get(), BTEMP_BALL, SAMPLE_16, RISING_EDGE, 0, ADC_SW); break; case SEC_BAT_ADC_CHANNEL_FULL_CHECK: adc = ab8500_gpadc_convert( ab8500_gpadc_get(), USB_CHARGER_C); break; default: return -1; break; } return adc; }
static int ab8500_read_sensor(struct abx500_temp *data, u8 sensor, int *temp) { int voltage, ret; struct ab8500_temp *ab8500_data = data->plat_data; if (sensor == BAT_CTRL) { *temp = ab8500_btemp_get_batctrl_temp(ab8500_data->btemp); } else if (sensor == BTEMP_BALL) { *temp = ab8500_btemp_get_temp(ab8500_data->btemp); } else { voltage = ab8500_gpadc_convert(ab8500_data->gpadc, sensor); if (voltage < 0) return voltage; ret = ab8500_voltage_to_temp(&ab8500_data->cfg, voltage, temp); if (ret < 0) return ret; } return 0; }
static void gpadc_monitor(struct work_struct *work) { unsigned long delay_in_jiffies; int val, i, ret; /* Container for alarm node name */ char alarm_node[30]; bool updated_min_alarm = false; bool updated_max_alarm = false; bool updated_max_hyst_alarm = false; struct ab8500_temp *data = container_of(work, struct ab8500_temp, work.work); for (i = 0; i < NUM_MONITORED_SENSORS; i++) { /* Thresholds are considered inactive if set to 0 */ if (data->max[i] == 0 && data->max_hyst[i] == 0 && data->min[i] == 0) continue; val = ab8500_gpadc_convert(data->gpadc, data->gpadc_addr[i]); if (val < 0) { dev_err(&data->pdev->dev, "GPADC read failed\n"); continue; } mutex_lock(&data->lock); if (data->min[i] != 0) { if (val < data->min[i]) { if (data->min_alarm[i] == 0) { data->min_alarm[i] = 1; updated_min_alarm = true; } } else { if (data->min_alarm[i] == 1) { data->min_alarm[i] = 0; updated_min_alarm = true; } } } if (data->max[i] != 0) { if (val > data->max[i]) { if (data->max_alarm[i] == 0) { data->max_alarm[i] = 1; updated_max_alarm = true; } } else { if (data->max_alarm[i] == 1) { data->max_alarm[i] = 0; updated_max_alarm = true; } } } if (data->max_hyst[i] != 0) { if (val > data->max_hyst[i]) { if (data->max_hyst_alarm[i] == 0) { data->max_hyst_alarm[i] = 1; updated_max_hyst_alarm = true; } } else { if (data->max_hyst_alarm[i] == 1) { data->max_hyst_alarm[i] = 0; updated_max_hyst_alarm = true; } } } mutex_unlock(&data->lock); /* hwmon attr index starts at 1, thus "i+1" below */ if (updated_min_alarm) { ret = snprintf(alarm_node, 16, "temp%d_min_alarm", (i + 1)); if (ret < 0) { dev_err(&data->pdev->dev, "Unable to update alarm node (%d)", ret); break; } sysfs_notify(&data->pdev->dev.kobj, NULL, alarm_node); } if (updated_max_alarm) { ret = snprintf(alarm_node, 16, "temp%d_max_alarm", (i + 1)); if (ret < 0) { dev_err(&data->pdev->dev, "Unable to update alarm node (%d)", ret); break; } sysfs_notify(&data->pdev->dev.kobj, NULL, alarm_node); } if (updated_max_hyst_alarm) { ret = snprintf(alarm_node, 21, "temp%d_max_hyst_alarm", (i + 1)); if (ret < 0) { dev_err(&data->pdev->dev, "Unable to update alarm node (%d)", ret); break; } sysfs_notify(&data->pdev->dev.kobj, NULL, alarm_node); } } delay_in_jiffies = msecs_to_jiffies(data->gpadc_monitor_delay); schedule_delayed_work(&data->work, delay_in_jiffies); }