mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 08:44:21 +08:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/nico/orion into devel-stable
This commit is contained in:
commit
4af8f24d99
@ -15,6 +15,7 @@ CONFIG_MACH_MV88F6281GTW_GE=y
|
||||
CONFIG_MACH_SHEEVAPLUG=y
|
||||
CONFIG_MACH_ESATA_SHEEVAPLUG=y
|
||||
CONFIG_MACH_GURUPLUG=y
|
||||
CONFIG_MACH_DOCKSTAR=y
|
||||
CONFIG_MACH_TS219=y
|
||||
CONFIG_MACH_TS41X=y
|
||||
CONFIG_MACH_OPENRD_BASE=y
|
||||
|
@ -58,6 +58,12 @@ config MACH_TS41X
|
||||
QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS
|
||||
devices.
|
||||
|
||||
config MACH_DOCKSTAR
|
||||
bool "Seagate FreeAgent DockStar"
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
Seagate FreeAgent DockStar.
|
||||
|
||||
config MACH_OPENRD
|
||||
bool
|
||||
|
||||
@ -100,6 +106,12 @@ config MACH_NETSPACE_MAX_V2
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
LaCie Network Space Max v2 NAS.
|
||||
|
||||
config MACH_D2NET_V2
|
||||
bool "LaCie d2 Network v2 NAS Board"
|
||||
help
|
||||
Say 'Y' here if you want your kernel to support the
|
||||
LaCie d2 Network v2 NAS.
|
||||
|
||||
config MACH_NET2BIG_V2
|
||||
bool "LaCie 2Big Network v2 NAS Board"
|
||||
help
|
||||
|
@ -7,14 +7,16 @@ obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o
|
||||
obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o
|
||||
obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG) += sheevaplug-setup.o
|
||||
obj-$(CONFIG_MACH_GURUPLUG) += guruplug-setup.o
|
||||
obj-$(CONFIG_MACH_DOCKSTAR) += dockstar-setup.o
|
||||
obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o
|
||||
obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o
|
||||
obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o
|
||||
obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o
|
||||
obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o
|
||||
obj-$(CONFIG_MACH_NETSPACE_MAX_V2) += netspace_v2-setup.o
|
||||
obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o
|
||||
obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o
|
||||
obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o
|
||||
obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o
|
||||
obj-$(CONFIG_MACH_NETSPACE_MAX_V2) += netspace_v2-setup.o lacie_v2-common.o
|
||||
obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o
|
||||
obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
|
||||
obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
|
||||
obj-$(CONFIG_MACH_T5325) += t5325-setup.o
|
||||
|
||||
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
|
||||
|
231
arch/arm/mach-kirkwood/d2net_v2-setup.c
Normal file
231
arch/arm/mach-kirkwood/d2net_v2-setup.c
Normal file
@ -0,0 +1,231 @@
|
||||
/*
|
||||
* arch/arm/mach-kirkwood/d2net_v2-setup.c
|
||||
*
|
||||
* LaCie d2 Network Space v2 Board Setup
|
||||
*
|
||||
* Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
|
||||
*
|
||||
* 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 program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/leds.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <mach/kirkwood.h>
|
||||
#include <mach/leds-ns2.h>
|
||||
#include "common.h"
|
||||
#include "mpp.h"
|
||||
#include "lacie_v2-common.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Ethernet
|
||||
****************************************************************************/
|
||||
|
||||
static struct mv643xx_eth_platform_data d2net_v2_ge00_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* SATA
|
||||
****************************************************************************/
|
||||
|
||||
static struct mv_sata_platform_data d2net_v2_sata_data = {
|
||||
.n_ports = 2,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* GPIO keys
|
||||
****************************************************************************/
|
||||
|
||||
#define D2NET_V2_GPIO_PUSH_BUTTON 34
|
||||
#define D2NET_V2_GPIO_POWER_SWITCH_ON 13
|
||||
#define D2NET_V2_GPIO_POWER_SWITCH_OFF 15
|
||||
|
||||
#define D2NET_V2_SWITCH_POWER_ON 0x1
|
||||
#define D2NET_V2_SWITCH_POWER_OFF 0x2
|
||||
|
||||
static struct gpio_keys_button d2net_v2_buttons[] = {
|
||||
[0] = {
|
||||
.type = EV_SW,
|
||||
.code = D2NET_V2_SWITCH_POWER_ON,
|
||||
.gpio = D2NET_V2_GPIO_POWER_SWITCH_ON,
|
||||
.desc = "Back power switch (on|auto)",
|
||||
.active_low = 0,
|
||||
},
|
||||
[1] = {
|
||||
.type = EV_SW,
|
||||
.code = D2NET_V2_SWITCH_POWER_OFF,
|
||||
.gpio = D2NET_V2_GPIO_POWER_SWITCH_OFF,
|
||||
.desc = "Back power switch (auto|off)",
|
||||
.active_low = 0,
|
||||
},
|
||||
[2] = {
|
||||
.code = KEY_POWER,
|
||||
.gpio = D2NET_V2_GPIO_PUSH_BUTTON,
|
||||
.desc = "Front Push Button",
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data d2net_v2_button_data = {
|
||||
.buttons = d2net_v2_buttons,
|
||||
.nbuttons = ARRAY_SIZE(d2net_v2_buttons),
|
||||
};
|
||||
|
||||
static struct platform_device d2net_v2_gpio_buttons = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &d2net_v2_button_data,
|
||||
},
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* GPIO LEDs
|
||||
****************************************************************************/
|
||||
|
||||
#define D2NET_V2_GPIO_RED_LED 12
|
||||
|
||||
static struct gpio_led d2net_v2_gpio_led_pins[] = {
|
||||
{
|
||||
.name = "d2net_v2:red:fail",
|
||||
.gpio = D2NET_V2_GPIO_RED_LED,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data d2net_v2_gpio_leds_data = {
|
||||
.num_leds = ARRAY_SIZE(d2net_v2_gpio_led_pins),
|
||||
.leds = d2net_v2_gpio_led_pins,
|
||||
};
|
||||
|
||||
static struct platform_device d2net_v2_gpio_leds = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &d2net_v2_gpio_leds_data,
|
||||
},
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Dual-GPIO CPLD LEDs
|
||||
****************************************************************************/
|
||||
|
||||
#define D2NET_V2_GPIO_BLUE_LED_SLOW 29
|
||||
#define D2NET_V2_GPIO_BLUE_LED_CMD 30
|
||||
|
||||
static struct ns2_led d2net_v2_led_pins[] = {
|
||||
{
|
||||
.name = "d2net_v2:blue:sata",
|
||||
.cmd = D2NET_V2_GPIO_BLUE_LED_CMD,
|
||||
.slow = D2NET_V2_GPIO_BLUE_LED_SLOW,
|
||||
},
|
||||
};
|
||||
|
||||
static struct ns2_led_platform_data d2net_v2_leds_data = {
|
||||
.num_leds = ARRAY_SIZE(d2net_v2_led_pins),
|
||||
.leds = d2net_v2_led_pins,
|
||||
};
|
||||
|
||||
static struct platform_device d2net_v2_leds = {
|
||||
.name = "leds-ns2",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &d2net_v2_leds_data,
|
||||
},
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
|
||||
static unsigned int d2net_v2_mpp_config[] __initdata = {
|
||||
MPP0_SPI_SCn,
|
||||
MPP1_SPI_MOSI,
|
||||
MPP2_SPI_SCK,
|
||||
MPP3_SPI_MISO,
|
||||
MPP6_SYSRST_OUTn,
|
||||
MPP7_GPO, /* Request power-off */
|
||||
MPP8_TW0_SDA,
|
||||
MPP9_TW0_SCK,
|
||||
MPP10_UART0_TXD,
|
||||
MPP11_UART0_RXD,
|
||||
MPP12_GPO, /* Red led */
|
||||
MPP13_GPIO, /* Rear power switch (on|auto) */
|
||||
MPP14_GPIO, /* USB fuse */
|
||||
MPP15_GPIO, /* Rear power switch (auto|off) */
|
||||
MPP16_GPIO, /* SATA 0 power */
|
||||
MPP21_SATA0_ACTn,
|
||||
MPP24_GPIO, /* USB mode select */
|
||||
MPP26_GPIO, /* USB device vbus */
|
||||
MPP28_GPIO, /* USB enable host vbus */
|
||||
MPP29_GPIO, /* Blue led (slow register) */
|
||||
MPP30_GPIO, /* Blue led (command register) */
|
||||
MPP34_GPIO, /* Power button (1 = Released, 0 = Pushed) */
|
||||
MPP35_GPIO, /* Inhibit power-off */
|
||||
0
|
||||
};
|
||||
|
||||
#define D2NET_V2_GPIO_POWER_OFF 7
|
||||
|
||||
static void d2net_v2_power_off(void)
|
||||
{
|
||||
gpio_set_value(D2NET_V2_GPIO_POWER_OFF, 1);
|
||||
}
|
||||
|
||||
static void __init d2net_v2_init(void)
|
||||
{
|
||||
/*
|
||||
* Basic setup. Needs to be called early.
|
||||
*/
|
||||
kirkwood_init();
|
||||
kirkwood_mpp_conf(d2net_v2_mpp_config);
|
||||
|
||||
lacie_v2_hdd_power_init(1);
|
||||
|
||||
kirkwood_ehci_init();
|
||||
kirkwood_ge00_init(&d2net_v2_ge00_data);
|
||||
kirkwood_sata_init(&d2net_v2_sata_data);
|
||||
kirkwood_uart0_init();
|
||||
lacie_v2_register_flash();
|
||||
lacie_v2_register_i2c_devices();
|
||||
|
||||
platform_device_register(&d2net_v2_leds);
|
||||
platform_device_register(&d2net_v2_gpio_leds);
|
||||
platform_device_register(&d2net_v2_gpio_buttons);
|
||||
|
||||
if (gpio_request(D2NET_V2_GPIO_POWER_OFF, "power-off") == 0 &&
|
||||
gpio_direction_output(D2NET_V2_GPIO_POWER_OFF, 0) == 0)
|
||||
pm_power_off = d2net_v2_power_off;
|
||||
else
|
||||
pr_err("d2net_v2: failed to configure power-off GPIO\n");
|
||||
}
|
||||
|
||||
MACHINE_START(D2NET_V2, "LaCie d2 Network v2")
|
||||
.phys_io = KIRKWOOD_REGS_PHYS_BASE,
|
||||
.io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000100,
|
||||
.init_machine = d2net_v2_init,
|
||||
.map_io = kirkwood_map_io,
|
||||
.init_irq = kirkwood_init_irq,
|
||||
.timer = &lacie_v2_timer,
|
||||
MACHINE_END
|
112
arch/arm/mach-kirkwood/dockstar-setup.c
Normal file
112
arch/arm/mach-kirkwood/dockstar-setup.c
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* arch/arm/mach-kirkwood/dockstar-setup.c
|
||||
*
|
||||
* Seagate FreeAgent DockStar Setup
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/leds.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <mach/kirkwood.h>
|
||||
#include <plat/mvsdio.h>
|
||||
#include "common.h"
|
||||
#include "mpp.h"
|
||||
|
||||
static struct mtd_partition dockstar_nand_parts[] = {
|
||||
{
|
||||
.name = "u-boot",
|
||||
.offset = 0,
|
||||
.size = SZ_1M
|
||||
}, {
|
||||
.name = "uImage",
|
||||
.offset = MTDPART_OFS_NXTBLK,
|
||||
.size = SZ_4M
|
||||
}, {
|
||||
.name = "root",
|
||||
.offset = MTDPART_OFS_NXTBLK,
|
||||
.size = MTDPART_SIZ_FULL
|
||||
},
|
||||
};
|
||||
|
||||
static struct mv643xx_eth_platform_data dockstar_ge00_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(0),
|
||||
};
|
||||
|
||||
static struct gpio_led dockstar_led_pins[] = {
|
||||
{
|
||||
.name = "dockstar:green:health",
|
||||
.default_trigger = "default-on",
|
||||
.gpio = 46,
|
||||
.active_low = 1,
|
||||
},
|
||||
{
|
||||
.name = "dockstar:orange:misc",
|
||||
.default_trigger = "none",
|
||||
.gpio = 47,
|
||||
.active_low = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data dockstar_led_data = {
|
||||
.leds = dockstar_led_pins,
|
||||
.num_leds = ARRAY_SIZE(dockstar_led_pins),
|
||||
};
|
||||
|
||||
static struct platform_device dockstar_leds = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &dockstar_led_data,
|
||||
}
|
||||
};
|
||||
|
||||
static unsigned int dockstar_mpp_config[] __initdata = {
|
||||
MPP29_GPIO, /* USB Power Enable */
|
||||
MPP46_GPIO, /* LED green */
|
||||
MPP47_GPIO, /* LED orange */
|
||||
0
|
||||
};
|
||||
|
||||
static void __init dockstar_init(void)
|
||||
{
|
||||
/*
|
||||
* Basic setup. Needs to be called early.
|
||||
*/
|
||||
kirkwood_init();
|
||||
|
||||
/* setup gpio pin select */
|
||||
kirkwood_mpp_conf(dockstar_mpp_config);
|
||||
|
||||
kirkwood_uart0_init();
|
||||
kirkwood_nand_init(ARRAY_AND_SIZE(dockstar_nand_parts), 25);
|
||||
|
||||
if (gpio_request(29, "USB Power Enable") != 0 ||
|
||||
gpio_direction_output(29, 1) != 0)
|
||||
printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n");
|
||||
kirkwood_ehci_init();
|
||||
|
||||
kirkwood_ge00_init(&dockstar_ge00_data);
|
||||
|
||||
platform_device_register(&dockstar_leds);
|
||||
}
|
||||
|
||||
MACHINE_START(DOCKSTAR, "Seagate FreeAgent DockStar")
|
||||
.phys_io = KIRKWOOD_REGS_PHYS_BASE,
|
||||
.io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
|
||||
.boot_params = 0x00000100,
|
||||
.init_machine = dockstar_init,
|
||||
.map_io = kirkwood_map_io,
|
||||
.init_irq = kirkwood_init_irq,
|
||||
.timer = &kirkwood_timer,
|
||||
MACHINE_END
|
55
arch/arm/mach-kirkwood/include/mach/leds-netxbig.h
Normal file
55
arch/arm/mach-kirkwood/include/mach/leds-netxbig.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* arch/arm/mach-kirkwood/include/mach/leds-netxbig.h
|
||||
*
|
||||
* Platform data structure for netxbig LED driver
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#ifndef __MACH_LEDS_NETXBIG_H
|
||||
#define __MACH_LEDS_NETXBIG_H
|
||||
|
||||
struct netxbig_gpio_ext {
|
||||
unsigned *addr;
|
||||
int num_addr;
|
||||
unsigned *data;
|
||||
int num_data;
|
||||
unsigned enable;
|
||||
};
|
||||
|
||||
enum netxbig_led_mode {
|
||||
NETXBIG_LED_OFF,
|
||||
NETXBIG_LED_ON,
|
||||
NETXBIG_LED_SATA,
|
||||
NETXBIG_LED_TIMER1,
|
||||
NETXBIG_LED_TIMER2,
|
||||
NETXBIG_LED_MODE_NUM,
|
||||
};
|
||||
|
||||
#define NETXBIG_LED_INVALID_MODE NETXBIG_LED_MODE_NUM
|
||||
|
||||
struct netxbig_led_timer {
|
||||
unsigned long delay_on;
|
||||
unsigned long delay_off;
|
||||
enum netxbig_led_mode mode;
|
||||
};
|
||||
|
||||
struct netxbig_led {
|
||||
const char *name;
|
||||
const char *default_trigger;
|
||||
int mode_addr;
|
||||
int *mode_val;
|
||||
int bright_addr;
|
||||
};
|
||||
|
||||
struct netxbig_led_platform_data {
|
||||
struct netxbig_gpio_ext *gpio_ext;
|
||||
struct netxbig_led_timer *timer;
|
||||
int num_timer;
|
||||
struct netxbig_led *leds;
|
||||
int num_leds;
|
||||
};
|
||||
|
||||
#endif /* __MACH_LEDS_NETXBIG_H */
|
127
arch/arm/mach-kirkwood/lacie_v2-common.c
Normal file
127
arch/arm/mach-kirkwood/lacie_v2-common.c
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* arch/arm/mach-kirkwood/lacie_v2-common.c
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/spi/flash.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/at24.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <mach/kirkwood.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <plat/time.h>
|
||||
#include "common.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
|
||||
****************************************************************************/
|
||||
|
||||
static struct mtd_partition lacie_v2_flash_parts[] = {
|
||||
{
|
||||
.name = "u-boot",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = 0,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
},
|
||||
};
|
||||
|
||||
static const struct flash_platform_data lacie_v2_flash = {
|
||||
.type = "mx25l4005a",
|
||||
.name = "spi_flash",
|
||||
.parts = lacie_v2_flash_parts,
|
||||
.nr_parts = ARRAY_SIZE(lacie_v2_flash_parts),
|
||||
};
|
||||
|
||||
static struct spi_board_info __initdata lacie_v2_spi_slave_info[] = {
|
||||
{
|
||||
.modalias = "m25p80",
|
||||
.platform_data = &lacie_v2_flash,
|
||||
.irq = -1,
|
||||
.max_speed_hz = 20000000,
|
||||
.bus_num = 0,
|
||||
.chip_select = 0,
|
||||
},
|
||||
};
|
||||
|
||||
void __init lacie_v2_register_flash(void)
|
||||
{
|
||||
spi_register_board_info(lacie_v2_spi_slave_info,
|
||||
ARRAY_SIZE(lacie_v2_spi_slave_info));
|
||||
kirkwood_spi_init();
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* I2C devices
|
||||
****************************************************************************/
|
||||
|
||||
static struct at24_platform_data at24c04 = {
|
||||
.byte_len = SZ_4K / 8,
|
||||
.page_size = 16,
|
||||
};
|
||||
|
||||
/*
|
||||
* i2c addr | chip | description
|
||||
* 0x50 | HT24LC04 | eeprom (512B)
|
||||
*/
|
||||
|
||||
static struct i2c_board_info __initdata lacie_v2_i2c_info[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("24c04", 0x50),
|
||||
.platform_data = &at24c04,
|
||||
}
|
||||
};
|
||||
|
||||
void __init lacie_v2_register_i2c_devices(void)
|
||||
{
|
||||
kirkwood_i2c_init();
|
||||
i2c_register_board_info(0, lacie_v2_i2c_info,
|
||||
ARRAY_SIZE(lacie_v2_i2c_info));
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Hard Disk power
|
||||
****************************************************************************/
|
||||
|
||||
static int __initdata lacie_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 };
|
||||
|
||||
void __init lacie_v2_hdd_power_init(int hdd_num)
|
||||
{
|
||||
int i;
|
||||
int err;
|
||||
|
||||
/* Power up all hard disks. */
|
||||
for (i = 0; i < hdd_num; i++) {
|
||||
err = gpio_request(lacie_v2_gpio_hdd_power[i], NULL);
|
||||
if (err == 0) {
|
||||
err = gpio_direction_output(
|
||||
lacie_v2_gpio_hdd_power[i], 1);
|
||||
/* Free the HDD power GPIOs. This allow user-space to
|
||||
* configure them via the gpiolib sysfs interface. */
|
||||
gpio_free(lacie_v2_gpio_hdd_power[i]);
|
||||
}
|
||||
if (err)
|
||||
pr_err("Failed to power up HDD%d\n", i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Timer
|
||||
****************************************************************************/
|
||||
|
||||
static void lacie_v2_timer_init(void)
|
||||
{
|
||||
kirkwood_tclk = 166666667;
|
||||
orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
|
||||
}
|
||||
|
||||
struct sys_timer lacie_v2_timer = {
|
||||
.init = lacie_v2_timer_init,
|
||||
};
|
18
arch/arm/mach-kirkwood/lacie_v2-common.h
Normal file
18
arch/arm/mach-kirkwood/lacie_v2-common.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* arch/arm/mach-kirkwood/lacie_v2-common.h
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_KIRKWOOD_LACIE_V2_COMMON_H
|
||||
#define __ARCH_KIRKWOOD_LACIE_V2_COMMON_H
|
||||
|
||||
void lacie_v2_register_flash(void);
|
||||
void lacie_v2_register_i2c_devices(void);
|
||||
void lacie_v2_hdd_power_init(int hdd_num);
|
||||
|
||||
extern struct sys_timer lacie_v2_timer;
|
||||
|
||||
#endif
|
@ -24,56 +24,19 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/spi/flash.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/at24.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/leds.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <mach/kirkwood.h>
|
||||
#include <mach/leds-ns2.h>
|
||||
#include <plat/time.h>
|
||||
#include "common.h"
|
||||
#include "mpp.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
|
||||
****************************************************************************/
|
||||
|
||||
static struct mtd_partition netspace_v2_flash_parts[] = {
|
||||
{
|
||||
.name = "u-boot",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = 0,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
},
|
||||
};
|
||||
|
||||
static const struct flash_platform_data netspace_v2_flash = {
|
||||
.type = "mx25l4005a",
|
||||
.name = "spi_flash",
|
||||
.parts = netspace_v2_flash_parts,
|
||||
.nr_parts = ARRAY_SIZE(netspace_v2_flash_parts),
|
||||
};
|
||||
|
||||
static struct spi_board_info __initdata netspace_v2_spi_slave_info[] = {
|
||||
{
|
||||
.modalias = "m25p80",
|
||||
.platform_data = &netspace_v2_flash,
|
||||
.irq = -1,
|
||||
.max_speed_hz = 20000000,
|
||||
.bus_num = 0,
|
||||
.chip_select = 0,
|
||||
},
|
||||
};
|
||||
#include "lacie_v2-common.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Ethernet
|
||||
@ -83,27 +46,6 @@ static struct mv643xx_eth_platform_data netspace_v2_ge00_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* I2C devices
|
||||
****************************************************************************/
|
||||
|
||||
static struct at24_platform_data at24c04 = {
|
||||
.byte_len = SZ_4K / 8,
|
||||
.page_size = 16,
|
||||
};
|
||||
|
||||
/*
|
||||
* i2c addr | chip | description
|
||||
* 0x50 | HT24LC04 | eeprom (512B)
|
||||
*/
|
||||
|
||||
static struct i2c_board_info __initdata netspace_v2_i2c_info[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("24c04", 0x50),
|
||||
.platform_data = &at24c04,
|
||||
}
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* SATA
|
||||
****************************************************************************/
|
||||
@ -112,35 +54,6 @@ static struct mv_sata_platform_data netspace_v2_sata_data = {
|
||||
.n_ports = 2,
|
||||
};
|
||||
|
||||
#define NETSPACE_V2_GPIO_SATA0_POWER 16
|
||||
#define NETSPACE_V2_GPIO_SATA1_POWER 17
|
||||
|
||||
static void __init netspace_v2_sata_power_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = gpio_request(NETSPACE_V2_GPIO_SATA0_POWER, "SATA0 power");
|
||||
if (err == 0) {
|
||||
err = gpio_direction_output(NETSPACE_V2_GPIO_SATA0_POWER, 1);
|
||||
if (err)
|
||||
gpio_free(NETSPACE_V2_GPIO_SATA0_POWER);
|
||||
}
|
||||
if (err)
|
||||
pr_err("netspace_v2: failed to setup SATA0 power\n");
|
||||
|
||||
if (machine_is_netspace_max_v2()) {
|
||||
err = gpio_request(NETSPACE_V2_GPIO_SATA1_POWER, "SATA1 power");
|
||||
if (err == 0) {
|
||||
err = gpio_direction_output(
|
||||
NETSPACE_V2_GPIO_SATA1_POWER, 1);
|
||||
if (err)
|
||||
gpio_free(NETSPACE_V2_GPIO_SATA1_POWER);
|
||||
}
|
||||
if (err)
|
||||
pr_err("netspace_v2: failed to setup SATA1 power\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* GPIO keys
|
||||
****************************************************************************/
|
||||
@ -223,20 +136,6 @@ static struct platform_device netspace_v2_leds = {
|
||||
},
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Timer
|
||||
****************************************************************************/
|
||||
|
||||
static void netspace_v2_timer_init(void)
|
||||
{
|
||||
kirkwood_tclk = 166666667;
|
||||
orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
|
||||
}
|
||||
|
||||
struct sys_timer netspace_v2_timer = {
|
||||
.init = netspace_v2_timer_init,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* General Setup
|
||||
****************************************************************************/
|
||||
@ -291,18 +190,17 @@ static void __init netspace_v2_init(void)
|
||||
kirkwood_init();
|
||||
kirkwood_mpp_conf(netspace_v2_mpp_config);
|
||||
|
||||
netspace_v2_sata_power_init();
|
||||
if (machine_is_netspace_max_v2())
|
||||
lacie_v2_hdd_power_init(2);
|
||||
else
|
||||
lacie_v2_hdd_power_init(1);
|
||||
|
||||
kirkwood_ehci_init();
|
||||
kirkwood_ge00_init(&netspace_v2_ge00_data);
|
||||
kirkwood_sata_init(&netspace_v2_sata_data);
|
||||
kirkwood_uart0_init();
|
||||
spi_register_board_info(netspace_v2_spi_slave_info,
|
||||
ARRAY_SIZE(netspace_v2_spi_slave_info));
|
||||
kirkwood_spi_init();
|
||||
kirkwood_i2c_init();
|
||||
i2c_register_board_info(0, netspace_v2_i2c_info,
|
||||
ARRAY_SIZE(netspace_v2_i2c_info));
|
||||
lacie_v2_register_flash();
|
||||
lacie_v2_register_i2c_devices();
|
||||
|
||||
platform_device_register(&netspace_v2_leds);
|
||||
platform_device_register(&netspace_v2_gpio_leds);
|
||||
@ -323,7 +221,7 @@ MACHINE_START(NETSPACE_V2, "LaCie Network Space v2")
|
||||
.init_machine = netspace_v2_init,
|
||||
.map_io = kirkwood_map_io,
|
||||
.init_irq = kirkwood_init_irq,
|
||||
.timer = &netspace_v2_timer,
|
||||
.timer = &lacie_v2_timer,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
@ -335,7 +233,7 @@ MACHINE_START(INETSPACE_V2, "LaCie Internet Space v2")
|
||||
.init_machine = netspace_v2_init,
|
||||
.map_io = kirkwood_map_io,
|
||||
.init_irq = kirkwood_init_irq,
|
||||
.timer = &netspace_v2_timer,
|
||||
.timer = &lacie_v2_timer,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
@ -347,6 +245,6 @@ MACHINE_START(NETSPACE_MAX_V2, "LaCie Network Space Max v2")
|
||||
.init_machine = netspace_v2_init,
|
||||
.map_io = kirkwood_map_io,
|
||||
.init_irq = kirkwood_init_irq,
|
||||
.timer = &netspace_v2_timer,
|
||||
.timer = &lacie_v2_timer,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
@ -23,55 +23,19 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/spi/flash.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/at24.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/leds.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <mach/kirkwood.h>
|
||||
#include <plat/time.h>
|
||||
#include <mach/leds-netxbig.h>
|
||||
#include "common.h"
|
||||
#include "mpp.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
|
||||
****************************************************************************/
|
||||
|
||||
static struct mtd_partition netxbig_v2_flash_parts[] = {
|
||||
{
|
||||
.name = "u-boot",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = 0,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
},
|
||||
};
|
||||
|
||||
static const struct flash_platform_data netxbig_v2_flash = {
|
||||
.type = "mx25l4005a",
|
||||
.name = "spi_flash",
|
||||
.parts = netxbig_v2_flash_parts,
|
||||
.nr_parts = ARRAY_SIZE(netxbig_v2_flash_parts),
|
||||
};
|
||||
|
||||
static struct spi_board_info __initdata netxbig_v2_spi_slave_info[] = {
|
||||
{
|
||||
.modalias = "m25p80",
|
||||
.platform_data = &netxbig_v2_flash,
|
||||
.irq = -1,
|
||||
.max_speed_hz = 20000000,
|
||||
.bus_num = 0,
|
||||
.chip_select = 0,
|
||||
},
|
||||
};
|
||||
#include "lacie_v2-common.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Ethernet
|
||||
@ -85,27 +49,6 @@ static struct mv643xx_eth_platform_data netxbig_v2_ge01_data = {
|
||||
.phy_addr = MV643XX_ETH_PHY_ADDR(0),
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* I2C devices
|
||||
****************************************************************************/
|
||||
|
||||
static struct at24_platform_data at24c04 = {
|
||||
.byte_len = SZ_4K / 8,
|
||||
.page_size = 16,
|
||||
};
|
||||
|
||||
/*
|
||||
* i2c addr | chip | description
|
||||
* 0x50 | HT24LC04 | eeprom (512B)
|
||||
*/
|
||||
|
||||
static struct i2c_board_info __initdata netxbig_v2_i2c_info[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("24c04", 0x50),
|
||||
.platform_data = &at24c04,
|
||||
}
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* SATA
|
||||
****************************************************************************/
|
||||
@ -114,34 +57,6 @@ static struct mv_sata_platform_data netxbig_v2_sata_data = {
|
||||
.n_ports = 2,
|
||||
};
|
||||
|
||||
static int __initdata netxbig_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 };
|
||||
|
||||
static void __init netxbig_v2_sata_power_init(void)
|
||||
{
|
||||
int i;
|
||||
int err;
|
||||
int hdd_nb;
|
||||
|
||||
if (machine_is_net2big_v2())
|
||||
hdd_nb = 2;
|
||||
else
|
||||
hdd_nb = 5;
|
||||
|
||||
/* Power up all hard disks. */
|
||||
for (i = 0; i < hdd_nb; i++) {
|
||||
err = gpio_request(netxbig_v2_gpio_hdd_power[i], NULL);
|
||||
if (err == 0) {
|
||||
err = gpio_direction_output(
|
||||
netxbig_v2_gpio_hdd_power[i], 1);
|
||||
/* Free the HDD power GPIOs. This allow user-space to
|
||||
* configure them via the gpiolib sysfs interface. */
|
||||
gpio_free(netxbig_v2_gpio_hdd_power[i]);
|
||||
}
|
||||
if (err)
|
||||
pr_err("netxbig_v2: failed to power up HDD%d\n", i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* GPIO keys
|
||||
****************************************************************************/
|
||||
@ -190,7 +105,7 @@ static struct platform_device netxbig_v2_gpio_buttons = {
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* GPIO LEDs
|
||||
* GPIO extension LEDs
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
@ -200,19 +115,32 @@ static struct platform_device netxbig_v2_gpio_buttons = {
|
||||
* - address register : bit [0-2] -> GPIO [47-49]
|
||||
* - data register : bit [0-2] -> GPIO [44-46]
|
||||
* - enable register : GPIO 29
|
||||
*
|
||||
*/
|
||||
|
||||
static int netxbig_v2_gpio_ext_addr[] = { 47, 48, 49 };
|
||||
static int netxbig_v2_gpio_ext_data[] = { 44, 45, 46 };
|
||||
|
||||
static struct netxbig_gpio_ext netxbig_v2_gpio_ext = {
|
||||
.addr = netxbig_v2_gpio_ext_addr,
|
||||
.num_addr = ARRAY_SIZE(netxbig_v2_gpio_ext_addr),
|
||||
.data = netxbig_v2_gpio_ext_data,
|
||||
.num_data = ARRAY_SIZE(netxbig_v2_gpio_ext_data),
|
||||
.enable = 29,
|
||||
};
|
||||
|
||||
/*
|
||||
* Address register selection:
|
||||
*
|
||||
* addr | register
|
||||
* ----------------------------
|
||||
* 0 | front LED
|
||||
* 1 | front LED brightness
|
||||
* 2 | HDD LED brightness
|
||||
* 3 | HDD1 LED
|
||||
* 4 | HDD2 LED
|
||||
* 5 | HDD3 LED
|
||||
* 6 | HDD4 LED
|
||||
* 7 | HDD5 LED
|
||||
* 2 | SATA LED brightness
|
||||
* 3 | SATA0 LED
|
||||
* 4 | SATA1 LED
|
||||
* 5 | SATA2 LED
|
||||
* 6 | SATA3 LED
|
||||
* 7 | SATA4 LED
|
||||
*
|
||||
* Data register configuration:
|
||||
*
|
||||
@ -233,30 +161,107 @@ static struct platform_device netxbig_v2_gpio_buttons = {
|
||||
* 6 | blink blue on=1 sec and red on=1 sec
|
||||
* 7 | blink blue on=0.5 sec and blue off=2.5 sec
|
||||
*
|
||||
* data | HDD LED mode
|
||||
* data | SATA LED mode
|
||||
* -------------------------------------------------
|
||||
* 0 | fix blue on
|
||||
* 0 | fix off
|
||||
* 1 | SATA activity blink
|
||||
* 2 | fix red on
|
||||
* 3 | blink blue on=1 sec and blue off=1 sec
|
||||
* 4 | blink red on=1 sec and red off=1 sec
|
||||
* 5 | blink blue on=2.5 sec and red on=0.5 sec
|
||||
* 6 | blink blue on=1 sec and red on=1 sec
|
||||
* 7 | blink blue on=0.5 sec and blue off=2.5 sec
|
||||
* 7 | fix blue on
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* Timer
|
||||
****************************************************************************/
|
||||
static int netxbig_v2_red_mled[NETXBIG_LED_MODE_NUM] = {
|
||||
[NETXBIG_LED_OFF] = 0,
|
||||
[NETXBIG_LED_ON] = 2,
|
||||
[NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE,
|
||||
[NETXBIG_LED_TIMER1] = 4,
|
||||
[NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE,
|
||||
};
|
||||
|
||||
static void netxbig_v2_timer_init(void)
|
||||
{
|
||||
kirkwood_tclk = 166666667;
|
||||
orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
|
||||
}
|
||||
static int netxbig_v2_blue_pwr_mled[NETXBIG_LED_MODE_NUM] = {
|
||||
[NETXBIG_LED_OFF] = 0,
|
||||
[NETXBIG_LED_ON] = 1,
|
||||
[NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE,
|
||||
[NETXBIG_LED_TIMER1] = 3,
|
||||
[NETXBIG_LED_TIMER2] = 7,
|
||||
};
|
||||
|
||||
struct sys_timer netxbig_v2_timer = {
|
||||
.init = netxbig_v2_timer_init,
|
||||
static int netxbig_v2_blue_sata_mled[NETXBIG_LED_MODE_NUM] = {
|
||||
[NETXBIG_LED_OFF] = 0,
|
||||
[NETXBIG_LED_ON] = 7,
|
||||
[NETXBIG_LED_SATA] = 1,
|
||||
[NETXBIG_LED_TIMER1] = 3,
|
||||
[NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE,
|
||||
};
|
||||
|
||||
static struct netxbig_led_timer netxbig_v2_led_timer[] = {
|
||||
[0] = {
|
||||
.delay_on = 500,
|
||||
.delay_off = 500,
|
||||
.mode = NETXBIG_LED_TIMER1,
|
||||
},
|
||||
[1] = {
|
||||
.delay_on = 500,
|
||||
.delay_off = 1000,
|
||||
.mode = NETXBIG_LED_TIMER2,
|
||||
},
|
||||
};
|
||||
|
||||
#define NETXBIG_LED(_name, maddr, mval, baddr) \
|
||||
{ .name = _name, \
|
||||
.mode_addr = maddr, \
|
||||
.mode_val = mval, \
|
||||
.bright_addr = baddr }
|
||||
|
||||
static struct netxbig_led net2big_v2_leds_ctrl[] = {
|
||||
NETXBIG_LED("net2big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1),
|
||||
NETXBIG_LED("net2big-v2:red:power", 0, netxbig_v2_red_mled, 1),
|
||||
NETXBIG_LED("net2big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
|
||||
NETXBIG_LED("net2big-v2:red:sata0", 3, netxbig_v2_red_mled, 2),
|
||||
NETXBIG_LED("net2big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
|
||||
NETXBIG_LED("net2big-v2:red:sata1", 4, netxbig_v2_red_mled, 2),
|
||||
};
|
||||
|
||||
static struct netxbig_led_platform_data net2big_v2_leds_data = {
|
||||
.gpio_ext = &netxbig_v2_gpio_ext,
|
||||
.timer = netxbig_v2_led_timer,
|
||||
.num_timer = ARRAY_SIZE(netxbig_v2_led_timer),
|
||||
.leds = net2big_v2_leds_ctrl,
|
||||
.num_leds = ARRAY_SIZE(net2big_v2_leds_ctrl),
|
||||
};
|
||||
|
||||
static struct netxbig_led net5big_v2_leds_ctrl[] = {
|
||||
NETXBIG_LED("net5big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1),
|
||||
NETXBIG_LED("net5big-v2:red:power", 0, netxbig_v2_red_mled, 1),
|
||||
NETXBIG_LED("net5big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
|
||||
NETXBIG_LED("net5big-v2:red:sata0", 3, netxbig_v2_red_mled, 2),
|
||||
NETXBIG_LED("net5big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
|
||||
NETXBIG_LED("net5big-v2:red:sata1", 4, netxbig_v2_red_mled, 2),
|
||||
NETXBIG_LED("net5big-v2:blue:sata2", 5, netxbig_v2_blue_sata_mled, 2),
|
||||
NETXBIG_LED("net5big-v2:red:sata2", 5, netxbig_v2_red_mled, 2),
|
||||
NETXBIG_LED("net5big-v2:blue:sata3", 6, netxbig_v2_blue_sata_mled, 2),
|
||||
NETXBIG_LED("net5big-v2:red:sata3", 6, netxbig_v2_red_mled, 2),
|
||||
NETXBIG_LED("net5big-v2:blue:sata4", 7, netxbig_v2_blue_sata_mled, 2),
|
||||
NETXBIG_LED("net5big-v2:red:sata5", 7, netxbig_v2_red_mled, 2),
|
||||
};
|
||||
|
||||
static struct netxbig_led_platform_data net5big_v2_leds_data = {
|
||||
.gpio_ext = &netxbig_v2_gpio_ext,
|
||||
.timer = netxbig_v2_led_timer,
|
||||
.num_timer = ARRAY_SIZE(netxbig_v2_led_timer),
|
||||
.leds = net5big_v2_leds_ctrl,
|
||||
.num_leds = ARRAY_SIZE(net5big_v2_leds_ctrl),
|
||||
};
|
||||
|
||||
static struct platform_device netxbig_v2_leds = {
|
||||
.name = "leds-netxbig",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &net2big_v2_leds_data,
|
||||
},
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
@ -284,18 +289,18 @@ static unsigned int net2big_v2_mpp_config[] __initdata = {
|
||||
MPP24_GPIO, /* USB mode select */
|
||||
MPP26_GPIO, /* USB device vbus */
|
||||
MPP28_GPIO, /* USB enable host vbus */
|
||||
MPP29_GPIO, /* CPLD extension ALE */
|
||||
MPP29_GPIO, /* GPIO extension ALE */
|
||||
MPP34_GPIO, /* Rear Push button */
|
||||
MPP35_GPIO, /* Inhibit switch power-off */
|
||||
MPP36_GPIO, /* SATA HDD1 presence */
|
||||
MPP37_GPIO, /* SATA HDD2 presence */
|
||||
MPP40_GPIO, /* eSATA presence */
|
||||
MPP44_GPIO, /* CPLD extension (data 0) */
|
||||
MPP45_GPIO, /* CPLD extension (data 1) */
|
||||
MPP46_GPIO, /* CPLD extension (data 2) */
|
||||
MPP47_GPIO, /* CPLD extension (addr 0) */
|
||||
MPP48_GPIO, /* CPLD extension (addr 1) */
|
||||
MPP49_GPIO, /* CPLD extension (addr 2) */
|
||||
MPP44_GPIO, /* GPIO extension (data 0) */
|
||||
MPP45_GPIO, /* GPIO extension (data 1) */
|
||||
MPP46_GPIO, /* GPIO extension (data 2) */
|
||||
MPP47_GPIO, /* GPIO extension (addr 0) */
|
||||
MPP48_GPIO, /* GPIO extension (addr 1) */
|
||||
MPP49_GPIO, /* GPIO extension (addr 2) */
|
||||
0
|
||||
};
|
||||
|
||||
@ -324,7 +329,7 @@ static unsigned int net5big_v2_mpp_config[] __initdata = {
|
||||
MPP26_GE1_RXD2,
|
||||
MPP27_GE1_RXD3,
|
||||
MPP28_GPIO, /* USB enable host vbus */
|
||||
MPP29_GPIO, /* CPLD extension ALE */
|
||||
MPP29_GPIO, /* GPIO extension ALE */
|
||||
MPP30_GE1_RXCTL,
|
||||
MPP31_GE1_RXCLK,
|
||||
MPP32_GE1_TCLKOUT,
|
||||
@ -339,12 +344,12 @@ static unsigned int net5big_v2_mpp_config[] __initdata = {
|
||||
MPP41_GPIO, /* SATA HDD3 power */
|
||||
MPP42_GPIO, /* SATA HDD4 power */
|
||||
MPP43_GPIO, /* SATA HDD5 power */
|
||||
MPP44_GPIO, /* CPLD extension (data 0) */
|
||||
MPP45_GPIO, /* CPLD extension (data 1) */
|
||||
MPP46_GPIO, /* CPLD extension (data 2) */
|
||||
MPP47_GPIO, /* CPLD extension (addr 0) */
|
||||
MPP48_GPIO, /* CPLD extension (addr 1) */
|
||||
MPP49_GPIO, /* CPLD extension (addr 2) */
|
||||
MPP44_GPIO, /* GPIO extension (data 0) */
|
||||
MPP45_GPIO, /* GPIO extension (data 1) */
|
||||
MPP46_GPIO, /* GPIO extension (data 2) */
|
||||
MPP47_GPIO, /* GPIO extension (addr 0) */
|
||||
MPP48_GPIO, /* GPIO extension (addr 1) */
|
||||
MPP49_GPIO, /* GPIO extension (addr 2) */
|
||||
0
|
||||
};
|
||||
|
||||
@ -366,7 +371,10 @@ static void __init netxbig_v2_init(void)
|
||||
else
|
||||
kirkwood_mpp_conf(net5big_v2_mpp_config);
|
||||
|
||||
netxbig_v2_sata_power_init();
|
||||
if (machine_is_net2big_v2())
|
||||
lacie_v2_hdd_power_init(2);
|
||||
else
|
||||
lacie_v2_hdd_power_init(5);
|
||||
|
||||
kirkwood_ehci_init();
|
||||
kirkwood_ge00_init(&netxbig_v2_ge00_data);
|
||||
@ -374,13 +382,12 @@ static void __init netxbig_v2_init(void)
|
||||
kirkwood_ge01_init(&netxbig_v2_ge01_data);
|
||||
kirkwood_sata_init(&netxbig_v2_sata_data);
|
||||
kirkwood_uart0_init();
|
||||
spi_register_board_info(netxbig_v2_spi_slave_info,
|
||||
ARRAY_SIZE(netxbig_v2_spi_slave_info));
|
||||
kirkwood_spi_init();
|
||||
kirkwood_i2c_init();
|
||||
i2c_register_board_info(0, netxbig_v2_i2c_info,
|
||||
ARRAY_SIZE(netxbig_v2_i2c_info));
|
||||
lacie_v2_register_flash();
|
||||
lacie_v2_register_i2c_devices();
|
||||
|
||||
if (machine_is_net5big_v2())
|
||||
netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data;
|
||||
platform_device_register(&netxbig_v2_leds);
|
||||
platform_device_register(&netxbig_v2_gpio_buttons);
|
||||
|
||||
if (gpio_request(NETXBIG_V2_GPIO_POWER_OFF, "power-off") == 0 &&
|
||||
@ -398,7 +405,7 @@ MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2")
|
||||
.init_machine = netxbig_v2_init,
|
||||
.map_io = kirkwood_map_io,
|
||||
.init_irq = kirkwood_init_irq,
|
||||
.timer = &netxbig_v2_timer,
|
||||
.timer = &lacie_v2_timer,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
@ -410,6 +417,6 @@ MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2")
|
||||
.init_machine = netxbig_v2_init,
|
||||
.map_io = kirkwood_map_io,
|
||||
.init_irq = kirkwood_init_irq,
|
||||
.timer = &netxbig_v2_timer,
|
||||
.timer = &lacie_v2_timer,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/ata_platform.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <mach/kirkwood.h>
|
||||
@ -57,7 +58,22 @@ static struct mvsdio_platform_data openrd_mvsdio_data = {
|
||||
};
|
||||
|
||||
static unsigned int openrd_mpp_config[] __initdata = {
|
||||
MPP12_SD_CLK,
|
||||
MPP13_SD_CMD,
|
||||
MPP14_SD_D0,
|
||||
MPP15_SD_D1,
|
||||
MPP16_SD_D2,
|
||||
MPP17_SD_D3,
|
||||
MPP28_GPIO,
|
||||
MPP29_GPIO,
|
||||
MPP34_GPIO,
|
||||
0
|
||||
};
|
||||
|
||||
/* Configure MPP for UART1 */
|
||||
static unsigned int openrd_uart1_mpp_config[] __initdata = {
|
||||
MPP13_UART1_TXD,
|
||||
MPP14_UART1_RXD,
|
||||
0
|
||||
};
|
||||
|
||||
@ -67,6 +83,68 @@ static struct i2c_board_info i2c_board_info[] __initdata = {
|
||||
},
|
||||
};
|
||||
|
||||
static int __initdata uart1;
|
||||
|
||||
static int __init sd_uart_selection(char *str)
|
||||
{
|
||||
uart1 = -EINVAL;
|
||||
|
||||
/* Default is SD. Change if required, for UART */
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
if (!strncmp(str, "232", 3)) {
|
||||
uart1 = 232;
|
||||
} else if (!strncmp(str, "485", 3)) {
|
||||
/* OpenRD-Base doesn't have RS485. Treat is as an
|
||||
* unknown argument & just have default setting -
|
||||
* which is SD */
|
||||
if (machine_is_openrd_base()) {
|
||||
uart1 = -ENODEV;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uart1 = 485;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* Parse boot_command_line string kw_openrd_init_uart1=232/485 */
|
||||
__setup("kw_openrd_init_uart1=", sd_uart_selection);
|
||||
|
||||
static int __init uart1_mpp_config(void)
|
||||
{
|
||||
kirkwood_mpp_conf(openrd_uart1_mpp_config);
|
||||
|
||||
if (gpio_request(34, "SD_UART1_SEL")) {
|
||||
printk(KERN_ERR "GPIO request failed for SD/UART1 selection"
|
||||
", gpio: 34\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (gpio_request(28, "RS232_RS485_SEL")) {
|
||||
printk(KERN_ERR "GPIO request failed for RS232/RS485 selection"
|
||||
", gpio# 28\n");
|
||||
gpio_free(34);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Select UART1
|
||||
* Pin # 34: 0 => UART1, 1 => SD */
|
||||
gpio_direction_output(34, 0);
|
||||
|
||||
/* Select RS232 OR RS485
|
||||
* Pin # 28: 0 => RS232, 1 => RS485 */
|
||||
if (uart1 == 232)
|
||||
gpio_direction_output(28, 0);
|
||||
else
|
||||
gpio_direction_output(28, 1);
|
||||
|
||||
gpio_free(34);
|
||||
gpio_free(28);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init openrd_init(void)
|
||||
{
|
||||
/*
|
||||
@ -90,7 +168,6 @@ static void __init openrd_init(void)
|
||||
kirkwood_ge01_init(&openrd_ge01_data);
|
||||
|
||||
kirkwood_sata_init(&openrd_sata_data);
|
||||
kirkwood_sdio_init(&openrd_mvsdio_data);
|
||||
|
||||
kirkwood_i2c_init();
|
||||
|
||||
@ -99,6 +176,28 @@ static void __init openrd_init(void)
|
||||
ARRAY_SIZE(i2c_board_info));
|
||||
kirkwood_audio_init();
|
||||
}
|
||||
|
||||
if (uart1 <= 0) {
|
||||
if (uart1 < 0)
|
||||
printk(KERN_ERR "Invalid kernel parameter to select "
|
||||
"UART1. Defaulting to SD. ERROR CODE: %d\n",
|
||||
uart1);
|
||||
|
||||
/* Select SD
|
||||
* Pin # 34: 0 => UART1, 1 => SD */
|
||||
if (gpio_request(34, "SD_UART1_SEL")) {
|
||||
printk(KERN_ERR "GPIO request failed for SD/UART1 "
|
||||
"selection, gpio: 34\n");
|
||||
} else {
|
||||
|
||||
gpio_direction_output(34, 1);
|
||||
gpio_free(34);
|
||||
kirkwood_sdio_init(&openrd_mvsdio_data);
|
||||
}
|
||||
} else {
|
||||
if (!uart1_mpp_config())
|
||||
kirkwood_uart1_init();
|
||||
}
|
||||
}
|
||||
|
||||
static int __init openrd_pci_init(void)
|
||||
|
@ -304,13 +304,22 @@ config LEDS_MC13783
|
||||
|
||||
config LEDS_NS2
|
||||
tristate "LED support for Network Space v2 GPIO LEDs"
|
||||
depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2
|
||||
depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2 || D2NET_V2
|
||||
default y
|
||||
help
|
||||
This option enable support for the dual-GPIO LED found on the
|
||||
Network Space v2 board (and parents). This include Internet Space v2,
|
||||
Network Space (Max) v2 and d2 Network v2 boards.
|
||||
|
||||
config LEDS_NETXBIG
|
||||
tristate "LED support for Big Network series LEDs"
|
||||
depends on MACH_NET2BIG_V2 || MACH_NET5BIG_V2
|
||||
default y
|
||||
help
|
||||
This option enable support for LEDs found on the LaCie 2Big
|
||||
and 5Big Network v2 boards. The LEDs are wired to a CPLD and are
|
||||
controlled through a GPIO extension bus.
|
||||
|
||||
config LEDS_TRIGGERS
|
||||
bool "LED Trigger support"
|
||||
help
|
||||
|
@ -38,6 +38,7 @@ obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o
|
||||
obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o
|
||||
obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o
|
||||
obj-$(CONFIG_LEDS_NS2) += leds-ns2.o
|
||||
obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o
|
||||
|
||||
# LED SPI Drivers
|
||||
obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
|
||||
|
449
drivers/leds/leds-netxbig.c
Normal file
449
drivers/leds/leds-netxbig.c
Normal file
@ -0,0 +1,449 @@
|
||||
/*
|
||||
* leds-netxbig.c - Driver for the 2Big and 5Big Network series LEDs
|
||||
*
|
||||
* Copyright (C) 2010 LaCie
|
||||
*
|
||||
* Author: Simon Guinot <sguinot@lacie.com>
|
||||
*
|
||||
* 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 program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/leds.h>
|
||||
#include <mach/leds-netxbig.h>
|
||||
|
||||
/*
|
||||
* GPIO extension bus.
|
||||
*/
|
||||
|
||||
static DEFINE_SPINLOCK(gpio_ext_lock);
|
||||
|
||||
static void gpio_ext_set_addr(struct netxbig_gpio_ext *gpio_ext, int addr)
|
||||
{
|
||||
int pin;
|
||||
|
||||
for (pin = 0; pin < gpio_ext->num_addr; pin++)
|
||||
gpio_set_value(gpio_ext->addr[pin], (addr >> pin) & 1);
|
||||
}
|
||||
|
||||
static void gpio_ext_set_data(struct netxbig_gpio_ext *gpio_ext, int data)
|
||||
{
|
||||
int pin;
|
||||
|
||||
for (pin = 0; pin < gpio_ext->num_data; pin++)
|
||||
gpio_set_value(gpio_ext->data[pin], (data >> pin) & 1);
|
||||
}
|
||||
|
||||
static void gpio_ext_enable_select(struct netxbig_gpio_ext *gpio_ext)
|
||||
{
|
||||
/* Enable select is done on the raising edge. */
|
||||
gpio_set_value(gpio_ext->enable, 0);
|
||||
gpio_set_value(gpio_ext->enable, 1);
|
||||
}
|
||||
|
||||
static void gpio_ext_set_value(struct netxbig_gpio_ext *gpio_ext,
|
||||
int addr, int value)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&gpio_ext_lock, flags);
|
||||
gpio_ext_set_addr(gpio_ext, addr);
|
||||
gpio_ext_set_data(gpio_ext, value);
|
||||
gpio_ext_enable_select(gpio_ext);
|
||||
spin_unlock_irqrestore(&gpio_ext_lock, flags);
|
||||
}
|
||||
|
||||
static int __devinit gpio_ext_init(struct netxbig_gpio_ext *gpio_ext)
|
||||
{
|
||||
int err;
|
||||
int i;
|
||||
|
||||
if (unlikely(!gpio_ext))
|
||||
return -EINVAL;
|
||||
|
||||
/* Configure address GPIOs. */
|
||||
for (i = 0; i < gpio_ext->num_addr; i++) {
|
||||
err = gpio_request(gpio_ext->addr[i], "GPIO extension addr");
|
||||
if (err)
|
||||
goto err_free_addr;
|
||||
err = gpio_direction_output(gpio_ext->addr[i], 0);
|
||||
if (err) {
|
||||
gpio_free(gpio_ext->addr[i]);
|
||||
goto err_free_addr;
|
||||
}
|
||||
}
|
||||
/* Configure data GPIOs. */
|
||||
for (i = 0; i < gpio_ext->num_data; i++) {
|
||||
err = gpio_request(gpio_ext->data[i], "GPIO extension data");
|
||||
if (err)
|
||||
goto err_free_data;
|
||||
err = gpio_direction_output(gpio_ext->data[i], 0);
|
||||
if (err) {
|
||||
gpio_free(gpio_ext->data[i]);
|
||||
goto err_free_data;
|
||||
}
|
||||
}
|
||||
/* Configure "enable select" GPIO. */
|
||||
err = gpio_request(gpio_ext->enable, "GPIO extension enable");
|
||||
if (err)
|
||||
goto err_free_data;
|
||||
err = gpio_direction_output(gpio_ext->enable, 0);
|
||||
if (err) {
|
||||
gpio_free(gpio_ext->enable);
|
||||
goto err_free_data;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_data:
|
||||
for (i = i - 1; i >= 0; i--)
|
||||
gpio_free(gpio_ext->data[i]);
|
||||
i = gpio_ext->num_addr;
|
||||
err_free_addr:
|
||||
for (i = i - 1; i >= 0; i--)
|
||||
gpio_free(gpio_ext->addr[i]);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __devexit gpio_ext_free(struct netxbig_gpio_ext *gpio_ext)
|
||||
{
|
||||
int i;
|
||||
|
||||
gpio_free(gpio_ext->enable);
|
||||
for (i = gpio_ext->num_addr - 1; i >= 0; i--)
|
||||
gpio_free(gpio_ext->addr[i]);
|
||||
for (i = gpio_ext->num_data - 1; i >= 0; i--)
|
||||
gpio_free(gpio_ext->data[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class LED driver.
|
||||
*/
|
||||
|
||||
struct netxbig_led_data {
|
||||
struct netxbig_gpio_ext *gpio_ext;
|
||||
struct led_classdev cdev;
|
||||
int mode_addr;
|
||||
int *mode_val;
|
||||
int bright_addr;
|
||||
int bright_max;
|
||||
struct netxbig_led_timer *timer;
|
||||
int num_timer;
|
||||
enum netxbig_led_mode mode;
|
||||
int sata;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
static int netxbig_led_get_timer_mode(enum netxbig_led_mode *mode,
|
||||
unsigned long delay_on,
|
||||
unsigned long delay_off,
|
||||
struct netxbig_led_timer *timer,
|
||||
int num_timer)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_timer; i++) {
|
||||
if (timer[i].delay_on == delay_on &&
|
||||
timer[i].delay_off == delay_off) {
|
||||
*mode = timer[i].mode;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int netxbig_led_blink_set(struct led_classdev *led_cdev,
|
||||
unsigned long *delay_on,
|
||||
unsigned long *delay_off)
|
||||
{
|
||||
struct netxbig_led_data *led_dat =
|
||||
container_of(led_cdev, struct netxbig_led_data, cdev);
|
||||
enum netxbig_led_mode mode;
|
||||
int mode_val;
|
||||
int ret;
|
||||
|
||||
/* Look for a LED mode with the requested timer frequency. */
|
||||
ret = netxbig_led_get_timer_mode(&mode, *delay_on, *delay_off,
|
||||
led_dat->timer, led_dat->num_timer);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mode_val = led_dat->mode_val[mode];
|
||||
if (mode_val == NETXBIG_LED_INVALID_MODE)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irq(&led_dat->lock);
|
||||
|
||||
gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val);
|
||||
led_dat->mode = mode;
|
||||
|
||||
spin_unlock_irq(&led_dat->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void netxbig_led_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness value)
|
||||
{
|
||||
struct netxbig_led_data *led_dat =
|
||||
container_of(led_cdev, struct netxbig_led_data, cdev);
|
||||
enum netxbig_led_mode mode;
|
||||
int mode_val, bright_val;
|
||||
int set_brightness = 1;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&led_dat->lock, flags);
|
||||
|
||||
if (value == LED_OFF) {
|
||||
mode = NETXBIG_LED_OFF;
|
||||
set_brightness = 0;
|
||||
} else {
|
||||
if (led_dat->sata)
|
||||
mode = NETXBIG_LED_SATA;
|
||||
else if (led_dat->mode == NETXBIG_LED_OFF)
|
||||
mode = NETXBIG_LED_ON;
|
||||
else /* Keep 'timer' mode. */
|
||||
mode = led_dat->mode;
|
||||
}
|
||||
mode_val = led_dat->mode_val[mode];
|
||||
|
||||
gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val);
|
||||
led_dat->mode = mode;
|
||||
/*
|
||||
* Note that the brightness register is shared between all the
|
||||
* SATA LEDs. So, change the brightness setting for a single
|
||||
* SATA LED will affect all the others.
|
||||
*/
|
||||
if (set_brightness) {
|
||||
bright_val = DIV_ROUND_UP(value * led_dat->bright_max,
|
||||
LED_FULL);
|
||||
gpio_ext_set_value(led_dat->gpio_ext,
|
||||
led_dat->bright_addr, bright_val);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&led_dat->lock, flags);
|
||||
}
|
||||
|
||||
static ssize_t netxbig_led_sata_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buff, size_t count)
|
||||
{
|
||||
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
struct netxbig_led_data *led_dat =
|
||||
container_of(led_cdev, struct netxbig_led_data, cdev);
|
||||
unsigned long enable;
|
||||
enum netxbig_led_mode mode;
|
||||
int mode_val;
|
||||
int ret;
|
||||
|
||||
ret = strict_strtoul(buff, 10, &enable);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
enable = !!enable;
|
||||
|
||||
spin_lock_irq(&led_dat->lock);
|
||||
|
||||
if (led_dat->sata == enable) {
|
||||
ret = count;
|
||||
goto exit_unlock;
|
||||
}
|
||||
|
||||
if (led_dat->mode != NETXBIG_LED_ON &&
|
||||
led_dat->mode != NETXBIG_LED_SATA)
|
||||
mode = led_dat->mode; /* Keep modes 'off' and 'timer'. */
|
||||
else if (enable)
|
||||
mode = NETXBIG_LED_SATA;
|
||||
else
|
||||
mode = NETXBIG_LED_ON;
|
||||
|
||||
mode_val = led_dat->mode_val[mode];
|
||||
if (mode_val == NETXBIG_LED_INVALID_MODE) {
|
||||
ret = -EINVAL;
|
||||
goto exit_unlock;
|
||||
}
|
||||
|
||||
gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val);
|
||||
led_dat->mode = mode;
|
||||
led_dat->sata = enable;
|
||||
|
||||
ret = count;
|
||||
|
||||
exit_unlock:
|
||||
spin_unlock_irq(&led_dat->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t netxbig_led_sata_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
struct netxbig_led_data *led_dat =
|
||||
container_of(led_cdev, struct netxbig_led_data, cdev);
|
||||
|
||||
return sprintf(buf, "%d\n", led_dat->sata);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store);
|
||||
|
||||
static void __devexit delete_netxbig_led(struct netxbig_led_data *led_dat)
|
||||
{
|
||||
if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE)
|
||||
device_remove_file(led_dat->cdev.dev, &dev_attr_sata);
|
||||
led_classdev_unregister(&led_dat->cdev);
|
||||
}
|
||||
|
||||
static int __devinit
|
||||
create_netxbig_led(struct platform_device *pdev,
|
||||
struct netxbig_led_data *led_dat,
|
||||
const struct netxbig_led *template)
|
||||
{
|
||||
struct netxbig_led_platform_data *pdata = pdev->dev.platform_data;
|
||||
int ret;
|
||||
|
||||
spin_lock_init(&led_dat->lock);
|
||||
led_dat->gpio_ext = pdata->gpio_ext;
|
||||
led_dat->cdev.name = template->name;
|
||||
led_dat->cdev.default_trigger = template->default_trigger;
|
||||
led_dat->cdev.blink_set = netxbig_led_blink_set;
|
||||
led_dat->cdev.brightness_set = netxbig_led_set;
|
||||
/*
|
||||
* Because the GPIO extension bus don't allow to read registers
|
||||
* value, there is no way to probe the LED initial state.
|
||||
* So, the initial sysfs LED value for the "brightness" and "sata"
|
||||
* attributes are inconsistent.
|
||||
*
|
||||
* Note that the initial LED state can't be reconfigured.
|
||||
* The reason is that the LED behaviour must stay uniform during
|
||||
* the whole boot process (bootloader+linux).
|
||||
*/
|
||||
led_dat->sata = 0;
|
||||
led_dat->cdev.brightness = LED_OFF;
|
||||
led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
|
||||
led_dat->mode_addr = template->mode_addr;
|
||||
led_dat->mode_val = template->mode_val;
|
||||
led_dat->bright_addr = template->bright_addr;
|
||||
led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1;
|
||||
led_dat->timer = pdata->timer;
|
||||
led_dat->num_timer = pdata->num_timer;
|
||||
|
||||
ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* If available, expose the SATA activity blink capability through
|
||||
* a "sata" sysfs attribute.
|
||||
*/
|
||||
if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) {
|
||||
ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
|
||||
if (ret)
|
||||
led_classdev_unregister(&led_dat->cdev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devinit netxbig_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct netxbig_led_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct netxbig_led_data *leds_data;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (!pdata)
|
||||
return -EINVAL;
|
||||
|
||||
leds_data = kzalloc(sizeof(struct netxbig_led_data) * pdata->num_leds,
|
||||
GFP_KERNEL);
|
||||
if (!leds_data)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = gpio_ext_init(pdata->gpio_ext);
|
||||
if (ret < 0)
|
||||
goto err_free_data;
|
||||
|
||||
for (i = 0; i < pdata->num_leds; i++) {
|
||||
ret = create_netxbig_led(pdev, &leds_data[i], &pdata->leds[i]);
|
||||
if (ret < 0)
|
||||
goto err_free_leds;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, leds_data);
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_leds:
|
||||
for (i = i - 1; i >= 0; i--)
|
||||
delete_netxbig_led(&leds_data[i]);
|
||||
|
||||
gpio_ext_free(pdata->gpio_ext);
|
||||
err_free_data:
|
||||
kfree(leds_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit netxbig_led_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct netxbig_led_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct netxbig_led_data *leds_data;
|
||||
int i;
|
||||
|
||||
leds_data = platform_get_drvdata(pdev);
|
||||
|
||||
for (i = 0; i < pdata->num_leds; i++)
|
||||
delete_netxbig_led(&leds_data[i]);
|
||||
|
||||
gpio_ext_free(pdata->gpio_ext);
|
||||
kfree(leds_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver netxbig_led_driver = {
|
||||
.probe = netxbig_led_probe,
|
||||
.remove = __devexit_p(netxbig_led_remove),
|
||||
.driver = {
|
||||
.name = "leds-netxbig",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
MODULE_ALIAS("platform:leds-netxbig");
|
||||
|
||||
static int __init netxbig_led_init(void)
|
||||
{
|
||||
return platform_driver_register(&netxbig_led_driver);
|
||||
}
|
||||
|
||||
static void __exit netxbig_led_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&netxbig_led_driver);
|
||||
}
|
||||
|
||||
module_init(netxbig_led_init);
|
||||
module_exit(netxbig_led_exit);
|
||||
|
||||
MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
|
||||
MODULE_DESCRIPTION("LED driver for LaCie xBig Network boards");
|
||||
MODULE_LICENSE("GPL");
|
@ -141,10 +141,12 @@ static ssize_t ns2_led_sata_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buff, size_t count)
|
||||
{
|
||||
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
struct ns2_led_data *led_dat =
|
||||
container_of(led_cdev, struct ns2_led_data, cdev);
|
||||
int ret;
|
||||
unsigned long enable;
|
||||
enum ns2_led_modes mode;
|
||||
struct ns2_led_data *led_dat = dev_get_drvdata(dev);
|
||||
|
||||
ret = strict_strtoul(buff, 10, &enable);
|
||||
if (ret < 0)
|
||||
@ -172,7 +174,9 @@ static ssize_t ns2_led_sata_store(struct device *dev,
|
||||
static ssize_t ns2_led_sata_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ns2_led_data *led_dat = dev_get_drvdata(dev);
|
||||
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
struct ns2_led_data *led_dat =
|
||||
container_of(led_cdev, struct ns2_led_data, cdev);
|
||||
|
||||
return sprintf(buf, "%d\n", led_dat->sata);
|
||||
}
|
||||
@ -234,7 +238,6 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
|
||||
if (ret < 0)
|
||||
goto err_free_slow;
|
||||
|
||||
dev_set_drvdata(led_dat->cdev.dev, led_dat);
|
||||
ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
|
||||
if (ret < 0)
|
||||
goto err_free_cdev;
|
||||
|
Loading…
Reference in New Issue
Block a user