1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * System Specific setup for Soekris net5501 4 * At the moment this means setup of GPIO control of LEDs and buttons 5 * on net5501 boards. 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 15 #include <linux/kernel.h> 16 #include <linux/init.h> 17 #include <linux/io.h> 18 #include <linux/string.h> 19 #include <linux/input.h> 20 #include <linux/gpio/machine.h> 21 #include <linux/gpio/property.h> 22 23 #include <asm/geode.h> 24 25 #include "geode-common.h" 26 27 #define BIOS_REGION_BASE 0xffff0000 28 #define BIOS_REGION_SIZE 0x00010000 29 30 static const struct geode_led net5501_leds[] __initconst = { 31 { 6, true }, 32 }; 33 34 static void __init register_net5501(void) 35 { 36 geode_create_restart_key(24); 37 geode_create_leds("net5501", net5501_leds, ARRAY_SIZE(net5501_leds)); 38 } 39 40 struct net5501_board { 41 u16 offset; 42 u16 len; 43 char *sig; 44 }; 45 46 static struct net5501_board __initdata boards[] = { 47 { 0xb7b, 7, "net5501" }, /* net5501 v1.33/1.33c */ 48 { 0xb1f, 7, "net5501" }, /* net5501 v1.32i */ 49 }; 50 51 static bool __init net5501_present(void) 52 { 53 int i; 54 unsigned char *rombase, *bios; 55 bool found = false; 56 57 rombase = ioremap(BIOS_REGION_BASE, BIOS_REGION_SIZE - 1); 58 if (!rombase) { 59 printk(KERN_ERR "%s: failed to get rombase\n", KBUILD_MODNAME); 60 return found; 61 } 62 63 bios = rombase + 0x20; /* null terminated */ 64 65 if (memcmp(bios, "comBIOS", 7)) 66 goto unmap; 67 68 for (i = 0; i < ARRAY_SIZE(boards); i++) { 69 unsigned char *model = rombase + boards[i].offset; 70 71 if (!memcmp(model, boards[i].sig, boards[i].len)) { 72 printk(KERN_INFO "%s: system is recognized as \"%s\"\n", 73 KBUILD_MODNAME, model); 74 75 found = true; 76 break; 77 } 78 } 79 80 unmap: 81 iounmap(rombase); 82 return found; 83 } 84 85 static int __init net5501_init(void) 86 { 87 if (!is_geode()) 88 return 0; 89 90 if (!net5501_present()) 91 return 0; 92 93 register_net5501(); 94 95 return 0; 96 } 97 device_initcall(net5501_init); 98