1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
23197059aSPhilip A. Prindeville /*
33197059aSPhilip A. Prindeville * System Specific setup for Traverse Technologies GEOS.
43197059aSPhilip A. Prindeville * At the moment this means setup of GPIO control of LEDs.
53197059aSPhilip A. Prindeville *
63197059aSPhilip A. Prindeville * Copyright (C) 2008 Constantin Baranov <const@mimas.ru>
73197059aSPhilip A. Prindeville * Copyright (C) 2011 Ed Wildgoose <kernel@wildgooses.com>
83197059aSPhilip A. Prindeville * and Philip Prindeville <philipp@redfish-solutions.com>
93197059aSPhilip A. Prindeville *
103197059aSPhilip A. Prindeville * TODO: There are large similarities with leds-net5501.c
113197059aSPhilip A. Prindeville * by Alessandro Zummo <a.zummo@towertech.it>
123197059aSPhilip A. Prindeville * In the future leds-net5501.c should be migrated over to platform
133197059aSPhilip A. Prindeville */
143197059aSPhilip A. Prindeville
153197059aSPhilip A. Prindeville #include <linux/kernel.h>
163197059aSPhilip A. Prindeville #include <linux/init.h>
173197059aSPhilip A. Prindeville #include <linux/io.h>
183197059aSPhilip A. Prindeville #include <linux/string.h>
193197059aSPhilip A. Prindeville #include <linux/leds.h>
203197059aSPhilip A. Prindeville #include <linux/platform_device.h>
213197059aSPhilip A. Prindeville #include <linux/input.h>
223197059aSPhilip A. Prindeville #include <linux/gpio_keys.h>
23*ab20fda2SLinus Walleij #include <linux/gpio/machine.h>
243197059aSPhilip A. Prindeville #include <linux/dmi.h>
253197059aSPhilip A. Prindeville
263197059aSPhilip A. Prindeville #include <asm/geode.h>
273197059aSPhilip A. Prindeville
283197059aSPhilip A. Prindeville static struct gpio_keys_button geos_gpio_buttons[] = {
293197059aSPhilip A. Prindeville {
303197059aSPhilip A. Prindeville .code = KEY_RESTART,
313197059aSPhilip A. Prindeville .gpio = 3,
323197059aSPhilip A. Prindeville .active_low = 1,
333197059aSPhilip A. Prindeville .desc = "Reset button",
343197059aSPhilip A. Prindeville .type = EV_KEY,
353197059aSPhilip A. Prindeville .wakeup = 0,
363197059aSPhilip A. Prindeville .debounce_interval = 100,
373197059aSPhilip A. Prindeville .can_disable = 0,
383197059aSPhilip A. Prindeville }
393197059aSPhilip A. Prindeville };
403197059aSPhilip A. Prindeville static struct gpio_keys_platform_data geos_buttons_data = {
413197059aSPhilip A. Prindeville .buttons = geos_gpio_buttons,
423197059aSPhilip A. Prindeville .nbuttons = ARRAY_SIZE(geos_gpio_buttons),
433197059aSPhilip A. Prindeville .poll_interval = 20,
443197059aSPhilip A. Prindeville };
453197059aSPhilip A. Prindeville
463197059aSPhilip A. Prindeville static struct platform_device geos_buttons_dev = {
473197059aSPhilip A. Prindeville .name = "gpio-keys-polled",
483197059aSPhilip A. Prindeville .id = 1,
493197059aSPhilip A. Prindeville .dev = {
503197059aSPhilip A. Prindeville .platform_data = &geos_buttons_data,
513197059aSPhilip A. Prindeville }
523197059aSPhilip A. Prindeville };
533197059aSPhilip A. Prindeville
543197059aSPhilip A. Prindeville static struct gpio_led geos_leds[] = {
553197059aSPhilip A. Prindeville {
563197059aSPhilip A. Prindeville .name = "geos:1",
573197059aSPhilip A. Prindeville .default_trigger = "default-on",
583197059aSPhilip A. Prindeville },
593197059aSPhilip A. Prindeville {
603197059aSPhilip A. Prindeville .name = "geos:2",
613197059aSPhilip A. Prindeville .default_trigger = "default-off",
623197059aSPhilip A. Prindeville },
633197059aSPhilip A. Prindeville {
643197059aSPhilip A. Prindeville .name = "geos:3",
653197059aSPhilip A. Prindeville .default_trigger = "default-off",
663197059aSPhilip A. Prindeville },
673197059aSPhilip A. Prindeville };
683197059aSPhilip A. Prindeville
693197059aSPhilip A. Prindeville static struct gpio_led_platform_data geos_leds_data = {
703197059aSPhilip A. Prindeville .num_leds = ARRAY_SIZE(geos_leds),
713197059aSPhilip A. Prindeville .leds = geos_leds,
723197059aSPhilip A. Prindeville };
733197059aSPhilip A. Prindeville
74*ab20fda2SLinus Walleij static struct gpiod_lookup_table geos_leds_gpio_table = {
75*ab20fda2SLinus Walleij .dev_id = "leds-gpio",
76*ab20fda2SLinus Walleij .table = {
77*ab20fda2SLinus Walleij /* The Geode GPIOs should be on the CS5535 companion chip */
78*ab20fda2SLinus Walleij GPIO_LOOKUP_IDX("cs5535-gpio", 6, NULL, 0, GPIO_ACTIVE_LOW),
79*ab20fda2SLinus Walleij GPIO_LOOKUP_IDX("cs5535-gpio", 25, NULL, 1, GPIO_ACTIVE_LOW),
80*ab20fda2SLinus Walleij GPIO_LOOKUP_IDX("cs5535-gpio", 27, NULL, 2, GPIO_ACTIVE_LOW),
81*ab20fda2SLinus Walleij { }
82*ab20fda2SLinus Walleij },
83*ab20fda2SLinus Walleij };
84*ab20fda2SLinus Walleij
853197059aSPhilip A. Prindeville static struct platform_device geos_leds_dev = {
863197059aSPhilip A. Prindeville .name = "leds-gpio",
873197059aSPhilip A. Prindeville .id = -1,
883197059aSPhilip A. Prindeville .dev.platform_data = &geos_leds_data,
893197059aSPhilip A. Prindeville };
903197059aSPhilip A. Prindeville
91a6d30e0fSBartlomiej Zolnierkiewicz static struct platform_device *geos_devs[] __initdata = {
923197059aSPhilip A. Prindeville &geos_buttons_dev,
933197059aSPhilip A. Prindeville &geos_leds_dev,
943197059aSPhilip A. Prindeville };
953197059aSPhilip A. Prindeville
register_geos(void)963197059aSPhilip A. Prindeville static void __init register_geos(void)
973197059aSPhilip A. Prindeville {
983197059aSPhilip A. Prindeville /* Setup LED control through leds-gpio driver */
99*ab20fda2SLinus Walleij gpiod_add_lookup_table(&geos_leds_gpio_table);
1003197059aSPhilip A. Prindeville platform_add_devices(geos_devs, ARRAY_SIZE(geos_devs));
1013197059aSPhilip A. Prindeville }
1023197059aSPhilip A. Prindeville
geos_init(void)1033197059aSPhilip A. Prindeville static int __init geos_init(void)
1043197059aSPhilip A. Prindeville {
1053197059aSPhilip A. Prindeville const char *vendor, *product;
1063197059aSPhilip A. Prindeville
1073197059aSPhilip A. Prindeville if (!is_geode())
1083197059aSPhilip A. Prindeville return 0;
1093197059aSPhilip A. Prindeville
1103197059aSPhilip A. Prindeville vendor = dmi_get_system_info(DMI_SYS_VENDOR);
1113197059aSPhilip A. Prindeville if (!vendor || strcmp(vendor, "Traverse Technologies"))
1123197059aSPhilip A. Prindeville return 0;
1133197059aSPhilip A. Prindeville
1143197059aSPhilip A. Prindeville product = dmi_get_system_info(DMI_PRODUCT_NAME);
1153197059aSPhilip A. Prindeville if (!product || strcmp(product, "Geos"))
1163197059aSPhilip A. Prindeville return 0;
1173197059aSPhilip A. Prindeville
1183197059aSPhilip A. Prindeville printk(KERN_INFO "%s: system is recognized as \"%s %s\"\n",
1193197059aSPhilip A. Prindeville KBUILD_MODNAME, vendor, product);
1203197059aSPhilip A. Prindeville
1213197059aSPhilip A. Prindeville register_geos();
1223197059aSPhilip A. Prindeville
1233197059aSPhilip A. Prindeville return 0;
1243197059aSPhilip A. Prindeville }
125eb61aee7SPaul Gortmaker device_initcall(geos_init);
126