1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2011 by Marcin Bukat
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
25 #include "i2c-rk27xx.h"
29 /* Driver for the rockchip rk27xx built-in I2C controller in master mode
31 Both the i2c_read and i2c_write function take the following arguments:
32 * slave, the address of the i2c slave device to read from / write to
33 * address, optional sub-address in the i2c slave (unused if -1)
34 * len, number of bytes to be transfered
35 * data, pointer to data to be transfered
36 A return value other than 0 indicates an error.
39 static struct mutex i2c_mtx
;
41 static bool i2c_write_byte(uint8_t data
, bool start
)
43 long timeout
= current_tick
+ HZ
/ 50;
46 I2C_CONR
|= (1<<3) | (1<<2); /* master port enable, transmit bit */
50 I2C_LCMR
= (1<<2) | (1<<0); /* resume op, start bit */
52 I2C_LCMR
= (1<<2); /* resume op */
54 I2C_CONR
&= ~(1<<4); /* ACK enable */
56 /* wait for ACK from slave */
57 while ( !(I2C_ISR
& (1<<0)) || (I2C_LSR
& (1<<0)) )
58 if (TIME_AFTER(current_tick
, timeout
))
61 /* clear status bit */
67 static bool i2c_read_byte(unsigned char *data
)
69 long timeout
= current_tick
+ HZ
/ 50;
71 I2C_LCMR
= (1<<2); /* resume op */
73 while (I2C_ISR
& (1<<1))
74 if (TIME_AFTER(current_tick
, timeout
))
79 /* clear status bit */
85 static bool i2c_stop(void)
87 long timeout
= current_tick
+ HZ
/ 50;
90 I2C_LCMR
|= (1<<2) | (1<<1); /* resume op, stop */
92 while (I2C_LCMR
& (1<<1))
93 if (TIME_AFTER(current_tick
, timeout
))
99 /* route i2c bus to internal codec or external bus
100 * internal codec has 0x27 i2c slave address so
101 * access to this address is routed to internal bus.
102 * All other addresses are routed to external pads
104 static void i2c_iomux(unsigned char slave
)
106 unsigned long muxa
= SCU_IOMUXA_CON
& ~(0x1f<<14);
108 if (slave
== (0x27<<1))
111 SCU_IOMUXA_CON
= muxa
| (1<<16) | (1<<14);
115 /* external I2C bus */
116 SCU_IOMUXA_CON
= muxa
| (1<<18);
122 mutex_init(&i2c_mtx
);
124 SCU_CLKCFG
&= ~(1<< 20);
126 I2C_OPR
|= (1<<7); /* reset state machine */
128 I2C_OPR
&= ~((1<<7) | (1<<6)); /* clear ENABLE bit, deasert reset */
130 /* set I2C divider to stay within allowed SCL freq limit
132 * SCLfreq = (APBfreq/5*(I2CCDVR[5:3] + 1) * 2^((I2CCDVR[2:0] + 1))
134 I2C_OPR
= (I2C_OPR
& ~(0x3F)) | (6<<3) | 1<<0;
138 I2C_OPR
|= (1<<6); /* enable i2c core */
141 int i2c_write(unsigned char slave
, int address
, int len
,
142 const unsigned char *data
)
144 mutex_lock(&i2c_mtx
);
149 if (! i2c_write_byte(slave
& ~1, true))
151 mutex_unlock(&i2c_mtx
);
157 if (! i2c_write_byte(address
, false))
159 mutex_unlock(&i2c_mtx
);
167 if (! i2c_write_byte(*data
++, false))
169 mutex_unlock(&i2c_mtx
);
177 mutex_unlock(&i2c_mtx
);
181 mutex_unlock(&i2c_mtx
);
185 int i2c_read(unsigned char slave
, int address
, int len
, unsigned char *data
)
187 mutex_lock(&i2c_mtx
);
194 if (! i2c_write_byte(slave
& ~1, true))
196 mutex_unlock(&i2c_mtx
);
201 if (! i2c_write_byte(address
, false))
203 mutex_unlock(&i2c_mtx
);
208 /* (repeated) START */
209 if (! i2c_write_byte(slave
| 1, true))
211 mutex_unlock(&i2c_mtx
);
215 I2C_CONR
&= ~(1<<3); /* clear transmit bit (switch to receive mode) */
219 if (! i2c_read_byte(data
++))
221 mutex_unlock(&i2c_mtx
);
226 I2C_CONR
|= (1<<4); /* NACK */
228 I2C_CONR
&= ~(1<<4); /* ACK */
236 mutex_unlock(&i2c_mtx
);
240 mutex_unlock(&i2c_mtx
);