--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -18,6 +18,9 @@ #include <linux/gpio_buttons.h> #include <linux/input.h> #include <linux/export.h> +#include <linux/spi/spi.h> +#include <linux/spi/spi_gpio.h> +#include <linux/spi/74x164.h> #include <asm/addrspace.h> #include <bcm63xx_board.h> #include <bcm63xx_cpu.h> @@ -39,6 +42,12 @@ #define CFE_OFFSET_64K 0x10000 #define CFE_OFFSET_128K 0x20000 +#define NB4_PID_OFFSET 0xff80 +#define NB4_74X164_GPIO_BASE 64 +#define NB4_SPI_GPIO_MOSI 7 +#define NB4_SPI_GPIO_CLK 6 +#define NB4_74HC64_GPIO(X) (NB4_74X164_GPIO_BASE + (X)) + static struct bcm963xx_nvram nvram; static unsigned int mac_addr_used; static struct board_info board; @@ -778,6 +787,496 @@ static struct board_info __initdata boar .has_ohci0 = 1, }; + +struct spi_gpio_platform_data nb4_spi_gpio_data = { + .sck = NB4_SPI_GPIO_CLK, + .mosi = NB4_SPI_GPIO_MOSI, + .miso = SPI_GPIO_NO_MISO, + .num_chipselect = 1, +}; + + +static struct platform_device nb4_spi_gpio = { + .name = "spi_gpio", + .id = 1, + .dev = { + .platform_data = &nb4_spi_gpio_data, + }, +}; + +static struct platform_device * __initdata nb4_devices[] = { + &nb4_spi_gpio, +}; + +const struct gen_74x164_chip_platform_data nb4_74x164_platform_data = { + .base = NB4_74X164_GPIO_BASE +}; + +static struct spi_board_info nb4_spi_devices[] = { + { + .modalias = "74x164", + .max_speed_hz = 781000, + .bus_num = 1, + .controller_data = (void *) SPI_GPIO_NO_CHIPSELECT, + .mode = SPI_MODE_0, + .platform_data = &nb4_74x164_platform_data + } +}; + +static struct board_info __initdata board_nb4_ser_r0 = { + .name = "NB4-SER-r0", + .expected_cpu_id = 0x6358, + + .has_uart0 = 1, + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + + .has_ohci0 = 1, + .has_pccard = 1, + .has_ehci0 = 1, + + .leds = { + { + .name = "adsl", + .gpio = NB4_74HC64_GPIO(4), + .active_low = 1, + }, + { + .name = "traffic", + .gpio = 2, + .active_low = 1, + }, + { + .name = "tel", + .gpio = NB4_74HC64_GPIO(3), + .active_low = 1, + }, + { + .name = "tv", + .gpio = NB4_74HC64_GPIO(2), + .active_low = 1, + }, + { + .name = "wifi", + .gpio = 15, + .active_low = 1, + }, + { + .name = "alarm", + .gpio = NB4_74HC64_GPIO(0), + .active_low = 1, + }, + { + .name = "service:red", + .gpio = 29, + .active_low = 1, + }, + { + .name = "service:green", + .gpio = 30, + .active_low = 1, + }, + { + .name = "service:blue", + .gpio = 4, + .active_low = 1, + }, + }, + .buttons = { + { + .desc = "reset", + .gpio = 34, + .type = EV_KEY, + .code = KEY_RESTART, + .threshold = 3, + }, + { + .desc = "wps", + .gpio = 37, + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .threshold = 3, + }, + }, + .devs = nb4_devices, + .num_devs = ARRAY_SIZE(nb4_devices), + .spis = nb4_spi_devices, + .num_spis = ARRAY_SIZE(nb4_spi_devices), +}; + +static struct board_info __initdata board_nb4_ser_r1 = { + .name = "NB4-SER-r1", + .expected_cpu_id = 0x6358, + + .has_uart0 = 1, + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + + .has_ohci0 = 1, + .has_pccard = 1, + .has_ehci0 = 1, + + .leds = { + { + .name = "adsl", + .gpio = NB4_74HC64_GPIO(4), + .active_low = 1, + }, + { + .name = "traffic", + .gpio = 2, + .active_low = 1, + }, + { + .name = "tel", + .gpio = NB4_74HC64_GPIO(3), + .active_low = 1, + }, + { + .name = "tv", + .gpio = NB4_74HC64_GPIO(2), + .active_low = 1, + }, + { + .name = "wifi", + .gpio = 15, + .active_low = 1, + }, + { + .name = "alarm", + .gpio = NB4_74HC64_GPIO(0), + .active_low = 1, + }, + { + .name = "service:red", + .gpio = 29, + .active_low = 1, + }, + { + .name = "service:green", + .gpio = 30, + .active_low = 1, + }, + { + .name = "service:blue", + .gpio = 4, + .active_low = 1, + }, + }, + .buttons = { + { + .desc = "reset", + .gpio = 34, + .type = EV_KEY, + .code = KEY_RESTART, + .threshold = 3, + }, + { + .desc = "wps", + .gpio = 37, + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .threshold = 3, + }, + }, + .devs = nb4_devices, + .num_devs = ARRAY_SIZE(nb4_devices), + .spis = nb4_spi_devices, + .num_spis = ARRAY_SIZE(nb4_spi_devices), +}; + +static struct board_info __initdata board_nb4_ser_r2 = { + .name = "NB4-SER-r2", + .expected_cpu_id = 0x6358, + + .has_uart0 = 1, + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + + .has_ohci0 = 1, + .has_pccard = 1, + .has_ehci0 = 1, + + .leds = { + { + .name = "adsl", + .gpio = NB4_74HC64_GPIO(4), + .active_low = 1, + }, + { + .name = "traffic", + .gpio = 2, + .active_low = 1, + }, + { + .name = "tel", + .gpio = NB4_74HC64_GPIO(3), + .active_low = 1, + }, + { + .name = "tv", + .gpio = NB4_74HC64_GPIO(2), + .active_low = 1, + }, + { + .name = "wifi", + .gpio = 15, + .active_low = 1, + }, + { + .name = "alarm", + .gpio = NB4_74HC64_GPIO(0), + .active_low = 1, + }, + { + .name = "service:red", + .gpio = 29, + .active_low = 1, + }, + { + .name = "service:green", + .gpio = 30, + .active_low = 1, + }, + { + .name = "service:blue", + .gpio = 4, + .active_low = 1, + }, + }, + .buttons = { + { + .desc = "reset", + .gpio = 34, + .type = EV_KEY, + .code = KEY_RESTART, + .threshold = 3, + }, + { + .desc = "wps", + .gpio = 37, + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .threshold = 3, + }, + }, + .devs = nb4_devices, + .num_devs = ARRAY_SIZE(nb4_devices), + .spis = nb4_spi_devices, + .num_spis = ARRAY_SIZE(nb4_spi_devices), +}; + +static struct board_info __initdata board_nb4_fxc_r1 = { + .name = "NB4-FXC-r1", + .expected_cpu_id = 0x6358, + + .has_uart0 = 1, + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + + .has_ohci0 = 1, + .has_pccard = 1, + .has_ehci0 = 1, + + .leds = { + { + .name = "adsl", + .gpio = NB4_74HC64_GPIO(4), + .active_low = 1, + }, + { + .name = "traffic", + .gpio = 2, + }, + { + .name = "tel", + .gpio = NB4_74HC64_GPIO(3), + .active_low = 1, + }, + { + .name = "tv", + .gpio = NB4_74HC64_GPIO(2), + .active_low = 1, + }, + { + .name = "wifi", + .gpio = 15, + }, + { + .name = "alarm", + .gpio = NB4_74HC64_GPIO(0), + .active_low = 1, + }, + { + .name = "service:red", + .gpio = 29, + }, + { + .name = "service:green", + .gpio = 30, + }, + { + .name = "service:blue", + .gpio = 4, + }, + }, + .buttons = { + { + .desc = "reset", + .gpio = 34, + .type = EV_KEY, + .code = KEY_RESTART, + .threshold = 3, + }, + { + .desc = "wps", + .gpio = 37, + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .threshold = 3, + }, + }, + .devs = nb4_devices, + .num_devs = ARRAY_SIZE(nb4_devices), + .spis = nb4_spi_devices, + .num_spis = ARRAY_SIZE(nb4_spi_devices), +}; + +static struct board_info __initdata board_nb4_fxc_r2 = { + .name = "NB4-FXC-r2", + .expected_cpu_id = 0x6358, + + .has_uart0 = 1, + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .enet1 = { + .force_speed_100 = 1, + .force_duplex_full = 1, + }, + + + .has_ohci0 = 1, + .has_pccard = 1, + .has_ehci0 = 1, + + .leds = { + { + .name = "adsl", + .gpio = NB4_74HC64_GPIO(4), + .active_low = 1, + }, + { + .name = "traffic", + .gpio = 2, + }, + { + .name = "tel", + .gpio = NB4_74HC64_GPIO(3), + .active_low = 1, + }, + { + .name = "tv", + .gpio = NB4_74HC64_GPIO(2), + .active_low = 1, + }, + { + .name = "wifi", + .gpio = 15, + }, + { + .name = "alarm", + .gpio = NB4_74HC64_GPIO(0), + .active_low = 1, + }, + { + .name = "service:red", + .gpio = 29, + }, + { + .name = "service:green", + .gpio = 30, + }, + { + .name = "service:blue", + .gpio = 4, + }, + }, + .buttons = { + { + .desc = "reset", + .gpio = 34, + .type = EV_KEY, + .code = KEY_RESTART, + .threshold = 3, + }, + { + .desc = "wps", + .gpio = 37, + .type = EV_KEY, + .code = KEY_WPS_BUTTON, + .threshold = 3, + }, + }, + .devs = nb4_devices, + .num_devs = ARRAY_SIZE(nb4_devices), + .spis = nb4_spi_devices, + .num_spis = ARRAY_SIZE(nb4_spi_devices), +}; #endif /* @@ -808,9 +1307,30 @@ static const struct board_info __initdat &board_96358vw2, &board_AGPFS0, &board_DWVS0, + &board_nb4_ser_r0, + &board_nb4_ser_r1, + &board_nb4_ser_r2, + &board_nb4_fxc_r1, + &board_nb4_fxc_r2, #endif }; +static void __init nb4_nvram_fixup(void) +{ + u8 *boot_addr, *p; + u32 val; + + if (BCMCPU_IS_6358() && (!strcmp(nvram.name, "96358VW"))) { + val = bcm_mpi_readl(MPI_CSBASE_REG(0)); + val &= MPI_CSBASE_BASE_MASK; + boot_addr = (u8 *)KSEG1ADDR(val); + /* Extract nb4 PID */ + p = boot_addr + NB4_PID_OFFSET; + if (!memcmp(p, "NB4-", 4)) + memcpy(nvram.name, p, sizeof("NB4-XXX-rX")); + } +} + /* * Register a sane SPROMv2 to make the on-board * bcm4318 WLAN work @@ -962,6 +1482,9 @@ void __init board_prom_init(void) boardid_fixup(boot_addr); } + /* Fixup broken nb4 board name */ + nb4_nvram_fixup(); + /* find board by name */ for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { if (strncmp(nvram.name, bcm963xx_boards[i]->name,