#include <asm/arch/mmc.h>
#include <asm/arch/power.h>
#include <asm/arch/mem.h>
+#include <asm/arch/hs_otg.h>
+#include <asm/arch/regs-otg.h>
+#include <asm/arch/rtc.h>
+#include <asm/arch/adc.h>
#include <asm/errno.h>
#include <fbutils.h>
#include <lcd.h>
#define C100_MACH_START 3000
#define C110_MACH_START 3100
-/* FIXME Neptune workaround */
-#define USE_NEPTUNE_BOARD
-#undef USE_NEPTUNE_BOARD
-
static unsigned int board_rev;
static unsigned int battery_soc;
static struct s5pc110_gpio *s5pc110_gpio;
MACH_WMG160 = 160,
- MACH_AQUILA = 2646,
+ MACH_PSEUDO_END,
MACH_KESSLER = 3102,
};
#define BAMBOO_BOARD 0x2000
/* board is MACH_KESSLER and board is like below */
-#define ARIES_BOARD 0x4000
+#define S1_BOARD 0x1000
+#define KESSLER_BOARD 0x4000
#define NEPTUNE_BOARD 0x8000
#define BOARD_MASK 0xFF00
return gd->bd->bi_arch_number - C110_MACH_START;
}
-static int machine_is_aquila(void)
+static int mach_is_aquila(void)
{
- return (gd->bd->bi_arch_number == MACH_AQUILA);
+ return gd->bd->bi_arch_number == MACH_TYPE_AQUILA;
}
-static int machine_is_tickertape(void)
+static int mach_is_tickertape(void)
{
return c110_machine_id() == MACH_TICKERTAPE;
}
-static int machine_is_geminus(void)
+static int mach_is_geminus(void)
{
return c110_machine_id() == MACH_GEMINUS;
}
-static int machine_is_cypress(void)
+static int mach_is_cypress(void)
{
return c110_machine_id() == MACH_CYPRESS;
}
static int board_is_limo_universal(void)
{
- return machine_is_aquila() && (board_rev & LIMO_UNIVERSAL_BOARD);
+ return mach_is_aquila() && (board_rev & LIMO_UNIVERSAL_BOARD);
}
static int board_is_limo_real(void)
{
- return machine_is_aquila() && (board_rev & LIMO_REAL_BOARD);
+ return mach_is_aquila() && (board_rev & LIMO_REAL_BOARD);
+}
+
+static int board_is_bamboo(void)
+{
+ return mach_is_aquila() && (board_rev & BAMBOO_BOARD);
}
static int board_is_media(void)
{
- return machine_is_aquila() && (board_rev & MEDIA_BOARD);
+ return mach_is_aquila() && (board_rev & MEDIA_BOARD);
}
static int board_is_j1b2(void)
{
- return machine_is_aquila() && (board_rev & J1_B2_BOARD);
+ return mach_is_aquila() && (board_rev & J1_B2_BOARD);
}
/* Kessler */
-static int machine_is_kessler(void)
+static int mach_is_kessler(void)
{
return gd->bd->bi_arch_number == MACH_KESSLER;
}
static int board_is_neptune(void)
{
- return machine_is_kessler() && (board_rev & NEPTUNE_BOARD);
+ return mach_is_kessler() && (board_rev & NEPTUNE_BOARD);
+}
+
+static int board_is_s1(void)
+{
+ return mach_is_kessler() && (board_rev & S1_BOARD);
}
/* DLNA Dongle */
-static int machine_is_wmg160(void)
+static int mach_is_wmg160(void)
{
return c110_machine_id() == MACH_WMG160;
}
-static void enable_battery(void);
+static void check_battery(int mode);
+static void check_micro_usb(int intr);
void i2c_init_board(void)
{
num_bus = ARRAY_SIZE(i2c_gpio);
- if (machine_is_aquila()) {
+ if (mach_is_aquila()) {
i2c_gpio[I2C_GPIO6].bus->gpio_base = 0;
i2c_gpio[I2C_GPIO7].bus->gpio_base = 0;
- } else if (machine_is_kessler()) {
+ } else if (mach_is_kessler()) {
i2c_gpio[I2C_GPIO7].bus->gpio_base =
(unsigned int)&gpio->gpio_mp0_5;
- } else if (machine_is_cypress()) {
+ } else if (mach_is_cypress()) {
i2c_gpio[I2C_GPIO7].bus = &i2c_cypress_gpio7;
i2c_gpio[I2C_GPIO7].bus->gpio_base =
(unsigned int)&gpio->gpio_mp0_5;
i2c_gpio_init(i2c_gpio, num_bus, I2C_PMIC);
+ /* Reset on fsa9480 early */
+ check_micro_usb(1);
/* Reset on max17040 early */
if (battery_soc == 0)
- enable_battery();
+ check_battery(1);
}
#ifdef CONFIG_MISC_INIT_R
-#define DEV_INFO_LEN 512
+#define DEV_INFO_LEN 256
static char device_info[DEV_INFO_LEN];
static int display_info;
+static void empty_device_info_buffer(void)
+{
+ memset(device_info, 0x0, DEV_INFO_LEN);
+}
+
static void dprintf(const char *fmt, ...)
{
va_list args;
if ((strlen(device_info) + strlen(buf)) > (DEV_INFO_LEN - 1)) {
puts("Flushing device info...\n");
puts(device_info);
- device_info[0] = 0;
+ empty_device_info_buffer();
}
- strcat(device_info, buf);
+ strncat(device_info, buf, 127);
puts(buf);
}
static const char *board_name[] = {
"Universal",
"TickerTape",
- "Aquila",
+ "Kessler",
"P1P2", /* Don't remove it */
"Geminus",
"Cypress",
- "Neptune",
+ "Limo SDK",
};
enum {
char *buf = feature_buffer;
char *name = NULL;
- if (board == MACH_AQUILA) {
+ if (board == MACH_TYPE_AQUILA) {
if (board_rev & SPLIT_SCREEN_FEATURE)
name = "SplitScreen";
if (board_rev & J1_B2_BOARD)
if (board_rev & BAMBOO_BOARD)
name = "Bamboo";
} else if (board == MACH_KESSLER) {
- if (board_rev & ARIES_BOARD)
- name = "Aries";
if (board_rev & NEPTUNE_BOARD)
- name = "Neptune";
+ name = "Limo SDK";
+ if (board_rev & S1_BOARD)
+ name = "S1";
}
if (name)
count += sprintf(buf + count, " - %s", name);
static char *get_board_name(int board)
{
- if (board == MACH_AQUILA)
+ if (board == MACH_TYPE_AQUILA)
return "Aquila";
else if (board == MACH_KESSLER)
return "Kessler";
static void check_board_revision(int board, int rev)
{
- if (board == MACH_AQUILA) {
+ if (board == MACH_TYPE_AQUILA) {
/* Limo Real or Universal */
if (rev & LIMO_UNIVERSAL_BOARD)
board_rev &= ~J1_B2_BOARD;
LIMO_REAL_BOARD |
MEDIA_BOARD);
} else if (board == MACH_KESSLER) {
- if (rev & ARIES_BOARD)
+ if (rev & KESSLER_BOARD)
board_rev &= ~(J1_B2_BOARD |
LIMO_UNIVERSAL_BOARD);
if (rev & NEPTUNE_BOARD)
board_rev &= ~(J1_B2_BOARD |
LIMO_UNIVERSAL_BOARD);
- } else
+ if (rev & S1_BOARD)
+ board_rev &= ~(J1_B2_BOARD | LIMO_UNIVERSAL_BOARD |
+ LIMO_REAL_BOARD);
+ } else {
board_rev &= ~BOARD_MASK;
+ }
}
static unsigned int get_hw_revision(struct s5pc1xx_gpio_bank *bank, int hwrev3)
{
unsigned int rev;
- int mode3 = 1;
-
- if (hwrev3)
- mode3 = 7;
gpio_direction_input(bank, 2);
gpio_direction_input(bank, 3);
gpio_direction_input(bank, 4);
- gpio_direction_input(bank, mode3);
+ gpio_direction_input(bank, hwrev3);
gpio_set_pull(bank, 2, GPIO_PULL_NONE); /* HWREV_MODE0 */
gpio_set_pull(bank, 3, GPIO_PULL_NONE); /* HWREV_MODE1 */
gpio_set_pull(bank, 4, GPIO_PULL_NONE); /* HWREV_MODE2 */
- gpio_set_pull(bank, mode3, GPIO_PULL_NONE); /* HWREV_MODE3 */
+ gpio_set_pull(bank, hwrev3, GPIO_PULL_NONE); /* HWREV_MODE3 */
rev = gpio_get_value(bank, 2);
rev |= (gpio_get_value(bank, 3) << 1);
rev |= (gpio_get_value(bank, 4) << 2);
- rev |= (gpio_get_value(bank, mode3) << 3);
+ rev |= (gpio_get_value(bank, hwrev3) << 3);
return rev;
}
} else {
struct s5pc110_gpio *gpio =
(struct s5pc110_gpio *)S5PC110_GPIO_BASE;
- int hwrev3 = 0;
+ int hwrev3 = 1;
board_rev = 0;
* ADDR = 0xE0200000 + OFF
*
* OFF Universal BB LRA LUA OA TT SS CYP
- * J1: 0x0264 0x10 0x10 0x00 0x00 0x00 0x00 0x00
- * J2: 0x0284 0x01 0x10 0x00
+ * J1: 0x0264 0x10 0x10 0x00 0x00 0x00 0x00 0x00
+ * J2: 0x0284 0x01 0x10 0x00
* H1: 0x0C24 W 0x28 0xA8 0x1C 0x0F
- * H3: 0x0C64 0x03 0x07 0x0F
+ * H3: 0x0C64 0x03 0x07 0x0F
* D1: 0x00C4 0x0F 0x3F 0x3F 0x0F 0xXC 0x3F
* I: 0x0224 0x02 0x00 0x08
* MP03: 0x0324 0x9x 0xbx 0x9x
/* C110 Aquila */
if (gpio_get_value(&gpio->gpio_j1, 4) == 0) {
- board = MACH_AQUILA;
+ board = MACH_TYPE_AQUILA;
board_rev |= J1_B2_BOARD;
gpio_set_pull(&gpio->gpio_j2, 6, GPIO_PULL_NONE);
/* Workaround: C110 Aquila Rev0.6 */
if (board_rev == 6) {
- board = MACH_AQUILA;
+ board = MACH_TYPE_AQUILA;
board_rev |= LIMO_REAL_BOARD;
}
/* C110 Aquila Bamboo */
if (gpio_get_value(&gpio->gpio_j2, 0) == 1) {
- board = MACH_AQUILA;
+ board = MACH_TYPE_AQUILA;
board_rev |= BAMBOO_BOARD;
}
}
if (wmg160) {
board = MACH_WMG160;
- hwrev3 = 1;
+ hwrev3 = 7;
}
}
gpio_direction_input(&gpio->gpio_j0, 6);
if (gpio_get_value(&gpio->gpio_j0, 6) == 1) {
board = MACH_GEMINUS;
- hwrev3 = 1;
+ hwrev3 = 7;
}
gpio_set_pull(&gpio->gpio_j0, 6, GPIO_PULL_DOWN);
gpio_direction_output(&gpio->gpio_mp0_5, 6, 0);
} else {
board = MACH_KESSLER;
- board_rev |= ARIES_BOARD;
-#ifdef USE_NEPTUNE_BOARD
- board_rev &= ~ARIES_BOARD;
- board_rev |= NEPTUNE_BOARD;
-#endif
+ board_rev |= KESSLER_BOARD;
+
+ /* Neptune MP0_5[4] == 1 */
+ gpio_direction_input(&gpio->gpio_mp0_5, 4);
+ if (gpio_get_value(&gpio->gpio_mp0_5, 4) == 1) {
+ board_rev &= ~KESSLER_BOARD;
+ board_rev |= NEPTUNE_BOARD;
+ }
}
gpio_set_pull(&gpio->gpio_j2, 2, GPIO_PULL_DOWN);
- hwrev3 = 1;
- } else
+ hwrev3 = 7;
+ } else {
gpio_direction_output(&gpio->gpio_mp0_5, 6, 0);
+ /* Kessler S1 board detection */
+ if (board == MACH_TICKERTAPE) {
+ board = MACH_KESSLER;
+ board_rev |= S1_BOARD;
+ hwrev3 = 7;
+ }
+ }
board_rev |= get_hw_revision(&gpio->gpio_j0, hwrev3);
}
/* Set machine id */
- if (board == MACH_AQUILA)
- gd->bd->bi_arch_number = MACH_AQUILA;
- else if (board == MACH_KESSLER)
- gd->bd->bi_arch_number = MACH_KESSLER;
- else if (cpu_is_s5pc110())
- gd->bd->bi_arch_number = C110_MACH_START + board;
- else
- gd->bd->bi_arch_number = C100_MACH_START + board;
+ if (board < MACH_PSEUDO_END) {
+ if (cpu_is_s5pc110())
+ gd->bd->bi_arch_number = C110_MACH_START + board;
+ else
+ gd->bd->bi_arch_number = C100_MACH_START + board;
+ } else {
+ gd->bd->bi_arch_number = board;
+ }
/* Architecture Common settings */
if (cpu_is_s5pc110()) {
}
}
- if (machine_is_aquila())
- board = MACH_AQUILA;
- else if (machine_is_kessler())
- board = MACH_KESSLER;
+ if (mach_is_kessler() || mach_is_aquila())
+ board = gd->bd->bi_arch_number;
else if (cpu_is_s5pc110())
board = gd->bd->bi_arch_number - C110_MACH_START;
else
check_board_revision(board, board_rev);
/* Set CPU Revision */
- if (machine_is_aquila()) {
+ if (mach_is_aquila()) {
if (board_is_limo_real()) {
if ((board_rev & 0xf) < 8)
s5pc1xx_set_cpu_rev(0);
}
- } else if (machine_is_kessler())
- s5pc1xx_set_cpu_rev(1);
- else if (machine_is_geminus()) {
+ else if (board_is_bamboo())
+ s5pc1xx_set_cpu_rev(0);
+ } else if (mach_is_kessler()) {
+ if (board_is_neptune() && hwrevision(2))
+ s5pc1xx_set_cpu_rev(2); /* EVT1-Fused */
+ else
+ s5pc1xx_set_cpu_rev(1);
+ } else if (mach_is_geminus()) {
if ((board_rev & 0xf) < 1)
s5pc1xx_set_cpu_rev(0);
- } else if (machine_is_cypress()) {
+ } else if (mach_is_cypress()) {
s5pc1xx_set_cpu_rev(1);
} else {
s5pc1xx_set_cpu_rev(0);
}
+ if (cpu_is_s5pc110())
+ writel(0xc1100000 | (0xffff & (s5pc1xx_get_cpu_rev() ? 1 : 0)),
+ S5PC110_INFORM3);
+
+ empty_device_info_buffer();
dprintf("HW Revision:\t%x (%s%s) %s\n",
board_rev, get_board_name(board),
display_features(board, board_rev),
char buf[64];
if (readl(magic_base) == 0x426f6f74) { /* ASICC: Boot */
- printf("Auto burning bootloader\n");
+ puts("Auto burning bootloader\n");
count += sprintf(buf + count, "run updateb; ");
}
if (readl(magic_base + 0x04) == 0x4b65726e) { /* ASICC: Kern */
- printf("Auto burning kernel\n");
+ puts("Auto burning kernel\n");
count += sprintf(buf + count, "run updatek; ");
}
unsigned int i;
unsigned int auto_download = 0;
- if (machine_is_wmg160())
+ if (mach_is_wmg160())
return;
if (cpu_is_s5pc100()) {
/* KEYIFCOL reg clear */
writel(0, reg + S5PC1XX_KEYIFCOL_OFFSET);
- if (machine_is_aquila() || machine_is_kessler()) {
- /* cam full shot & volume down */
- if ((row_state[0] & 0x1) && (row_state[1] & 0x2))
- auto_download = 1;
+ if (mach_is_aquila() || mach_is_kessler()) {
/* volume down */
- else if ((row_state[1] & 0x2))
+ if (row_state[1] & 0x2)
display_info = 1;
- } else if (machine_is_geminus())
+ if (board_is_neptune() && hwrevision(0)) {
+ /* home & volume down */
+ if ((row_state[1] & 0x1) && (row_state[1] & 0x2))
+ auto_download = 1;
+ } else if (board_is_neptune() && hwrevision(2)) {
+ /* cam full shot & volume down */
+ if ((row_state[1] & 0x6) && (row_state[2] & 0x4))
+ auto_download = 1;
+ } else {
+ /* cam full shot & volume down */
+ if ((row_state[0] & 0x1) && (row_state[1] & 0x2))
+ auto_download = 1;
+ }
+ } else if (mach_is_geminus())
/* volume down & home */
if ((row_state[1] & 0x2) && (row_state[2] & 0x1))
auto_download = 1;
setenv("bootcmd", "usbdown");
}
-static void enable_battery(void)
-{
- unsigned char val[2];
- unsigned char addr = 0x36; /* max17040 fuel gauge */
-
- i2c_set_bus_num(I2C_GPIO3);
-
- if (machine_is_aquila()) {
- if (board_is_j1b2())
- return;
- } else if (machine_is_kessler())
- i2c_set_bus_num(I2C_GPIO7);
- else if (machine_is_tickertape()) {
- return;
- } else if (machine_is_cypress()) {
- i2c_set_bus_num(I2C_GPIO7);
- } else if (machine_is_geminus()) {
- if (hwrevision(1))
- i2c_set_bus_num(I2C_GPIO7);
- }
-
- if (i2c_probe(addr)) {
- printf("Can't found max17040 fuel gauge\n");
- return;
- }
-
- val[0] = 0x54;
- val[1] = 0x00;
- i2c_write(addr, 0xfe, 1, val, 2);
-}
-
-static void check_battery(void)
+static void check_battery(int mode)
{
unsigned char val[2];
unsigned char addr = 0x36; /* max17040 fuel gauge */
i2c_set_bus_num(I2C_GPIO3);
- if (machine_is_aquila()) {
+ if (mach_is_aquila()) {
if (board_is_j1b2())
return;
- } else if (machine_is_kessler())
+ } else if (mach_is_kessler()) {
i2c_set_bus_num(I2C_GPIO7);
- else if (machine_is_cypress()) {
+ } else if (mach_is_cypress()) {
i2c_set_bus_num(I2C_GPIO7);
- } else if (machine_is_geminus()) {
+ } else if (mach_is_geminus()) {
if (hwrevision(1))
i2c_set_bus_num(I2C_GPIO7);
} else
return;
if (i2c_probe(addr)) {
- printf("Can't found max17040 fuel gauge\n");
+ puts("Can't found max17040 fuel gauge\n");
return;
}
- i2c_read(addr, 0x04, 1, val, 1);
-
- dprintf("battery:\t%d%%\n", val[0]);
-
- battery_soc = val[0];
+ /* mode 0: check mode / 1: enable mode */
+ if (mode) {
+ val[0] = 0x54;
+ val[1] = 0x00;
+ i2c_write(addr, 0xfe, 1, val, 2);
+ } else {
+ i2c_read(addr, 0x04, 1, val, 1);
+ dprintf("battery:\t%d%%\n", val[0]);
+ battery_soc = val[0];
+ }
}
static void check_mhl(void)
/* set usb path */
if (i2c_probe(addr)) {
- printf("Can't found MHL Chip\n");
+ puts("Can't found MHL Chip\n");
return;
}
i2c_read((0x72 >> 1), 0xa0, 1, val, 1);
}
+static int max8998_probe(void)
+{
+ unsigned char addr = 0xCC >> 1;
+
+ i2c_set_bus_num(I2C_PMIC);
+
+ if (i2c_probe(addr)) {
+ puts("Can't found max8998\n");
+ return 1;
+ }
+
+ return 0;
+}
+
#define CHARGER_ANIMATION_FRAME 6
+static void max8998_clear_interrupt(void)
+{
+ unsigned char addr, val[2];
+ addr = 0xCC >> 1;
+
+ if (max8998_probe())
+ return;
+
+ i2c_read(addr, 0x00, 1, val, 1);
+ i2c_read(addr, 0x01, 1, val, 1);
+ i2c_read(addr, 0x02, 1, val, 1);
+ i2c_read(addr, 0x03, 1, val, 1);
+}
+
static int max8998_power_key(void)
{
unsigned char addr, val[2];
- i2c_set_bus_num(I2C_PMIC);
addr = 0xCC >> 1;
- if (i2c_probe(addr)) {
- printf("Can't found max8998\n");
+
+ if (max8998_probe())
return 0;
- }
/* Accessing IRQ1 register */
i2c_read(addr, 0x00, 1, val, 1);
static int max8998_has_ext_power_source(void)
{
unsigned char addr, val[2];
- i2c_set_bus_num(I2C_PMIC);
addr = 0xCC >> 1;
- if (i2c_probe(addr)) {
- printf("Can't found max8998\n");
+
+ if (max8998_probe())
return 0;
- }
/* Accessing STATUS2 register */
i2c_read(addr, 0x09, 1, val, 1);
return 0;
}
+struct thermister_stat {
+ short centigrade;
+ unsigned short adc;
+};
+
+static struct thermister_stat adc_to_temperature_data[] = {
+ { .centigrade = -20, .adc = 1856, },
+ { .centigrade = -15, .adc = 1799, },
+ { .centigrade = -10, .adc = 1730, },
+ { .centigrade = -5, .adc = 1649, },
+ { .centigrade = 0, .adc = 1556, },
+ { .centigrade = 5, .adc = 1454, },
+ { .centigrade = 10, .adc = 1343, },
+ { .centigrade = 15, .adc = 1227, },
+ { .centigrade = 20, .adc = 1109, },
+ { .centigrade = 25, .adc = 992, },
+ { .centigrade = 30, .adc = 880, },
+ { .centigrade = 35, .adc = 773, },
+ { .centigrade = 40, .adc = 675, },
+ { .centigrade = 45, .adc = 586, },
+ { .centigrade = 50, .adc = 507, },
+ { .centigrade = 55, .adc = 436, },
+ { .centigrade = 58, .adc = 399, },
+ { .centigrade = 63, .adc = 343, },
+ { .centigrade = 65, .adc = 322, },
+};
+
+#ifndef USHRT_MAX
+#define USHRT_MAX 0xFFFFU
+#endif
+static int adc_to_temperature_centigrade(unsigned short adc)
+{
+ int i;
+ int approximation;
+ /* low_*: Greatest Lower Bound,
+ * * * * high_*: Smallest Upper Bound */
+ int low_temp = 0, high_temp = 0;
+ unsigned short low_adc = 0, high_adc = USHRT_MAX;
+ for (i = 0; i < ARRAY_SIZE(adc_to_temperature_data); i++) {
+ if (adc_to_temperature_data[i].adc <= adc &&
+ adc_to_temperature_data[i].adc >= low_adc) {
+ low_temp = adc_to_temperature_data[i].centigrade;
+ low_adc = adc_to_temperature_data[i].adc;
+ }
+ if (adc_to_temperature_data[i].adc >= adc &&
+ adc_to_temperature_data[i].adc <= high_adc) {
+ high_temp = adc_to_temperature_data[i].centigrade;
+ high_adc = adc_to_temperature_data[i].adc;
+ }
+ }
+
+ /* Linear approximation between cloest low and high,
+ * which is the weighted average of the two. */
+
+ /* The following equation is correct only when the two are different */
+ if (low_adc == high_adc)
+ return low_temp;
+ if (ARRAY_SIZE(adc_to_temperature_data) < 2)
+ return 20; /* The room temperature */
+ if (low_adc == 0)
+ return high_temp;
+ if (high_adc == USHRT_MAX)
+ return low_temp;
+
+ approximation = low_temp * (adc - low_adc) +
+ high_temp * (high_adc - adc);
+ approximation /= high_adc - low_adc;
+
+ return approximation;
+}
+
+static unsigned short get_adc_value(int channel)
+{
+ struct s5pc110_adc *adc = (struct s5pc110_adc *) S5PC110_ADC_BASE;
+ unsigned short ret = 0;
+ unsigned int reg;
+ int ldonum = 8;
+ char buf[64];
+ unsigned int loop = 0;
+
+ if (mach_is_kessler())
+ ldonum = 4;
+ else if (mach_is_geminus())
+ ldonum = 4;
+ else if (mach_is_wmg160())
+ ldonum = 4;
+ else if (mach_is_cypress())
+ ldonum = 8;
+ else if (mach_is_tickertape())
+ ldonum = 8;
+ else if (mach_is_aquila())
+ ldonum = 8;
+ /*
+ else if (mach_is_p1p2())
+ ldonum = 4;
+ */
+
+ sprintf(buf, "pmic ldo %d on", ldonum);
+ run_command(buf, 0);
+
+ writel(channel & 0xF, &adc->adcmux);
+ writel((1 << 14) | (49 << 6), &adc->adccon);
+ writel(1000 & 0xffff, &adc->adcdly);
+ writel(readl(&adc->adccon) | (1 << 16), &adc->adccon); /* 12 bit */
+ udelay(10);
+ writel(readl(&adc->adccon) | (1 << 0), &adc->adccon); /* Enable */
+ udelay(10);
+
+ do {
+ udelay(1);
+ reg = readl(&adc->adccon);
+ } while (!(reg & (1 << 15)) && (loop++ < 1000));
+
+ ret = readl(&adc->adcdat0) & 0xFFF;
+ sprintf(buf, "pmic ldo %d off", ldonum);
+ run_command(buf, 0);
+
+ return ret;
+}
+
+static int adc_get_average_ambient_temperature(void)
+{
+ if (mach_is_kessler()) {
+ unsigned short min = USHRT_MAX;
+ unsigned short max = 0;
+ unsigned int sum = 0;
+ unsigned int measured = 0;
+ int i;
+
+ for (i = 0; i < 7; i++) {
+ unsigned short measurement = get_adc_value(6);
+ sum += measurement;
+ measured++;
+ if (min > measurement)
+ min = measurement;
+ if (max < measurement)
+ max = measurement;
+ }
+ if (measured >= 3) {
+ measured -= 2;
+ sum -= min;
+ sum -= max;
+ }
+ sum /= measured;
+ printf("Average Ambient Temperature = %d(ADC=%d)\n",
+ adc_to_temperature_centigrade(sum), sum);
+ return adc_to_temperature_centigrade(sum);
+ }
+
+ return 20; /* 20 Centigrade */
+}
+
+enum temperature_level {
+ _TEMP_OK,
+ _TEMP_OK_HIGH,
+ _TEMP_OK_LOW,
+ _TEMP_TOO_HIGH,
+ _TEMP_TOO_LOW,
+};
+
+static enum temperature_level temperature_check(void)
+{
+ int temp = adc_get_average_ambient_temperature();
+ if (temp < -5)
+ return _TEMP_TOO_LOW;
+ if (temp < 0)
+ return _TEMP_OK_LOW;
+ if (temp > 63)
+ return _TEMP_TOO_HIGH;
+ if (temp > 58)
+ return _TEMP_OK_HIGH;
+ return _TEMP_OK;
+}
+
extern void lcd_display_clear(void);
extern int lcd_display_bitmap(ulong bmp_image, int x, int y);
-static void into_charge_mode(void)
+static void charger_en(int enable)
{
- unsigned char addr = 0xCC >> 1; /* max8998 */;
+ /* 0: disable
+ * 600: 600mA
+ * 475: 475mA
+ */
+ unsigned char addr = 0xCC >> 1; /* max8998 */
unsigned char val[2];
+
+ if (max8998_probe())
+ return;
+
+ if (!enable) {
+ puts("Disable the charger.\n");
+ i2c_read(addr, 0x0D, 1, val, 1);
+ val[0] &= ~(0x1);
+ val[0] |= 0x1;
+ i2c_write(addr, 0x0D, 1, val, 1);
+ } else {
+ i2c_read(addr, 0x0C, 1, val, 1);
+ val[0] &= ~(0x7 << 0);
+ val[0] &= ~(0x7 << 5);
+ if (enable == 600) {
+ val[0] |= 5; /* 600mA */
+ val[0] |= (3 << 5); /* Stop at 150mA (25%) */
+ } else { /* Assume 475 mA */
+ enable = 475;
+ val[0] |= 2; /* 475mA */
+ val[0] |= (4 << 5); /* Stop at 142.5mA (30%) */
+ }
+ i2c_write(addr, 0x0C, 1, val, 1);
+
+ i2c_read(addr, 0x0D, 1, val, 1);
+ val[0] &= ~(0x1);
+ i2c_write(addr, 0x0D, 1, val, 1);
+ printf("Enable the charger @ %dmA\n", enable);
+ }
+}
+
+void lcd_power_on(unsigned int onoff);
+extern int do_sleep (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int drv_lcd_init_resume (void);
+
+static void into_charge_mode(void)
+{
unsigned int level;
int i, j;
bmp_image_t *bmp;
unsigned long len;
ulong bmp_addr[CHARGER_ANIMATION_FRAME];
+ unsigned int reg, wakeup_stat;
+ int charger_speed = 600;
- i2c_set_bus_num(I2C_PMIC);
+ max8998_clear_interrupt();
- if (i2c_probe(addr)) {
- printf("Can't found max8998\n");
- return;
- }
-
- printf("Charge Mode\n");
-
- i2c_read(addr, 0x0C, 1, val, 1);
- val[0] &= ~(0x7 << 0);
- val[0] &= ~(0x7 << 5);
- val[0] |= 5; /* 600mA */
- val[0] |= (3 << 5); /* Stop at 150mA(25%) */
- i2c_write(addr, 0x0C, 1, val, 1);
+ puts("Charge Mode\n");
+ charger_en(charger_speed);
#ifdef CONFIG_S5PC1XXFB
init_font();
int k;
bmp = gunzip_bmp(bmp_addr[j], &len);
- lcd_display_bitmap((ulong) bmp, 140, 202);
+ lcd_display_bitmap((ulong)bmp, 140, 202);
free(bmp);
- for (k = 0; k < 10; k++)
+ for (k = 0; k < 10; k++) {
if (max8998_power_key()) {
lcd_display_clear();
- return;
+ goto restore_screen;
} else if (!max8998_has_ext_power_source()) {
lcd_display_clear();
- return;
- } else
+ goto restore_screen;
+ } else {
udelay(100 * 1000);
+ }
+ }
}
}
exit_font();
+
+ /* Disable the display to prevent flickering */
+ /* TODO: how to reenable the display later? */
+ lcd_power_on(0);
#endif
- /* EVT0: sleep 1, EVT1: sleep */
- if (s5pc1xx_get_cpu_rev() == 0) {
- run_command("sleep 1", 0);
- return;
- }
+ do {
+ struct s5pc110_rtc *rtc = (struct s5pc110_rtc *)S5PC110_RTC_BASE;
+ unsigned int org, org_ip3;
+ enum temperature_level previous_state = _TEMP_OK;
- run_command("sleep", 0);
+ empty_device_info_buffer();
+ if (max8998_power_key())
+ break;
+ else if (!max8998_has_ext_power_source())
+ break;
+
+ /* Enable RTC, SYSTIMER, ADC at CLKGATE IP3 */
+ org_ip3 = readl(0xE010046C);
+ writel(org_ip3 | (1 << 15) | (1 << 16) | (1 << 24), 0xE010046C);
+
+ reg = org = readl(&rtc->rtccon);
+ reg |= (1 << 0);
+ writel(reg, &rtc->rtccon);
+
+ reg = readl(&rtc->rtccon);
+ writel(reg | (1 << 3), &rtc->rtccon);
+ udelay(10);
+ writel(reg & ~(1 << 3), &rtc->rtccon);
+ udelay(10);
+
+ reg = readl(&rtc->rtccon);
+ reg &= ~((1 << 8) | (0xF << 4));
+ reg |= (1 << 8) | (0xD << 4); /* D: 4 Hz, 9: 64 Hz */
+ writel(reg, &rtc->rtccon);
+
+ reg = 15 * 4 - 1; /* 15 sec */
+ writel(reg, &rtc->ticcnt);
+
+ /* EVT0: sleep 1, EVT1: sleep */
+ if (cpu_is_s5pc110()) {
+ char *name = "dummy";
+ char *usage = "N/A";
+ char *help = NULL;
+ cmd_tbl_t ctt;
+ ctt.name = name;
+ ctt.usage = usage;
+ ctt.help = help;
+
+ if (s5pc1xx_get_cpu_rev() == 0) {
+ char *argv[] = {"1", "1"};
+ wakeup_stat = do_sleep(&ctt, 0, 2, argv);
+ } else {
+ char *argv[] = {"0", "0"};
+ wakeup_stat = do_sleep(&ctt, 0, 1, argv);
+ }
+ } else {
+ puts("\n\n\nERROR: this is not S5PC110.\n\n\n");
+ return;
+ }
+
+ /* Check TEMP HIGH/LOW */
+ switch (temperature_check()) {
+ case _TEMP_OK:
+ charger_en(charger_speed);
+ previous_state = _TEMP_OK;
+ break;
+ case _TEMP_TOO_LOW:
+ charger_en(0);
+ previous_state = _TEMP_TOO_LOW;
+ break;
+ case _TEMP_TOO_HIGH:
+ charger_en(0);
+ previous_state = _TEMP_TOO_HIGH;
+ break;
+ case _TEMP_OK_LOW:
+ if (previous_state == _TEMP_TOO_LOW) {
+ charger_en(0);
+ } else {
+ charger_en(charger_speed);
+ previous_state = _TEMP_OK;
+ }
+ break;
+ case _TEMP_OK_HIGH:
+ if (previous_state == _TEMP_TOO_HIGH) {
+ charger_en(0);
+ } else {
+ charger_en(charger_speed);
+ previous_state = _TEMP_OK;
+ }
+ break;
+ }
+
+ writel(org, &rtc->rtccon);
+ writel(org_ip3, 0xE010046C);
+
+ } while (wakeup_stat == 0x04); /* RTC TICK */
+
+#ifdef CONFIG_S5PC1XXFB
+restore_screen:
+ /* TODO: Reenable logo display (not working yet) */
+ lcd_power_on(1);
+ drv_lcd_init_resume();
+#endif
}
-static void check_micro_usb(int intr)
+#define S5PC110_RST_STAT 0xE010A000
+
+#define SWRESET (1 << 3)
+#define WDTRESET (1 << 2)
+#define WARMRESET (1 << 1)
+#define EXTRESET (1 << 0)
+
+static int get_reset_status(void)
{
- unsigned char addr;
- unsigned char val[2];
- static int started_charging_once = 0;
- char *path;
+ return readl(S5PC110_RST_STAT) & 0xf;
+}
+
+static int fsa9480_probe(void)
+{
+ unsigned char addr = 0x25;
if (cpu_is_s5pc100())
- return;
+ return 1;
if (board_is_limo_real()) {
if (hwrevision(0) || hwrevision(1))
- return;
+ return 1;
}
i2c_set_bus_num(I2C_PMIC);
- if (machine_is_kessler())
+ if (mach_is_kessler()) {
i2c_set_bus_num(I2C_GPIO6);
- else if (machine_is_cypress()) {
+ } else if (mach_is_cypress()) {
i2c_set_bus_num(I2C_GPIO6);
- } else if (machine_is_geminus()) {
+ } else if (mach_is_geminus()) {
if (hwrevision(1))
i2c_set_bus_num(I2C_GPIO6);
- } else if (machine_is_wmg160())
+ } else if (mach_is_wmg160()) {
i2c_set_bus_num(I2C_GPIO6);
+ }
- addr = 0x25; /* fsa9480 */
if (i2c_probe(addr)) {
- printf("Can't found fsa9480\n");
- return;
+ puts("Can't found fsa9480\n");
+ return 1;
}
+ return 0;
+}
+
+static void check_micro_usb(int intr)
+{
+ unsigned char addr;
+ unsigned char val[2];
+ static int started_charging_once = 0;
+ char *path;
+
+ if (fsa9480_probe())
+ return;
+
+ addr = 0x25; /* fsa9480 */
+
/* Clear Interrupt */
if (intr) {
i2c_read(addr, 0x03, 1, val, 2);
- udelay(500 * 1000);
+ return;
}
/* Read Device Type 1 */
*/
if ((val[0] & FSA_DEV1_CHARGER) && !started_charging_once) {
started_charging_once = 1;
- into_charge_mode();
+
+ /* If it's full, do not charge. */
+ if (battery_soc < 100)
+ into_charge_mode();
+ else
+ charger_en(0);
+ } else if (val[0] & FSA_DEV1_USB) {
+ if (battery_soc < 100)
+ charger_en(475); /* enable charger and keep booting */
+ else
+ charger_en(0);
}
- /* If Factory Mode is Boot ON-USB, go to download mode */
- i2c_read(addr, 0x07, 1, val, 1);
+ /* If reset status is watchdog reset then skip it */
+ if (!(get_reset_status() & WDTRESET)) {
+ /* If Factory Mode is Boot ON-USB, go to download mode */
+ i2c_read(addr, 0x07, 1, val, 1);
#define FSA_ADC_FAC_USB_OFF 0x18
#define FSA_ADC_FAC_USB_ON 0x19
#define FSA_ADC_FAC_UART 0x1d
- if (val[0] == FSA_ADC_FAC_USB_ON || val[0] == FSA_ADC_FAC_USB_OFF)
- setenv("bootcmd", "usbdown");
+ if (val[0] == FSA_ADC_FAC_USB_ON ||
+ val[0] == FSA_ADC_FAC_USB_OFF)
+ setenv("bootcmd", "usbdown");
+ }
path = getenv("usb");
unsigned char addr;
unsigned char val[2];
- i2c_set_bus_num(I2C_PMIC);
-
- if (machine_is_kessler())
- i2c_set_bus_num(I2C_GPIO6);
- else if (machine_is_cypress()) {
- i2c_set_bus_num(I2C_GPIO6);
- } else if (machine_is_geminus()) {
- if (hwrevision(1))
- i2c_set_bus_num(I2C_GPIO6);
- } else if (machine_is_wmg160()) {
- i2c_set_bus_num(I2C_GPIO6);
+ if (fsa9480_probe())
return;
- }
addr = 0x25; /* fsa9480 */
- if (i2c_probe(addr)) {
- printf("Can't found fsa9480\n");
- return;
- }
if (path)
val[0] = 0x90; /* VAUDIO */
if (cpu_is_s5pc100())
return;
- i2c_set_bus_num(I2C_PMIC);
-
addr = 0xCC >> 1; /* max8998 */
- if (i2c_probe(addr)) {
- if (i2c_probe(addr)) {
- printf("Can't found max8998\n");
- return;
- }
- }
+ if (max8998_probe())
+ return;
/* ONOFF1 */
i2c_read(addr, MAX8998_REG_ONOFF1, 1, val, 1);
val[0] &= ~(MAX8998_LDO10 | MAX8998_LDO11 |
MAX8998_LDO12 | MAX8998_LDO13);
- if (machine_is_kessler())
+ if (mach_is_kessler())
val[0] |= MAX8998_LDO7; /* LDO7: VLCD_1.8V */
i2c_write(addr, MAX8998_REG_ONOFF2, 1, val, 1);
val[0] &= ~(MAX8998_LDO14 | MAX8998_LDO15 |
MAX8998_LDO16 | MAX8998_LDO17);
- if (machine_is_kessler())
+ if (mach_is_kessler())
val[0] |= MAX8998_LDO17; /* LDO17: VCC_3.0V_LCD */
i2c_write(addr, MAX8998_REG_ONOFF3, 1, val, 1);
return;
/* Only Limo real and kessler supports worked for sleep currnet */
- if (machine_is_aquila()) {
+ if (mach_is_aquila()) {
if (board_is_limo_real())
/* Support */;
else
return;
- } else if (machine_is_kessler()) {
+ } else if (mach_is_kessler()) {
/* Support */;
- } else if (machine_is_geminus()) {
+ } else if (mach_is_geminus()) {
/* Support */;
- } else
+ } else {
return;
+ }
- if (machine_is_aquila()) {
+ if (mach_is_aquila()) {
/* Aquila rev 0.8 or lower */
p = aquila_powerdown_modes;
ge = aquila_external_powerdown_modes;
n_p = ARRAY_SIZE(aquila_powerdown_modes);
n_ge = ARRAY_SIZE(aquila_external_powerdown_modes);
n_mr = ARRAY_SIZE(aquila_mirror_powerdown_mode);
- } else if (machine_is_kessler()) {
+ } else if (mach_is_kessler()) {
/* Aquila rev 0.9 */
p = kessler_powerdown_modes;
ge = kessler_external_powerdown_modes;
n_p = ARRAY_SIZE(kessler_powerdown_modes);
n_ge = ARRAY_SIZE(kessler_external_powerdown_modes);
n_mr = ARRAY_SIZE(kessler_mirror_powerdown_mode);
- } else if (machine_is_geminus()) {
+ } else if (mach_is_geminus()) {
if (hwrevision(1)) {
/* Same as Aquila rev 0.9 */
#if 0
for (i = 0; i < n_mr; i++) {
unsigned int reg = readl(&mr->bank->pdn_con);
- reg &= ~(1 << mr->number);
+ reg &= ~(0x3 << (mr->number << 1));
if (readl(&mr->bank->dat) & (1 << mr->number))
- reg |= 1 << mr->number;
+ reg |= 0x1 << (mr->number << 1);
writel(reg, &mr->bank->pdn_con);
-
- printf("[%8.8X] = %8.8X\n", (unsigned int) (&mr->bank->pdn_con), reg);
-
mr++;
}
}
gpio_cfg_pin(&gpio_base->gpio_j1, 3, GPIO_OUTPUT);
/* LCD_BACKLIGHT_EN */
- if (machine_is_geminus())
+ if (mach_is_geminus())
gpio_cfg_pin(&gpio_base->gpio_mp0_5, 0, GPIO_OUTPUT);
+ if (board_is_neptune() && hwrevision(0)) {
+ gpio_cfg_pin(&gpio_base->gpio_mp0_4, 4, GPIO_OUTPUT);
+ gpio_direction_output(&gpio_base->gpio_mp0_4, 4, 0);
+ }
/*
* gpio pad configuration for
gpio_cfg_pin(&gpio_base->gpio_mp0_4, 2, GPIO_INPUT);
gpio_cfg_pin(&gpio_base->gpio_mp0_4, 3, GPIO_OUTPUT);
- if (machine_is_aquila() || machine_is_kessler()) {
+ if (mach_is_aquila() || mach_is_kessler()) {
spi_pd.cs_bank = &gpio_base->gpio_mp0_1;
spi_pd.cs_num = 1;
spi_pd.clk_bank = &gpio_base->gpio_mp0_4;
spi_pd.so_bank = &gpio_base->gpio_mp0_4;
spi_pd.so_num = 2;
- if (board_is_neptune())
+ if (board_is_neptune() && hwrevision(0))
s6d16a0x_set_platform_data(&spi_pd);
else {
s6e63m0_set_platform_data(&spi_pd);
}
}
- if (machine_is_cypress()) {
+ if (mach_is_cypress()) {
#if 0 /* universal cypress */
/* FLCD_CS */
gpio_cfg_pin(&gpio_base->gpio_mp0_1, 0, GPIO_OUTPUT);
return;
}
+#define SWRST_REG 0x00
+#define LEDCON_REG 0x01
+#define LED_CUR_SET_REG 0x03
+#define LED_CUR_TR_REG 0x08
+
+#define SWRST 0x01
+#define NORMAL_MODE 0x09
+#define CUR_SET 0x63
+#define TR_SET 0x00
void backlight_on(unsigned int onoff)
{
+
+ unsigned char addr;
+ unsigned char val[2];
struct s5pc110_gpio *gpio = (struct s5pc110_gpio *) S5PC110_GPIO_BASE;
if (onoff) {
- if (machine_is_geminus())
+ if (mach_is_geminus())
gpio_set_value(&gpio->gpio_mp0_5, 0, 1);
} else {
- if (machine_is_geminus())
+ if (mach_is_geminus())
gpio_set_value(&gpio->gpio_mp0_5, 0, 0);
}
+
+ if (mach_is_kessler() && board_is_neptune() && hwrevision(0)) {
+ gpio_set_value(&gpio->gpio_mp0_4, 4, 1);
+ udelay(6);
+
+ i2c_set_bus_num(I2C_GPIO5);
+
+ addr = 0x76;
+ if (i2c_probe(addr)) {
+ if (i2c_probe(addr)) {
+ puts("Can't found s6d16a0x backlight i2c\n");
+ return;
+ }
+ }
+ val[0] = SWRST;
+ i2c_write(addr, SWRST_REG, 1, val, 1);
+ /* NORMAL MODE */
+ val[0] = CUR_SET;
+ i2c_write(addr, LED_CUR_SET_REG, 1, val, 1);
+ val[0] = TR_SET;
+ i2c_write(addr, LED_CUR_TR_REG, 1, val, 1);
+ val[0] = NORMAL_MODE;
+ i2c_write(addr, LEDCON_REG, 1, val, 1);
+ udelay(5000);
+ }
}
void reset_lcd(void)
{
struct s5pc110_gpio *gpio = (struct s5pc110_gpio *) S5PC110_GPIO_BASE;
- if (machine_is_aquila() || machine_is_kessler() || machine_is_geminus())
+ if (mach_is_aquila() || mach_is_kessler() || mach_is_geminus())
gpio_set_value(&gpio->gpio_mp0_5, 5, 1);
- if (machine_is_cypress())
+ if (mach_is_cypress())
gpio_set_value(&gpio->gpio_mp0_4, 5, 1);
}
struct s5pc110_gpio *gpio = (struct s5pc110_gpio *) S5PC110_GPIO_BASE;
if (onoff) {
/* TSP_LDO_ON */
- if (machine_is_aquila() || machine_is_geminus())
+ if (mach_is_aquila() || mach_is_geminus())
gpio_set_value(&gpio->gpio_j1, 3, 1);
- if (machine_is_cypress())
+ if (mach_is_cypress())
gpio_set_value(&gpio->gpio_g2, 2, 1);
- if (machine_is_kessler()) {
+ if (mach_is_kessler()) {
unsigned char addr;
unsigned char val[2];
unsigned char val2[2];
gpio_set_value(&gpio->gpio_j1, 3, 1);
- i2c_set_bus_num(I2C_PMIC);
addr = 0xCC >> 1; /* max8998 */
- if (i2c_probe(addr)) {
- printf("Can't found max8998\n");
+ if (max8998_probe())
return;
- }
+
i2c_read(addr, MAX8998_REG_ONOFF3, 1, val, 1);
val[0] &= ~(MAX8998_LDO17);
- val[0] |= MAX8998_LDO17; /* LDO17: VCC_3.0V_LCD */
+ val[0] |= MAX8998_LDO17; /* LDO17: VCC_3.0V_LCD */
i2c_write(addr, MAX8998_REG_ONOFF3, 1, val, 1);
i2c_read(addr, MAX8998_REG_ONOFF3, 1, val, 1);
i2c_write(addr, MAX8998_REG_ONOFF2, 1, val, 1);
}
} else {
- if (machine_is_aquila() || machine_is_geminus())
+ if (mach_is_aquila() || mach_is_geminus())
gpio_set_value(&gpio->gpio_j1, 3, 0);
- if (machine_is_cypress())
+ if (mach_is_cypress())
gpio_set_value(&gpio->gpio_g2, 2, 0);
- if (machine_is_kessler()) {
+ if (mach_is_kessler()) {
unsigned char addr;
unsigned char val[2];
- i2c_set_bus_num(I2C_PMIC);
+ gpio_set_value(&gpio->gpio_j1, 3, 0);
+
addr = 0xCC >> 1; /* max8998 */
- if (i2c_probe(addr)) {
- printf("Can't found max8998\n");
+ if (max8998_probe())
return;
- }
i2c_read(addr, MAX8998_REG_ONOFF2, 1, val, 1);
- val[0] &= ~(1 << 7);
+ val[0] &= ~(MAX8998_LDO7);
i2c_write(addr, MAX8998_REG_ONOFF2, 1, val, 1);
i2c_read(addr, MAX8998_REG_ONOFF2, 1, val, 1);
i2c_read(addr, MAX8998_REG_ONOFF3, 1, val, 1);
- val[0] &= ~MAX8998_LDO17;
+ val[0] &= ~(MAX8998_LDO17);
i2c_write(addr, MAX8998_REG_ONOFF3, 1, val, 1);
i2c_read(addr, MAX8998_REG_ONOFF3, 1, val, 1);
}
int s5p_no_lcd_support(void)
{
- if (machine_is_wmg160())
+ if (mach_is_wmg160())
return 1;
return 0;
}
vid->vl_vbpd = 3;
vid->vl_vfpd = 28;
- if (machine_is_aquila() || machine_is_kessler() || machine_is_cypress()) {
+ if (mach_is_aquila() || mach_is_kessler()
+ || mach_is_cypress()) {
vid->cfg_gpio = lcd_cfg_gpio;
vid->reset_lcd = reset_lcd;
vid->backlight_on = backlight_on;
vid->reset_delay = 120000;
}
- if (board_is_neptune()) {
+ if (board_is_neptune() && hwrevision(0)) {
vid->vl_freq = 100;
vid->vl_col = 320;
vid->vl_row = 480;
vid->vl_vfpd = 4;
vid->cfg_gpio = lcd_cfg_gpio;
- vid->backlight_on = NULL;
+ vid->backlight_on = backlight_on;
vid->lcd_power_on = lcd_power_on;
vid->reset_lcd = reset_lcd;
vid->cfg_ldo = s6d16a0x_cfg_ldo;
}
- if (machine_is_geminus()) {
+ if (mach_is_geminus()) {
vid->vl_freq = 60;
vid->vl_col = 1024,
vid->vl_row = 600,
/* It should be located at first */
lcd_is_enabled = 0;
- if (machine_is_aquila() || machine_is_kessler()) {
- if (board_is_neptune())
+ if (mach_is_aquila() || mach_is_kessler()) {
+ if (board_is_neptune() && hwrevision(0))
setenv("lcdinfo", "lcd=s6d16a0x");
else if (board_is_media())
setenv("lcdinfo", "lcd=s6e63m0");
else
setenv("lcdinfo", "lcd=s6e63m0");
}
- if (machine_is_geminus())
+ if (mach_is_geminus())
setenv("lcdinfo", "lcd=lms480jc01");
- if (machine_is_cypress())
+ if (mach_is_cypress())
setenv("lcdinfo", "lcd=s6e63m0");
#endif
setup_meminfo();
setup_power_down_mode_registers();
/* check max17040 */
- check_battery();
+ check_battery(0);
/* check fsa9480 */
check_micro_usb(0);
/* Set Initial global variables */
s5pc110_gpio = (struct s5pc110_gpio *) S5PC110_GPIO_BASE;
- gd->bd->bi_arch_number = MACH_AQUILA;
+ gd->bd->bi_arch_number = MACH_TYPE_AQUILA;
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
+#ifdef CONFIG_LCD
+ /*
+ * set reserved memory region for framebuffer.
+ *
+ * this region wouldn't be rewrited by kernel so
+ * could avoid nosie screen filled by garbages
+ * after hibernation resume has been completed.
+ */
+ gd->fb_base = CONFIG_FB_RESERVED_MEM;
+#endif
+
/* Check H/W Revision */
check_hw_revision();
* Aquila Rev0.5 4G3G1G
* Aquila Rev0.8 4G3G1G
* Aquila Rev0.9 4G3G1G
+ * Neptune Rev 0.2 4G3G1G
*/
- if (machine_is_aquila() || machine_is_kessler())
- if (hwrevision(5) || hwrevision(8) || hwrevision(9)) {
+ if (mach_is_aquila() || mach_is_kessler()) {
+ if ((!board_is_neptune() && (hwrevision(5) ||
+ hwrevision(8) || hwrevision(9))) ||
+ (board_is_neptune() && hwrevision(2))) {
memconfig1 = readl(base + MEMCONFIG1_OFFSET);
sz = (memconfig1 >> 16) & 0xFF;
sz = ((unsigned char) ~sz) + 1;
sz = sz << 4;
}
-
+ if (mach_is_kessler() && board_is_s1())
+ sz = 0;
+ }
}
/*
* bi_dram[1].size contains all DMC1 memory size
/* MHL off */
gpio_direction_output(&s5pc110_gpio->gpio_j2, 2, 0);
gpio_direction_output(&s5pc110_gpio->gpio_mp0_4, 7, 0);
- gpio_direction_output(&s5pc110_gpio->gpio_j2, 3, 0); /* MHL_ON for REV02 or higher */
-
-
+ /* MHL_ON for REV02 or higher */
+ gpio_direction_output(&s5pc110_gpio->gpio_j2, 3, 0);
}
+
void board_sleep_init(void)
{
unsigned char addr;
unsigned char val[2];
- i2c_set_bus_num(I2C_PMIC);
addr = 0xCC >> 1;
- if (i2c_probe(addr)) {
- printf("Can't find max8998\n");
+ if (max8998_probe())
return;
- }
- /* Set ONOFF1 */
- i2c_read(addr, MAX8998_REG_ONOFF1, 1, val, 1);
- saved_val[0][0] = val[0];
- saved_val[0][1] = val[1];
- val[0] &= ~((1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) |
- (1 << 1) | (1 << 0));
- i2c_write(addr, MAX8998_REG_ONOFF1, 1, val, 1);
- i2c_read(addr, MAX8998_REG_ONOFF1, 1, val, 1);
- /* Set ONOFF2 */
- i2c_read(addr, MAX8998_REG_ONOFF2, 1, val, 1);
- saved_val[1][0] = val[0];
- saved_val[1][1] = val[1];
- val[0] &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 3) |
- (1 << 2) | (1 << 1) | (1 << 0));
- val[0] |= (1 << 7);
- i2c_write(addr, MAX8998_REG_ONOFF2, 1, val, 1);
- i2c_read(addr, MAX8998_REG_ONOFF2, 1, val, 1);
- /* Set ONOFF3 */
- i2c_read(addr, MAX8998_REG_ONOFF3, 1, val, 1);
- saved_val[2][0] = val[0];
- saved_val[2][1] = val[1];
- val[0] &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4));
- i2c_write(addr, MAX8998_REG_ONOFF3, 1, val, 1);
- i2c_read(addr, MAX8998_REG_ONOFF3, 1, val, 1);
- /* Set ONOFF4 */
- i2c_read(addr, MAX8998_REG_ONOFF3+1, 1, val, 1);
- saved_val[3][0] = val[0];
- saved_val[3][1] = val[1];
- val[0] &= ~((1 << 7) | (1 << 6) | (1 << 4));
- i2c_write(addr, MAX8998_REG_ONOFF3+1, 1, val, 1);
- i2c_read(addr, MAX8998_REG_ONOFF3+1, 1, val, 1);
- printf("Turned off regulators. Preparing to sleep. [%s:%d]\n",
- __FILE__, __LINE__);
+ if (mach_is_kessler()) {
+ /* Set ONOFF1 */
+ i2c_read(addr, MAX8998_REG_ONOFF1, 1, val, 1);
+ saved_val[0][0] = val[0];
+ saved_val[0][1] = val[1];
+ val[0] &= ~((1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) |
+ (1 << 1) | (1 << 0));
+ i2c_write(addr, MAX8998_REG_ONOFF1, 1, val, 1);
+ i2c_read(addr, MAX8998_REG_ONOFF1, 1, val, 1);
+
+ /* Set ONOFF2 */
+ i2c_read(addr, MAX8998_REG_ONOFF2, 1, val, 1);
+ saved_val[1][0] = val[0];
+ saved_val[1][1] = val[1];
+ val[0] &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 3) |
+ (1 << 2) | (1 << 1) | (1 << 0));
+ val[0] |= (1 << 7);
+ i2c_write(addr, MAX8998_REG_ONOFF2, 1, val, 1);
+ i2c_read(addr, MAX8998_REG_ONOFF2, 1, val, 1);
+
+ /* Set ONOFF3 */
+ i2c_read(addr, MAX8998_REG_ONOFF3, 1, val, 1);
+ saved_val[2][0] = val[0];
+ saved_val[2][1] = val[1];
+ val[0] &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4));
+ i2c_write(addr, MAX8998_REG_ONOFF3, 1, val, 1);
+ i2c_read(addr, MAX8998_REG_ONOFF3, 1, val, 1);
+
+ /* Set ONOFF4 */
+ i2c_read(addr, MAX8998_REG_ONOFF3+1, 1, val, 1);
+ saved_val[3][0] = val[0];
+ saved_val[3][1] = val[1];
+ val[0] &= ~((1 << 6) | (1 << 4));
+ i2c_write(addr, MAX8998_REG_ONOFF3+1, 1, val, 1);
+ i2c_read(addr, MAX8998_REG_ONOFF3+1, 1, val, 1);
+
+ printf("Turned off regulators with Kessler setting."
+ " Preparing to sleep. [%s:%d]\n",
+ __FILE__, __LINE__);
+ } else { /* Default */
+ /* Set ONOFF1 */
+ i2c_read(addr, MAX8998_REG_ONOFF1, 1, val, 1);
+ saved_val[0][0] = val[0];
+ saved_val[0][1] = val[1];
+ val[0] &= ~((1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) |
+ (1 << 1) | (1 << 0));
+ i2c_write(addr, MAX8998_REG_ONOFF1, 1, val, 1);
+ i2c_read(addr, MAX8998_REG_ONOFF1, 1, val, 1);
+
+ /* Set ONOFF2 */
+ i2c_read(addr, MAX8998_REG_ONOFF2, 1, val, 1);
+ saved_val[1][0] = val[0];
+ saved_val[1][1] = val[1];
+ val[0] &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 3) |
+ (1 << 2) | (1 << 1) | (1 << 0));
+ val[0] |= (1 << 7);
+ i2c_write(addr, MAX8998_REG_ONOFF2, 1, val, 1);
+ i2c_read(addr, MAX8998_REG_ONOFF2, 1, val, 1);
+
+ /* Set ONOFF3 */
+ i2c_read(addr, MAX8998_REG_ONOFF3, 1, val, 1);
+ saved_val[2][0] = val[0];
+ saved_val[2][1] = val[1];
+ val[0] &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4));
+ i2c_write(addr, MAX8998_REG_ONOFF3, 1, val, 1);
+ i2c_read(addr, MAX8998_REG_ONOFF3, 1, val, 1);
+
+ /* Set ONOFF4 */
+ i2c_read(addr, MAX8998_REG_ONOFF3+1, 1, val, 1);
+ saved_val[3][0] = val[0];
+ saved_val[3][1] = val[1];
+ val[0] &= ~((1 << 7) | (1 << 6) | (1 << 4));
+ i2c_write(addr, MAX8998_REG_ONOFF3+1, 1, val, 1);
+ i2c_read(addr, MAX8998_REG_ONOFF3+1, 1, val, 1);
+
+ printf("Turned off regulators with default(Aquila) setting."
+ " Preparing to sleep. [%s:%d]\n",
+ __FILE__, __LINE__);
+ }
}
void board_sleep_resume(void)
show_hw_revision();
- i2c_set_bus_num(I2C_PMIC);
addr = 0xCC >> 1;
- if (i2c_probe(addr)) {
- printf("Can't find max8998\n");
+ if (max8998_probe())
return;
- }
/* Set ONOFF1 */
i2c_write(addr, MAX8998_REG_ONOFF1, 1, saved_val[0], 1);
/* Set ONOFF4 */
i2c_write(addr, MAX8998_REG_ONOFF3+1, 1, saved_val[3], 1);
i2c_read(addr, MAX8998_REG_ONOFF3+1, 1, val, 1);
- printf("Waked up.\n");
+ puts("Waked up.\n");
/* check max17040 */
- check_battery();
+ check_battery(0);
/* check fsa9480 */
- check_micro_usb(1);
+ check_micro_usb(0);
+}
+
+#if defined(CONFIG_USB_GADGET_S3C_UDC_OTG)
+
+static int s5pc1xx_phy_control(int on)
+{
+ static int status;
+
+ if (on && !status) {
+#ifdef CONFIG_CMD_PMIC
+ run_command("pmic ldo 3 on", 0);
+#endif
+ /* S5PC110 */
+ if (board_is_limo_universal() ||
+ board_is_limo_real() ||
+ board_is_media()) {
+ /* check usb path */
+ if (board_is_limo_real() && !hwrevision(6))
+ check_mhl();
+ }
+
+ if (mach_is_tickertape())
+ /* USB_SEL: XM0ADDR_0: MP04[0] output mode */
+ gpio_direction_output(&s5pc110_gpio->gpio_mp0_4, 0, 0);
+
+ /* USB Path to AP */
+ micro_usb_switch(0);
+ status = 1;
+ } else if (!on && status) {
+#ifdef CONFIG_CMD_PMIC
+ run_command("pmic ldo 3 off", 0);
+#endif
+ status = 0;
+ }
+ udelay(10000);
+
+ return 0;
}
+struct s3c_plat_otg_data s5pc110_otg_data = {
+ .phy_control = s5pc1xx_phy_control,
+ .regs_phy = S5PC110_PHY_BASE,
+ .regs_otg = S5PC110_OTG_BASE,
+};
+
+int board_eth_init(bd_t *bis)
+{
+ int res = -1;
+
+ if (cpu_is_s5pc100())
+ return -1;
+
+ s3c_udc_probe(&s5pc110_otg_data);
+ if (usb_eth_initialize(bis) >= 0)
+ res = 0;
+ return res;
+}
+#endif
+
#ifdef CONFIG_CMD_USBDOWN
int usb_board_init(void)
{
/* PMIC */
if (i2c_read(0x66, 0, 1, val, 2)) {
- printf("i2c_read error\n");
+ puts("i2c_read error\n");
return 1;
}
val[1] |= (1 << 5);
if (i2c_write(0x66, 0, 1, val, 2)) {
- printf("i2c_write error\n");
+ puts("i2c_write error\n");
return 1;
}
i2c_read(0x66, 0, 1, val, 2);
check_mhl();
}
- if (machine_is_tickertape())
+ if (mach_is_tickertape())
/* USB_SEL: XM0ADDR_0: MP04[0] output mode */
gpio_direction_output(&s5pc110_gpio->gpio_mp0_4, 0, 0);
#ifdef CONFIG_GENERIC_MMC
int s5p_no_mmc_support(void)
{
- if (machine_is_wmg160())
+ if (mach_is_wmg160())
return 1;
return 0;
}
int i;
/* MASSMEMORY_EN: XMSMDATA7: GPJ2[7] output high */
- if (machine_is_kessler())
+ if (mach_is_kessler())
gpio_direction_output(&s5pc110_gpio->gpio_j2, 7, 1);
- if (machine_is_wmg160())
+ if (mach_is_wmg160())
return -1;
/* MMC0 Clock source = SCLKMPLL */
gpio_set_drv(&s5pc110_gpio->gpio_g0, i, GPIO_DRV_4X);
}
+ if (mach_is_geminus()) {
+ gpio_direction_output(&s5pc110_gpio->gpio_j2, 7, 1);
+ gpio_set_pull(&s5pc110_gpio->gpio_j2, 7, GPIO_PULL_NONE);
+ }
+
return s5pc1xx_mmc_init(0);
}
#endif
unsigned char addr, val[2];
int reg, i;
- i2c_set_bus_num(I2C_PMIC);
addr = 0xCC >> 1;
- if (i2c_probe(addr)) {
- printf("Can't found max8998\n");
+
+ if (max8998_probe())
return -1;
- }
reg = 0x11;
i2c_read(addr, reg, 1, val, 1);
} else
return -1;
- i2c_set_bus_num(I2C_PMIC);
addr = 0xCC >> 1;
- if (i2c_probe(addr)) {
- printf("Can't found max8998\n");
+
+ if (max8998_probe())
return -1;
- }
i2c_read(addr, reg, 1, val, 1);
if (on)
#endif
#ifdef CONFIG_CMD_DEVICE_POWER
-
-enum {
- POWER_NONE,
- POWER_TOUCH,
- POWER_3_TOUCHKEY,
- POWER_LCD,
- POWER_HAPTIC,
- POWER_AUDIO_CODEC,
- POWER_FM_RADIO,
- POWER_BT_WIFI,
- POWER_HDMI,
-};
-
-static void power_display_devices(void)
-{
- printf("devices:\n");
- printf("\t%d - touch\n", POWER_TOUCH);
- printf("\t%d - 3 touchkey\n", POWER_3_TOUCHKEY);
- printf("\t%d - LCD\n", POWER_LCD);
- printf("\t%d - Haptic\n", POWER_HAPTIC);
- printf("\t%d - Audio Codec\n", POWER_AUDIO_CODEC);
- printf("\t%d - FM Radio\n", POWER_FM_RADIO);
- printf("\t%d - BT/WiFi\n", POWER_BT_WIFI);
- printf("\t%d - HDMI\n", POWER_HDMI);
-}
-
-static int power_hdmi(int on)
-{
- /* HDMI_EN1: GPJ2[2] */
- gpio_direction_output(&s5pc110_gpio->gpio_j2, 2, on);
- /* MHL_ON: GPJ2[3] */
- gpio_direction_output(&s5pc110_gpio->gpio_j2, 3, on);
- return 0;
-}
-
-static int power_bt_wifi(int on)
-{
- /* WLAN_BT_EN: GPB[5] */
- gpio_direction_output(&s5pc110_gpio->gpio_b, 5, on);
- return 0;
-}
-
-static int power_fm_radio(int on)
-{
- /* FM_BUS_nRST: GPJ2[5] */
- gpio_direction_output(&s5pc110_gpio->gpio_j2, 5, !on);
- return 0;
-}
-
-static int power_audio_codec(int on)
-{
- /* CODEC_LDO_EN: GPF3[4] */
- gpio_direction_output(&s5pc110_gpio->gpio_f3, 4, on);
- /* CODEC_XTAL_EN: GPH3[2] */
- gpio_direction_output(&s5pc110_gpio->gpio_h3, 2, on);
- return 0;
-}
-
-static int power_haptic(int on)
-{
- /* HAPTIC_ON: GPJ1[1] */
- gpio_direction_output(&s5pc110_gpio->gpio_j1, 1, on);
- return 0;
-}
-
-static int power_lcd(int on)
-{
- /* MLCD_ON: GPJ1[3] */
- gpio_direction_output(&s5pc110_gpio->gpio_j1, 3, on);
- return 0;
-}
-
-static int power_touch(int on)
-{
- /* TOUCH_EN: GPG3[6] */
- gpio_direction_output(&s5pc110_gpio->gpio_g3, 6, on);
- return 0;
-}
-
-static int power_3_touchkey(int on)
-{
- if (on) {
- /* 3_TOUCH_EN - GPJ3[0] : (J1B2) */
- /* 3_TOUCH_EN - GPJ3[5] : (not J1B2) */
- if (board_rev & J1_B2_BOARD)
- gpio_direction_output(&s5pc110_gpio->gpio_j3, 0, on);
- else
- gpio_direction_output(&s5pc110_gpio->gpio_j3, 5, on);
-
- /* 3_TOUCH_CE - GPJ2[6] */
- gpio_direction_output(&s5pc110_gpio->gpio_j2, 6, on); /* TOUCH_CE */
- } else {
- /* 3_TOUCH_CE - GPJ2[6] */
- gpio_direction_output(&s5pc110_gpio->gpio_j2, 6, on); /* TOUCH_CE */
- }
-
- if (on) {
- unsigned int reg;
- unsigned char val[2];
- unsigned char addr = 0x20; /* mcs5000 3-touchkey */
-
- /* Require 100ms */
- udelay(80 * 1000);
-
- /* 3 touchkey */
- i2c_set_bus_num(I2C_GPIO10);
-
- /* Workaround to probe */
- if (i2c_probe(addr)) {
- if (i2c_probe(addr)) {
- printf("Can't found 3 touchkey\n");
- return -ENODEV;
- }
- }
-
-#define MCS5000_TK_HW_VERSION 0x06
-#define MCS5000_TK_FW_VERSION 0x0A
-#define MCS5000_TK_MI_VERSION 0x0B
-
- reg = MCS5000_TK_MI_VERSION;
- i2c_read(addr, reg, 1, val, 1);
- printf("3-touchkey:\tM/I 0x%x, ", val[0]);
- reg = MCS5000_TK_HW_VERSION;
- i2c_read(addr, reg, 1, val, 1);
- printf("H/W 0x%x, ", val[0]);
- reg = MCS5000_TK_FW_VERSION;
- i2c_read(addr, reg, 1, val, 1);
- printf("F/W 0x%x\n", val[0]);
- }
- return 0;
-}
-
-static int power_control(int device, int on)
-{
- switch (device) {
- case POWER_TOUCH:
- return power_touch(on);
- case POWER_3_TOUCHKEY:
- return power_3_touchkey(on);
- case POWER_LCD:
- return power_lcd(on);
- case POWER_HAPTIC:
- return power_haptic(on);
- case POWER_AUDIO_CODEC:
- return power_audio_codec(on);
- case POWER_FM_RADIO:
- return power_fm_radio(on);
- case POWER_BT_WIFI:
- return power_bt_wifi(on);
- case POWER_HDMI:
- return power_hdmi(on);
- default:
- printf("I don't know device %d\n", device);
- break;
- }
- return 0;
-}
-
-static int power_on(int on)
-{
- power_touch(on);
- power_3_touchkey(on);
- power_lcd(on);
- power_haptic(on);
- power_audio_codec(on);
- power_fm_radio(on);
- power_bt_wifi(on);
- power_hdmi(on);
-
- return 0;
-}
-
-static int do_power(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
-{
- int device, on;
-
- if (!machine_is_aquila() && !machine_is_kessler())
- goto out;
-
- switch (argc) {
- case 2:
- if (strncmp(argv[1], "on", 2) == 0)
- return power_on(1);
- if (strncmp(argv[1], "off", 3) == 0)
- return power_on(0);
- break;
- case 3:
- device = simple_strtoul(argv[1], NULL, 10);
- if (device < 0)
- break;
-
- if (strncmp(argv[2], "on", 2) == 0)
- on = 1;
- else if (strncmp(argv[2], "off", 3) == 0)
- on = 0;
- else
- break;
- return power_control(device, on);
- default:
- break;
- }
-out:
- cmd_usage(cmdtp);
- power_display_devices();
- return 1;
-}
-
-U_BOOT_CMD(
- power, CONFIG_SYS_MAXARGS, 1, do_power,
- "Device Power Management control",
- "device on/off - Turn on/off the device\n"
-);
-
static int do_microusb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
switch (argc) {