1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * PP502X and PP5002 I2C driver
12 * Based on code from the ipodlinux project - http://ipodlinux.org/
13 * Adapted for Rockbox in November 2005
15 * Original file: linux/arch/armnommu/mach-ipod/hardware.c
17 * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
19 * All files in this archive are subject to the GNU General Public License.
20 * See the file COPYING in the source tree root for full license agreement.
22 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
23 * KIND, either express or implied.
25 ****************************************************************************/
35 /* Local functions definitions */
36 static struct mutex i2c_mtx SHAREDBSS_ATTR
;
38 #define POLL_TIMEOUT (HZ)
40 static int pp_i2c_wait_not_busy(void)
42 unsigned long timeout
;
43 timeout
= current_tick
+ POLL_TIMEOUT
;
44 while (TIME_BEFORE(current_tick
, timeout
)) {
45 if (!(I2C_STATUS
& I2C_BUSY
)) {
54 static int pp_i2c_read_byte(unsigned int addr
, unsigned int *data
)
56 if (pp_i2c_wait_not_busy() < 0)
63 int old_irq_level
= disable_irq_save();
65 /* clear top 15 bits, left shift 1, or in 0x1 for a read */
66 I2C_ADDR
= ((addr
<< 17) >> 16) | 0x1 ;
72 restore_irq(old_irq_level
);
73 if (pp_i2c_wait_not_busy() < 0)
77 old_irq_level
= disable_irq_save();
84 restore_irq(old_irq_level
);
90 static int pp_i2c_send_bytes(unsigned int addr
, unsigned int len
, unsigned char *data
)
94 if (len
< 1 || len
> 4)
99 if (pp_i2c_wait_not_busy() < 0)
105 int old_irq_level
= disable_irq_save();
107 /* clear top 15 bits, left shift 1 */
108 I2C_ADDR
= (addr
<< 17) >> 16;
112 for ( i
= 0; i
< len
; i
++ )
114 I2C_DATA(i
) = *data
++;
117 I2C_CTRL
= (I2C_CTRL
& ~0x26) | ((len
-1) << 1);
119 I2C_CTRL
|= I2C_SEND
;
121 restore_irq(old_irq_level
);
127 static int pp_i2c_send_byte(unsigned int addr
, int data0
)
129 unsigned char data
[1];
133 return pp_i2c_send_bytes(addr
, 1, data
);
136 /* Public functions */
139 mutex_lock(&i2c_mtx
);
142 void i2c_unlock(void)
144 mutex_unlock(&i2c_mtx
);
147 int i2c_readbytes(unsigned int dev_addr
, int addr
, int len
, unsigned char *data
) {
150 mutex_lock(&i2c_mtx
);
151 pp_i2c_send_byte(dev_addr
, addr
);
152 for (i
= 0; i
< len
; i
++) {
153 pp_i2c_read_byte(dev_addr
, &temp
);
156 mutex_unlock(&i2c_mtx
);
160 int i2c_readbyte(unsigned int dev_addr
, int addr
)
164 mutex_lock(&i2c_mtx
);
165 pp_i2c_send_byte(dev_addr
, addr
);
166 pp_i2c_read_byte(dev_addr
, &data
);
167 mutex_unlock(&i2c_mtx
);
172 int pp_i2c_send(unsigned int addr
, int data0
, int data1
)
175 unsigned char data
[2];
180 mutex_lock(&i2c_mtx
);
181 retval
= pp_i2c_send_bytes(addr
, 2, data
);
182 mutex_unlock(&i2c_mtx
);
190 mutex_init(&i2c_mtx
);
193 /* GPIO port C disable port 0x10 */
194 GPIOC_ENABLE
&= ~0x10;
196 /* GPIO port C disable port 0x20 */
197 GPIOC_ENABLE
&= ~0x20;
200 #if CONFIG_I2C == I2C_PP5002
203 DEV_EN
|= DEV_I2C
; /* Enable I2C */
205 DEV_RS
|= DEV_I2C
; /* Start I2C Reset */
206 DEV_RS
&=~DEV_I2C
; /* End I2C Reset */
208 #if CONFIG_I2C == I2C_PP5020
209 outl(0x0, 0x600060a4);
210 outl(0x80 | (0 << 8), 0x600060a4);
211 #elif CONFIG_I2C == I2C_PP5024
213 /* Sansa OF sets this to 0x20 first, communicates with the AS3514
214 then sets it to 0x23 - this still works fine though */
215 outl(0x0, 0x600060a4);
216 outl(0x23, 0x600060a4);
217 #elif defined(SANSA_C200)
218 /* This is the init sequence from the Sansa c200 bootloader.
219 I'm not sure what's really necessary. */
220 pp_i2c_wait_not_busy();
223 outl(0x64, 0x600060a4);
225 outl(0x55, 0x7000c02c);
226 outl(0x54, 0x7000c030);
229 outl(0x1e, 0x600060a4);
231 pp_i2c_send(AS3514_I2C_ADDR
, SUPERVISOR
, 5);
235 i2c_readbyte(0x8, 0);