Commit 3f8550c5e93c65433d51c711e5d8d58fa5dfde7d
Exists in
master
and in
54 other branches
Merge branch 'master' of /home/wd/git/u-boot/custodians
* 'master' of /home/wd/git/u-boot/custodians: i2c:designware Turn off the ctrl when setting the speed i2c: Add support for designware i2c controller sh: i2c: Add support I2C controller of SH7734
Showing 7 changed files Side-by-side Diff
arch/arm/include/asm/arch-spear/spr_i2c.h
1 | -/* | |
2 | - * (C) Copyright 2009 | |
3 | - * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. | |
4 | - * | |
5 | - * See file CREDITS for list of people who contributed to this | |
6 | - * project. | |
7 | - * | |
8 | - * This program is free software; you can redistribute it and/or | |
9 | - * modify it under the terms of the GNU General Public License as | |
10 | - * published by the Free Software Foundation; either version 2 of | |
11 | - * the License, or (at your option) any later version. | |
12 | - * | |
13 | - * This program is distributed in the hope that it will be useful, | |
14 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | - * GNU General Public License for more details. | |
17 | - * | |
18 | - * You should have received a copy of the GNU General Public License | |
19 | - * along with this program; if not, write to the Free Software | |
20 | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | - * MA 02111-1307 USA | |
22 | - */ | |
23 | - | |
24 | -#ifndef __SPR_I2C_H_ | |
25 | -#define __SPR_I2C_H_ | |
26 | - | |
27 | -struct i2c_regs { | |
28 | - u32 ic_con; | |
29 | - u32 ic_tar; | |
30 | - u32 ic_sar; | |
31 | - u32 ic_hs_maddr; | |
32 | - u32 ic_cmd_data; | |
33 | - u32 ic_ss_scl_hcnt; | |
34 | - u32 ic_ss_scl_lcnt; | |
35 | - u32 ic_fs_scl_hcnt; | |
36 | - u32 ic_fs_scl_lcnt; | |
37 | - u32 ic_hs_scl_hcnt; | |
38 | - u32 ic_hs_scl_lcnt; | |
39 | - u32 ic_intr_stat; | |
40 | - u32 ic_intr_mask; | |
41 | - u32 ic_raw_intr_stat; | |
42 | - u32 ic_rx_tl; | |
43 | - u32 ic_tx_tl; | |
44 | - u32 ic_clr_intr; | |
45 | - u32 ic_clr_rx_under; | |
46 | - u32 ic_clr_rx_over; | |
47 | - u32 ic_clr_tx_over; | |
48 | - u32 ic_clr_rd_req; | |
49 | - u32 ic_clr_tx_abrt; | |
50 | - u32 ic_clr_rx_done; | |
51 | - u32 ic_clr_activity; | |
52 | - u32 ic_clr_stop_det; | |
53 | - u32 ic_clr_start_det; | |
54 | - u32 ic_clr_gen_call; | |
55 | - u32 ic_enable; | |
56 | - u32 ic_status; | |
57 | - u32 ic_txflr; | |
58 | - u32 ix_rxflr; | |
59 | - u32 reserved_1; | |
60 | - u32 ic_tx_abrt_source; | |
61 | -}; | |
62 | - | |
63 | -#define IC_CLK 166 | |
64 | -#define NANO_TO_MICRO 1000 | |
65 | - | |
66 | -/* High and low times in different speed modes (in ns) */ | |
67 | -#define MIN_SS_SCL_HIGHTIME 4000 | |
68 | -#define MIN_SS_SCL_LOWTIME 5000 | |
69 | -#define MIN_FS_SCL_HIGHTIME 800 | |
70 | -#define MIN_FS_SCL_LOWTIME 1700 | |
71 | -#define MIN_HS_SCL_HIGHTIME 60 | |
72 | -#define MIN_HS_SCL_LOWTIME 160 | |
73 | - | |
74 | -/* Worst case timeout for 1 byte is kept as 2ms */ | |
75 | -#define I2C_BYTE_TO (CONFIG_SYS_HZ/500) | |
76 | -#define I2C_STOPDET_TO (CONFIG_SYS_HZ/500) | |
77 | -#define I2C_BYTE_TO_BB (I2C_BYTE_TO * 16) | |
78 | - | |
79 | -/* i2c control register definitions */ | |
80 | -#define IC_CON_SD 0x0040 | |
81 | -#define IC_CON_RE 0x0020 | |
82 | -#define IC_CON_10BITADDRMASTER 0x0010 | |
83 | -#define IC_CON_10BITADDR_SLAVE 0x0008 | |
84 | -#define IC_CON_SPD_MSK 0x0006 | |
85 | -#define IC_CON_SPD_SS 0x0002 | |
86 | -#define IC_CON_SPD_FS 0x0004 | |
87 | -#define IC_CON_SPD_HS 0x0006 | |
88 | -#define IC_CON_MM 0x0001 | |
89 | - | |
90 | -/* i2c target address register definitions */ | |
91 | -#define TAR_ADDR 0x0050 | |
92 | - | |
93 | -/* i2c slave address register definitions */ | |
94 | -#define IC_SLAVE_ADDR 0x0002 | |
95 | - | |
96 | -/* i2c data buffer and command register definitions */ | |
97 | -#define IC_CMD 0x0100 | |
98 | - | |
99 | -/* i2c interrupt status register definitions */ | |
100 | -#define IC_GEN_CALL 0x0800 | |
101 | -#define IC_START_DET 0x0400 | |
102 | -#define IC_STOP_DET 0x0200 | |
103 | -#define IC_ACTIVITY 0x0100 | |
104 | -#define IC_RX_DONE 0x0080 | |
105 | -#define IC_TX_ABRT 0x0040 | |
106 | -#define IC_RD_REQ 0x0020 | |
107 | -#define IC_TX_EMPTY 0x0010 | |
108 | -#define IC_TX_OVER 0x0008 | |
109 | -#define IC_RX_FULL 0x0004 | |
110 | -#define IC_RX_OVER 0x0002 | |
111 | -#define IC_RX_UNDER 0x0001 | |
112 | - | |
113 | -/* fifo threshold register definitions */ | |
114 | -#define IC_TL0 0x00 | |
115 | -#define IC_TL1 0x01 | |
116 | -#define IC_TL2 0x02 | |
117 | -#define IC_TL3 0x03 | |
118 | -#define IC_TL4 0x04 | |
119 | -#define IC_TL5 0x05 | |
120 | -#define IC_TL6 0x06 | |
121 | -#define IC_TL7 0x07 | |
122 | -#define IC_RX_TL IC_TL0 | |
123 | -#define IC_TX_TL IC_TL0 | |
124 | - | |
125 | -/* i2c enable register definitions */ | |
126 | -#define IC_ENABLE_0B 0x0001 | |
127 | - | |
128 | -/* i2c status register definitions */ | |
129 | -#define IC_STATUS_SA 0x0040 | |
130 | -#define IC_STATUS_MA 0x0020 | |
131 | -#define IC_STATUS_RFF 0x0010 | |
132 | -#define IC_STATUS_RFNE 0x0008 | |
133 | -#define IC_STATUS_TFE 0x0004 | |
134 | -#define IC_STATUS_TFNF 0x0002 | |
135 | -#define IC_STATUS_ACT 0x0001 | |
136 | - | |
137 | -/* Speed Selection */ | |
138 | -#define IC_SPEED_MODE_STANDARD 1 | |
139 | -#define IC_SPEED_MODE_FAST 2 | |
140 | -#define IC_SPEED_MODE_MAX 3 | |
141 | - | |
142 | -#define I2C_MAX_SPEED 3400000 | |
143 | -#define I2C_FAST_SPEED 400000 | |
144 | -#define I2C_STANDARD_SPEED 100000 | |
145 | - | |
146 | -#endif /* __SPR_I2C_H_ */ |
drivers/i2c/Makefile
... | ... | @@ -27,6 +27,7 @@ |
27 | 27 | |
28 | 28 | COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o |
29 | 29 | COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o |
30 | +COBJS-$(CONFIG_DW_I2C) += designware_i2c.o | |
30 | 31 | COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o |
31 | 32 | COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o |
32 | 33 | COBJS-$(CONFIG_I2C_MV) += mv_i2c.o |
33 | 34 | |
... | ... | @@ -40,11 +41,11 @@ |
40 | 41 | COBJS-$(CONFIG_DRIVER_S3C24X0_I2C) += s3c24x0_i2c.o |
41 | 42 | COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o |
42 | 43 | COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o |
43 | -COBJS-$(CONFIG_SPEAR_I2C) += spr_i2c.o | |
44 | 44 | COBJS-$(CONFIG_TEGRA_I2C) += tegra_i2c.o |
45 | 45 | COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o |
46 | 46 | COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o |
47 | 47 | COBJS-$(CONFIG_SH_I2C) += sh_i2c.o |
48 | +COBJS-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o | |
48 | 49 | |
49 | 50 | COBJS := $(COBJS-y) |
50 | 51 | SRCS := $(COBJS:.o=.c) |
drivers/i2c/designware_i2c.c
1 | +/* | |
2 | + * (C) Copyright 2009 | |
3 | + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. | |
4 | + * | |
5 | + * See file CREDITS for list of people who contributed to this | |
6 | + * project. | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or | |
9 | + * modify it under the terms of the GNU General Public License as | |
10 | + * published by the Free Software Foundation; either version 2 of | |
11 | + * the License, or (at your option) any later version. | |
12 | + * | |
13 | + * This program is distributed in the hope that it will be useful, | |
14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | + * GNU General Public License for more details. | |
17 | + * | |
18 | + * You should have received a copy of the GNU General Public License | |
19 | + * along with this program; if not, write to the Free Software | |
20 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | + * MA 02111-1307 USA | |
22 | + */ | |
23 | + | |
24 | +#include <common.h> | |
25 | +#include <asm/io.h> | |
26 | +#include <asm/arch/hardware.h> | |
27 | +#include "designware_i2c.h" | |
28 | + | |
29 | +static struct i2c_regs *const i2c_regs_p = | |
30 | + (struct i2c_regs *)CONFIG_SYS_I2C_BASE; | |
31 | + | |
32 | +/* | |
33 | + * set_speed - Set the i2c speed mode (standard, high, fast) | |
34 | + * @i2c_spd: required i2c speed mode | |
35 | + * | |
36 | + * Set the i2c speed mode (standard, high, fast) | |
37 | + */ | |
38 | +static void set_speed(int i2c_spd) | |
39 | +{ | |
40 | + unsigned int cntl; | |
41 | + unsigned int hcnt, lcnt; | |
42 | + unsigned int high, low; | |
43 | + unsigned int enbl; | |
44 | + | |
45 | + /* to set speed cltr must be disabled */ | |
46 | + enbl = readl(&i2c_regs_p->ic_enable); | |
47 | + enbl &= ~IC_ENABLE_0B; | |
48 | + writel(enbl, &i2c_regs_p->ic_enable); | |
49 | + | |
50 | + | |
51 | + cntl = (readl(&i2c_regs_p->ic_con) & (~IC_CON_SPD_MSK)); | |
52 | + | |
53 | + switch (i2c_spd) { | |
54 | + case IC_SPEED_MODE_MAX: | |
55 | + cntl |= IC_CON_SPD_HS; | |
56 | + high = MIN_HS_SCL_HIGHTIME; | |
57 | + low = MIN_HS_SCL_LOWTIME; | |
58 | + break; | |
59 | + | |
60 | + case IC_SPEED_MODE_STANDARD: | |
61 | + cntl |= IC_CON_SPD_SS; | |
62 | + high = MIN_SS_SCL_HIGHTIME; | |
63 | + low = MIN_SS_SCL_LOWTIME; | |
64 | + break; | |
65 | + | |
66 | + case IC_SPEED_MODE_FAST: | |
67 | + default: | |
68 | + cntl |= IC_CON_SPD_FS; | |
69 | + high = MIN_FS_SCL_HIGHTIME; | |
70 | + low = MIN_FS_SCL_LOWTIME; | |
71 | + break; | |
72 | + } | |
73 | + | |
74 | + writel(cntl, &i2c_regs_p->ic_con); | |
75 | + | |
76 | + hcnt = (IC_CLK * high) / NANO_TO_MICRO; | |
77 | + writel(hcnt, &i2c_regs_p->ic_fs_scl_hcnt); | |
78 | + | |
79 | + lcnt = (IC_CLK * low) / NANO_TO_MICRO; | |
80 | + writel(lcnt, &i2c_regs_p->ic_fs_scl_lcnt); | |
81 | + | |
82 | + /* re-enable i2c ctrl back now that speed is set */ | |
83 | + enbl |= IC_ENABLE_0B; | |
84 | + writel(enbl, &i2c_regs_p->ic_enable); | |
85 | +} | |
86 | + | |
87 | +/* | |
88 | + * i2c_set_bus_speed - Set the i2c speed | |
89 | + * @speed: required i2c speed | |
90 | + * | |
91 | + * Set the i2c speed. | |
92 | + */ | |
93 | +void i2c_set_bus_speed(int speed) | |
94 | +{ | |
95 | + if (speed >= I2C_MAX_SPEED) | |
96 | + set_speed(IC_SPEED_MODE_MAX); | |
97 | + else if (speed >= I2C_FAST_SPEED) | |
98 | + set_speed(IC_SPEED_MODE_FAST); | |
99 | + else | |
100 | + set_speed(IC_SPEED_MODE_STANDARD); | |
101 | +} | |
102 | + | |
103 | +/* | |
104 | + * i2c_get_bus_speed - Gets the i2c speed | |
105 | + * | |
106 | + * Gets the i2c speed. | |
107 | + */ | |
108 | +int i2c_get_bus_speed(void) | |
109 | +{ | |
110 | + u32 cntl; | |
111 | + | |
112 | + cntl = (readl(&i2c_regs_p->ic_con) & IC_CON_SPD_MSK); | |
113 | + | |
114 | + if (cntl == IC_CON_SPD_HS) | |
115 | + return I2C_MAX_SPEED; | |
116 | + else if (cntl == IC_CON_SPD_FS) | |
117 | + return I2C_FAST_SPEED; | |
118 | + else if (cntl == IC_CON_SPD_SS) | |
119 | + return I2C_STANDARD_SPEED; | |
120 | + | |
121 | + return 0; | |
122 | +} | |
123 | + | |
124 | +/* | |
125 | + * i2c_init - Init function | |
126 | + * @speed: required i2c speed | |
127 | + * @slaveadd: slave address for the device | |
128 | + * | |
129 | + * Initialization function. | |
130 | + */ | |
131 | +void i2c_init(int speed, int slaveadd) | |
132 | +{ | |
133 | + unsigned int enbl; | |
134 | + | |
135 | + /* Disable i2c */ | |
136 | + enbl = readl(&i2c_regs_p->ic_enable); | |
137 | + enbl &= ~IC_ENABLE_0B; | |
138 | + writel(enbl, &i2c_regs_p->ic_enable); | |
139 | + | |
140 | + writel((IC_CON_SD | IC_CON_SPD_FS | IC_CON_MM), &i2c_regs_p->ic_con); | |
141 | + writel(IC_RX_TL, &i2c_regs_p->ic_rx_tl); | |
142 | + writel(IC_TX_TL, &i2c_regs_p->ic_tx_tl); | |
143 | + i2c_set_bus_speed(speed); | |
144 | + writel(IC_STOP_DET, &i2c_regs_p->ic_intr_mask); | |
145 | + writel(slaveadd, &i2c_regs_p->ic_sar); | |
146 | + | |
147 | + /* Enable i2c */ | |
148 | + enbl = readl(&i2c_regs_p->ic_enable); | |
149 | + enbl |= IC_ENABLE_0B; | |
150 | + writel(enbl, &i2c_regs_p->ic_enable); | |
151 | +} | |
152 | + | |
153 | +/* | |
154 | + * i2c_setaddress - Sets the target slave address | |
155 | + * @i2c_addr: target i2c address | |
156 | + * | |
157 | + * Sets the target slave address. | |
158 | + */ | |
159 | +static void i2c_setaddress(unsigned int i2c_addr) | |
160 | +{ | |
161 | + writel(i2c_addr, &i2c_regs_p->ic_tar); | |
162 | +} | |
163 | + | |
164 | +/* | |
165 | + * i2c_flush_rxfifo - Flushes the i2c RX FIFO | |
166 | + * | |
167 | + * Flushes the i2c RX FIFO | |
168 | + */ | |
169 | +static void i2c_flush_rxfifo(void) | |
170 | +{ | |
171 | + while (readl(&i2c_regs_p->ic_status) & IC_STATUS_RFNE) | |
172 | + readl(&i2c_regs_p->ic_cmd_data); | |
173 | +} | |
174 | + | |
175 | +/* | |
176 | + * i2c_wait_for_bb - Waits for bus busy | |
177 | + * | |
178 | + * Waits for bus busy | |
179 | + */ | |
180 | +static int i2c_wait_for_bb(void) | |
181 | +{ | |
182 | + unsigned long start_time_bb = get_timer(0); | |
183 | + | |
184 | + while ((readl(&i2c_regs_p->ic_status) & IC_STATUS_MA) || | |
185 | + !(readl(&i2c_regs_p->ic_status) & IC_STATUS_TFE)) { | |
186 | + | |
187 | + /* Evaluate timeout */ | |
188 | + if (get_timer(start_time_bb) > (unsigned long)(I2C_BYTE_TO_BB)) | |
189 | + return 1; | |
190 | + } | |
191 | + | |
192 | + return 0; | |
193 | +} | |
194 | + | |
195 | +/* check parameters for i2c_read and i2c_write */ | |
196 | +static int check_params(uint addr, int alen, uchar *buffer, int len) | |
197 | +{ | |
198 | + if (buffer == NULL) { | |
199 | + printf("Buffer is invalid\n"); | |
200 | + return 1; | |
201 | + } | |
202 | + | |
203 | + if (alen > 1) { | |
204 | + printf("addr len %d not supported\n", alen); | |
205 | + return 1; | |
206 | + } | |
207 | + | |
208 | + if (addr + len > 256) { | |
209 | + printf("address out of range\n"); | |
210 | + return 1; | |
211 | + } | |
212 | + | |
213 | + return 0; | |
214 | +} | |
215 | + | |
216 | +static int i2c_xfer_init(uchar chip, uint addr) | |
217 | +{ | |
218 | + if (i2c_wait_for_bb()) { | |
219 | + printf("Timed out waiting for bus\n"); | |
220 | + return 1; | |
221 | + } | |
222 | + | |
223 | + i2c_setaddress(chip); | |
224 | + writel(addr, &i2c_regs_p->ic_cmd_data); | |
225 | + | |
226 | + return 0; | |
227 | +} | |
228 | + | |
229 | +static int i2c_xfer_finish(void) | |
230 | +{ | |
231 | + ulong start_stop_det = get_timer(0); | |
232 | + | |
233 | + while (1) { | |
234 | + if ((readl(&i2c_regs_p->ic_raw_intr_stat) & IC_STOP_DET)) { | |
235 | + readl(&i2c_regs_p->ic_clr_stop_det); | |
236 | + break; | |
237 | + } else if (get_timer(start_stop_det) > I2C_STOPDET_TO) { | |
238 | + break; | |
239 | + } | |
240 | + } | |
241 | + | |
242 | + if (i2c_wait_for_bb()) { | |
243 | + printf("Timed out waiting for bus\n"); | |
244 | + return 1; | |
245 | + } | |
246 | + | |
247 | + i2c_flush_rxfifo(); | |
248 | + | |
249 | + /* Wait for read/write operation to complete on actual memory */ | |
250 | + udelay(10000); | |
251 | + | |
252 | + return 0; | |
253 | +} | |
254 | + | |
255 | +/* | |
256 | + * i2c_read - Read from i2c memory | |
257 | + * @chip: target i2c address | |
258 | + * @addr: address to read from | |
259 | + * @alen: | |
260 | + * @buffer: buffer for read data | |
261 | + * @len: no of bytes to be read | |
262 | + * | |
263 | + * Read from i2c memory. | |
264 | + */ | |
265 | +int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) | |
266 | +{ | |
267 | + unsigned long start_time_rx; | |
268 | + | |
269 | + if (check_params(addr, alen, buffer, len)) | |
270 | + return 1; | |
271 | + | |
272 | + if (i2c_xfer_init(chip, addr)) | |
273 | + return 1; | |
274 | + | |
275 | + start_time_rx = get_timer(0); | |
276 | + while (len) { | |
277 | + writel(IC_CMD, &i2c_regs_p->ic_cmd_data); | |
278 | + | |
279 | + if (readl(&i2c_regs_p->ic_status) & IC_STATUS_RFNE) { | |
280 | + *buffer++ = (uchar)readl(&i2c_regs_p->ic_cmd_data); | |
281 | + len--; | |
282 | + start_time_rx = get_timer(0); | |
283 | + | |
284 | + } else if (get_timer(start_time_rx) > I2C_BYTE_TO) { | |
285 | + printf("Timed out. i2c read Failed\n"); | |
286 | + return 1; | |
287 | + } | |
288 | + } | |
289 | + | |
290 | + return i2c_xfer_finish(); | |
291 | +} | |
292 | + | |
293 | +/* | |
294 | + * i2c_write - Write to i2c memory | |
295 | + * @chip: target i2c address | |
296 | + * @addr: address to read from | |
297 | + * @alen: | |
298 | + * @buffer: buffer for read data | |
299 | + * @len: no of bytes to be read | |
300 | + * | |
301 | + * Write to i2c memory. | |
302 | + */ | |
303 | +int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) | |
304 | +{ | |
305 | + int nb = len; | |
306 | + unsigned long start_time_tx; | |
307 | + | |
308 | + if (check_params(addr, alen, buffer, len)) | |
309 | + return 1; | |
310 | + | |
311 | + if (i2c_xfer_init(chip, addr)) | |
312 | + return 1; | |
313 | + | |
314 | + start_time_tx = get_timer(0); | |
315 | + while (len) { | |
316 | + if (readl(&i2c_regs_p->ic_status) & IC_STATUS_TFNF) { | |
317 | + writel(*buffer, &i2c_regs_p->ic_cmd_data); | |
318 | + buffer++; | |
319 | + len--; | |
320 | + start_time_tx = get_timer(0); | |
321 | + | |
322 | + } else if (get_timer(start_time_tx) > (nb * I2C_BYTE_TO)) { | |
323 | + printf("Timed out. i2c write Failed\n"); | |
324 | + return 1; | |
325 | + } | |
326 | + } | |
327 | + | |
328 | + return i2c_xfer_finish(); | |
329 | +} | |
330 | + | |
331 | +/* | |
332 | + * i2c_probe - Probe the i2c chip | |
333 | + */ | |
334 | +int i2c_probe(uchar chip) | |
335 | +{ | |
336 | + u32 tmp; | |
337 | + | |
338 | + /* | |
339 | + * Try to read the first location of the chip. | |
340 | + */ | |
341 | + return i2c_read(chip, 0, 1, (uchar *)&tmp, 1); | |
342 | +} |
drivers/i2c/designware_i2c.h
1 | +/* | |
2 | + * (C) Copyright 2009 | |
3 | + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. | |
4 | + * | |
5 | + * See file CREDITS for list of people who contributed to this | |
6 | + * project. | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or | |
9 | + * modify it under the terms of the GNU General Public License as | |
10 | + * published by the Free Software Foundation; either version 2 of | |
11 | + * the License, or (at your option) any later version. | |
12 | + * | |
13 | + * This program is distributed in the hope that it will be useful, | |
14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | + * GNU General Public License for more details. | |
17 | + * | |
18 | + * You should have received a copy of the GNU General Public License | |
19 | + * along with this program; if not, write to the Free Software | |
20 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | + * MA 02111-1307 USA | |
22 | + */ | |
23 | + | |
24 | +#ifndef __DW_I2C_H_ | |
25 | +#define __DW_I2C_H_ | |
26 | + | |
27 | +struct i2c_regs { | |
28 | + u32 ic_con; | |
29 | + u32 ic_tar; | |
30 | + u32 ic_sar; | |
31 | + u32 ic_hs_maddr; | |
32 | + u32 ic_cmd_data; | |
33 | + u32 ic_ss_scl_hcnt; | |
34 | + u32 ic_ss_scl_lcnt; | |
35 | + u32 ic_fs_scl_hcnt; | |
36 | + u32 ic_fs_scl_lcnt; | |
37 | + u32 ic_hs_scl_hcnt; | |
38 | + u32 ic_hs_scl_lcnt; | |
39 | + u32 ic_intr_stat; | |
40 | + u32 ic_intr_mask; | |
41 | + u32 ic_raw_intr_stat; | |
42 | + u32 ic_rx_tl; | |
43 | + u32 ic_tx_tl; | |
44 | + u32 ic_clr_intr; | |
45 | + u32 ic_clr_rx_under; | |
46 | + u32 ic_clr_rx_over; | |
47 | + u32 ic_clr_tx_over; | |
48 | + u32 ic_clr_rd_req; | |
49 | + u32 ic_clr_tx_abrt; | |
50 | + u32 ic_clr_rx_done; | |
51 | + u32 ic_clr_activity; | |
52 | + u32 ic_clr_stop_det; | |
53 | + u32 ic_clr_start_det; | |
54 | + u32 ic_clr_gen_call; | |
55 | + u32 ic_enable; | |
56 | + u32 ic_status; | |
57 | + u32 ic_txflr; | |
58 | + u32 ix_rxflr; | |
59 | + u32 reserved_1; | |
60 | + u32 ic_tx_abrt_source; | |
61 | +}; | |
62 | + | |
63 | +#define IC_CLK 166 | |
64 | +#define NANO_TO_MICRO 1000 | |
65 | + | |
66 | +/* High and low times in different speed modes (in ns) */ | |
67 | +#define MIN_SS_SCL_HIGHTIME 4000 | |
68 | +#define MIN_SS_SCL_LOWTIME 5000 | |
69 | +#define MIN_FS_SCL_HIGHTIME 800 | |
70 | +#define MIN_FS_SCL_LOWTIME 1700 | |
71 | +#define MIN_HS_SCL_HIGHTIME 60 | |
72 | +#define MIN_HS_SCL_LOWTIME 160 | |
73 | + | |
74 | +/* Worst case timeout for 1 byte is kept as 2ms */ | |
75 | +#define I2C_BYTE_TO (CONFIG_SYS_HZ/500) | |
76 | +#define I2C_STOPDET_TO (CONFIG_SYS_HZ/500) | |
77 | +#define I2C_BYTE_TO_BB (I2C_BYTE_TO * 16) | |
78 | + | |
79 | +/* i2c control register definitions */ | |
80 | +#define IC_CON_SD 0x0040 | |
81 | +#define IC_CON_RE 0x0020 | |
82 | +#define IC_CON_10BITADDRMASTER 0x0010 | |
83 | +#define IC_CON_10BITADDR_SLAVE 0x0008 | |
84 | +#define IC_CON_SPD_MSK 0x0006 | |
85 | +#define IC_CON_SPD_SS 0x0002 | |
86 | +#define IC_CON_SPD_FS 0x0004 | |
87 | +#define IC_CON_SPD_HS 0x0006 | |
88 | +#define IC_CON_MM 0x0001 | |
89 | + | |
90 | +/* i2c target address register definitions */ | |
91 | +#define TAR_ADDR 0x0050 | |
92 | + | |
93 | +/* i2c slave address register definitions */ | |
94 | +#define IC_SLAVE_ADDR 0x0002 | |
95 | + | |
96 | +/* i2c data buffer and command register definitions */ | |
97 | +#define IC_CMD 0x0100 | |
98 | + | |
99 | +/* i2c interrupt status register definitions */ | |
100 | +#define IC_GEN_CALL 0x0800 | |
101 | +#define IC_START_DET 0x0400 | |
102 | +#define IC_STOP_DET 0x0200 | |
103 | +#define IC_ACTIVITY 0x0100 | |
104 | +#define IC_RX_DONE 0x0080 | |
105 | +#define IC_TX_ABRT 0x0040 | |
106 | +#define IC_RD_REQ 0x0020 | |
107 | +#define IC_TX_EMPTY 0x0010 | |
108 | +#define IC_TX_OVER 0x0008 | |
109 | +#define IC_RX_FULL 0x0004 | |
110 | +#define IC_RX_OVER 0x0002 | |
111 | +#define IC_RX_UNDER 0x0001 | |
112 | + | |
113 | +/* fifo threshold register definitions */ | |
114 | +#define IC_TL0 0x00 | |
115 | +#define IC_TL1 0x01 | |
116 | +#define IC_TL2 0x02 | |
117 | +#define IC_TL3 0x03 | |
118 | +#define IC_TL4 0x04 | |
119 | +#define IC_TL5 0x05 | |
120 | +#define IC_TL6 0x06 | |
121 | +#define IC_TL7 0x07 | |
122 | +#define IC_RX_TL IC_TL0 | |
123 | +#define IC_TX_TL IC_TL0 | |
124 | + | |
125 | +/* i2c enable register definitions */ | |
126 | +#define IC_ENABLE_0B 0x0001 | |
127 | + | |
128 | +/* i2c status register definitions */ | |
129 | +#define IC_STATUS_SA 0x0040 | |
130 | +#define IC_STATUS_MA 0x0020 | |
131 | +#define IC_STATUS_RFF 0x0010 | |
132 | +#define IC_STATUS_RFNE 0x0008 | |
133 | +#define IC_STATUS_TFE 0x0004 | |
134 | +#define IC_STATUS_TFNF 0x0002 | |
135 | +#define IC_STATUS_ACT 0x0001 | |
136 | + | |
137 | +/* Speed Selection */ | |
138 | +#define IC_SPEED_MODE_STANDARD 1 | |
139 | +#define IC_SPEED_MODE_FAST 2 | |
140 | +#define IC_SPEED_MODE_MAX 3 | |
141 | + | |
142 | +#define I2C_MAX_SPEED 3400000 | |
143 | +#define I2C_FAST_SPEED 400000 | |
144 | +#define I2C_STANDARD_SPEED 100000 | |
145 | + | |
146 | +#endif /* __DW_I2C_H_ */ |
drivers/i2c/sh_sh7734_i2c.c
1 | +/* | |
2 | + * Copyright (C) 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> | |
3 | + * Copyright (C) 2012 Renesas Solutions Corp. | |
4 | + * | |
5 | + * This program is free software; you can redistribute it and/or | |
6 | + * modify it under the terms of the GNU General Public License as | |
7 | + * published by the Free Software Foundation; either version 2 of | |
8 | + * the License, or (at your option) any later version. | |
9 | + * | |
10 | + * This program is distributed in the hope that it will be useful, | |
11 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | + * GNU General Public License for more details. | |
14 | + * | |
15 | + * You should have received a copy of the GNU General Public License | |
16 | + * along with this program; if not, write to the Free Software | |
17 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
18 | + * MA 02111-1307 USA | |
19 | + */ | |
20 | + | |
21 | +#include <common.h> | |
22 | +#include <i2c.h> | |
23 | +#include <asm/io.h> | |
24 | + | |
25 | +struct sh_i2c { | |
26 | + u8 iccr1; | |
27 | + u8 iccr2; | |
28 | + u8 icmr; | |
29 | + u8 icier; | |
30 | + u8 icsr; | |
31 | + u8 sar; | |
32 | + u8 icdrt; | |
33 | + u8 icdrr; | |
34 | + u8 nf2cyc; | |
35 | + u8 __pad0; | |
36 | + u8 __pad1; | |
37 | +}; | |
38 | + | |
39 | +static struct sh_i2c *base; | |
40 | +static u8 iccr1_cks, nf2cyc; | |
41 | + | |
42 | +/* ICCR1 */ | |
43 | +#define SH_I2C_ICCR1_ICE (1 << 7) | |
44 | +#define SH_I2C_ICCR1_RCVD (1 << 6) | |
45 | +#define SH_I2C_ICCR1_MST (1 << 5) | |
46 | +#define SH_I2C_ICCR1_TRS (1 << 4) | |
47 | +#define SH_I2C_ICCR1_MTRS \ | |
48 | + (SH_I2C_ICCR1_MST | SH_I2C_ICCR1_TRS) | |
49 | + | |
50 | +/* ICCR1 */ | |
51 | +#define SH_I2C_ICCR2_BBSY (1 << 7) | |
52 | +#define SH_I2C_ICCR2_SCP (1 << 6) | |
53 | +#define SH_I2C_ICCR2_SDAO (1 << 5) | |
54 | +#define SH_I2C_ICCR2_SDAOP (1 << 4) | |
55 | +#define SH_I2C_ICCR2_SCLO (1 << 3) | |
56 | +#define SH_I2C_ICCR2_IICRST (1 << 1) | |
57 | + | |
58 | +#define SH_I2C_ICIER_TIE (1 << 7) | |
59 | +#define SH_I2C_ICIER_TEIE (1 << 6) | |
60 | +#define SH_I2C_ICIER_RIE (1 << 5) | |
61 | +#define SH_I2C_ICIER_NAKIE (1 << 4) | |
62 | +#define SH_I2C_ICIER_STIE (1 << 3) | |
63 | +#define SH_I2C_ICIER_ACKE (1 << 2) | |
64 | +#define SH_I2C_ICIER_ACKBR (1 << 1) | |
65 | +#define SH_I2C_ICIER_ACKBT (1 << 0) | |
66 | + | |
67 | +#define SH_I2C_ICSR_TDRE (1 << 7) | |
68 | +#define SH_I2C_ICSR_TEND (1 << 6) | |
69 | +#define SH_I2C_ICSR_RDRF (1 << 5) | |
70 | +#define SH_I2C_ICSR_NACKF (1 << 4) | |
71 | +#define SH_I2C_ICSR_STOP (1 << 3) | |
72 | +#define SH_I2C_ICSR_ALOVE (1 << 2) | |
73 | +#define SH_I2C_ICSR_AAS (1 << 1) | |
74 | +#define SH_I2C_ICSR_ADZ (1 << 0) | |
75 | + | |
76 | +#define IRQ_WAIT 1000 | |
77 | + | |
78 | +static void sh_i2c_send_stop(struct sh_i2c *base) | |
79 | +{ | |
80 | + clrbits_8(&base->iccr2, SH_I2C_ICCR2_BBSY | SH_I2C_ICCR2_SCP); | |
81 | +} | |
82 | + | |
83 | +static int check_icsr_bits(struct sh_i2c *base, u8 bits) | |
84 | +{ | |
85 | + int i; | |
86 | + | |
87 | + for (i = 0; i < IRQ_WAIT; i++) { | |
88 | + if (bits & readb(&base->icsr)) | |
89 | + return 0; | |
90 | + udelay(10); | |
91 | + } | |
92 | + | |
93 | + return 1; | |
94 | +} | |
95 | + | |
96 | +static int check_stop(struct sh_i2c *base) | |
97 | +{ | |
98 | + int ret = check_icsr_bits(base, SH_I2C_ICSR_STOP); | |
99 | + clrbits_8(&base->icsr, SH_I2C_ICSR_STOP); | |
100 | + | |
101 | + return ret; | |
102 | +} | |
103 | + | |
104 | +static int check_tend(struct sh_i2c *base, int stop) | |
105 | +{ | |
106 | + int ret = check_icsr_bits(base, SH_I2C_ICSR_TEND); | |
107 | + | |
108 | + if (stop) { | |
109 | + clrbits_8(&base->icsr, SH_I2C_ICSR_STOP); | |
110 | + sh_i2c_send_stop(base); | |
111 | + } | |
112 | + | |
113 | + clrbits_8(&base->icsr, SH_I2C_ICSR_TEND); | |
114 | + return ret; | |
115 | +} | |
116 | + | |
117 | +static int check_tdre(struct sh_i2c *base) | |
118 | +{ | |
119 | + return check_icsr_bits(base, SH_I2C_ICSR_TDRE); | |
120 | +} | |
121 | + | |
122 | +static int check_rdrf(struct sh_i2c *base) | |
123 | +{ | |
124 | + return check_icsr_bits(base, SH_I2C_ICSR_RDRF); | |
125 | +} | |
126 | + | |
127 | +static int check_bbsy(struct sh_i2c *base) | |
128 | +{ | |
129 | + int i; | |
130 | + | |
131 | + for (i = 0 ; i < IRQ_WAIT ; i++) { | |
132 | + if (!(SH_I2C_ICCR2_BBSY & readb(&base->iccr2))) | |
133 | + return 0; | |
134 | + udelay(10); | |
135 | + } | |
136 | + return 1; | |
137 | +} | |
138 | + | |
139 | +static int check_ackbr(struct sh_i2c *base) | |
140 | +{ | |
141 | + int i; | |
142 | + | |
143 | + for (i = 0 ; i < IRQ_WAIT ; i++) { | |
144 | + if (!(SH_I2C_ICIER_ACKBR & readb(&base->icier))) | |
145 | + return 0; | |
146 | + udelay(10); | |
147 | + } | |
148 | + | |
149 | + return 1; | |
150 | +} | |
151 | + | |
152 | +static void sh_i2c_reset(struct sh_i2c *base) | |
153 | +{ | |
154 | + setbits_8(&base->iccr2, SH_I2C_ICCR2_IICRST); | |
155 | + | |
156 | + udelay(100); | |
157 | + | |
158 | + clrbits_8(&base->iccr2, SH_I2C_ICCR2_IICRST); | |
159 | +} | |
160 | + | |
161 | +static int i2c_set_addr(struct sh_i2c *base, u8 id, u8 reg) | |
162 | +{ | |
163 | + if (check_bbsy(base)) { | |
164 | + puts("i2c bus busy\n"); | |
165 | + goto fail; | |
166 | + } | |
167 | + | |
168 | + setbits_8(&base->iccr1, SH_I2C_ICCR1_MTRS); | |
169 | + clrsetbits_8(&base->iccr2, SH_I2C_ICCR2_SCP, SH_I2C_ICCR2_BBSY); | |
170 | + | |
171 | + writeb((id << 1), &base->icdrt); | |
172 | + | |
173 | + if (check_tend(base, 0)) { | |
174 | + puts("TEND check fail...\n"); | |
175 | + goto fail; | |
176 | + } | |
177 | + | |
178 | + if (check_ackbr(base)) { | |
179 | + check_tend(base, 0); | |
180 | + sh_i2c_send_stop(base); | |
181 | + goto fail; | |
182 | + } | |
183 | + | |
184 | + writeb(reg, &base->icdrt); | |
185 | + | |
186 | + if (check_tdre(base)) { | |
187 | + puts("TDRE check fail...\n"); | |
188 | + goto fail; | |
189 | + } | |
190 | + | |
191 | + if (check_tend(base, 0)) { | |
192 | + puts("TEND check fail...\n"); | |
193 | + goto fail; | |
194 | + } | |
195 | + | |
196 | + return 0; | |
197 | +fail: | |
198 | + | |
199 | + return 1; | |
200 | +} | |
201 | + | |
202 | +static int | |
203 | +i2c_raw_write(struct sh_i2c *base, u8 id, u8 reg, u8 *val, int size) | |
204 | +{ | |
205 | + int i; | |
206 | + | |
207 | + if (i2c_set_addr(base, id, reg)) { | |
208 | + puts("Fail set slave address\n"); | |
209 | + return 1; | |
210 | + } | |
211 | + | |
212 | + for (i = 0; i < size; i++) { | |
213 | + writeb(val[i], &base->icdrt); | |
214 | + check_tdre(base); | |
215 | + } | |
216 | + | |
217 | + check_tend(base, 1); | |
218 | + check_stop(base); | |
219 | + | |
220 | + udelay(100); | |
221 | + | |
222 | + clrbits_8(&base->iccr1, SH_I2C_ICCR1_MTRS); | |
223 | + clrbits_8(&base->icsr, SH_I2C_ICSR_TDRE); | |
224 | + sh_i2c_reset(base); | |
225 | + | |
226 | + return 0; | |
227 | +} | |
228 | + | |
229 | +static u8 i2c_raw_read(struct sh_i2c *base, u8 id, u8 reg) | |
230 | +{ | |
231 | + u8 ret = 0; | |
232 | + | |
233 | + if (i2c_set_addr(base, id, reg)) { | |
234 | + puts("Fail set slave address\n"); | |
235 | + goto fail; | |
236 | + } | |
237 | + | |
238 | + clrsetbits_8(&base->iccr2, SH_I2C_ICCR2_SCP, SH_I2C_ICCR2_BBSY); | |
239 | + writeb((id << 1) | 1, &base->icdrt); | |
240 | + | |
241 | + if (check_tend(base, 0)) | |
242 | + puts("TDRE check fail...\n"); | |
243 | + | |
244 | + clrsetbits_8(&base->iccr1, SH_I2C_ICCR1_TRS, SH_I2C_ICCR1_MST); | |
245 | + clrbits_8(&base->icsr, SH_I2C_ICSR_TDRE); | |
246 | + setbits_8(&base->icier, SH_I2C_ICIER_ACKBT); | |
247 | + setbits_8(&base->iccr1, SH_I2C_ICCR1_RCVD); | |
248 | + | |
249 | + /* read data (dummy) */ | |
250 | + ret = readb(&base->icdrr); | |
251 | + | |
252 | + if (check_rdrf(base)) { | |
253 | + puts("check RDRF error\n"); | |
254 | + goto fail; | |
255 | + } | |
256 | + | |
257 | + clrbits_8(&base->icsr, SH_I2C_ICSR_STOP); | |
258 | + udelay(1000); | |
259 | + | |
260 | + sh_i2c_send_stop(base); | |
261 | + | |
262 | + if (check_stop(base)) { | |
263 | + puts("check STOP error\n"); | |
264 | + goto fail; | |
265 | + } | |
266 | + | |
267 | + clrbits_8(&base->iccr1, SH_I2C_ICCR1_MTRS); | |
268 | + clrbits_8(&base->icsr, SH_I2C_ICSR_TDRE); | |
269 | + | |
270 | + /* data read */ | |
271 | + ret = readb(&base->icdrr); | |
272 | + | |
273 | +fail: | |
274 | + clrbits_8(&base->iccr1, SH_I2C_ICCR1_RCVD); | |
275 | + | |
276 | + return ret; | |
277 | +} | |
278 | + | |
279 | +#ifdef CONFIG_I2C_MULTI_BUS | |
280 | +static unsigned int current_bus; | |
281 | + | |
282 | +/** | |
283 | + * i2c_set_bus_num - change active I2C bus | |
284 | + * @bus: bus index, zero based | |
285 | + * @returns: 0 on success, non-0 on failure | |
286 | + */ | |
287 | +int i2c_set_bus_num(unsigned int bus) | |
288 | +{ | |
289 | + switch (bus) { | |
290 | + case 0: | |
291 | + base = (void *)CONFIG_SH_I2C_BASE0; | |
292 | + break; | |
293 | + case 1: | |
294 | + base = (void *)CONFIG_SH_I2C_BASE1; | |
295 | + break; | |
296 | + default: | |
297 | + printf("Bad bus: %d\n", bus); | |
298 | + return -1; | |
299 | + } | |
300 | + | |
301 | + current_bus = bus; | |
302 | + | |
303 | + return 0; | |
304 | +} | |
305 | + | |
306 | +/** | |
307 | + * i2c_get_bus_num - returns index of active I2C bus | |
308 | + */ | |
309 | +unsigned int i2c_get_bus_num(void) | |
310 | +{ | |
311 | + return current_bus; | |
312 | +} | |
313 | +#endif | |
314 | + | |
315 | +void i2c_init(int speed, int slaveaddr) | |
316 | +{ | |
317 | +#ifdef CONFIG_I2C_MULTI_BUS | |
318 | + current_bus = 0; | |
319 | +#endif | |
320 | + base = (struct sh_i2c *)CONFIG_SH_I2C_BASE0; | |
321 | + | |
322 | + if (speed == 400000) | |
323 | + iccr1_cks = 0x07; | |
324 | + else | |
325 | + iccr1_cks = 0x0F; | |
326 | + | |
327 | + nf2cyc = 1; | |
328 | + | |
329 | + /* Reset */ | |
330 | + sh_i2c_reset(base); | |
331 | + | |
332 | + /* ICE enable and set clock */ | |
333 | + writeb(SH_I2C_ICCR1_ICE | iccr1_cks, &base->iccr1); | |
334 | + writeb(nf2cyc, &base->nf2cyc); | |
335 | +} | |
336 | + | |
337 | +/* | |
338 | + * i2c_read: - Read multiple bytes from an i2c device | |
339 | + * | |
340 | + * The higher level routines take into account that this function is only | |
341 | + * called with len < page length of the device (see configuration file) | |
342 | + * | |
343 | + * @chip: address of the chip which is to be read | |
344 | + * @addr: i2c data address within the chip | |
345 | + * @alen: length of the i2c data address (1..2 bytes) | |
346 | + * @buffer: where to write the data | |
347 | + * @len: how much byte do we want to read | |
348 | + * @return: 0 in case of success | |
349 | + */ | |
350 | +int i2c_read(u8 chip, u32 addr, int alen, u8 *buffer, int len) | |
351 | +{ | |
352 | + int i = 0; | |
353 | + for (i = 0; i < len; i++) | |
354 | + buffer[i] = i2c_raw_read(base, chip, addr + i); | |
355 | + | |
356 | + return 0; | |
357 | +} | |
358 | + | |
359 | +/* | |
360 | + * i2c_write: - Write multiple bytes to an i2c device | |
361 | + * | |
362 | + * The higher level routines take into account that this function is only | |
363 | + * called with len < page length of the device (see configuration file) | |
364 | + * | |
365 | + * @chip: address of the chip which is to be written | |
366 | + * @addr: i2c data address within the chip | |
367 | + * @alen: length of the i2c data address (1..2 bytes) | |
368 | + * @buffer: where to find the data to be written | |
369 | + * @len: how much byte do we want to read | |
370 | + * @return: 0 in case of success | |
371 | + */ | |
372 | +int i2c_write(u8 chip, u32 addr, int alen, u8 *buffer, int len) | |
373 | +{ | |
374 | + return i2c_raw_write(base, chip, addr, buffer, len); | |
375 | +} | |
376 | + | |
377 | +/* | |
378 | + * i2c_probe: - Test if a chip answers for a given i2c address | |
379 | + * | |
380 | + * @chip: address of the chip which is searched for | |
381 | + * @return: 0 if a chip was found, -1 otherwhise | |
382 | + */ | |
383 | +int i2c_probe(u8 chip) | |
384 | +{ | |
385 | + u8 byte; | |
386 | + return i2c_read(chip, 0, 0, &byte, 1); | |
387 | +} |
drivers/i2c/spr_i2c.c
1 | -/* | |
2 | - * (C) Copyright 2009 | |
3 | - * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. | |
4 | - * | |
5 | - * See file CREDITS for list of people who contributed to this | |
6 | - * project. | |
7 | - * | |
8 | - * This program is free software; you can redistribute it and/or | |
9 | - * modify it under the terms of the GNU General Public License as | |
10 | - * published by the Free Software Foundation; either version 2 of | |
11 | - * the License, or (at your option) any later version. | |
12 | - * | |
13 | - * This program is distributed in the hope that it will be useful, | |
14 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | - * GNU General Public License for more details. | |
17 | - * | |
18 | - * You should have received a copy of the GNU General Public License | |
19 | - * along with this program; if not, write to the Free Software | |
20 | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | - * MA 02111-1307 USA | |
22 | - */ | |
23 | - | |
24 | -#include <common.h> | |
25 | -#include <asm/io.h> | |
26 | -#include <asm/arch/hardware.h> | |
27 | -#include <asm/arch/spr_i2c.h> | |
28 | - | |
29 | -static struct i2c_regs *const i2c_regs_p = | |
30 | - (struct i2c_regs *)CONFIG_SYS_I2C_BASE; | |
31 | - | |
32 | -/* | |
33 | - * set_speed - Set the i2c speed mode (standard, high, fast) | |
34 | - * @i2c_spd: required i2c speed mode | |
35 | - * | |
36 | - * Set the i2c speed mode (standard, high, fast) | |
37 | - */ | |
38 | -static void set_speed(int i2c_spd) | |
39 | -{ | |
40 | - unsigned int cntl; | |
41 | - unsigned int hcnt, lcnt; | |
42 | - unsigned int high, low; | |
43 | - | |
44 | - cntl = (readl(&i2c_regs_p->ic_con) & (~IC_CON_SPD_MSK)); | |
45 | - | |
46 | - switch (i2c_spd) { | |
47 | - case IC_SPEED_MODE_MAX: | |
48 | - cntl |= IC_CON_SPD_HS; | |
49 | - high = MIN_HS_SCL_HIGHTIME; | |
50 | - low = MIN_HS_SCL_LOWTIME; | |
51 | - break; | |
52 | - | |
53 | - case IC_SPEED_MODE_STANDARD: | |
54 | - cntl |= IC_CON_SPD_SS; | |
55 | - high = MIN_SS_SCL_HIGHTIME; | |
56 | - low = MIN_SS_SCL_LOWTIME; | |
57 | - break; | |
58 | - | |
59 | - case IC_SPEED_MODE_FAST: | |
60 | - default: | |
61 | - cntl |= IC_CON_SPD_FS; | |
62 | - high = MIN_FS_SCL_HIGHTIME; | |
63 | - low = MIN_FS_SCL_LOWTIME; | |
64 | - break; | |
65 | - } | |
66 | - | |
67 | - writel(cntl, &i2c_regs_p->ic_con); | |
68 | - | |
69 | - hcnt = (IC_CLK * high) / NANO_TO_MICRO; | |
70 | - writel(hcnt, &i2c_regs_p->ic_fs_scl_hcnt); | |
71 | - | |
72 | - lcnt = (IC_CLK * low) / NANO_TO_MICRO; | |
73 | - writel(lcnt, &i2c_regs_p->ic_fs_scl_lcnt); | |
74 | -} | |
75 | - | |
76 | -/* | |
77 | - * i2c_set_bus_speed - Set the i2c speed | |
78 | - * @speed: required i2c speed | |
79 | - * | |
80 | - * Set the i2c speed. | |
81 | - */ | |
82 | -void i2c_set_bus_speed(int speed) | |
83 | -{ | |
84 | - if (speed >= I2C_MAX_SPEED) | |
85 | - set_speed(IC_SPEED_MODE_MAX); | |
86 | - else if (speed >= I2C_FAST_SPEED) | |
87 | - set_speed(IC_SPEED_MODE_FAST); | |
88 | - else | |
89 | - set_speed(IC_SPEED_MODE_STANDARD); | |
90 | -} | |
91 | - | |
92 | -/* | |
93 | - * i2c_get_bus_speed - Gets the i2c speed | |
94 | - * | |
95 | - * Gets the i2c speed. | |
96 | - */ | |
97 | -int i2c_get_bus_speed(void) | |
98 | -{ | |
99 | - u32 cntl; | |
100 | - | |
101 | - cntl = (readl(&i2c_regs_p->ic_con) & IC_CON_SPD_MSK); | |
102 | - | |
103 | - if (cntl == IC_CON_SPD_HS) | |
104 | - return I2C_MAX_SPEED; | |
105 | - else if (cntl == IC_CON_SPD_FS) | |
106 | - return I2C_FAST_SPEED; | |
107 | - else if (cntl == IC_CON_SPD_SS) | |
108 | - return I2C_STANDARD_SPEED; | |
109 | - | |
110 | - return 0; | |
111 | -} | |
112 | - | |
113 | -/* | |
114 | - * i2c_init - Init function | |
115 | - * @speed: required i2c speed | |
116 | - * @slaveadd: slave address for the spear device | |
117 | - * | |
118 | - * Initialization function. | |
119 | - */ | |
120 | -void i2c_init(int speed, int slaveadd) | |
121 | -{ | |
122 | - unsigned int enbl; | |
123 | - | |
124 | - /* Disable i2c */ | |
125 | - enbl = readl(&i2c_regs_p->ic_enable); | |
126 | - enbl &= ~IC_ENABLE_0B; | |
127 | - writel(enbl, &i2c_regs_p->ic_enable); | |
128 | - | |
129 | - writel((IC_CON_SD | IC_CON_SPD_FS | IC_CON_MM), &i2c_regs_p->ic_con); | |
130 | - writel(IC_RX_TL, &i2c_regs_p->ic_rx_tl); | |
131 | - writel(IC_TX_TL, &i2c_regs_p->ic_tx_tl); | |
132 | - i2c_set_bus_speed(speed); | |
133 | - writel(IC_STOP_DET, &i2c_regs_p->ic_intr_mask); | |
134 | - writel(slaveadd, &i2c_regs_p->ic_sar); | |
135 | - | |
136 | - /* Enable i2c */ | |
137 | - enbl = readl(&i2c_regs_p->ic_enable); | |
138 | - enbl |= IC_ENABLE_0B; | |
139 | - writel(enbl, &i2c_regs_p->ic_enable); | |
140 | -} | |
141 | - | |
142 | -/* | |
143 | - * i2c_setaddress - Sets the target slave address | |
144 | - * @i2c_addr: target i2c address | |
145 | - * | |
146 | - * Sets the target slave address. | |
147 | - */ | |
148 | -static void i2c_setaddress(unsigned int i2c_addr) | |
149 | -{ | |
150 | - writel(i2c_addr, &i2c_regs_p->ic_tar); | |
151 | -} | |
152 | - | |
153 | -/* | |
154 | - * i2c_flush_rxfifo - Flushes the i2c RX FIFO | |
155 | - * | |
156 | - * Flushes the i2c RX FIFO | |
157 | - */ | |
158 | -static void i2c_flush_rxfifo(void) | |
159 | -{ | |
160 | - while (readl(&i2c_regs_p->ic_status) & IC_STATUS_RFNE) | |
161 | - readl(&i2c_regs_p->ic_cmd_data); | |
162 | -} | |
163 | - | |
164 | -/* | |
165 | - * i2c_wait_for_bb - Waits for bus busy | |
166 | - * | |
167 | - * Waits for bus busy | |
168 | - */ | |
169 | -static int i2c_wait_for_bb(void) | |
170 | -{ | |
171 | - unsigned long start_time_bb = get_timer(0); | |
172 | - | |
173 | - while ((readl(&i2c_regs_p->ic_status) & IC_STATUS_MA) || | |
174 | - !(readl(&i2c_regs_p->ic_status) & IC_STATUS_TFE)) { | |
175 | - | |
176 | - /* Evaluate timeout */ | |
177 | - if (get_timer(start_time_bb) > (unsigned long)(I2C_BYTE_TO_BB)) | |
178 | - return 1; | |
179 | - } | |
180 | - | |
181 | - return 0; | |
182 | -} | |
183 | - | |
184 | -/* check parameters for i2c_read and i2c_write */ | |
185 | -static int check_params(uint addr, int alen, uchar *buffer, int len) | |
186 | -{ | |
187 | - if (buffer == NULL) { | |
188 | - printf("Buffer is invalid\n"); | |
189 | - return 1; | |
190 | - } | |
191 | - | |
192 | - if (alen > 1) { | |
193 | - printf("addr len %d not supported\n", alen); | |
194 | - return 1; | |
195 | - } | |
196 | - | |
197 | - if (addr + len > 256) { | |
198 | - printf("address out of range\n"); | |
199 | - return 1; | |
200 | - } | |
201 | - | |
202 | - return 0; | |
203 | -} | |
204 | - | |
205 | -static int i2c_xfer_init(uchar chip, uint addr) | |
206 | -{ | |
207 | - if (i2c_wait_for_bb()) { | |
208 | - printf("Timed out waiting for bus\n"); | |
209 | - return 1; | |
210 | - } | |
211 | - | |
212 | - i2c_setaddress(chip); | |
213 | - writel(addr, &i2c_regs_p->ic_cmd_data); | |
214 | - | |
215 | - return 0; | |
216 | -} | |
217 | - | |
218 | -static int i2c_xfer_finish(void) | |
219 | -{ | |
220 | - ulong start_stop_det = get_timer(0); | |
221 | - | |
222 | - while (1) { | |
223 | - if ((readl(&i2c_regs_p->ic_raw_intr_stat) & IC_STOP_DET)) { | |
224 | - readl(&i2c_regs_p->ic_clr_stop_det); | |
225 | - break; | |
226 | - } else if (get_timer(start_stop_det) > I2C_STOPDET_TO) { | |
227 | - break; | |
228 | - } | |
229 | - } | |
230 | - | |
231 | - if (i2c_wait_for_bb()) { | |
232 | - printf("Timed out waiting for bus\n"); | |
233 | - return 1; | |
234 | - } | |
235 | - | |
236 | - i2c_flush_rxfifo(); | |
237 | - | |
238 | - /* Wait for read/write operation to complete on actual memory */ | |
239 | - udelay(10000); | |
240 | - | |
241 | - return 0; | |
242 | -} | |
243 | - | |
244 | -/* | |
245 | - * i2c_read - Read from i2c memory | |
246 | - * @chip: target i2c address | |
247 | - * @addr: address to read from | |
248 | - * @alen: | |
249 | - * @buffer: buffer for read data | |
250 | - * @len: no of bytes to be read | |
251 | - * | |
252 | - * Read from i2c memory. | |
253 | - */ | |
254 | -int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) | |
255 | -{ | |
256 | - unsigned long start_time_rx; | |
257 | - | |
258 | - if (check_params(addr, alen, buffer, len)) | |
259 | - return 1; | |
260 | - | |
261 | - if (i2c_xfer_init(chip, addr)) | |
262 | - return 1; | |
263 | - | |
264 | - start_time_rx = get_timer(0); | |
265 | - while (len) { | |
266 | - writel(IC_CMD, &i2c_regs_p->ic_cmd_data); | |
267 | - | |
268 | - if (readl(&i2c_regs_p->ic_status) & IC_STATUS_RFNE) { | |
269 | - *buffer++ = (uchar)readl(&i2c_regs_p->ic_cmd_data); | |
270 | - len--; | |
271 | - start_time_rx = get_timer(0); | |
272 | - | |
273 | - } else if (get_timer(start_time_rx) > I2C_BYTE_TO) { | |
274 | - printf("Timed out. i2c read Failed\n"); | |
275 | - return 1; | |
276 | - } | |
277 | - } | |
278 | - | |
279 | - return i2c_xfer_finish(); | |
280 | -} | |
281 | - | |
282 | -/* | |
283 | - * i2c_write - Write to i2c memory | |
284 | - * @chip: target i2c address | |
285 | - * @addr: address to read from | |
286 | - * @alen: | |
287 | - * @buffer: buffer for read data | |
288 | - * @len: no of bytes to be read | |
289 | - * | |
290 | - * Write to i2c memory. | |
291 | - */ | |
292 | -int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) | |
293 | -{ | |
294 | - int nb = len; | |
295 | - unsigned long start_time_tx; | |
296 | - | |
297 | - if (check_params(addr, alen, buffer, len)) | |
298 | - return 1; | |
299 | - | |
300 | - if (i2c_xfer_init(chip, addr)) | |
301 | - return 1; | |
302 | - | |
303 | - start_time_tx = get_timer(0); | |
304 | - while (len) { | |
305 | - if (readl(&i2c_regs_p->ic_status) & IC_STATUS_TFNF) { | |
306 | - writel(*buffer, &i2c_regs_p->ic_cmd_data); | |
307 | - buffer++; | |
308 | - len--; | |
309 | - start_time_tx = get_timer(0); | |
310 | - | |
311 | - } else if (get_timer(start_time_tx) > (nb * I2C_BYTE_TO)) { | |
312 | - printf("Timed out. i2c write Failed\n"); | |
313 | - return 1; | |
314 | - } | |
315 | - } | |
316 | - | |
317 | - return i2c_xfer_finish(); | |
318 | -} | |
319 | - | |
320 | -/* | |
321 | - * i2c_probe - Probe the i2c chip | |
322 | - */ | |
323 | -int i2c_probe(uchar chip) | |
324 | -{ | |
325 | - u32 tmp; | |
326 | - | |
327 | - /* | |
328 | - * Try to read the first location of the chip. | |
329 | - */ | |
330 | - return i2c_read(chip, 0, 1, (uchar *)&tmp, 1); | |
331 | -} |
include/configs/spear-common.h