Input: ili210x - implement pressure reporting for ILI251x
[linux-2.6-microblaze.git] / drivers / input / touchscreen / ili210x.c
index 199cf3d..d8fccf0 100644 (file)
@@ -29,11 +29,13 @@ struct ili2xxx_chip {
                        void *buf, size_t len);
        int (*get_touch_data)(struct i2c_client *client, u8 *data);
        bool (*parse_touch_data)(const u8 *data, unsigned int finger,
-                                unsigned int *x, unsigned int *y);
+                                unsigned int *x, unsigned int *y,
+                                unsigned int *z);
        bool (*continue_polling)(const u8 *data, bool touch);
        unsigned int max_touches;
        unsigned int resolution;
        bool has_calibrate_reg;
+       bool has_pressure_reg;
 };
 
 struct ili210x {
@@ -82,7 +84,8 @@ static int ili210x_read_touch_data(struct i2c_client *client, u8 *data)
 
 static bool ili210x_touchdata_to_coords(const u8 *touchdata,
                                        unsigned int finger,
-                                       unsigned int *x, unsigned int *y)
+                                       unsigned int *x, unsigned int *y,
+                                       unsigned int *z)
 {
        if (touchdata[0] & BIT(finger))
                return false;
@@ -137,7 +140,8 @@ static int ili211x_read_touch_data(struct i2c_client *client, u8 *data)
 
 static bool ili211x_touchdata_to_coords(const u8 *touchdata,
                                        unsigned int finger,
-                                       unsigned int *x, unsigned int *y)
+                                       unsigned int *x, unsigned int *y,
+                                       unsigned int *z)
 {
        u32 data;
 
@@ -169,7 +173,8 @@ static const struct ili2xxx_chip ili211x_chip = {
 
 static bool ili212x_touchdata_to_coords(const u8 *touchdata,
                                        unsigned int finger,
-                                       unsigned int *x, unsigned int *y)
+                                       unsigned int *x, unsigned int *y,
+                                       unsigned int *z)
 {
        u16 val;
 
@@ -235,7 +240,8 @@ static int ili251x_read_touch_data(struct i2c_client *client, u8 *data)
 
 static bool ili251x_touchdata_to_coords(const u8 *touchdata,
                                        unsigned int finger,
-                                       unsigned int *x, unsigned int *y)
+                                       unsigned int *x, unsigned int *y,
+                                       unsigned int *z)
 {
        u16 val;
 
@@ -245,6 +251,7 @@ static bool ili251x_touchdata_to_coords(const u8 *touchdata,
 
        *x = val & 0x3fff;
        *y = get_unaligned_be16(touchdata + 1 + (finger * 5) + 2);
+       *z = touchdata[1 + (finger * 5) + 4];
 
        return true;
 }
@@ -261,6 +268,7 @@ static const struct ili2xxx_chip ili251x_chip = {
        .continue_polling       = ili251x_check_continue_polling,
        .max_touches            = 10,
        .has_calibrate_reg      = true,
+       .has_pressure_reg       = true,
 };
 
 static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata)
@@ -268,14 +276,16 @@ static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata)
        struct input_dev *input = priv->input;
        int i;
        bool contact = false, touch;
-       unsigned int x = 0, y = 0;
+       unsigned int x = 0, y = 0, z = 0;
 
        for (i = 0; i < priv->chip->max_touches; i++) {
-               touch = priv->chip->parse_touch_data(touchdata, i, &x, &y);
+               touch = priv->chip->parse_touch_data(touchdata, i, &x, &y, &z);
 
                input_mt_slot(input, i);
                if (input_mt_report_slot_state(input, MT_TOOL_FINGER, touch)) {
                        touchscreen_report_pos(input, &priv->prop, x, y, true);
+                       if (priv->chip->has_pressure_reg)
+                               input_report_abs(input, ABS_MT_PRESSURE, z);
                        contact = true;
                }
        }
@@ -437,6 +447,8 @@ static int ili210x_i2c_probe(struct i2c_client *client,
        max_xy = (chip->resolution ?: SZ_64K) - 1;
        input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_xy, 0, 0);
        input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_xy, 0, 0);
+       if (priv->chip->has_pressure_reg)
+               input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xa, 0, 0);
        touchscreen_parse_properties(input, true, &priv->prop);
 
        error = input_mt_init_slots(input, priv->chip->max_touches,