4 * http://www.dave-tech.it
5 * http://www.wawnet.biz
6 * mailto:info@wawnet.biz
8 * See file CREDITS for list of people who contributed to this
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 #include <asm/hardware.h>
32 * Initialization, must be called once on start up, may be called
33 * repeatedly to change the speed and slave addresses.
35 void i2c_init(int speed
, int slaveaddr
)
38 setting up I2C support
40 unsigned int save_F
,save_PF
,rIICCON
,rPCONA
,rPDATA
,rPCONF
,rPUPF
;
45 rPCONF
= ((save_F
& ~(0xF))| 0xa);
46 rPUPF
= (save_PF
| 0x3);
47 PCONF
= rPCONF
; /*PF0:IICSCL, PF1:IICSDA*/
48 PUPF
= rPUPF
; /* Disable pull-up */
50 /* Configuring pin for WC pin of EEprom */
60 Enable ACK, IICCLK=MCLK/16, enable interrupt
61 75MHz/16/(12+1) = 390625 Hz
63 rIICCON
=(1<<7)|(0<<6)|(1<<5)|(0xC);
70 * Probe the given I2C chip address. Returns 0 if a chip responded,
73 int i2c_probe(uchar chip
)
79 printf("i2c_probe chip %d\n", (int) chip
);
84 * Read/Write interface:
85 * chip: I2C chip address, range 0..127
86 * addr: Memory (register) address within the chip
87 * alen: Number of bytes to use for addr (typically 1, 2 for larger
88 * memories, 0 for register type devices with only one
90 * buffer: Where to read/write the data
91 * len: How many bytes to read/write
93 * Returns: 0 on success, not 0 on failure
96 #define S3C44B0X_rIIC_INTPEND (1<<4)
97 #define S3C44B0X_rIIC_LAST_RECEIV_BIT (1<<0)
98 #define S3C44B0X_rIIC_INTERRUPT_ENABLE (1<<5)
99 #define S3C44B0_IIC_TIMEOUT 100
101 int i2c_read(uchar chip
, uint addr
, int alen
, uchar
*buffer
, int len
)
108 send the device offset
114 IICDS
= chip
; /* this is a write operation... */
119 for(k
=0; k
<S3C44B0_IIC_TIMEOUT
; k
++) {
121 if( (temp
& S3C44B0X_rIIC_INTPEND
) == S3C44B0X_rIIC_INTPEND
)
125 if (k
==S3C44B0_IIC_TIMEOUT
)
128 /* wait and check ACK */
130 if ((temp
& S3C44B0X_rIIC_LAST_RECEIV_BIT
) == S3C44B0X_rIIC_LAST_RECEIV_BIT
)
134 IICCON
= IICCON
& ~(S3C44B0X_rIIC_INTPEND
);
136 /* wait and check ACK */
137 for(k
=0; k
<S3C44B0_IIC_TIMEOUT
; k
++) {
139 if( (temp
& S3C44B0X_rIIC_INTPEND
) == S3C44B0X_rIIC_INTPEND
)
143 if (k
==S3C44B0_IIC_TIMEOUT
)
147 if ((temp
& S3C44B0X_rIIC_LAST_RECEIV_BIT
) == S3C44B0X_rIIC_LAST_RECEIV_BIT
)
151 now we can start with the read operation...
154 IICDS
= chip
| 0x01; /* this is a read operation... */
156 rIICSTAT
= 0x90; /*master recv*/
160 IICCON
= IICCON
& ~(S3C44B0X_rIIC_INTPEND
);
162 /* wait and check ACK */
163 for(k
=0; k
<S3C44B0_IIC_TIMEOUT
; k
++) {
165 if( (temp
& S3C44B0X_rIIC_INTPEND
) == S3C44B0X_rIIC_INTPEND
)
169 if (k
==S3C44B0_IIC_TIMEOUT
)
173 if ((temp
& S3C44B0X_rIIC_LAST_RECEIV_BIT
) == S3C44B0X_rIIC_LAST_RECEIV_BIT
)
176 for (j
=0; j
<len
-1; j
++) {
178 /*clear pending bit to resume */
180 temp
= IICCON
& ~(S3C44B0X_rIIC_INTPEND
);
183 /* wait and check ACK */
184 for(k
=0; k
<S3C44B0_IIC_TIMEOUT
; k
++) {
186 if( (temp
& S3C44B0X_rIIC_INTPEND
) == S3C44B0X_rIIC_INTPEND
)
190 if (k
==S3C44B0_IIC_TIMEOUT
)
194 buffer
[j
] = IICDS
; /*save readed data*/
199 reading the last data
202 temp
= IICCON
& ~(S3C44B0X_rIIC_INTPEND
| (1<<7));
205 /* wait but NOT check ACK */
206 for(k
=0; k
<S3C44B0_IIC_TIMEOUT
; k
++) {
208 if( (temp
& S3C44B0X_rIIC_INTPEND
) == S3C44B0X_rIIC_INTPEND
)
212 if (k
==S3C44B0_IIC_TIMEOUT
)
215 buffer
[j
] = IICDS
; /*save readed data*/
217 rIICSTAT
= 0x90; /*master recv*/
219 /* Write operation Terminate sending STOP */
221 /*Clear Int Pending Bit to RESUME*/
223 IICCON
= temp
& (~S3C44B0X_rIIC_INTPEND
);
225 IICCON
= IICCON
| (1<<7); /*restore ACK generation*/
230 int i2c_write(uchar chip
, uint addr
, int alen
, uchar
*buffer
, int len
)
237 send the device offset
243 IICDS
= chip
; /* this is a write operation... */
248 IICCON
= IICCON
& ~(S3C44B0X_rIIC_INTPEND
);
250 /* wait and check ACK */
251 for(k
=0; k
<S3C44B0_IIC_TIMEOUT
; k
++) {
253 if( (temp
& S3C44B0X_rIIC_INTPEND
) == S3C44B0X_rIIC_INTPEND
)
257 if (k
==S3C44B0_IIC_TIMEOUT
)
261 if ((temp
& S3C44B0X_rIIC_LAST_RECEIV_BIT
) == S3C44B0X_rIIC_LAST_RECEIV_BIT
)
265 IICCON
= IICCON
& ~(S3C44B0X_rIIC_INTPEND
);
267 /* wait and check ACK */
268 for(k
=0; k
<S3C44B0_IIC_TIMEOUT
; k
++) {
270 if( (temp
& S3C44B0X_rIIC_INTPEND
) == S3C44B0X_rIIC_INTPEND
)
274 if (k
==S3C44B0_IIC_TIMEOUT
)
278 if ((temp
& S3C44B0X_rIIC_LAST_RECEIV_BIT
) == S3C44B0X_rIIC_LAST_RECEIV_BIT
)
282 now we can start with the read write operation
284 for (j
=0; j
<len
; j
++) {
286 IICDS
= buffer
[j
]; /*prerare data to write*/
288 /*clear pending bit to resume*/
290 temp
= IICCON
& ~(S3C44B0X_rIIC_INTPEND
);
293 /* wait but NOT check ACK */
294 for(k
=0; k
<S3C44B0_IIC_TIMEOUT
; k
++) {
296 if( (temp
& S3C44B0X_rIIC_INTPEND
) == S3C44B0X_rIIC_INTPEND
)
302 if (k
==S3C44B0_IIC_TIMEOUT
)
307 /* sending stop to terminate */
308 rIICSTAT
= 0xD0; /*master send*/
310 /*Clear Int Pending Bit to RESUME*/
312 IICCON
= temp
& (~S3C44B0X_rIIC_INTPEND
);