blob: 2e1404fa09ae8ef0f399cf57779961de54ebebd5 [file] [log] [blame]
Sonic Zhange7b9aa92011-11-29 15:05:35 +08001/*
2 * U-boot - main board file
3 *
4 * Copyright (c) 2008-2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <common.h>
10#include <asm/blackfin.h>
11#include <asm/io.h>
12#include <i2c.h>
13#include "soft_switch.h"
14
15#define SWITCH_ADDR 0x21
16
17#define NUM_SWITCH 3
18#define IODIRA 0x0
19#define IODIRB 0x1
20#define OLATA 0x14
21#define OLATB 0x15
22
23struct switch_config {
24 uchar dir0; /* IODIRA */
25 uchar dir1; /* IODIRB */
26 uchar value0; /* OLATA */
27 uchar value1; /* OLATB */
28};
29
30static struct switch_config switch_config_array[NUM_SWITCH] = {
31 {
32/*
33 U45 Port A U45 Port B
34
35 7--------------- RMII_CLK_EN | 7--------------- ~TEMP_THERM_EN
36 | 6------------- ~CNT0ZM_EN | | 6------------- ~TEMP_IRQ_EN
37 | | 5----------- ~CNT0DG_EN | | | 5----------- ~UART0CTS_146_EN
38 | | | 4--------- ~CNT0UD_EN | | | | 4--------- ~UART0CTS_RST_EN
39 | | | | 3------- ~CAN0RX_EN | | | | | 3------- ~UART0CTS_RTS_LPBK
40 | | | | | 2----- ~CAN0_ERR_EN | | | | | | 2----- ~UART0CTS_EN
41 | | | | | | 1--- ~CAN_STB | | | | | | | 1--- ~UART0RX_EN
42 | | | | | | | 0- CAN_EN | | | | | | | | 0- ~UART0RTS_EN
43 | | | | | | | | | | | | | | | | |
44 O O O O O O O O | O O O O O O O O (I/O direction)
45 1 0 0 0 0 0 1 1 | 1 1 1 1 1 0 0 0 (value being set)
46*/
47 .dir0 = 0x0, /* all output */
48 .dir1 = 0x0, /* all output */
49 .value0 = RMII_CLK_EN | CAN_STB | CAN_EN,
50 .value1 = TEMP_THERM_EN | TEMP_IRQ_EN | UART0CTS_146_EN
51 | UART0CTS_RST_EN | UART0CTS_RTS_LPBK,
52 },
53 {
54/*
55 U46 Port A U46 Port B
56
57 7--------------- ~LED4_GPIO_EN | 7--------------- EMPTY
58 | 6------------- ~LED3_GPIO_EN | | 6------------- ~SPI0D3_EN
59 | | 5----------- ~LED2_GPIO_EN | | | 5----------- ~SPI0D2_EN
60 | | | 4--------- ~LED1_GPIO_EN | | | | 4--------- ~SPIFLASH_CS_EN
61 | | | | 3------- SMC0_LP0_EN | | | | | 3------- ~SD_WP_EN
62 | | | | | 2----- EMPTY | | | | | | 2----- ~SD_CD_EN
63 | | | | | | 1--- SMC0_EPPI2 | | | | | | | 1--- ~PUSHBUTTON2_EN
64 _LP1_SWITCH
65 | | | | | | | 0- OVERRIDE_SMC0 | | | | | | | | 0- ~PUSHBUTTON1_EN
66 _LP0_BOOT
67 | | | | | | | | | | | | | | | | |
68 O O O O O O O O | O O O O O O O O (I/O direction)
69 0 0 0 0 0 X 0 1 | X 0 0 0 0 0 0 0 (value being set)
70*/
71 .dir0 = 0x0, /* all output */
72 .dir1 = 0x0, /* all output */
73#ifdef CONFIG_BFIN_LINKPORT
74 .value0 = OVERRIDE_SMC0_LP0_BOOT,
75#else
76 .value0 = SMC0_EPPI2_LP1_SWITCH,
77#endif
78 .value1 = 0x0,
79 },
80 {
81/*
82 U47 Port A U47 Port B
83
84 7--------------- ~PD2_SPI0MISO | 7--------------- EMPTY
85 _EI3_EN
86 | 6------------- ~PD1_SPI0D3 | | 6------------- EMPTY
87 _EPPI1D17
88 _SPI0SEL2
89 _EI3_EN
90 | | 5----------- ~PD0_SPI0D2 | | | 5----------- EMPTY
91 _EPPI1D16
92 _SPI0SEL3
93 _EI3_EN
94 | | | 4--------- ~WAKE_PUSH | | | | 4--------- EMPTY
95 BUTTON_EN
96 | | | | 3------- ~ETHERNET_EN | | | | | 3------- EMPTY
97 | | | | | 2----- PHYAD0 | | | | | | 2----- EMPTY
98 | | | | | | 1--- PHY_PWR | | | | | | | 1--- ~PD4_SPI0CK_EI3_EN
99 _DWN_INT
100 | | | | | | | 0- ~PHYINT_EN | | | | | | | | 0- ~PD3_SPI0MOSI_EI3_EN
101 | | | | | | | | | | | | | | | | |
102 O O O O O I I O | O O O O O O O O (I/O direction)
103 1 1 1 0 0 0 0 0 | X X X X X X 1 1 (value being set)
104*/
105 .dir0 = 0x6, /* bits 1 and 2 input, all others output */
106 .dir1 = 0x0, /* all output */
107 .value0 = PD1_SPI0D3_EN | PD0_SPI0D2_EN,
108 .value1 = 0,
109 },
110};
111
112static int setup_soft_switch(int addr, struct switch_config *config)
113{
114 int ret = 0;
115
116 ret = i2c_write(addr, OLATA, 1, &config->value0, 1);
117 if (ret)
118 return ret;
119 ret = i2c_write(addr, OLATB, 1, &config->value1, 1);
120 if (ret)
121 return ret;
122
123 ret = i2c_write(addr, IODIRA, 1, &config->dir0, 1);
124 if (ret)
125 return ret;
126 return i2c_write(addr, IODIRB, 1, &config->dir1, 1);
127}
128
129int config_switch_bit(int num, int port, int bit, int dir, uchar value)
130{
131 int addr = SWITCH_ADDR + num;
132 int ret, data_reg, dir_reg;
133 uchar tmp;
134
135 if (port == IO_PORT_A) {
136 data_reg = OLATA;
137 dir_reg = IODIRA;
138 } else {
139 data_reg = OLATB;
140 dir_reg = IODIRB;
141 }
142
143 if (dir == IO_PORT_INPUT) {
144 ret = i2c_read(addr, dir_reg, 1, &tmp, 1);
145 if (ret)
146 return ret;
147 tmp |= bit;
148 return i2c_write(addr, dir_reg, 1, &tmp, 1);
149 } else {
150 ret = i2c_read(addr, data_reg, 1, &tmp, 1);
151 if (ret)
152 return ret;
153 if (value)
154 tmp |= bit;
155 else
156 tmp &= ~bit;
157 ret = i2c_write(addr, data_reg, 1, &tmp, 1);
158 if (ret)
159 return ret;
160 ret = i2c_read(addr, dir_reg, 1, &tmp, 1);
161 if (ret)
162 return ret;
163 tmp &= ~bit;
164 return i2c_write(addr, dir_reg, 1, &tmp, 1);
165 }
166}
167
168int setup_board_switches(void)
169{
170 int ret;
171 int i;
172
173 for (i = 0; i < NUM_SWITCH; i++) {
174 ret = setup_soft_switch(SWITCH_ADDR + i,
175 &switch_config_array[i]);
176 if (ret)
177 return ret;
178 }
179 return 0;
180}