Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.9 148 lines 3.3 kB view raw
1/* 2 * System Specific setup for Soekris net5501 3 * At the moment this means setup of GPIO control of LEDs and buttons 4 * on net5501 boards. 5 * 6 * 7 * Copyright (C) 2008-2009 Tower Technologies 8 * Written by Alessandro Zummo <a.zummo@towertech.it> 9 * 10 * Copyright (C) 2008 Constantin Baranov <const@mimas.ru> 11 * Copyright (C) 2011 Ed Wildgoose <kernel@wildgooses.com> 12 * and Philip Prindeville <philipp@redfish-solutions.com> 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License version 2 16 * as published by the Free Software Foundation. 17 */ 18 19#include <linux/kernel.h> 20#include <linux/init.h> 21#include <linux/io.h> 22#include <linux/string.h> 23#include <linux/leds.h> 24#include <linux/platform_device.h> 25#include <linux/gpio.h> 26#include <linux/input.h> 27#include <linux/gpio_keys.h> 28 29#include <asm/geode.h> 30 31#define BIOS_REGION_BASE 0xffff0000 32#define BIOS_REGION_SIZE 0x00010000 33 34static struct gpio_keys_button net5501_gpio_buttons[] = { 35 { 36 .code = KEY_RESTART, 37 .gpio = 24, 38 .active_low = 1, 39 .desc = "Reset button", 40 .type = EV_KEY, 41 .wakeup = 0, 42 .debounce_interval = 100, 43 .can_disable = 0, 44 } 45}; 46static struct gpio_keys_platform_data net5501_buttons_data = { 47 .buttons = net5501_gpio_buttons, 48 .nbuttons = ARRAY_SIZE(net5501_gpio_buttons), 49 .poll_interval = 20, 50}; 51 52static struct platform_device net5501_buttons_dev = { 53 .name = "gpio-keys-polled", 54 .id = 1, 55 .dev = { 56 .platform_data = &net5501_buttons_data, 57 } 58}; 59 60static struct gpio_led net5501_leds[] = { 61 { 62 .name = "net5501:1", 63 .gpio = 6, 64 .default_trigger = "default-on", 65 .active_low = 0, 66 }, 67}; 68 69static struct gpio_led_platform_data net5501_leds_data = { 70 .num_leds = ARRAY_SIZE(net5501_leds), 71 .leds = net5501_leds, 72}; 73 74static struct platform_device net5501_leds_dev = { 75 .name = "leds-gpio", 76 .id = -1, 77 .dev.platform_data = &net5501_leds_data, 78}; 79 80static struct platform_device *net5501_devs[] __initdata = { 81 &net5501_buttons_dev, 82 &net5501_leds_dev, 83}; 84 85static void __init register_net5501(void) 86{ 87 /* Setup LED control through leds-gpio driver */ 88 platform_add_devices(net5501_devs, ARRAY_SIZE(net5501_devs)); 89} 90 91struct net5501_board { 92 u16 offset; 93 u16 len; 94 char *sig; 95}; 96 97static struct net5501_board __initdata boards[] = { 98 { 0xb7b, 7, "net5501" }, /* net5501 v1.33/1.33c */ 99 { 0xb1f, 7, "net5501" }, /* net5501 v1.32i */ 100}; 101 102static bool __init net5501_present(void) 103{ 104 int i; 105 unsigned char *rombase, *bios; 106 bool found = false; 107 108 rombase = ioremap(BIOS_REGION_BASE, BIOS_REGION_SIZE - 1); 109 if (!rombase) { 110 printk(KERN_ERR "%s: failed to get rombase\n", KBUILD_MODNAME); 111 return found; 112 } 113 114 bios = rombase + 0x20; /* null terminated */ 115 116 if (memcmp(bios, "comBIOS", 7)) 117 goto unmap; 118 119 for (i = 0; i < ARRAY_SIZE(boards); i++) { 120 unsigned char *model = rombase + boards[i].offset; 121 122 if (!memcmp(model, boards[i].sig, boards[i].len)) { 123 printk(KERN_INFO "%s: system is recognized as \"%s\"\n", 124 KBUILD_MODNAME, model); 125 126 found = true; 127 break; 128 } 129 } 130 131unmap: 132 iounmap(rombase); 133 return found; 134} 135 136static int __init net5501_init(void) 137{ 138 if (!is_geode()) 139 return 0; 140 141 if (!net5501_present()) 142 return 0; 143 144 register_net5501(); 145 146 return 0; 147} 148device_initcall(net5501_init);