]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/bf609-ezkit/soft_switch.c
Merge branch 'u-boot-samsung/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / board / bf609-ezkit / soft_switch.c
1 /*
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 struct switch_config {
16         uchar dir0; /* IODIRA */
17         uchar dir1; /* IODIRB */
18         uchar value0; /* OLATA */
19         uchar value1; /* OLATB */
20 };
21
22 static 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
104 static 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
121 int config_switch_bit(int addr, int port, int bit, int dir, uchar value)
122 {
123         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
159 int 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 }