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
bcm47xx_buttons_add(const struct bcm47xx_gpio_key * buttons,int nbuttons)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
bcm47xx_buttons_register(void)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