1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Wacom W9000-series penabled I2C touchscreen driver 4 * 5 * Copyright (c) 2026 Hendrik Noack <hendrik-noack@gmx.de> 6 * 7 * Partially based on vendor driver: 8 * Copyright (C) 2012, Samsung Electronics Co. Ltd. 9 */ 10 11 #include <linux/delay.h> 12 #include <linux/gpio/consumer.h> 13 #include <linux/i2c.h> 14 #include <linux/input.h> 15 #include <linux/input/touchscreen.h> 16 #include <linux/interrupt.h> 17 #include <linux/lockdep.h> 18 #include <linux/regulator/consumer.h> 19 #include <linux/unaligned.h> 20 21 /* Some chips have flaky firmware that requires many retries before responding. */ 22 #define CMD_QUERY_RETRIES 8 23 24 /* Message length */ 25 #define CMD_QUERY_NUM_MAX 9 26 #define MSG_COORD_NUM_MAX 12 27 28 /* Commands */ 29 #define CMD_QUERY 0x2a 30 31 struct wacom_w9000_variant { 32 const u8 cmd_query_num; 33 const u8 msg_coord_num; 34 const char *name; 35 }; 36 37 struct wacom_w9000_data { 38 struct i2c_client *client; 39 struct input_dev *input_dev; 40 const struct wacom_w9000_variant *variant; 41 u16 fw_version; 42 43 struct touchscreen_properties prop; 44 u16 max_pressure; 45 46 struct regulator *regulator; 47 48 struct gpio_desc *flash_mode_gpio; 49 struct gpio_desc *reset_gpio; 50 51 unsigned int irq; 52 53 bool pen_proximity; 54 }; 55 56 static int wacom_w9000_read(struct i2c_client *client, u8 command, u8 len, u8 *data) 57 { 58 int error, res; 59 struct i2c_msg msg[] = { 60 { 61 .addr = client->addr, 62 .flags = 0, 63 .buf = &command, 64 .len = sizeof(command), 65 }, { 66 .addr = client->addr, 67 .flags = I2C_M_RD, 68 .buf = data, 69 .len = len, 70 } 71 }; 72 73 res = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); 74 if (res != ARRAY_SIZE(msg)) { 75 error = res < 0 ? res : -EIO; 76 dev_err(&client->dev, "%s: i2c transfer failed: %d (%d)\n", 77 __func__, error, res); 78 return error; 79 } 80 81 return 0; 82 } 83 84 static int wacom_w9000_query(struct wacom_w9000_data *wacom_data) 85 { 86 struct i2c_client *client = wacom_data->client; 87 struct device *dev = &wacom_data->client->dev; 88 u8 data[CMD_QUERY_NUM_MAX]; 89 int retry; 90 int error; 91 92 for (retry = 0; retry < CMD_QUERY_RETRIES; retry++) { 93 error = wacom_w9000_read(client, CMD_QUERY, 94 wacom_data->variant->cmd_query_num, 95 data); 96 if (!error && data[0] == 0x0f) 97 break; 98 } 99 100 if (error) 101 return error; 102 103 if (data[0] != 0x0f) 104 return -EIO; 105 106 dev_dbg(dev, "query: %*ph, %d\n", 107 wacom_data->variant->cmd_query_num, data, retry); 108 109 wacom_data->prop.max_x = get_unaligned_be16(&data[1]); 110 wacom_data->prop.max_y = get_unaligned_be16(&data[3]); 111 wacom_data->max_pressure = get_unaligned_be16(&data[5]); 112 wacom_data->fw_version = get_unaligned_be16(&data[7]); 113 114 dev_dbg(dev, "max_x:%d, max_y:%d, max_pressure:%d, fw:%#x\n", 115 wacom_data->prop.max_x, wacom_data->prop.max_y, 116 wacom_data->max_pressure, wacom_data->fw_version); 117 118 return 0; 119 } 120 121 static int wacom_w9000_power_on(struct wacom_w9000_data *wacom_data) 122 { 123 int error; 124 125 lockdep_assert_held(&wacom_data->input_dev->mutex); 126 127 error = regulator_enable(wacom_data->regulator); 128 if (error) { 129 dev_err(&wacom_data->client->dev, "Failed to enable regulators: %d\n", error); 130 return error; 131 } 132 133 msleep(200); 134 135 gpiod_set_value_cansleep(wacom_data->reset_gpio, 0); 136 enable_irq(wacom_data->irq); 137 138 return 0; 139 } 140 141 static int wacom_w9000_power_off(struct wacom_w9000_data *wacom_data) 142 { 143 lockdep_assert_held(&wacom_data->input_dev->mutex); 144 145 disable_irq(wacom_data->irq); 146 gpiod_set_value_cansleep(wacom_data->reset_gpio, 1); 147 regulator_disable(wacom_data->regulator); 148 149 return 0; 150 } 151 152 static void wacom_w9000_coord(struct wacom_w9000_data *wacom_data) 153 { 154 struct i2c_client *client = wacom_data->client; 155 struct device *dev = &wacom_data->client->dev; 156 u8 data[MSG_COORD_NUM_MAX]; 157 bool touch, rubber, side_button; 158 u16 x, y, pressure; 159 u8 distance = 0; 160 int error; 161 162 error = i2c_master_recv(client, data, wacom_data->variant->msg_coord_num); 163 if (error != wacom_data->variant->msg_coord_num) { 164 if (error >= 0) 165 error = -EIO; 166 dev_err_ratelimited(dev, "%s: i2c receive failed (%d)\n", __func__, error); 167 return; 168 } 169 170 dev_dbg(dev, "data: %*ph\n", wacom_data->variant->msg_coord_num, data); 171 172 if (data[0] & BIT(7)) { 173 wacom_data->pen_proximity = true; 174 175 touch = !!(data[0] & BIT(4)); 176 side_button = !!(data[0] & BIT(5)); 177 rubber = !!(data[0] & BIT(6)); 178 179 x = get_unaligned_be16(&data[1]); 180 y = get_unaligned_be16(&data[3]); 181 pressure = get_unaligned_be16(&data[5]); 182 183 if (wacom_data->variant->msg_coord_num > 7) 184 distance = data[7]; 185 186 if (x > wacom_data->prop.max_x || y > wacom_data->prop.max_y) { 187 dev_warn_ratelimited(dev, "Coordinates out of range x=%d, y=%d\n", x, y); 188 return; 189 } 190 191 if (pressure > wacom_data->max_pressure) { 192 dev_warn_ratelimited(dev, "Pressure out of range %d\n", pressure); 193 return; 194 } 195 196 touchscreen_report_pos(wacom_data->input_dev, &wacom_data->prop, x, y, false); 197 input_report_abs(wacom_data->input_dev, ABS_PRESSURE, pressure); 198 199 if (wacom_data->variant->msg_coord_num > 7) 200 input_report_abs(wacom_data->input_dev, ABS_DISTANCE, distance); 201 202 input_report_key(wacom_data->input_dev, BTN_STYLUS, side_button); 203 input_report_key(wacom_data->input_dev, BTN_TOUCH, touch); 204 input_report_key(wacom_data->input_dev, BTN_TOOL_PEN, !rubber); 205 input_report_key(wacom_data->input_dev, BTN_TOOL_RUBBER, rubber); 206 input_sync(wacom_data->input_dev); 207 } else if (wacom_data->pen_proximity) { 208 input_report_abs(wacom_data->input_dev, ABS_PRESSURE, 0); 209 210 if (wacom_data->variant->msg_coord_num > 7) 211 input_report_abs(wacom_data->input_dev, ABS_DISTANCE, 255); 212 213 input_report_key(wacom_data->input_dev, BTN_STYLUS, 0); 214 input_report_key(wacom_data->input_dev, BTN_TOUCH, 0); 215 input_report_key(wacom_data->input_dev, BTN_TOOL_PEN, 0); 216 input_report_key(wacom_data->input_dev, BTN_TOOL_RUBBER, 0); 217 input_sync(wacom_data->input_dev); 218 219 wacom_data->pen_proximity = false; 220 } 221 } 222 223 static irqreturn_t wacom_w9000_interrupt(int irq, void *dev_id) 224 { 225 struct wacom_w9000_data *wacom_data = dev_id; 226 227 wacom_w9000_coord(wacom_data); 228 229 return IRQ_HANDLED; 230 } 231 232 static int wacom_w9000_open(struct input_dev *dev) 233 { 234 struct wacom_w9000_data *wacom_data = input_get_drvdata(dev); 235 236 return wacom_w9000_power_on(wacom_data); 237 } 238 239 static void wacom_w9000_close(struct input_dev *dev) 240 { 241 struct wacom_w9000_data *wacom_data = input_get_drvdata(dev); 242 243 wacom_w9000_power_off(wacom_data); 244 } 245 246 static int wacom_w9000_probe(struct i2c_client *client) 247 { 248 struct device *dev = &client->dev; 249 struct wacom_w9000_data *wacom_data; 250 struct input_dev *input_dev; 251 int error; 252 u32 val; 253 254 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 255 dev_err(dev, "i2c_check_functionality error\n"); 256 return -EIO; 257 } 258 259 wacom_data = devm_kzalloc(dev, sizeof(*wacom_data), GFP_KERNEL); 260 if (!wacom_data) 261 return -ENOMEM; 262 263 wacom_data->variant = i2c_get_match_data(client); 264 if (!wacom_data->variant) { 265 dev_err(dev, "No i2c match_data available\n"); 266 return -EINVAL; 267 } 268 269 if (wacom_data->variant->cmd_query_num > CMD_QUERY_NUM_MAX || 270 wacom_data->variant->msg_coord_num > MSG_COORD_NUM_MAX) { 271 dev_err(dev, "Length of message for %s exceeds the maximum\n", 272 wacom_data->variant->name); 273 return -EINVAL; 274 } 275 276 if (wacom_data->variant->msg_coord_num < 7) { 277 dev_err(dev, "Length of coordinates message for %s too short\n", 278 wacom_data->variant->name); 279 return -EINVAL; 280 } 281 282 wacom_data->client = client; 283 wacom_data->irq = client->irq; 284 i2c_set_clientdata(client, wacom_data); 285 286 wacom_data->regulator = devm_regulator_get(dev, "vdd"); 287 if (IS_ERR(wacom_data->regulator)) 288 return dev_err_probe(dev, PTR_ERR(wacom_data->regulator), 289 "Failed to get regulators\n"); 290 291 wacom_data->flash_mode_gpio = devm_gpiod_get_optional(dev, "flash-mode", GPIOD_OUT_LOW); 292 if (IS_ERR(wacom_data->flash_mode_gpio)) 293 return dev_err_probe(dev, PTR_ERR(wacom_data->flash_mode_gpio), 294 "Failed to get flash-mode gpio\n"); 295 296 wacom_data->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); 297 if (IS_ERR(wacom_data->reset_gpio)) 298 return dev_err_probe(dev, PTR_ERR(wacom_data->reset_gpio), 299 "Failed to get reset gpio\n"); 300 301 error = regulator_enable(wacom_data->regulator); 302 if (error) 303 return dev_err_probe(dev, error, "Failed to enable regulators\n"); 304 305 msleep(200); 306 307 gpiod_set_value_cansleep(wacom_data->reset_gpio, 0); 308 309 error = wacom_w9000_query(wacom_data); 310 311 gpiod_set_value_cansleep(wacom_data->reset_gpio, 1); 312 regulator_disable(wacom_data->regulator); 313 314 if (error) 315 return dev_err_probe(dev, error, "Failed to query\n"); 316 317 error = devm_request_threaded_irq(dev, wacom_data->irq, NULL, wacom_w9000_interrupt, 318 IRQF_ONESHOT | IRQF_NO_AUTOEN, client->name, wacom_data); 319 if (error) 320 return dev_err_probe(dev, error, "Failed to register interrupt\n"); 321 322 input_dev = devm_input_allocate_device(dev); 323 if (!input_dev) 324 return -ENOMEM; 325 326 wacom_data->input_dev = input_dev; 327 input_set_drvdata(input_dev, wacom_data); 328 329 input_dev->name = wacom_data->variant->name; 330 input_dev->id.bustype = BUS_I2C; 331 input_dev->id.vendor = 0x56a; 332 input_dev->id.version = wacom_data->fw_version; 333 input_dev->open = wacom_w9000_open; 334 input_dev->close = wacom_w9000_close; 335 336 input_set_capability(input_dev, EV_KEY, BTN_TOUCH); 337 input_set_capability(input_dev, EV_KEY, BTN_TOOL_PEN); 338 input_set_capability(input_dev, EV_KEY, BTN_TOOL_RUBBER); 339 input_set_capability(input_dev, EV_KEY, BTN_STYLUS); 340 341 input_set_abs_params(input_dev, ABS_X, 0, wacom_data->prop.max_x, 4, 0); 342 input_set_abs_params(input_dev, ABS_Y, 0, wacom_data->prop.max_y, 4, 0); 343 input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_data->max_pressure, 0, 0); 344 345 if (wacom_data->variant->msg_coord_num > 7) 346 input_set_abs_params(input_dev, ABS_DISTANCE, 0, 255, 0, 0); 347 348 touchscreen_parse_properties(input_dev, false, &wacom_data->prop); 349 350 dev_info(dev, "%s size X%uY%u\n", wacom_data->variant->name, 351 wacom_data->prop.max_x, wacom_data->prop.max_y); 352 353 error = device_property_read_u32(dev, "touchscreen-x-mm", &val); 354 if (!error && val) 355 input_abs_set_res(input_dev, wacom_data->prop.swap_x_y ? ABS_Y : ABS_X, 356 wacom_data->prop.max_x / val); 357 error = device_property_read_u32(dev, "touchscreen-y-mm", &val); 358 if (!error && val) 359 input_abs_set_res(input_dev, wacom_data->prop.swap_x_y ? ABS_X : ABS_Y, 360 wacom_data->prop.max_y / val); 361 362 error = input_register_device(wacom_data->input_dev); 363 if (error) 364 return dev_err_probe(dev, error, "Failed to register input device\n"); 365 366 return 0; 367 } 368 369 static int wacom_w9000_suspend(struct device *dev) 370 { 371 struct i2c_client *client = to_i2c_client(dev); 372 struct wacom_w9000_data *wacom_data = i2c_get_clientdata(client); 373 374 guard(mutex)(&wacom_data->input_dev->mutex); 375 376 if (input_device_enabled(wacom_data->input_dev)) 377 return wacom_w9000_power_off(wacom_data); 378 379 return 0; 380 } 381 382 static int wacom_w9000_resume(struct device *dev) 383 { 384 struct i2c_client *client = to_i2c_client(dev); 385 struct wacom_w9000_data *wacom_data = i2c_get_clientdata(client); 386 387 guard(mutex)(&wacom_data->input_dev->mutex); 388 389 if (input_device_enabled(wacom_data->input_dev)) 390 return wacom_w9000_power_on(wacom_data); 391 392 return 0; 393 } 394 395 static DEFINE_SIMPLE_DEV_PM_OPS(wacom_w9000_pm, wacom_w9000_suspend, wacom_w9000_resume); 396 397 static const struct wacom_w9000_variant w9002 = { 398 .cmd_query_num = 9, 399 .msg_coord_num = 7, 400 .name = "Wacom W9002 Digitizer", 401 }; 402 403 static const struct wacom_w9000_variant w9007a_lt03 = { 404 .cmd_query_num = 9, 405 .msg_coord_num = 8, 406 .name = "Wacom W9007A LT03 Digitizer", 407 }; 408 409 static const struct wacom_w9000_variant w9007a_v1 = { 410 .cmd_query_num = 9, 411 .msg_coord_num = 12, 412 .name = "Wacom W9007A V1 Digitizer", 413 }; 414 415 static const struct of_device_id wacom_w9000_of_match[] = { 416 { .compatible = "wacom,w9002", .data = &w9002 }, 417 { .compatible = "wacom,w9007a-lt03", .data = &w9007a_lt03, }, 418 { .compatible = "wacom,w9007a-v1", .data = &w9007a_v1, }, 419 { } 420 }; 421 MODULE_DEVICE_TABLE(of, wacom_w9000_of_match); 422 423 static const struct i2c_device_id wacom_w9000_id[] = { 424 { .name = "w9002", .driver_data = (kernel_ulong_t)&w9002 }, 425 { .name = "w9007a-lt03", .driver_data = (kernel_ulong_t)&w9007a_lt03 }, 426 { .name = "w9007a-v1", .driver_data = (kernel_ulong_t)&w9007a_v1 }, 427 { } 428 }; 429 MODULE_DEVICE_TABLE(i2c, wacom_w9000_id); 430 431 static struct i2c_driver wacom_w9000_driver = { 432 .driver = { 433 .name = "wacom_w9000", 434 .of_match_table = wacom_w9000_of_match, 435 .pm = pm_sleep_ptr(&wacom_w9000_pm), 436 }, 437 .probe = wacom_w9000_probe, 438 .id_table = wacom_w9000_id, 439 }; 440 module_i2c_driver(wacom_w9000_driver); 441 442 MODULE_AUTHOR("Hendrik Noack <hendrik-noack@gmx.de>"); 443 MODULE_DESCRIPTION("Wacom W9000-series penabled touchscreen driver"); 444 MODULE_LICENSE("GPL"); 445