1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2025, Sebastian Reichel 4 */ 5 6 #include <linux/bitfield.h> 7 #include <linux/bits.h> 8 #include <linux/cleanup.h> 9 #include <linux/container_of.h> 10 #include <linux/device.h> 11 #include <linux/delay.h> 12 #include <linux/dev_printk.h> 13 #include <linux/err.h> 14 #include <linux/i2c.h> 15 #include <linux/input.h> 16 #include <linux/input/sparse-keymap.h> 17 #include <linux/interrupt.h> 18 #include <linux/leds.h> 19 #include <linux/lockdep.h> 20 #include <linux/module.h> 21 #include <linux/regmap.h> 22 #include <linux/slab.h> 23 24 #define T14S_EC_CMD_ECRD 0x02 25 #define T14S_EC_CMD_ECWR 0x03 26 #define T14S_EC_CMD_EVT 0xf0 27 28 #define T14S_EC_REG_LED 0x0c 29 #define T14S_EC_REG_KBD_BL1 0x0d 30 #define T14S_EC_REG_KBD_BL2 0xe1 31 #define T14S_EC_KBD_BL1_MASK GENMASK_U8(7, 6) 32 #define T14S_EC_KBD_BL2_MASK GENMASK_U8(3, 2) 33 #define T14S_EC_REG_AUD 0x30 34 #define T14S_EC_MIC_MUTE_LED BIT(5) 35 #define T14S_EC_SPK_MUTE_LED BIT(6) 36 37 #define T14S_EC_EVT_NONE 0x00 38 #define T14S_EC_EVT_KEY_FN_4 0x13 39 #define T14S_EC_EVT_KEY_FN_F7 0x16 40 #define T14S_EC_EVT_KEY_FN_SPACE 0x1f 41 #define T14S_EC_EVT_KEY_TP_DOUBLE_TAP 0x20 42 #define T14S_EC_EVT_AC_CONNECTED 0x26 43 #define T14S_EC_EVT_AC_DISCONNECTED 0x27 44 #define T14S_EC_EVT_KEY_POWER 0x28 45 #define T14S_EC_EVT_LID_OPEN 0x2a 46 #define T14S_EC_EVT_LID_CLOSED 0x2b 47 #define T14S_EC_EVT_THERMAL_TZ40 0x5c 48 #define T14S_EC_EVT_THERMAL_TZ42 0x5d 49 #define T14S_EC_EVT_THERMAL_TZ39 0x5e 50 #define T14S_EC_EVT_KEY_FN_F12 0x62 51 #define T14S_EC_EVT_KEY_FN_TAB 0x63 52 #define T14S_EC_EVT_KEY_FN_F8 0x64 53 #define T14S_EC_EVT_KEY_FN_F10 0x65 54 #define T14S_EC_EVT_KEY_FN_F4 0x6a 55 #define T14S_EC_EVT_KEY_FN_D 0x6b 56 #define T14S_EC_EVT_KEY_FN_T 0x6c 57 #define T14S_EC_EVT_KEY_FN_H 0x6d 58 #define T14S_EC_EVT_KEY_FN_M 0x6e 59 #define T14S_EC_EVT_KEY_FN_L 0x6f 60 #define T14S_EC_EVT_KEY_FN_RIGHT_SHIFT 0x71 61 #define T14S_EC_EVT_KEY_FN_ESC 0x74 62 #define T14S_EC_EVT_KEY_FN_N 0x79 63 #define T14S_EC_EVT_KEY_FN_F11 0x7a 64 #define T14S_EC_EVT_KEY_FN_G 0x7e 65 66 /* Hardware LED blink rate is 1 Hz (500ms off, 500ms on) */ 67 #define T14S_EC_BLINK_RATE_ON_OFF_MS 500 68 69 /* 70 * Add a virtual offset on all key event codes for sparse keymap handling, 71 * since the sparse keymap infrastructure does not map some raw key event 72 * codes used by the EC. For example 0x16 (T14S_EC_EVT_KEY_FN_F7) is mapped 73 * to KEY_MUTE if no offset is applied. 74 */ 75 #define T14S_EC_KEY_EVT_OFFSET 0x1000 76 #define T14S_EC_KEY_ENTRY(key, value) \ 77 { KE_KEY, T14S_EC_KEY_EVT_OFFSET + T14S_EC_EVT_KEY_##key, { value } } 78 79 enum t14s_ec_led_status_t { 80 T14S_EC_LED_OFF = 0x00, 81 T14S_EC_LED_ON = 0x80, 82 T14S_EC_LED_BLINK = 0xc0, 83 }; 84 85 struct t14s_ec_led_classdev { 86 struct led_classdev led_classdev; 87 int led; 88 enum t14s_ec_led_status_t cache; 89 struct t14s_ec *ec; 90 }; 91 92 struct t14s_ec { 93 struct regmap *regmap; 94 struct device *dev; 95 struct t14s_ec_led_classdev led_pwr_btn; 96 struct t14s_ec_led_classdev led_chrg_orange; 97 struct t14s_ec_led_classdev led_chrg_white; 98 struct t14s_ec_led_classdev led_lid_logo_dot; 99 struct led_classdev kbd_backlight; 100 struct led_classdev led_mic_mute; 101 struct led_classdev led_spk_mute; 102 struct input_dev *inputdev; 103 }; 104 105 static const struct regmap_config t14s_ec_regmap_config = { 106 .reg_bits = 8, 107 .val_bits = 8, 108 .max_register = 0xff, 109 }; 110 111 static int t14s_ec_write(void *context, unsigned int reg, 112 unsigned int val) 113 { 114 struct t14s_ec *ec = context; 115 struct i2c_client *client = to_i2c_client(ec->dev); 116 u8 buf[5] = {T14S_EC_CMD_ECWR, reg, 0x00, 0x01, val}; 117 int ret; 118 119 ret = i2c_master_send(client, buf, sizeof(buf)); 120 if (ret < 0) 121 return ret; 122 123 fsleep(10000); 124 return 0; 125 } 126 127 static int t14s_ec_read(void *context, unsigned int reg, 128 unsigned int *val) 129 { 130 struct t14s_ec *ec = context; 131 struct i2c_client *client = to_i2c_client(ec->dev); 132 u8 buf[4] = {T14S_EC_CMD_ECRD, reg, 0x00, 0x01}; 133 struct i2c_msg request, response; 134 u8 result; 135 int ret; 136 137 request.addr = client->addr; 138 request.flags = I2C_M_STOP; 139 request.len = sizeof(buf); 140 request.buf = buf; 141 response.addr = client->addr; 142 response.flags = I2C_M_RD; 143 response.len = 1; 144 response.buf = &result; 145 146 i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT); 147 148 ret = __i2c_transfer(client->adapter, &request, 1); 149 if (ret < 0) 150 goto out; 151 152 ret = __i2c_transfer(client->adapter, &response, 1); 153 if (ret < 0) 154 goto out; 155 156 *val = result; 157 ret = 0; 158 159 out: 160 i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT); 161 fsleep(10000); 162 return ret; 163 } 164 165 static const struct regmap_bus t14s_ec_regmap_bus = { 166 .reg_write = t14s_ec_write, 167 .reg_read = t14s_ec_read, 168 }; 169 170 static int t14s_ec_read_evt(struct t14s_ec *ec, u8 *val) 171 { 172 struct i2c_client *client = to_i2c_client(ec->dev); 173 u8 buf[4] = {T14S_EC_CMD_EVT, 0x00, 0x00, 0x01}; 174 struct i2c_msg request, response; 175 int ret; 176 177 request.addr = client->addr; 178 request.flags = I2C_M_STOP; 179 request.len = sizeof(buf); 180 request.buf = buf; 181 response.addr = client->addr; 182 response.flags = I2C_M_RD; 183 response.len = 1; 184 response.buf = val; 185 186 i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT); 187 188 ret = __i2c_transfer(client->adapter, &request, 1); 189 if (ret < 0) 190 goto out; 191 192 ret = __i2c_transfer(client->adapter, &response, 1); 193 if (ret < 0) 194 goto out; 195 196 fsleep(10000); 197 198 ret = 0; 199 200 out: 201 i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT); 202 return ret; 203 } 204 205 static int t14s_led_set_status(struct t14s_ec *ec, 206 struct t14s_ec_led_classdev *led, 207 const enum t14s_ec_led_status_t ledstatus) 208 { 209 int ret; 210 211 ret = regmap_write(ec->regmap, T14S_EC_REG_LED, 212 led->led | ledstatus); 213 if (ret < 0) 214 return ret; 215 216 led->cache = ledstatus; 217 return 0; 218 } 219 220 static int t14s_led_brightness_set(struct led_classdev *led_cdev, 221 enum led_brightness brightness) 222 { 223 struct t14s_ec_led_classdev *led = container_of(led_cdev, 224 struct t14s_ec_led_classdev, led_classdev); 225 enum t14s_ec_led_status_t new_state; 226 227 if (brightness == LED_OFF) 228 new_state = T14S_EC_LED_OFF; 229 else if (led->cache == T14S_EC_LED_BLINK) 230 new_state = T14S_EC_LED_BLINK; 231 else 232 new_state = T14S_EC_LED_ON; 233 234 return t14s_led_set_status(led->ec, led, new_state); 235 } 236 237 static int t14s_led_blink_set(struct led_classdev *led_cdev, 238 unsigned long *delay_on, 239 unsigned long *delay_off) 240 { 241 struct t14s_ec_led_classdev *led = container_of(led_cdev, 242 struct t14s_ec_led_classdev, led_classdev); 243 244 if (*delay_on == 0 && *delay_off == 0) { 245 /* Userspace does not provide a blink rate; we can choose it */ 246 *delay_on = T14S_EC_BLINK_RATE_ON_OFF_MS; 247 *delay_off = T14S_EC_BLINK_RATE_ON_OFF_MS; 248 } else if ((*delay_on != T14S_EC_BLINK_RATE_ON_OFF_MS) || 249 (*delay_off != T14S_EC_BLINK_RATE_ON_OFF_MS)) 250 return -EINVAL; 251 252 return t14s_led_set_status(led->ec, led, T14S_EC_LED_BLINK); 253 } 254 255 static int t14s_init_led(struct t14s_ec *ec, struct t14s_ec_led_classdev *led, 256 u8 id, const char *name) 257 { 258 led->led_classdev.name = name; 259 led->led_classdev.flags = LED_RETAIN_AT_SHUTDOWN; 260 led->led_classdev.max_brightness = 1; 261 led->led_classdev.brightness_set_blocking = t14s_led_brightness_set; 262 led->led_classdev.blink_set = t14s_led_blink_set; 263 led->ec = ec; 264 led->led = id; 265 266 return devm_led_classdev_register(ec->dev, &led->led_classdev); 267 } 268 269 static int t14s_leds_probe(struct t14s_ec *ec) 270 { 271 int ret; 272 273 ret = t14s_init_led(ec, &ec->led_pwr_btn, 0, "platform::power"); 274 if (ret) 275 return ret; 276 277 ret = t14s_init_led(ec, &ec->led_chrg_orange, 1, 278 "platform:amber:battery-charging"); 279 if (ret) 280 return ret; 281 282 ret = t14s_init_led(ec, &ec->led_chrg_white, 2, 283 "platform:white:battery-full"); 284 if (ret) 285 return ret; 286 287 ret = t14s_init_led(ec, &ec->led_lid_logo_dot, 10, 288 "platform::lid_logo_dot"); 289 if (ret) 290 return ret; 291 292 return 0; 293 } 294 295 static int t14s_kbd_bl_set(struct led_classdev *led_cdev, 296 enum led_brightness brightness) 297 { 298 struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec, 299 kbd_backlight); 300 int ret; 301 u8 val; 302 303 val = FIELD_PREP(T14S_EC_KBD_BL1_MASK, brightness); 304 ret = regmap_update_bits(ec->regmap, T14S_EC_REG_KBD_BL1, 305 T14S_EC_KBD_BL1_MASK, val); 306 if (ret < 0) 307 return ret; 308 309 val = FIELD_PREP(T14S_EC_KBD_BL2_MASK, brightness); 310 ret = regmap_update_bits(ec->regmap, T14S_EC_REG_KBD_BL2, 311 T14S_EC_KBD_BL2_MASK, val); 312 if (ret < 0) 313 return ret; 314 315 return 0; 316 } 317 318 static enum led_brightness t14s_kbd_bl_get(struct led_classdev *led_cdev) 319 { 320 struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec, 321 kbd_backlight); 322 unsigned int val; 323 int ret; 324 325 ret = regmap_read(ec->regmap, T14S_EC_REG_KBD_BL1, &val); 326 if (ret < 0) 327 return ret; 328 329 return FIELD_GET(T14S_EC_KBD_BL1_MASK, val); 330 } 331 332 static void t14s_kbd_bl_update(struct t14s_ec *ec) 333 { 334 enum led_brightness brightness = t14s_kbd_bl_get(&ec->kbd_backlight); 335 336 led_classdev_notify_brightness_hw_changed(&ec->kbd_backlight, brightness); 337 } 338 339 static int t14s_kbd_backlight_probe(struct t14s_ec *ec) 340 { 341 ec->kbd_backlight.name = "platform::kbd_backlight"; 342 ec->kbd_backlight.flags = LED_BRIGHT_HW_CHANGED; 343 ec->kbd_backlight.max_brightness = 2; 344 ec->kbd_backlight.brightness_set_blocking = t14s_kbd_bl_set; 345 ec->kbd_backlight.brightness_get = t14s_kbd_bl_get; 346 347 return devm_led_classdev_register(ec->dev, &ec->kbd_backlight); 348 } 349 350 static enum led_brightness t14s_audio_led_get(struct t14s_ec *ec, u8 led_bit) 351 { 352 unsigned int val; 353 int ret; 354 355 ret = regmap_read(ec->regmap, T14S_EC_REG_AUD, &val); 356 if (ret < 0) 357 return ret; 358 359 return !!(val & led_bit) ? LED_ON : LED_OFF; 360 } 361 362 static enum led_brightness t14s_audio_led_set(struct t14s_ec *ec, 363 u8 led_mask, 364 enum led_brightness brightness) 365 { 366 return regmap_assign_bits(ec->regmap, T14S_EC_REG_AUD, led_mask, brightness > 0); 367 } 368 369 static enum led_brightness t14s_mic_mute_led_get(struct led_classdev *led_cdev) 370 { 371 struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec, 372 led_mic_mute); 373 374 return t14s_audio_led_get(ec, T14S_EC_MIC_MUTE_LED); 375 } 376 377 static int t14s_mic_mute_led_set(struct led_classdev *led_cdev, 378 enum led_brightness brightness) 379 { 380 struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec, 381 led_mic_mute); 382 383 return t14s_audio_led_set(ec, T14S_EC_MIC_MUTE_LED, brightness); 384 } 385 386 static enum led_brightness t14s_spk_mute_led_get(struct led_classdev *led_cdev) 387 { 388 struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec, 389 led_spk_mute); 390 391 return t14s_audio_led_get(ec, T14S_EC_SPK_MUTE_LED); 392 } 393 394 static int t14s_spk_mute_led_set(struct led_classdev *led_cdev, 395 enum led_brightness brightness) 396 { 397 struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec, 398 led_spk_mute); 399 400 return t14s_audio_led_set(ec, T14S_EC_SPK_MUTE_LED, brightness); 401 } 402 403 static int t14s_kbd_audio_led_probe(struct t14s_ec *ec) 404 { 405 int ret; 406 407 ec->led_mic_mute.name = "platform::micmute"; 408 ec->led_mic_mute.max_brightness = 1; 409 ec->led_mic_mute.default_trigger = "audio-micmute"; 410 ec->led_mic_mute.brightness_set_blocking = t14s_mic_mute_led_set; 411 ec->led_mic_mute.brightness_get = t14s_mic_mute_led_get; 412 413 ec->led_spk_mute.name = "platform::mute"; 414 ec->led_spk_mute.max_brightness = 1; 415 ec->led_spk_mute.default_trigger = "audio-mute"; 416 ec->led_spk_mute.brightness_set_blocking = t14s_spk_mute_led_set; 417 ec->led_spk_mute.brightness_get = t14s_spk_mute_led_get; 418 419 ret = devm_led_classdev_register(ec->dev, &ec->led_mic_mute); 420 if (ret) 421 return ret; 422 423 return devm_led_classdev_register(ec->dev, &ec->led_spk_mute); 424 } 425 426 static const struct key_entry t14s_keymap[] = { 427 T14S_EC_KEY_ENTRY(FN_4, KEY_SLEEP), 428 T14S_EC_KEY_ENTRY(FN_N, KEY_VENDOR), 429 T14S_EC_KEY_ENTRY(FN_F4, KEY_MICMUTE), 430 T14S_EC_KEY_ENTRY(FN_F7, KEY_SWITCHVIDEOMODE), 431 T14S_EC_KEY_ENTRY(FN_F8, KEY_PERFORMANCE), 432 T14S_EC_KEY_ENTRY(FN_F10, KEY_SELECTIVE_SCREENSHOT), 433 T14S_EC_KEY_ENTRY(FN_F11, KEY_LINK_PHONE), 434 T14S_EC_KEY_ENTRY(FN_F12, KEY_BOOKMARKS), 435 T14S_EC_KEY_ENTRY(FN_SPACE, KEY_KBDILLUMTOGGLE), 436 T14S_EC_KEY_ENTRY(FN_ESC, KEY_FN_ESC), 437 T14S_EC_KEY_ENTRY(FN_TAB, KEY_ZOOM), 438 T14S_EC_KEY_ENTRY(FN_RIGHT_SHIFT, KEY_FN_RIGHT_SHIFT), 439 T14S_EC_KEY_ENTRY(TP_DOUBLE_TAP, KEY_PROG4), 440 { KE_END } 441 }; 442 443 static int t14s_input_probe(struct t14s_ec *ec) 444 { 445 int ret; 446 447 ec->inputdev = devm_input_allocate_device(ec->dev); 448 if (!ec->inputdev) 449 return -ENOMEM; 450 451 ec->inputdev->name = "ThinkPad Extra Buttons"; 452 ec->inputdev->phys = "thinkpad/input0"; 453 ec->inputdev->id.bustype = BUS_HOST; 454 ec->inputdev->dev.parent = ec->dev; 455 456 ret = sparse_keymap_setup(ec->inputdev, t14s_keymap, NULL); 457 if (ret) 458 return ret; 459 460 return input_register_device(ec->inputdev); 461 } 462 463 static irqreturn_t t14s_ec_irq_handler(int irq, void *data) 464 { 465 struct t14s_ec *ec = data; 466 int ret; 467 u8 val; 468 469 ret = t14s_ec_read_evt(ec, &val); 470 if (ret < 0) { 471 dev_err(ec->dev, "Failed to read event\n"); 472 return IRQ_HANDLED; 473 } 474 475 switch (val) { 476 case T14S_EC_EVT_NONE: 477 break; 478 case T14S_EC_EVT_KEY_FN_SPACE: 479 t14s_kbd_bl_update(ec); 480 fallthrough; 481 case T14S_EC_EVT_KEY_FN_F4: 482 case T14S_EC_EVT_KEY_FN_F7: 483 case T14S_EC_EVT_KEY_FN_4: 484 case T14S_EC_EVT_KEY_FN_F8: 485 case T14S_EC_EVT_KEY_FN_F12: 486 case T14S_EC_EVT_KEY_FN_TAB: 487 case T14S_EC_EVT_KEY_FN_F10: 488 case T14S_EC_EVT_KEY_FN_N: 489 case T14S_EC_EVT_KEY_FN_F11: 490 case T14S_EC_EVT_KEY_FN_ESC: 491 case T14S_EC_EVT_KEY_FN_RIGHT_SHIFT: 492 case T14S_EC_EVT_KEY_TP_DOUBLE_TAP: 493 sparse_keymap_report_event(ec->inputdev, 494 T14S_EC_KEY_EVT_OFFSET + val, 1, true); 495 break; 496 case T14S_EC_EVT_AC_CONNECTED: 497 dev_dbg(ec->dev, "AC connected\n"); 498 break; 499 case T14S_EC_EVT_AC_DISCONNECTED: 500 dev_dbg(ec->dev, "AC disconnected\n"); 501 break; 502 case T14S_EC_EVT_KEY_POWER: 503 dev_dbg(ec->dev, "power button\n"); 504 break; 505 case T14S_EC_EVT_LID_OPEN: 506 dev_dbg(ec->dev, "LID open\n"); 507 break; 508 case T14S_EC_EVT_LID_CLOSED: 509 dev_dbg(ec->dev, "LID closed\n"); 510 break; 511 case T14S_EC_EVT_THERMAL_TZ40: 512 dev_dbg(ec->dev, "Thermal Zone 40 Status Change Event (CPU/GPU)\n"); 513 break; 514 case T14S_EC_EVT_THERMAL_TZ42: 515 dev_dbg(ec->dev, "Thermal Zone 42 Status Change Event (Battery)\n"); 516 break; 517 case T14S_EC_EVT_THERMAL_TZ39: 518 dev_dbg(ec->dev, "Thermal Zone 39 Status Change Event (CPU/GPU)\n"); 519 break; 520 case T14S_EC_EVT_KEY_FN_G: 521 dev_dbg(ec->dev, "FN + G - toggle double-tapping\n"); 522 break; 523 case T14S_EC_EVT_KEY_FN_L: 524 dev_dbg(ec->dev, "FN + L - low performance mode\n"); 525 break; 526 case T14S_EC_EVT_KEY_FN_M: 527 dev_dbg(ec->dev, "FN + M - medium performance mode\n"); 528 break; 529 case T14S_EC_EVT_KEY_FN_H: 530 dev_dbg(ec->dev, "FN + H - high performance mode\n"); 531 break; 532 case T14S_EC_EVT_KEY_FN_T: 533 dev_dbg(ec->dev, "FN + T - toggle intelligent cooling mode\n"); 534 break; 535 case T14S_EC_EVT_KEY_FN_D: 536 dev_dbg(ec->dev, "FN + D - toggle privacy guard mode\n"); 537 break; 538 default: 539 dev_info(ec->dev, "Unknown EC event: 0x%02x\n", val); 540 break; 541 } 542 543 return IRQ_HANDLED; 544 } 545 546 static int t14s_ec_probe(struct i2c_client *client) 547 { 548 struct device *dev = &client->dev; 549 struct t14s_ec *ec; 550 int ret; 551 552 ec = devm_kzalloc(dev, sizeof(*ec), GFP_KERNEL); 553 if (!ec) 554 return -ENOMEM; 555 556 ec->dev = dev; 557 558 ec->regmap = devm_regmap_init(dev, &t14s_ec_regmap_bus, 559 ec, &t14s_ec_regmap_config); 560 if (IS_ERR(ec->regmap)) 561 return dev_err_probe(dev, PTR_ERR(ec->regmap), 562 "Failed to init regmap\n"); 563 564 ret = t14s_leds_probe(ec); 565 if (ret < 0) 566 return ret; 567 568 ret = t14s_kbd_backlight_probe(ec); 569 if (ret < 0) 570 return ret; 571 572 ret = t14s_kbd_audio_led_probe(ec); 573 if (ret < 0) 574 return ret; 575 576 ret = t14s_input_probe(ec); 577 if (ret < 0) 578 return ret; 579 580 ret = devm_request_threaded_irq(dev, client->irq, NULL, 581 t14s_ec_irq_handler, 582 IRQF_ONESHOT, dev_name(dev), ec); 583 if (ret < 0) 584 return dev_err_probe(dev, ret, "Failed to get IRQ\n"); 585 586 /* 587 * Disable wakeup support by default, because the driver currently does 588 * not support masking any events and the laptop should not wake up when 589 * the LID is closed. 590 */ 591 device_wakeup_disable(dev); 592 593 return 0; 594 } 595 596 static const struct of_device_id t14s_ec_of_match[] = { 597 { .compatible = "lenovo,thinkpad-t14s-ec" }, 598 {} 599 }; 600 MODULE_DEVICE_TABLE(of, t14s_ec_of_match); 601 602 static const struct i2c_device_id t14s_ec_i2c_id_table[] = { 603 { "thinkpad-t14s-ec", }, 604 {} 605 }; 606 MODULE_DEVICE_TABLE(i2c, t14s_ec_i2c_id_table); 607 608 static struct i2c_driver t14s_ec_i2c_driver = { 609 .driver = { 610 .name = "thinkpad-t14s-ec", 611 .of_match_table = t14s_ec_of_match, 612 }, 613 .probe = t14s_ec_probe, 614 .id_table = t14s_ec_i2c_id_table, 615 }; 616 module_i2c_driver(t14s_ec_i2c_driver); 617 618 MODULE_AUTHOR("Sebastian Reichel <sre@kernel.org>"); 619 MODULE_DESCRIPTION("Lenovo Thinkpad T14s Embedded Controller"); 620 MODULE_LICENSE("GPL"); 621