mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-08 17:18:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
37
arch/mips/bcm47xx/Kconfig
Normal file
37
arch/mips/bcm47xx/Kconfig
Normal file
|
@ -0,0 +1,37 @@
|
|||
if BCM47XX
|
||||
|
||||
config BCM47XX_SSB
|
||||
bool "SSB Support for Broadcom BCM47XX"
|
||||
select SYS_HAS_CPU_BMIPS32_3300
|
||||
select SSB
|
||||
select SSB_DRIVER_MIPS
|
||||
select SSB_DRIVER_EXTIF
|
||||
select SSB_EMBEDDED
|
||||
select SSB_B43_PCI_BRIDGE if PCI
|
||||
select SSB_DRIVER_PCICORE if PCI
|
||||
select SSB_PCICORE_HOSTMODE if PCI
|
||||
select SSB_DRIVER_GPIO
|
||||
default y
|
||||
help
|
||||
Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support.
|
||||
|
||||
This will generate an image with support for SSB and MIPS32 R1 instruction set.
|
||||
|
||||
config BCM47XX_BCMA
|
||||
bool "BCMA Support for Broadcom BCM47XX"
|
||||
select SYS_HAS_CPU_MIPS32_R2
|
||||
select SYS_SUPPORTS_HIGHMEM
|
||||
select CPU_MIPSR2_IRQ_VI
|
||||
select BCMA
|
||||
select BCMA_HOST_SOC
|
||||
select BCMA_DRIVER_MIPS
|
||||
select BCMA_HOST_PCI if PCI
|
||||
select BCMA_DRIVER_PCI_HOSTMODE if PCI
|
||||
select BCMA_DRIVER_GPIO
|
||||
default y
|
||||
help
|
||||
Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
|
||||
|
||||
This will generate an image with support for BCMA and MIPS32 R2 instruction set.
|
||||
|
||||
endif
|
7
arch/mips/bcm47xx/Makefile
Normal file
7
arch/mips/bcm47xx/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Makefile for the BCM47XX specific kernel interface routines
|
||||
# under Linux.
|
||||
#
|
||||
|
||||
obj-y += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
|
||||
obj-y += board.o buttons.o leds.o workarounds.o
|
7
arch/mips/bcm47xx/Platform
Normal file
7
arch/mips/bcm47xx/Platform
Normal file
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Broadcom BCM47XX boards
|
||||
#
|
||||
platform-$(CONFIG_BCM47XX) += bcm47xx/
|
||||
cflags-$(CONFIG_BCM47XX) += \
|
||||
-I$(srctree)/arch/mips/include/asm/mach-bcm47xx
|
||||
load-$(CONFIG_BCM47XX) := 0xffffffff80001000
|
18
arch/mips/bcm47xx/bcm47xx_private.h
Normal file
18
arch/mips/bcm47xx/bcm47xx_private.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef LINUX_BCM47XX_PRIVATE_H_
|
||||
#define LINUX_BCM47XX_PRIVATE_H_
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
/* prom.c */
|
||||
void __init bcm47xx_prom_highmem_init(void);
|
||||
|
||||
/* buttons.c */
|
||||
int __init bcm47xx_buttons_register(void);
|
||||
|
||||
/* leds.c */
|
||||
void __init bcm47xx_leds_register(void);
|
||||
|
||||
/* workarounds.c */
|
||||
void __init bcm47xx_workarounds(void);
|
||||
|
||||
#endif
|
353
arch/mips/bcm47xx/board.c
Normal file
353
arch/mips/bcm47xx/board.c
Normal file
|
@ -0,0 +1,353 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/string.h>
|
||||
#include <bcm47xx_board.h>
|
||||
#include <bcm47xx_nvram.h>
|
||||
|
||||
struct bcm47xx_board_type {
|
||||
const enum bcm47xx_board board;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct bcm47xx_board_type_list1 {
|
||||
struct bcm47xx_board_type board;
|
||||
const char *value1;
|
||||
};
|
||||
|
||||
struct bcm47xx_board_type_list2 {
|
||||
struct bcm47xx_board_type board;
|
||||
const char *value1;
|
||||
const char *value2;
|
||||
};
|
||||
|
||||
struct bcm47xx_board_type_list3 {
|
||||
struct bcm47xx_board_type board;
|
||||
const char *value1;
|
||||
const char *value2;
|
||||
const char *value3;
|
||||
};
|
||||
|
||||
struct bcm47xx_board_store {
|
||||
enum bcm47xx_board board;
|
||||
char name[BCM47XX_BOARD_MAX_NAME];
|
||||
};
|
||||
|
||||
/* model_name */
|
||||
static const
|
||||
struct bcm47xx_board_type_list1 bcm47xx_board_list_model_name[] __initconst = {
|
||||
{{BCM47XX_BOARD_DLINK_DIR130, "D-Link DIR-130"}, "DIR-130"},
|
||||
{{BCM47XX_BOARD_DLINK_DIR330, "D-Link DIR-330"}, "DIR-330"},
|
||||
{ {0}, NULL},
|
||||
};
|
||||
|
||||
/* model_no */
|
||||
static const
|
||||
struct bcm47xx_board_type_list1 bcm47xx_board_list_model_no[] __initconst = {
|
||||
{{BCM47XX_BOARD_ASUS_WL700GE, "Asus WL700"}, "WL700"},
|
||||
{ {0}, NULL},
|
||||
};
|
||||
|
||||
/* machine_name */
|
||||
static const
|
||||
struct bcm47xx_board_type_list1 bcm47xx_board_list_machine_name[] __initconst = {
|
||||
{{BCM47XX_BOARD_LINKSYS_WRTSL54GS, "Linksys WRTSL54GS"}, "WRTSL54GS"},
|
||||
{ {0}, NULL},
|
||||
};
|
||||
|
||||
/* hardware_version */
|
||||
static const
|
||||
struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initconst = {
|
||||
{{BCM47XX_BOARD_ASUS_RTN10U, "Asus RT-N10U"}, "RTN10U"},
|
||||
{{BCM47XX_BOARD_ASUS_RTN10D, "Asus RT-N10D"}, "RTN10D"},
|
||||
{{BCM47XX_BOARD_ASUS_RTN12, "Asus RT-N12"}, "RT-N12"},
|
||||
{{BCM47XX_BOARD_ASUS_RTN12B1, "Asus RT-N12B1"}, "RTN12B1"},
|
||||
{{BCM47XX_BOARD_ASUS_RTN12C1, "Asus RT-N12C1"}, "RTN12C1"},
|
||||
{{BCM47XX_BOARD_ASUS_RTN12D1, "Asus RT-N12D1"}, "RTN12D1"},
|
||||
{{BCM47XX_BOARD_ASUS_RTN12HP, "Asus RT-N12HP"}, "RTN12HP"},
|
||||
{{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16-"},
|
||||
{{BCM47XX_BOARD_ASUS_WL320GE, "Asus WL320GE"}, "WL320G-"},
|
||||
{{BCM47XX_BOARD_ASUS_WL330GE, "Asus WL330GE"}, "WL330GE-"},
|
||||
{{BCM47XX_BOARD_ASUS_WL500GD, "Asus WL500GD"}, "WL500gd-"},
|
||||
{{BCM47XX_BOARD_ASUS_WL500GPV1, "Asus WL500GP V1"}, "WL500gp-"},
|
||||
{{BCM47XX_BOARD_ASUS_WL500GPV2, "Asus WL500GP V2"}, "WL500GPV2-"},
|
||||
{{BCM47XX_BOARD_ASUS_WL500W, "Asus WL500W"}, "WL500gW-"},
|
||||
{{BCM47XX_BOARD_ASUS_WL520GC, "Asus WL520GC"}, "WL520GC-"},
|
||||
{{BCM47XX_BOARD_ASUS_WL520GU, "Asus WL520GU"}, "WL520GU-"},
|
||||
{{BCM47XX_BOARD_BELKIN_F7D3301, "Belkin F7D3301"}, "F7D3301"},
|
||||
{{BCM47XX_BOARD_BELKIN_F7D3302, "Belkin F7D3302"}, "F7D3302"},
|
||||
{{BCM47XX_BOARD_BELKIN_F7D4301, "Belkin F7D4301"}, "F7D4301"},
|
||||
{{BCM47XX_BOARD_BELKIN_F7D4302, "Belkin F7D4302"}, "F7D4302"},
|
||||
{{BCM47XX_BOARD_BELKIN_F7D4401, "Belkin F7D4401"}, "F7D4401"},
|
||||
{ {0}, NULL},
|
||||
};
|
||||
|
||||
/* hardware_version, boardnum */
|
||||
static const
|
||||
struct bcm47xx_board_type_list2 bcm47xx_board_list_hw_version_num[] __initconst = {
|
||||
{{BCM47XX_BOARD_MICROSOFT_MN700, "Microsoft MN-700"}, "WL500-", "mn700"},
|
||||
{{BCM47XX_BOARD_ASUS_WL500G, "Asus WL500G"}, "WL500-", "asusX"},
|
||||
{ {0}, NULL},
|
||||
};
|
||||
|
||||
/* productid */
|
||||
static const
|
||||
struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = {
|
||||
{{BCM47XX_BOARD_ASUS_RTAC66U, "Asus RT-AC66U"}, "RT-AC66U"},
|
||||
{{BCM47XX_BOARD_ASUS_RTN10, "Asus RT-N10"}, "RT-N10"},
|
||||
{{BCM47XX_BOARD_ASUS_RTN10D, "Asus RT-N10D"}, "RT-N10D"},
|
||||
{{BCM47XX_BOARD_ASUS_RTN15U, "Asus RT-N15U"}, "RT-N15U"},
|
||||
{{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16"},
|
||||
{{BCM47XX_BOARD_ASUS_RTN53, "Asus RT-N53"}, "RT-N53"},
|
||||
{{BCM47XX_BOARD_ASUS_RTN66U, "Asus RT-N66U"}, "RT-N66U"},
|
||||
{{BCM47XX_BOARD_ASUS_WL300G, "Asus WL300G"}, "WL300g"},
|
||||
{{BCM47XX_BOARD_ASUS_WLHDD, "Asus WLHDD"}, "WLHDD"},
|
||||
{ {0}, NULL},
|
||||
};
|
||||
|
||||
/* ModelId */
|
||||
static const
|
||||
struct bcm47xx_board_type_list1 bcm47xx_board_list_ModelId[] __initconst = {
|
||||
{{BCM47XX_BOARD_DELL_TM2300, "Dell TrueMobile 2300"}, "WX-5565"},
|
||||
{{BCM47XX_BOARD_MOTOROLA_WE800G, "Motorola WE800G"}, "WE800G"},
|
||||
{{BCM47XX_BOARD_MOTOROLA_WR850GP, "Motorola WR850GP"}, "WR850GP"},
|
||||
{{BCM47XX_BOARD_MOTOROLA_WR850GV2V3, "Motorola WR850G"}, "WR850G"},
|
||||
{ {0}, NULL},
|
||||
};
|
||||
|
||||
/* melco_id or buf1falo_id */
|
||||
static const
|
||||
struct bcm47xx_board_type_list1 bcm47xx_board_list_melco_id[] __initconst = {
|
||||
{{BCM47XX_BOARD_BUFFALO_WBR2_G54, "Buffalo WBR2-G54"}, "29bb0332"},
|
||||
{{BCM47XX_BOARD_BUFFALO_WHR2_A54G54, "Buffalo WHR2-A54G54"}, "290441dd"},
|
||||
{{BCM47XX_BOARD_BUFFALO_WHR_G125, "Buffalo WHR-G125"}, "32093"},
|
||||
{{BCM47XX_BOARD_BUFFALO_WHR_G54S, "Buffalo WHR-G54S"}, "30182"},
|
||||
{{BCM47XX_BOARD_BUFFALO_WHR_HP_G54, "Buffalo WHR-HP-G54"}, "30189"},
|
||||
{{BCM47XX_BOARD_BUFFALO_WLA2_G54L, "Buffalo WLA2-G54L"}, "29129"},
|
||||
{{BCM47XX_BOARD_BUFFALO_WZR_G300N, "Buffalo WZR-G300N"}, "31120"},
|
||||
{{BCM47XX_BOARD_BUFFALO_WZR_RS_G54, "Buffalo WZR-RS-G54"}, "30083"},
|
||||
{{BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP, "Buffalo WZR-RS-G54HP"}, "30103"},
|
||||
{ {0}, NULL},
|
||||
};
|
||||
|
||||
/* boot_hw_model, boot_hw_ver */
|
||||
static const
|
||||
struct bcm47xx_board_type_list2 bcm47xx_board_list_boot_hw[] __initconst = {
|
||||
/* like WRT160N v3.0 */
|
||||
{{BCM47XX_BOARD_CISCO_M10V1, "Cisco M10"}, "M10", "1.0"},
|
||||
/* like WRT310N v2.0 */
|
||||
{{BCM47XX_BOARD_CISCO_M20V1, "Cisco M20"}, "M20", "1.0"},
|
||||
{{BCM47XX_BOARD_LINKSYS_E900V1, "Linksys E900 V1"}, "E900", "1.0"},
|
||||
/* like WRT160N v3.0 */
|
||||
{{BCM47XX_BOARD_LINKSYS_E1000V1, "Linksys E1000 V1"}, "E100", "1.0"},
|
||||
{{BCM47XX_BOARD_LINKSYS_E1000V2, "Linksys E1000 V2"}, "E1000", "2.0"},
|
||||
{{BCM47XX_BOARD_LINKSYS_E1000V21, "Linksys E1000 V2.1"}, "E1000", "2.1"},
|
||||
{{BCM47XX_BOARD_LINKSYS_E1200V2, "Linksys E1200 V2"}, "E1200", "2.0"},
|
||||
{{BCM47XX_BOARD_LINKSYS_E2000V1, "Linksys E2000 V1"}, "Linksys E2000", "1.0"},
|
||||
/* like WRT610N v2.0 */
|
||||
{{BCM47XX_BOARD_LINKSYS_E3000V1, "Linksys E3000 V1"}, "E300", "1.0"},
|
||||
{{BCM47XX_BOARD_LINKSYS_E3200V1, "Linksys E3200 V1"}, "E3200", "1.0"},
|
||||
{{BCM47XX_BOARD_LINKSYS_E4200V1, "Linksys E4200 V1"}, "E4200", "1.0"},
|
||||
{{BCM47XX_BOARD_LINKSYS_WRT150NV11, "Linksys WRT150N V1.1"}, "WRT150N", "1.1"},
|
||||
{{BCM47XX_BOARD_LINKSYS_WRT150NV1, "Linksys WRT150N V1"}, "WRT150N", "1"},
|
||||
{{BCM47XX_BOARD_LINKSYS_WRT160NV1, "Linksys WRT160N V1"}, "WRT160N", "1.0"},
|
||||
{{BCM47XX_BOARD_LINKSYS_WRT160NV3, "Linksys WRT160N V3"}, "WRT160N", "3.0"},
|
||||
{{BCM47XX_BOARD_LINKSYS_WRT300NV11, "Linksys WRT300N V1.1"}, "WRT300N", "1.1"},
|
||||
{{BCM47XX_BOARD_LINKSYS_WRT310NV1, "Linksys WRT310N V1"}, "WRT310N", "1.0"},
|
||||
{{BCM47XX_BOARD_LINKSYS_WRT310NV2, "Linksys WRT310N V2"}, "WRT310N", "2.0"},
|
||||
{{BCM47XX_BOARD_LINKSYS_WRT54G3GV2, "Linksys WRT54G3GV2-VF"}, "WRT54G3GV2-VF", "1.0"},
|
||||
{{BCM47XX_BOARD_LINKSYS_WRT610NV1, "Linksys WRT610N V1"}, "WRT610N", "1.0"},
|
||||
{{BCM47XX_BOARD_LINKSYS_WRT610NV2, "Linksys WRT610N V2"}, "WRT610N", "2.0"},
|
||||
{ {0}, NULL},
|
||||
};
|
||||
|
||||
/* board_id */
|
||||
static const
|
||||
struct bcm47xx_board_type_list1 bcm47xx_board_list_board_id[] __initconst = {
|
||||
{{BCM47XX_BOARD_NETGEAR_WGR614V8, "Netgear WGR614 V8"}, "U12H072T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WGR614V9, "Netgear WGR614 V9"}, "U12H094T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNDR3300, "Netgear WNDR3300"}, "U12H093T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNDR3400V1, "Netgear WNDR3400 V1"}, "U12H155T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNDR3400V2, "Netgear WNDR3400 V2"}, "U12H187T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNDR3400VCNA, "Netgear WNDR3400 Vcna"}, "U12H155T01_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNDR3700V3, "Netgear WNDR3700 V3"}, "U12H194T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNDR4000, "Netgear WNDR4000"}, "U12H181T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNDR4500V1, "Netgear WNDR4500 V1"}, "U12H189T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNDR4500V2, "Netgear WNDR4500 V2"}, "U12H224T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNR2000, "Netgear WNR2000"}, "U12H114T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "U12H136T99_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNR3500U, "Netgear WNR3500U"}, "U12H136T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNR3500V2, "Netgear WNR3500 V2"}, "U12H127T00_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNR3500V2VC, "Netgear WNR3500 V2vc"}, "U12H127T70_NETGEAR"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNR834BV2, "Netgear WNR834B V2"}, "U12H081T00_NETGEAR"},
|
||||
{ {0}, NULL},
|
||||
};
|
||||
|
||||
/* boardtype, boardnum, boardrev */
|
||||
static const
|
||||
struct bcm47xx_board_type_list3 bcm47xx_board_list_board[] __initconst = {
|
||||
{{BCM47XX_BOARD_HUAWEI_E970, "Huawei E970"}, "0x048e", "0x5347", "0x11"},
|
||||
{{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"},
|
||||
{{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"},
|
||||
{{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "0x04CF", "3500", "02"},
|
||||
{{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101, "Linksys WRT54G/GS/GL"}, "0x0101", "42", "0x10"},
|
||||
{{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467, "Linksys WRT54G/GS/GL"}, "0x0467", "42", "0x10"},
|
||||
{{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708, "Linksys WRT54G/GS/GL"}, "0x0708", "42", "0x10"},
|
||||
{ {0}, NULL},
|
||||
};
|
||||
|
||||
/* boardtype, boardrev */
|
||||
static const
|
||||
struct bcm47xx_board_type_list2 bcm47xx_board_list_board_type_rev[] __initconst = {
|
||||
{{BCM47XX_BOARD_SIEMENS_SE505V2, "Siemens SE505 V2"}, "0x0101", "0x10"},
|
||||
{ {0}, NULL},
|
||||
};
|
||||
|
||||
static const
|
||||
struct bcm47xx_board_type bcm47xx_board_unknown[] __initconst = {
|
||||
{BCM47XX_BOARD_UNKNOWN, "Unknown Board"},
|
||||
};
|
||||
|
||||
static struct bcm47xx_board_store bcm47xx_board = {BCM47XX_BOARD_NO, "Unknown Board"};
|
||||
|
||||
static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void)
|
||||
{
|
||||
char buf1[30];
|
||||
char buf2[30];
|
||||
char buf3[30];
|
||||
const struct bcm47xx_board_type_list1 *e1;
|
||||
const struct bcm47xx_board_type_list2 *e2;
|
||||
const struct bcm47xx_board_type_list3 *e3;
|
||||
|
||||
if (bcm47xx_nvram_getenv("model_name", buf1, sizeof(buf1)) >= 0) {
|
||||
for (e1 = bcm47xx_board_list_model_name; e1->value1; e1++) {
|
||||
if (!strcmp(buf1, e1->value1))
|
||||
return &e1->board;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcm47xx_nvram_getenv("model_no", buf1, sizeof(buf1)) >= 0) {
|
||||
for (e1 = bcm47xx_board_list_model_no; e1->value1; e1++) {
|
||||
if (strstarts(buf1, e1->value1))
|
||||
return &e1->board;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcm47xx_nvram_getenv("machine_name", buf1, sizeof(buf1)) >= 0) {
|
||||
for (e1 = bcm47xx_board_list_machine_name; e1->value1; e1++) {
|
||||
if (strstarts(buf1, e1->value1))
|
||||
return &e1->board;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0) {
|
||||
for (e1 = bcm47xx_board_list_hardware_version; e1->value1; e1++) {
|
||||
if (strstarts(buf1, e1->value1))
|
||||
return &e1->board;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0 &&
|
||||
bcm47xx_nvram_getenv("boardnum", buf2, sizeof(buf2)) >= 0) {
|
||||
for (e2 = bcm47xx_board_list_hw_version_num; e2->value1; e2++) {
|
||||
if (!strstarts(buf1, e2->value1) &&
|
||||
!strcmp(buf2, e2->value2))
|
||||
return &e2->board;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcm47xx_nvram_getenv("productid", buf1, sizeof(buf1)) >= 0) {
|
||||
for (e1 = bcm47xx_board_list_productid; e1->value1; e1++) {
|
||||
if (!strcmp(buf1, e1->value1))
|
||||
return &e1->board;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcm47xx_nvram_getenv("ModelId", buf1, sizeof(buf1)) >= 0) {
|
||||
for (e1 = bcm47xx_board_list_ModelId; e1->value1; e1++) {
|
||||
if (!strcmp(buf1, e1->value1))
|
||||
return &e1->board;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcm47xx_nvram_getenv("melco_id", buf1, sizeof(buf1)) >= 0 ||
|
||||
bcm47xx_nvram_getenv("buf1falo_id", buf1, sizeof(buf1)) >= 0) {
|
||||
/* buffalo hardware, check id for specific hardware matches */
|
||||
for (e1 = bcm47xx_board_list_melco_id; e1->value1; e1++) {
|
||||
if (!strcmp(buf1, e1->value1))
|
||||
return &e1->board;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcm47xx_nvram_getenv("boot_hw_model", buf1, sizeof(buf1)) >= 0 &&
|
||||
bcm47xx_nvram_getenv("boot_hw_ver", buf2, sizeof(buf2)) >= 0) {
|
||||
for (e2 = bcm47xx_board_list_boot_hw; e2->value1; e2++) {
|
||||
if (!strcmp(buf1, e2->value1) &&
|
||||
!strcmp(buf2, e2->value2))
|
||||
return &e2->board;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcm47xx_nvram_getenv("board_id", buf1, sizeof(buf1)) >= 0) {
|
||||
for (e1 = bcm47xx_board_list_board_id; e1->value1; e1++) {
|
||||
if (!strcmp(buf1, e1->value1))
|
||||
return &e1->board;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcm47xx_nvram_getenv("boardtype", buf1, sizeof(buf1)) >= 0 &&
|
||||
bcm47xx_nvram_getenv("boardnum", buf2, sizeof(buf2)) >= 0 &&
|
||||
bcm47xx_nvram_getenv("boardrev", buf3, sizeof(buf3)) >= 0) {
|
||||
for (e3 = bcm47xx_board_list_board; e3->value1; e3++) {
|
||||
if (!strcmp(buf1, e3->value1) &&
|
||||
!strcmp(buf2, e3->value2) &&
|
||||
!strcmp(buf3, e3->value3))
|
||||
return &e3->board;
|
||||
}
|
||||
}
|
||||
|
||||
if (bcm47xx_nvram_getenv("boardtype", buf1, sizeof(buf1)) >= 0 &&
|
||||
bcm47xx_nvram_getenv("boardrev", buf2, sizeof(buf2)) >= 0 &&
|
||||
bcm47xx_nvram_getenv("boardnum", buf3, sizeof(buf3)) == -ENOENT) {
|
||||
for (e2 = bcm47xx_board_list_board_type_rev; e2->value1; e2++) {
|
||||
if (!strcmp(buf1, e2->value1) &&
|
||||
!strcmp(buf2, e2->value2))
|
||||
return &e2->board;
|
||||
}
|
||||
}
|
||||
return bcm47xx_board_unknown;
|
||||
}
|
||||
|
||||
void __init bcm47xx_board_detect(void)
|
||||
{
|
||||
int err;
|
||||
char buf[10];
|
||||
const struct bcm47xx_board_type *board_detected;
|
||||
|
||||
if (bcm47xx_board.board != BCM47XX_BOARD_NO)
|
||||
return;
|
||||
|
||||
/* check if the nvram is available */
|
||||
err = bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf));
|
||||
|
||||
/* init of nvram failed, probably too early now */
|
||||
if (err == -ENXIO) {
|
||||
return;
|
||||
}
|
||||
|
||||
board_detected = bcm47xx_board_get_nvram();
|
||||
bcm47xx_board.board = board_detected->board;
|
||||
strlcpy(bcm47xx_board.name, board_detected->name,
|
||||
BCM47XX_BOARD_MAX_NAME);
|
||||
}
|
||||
|
||||
enum bcm47xx_board bcm47xx_board_get(void)
|
||||
{
|
||||
return bcm47xx_board.board;
|
||||
}
|
||||
EXPORT_SYMBOL(bcm47xx_board_get);
|
||||
|
||||
const char *bcm47xx_board_get_name(void)
|
||||
{
|
||||
return bcm47xx_board.name;
|
||||
}
|
||||
EXPORT_SYMBOL(bcm47xx_board_get_name);
|
592
arch/mips/bcm47xx/buttons.c
Normal file
592
arch/mips/bcm47xx/buttons.c
Normal file
|
@ -0,0 +1,592 @@
|
|||
#include "bcm47xx_private.h"
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <bcm47xx_board.h>
|
||||
#include <bcm47xx.h>
|
||||
|
||||
/**************************************************
|
||||
* Database
|
||||
**************************************************/
|
||||
|
||||
#define BCM47XX_GPIO_KEY(_gpio, _code) \
|
||||
{ \
|
||||
.code = _code, \
|
||||
.gpio = _gpio, \
|
||||
.active_low = 1, \
|
||||
}
|
||||
|
||||
/* Asus */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_rtn12[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(1, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(4, BTN_0), /* Router mode */
|
||||
BCM47XX_GPIO_KEY(5, BTN_1), /* Repeater mode */
|
||||
BCM47XX_GPIO_KEY(6, BTN_2), /* AP mode */
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_rtn16[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(8, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_rtn66u[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(9, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wl300g[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wl320ge[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wl330ge[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(2, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wl500g[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wl500gd[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wl500gpv1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(0, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wl500gpv2[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(2, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wl500w[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(7, KEY_WPS_BUTTON),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wl520gc[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(2, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wl520gu[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(2, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wl700ge[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(0, KEY_POWER), /* Hard disk power switch */
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), /* EZSetup */
|
||||
BCM47XX_GPIO_KEY(6, KEY_COPY), /* Copy data from USB to internal disk */
|
||||
BCM47XX_GPIO_KEY(7, KEY_RESTART), /* Hard reset */
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_asus_wlhdd[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
/* Huawei */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_huawei_e970[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
/* Belkin */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_belkin_f7d4301[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
|
||||
};
|
||||
|
||||
/* Buffalo */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_buffalo_whr2_a54g54[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_buffalo_whr_g125[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(4, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_buffalo_whr_g54s[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(4, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_buffalo_whr_hp_g54[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(4, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_buffalo_wzr_g300n[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_buffalo_wzr_rs_g54[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(4, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_buffalo_wzr_rs_g54hp[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(4, KEY_RESTART),
|
||||
};
|
||||
|
||||
/* Dell */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_dell_tm2300[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(0, KEY_RESTART),
|
||||
};
|
||||
|
||||
/* D-Link */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_dlink_dir130[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(3, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(7, KEY_UNKNOWN),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_dlink_dir330[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(3, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(7, KEY_UNKNOWN),
|
||||
};
|
||||
|
||||
/* Linksys */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_e1000v1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_e1000v21[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(9, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(10, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_e2000v1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(8, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_e3000v1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_e3200v1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(5, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_e4200v1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_wrt150nv1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_wrt150nv11[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_wrt160nv1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_wrt160nv3[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_wrt300nv11[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_UNKNOWN),
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_wrt310nv1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(8, KEY_UNKNOWN),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_wrt54g3gv2[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(5, KEY_WIMAX),
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_wrt54g_generic[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_wrt610nv1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_wrt610nv2[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_linksys_wrtsl54gs[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
/* Microsoft */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_microsoft_nm700[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(7, KEY_RESTART),
|
||||
};
|
||||
|
||||
/* Motorola */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_motorola_we800g[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(0, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_motorola_wr850gp[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(5, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_motorola_wr850gv2v3[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(5, KEY_RESTART),
|
||||
};
|
||||
|
||||
/* Netgear */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_netgear_wndr3400v1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(8, KEY_RFKILL),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_netgear_wndr3700v3[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(2, KEY_RFKILL),
|
||||
BCM47XX_GPIO_KEY(3, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_netgear_wndr4500v1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
|
||||
BCM47XX_GPIO_KEY(5, KEY_RFKILL),
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_netgear_wnr3500lv1[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(4, KEY_RESTART),
|
||||
BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
|
||||
};
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_netgear_wnr834bv2[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(6, KEY_RESTART),
|
||||
};
|
||||
|
||||
/* SimpleTech */
|
||||
|
||||
static const struct gpio_keys_button
|
||||
bcm47xx_buttons_simpletech_simpleshare[] __initconst = {
|
||||
BCM47XX_GPIO_KEY(0, KEY_RESTART),
|
||||
};
|
||||
|
||||
/**************************************************
|
||||
* Init
|
||||
**************************************************/
|
||||
|
||||
static struct gpio_keys_platform_data bcm47xx_button_pdata;
|
||||
|
||||
static struct platform_device bcm47xx_buttons_gpio_keys = {
|
||||
.name = "gpio-keys",
|
||||
.dev = {
|
||||
.platform_data = &bcm47xx_button_pdata,
|
||||
}
|
||||
};
|
||||
|
||||
/* Copy data from __initconst */
|
||||
static int __init bcm47xx_buttons_copy(const struct gpio_keys_button *buttons,
|
||||
size_t nbuttons)
|
||||
{
|
||||
size_t size = nbuttons * sizeof(*buttons);
|
||||
|
||||
bcm47xx_button_pdata.buttons = kmalloc(size, GFP_KERNEL);
|
||||
if (!bcm47xx_button_pdata.buttons)
|
||||
return -ENOMEM;
|
||||
memcpy(bcm47xx_button_pdata.buttons, buttons, size);
|
||||
bcm47xx_button_pdata.nbuttons = nbuttons;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define bcm47xx_copy_bdata(dev_buttons) \
|
||||
bcm47xx_buttons_copy(dev_buttons, ARRAY_SIZE(dev_buttons));
|
||||
|
||||
int __init bcm47xx_buttons_register(void)
|
||||
{
|
||||
enum bcm47xx_board board = bcm47xx_board_get();
|
||||
int err;
|
||||
|
||||
switch (board) {
|
||||
case BCM47XX_BOARD_ASUS_RTN12:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn12);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_RTN16:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn16);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_RTN66U:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn66u);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL300G:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl300g);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL320GE:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl320ge);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL330GE:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl330ge);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL500G:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500g);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL500GD:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gd);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL500GPV1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gpv1);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL500GPV2:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gpv2);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL500W:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500w);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL520GC:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl520gc);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL520GU:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl520gu);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL700GE:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl700ge);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WLHDD:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wlhdd);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_BELKIN_F7D3301:
|
||||
case BCM47XX_BOARD_BELKIN_F7D3302:
|
||||
case BCM47XX_BOARD_BELKIN_F7D4301:
|
||||
case BCM47XX_BOARD_BELKIN_F7D4302:
|
||||
case BCM47XX_BOARD_BELKIN_F7D4401:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_belkin_f7d4301);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_BUFFALO_WHR2_A54G54:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr2_a54g54);
|
||||
break;
|
||||
case BCM47XX_BOARD_BUFFALO_WHR_G125:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_g125);
|
||||
break;
|
||||
case BCM47XX_BOARD_BUFFALO_WHR_G54S:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_g54s);
|
||||
break;
|
||||
case BCM47XX_BOARD_BUFFALO_WHR_HP_G54:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_hp_g54);
|
||||
break;
|
||||
case BCM47XX_BOARD_BUFFALO_WZR_G300N:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_g300n);
|
||||
break;
|
||||
case BCM47XX_BOARD_BUFFALO_WZR_RS_G54:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_rs_g54);
|
||||
break;
|
||||
case BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_rs_g54hp);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_DELL_TM2300:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_dell_tm2300);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_DLINK_DIR130:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_dlink_dir130);
|
||||
break;
|
||||
case BCM47XX_BOARD_DLINK_DIR330:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_dlink_dir330);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_HUAWEI_E970:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_huawei_e970);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_LINKSYS_E1000V1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e1000v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_E1000V21:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e1000v21);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_E2000V1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e2000v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_E3000V1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e3000v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_E3200V1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e3200v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_E4200V1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e4200v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT150NV1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt150nv1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT150NV11:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt150nv11);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT160NV1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt160nv1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT160NV3:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt160nv3);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT300NV11:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt300nv11);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT310NV1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt310nv1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT54G3GV2:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g3gv2);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101:
|
||||
case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467:
|
||||
case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g_generic);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT610NV1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT610NV2:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv2);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRTSL54GS:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrtsl54gs);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_MICROSOFT_MN700:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_microsoft_nm700);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_MOTOROLA_WE800G:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_we800g);
|
||||
break;
|
||||
case BCM47XX_BOARD_MOTOROLA_WR850GP:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_wr850gp);
|
||||
break;
|
||||
case BCM47XX_BOARD_MOTOROLA_WR850GV2V3:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_wr850gv2v3);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_NETGEAR_WNDR3400V1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3400v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_NETGEAR_WNDR3700V3:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3700v3);
|
||||
break;
|
||||
case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_NETGEAR_WNR3500L:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr3500lv1);
|
||||
break;
|
||||
case BCM47XX_BOARD_NETGEAR_WNR834BV2:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr834bv2);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE:
|
||||
err = bcm47xx_copy_bdata(bcm47xx_buttons_simpletech_simpleshare);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_debug("No buttons configuration found for this device\n");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return -ENOMEM;
|
||||
|
||||
err = platform_device_register(&bcm47xx_buttons_gpio_keys);
|
||||
if (err) {
|
||||
pr_err("Failed to register platform device: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
90
arch/mips/bcm47xx/irq.c
Normal file
90
arch/mips/bcm47xx/irq.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/irq_cpu.h>
|
||||
#include <bcm47xx.h>
|
||||
|
||||
asmlinkage void plat_irq_dispatch(void)
|
||||
{
|
||||
u32 cause;
|
||||
|
||||
cause = read_c0_cause() & read_c0_status() & CAUSEF_IP;
|
||||
|
||||
clear_c0_status(cause);
|
||||
|
||||
if (cause & CAUSEF_IP7)
|
||||
do_IRQ(7);
|
||||
if (cause & CAUSEF_IP2)
|
||||
do_IRQ(2);
|
||||
if (cause & CAUSEF_IP3)
|
||||
do_IRQ(3);
|
||||
if (cause & CAUSEF_IP4)
|
||||
do_IRQ(4);
|
||||
if (cause & CAUSEF_IP5)
|
||||
do_IRQ(5);
|
||||
if (cause & CAUSEF_IP6)
|
||||
do_IRQ(6);
|
||||
}
|
||||
|
||||
#define DEFINE_HWx_IRQDISPATCH(x) \
|
||||
static void bcm47xx_hw ## x ## _irqdispatch(void) \
|
||||
{ \
|
||||
do_IRQ(x); \
|
||||
}
|
||||
DEFINE_HWx_IRQDISPATCH(2)
|
||||
DEFINE_HWx_IRQDISPATCH(3)
|
||||
DEFINE_HWx_IRQDISPATCH(4)
|
||||
DEFINE_HWx_IRQDISPATCH(5)
|
||||
DEFINE_HWx_IRQDISPATCH(6)
|
||||
DEFINE_HWx_IRQDISPATCH(7)
|
||||
|
||||
void __init arch_init_irq(void)
|
||||
{
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) {
|
||||
bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core,
|
||||
BCMA_MIPS_MIPS74K_INTMASK(5), 1 << 31);
|
||||
/*
|
||||
* the kernel reads the timer irq from some register and thinks
|
||||
* it's #5, but we offset it by 2 and route to #7
|
||||
*/
|
||||
cp0_compare_irq = 7;
|
||||
}
|
||||
#endif
|
||||
mips_cpu_irq_init();
|
||||
|
||||
if (cpu_has_vint) {
|
||||
pr_info("Setting up vectored interrupts\n");
|
||||
set_vi_handler(2, bcm47xx_hw2_irqdispatch);
|
||||
set_vi_handler(3, bcm47xx_hw3_irqdispatch);
|
||||
set_vi_handler(4, bcm47xx_hw4_irqdispatch);
|
||||
set_vi_handler(5, bcm47xx_hw5_irqdispatch);
|
||||
set_vi_handler(6, bcm47xx_hw6_irqdispatch);
|
||||
set_vi_handler(7, bcm47xx_hw7_irqdispatch);
|
||||
}
|
||||
}
|
657
arch/mips/bcm47xx/leds.c
Normal file
657
arch/mips/bcm47xx/leds.c
Normal file
|
@ -0,0 +1,657 @@
|
|||
#include "bcm47xx_private.h"
|
||||
|
||||
#include <linux/leds.h>
|
||||
#include <bcm47xx_board.h>
|
||||
|
||||
/**************************************************
|
||||
* Database
|
||||
**************************************************/
|
||||
|
||||
#define BCM47XX_GPIO_LED(_gpio, _color, _function, _active_low, \
|
||||
_default_state) \
|
||||
{ \
|
||||
.name = "bcm47xx:" _color ":" _function, \
|
||||
.gpio = _gpio, \
|
||||
.active_low = _active_low, \
|
||||
.default_state = _default_state, \
|
||||
}
|
||||
|
||||
#define BCM47XX_GPIO_LED_TRIGGER(_gpio, _color, _function, _active_low, \
|
||||
_default_trigger) \
|
||||
{ \
|
||||
.name = "bcm47xx:" _color ":" _function, \
|
||||
.gpio = _gpio, \
|
||||
.active_low = _active_low, \
|
||||
.default_state = LEDS_GPIO_DEFSTATE_OFF, \
|
||||
.default_trigger = _default_trigger, \
|
||||
}
|
||||
|
||||
/* Asus */
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_rtn12[] __initconst = {
|
||||
BCM47XX_GPIO_LED(2, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(7, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_rtn15u[] __initconst = {
|
||||
/* TODO: Add "wlan" LED */
|
||||
BCM47XX_GPIO_LED(3, "blue", "wan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(4, "blue", "lan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(6, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(9, "blue", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_rtn16[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(7, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_rtn66u[] __initconst = {
|
||||
BCM47XX_GPIO_LED(12, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(15, "blue", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_wl300g[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_wl320ge[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(2, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(11, "unk", "link", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_wl330ge[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_wl500g[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_wl500gd[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_wl500gpv1[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_wl500gpv2[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_wl500w[] __initconst = {
|
||||
BCM47XX_GPIO_LED(5, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_wl520gc[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_wl520gu[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_wl700ge[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), /* Labeled "READY" (there is no "power" LED). Originally ON, flashing on USB activity. */
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_asus_wlhdd[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(2, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
/* Belkin */
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_belkin_f7d4301[] __initconst = {
|
||||
BCM47XX_GPIO_LED(10, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(11, "amber", "power", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(12, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(13, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(14, "unk", "usb0", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(15, "unk", "usb1", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
/* Buffalo */
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_buffalo_whr2_a54g54[] __initconst = {
|
||||
BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_buffalo_whr_g125[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_buffalo_whr_g54s[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_buffalo_whr_hp_g54[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_buffalo_wzr_g300n[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_buffalo_wzr_rs_g54[] __initconst = {
|
||||
BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "unk", "vpn", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_buffalo_wzr_rs_g54hp[] __initconst = {
|
||||
BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "unk", "vpn", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
/* Dell */
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_dell_tm2300[] __initconst = {
|
||||
BCM47XX_GPIO_LED(6, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(7, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
};
|
||||
|
||||
/* D-Link */
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_dlink_dir130[] __initconst = {
|
||||
BCM47XX_GPIO_LED_TRIGGER(0, "green", "status", 1, "timer"), /* Originally blinking when device is ready, separated from "power" LED */
|
||||
BCM47XX_GPIO_LED(6, "blue", "unk", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_dlink_dir330[] __initconst = {
|
||||
BCM47XX_GPIO_LED_TRIGGER(0, "green", "status", 1, "timer"), /* Originally blinking when device is ready, separated from "power" LED */
|
||||
BCM47XX_GPIO_LED(4, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(6, "blue", "unk", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
/* Huawei */
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_huawei_e970[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
/* Linksys */
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_e1000v1[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(2, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(4, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_e1000v21[] __initconst = {
|
||||
BCM47XX_GPIO_LED(5, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(6, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(7, "amber", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(8, "blue", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_e2000v1[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(2, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(4, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_e3000v1[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(5, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(7, "unk", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_e3200v1[] __initconst = {
|
||||
BCM47XX_GPIO_LED(3, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_e4200v1[] __initconst = {
|
||||
BCM47XX_GPIO_LED(5, "white", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrt150nv1[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrt150nv11[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrt160nv1[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(5, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrt160nv3[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(2, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(4, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrt300nv11[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrt310nv1[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(9, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrt54g_generic[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(7, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrt54g3gv2[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(2, "green", "3g", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(3, "blue", "3g", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
/* Verified on: WRT54GS V1.0 */
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrt54g_type_0101[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "green", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(7, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
/* Verified on: WRT54GL V1.1 */
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrt54g_type_0467[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "green", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(2, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(3, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(7, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrt610nv1[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(9, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrt610nv2[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(5, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(7, "unk", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_linksys_wrtsl54gs[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(7, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
/* Microsoft */
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_microsoft_nm700[] __initconst = {
|
||||
BCM47XX_GPIO_LED(6, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
};
|
||||
|
||||
/* Motorola */
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_motorola_we800g[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "amber", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(2, "unk", "unk", 1, LEDS_GPIO_DEFSTATE_OFF), /* There are only 3 LEDs: Power, Wireless and Device (ethernet) */
|
||||
BCM47XX_GPIO_LED(4, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_motorola_wr850gp[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(6, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_motorola_wr850gv2v3[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
/* Netgear */
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_netgear_wndr3400v1[] __initconst = {
|
||||
BCM47XX_GPIO_LED(2, "green", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(3, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(7, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_netgear_wndr4500v1[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(2, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(3, "amber", "power", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(8, "green", "usb1", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(9, "green", "2ghz", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(11, "blue", "5ghz", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(14, "green", "usb2", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_netgear_wnr3500lv1[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "blue", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(1, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(2, "green", "wan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(3, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(7, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_netgear_wnr834bv2[] __initconst = {
|
||||
BCM47XX_GPIO_LED(2, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
|
||||
BCM47XX_GPIO_LED(3, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(7, "unk", "connected", 0, LEDS_GPIO_DEFSTATE_OFF),
|
||||
};
|
||||
|
||||
/* Siemens */
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_siemens_se505v2[] __initconst = {
|
||||
BCM47XX_GPIO_LED(0, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(3, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
|
||||
BCM47XX_GPIO_LED(5, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
|
||||
};
|
||||
|
||||
/* SimpleTech */
|
||||
|
||||
static const struct gpio_led
|
||||
bcm47xx_leds_simpletech_simpleshare[] __initconst = {
|
||||
BCM47XX_GPIO_LED(1, "unk", "status", 1, LEDS_GPIO_DEFSTATE_OFF), /* "Ready" LED */
|
||||
};
|
||||
|
||||
/**************************************************
|
||||
* Init
|
||||
**************************************************/
|
||||
|
||||
static struct gpio_led_platform_data bcm47xx_leds_pdata;
|
||||
|
||||
#define bcm47xx_set_pdata(dev_leds) do { \
|
||||
bcm47xx_leds_pdata.leds = dev_leds; \
|
||||
bcm47xx_leds_pdata.num_leds = ARRAY_SIZE(dev_leds); \
|
||||
} while (0)
|
||||
|
||||
void __init bcm47xx_leds_register(void)
|
||||
{
|
||||
enum bcm47xx_board board = bcm47xx_board_get();
|
||||
|
||||
switch (board) {
|
||||
case BCM47XX_BOARD_ASUS_RTN12:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_rtn12);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_RTN15U:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_rtn15u);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_RTN16:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_rtn16);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_RTN66U:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_rtn66u);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL300G:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_wl300g);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL320GE:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_wl320ge);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL330GE:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_wl330ge);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL500G:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_wl500g);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL500GD:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gd);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL500GPV1:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gpv1);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL500GPV2:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gpv2);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL500W:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_wl500w);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL520GC:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_wl520gc);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL520GU:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_wl520gu);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WL700GE:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_wl700ge);
|
||||
break;
|
||||
case BCM47XX_BOARD_ASUS_WLHDD:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_asus_wlhdd);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_BELKIN_F7D3301:
|
||||
case BCM47XX_BOARD_BELKIN_F7D3302:
|
||||
case BCM47XX_BOARD_BELKIN_F7D4301:
|
||||
case BCM47XX_BOARD_BELKIN_F7D4302:
|
||||
case BCM47XX_BOARD_BELKIN_F7D4401:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_belkin_f7d4301);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_BUFFALO_WHR2_A54G54:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr2_a54g54);
|
||||
break;
|
||||
case BCM47XX_BOARD_BUFFALO_WHR_G125:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_g125);
|
||||
break;
|
||||
case BCM47XX_BOARD_BUFFALO_WHR_G54S:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_g54s);
|
||||
break;
|
||||
case BCM47XX_BOARD_BUFFALO_WHR_HP_G54:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_hp_g54);
|
||||
break;
|
||||
case BCM47XX_BOARD_BUFFALO_WZR_G300N:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_g300n);
|
||||
break;
|
||||
case BCM47XX_BOARD_BUFFALO_WZR_RS_G54:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_rs_g54);
|
||||
break;
|
||||
case BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_rs_g54hp);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_DELL_TM2300:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_dell_tm2300);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_DLINK_DIR130:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_dlink_dir130);
|
||||
break;
|
||||
case BCM47XX_BOARD_DLINK_DIR330:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_dlink_dir330);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_HUAWEI_E970:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_huawei_e970);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_LINKSYS_E1000V1:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_e1000v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_E1000V21:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_e1000v21);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_E2000V1:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_e2000v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_E3000V1:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_e3000v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_E3200V1:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_e3200v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_E4200V1:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_e4200v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT150NV1:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt150nv1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT150NV11:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt150nv11);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT160NV1:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt160nv1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT160NV3:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt160nv3);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT300NV11:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt300nv11);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT310NV1:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt310nv1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT54G3GV2:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g3gv2);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_type_0101);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_type_0467);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_generic);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT610NV1:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv1);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRT610NV2:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv2);
|
||||
break;
|
||||
case BCM47XX_BOARD_LINKSYS_WRTSL54GS:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_linksys_wrtsl54gs);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_MICROSOFT_MN700:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_microsoft_nm700);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_MOTOROLA_WE800G:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_motorola_we800g);
|
||||
break;
|
||||
case BCM47XX_BOARD_MOTOROLA_WR850GP:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_motorola_wr850gp);
|
||||
break;
|
||||
case BCM47XX_BOARD_MOTOROLA_WR850GV2V3:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_motorola_wr850gv2v3);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_NETGEAR_WNDR3400V1:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr3400v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr4500v1);
|
||||
break;
|
||||
case BCM47XX_BOARD_NETGEAR_WNR3500L:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr3500lv1);
|
||||
break;
|
||||
case BCM47XX_BOARD_NETGEAR_WNR834BV2:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr834bv2);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_SIEMENS_SE505V2:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_siemens_se505v2);
|
||||
break;
|
||||
|
||||
case BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE:
|
||||
bcm47xx_set_pdata(bcm47xx_leds_simpletech_simpleshare);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_debug("No LEDs configuration found for this device\n");
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_led_register_device(-1, &bcm47xx_leds_pdata);
|
||||
}
|
211
arch/mips/bcm47xx/nvram.c
Normal file
211
arch/mips/bcm47xx/nvram.c
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* BCM947xx nvram variable access
|
||||
*
|
||||
* Copyright (C) 2005 Broadcom Corporation
|
||||
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
|
||||
* Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ssb/ssb.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <bcm47xx_nvram.h>
|
||||
#include <asm/mach-bcm47xx/bcm47xx.h>
|
||||
|
||||
static char nvram_buf[NVRAM_SPACE];
|
||||
static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000};
|
||||
|
||||
static u32 find_nvram_size(u32 end)
|
||||
{
|
||||
struct nvram_header *header;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
|
||||
header = (struct nvram_header *)KSEG1ADDR(end - nvram_sizes[i]);
|
||||
if (header->magic == NVRAM_HEADER)
|
||||
return nvram_sizes[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Probe for NVRAM header */
|
||||
static int nvram_find_and_copy(u32 base, u32 lim)
|
||||
{
|
||||
struct nvram_header *header;
|
||||
int i;
|
||||
u32 off;
|
||||
u32 *src, *dst;
|
||||
u32 size;
|
||||
|
||||
/* TODO: when nvram is on nand flash check for bad blocks first. */
|
||||
off = FLASH_MIN;
|
||||
while (off <= lim) {
|
||||
/* Windowed flash access */
|
||||
size = find_nvram_size(base + off);
|
||||
if (size) {
|
||||
header = (struct nvram_header *)KSEG1ADDR(base + off -
|
||||
size);
|
||||
goto found;
|
||||
}
|
||||
off <<= 1;
|
||||
}
|
||||
|
||||
/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
|
||||
header = (struct nvram_header *) KSEG1ADDR(base + 4096);
|
||||
if (header->magic == NVRAM_HEADER) {
|
||||
size = NVRAM_SPACE;
|
||||
goto found;
|
||||
}
|
||||
|
||||
header = (struct nvram_header *) KSEG1ADDR(base + 1024);
|
||||
if (header->magic == NVRAM_HEADER) {
|
||||
size = NVRAM_SPACE;
|
||||
goto found;
|
||||
}
|
||||
|
||||
pr_err("no nvram found\n");
|
||||
return -ENXIO;
|
||||
|
||||
found:
|
||||
|
||||
if (header->len > size)
|
||||
pr_err("The nvram size accoridng to the header seems to be bigger than the partition on flash\n");
|
||||
if (header->len > NVRAM_SPACE)
|
||||
pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
|
||||
header->len, NVRAM_SPACE);
|
||||
|
||||
src = (u32 *) header;
|
||||
dst = (u32 *) nvram_buf;
|
||||
for (i = 0; i < sizeof(struct nvram_header); i += 4)
|
||||
*dst++ = *src++;
|
||||
for (; i < header->len && i < NVRAM_SPACE && i < size; i += 4)
|
||||
*dst++ = le32_to_cpu(*src++);
|
||||
memset(dst, 0x0, NVRAM_SPACE - i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
static int nvram_init_ssb(void)
|
||||
{
|
||||
struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore;
|
||||
u32 base;
|
||||
u32 lim;
|
||||
|
||||
if (mcore->pflash.present) {
|
||||
base = mcore->pflash.window;
|
||||
lim = mcore->pflash.window_size;
|
||||
} else {
|
||||
pr_err("Couldn't find supported flash memory\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return nvram_find_and_copy(base, lim);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
static int nvram_init_bcma(void)
|
||||
{
|
||||
struct bcma_drv_cc *cc = &bcm47xx_bus.bcma.bus.drv_cc;
|
||||
u32 base;
|
||||
u32 lim;
|
||||
|
||||
#ifdef CONFIG_BCMA_NFLASH
|
||||
if (cc->nflash.boot) {
|
||||
base = BCMA_SOC_FLASH1;
|
||||
lim = BCMA_SOC_FLASH1_SZ;
|
||||
} else
|
||||
#endif
|
||||
if (cc->pflash.present) {
|
||||
base = cc->pflash.window;
|
||||
lim = cc->pflash.window_size;
|
||||
#ifdef CONFIG_BCMA_SFLASH
|
||||
} else if (cc->sflash.present) {
|
||||
base = cc->sflash.window;
|
||||
lim = cc->sflash.size;
|
||||
#endif
|
||||
} else {
|
||||
pr_err("Couldn't find supported flash memory\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
return nvram_find_and_copy(base, lim);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int nvram_init(void)
|
||||
{
|
||||
switch (bcm47xx_bus_type) {
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
case BCM47XX_BUS_TYPE_SSB:
|
||||
return nvram_init_ssb();
|
||||
#endif
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
case BCM47XX_BUS_TYPE_BCMA:
|
||||
return nvram_init_bcma();
|
||||
#endif
|
||||
}
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len)
|
||||
{
|
||||
char *var, *value, *end, *eq;
|
||||
int err;
|
||||
|
||||
if (!name)
|
||||
return -EINVAL;
|
||||
|
||||
if (!nvram_buf[0]) {
|
||||
err = nvram_init();
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Look for name=value and return value */
|
||||
var = &nvram_buf[sizeof(struct nvram_header)];
|
||||
end = nvram_buf + sizeof(nvram_buf) - 2;
|
||||
end[0] = end[1] = '\0';
|
||||
for (; *var; var = value + strlen(value) + 1) {
|
||||
eq = strchr(var, '=');
|
||||
if (!eq)
|
||||
break;
|
||||
value = eq + 1;
|
||||
if ((eq - var) == strlen(name) &&
|
||||
strncmp(var, name, (eq - var)) == 0) {
|
||||
return snprintf(val, val_len, "%s", value);
|
||||
}
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
EXPORT_SYMBOL(bcm47xx_nvram_getenv);
|
||||
|
||||
int bcm47xx_nvram_gpio_pin(const char *name)
|
||||
{
|
||||
int i, err;
|
||||
char nvram_var[10];
|
||||
char buf[30];
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
err = snprintf(nvram_var, sizeof(nvram_var), "gpio%i", i);
|
||||
if (err <= 0)
|
||||
continue;
|
||||
err = bcm47xx_nvram_getenv(nvram_var, buf, sizeof(buf));
|
||||
if (err <= 0)
|
||||
continue;
|
||||
if (!strcmp(name, buf))
|
||||
return i;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
EXPORT_SYMBOL(bcm47xx_nvram_gpio_pin);
|
182
arch/mips/bcm47xx/prom.c
Normal file
182
arch/mips/bcm47xx/prom.c
Normal file
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
|
||||
* Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
|
||||
* Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/ssb/ssb_driver_chipcommon.h>
|
||||
#include <linux/ssb/ssb_regs.h>
|
||||
#include <linux/smp.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <bcm47xx.h>
|
||||
#include <bcm47xx_board.h>
|
||||
|
||||
|
||||
static char bcm47xx_system_type[20] = "Broadcom BCM47XX";
|
||||
|
||||
const char *get_system_type(void)
|
||||
{
|
||||
return bcm47xx_system_type;
|
||||
}
|
||||
|
||||
__init void bcm47xx_set_system_type(u16 chip_id)
|
||||
{
|
||||
snprintf(bcm47xx_system_type, sizeof(bcm47xx_system_type),
|
||||
(chip_id > 0x9999) ? "Broadcom BCM%d" :
|
||||
"Broadcom BCM%04X",
|
||||
chip_id);
|
||||
}
|
||||
|
||||
static unsigned long lowmem __initdata;
|
||||
|
||||
static __init void prom_init_mem(void)
|
||||
{
|
||||
unsigned long mem;
|
||||
unsigned long max;
|
||||
unsigned long off;
|
||||
struct cpuinfo_mips *c = ¤t_cpu_data;
|
||||
|
||||
/* Figure out memory size by finding aliases.
|
||||
*
|
||||
* We should theoretically use the mapping from CFE using cfe_enummem().
|
||||
* However as the BCM47XX is mostly used on low-memory systems, we
|
||||
* want to reuse the memory used by CFE (around 4MB). That means cfe_*
|
||||
* functions stop to work at some point during the boot, we should only
|
||||
* call them at the beginning of the boot.
|
||||
*
|
||||
* BCM47XX uses 128MB for addressing the ram, if the system contains
|
||||
* less that that amount of ram it remaps the ram more often into the
|
||||
* available space.
|
||||
*/
|
||||
|
||||
/* Physical address, without mapping to any kernel segment */
|
||||
off = CPHYSADDR((unsigned long)prom_init);
|
||||
|
||||
/* Accessing memory after 128 MiB will cause an exception */
|
||||
max = 128 << 20;
|
||||
|
||||
for (mem = 1 << 20; mem < max; mem += 1 << 20) {
|
||||
/* Loop condition may be not enough, off may be over 1 MiB */
|
||||
if (off + mem >= max) {
|
||||
mem = max;
|
||||
printk(KERN_DEBUG "assume 128MB RAM\n");
|
||||
break;
|
||||
}
|
||||
if (!memcmp(prom_init, prom_init + mem, 32))
|
||||
break;
|
||||
}
|
||||
lowmem = mem;
|
||||
|
||||
/* Ignoring the last page when ddr size is 128M. Cached
|
||||
* accesses to last page is causing the processor to prefetch
|
||||
* using address above 128M stepping out of the ddr address
|
||||
* space.
|
||||
*/
|
||||
if (c->cputype == CPU_74K && (mem == (128 << 20)))
|
||||
mem -= 0x1000;
|
||||
add_memory_region(0, mem, BOOT_MEM_RAM);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the first serial on the chip common core, it is at this position
|
||||
* for sb (ssb) and ai (bcma) bus.
|
||||
*/
|
||||
#define BCM47XX_SERIAL_ADDR (SSB_ENUM_BASE + SSB_CHIPCO_UART0_DATA)
|
||||
|
||||
void __init prom_init(void)
|
||||
{
|
||||
prom_init_mem();
|
||||
setup_8250_early_printk_port(CKSEG1ADDR(BCM47XX_SERIAL_ADDR), 0, 0);
|
||||
}
|
||||
|
||||
void __init prom_free_prom_memory(void)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM)
|
||||
|
||||
#define EXTVBASE 0xc0000000
|
||||
#define ENTRYLO(x) ((pte_val(pfn_pte((x) >> _PFN_SHIFT, PAGE_KERNEL_UNCACHED)) >> 6) | 1)
|
||||
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
/* Stripped version of tlb_init, with the call to build_tlb_refill_handler
|
||||
* dropped. Calling it at this stage causes a hang.
|
||||
*/
|
||||
void __cpuinit early_tlb_init(void)
|
||||
{
|
||||
write_c0_pagemask(PM_DEFAULT_MASK);
|
||||
write_c0_wired(0);
|
||||
temp_tlb_entry = current_cpu_data.tlbsize - 1;
|
||||
local_flush_tlb_all();
|
||||
}
|
||||
|
||||
void __init bcm47xx_prom_highmem_init(void)
|
||||
{
|
||||
unsigned long off = (unsigned long)prom_init;
|
||||
unsigned long extmem = 0;
|
||||
bool highmem_region = false;
|
||||
|
||||
if (WARN_ON(bcm47xx_bus_type != BCM47XX_BUS_TYPE_BCMA))
|
||||
return;
|
||||
|
||||
if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
|
||||
highmem_region = true;
|
||||
|
||||
if (lowmem != 128 << 20 || !highmem_region)
|
||||
return;
|
||||
|
||||
early_tlb_init();
|
||||
|
||||
/* Add one temporary TLB entry to map SDRAM Region 2.
|
||||
* Physical Virtual
|
||||
* 0x80000000 0xc0000000 (1st: 256MB)
|
||||
* 0x90000000 0xd0000000 (2nd: 256MB)
|
||||
*/
|
||||
add_temporary_entry(ENTRYLO(0x80000000),
|
||||
ENTRYLO(0x80000000 + (256 << 20)),
|
||||
EXTVBASE, PM_256M);
|
||||
|
||||
off = EXTVBASE + __pa(off);
|
||||
for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) {
|
||||
if (!memcmp(prom_init, (void *)(off + extmem), 16))
|
||||
break;
|
||||
}
|
||||
extmem -= lowmem;
|
||||
|
||||
early_tlb_init();
|
||||
|
||||
if (!extmem)
|
||||
return;
|
||||
|
||||
pr_warn("Found %lu MiB of extra memory, but highmem is unsupported yet!\n",
|
||||
extmem >> 20);
|
||||
|
||||
/* TODO: Register extra memory */
|
||||
}
|
||||
|
||||
#endif /* defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) */
|
96
arch/mips/bcm47xx/serial.c
Normal file
96
arch/mips/bcm47xx/serial.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_8250.h>
|
||||
#include <linux/ssb/ssb.h>
|
||||
#include <bcm47xx.h>
|
||||
|
||||
static struct plat_serial8250_port uart8250_data[5];
|
||||
|
||||
static struct platform_device uart8250_device = {
|
||||
.name = "serial8250",
|
||||
.id = PLAT8250_DEV_PLATFORM,
|
||||
.dev = {
|
||||
.platform_data = uart8250_data,
|
||||
},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
static int __init uart8250_init_ssb(void)
|
||||
{
|
||||
int i;
|
||||
struct ssb_mipscore *mcore = &(bcm47xx_bus.ssb.mipscore);
|
||||
|
||||
memset(&uart8250_data, 0, sizeof(uart8250_data));
|
||||
|
||||
for (i = 0; i < mcore->nr_serial_ports &&
|
||||
i < ARRAY_SIZE(uart8250_data) - 1; i++) {
|
||||
struct plat_serial8250_port *p = &(uart8250_data[i]);
|
||||
struct ssb_serial_port *ssb_port = &(mcore->serial_ports[i]);
|
||||
|
||||
p->mapbase = (unsigned int) ssb_port->regs;
|
||||
p->membase = (void *) ssb_port->regs;
|
||||
p->irq = ssb_port->irq + 2;
|
||||
p->uartclk = ssb_port->baud_base;
|
||||
p->regshift = ssb_port->reg_shift;
|
||||
p->iotype = UPIO_MEM;
|
||||
p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
|
||||
}
|
||||
return platform_device_register(&uart8250_device);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
static int __init uart8250_init_bcma(void)
|
||||
{
|
||||
int i;
|
||||
struct bcma_drv_cc *cc = &(bcm47xx_bus.bcma.bus.drv_cc);
|
||||
|
||||
memset(&uart8250_data, 0, sizeof(uart8250_data));
|
||||
|
||||
for (i = 0; i < cc->nr_serial_ports &&
|
||||
i < ARRAY_SIZE(uart8250_data) - 1; i++) {
|
||||
struct plat_serial8250_port *p = &(uart8250_data[i]);
|
||||
struct bcma_serial_port *bcma_port;
|
||||
bcma_port = &(cc->serial_ports[i]);
|
||||
|
||||
p->mapbase = (unsigned int) bcma_port->regs;
|
||||
p->membase = (void *) bcma_port->regs;
|
||||
p->irq = bcma_port->irq;
|
||||
p->uartclk = bcma_port->baud_base;
|
||||
p->regshift = bcma_port->reg_shift;
|
||||
p->iotype = UPIO_MEM;
|
||||
p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
|
||||
}
|
||||
return platform_device_register(&uart8250_device);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __init uart8250_init(void)
|
||||
{
|
||||
switch (bcm47xx_bus_type) {
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
case BCM47XX_BUS_TYPE_SSB:
|
||||
return uart8250_init_ssb();
|
||||
#endif
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
case BCM47XX_BUS_TYPE_BCMA:
|
||||
return uart8250_init_bcma();
|
||||
#endif
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
module_init(uart8250_init);
|
||||
|
||||
MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("8250 UART probe driver for the BCM47XX platforms");
|
306
arch/mips/bcm47xx/setup.c
Normal file
306
arch/mips/bcm47xx/setup.c
Normal file
|
@ -0,0 +1,306 @@
|
|||
/*
|
||||
* Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
|
||||
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
|
||||
* Copyright (C) 2006 Michael Buesch <m@bues.ch>
|
||||
* Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org>
|
||||
* Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "bcm47xx_private.h"
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/phy_fixed.h>
|
||||
#include <linux/ssb/ssb.h>
|
||||
#include <linux/ssb/ssb_embedded.h>
|
||||
#include <linux/bcma/bcma_soc.h>
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/idle.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/time.h>
|
||||
#include <bcm47xx.h>
|
||||
#include <bcm47xx_nvram.h>
|
||||
#include <bcm47xx_board.h>
|
||||
|
||||
union bcm47xx_bus bcm47xx_bus;
|
||||
EXPORT_SYMBOL(bcm47xx_bus);
|
||||
|
||||
enum bcm47xx_bus_type bcm47xx_bus_type;
|
||||
EXPORT_SYMBOL(bcm47xx_bus_type);
|
||||
|
||||
static void bcm47xx_machine_restart(char *command)
|
||||
{
|
||||
printk(KERN_ALERT "Please stand by while rebooting the system...\n");
|
||||
local_irq_disable();
|
||||
/* Set the watchdog timer to reset immediately */
|
||||
switch (bcm47xx_bus_type) {
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
case BCM47XX_BUS_TYPE_SSB:
|
||||
if (bcm47xx_bus.ssb.chip_id == 0x4785)
|
||||
write_c0_diag4(1 << 22);
|
||||
ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
|
||||
if (bcm47xx_bus.ssb.chip_id == 0x4785) {
|
||||
__asm__ __volatile__(
|
||||
".set\tmips3\n\t"
|
||||
"sync\n\t"
|
||||
"wait\n\t"
|
||||
".set\tmips0");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
case BCM47XX_BUS_TYPE_BCMA:
|
||||
bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
while (1)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
static void bcm47xx_machine_halt(void)
|
||||
{
|
||||
/* Disable interrupts and watchdog and spin forever */
|
||||
local_irq_disable();
|
||||
switch (bcm47xx_bus_type) {
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
case BCM47XX_BUS_TYPE_SSB:
|
||||
ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
case BCM47XX_BUS_TYPE_BCMA:
|
||||
bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
while (1)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
|
||||
{
|
||||
char prefix[10];
|
||||
|
||||
if (bus->bustype == SSB_BUSTYPE_PCI) {
|
||||
memset(out, 0, sizeof(struct ssb_sprom));
|
||||
snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
|
||||
bus->host_pci->bus->number + 1,
|
||||
PCI_SLOT(bus->host_pci->devfn));
|
||||
bcm47xx_fill_sprom(out, prefix, false);
|
||||
return 0;
|
||||
} else {
|
||||
printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int bcm47xx_get_invariants(struct ssb_bus *bus,
|
||||
struct ssb_init_invariants *iv)
|
||||
{
|
||||
char buf[20];
|
||||
|
||||
/* Fill boardinfo structure */
|
||||
memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
|
||||
|
||||
bcm47xx_fill_ssb_boardinfo(&iv->boardinfo, NULL);
|
||||
|
||||
memset(&iv->sprom, 0, sizeof(struct ssb_sprom));
|
||||
bcm47xx_fill_sprom(&iv->sprom, NULL, false);
|
||||
|
||||
if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
|
||||
iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init bcm47xx_register_ssb(void)
|
||||
{
|
||||
int err;
|
||||
char buf[100];
|
||||
struct ssb_mipscore *mcore;
|
||||
|
||||
err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb);
|
||||
if (err)
|
||||
printk(KERN_WARNING "bcm47xx: someone else already registered"
|
||||
" a ssb SPROM callback handler (err %d)\n", err);
|
||||
|
||||
err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE,
|
||||
bcm47xx_get_invariants);
|
||||
if (err)
|
||||
panic("Failed to initialize SSB bus (err %d)", err);
|
||||
|
||||
mcore = &bcm47xx_bus.ssb.mipscore;
|
||||
if (bcm47xx_nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
|
||||
if (strstr(buf, "console=ttyS1")) {
|
||||
struct ssb_serial_port port;
|
||||
|
||||
printk(KERN_DEBUG "Swapping serial ports!\n");
|
||||
/* swap serial ports */
|
||||
memcpy(&port, &mcore->serial_ports[0], sizeof(port));
|
||||
memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1],
|
||||
sizeof(port));
|
||||
memcpy(&mcore->serial_ports[1], &port, sizeof(port));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
|
||||
{
|
||||
char prefix[10];
|
||||
struct bcma_device *core;
|
||||
|
||||
switch (bus->hosttype) {
|
||||
case BCMA_HOSTTYPE_PCI:
|
||||
memset(out, 0, sizeof(struct ssb_sprom));
|
||||
snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
|
||||
bus->host_pci->bus->number + 1,
|
||||
PCI_SLOT(bus->host_pci->devfn));
|
||||
bcm47xx_fill_sprom(out, prefix, false);
|
||||
return 0;
|
||||
case BCMA_HOSTTYPE_SOC:
|
||||
memset(out, 0, sizeof(struct ssb_sprom));
|
||||
core = bcma_find_core(bus, BCMA_CORE_80211);
|
||||
if (core) {
|
||||
snprintf(prefix, sizeof(prefix), "sb/%u/",
|
||||
core->core_index);
|
||||
bcm47xx_fill_sprom(out, prefix, true);
|
||||
} else {
|
||||
bcm47xx_fill_sprom(out, NULL, false);
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static void __init bcm47xx_register_bcma(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma);
|
||||
if (err)
|
||||
pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err);
|
||||
|
||||
err = bcma_host_soc_register(&bcm47xx_bus.bcma);
|
||||
if (err)
|
||||
panic("Failed to register BCMA bus (err %d)", err);
|
||||
|
||||
err = bcma_host_soc_init(&bcm47xx_bus.bcma);
|
||||
if (err)
|
||||
panic("Failed to initialize BCMA bus (err %d)", err);
|
||||
|
||||
bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init plat_mem_setup(void)
|
||||
{
|
||||
struct cpuinfo_mips *c = ¤t_cpu_data;
|
||||
|
||||
if ((c->cputype == CPU_74K) || (c->cputype == CPU_1074K)) {
|
||||
printk(KERN_INFO "bcm47xx: using bcma bus\n");
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
|
||||
bcm47xx_register_bcma();
|
||||
bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
bcm47xx_prom_highmem_init();
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
printk(KERN_INFO "bcm47xx: using ssb bus\n");
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
|
||||
bcm47xx_register_ssb();
|
||||
bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
_machine_restart = bcm47xx_machine_restart;
|
||||
_machine_halt = bcm47xx_machine_halt;
|
||||
pm_power_off = bcm47xx_machine_halt;
|
||||
bcm47xx_board_detect();
|
||||
mips_set_machine_name(bcm47xx_board_get_name());
|
||||
}
|
||||
|
||||
static int __init bcm47xx_cpu_fixes(void)
|
||||
{
|
||||
switch (bcm47xx_bus_type) {
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
case BCM47XX_BUS_TYPE_SSB:
|
||||
/* Nothing to do */
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
case BCM47XX_BUS_TYPE_BCMA:
|
||||
/* The BCM4706 has a problem with the CPU wait instruction.
|
||||
* When r4k_wait or r4k_wait_irqoff is used will just hang and
|
||||
* not return from a msleep(). Removing the cpu_wait
|
||||
* functionality is a workaround for this problem. The BCM4716
|
||||
* does not have this problem.
|
||||
*/
|
||||
if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
|
||||
cpu_wait = NULL;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(bcm47xx_cpu_fixes);
|
||||
|
||||
static struct fixed_phy_status bcm47xx_fixed_phy_status __initdata = {
|
||||
.link = 1,
|
||||
.speed = SPEED_100,
|
||||
.duplex = DUPLEX_FULL,
|
||||
};
|
||||
|
||||
static int __init bcm47xx_register_bus_complete(void)
|
||||
{
|
||||
switch (bcm47xx_bus_type) {
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
case BCM47XX_BUS_TYPE_SSB:
|
||||
/* Nothing to do */
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
case BCM47XX_BUS_TYPE_BCMA:
|
||||
bcma_bus_register(&bcm47xx_bus.bcma.bus);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
bcm47xx_buttons_register();
|
||||
bcm47xx_leds_register();
|
||||
bcm47xx_workarounds();
|
||||
|
||||
fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status);
|
||||
return 0;
|
||||
}
|
||||
device_initcall(bcm47xx_register_bus_complete);
|
803
arch/mips/bcm47xx/sprom.c
Normal file
803
arch/mips/bcm47xx/sprom.c
Normal file
|
@ -0,0 +1,803 @@
|
|||
/*
|
||||
* Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
|
||||
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
|
||||
* Copyright (C) 2006 Michael Buesch <m@bues.ch>
|
||||
* Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org>
|
||||
* Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <bcm47xx.h>
|
||||
#include <bcm47xx_nvram.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
static void create_key(const char *prefix, const char *postfix,
|
||||
const char *name, char *buf, int len)
|
||||
{
|
||||
if (prefix && postfix)
|
||||
snprintf(buf, len, "%s%s%s", prefix, name, postfix);
|
||||
else if (prefix)
|
||||
snprintf(buf, len, "%s%s", prefix, name);
|
||||
else if (postfix)
|
||||
snprintf(buf, len, "%s%s", name, postfix);
|
||||
else
|
||||
snprintf(buf, len, "%s", name);
|
||||
}
|
||||
|
||||
static int get_nvram_var(const char *prefix, const char *postfix,
|
||||
const char *name, char *buf, int len, bool fallback)
|
||||
{
|
||||
char key[40];
|
||||
int err;
|
||||
|
||||
create_key(prefix, postfix, name, key, sizeof(key));
|
||||
|
||||
err = bcm47xx_nvram_getenv(key, buf, len);
|
||||
if (fallback && err == -ENOENT && prefix) {
|
||||
create_key(NULL, postfix, name, key, sizeof(key));
|
||||
err = bcm47xx_nvram_getenv(key, buf, len);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
#define NVRAM_READ_VAL(type) \
|
||||
static void nvram_read_ ## type (const char *prefix, \
|
||||
const char *postfix, const char *name, \
|
||||
type *val, type allset, bool fallback) \
|
||||
{ \
|
||||
char buf[100]; \
|
||||
int err; \
|
||||
type var; \
|
||||
\
|
||||
err = get_nvram_var(prefix, postfix, name, buf, sizeof(buf), \
|
||||
fallback); \
|
||||
if (err < 0) \
|
||||
return; \
|
||||
err = kstrto ## type(strim(buf), 0, &var); \
|
||||
if (err) { \
|
||||
pr_warn("can not parse nvram name %s%s%s with value %s got %i\n", \
|
||||
prefix, name, postfix, buf, err); \
|
||||
return; \
|
||||
} \
|
||||
if (allset && var == allset) \
|
||||
return; \
|
||||
*val = var; \
|
||||
}
|
||||
|
||||
NVRAM_READ_VAL(u8)
|
||||
NVRAM_READ_VAL(s8)
|
||||
NVRAM_READ_VAL(u16)
|
||||
NVRAM_READ_VAL(u32)
|
||||
|
||||
#undef NVRAM_READ_VAL
|
||||
|
||||
static void nvram_read_u32_2(const char *prefix, const char *name,
|
||||
u16 *val_lo, u16 *val_hi, bool fallback)
|
||||
{
|
||||
char buf[100];
|
||||
int err;
|
||||
u32 val;
|
||||
|
||||
err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback);
|
||||
if (err < 0)
|
||||
return;
|
||||
err = kstrtou32(strim(buf), 0, &val);
|
||||
if (err) {
|
||||
pr_warn("can not parse nvram name %s%s with value %s got %i\n",
|
||||
prefix, name, buf, err);
|
||||
return;
|
||||
}
|
||||
*val_lo = (val & 0x0000FFFFU);
|
||||
*val_hi = (val & 0xFFFF0000U) >> 16;
|
||||
}
|
||||
|
||||
static void nvram_read_leddc(const char *prefix, const char *name,
|
||||
u8 *leddc_on_time, u8 *leddc_off_time,
|
||||
bool fallback)
|
||||
{
|
||||
char buf[100];
|
||||
int err;
|
||||
u32 val;
|
||||
|
||||
err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback);
|
||||
if (err < 0)
|
||||
return;
|
||||
err = kstrtou32(strim(buf), 0, &val);
|
||||
if (err) {
|
||||
pr_warn("can not parse nvram name %s%s with value %s got %i\n",
|
||||
prefix, name, buf, err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (val == 0xffff || val == 0xffffffff)
|
||||
return;
|
||||
|
||||
*leddc_on_time = val & 0xff;
|
||||
*leddc_off_time = (val >> 16) & 0xff;
|
||||
}
|
||||
|
||||
static void nvram_read_macaddr(const char *prefix, const char *name,
|
||||
u8 val[6], bool fallback)
|
||||
{
|
||||
char buf[100];
|
||||
int err;
|
||||
|
||||
err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback);
|
||||
if (err < 0)
|
||||
return;
|
||||
|
||||
bcm47xx_nvram_parse_macaddr(buf, val);
|
||||
}
|
||||
|
||||
static void nvram_read_alpha2(const char *prefix, const char *name,
|
||||
char val[2], bool fallback)
|
||||
{
|
||||
char buf[10];
|
||||
int err;
|
||||
|
||||
err = get_nvram_var(prefix, NULL, name, buf, sizeof(buf), fallback);
|
||||
if (err < 0)
|
||||
return;
|
||||
if (buf[0] == '0')
|
||||
return;
|
||||
if (strlen(buf) > 2) {
|
||||
pr_warn("alpha2 is too long %s\n", buf);
|
||||
return;
|
||||
}
|
||||
memcpy(val, buf, 2);
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom,
|
||||
const char *prefix, bool fallback)
|
||||
{
|
||||
nvram_read_u16(prefix, NULL, "devid", &sprom->dev_id, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff, fallback);
|
||||
nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff, fallback);
|
||||
nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff, fallback);
|
||||
nvram_read_u8(prefix, NULL, "ledbh3", &sprom->gpio3, 0xff, fallback);
|
||||
nvram_read_u8(prefix, NULL, "aa2g", &sprom->ant_available_bg, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "aa5g", &sprom->ant_available_a, 0,
|
||||
fallback);
|
||||
nvram_read_s8(prefix, NULL, "ag0", &sprom->antenna_gain.a0, 0,
|
||||
fallback);
|
||||
nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0,
|
||||
fallback);
|
||||
nvram_read_alpha2(prefix, "ccode", sprom->alpha2, fallback);
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom,
|
||||
const char *prefix, bool fallback)
|
||||
{
|
||||
nvram_read_u16(prefix, NULL, "pa0b0", &sprom->pa0b0, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "pa0b1", &sprom->pa0b1, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "pa0b2", &sprom->pa0b2, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "pa0itssit", &sprom->itssi_bg, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "pa0maxpwr", &sprom->maxpwr_bg, 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "pa1b0", &sprom->pa1b0, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "pa1b1", &sprom->pa1b1, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "pa1b2", &sprom->pa1b2, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "pa1itssit", &sprom->itssi_a, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "pa1maxpwr", &sprom->maxpwr_a, 0, fallback);
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom_r1(struct ssb_sprom *sprom, const char *prefix,
|
||||
bool fallback)
|
||||
{
|
||||
nvram_read_u16(prefix, NULL, "boardflags", &sprom->boardflags_lo, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "cc", &sprom->country_code, 0, fallback);
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom_r2389(struct ssb_sprom *sprom,
|
||||
const char *prefix, bool fallback)
|
||||
{
|
||||
nvram_read_u8(prefix, NULL, "opo", &sprom->opo, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "pa1lob0", &sprom->pa1lob0, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "pa1lob1", &sprom->pa1lob1, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "pa1lob2", &sprom->pa1lob2, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "pa1hib0", &sprom->pa1hib0, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "pa1hib1", &sprom->pa1hib1, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "pa1hib2", &sprom->pa1hib2, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "pa1lomaxpwr", &sprom->maxpwr_al, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "pa1himaxpwr", &sprom->maxpwr_ah, 0,
|
||||
fallback);
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom_r389(struct ssb_sprom *sprom, const char *prefix,
|
||||
bool fallback)
|
||||
{
|
||||
nvram_read_u8(prefix, NULL, "bxa2g", &sprom->bxa2g, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rssisav2g", &sprom->rssisav2g, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "rssismc2g", &sprom->rssismc2g, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "rssismf2g", &sprom->rssismf2g, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "bxa5g", &sprom->bxa5g, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rssisav5g", &sprom->rssisav5g, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "rssismc5g", &sprom->rssismc5g, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "rssismf5g", &sprom->rssismf5g, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "tri2g", &sprom->tri2g, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "tri5g", &sprom->tri5g, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "tri5gl", &sprom->tri5gl, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "tri5gh", &sprom->tri5gh, 0, fallback);
|
||||
nvram_read_s8(prefix, NULL, "rxpo2g", &sprom->rxpo2g, 0, fallback);
|
||||
nvram_read_s8(prefix, NULL, "rxpo5g", &sprom->rxpo5g, 0, fallback);
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix,
|
||||
bool fallback)
|
||||
{
|
||||
nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0, fallback);
|
||||
nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time,
|
||||
&sprom->leddc_off_time, fallback);
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom_r4589(struct ssb_sprom *sprom,
|
||||
const char *prefix, bool fallback)
|
||||
{
|
||||
nvram_read_u8(prefix, NULL, "regrev", &sprom->regrev, 0, fallback);
|
||||
nvram_read_s8(prefix, NULL, "ag2", &sprom->antenna_gain.a2, 0,
|
||||
fallback);
|
||||
nvram_read_s8(prefix, NULL, "ag3", &sprom->antenna_gain.a3, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txchain", &sprom->txchain, 0xf, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxchain", &sprom->rxchain, 0xf, fallback);
|
||||
nvram_read_u8(prefix, NULL, "antswitch", &sprom->antswitch, 0xff,
|
||||
fallback);
|
||||
nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time,
|
||||
&sprom->leddc_off_time, fallback);
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom_r458(struct ssb_sprom *sprom, const char *prefix,
|
||||
bool fallback)
|
||||
{
|
||||
nvram_read_u16(prefix, NULL, "cck2gpo", &sprom->cck2gpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "ofdm2gpo", &sprom->ofdm2gpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "ofdm5gpo", &sprom->ofdm5gpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "ofdm5glpo", &sprom->ofdm5glpo, 0,
|
||||
fallback);
|
||||
nvram_read_u32(prefix, NULL, "ofdm5ghpo", &sprom->ofdm5ghpo, 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "cddpo", &sprom->cddpo, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "stbcpo", &sprom->stbcpo, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "bw40po", &sprom->bw40po, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "bwduppo", &sprom->bwduppo, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs2gpo0", &sprom->mcs2gpo[0], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs2gpo1", &sprom->mcs2gpo[1], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs2gpo2", &sprom->mcs2gpo[2], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs2gpo3", &sprom->mcs2gpo[3], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs2gpo4", &sprom->mcs2gpo[4], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs2gpo5", &sprom->mcs2gpo[5], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs2gpo6", &sprom->mcs2gpo[6], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs2gpo7", &sprom->mcs2gpo[7], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5gpo0", &sprom->mcs5gpo[0], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5gpo1", &sprom->mcs5gpo[1], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5gpo2", &sprom->mcs5gpo[2], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5gpo3", &sprom->mcs5gpo[3], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5gpo4", &sprom->mcs5gpo[4], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5gpo5", &sprom->mcs5gpo[5], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5gpo6", &sprom->mcs5gpo[6], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5gpo7", &sprom->mcs5gpo[7], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5glpo0", &sprom->mcs5glpo[0], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5glpo1", &sprom->mcs5glpo[1], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5glpo2", &sprom->mcs5glpo[2], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5glpo3", &sprom->mcs5glpo[3], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5glpo4", &sprom->mcs5glpo[4], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5glpo5", &sprom->mcs5glpo[5], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5glpo6", &sprom->mcs5glpo[6], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5glpo7", &sprom->mcs5glpo[7], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5ghpo0", &sprom->mcs5ghpo[0], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5ghpo1", &sprom->mcs5ghpo[1], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5ghpo2", &sprom->mcs5ghpo[2], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5ghpo3", &sprom->mcs5ghpo[3], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5ghpo4", &sprom->mcs5ghpo[4], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5ghpo5", &sprom->mcs5ghpo[5], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5ghpo6", &sprom->mcs5ghpo[6], 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs5ghpo7", &sprom->mcs5ghpo[7], 0,
|
||||
fallback);
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom_r45(struct ssb_sprom *sprom, const char *prefix,
|
||||
bool fallback)
|
||||
{
|
||||
nvram_read_u8(prefix, NULL, "txpid2ga0", &sprom->txpid2g[0], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid2ga1", &sprom->txpid2g[1], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid2ga2", &sprom->txpid2g[2], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid2ga3", &sprom->txpid2g[3], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid5ga0", &sprom->txpid5g[0], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid5ga1", &sprom->txpid5g[1], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid5ga2", &sprom->txpid5g[2], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid5ga3", &sprom->txpid5g[3], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid5gla0", &sprom->txpid5gl[0], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid5gla1", &sprom->txpid5gl[1], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid5gla2", &sprom->txpid5gl[2], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid5gla3", &sprom->txpid5gl[3], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid5gha0", &sprom->txpid5gh[0], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid5gha1", &sprom->txpid5gh[1], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid5gha2", &sprom->txpid5gh[2], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "txpid5gha3", &sprom->txpid5gh[3], 0,
|
||||
fallback);
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom_r89(struct ssb_sprom *sprom, const char *prefix,
|
||||
bool fallback)
|
||||
{
|
||||
nvram_read_u8(prefix, NULL, "tssipos2g", &sprom->fem.ghz2.tssipos, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "extpagain2g",
|
||||
&sprom->fem.ghz2.extpa_gain, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "pdetrange2g",
|
||||
&sprom->fem.ghz2.pdet_range, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "triso2g", &sprom->fem.ghz2.tr_iso, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "antswctl2g", &sprom->fem.ghz2.antswlut, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "tssipos5g", &sprom->fem.ghz5.tssipos, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "extpagain5g",
|
||||
&sprom->fem.ghz5.extpa_gain, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "pdetrange5g",
|
||||
&sprom->fem.ghz5.pdet_range, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "triso5g", &sprom->fem.ghz5.tr_iso, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "antswctl5g", &sprom->fem.ghz5.antswlut, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "tempthresh", &sprom->tempthresh, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "tempoffset", &sprom->tempoffset, 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "rawtempsense", &sprom->rawtempsense, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "measpower", &sprom->measpower, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "tempsense_slope",
|
||||
&sprom->tempsense_slope, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "tempcorrx", &sprom->tempcorrx, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "tempsense_option",
|
||||
&sprom->tempsense_option, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "freqoffset_corr",
|
||||
&sprom->freqoffset_corr, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "iqcal_swp_dis", &sprom->iqcal_swp_dis, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "hw_iqcal_en", &sprom->hw_iqcal_en, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "elna2g", &sprom->elna2g, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "elna5g", &sprom->elna5g, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "phycal_tempdelta",
|
||||
&sprom->phycal_tempdelta, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "temps_period", &sprom->temps_period, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "temps_hysteresis",
|
||||
&sprom->temps_hysteresis, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "measpower1", &sprom->measpower1, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "measpower2", &sprom->measpower2, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr2ga0",
|
||||
&sprom->rxgainerr2ga[0], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr2ga1",
|
||||
&sprom->rxgainerr2ga[1], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr2ga2",
|
||||
&sprom->rxgainerr2ga[2], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr5gla0",
|
||||
&sprom->rxgainerr5gla[0], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr5gla1",
|
||||
&sprom->rxgainerr5gla[1], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr5gla2",
|
||||
&sprom->rxgainerr5gla[2], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr5gma0",
|
||||
&sprom->rxgainerr5gma[0], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr5gma1",
|
||||
&sprom->rxgainerr5gma[1], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr5gma2",
|
||||
&sprom->rxgainerr5gma[2], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr5gha0",
|
||||
&sprom->rxgainerr5gha[0], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr5gha1",
|
||||
&sprom->rxgainerr5gha[1], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr5gha2",
|
||||
&sprom->rxgainerr5gha[2], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr5gua0",
|
||||
&sprom->rxgainerr5gua[0], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr5gua1",
|
||||
&sprom->rxgainerr5gua[1], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "rxgainerr5gua2",
|
||||
&sprom->rxgainerr5gua[2], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl2ga0", &sprom->noiselvl2ga[0], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl2ga1", &sprom->noiselvl2ga[1], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl2ga2", &sprom->noiselvl2ga[2], 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl5gla0",
|
||||
&sprom->noiselvl5gla[0], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl5gla1",
|
||||
&sprom->noiselvl5gla[1], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl5gla2",
|
||||
&sprom->noiselvl5gla[2], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl5gma0",
|
||||
&sprom->noiselvl5gma[0], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl5gma1",
|
||||
&sprom->noiselvl5gma[1], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl5gma2",
|
||||
&sprom->noiselvl5gma[2], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl5gha0",
|
||||
&sprom->noiselvl5gha[0], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl5gha1",
|
||||
&sprom->noiselvl5gha[1], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl5gha2",
|
||||
&sprom->noiselvl5gha[2], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl5gua0",
|
||||
&sprom->noiselvl5gua[0], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl5gua1",
|
||||
&sprom->noiselvl5gua[1], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "noiselvl5gua2",
|
||||
&sprom->noiselvl5gua[2], 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "pcieingress_war",
|
||||
&sprom->pcieingress_war, 0, fallback);
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom_r9(struct ssb_sprom *sprom, const char *prefix,
|
||||
bool fallback)
|
||||
{
|
||||
nvram_read_u16(prefix, NULL, "cckbw202gpo", &sprom->cckbw202gpo, 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "cckbw20ul2gpo", &sprom->cckbw20ul2gpo, 0,
|
||||
fallback);
|
||||
nvram_read_u32(prefix, NULL, "legofdmbw202gpo",
|
||||
&sprom->legofdmbw202gpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "legofdmbw20ul2gpo",
|
||||
&sprom->legofdmbw20ul2gpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "legofdmbw205glpo",
|
||||
&sprom->legofdmbw205glpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "legofdmbw20ul5glpo",
|
||||
&sprom->legofdmbw20ul5glpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "legofdmbw205gmpo",
|
||||
&sprom->legofdmbw205gmpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "legofdmbw20ul5gmpo",
|
||||
&sprom->legofdmbw20ul5gmpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "legofdmbw205ghpo",
|
||||
&sprom->legofdmbw205ghpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "legofdmbw20ul5ghpo",
|
||||
&sprom->legofdmbw20ul5ghpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "mcsbw202gpo", &sprom->mcsbw202gpo, 0,
|
||||
fallback);
|
||||
nvram_read_u32(prefix, NULL, "mcsbw20ul2gpo", &sprom->mcsbw20ul2gpo, 0,
|
||||
fallback);
|
||||
nvram_read_u32(prefix, NULL, "mcsbw402gpo", &sprom->mcsbw402gpo, 0,
|
||||
fallback);
|
||||
nvram_read_u32(prefix, NULL, "mcsbw205glpo", &sprom->mcsbw205glpo, 0,
|
||||
fallback);
|
||||
nvram_read_u32(prefix, NULL, "mcsbw20ul5glpo",
|
||||
&sprom->mcsbw20ul5glpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "mcsbw405glpo", &sprom->mcsbw405glpo, 0,
|
||||
fallback);
|
||||
nvram_read_u32(prefix, NULL, "mcsbw205gmpo", &sprom->mcsbw205gmpo, 0,
|
||||
fallback);
|
||||
nvram_read_u32(prefix, NULL, "mcsbw20ul5gmpo",
|
||||
&sprom->mcsbw20ul5gmpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "mcsbw405gmpo", &sprom->mcsbw405gmpo, 0,
|
||||
fallback);
|
||||
nvram_read_u32(prefix, NULL, "mcsbw205ghpo", &sprom->mcsbw205ghpo, 0,
|
||||
fallback);
|
||||
nvram_read_u32(prefix, NULL, "mcsbw20ul5ghpo",
|
||||
&sprom->mcsbw20ul5ghpo, 0, fallback);
|
||||
nvram_read_u32(prefix, NULL, "mcsbw405ghpo", &sprom->mcsbw405ghpo, 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "mcs32po", &sprom->mcs32po, 0, fallback);
|
||||
nvram_read_u16(prefix, NULL, "legofdm40duppo",
|
||||
&sprom->legofdm40duppo, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "sar2g", &sprom->sar2g, 0, fallback);
|
||||
nvram_read_u8(prefix, NULL, "sar5g", &sprom->sar5g, 0, fallback);
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom,
|
||||
const char *prefix, bool fallback)
|
||||
{
|
||||
char postfix[2];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
|
||||
struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
|
||||
snprintf(postfix, sizeof(postfix), "%i", i);
|
||||
nvram_read_u8(prefix, postfix, "maxp2ga",
|
||||
&pwr_info->maxpwr_2g, 0, fallback);
|
||||
nvram_read_u8(prefix, postfix, "itt2ga",
|
||||
&pwr_info->itssi_2g, 0, fallback);
|
||||
nvram_read_u8(prefix, postfix, "itt5ga",
|
||||
&pwr_info->itssi_5g, 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa2gw0a",
|
||||
&pwr_info->pa_2g[0], 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa2gw1a",
|
||||
&pwr_info->pa_2g[1], 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa2gw2a",
|
||||
&pwr_info->pa_2g[2], 0, fallback);
|
||||
nvram_read_u8(prefix, postfix, "maxp5ga",
|
||||
&pwr_info->maxpwr_5g, 0, fallback);
|
||||
nvram_read_u8(prefix, postfix, "maxp5gha",
|
||||
&pwr_info->maxpwr_5gh, 0, fallback);
|
||||
nvram_read_u8(prefix, postfix, "maxp5gla",
|
||||
&pwr_info->maxpwr_5gl, 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa5gw0a",
|
||||
&pwr_info->pa_5g[0], 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa5gw1a",
|
||||
&pwr_info->pa_5g[1], 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa5gw2a",
|
||||
&pwr_info->pa_5g[2], 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa5glw0a",
|
||||
&pwr_info->pa_5gl[0], 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa5glw1a",
|
||||
&pwr_info->pa_5gl[1], 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa5glw2a",
|
||||
&pwr_info->pa_5gl[2], 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa5ghw0a",
|
||||
&pwr_info->pa_5gh[0], 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa5ghw1a",
|
||||
&pwr_info->pa_5gh[1], 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa5ghw2a",
|
||||
&pwr_info->pa_5gh[2], 0, fallback);
|
||||
}
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom,
|
||||
const char *prefix, bool fallback)
|
||||
{
|
||||
char postfix[2];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sprom->core_pwr_info); i++) {
|
||||
struct ssb_sprom_core_pwr_info *pwr_info = &sprom->core_pwr_info[i];
|
||||
snprintf(postfix, sizeof(postfix), "%i", i);
|
||||
nvram_read_u16(prefix, postfix, "pa2gw3a",
|
||||
&pwr_info->pa_2g[3], 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa5gw3a",
|
||||
&pwr_info->pa_5g[3], 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa5glw3a",
|
||||
&pwr_info->pa_5gl[3], 0, fallback);
|
||||
nvram_read_u16(prefix, postfix, "pa5ghw3a",
|
||||
&pwr_info->pa_5gh[3], 0, fallback);
|
||||
}
|
||||
}
|
||||
|
||||
static bool bcm47xx_is_valid_mac(u8 *mac)
|
||||
{
|
||||
return mac && !(mac[0] == 0x00 && mac[1] == 0x90 && mac[2] == 0x4c);
|
||||
}
|
||||
|
||||
static int bcm47xx_increase_mac_addr(u8 *mac, u8 num)
|
||||
{
|
||||
u8 *oui = mac + ETH_ALEN/2 - 1;
|
||||
u8 *p = mac + ETH_ALEN - 1;
|
||||
|
||||
do {
|
||||
(*p) += num;
|
||||
if (*p > num)
|
||||
break;
|
||||
p--;
|
||||
num = 1;
|
||||
} while (p != oui);
|
||||
|
||||
if (p == oui) {
|
||||
pr_err("unable to fetch mac address\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mac_addr_used = 2;
|
||||
|
||||
static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
|
||||
const char *prefix, bool fallback)
|
||||
{
|
||||
nvram_read_macaddr(prefix, "et0macaddr", sprom->et0mac, fallback);
|
||||
nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0,
|
||||
fallback);
|
||||
|
||||
nvram_read_macaddr(prefix, "et1macaddr", sprom->et1mac, fallback);
|
||||
nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0,
|
||||
fallback);
|
||||
nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0,
|
||||
fallback);
|
||||
|
||||
nvram_read_macaddr(prefix, "macaddr", sprom->il0mac, fallback);
|
||||
nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback);
|
||||
|
||||
/* The address prefix 00:90:4C is used by Broadcom in their initial
|
||||
configuration. When a mac address with the prefix 00:90:4C is used
|
||||
all devices from the same series are sharing the same mac address.
|
||||
To prevent mac address collisions we replace them with a mac address
|
||||
based on the base address. */
|
||||
if (!bcm47xx_is_valid_mac(sprom->il0mac)) {
|
||||
u8 mac[6];
|
||||
|
||||
nvram_read_macaddr(NULL, "et0macaddr", mac, false);
|
||||
if (bcm47xx_is_valid_mac(mac)) {
|
||||
int err = bcm47xx_increase_mac_addr(mac, mac_addr_used);
|
||||
|
||||
if (!err) {
|
||||
ether_addr_copy(sprom->il0mac, mac);
|
||||
mac_addr_used++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix,
|
||||
bool fallback)
|
||||
{
|
||||
nvram_read_u16(prefix, NULL, "boardrev", &sprom->board_rev, 0, true);
|
||||
nvram_read_u16(prefix, NULL, "boardnum", &sprom->board_num, 0,
|
||||
fallback);
|
||||
nvram_read_u16(prefix, NULL, "boardtype", &sprom->board_type, 0, true);
|
||||
nvram_read_u32_2(prefix, "boardflags", &sprom->boardflags_lo,
|
||||
&sprom->boardflags_hi, fallback);
|
||||
nvram_read_u32_2(prefix, "boardflags2", &sprom->boardflags2_lo,
|
||||
&sprom->boardflags2_hi, fallback);
|
||||
}
|
||||
|
||||
void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix,
|
||||
bool fallback)
|
||||
{
|
||||
bcm47xx_fill_sprom_ethernet(sprom, prefix, fallback);
|
||||
bcm47xx_fill_board_data(sprom, prefix, fallback);
|
||||
|
||||
nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0, fallback);
|
||||
|
||||
switch (sprom->revision) {
|
||||
case 1:
|
||||
bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r1(sprom, prefix, fallback);
|
||||
break;
|
||||
case 2:
|
||||
bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r2389(sprom, prefix, fallback);
|
||||
break;
|
||||
case 3:
|
||||
bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r2389(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r389(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r3(sprom, prefix, fallback);
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r4589(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r458(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r45(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_path_r45(sprom, prefix, fallback);
|
||||
break;
|
||||
case 8:
|
||||
bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r2389(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r389(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r4589(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r458(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r89(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback);
|
||||
break;
|
||||
case 9:
|
||||
bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r2389(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r389(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r4589(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r89(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r9(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback);
|
||||
break;
|
||||
default:
|
||||
pr_warn("Unsupported SPROM revision %d detected. Will extract"
|
||||
" v1\n", sprom->revision);
|
||||
sprom->revision = 1;
|
||||
bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r12389(sprom, prefix, fallback);
|
||||
bcm47xx_fill_sprom_r1(sprom, prefix, fallback);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo,
|
||||
const char *prefix)
|
||||
{
|
||||
nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0,
|
||||
true);
|
||||
if (!boardinfo->vendor)
|
||||
boardinfo->vendor = SSB_BOARDVENDOR_BCM;
|
||||
|
||||
nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo,
|
||||
const char *prefix)
|
||||
{
|
||||
nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0,
|
||||
true);
|
||||
if (!boardinfo->vendor)
|
||||
boardinfo->vendor = SSB_BOARDVENDOR_BCM;
|
||||
|
||||
nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true);
|
||||
}
|
||||
#endif
|
83
arch/mips/bcm47xx/time.c
Normal file
83
arch/mips/bcm47xx/time.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/ssb/ssb.h>
|
||||
#include <asm/time.h>
|
||||
#include <bcm47xx.h>
|
||||
#include <bcm47xx_nvram.h>
|
||||
#include <bcm47xx_board.h>
|
||||
|
||||
void __init plat_time_init(void)
|
||||
{
|
||||
unsigned long hz = 0;
|
||||
u16 chip_id = 0;
|
||||
char buf[10];
|
||||
int len;
|
||||
enum bcm47xx_board board = bcm47xx_board_get();
|
||||
|
||||
/*
|
||||
* Use deterministic values for initial counter interrupt
|
||||
* so that calibrate delay avoids encountering a counter wrap.
|
||||
*/
|
||||
write_c0_count(0);
|
||||
write_c0_compare(0xffff);
|
||||
|
||||
switch (bcm47xx_bus_type) {
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
case BCM47XX_BUS_TYPE_SSB:
|
||||
hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
|
||||
chip_id = bcm47xx_bus.ssb.chip_id;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
case BCM47XX_BUS_TYPE_BCMA:
|
||||
hz = bcma_cpu_clock(&bcm47xx_bus.bcma.bus.drv_mips) / 2;
|
||||
chip_id = bcm47xx_bus.bcma.bus.chipinfo.id;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (chip_id == 0x5354) {
|
||||
len = bcm47xx_nvram_getenv("clkfreq", buf, sizeof(buf));
|
||||
if (len >= 0 && !strncmp(buf, "200", 4))
|
||||
hz = 100000000;
|
||||
}
|
||||
|
||||
switch (board) {
|
||||
case BCM47XX_BOARD_ASUS_WL520GC:
|
||||
case BCM47XX_BOARD_ASUS_WL520GU:
|
||||
hz = 100000000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hz)
|
||||
hz = 100000000;
|
||||
|
||||
/* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
|
||||
mips_hpt_frequency = hz;
|
||||
}
|
31
arch/mips/bcm47xx/workarounds.c
Normal file
31
arch/mips/bcm47xx/workarounds.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include "bcm47xx_private.h"
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <bcm47xx_board.h>
|
||||
#include <bcm47xx.h>
|
||||
|
||||
static void __init bcm47xx_workarounds_netgear_wnr3500l(void)
|
||||
{
|
||||
const int usb_power = 12;
|
||||
int err;
|
||||
|
||||
err = gpio_request_one(usb_power, GPIOF_OUT_INIT_HIGH, "usb_power");
|
||||
if (err)
|
||||
pr_err("Failed to request USB power gpio: %d\n", err);
|
||||
else
|
||||
gpio_free(usb_power);
|
||||
}
|
||||
|
||||
void __init bcm47xx_workarounds(void)
|
||||
{
|
||||
enum bcm47xx_board board = bcm47xx_board_get();
|
||||
|
||||
switch (board) {
|
||||
case BCM47XX_BOARD_NETGEAR_WNR3500L:
|
||||
bcm47xx_workarounds_netgear_wnr3500l();
|
||||
break;
|
||||
default:
|
||||
/* No workaround(s) needed */
|
||||
break;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue