]>
Commit | Line | Data |
---|---|---|
1f045217 WD |
1 | /* |
2 | * (C) Copyright 2001 | |
3 | * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. | |
4 | * | |
1a459660 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
1f045217 WD |
6 | * |
7 | * The original I2C interface was | |
8 | * (C) 2000 by Paolo Scaffardi (arsenio@tin.it) | |
9 | * AIRVENT SAM s.p.a - RIMINI(ITALY) | |
10 | * but has been changed substantially. | |
11 | */ | |
12 | ||
13 | #ifndef _I2C_H_ | |
14 | #define _I2C_H_ | |
15 | ||
16 | /* | |
17 | * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING | |
18 | * | |
19 | * The implementation MUST NOT use static or global variables if the | |
20 | * I2C routines are used to read SDRAM configuration information | |
21 | * because this is done before the memories are initialized. Limited | |
22 | * use of stack-based variables are OK (the initial stack size is | |
23 | * limited). | |
24 | * | |
25 | * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING | |
26 | */ | |
27 | ||
28 | /* | |
29 | * Configuration items. | |
30 | */ | |
31 | #define I2C_RXTX_LEN 128 /* maximum tx/rx buffer length */ | |
32 | ||
cd7b4e82 MV |
33 | #ifdef CONFIG_I2C_MULTI_BUS |
34 | #define MAX_I2C_BUS 2 | |
35 | #define I2C_MULTI_BUS 1 | |
79b2d0bb | 36 | #else |
cd7b4e82 MV |
37 | #define MAX_I2C_BUS 1 |
38 | #define I2C_MULTI_BUS 0 | |
39 | #endif | |
40 | ||
41 | #if !defined(CONFIG_SYS_MAX_I2C_BUS) | |
42 | #define CONFIG_SYS_MAX_I2C_BUS MAX_I2C_BUS | |
79b2d0bb SR |
43 | #endif |
44 | ||
8c12045a | 45 | /* define the I2C bus number for RTC and DTT if not already done */ |
6d0f6bcf JCPV |
46 | #if !defined(CONFIG_SYS_RTC_BUS_NUM) |
47 | #define CONFIG_SYS_RTC_BUS_NUM 0 | |
8c12045a | 48 | #endif |
6d0f6bcf JCPV |
49 | #if !defined(CONFIG_SYS_DTT_BUS_NUM) |
50 | #define CONFIG_SYS_DTT_BUS_NUM 0 | |
8c12045a | 51 | #endif |
6d0f6bcf JCPV |
52 | #if !defined(CONFIG_SYS_SPD_BUS_NUM) |
53 | #define CONFIG_SYS_SPD_BUS_NUM 0 | |
d8a8ea5c | 54 | #endif |
8c12045a | 55 | |
98aed379 HS |
56 | #ifndef I2C_SOFT_DECLARATIONS |
57 | # if defined(CONFIG_MPC8260) | |
6d0f6bcf | 58 | # define I2C_SOFT_DECLARATIONS volatile ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, I2C_PORT); |
98aed379 | 59 | # elif defined(CONFIG_8xx) |
6d0f6bcf | 60 | # define I2C_SOFT_DECLARATIONS volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; |
0cf0b931 JS |
61 | |
62 | # elif (defined(CONFIG_AT91RM9200) || \ | |
63 | defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9261) || \ | |
64 | defined(CONFIG_AT91SAM9263)) && !defined(CONFIG_AT91_LEGACY) | |
78132275 | 65 | # define I2C_SOFT_DECLARATIONS at91_pio_t *pio = (at91_pio_t *) ATMEL_BASE_PIOA; |
98aed379 HS |
66 | # else |
67 | # define I2C_SOFT_DECLARATIONS | |
68 | # endif | |
69 | #endif | |
ecf5f077 TT |
70 | |
71 | #ifdef CONFIG_8xx | |
9c90a2c8 | 72 | /* Set default value for the I2C bus speed on 8xx. In the |
ecf5f077 TT |
73 | * future, we'll define these in all 8xx board config files. |
74 | */ | |
75 | #ifndef CONFIG_SYS_I2C_SPEED | |
76 | #define CONFIG_SYS_I2C_SPEED 50000 | |
77 | #endif | |
9c90a2c8 | 78 | #endif |
ecf5f077 | 79 | |
9c90a2c8 PT |
80 | /* |
81 | * Many boards/controllers/drivers don't support an I2C slave interface so | |
82 | * provide a default slave address for them for use in common code. A real | |
83 | * value for CONFIG_SYS_I2C_SLAVE should be defined for any board which does | |
84 | * support a slave interface. | |
85 | */ | |
ecf5f077 | 86 | #ifndef CONFIG_SYS_I2C_SLAVE |
9c90a2c8 | 87 | #define CONFIG_SYS_I2C_SLAVE 0xfe |
ecf5f077 TT |
88 | #endif |
89 | ||
1f045217 WD |
90 | /* |
91 | * Initialization, must be called once on start up, may be called | |
92 | * repeatedly to change the speed and slave addresses. | |
93 | */ | |
94 | void i2c_init(int speed, int slaveaddr); | |
06d01dbe | 95 | void i2c_init_board(void); |
26a33504 RR |
96 | #ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT |
97 | void i2c_board_late_init(void); | |
98 | #endif | |
1f045217 | 99 | |
67b23a32 HS |
100 | #if defined(CONFIG_I2C_MUX) |
101 | ||
102 | typedef struct _mux { | |
103 | uchar chip; | |
104 | uchar channel; | |
105 | char *name; | |
106 | struct _mux *next; | |
107 | } I2C_MUX; | |
108 | ||
109 | typedef struct _mux_device { | |
110 | int busid; | |
111 | I2C_MUX *mux; /* List of muxes, to reach the device */ | |
112 | struct _mux_device *next; | |
113 | } I2C_MUX_DEVICE; | |
114 | ||
67b23a32 HS |
115 | I2C_MUX_DEVICE *i2c_mux_search_device(int id); |
116 | I2C_MUX_DEVICE *i2c_mux_ident_muxstring (uchar *buf); | |
117 | int i2x_mux_select_mux(int bus); | |
118 | int i2c_mux_ident_muxstring_f (uchar *buf); | |
119 | #endif | |
120 | ||
1f045217 WD |
121 | /* |
122 | * Probe the given I2C chip address. Returns 0 if a chip responded, | |
123 | * not 0 on failure. | |
124 | */ | |
125 | int i2c_probe(uchar chip); | |
126 | ||
127 | /* | |
128 | * Read/Write interface: | |
129 | * chip: I2C chip address, range 0..127 | |
130 | * addr: Memory (register) address within the chip | |
131 | * alen: Number of bytes to use for addr (typically 1, 2 for larger | |
132 | * memories, 0 for register type devices with only one | |
133 | * register) | |
134 | * buffer: Where to read/write the data | |
135 | * len: How many bytes to read/write | |
136 | * | |
137 | * Returns: 0 on success, not 0 on failure | |
138 | */ | |
139 | int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len); | |
140 | int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len); | |
141 | ||
142 | /* | |
143 | * Utility routines to read/write registers. | |
144 | */ | |
ecf5f077 TT |
145 | static inline u8 i2c_reg_read(u8 addr, u8 reg) |
146 | { | |
147 | u8 buf; | |
148 | ||
149 | #ifdef CONFIG_8xx | |
150 | /* MPC8xx needs this. Maybe one day we can get rid of it. */ | |
151 | i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); | |
152 | #endif | |
153 | ||
154 | #ifdef DEBUG | |
155 | printf("%s: addr=0x%02x, reg=0x%02x\n", __func__, addr, reg); | |
156 | #endif | |
157 | ||
ecf5f077 | 158 | i2c_read(addr, reg, 1, &buf, 1); |
ecf5f077 TT |
159 | |
160 | return buf; | |
161 | } | |
162 | ||
163 | static inline void i2c_reg_write(u8 addr, u8 reg, u8 val) | |
164 | { | |
165 | #ifdef CONFIG_8xx | |
166 | /* MPC8xx needs this. Maybe one day we can get rid of it. */ | |
167 | i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); | |
168 | #endif | |
169 | ||
170 | #ifdef DEBUG | |
171 | printf("%s: addr=0x%02x, reg=0x%02x, val=0x%02x\n", | |
172 | __func__, addr, reg, val); | |
173 | #endif | |
174 | ||
ecf5f077 | 175 | i2c_write(addr, reg, 1, &val, 1); |
ecf5f077 | 176 | } |
1f045217 | 177 | |
bb99ad6d BW |
178 | /* |
179 | * Functions for setting the current I2C bus and its speed | |
180 | */ | |
181 | ||
182 | /* | |
183 | * i2c_set_bus_num: | |
184 | * | |
185 | * Change the active I2C bus. Subsequent read/write calls will | |
186 | * go to this one. | |
187 | * | |
53677ef1 | 188 | * bus - bus index, zero based |
bb99ad6d | 189 | * |
53677ef1 | 190 | * Returns: 0 on success, not 0 on failure |
bb99ad6d BW |
191 | * |
192 | */ | |
9ca880a2 | 193 | int i2c_set_bus_num(unsigned int bus); |
bb99ad6d BW |
194 | |
195 | /* | |
196 | * i2c_get_bus_num: | |
197 | * | |
198 | * Returns index of currently active I2C bus. Zero-based. | |
199 | */ | |
200 | ||
9ca880a2 | 201 | unsigned int i2c_get_bus_num(void); |
bb99ad6d BW |
202 | |
203 | /* | |
204 | * i2c_set_bus_speed: | |
205 | * | |
206 | * Change the speed of the active I2C bus | |
207 | * | |
53677ef1 | 208 | * speed - bus speed in Hz |
bb99ad6d | 209 | * |
53677ef1 | 210 | * Returns: 0 on success, not 0 on failure |
bb99ad6d BW |
211 | * |
212 | */ | |
9ca880a2 | 213 | int i2c_set_bus_speed(unsigned int); |
bb99ad6d BW |
214 | |
215 | /* | |
216 | * i2c_get_bus_speed: | |
217 | * | |
218 | * Returns speed of currently active I2C bus in Hz | |
219 | */ | |
220 | ||
9ca880a2 | 221 | unsigned int i2c_get_bus_speed(void); |
bb99ad6d | 222 | |
cd7b4e82 MV |
223 | /* NOTE: These two functions MUST be always_inline to avoid code growth! */ |
224 | static inline unsigned int I2C_GET_BUS(void) __attribute__((always_inline)); | |
225 | static inline unsigned int I2C_GET_BUS(void) | |
226 | { | |
227 | return I2C_MULTI_BUS ? i2c_get_bus_num() : 0; | |
228 | } | |
229 | ||
230 | static inline void I2C_SET_BUS(unsigned int bus) __attribute__((always_inline)); | |
231 | static inline void I2C_SET_BUS(unsigned int bus) | |
232 | { | |
233 | if (I2C_MULTI_BUS) | |
234 | i2c_set_bus_num(bus); | |
235 | } | |
236 | ||
7ca8f73a ŁM |
237 | /* Multi I2C definitions */ |
238 | enum { | |
239 | I2C_0, I2C_1, I2C_2, I2C_3, I2C_4, I2C_5, I2C_6, I2C_7, | |
240 | I2C_8, I2C_9, I2C_10, | |
241 | }; | |
242 | ||
243 | /* Multi I2C busses handling */ | |
244 | #ifdef CONFIG_SOFT_I2C_MULTI_BUS | |
245 | extern int get_multi_scl_pin(void); | |
246 | extern int get_multi_sda_pin(void); | |
247 | extern int multi_i2c_init(void); | |
248 | #endif | |
a9d2ae70 RS |
249 | |
250 | /** | |
251 | * Get FDT values for i2c bus. | |
252 | * | |
253 | * @param blob Device tree blbo | |
254 | * @return the number of I2C bus | |
255 | */ | |
256 | void board_i2c_init(const void *blob); | |
257 | ||
258 | /** | |
259 | * Find the I2C bus number by given a FDT I2C node. | |
260 | * | |
261 | * @param blob Device tree blbo | |
262 | * @param node FDT I2C node to find | |
263 | * @return the number of I2C bus (zero based), or -1 on error | |
264 | */ | |
265 | int i2c_get_bus_num_fdt(int node); | |
266 | ||
267 | /** | |
268 | * Reset the I2C bus represented by the given a FDT I2C node. | |
269 | * | |
270 | * @param blob Device tree blbo | |
271 | * @param node FDT I2C node to find | |
272 | * @return 0 if port was reset, -1 if not found | |
273 | */ | |
274 | int i2c_reset_port_fdt(const void *blob, int node); | |
1f045217 | 275 | #endif /* _I2C_H_ */ |