diff options
Diffstat (limited to 'board/LaCie')
-rw-r--r-- | board/LaCie/common/cpld-gpio-bus.c | 50 | ||||
-rw-r--r-- | board/LaCie/common/cpld-gpio-bus.h | 24 | ||||
-rw-r--r-- | board/LaCie/net2big_v2/Makefile | 3 | ||||
-rw-r--r-- | board/LaCie/net2big_v2/net2big_v2.c | 154 | ||||
-rw-r--r-- | board/LaCie/net2big_v2/net2big_v2.h | 5 |
5 files changed, 228 insertions, 8 deletions
diff --git a/board/LaCie/common/cpld-gpio-bus.c b/board/LaCie/common/cpld-gpio-bus.c new file mode 100644 index 0000000000..fb9bf8d5db --- /dev/null +++ b/board/LaCie/common/cpld-gpio-bus.c @@ -0,0 +1,50 @@ +/* + * cpld-gpio-bus.c: provides support for the CPLD GPIO bus found on some LaCie + * boards (as the 2Big/5Big Network v2 and the 2Big NAS). This parallel GPIO + * bus exposes two registers (address and data). Each of this register is made + * up of several dedicated GPIOs. An extra GPIO is used to notify the CPLD that + * the registers have been updated. + * + * Mostly this bus is used to configure the LEDs on LaCie boards. + * + * Copyright (C) 2013 Simon Guinot <simon.guinot@sequanux.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. + */ + +#include <asm/arch/gpio.h> +#include "cpld-gpio-bus.h" + +static void cpld_gpio_bus_set_addr(struct cpld_gpio_bus *bus, unsigned addr) +{ + int pin; + + for (pin = 0; pin < bus->num_addr; pin++) + kw_gpio_set_value(bus->addr[pin], (addr >> pin) & 1); +} + +static void cpld_gpio_bus_set_data(struct cpld_gpio_bus *bus, unsigned data) +{ + int pin; + + for (pin = 0; pin < bus->num_data; pin++) + kw_gpio_set_value(bus->data[pin], (data >> pin) & 1); +} + +static void cpld_gpio_bus_enable_select(struct cpld_gpio_bus *bus) +{ + /* The transfer is enabled on the raising edge. */ + kw_gpio_set_value(bus->enable, 0); + kw_gpio_set_value(bus->enable, 1); +} + +void cpld_gpio_bus_write(struct cpld_gpio_bus *bus, + unsigned addr, unsigned value) +{ + cpld_gpio_bus_set_addr(bus, addr); + cpld_gpio_bus_set_data(bus, value); + cpld_gpio_bus_enable_select(bus); +} diff --git a/board/LaCie/common/cpld-gpio-bus.h b/board/LaCie/common/cpld-gpio-bus.h new file mode 100644 index 0000000000..e9e9b96041 --- /dev/null +++ b/board/LaCie/common/cpld-gpio-bus.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2013 Simon Guinot <simon.guinot@sequanux.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. + */ + +#ifndef _LACIE_CPLD_GPI0_BUS_H +#define _LACIE_CPLD_GPI0_BUS_H + +struct cpld_gpio_bus { + unsigned *addr; + unsigned num_addr; + unsigned *data; + unsigned num_data; + unsigned enable; +}; + +void cpld_gpio_bus_write(struct cpld_gpio_bus *cpld_gpio_bus, + unsigned addr, unsigned value); + +#endif /* _LACIE_CPLD_GPI0_BUS_H */ diff --git a/board/LaCie/net2big_v2/Makefile b/board/LaCie/net2big_v2/Makefile index fbae48ef24..9a6dfb619b 100644 --- a/board/LaCie/net2big_v2/Makefile +++ b/board/LaCie/net2big_v2/Makefile @@ -28,6 +28,9 @@ endif LIB = $(obj)lib$(BOARD).o COBJS := $(BOARD).o ../common/common.o +ifneq ($(and $(CONFIG_KIRKWOOD_GPIO),$(CONFIG_NET2BIG_V2)),) +COBJS += ../common/cpld-gpio-bus.o +endif SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/LaCie/net2big_v2/net2big_v2.c b/board/LaCie/net2big_v2/net2big_v2.c index e524f3511d..b133f7cb3b 100644 --- a/board/LaCie/net2big_v2/net2big_v2.c +++ b/board/LaCie/net2big_v2/net2big_v2.c @@ -22,6 +22,7 @@ #include <common.h> #include <command.h> +#include <i2c.h> #include <asm/arch/cpu.h> #include <asm/arch/kirkwood.h> #include <asm/arch/mpp.h> @@ -29,6 +30,7 @@ #include "net2big_v2.h" #include "../common/common.h" +#include "../common/cpld-gpio-bus.h" DECLARE_GLOBAL_DATA_PTR; @@ -60,18 +62,18 @@ int board_early_init_f(void) MPP24_GPIO, /* USB mode select */ MPP26_GPIO, /* USB device vbus */ MPP28_GPIO, /* USB enable host vbus */ - MPP29_GPIO, /* GPIO extension ALE */ + MPP29_GPIO, /* CPLD GPIO bus ALE */ MPP34_GPIO, /* Rear Push button 0=on 1=off */ MPP35_GPIO, /* Inhibit switch power-off */ MPP36_GPIO, /* SATA HDD1 presence */ MPP37_GPIO, /* SATA HDD2 presence */ MPP40_GPIO, /* eSATA presence */ - 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) */ + MPP44_GPIO, /* CPLD GPIO bus (data 0) */ + MPP45_GPIO, /* CPLD GPIO bus (data 1) */ + MPP46_GPIO, /* CPLD GPIO bus (data 2) */ + MPP47_GPIO, /* CPLD GPIO bus (addr 0) */ + MPP48_GPIO, /* CPLD GPIO bus (addr 1) */ + MPP49_GPIO, /* CPLD GPIO bus (addr 2) */ 0 }; @@ -92,8 +94,142 @@ int board_init(void) } #if defined(CONFIG_MISC_INIT_R) + +#if defined(CONFIG_CMD_I2C) && defined(CONFIG_SYS_I2C_G762_ADDR) +/* + * Start I2C fan (GMT G762 controller) + */ +static void init_fan(void) +{ + u8 data; + + i2c_set_bus_num(0); + + /* Enable open-loop and PWM modes */ + data = 0x20; + if (i2c_write(CONFIG_SYS_I2C_G762_ADDR, + G762_REG_FAN_CMD1, 1, &data, 1) != 0) + goto err; + data = 0; + if (i2c_write(CONFIG_SYS_I2C_G762_ADDR, + G762_REG_SET_CNT, 1, &data, 1) != 0) + goto err; + /* + * RPM to PWM (set_out register) fan speed conversion array: + * 0 0x00 + * 1500 0x04 + * 2800 0x08 + * 3400 0x0C + * 3700 0x10 + * 4400 0x20 + * 4700 0x30 + * 4800 0x50 + * 5200 0x80 + * 5400 0xC0 + * 5500 0xFF + * + * Start fan at low speed (2800 RPM): + */ + data = 0x08; + if (i2c_write(CONFIG_SYS_I2C_G762_ADDR, + G762_REG_SET_OUT, 1, &data, 1) != 0) + goto err; + + return; +err: + printf("Error: failed to start I2C fan @%02x\n", + CONFIG_SYS_I2C_G762_ADDR); +} +#else +static void init_fan(void) {} +#endif /* CONFIG_CMD_I2C && CONFIG_SYS_I2C_G762_ADDR */ + +#if defined(CONFIG_NET2BIG_V2) && defined(CONFIG_KIRKWOOD_GPIO) +/* + * CPLD GPIO bus: + * + * - address register : bit [0-2] -> GPIO [47-49] + * - data register : bit [0-2] -> GPIO [44-46] + * - enable register : GPIO 29 + */ +static unsigned cpld_gpio_bus_addr[] = { 47, 48, 49 }; +static unsigned cpld_gpio_bus_data[] = { 44, 45, 46 }; + +static struct cpld_gpio_bus cpld_gpio_bus = { + .addr = cpld_gpio_bus_addr, + .num_addr = ARRAY_SIZE(cpld_gpio_bus_addr), + .data = cpld_gpio_bus_data, + .num_data = ARRAY_SIZE(cpld_gpio_bus_data), + .enable = 29, +}; + +/* + * LEDs configuration: + * + * The LEDs are controlled by a CPLD and can be configured through + * the CPLD GPIO bus. + * + * Address register selection: + * + * addr | register + * ---------------------------- + * 0 | front LED + * 1 | front LED brightness + * 2 | SATA LED brightness + * 3 | SATA0 LED + * 4 | SATA1 LED + * 5 | SATA2 LED + * 6 | SATA3 LED + * 7 | SATA4 LED + * + * Data register configuration: + * + * data | LED brightness + * ------------------------------------------------- + * 0 | min (off) + * - | - + * 7 | max + * + * data | front LED mode + * ------------------------------------------------- + * 0 | fix off + * 1 | fix blue on + * 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 + * + * data | SATA LED mode + * ------------------------------------------------- + * 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 | fix blue on + */ +static void init_leds(void) +{ + /* Enable the front blue LED */ + cpld_gpio_bus_write(&cpld_gpio_bus, 0, 1); + cpld_gpio_bus_write(&cpld_gpio_bus, 1, 3); + + /* Configure SATA LEDs to blink in relation with the SATA activity */ + cpld_gpio_bus_write(&cpld_gpio_bus, 3, 1); + cpld_gpio_bus_write(&cpld_gpio_bus, 4, 1); + cpld_gpio_bus_write(&cpld_gpio_bus, 2, 3); +} +#else +static void init_leds(void) {} +#endif /* CONFIG_NET2BIG_V2 && CONFIG_KIRKWOOD_GPIO */ + int misc_init_r(void) { + init_fan(); #if defined(CONFIG_CMD_I2C) && defined(CONFIG_SYS_I2C_EEPROM_ADDR) if (!getenv("ethaddr")) { uchar mac[6]; @@ -101,9 +237,11 @@ int misc_init_r(void) eth_setenv_enetaddr("ethaddr", mac); } #endif + init_leds(); + return 0; } -#endif +#endif /* CONFIG_MISC_INIT_R */ #if defined(CONFIG_CMD_NET) && defined(CONFIG_RESET_PHY_R) /* Configure and initialize PHY */ diff --git a/board/LaCie/net2big_v2/net2big_v2.h b/board/LaCie/net2big_v2/net2big_v2.h index f9778f4f0c..83537d6b9a 100644 --- a/board/LaCie/net2big_v2/net2big_v2.h +++ b/board/LaCie/net2big_v2/net2big_v2.h @@ -32,4 +32,9 @@ /* Buttons */ #define NET2BIG_V2_GPIO_PUSH_BUTTON 34 +/* GMT G762 registers (I2C fan controller) */ +#define G762_REG_SET_CNT 0x00 +#define G762_REG_SET_OUT 0x03 +#define G762_REG_FAN_CMD1 0x04 + #endif /* NET2BIG_V2_H */ |