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