| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 |
|
| 7 | #include <linux/bitfield.h>
|
| 8 | #include <linux/bits.h>
|
| 9 | #include <linux/module.h>
|
| 10 | #include <linux/delay.h>
|
| 11 | #include <linux/of.h>
|
| 12 | #include <linux/i2c.h>
|
| 13 | #include <linux/input/mt.h>
|
| 14 | #include <linux/input/touchscreen.h>
|
| 15 | #include <linux/interrupt.h>
|
| 16 | #include <linux/regulator/consumer.h>
|
| 17 | #include <linux/slab.h>
|
| 18 |
|
| 19 |
|
| 20 | #define MMS114_MODE_CONTROL 0x01
|
| 21 | #define MMS114_OPERATION_MODE_MASK 0xE
|
| 22 | #define MMS114_ACTIVE BIT(1)
|
| 23 |
|
| 24 | #define MMS114_XY_RESOLUTION_H 0x02
|
| 25 | #define MMS114_X_RESOLUTION 0x03
|
| 26 | #define MMS114_Y_RESOLUTION 0x04
|
| 27 | #define MMS114_CONTACT_THRESHOLD 0x05
|
| 28 | #define MMS114_MOVING_THRESHOLD 0x06
|
| 29 |
|
| 30 |
|
| 31 | #define MMS114_PACKET_SIZE 0x0F
|
| 32 | #define MMS114_INFORMATION 0x10
|
| 33 | #define MMS114_TSP_REV 0xF0
|
| 34 |
|
| 35 | #define MMS152_FW_REV 0xE1
|
| 36 | #define MMS152_COMPAT_GROUP 0xF2
|
| 37 |
|
| 38 |
|
| 39 | #define MMS114_I2C_DELAY 50
|
| 40 |
|
| 41 |
|
| 42 | #define MMS114_POWERON_DELAY 200
|
| 43 |
|
| 44 |
|
| 45 | #define MMS114_MAX_AREA 0xff
|
| 46 |
|
| 47 | #define MMS114_MAX_TOUCHKEYS 15
|
| 48 | #define MMS114_MAX_TOUCH 10
|
| 49 | #define MMS114_EVENT_SIZE 8
|
| 50 | #define MMS136_EVENT_SIZE 6
|
| 51 |
|
| 52 |
|
| 53 | #define MMS114_TYPE_NONE 0
|
| 54 | #define MMS114_TYPE_TOUCHSCREEN 1
|
| 55 | #define MMS114_TYPE_TOUCHKEY 2
|
| 56 |
|
| 57 | struct mms114_data {
|
| 58 | const struct mms_chip *chip;
|
| 59 | struct i2c_client *client;
|
| 60 | struct input_dev *input_dev;
|
| 61 | struct regulator *core_reg;
|
| 62 | struct regulator *io_reg;
|
| 63 | struct touchscreen_properties props;
|
| 64 | unsigned int contact_threshold;
|
| 65 | unsigned int moving_threshold;
|
| 66 |
|
| 67 | u32 keycodes[MMS114_MAX_TOUCHKEYS];
|
| 68 | int num_keycodes;
|
| 69 |
|
| 70 |
|
| 71 | u8 cache_mode_control;
|
| 72 | };
|
| 73 |
|
| 74 | struct mms_chip {
|
| 75 | const char *name;
|
| 76 | int event_size;
|
| 77 | bool has_config_regs;
|
| 78 | int (*get_version)(struct mms114_data *data);
|
| 79 | };
|
| 80 |
|
| 81 | #define MMS114_FLAGS_ID_MASK GENMASK(3, 0)
|
| 82 | #define MMS114_FLAGS_TYPE_MASK GENMASK(6, 5)
|
| 83 | #define MMS114_FLAGS_PRESSED_MASK BIT(7)
|
| 84 |
|
| 85 | #define MMS114_XY_HI_X_MASK GENMASK(3, 0)
|
| 86 | #define MMS114_XY_HI_Y_MASK GENMASK(7, 4)
|
| 87 |
|
| 88 | struct mms114_touch {
|
| 89 | u8 flags;
|
| 90 | u8 xy_hi;
|
| 91 | u8 x_lo;
|
| 92 | u8 y_lo;
|
| 93 | u8 width;
|
| 94 | u8 strength;
|
| 95 | u8 reserved[2];
|
| 96 | } __packed;
|
| 97 |
|
| 98 | static int __mms114_read_reg(struct mms114_data *data, u8 reg,
|
| 99 | unsigned int len, void *val)
|
| 100 | {
|
| 101 | struct i2c_client *client = data->client;
|
| 102 | struct i2c_msg xfer[2];
|
| 103 | u8 buf = reg;
|
| 104 | int error;
|
| 105 |
|
| 106 | if (WARN_ON(reg <= MMS114_MODE_CONTROL && reg + len > MMS114_MODE_CONTROL))
|
| 107 | return -EINVAL;
|
| 108 |
|
| 109 |
|
| 110 | xfer[0].addr = client->addr;
|
| 111 | xfer[0].flags = client->flags & I2C_M_TEN;
|
| 112 | xfer[0].len = 1;
|
| 113 | xfer[0].buf = &buf;
|
| 114 |
|
| 115 |
|
| 116 | xfer[1].addr = client->addr;
|
| 117 | xfer[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
|
| 118 | xfer[1].len = len;
|
| 119 | xfer[1].buf = val;
|
| 120 |
|
| 121 | error = i2c_transfer(client->adapter, xfer, 2);
|
| 122 | if (error != 2) {
|
| 123 | dev_err(&client->dev,
|
| 124 | "%s: i2c transfer failed (%d)\n", __func__, error);
|
| 125 | return error < 0 ? error : -EIO;
|
| 126 | }
|
| 127 | usleep_range(MMS114_I2C_DELAY, MMS114_I2C_DELAY + 50);
|
| 128 |
|
| 129 | return 0;
|
| 130 | }
|
| 131 |
|
| 132 | static int mms114_read_reg(struct mms114_data *data, u8 reg)
|
| 133 | {
|
| 134 | u8 val;
|
| 135 | int error;
|
| 136 |
|
| 137 | if (reg == MMS114_MODE_CONTROL)
|
| 138 | return data->cache_mode_control;
|
| 139 |
|
| 140 | error = __mms114_read_reg(data, reg, 1, &val);
|
| 141 | return error < 0 ? error : val;
|
| 142 | }
|
| 143 |
|
| 144 | static int mms114_write_reg(struct mms114_data *data, u8 reg, u8 val)
|
| 145 | {
|
| 146 | struct i2c_client *client = data->client;
|
| 147 | u8 buf[2];
|
| 148 | int error;
|
| 149 |
|
| 150 | buf[0] = reg;
|
| 151 | buf[1] = val;
|
| 152 |
|
| 153 | error = i2c_master_send(client, buf, 2);
|
| 154 | if (error != 2) {
|
| 155 | dev_err(&client->dev,
|
| 156 | "%s: i2c send failed (%d)\n", __func__, error);
|
| 157 | return error < 0 ? error : -EIO;
|
| 158 | }
|
| 159 | usleep_range(MMS114_I2C_DELAY, MMS114_I2C_DELAY + 50);
|
| 160 |
|
| 161 | if (reg == MMS114_MODE_CONTROL)
|
| 162 | data->cache_mode_control = val;
|
| 163 |
|
| 164 | return 0;
|
| 165 | }
|
| 166 |
|
| 167 | static int mms114_get_version(struct mms114_data *data)
|
| 168 | {
|
| 169 | struct device *dev = &data->client->dev;
|
| 170 | u8 buf[6];
|
| 171 | int error;
|
| 172 |
|
| 173 | error = __mms114_read_reg(data, MMS114_TSP_REV, 6, buf);
|
| 174 | if (error)
|
| 175 | return error;
|
| 176 |
|
| 177 | dev_info(dev, "TSP Rev: 0x%x, HW Rev: 0x%x, Firmware Ver: 0x%x\n",
|
| 178 | buf[0], buf[1], buf[3]);
|
| 179 | return 0;
|
| 180 | }
|
| 181 |
|
| 182 | static int mms152_get_version(struct mms114_data *data)
|
| 183 | {
|
| 184 | struct device *dev = &data->client->dev;
|
| 185 | u8 buf[3];
|
| 186 | int group;
|
| 187 | int error;
|
| 188 |
|
| 189 | error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf);
|
| 190 | if (error)
|
| 191 | return error;
|
| 192 |
|
| 193 | group = i2c_smbus_read_byte_data(data->client, MMS152_COMPAT_GROUP);
|
| 194 | if (group < 0)
|
| 195 | return group;
|
| 196 |
|
| 197 | dev_info(dev, "TSP FW Rev: bootloader 0x%x / core 0x%x / config 0x%x, Compat group: %c\n",
|
| 198 | buf[0], buf[1], buf[2], group);
|
| 199 | return 0;
|
| 200 | }
|
| 201 |
|
| 202 | static int mms345l_get_version(struct mms114_data *data)
|
| 203 | {
|
| 204 | struct device *dev = &data->client->dev;
|
| 205 | u8 buf[3];
|
| 206 | int error;
|
| 207 |
|
| 208 | error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf);
|
| 209 | if (error)
|
| 210 | return error;
|
| 211 |
|
| 212 | dev_info(dev, "TSP FW Rev: bootloader 0x%x / core 0x%x / config 0x%x\n",
|
| 213 | buf[0], buf[1], buf[2]);
|
| 214 | return 0;
|
| 215 | }
|
| 216 |
|
| 217 | static const struct mms_chip mms114_descriptor = {
|
| 218 | .name = "MMS114",
|
| 219 | .event_size = MMS114_EVENT_SIZE,
|
| 220 | .has_config_regs = true,
|
| 221 | .get_version = mms114_get_version,
|
| 222 | };
|
| 223 |
|
| 224 | static const struct mms_chip mms134s_descriptor = {
|
| 225 | .name = "MMS134S",
|
| 226 | .event_size = MMS136_EVENT_SIZE,
|
| 227 | .has_config_regs = true,
|
| 228 | .get_version = mms114_get_version,
|
| 229 | };
|
| 230 |
|
| 231 | static const struct mms_chip mms136_descriptor = {
|
| 232 | .name = "MMS136",
|
| 233 | .event_size = MMS136_EVENT_SIZE,
|
| 234 | .has_config_regs = true,
|
| 235 | .get_version = mms114_get_version,
|
| 236 | };
|
| 237 |
|
| 238 | static const struct mms_chip mms152_descriptor = {
|
| 239 | .name = "MMS152",
|
| 240 | .event_size = MMS114_EVENT_SIZE,
|
| 241 | .has_config_regs = false,
|
| 242 | .get_version = mms152_get_version,
|
| 243 | };
|
| 244 |
|
| 245 | static const struct mms_chip mms345l_descriptor = {
|
| 246 | .name = "MMS345L",
|
| 247 | .event_size = MMS114_EVENT_SIZE,
|
| 248 | .has_config_regs = false,
|
| 249 | .get_version = mms345l_get_version,
|
| 250 | };
|
| 251 |
|
| 252 | static void mms114_process_mt(struct mms114_data *data, struct mms114_touch *touch)
|
| 253 | {
|
| 254 | struct i2c_client *client = data->client;
|
| 255 | struct input_dev *input_dev = data->input_dev;
|
| 256 | unsigned int id = FIELD_GET(MMS114_FLAGS_ID_MASK, touch->flags);
|
| 257 | unsigned int type = FIELD_GET(MMS114_FLAGS_TYPE_MASK, touch->flags);
|
| 258 | bool pressed = FIELD_GET(MMS114_FLAGS_PRESSED_MASK, touch->flags);
|
| 259 | unsigned int x;
|
| 260 | unsigned int y;
|
| 261 |
|
| 262 | if (id == 0 || id > MMS114_MAX_TOUCH) {
|
| 263 | dev_err(&client->dev, "Wrong touch id (%d)\n", id);
|
| 264 | return;
|
| 265 | }
|
| 266 |
|
| 267 | id--;
|
| 268 | x = touch->x_lo | FIELD_GET(MMS114_XY_HI_X_MASK, touch->xy_hi) << 8;
|
| 269 | y = touch->y_lo | FIELD_GET(MMS114_XY_HI_Y_MASK, touch->xy_hi) << 8;
|
| 270 |
|
| 271 | dev_dbg(&client->dev,
|
| 272 | "id: %d, type: %d, pressed: %d, x: %d, y: %d, width: %d, strength: %d\n",
|
| 273 | id, type, pressed,
|
| 274 | x, y, touch->width, touch->strength);
|
| 275 |
|
| 276 | input_mt_slot(input_dev, id);
|
| 277 | input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, pressed);
|
| 278 |
|
| 279 | if (pressed) {
|
| 280 | touchscreen_report_pos(input_dev, &data->props, x, y, true);
|
| 281 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, touch->width);
|
| 282 | input_report_abs(input_dev, ABS_MT_PRESSURE, touch->strength);
|
| 283 | }
|
| 284 | }
|
| 285 |
|
| 286 | static void mms114_process_touchkey(struct mms114_data *data,
|
| 287 | struct mms114_touch *touch)
|
| 288 | {
|
| 289 | struct i2c_client *client = data->client;
|
| 290 | struct input_dev *input_dev = data->input_dev;
|
| 291 | unsigned int keycode_id;
|
| 292 | unsigned int id = FIELD_GET(MMS114_FLAGS_ID_MASK, touch->flags);
|
| 293 | bool pressed = FIELD_GET(MMS114_FLAGS_PRESSED_MASK, touch->flags);
|
| 294 |
|
| 295 | if (id == 0)
|
| 296 | return;
|
| 297 |
|
| 298 | if (id > data->num_keycodes) {
|
| 299 | dev_err(&client->dev, "Wrong touch id for touchkey (%d)\n",
|
| 300 | id);
|
| 301 | return;
|
| 302 | }
|
| 303 |
|
| 304 | keycode_id = id - 1;
|
| 305 | dev_dbg(&client->dev, "keycode id: %d, pressed: %d\n", keycode_id,
|
| 306 | pressed);
|
| 307 |
|
| 308 | input_report_key(input_dev, data->keycodes[keycode_id], pressed);
|
| 309 | }
|
| 310 |
|
| 311 | static irqreturn_t mms114_interrupt(int irq, void *dev_id)
|
| 312 | {
|
| 313 | struct mms114_data *data = dev_id;
|
| 314 | struct i2c_client *client = data->client;
|
| 315 | struct mms114_touch touch[MMS114_MAX_TOUCH];
|
| 316 | struct mms114_touch *t;
|
| 317 | int event_size = data->chip->event_size;
|
| 318 | int packet_size;
|
| 319 | int touch_size;
|
| 320 | int index;
|
| 321 | int error;
|
| 322 |
|
| 323 | packet_size = mms114_read_reg(data, MMS114_PACKET_SIZE);
|
| 324 | if (packet_size <= 0)
|
| 325 | goto out;
|
| 326 |
|
| 327 | if (packet_size > sizeof(touch)) {
|
| 328 | dev_err(&client->dev, "Invalid packet size %d (max %zu)\n",
|
| 329 | packet_size, sizeof(touch));
|
| 330 | goto out;
|
| 331 | }
|
| 332 |
|
| 333 | touch_size = packet_size / event_size;
|
| 334 |
|
| 335 | error = __mms114_read_reg(data, MMS114_INFORMATION, packet_size, touch);
|
| 336 | if (error)
|
| 337 | goto out;
|
| 338 |
|
| 339 | for (index = 0; index < touch_size; index++) {
|
| 340 | t = (struct mms114_touch *)((u8 *)touch + index * event_size);
|
| 341 | unsigned int type = FIELD_GET(MMS114_FLAGS_TYPE_MASK, t->flags);
|
| 342 |
|
| 343 | switch (type) {
|
| 344 | case MMS114_TYPE_TOUCHSCREEN:
|
| 345 | mms114_process_mt(data, t);
|
| 346 | break;
|
| 347 |
|
| 348 | case MMS114_TYPE_TOUCHKEY:
|
| 349 | mms114_process_touchkey(data, t);
|
| 350 | break;
|
| 351 |
|
| 352 | default:
|
| 353 | dev_err(&client->dev, "Wrong touch type (%d)\n",
|
| 354 | type);
|
| 355 | break;
|
| 356 | }
|
| 357 | }
|
| 358 |
|
| 359 | input_mt_report_pointer_emulation(data->input_dev, true);
|
| 360 | input_sync(data->input_dev);
|
| 361 |
|
| 362 | out:
|
| 363 | return IRQ_HANDLED;
|
| 364 | }
|
| 365 |
|
| 366 | static int mms114_set_active(struct mms114_data *data, bool active)
|
| 367 | {
|
| 368 | int val;
|
| 369 |
|
| 370 | val = mms114_read_reg(data, MMS114_MODE_CONTROL);
|
| 371 | if (val < 0)
|
| 372 | return val;
|
| 373 |
|
| 374 | val &= ~MMS114_OPERATION_MODE_MASK;
|
| 375 |
|
| 376 |
|
| 377 | if (active)
|
| 378 | val |= MMS114_ACTIVE;
|
| 379 |
|
| 380 | return mms114_write_reg(data, MMS114_MODE_CONTROL, val);
|
| 381 | }
|
| 382 |
|
| 383 | static int mms114_setup_regs(struct mms114_data *data)
|
| 384 | {
|
| 385 | const struct touchscreen_properties *props = &data->props;
|
| 386 | int val;
|
| 387 | int error;
|
| 388 |
|
| 389 | error = data->chip->get_version(data);
|
| 390 | if (error)
|
| 391 | return error;
|
| 392 |
|
| 393 | if (!data->chip->has_config_regs)
|
| 394 | return 0;
|
| 395 |
|
| 396 | error = mms114_set_active(data, true);
|
| 397 | if (error < 0)
|
| 398 | return error;
|
| 399 |
|
| 400 | val = (props->max_x >> 8) & 0xf;
|
| 401 | val |= ((props->max_y >> 8) & 0xf) << 4;
|
| 402 | error = mms114_write_reg(data, MMS114_XY_RESOLUTION_H, val);
|
| 403 | if (error < 0)
|
| 404 | return error;
|
| 405 |
|
| 406 | val = props->max_x & 0xff;
|
| 407 | error = mms114_write_reg(data, MMS114_X_RESOLUTION, val);
|
| 408 | if (error < 0)
|
| 409 | return error;
|
| 410 |
|
| 411 | val = props->max_y & 0xff;
|
| 412 | error = mms114_write_reg(data, MMS114_Y_RESOLUTION, val);
|
| 413 | if (error < 0)
|
| 414 | return error;
|
| 415 |
|
| 416 | if (data->contact_threshold) {
|
| 417 | error = mms114_write_reg(data, MMS114_CONTACT_THRESHOLD,
|
| 418 | data->contact_threshold);
|
| 419 | if (error < 0)
|
| 420 | return error;
|
| 421 | }
|
| 422 |
|
| 423 | if (data->moving_threshold) {
|
| 424 | error = mms114_write_reg(data, MMS114_MOVING_THRESHOLD,
|
| 425 | data->moving_threshold);
|
| 426 | if (error < 0)
|
| 427 | return error;
|
| 428 | }
|
| 429 |
|
| 430 | return 0;
|
| 431 | }
|
| 432 |
|
| 433 | static int mms114_start(struct mms114_data *data)
|
| 434 | {
|
| 435 | struct i2c_client *client = data->client;
|
| 436 | int error;
|
| 437 |
|
| 438 | error = regulator_enable(data->core_reg);
|
| 439 | if (error) {
|
| 440 | dev_err(&client->dev, "Failed to enable avdd: %d\n", error);
|
| 441 | return error;
|
| 442 | }
|
| 443 |
|
| 444 | error = regulator_enable(data->io_reg);
|
| 445 | if (error) {
|
| 446 | dev_err(&client->dev, "Failed to enable vdd: %d\n", error);
|
| 447 | regulator_disable(data->core_reg);
|
| 448 | return error;
|
| 449 | }
|
| 450 |
|
| 451 | msleep(MMS114_POWERON_DELAY);
|
| 452 |
|
| 453 | error = mms114_setup_regs(data);
|
| 454 | if (error < 0) {
|
| 455 | regulator_disable(data->io_reg);
|
| 456 | regulator_disable(data->core_reg);
|
| 457 | return error;
|
| 458 | }
|
| 459 |
|
| 460 | enable_irq(client->irq);
|
| 461 |
|
| 462 | return 0;
|
| 463 | }
|
| 464 |
|
| 465 | static void mms114_stop(struct mms114_data *data)
|
| 466 | {
|
| 467 | struct i2c_client *client = data->client;
|
| 468 | int error;
|
| 469 |
|
| 470 | disable_irq(client->irq);
|
| 471 |
|
| 472 | error = regulator_disable(data->io_reg);
|
| 473 | if (error)
|
| 474 | dev_warn(&client->dev, "Failed to disable vdd: %d\n", error);
|
| 475 |
|
| 476 | error = regulator_disable(data->core_reg);
|
| 477 | if (error)
|
| 478 | dev_warn(&client->dev, "Failed to disable avdd: %d\n", error);
|
| 479 | }
|
| 480 |
|
| 481 | static int mms114_input_open(struct input_dev *dev)
|
| 482 | {
|
| 483 | struct mms114_data *data = input_get_drvdata(dev);
|
| 484 |
|
| 485 | return mms114_start(data);
|
| 486 | }
|
| 487 |
|
| 488 | static void mms114_input_close(struct input_dev *dev)
|
| 489 | {
|
| 490 | struct mms114_data *data = input_get_drvdata(dev);
|
| 491 |
|
| 492 | mms114_stop(data);
|
| 493 | }
|
| 494 |
|
| 495 | static int mms114_parse_legacy_bindings(struct mms114_data *data)
|
| 496 | {
|
| 497 | struct device *dev = &data->client->dev;
|
| 498 | struct touchscreen_properties *props = &data->props;
|
| 499 |
|
| 500 | if (device_property_read_u32(dev, "x-size", &props->max_x)) {
|
| 501 | dev_dbg(dev, "failed to get legacy x-size property\n");
|
| 502 | return -EINVAL;
|
| 503 | }
|
| 504 |
|
| 505 | if (device_property_read_u32(dev, "y-size", &props->max_y)) {
|
| 506 | dev_dbg(dev, "failed to get legacy y-size property\n");
|
| 507 | return -EINVAL;
|
| 508 | }
|
| 509 |
|
| 510 | device_property_read_u32(dev, "contact-threshold",
|
| 511 | &data->contact_threshold);
|
| 512 | device_property_read_u32(dev, "moving-threshold",
|
| 513 | &data->moving_threshold);
|
| 514 |
|
| 515 | if (device_property_read_bool(dev, "x-invert"))
|
| 516 | props->invert_x = true;
|
| 517 | if (device_property_read_bool(dev, "y-invert"))
|
| 518 | props->invert_y = true;
|
| 519 |
|
| 520 | props->swap_x_y = false;
|
| 521 |
|
| 522 | return 0;
|
| 523 | }
|
| 524 |
|
| 525 | static int mms114_probe(struct i2c_client *client)
|
| 526 | {
|
| 527 | struct mms114_data *data;
|
| 528 | struct input_dev *input_dev;
|
| 529 | int error;
|
| 530 | int i;
|
| 531 |
|
| 532 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
| 533 | dev_err(&client->dev, "Not supported I2C adapter\n");
|
| 534 | return -ENODEV;
|
| 535 | }
|
| 536 |
|
| 537 | data = devm_kzalloc(&client->dev, sizeof(struct mms114_data),
|
| 538 | GFP_KERNEL);
|
| 539 | input_dev = devm_input_allocate_device(&client->dev);
|
| 540 | if (!data || !input_dev) {
|
| 541 | dev_err(&client->dev, "Failed to allocate memory\n");
|
| 542 | return -ENOMEM;
|
| 543 | }
|
| 544 |
|
| 545 | data->client = client;
|
| 546 | data->input_dev = input_dev;
|
| 547 |
|
| 548 | data->chip = i2c_get_match_data(client);
|
| 549 | if (!data->chip)
|
| 550 | return -EINVAL;
|
| 551 |
|
| 552 | data->num_keycodes = device_property_count_u32(&client->dev,
|
| 553 | "linux,keycodes");
|
| 554 | if (data->num_keycodes == -EINVAL) {
|
| 555 | data->num_keycodes = 0;
|
| 556 | } else if (data->num_keycodes < 0) {
|
| 557 | dev_err(&client->dev,
|
| 558 | "Unable to parse linux,keycodes property: %d\n",
|
| 559 | data->num_keycodes);
|
| 560 | return data->num_keycodes;
|
| 561 | } else if (data->num_keycodes > MMS114_MAX_TOUCHKEYS) {
|
| 562 | dev_warn(&client->dev,
|
| 563 | "Found %d linux,keycodes but max is %d, ignoring the rest\n",
|
| 564 | data->num_keycodes, MMS114_MAX_TOUCHKEYS);
|
| 565 | data->num_keycodes = MMS114_MAX_TOUCHKEYS;
|
| 566 | }
|
| 567 |
|
| 568 | if (data->num_keycodes > 0) {
|
| 569 | error = device_property_read_u32_array(&client->dev,
|
| 570 | "linux,keycodes",
|
| 571 | data->keycodes,
|
| 572 | data->num_keycodes);
|
| 573 | if (error) {
|
| 574 | dev_err(&client->dev,
|
| 575 | "Unable to read linux,keycodes values: %d\n",
|
| 576 | error);
|
| 577 | return error;
|
| 578 | }
|
| 579 |
|
| 580 | input_dev->keycode = data->keycodes;
|
| 581 | input_dev->keycodemax = data->num_keycodes;
|
| 582 | input_dev->keycodesize = sizeof(data->keycodes[0]);
|
| 583 | for (i = 0; i < data->num_keycodes; i++)
|
| 584 | input_set_capability(input_dev,
|
| 585 | EV_KEY, data->keycodes[i]);
|
| 586 | }
|
| 587 |
|
| 588 | input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X);
|
| 589 | input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y);
|
| 590 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
|
| 591 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
|
| 592 | 0, MMS114_MAX_AREA, 0, 0);
|
| 593 |
|
| 594 | touchscreen_parse_properties(input_dev, true, &data->props);
|
| 595 | if (!data->props.max_x || !data->props.max_y) {
|
| 596 | dev_dbg(&client->dev,
|
| 597 | "missing X/Y size properties, trying legacy bindings\n");
|
| 598 | error = mms114_parse_legacy_bindings(data);
|
| 599 | if (error)
|
| 600 | return error;
|
| 601 |
|
| 602 | input_set_abs_params(input_dev, ABS_MT_POSITION_X,
|
| 603 | 0, data->props.max_x, 0, 0);
|
| 604 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
|
| 605 | 0, data->props.max_y, 0, 0);
|
| 606 | }
|
| 607 |
|
| 608 | if (data->chip->has_config_regs) {
|
| 609 | |
| 610 | * The firmware handles movement and pressure fuzz, so
|
| 611 | * don't duplicate that in software.
|
| 612 |
|
| 613 | data->moving_threshold = input_abs_get_fuzz(input_dev,
|
| 614 | ABS_MT_POSITION_X);
|
| 615 | data->contact_threshold = input_abs_get_fuzz(input_dev,
|
| 616 | ABS_MT_PRESSURE);
|
| 617 | input_abs_set_fuzz(input_dev, ABS_MT_POSITION_X, 0);
|
| 618 | input_abs_set_fuzz(input_dev, ABS_MT_POSITION_Y, 0);
|
| 619 | input_abs_set_fuzz(input_dev, ABS_MT_PRESSURE, 0);
|
| 620 | }
|
| 621 |
|
| 622 | input_dev->name = devm_kasprintf(&client->dev, GFP_KERNEL,
|
| 623 | "MELFAS %s Touchscreen",
|
| 624 | data->chip->name);
|
| 625 | if (!input_dev->name)
|
| 626 | return -ENOMEM;
|
| 627 |
|
| 628 | input_dev->id.bustype = BUS_I2C;
|
| 629 | input_dev->dev.parent = &client->dev;
|
| 630 | input_dev->open = mms114_input_open;
|
| 631 | input_dev->close = mms114_input_close;
|
| 632 |
|
| 633 | error = input_mt_init_slots(input_dev, MMS114_MAX_TOUCH,
|
| 634 | INPUT_MT_DIRECT);
|
| 635 | if (error)
|
| 636 | return error;
|
| 637 |
|
| 638 | input_set_drvdata(input_dev, data);
|
| 639 | i2c_set_clientdata(client, data);
|
| 640 |
|
| 641 | data->core_reg = devm_regulator_get(&client->dev, "avdd");
|
| 642 | if (IS_ERR(data->core_reg)) {
|
| 643 | error = PTR_ERR(data->core_reg);
|
| 644 | dev_err(&client->dev,
|
| 645 | "Unable to get the Core regulator (%d)\n", error);
|
| 646 | return error;
|
| 647 | }
|
| 648 |
|
| 649 | data->io_reg = devm_regulator_get(&client->dev, "vdd");
|
| 650 | if (IS_ERR(data->io_reg)) {
|
| 651 | error = PTR_ERR(data->io_reg);
|
| 652 | dev_err(&client->dev,
|
| 653 | "Unable to get the IO regulator (%d)\n", error);
|
| 654 | return error;
|
| 655 | }
|
| 656 |
|
| 657 | error = devm_request_threaded_irq(&client->dev, client->irq,
|
| 658 | NULL, mms114_interrupt,
|
| 659 | IRQF_ONESHOT | IRQF_NO_AUTOEN,
|
| 660 | dev_name(&client->dev), data);
|
| 661 | if (error) {
|
| 662 | dev_err(&client->dev, "Failed to register interrupt\n");
|
| 663 | return error;
|
| 664 | }
|
| 665 |
|
| 666 | error = input_register_device(data->input_dev);
|
| 667 | if (error) {
|
| 668 | dev_err(&client->dev, "Failed to register input device\n");
|
| 669 | return error;
|
| 670 | }
|
| 671 |
|
| 672 | return 0;
|
| 673 | }
|
| 674 |
|
| 675 | static int mms114_suspend(struct device *dev)
|
| 676 | {
|
| 677 | struct i2c_client *client = to_i2c_client(dev);
|
| 678 | struct mms114_data *data = i2c_get_clientdata(client);
|
| 679 | struct input_dev *input_dev = data->input_dev;
|
| 680 | int id;
|
| 681 |
|
| 682 |
|
| 683 | for (id = 0; id < MMS114_MAX_TOUCH; id++) {
|
| 684 | input_mt_slot(input_dev, id);
|
| 685 | input_mt_report_slot_inactive(input_dev);
|
| 686 | }
|
| 687 |
|
| 688 | input_mt_report_pointer_emulation(input_dev, true);
|
| 689 | input_sync(input_dev);
|
| 690 |
|
| 691 | guard(mutex)(&input_dev->mutex);
|
| 692 |
|
| 693 | if (input_device_enabled(input_dev))
|
| 694 | mms114_stop(data);
|
| 695 |
|
| 696 | return 0;
|
| 697 | }
|
| 698 |
|
| 699 | static int mms114_resume(struct device *dev)
|
| 700 | {
|
| 701 | struct i2c_client *client = to_i2c_client(dev);
|
| 702 | struct mms114_data *data = i2c_get_clientdata(client);
|
| 703 | struct input_dev *input_dev = data->input_dev;
|
| 704 | int error;
|
| 705 |
|
| 706 | guard(mutex)(&input_dev->mutex);
|
| 707 |
|
| 708 | if (input_device_enabled(input_dev)) {
|
| 709 | error = mms114_start(data);
|
| 710 | if (error)
|
| 711 | return error;
|
| 712 | }
|
| 713 |
|
| 714 | return 0;
|
| 715 | }
|
| 716 |
|
| 717 | static DEFINE_SIMPLE_DEV_PM_OPS(mms114_pm_ops, mms114_suspend, mms114_resume);
|
| 718 |
|
| 719 | static const struct i2c_device_id mms114_id[] = {
|
| 720 | { .name = "mms114", .driver_data = (kernel_ulong_t)&mms114_descriptor },
|
| 721 | { .name = "mms134s", .driver_data = (kernel_ulong_t)&mms134s_descriptor },
|
| 722 | { .name = "mms136", .driver_data = (kernel_ulong_t)&mms136_descriptor },
|
| 723 | { .name = "mms152", .driver_data = (kernel_ulong_t)&mms152_descriptor },
|
| 724 | { .name = "mms345l", .driver_data = (kernel_ulong_t)&mms345l_descriptor },
|
| 725 | { }
|
| 726 | };
|
| 727 | MODULE_DEVICE_TABLE(i2c, mms114_id);
|
| 728 |
|
| 729 | #ifdef CONFIG_OF
|
| 730 | static const struct of_device_id mms114_dt_match[] = {
|
| 731 | { .compatible = "melfas,mms114", .data = &mms114_descriptor },
|
| 732 | { .compatible = "melfas,mms134s", .data = &mms134s_descriptor },
|
| 733 | { .compatible = "melfas,mms136", .data = &mms136_descriptor },
|
| 734 | { .compatible = "melfas,mms152", .data = &mms152_descriptor },
|
| 735 | { .compatible = "melfas,mms345l", .data = &mms345l_descriptor },
|
| 736 | { }
|
| 737 | };
|
| 738 | MODULE_DEVICE_TABLE(of, mms114_dt_match);
|
| 739 | #endif
|
| 740 |
|
| 741 | static struct i2c_driver mms114_driver = {
|
| 742 | .driver = {
|
| 743 | .name = "mms114",
|
| 744 | .pm = pm_sleep_ptr(&mms114_pm_ops),
|
| 745 | .of_match_table = of_match_ptr(mms114_dt_match),
|
| 746 | },
|
| 747 | .probe = mms114_probe,
|
| 748 | .id_table = mms114_id,
|
| 749 | };
|
| 750 |
|
| 751 | module_i2c_driver(mms114_driver);
|
| 752 |
|
| 753 |
|
| 754 | MODULE_AUTHOR("Joonyoung Shim <[email protected]>");
|
| 755 | MODULE_DESCRIPTION("MELFAS mms114 Touchscreen driver");
|
| 756 | MODULE_LICENSE("GPL");
|