1 // SPDX-License-Identifier: GPL-2.0 2 #include "bcm47xx_private.h" 3 4 #include "linux/err.h" 5 #include <linux/gpio/machine.h> 6 #include <linux/gpio/property.h> 7 #include <linux/input-event-codes.h> 8 #include <linux/interrupt.h> 9 #include <linux/platform_device.h> 10 #include <linux/property.h> 11 12 #include <bcm47xx_board.h> 13 #include <bcm47xx.h> 14 15 /************************************************** 16 * Database 17 **************************************************/ 18 19 struct bcm47xx_gpio_key { 20 u16 code; 21 u8 pin; 22 u8 flags; 23 }; 24 25 #define BCM47XX_GPIO_KEY(_gpio, _code) \ 26 { \ 27 .code = _code, \ 28 .pin = _gpio, \ 29 .flags = GPIO_ACTIVE_LOW, \ 30 } 31 32 #define BCM47XX_GPIO_KEY_H(_gpio, _code) \ 33 { \ 34 .code = _code, \ 35 .pin = _gpio, \ 36 .flags = GPIO_ACTIVE_HIGH, \ 37 } 38 39 /* Asus */ 40 41 static const struct bcm47xx_gpio_key bcm47xx_buttons_asus_rtn10u[] __initconst = { 42 BCM47XX_GPIO_KEY(20, KEY_WPS_BUTTON), 43 BCM47XX_GPIO_KEY(21, KEY_RESTART), 44 }; 45 46 static const struct bcm47xx_gpio_key bcm47xx_buttons_asus_rtn12[] __initconst = { 47 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), 48 BCM47XX_GPIO_KEY(1, KEY_RESTART), 49 BCM47XX_GPIO_KEY(4, BTN_0), /* Router mode */ 50 BCM47XX_GPIO_KEY(5, BTN_1), /* Repeater mode */ 51 BCM47XX_GPIO_KEY(6, BTN_2), /* AP mode */ 52 }; 53 54 static const struct bcm47xx_gpio_key bcm47xx_buttons_asus_rtn16[] __initconst = { 55 BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON), 56 BCM47XX_GPIO_KEY(8, KEY_RESTART), 57 }; 58 59 static const struct bcm47xx_gpio_key 60 bcm47xx_buttons_asus_rtn66u[] __initconst = { 61 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 62 BCM47XX_GPIO_KEY(9, KEY_RESTART), 63 }; 64 65 static const struct bcm47xx_gpio_key 66 bcm47xx_buttons_asus_wl300g[] __initconst = { 67 BCM47XX_GPIO_KEY(6, KEY_RESTART), 68 }; 69 70 static const struct bcm47xx_gpio_key 71 bcm47xx_buttons_asus_wl320ge[] __initconst = { 72 BCM47XX_GPIO_KEY(6, KEY_RESTART), 73 }; 74 75 static const struct bcm47xx_gpio_key 76 bcm47xx_buttons_asus_wl330ge[] __initconst = { 77 BCM47XX_GPIO_KEY(2, KEY_RESTART), 78 }; 79 80 static const struct bcm47xx_gpio_key 81 bcm47xx_buttons_asus_wl500g[] __initconst = { 82 BCM47XX_GPIO_KEY(6, KEY_RESTART), 83 }; 84 85 static const struct bcm47xx_gpio_key 86 bcm47xx_buttons_asus_wl500gd[] __initconst = { 87 BCM47XX_GPIO_KEY(6, KEY_RESTART), 88 }; 89 90 static const struct bcm47xx_gpio_key 91 bcm47xx_buttons_asus_wl500gpv1[] __initconst = { 92 BCM47XX_GPIO_KEY(0, KEY_RESTART), 93 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 94 }; 95 96 static const struct bcm47xx_gpio_key 97 bcm47xx_buttons_asus_wl500gpv2[] __initconst = { 98 BCM47XX_GPIO_KEY(2, KEY_RESTART), 99 BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON), 100 }; 101 102 static const struct bcm47xx_gpio_key 103 bcm47xx_buttons_asus_wl500w[] __initconst = { 104 BCM47XX_GPIO_KEY_H(6, KEY_RESTART), 105 BCM47XX_GPIO_KEY_H(7, KEY_WPS_BUTTON), 106 }; 107 108 static const struct bcm47xx_gpio_key 109 bcm47xx_buttons_asus_wl520gc[] __initconst = { 110 BCM47XX_GPIO_KEY(2, KEY_RESTART), 111 BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON), 112 }; 113 114 static const struct bcm47xx_gpio_key 115 bcm47xx_buttons_asus_wl520gu[] __initconst = { 116 BCM47XX_GPIO_KEY(2, KEY_RESTART), 117 BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON), 118 }; 119 120 static const struct bcm47xx_gpio_key 121 bcm47xx_buttons_asus_wl700ge[] __initconst = { 122 BCM47XX_GPIO_KEY(0, KEY_POWER), /* Hard disk power switch */ 123 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), /* EZSetup */ 124 BCM47XX_GPIO_KEY(6, KEY_COPY), /* Copy data from USB to internal disk */ 125 BCM47XX_GPIO_KEY(7, KEY_RESTART), /* Hard reset */ 126 }; 127 128 static const struct bcm47xx_gpio_key 129 bcm47xx_buttons_asus_wlhdd[] __initconst = { 130 BCM47XX_GPIO_KEY(6, KEY_RESTART), 131 }; 132 133 /* Huawei */ 134 135 static const struct bcm47xx_gpio_key 136 bcm47xx_buttons_huawei_e970[] __initconst = { 137 BCM47XX_GPIO_KEY(6, KEY_RESTART), 138 }; 139 140 /* Belkin */ 141 142 static const struct bcm47xx_gpio_key 143 bcm47xx_buttons_belkin_f7d4301[] __initconst = { 144 BCM47XX_GPIO_KEY(6, KEY_RESTART), 145 BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON), 146 }; 147 148 /* Buffalo */ 149 150 static const struct bcm47xx_gpio_key 151 bcm47xx_buttons_buffalo_whr2_a54g54[] __initconst = { 152 BCM47XX_GPIO_KEY(4, KEY_RESTART), 153 }; 154 155 static const struct bcm47xx_gpio_key 156 bcm47xx_buttons_buffalo_whr_g125[] __initconst = { 157 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), 158 BCM47XX_GPIO_KEY(4, KEY_RESTART), 159 BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode switch */ 160 }; 161 162 static const struct bcm47xx_gpio_key 163 bcm47xx_buttons_buffalo_whr_g54s[] __initconst = { 164 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), 165 BCM47XX_GPIO_KEY_H(4, KEY_RESTART), 166 BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode switch */ 167 }; 168 169 static const struct bcm47xx_gpio_key 170 bcm47xx_buttons_buffalo_whr_hp_g54[] __initconst = { 171 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), 172 BCM47XX_GPIO_KEY(4, KEY_RESTART), 173 BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode switch */ 174 }; 175 176 static const struct bcm47xx_gpio_key 177 bcm47xx_buttons_buffalo_wzr_g300n[] __initconst = { 178 BCM47XX_GPIO_KEY(4, KEY_RESTART), 179 }; 180 181 static const struct bcm47xx_gpio_key 182 bcm47xx_buttons_buffalo_wzr_rs_g54[] __initconst = { 183 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), 184 BCM47XX_GPIO_KEY(4, KEY_RESTART), 185 }; 186 187 static const struct bcm47xx_gpio_key 188 bcm47xx_buttons_buffalo_wzr_rs_g54hp[] __initconst = { 189 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), 190 BCM47XX_GPIO_KEY(4, KEY_RESTART), 191 }; 192 193 /* Dell */ 194 195 static const struct bcm47xx_gpio_key 196 bcm47xx_buttons_dell_tm2300[] __initconst = { 197 BCM47XX_GPIO_KEY(0, KEY_RESTART), 198 }; 199 200 /* D-Link */ 201 202 static const struct bcm47xx_gpio_key 203 bcm47xx_buttons_dlink_dir130[] __initconst = { 204 BCM47XX_GPIO_KEY(3, KEY_RESTART), 205 BCM47XX_GPIO_KEY(7, KEY_UNKNOWN), 206 }; 207 208 static const struct bcm47xx_gpio_key 209 bcm47xx_buttons_dlink_dir330[] __initconst = { 210 BCM47XX_GPIO_KEY(3, KEY_RESTART), 211 BCM47XX_GPIO_KEY(7, KEY_UNKNOWN), 212 }; 213 214 /* Linksys */ 215 216 static const struct bcm47xx_gpio_key 217 bcm47xx_buttons_linksys_e1000v1[] __initconst = { 218 BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON), 219 BCM47XX_GPIO_KEY(6, KEY_RESTART), 220 }; 221 222 static const struct bcm47xx_gpio_key 223 bcm47xx_buttons_linksys_e1000v21[] __initconst = { 224 BCM47XX_GPIO_KEY(9, KEY_WPS_BUTTON), 225 BCM47XX_GPIO_KEY(10, KEY_RESTART), 226 }; 227 228 static const struct bcm47xx_gpio_key 229 bcm47xx_buttons_linksys_e2000v1[] __initconst = { 230 BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON), 231 BCM47XX_GPIO_KEY(8, KEY_RESTART), 232 }; 233 234 static const struct bcm47xx_gpio_key 235 bcm47xx_buttons_linksys_e2500v3[] __initconst = { 236 BCM47XX_GPIO_KEY(9, KEY_WPS_BUTTON), 237 BCM47XX_GPIO_KEY(10, KEY_RESTART), 238 }; 239 240 static const struct bcm47xx_gpio_key 241 bcm47xx_buttons_linksys_e3000v1[] __initconst = { 242 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 243 BCM47XX_GPIO_KEY(6, KEY_RESTART), 244 }; 245 246 static const struct bcm47xx_gpio_key 247 bcm47xx_buttons_linksys_e3200v1[] __initconst = { 248 BCM47XX_GPIO_KEY(5, KEY_RESTART), 249 BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON), 250 }; 251 252 static const struct bcm47xx_gpio_key 253 bcm47xx_buttons_linksys_e4200v1[] __initconst = { 254 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 255 BCM47XX_GPIO_KEY(6, KEY_RESTART), 256 }; 257 258 static const struct bcm47xx_gpio_key 259 bcm47xx_buttons_linksys_wrt150nv1[] __initconst = { 260 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 261 BCM47XX_GPIO_KEY(6, KEY_RESTART), 262 }; 263 264 static const struct bcm47xx_gpio_key 265 bcm47xx_buttons_linksys_wrt150nv11[] __initconst = { 266 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 267 BCM47XX_GPIO_KEY(6, KEY_RESTART), 268 }; 269 270 static const struct bcm47xx_gpio_key 271 bcm47xx_buttons_linksys_wrt160nv1[] __initconst = { 272 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 273 BCM47XX_GPIO_KEY(6, KEY_RESTART), 274 }; 275 276 static const struct bcm47xx_gpio_key 277 bcm47xx_buttons_linksys_wrt160nv3[] __initconst = { 278 BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON), 279 BCM47XX_GPIO_KEY(6, KEY_RESTART), 280 }; 281 282 static const struct bcm47xx_gpio_key 283 bcm47xx_buttons_linksys_wrt300n_v1[] __initconst = { 284 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 285 BCM47XX_GPIO_KEY(6, KEY_RESTART), 286 }; 287 288 static const struct bcm47xx_gpio_key 289 bcm47xx_buttons_linksys_wrt300nv11[] __initconst = { 290 BCM47XX_GPIO_KEY(4, KEY_UNKNOWN), 291 BCM47XX_GPIO_KEY(6, KEY_RESTART), 292 }; 293 294 static const struct bcm47xx_gpio_key 295 bcm47xx_buttons_linksys_wrt310nv1[] __initconst = { 296 BCM47XX_GPIO_KEY(6, KEY_RESTART), 297 BCM47XX_GPIO_KEY(8, KEY_UNKNOWN), 298 }; 299 300 static const struct bcm47xx_gpio_key 301 bcm47xx_buttons_linksys_wrt310n_v2[] __initconst = { 302 BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON), 303 BCM47XX_GPIO_KEY(6, KEY_RESTART), 304 }; 305 306 static const struct bcm47xx_gpio_key 307 bcm47xx_buttons_linksys_wrt320n_v1[] __initconst = { 308 BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON), 309 BCM47XX_GPIO_KEY(8, KEY_RESTART), 310 }; 311 312 static const struct bcm47xx_gpio_key 313 bcm47xx_buttons_linksys_wrt54g3gv2[] __initconst = { 314 BCM47XX_GPIO_KEY(5, KEY_WIMAX), 315 BCM47XX_GPIO_KEY(6, KEY_RESTART), 316 }; 317 318 static const struct bcm47xx_gpio_key 319 bcm47xx_buttons_linksys_wrt54g_generic[] __initconst = { 320 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 321 BCM47XX_GPIO_KEY(6, KEY_RESTART), 322 }; 323 324 static const struct bcm47xx_gpio_key 325 bcm47xx_buttons_linksys_wrt610nv1[] __initconst = { 326 BCM47XX_GPIO_KEY(6, KEY_RESTART), 327 BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON), 328 }; 329 330 static const struct bcm47xx_gpio_key 331 bcm47xx_buttons_linksys_wrt610nv2[] __initconst = { 332 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 333 BCM47XX_GPIO_KEY(6, KEY_RESTART), 334 }; 335 336 static const struct bcm47xx_gpio_key 337 bcm47xx_buttons_linksys_wrtsl54gs[] __initconst = { 338 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 339 BCM47XX_GPIO_KEY(6, KEY_RESTART), 340 }; 341 342 /* Luxul */ 343 344 static const struct bcm47xx_gpio_key 345 bcm47xx_buttons_luxul_abr_4400_v1[] = { 346 BCM47XX_GPIO_KEY(14, KEY_RESTART), 347 }; 348 349 static const struct bcm47xx_gpio_key 350 bcm47xx_buttons_luxul_xap_310_v1[] = { 351 BCM47XX_GPIO_KEY(20, KEY_RESTART), 352 }; 353 354 static const struct bcm47xx_gpio_key 355 bcm47xx_buttons_luxul_xap_1210_v1[] = { 356 BCM47XX_GPIO_KEY(8, KEY_RESTART), 357 }; 358 359 static const struct bcm47xx_gpio_key 360 bcm47xx_buttons_luxul_xap_1230_v1[] = { 361 BCM47XX_GPIO_KEY(8, KEY_RESTART), 362 }; 363 364 static const struct bcm47xx_gpio_key 365 bcm47xx_buttons_luxul_xap_1240_v1[] = { 366 BCM47XX_GPIO_KEY(8, KEY_RESTART), 367 }; 368 369 static const struct bcm47xx_gpio_key 370 bcm47xx_buttons_luxul_xap_1500_v1[] = { 371 BCM47XX_GPIO_KEY(14, KEY_RESTART), 372 }; 373 374 static const struct bcm47xx_gpio_key 375 bcm47xx_buttons_luxul_xbr_4400_v1[] = { 376 BCM47XX_GPIO_KEY(14, KEY_RESTART), 377 }; 378 379 static const struct bcm47xx_gpio_key 380 bcm47xx_buttons_luxul_xvw_p30_v1[] = { 381 BCM47XX_GPIO_KEY(20, KEY_RESTART), 382 }; 383 384 static const struct bcm47xx_gpio_key 385 bcm47xx_buttons_luxul_xwr_600_v1[] = { 386 BCM47XX_GPIO_KEY(8, KEY_RESTART), 387 }; 388 389 static const struct bcm47xx_gpio_key 390 bcm47xx_buttons_luxul_xwr_1750_v1[] = { 391 BCM47XX_GPIO_KEY(14, KEY_RESTART), 392 }; 393 394 /* Microsoft */ 395 396 static const struct bcm47xx_gpio_key 397 bcm47xx_buttons_microsoft_nm700[] __initconst = { 398 BCM47XX_GPIO_KEY(7, KEY_RESTART), 399 }; 400 401 /* Motorola */ 402 403 static const struct bcm47xx_gpio_key 404 bcm47xx_buttons_motorola_we800g[] __initconst = { 405 BCM47XX_GPIO_KEY(0, KEY_RESTART), 406 }; 407 408 static const struct bcm47xx_gpio_key 409 bcm47xx_buttons_motorola_wr850gp[] __initconst = { 410 BCM47XX_GPIO_KEY(5, KEY_RESTART), 411 }; 412 413 static const struct bcm47xx_gpio_key 414 bcm47xx_buttons_motorola_wr850gv2v3[] __initconst = { 415 BCM47XX_GPIO_KEY(5, KEY_RESTART), 416 }; 417 418 /* Netgear */ 419 420 static const struct bcm47xx_gpio_key 421 bcm47xx_buttons_netgear_r6200_v1[] __initconst = { 422 BCM47XX_GPIO_KEY(2, KEY_RFKILL), 423 BCM47XX_GPIO_KEY(3, KEY_RESTART), 424 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 425 }; 426 427 static const struct bcm47xx_gpio_key 428 bcm47xx_buttons_netgear_r6300_v1[] __initconst = { 429 BCM47XX_GPIO_KEY(6, KEY_RESTART), 430 }; 431 432 static const struct bcm47xx_gpio_key 433 bcm47xx_buttons_netgear_wn2500rp_v1[] __initconst = { 434 BCM47XX_GPIO_KEY(12, KEY_RESTART), 435 BCM47XX_GPIO_KEY(31, KEY_WPS_BUTTON), 436 }; 437 438 static const struct bcm47xx_gpio_key 439 bcm47xx_buttons_netgear_wndr3400v1[] __initconst = { 440 BCM47XX_GPIO_KEY(4, KEY_RESTART), 441 BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON), 442 BCM47XX_GPIO_KEY(8, KEY_RFKILL), 443 }; 444 445 static const struct bcm47xx_gpio_key 446 bcm47xx_buttons_netgear_wndr3400_v3[] __initconst = { 447 BCM47XX_GPIO_KEY(12, KEY_RESTART), 448 BCM47XX_GPIO_KEY(23, KEY_WPS_BUTTON), 449 }; 450 451 static const struct bcm47xx_gpio_key 452 bcm47xx_buttons_netgear_wndr3700v3[] __initconst = { 453 BCM47XX_GPIO_KEY(2, KEY_RFKILL), 454 BCM47XX_GPIO_KEY(3, KEY_RESTART), 455 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 456 }; 457 458 static const struct bcm47xx_gpio_key 459 bcm47xx_buttons_netgear_wndr4500v1[] __initconst = { 460 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 461 BCM47XX_GPIO_KEY(5, KEY_RFKILL), 462 BCM47XX_GPIO_KEY(6, KEY_RESTART), 463 }; 464 465 static const struct bcm47xx_gpio_key 466 bcm47xx_buttons_netgear_wnr1000_v3[] __initconst = { 467 BCM47XX_GPIO_KEY(2, KEY_WPS_BUTTON), 468 BCM47XX_GPIO_KEY(3, KEY_RESTART), 469 }; 470 471 static const struct bcm47xx_gpio_key 472 bcm47xx_buttons_netgear_wnr3500lv1[] __initconst = { 473 BCM47XX_GPIO_KEY(4, KEY_RESTART), 474 BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON), 475 }; 476 477 static const struct bcm47xx_gpio_key 478 bcm47xx_buttons_netgear_wnr3500lv2[] __initconst = { 479 BCM47XX_GPIO_KEY(4, KEY_RESTART), 480 BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON), 481 BCM47XX_GPIO_KEY(8, KEY_RFKILL), 482 }; 483 484 static const struct bcm47xx_gpio_key 485 bcm47xx_buttons_netgear_wnr834bv2[] __initconst = { 486 BCM47XX_GPIO_KEY(6, KEY_RESTART), 487 }; 488 489 /* SimpleTech */ 490 491 static const struct bcm47xx_gpio_key 492 bcm47xx_buttons_simpletech_simpleshare[] __initconst = { 493 BCM47XX_GPIO_KEY(0, KEY_RESTART), 494 }; 495 496 /************************************************** 497 * Init 498 **************************************************/ 499 500 static int __init 501 bcm47xx_buttons_add(const struct bcm47xx_gpio_key *buttons, int nbuttons) 502 { 503 struct platform_device *pdev; 504 const struct software_node *gpio_swnode; 505 struct property_entry *p; 506 int error; 507 int i; 508 509 switch (bcm47xx_bus_type) { 510 #ifdef CONFIG_BCM47XX_BCMA 511 case BCM47XX_BUS_TYPE_BCMA: 512 gpio_swnode = &bcma_gpio_swnode; 513 break; 514 #endif 515 #ifdef CONFIG_BCM47XX_SSB 516 case BCM47XX_BUS_TYPE_SSB: 517 gpio_swnode = &ssb_gpio_swnode; 518 break; 519 #endif 520 default: 521 return -ENODEV; 522 } 523 524 /* 1 node for gpio-keys device, 1 node for each button, 1 terminator */ 525 const struct software_node **node_group __free(kfree) = 526 kzalloc_objs(*node_group, 1 + nbuttons + 1); 527 if (!node_group) 528 return -ENOMEM; 529 530 /* 1 code property, 1 gpio property, 1 terminator */ 531 struct property_entry *props __free(kfree) = 532 kzalloc_objs(*props, nbuttons * 3); 533 if (!props) 534 return -ENOMEM; 535 536 /* 1 node for gpio-keys device, 1 node for each button */ 537 struct software_node *nodes __free(kfree) = 538 kzalloc_objs(*nodes, 1 + nbuttons); 539 if (!nodes) 540 return -ENOMEM; 541 542 struct software_node_ref_args *ref_args __free(kfree) = 543 kzalloc_objs(*ref_args, nbuttons); 544 if (!ref_args) 545 return -ENOMEM; 546 547 /* gpio-keys node */ 548 nodes[0].name = "bcm47xx-gpio-buttons"; 549 550 p = props; 551 for (i = 0; i < nbuttons; i++) { 552 const struct bcm47xx_gpio_key *button = &buttons[i]; 553 struct software_node *node = &nodes[1 + i]; 554 struct software_node_ref_args *ref = &ref_args[i]; 555 556 node->parent = &nodes[0]; 557 node->properties = p; 558 559 *ref = SOFTWARE_NODE_REFERENCE(gpio_swnode, button->pin, button->flags); 560 *p++ = PROPERTY_ENTRY_REF("gpios", &ref_args[i]); 561 *p++ = PROPERTY_ENTRY_U32("linux,code", button->code); 562 p++; 563 } 564 565 for (i = 0; i < nbuttons + 1; i++) 566 node_group[i] = &nodes[i]; 567 568 error = software_node_register_node_group(node_group); 569 if (error) 570 return error; 571 572 pdev = platform_device_register_full(&(struct platform_device_info){ 573 .name = "gpio-keys", 574 .swnode = &nodes[0], 575 }); 576 error = PTR_ERR_OR_ZERO(pdev); 577 if (error) { 578 software_node_unregister_node_group(node_group); 579 return error; 580 } 581 582 retain_and_null_ptr(props); 583 retain_and_null_ptr(nodes); 584 retain_and_null_ptr(ref_args); 585 return 0; 586 } 587 588 #define bcm47xx_add_bdata(dev_buttons) \ 589 bcm47xx_buttons_add(dev_buttons, ARRAY_SIZE(dev_buttons)) 590 591 int __init bcm47xx_buttons_register(void) 592 { 593 enum bcm47xx_board board = bcm47xx_board_get(); 594 int err; 595 596 switch (board) { 597 case BCM47XX_BOARD_ASUS_RTN10U: 598 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_rtn10u); 599 break; 600 case BCM47XX_BOARD_ASUS_RTN12: 601 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_rtn12); 602 break; 603 case BCM47XX_BOARD_ASUS_RTN16: 604 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_rtn16); 605 break; 606 case BCM47XX_BOARD_ASUS_RTN66U: 607 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_rtn66u); 608 break; 609 case BCM47XX_BOARD_ASUS_WL300G: 610 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_wl300g); 611 break; 612 case BCM47XX_BOARD_ASUS_WL320GE: 613 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_wl320ge); 614 break; 615 case BCM47XX_BOARD_ASUS_WL330GE: 616 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_wl330ge); 617 break; 618 case BCM47XX_BOARD_ASUS_WL500G: 619 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_wl500g); 620 break; 621 case BCM47XX_BOARD_ASUS_WL500GD: 622 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_wl500gd); 623 break; 624 case BCM47XX_BOARD_ASUS_WL500GPV1: 625 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_wl500gpv1); 626 break; 627 case BCM47XX_BOARD_ASUS_WL500GPV2: 628 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_wl500gpv2); 629 break; 630 case BCM47XX_BOARD_ASUS_WL500W: 631 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_wl500w); 632 break; 633 case BCM47XX_BOARD_ASUS_WL520GC: 634 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_wl520gc); 635 break; 636 case BCM47XX_BOARD_ASUS_WL520GU: 637 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_wl520gu); 638 break; 639 case BCM47XX_BOARD_ASUS_WL700GE: 640 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_wl700ge); 641 break; 642 case BCM47XX_BOARD_ASUS_WLHDD: 643 err = bcm47xx_add_bdata(bcm47xx_buttons_asus_wlhdd); 644 break; 645 646 case BCM47XX_BOARD_BELKIN_F7D3301: 647 case BCM47XX_BOARD_BELKIN_F7D3302: 648 case BCM47XX_BOARD_BELKIN_F7D4301: 649 case BCM47XX_BOARD_BELKIN_F7D4302: 650 case BCM47XX_BOARD_BELKIN_F7D4401: 651 err = bcm47xx_add_bdata(bcm47xx_buttons_belkin_f7d4301); 652 break; 653 654 case BCM47XX_BOARD_BUFFALO_WHR2_A54G54: 655 err = bcm47xx_add_bdata(bcm47xx_buttons_buffalo_whr2_a54g54); 656 break; 657 case BCM47XX_BOARD_BUFFALO_WHR_G125: 658 err = bcm47xx_add_bdata(bcm47xx_buttons_buffalo_whr_g125); 659 break; 660 case BCM47XX_BOARD_BUFFALO_WHR_G54S: 661 err = bcm47xx_add_bdata(bcm47xx_buttons_buffalo_whr_g54s); 662 break; 663 case BCM47XX_BOARD_BUFFALO_WHR_HP_G54: 664 err = bcm47xx_add_bdata(bcm47xx_buttons_buffalo_whr_hp_g54); 665 break; 666 case BCM47XX_BOARD_BUFFALO_WZR_G300N: 667 err = bcm47xx_add_bdata(bcm47xx_buttons_buffalo_wzr_g300n); 668 break; 669 case BCM47XX_BOARD_BUFFALO_WZR_RS_G54: 670 err = bcm47xx_add_bdata(bcm47xx_buttons_buffalo_wzr_rs_g54); 671 break; 672 case BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP: 673 err = bcm47xx_add_bdata(bcm47xx_buttons_buffalo_wzr_rs_g54hp); 674 break; 675 676 case BCM47XX_BOARD_DELL_TM2300: 677 err = bcm47xx_add_bdata(bcm47xx_buttons_dell_tm2300); 678 break; 679 680 case BCM47XX_BOARD_DLINK_DIR130: 681 err = bcm47xx_add_bdata(bcm47xx_buttons_dlink_dir130); 682 break; 683 case BCM47XX_BOARD_DLINK_DIR330: 684 err = bcm47xx_add_bdata(bcm47xx_buttons_dlink_dir330); 685 break; 686 687 case BCM47XX_BOARD_HUAWEI_E970: 688 err = bcm47xx_add_bdata(bcm47xx_buttons_huawei_e970); 689 break; 690 691 case BCM47XX_BOARD_LINKSYS_E1000V1: 692 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_e1000v1); 693 break; 694 case BCM47XX_BOARD_LINKSYS_E1000V21: 695 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_e1000v21); 696 break; 697 case BCM47XX_BOARD_LINKSYS_E2000V1: 698 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_e2000v1); 699 break; 700 case BCM47XX_BOARD_LINKSYS_E2500V3: 701 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_e2500v3); 702 break; 703 case BCM47XX_BOARD_LINKSYS_E3000V1: 704 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_e3000v1); 705 break; 706 case BCM47XX_BOARD_LINKSYS_E3200V1: 707 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_e3200v1); 708 break; 709 case BCM47XX_BOARD_LINKSYS_E4200V1: 710 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_e4200v1); 711 break; 712 case BCM47XX_BOARD_LINKSYS_WRT150NV1: 713 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrt150nv1); 714 break; 715 case BCM47XX_BOARD_LINKSYS_WRT150NV11: 716 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrt150nv11); 717 break; 718 case BCM47XX_BOARD_LINKSYS_WRT160NV1: 719 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrt160nv1); 720 break; 721 case BCM47XX_BOARD_LINKSYS_WRT160NV3: 722 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrt160nv3); 723 break; 724 case BCM47XX_BOARD_LINKSYS_WRT300N_V1: 725 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrt300n_v1); 726 break; 727 case BCM47XX_BOARD_LINKSYS_WRT300NV11: 728 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrt300nv11); 729 break; 730 case BCM47XX_BOARD_LINKSYS_WRT310NV1: 731 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrt310nv1); 732 break; 733 case BCM47XX_BOARD_LINKSYS_WRT310NV2: 734 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrt310n_v2); 735 break; 736 case BCM47XX_BOARD_LINKSYS_WRT320N_V1: 737 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrt320n_v1); 738 break; 739 case BCM47XX_BOARD_LINKSYS_WRT54G3GV2: 740 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrt54g3gv2); 741 break; 742 case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101: 743 case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467: 744 case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708: 745 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrt54g_generic); 746 break; 747 case BCM47XX_BOARD_LINKSYS_WRT610NV1: 748 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrt610nv1); 749 break; 750 case BCM47XX_BOARD_LINKSYS_WRT610NV2: 751 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrt610nv2); 752 break; 753 case BCM47XX_BOARD_LINKSYS_WRTSL54GS: 754 err = bcm47xx_add_bdata(bcm47xx_buttons_linksys_wrtsl54gs); 755 break; 756 757 case BCM47XX_BOARD_LUXUL_ABR_4400_V1: 758 err = bcm47xx_add_bdata(bcm47xx_buttons_luxul_abr_4400_v1); 759 break; 760 case BCM47XX_BOARD_LUXUL_XAP_310_V1: 761 err = bcm47xx_add_bdata(bcm47xx_buttons_luxul_xap_310_v1); 762 break; 763 case BCM47XX_BOARD_LUXUL_XAP_1210_V1: 764 err = bcm47xx_add_bdata(bcm47xx_buttons_luxul_xap_1210_v1); 765 break; 766 case BCM47XX_BOARD_LUXUL_XAP_1230_V1: 767 err = bcm47xx_add_bdata(bcm47xx_buttons_luxul_xap_1230_v1); 768 break; 769 case BCM47XX_BOARD_LUXUL_XAP_1240_V1: 770 err = bcm47xx_add_bdata(bcm47xx_buttons_luxul_xap_1240_v1); 771 break; 772 case BCM47XX_BOARD_LUXUL_XAP_1500_V1: 773 err = bcm47xx_add_bdata(bcm47xx_buttons_luxul_xap_1500_v1); 774 break; 775 case BCM47XX_BOARD_LUXUL_XBR_4400_V1: 776 err = bcm47xx_add_bdata(bcm47xx_buttons_luxul_xbr_4400_v1); 777 break; 778 case BCM47XX_BOARD_LUXUL_XVW_P30_V1: 779 err = bcm47xx_add_bdata(bcm47xx_buttons_luxul_xvw_p30_v1); 780 break; 781 case BCM47XX_BOARD_LUXUL_XWR_600_V1: 782 err = bcm47xx_add_bdata(bcm47xx_buttons_luxul_xwr_600_v1); 783 break; 784 case BCM47XX_BOARD_LUXUL_XWR_1750_V1: 785 err = bcm47xx_add_bdata(bcm47xx_buttons_luxul_xwr_1750_v1); 786 break; 787 788 case BCM47XX_BOARD_MICROSOFT_MN700: 789 err = bcm47xx_add_bdata(bcm47xx_buttons_microsoft_nm700); 790 break; 791 792 case BCM47XX_BOARD_MOTOROLA_WE800G: 793 err = bcm47xx_add_bdata(bcm47xx_buttons_motorola_we800g); 794 break; 795 case BCM47XX_BOARD_MOTOROLA_WR850GP: 796 err = bcm47xx_add_bdata(bcm47xx_buttons_motorola_wr850gp); 797 break; 798 case BCM47XX_BOARD_MOTOROLA_WR850GV2V3: 799 err = bcm47xx_add_bdata(bcm47xx_buttons_motorola_wr850gv2v3); 800 break; 801 802 case BCM47XX_BOARD_NETGEAR_R6200_V1: 803 err = bcm47xx_add_bdata(bcm47xx_buttons_netgear_r6200_v1); 804 break; 805 case BCM47XX_BOARD_NETGEAR_R6300_V1: 806 err = bcm47xx_add_bdata(bcm47xx_buttons_netgear_r6300_v1); 807 break; 808 case BCM47XX_BOARD_NETGEAR_WN2500RP_V1: 809 err = bcm47xx_add_bdata(bcm47xx_buttons_netgear_wn2500rp_v1); 810 break; 811 case BCM47XX_BOARD_NETGEAR_WNDR3400V1: 812 err = bcm47xx_add_bdata(bcm47xx_buttons_netgear_wndr3400v1); 813 break; 814 case BCM47XX_BOARD_NETGEAR_WNDR3400_V3: 815 err = bcm47xx_add_bdata(bcm47xx_buttons_netgear_wndr3400_v3); 816 break; 817 case BCM47XX_BOARD_NETGEAR_WNDR3700V3: 818 err = bcm47xx_add_bdata(bcm47xx_buttons_netgear_wndr3700v3); 819 break; 820 case BCM47XX_BOARD_NETGEAR_WNDR4500V1: 821 err = bcm47xx_add_bdata(bcm47xx_buttons_netgear_wndr4500v1); 822 break; 823 case BCM47XX_BOARD_NETGEAR_WNR1000_V3: 824 err = bcm47xx_add_bdata(bcm47xx_buttons_netgear_wnr1000_v3); 825 break; 826 case BCM47XX_BOARD_NETGEAR_WNR3500L: 827 err = bcm47xx_add_bdata(bcm47xx_buttons_netgear_wnr3500lv1); 828 break; 829 case BCM47XX_BOARD_NETGEAR_WNR3500L_V2: 830 err = bcm47xx_add_bdata(bcm47xx_buttons_netgear_wnr3500lv2); 831 break; 832 case BCM47XX_BOARD_NETGEAR_WNR834BV2: 833 err = bcm47xx_add_bdata(bcm47xx_buttons_netgear_wnr834bv2); 834 break; 835 836 case BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE: 837 err = bcm47xx_add_bdata(bcm47xx_buttons_simpletech_simpleshare); 838 break; 839 840 default: 841 pr_debug("No buttons configuration found for this device\n"); 842 return -ENOTSUPP; 843 } 844 845 if (err) 846 return err; 847 848 return 0; 849 } 850