Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2011-2016 Synaptics Incorporated
0004  * Copyright (c) 2011 Unixphere
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 /* maximum ABS_MT_POSITION displacement (in mm) */
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     /* we keep the previous values if the finger is released */
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      * Here checking if X offset or y offset are specified is
0043      * redundant. We just add the offsets or clip the values.
0044      *
0045      * Note: offsets need to be applied before clipping occurs,
0046      * or we could get funny values that are outside of
0047      * clipping boundaries.
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);