static ssize_t geomagnetic_filter_threshold_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct input_dev *input_data = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_data); struct yas_mag_filter filter; int value; if (hwdep_driver.get_filter == NULL || hwdep_driver.set_filter == NULL) { return -ENOTTY; } value = simple_strtol(buf, NULL, 10); if (geomagnetic_multi_lock() < 0) { return count; } hwdep_driver.get_filter(&filter); filter.threshold = value; if (hwdep_driver.set_filter(&filter) == 0) { data->filter_threshold = value; } geomagnetic_multi_unlock(); return count; }
static ssize_t geomagnetic_raw_distortion_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct input_dev *input_raw = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_raw); int32_t distortion[3]; static int32_t val = 1; int i; geomagnetic_multi_lock(); sscanf(buf, "%d %d %d", &distortion[0], &distortion[1], &distortion[2]); if (distortion[0] > 0 && distortion[1] > 0 && distortion[2] > 0) { for (i = 0; i < 3; i++) { data->distortion[i] = distortion[i]; } input_report_abs(data->input_raw, ABS_RAW_DISTORTION, val++); } geomagnetic_multi_unlock(); return count; }
static ssize_t geomagnetic_filter_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct input_dev *input_data = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_data); int value; if (hwdep_driver.set_filter_enable == NULL) { return -ENOTTY; } value = simple_strtol(buf, NULL, 10); if (geomagnetic_multi_lock() < 0) { return count; } if (hwdep_driver.set_filter_enable(value) == 0) { data->filter_enable = !!value; } geomagnetic_multi_unlock(); return count; }
static ssize_t geomagnetic_raw_offsets_show(struct device *dev, struct device_attribute *attr, char *buf) { struct input_dev *input_raw = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_raw); struct yas_mag_offset offset; int accuracy; geomagnetic_multi_lock(); offset = data->driver_offset; accuracy = atomic_read(&data->last_status); geomagnetic_multi_unlock(); return sprintf(buf, "%d %d %d %d %d %d %d\n", offset.hard_offset[0], offset.hard_offset[1], offset.hard_offset[2], offset.calib_offset.v[0], offset.calib_offset.v[1], offset.calib_offset.v[2], accuracy); }
static ssize_t geomagnetic_filter_noise_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct input_dev *input_raw = to_input_dev(dev); struct yas_mag_filter filter; struct geomagnetic_data *data = input_get_drvdata(input_raw); int32_t filter_noise[3]; geomagnetic_multi_lock(); sscanf(buf, "%d %d %d", &filter_noise[0], &filter_noise[1], &filter_noise[2]); hwdep_driver.get_filter(&filter); memcpy(filter.noise, filter_noise, sizeof(filter.noise)); if (hwdep_driver.set_filter(&filter) == 0) { memcpy(data->filter_noise, filter_noise, sizeof(data->filter_noise)); } geomagnetic_multi_unlock(); return count; }
static ssize_t geomagnetic_raw_manual_offsets_show(struct device *dev, struct device_attribute *attr, char *buf) { struct input_dev *input_raw = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_raw); struct yas_vector offset; geomagnetic_multi_lock(); offset = data->manual_offset; geomagnetic_multi_unlock(); return sprintf(buf, "%d %d %d\n", offset.v[0], offset.v[1], offset.v[2]); }
static ssize_t geomagnetic_raw_shape_show(struct device *dev, struct device_attribute *attr, char *buf) { struct input_dev *input_raw = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_raw); int shape; geomagnetic_multi_lock(); shape = data->shape; geomagnetic_multi_unlock(); return sprintf(buf, "%d\n", shape); }
static ssize_t geomagnetic_filter_len_show(struct device *dev, struct device_attribute *attr, char *buf) { struct input_dev *input_data = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_data); int filter_len; geomagnetic_multi_lock(); filter_len = data->filter_len; geomagnetic_multi_unlock(); return sprintf(buf, "%d\n", filter_len); }
static ssize_t geomagnetic_raw_threshold_show(struct device *dev, struct device_attribute *attr, char *buf) { struct input_dev *input_raw = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_raw); int threshold; geomagnetic_multi_lock(); threshold = data->threshold; geomagnetic_multi_unlock(); return sprintf(buf, "%d\n", threshold); }
/* Sysfs interface */ static ssize_t geomagnetic_delay_show(struct device *dev, struct device_attribute *attr, char *buf) { struct input_dev *input_data = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_data); int delay; geomagnetic_multi_lock(); delay = data->delay; geomagnetic_multi_unlock(); return sprintf(buf, "%d\n", delay); }
static ssize_t geomagnetic_raw_transform_matrix_show(struct device *dev, struct device_attribute *attr, char *buf) { struct input_dev *input_raw = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_raw); int32_t matrix[9]; geomagnetic_multi_lock(); memcpy(matrix, data->transform_matrix, sizeof(matrix)); geomagnetic_multi_unlock(); return sprintf(buf, "%d %d %d %d %d %d %d %d %d\n", matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6], matrix[7], matrix[8]); }
static ssize_t geomagnetic_raw_distortion_show(struct device *dev, struct device_attribute *attr, char *buf) { struct input_dev *input_raw = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_raw); int rt; geomagnetic_multi_lock(); rt = sprintf(buf, "%d %d %d\n", data->distortion[0], data->distortion[1], data->distortion[2]); geomagnetic_multi_unlock(); return rt; }
static ssize_t geomagnetic_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct input_dev *input_data = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_data); int value; dbg_func_in(); value = !!simple_strtol(buf, NULL, 10); dbg("%s : enable(%d)\n", __func__, value); if (hwdep_driver.set_enable == NULL) { return -ENOTTY; } #ifndef PANTECH_AVOID_DEADLOCK //p12911 : ef33s sensor patch if (geomagnetic_multi_lock() < 0) { return count; } #endif if (hwdep_driver.set_enable(value) == 0) { if (value) { geomagnetic_enable(data); } else { geomagnetic_disable(data); } } #ifndef PANTECH_AVOID_DEADLOCK geomagnetic_multi_unlock(); #endif dbg_func_out(); return count; }
static ssize_t geomagnetic_raw_shape_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct input_dev *input_raw = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_raw); int value = simple_strtol(buf, NULL, 10); geomagnetic_multi_lock(); if (0 <= value && value <= 1) { data->shape = value; input_report_abs(data->input_raw, ABS_RAW_SHAPE, value); } geomagnetic_multi_unlock(); return count; }
static ssize_t geomagnetic_raw_manual_offsets_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct input_dev *input_raw = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_raw); struct yas_vector offset; geomagnetic_multi_lock(); sscanf(buf, "%d %d %d", &offset.v[0], &offset.v[1], &offset.v[2]); if (hwdep_driver.set_manual_offset(&offset) == 0) { data->manual_offset = offset; } geomagnetic_multi_unlock(); return count; }
static int geomagnetic_api_enable(int enable) { struct geomagnetic_data *data = i2c_get_clientdata(this_client); int rt; if (geomagnetic_multi_lock() < 0) { return -1; } enable = !!enable; if ((rt = hwdep_driver.set_enable(enable)) == 0) { atomic_set(&data->enable, enable); if (enable) { rt = hwdep_driver.set_delay(20); } } geomagnetic_multi_unlock(); return rt; }
static ssize_t geomagnetic_raw_offsets_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct input_dev *input_raw = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_raw); struct yas_mag_offset offset; int32_t hard_offset[3]; int i, accuracy; geomagnetic_multi_lock(); sscanf(buf, "%d %d %d %d %d %d %d", &hard_offset[0], &hard_offset[1], &hard_offset[2], &offset.calib_offset.v[0], &offset.calib_offset.v[1], &offset.calib_offset.v[2], &accuracy); if (0 <= accuracy && accuracy <= 3) { for (i = 0; i < 3; i++) { offset.hard_offset[i] = (int8_t)hard_offset[i]; } if (hwdep_driver.set_offset(&offset) == 0) { atomic_set(&data->last_status, accuracy); data->driver_offset = offset; } } geomagnetic_multi_unlock(); return count; }
static ssize_t geomagnetic_raw_transform_matrix_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct input_dev *input_raw = to_input_dev(dev); struct geomagnetic_data *data = input_get_drvdata(input_raw); int32_t matrix[9]; geomagnetic_multi_lock(); sscanf(buf, "%d %d %d %d %d %d %d %d %d", &matrix[0], &matrix[1], &matrix[2], &matrix[3], &matrix[4], &matrix[5], &matrix[6], &matrix[7], &matrix[8]); if (hwdep_driver.set_transform_matrix(matrix) == 0) { memcpy(data->transform_matrix, matrix, sizeof(data->transform_matrix)); } geomagnetic_multi_unlock(); return count; }
static void geomagnetic_input_work_func(struct work_struct *work) { struct geomagnetic_data *data = container_of((struct delayed_work *)work, struct geomagnetic_data, work); uint32_t time_delay_ms = 100; struct yas_mag_offset offset; struct yas_mag_data magdata; int rt, i, accuracy; YLOGE(("[HSS] geomagnetic_input_work_func\n")); if (hwdep_driver.measure == NULL || hwdep_driver.get_offset == NULL) { return; } rt = hwdep_driver.measure(&magdata, &time_delay_ms); if (rt < 0) { YLOGE(("measure failed[%d]\n", rt)); } YLOGE(("xy1y2 [%d][%d][%d] raw[%d][%d][%d]\n", magdata.xy1y2.v[0], magdata.xy1y2.v[1], magdata.xy1y2.v[2], magdata.xyz.v[0], magdata.xyz.v[1], magdata.xyz.v[2])); if (rt >= 0) { accuracy = atomic_read(&data->last_status); if ((rt & YAS_REPORT_OVERFLOW_OCCURED) || (rt & YAS_REPORT_HARD_OFFSET_CHANGED) || (rt & YAS_REPORT_CALIB_OFFSET_CHANGED)) { static uint16_t count = 1; int code = 0; int value = 0; hwdep_driver.get_offset(&offset); geomagnetic_multi_lock(); data->driver_offset = offset; if (rt & YAS_REPORT_OVERFLOW_OCCURED) { atomic_set(&data->last_status, 0); accuracy = 0; } geomagnetic_multi_unlock(); /* report event */ code |= (rt & YAS_REPORT_OVERFLOW_OCCURED); code |= (rt & YAS_REPORT_HARD_OFFSET_CHANGED); code |= (rt & YAS_REPORT_CALIB_OFFSET_CHANGED); value = (count++ << 16) | (code); input_report_abs(data->input_raw, ABS_RAW_REPORT, value); } if (rt & YAS_REPORT_DATA) { for (i = 0; i < 3; i++) { atomic_set(&data->last_data[i], magdata.xyz.v[i]); } /* report magnetic data in [nT] */ input_report_abs(data->input_data, ABS_X, magdata.xyz.v[0]); input_report_abs(data->input_data, ABS_Y, magdata.xyz.v[1]); input_report_abs(data->input_data, ABS_Z, magdata.xyz.v[2]); input_report_abs(data->input_data, ABS_STATUS, accuracy); input_sync(data->input_data); } if (rt & YAS_REPORT_CALIB) { /* report raw magnetic data */ input_report_abs(data->input_raw, ABS_X, magdata.raw.v[0]); input_report_abs(data->input_raw, ABS_Y, magdata.raw.v[1]); input_report_abs(data->input_raw, ABS_Z, magdata.raw.v[2]); input_sync(data->input_raw); } } else { time_delay_ms = 100; } if (time_delay_ms > 0) { schedule_delayed_work(&data->work, msecs_to_jiffies(time_delay_ms) + 1); } else { schedule_delayed_work(&data->work, 0); } }
static int geomagnetic_work(struct yas_mag_data *magdata) { struct geomagnetic_data *data = i2c_get_clientdata(this_client); uint32_t time_delay_ms = 100; struct yas_mag_offset offset; int rt, i, accuracy; if (hwdep_driver.measure == NULL || hwdep_driver.get_offset == NULL) { return time_delay_ms; } rt = hwdep_driver.measure(magdata, &time_delay_ms); if (rt < 0) { YLOGE(("measure failed[%d]\n", rt)); } YLOGD(("xy1y2 [%d][%d][%d] raw[%d][%d][%d]\n", magdata->xy1y2.v[0], magdata->xy1y2.v[1], magdata->xy1y2.v[2], magdata->xyz.v[0], magdata->xyz.v[1], magdata->xyz.v[2])); if (rt >= 0) { accuracy = atomic_read(&data->last_status); if ((rt & YAS_REPORT_OVERFLOW_OCCURED) || (rt & YAS_REPORT_HARD_OFFSET_CHANGED) || (rt & YAS_REPORT_CALIB_OFFSET_CHANGED)) { static uint16_t count = 1; int code = 0; int value = 0; hwdep_driver.get_offset(&offset); geomagnetic_multi_lock(); data->driver_offset = offset; if (rt & YAS_REPORT_OVERFLOW_OCCURED) { atomic_set(&data->last_status, 0); accuracy = 0; } geomagnetic_multi_unlock(); /* report event */ code |= (rt & YAS_REPORT_OVERFLOW_OCCURED); code |= (rt & YAS_REPORT_HARD_OFFSET_CHANGED); code |= (rt & YAS_REPORT_CALIB_OFFSET_CHANGED); value = (count++ << 16) | (code); input_report_abs(data->input_raw, ABS_RAW_REPORT, value); } if (rt & YAS_REPORT_DATA) { for (i = 0; i < 3; i++) { atomic_set(&data->last_data[i], magdata->xyz.v[i]); } /* report magnetic data in [nT] */ input_report_abs(data->input_data, ABS_X, magdata->xyz.v[0]); input_report_abs(data->input_data, ABS_Y, magdata->xyz.v[1]); input_report_abs(data->input_data, ABS_Z, magdata->xyz.v[2]); input_report_abs(data->input_data, ABS_STATUS, accuracy); input_sync(data->input_data); } /* report raw magnetic data */ input_report_abs(data->input_raw, ABS_X, magdata->raw.v[0]); input_report_abs(data->input_raw, ABS_Y, magdata->raw.v[1]); input_report_abs(data->input_raw, ABS_Z, magdata->raw.v[2]); input_sync(data->input_raw); } else { time_delay_ms = 100; } return time_delay_ms; }