0001
0002
0003
0004
0005
0006
0007 #include <linux/kernel.h>
0008 #include <linux/device.h>
0009 #include <linux/of.h>
0010 #include <linux/input.h>
0011 #include <linux/input/mt.h>
0012 #include <linux/rmi.h>
0013 #include "rmi_driver.h"
0014 #include "rmi_2d_sensor.h"
0015
0016 #define RMI_2D_REL_POS_MIN -128
0017 #define RMI_2D_REL_POS_MAX 127
0018
0019
0020 #define DMAX 10
0021
0022 void rmi_2d_sensor_abs_process(struct rmi_2d_sensor *sensor,
0023 struct rmi_2d_sensor_abs_object *obj,
0024 int slot)
0025 {
0026 struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
0027
0028
0029 if (obj->type == RMI_2D_OBJECT_NONE)
0030 return;
0031
0032 if (axis_align->flip_x)
0033 obj->x = sensor->max_x - obj->x;
0034
0035 if (axis_align->flip_y)
0036 obj->y = sensor->max_y - obj->y;
0037
0038 if (axis_align->swap_axes)
0039 swap(obj->x, obj->y);
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 obj->x += axis_align->offset_x;
0050 obj->y += axis_align->offset_y;
0051
0052 obj->x = max(axis_align->clip_x_low, obj->x);
0053 obj->y = max(axis_align->clip_y_low, obj->y);
0054
0055 if (axis_align->clip_x_high)
0056 obj->x = min(sensor->max_x, obj->x);
0057
0058 if (axis_align->clip_y_high)
0059 obj->y = min(sensor->max_y, obj->y);
0060
0061 sensor->tracking_pos[slot].x = obj->x;
0062 sensor->tracking_pos[slot].y = obj->y;
0063 }
0064 EXPORT_SYMBOL_GPL(rmi_2d_sensor_abs_process);
0065
0066 void rmi_2d_sensor_abs_report(struct rmi_2d_sensor *sensor,
0067 struct rmi_2d_sensor_abs_object *obj,
0068 int slot)
0069 {
0070 struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
0071 struct input_dev *input = sensor->input;
0072 int wide, major, minor;
0073
0074 if (sensor->kernel_tracking)
0075 input_mt_slot(input, sensor->tracking_slots[slot]);
0076 else
0077 input_mt_slot(input, slot);
0078
0079 input_mt_report_slot_state(input, obj->mt_tool,
0080 obj->type != RMI_2D_OBJECT_NONE);
0081
0082 if (obj->type != RMI_2D_OBJECT_NONE) {
0083 obj->x = sensor->tracking_pos[slot].x;
0084 obj->y = sensor->tracking_pos[slot].y;
0085
0086 if (axis_align->swap_axes)
0087 swap(obj->wx, obj->wy);
0088
0089 wide = (obj->wx > obj->wy);
0090 major = max(obj->wx, obj->wy);
0091 minor = min(obj->wx, obj->wy);
0092
0093 if (obj->type == RMI_2D_OBJECT_STYLUS) {
0094 major = max(1, major);
0095 minor = max(1, minor);
0096 }
0097
0098 input_event(sensor->input, EV_ABS, ABS_MT_POSITION_X, obj->x);
0099 input_event(sensor->input, EV_ABS, ABS_MT_POSITION_Y, obj->y);
0100 input_event(sensor->input, EV_ABS, ABS_MT_ORIENTATION, wide);
0101 input_event(sensor->input, EV_ABS, ABS_MT_PRESSURE, obj->z);
0102 input_event(sensor->input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
0103 input_event(sensor->input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
0104
0105 rmi_dbg(RMI_DEBUG_2D_SENSOR, &sensor->input->dev,
0106 "%s: obj[%d]: type: 0x%02x X: %d Y: %d Z: %d WX: %d WY: %d\n",
0107 __func__, slot, obj->type, obj->x, obj->y, obj->z,
0108 obj->wx, obj->wy);
0109 }
0110 }
0111 EXPORT_SYMBOL_GPL(rmi_2d_sensor_abs_report);
0112
0113 void rmi_2d_sensor_rel_report(struct rmi_2d_sensor *sensor, int x, int y)
0114 {
0115 struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
0116
0117 x = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)x));
0118 y = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)y));
0119
0120 if (axis_align->flip_x)
0121 x = min(RMI_2D_REL_POS_MAX, -x);
0122
0123 if (axis_align->flip_y)
0124 y = min(RMI_2D_REL_POS_MAX, -y);
0125
0126 if (axis_align->swap_axes)
0127 swap(x, y);
0128
0129 if (x || y) {
0130 input_report_rel(sensor->input, REL_X, x);
0131 input_report_rel(sensor->input, REL_Y, y);
0132 }
0133 }
0134 EXPORT_SYMBOL_GPL(rmi_2d_sensor_rel_report);
0135
0136 static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor)
0137 {
0138 struct input_dev *input = sensor->input;
0139 int res_x;
0140 int res_y;
0141 int max_x, max_y;
0142 int input_flags = 0;
0143
0144 if (sensor->report_abs) {
0145 sensor->min_x = sensor->axis_align.clip_x_low;
0146 if (sensor->axis_align.clip_x_high)
0147 sensor->max_x = min(sensor->max_x,
0148 sensor->axis_align.clip_x_high);
0149
0150 sensor->min_y = sensor->axis_align.clip_y_low;
0151 if (sensor->axis_align.clip_y_high)
0152 sensor->max_y = min(sensor->max_y,
0153 sensor->axis_align.clip_y_high);
0154
0155 set_bit(EV_ABS, input->evbit);
0156
0157 max_x = sensor->max_x;
0158 max_y = sensor->max_y;
0159 if (sensor->axis_align.swap_axes)
0160 swap(max_x, max_y);
0161 input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
0162 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
0163
0164 if (sensor->x_mm && sensor->y_mm) {
0165 res_x = (sensor->max_x - sensor->min_x) / sensor->x_mm;
0166 res_y = (sensor->max_y - sensor->min_y) / sensor->y_mm;
0167 if (sensor->axis_align.swap_axes)
0168 swap(res_x, res_y);
0169
0170 input_abs_set_res(input, ABS_X, res_x);
0171 input_abs_set_res(input, ABS_Y, res_y);
0172
0173 input_abs_set_res(input, ABS_MT_POSITION_X, res_x);
0174 input_abs_set_res(input, ABS_MT_POSITION_Y, res_y);
0175
0176 if (!sensor->dmax)
0177 sensor->dmax = DMAX * res_x;
0178 }
0179
0180 input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xff, 0, 0);
0181 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 0x0f, 0, 0);
0182 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 0x0f, 0, 0);
0183 input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0);
0184 input_set_abs_params(input, ABS_MT_TOOL_TYPE,
0185 0, MT_TOOL_MAX, 0, 0);
0186
0187 if (sensor->sensor_type == rmi_sensor_touchpad)
0188 input_flags = INPUT_MT_POINTER;
0189 else
0190 input_flags = INPUT_MT_DIRECT;
0191
0192 if (sensor->kernel_tracking)
0193 input_flags |= INPUT_MT_TRACK;
0194
0195 input_mt_init_slots(input, sensor->nbr_fingers, input_flags);
0196 }
0197
0198 if (sensor->report_rel) {
0199 set_bit(EV_REL, input->evbit);
0200 set_bit(REL_X, input->relbit);
0201 set_bit(REL_Y, input->relbit);
0202 }
0203
0204 if (sensor->topbuttonpad)
0205 set_bit(INPUT_PROP_TOPBUTTONPAD, input->propbit);
0206 }
0207
0208 int rmi_2d_sensor_configure_input(struct rmi_function *fn,
0209 struct rmi_2d_sensor *sensor)
0210 {
0211 struct rmi_device *rmi_dev = fn->rmi_dev;
0212 struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
0213
0214 if (!drv_data->input)
0215 return -ENODEV;
0216
0217 sensor->input = drv_data->input;
0218 rmi_2d_sensor_set_input_params(sensor);
0219
0220 return 0;
0221 }
0222 EXPORT_SYMBOL_GPL(rmi_2d_sensor_configure_input);
0223
0224 #ifdef CONFIG_OF
0225 int rmi_2d_sensor_of_probe(struct device *dev,
0226 struct rmi_2d_sensor_platform_data *pdata)
0227 {
0228 int retval;
0229 u32 val;
0230
0231 pdata->axis_align.swap_axes = of_property_read_bool(dev->of_node,
0232 "touchscreen-swapped-x-y");
0233
0234 pdata->axis_align.flip_x = of_property_read_bool(dev->of_node,
0235 "touchscreen-inverted-x");
0236
0237 pdata->axis_align.flip_y = of_property_read_bool(dev->of_node,
0238 "touchscreen-inverted-y");
0239
0240 retval = rmi_of_property_read_u32(dev, &val, "syna,clip-x-low", 1);
0241 if (retval)
0242 return retval;
0243
0244 pdata->axis_align.clip_x_low = val;
0245
0246 retval = rmi_of_property_read_u32(dev, &val, "syna,clip-y-low", 1);
0247 if (retval)
0248 return retval;
0249
0250 pdata->axis_align.clip_y_low = val;
0251
0252 retval = rmi_of_property_read_u32(dev, &val, "syna,clip-x-high", 1);
0253 if (retval)
0254 return retval;
0255
0256 pdata->axis_align.clip_x_high = val;
0257
0258 retval = rmi_of_property_read_u32(dev, &val, "syna,clip-y-high", 1);
0259 if (retval)
0260 return retval;
0261
0262 pdata->axis_align.clip_y_high = val;
0263
0264 retval = rmi_of_property_read_u32(dev, &val, "syna,offset-x", 1);
0265 if (retval)
0266 return retval;
0267
0268 pdata->axis_align.offset_x = val;
0269
0270 retval = rmi_of_property_read_u32(dev, &val, "syna,offset-y", 1);
0271 if (retval)
0272 return retval;
0273
0274 pdata->axis_align.offset_y = val;
0275
0276 retval = rmi_of_property_read_u32(dev, &val, "syna,delta-x-threshold",
0277 1);
0278 if (retval)
0279 return retval;
0280
0281 pdata->axis_align.delta_x_threshold = val;
0282
0283 retval = rmi_of_property_read_u32(dev, &val, "syna,delta-y-threshold",
0284 1);
0285 if (retval)
0286 return retval;
0287
0288 pdata->axis_align.delta_y_threshold = val;
0289
0290 retval = rmi_of_property_read_u32(dev, (u32 *)&pdata->sensor_type,
0291 "syna,sensor-type", 1);
0292 if (retval)
0293 return retval;
0294
0295 retval = rmi_of_property_read_u32(dev, &val, "touchscreen-x-mm", 1);
0296 if (retval)
0297 return retval;
0298
0299 pdata->x_mm = val;
0300
0301 retval = rmi_of_property_read_u32(dev, &val, "touchscreen-y-mm", 1);
0302 if (retval)
0303 return retval;
0304
0305 pdata->y_mm = val;
0306
0307 retval = rmi_of_property_read_u32(dev, &val,
0308 "syna,disable-report-mask", 1);
0309 if (retval)
0310 return retval;
0311
0312 pdata->disable_report_mask = val;
0313
0314 retval = rmi_of_property_read_u32(dev, &val, "syna,rezero-wait-ms",
0315 1);
0316 if (retval)
0317 return retval;
0318
0319 pdata->rezero_wait = val;
0320
0321 return 0;
0322 }
0323 #else
0324 inline int rmi_2d_sensor_of_probe(struct device *dev,
0325 struct rmi_2d_sensor_platform_data *pdata)
0326 {
0327 return -ENODEV;
0328 }
0329 #endif
0330 EXPORT_SYMBOL_GPL(rmi_2d_sensor_of_probe);