1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Michael Sevakis
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 "avic-imx31.h"
26 #include "ccm-imx31.h"
27 #include "i2c-imx31.h"
29 /* Forward interrupt handler declarations */
30 #if (I2C_MODULE_MASK & USE_I2C1_MODULE)
31 static __attribute__((interrupt("IRQ"))) void I2C1_HANDLER(void);
33 #if (I2C_MODULE_MASK & USE_I2C2_MODULE)
34 static __attribute__((interrupt("IRQ"))) void I2C2_HANDLER(void);
36 #if (I2C_MODULE_MASK & USE_I2C3_MODULE)
37 static __attribute__((interrupt("IRQ"))) void I2C3_HANDLER(void);
40 #define IADR (0x00 / sizeof (unsigned short)) /* 00h */
41 #define IFDR (0x04 / sizeof (unsigned short)) /* 04h */
42 #define I2CR (0x08 / sizeof (unsigned short)) /* 08h */
43 #define I2SR (0x0c / sizeof (unsigned short)) /* 0ch */
44 #define I2DR (0x10 / sizeof (unsigned short)) /* 10h */
46 static struct i2c_module_descriptor
48 volatile unsigned short * const base
; /* Module base address */
49 void (* const handler
)(void); /* Module interrupt handler */
50 struct mutex m
; /* Node mutual-exclusion */
51 struct wakeup w
; /* I2C done signal */
52 unsigned char *addr_data
; /* Additional addressing data */
53 int addr_count
; /* Addressing byte count */
54 unsigned char *data
; /* TX/RX buffer (actual data) */
55 int data_count
; /* TX/RX byte count */
56 unsigned char addr
; /* Address + r/w bit */
57 uint8_t enable
; /* Enable count */
58 const uint8_t cg
; /* Clock gating index */
59 const uint8_t ints
; /* Module interrupt number */
60 } i2c_descs
[I2C_NUM_I2C
] =
62 #if (I2C_MODULE_MASK & USE_I2C1_MODULE)
64 .base
= (unsigned short *)I2C1_BASE_ADDR
,
67 .handler
= I2C1_HANDLER
,
70 #if (I2C_MODULE_MASK & USE_I2C2_MODULE)
72 .base
= (unsigned short *)I2C2_BASE_ADDR
,
75 .handler
= I2C2_HANDLER
,
78 #if (I2C_MODULE_MASK & USE_I2C3_MODULE)
80 .base
= (unsigned short *)I2C3_BASE_ADDR
,
83 .handler
= I2C3_HANDLER
,
88 static void i2c_interrupt(enum i2c_module_number i2c
)
90 struct i2c_module_descriptor
* const desc
= &i2c_descs
[i2c
];
91 volatile unsigned short * const base
= desc
->base
;
92 unsigned short i2sr
= base
[I2SR
];
94 base
[I2SR
] = 0; /* Clear IIF */
96 if (desc
->addr_count
>= 0)
98 /* ADDR cycle - either done or more to send */
99 if ((i2sr
& I2C_I2SR_RXAK
) != 0)
101 goto i2c_stop
; /* problem */
104 if (--desc
->addr_count
< 0)
106 /* Switching to data cycle */
107 if (desc
->addr
& 0x1)
109 base
[I2CR
] &= ~I2C_I2CR_MTX
; /* Switch to RX mode */
110 base
[I2DR
]; /* Dummy read */
113 /* else remaining data is TX - handle below */
118 base
[I2DR
] = *desc
->addr_data
++; /* Send next addressing byte */
123 if (base
[I2CR
] & I2C_I2CR_MTX
)
125 /* Transmitting data */
126 if ((i2sr
& I2C_I2SR_RXAK
) == 0)
129 if (desc
->data_count
> 0)
131 /* More bytes to send, got ACK from previous byte */
132 base
[I2DR
] = *desc
->data
++;
137 /* else done or no ACK received */
142 if (--desc
->data_count
> 0)
144 if (desc
->data_count
== 1)
146 /* 2nd to Last byte - NACK */
147 base
[I2CR
] |= I2C_I2CR_TXAK
;
150 *desc
->data
++ = base
[I2DR
]; /* Read data from I2DR and store */
155 /* Generate STOP signal before reading data */
156 base
[I2CR
] &= ~(I2C_I2CR_MSTA
| I2C_I2CR_IIEN
);
157 *desc
->data
++ = base
[I2DR
]; /* Read data from I2DR and store */
163 /* Generate STOP signal */
164 base
[I2CR
] &= ~(I2C_I2CR_MSTA
| I2C_I2CR_IIEN
);
166 /* Signal thread we're done */
167 wakeup_signal(&desc
->w
);
170 #if (I2C_MODULE_MASK & USE_I2C1_MODULE)
171 static __attribute__((interrupt("IRQ"))) void I2C1_HANDLER(void)
173 i2c_interrupt(I2C1_NUM
);
176 #if (I2C_MODULE_MASK & USE_I2C2_MODULE)
177 static __attribute__((interrupt("IRQ"))) void I2C2_HANDLER(void)
179 i2c_interrupt(I2C2_NUM
);
182 #if (I2C_MODULE_MASK & USE_I2C3_MODULE)
183 static __attribute__((interrupt("IRQ"))) void I2C3_HANDLER(void)
185 i2c_interrupt(I2C3_NUM
);
189 static int i2c_transfer(struct i2c_node
* const node
,
190 struct i2c_module_descriptor
*const desc
)
192 volatile unsigned short * const base
= desc
->base
;
193 int count
= desc
->data_count
;
196 /* Make sure bus is idle. */
197 while (base
[I2SR
] & I2C_I2SR_IBB
);
200 base
[IFDR
] = node
->ifdr
;
203 base
[I2CR
] = I2C_I2CR_IEN
;
205 /* Enable Interrupt, Master */
206 i2cr
= I2C_I2CR_IEN
| I2C_I2CR_IIEN
| I2C_I2CR_MTX
;
208 if ((desc
->addr
& 0x1) && desc
->data_count
< 2)
210 /* Receiving less than two bytes - disable ACK generation */
211 i2cr
|= I2C_I2CR_TXAK
;
218 base
[I2CR
] = i2cr
| I2C_I2CR_MSTA
;
220 /* Address slave (first byte sent) and begin session. */
221 base
[I2DR
] = desc
->addr
;
223 /* Wait for transfer to complete */
224 if (wakeup_wait(&desc
->w
, HZ
) == OBJ_WAIT_SUCCEEDED
)
226 count
-= desc
->data_count
;
230 /* Generate STOP if timeout */
231 base
[I2CR
] &= ~(I2C_I2CR_MSTA
| I2C_I2CR_IIEN
);
235 desc
->addr_count
= 0;
240 int i2c_read(struct i2c_node
*node
, int reg
,
241 unsigned char *data
, int data_count
)
243 struct i2c_module_descriptor
*const desc
= &i2c_descs
[node
->num
];
246 mutex_lock(&desc
->m
);
248 desc
->addr
= (node
->addr
& 0xfe) | 0x1; /* Slave address/rd */
253 desc
->addr_count
= 1;
254 desc
->addr_data
= ad
;
257 /* else raw read from slave */
260 desc
->data_count
= data_count
;
262 data_count
= i2c_transfer(node
, desc
);
264 mutex_unlock(&desc
->m
);
269 int i2c_write(struct i2c_node
*node
, const unsigned char *data
, int data_count
)
271 struct i2c_module_descriptor
*const desc
= &i2c_descs
[node
->num
];
273 mutex_lock(&desc
->m
);
275 desc
->addr
= node
->addr
& 0xfe; /* Slave address/wr */
276 desc
->data
= (unsigned char *)data
;
277 desc
->data_count
= data_count
;
279 data_count
= i2c_transfer(node
, desc
);
281 mutex_unlock(&desc
->m
);
290 /* Do one-time inits for each module that will be used - leave
291 * module disabled and unclocked until something wants it */
292 for (i
= 0; i
< I2C_NUM_I2C
; i
++)
294 struct i2c_module_descriptor
*const desc
= &i2c_descs
[i
];
295 ccm_module_clock_gating(desc
->cg
, CGM_ON_RUN_WAIT
);
296 mutex_init(&desc
->m
);
297 wakeup_init(&desc
->w
);
298 desc
->base
[I2CR
] = 0;
299 ccm_module_clock_gating(desc
->cg
, CGM_OFF
);
303 void i2c_enable_node(struct i2c_node
*node
, bool enable
)
305 struct i2c_module_descriptor
*const desc
= &i2c_descs
[node
->num
];
307 mutex_lock(&desc
->m
);
311 if (++desc
->enable
== 1)
314 ccm_module_clock_gating(desc
->cg
, CGM_ON_RUN_WAIT
);
315 avic_enable_int(desc
->ints
, INT_TYPE_IRQ
, INT_PRIO_DEFAULT
,
321 if (desc
->enable
> 0 && --desc
->enable
== 0)
324 while (desc
->base
[I2SR
] & I2C_I2SR_IBB
); /* Wait for STOP */
325 desc
->base
[I2CR
] &= ~I2C_I2CR_IEN
;
326 avic_disable_int(desc
->ints
);
327 ccm_module_clock_gating(desc
->cg
, CGM_OFF
);
331 mutex_unlock(&desc
->m
);
334 void i2c_lock_node(struct i2c_node
*node
)
336 struct i2c_module_descriptor
*const desc
= &i2c_descs
[node
->num
];
337 mutex_lock(&desc
->m
);
340 void i2c_unlock_node(struct i2c_node
*node
)
342 struct i2c_module_descriptor
*const desc
= &i2c_descs
[node
->num
];
343 mutex_unlock(&desc
->m
);