From d1f333874d4c4ff3f4a27ec3eb08d3f7ca6d8e43 Mon Sep 17 00:00:00 2001 From: juhosg Date: Tue, 31 Aug 2010 20:13:47 +0000 Subject: ar71xx: rewrite SPI drivers for the RB4xx boards * add a new SPI controller driver * add SPI driver for the CPLD chip * convert the NAND driver * enable the mikroSD slot * enable more LEDs git-svn-id: svn://svn.openwrt.org/openwrt/trunk@22863 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../ar71xx/files/arch/mips/ar71xx/mach-rb4xx.c | 157 +++++++++++++-------- .../arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h | 48 +++++++ 2 files changed, 146 insertions(+), 59 deletions(-) create mode 100644 target/linux/ar71xx/files/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h (limited to 'target/linux/ar71xx/files/arch') diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/mach-rb4xx.c b/target/linux/ar71xx/files/arch/mips/ar71xx/mach-rb4xx.c index a477cd3ad..8694211d9 100644 --- a/target/linux/ar71xx/files/arch/mips/ar71xx/mach-rb4xx.c +++ b/target/linux/ar71xx/files/arch/mips/ar71xx/mach-rb4xx.c @@ -1,7 +1,7 @@ /* * MikroTik RouterBOARD 4xx series support * - * Copyright (C) 2008 Gabor Juhos + * Copyright (C) 2008-2010 Gabor Juhos * Copyright (C) 2008 Imre Kaloz * * This program is free software; you can redistribute it and/or modify it @@ -15,9 +15,12 @@ #include #include #include +#include +#include #include #include +#include #include "machtype.h" #include "devices.h" @@ -28,6 +31,13 @@ #define RB4XX_GPIO_USER_LED 4 #define RB4XX_GPIO_RESET_SWITCH 7 +#define RB4XX_GPIO_CPLD_BASE 32 +#define RB4XX_GPIO_CPLD_LED1 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED1) +#define RB4XX_GPIO_CPLD_LED2 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED2) +#define RB4XX_GPIO_CPLD_LED3 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED3) +#define RB4XX_GPIO_CPLD_LED4 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED4) +#define RB4XX_GPIO_CPLD_LED5 (RB4XX_GPIO_CPLD_BASE + CPLD_GPIO_nLED5) + #define RB4XX_BUTTONS_POLL_INTERVAL 20 static struct gpio_led rb4xx_leds_gpio[] __initdata = { @@ -35,6 +45,26 @@ static struct gpio_led rb4xx_leds_gpio[] __initdata = { .name = "rb4xx:yellow:user", .gpio = RB4XX_GPIO_USER_LED, .active_low = 0, + }, { + .name = "rb4xx:green:led1", + .gpio = RB4XX_GPIO_CPLD_LED1, + .active_low = 1, + }, { + .name = "rb4xx:green:led2", + .gpio = RB4XX_GPIO_CPLD_LED2, + .active_low = 1, + }, { + .name = "rb4xx:green:led3", + .gpio = RB4XX_GPIO_CPLD_LED3, + .active_low = 1, + }, { + .name = "rb4xx:green:led4", + .gpio = RB4XX_GPIO_CPLD_LED4, + .active_low = 1, + }, { + .name = "rb4xx:green:led5", + .gpio = RB4XX_GPIO_CPLD_LED5, + .active_low = 0, }, }; @@ -78,84 +108,90 @@ static struct ar71xx_pci_irq rb4xx_pci_irqs[] __initdata = { } }; -#if 0 -/* - * SPI device support is experimental - */ +#ifdef CONFIG_MTD_PARTITIONS +static struct mtd_partition rb4xx_partitions[] = { + { + .name = "routerboot", + .offset = 0, + .size = 0x0b000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "hard_config", + .offset = 0x0b000, + .size = 0x01000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "bios", + .offset = 0x0d000, + .size = 0x02000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "soft_config", + .offset = 0x0f000, + .size = 0x01000, + } +}; +#define rb4xx_num_partitions ARRAY_SIZE(rb4xx_partitions) +#else /* CONFIG_MTD_PARTITIONS */ +#define rb4xx_partitions NULL +#define rb4xx_num_partitions 0 +#endif /* CONFIG_MTD_PARTITIONS */ + static struct flash_platform_data rb4xx_flash_data = { .type = "pm25lv512", + .parts = rb4xx_partitions, + .nr_parts = rb4xx_num_partitions, }; -static struct spi_board_info rb4xx_spi_info[] = { - { - .bus_num = 0, - .chip_select = 0, - .max_speed_hz = 25000000, - .modalias = "m25p80", - .platform_data = &rb4xx_flash_data, - } +static struct rb4xx_cpld_platform_data rb4xx_cpld_data = { + .gpio_base = RB4XX_GPIO_CPLD_BASE, }; -static struct mmc_spi_platform_data rb433_mmc_data = { +static struct mmc_spi_platform_data rb4xx_mmc_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, }; -static struct spi_board_info rb433_spi_info[] = { +static struct spi_board_info rb4xx_spi_info[] = { { .bus_num = 0, .chip_select = 0, .max_speed_hz = 25000000, .modalias = "m25p80", - .platform_data = &rb433_flash_data, + .platform_data = &rb4xx_flash_data, }, { .bus_num = 0, - .chip_select = 2, + .chip_select = 1, .max_speed_hz = 25000000, - .modalias = "mmc_spi", - .platform_data = &rb433_mmc_data, + .modalias = "spi-rb4xx-cpld", + .platform_data = &rb4xx_cpld_data, } }; -static u32 rb433_spi_get_ioc_base(u8 chip_select, int cs_high, int is_on) -{ - u32 ret; - - if (is_on == AR71XX_SPI_CS_INACTIVE) { - ret = SPI_IOC_CS0 | SPI_IOC_CS1; - } else { - if (cs_high) { - ret = SPI_IOC_CS0 | SPI_IOC_CS1; - } else { - if ((chip_select ^ 2) == 0) - ret = SPI_IOC_CS1 ^ (SPI_IOC_CS0 | SPI_IOC_CS1); - else - ret = SPI_IOC_CS0 ^ (SPI_IOC_CS0 | SPI_IOC_CS1); - } +static struct spi_board_info rb4xx_microsd_info[] = { + { + .bus_num = 0, + .chip_select = 2, + .max_speed_hz = 25000000, + .modalias = "mmc_spi", + .platform_data = &rb4xx_mmc_data, } +}; - return ret; -} -struct ar71xx_spi_platform_data rb433_spi_data = { - .bus_num = 0, - .num_chipselect = 3, - .get_ioc_base = rb433_spi_get_ioc_base, +static struct resource rb4xx_spi_resources[] = { + { + .start = AR71XX_SPI_BASE, + .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, + .flags = IORESOURCE_MEM, + }, }; -static void rb4xx_add_device_spi(void) -{ - ar71xx_add_device_spi(NULL, rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info)); -} - -static void rb433_add_device_spi(void) -{ - ar71xx_add_device_spi(&rb433_spi_data, rb433_spi_info, - ARRAY_SIZE(rb433_spi_info)); -} -#else -static inline void rb4xx_add_device_spi(void) {} -static inline void rb433_add_device_spi(void) {} -#endif +static struct platform_device rb4xx_spi_device = { + .name = "rb4xx-spi", + .id = -1, + .resource = rb4xx_spi_resources, + .num_resources = ARRAY_SIZE(rb4xx_spi_resources), +}; static void __init rb4xx_generic_setup(void) { @@ -169,13 +205,16 @@ static void __init rb4xx_generic_setup(void) ARRAY_SIZE(rb4xx_gpio_buttons), rb4xx_gpio_buttons); + spi_register_board_info(rb4xx_spi_info, ARRAY_SIZE(rb4xx_spi_info)); + platform_device_register(&rb4xx_spi_device); platform_device_register(&rb4xx_nand_device); } static void __init rb411_setup(void) { rb4xx_generic_setup(); - rb4xx_add_device_spi(); + spi_register_board_info(rb4xx_microsd_info, + ARRAY_SIZE(rb4xx_microsd_info)); ar71xx_add_device_mdio(0xfffffffc); @@ -207,7 +246,8 @@ MIPS_MACHINE(AR71XX_MACH_RB_411U, "411U", "MikroTik RouterBOARD 411U", static void __init rb433_setup(void) { rb4xx_generic_setup(); - rb433_add_device_spi(); + spi_register_board_info(rb4xx_microsd_info, + ARRAY_SIZE(rb4xx_microsd_info)); ar71xx_add_device_mdio(~RB433_MDIO_PHYMASK); @@ -244,8 +284,6 @@ MIPS_MACHINE(AR71XX_MACH_RB_433U, "433U", "MikroTik RouterBOARD 433UAH", static void __init rb450_generic_setup(int gige) { rb4xx_generic_setup(); - rb4xx_add_device_spi(); - ar71xx_add_device_mdio(~RB450_MDIO_PHYMASK); ar71xx_init_mac(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, 1); @@ -271,6 +309,8 @@ MIPS_MACHINE(AR71XX_MACH_RB_450, "450", "MikroTik RouterBOARD 450", static void __init rb450g_setup(void) { rb450_generic_setup(1); + spi_register_board_info(rb4xx_microsd_info, + ARRAY_SIZE(rb4xx_microsd_info)); } MIPS_MACHINE(AR71XX_MACH_RB_450G, "450G", "MikroTik RouterBOARD 450G", @@ -279,7 +319,6 @@ MIPS_MACHINE(AR71XX_MACH_RB_450G, "450G", "MikroTik RouterBOARD 450G", static void __init rb493_setup(void) { rb4xx_generic_setup(); - rb4xx_add_device_spi(); ar71xx_add_device_mdio(0x3fffff00); diff --git a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h new file mode 100644 index 000000000..5b17e94b6 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ar71xx/rb4xx_cpld.h @@ -0,0 +1,48 @@ +/* + * SPI driver definitions for the CPLD chip on the Mikrotik RB4xx boards + * + * Copyright (C) 2010 Gabor Juhos + * + * This file was based on the patches for Linux 2.6.27.39 published by + * MikroTik for their RouterBoard 4xx series devices. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#define CPLD_GPIO_nLED1 0 +#define CPLD_GPIO_nLED2 1 +#define CPLD_GPIO_nLED3 2 +#define CPLD_GPIO_nLED4 3 +#define CPLD_GPIO_FAN 4 +#define CPLD_GPIO_ALE 5 +#define CPLD_GPIO_CLE 6 +#define CPLD_GPIO_nCE 7 +#define CPLD_GPIO_nLED5 8 + +#define CPLD_NUM_GPIOS 9 + +#define CPLD_CFG_nLED1 BIT(CPLD_GPIO_nLED1) +#define CPLD_CFG_nLED2 BIT(CPLD_GPIO_nLED2) +#define CPLD_CFG_nLED3 BIT(CPLD_GPIO_nLED3) +#define CPLD_CFG_nLED4 BIT(CPLD_GPIO_nLED4) +#define CPLD_CFG_FAN BIT(CPLD_GPIO_FAN) +#define CPLD_CFG_ALE BIT(CPLD_GPIO_ALE) +#define CPLD_CFG_CLE BIT(CPLD_GPIO_CLE) +#define CPLD_CFG_nCE BIT(CPLD_GPIO_nCE) +#define CPLD_CFG_nLED5 BIT(CPLD_GPIO_nLED5) + +struct rb4xx_cpld_platform_data { + unsigned gpio_base; +}; + +extern int rb4xx_cpld_change_cfg(unsigned mask, unsigned value); +extern int rb4xx_cpld_read(unsigned char *rx_buf, + const unsigned char *verify_buf, + unsigned cnt); +extern int rb4xx_cpld_read_from(unsigned addr, + unsigned char *rx_buf, + const unsigned char *verify_buf, + unsigned cnt); +extern int rb4xx_cpld_write(const unsigned char *buf, unsigned count); -- cgit v1.2.3