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 return 0; 124 } 125 126 static int t14s_ec_read(void *context, unsigned int reg, 127 unsigned int *val) 128 { 129 struct t14s_ec *ec = context; 130 struct i2c_client *client = to_i2c_client(ec->dev); 131 u8 buf[4] = {T14S_EC_CMD_ECRD, reg, 0x00, 0x01}; 132 struct i2c_msg request, response; 133 u8 result; 134 int ret; 135 136 request.addr = client->addr; 137 request.flags = I2C_M_STOP; 138 request.len = sizeof(buf); 139 request.buf = buf; 140 response.addr = client->addr; 141 response.flags = I2C_M_RD; 142 response.len = 1; 143 response.buf = &result; 144 145 i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT); 146 147 ret = __i2c_transfer(client->adapter, &request, 1); 148 if (ret < 0) 149 goto out; 150 151 ret = __i2c_transfer(client->adapter, &response, 1); 152 if (ret < 0) 153 goto out; 154 155 *val = result; 156 ret = 0; 157 158 out: 159 i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT); 160 return ret; 161 } 162 163 static const struct regmap_bus t14s_ec_regmap_bus = { 164 .reg_write = t14s_ec_write, 165 .reg_read = t14s_ec_read, 166 }; 167 168 static int t14s_ec_read_evt(struct t14s_ec *ec, u8 *val) 169 { 170 struct i2c_client *client = to_i2c_client(ec->dev); 171 u8 buf[4] = {T14S_EC_CMD_EVT, 0x00, 0x00, 0x01}; 172 struct i2c_msg request, response; 173 int ret; 174 175 request.addr = client->addr; 176 request.flags = I2C_M_STOP; 177 request.len = sizeof(buf); 178 request.buf = buf; 179 response.addr = client->addr; 180 response.flags = I2C_M_RD; 181 response.len = 1; 182 response.buf = val; 183 184 i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT); 185 186 ret = __i2c_transfer(client->adapter, &request, 1); 187 if (ret < 0) 188 goto out; 189 190 ret = __i2c_transfer(client->adapter, &response, 1); 191 if (ret < 0) 192 goto out; 193 194 ret = 0; 195 196 out: 197 i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT); 198 return ret; 199 } 200 201 static int t14s_led_set_status(struct t14s_ec *ec, 202 struct t14s_ec_led_classdev *led, 203 const enum t14s_ec_led_status_t ledstatus) 204 { 205 int ret; 206 207 ret = regmap_write(ec->regmap, T14S_EC_REG_LED, 208 led->led | ledstatus); 209 if (ret < 0) 210 return ret; 211 212 led->cache = ledstatus; 213 return 0; 214 } 215 216 static int t14s_led_brightness_set(struct led_classdev *led_cdev, 217 enum led_brightness brightness) 218 { 219 struct t14s_ec_led_classdev *led = container_of(led_cdev, 220 struct t14s_ec_led_classdev, led_classdev); 221 enum t14s_ec_led_status_t new_state; 222 223 if (brightness == LED_OFF) 224 new_state = T14S_EC_LED_OFF; 225 else if (led->cache == T14S_EC_LED_BLINK) 226 new_state = T14S_EC_LED_BLINK; 227 else 228 new_state = T14S_EC_LED_ON; 229 230 return t14s_led_set_status(led->ec, led, new_state); 231 } 232 233 static int t14s_led_blink_set(struct led_classdev *led_cdev, 234 unsigned long *delay_on, 235 unsigned long *delay_off) 236 { 237 struct t14s_ec_led_classdev *led = container_of(led_cdev, 238 struct t14s_ec_led_classdev, led_classdev); 239 240 if (*delay_on == 0 && *delay_off == 0) { 241 /* Userspace does not provide a blink rate; we can choose it */ 242 *delay_on = T14S_EC_BLINK_RATE_ON_OFF_MS; 243 *delay_off = T14S_EC_BLINK_RATE_ON_OFF_MS; 244 } else if ((*delay_on != T14S_EC_BLINK_RATE_ON_OFF_MS) || 245 (*delay_off != T14S_EC_BLINK_RATE_ON_OFF_MS)) 246 return -EINVAL; 247 248 return t14s_led_set_status(led->ec, led, T14S_EC_LED_BLINK); 249 } 250 251 static int t14s_init_led(struct t14s_ec *ec, struct t14s_ec_led_classdev *led, 252 u8 id, const char *name) 253 { 254 led->led_classdev.name = name; 255 led->led_classdev.flags = LED_RETAIN_AT_SHUTDOWN; 256 led->led_classdev.max_brightness = 1; 257 led->led_classdev.brightness_set_blocking = t14s_led_brightness_set; 258 led->led_classdev.blink_set = t14s_led_blink_set; 259 led->ec = ec; 260 led->led = id; 261 262 return devm_led_classdev_register(ec->dev, &led->led_classdev); 263 } 264 265 static int t14s_leds_probe(struct t14s_ec *ec) 266 { 267 int ret; 268 269 ret = t14s_init_led(ec, &ec->led_pwr_btn, 0, "platform::power"); 270 if (ret) 271 return ret; 272 273 ret = t14s_init_led(ec, &ec->led_chrg_orange, 1, 274 "platform:amber:battery-charging"); 275 if (ret) 276 return ret; 277 278 ret = t14s_init_led(ec, &ec->led_chrg_white, 2, 279 "platform:white:battery-full"); 280 if (ret) 281 return ret; 282 283 ret = t14s_init_led(ec, &ec->led_lid_logo_dot, 10, 284 "platform::lid_logo_dot"); 285 if (ret) 286 return ret; 287 288 return 0; 289 } 290 291 static int t14s_kbd_bl_set(struct led_classdev *led_cdev, 292 enum led_brightness brightness) 293 { 294 struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec, 295 kbd_backlight); 296 int ret; 297 u8 val; 298 299 val = FIELD_PREP(T14S_EC_KBD_BL1_MASK, brightness); 300 ret = regmap_update_bits(ec->regmap, T14S_EC_REG_KBD_BL1, 301 T14S_EC_KBD_BL1_MASK, val); 302 if (ret < 0) 303 return ret; 304 305 val = FIELD_PREP(T14S_EC_KBD_BL2_MASK, brightness); 306 ret = regmap_update_bits(ec->regmap, T14S_EC_REG_KBD_BL2, 307 T14S_EC_KBD_BL2_MASK, val); 308 if (ret < 0) 309 return ret; 310 311 return 0; 312 } 313 314 static enum led_brightness t14s_kbd_bl_get(struct led_classdev *led_cdev) 315 { 316 struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec, 317 kbd_backlight); 318 unsigned int val; 319 int ret; 320 321 ret = regmap_read(ec->regmap, T14S_EC_REG_KBD_BL1, &val); 322 if (ret < 0) 323 return ret; 324 325 return FIELD_GET(T14S_EC_KBD_BL1_MASK, val); 326 } 327 328 static void t14s_kbd_bl_update(struct t14s_ec *ec) 329 { 330 enum led_brightness brightness = t14s_kbd_bl_get(&ec->kbd_backlight); 331 332 led_classdev_notify_brightness_hw_changed(&ec->kbd_backlight, brightness); 333 } 334 335 static int t14s_kbd_backlight_probe(struct t14s_ec *ec) 336 { 337 ec->kbd_backlight.name = "platform::kbd_backlight"; 338 ec->kbd_backlight.flags = LED_BRIGHT_HW_CHANGED; 339 ec->kbd_backlight.max_brightness = 2; 340 ec->kbd_backlight.brightness_set_blocking = t14s_kbd_bl_set; 341 ec->kbd_backlight.brightness_get = t14s_kbd_bl_get; 342 343 return devm_led_classdev_register(ec->dev, &ec->kbd_backlight); 344 } 345 346 static enum led_brightness t14s_audio_led_get(struct t14s_ec *ec, u8 led_bit) 347 { 348 unsigned int val; 349 int ret; 350 351 ret = regmap_read(ec->regmap, T14S_EC_REG_AUD, &val); 352 if (ret < 0) 353 return ret; 354 355 return !!(val & led_bit) ? LED_ON : LED_OFF; 356 } 357 358 static enum led_brightness t14s_audio_led_set(struct t14s_ec *ec, 359 u8 led_mask, 360 enum led_brightness brightness) 361 { 362 return regmap_assign_bits(ec->regmap, T14S_EC_REG_AUD, led_mask, brightness > 0); 363 } 364 365 static enum led_brightness t14s_mic_mute_led_get(struct led_classdev *led_cdev) 366 { 367 struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec, 368 led_mic_mute); 369 370 return t14s_audio_led_get(ec, T14S_EC_MIC_MUTE_LED); 371 } 372 373 static int t14s_mic_mute_led_set(struct led_classdev *led_cdev, 374 enum led_brightness brightness) 375 { 376 struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec, 377 led_mic_mute); 378 379 return t14s_audio_led_set(ec, T14S_EC_MIC_MUTE_LED, brightness); 380 } 381 382 static enum led_brightness t14s_spk_mute_led_get(struct led_classdev *led_cdev) 383 { 384 struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec, 385 led_spk_mute); 386 387 return t14s_audio_led_get(ec, T14S_EC_SPK_MUTE_LED); 388 } 389 390 static int t14s_spk_mute_led_set(struct led_classdev *led_cdev, 391 enum led_brightness brightness) 392 { 393 struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec, 394 led_spk_mute); 395 396 return t14s_audio_led_set(ec, T14S_EC_SPK_MUTE_LED, brightness); 397 } 398 399 static int t14s_kbd_audio_led_probe(struct t14s_ec *ec) 400 { 401 int ret; 402 403 ec->led_mic_mute.name = "platform::micmute"; 404 ec->led_mic_mute.max_brightness = 1; 405 ec->led_mic_mute.default_trigger = "audio-micmute"; 406 ec->led_mic_mute.brightness_set_blocking = t14s_mic_mute_led_set; 407 ec->led_mic_mute.brightness_get = t14s_mic_mute_led_get; 408 409 ec->led_spk_mute.name = "platform::mute"; 410 ec->led_spk_mute.max_brightness = 1; 411 ec->led_spk_mute.default_trigger = "audio-mute"; 412 ec->led_spk_mute.brightness_set_blocking = t14s_spk_mute_led_set; 413 ec->led_spk_mute.brightness_get = t14s_spk_mute_led_get; 414 415 ret = devm_led_classdev_register(ec->dev, &ec->led_mic_mute); 416 if (ret) 417 return ret; 418 419 return devm_led_classdev_register(ec->dev, &ec->led_spk_mute); 420 } 421 422 static const struct key_entry t14s_keymap[] = { 423 T14S_EC_KEY_ENTRY(FN_4, KEY_SLEEP), 424 T14S_EC_KEY_ENTRY(FN_N, KEY_VENDOR), 425 T14S_EC_KEY_ENTRY(FN_F4, KEY_MICMUTE), 426 T14S_EC_KEY_ENTRY(FN_F7, KEY_SWITCHVIDEOMODE), 427 T14S_EC_KEY_ENTRY(FN_F8, KEY_PERFORMANCE), 428 T14S_EC_KEY_ENTRY(FN_F10, KEY_SELECTIVE_SCREENSHOT), 429 T14S_EC_KEY_ENTRY(FN_F11, KEY_LINK_PHONE), 430 T14S_EC_KEY_ENTRY(FN_F12, KEY_BOOKMARKS), 431 T14S_EC_KEY_ENTRY(FN_SPACE, KEY_KBDILLUMTOGGLE), 432 T14S_EC_KEY_ENTRY(FN_ESC, KEY_FN_ESC), 433 T14S_EC_KEY_ENTRY(FN_TAB, KEY_ZOOM), 434 T14S_EC_KEY_ENTRY(FN_RIGHT_SHIFT, KEY_FN_RIGHT_SHIFT), 435 T14S_EC_KEY_ENTRY(TP_DOUBLE_TAP, KEY_PROG4), 436 { KE_END } 437 }; 438 439 static int t14s_input_probe(struct t14s_ec *ec) 440 { 441 int ret; 442 443 ec->inputdev = devm_input_allocate_device(ec->dev); 444 if (!ec->inputdev) 445 return -ENOMEM; 446 447 ec->inputdev->name = "ThinkPad Extra Buttons"; 448 ec->inputdev->phys = "thinkpad/input0"; 449 ec->inputdev->id.bustype = BUS_HOST; 450 ec->inputdev->dev.parent = ec->dev; 451 452 ret = sparse_keymap_setup(ec->inputdev, t14s_keymap, NULL); 453 if (ret) 454 return ret; 455 456 return input_register_device(ec->inputdev); 457 } 458 459 static irqreturn_t t14s_ec_irq_handler(int irq, void *data) 460 { 461 struct t14s_ec *ec = data; 462 int ret; 463 u8 val; 464 465 ret = t14s_ec_read_evt(ec, &val); 466 if (ret < 0) { 467 dev_err(ec->dev, "Failed to read event\n"); 468 return IRQ_HANDLED; 469 } 470 471 switch (val) { 472 case T14S_EC_EVT_NONE: 473 break; 474 case T14S_EC_EVT_KEY_FN_SPACE: 475 t14s_kbd_bl_update(ec); 476 fallthrough; 477 case T14S_EC_EVT_KEY_FN_F4: 478 case T14S_EC_EVT_KEY_FN_F7: 479 case T14S_EC_EVT_KEY_FN_4: 480 case T14S_EC_EVT_KEY_FN_F8: 481 case T14S_EC_EVT_KEY_FN_F12: 482 case T14S_EC_EVT_KEY_FN_TAB: 483 case T14S_EC_EVT_KEY_FN_F10: 484 case T14S_EC_EVT_KEY_FN_N: 485 case T14S_EC_EVT_KEY_FN_F11: 486 case T14S_EC_EVT_KEY_FN_ESC: 487 case T14S_EC_EVT_KEY_FN_RIGHT_SHIFT: 488 case T14S_EC_EVT_KEY_TP_DOUBLE_TAP: 489 sparse_keymap_report_event(ec->inputdev, 490 T14S_EC_KEY_EVT_OFFSET + val, 1, true); 491 break; 492 case T14S_EC_EVT_AC_CONNECTED: 493 dev_dbg(ec->dev, "AC connected\n"); 494 break; 495 case T14S_EC_EVT_AC_DISCONNECTED: 496 dev_dbg(ec->dev, "AC disconnected\n"); 497 break; 498 case T14S_EC_EVT_KEY_POWER: 499 dev_dbg(ec->dev, "power button\n"); 500 break; 501 case T14S_EC_EVT_LID_OPEN: 502 dev_dbg(ec->dev, "LID open\n"); 503 break; 504 case T14S_EC_EVT_LID_CLOSED: 505 dev_dbg(ec->dev, "LID closed\n"); 506 break; 507 case T14S_EC_EVT_THERMAL_TZ40: 508 dev_dbg(ec->dev, "Thermal Zone 40 Status Change Event (CPU/GPU)\n"); 509 break; 510 case T14S_EC_EVT_THERMAL_TZ42: 511 dev_dbg(ec->dev, "Thermal Zone 42 Status Change Event (Battery)\n"); 512 break; 513 case T14S_EC_EVT_THERMAL_TZ39: 514 dev_dbg(ec->dev, "Thermal Zone 39 Status Change Event (CPU/GPU)\n"); 515 break; 516 case T14S_EC_EVT_KEY_FN_G: 517 dev_dbg(ec->dev, "FN + G - toggle double-tapping\n"); 518 break; 519 case T14S_EC_EVT_KEY_FN_L: 520 dev_dbg(ec->dev, "FN + L - low performance mode\n"); 521 break; 522 case T14S_EC_EVT_KEY_FN_M: 523 dev_dbg(ec->dev, "FN + M - medium performance mode\n"); 524 break; 525 case T14S_EC_EVT_KEY_FN_H: 526 dev_dbg(ec->dev, "FN + H - high performance mode\n"); 527 break; 528 case T14S_EC_EVT_KEY_FN_T: 529 dev_dbg(ec->dev, "FN + T - toggle intelligent cooling mode\n"); 530 break; 531 case T14S_EC_EVT_KEY_FN_D: 532 dev_dbg(ec->dev, "FN + D - toggle privacy guard mode\n"); 533 break; 534 default: 535 dev_info(ec->dev, "Unknown EC event: 0x%02x\n", val); 536 break; 537 } 538 539 return IRQ_HANDLED; 540 } 541 542 static int t14s_ec_probe(struct i2c_client *client) 543 { 544 struct device *dev = &client->dev; 545 struct t14s_ec *ec; 546 int ret; 547 548 ec = devm_kzalloc(dev, sizeof(*ec), GFP_KERNEL); 549 if (!ec) 550 return -ENOMEM; 551 552 ec->dev = dev; 553 554 ec->regmap = devm_regmap_init(dev, &t14s_ec_regmap_bus, 555 ec, &t14s_ec_regmap_config); 556 if (IS_ERR(ec->regmap)) 557 return dev_err_probe(dev, PTR_ERR(ec->regmap), 558 "Failed to init regmap\n"); 559 560 ret = devm_request_threaded_irq(dev, client->irq, NULL, 561 t14s_ec_irq_handler, 562 IRQF_ONESHOT, dev_name(dev), ec); 563 if (ret < 0) 564 return dev_err_probe(dev, ret, "Failed to get IRQ\n"); 565 566 ret = t14s_leds_probe(ec); 567 if (ret < 0) 568 return ret; 569 570 ret = t14s_kbd_backlight_probe(ec); 571 if (ret < 0) 572 return ret; 573 574 ret = t14s_kbd_audio_led_probe(ec); 575 if (ret < 0) 576 return ret; 577 578 ret = t14s_input_probe(ec); 579 if (ret < 0) 580 return ret; 581 582 /* 583 * Disable wakeup support by default, because the driver currently does 584 * not support masking any events and the laptop should not wake up when 585 * the LID is closed. 586 */ 587 device_wakeup_disable(dev); 588 589 return 0; 590 } 591 592 static const struct of_device_id t14s_ec_of_match[] = { 593 { .compatible = "lenovo,thinkpad-t14s-ec" }, 594 {} 595 }; 596 MODULE_DEVICE_TABLE(of, t14s_ec_of_match); 597 598 static const struct i2c_device_id t14s_ec_i2c_id_table[] = { 599 { "thinkpad-t14s-ec", }, 600 {} 601 }; 602 MODULE_DEVICE_TABLE(i2c, t14s_ec_i2c_id_table); 603 604 static struct i2c_driver t14s_ec_i2c_driver = { 605 .driver = { 606 .name = "thinkpad-t14s-ec", 607 .of_match_table = t14s_ec_of_match, 608 }, 609 .probe = t14s_ec_probe, 610 .id_table = t14s_ec_i2c_id_table, 611 }; 612 module_i2c_driver(t14s_ec_i2c_driver); 613 614 MODULE_AUTHOR("Sebastian Reichel <sre@kernel.org>"); 615 MODULE_DESCRIPTION("Lenovo Thinkpad T14s Embedded Controller"); 616 MODULE_LICENSE("GPL"); 617