root/drivers/input/touchscreen/zet6223.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. zet6223_start
  2. zet6223_stop
  3. zet6223_irq
  4. zet6223_power_off
  5. zet6223_power_on
  6. zet6223_query_device
  7. zet6223_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2016, Jelle van der Waa <jelle@vdwaa.nl>
   4  */
   5 
   6 #include <linux/delay.h>
   7 #include <linux/i2c.h>
   8 #include <linux/input.h>
   9 #include <linux/input/mt.h>
  10 #include <linux/input/touchscreen.h>
  11 #include <linux/interrupt.h>
  12 #include <linux/module.h>
  13 #include <linux/regulator/consumer.h>
  14 #include <asm/unaligned.h>
  15 
  16 #define ZET6223_MAX_FINGERS             16
  17 #define ZET6223_MAX_PKT_SIZE            (3 + 4 * ZET6223_MAX_FINGERS)
  18 
  19 #define ZET6223_CMD_INFO                0xB2
  20 #define ZET6223_CMD_INFO_LENGTH         17
  21 #define ZET6223_VALID_PACKET            0x3c
  22 
  23 #define ZET6223_POWER_ON_DELAY_MSEC     30
  24 
  25 struct zet6223_ts {
  26         struct i2c_client *client;
  27         struct input_dev *input;
  28         struct regulator *vcc;
  29         struct regulator *vio;
  30         struct touchscreen_properties prop;
  31         struct regulator_bulk_data supplies[2];
  32         u16 max_x;
  33         u16 max_y;
  34         u8 fingernum;
  35 };
  36 
  37 static int zet6223_start(struct input_dev *dev)
  38 {
  39         struct zet6223_ts *ts = input_get_drvdata(dev);
  40 
  41         enable_irq(ts->client->irq);
  42 
  43         return 0;
  44 }
  45 
  46 static void zet6223_stop(struct input_dev *dev)
  47 {
  48         struct zet6223_ts *ts = input_get_drvdata(dev);
  49 
  50         disable_irq(ts->client->irq);
  51 }
  52 
  53 static irqreturn_t zet6223_irq(int irq, void *dev_id)
  54 {
  55         struct zet6223_ts *ts = dev_id;
  56         u16 finger_bits;
  57 
  58         /*
  59          * First 3 bytes are an identifier, two bytes of finger data.
  60          * X, Y data per finger is 4 bytes.
  61          */
  62         u8 bufsize = 3 + 4 * ts->fingernum;
  63         u8 buf[ZET6223_MAX_PKT_SIZE];
  64         int i;
  65         int ret;
  66         int error;
  67 
  68         ret = i2c_master_recv(ts->client, buf, bufsize);
  69         if (ret != bufsize) {
  70                 error = ret < 0 ? ret : -EIO;
  71                 dev_err_ratelimited(&ts->client->dev,
  72                                     "Error reading input data: %d\n", error);
  73                 return IRQ_HANDLED;
  74         }
  75 
  76         if (buf[0] != ZET6223_VALID_PACKET)
  77                 return IRQ_HANDLED;
  78 
  79         finger_bits = get_unaligned_be16(buf + 1);
  80         for (i = 0; i < ts->fingernum; i++) {
  81                 if (!(finger_bits & BIT(15 - i)))
  82                         continue;
  83 
  84                 input_mt_slot(ts->input, i);
  85                 input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
  86                 input_event(ts->input, EV_ABS, ABS_MT_POSITION_X,
  87                                 ((buf[i + 3] >> 4) << 8) + buf[i + 4]);
  88                 input_event(ts->input, EV_ABS, ABS_MT_POSITION_Y,
  89                                 ((buf[i + 3] & 0xF) << 8) + buf[i + 5]);
  90         }
  91 
  92         input_mt_sync_frame(ts->input);
  93         input_sync(ts->input);
  94 
  95         return IRQ_HANDLED;
  96 }
  97 
  98 static void zet6223_power_off(void *_ts)
  99 {
 100         struct zet6223_ts *ts = _ts;
 101 
 102         regulator_bulk_disable(ARRAY_SIZE(ts->supplies), ts->supplies);
 103 }
 104 
 105 static int zet6223_power_on(struct zet6223_ts *ts)
 106 {
 107         struct device *dev = &ts->client->dev;
 108         int error;
 109 
 110         ts->supplies[0].supply = "vio";
 111         ts->supplies[1].supply = "vcc";
 112 
 113         error = devm_regulator_bulk_get(dev, ARRAY_SIZE(ts->supplies),
 114                                         ts->supplies);
 115         if (error)
 116                 return error;
 117 
 118         error = regulator_bulk_enable(ARRAY_SIZE(ts->supplies), ts->supplies);
 119         if (error)
 120                 return error;
 121 
 122         msleep(ZET6223_POWER_ON_DELAY_MSEC);
 123 
 124         error = devm_add_action_or_reset(dev, zet6223_power_off, ts);
 125         if (error) {
 126                 dev_err(dev, "failed to install poweroff action: %d\n", error);
 127                 return error;
 128         }
 129 
 130         return 0;
 131 }
 132 
 133 static int zet6223_query_device(struct zet6223_ts *ts)
 134 {
 135         u8 buf[ZET6223_CMD_INFO_LENGTH];
 136         u8 cmd = ZET6223_CMD_INFO;
 137         int ret;
 138         int error;
 139 
 140         ret = i2c_master_send(ts->client, &cmd, sizeof(cmd));
 141         if (ret != sizeof(cmd)) {
 142                 error = ret < 0 ? ret : -EIO;
 143                 dev_err(&ts->client->dev,
 144                         "touchpanel info cmd failed: %d\n", error);
 145                 return error;
 146         }
 147 
 148         ret = i2c_master_recv(ts->client, buf, sizeof(buf));
 149         if (ret != sizeof(buf)) {
 150                 error = ret < 0 ? ret : -EIO;
 151                 dev_err(&ts->client->dev,
 152                         "failed to retrieve touchpanel info: %d\n", error);
 153                 return error;
 154         }
 155 
 156         ts->fingernum = buf[15] & 0x7F;
 157         if (ts->fingernum > ZET6223_MAX_FINGERS) {
 158                 dev_warn(&ts->client->dev,
 159                          "touchpanel reports %d fingers, limiting to %d\n",
 160                          ts->fingernum, ZET6223_MAX_FINGERS);
 161                 ts->fingernum = ZET6223_MAX_FINGERS;
 162         }
 163 
 164         ts->max_x = get_unaligned_le16(&buf[8]);
 165         ts->max_y = get_unaligned_le16(&buf[10]);
 166 
 167         return 0;
 168 }
 169 
 170 static int zet6223_probe(struct i2c_client *client,
 171                          const struct i2c_device_id *id)
 172 {
 173         struct device *dev = &client->dev;
 174         struct zet6223_ts *ts;
 175         struct input_dev *input;
 176         int error;
 177 
 178         if (!client->irq) {
 179                 dev_err(dev, "no irq specified\n");
 180                 return -EINVAL;
 181         }
 182 
 183         ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
 184         if (!ts)
 185                 return -ENOMEM;
 186 
 187         ts->client = client;
 188 
 189         error = zet6223_power_on(ts);
 190         if (error)
 191                 return error;
 192 
 193         error = zet6223_query_device(ts);
 194         if (error)
 195                 return error;
 196 
 197         ts->input = input = devm_input_allocate_device(dev);
 198         if (!input)
 199                 return -ENOMEM;
 200 
 201         input_set_drvdata(input, ts);
 202 
 203         input->name = client->name;
 204         input->id.bustype = BUS_I2C;
 205         input->open = zet6223_start;
 206         input->close = zet6223_stop;
 207 
 208         input_set_abs_params(input, ABS_MT_POSITION_X, 0, ts->max_x, 0, 0);
 209         input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ts->max_y, 0, 0);
 210 
 211         touchscreen_parse_properties(input, true, &ts->prop);
 212 
 213         error = input_mt_init_slots(input, ts->fingernum,
 214                                     INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
 215         if (error)
 216                 return error;
 217 
 218         error = devm_request_threaded_irq(dev, client->irq, NULL, zet6223_irq,
 219                                           IRQF_ONESHOT, client->name, ts);
 220         if (error) {
 221                 dev_err(dev, "failed to request irq %d: %d\n",
 222                         client->irq, error);
 223                 return error;
 224         }
 225 
 226         zet6223_stop(input);
 227 
 228         error = input_register_device(input);
 229         if (error)
 230                 return error;
 231 
 232         return 0;
 233 }
 234 
 235 static const struct of_device_id zet6223_of_match[] = {
 236         { .compatible = "zeitec,zet6223" },
 237         { }
 238 };
 239 MODULE_DEVICE_TABLE(of, zet6223_of_match);
 240 
 241 static const struct i2c_device_id zet6223_id[] = {
 242         { "zet6223", 0},
 243         { }
 244 };
 245 MODULE_DEVICE_TABLE(i2c, zet6223_id);
 246 
 247 static struct i2c_driver zet6223_driver = {
 248         .driver = {
 249                 .name = "zet6223",
 250                 .of_match_table = zet6223_of_match,
 251         },
 252         .probe = zet6223_probe,
 253         .id_table = zet6223_id
 254 };
 255 module_i2c_driver(zet6223_driver);
 256 
 257 MODULE_AUTHOR("Jelle van der Waa <jelle@vdwaa.nl>");
 258 MODULE_DESCRIPTION("ZEITEC zet622x I2C touchscreen driver");
 259 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */