1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * System Specific setup for Traverse Technologies GEOS. |
4 | * At the moment this means setup of GPIO control of LEDs. |
5 | * |
6 | * Copyright (C) 2008 Constantin Baranov <const@mimas.ru> |
7 | * Copyright (C) 2011 Ed Wildgoose <kernel@wildgooses.com> |
8 | * and Philip Prindeville <philipp@redfish-solutions.com> |
9 | * |
10 | * TODO: There are large similarities with leds-net5501.c |
11 | * by Alessandro Zummo <a.zummo@towertech.it> |
12 | * In the future leds-net5501.c should be migrated over to platform |
13 | */ |
14 | |
15 | #include <linux/kernel.h> |
16 | #include <linux/init.h> |
17 | #include <linux/io.h> |
18 | #include <linux/string.h> |
19 | #include <linux/leds.h> |
20 | #include <linux/platform_device.h> |
21 | #include <linux/input.h> |
22 | #include <linux/gpio_keys.h> |
23 | #include <linux/gpio/machine.h> |
24 | #include <linux/dmi.h> |
25 | |
26 | #include <asm/geode.h> |
27 | |
28 | static struct gpio_keys_button geos_gpio_buttons[] = { |
29 | { |
30 | .code = KEY_RESTART, |
31 | .gpio = 3, |
32 | .active_low = 1, |
33 | .desc = "Reset button" , |
34 | .type = EV_KEY, |
35 | .wakeup = 0, |
36 | .debounce_interval = 100, |
37 | .can_disable = 0, |
38 | } |
39 | }; |
40 | static struct gpio_keys_platform_data geos_buttons_data = { |
41 | .buttons = geos_gpio_buttons, |
42 | .nbuttons = ARRAY_SIZE(geos_gpio_buttons), |
43 | .poll_interval = 20, |
44 | }; |
45 | |
46 | static struct platform_device geos_buttons_dev = { |
47 | .name = "gpio-keys-polled" , |
48 | .id = 1, |
49 | .dev = { |
50 | .platform_data = &geos_buttons_data, |
51 | } |
52 | }; |
53 | |
54 | static struct gpio_led geos_leds[] = { |
55 | { |
56 | .name = "geos:1" , |
57 | .default_trigger = "default-on" , |
58 | }, |
59 | { |
60 | .name = "geos:2" , |
61 | .default_trigger = "default-off" , |
62 | }, |
63 | { |
64 | .name = "geos:3" , |
65 | .default_trigger = "default-off" , |
66 | }, |
67 | }; |
68 | |
69 | static struct gpio_led_platform_data geos_leds_data = { |
70 | .num_leds = ARRAY_SIZE(geos_leds), |
71 | .leds = geos_leds, |
72 | }; |
73 | |
74 | static struct gpiod_lookup_table geos_leds_gpio_table = { |
75 | .dev_id = "leds-gpio" , |
76 | .table = { |
77 | /* The Geode GPIOs should be on the CS5535 companion chip */ |
78 | GPIO_LOOKUP_IDX("cs5535-gpio" , 6, NULL, 0, GPIO_ACTIVE_LOW), |
79 | GPIO_LOOKUP_IDX("cs5535-gpio" , 25, NULL, 1, GPIO_ACTIVE_LOW), |
80 | GPIO_LOOKUP_IDX("cs5535-gpio" , 27, NULL, 2, GPIO_ACTIVE_LOW), |
81 | { } |
82 | }, |
83 | }; |
84 | |
85 | static struct platform_device geos_leds_dev = { |
86 | .name = "leds-gpio" , |
87 | .id = -1, |
88 | .dev.platform_data = &geos_leds_data, |
89 | }; |
90 | |
91 | static struct platform_device *geos_devs[] __initdata = { |
92 | &geos_buttons_dev, |
93 | &geos_leds_dev, |
94 | }; |
95 | |
96 | static void __init register_geos(void) |
97 | { |
98 | /* Setup LED control through leds-gpio driver */ |
99 | gpiod_add_lookup_table(table: &geos_leds_gpio_table); |
100 | platform_add_devices(geos_devs, ARRAY_SIZE(geos_devs)); |
101 | } |
102 | |
103 | static int __init geos_init(void) |
104 | { |
105 | const char *vendor, *product; |
106 | |
107 | if (!is_geode()) |
108 | return 0; |
109 | |
110 | vendor = dmi_get_system_info(field: DMI_SYS_VENDOR); |
111 | if (!vendor || strcmp(vendor, "Traverse Technologies" )) |
112 | return 0; |
113 | |
114 | product = dmi_get_system_info(field: DMI_PRODUCT_NAME); |
115 | if (!product || strcmp(product, "Geos" )) |
116 | return 0; |
117 | |
118 | printk(KERN_INFO "%s: system is recognized as \"%s %s\"\n" , |
119 | KBUILD_MODNAME, vendor, product); |
120 | |
121 | register_geos(); |
122 | |
123 | return 0; |
124 | } |
125 | device_initcall(geos_init); |
126 | |