source: svn/trunk/newcon3bcm2_21bu/magnum/portinginterface/i2c/7552/bi2c.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 190.4 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2012, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bi2c.c $
11 * $brcm_Revision: Hydra_Software_Devel/193 $
12 * $brcm_Date: 2/1/12 12:16a $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/i2c/7346/bi2c.c $
19 *
20 * Hydra_Software_Devel/193   2/1/12 12:16a agin
21 * SW7346-657:  Subaddress not handled properly for
22 * BI2C_P_WriteBy4BytesCmd.
23 *
24 * Hydra_Software_Devel/192   1/14/12 5:08p agin
25 * SWNOOS-507:  Fixed zero byte write problem with
26 * BI2C_P_WriteBy4BytesCmd.
27 *
28 * Hydra_Software_Devel/191   1/12/12 4:35p agin
29 * SWNOOS-507:  Back off last change.
30 *
31 * Hydra_Software_Devel/190   1/12/12 2:51p agin
32 * SWNOOS-507:  Make 4 byte xfer the default for chips which can support
33 * it.
34 *
35 * Hydra_Software_Devel/189   1/9/12 10:43a agin
36 * SWNOOS-507:  Eliminate redundant functions.
37 *
38 * Hydra_Software_Devel/188   1/7/12 1:42p agin
39 * SWNOOS-507:  Don't require a buffer for BI2C_P_WriteBy4BytesCmd.
40 *
41 * Hydra_Software_Devel/187   1/5/12 11:50a agin
42 * SWNOOS-507:  Allocate memory per channel for 4 byte transfers.
43 *
44 * Hydra_Software_Devel/186   1/3/12 1:15p agin
45 * SWNOOS-507:  Improve i2c performance.
46 *
47 * Hydra_Software_Devel/185   12/16/11 7:37p bselva
48 * SW7360-6: Added appframework support for 7360 platform
49 *
50 * Hydra_Software_Devel/184   12/6/11 4:24p mward
51 * SW7429-7:  Add 7429 to SUPPORT_I2C_VIA_GPIO list, define the GPIO
52 * parameters for it.
53 *
54 * Hydra_Software_Devel/183   11/21/11 6:18p mward
55 * SW7435-7: Add 7435.
56 *
57 * Hydra_Software_Devel/182   11/10/11 11:09a agin
58 * SWNOOS-496:  Define additional macros for AON GPIO.
59 *
60 * Hydra_Software_Devel/181   11/6/11 9:07a agin
61 * SWNOOS-496:  Correct i2c BSCx to BSC_Mx mapping.
62 *
63 * Hydra_Software_Devel/180   10/7/11 6:49a agin
64 * SW7429-7:  Add support for i2c.
65 *
66 * Hydra_Software_Devel/179   9/30/11 9:47a agin
67 * SWNOOS-485:  Support 7346 B0.
68 *
69 * Hydra_Software_Devel/178   9/21/11 11:17a agin
70 * SWNOOS-487:  Fixed problem with previous revision.
71 *
72 * Hydra_Software_Devel/177   9/21/11 8:20a agin
73 * SWNOOS-487:  Updated for 7344 B0.
74 *
75 * Hydra_Software_Devel/176   8/29/11 1:51p jrubio
76 * SW7346-470: remove 7346A0 wrap over code
77 *
78 * Hydra_Software_Devel/175   8/29/11 1:48p jrubio
79 * SW7346-470: add 7346 B0
80 *
81 * Hydra_Software_Devel/174   8/16/11 3:10p jessem
82 * SW7425-1097: Added B0 support.
83 *
84 * Hydra_Software_Devel/173   8/9/11 7:44p agin
85 * SW7231-253:  Support 7231B0.
86 *
87 * Hydra_Software_Devel/172   8/8/11 1:51p mward
88 * SW7125-1061:  Null pointer to indicate freed.
89 *
90 * Hydra_Software_Devel/171   8/8/11 12:10p mward
91 * SW7125-1058: Fix FORWARD_NULL
92 *
93 * Hydra_Software_Devel/170   6/22/11 4:05p agin
94 * SWNOOS-464:  Initialize DATA_REG_SIZE in the BSC channels.
95 *
96 * Hydra_Software_Devel/169   4/28/11 4:01p vanessah
97 * SW7425-340: add 7425B0 appframework support
98 *
99 * Hydra_Software_Devel/168   4/14/11 3:17p agin
100 * SW7344-44:  Add mutex protection for i2c accesses, handle EDDC
101 * different.
102 *
103 * Hydra_Software_Devel/167   4/13/11 5:12p agin
104 * SW7344-44:  Add mutex protection for i2c accesses on a channel basis.
105 *
106 * Hydra_Software_Devel/166   3/21/11 4:08p agin
107 * SW7346-96:  Add BI2C_P_WriteSwA24,  BI2C_P_ReadSwA24,
108 * BI2C_P_WriteSwA16.
109 *
110 * Hydra_Software_Devel/165   3/16/11 1:46p agin
111 * SW7346-96:  Allow sub address bytes of 2 and 3 for BI2C_P_WriteSwCmd.
112 *
113 * Hydra_Software_Devel/164   3/9/11 7:41p etrudeau
114 * SWBLURAY-23692: fix warning about done label
115 *
116 * Hydra_Software_Devel/163   3/9/11 5:31p etrudeau
117 * SWBLURAY-23692: 7640 has 4 i2c channels with BSC Master C not connected
118 * and BSC Master D is on AON
119 *
120 * Hydra_Software_Devel/162   3/2/11 5:50p agin
121 * SW7346-96:  For extra gpio i2c channel, return early from
122 * BI2C_CloseChannel.
123 *
124 * Hydra_Software_Devel/161   3/2/11 4:55p agin
125 * SW7346-96:  For extra gpio i2c channel, return early from BI2C_SetClk
126 * and BI2C_SetSdaDelay.
127 *
128 * Hydra_Software_Devel/160   2/24/11 6:51a agin
129 * SW7346-96:  Fix compiler error.
130 *
131 * Hydra_Software_Devel/159   2/23/11 7:33p agin
132 * SW7346-96:  Fix compiler error.
133 *
134 * Hydra_Software_Devel/158   2/21/11 3:45p hongtaoz
135 * SW7346-96: fixed compile error of previous checkin; add 7425 support
136 * same as 7422;
137 *
138 * Hydra_Software_Devel/157   2/21/11 7:35a agin
139 * SW7346-96:  Add ability to use GPIO lines not tied to the BSC I2C for
140 * I2C bit bang.
141 *
142 * Hydra_Software_Devel/156   11/17/10 7:28p agin
143 * SW7231-19:  Add I2C PI support for 7231/7344/7346
144 *
145 * Hydra_Software_Devel/155   11/1/10 5:08p xhuang
146 * SW7552-4: Add 7552 support
147 *
148 * Hydra_Software_Devel/154   8/27/10 5:17p tdo
149 * SW7425-12: Add 7425 I2C support
150 *
151 * Hydra_Software_Devel/153   8/19/10 6:43a agin
152 * SW7358-7:  Fix compile error for 7358.
153 *
154 * Hydra_Software_Devel/SW7358-7/1   8/19/10 6:09p xhuang
155 * SW7358-7: fix compile error for 7358
156 *
157 * Hydra_Software_Devel/152   6/30/10 5:18p vanessah
158 * SW7422-12:  include bchp_irq0_aon.h
159 *
160 * Hydra_Software_Devel/151   6/30/10 2:21p agin
161 * SW7422-12:  Defined BCHP_INT_ID_iicd_irqen and BCHP_INT_ID_iice_irqen
162 * locally for 7422.
163 *
164 * Hydra_Software_Devel/150   6/25/10 12:40p agin
165 * SW7422-12:  Include bchp_aon_pin_ctrl.h for 7422.  Add support for soft
166 * i2c for 7422.
167 *
168 * Hydra_Software_Devel/149   6/22/10 11:40a vanessah
169 * SW7422-12:  To support appframework. Missing files added:
170 * magnum\portinginterface\pwr rockford\appframework\src\board\97422  To
171 * do list: 1. in framework_board.c, more initialization to be done.  2.
172 * More registers mapping, like clock generation as well as
173 * BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL etc
174 *
175 * Hydra_Software_Devel/148   3/24/10 11:47a vle
176 * SW7601-171: Add BI2C_P_SetupHdmiHwAccess to set up I2C for HDMI HDCP
177 * auto Ri/Pj link integrity check feature
178 *
179 * Hydra_Software_Devel/SW7601-171/1   3/9/10 3:22p vle
180 * SW7601-171: Add BI2C_P_SetupHdmiHwAccess to set up I2C for HDMI HDCP
181 * auto Ri/Pj link integrity check feature
182 *
183 * Hydra_Software_Devel/147   3/8/10 3:08p agin
184 * SW7342-176:  I2c caused Oops in kernel mode.
185 *
186 * Hydra_Software_Devel/146   11/19/09 10:59a gmohile
187 * SW7408-1 : Fix i2c build errors for 7408
188 *
189 * Hydra_Software_Devel/145   11/16/09 10:55a agin
190 * SW7550-41:  Fix BCHP_INT_ID for general case.
191 *
192 * Hydra_Software_Devel/144   11/16/09 6:55a agin
193 * SW7550-41:  UPG PIs are not compiling.
194 *
195 * Hydra_Software_Devel/143   11/11/09 2:11p agin
196 * SW7400-2592:  False i2c REPEAT-START condition generated due to read-
197 * modified-write manner of sw i2c implementation.
198 *
199 * Hydra_Software_Devel/142   11/9/09 11:27a gmohile
200 * SW7408-1 : Add 7408 support
201 *
202 * Hydra_Software_Devel/141   11/2/09 9:42a maivu
203 * SW3548-2587: Fixed warnings
204 *
205 * Hydra_Software_Devel/140   10/26/09 1:52p agin
206 * SW7115-841: Add support for BERR_Code BI2C_P_ReadSwNoAck and
207 * BI2C_P_ReadSwNoAddrNoAck.
208 *
209 * Hydra_Software_Devel/139   10/22/09 2:06p agin
210 * SW7405-2686: Change BREG_I2C to abstract SW and HW implementation.
211 *
212 * Hydra_Software_Devel/138   10/14/09 2:18p mward
213 * SW7125-4: Add 7125 to SUPPORT_I2C_VIA_GPIO list, define the GPIO
214 * parameters for it.
215 *
216 * Hydra_Software_Devel/137   9/28/09 11:11a vishk
217 * SW7405-3038:  Remove test for warnings.
218 *
219 * fixed the comment to remove build errors.
220 *
221 * Hydra_Software_Devel/136   9/25/09 3:56p agin
222 * SW7405-3038:  Remove test for warnings.
223 *
224 * Hydra_Software_Devel/135   9/25/09 1:21p agin
225 * SW7405-3038:  Add BI2C_SwReset().
226 *
227 * Hydra_Software_Devel/134   9/16/09 9:51a pntruong
228 * SW7630-45: Fixed previous checked build errors and warnings.
229 *
230 * Hydra_Software_Devel/132   9/15/09 10:40a rpereira
231 * SW7630-45: Adding 7630 support
232 *
233 * Hydra_Software_Devel/131   9/1/09 8:59p rpereira
234 * SW7550-30: Adding 7550 support
235 *
236 * Hydra_Software_Devel/130   8/4/09 5:21p agin
237 * PR57319: I2C bit bang mode doesn't work with 7325 for HDMI.
238 *
239 * Hydra_Software_Devel/129   7/29/09 12:36p jrubio
240 * PR55232: add 7342/7340
241 *
242 * Hydra_Software_Devel/128   7/23/09 11:03a mward
243 * PR 55545: Support 7125.
244 *
245 * Hydra_Software_Devel/127   7/20/09 10:19a agin
246 * PR56687: Change I2C clock enum from Khz to Hz.
247 *
248 * Hydra_Software_Devel/126   5/2/09 1:13p agin
249 * PR54671:  Perform a dummy gpio read following a gpio write for the sw
250 * i2c implementation.
251 *
252 * Hydra_Software_Devel/125   4/27/09 11:16a jhaberf
253 * PR53796: Updating i2c build to support BCM35130 DTV chip.
254 *
255 * Hydra_Software_Devel/124   4/10/09 2:42p katrep
256 * PR52971: compiler warning
257 *
258 * Hydra_Software_Devel/123   4/9/09 6:07p rpereira
259 * PR52971: added 7635 support
260 *
261 * Hydra_Software_Devel/122   4/9/09 8:48a agin
262 * PR54035: Do not send stop condition after HW detects no-ack (hw does it
263 * already).  Handle BERR_OS_ERROR also.
264 *
265 * Hydra_Software_Devel/121   3/9/09 5:06p jkim
266 * PR50133: Remove deadcode flaged by Coverity
267 *
268 * Hydra_Software_Devel/120   3/5/09 11:26a agin
269 * PR52310: Fix cut & paste error for modifying SDA_DELAY_SEL field.
270 *
271 * Hydra_Software_Devel/119   2/25/09 2:24p agin
272 * PR52112: Fixed warnings.
273 *
274 * Hydra_Software_Devel/118   2/25/09 11:02a agin
275 * PR52112: For clock stretching, add timeout.
276 *
277 * Hydra_Software_Devel/117   2/20/09 10:58a agin
278 * PR52346: Used wrong i2c mask value for setting data transfer type
279 *
280 * Hydra_Software_Devel/116   2/19/09 3:28p agin
281 * PR52310: Add i2c sda delay control for 7601.
282 *
283 * Hydra_Software_Devel/115   2/18/09 10:55a agin
284 * PR52112: Don't send 0x60 and segment pointer if segment==0 for sw bit
285 * bang.
286 *
287 * Hydra_Software_Devel/114   2/14/09 8:08a agin
288 * PR52112: Handle no-ack cases by aborting transfer.
289 *
290 * Hydra_Software_Devel/113   2/5/09 12:04p agin
291 * PR51859: I2C default settings defined BI2C_MAX_I2C_CHANNELS
292 * incorrectly.
293 *
294 * Hydra_Software_Devel/112   1/31/09 2:56p pntruong
295 * PR51629: Fixed build errors.
296 *
297 * Hydra_Software_Devel/111   1/31/09 1:29a jrubio
298 * PR51629: add 7336 support
299 *
300 * Hydra_Software_Devel/110   1/12/09 1:01p maivu
301 * PR 50693: Fix warning errors
302 *
303 * Hydra_Software_Devel/110   1/12/09 12:54p maivu
304 * PR 50693: Fix warning errors
305 *
306 * Hydra_Software_Devel/109   12/31/08 9:20a agin
307 * PR49585: Need to enable i2c support for 7325, 7335, 7413.
308 *
309 * Hydra_Software_Devel/108   12/31/08 9:16a agin
310 * PR49585: Add sw i2c support for 7325, 7335, 7413.
311 *
312 * Hydra_Software_Devel/107   12/13/08 3:45p agin
313 * PR42305: Support i2c via gpio for read EDDC.
314 *
315 * Hydra_Software_Devel/106   12/8/08 5:28p agin
316 * PR49867: Fixed 7420 gpio i2c.
317 *
318 * Hydra_Software_Devel/105   12/2/08 4:39p agin
319 * PR49585: Fixed warnings.
320 *
321 * Hydra_Software_Devel/104   12/2/08 4:25p kaushikb
322 * PR49867: Adding support for 7420
323 *
324 * Hydra_Software_Devel/103   11/21/08 11:40a agin
325 * PR49585: Compile error.
326 *
327 * Hydra_Software_Devel/102   11/21/08 10:56a agin
328 * PR49585: Add sw i2c support for 7601.
329 *
330 * Hydra_Software_Devel/101   10/17/08 5:06p agin
331 * PR42305: Fixed warnings.
332 *
333 * Hydra_Software_Devel/100   10/14/08 8:41p pntruong
334 * PR42305: Fixed cplusplus comment build errors.
335 *
336 * Hydra_Software_Devel/100   10/14/08 8:37p pntruong
337 * PR42305: Fixed cplusplus comment build errors.
338 *
339 * Hydra_Software_Devel/99   10/14/08 5:07p agin
340 * PR42305: Add BI2C_P_ReadSwNoAddr and BI2C_P_ReadSwEDDC.
341 *
342 * Hydra_Software_Devel/98   10/14/08 4:41p jkim
343 * PR46727: add sw i2c function for 7405
344 *
345 * Hydra_Software_Devel/97   8/28/08 9:37a agin
346 * PR46159: Kernel oops from the function "BI2C_P_ReadCmd()" of BI2C
347 * module.
348 *
349 * Hydra_Software_Devel/96   8/21/08 8:27a fbasso
350 * PR 44540: added support for 7601.
351 *
352 * Hydra_Software_Devel/95   7/7/08 2:25p vishk
353 * PR 44620: The return value for ReadCmd and WriteCmd were modified to
354 * meet coverity requirements and needs to be reverted back.
355 *
356 * Hydra_Software_Devel/94   6/11/08 6:43p maivu
357 * PR 43537: Modify correct 3548 ii2c interrupt id
358 *
359 * Hydra_Software_Devel/93   5/7/08 7:22p agin
360 * PR42305: Add delay based on clk rate for i2c gpio.
361 *
362 * Hydra_Software_Devel/92   5/7/08 10:44a agin
363 * PR42305: Fixed warnings.
364 *
365 * Hydra_Software_Devel/91   5/6/08 4:05p agin
366 * PR42305: Fixed warnings.
367 *
368 * Hydra_Software_Devel/90   5/6/08 11:23a agin
369 * PR42305: Support 7400 i2c gpio.
370 *
371 * Hydra_Software_Devel/89   5/5/08 6:35p agin
372 * PR42305: Remove limit for number of bytes to transfer or i2c gpio.
373 * Restore sun_top_ctrl register properly.
374 *
375 * Hydra_Software_Devel/88   5/5/08 5:05p agin
376 * PR42305: Need to set gpio as output for BI2C_P_WriteSwCmd.
377 *
378 * Hydra_Software_Devel/87   5/5/08 2:53p agin
379 * PR42305: Fixed warnings.
380 *
381 * Hydra_Software_Devel/86   5/4/08 7:11p agin
382 * PR42305: Use reg handles generically.
383 *
384 * Hydra_Software_Devel/85   5/4/08 2:08a agin
385 * PR42305: Support i2c via gpio.
386 *
387 * Hydra_Software_Devel/84   4/21/08 1:17p farshidf
388 * PR41729: Add BREG_I2C_ReadNoAddrNoAck function
389 *
390 * Hydra_Software_Devel/83   4/10/08 2:24p vishk
391 * PR 41190: Coverity Defect ID:7917 CHECKED_RETURN
392 *
393 * Hydra_Software_Devel/82   4/7/08 11:43a farshidf
394 * PR39178: fix the i2c compile issue
395 *
396 * Hydra_Software_Devel/81   4/4/08 10:43a farshidf
397 * PR39178: add 3548 support
398 *
399 * Hydra_Software_Devel/80   4/4/08 10:09a vishk
400 * PR 41190: Coverity Defect ID:7917 CHECKED_RETURN,
401 * PR 41189: Coverity Defect ID:7917 CHECKED_RETURN
402 *
403 * Hydra_Software_Devel/79   2/26/08 2:19p jkim
404 * PR39964: remove compiler warning by deleteing lines checking for
405 * BI2C_MAX_I2C_MSTR_CHANNELS and BI2C_MAX_I2C_CHANNELS since these
406 * definitions are not used for 7405, which this function is for.
407 *
408 * Hydra_Software_Devel/78   1/28/08 7:10p agin
409 * PR39047: Ensure that the stop condition was not previously sent out
410 * before sending it.
411 *
412 * Hydra_Software_Devel/77   1/25/08 11:08p agin
413 * PR39047: Send stop condition after I2C wait for completion failure due
414 * to no-ack.
415 *
416 * Hydra_Software_Devel/76   11/27/07 6:02p farshidf
417 * PR36894: I2c update for 7335
418 *
419 * Hydra_Software_Devel/75   10/18/07 4:01p jkim
420 * PR29251: fix I2C problrm related to 32 byte transfer
421 *
422 * Hydra_Software_Devel/74   10/14/07 3:51p jkim
423 * PR14344: Add 7325 support
424 *
425 * Hydra_Software_Devel/73   10/4/07 3:27p brianlee
426 * PR35095: Another check for return code.
427 *
428 * Hydra_Software_Devel/72   10/4/07 3:19p brianlee
429 * PR35050: Check return code after wait for completion.
430 *
431w * Hydra_Software_Devel/71   6/4/07 11:42a farshidf
432 * PR29538: Add burst mode support
433 *
434 * Hydra_Software_Devel/PR29538/1   5/17/07 4:52p dyzhang
435 * PR29538: Add burst mode support
436 *
437 * Hydra_Software_Devel/70   5/24/07 1:56p jkim
438 * PR29251: fix compiler warning
439 *
440 * Hydra_Software_Devel/69   5/24/07 11:51a jkim
441 * PR29251: Add 4byte transfer support for 7405
442 *
443 * Hydra_Software_Devel/68   5/2/07 10:15a jkim
444 * PR30340: undo the changes
445 *
446 * Hydra_Software_Devel/67   5/1/07 5:51p jkim
447 * PR30340: initialize the event to NULL during channelOpen
448 *
449 * Hydra_Software_Devel/66   4/24/07 5:29p jkim
450 * PR29538: Add burst mode support
451 *
452 * Hydra_Software_Devel/65   4/3/07 12:46p katrep
453 * PR29073:Added support for 7405
454 *
455 * Hydra_Software_Devel/65   3/30/07 6:59p katrep
456 * PR29073:Added Support for 7405
457 *
458 * Hydra_Software_Devel/65   3/30/07 6:55p katrep
459 * PR29073:Added support for 7405
460 *
461 * Hydra_Software_Devel/65   3/30/07 6:54p katrep
462 * PR29073:Added support for 7405
463 *
464 * Hydra_Software_Devel/65   3/30/07 6:50p katrep
465 * PR29073:Added 7405 support does not include the 32byte buffer support
466 * for i2c
467 *
468 * Hydra_Software_Devel/64   2/2/07 11:19a jkim
469 * PR27238: Modify to use the correct IRQ definition
470 *
471 * Hydra_Software_Devel/63   1/20/07 2:08p agin
472 * PR27240: hChnEvent was set to NULL after it was created.
473 *
474 * Hydra_Software_Devel/62   1/18/07 5:22p jkim
475 * PR26978: Initialize hChnEvent and hChnCallback to NULL.
476 *
477 * Hydra_Software_Devel/61   1/12/07 4:22p jkim
478 * PR14344: Add 3563 support
479 *
480 * Hydra_Software_Devel/60   10/31/06 3:14p erickson
481 * PR25108: add 7403 support
482 *
483 * Hydra_Software_Devel/59   9/18/06 2:21p agin
484 * PR23800: Timeout value hardcoded in bi2c.c
485 *
486 * Hydra_Software_Devel/58   9/6/06 4:12p jkim
487 * PR14344: add ing 7440 support
488 *
489 * Hydra_Software_Devel/57   8/9/06 10:46a agin
490 * PR23362: Add 3563 support.
491 *
492 * Hydra_Software_Devel/56   6/23/06 12:11a erickson
493 * PR21861: increased timeout to 20 milliseconds based on observed
494 * requirements
495 *
496 * Hydra_Software_Devel/55   6/16/06 11:48a mward
497 * PR21846: add "-mips2 -O3" gcc option to appframework
498 *
499 * Hydra_Software_Devel/54   6/15/06 5:14p mward
500 * PR21678: Add support for 7118 chip 97118 board
501 *
502 * Hydra_Software_Devel/53   5/5/06 3:40p dlwin
503 * PR 20343: Disable the use BERR_TRACE() for timeout errors. It generated
504 * error messages when probling for optional cards.
505 *
506 * Hydra_Software_Devel/52   4/20/06 6:50p agin
507 * PR14597: Don't need MSB fix for BX chips.
508 *
509 * Hydra_Software_Devel/51   2/14/06 2:58p agin
510 * PR19666: 7438, not 7348.
511 *
512 * Hydra_Software_Devel/50   2/14/06 2:28p agin
513 * PR19666: Need to create 7438 I2C porting interface.
514 *
515 * Hydra_Software_Devel/49   2/14/06 10:57a jgarrett
516 * PR 19663: Extending minimum I2C timeout to 1s for 7400, not 1ms.
517 *
518 * Hydra_Software_Devel/48   1/25/06 11:52a gmullen
519 * PR19220: Added INT ID for 5th I2C master.
520 *
521 * Hydra_Software_Devel/47   1/23/06 4:58p agin
522 * PR19220: Support 5th I2C controller.
523 *
524 * Hydra_Software_Devel/46   1/14/06 10:13p agin
525 * PR19076: Support BCM7400.
526 *
527 * Hydra_Software_Devel/45   12/22/05 10:37a agin
528 * PR18787: Update I2C, KIR with C3 defines using new version method.
529 *
530 * Hydra_Software_Devel/44   9/27/05 2:13p mphillip
531 * PR16012: I believe this was the intention of the conditional (fixes the
532 * pre-C2/B2 workaround so it doesn't apply for C2/B2 builds)
533 *
534 * Hydra_Software_Devel/43   9/9/05 5:06p jkim
535 * PR16945:Per conversation with Dave Lwin, change BI2C_Delete2cRegHandle
536 * back to BI2C_CloseI2cRegHandle
537 *
538 * Hydra_Software_Devel/42   9/7/05 3:42p jkim
539 * PR16945: Change BI2C_CloseI2CRegHandle to BI2C_DeleteI2CRegHandle
540 *
541 * Hydra_Software_Devel/41   8/1/05 5:22p vsilyaev
542 * PR 16012: Added support for 7401
543 *
544 * Hydra_Software_Devel/40   6/24/05 5:17p agin
545 * PR14597: Make MSB fix applicable to B1/C1 or earlier chips.  And don't
546 * forget the 3560 chip.
547 *
548 * Hydra_Software_Devel/39   6/23/05 2:35p agin
549 * PR14597: Make MSB fix applicable to B1/C1 or earlier chips.
550 *
551 * Hydra_Software_Devel/38   4/18/05 10:46a agin
552 * PR14828: add read and write no ack functions.
553 *
554 * Hydra_Software_Devel/37   4/4/05 10:24a agin
555 * PR14351: Removed conditional compile call to BI2C_P_WriteCmdNoAck from
556 * BI2C_P_WriteNoAddr.
557 *
558 * Hydra_Software_Devel/36   4/1/05 9:36a agin
559 * PR14597: fix compiler problem with comment again.
560 *
561 * Hydra_Software_Devel/35   3/31/05 9:13p agin
562 * PR14597: make sure that no ack is properly returned for read.
563 *
564 * Hydra_Software_Devel/34   3/29/05 3:47p agin
565 * PR14597: fix compiler problem with comment.
566 *
567 * Hydra_Software_Devel/33   3/29/05 10:38a agin
568 * PR14597: Fix for msb I2C problem.
569 *
570 * Hydra_Software_Devel/32   3/22/05 9:43p dlwin
571 * PR 14351: More compiler warning fixes.
572 *
573 * Hydra_Software_Devel/31   3/18/05 4:40p agin
574 * PR14351: Fassl's changes, fixed compiler error w/ incorrect num of
575 * parameters.
576 *
577 * Hydra_Software_Devel/30   3/16/05 4:39p dlwin
578 * PR 14240: More updated for 3560
579 *
580 * Hydra_Software_Devel/28   3/14/05 5:51p agin
581 * PR14351: Fassl's changes
582 *
583 * Hydra_Software_Devel/27   3/10/05 8:29a dlwin
584 * PR 14240: Added support for 3560 and future chip that use this same
585 * I2C core.
586 *
587 * Hydra_Software_Devel/26   3/3/05 2:18p agin
588 * PR14318:  removed #ifdef.
589 *
590 * Hydra_Software_Devel/25   3/2/05 5:49p agin
591 * PR14318:  Added support for I2C write for NVRAM devices.
592 *
593 * Hydra_Software_Devel/24   2/10/05 6:25p agin
594 * PR14102:  Handle I2C zero data byte write.
595 *
596 * Hydra_Software_Devel/23   2/2/05 4:07p pntruong
597 * PR12342: Removed Metrowerks build errors and warnings.
598 *
599 * Hydra_Software_Devel/22   7/12/04 1:58p brianlee
600 * PR11723: Get rid of floating point calculation.
601 *
602 * Hydra_Software_Devel/21   7/8/04 2:23p brianlee
603 * PR11845: Add I2C API for 3-byte sub address.
604 *
605 * Hydra_Software_Devel/20   3/26/04 5:49p brianlee
606 * PR10174: Fix the handling of 10-bit address.
607 *
608 * Hydra_Software_Devel/19   3/26/04 4:32p brianlee
609 * PR8971: Remove BDBG_ASSERT() for malloc failure.
610 *
611 * Hydra_Software_Devel/18   1/28/04 10:21a brianlee
612 * PR9499: Fix breg_i2c.h file inclusion.
613 *
614 * Hydra_Software_Devel/17   1/13/04 5:02p brianlee
615 * PR9268: Make write structures constant.
616 *
617 * Hydra_Software_Devel/16   12/29/03 3:59p marcusk
618 * PR9117: Updated with changes required to support interrupt ids rather
619 * than strings.
620 *
621 * Hydra_Software_Devel/15   12/18/03 2:16p marcusk
622 * PR8985: The interrupt interface will automatically unmask the interrupt
623 * register.  No need to program it directly.
624 *
625 * Hydra_Software_Devel/14   11/21/03 10:06a brianlee
626 * Put BERR_TRACE macro around the places where error code is returned.
627 *
628 * Hydra_Software_Devel/13   11/6/03 9:47a brianlee
629 * Added BI2C_CloseI2cRegHandle() function.
630 *
631 * Hydra_Software_Devel/12   11/4/03 6:47p brianlee
632 * Get rid of enter/leave macros.
633 *
634 * Hydra_Software_Devel/11   10/27/03 5:22p brianlee
635 * In EDDC read/write functions, ignore ACK during the writing of the
636 * segment pointer.
637 *
638 * Hydra_Software_Devel/10   10/15/03 5:06p brianlee
639 * Fixed a hang with no ACK occurs.
640 *
641 * Hydra_Software_Devel/9   10/9/03 7:04p brianlee
642 * Fixed a problem with writing multiple bytes.
643 *
644 * Hydra_Software_Devel/8   10/3/03 9:52a brianlee
645 * Fixed a bug when copying data from I2C to buffer.
646 *
647 * Hydra_Software_Devel/7   9/24/03 11:56a brianlee
648 * Changed the names of header files.
649 *
650 * Hydra_Software_Devel/6   9/19/03 12:20p brianlee
651 * Fixed warnings from Midas build.
652 *
653 * Hydra_Software_Devel/5   9/18/03 10:16a brianlee
654 * Make SetClk and GetClk functions public so the caller can change the
655 * clock rate after the channel is opened.
656 *
657 * Hydra_Software_Devel/4   9/15/03 10:25a brianlee
658 * Changed TRUE/FALSE to lower case.
659 *
660 * Hydra_Software_Devel/3   9/12/03 5:02p brianlee
661 * Add chip address to EDDC read/write functions instead of using the
662 * fixed value of A0.
663 *
664 * Hydra_Software_Devel/2   9/11/03 5:09p brianlee
665 * Don't disable callback inside ISR.
666 *
667 * Hydra_Software_Devel/1   9/11/03 11:43a brianlee
668 * Initial version.
669 *
670 ***************************************************************************/
671#include "bstd.h"
672#include "breg_i2c_priv.h"
673#include "bi2c.h"
674#include "bi2c_priv.h"
675#include "bchp_irq0.h"
676#include "bchp_int_id_irq0.h"
677#if ((BCHP_CHIP==7344) && (BCHP_VER>=BCHP_VER_B0)) || (BCHP_CHIP==7425) || (BCHP_CHIP==7429) || (BCHP_CHIP==7640) || (BCHP_CHIP==7435)
678#include "bchp_int_id_irq0_aon.h"
679#endif
680#include "bchp_gio.h"
681#if (BCHP_CHIP==7346) || (BCHP_CHIP==7425) || (BCHP_CHIP==7435) || (BCHP_CHIP==7429)
682#include "bchp_gio_aon.h"
683#endif
684#include "bchp_sun_top_ctrl.h"
685
686#if (BCHP_CHIP==7231 || BCHP_CHIP==7422 || BCHP_CHIP==7358 || BCHP_CHIP==7552 || BCHP_CHIP==7360)
687#include "bchp_aon_pin_ctrl.h"
688#include "bchp_irq0_aon.h"
689#define BCHP_INT_ID_iicd_irqen       BCHP_INT_ID_CREATE(BCHP_IRQ0_AON_IRQEN, BCHP_IRQ0_AON_IRQEN_iicd_irqen_SHIFT)
690#define BCHP_INT_ID_iice_irqen       BCHP_INT_ID_CREATE(BCHP_IRQ0_AON_IRQEN, BCHP_IRQ0_AON_IRQEN_iice_irqen_SHIFT)
691#endif
692
693#if (BCHP_CHIP==7435) || (BCHP_CHIP==7429)
694#include "bchp_aon_pin_ctrl.h"
695#include "bchp_irq0_aon.h"
696#endif
697
698#if (BCHP_CHIP==7344)
699#include "bchp_aon_pin_ctrl.h"
700#include "bchp_irq0_aon.h"
701#if (BCHP_VER<BCHP_VER_B0)
702#define BCHP_INT_ID_iicd_irqen       BCHP_INT_ID_CREATE(BCHP_IRQ0_AON_IRQEN, BCHP_IRQ0_AON_IRQEN_iicd_irqen_SHIFT)
703#endif
704#define BCHP_INT_ID_iice_irqen       BCHP_INT_ID_CREATE(BCHP_IRQ0_AON_IRQEN, BCHP_IRQ0_AON_IRQEN_iice_irqen_SHIFT)
705#endif
706
707#if (BCHP_CHIP==7346)
708#include "bchp_aon_pin_ctrl.h"
709#include "bchp_irq0_aon.h"
710#if (BCHP_VER >= BCHP_VER_B0)
711#define BCHP_IRQ0_IRQEN_iicd_irqen_SHIFT     27
712#define BCHP_IRQ0_AON_IRQEN_iice_irqen_SHIFT 27
713#define BCHP_INT_ID_iicd_irqen       BCHP_INT_ID_CREATE(BCHP_IRQ0_IRQEN, BCHP_IRQ0_IRQEN_iicd_irqen_SHIFT)
714#define BCHP_INT_ID_iice_irqen       BCHP_INT_ID_CREATE(BCHP_IRQ0_AON_IRQEN, BCHP_IRQ0_AON_IRQEN_iice_irqen_SHIFT)
715#else
716#define BCHP_INT_ID_iicd_irqen       BCHP_INT_ID_CREATE(BCHP_IRQ0_AON_IRQEN, BCHP_IRQ0_AON_IRQEN_iicd_irqen_SHIFT)
717#define BCHP_INT_ID_iice_irqen       BCHP_INT_ID_CREATE(BCHP_IRQ0_AON_IRQEN, BCHP_IRQ0_AON_IRQEN_iice_irqen_SHIFT)
718#endif
719#endif
720
721#if (BCHP_CHIP==7425)
722#include "bchp_aon_pin_ctrl.h"
723#include "bchp_irq0_aon.h"
724#if (BCHP_VER==BCHP_VER_A0 || BCHP_VER==BCHP_VER_A1)
725#define BCHP_INT_ID_iicd_irqen       BCHP_INT_ID_CREATE(BCHP_IRQ0_AON_IRQEN, BCHP_IRQ0_AON_IRQEN_iicd_irqen_SHIFT)
726#define BCHP_INT_ID_iice_irqen       BCHP_INT_ID_CREATE(BCHP_IRQ0_AON_IRQEN, BCHP_IRQ0_AON_IRQEN_iice_irqen_SHIFT)
727#endif
728#endif
729
730#include "bchp_bsca.h"
731#if (BI2C_MAX_I2C_MSTR_CHANNELS >= 2)
732#include "bchp_bscb.h"
733#endif
734#if (BI2C_MAX_I2C_MSTR_CHANNELS >= 3)
735#include "bchp_bscc.h"
736#endif
737#if (BI2C_MAX_I2C_MSTR_CHANNELS >= 4)
738#include "bchp_bscd.h"
739#endif
740#if (BI2C_MAX_I2C_MSTR_CHANNELS >= 5)
741#include "bchp_bsce.h"
742#endif
743
744#if (BI2C_MAX_I2C_MSTR_CHANNELS == 1)
745#include "bchp_pm.h"
746#endif
747
748#if (BI2C_MAX_I2C_MSTR_CHANNELS != 1) && (BI2C_MAX_I2C_MSTR_CHANNELS != BI2C_MAX_I2C_CHANNELS)
749#error Invalid combination of I2C channels and I2C Masters.
750#endif
751
752#if (BI2C_MAX_I2C_MSTR_CHANNELS == 1)
753#define BI2C_SERIALIZE_SINGLE_SHARED_MASTER 1
754#else
755#define BI2C_SERIALIZE_SINGLE_SHARED_MASTER 0
756#endif
757
758#include "bkni_multi.h"
759
760#define BI2C_P_ACQUIRE_MUTEX(handle) BKNI_AcquireMutex((handle)->hMutex)
761#define BI2C_P_RELEASE_MUTEX(handle) BKNI_ReleaseMutex((handle)->hMutex)
762
763#if (BCHP_CHIP==7400)
764#define BI2C_P_MIN_TIMEOUT_MS 1000  /* JDG - Temporary patch to avoid FPGA timeouts */
765#else
766#define BI2C_P_MIN_TIMEOUT_MS 20 /* PR 21861 - 4 millseconds observed to be required on realtime OS. */
767#endif
768
769/* Add 10% for fudge factor and round it up */
770#define BI2C_P_CALCULATE_TIMEOUT(lval, clkRate) ((((lval) * 1100)/(clkRate)) + BI2C_P_MIN_TIMEOUT_MS)
771
772#if (BCHP_CHIP==7038) && (BCHP_VER <= BCHP_VER_C1)
773/* This MSB fix is only for 7038 C1 Chips and earlier. */
774#define BI2C_MSB_FIX 1
775#else
776#define BI2C_MSB_FIX 0
777#endif
778
779BDBG_MODULE(bi2c);
780
781#define DEV_MAGIC_ID            ((BERR_I2C_ID<<16) | 0xFACE)
782
783#define BI2C_CHK_RETCODE( rc, func )        \
784do {                                        \
785    if( (rc = BERR_TRACE(func)) != BERR_SUCCESS ) \
786    {                                       \
787        goto done;                          \
788    }                                       \
789} while(0)
790
791
792#define MAX_I2C_READ_REQUEST            8
793#define MAX_I2C_READ_NO_ADDR_REQUEST    8
794#define MAX_I2C_WRITE_REQUEST           8
795#define MAX_I2C_WRITE_NO_ADDR_REQUEST   8
796#define I2C_POLLING_INTERVAL            50      /* in usecs */
797
798#define EDDC_SEGMENT_CHIP_ADDR          0x60
799
800#if (BCHP_CHIP==7038) || (BCHP_CHIP==7325) || (BCHP_CHIP==7335) || \
801    (BCHP_CHIP==7336) || (BCHP_CHIP==7346) || (BCHP_CHIP==7400) || (BCHP_CHIP==7413) || \
802    (BCHP_CHIP==7420) || (BCHP_CHIP==7550) || (BCHP_CHIP==7405) || \
803    (BCHP_CHIP==7601) || (BCHP_CHIP==7635) || (BCHP_CHIP==7630) || \
804    (BCHP_CHIP==7125) || (BCHP_CHIP==7408) || (BCHP_CHIP==7422) || \
805    (BCHP_CHIP==7425) || (BCHP_CHIP==7231) || (BCHP_CHIP==7435) || \
806        (BCHP_CHIP==7429)
807    #define BI2C_SUPPORT_I2C_VIA_GPIO       1
808#else
809    #define BI2C_SUPPORT_I2C_VIA_GPIO       0
810#endif
811
812#ifdef BCHP_BSCA_CTLHI_REG_DATA_REG_SIZE_MASK
813    #define BI2C_SUPPORT_4_BYTE_XFR_MODE
814#endif
815
816/*#define BI2C_DEBUG*/
817
818int BI2C_P_RegBitSet(BREG_Handle hReg, uint32_t addr, uint32_t mask, uint8_t val);
819int _BI2C_P_SunTopScl(BREG_Handle hReg, int ch, uint8_t val);
820int _BI2C_P_SunTopSda(BREG_Handle hReg, int ch, uint8_t val);
821BERR_Code _BI2C_P_ClkSet(BREG_Handle hReg, int ch, int clk, BI2C_Clk rate);
822int _BI2C_P_DataGet(BREG_Handle hReg, int ch);
823BERR_Code _BI2C_P_DataSet(BREG_Handle hReg, int ch, int data, BI2C_Clk rate);
824BERR_Code _BI2C_P_ByteWrite(BREG_Handle hReg, int ch, unsigned char data, BI2C_Clk rate, int *ret_ack);
825BERR_Code _BI2C_P_ByteRead(BREG_Handle hReg, int ch, int generate_ack, BI2C_Clk rate, unsigned char *ret_data);
826
827#define BI2C_P_OdenScl(val) BI2C_P_RegBitSet(hReg, i2c_gpio[ch].gio_oden_scl_reg, i2c_gpio[ch].gio_scl_mask, val)
828#define BI2C_P_OdenSda(val) BI2C_P_RegBitSet(hReg, i2c_gpio[ch].gio_oden_sda_reg, i2c_gpio[ch].gio_sda_mask, val)
829#define BI2C_P_IodirScl(val) BI2C_P_RegBitSet(hReg, i2c_gpio[ch].gio_iodir_scl_reg, i2c_gpio[ch].gio_scl_mask, val)
830#define BI2C_P_IodirSda(val) BI2C_P_RegBitSet(hReg, i2c_gpio[ch].gio_iodir_sda_reg, i2c_gpio[ch].gio_sda_mask, val)
831#define BI2C_P_DataScl(val) BI2C_P_RegBitSet(hReg, i2c_gpio[ch].gio_data_scl_reg, i2c_gpio[ch].gio_scl_mask, val)
832#define BI2C_P_DataSda(val) BI2C_P_RegBitSet(hReg, i2c_gpio[ch].gio_data_sda_reg, i2c_gpio[ch].gio_sda_mask, val)
833
834#define BI2C_P_SunTopScl(val) _BI2C_P_SunTopScl(hReg, ch, val)
835#define BI2C_P_SunTopSda(val) _BI2C_P_SunTopSda(hReg, ch, val)
836#define BI2C_P_ClkSet(clk) _BI2C_P_ClkSet(hReg, ch, clk, rate)
837#define BI2C_P_DataGet() _BI2C_P_DataGet(hReg, ch)
838#define BI2C_P_DataSet(clk) _BI2C_P_DataSet(hReg, ch, clk, rate)
839#define BI2C_P_ByteWrite(data, ret_ack) _BI2C_P_ByteWrite(hReg, ch, data, rate, ret_ack)
840#define BI2C_P_ByteRead(generate_ack, ret_data) _BI2C_P_ByteRead(hReg, ch, generate_ack, rate, ret_data)
841
842/*******************************************************************************
843*
844*   Private Module Handles
845*
846*******************************************************************************/
847
848typedef struct BI2C_P_Handle
849{
850    uint32_t        magicId;                    /* Used to check if structure is corrupt */
851    BCHP_Handle     hChip;
852    BREG_Handle     hRegister;
853    BINT_Handle     hInterrupt;
854    unsigned int    maxChnNo;
855    BI2C_ChannelHandle hI2cChn[BI2C_MAX_I2C_CHANNELS+EXTRA_SW_I2C_MSTR_CHANNELS];
856#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
857    BKNI_MutexHandle hMutex;                    /* Mutex handle for serialization */
858#endif
859} BI2C_P_Handle;
860
861typedef struct BI2C_P_ChannelHandle
862{
863    uint32_t        magicId;                    /* Used to check if structure is corrupt */
864    BI2C_Handle     hI2c;
865    unsigned int    chnNo;
866    uint32_t        coreOffset;
867    BKNI_EventHandle    hChnEvent;
868    BINT_CallbackHandle hChnCallback;
869#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 0)
870    BKNI_MutexHandle hMutex;                    /* Mutex handle for serialization */
871#endif
872
873    BI2C_Clk            clkRate;
874    unsigned int        timeoutMs;
875    bool                intMode;
876    bool                noAck;
877    bool                nvramAck;
878
879    /* use burst mode R/W or not */
880    bool                burstMode;
881
882    /* use software i2c or not */
883    bool                softI2c;
884
885} BI2C_P_ChannelHandle;
886
887/* Ack/Nack bits in I2C protocol */
888#define I2C_ACK         0
889#define I2C_NACK        1
890
891/* user defined delay for I2C */
892int I2c_delay_count = 200;
893
894typedef struct i2c_gpio_params {
895    unsigned long gio_scl_mask;
896    unsigned long gio_sda_mask;
897    unsigned long gio_data_scl_reg;
898    unsigned long gio_data_sda_reg;
899    unsigned long gio_iodir_scl_reg;
900    unsigned long gio_iodir_sda_reg;
901    unsigned long gio_oden_scl_reg;
902    unsigned long gio_oden_sda_reg;
903    unsigned long sun_top_scl_reg;
904    unsigned long sun_top_scl_shift;
905    unsigned long sun_top_scl_mask;
906    unsigned long sun_top_sda_reg;
907    unsigned long sun_top_sda_shift;
908    unsigned long sun_top_sda_mask;
909} i2c_gpio_params;
910
911i2c_gpio_params i2c_gpio[BI2C_MAX_I2C_CHANNELS+EXTRA_SW_I2C_MSTR_CHANNELS];
912
913/*******************************************************************************
914*
915*   Default Module Settings
916*
917*******************************************************************************/
918static const BI2C_Settings defI2cSettings =
919{
920    NULL
921};
922
923static const BI2C_ChannelSettings defI2cXChnSettings[] =
924{
925    {   /* Channel A */
926        BI2C_Clk_eClk400Khz,
927        true,
928        BI2C_TimeoutBasedOnClkSpeed,
929        false,
930        false,
931        true
932    }
933#if (BI2C_MAX_I2C_CHANNELS+EXTRA_SW_I2C_MSTR_CHANNELS >= 2)
934    ,{  /* Channel B */
935        BI2C_Clk_eClk400Khz,
936        true,
937        BI2C_TimeoutBasedOnClkSpeed,
938        false,
939        false,
940        true
941    }
942#endif
943#if (BI2C_MAX_I2C_CHANNELS+EXTRA_SW_I2C_MSTR_CHANNELS >= 3)
944    ,{  /* Channel C */
945        BI2C_Clk_eClk400Khz,
946        true,
947        BI2C_TimeoutBasedOnClkSpeed,
948        false,
949        false,
950        true
951    }
952#endif
953#if (BI2C_MAX_I2C_CHANNELS+EXTRA_SW_I2C_MSTR_CHANNELS >= 4)
954    ,{  /* Channel D */
955        BI2C_Clk_eClk400Khz,
956        true,
957        BI2C_TimeoutBasedOnClkSpeed,
958        false,
959        false,
960        true
961    }
962#endif
963#if (BI2C_MAX_I2C_CHANNELS+EXTRA_SW_I2C_MSTR_CHANNELS >= 5)
964    ,{  /* Channel E */
965        BI2C_Clk_eClk400Khz,
966        true,
967        BI2C_TimeoutBasedOnClkSpeed,
968        false,
969        false,
970        true
971    }
972#endif
973};
974
975static const BINT_Id IntId[] =
976{
977    #if defined(BCHP_INT_ID_iica)
978    BCHP_INT_ID_iica
979    #elif defined(BCHP_INT_ID_iica_irqen)
980    BCHP_INT_ID_iica_irqen
981    #else
982        #error "Not supported in chip"
983    #endif
984
985#if (BI2C_MAX_I2C_MSTR_CHANNELS >= 2)
986    #if defined(BCHP_INT_ID_iicb)
987    ,BCHP_INT_ID_iicb
988    #elif defined(BCHP_INT_ID_iicb_irqen)
989    ,BCHP_INT_ID_iicb_irqen
990    #else
991        #error "Not supported in chip"
992    #endif
993#endif
994
995#if (BI2C_MAX_I2C_MSTR_CHANNELS >= 3)
996    #if defined(BCHP_INT_ID_iicc)
997    ,BCHP_INT_ID_iicc
998    #elif defined(BCHP_INT_ID_iicc_irqen)
999    ,BCHP_INT_ID_iicc_irqen
1000    #else
1001        #error "Not supported in chip"
1002    #endif
1003#endif
1004
1005#if (BI2C_MAX_I2C_MSTR_CHANNELS >= 4)
1006    #if defined(BCHP_INT_ID_iicd)
1007    ,BCHP_INT_ID_iicd
1008    #elif defined(BCHP_INT_ID_iicd_irqen)
1009    ,BCHP_INT_ID_iicd_irqen
1010    #else
1011        #error "Not supported in chip"
1012    #endif
1013#endif
1014
1015#if (BI2C_MAX_I2C_MSTR_CHANNELS >= 5)
1016    #if defined(BCHP_INT_ID_iice)
1017    ,BCHP_INT_ID_iice
1018    #elif defined(BCHP_INT_ID_iice_irqen)
1019    ,BCHP_INT_ID_iice_irqen
1020    #else
1021        #error "Not supported in chip"
1022    #endif
1023#endif
1024};
1025
1026static const uint32_t coreOffsetVal[] =
1027{
1028    0
1029#if (BI2C_MAX_I2C_MSTR_CHANNELS >= 2)
1030    , BCHP_BSCB_CHIP_ADDRESS - BCHP_BSCA_CHIP_ADDRESS
1031#endif
1032#if (BI2C_MAX_I2C_MSTR_CHANNELS >= 3)
1033    , BCHP_BSCC_CHIP_ADDRESS - BCHP_BSCA_CHIP_ADDRESS
1034#endif
1035#if (BI2C_MAX_I2C_MSTR_CHANNELS >= 4)
1036    , BCHP_BSCD_CHIP_ADDRESS - BCHP_BSCA_CHIP_ADDRESS
1037#endif
1038#if (BI2C_MAX_I2C_MSTR_CHANNELS >= 5)
1039    , BCHP_BSCE_CHIP_ADDRESS - BCHP_BSCA_CHIP_ADDRESS
1040#endif
1041};
1042
1043/*******************************************************************************
1044*
1045*   Public Module Functions
1046*
1047*******************************************************************************/
1048BERR_Code BI2C_Open(
1049    BI2C_Handle *pI2c,                  /* [output] Returns handle */
1050    BCHP_Handle hChip,                  /* Chip handle */
1051    BREG_Handle hRegister,              /* Register handle */
1052    BINT_Handle hInterrupt,             /* Interrupt handle */
1053    const BI2C_Settings *pDefSettings   /* Default settings */
1054    )
1055{
1056    BERR_Code retCode = BERR_SUCCESS;
1057    BI2C_Handle hDev;
1058    unsigned int chnIdx;
1059
1060    /* Sanity check on the handles we've been given. */
1061    BDBG_ASSERT( hChip );
1062    BDBG_ASSERT( hRegister );
1063    BDBG_ASSERT( hInterrupt );
1064    BSTD_UNUSED( pDefSettings );
1065
1066    /* Alloc memory from the system heap */
1067    hDev = (BI2C_Handle) BKNI_Malloc( sizeof( BI2C_P_Handle ) );
1068    if( hDev == NULL )
1069    {
1070        *pI2c = NULL;
1071        retCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
1072        BDBG_ERR(("BI2C_Open: BKNI_malloc() failed\n"));
1073        goto done;
1074    }
1075
1076    hDev->magicId   = DEV_MAGIC_ID;
1077    hDev->hChip     = hChip;
1078    hDev->hRegister = hRegister;
1079    hDev->hInterrupt = hInterrupt;
1080    hDev->maxChnNo  = BI2C_MAX_I2C_CHANNELS+EXTRA_SW_I2C_MSTR_CHANNELS;
1081    for( chnIdx = 0; chnIdx < hDev->maxChnNo; chnIdx++ )
1082    {
1083        hDev->hI2cChn[chnIdx] = NULL;
1084    }
1085
1086#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
1087    retCode = BKNI_CreateMutex( &hDev->hMutex );
1088    if( retCode != BERR_SUCCESS )
1089    {
1090        BKNI_Free( hDev );
1091        goto done;
1092    }
1093#elif (BI2C_MAX_I2C_MSTR_CHANNELS == 1)
1094    BDBG_MSG(("BI2C_Open: No serialization mechanism employed for sharing shared signle I2C master core"));
1095#endif
1096
1097    BI2C_P_GpioInit();
1098
1099    *pI2c = hDev;
1100
1101done:
1102    return( retCode );
1103}
1104
1105BERR_Code BI2C_Close(
1106    BI2C_Handle hDev                    /* Device handle */
1107    )
1108{
1109    BERR_Code retCode = BERR_SUCCESS;
1110
1111
1112    BDBG_ASSERT( hDev );
1113    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
1114
1115#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
1116    BKNI_DestroyMutex(hDev->hMutex);
1117#endif
1118    BKNI_Free( (void *) hDev );
1119
1120    return( retCode );
1121}
1122
1123BERR_Code BI2C_GetDefaultSettings(
1124    BI2C_Settings *pDefSettings,        /* [output] Returns default setting */
1125    BCHP_Handle hChip                   /* Chip handle */
1126    )
1127{
1128    BERR_Code retCode = BERR_SUCCESS;
1129
1130    BSTD_UNUSED( hChip );
1131
1132    *pDefSettings = defI2cSettings;
1133
1134    return( retCode );
1135}
1136
1137BERR_Code BI2C_GetTotalChannels(
1138    BI2C_Handle hDev,                   /* Device handle */
1139    unsigned int *totalChannels         /* [output] Returns total number downstream channels supported */
1140    )
1141{
1142    BERR_Code retCode = BERR_SUCCESS;
1143
1144
1145    BDBG_ASSERT( hDev );
1146    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
1147
1148    *totalChannels = hDev->maxChnNo;
1149
1150    return( retCode );
1151}
1152
1153BERR_Code BI2C_GetChannelDefaultSettings(
1154    BI2C_Handle hDev,                   /* Device handle */
1155    unsigned int channelNo,             /* Channel number to default setting for */
1156    BI2C_ChannelSettings *pChnDefSettings /* [output] Returns channel default setting */
1157    )
1158{
1159    BERR_Code retCode = BERR_SUCCESS;
1160
1161#if !BDBG_DEBUG_BUILD
1162    BSTD_UNUSED(hDev);
1163#endif
1164
1165    BDBG_ASSERT( hDev );
1166    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
1167
1168    if( channelNo < BI2C_MAX_I2C_CHANNELS+EXTRA_SW_I2C_MSTR_CHANNELS )
1169    {
1170        *pChnDefSettings = defI2cXChnSettings[channelNo];
1171    }
1172    else
1173    {
1174        retCode = BERR_TRACE (BERR_INVALID_PARAMETER);
1175    }
1176
1177    return( retCode );
1178}
1179
1180BERR_Code BI2C_OpenChannel(
1181    BI2C_Handle hDev,                   /* Device handle */
1182    BI2C_ChannelHandle *phChn,          /* [output] Returns channel handle */
1183    unsigned int channelNo,             /* Channel number to open */
1184    const BI2C_ChannelSettings *pChnDefSettings /* Channel default setting */
1185    )
1186{
1187    BERR_Code           retCode = BERR_SUCCESS;
1188    BI2C_ChannelHandle  hChn;
1189    uint32_t            lval;
1190
1191    BDBG_ASSERT( hDev );
1192    BDBG_ASSERT( hDev->magicId == DEV_MAGIC_ID );
1193
1194    hChn = NULL;
1195    if( channelNo < hDev->maxChnNo )
1196    {
1197        if( hDev->hI2cChn[channelNo] == NULL )
1198        {
1199            /* Alloc memory from the system heap */
1200            hChn = (BI2C_ChannelHandle) BKNI_Malloc( sizeof( BI2C_P_ChannelHandle ) );
1201            if( hChn == NULL )
1202            {
1203                *phChn = NULL;
1204                retCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
1205                BDBG_ERR(("BI2C_OpenChannel: BKNI_malloc() failed\n"));
1206                goto done;
1207            }
1208
1209#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
1210            /* Single I2C Master core */
1211            if (channelNo == 0)
1212#else
1213            retCode = BKNI_CreateMutex( &hChn->hMutex );
1214            if( retCode != BERR_SUCCESS )
1215            {
1216                BKNI_Free( hChn );
1217                hChn = NULL;
1218                goto done;
1219            }
1220#endif
1221            {
1222                #if (EXTRA_SW_I2C_MSTR_CHANNELS > 0)
1223                if (channelNo < BI2C_MAX_I2C_MSTR_CHANNELS)
1224                #endif
1225                {
1226                    BI2C_CHK_RETCODE( retCode, BKNI_CreateEvent( &(hChn->hChnEvent) ) );
1227                    hChn->magicId = DEV_MAGIC_ID;
1228                    hChn->hI2c = hDev;
1229                    hChn->chnNo = channelNo;
1230                    hDev->hI2cChn[channelNo] = hChn;
1231                    hChn->nvramAck = 0;
1232
1233                    /*
1234                     * Offsets are based off of BSCA
1235                     */
1236                    hChn->coreOffset = coreOffsetVal[channelNo];
1237
1238                    /* Program I2C clock rate */
1239                    BI2C_SetClk (hChn, pChnDefSettings->clkRate);
1240
1241                    #if (BCHP_CHIP==7601) && (BCHP_VER >= BCHP_VER_B0)
1242                        BI2C_SetSdaDelay(hChn, BI2C_eSdaDelay815ns);
1243                    #endif
1244
1245                    #ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
1246                        if (pChnDefSettings->fourByteXferMode)
1247                            BI2C_Set4ByteXfrMode(hChn, true);
1248                        else
1249                            BI2C_Set4ByteXfrMode(hChn, false);
1250                    #endif
1251
1252                    /* Copy timeout value */
1253                    hChn->timeoutMs = pChnDefSettings->timeoutMs;
1254
1255                    /* Enable/Disable burst mode for this channel */
1256                    hChn->burstMode = pChnDefSettings->burstMode;
1257
1258                    /* Enable/Disable soft i2c for this channel */
1259                    hChn->softI2c = pChnDefSettings->softI2c;
1260
1261                    /*
1262                     * Enable interrupt for this channel
1263                     */
1264                    hChn->intMode = pChnDefSettings->intMode;
1265
1266                    /*
1267                     * Initialize the hChnCallback to NULL.
1268                     * If intMode is true, this pointer will be assigned accordingly.
1269                     */
1270                    hChn->hChnCallback = NULL;
1271
1272                    if (hChn->intMode == true)
1273                    {
1274                        /*
1275                         * Register and enable L2 interrupt.
1276                         */
1277
1278                        BI2C_CHK_RETCODE( retCode, BINT_CreateCallback(
1279                            &(hChn->hChnCallback), hDev->hInterrupt, IntId[channelNo],
1280                            BI2C_P_HandleInterrupt_Isr, (void *) hChn, 0x00 ) );
1281                        BI2C_CHK_RETCODE( retCode, BINT_EnableCallback( hChn->hChnCallback ) );
1282
1283                        /*
1284                         * Enable I2C interrupt in I2C Core
1285                         */
1286                        lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
1287                        lval |= BCHP_BSCA_CTL_REG_INT_EN_MASK;
1288                        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), lval );
1289                    }
1290                }
1291                #if (EXTRA_SW_I2C_MSTR_CHANNELS > 0)
1292                else
1293                {
1294                    /* This is for any extra I2C master channels requested for sw bit bang. */
1295                    /* Enable/Disable soft i2c for this channel */
1296                    hChn->magicId = DEV_MAGIC_ID;
1297                    hChn->hI2c = hDev;
1298                    hChn->chnNo = channelNo;
1299                    hDev->hI2cChn[channelNo] = hChn;
1300                    hChn->clkRate = pChnDefSettings->clkRate;
1301                    hChn->softI2c = true;
1302                }
1303                #endif
1304            }
1305#if (BI2C_MAX_I2C_MSTR_CHANNELS == 1)
1306            else
1307            {
1308                /*
1309                   Since this is a single I2C master core, we will only use the
1310                   configuration from the first channel, channel 0.  Other channels
1311                   will only control the GPIO port selection.  This PI will rely
1312                   on upper layers to manage the resource sharing of Channel 0.
1313                */
1314                hChn->magicId = DEV_MAGIC_ID;
1315                hChn->hI2c = hDev;
1316                hChn->chnNo = channelNo;
1317                hDev->hI2cChn[channelNo] = hChn;
1318                hChn->nvramAck = 0;
1319                hChn->hChnEvent = NULL;
1320                hChn->hChnCallback = NULL;
1321
1322                hChn->coreOffset = coreOffsetVal[0];
1323
1324                hChn->intMode = pChnDefSettings->intMode;
1325#if (BCHP_CHIP==3563)
1326                hChn->clkRate = pChnDefSettings->clkRate;
1327                hChn->burstMode = pChnDefSettings->burstMode;
1328#endif
1329                hChn->softI2c = pChnDefSettings->softI2c;
1330                BDBG_WRN(("BI2C_OpenChannel: Single I2C Master core, using configuration from Channel 0"));
1331            }
1332#endif
1333            *phChn = hChn;
1334        }
1335        else
1336        {
1337            retCode = BERR_TRACE (BI2C_ERR_NOTAVAIL_CHN_NO);
1338        }
1339    }
1340    else
1341    {
1342        retCode = BERR_TRACE (BERR_INVALID_PARAMETER);
1343    }
1344
1345done:
1346    if( retCode != BERR_SUCCESS )
1347    {
1348        if( hChn != NULL )
1349        {
1350            if( hChn->hChnEvent != NULL )
1351            {
1352                BKNI_DestroyEvent( hChn->hChnEvent );
1353            }
1354            BKNI_Free( hChn );
1355            hDev->hI2cChn[channelNo] = NULL;
1356            *phChn = NULL;
1357        }
1358    }
1359    return( retCode );
1360}
1361
1362BERR_Code BI2C_CloseChannel(
1363    BI2C_ChannelHandle hChn         /* Device channel handle */
1364    )
1365{
1366    BERR_Code retCode = BERR_SUCCESS;
1367    BI2C_Handle hDev;
1368    unsigned int chnNo;
1369    uint32_t    ctlReg;
1370
1371
1372    BDBG_ASSERT( hChn );
1373    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
1374
1375    hDev = hChn->hI2c;
1376
1377#if EXTRA_SW_I2C_MSTR_CHANNELS > 0
1378    if (hChn->chnNo >= BI2C_MAX_I2C_CHANNELS) {
1379        /* Sofware I2C channel. Nothing to do */
1380        goto swChannel;
1381    }
1382#endif
1383    /*
1384     * Disable interrupt for this channel
1385     */
1386    BKNI_EnterCriticalSection();
1387    ctlReg = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
1388    ctlReg &= ~BCHP_BSCA_CTL_REG_INT_EN_MASK;
1389    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), ctlReg );
1390    BKNI_LeaveCriticalSection();
1391
1392    if (hChn->hChnCallback != NULL)
1393    {
1394        BI2C_CHK_RETCODE( retCode, BINT_DisableCallback( hChn->hChnCallback ) );
1395        BI2C_CHK_RETCODE( retCode, BINT_DestroyCallback( hChn->hChnCallback ) );
1396    }
1397
1398    if( hChn->hChnEvent != NULL )
1399    {
1400        BKNI_DestroyEvent( hChn->hChnEvent );
1401    }
1402
1403#if EXTRA_SW_I2C_MSTR_CHANNELS > 0
1404swChannel:
1405#endif
1406    chnNo = hChn->chnNo;
1407#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 0)
1408    BKNI_DestroyMutex(hChn->hMutex);
1409#endif
1410    BKNI_Free( hChn );
1411    hDev->hI2cChn[chnNo] = NULL;
1412
1413done:
1414    return( retCode );
1415}
1416
1417BERR_Code BI2C_GetDevice(
1418    BI2C_ChannelHandle hChn,            /* Device channel handle */
1419    BI2C_Handle *phDev                  /* [output] Returns Device handle */
1420    )
1421{
1422    BERR_Code retCode = BERR_SUCCESS;
1423
1424
1425    BDBG_ASSERT( hChn );
1426    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
1427
1428    *phDev = hChn->hI2c;
1429
1430    return( retCode );
1431}
1432
1433
1434BERR_Code BI2C_CreateI2cRegHandle(
1435    BI2C_ChannelHandle hChn,            /* Device channel handle */
1436    BREG_I2C_Handle *pI2cReg            /* [output]  */
1437    )
1438{
1439    BERR_Code retCode = BERR_SUCCESS;
1440
1441
1442    BDBG_ASSERT( hChn );
1443    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
1444
1445
1446    *pI2cReg = (BREG_I2C_Handle)BKNI_Malloc( sizeof(BREG_I2C_Impl) );
1447    if( *pI2cReg == NULL )
1448    {
1449        retCode = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
1450        BDBG_ERR(("BI2C_CreateI2cRegHandle: BKNI_malloc() failed"));
1451        goto done;
1452    }
1453
1454#if (BI2C_MAX_I2C_MSTR_CHANNELS == 1)
1455    /* Make that Channel 0 is defined, since the other channels are just virutal channels */
1456    if (hChn->hI2c->hI2cChn[0] == NULL)
1457    {
1458        retCode = BERR_TRACE(BI2C_ERR_SINGLE_MSTR_CREATE);
1459        BDBG_ERR(("BI2C_CreateI2cRegHandle: For Single I2C master core, Channel 0 must be created"));
1460        goto done;
1461    }
1462#endif
1463    if (hChn->softI2c)
1464    {
1465        (*pI2cReg)->context                     = (void *)hChn;
1466        (*pI2cReg)->BREG_I2C_Write_Func         = BI2C_P_WriteSw;
1467        (*pI2cReg)->BREG_I2C_WriteSw_Func       = BI2C_P_WriteSw;
1468        (*pI2cReg)->BREG_I2C_WriteNoAck_Func    = BI2C_P_WriteNoAck;
1469        (*pI2cReg)->BREG_I2C_WriteA16_Func      = BI2C_P_WriteSwA16;
1470        (*pI2cReg)->BREG_I2C_WriteSwA16_Func    = BI2C_P_WriteSwA16;
1471        (*pI2cReg)->BREG_I2C_WriteA24_Func      = BI2C_P_WriteA24;
1472        (*pI2cReg)->BREG_I2C_WriteSwA24_Func    = BI2C_P_WriteSwA24;
1473        (*pI2cReg)->BREG_I2C_WriteNoAddr_Func   = BI2C_P_WriteNoAddr;
1474        (*pI2cReg)->BREG_I2C_WriteNoAddrNoAck_Func  = BI2C_P_WriteNoAddrNoAck;
1475        (*pI2cReg)->BREG_I2C_WriteNvram_Func    = BI2C_P_WriteNvram;
1476        (*pI2cReg)->BREG_I2C_Read_Func          = BI2C_P_ReadSw;
1477        (*pI2cReg)->BREG_I2C_ReadSw_Func        = BI2C_P_ReadSw;
1478        (*pI2cReg)->BREG_I2C_ReadNoAck_Func     = BI2C_P_ReadSwNoAck;
1479        (*pI2cReg)->BREG_I2C_ReadA16_Func       = BI2C_P_ReadSwA16;
1480        (*pI2cReg)->BREG_I2C_ReadSwA16_Func     = BI2C_P_ReadSwA16;
1481        (*pI2cReg)->BREG_I2C_ReadA24_Func       = BI2C_P_ReadSwA24;
1482        (*pI2cReg)->BREG_I2C_ReadSwA24_Func     = BI2C_P_ReadSwA24;
1483        (*pI2cReg)->BREG_I2C_ReadNoAddr_Func    = BI2C_P_ReadSwNoAddr;
1484        (*pI2cReg)->BREG_I2C_ReadSwNoAddr_Func  = BI2C_P_ReadSwNoAddr;
1485        (*pI2cReg)->BREG_I2C_ReadNoAddrNoAck_Func  = BI2C_P_ReadSwNoAddrNoAck;
1486        (*pI2cReg)->BREG_I2C_ReadEDDC_Func      = BI2C_P_ReadSwEDDC;
1487        (*pI2cReg)->BREG_I2C_ReadSwEDDC_Func    = BI2C_P_ReadSwEDDC;
1488        (*pI2cReg)->BREG_I2C_WriteEDDC_Func     = BI2C_P_WriteEDDC;
1489        (*pI2cReg)->BREG_I2C_SetupHdmiHwAccess_Func = BI2C_P_SetupHdmiHwAccess;
1490    }
1491    else
1492    {
1493        (*pI2cReg)->context                     = (void *)hChn;
1494        (*pI2cReg)->BREG_I2C_Write_Func         = BI2C_P_Write;
1495        (*pI2cReg)->BREG_I2C_WriteSw_Func       = BI2C_P_WriteSw;
1496        (*pI2cReg)->BREG_I2C_WriteNoAck_Func    = BI2C_P_WriteNoAck;
1497        (*pI2cReg)->BREG_I2C_WriteA16_Func      = BI2C_P_WriteA16;
1498        (*pI2cReg)->BREG_I2C_WriteSwA16_Func    = BI2C_P_WriteSwA16;
1499        (*pI2cReg)->BREG_I2C_WriteA24_Func      = BI2C_P_WriteA24;
1500        (*pI2cReg)->BREG_I2C_WriteSwA24_Func    = BI2C_P_WriteSwA24;
1501        (*pI2cReg)->BREG_I2C_WriteNoAddr_Func   = BI2C_P_WriteNoAddr;
1502        (*pI2cReg)->BREG_I2C_WriteNoAddrNoAck_Func  = BI2C_P_WriteNoAddrNoAck;
1503        (*pI2cReg)->BREG_I2C_WriteNvram_Func    = BI2C_P_WriteNvram;
1504        (*pI2cReg)->BREG_I2C_Read_Func          = BI2C_P_Read;
1505        (*pI2cReg)->BREG_I2C_ReadSw_Func        = BI2C_P_ReadSw;
1506        (*pI2cReg)->BREG_I2C_ReadNoAck_Func     = BI2C_P_ReadNoAck;
1507        (*pI2cReg)->BREG_I2C_ReadA16_Func       = BI2C_P_ReadA16;
1508        (*pI2cReg)->BREG_I2C_ReadSwA16_Func     = BI2C_P_ReadSwA16;
1509        (*pI2cReg)->BREG_I2C_ReadA24_Func       = BI2C_P_ReadA24;
1510        (*pI2cReg)->BREG_I2C_ReadSwA24_Func     = BI2C_P_ReadSwA24;
1511        (*pI2cReg)->BREG_I2C_ReadNoAddr_Func    = BI2C_P_ReadNoAddr;
1512        (*pI2cReg)->BREG_I2C_ReadSwNoAddr_Func  = BI2C_P_ReadSwNoAddr;
1513        (*pI2cReg)->BREG_I2C_ReadNoAddrNoAck_Func  = BI2C_P_ReadNoAddrNoAck;
1514        (*pI2cReg)->BREG_I2C_ReadEDDC_Func      = BI2C_P_ReadEDDC;
1515        (*pI2cReg)->BREG_I2C_ReadSwEDDC_Func    = BI2C_P_ReadSwEDDC;
1516        (*pI2cReg)->BREG_I2C_WriteEDDC_Func     = BI2C_P_WriteEDDC;
1517        (*pI2cReg)->BREG_I2C_SetupHdmiHwAccess_Func = BI2C_P_SetupHdmiHwAccess;
1518    }   
1519
1520done:
1521    return( retCode );
1522}
1523
1524BERR_Code BI2C_CloseI2cRegHandle(
1525    BREG_I2C_Handle     hI2cReg
1526    )
1527{
1528    BERR_Code retCode = BERR_SUCCESS;
1529
1530    BDBG_ASSERT( hI2cReg );
1531    BKNI_Free( (void *) hI2cReg );
1532
1533    return( retCode );
1534}
1535
1536void BI2C_SetClk(
1537    BI2C_ChannelHandle  hChn,           /* Device channel handle */
1538    BI2C_Clk            clkRate         /* pointer to clock rate setting */
1539    )
1540{
1541    BI2C_Handle hDev;
1542    uint32_t    ctlReg;
1543
1544    BDBG_ASSERT( hChn );
1545    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
1546
1547    hDev = hChn->hI2c;
1548
1549#if (BCHP_CHIP!=3560) && (BCHP_CHIP!=3563)
1550#if (BI2C_MAX_I2C_MSTR_CHANNELS == 1) && (BI2C_MAX_I2C_CHANNELS != 1)
1551    if( hChn->chnNo != 0 )
1552    {
1553        /* On single I2C master core, only Channel 0 can be changed. */
1554        BDBG_WRN(("BI2C_SetClk: Single I2C Master core, only Channel 0 configuration can be changed"));
1555        return;
1556    }
1557#endif
1558#endif
1559
1560    hChn->clkRate = clkRate;
1561
1562#if EXTRA_SW_I2C_MSTR_CHANNELS > 0
1563    if (hChn->chnNo >= BI2C_MAX_I2C_CHANNELS) {
1564        /* Sofware I2C channel. Nothing to do */
1565        return;
1566    }
1567#endif
1568    ctlReg = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
1569    ctlReg &= ~(BCHP_BSCA_CTL_REG_SCL_SEL_MASK | BCHP_BSCA_CTL_REG_DIV_CLK_MASK);
1570    switch (clkRate)
1571    {
1572        case BI2C_Clk_eClk100Khz:
1573        case BI2C_Clk_eClk400Khz:
1574            ctlReg |= (0x01 << BCHP_BSCA_CTL_REG_SCL_SEL_SHIFT);
1575            break;
1576
1577        case BI2C_Clk_eClk47Khz:
1578        case BI2C_Clk_eClk187Khz:
1579            ctlReg |= (0x02 << BCHP_BSCA_CTL_REG_SCL_SEL_SHIFT);
1580            break;
1581
1582        case BI2C_Clk_eClk50Khz:
1583        case BI2C_Clk_eClk200Khz:
1584            ctlReg |= (0x03 << BCHP_BSCA_CTL_REG_SCL_SEL_SHIFT);
1585            break;
1586
1587        case BI2C_Clk_eClk93Khz:
1588        case BI2C_Clk_eClk375Khz:
1589            break;
1590
1591    }
1592    if (clkRate < BI2C_Clk_eClk187Khz)
1593        ctlReg |= BCHP_BSCA_CTL_REG_DIV_CLK_MASK;
1594
1595    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), ctlReg );
1596}
1597
1598#if (BCHP_CHIP==7601) && (BCHP_VER >= BCHP_VER_B0)
1599void BI2C_SetSdaDelay(
1600    BI2C_ChannelHandle  hChn,           /* Device channel handle */
1601    BI2C_SdaDelay       sdaDelay        /* Sda delay value */
1602    )
1603{
1604    BI2C_Handle hDev;
1605    uint32_t    ctlReg;
1606
1607    BDBG_ASSERT( hChn );
1608    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
1609
1610    hDev = hChn->hI2c;
1611
1612#if EXTRA_SW_I2C_MSTR_CHANNELS > 0
1613    if (hChn->chnNo >= BI2C_MAX_I2C_CHANNELS) {
1614        /* Sofware I2C channel. Nothing to do */
1615        return;
1616    }
1617#endif
1618    ctlReg = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
1619    ctlReg &= ~(BCHP_BSCA_CTL_REG_reserved0_MASK | BCHP_BSCA_CTL_REG_SDA_DELAY_SEL_MASK);
1620    switch (sdaDelay)
1621    {
1622        /*
1623        case BI2C_eSdaDelay815ns:
1624            ctlReg |= (0x0 << BCHP_BSCA_CTL_REG_SDA_DELAY_SEL_SHIFT);
1625            break;
1626        */
1627        case BI2C_eSdaDelay370ns:
1628            ctlReg |= (0x1 << BCHP_BSCA_CTL_REG_SDA_DELAY_SEL_SHIFT);
1629            break;
1630        case BI2C_eSdaDelay482ns:
1631            ctlReg |= (0x2 << BCHP_BSCA_CTL_REG_SDA_DELAY_SEL_SHIFT);
1632            break;
1633        case BI2C_eSdaDelay593ns:
1634            ctlReg |= (0x3 << BCHP_BSCA_CTL_REG_SDA_DELAY_SEL_SHIFT);
1635            break;
1636        case BI2C_eSdaDelay704ns:
1637            ctlReg |= (0x4 << BCHP_BSCA_CTL_REG_SDA_DELAY_SEL_SHIFT);
1638            break;
1639        case BI2C_eSdaDelay815ns:
1640            ctlReg |= (0x5 << BCHP_BSCA_CTL_REG_SDA_DELAY_SEL_SHIFT);
1641            break;
1642        case BI2C_eSdaDelay926ns:
1643            ctlReg |= (0x6 << BCHP_BSCA_CTL_REG_SDA_DELAY_SEL_SHIFT);
1644            break;
1645        case BI2C_eSdaDelay1037ns:
1646            ctlReg |= (0x7 << BCHP_BSCA_CTL_REG_SDA_DELAY_SEL_SHIFT);
1647            break;
1648    }
1649    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), ctlReg );
1650}
1651#endif
1652
1653BI2C_Clk BI2C_GetClk(
1654    BI2C_ChannelHandle  hChn            /* Device channel handle */
1655)
1656{
1657    BDBG_ASSERT( hChn );
1658    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
1659
1660    /* TODO: how to handle the Single-Master/Multi-Channel configuration */
1661    return hChn->clkRate;
1662}
1663
1664BERR_Code BI2C_SetBurstMode(
1665    BI2C_ChannelHandle hChn,    /* [in] I2C channel handle */
1666    bool bBurstMode             /* [out] Enable or Disable burst mode */
1667    )
1668{
1669    if (hChn == NULL)
1670    {
1671        BDBG_ERR(("Invalid I2C channel handle"));
1672        return BERR_INVALID_PARAMETER;
1673    }
1674
1675    hChn->burstMode = bBurstMode;
1676
1677    return BERR_SUCCESS;
1678}
1679
1680BERR_Code BI2C_GetBurstMode(
1681    BI2C_ChannelHandle hChn,    /* [in] I2C channel handle */
1682    bool *pbBurstMode           /* [out] current burst mode? */
1683    )
1684{
1685    if ((hChn == NULL) || (pbBurstMode == NULL))
1686    {
1687        BDBG_ERR(("Invalid parameters\n"));
1688        return BERR_INVALID_PARAMETER;
1689    }
1690
1691    *pbBurstMode = hChn->burstMode;
1692
1693    return BERR_SUCCESS;
1694}
1695
1696#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
1697void BI2C_Set4ByteXfrMode(
1698    BI2C_ChannelHandle  hChn,           /* Device channel handle */
1699    bool b4ByteMode                     /* Enable or Disable 4 byte xfr mode */
1700    )
1701{
1702    BI2C_Handle hDev;
1703    uint32_t    ctlReg;
1704
1705    BDBG_ASSERT( hChn );
1706    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
1707
1708    hDev = hChn->hI2c;
1709
1710    ctlReg = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG));
1711    if (b4ByteMode)
1712    {
1713        ctlReg |= BCHP_BSCA_CTLHI_REG_DATA_REG_SIZE_MASK;
1714    }
1715    else
1716    {
1717        ctlReg &= ~BCHP_BSCA_CTLHI_REG_DATA_REG_SIZE_MASK;
1718    }
1719
1720    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG), ctlReg );
1721
1722}
1723
1724bool BI2C_Is4ByteXfrMode(
1725    BI2C_ChannelHandle  hChn           /* Device channel handle */
1726    )
1727{
1728    BI2C_Handle hDev;
1729    uint32_t    ctlReg;
1730
1731    BDBG_ASSERT( hChn );
1732    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
1733
1734    hDev = hChn->hI2c;
1735
1736    ctlReg = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG));
1737    if (ctlReg & BCHP_BSCA_CTLHI_REG_DATA_REG_SIZE_MASK)
1738    {
1739        return true;
1740    }
1741
1742    return false;
1743}
1744#endif
1745
1746/*******************************************************************************
1747*
1748*   Private Module Functions
1749*
1750*******************************************************************************/
1751BERR_Code BI2C_P_Read
1752(
1753    void *context,              /* Device channel handle */
1754    uint16_t chipAddr,                  /* chip address */
1755    uint8_t subAddr,                    /* 8-bit sub address */
1756    uint8_t *pData,             /* pointer to memory location to store read data  */
1757    size_t length                       /* number of bytes to read */
1758)
1759{
1760    BI2C_ChannelHandle hChn;
1761
1762    if (context == NULL)
1763    {
1764        BDBG_ERR(("Invalid I2C handle\n"));
1765        return BERR_INVALID_PARAMETER;
1766    }
1767
1768    hChn = (BI2C_ChannelHandle)context;
1769
1770#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
1771    if (BI2C_Is4ByteXfrMode(hChn) == true)
1772        return BI2C_P_ReadBy4BytesCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 1, pData, length, true /*mutex*/, true /*ack*/);
1773    else
1774#else
1775    if (hChn->burstMode)
1776        return BI2C_P_BurstReadCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 1, pData, length);
1777    else
1778#endif
1779        return BI2C_P_ReadCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 1, pData, length, true /*mutex*/, true /*ack*/);
1780}
1781
1782BERR_Code BI2C_P_ReadSw
1783(
1784    void *context,              /* Device channel handle */
1785    uint16_t chipAddr,                  /* chip address */
1786    uint8_t subAddr,                    /* 8-bit sub address */
1787    uint8_t *pData,             /* pointer to memory location to store read data  */
1788    size_t length                       /* number of bytes to read */
1789)
1790{
1791    return BI2C_P_ReadSwCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 1, pData, length, false /*EDDC*/, 0, true /*ack*/);
1792}
1793
1794BERR_Code BI2C_P_ReadNoAck
1795(
1796    void *context,              /* Device channel handle */
1797    uint16_t chipAddr,                  /* chip address */
1798    uint8_t subAddr,                    /* 8-bit sub address */
1799    uint8_t *pData,             /* pointer to memory location to store read data  */
1800    size_t length                       /* number of bytes to read */
1801)
1802{
1803    BI2C_ChannelHandle hChn;
1804
1805    if (context == NULL)
1806    {
1807        BDBG_ERR(("Invalid I2C handle\n"));
1808        return BERR_INVALID_PARAMETER;
1809    }
1810
1811    hChn = (BI2C_ChannelHandle)context;
1812
1813#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
1814    if (BI2C_Is4ByteXfrMode(hChn) == true)
1815        return BI2C_P_ReadBy4BytesCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 1, pData, length, true /*mutex*/, false /*ack*/);
1816    else
1817#else
1818    if (hChn->burstMode)
1819        return BI2C_P_BurstReadCmdNoAck ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 1, pData, length);
1820    else
1821#endif   
1822        return BI2C_P_ReadCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 1, pData, length, true /*mutex*/, false /*ack*/);
1823}
1824
1825BERR_Code BI2C_P_ReadSwNoAck
1826(
1827    void *context,              /* Device channel handle */
1828    uint16_t chipAddr,                  /* chip address */
1829    uint8_t subAddr,                    /* 8-bit sub address */
1830    uint8_t *pData,             /* pointer to memory location to store read data  */
1831    size_t length                       /* number of bytes to read */
1832)
1833{
1834    if (context == NULL)
1835    {
1836        BDBG_ERR(("Invalid I2C handle\n"));
1837        return BERR_INVALID_PARAMETER;
1838    }
1839
1840    return BI2C_P_ReadSwCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 1, pData, length, false /*EDDC*/, 0, false /*ack*/);
1841}
1842
1843BERR_Code BI2C_P_ReadA16
1844(
1845    void *context,              /* Device channel handle */
1846    uint16_t chipAddr,                  /* chip address */
1847    uint16_t subAddr,                   /* 16-bit sub address */
1848    uint8_t *pData,             /* pointer to memory location to store read data  */
1849    size_t length                       /* number of bytes to read */
1850)
1851{
1852    BI2C_ChannelHandle hChn;
1853
1854    if (context == NULL)
1855    {
1856        BDBG_ERR(("Invalid I2C handle\n"));
1857        return BERR_INVALID_PARAMETER;
1858    }
1859
1860    hChn = (BI2C_ChannelHandle)context;
1861
1862#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
1863    if (BI2C_Is4ByteXfrMode(hChn) == true)
1864        return BI2C_P_ReadBy4BytesCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 2, pData, length, true /*mutex*/, true /*ack*/);
1865    else
1866#else
1867    if (hChn->burstMode)
1868        return BI2C_P_BurstReadCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 2, pData, length);
1869    else
1870#endif   
1871        return BI2C_P_ReadCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 2, pData, length, true /*mutex*/, true /*ack*/);
1872}
1873
1874BERR_Code BI2C_P_ReadSwA16
1875(
1876    void *context,              /* Device channel handle */
1877    uint16_t chipAddr,                  /* chip address */
1878    uint16_t subAddr,                   /* 16-bit sub address */
1879    uint8_t *pData,             /* pointer to memory location to store read data  */
1880    size_t length                       /* number of bytes to read */
1881)
1882{
1883    BI2C_ChannelHandle hChn;
1884
1885    if (context == NULL)
1886    {
1887        BDBG_ERR(("Invalid I2C handle\n"));
1888        return BERR_INVALID_PARAMETER;
1889    }
1890
1891    hChn = (BI2C_ChannelHandle)context;
1892
1893    return BI2C_P_ReadSwCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 2, pData, length, false /*EDDC*/, 0, true /*ack*/);
1894}
1895
1896BERR_Code BI2C_P_ReadA24
1897(
1898    void *context,              /* Device channel handle */
1899    uint16_t chipAddr,                  /* chip address */
1900    uint32_t subAddr,                   /* 24-bit sub address */
1901    uint8_t *pData,             /* pointer to memory location to store read data  */
1902    size_t length                       /* number of bytes to read */
1903)
1904{
1905    BI2C_ChannelHandle hChn;
1906
1907    if (context == NULL)
1908    {
1909        BDBG_ERR(("Invalid I2C handle\n"));
1910        return BERR_INVALID_PARAMETER;
1911    }
1912
1913    hChn = (BI2C_ChannelHandle)context;
1914
1915#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
1916    if (BI2C_Is4ByteXfrMode(hChn) == true)
1917        return BI2C_P_ReadBy4BytesCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 3, pData, length, true /*mutex*/, true /*ack*/);
1918    else
1919#else
1920    if (hChn->burstMode)
1921        return BI2C_P_BurstReadCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 3, pData, length);
1922    else
1923#endif   
1924        return BI2C_P_ReadCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 3, pData, length, true /*mutex*/, true /*ack*/);
1925}
1926
1927BERR_Code BI2C_P_ReadSwA24
1928(
1929    void *context,              /* Device channel handle */
1930    uint16_t chipAddr,                  /* chip address */
1931    uint32_t subAddr,                   /* 24-bit sub address */
1932    uint8_t *pData,             /* pointer to memory location to store read data  */
1933    size_t length                       /* number of bytes to read */
1934)
1935{
1936    BI2C_ChannelHandle hChn;
1937
1938    if (context == NULL)
1939    {
1940        BDBG_ERR(("Invalid I2C handle\n"));
1941        return BERR_INVALID_PARAMETER;
1942    }
1943
1944    hChn = (BI2C_ChannelHandle)context;
1945
1946    return BI2C_P_ReadSwCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 3, pData, length, false /*EDDC*/, 0, true /*ack*/);
1947}
1948
1949BERR_Code BI2C_P_ReadNoAddr
1950(
1951    void *context,              /* Device channel handle */
1952    uint16_t chipAddr,                  /* chip address */
1953    uint8_t *pData,             /* pointer to memory location to store read data  */
1954    size_t length                       /* number of bytes to read */
1955)
1956{
1957    BI2C_ChannelHandle hChn;
1958
1959    if (context == NULL)
1960    {
1961        BDBG_ERR(("Invalid I2C handle\n"));
1962        return BERR_INVALID_PARAMETER;
1963    }
1964
1965    hChn = (BI2C_ChannelHandle)context;
1966
1967#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
1968    if (BI2C_Is4ByteXfrMode(hChn) == true)
1969        return BI2C_P_ReadBy4BytesCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)NULL, 0, pData, length, true /*mutex*/, true /*ack*/);
1970    else
1971#else
1972    if (hChn->burstMode)
1973        return BI2C_P_BurstReadCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)NULL, 0, pData, length);
1974    else
1975#endif   
1976        return BI2C_P_ReadCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)NULL, 0, pData, length, true /*mutex*/, true /*ack*/);
1977}
1978
1979BERR_Code BI2C_P_ReadSwNoAddr
1980(
1981    void *context,              /* Device channel handle */
1982    uint16_t chipAddr,                  /* chip address */
1983    uint8_t *pData,             /* pointer to memory location to store read data  */
1984    size_t length                       /* number of bytes to read */
1985)
1986{
1987    BI2C_ChannelHandle hChn;
1988
1989    if (context == NULL)
1990    {
1991        BDBG_ERR(("Invalid I2C handle\n"));
1992        return BERR_INVALID_PARAMETER;
1993    }
1994
1995    hChn = (BI2C_ChannelHandle)context;
1996
1997    return BI2C_P_ReadSwCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)NULL, 0, pData, length, false /*EDDC*/, 0, true /*ack*/);
1998}
1999
2000BERR_Code BI2C_P_ReadNoAddrNoAck
2001(
2002    void *context,              /* Device channel handle */
2003    uint16_t chipAddr,                  /* chip address */
2004    uint8_t *pData,             /* pointer to memory location to store read data  */
2005    size_t length                       /* number of bytes to read */
2006)
2007{
2008    BI2C_ChannelHandle hChn;
2009
2010    if (context == NULL)
2011    {
2012        BDBG_ERR(("Invalid I2C handle\n"));
2013        return BERR_INVALID_PARAMETER;
2014    }
2015
2016    hChn = (BI2C_ChannelHandle)context;
2017
2018#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
2019    if (BI2C_Is4ByteXfrMode(hChn) == true)
2020        return BI2C_P_ReadBy4BytesCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)NULL, 0, pData, length, true /*mutex*/, false /*ack*/);
2021    else
2022#else
2023    if (hChn->burstMode)
2024        return BI2C_P_BurstReadCmdNoAck ((BI2C_ChannelHandle)context, chipAddr, (void *)NULL, 0, pData, length);
2025    else
2026#endif   
2027        return BI2C_P_ReadCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)NULL, 0, pData, length, true /*mutex*/, false /*ack*/);
2028}
2029
2030BERR_Code BI2C_P_ReadSwNoAddrNoAck
2031(
2032    void *context,              /* Device channel handle */
2033    uint16_t chipAddr,                  /* chip address */
2034    uint8_t *pData,             /* pointer to memory location to store read data  */
2035    size_t length                       /* number of bytes to read */
2036)
2037{
2038    if (context == NULL)
2039    {
2040        BDBG_ERR(("Invalid I2C handle\n"));
2041        return BERR_INVALID_PARAMETER;
2042    }
2043
2044    return BI2C_P_ReadSwCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)NULL, 0, pData, length, false /*EDDC*/, 0, false /*ack*/);
2045}
2046
2047BERR_Code BI2C_P_Write
2048(
2049    void *context,              /* Device channel handle */
2050    uint16_t chipAddr,                  /* chip address */
2051    uint8_t subAddr,                    /* 8-bit sub address */
2052    const uint8_t *pData,               /* pointer to data to write */
2053    size_t length                       /* number of bytes to write */
2054)
2055{
2056#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
2057    if (BI2C_Is4ByteXfrMode((BI2C_ChannelHandle)context) == true)
2058        return BI2C_P_WriteBy4BytesCmd ((BI2C_ChannelHandle)context, chipAddr, subAddr, 1, pData, length, false /*NVRAM*/, true /*mutex*/, true /*ack*/);
2059    else
2060#endif   
2061        return BI2C_P_WriteCmd ((BI2C_ChannelHandle)context, chipAddr, subAddr, 1, pData, length, false /*NVRAM*/, true /*mutex*/, true /*ack*/);
2062}
2063
2064BERR_Code BI2C_P_WriteSw
2065(
2066    void *context,              /* Device channel handle */
2067    uint16_t chipAddr,                  /* chip address */
2068    uint8_t subAddr,                    /* 8-bit sub address */
2069    const uint8_t *pData,               /* pointer to data to write */
2070    size_t length                       /* number of bytes to write */
2071)
2072{
2073    return BI2C_P_WriteSwCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 1, pData, length, false /*NVRAM*/);
2074}
2075
2076BERR_Code BI2C_P_WriteNoAck
2077(
2078    void *context,              /* Device channel handle */
2079    uint16_t chipAddr,                  /* chip address */
2080    uint8_t subAddr,                    /* 8-bit sub address */
2081    const uint8_t *pData,               /* pointer to data to write */
2082    size_t length                       /* number of bytes to write */
2083)
2084{
2085#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
2086    if (BI2C_Is4ByteXfrMode((BI2C_ChannelHandle)context) == true)
2087        return BI2C_P_WriteBy4BytesCmd ((BI2C_ChannelHandle)context, chipAddr, subAddr, 1, pData, length, false /*NVRAM*/, true /*mutex*/, false /*ack*/);
2088    else
2089#endif
2090        return BI2C_P_WriteCmd ((BI2C_ChannelHandle)context, chipAddr, subAddr, 1, pData, length, false /*NVRAM*/, true /*mutex*/, false /*ack*/ );
2091}
2092
2093BERR_Code BI2C_P_WriteA16
2094(
2095    void *context,              /* Device channel handle */
2096    uint16_t chipAddr,                  /* chip address */
2097    uint16_t subAddr,                   /* 16-bit sub address */
2098    const uint8_t *pData,               /* pointer to data to write */
2099    size_t length                       /* number of bytes to write */
2100)
2101{
2102#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
2103    if (BI2C_Is4ByteXfrMode((BI2C_ChannelHandle)context) == true)
2104        return BI2C_P_WriteBy4BytesCmd ((BI2C_ChannelHandle)context, chipAddr, subAddr, 2, pData, length, false /*NVRAM*/, true /*mutex*/, true /*ack*/);
2105    else
2106#endif   
2107        return BI2C_P_WriteCmd ((BI2C_ChannelHandle)context, chipAddr, subAddr, 2, pData, length, false /*NVRAM*/, true /*mutex*/, true /*ack*/);
2108}
2109
2110BERR_Code BI2C_P_WriteSwA16
2111(
2112    void *context,              /* Device channel handle */
2113    uint16_t chipAddr,                  /* chip address */
2114    uint16_t subAddr,                   /* 16-bit sub address */
2115    const uint8_t *pData,               /* pointer to data to write */
2116    size_t length                       /* number of bytes to write */
2117)
2118{
2119    return BI2C_P_WriteSwCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 2, pData, length, false /*NVRAM*/);
2120}
2121
2122BERR_Code BI2C_P_WriteA24
2123(
2124    void *context,              /* Device channel handle */
2125    uint16_t chipAddr,                  /* chip address */
2126    uint32_t subAddr,                   /* 24-bit sub address */
2127    const uint8_t *pData,               /* pointer to data to write */
2128    size_t length                       /* number of bytes to write */
2129)
2130{
2131#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
2132    if (BI2C_Is4ByteXfrMode((BI2C_ChannelHandle)context) == true)
2133        return BI2C_P_WriteBy4BytesCmd ((BI2C_ChannelHandle)context, chipAddr, subAddr, 3, pData, length, false /*NVRAM*/, true /*mutex*/, true /*ack*/);
2134    else
2135#endif
2136        return BI2C_P_WriteCmd ((BI2C_ChannelHandle)context, chipAddr, subAddr, 3, pData, length, false /*NVRAM*/, true /*mutex*/, true /*ack*/);
2137}
2138
2139BERR_Code BI2C_P_WriteSwA24
2140(
2141    void *context,              /* Device channel handle */
2142    uint16_t chipAddr,                  /* chip address */
2143    uint32_t subAddr,                   /* 24-bit sub address */
2144    const uint8_t *pData,               /* pointer to data to write */
2145    size_t length                       /* number of bytes to write */
2146)
2147{
2148    return BI2C_P_WriteSwCmd ((BI2C_ChannelHandle)context, chipAddr, (void *)&subAddr, 3, pData, length, false /*NVRAM*/);
2149}
2150
2151BERR_Code BI2C_P_WriteNoAddr
2152(
2153    void *context,              /* Device channel handle */
2154    uint16_t chipAddr,                  /* chip address */
2155    const uint8_t *pData,               /* pointer to data to write */
2156    size_t length                       /* number of bytes to write */
2157)
2158{
2159#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
2160    if (BI2C_Is4ByteXfrMode((BI2C_ChannelHandle)context) == true)
2161        return BI2C_P_WriteBy4BytesCmd ((BI2C_ChannelHandle)context, chipAddr, 0, 0, pData, length, false /*NVRAM*/, true /*mutex*/, true /*ack*/);
2162    else
2163#endif   
2164        return BI2C_P_WriteCmd ((BI2C_ChannelHandle)context, chipAddr, 0, 0, pData, length, false /*NVRAM*/, true /*mutex*/, false /*ack*/);
2165}
2166
2167BERR_Code BI2C_P_WriteNoAddrNoAck
2168(
2169    void *context,              /* Device channel handle */
2170    uint16_t chipAddr,                  /* chip address */
2171    const uint8_t *pData,               /* pointer to data to write */
2172    size_t length                       /* number of bytes to write */
2173)
2174{
2175#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
2176    if (BI2C_Is4ByteXfrMode((BI2C_ChannelHandle)context) == true)
2177        return BI2C_P_WriteBy4BytesCmd ((BI2C_ChannelHandle)context, chipAddr, 0, 0, pData, length, false /*NVRAM*/, true /*mutex*/, false /*ack*/);
2178    else
2179#endif   
2180        return BI2C_P_WriteCmd ((BI2C_ChannelHandle)context, chipAddr, 0, 0, pData, length, false /*NVRAM*/, true /*mutex*/, false /*ack*/);
2181}
2182
2183BERR_Code BI2C_P_WriteNvram
2184(
2185    void *context,              /* Device channel handle */
2186    uint16_t chipAddr,                  /* chip address */
2187    uint8_t subAddr,                    /* 8-bit sub address */
2188    const uint8_t *pData,               /* pointer to data to write */
2189    size_t length                       /* number of bytes to write */
2190)
2191{
2192#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
2193    if (BI2C_Is4ByteXfrMode((BI2C_ChannelHandle)context) == true)
2194        return BI2C_P_WriteBy4BytesCmd ((BI2C_ChannelHandle)context, chipAddr, subAddr, 1, pData, length, true /*NVRAM*/, true /*mutex*/, true /*ack*/);
2195    else
2196#endif   
2197        return BI2C_P_WriteCmd ((BI2C_ChannelHandle)context, chipAddr, subAddr, 1, pData, length, true /*NVRAM*/, true /*mutex*/, true /*ack*/);
2198}
2199
2200BERR_Code BI2C_P_ReadEDDC(
2201    void                *context,               /* Device channel handle */
2202    uint8_t             chipAddr,               /* chip address */
2203    uint8_t             segment,                /* EDDC segment */
2204    uint8_t             subAddr,                /* 8-bit sub address */
2205    uint8_t             *pData,                 /* pointer to memory location to store read data */
2206    size_t              length                  /* number of bytes to read */
2207    )
2208{
2209    BERR_Code           retCode = BERR_SUCCESS;
2210    BI2C_Handle         hDev;
2211    BI2C_ChannelHandle  hChn = (BI2C_ChannelHandle)context;
2212    uint32_t            lval;
2213#if (BCHP_CHIP==3563)
2214    BI2C_Clk            eClkRate;
2215#endif
2216    BDBG_ASSERT( hChn );
2217    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
2218
2219    /* Get I2C handle from channel handle */
2220    hDev = hChn->hI2c;
2221
2222#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
2223    BI2C_P_ACQUIRE_MUTEX( hDev );
2224    /* Now, resource is lock, so work can begin, first config. IO ports */
2225    {
2226        int muxReg;
2227
2228#if (BCHP_CHIP==3563)
2229        eClkRate= BI2C_GetClk(hChn);
2230        BI2C_SetClk(hChn, eClkRate);
2231#endif
2232
2233        muxReg = BREG_Read32( hDev->hRegister, BCHP_PM_CONFIG );
2234        muxReg &= ~BCHP_MASK( PM_CONFIG, bsc_port_sel );
2235        muxReg |= BCHP_FIELD_DATA( PM_CONFIG, bsc_port_sel, hChn->chnNo );
2236        BREG_Write32( hDev->hRegister, BCHP_PM_CONFIG, muxReg );
2237    }
2238    /* Always use the first channel when configured for single I2C Master configuration */
2239    hChn = hDev->hI2cChn[0];
2240#else   
2241    BI2C_P_ACQUIRE_MUTEX( hChn );
2242#endif
2243
2244    /***********************************
2245     * Step 1: Write the segment pointer
2246     **********************************/
2247    #if 1
2248    /* program slave device's (id) */
2249    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), (uint32_t)EDDC_SEGMENT_CHIP_ADDR );
2250
2251    /* write segment pointer into fifo */
2252    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_IN0), (uint32_t)segment );
2253
2254    /* program amount of bytes to write/read */
2255    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), 1 );
2256
2257    /* program data transfer type */
2258    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
2259    lval &= ~(BCHP_BSCA_CTL_REG_reserved0_MASK | BCHP_BSCA_CTL_REG_DTF_MASK);
2260    lval |= BI2C_P_eWriteOnly ;
2261    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), lval );
2262
2263    /* ignore ack */
2264    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG));
2265    lval |= BCHP_BSCA_CTLHI_REG_IGNORE_ACK_MASK ;
2266    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG), lval );
2267
2268    /* start the write command */
2269    lval = (BCHP_BSCA_IIC_ENABLE_RESTART_MASK | BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK |
2270            BCHP_BSCA_IIC_ENABLE_ENABLE_MASK);
2271    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE), lval );
2272
2273    retCode = BI2C_P_WaitForCompletion(hChn, 1);
2274    if (retCode != BERR_SUCCESS)
2275        goto done;
2276
2277    /* get rid of ignore ack */
2278    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG));
2279    lval &= ~BCHP_BSCA_CTLHI_REG_IGNORE_ACK_MASK ;
2280    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG), lval );
2281    #else
2282    /* This needs to be tested */
2283    if (segment)
2284    {
2285        /* program slave device's (id) */
2286        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), (uint32_t)EDDC_SEGMENT_CHIP_ADDR );
2287
2288        /* Send only the 0x60 */
2289        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), 0 );
2290
2291        /* program data transfer type */
2292        lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
2293        lval &= ~(BCHP_BSCA_CTL_REG_reserved0_MASK | BCHP_BSCA_CTL_REG_DTF_MASK);
2294        lval |= BI2C_P_eWriteOnly ;
2295        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), lval );
2296
2297        /* ignore ack */
2298        lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG));
2299        lval |= BCHP_BSCA_CTLHI_REG_IGNORE_ACK_MASK ;
2300        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG), lval );
2301
2302        /* start the write command */
2303        lval = (/*BCHP_BSCA_IIC_ENABLE_RESTART_MASK | */BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK |
2304                BCHP_BSCA_IIC_ENABLE_ENABLE_MASK);
2305        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE), lval );
2306
2307        retCode = BI2C_P_WaitForCompletion(hChn, 1);
2308        if (retCode != BERR_SUCCESS)
2309            goto done;
2310
2311        /* write segment pointer into fifo */
2312        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_IN0), (uint32_t)segment );
2313
2314        /* Send the segment pointer now */
2315        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), 1 );
2316
2317        /* check ack */
2318        lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG));
2319        lval &= ~BCHP_BSCA_CTLHI_REG_IGNORE_ACK_MASK ;
2320        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG), lval );
2321
2322        /* start the write command */
2323        lval = (BCHP_BSCA_IIC_ENABLE_RESTART_MASK | BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK |
2324                BCHP_BSCA_IIC_ENABLE_NO_START_MASK | BCHP_BSCA_IIC_ENABLE_ENABLE_MASK);
2325        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE), lval );
2326
2327        retCode = BI2C_P_WaitForCompletion(hChn, 1);
2328        if (retCode != BERR_SUCCESS)
2329            goto done;
2330    }
2331    #endif
2332
2333    /****************************************
2334     * Step 2: Read the data with sub address
2335     ***************************************/
2336
2337#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
2338    if (BI2C_Is4ByteXfrMode(hChn) == true)
2339        retCode = BI2C_P_ReadBy4BytesCmd (hChn, chipAddr, (void *)&subAddr, 1, pData, length, false /*mutex*/, true /*ack*/);
2340    else
2341#endif
2342        retCode = BI2C_P_ReadCmd (hChn, chipAddr, (void *)&subAddr, 1, pData, length, false /*mutex*/, true /*ack*/);
2343
2344done:
2345#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
2346    BI2C_P_RELEASE_MUTEX( hDev );
2347#else
2348    BI2C_P_RELEASE_MUTEX( hChn );
2349#endif
2350    return( retCode );
2351}
2352
2353BERR_Code BI2C_P_ReadSwEDDC(
2354    void                *context,               /* Device channel handle */
2355    uint8_t             chipAddr,               /* chip address */
2356    uint8_t             segment,                /* EDDC segment */
2357    uint8_t             subAddr,                /* 8-bit sub address */
2358    uint8_t             *pData,                 /* pointer to memory location to store read data */
2359    size_t              length                  /* number of bytes to read */
2360    )
2361{
2362    BERR_Code           retCode = BERR_SUCCESS;
2363    BI2C_ChannelHandle  hChn = (BI2C_ChannelHandle)context;
2364
2365    BDBG_ASSERT( hChn );
2366    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
2367
2368    retCode = BI2C_P_ReadSwCmd (hChn, chipAddr, (void *)&subAddr, 1, pData, length, true /*EDDC*/, segment, true /*ack*/);
2369
2370    return( retCode );
2371}
2372
2373BERR_Code BI2C_P_WriteEDDC(
2374    void                *context,       /* Device channel handle */
2375    uint8_t             chipAddr,       /* chip address */
2376    uint8_t             segment,        /* EDDC segment */
2377    uint8_t             subAddr,        /* 8-bit sub address */
2378    const uint8_t       *pData,         /* pointer to data to write */
2379    size_t              length          /* number of bytes to read */
2380    )
2381{
2382    BERR_Code           retCode = BERR_SUCCESS;
2383    BI2C_Handle         hDev;
2384    BI2C_ChannelHandle  hChn = (BI2C_ChannelHandle)context;
2385    uint32_t            lval;
2386#if (BCHP_CHIP==3563)
2387    BI2C_Clk            eClkRate;
2388#endif
2389    BDBG_ASSERT( hChn );
2390    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
2391
2392    /* Get I2C handle from channel handle */
2393    hDev = hChn->hI2c;
2394
2395#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
2396    BI2C_P_ACQUIRE_MUTEX( hDev );
2397    /* Now, resource is lock, so work can begin, first config. IO ports */
2398    {
2399        int muxReg;
2400#if (BCHP_CHIP==3563)
2401        eClkRate = BI2C_GetClk(hChn);
2402        BI2C_SetClk(hChn, eClkRate);
2403#endif
2404        muxReg = BREG_Read32( hDev->hRegister, BCHP_PM_CONFIG );
2405        muxReg &= ~BCHP_MASK( PM_CONFIG, bsc_port_sel );
2406        muxReg |= BCHP_FIELD_DATA( PM_CONFIG, bsc_port_sel, hChn->chnNo );
2407        BREG_Write32( hDev->hRegister, BCHP_PM_CONFIG, muxReg );
2408    }
2409    /* Always use the first channel when configured for single I2C Master configuration */
2410    hChn = hDev->hI2cChn[0];
2411#else   
2412    BI2C_P_ACQUIRE_MUTEX( hChn );
2413#endif
2414
2415    /***********************************
2416     * Step 1: Write the segment pointer
2417     **********************************/
2418    /* program slave device's (id) */
2419    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), (uint32_t)EDDC_SEGMENT_CHIP_ADDR );
2420
2421    /* write segment pointer into fifo */
2422    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_IN0), (uint32_t)segment );
2423
2424    /* program amount of bytes to write/read */
2425    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), 1 );
2426
2427    /* program data transfer type */
2428    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
2429    lval &= ~(BCHP_BSCA_CTL_REG_reserved0_MASK | BCHP_BSCA_CTL_REG_DTF_MASK);
2430    lval |= BI2C_P_eWriteOnly ;
2431    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), lval );
2432
2433    /* ignore ack */
2434    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG));
2435    lval |= BCHP_BSCA_CTLHI_REG_IGNORE_ACK_MASK ;
2436    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG), lval );
2437
2438    /* start the write command */
2439    lval = (BCHP_BSCA_IIC_ENABLE_RESTART_MASK | BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK |
2440            BCHP_BSCA_IIC_ENABLE_ENABLE_MASK);
2441    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE), lval );
2442
2443    retCode = BI2C_P_WaitForCompletion(hChn, 1);
2444    if (retCode != BERR_SUCCESS)
2445        goto done;
2446
2447    /* get rid of ignore ack */
2448    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG));
2449    lval &= ~BCHP_BSCA_CTLHI_REG_IGNORE_ACK_MASK ;
2450    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG), lval );
2451
2452    /****************************************
2453     * Step 2: Write the data with sub address
2454     ***************************************/
2455
2456#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
2457    if (BI2C_Is4ByteXfrMode((BI2C_ChannelHandle)context) == true)
2458        retCode = BI2C_P_WriteBy4BytesCmd (hChn, chipAddr, subAddr, 1, pData, length, false /*NVRAM*/, false /*mutex*/, true /*ack*/);
2459    else
2460#endif
2461    retCode = BI2C_P_WriteCmd (hChn, chipAddr, subAddr, 1, pData, length, false /*NVRAM*/, false /*mutex*/, true /*ack*/);
2462
2463done:
2464#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
2465    BI2C_P_RELEASE_MUTEX( hDev );
2466#else
2467    BI2C_P_RELEASE_MUTEX( hChn );
2468#endif
2469    return( retCode );
2470}
2471
2472#define I2C_MUX_CTRL_SCL(ch, sun_top, sgpio) \
2473    i2c_gpio[ch].sun_top_scl_reg = sun_top; \
2474    i2c_gpio[ch].sun_top_scl_shift = sun_top##_##sgpio##_SHIFT; \
2475    i2c_gpio[ch].sun_top_scl_mask = sun_top##_##sgpio##_MASK;
2476
2477#define I2C_MUX_CTRL_SDA(ch, sun_top, sgpio) \
2478    i2c_gpio[ch].sun_top_sda_reg = sun_top; \
2479    i2c_gpio[ch].sun_top_sda_shift = sun_top##_##sgpio##_SHIFT; \
2480    i2c_gpio[ch].sun_top_sda_mask = sun_top##_##sgpio##_MASK;
2481
2482#define I2C_GPIO(ext_or_hi) \
2483    { \
2484        int i; \
2485        for (i=0; i<BI2C_MAX_I2C_MSTR_CHANNELS; i++) \
2486        { \
2487            i2c_gpio[i].gio_data_scl_reg = BCHP_GIO_DATA_##ext_or_hi; \
2488            i2c_gpio[i].gio_data_sda_reg = BCHP_GIO_DATA_##ext_or_hi; \
2489            i2c_gpio[i].gio_iodir_scl_reg = BCHP_GIO_IODIR_##ext_or_hi; \
2490            i2c_gpio[i].gio_iodir_sda_reg = BCHP_GIO_IODIR_##ext_or_hi; \
2491            i2c_gpio[i].gio_oden_scl_reg = BCHP_GIO_ODEN_##ext_or_hi; \
2492            i2c_gpio[i].gio_oden_sda_reg = BCHP_GIO_ODEN_##ext_or_hi; \
2493            i2c_gpio[i].gio_scl_mask = (1 << i*2); \
2494            i2c_gpio[i].gio_sda_mask = (1 << (i*2+1)); \
2495        } \
2496    }
2497
2498#define I2C_GPIO_AON_SCL_LO(ch, gpio) \
2499    i2c_gpio[ch].gio_data_scl_reg = BCHP_GIO_AON_DATA_LO; \
2500    i2c_gpio[ch].gio_iodir_scl_reg = BCHP_GIO_AON_IODIR_LO; \
2501    i2c_gpio[ch].gio_oden_scl_reg = BCHP_GIO_AON_ODEN_LO; \
2502    i2c_gpio[ch].gio_scl_mask = (1 << gpio);
2503
2504#define I2C_GPIO_AON_SDA_LO(ch, gpio) \
2505    i2c_gpio[ch].gio_data_sda_reg = BCHP_GIO_AON_DATA_LO; \
2506    i2c_gpio[ch].gio_iodir_sda_reg = BCHP_GIO_AON_IODIR_LO; \
2507    i2c_gpio[ch].gio_oden_sda_reg = BCHP_GIO_AON_ODEN_LO; \
2508    i2c_gpio[ch].gio_sda_mask = (1 << gpio);
2509
2510#define I2C_GPIO_AON_SCL_EXT(ch, gpio) \
2511    i2c_gpio[ch].gio_data_scl_reg = BCHP_GIO_AON_DATA_EXT; \
2512    i2c_gpio[ch].gio_iodir_scl_reg = BCHP_GIO_AON_IODIR_EXT; \
2513    i2c_gpio[ch].gio_oden_scl_reg = BCHP_GIO_AON_ODEN_EXT; \
2514    i2c_gpio[ch].gio_scl_mask = (1 << gpio);
2515
2516#define I2C_GPIO_AON_SDA_EXT(ch, gpio) \
2517    i2c_gpio[ch].gio_data_sda_reg = BCHP_GIO_AON_DATA_EXT; \
2518    i2c_gpio[ch].gio_iodir_sda_reg = BCHP_GIO_AON_IODIR_EXT; \
2519    i2c_gpio[ch].gio_oden_sda_reg = BCHP_GIO_AON_ODEN_EXT; \
2520    i2c_gpio[ch].gio_sda_mask = (1 << gpio);
2521
2522#define I2C_GPIO_SCL_EXT(ch, gpio) \
2523    i2c_gpio[ch].gio_data_scl_reg = BCHP_GIO_DATA_EXT; \
2524    i2c_gpio[ch].gio_iodir_scl_reg = BCHP_GIO_IODIR_EXT; \
2525    i2c_gpio[ch].gio_oden_scl_reg = BCHP_GIO_ODEN_EXT; \
2526    i2c_gpio[ch].gio_scl_mask = (1 << gpio);
2527
2528#define I2C_GPIO_SDA_EXT(ch, gpio) \
2529    i2c_gpio[ch].gio_data_sda_reg = BCHP_GIO_DATA_EXT; \
2530    i2c_gpio[ch].gio_iodir_sda_reg = BCHP_GIO_IODIR_EXT; \
2531    i2c_gpio[ch].gio_oden_sda_reg = BCHP_GIO_ODEN_EXT; \
2532    i2c_gpio[ch].gio_sda_mask = (1 << gpio);
2533
2534#define I2C_GPIO_SCL_LO(ch, gpio) \
2535    i2c_gpio[ch].gio_data_scl_reg = BCHP_GIO_DATA_LO; \
2536    i2c_gpio[ch].gio_iodir_scl_reg = BCHP_GIO_IODIR_LO; \
2537    i2c_gpio[ch].gio_oden_scl_reg = BCHP_GIO_ODEN_LO; \
2538    i2c_gpio[ch].gio_scl_mask = (1 << gpio);
2539
2540#define I2C_GPIO_SDA_LO(ch, gpio) \
2541    i2c_gpio[ch].gio_data_sda_reg = BCHP_GIO_DATA_LO; \
2542    i2c_gpio[ch].gio_iodir_sda_reg = BCHP_GIO_IODIR_LO; \
2543    i2c_gpio[ch].gio_oden_sda_reg = BCHP_GIO_ODEN_LO; \
2544    i2c_gpio[ch].gio_sda_mask = (1 << gpio);
2545
2546/***********************************************************************func
2547 * Name: BI2C_P_GpioInit
2548 *   -
2549 *
2550 * NOTE:
2551 ***************************************************************************/
2552void BI2C_P_GpioInit(void)
2553{
2554    #if (BI2C_SUPPORT_I2C_VIA_GPIO==1)
2555    /*
2556     * Ideally, this is the only section of code which needs to be modified in
2557     * order to support I2C via GPIO for a particular chip.  What we are doing
2558     * is mapping GPIO's to an i2c channel's SDA and SCL control lines.
2559     * Typically, it always involves SGPIO and:
2560     * SGPIO 0 maps to channel 0 SCL
2561     * SGPIO 1 maps to channel 0 SDA
2562     * SGPIO 2 maps to channel 1 SCL
2563     * SGPIO 3 maps to channel 1 SDA
2564     * etc
2565     * etc
2566     *
2567     * The only thing that differs is where the SGPIO's are placed, in terms
2568     * of BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_XX, and whether the SGPIO's are in
2569     * BCHP_GIO_DATA_EXT or BCHP_GIO_DATA_HI.
2570     *
2571     * Instructions:
2572     *
2573     * I2C_GPIO(EXT) or I2C_GPIO(HI)
2574     * - Use one depending on whether the sgpio's are mapped to
2575     *   BCHP_GIO_DATA_EXT or BCHP_GIO_DATA_HI
2576     *
2577     * I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_10, sgpio_00)
2578     * - The first parameter is the i2c channel
2579     * - The second parameter is which SUN_TOP_CTRL_PIN_MUX the
2580     *   corresponding sgpio is mapped to.
2581     * - The third parameter is the sgpio that is mapped to the i2c channel
2582     *   and SCL.
2583     *
2584     * I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_10, sgpio_00)
2585     * - The first parameter is the i2c channel
2586     * - The second parameter is which SUN_TOP_CTRL_PIN_MUX the
2587     *   corresponding sgpio is mapped to.
2588     * - The third parameter is the sgpio that is mapped to the i2c channel
2589     *   and SDA.
2590     *
2591     */
2592    #if (BCHP_CHIP==7038)
2593    I2C_GPIO(EXT);
2594    I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_10, sgpio_00);
2595    I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_10, sgpio_01);
2596    I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_02);
2597    I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_03);
2598    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_04);
2599    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_05);
2600    I2C_MUX_CTRL_SCL(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_06);
2601    I2C_MUX_CTRL_SDA(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_07);
2602    #elif (BCHP_CHIP==7231)
2603        I2C_GPIO(EXT);
2604        #if (BCHP_VER >= BCHP_VER_B0)
2605            I2C_MUX_CTRL_SCL(0, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, sgpio_00);
2606            I2C_MUX_CTRL_SDA(0, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, sgpio_01);
2607            I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_17, sgpio_02);
2608            I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_03);
2609            I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_04);
2610            I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_05);
2611            I2C_MUX_CTRL_SCL(3, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_2, aon_sgpio_00);
2612            I2C_MUX_CTRL_SDA(3, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_01);
2613        #else
2614            I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_17, sgpio_00);
2615            I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_01);
2616            I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_02);
2617            I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_03);
2618            I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_04);
2619            I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_05);
2620            I2C_MUX_CTRL_SCL(3, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_2, aon_sgpio_00);
2621            I2C_MUX_CTRL_SDA(3, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_01);
2622        #endif
2623    #elif (BCHP_CHIP==7325)
2624    I2C_GPIO(EXT);
2625    I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_00);
2626    I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_01);
2627    I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_02);
2628    I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_03);
2629    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_04);
2630    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_05);
2631    I2C_MUX_CTRL_SCL(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_06);
2632    I2C_MUX_CTRL_SDA(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_07);
2633    #elif (BCHP_CHIP==7335) || (BCHP_CHIP==7336)
2634    I2C_GPIO(EXT);
2635    I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_14, sgpio_00);
2636    I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_14, sgpio_01);
2637    I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_14, sgpio_02);
2638    I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_14, sgpio_03);
2639    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_14, sgpio_04);
2640    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_14, sgpio_05);
2641    I2C_MUX_CTRL_SCL(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_14, sgpio_06);
2642    I2C_MUX_CTRL_SDA(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_14, sgpio_07);
2643    #elif (BCHP_CHIP==7346)
2644    I2C_GPIO(EXT);
2645    I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_16, sgpio_00);
2646    I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_16, sgpio_01);
2647    I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_16, sgpio_02);
2648    I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_16, sgpio_03);
2649    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_16, sgpio_04);
2650    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_17, sgpio_05);
2651    I2C_MUX_CTRL_SCL(3, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_00);
2652    I2C_MUX_CTRL_SDA(3, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_01);
2653
2654    /* Extra SW I2C Master Channel */
2655    #if (EXTRA_SW_I2C_MSTR_CHANNELS == 1)
2656    I2C_GPIO_AON_SCL_LO(4, 2)
2657    I2C_GPIO_AON_SDA_LO(4, 3)
2658    I2C_MUX_CTRL_SCL(4, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_0, aon_gpio_002);
2659    I2C_MUX_CTRL_SDA(4, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_0, aon_gpio_003);
2660    #endif
2661
2662    #elif ((BCHP_CHIP==7400) || (BCHP_CHIP==7405))
2663    I2C_GPIO(EXT);
2664    I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_00);
2665    I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_01);
2666    I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_02);
2667    I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_03);
2668    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_04);
2669    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_05);
2670    I2C_MUX_CTRL_SCL(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_06);
2671    I2C_MUX_CTRL_SDA(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_07);
2672    #if (BCHP_CHIP==7400)
2673    I2C_MUX_CTRL_SCL(4, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_08);
2674    I2C_MUX_CTRL_SDA(4, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_09);
2675    #endif
2676    #elif (BCHP_CHIP==7413)
2677    I2C_GPIO(EXT);
2678    I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_00);
2679    I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_01);
2680    I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_02);
2681    I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_03);
2682    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_04);
2683    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_05);
2684    I2C_MUX_CTRL_SCL(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_06);
2685    I2C_MUX_CTRL_SDA(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_07);
2686    #elif (BCHP_CHIP==7420)
2687    I2C_GPIO(EXT);
2688    I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_21, sgpio_00);
2689    I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_21, sgpio_01);
2690    I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_21, sgpio_02);
2691    I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_21, sgpio_03);
2692    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_21, sgpio_04);
2693    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_21, sgpio_05);
2694    I2C_MUX_CTRL_SCL(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_21, sgpio_06);
2695    I2C_MUX_CTRL_SDA(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_22, sgpio_07);
2696    I2C_MUX_CTRL_SCL(4, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_22, sgpio_08);
2697    I2C_MUX_CTRL_SDA(4, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_22, sgpio_09);
2698    #elif (BCHP_CHIP==7422) || (BCHP_CHIP==7425)
2699        #if (BCHP_VER < BCHP_VER_B0)
2700            /*
2701                The BSCx mapping to BSC_Mx does not have the normal one-to-one correspondence.
2702                I.e.,
2703                    BSC_M0 is BSCD (should be BSCA)
2704                    BSC_M1 is BSCE (should be BSCB)
2705                    BSC_M2 is BSCA (should be BSCC)
2706                    BSC_M3 is BSCB (should be BSCD)
2707                    BSC_M4 is BSCC (should be BSCE)
2708                Therefore , the following mapping will have to be hacked to accomodate this.
2709                    I2C_GPIO(EXT);
2710                    I2C_MUX_CTRL_SCL(0, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_2, aon_sgpio_00);
2711                    I2C_MUX_CTRL_SDA(0, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_01);
2712                    I2C_MUX_CTRL_SCL(1, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_02);
2713                    I2C_MUX_CTRL_SDA(1, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_03);
2714                    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_00);
2715                    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_01);
2716                    I2C_MUX_CTRL_SCL(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_02);
2717                    I2C_MUX_CTRL_SDA(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_03);
2718                    I2C_MUX_CTRL_SCL(4, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_04);
2719                    I2C_MUX_CTRL_SDA(4, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_05);
2720            */
2721            I2C_GPIO(EXT);
2722            I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_00);
2723            I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_01);
2724            I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_02);
2725            I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_03);
2726            I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_04);
2727            I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_05);
2728            I2C_MUX_CTRL_SCL(3, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_2, aon_sgpio_00);
2729            I2C_MUX_CTRL_SDA(3, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_01);
2730            I2C_MUX_CTRL_SCL(4, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_02);
2731            I2C_MUX_CTRL_SDA(4, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_03);
2732        #else
2733            /* I2C_GPIO(EXT); */
2734            I2C_GPIO_AON_SCL_EXT(0, 0); /* aon_sgpio_00 */
2735            I2C_GPIO_AON_SDA_EXT(0, 1); /* aon_sgpio_01 */                     
2736            I2C_GPIO_AON_SCL_EXT(1, 2); /* aon_sgpio_02 */
2737            I2C_GPIO_AON_SDA_EXT(1, 3); /* aon_sgpio_03 */
2738            I2C_GPIO_SCL_EXT(2, 0); /* sgpio_00 */
2739            I2C_GPIO_SDA_EXT(2, 1); /* sgpio_01 */
2740            I2C_GPIO_SCL_EXT(3, 2); /* sgpio_02 */
2741            I2C_GPIO_SDA_EXT(3, 3); /* sgpio_03 */                     
2742            I2C_GPIO_AON_SCL_EXT(4, 4); /* aon_sgpio_04 */
2743            I2C_GPIO_AON_SDA_EXT(4, 5); /* aon_sgpio_05 */
2744            I2C_MUX_CTRL_SCL(0, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_2, aon_sgpio_00);
2745            I2C_MUX_CTRL_SDA(0, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_2, aon_sgpio_01);
2746            I2C_MUX_CTRL_SCL(1, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_02);
2747            I2C_MUX_CTRL_SDA(1, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_03);
2748            I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_00);
2749            I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_01);
2750            I2C_MUX_CTRL_SCL(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_02);
2751            I2C_MUX_CTRL_SDA(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_03);
2752            I2C_MUX_CTRL_SDA(4, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_05);
2753            I2C_MUX_CTRL_SCL(4, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_04);
2754        #endif
2755    #elif (BCHP_CHIP==7429)
2756    /* I2C_GPIO(EXT); */
2757    I2C_GPIO_AON_SCL_EXT(0, 0); /* aon_sgpio_00 */
2758    I2C_GPIO_AON_SDA_EXT(0, 1); /* aon_sgpio_01 */                     
2759    I2C_GPIO_AON_SCL_EXT(1, 2); /* aon_sgpio_02 */
2760    I2C_GPIO_AON_SDA_EXT(1, 3); /* aon_sgpio_03 */
2761    I2C_GPIO_AON_SCL_EXT(2, 4); /* aon_sgpio_04 */
2762    I2C_GPIO_AON_SDA_EXT(2, 5); /* aon_sgpio_05 */
2763    I2C_GPIO_SCL_EXT(3, 0); /* sgpio_00 */
2764    I2C_GPIO_SDA_EXT(3, 1); /* sgpio_01 */
2765    I2C_GPIO_SCL_EXT(4, 2); /* sgpio_02 */
2766    I2C_GPIO_SDA_EXT(4, 3); /* sgpio_03 */                     
2767    I2C_MUX_CTRL_SCL(0, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_2, aon_sgpio_00);
2768    I2C_MUX_CTRL_SDA(0, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_01);
2769    I2C_MUX_CTRL_SCL(1, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_02);
2770    I2C_MUX_CTRL_SDA(1, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_03);
2771    I2C_MUX_CTRL_SCL(2, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_04);
2772    I2C_MUX_CTRL_SDA(2, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_05);
2773    I2C_MUX_CTRL_SCL(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_00);
2774    I2C_MUX_CTRL_SDA(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_01);
2775    I2C_MUX_CTRL_SCL(4, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_02);
2776    I2C_MUX_CTRL_SDA(4, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_03);
2777    #elif (BCHP_CHIP==7435)
2778    /* I2C_GPIO(EXT); */
2779    I2C_GPIO_AON_SCL_EXT(0, 0); /* aon_sgpio_00 */
2780    I2C_GPIO_AON_SDA_EXT(0, 1); /* aon_sgpio_01 */                     
2781    I2C_GPIO_AON_SCL_EXT(1, 2); /* aon_sgpio_02 */
2782    I2C_GPIO_AON_SDA_EXT(1, 3); /* aon_sgpio_03 */
2783    I2C_GPIO_SCL_EXT(2, 0); /* sgpio_00 */
2784    I2C_GPIO_SDA_EXT(2, 1); /* sgpio_01 */
2785    I2C_GPIO_SCL_EXT(3, 2); /* sgpio_02 */
2786    I2C_GPIO_SDA_EXT(3, 3); /* sgpio_03 */                     
2787    I2C_GPIO_AON_SCL_EXT(4, 4); /* aon_sgpio_04 */
2788    I2C_GPIO_AON_SDA_EXT(4, 5); /* aon_sgpio_05 */
2789    I2C_MUX_CTRL_SCL(0, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_2, aon_sgpio_00);
2790    I2C_MUX_CTRL_SDA(0, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_2, aon_sgpio_01);
2791    I2C_MUX_CTRL_SCL(1, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_02);
2792    I2C_MUX_CTRL_SDA(1, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_03);
2793    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_18, sgpio_00);
2794    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_01);
2795    I2C_MUX_CTRL_SCL(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_02);
2796    I2C_MUX_CTRL_SDA(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_19, sgpio_03);
2797    I2C_MUX_CTRL_SDA(4, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_05);
2798    I2C_MUX_CTRL_SCL(4, BCHP_AON_PIN_CTRL_PIN_MUX_CTRL_3, aon_sgpio_04);
2799    #elif (BCHP_CHIP==7601)
2800    I2C_GPIO(HI);
2801    I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_7, sgpio_00);
2802    I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_7, sgpio_01);
2803    I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_7, sgpio_02);
2804    I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_7, sgpio_03);
2805    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_7, sgpio_04);
2806    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_7, sgpio_05);
2807    #elif (BCHP_CHIP==7635)
2808    I2C_GPIO(EXT);
2809    I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_15, sgpio_00);
2810    I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_15, sgpio_01);
2811    I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_15, sgpio_02);
2812    I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_16, sgpio_03);
2813    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_16, sgpio_04);
2814    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_16, sgpio_05);
2815    #elif (BCHP_CHIP==7630)
2816    I2C_GPIO(EXT);
2817    I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_00);
2818    I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_01);
2819    I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_02);
2820    I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_03);
2821    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_04);
2822    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_13, sgpio_05);
2823    #elif (BCHP_CHIP==7550)
2824    /* left blank for now */
2825    #elif (BCHP_CHIP==7125)
2826    I2C_GPIO(EXT);
2827    I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_10, sgpio_00);
2828    I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_10, sgpio_01);
2829    I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_10, sgpio_02);
2830    I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_10, sgpio_03);
2831    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_10, sgpio_04);
2832    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_10, sgpio_05);
2833    I2C_MUX_CTRL_SCL(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_10, sgpio_06);
2834    I2C_MUX_CTRL_SDA(3, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_11, sgpio_07);
2835    #elif (BCHP_CHIP==7408)
2836    I2C_GPIO(EXT);
2837    I2C_MUX_CTRL_SCL(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_7, sgpio_00);
2838    I2C_MUX_CTRL_SDA(0, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_7, sgpio_01);
2839    I2C_MUX_CTRL_SCL(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_7, sgpio_02);
2840    I2C_MUX_CTRL_SDA(1, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_7, sgpio_03);
2841    I2C_MUX_CTRL_SCL(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_8, sgpio_04);
2842    I2C_MUX_CTRL_SDA(2, BCHP_SUN_TOP_CTRL_PIN_MUX_CTRL_8, sgpio_05);
2843    #else
2844    #error Unsupported chip at this time.  Need to define I2C GPIO mapping!
2845    #endif
2846    #endif
2847}
2848
2849/***********************************************************************func
2850 * Name: BI2C_P_Delay
2851 *   -
2852 *
2853 * NOTE:
2854 ***************************************************************************/
2855void BI2C_P_Delay(BI2C_Clk rate)
2856{
2857    /* If you get a compile error not having this function defined. You should have this defined
2858        in kernel interface. */
2859    /* bcmKNIDelay(10); */
2860/*
2861//  BKNI_Delay(7); // 43KHz
2862//  BKNI_Delay(6); // 48KHz
2863//  BKNI_Delay(5); // 54KHz
2864//  BKNI_Delay(4); // 57KHz
2865//  BKNI_Delay(3); // 67KHz
2866//  BKNI_Delay(2); // 81KHz
2867//  BKNI_Delay(1); // 98KHz
2868// no delay // 127KHz
2869*/
2870    switch (rate)
2871    {
2872        case BI2C_Clk_eClk47Khz:
2873            BKNI_Delay(7); /* 43KHz*/
2874        case BI2C_Clk_eClk50Khz:
2875            BKNI_Delay(6); /* 48KHz*/
2876            break;
2877        case BI2C_Clk_eClk93Khz:
2878            BKNI_Delay(2); /* 81KHz*/
2879            break;
2880        case BI2C_Clk_eClk100Khz:
2881/*            BKNI_Delay(1);*/
2882            break;
2883        case BI2C_Clk_eClk187Khz:
2884        case BI2C_Clk_eClk200Khz:
2885        case BI2C_Clk_eClk375Khz:
2886        case BI2C_Clk_eClk400Khz:
2887        default:
2888            break;
2889    }
2890}
2891
2892/***********************************************************************func
2893 * Name: BI2C_P_ClkSet
2894 *   - set the CLOCK bit high/low.
2895 *
2896 * NOTE:
2897 ***************************************************************************/
2898BERR_Code _BI2C_P_ClkSet(BREG_Handle hReg, int ch, int clk, BI2C_Clk rate)
2899{
2900    uint32_t data, count=0;
2901    uint32_t mask = i2c_gpio[ch].gio_scl_mask;
2902    uint32_t addr = i2c_gpio[ch].gio_data_scl_reg;
2903#define CLK_STRETCH_TIMEOUT 5000000 /* 5 seconds */
2904
2905    /* put in delay for timing purposes */
2906    BI2C_P_Delay(rate);
2907
2908    #ifdef RMW_METHOD
2909    /* read clk port */
2910    data = BREG_Read32(hReg, addr);
2911
2912    /* set CLOCK bit high/low */
2913    if (clk)
2914        data |= mask;
2915    else
2916        data &= ~mask;
2917
2918    /* write clk port with new CLOCK value */
2919    BREG_Write32(hReg, addr, data);
2920    #else
2921    BI2C_P_IodirScl(clk);
2922    #endif
2923
2924    /* clock stretching */
2925    if (clk)
2926    {
2927        /* we have to wait until we see clock is set before we leave. */
2928        while (!(BREG_Read32(hReg, addr) & mask))
2929        {
2930            BKNI_Delay(1);
2931            if(++count > CLK_STRETCH_TIMEOUT)
2932            {
2933                BDBG_ERR(("clock stretch timer expired\n"));
2934                return BERR_TIMEOUT;
2935            }
2936        }
2937    }
2938    else
2939    {
2940        /* dummy read to force the write to flush out */
2941        data = BREG_Read32(hReg, addr);
2942    }
2943
2944    return BERR_SUCCESS;
2945}
2946
2947/***********************************************************************func
2948 * Name: BI2C_P_DataSet
2949 *   - set the DATA bit high/low.
2950 *
2951 * NOTE:
2952 ***************************************************************************/
2953BERR_Code _BI2C_P_DataSet(BREG_Handle hReg, int ch, int data, BI2C_Clk rate)
2954{
2955    #ifdef RMW_METHOD
2956    uint32_t port_data;
2957    uint32_t addr = i2c_gpio[ch].gio_data_sda_reg;
2958    uint32_t mask = i2c_gpio[ch].gio_sda_mask;
2959    #endif
2960
2961    /* put in delay for timing purposes */
2962    BI2C_P_Delay(rate);
2963
2964    #ifdef RMW_METHOD
2965    port_data = BREG_Read32(hReg, addr);
2966    if (data)
2967        BREG_Write32(hReg, addr, port_data | mask);
2968    else
2969        BREG_Write32(hReg, addr, port_data & ~mask);
2970
2971    /* dummy read to force the write to flush out */
2972    port_data = BREG_Read32(hReg, addr);
2973    #else
2974    BI2C_P_IodirSda(data);
2975    #endif
2976
2977    return BERR_SUCCESS;
2978}
2979
2980/***********************************************************************func
2981 * Name: BI2C_P_DataGet
2982 *   - returns the state of the DATA bit (high/low).
2983 *
2984 * NOTE:
2985 ***************************************************************************/
2986int _BI2C_P_DataGet(BREG_Handle hReg, int ch)
2987{
2988    uint32_t port_data;
2989
2990    port_data = BREG_Read32(hReg, i2c_gpio[ch].gio_data_sda_reg);
2991
2992    /* return state of DATA bit */
2993    if (port_data & i2c_gpio[ch].gio_sda_mask)
2994        return 1;
2995    else return 0;
2996}
2997
2998/***********************************************************************func
2999 * Name: _BI2C_P_ByteWrite
3000 *   - clocks out 1 bytes of data and returns the status
3001 *     of the Ack/Nack bit.
3002 *
3003 * NOTE:
3004 ***************************************************************************/
3005BERR_Code _BI2C_P_ByteWrite(BREG_Handle hReg, int ch, unsigned char data, BI2C_Clk rate, int *ret_ack)
3006{
3007    BERR_Code rc;
3008    unsigned char i;
3009
3010    /* clock out data byte */
3011    for (i = 0; i < 8; i++)
3012    {
3013        BI2C_P_ClkSet(0);
3014        BI2C_P_DataSet(data & 0x80);
3015        data = data << 1;
3016        if ((rc = BI2C_P_ClkSet(1)) != BERR_SUCCESS) return rc;
3017    }
3018
3019    BI2C_P_ClkSet(0);
3020    BI2C_P_DataSet(1);
3021
3022    /* read ack bit */
3023    if ((rc = BI2C_P_ClkSet(1)) != BERR_SUCCESS) return rc;
3024    *ret_ack = BI2C_P_DataGet();
3025    BI2C_P_ClkSet(0);
3026    BI2C_P_DataSet(0);
3027    return BERR_SUCCESS;
3028}
3029
3030/***********************************************************************func
3031 * Name: _BI2C_P_ByteRead
3032 *   - reads 1 bytes of data and returns the status of the
3033 *     Ack/Nack bit.
3034 *
3035 * NOTE:
3036 ***************************************************************************/
3037BERR_Code _BI2C_P_ByteRead(BREG_Handle hReg, int ch, int generate_ack, BI2C_Clk rate, unsigned char *ret_data)
3038{
3039    BERR_Code rc;
3040    unsigned char data;
3041    unsigned char i;
3042
3043    /* initialize data to 0 */
3044    data = 0;
3045
3046    /* clock in data byte */
3047    for (i = 0; i < 8; i++)
3048    {
3049        BI2C_P_ClkSet(0);
3050        BI2C_P_DataSet(1);
3051        if ((rc = BI2C_P_ClkSet(1)) != BERR_SUCCESS) return rc;
3052        data = (data << 1) | BI2C_P_DataGet();
3053    }
3054
3055    BI2C_P_ClkSet(0);
3056
3057    /* generate Ack/Nack */
3058    if (generate_ack)
3059        BI2C_P_DataSet(0);
3060    else BI2C_P_DataSet(1);
3061
3062    /* clock in Ack/Nack */
3063    if ((rc = BI2C_P_ClkSet(1)) != BERR_SUCCESS) return rc;
3064    BI2C_P_ClkSet(0);
3065    BI2C_P_DataSet(0);
3066
3067    *ret_data = data;
3068    return BERR_SUCCESS;
3069}
3070
3071/***********************************************************************func
3072 * Name: BI2C_P_RegBitSet
3073 *   - set register bit, return previous value.
3074 *
3075 * NOTE:
3076 ***************************************************************************/
3077int BI2C_P_RegBitSet(BREG_Handle hReg, uint32_t addr, uint32_t mask, uint8_t val)
3078{
3079    uint32_t temp;
3080    temp = BREG_Read32(hReg, addr);
3081    if (val)
3082        BREG_Write32(hReg, addr, temp | mask);
3083    else
3084        BREG_Write32(hReg, addr, temp & ~mask);
3085
3086    /* Dummy read to force the flush out */
3087    BREG_Read32(hReg, addr);
3088    return ((temp & mask) ? 1 : 0);
3089}
3090
3091#if 0
3092/***********************************************************************func
3093 * Name: BI2C_P_RegFieldSet
3094 *   - set register field, return previous value.
3095 *
3096 * NOTE:
3097 ***************************************************************************/
3098int BI2C_P_RegFieldSet(BREG_Handle hReg, uint32_t addr, uint8_t shift, uint8_t val)
3099{
3100    uint32_t temp, masked;
3101    temp = BREG_Read32(hReg, addr);
3102
3103    /* modifying a 3 bit field */
3104    masked = temp & ~(0x3 << shift);
3105    BREG_Write32(hReg, addr, masked | (val << shift));
3106
3107    return ((temp >> shift) & 0x3);
3108}
3109#endif
3110
3111/***********************************************************************func
3112 * Name: _BI2C_P_SunTopScl
3113 *   - set register field, return previous value.
3114 *
3115 * NOTE:
3116 ***************************************************************************/
3117int _BI2C_P_SunTopScl(BREG_Handle hReg, int ch, uint8_t val)
3118{
3119    uint32_t retval=0;
3120    uint32_t lval;
3121    uint32_t reg = i2c_gpio[ch].sun_top_scl_reg;
3122    uint32_t shift = i2c_gpio[ch].sun_top_scl_shift;
3123    uint32_t mask = i2c_gpio[ch].sun_top_scl_mask;
3124    if (ch<BI2C_MAX_I2C_MSTR_CHANNELS+EXTRA_SW_I2C_MSTR_CHANNELS)
3125    {
3126        lval = BREG_Read32 (hReg, reg);
3127        retval = (lval & mask) >> shift;
3128        lval &= ~mask;
3129        lval |= (val << shift);
3130        BREG_Write32 (hReg, reg, lval);
3131    }
3132    else
3133    {
3134        BDBG_ERR(("Unknown channel in BI2C_P_SunTopSda\n"));
3135    }
3136    return (retval);
3137}
3138
3139/***********************************************************************func
3140 * Name: _BI2C_P_SunTopSda
3141 *   - set register field, return previous value.
3142 *
3143 * NOTE:
3144 ***************************************************************************/
3145int _BI2C_P_SunTopSda(BREG_Handle hReg, int ch, uint8_t val)
3146{
3147    uint32_t retval=0;
3148    uint32_t lval;
3149    uint32_t reg = i2c_gpio[ch].sun_top_sda_reg;
3150    uint32_t shift = i2c_gpio[ch].sun_top_sda_shift;
3151    uint32_t mask = i2c_gpio[ch].sun_top_sda_mask;
3152
3153    if (ch<BI2C_MAX_I2C_MSTR_CHANNELS+EXTRA_SW_I2C_MSTR_CHANNELS)
3154    {
3155        lval = BREG_Read32 (hReg, reg);
3156        retval = (lval & mask) >> shift;
3157        lval &= ~mask;
3158        lval |= (val << shift);
3159        BREG_Write32 (hReg, reg, lval);
3160    }
3161    else
3162    {
3163        BDBG_ERR(("Unknown channel in BI2C_P_SunTopSda\n"));
3164    }
3165    return (retval);
3166}
3167
3168/***********************************************************************func
3169 * Name: BI2C_P_ReadSwCmd
3170 *   - Read data from i2c slave device.
3171 *       write (1 byte of slave device register's address, subAddr)
3172 *   and read  (0-8 bytes of data)
3173 *   Using i2c Write.& Read
3174 *
3175 * NOTE: This function will be called by BI2C_P_Read, BI2C_P_ReadA16, BI2C_P_ReadNoAddr
3176 ***************************************************************************/
3177BERR_Code BI2C_P_ReadSwCmd
3178(
3179    BI2C_ChannelHandle  hChn,           /* Device channel handle */
3180    uint16_t        chipAddr,           /* i2c chip address.  this is unshifted */
3181    void            *pSubAddr,          /* pointer to register address */
3182    uint8_t         numSubAddrBytes,    /* number of bytes in register address */
3183    uint8_t         *pData,             /* storage */
3184    size_t          numBytes,           /* number of bytes to read */
3185    bool            eddc,               /* EDDC mode */
3186    uint8_t         segment,            /* EDDC segment */
3187    bool            checkForAck         /* Check for ack? */
3188)
3189{
3190    #if (BI2C_SUPPORT_I2C_VIA_GPIO==1)
3191    uint16_t i;
3192    uint8_t oden_scl, oden_sda;
3193    uint8_t iodir_scl, iodir_sda;
3194    uint8_t sun_top_sda, sun_top_scl;
3195    int no_ack = 0;
3196    int ch = hChn->chnNo;
3197    BI2C_Handle hDev;
3198    BREG_Handle hReg;
3199    BI2C_Clk rate = hChn->clkRate;
3200    uint8_t lval;
3201    int ret_ack;
3202    BERR_Code rc;
3203    unsigned char ret_data;
3204    uint32_t subAddr = 0;
3205
3206    BDBG_ASSERT( hChn );
3207    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
3208    BDBG_ASSERT( numSubAddrBytes <= 3);
3209        BDBG_ASSERT( pData );
3210
3211#define RD 0x01
3212#define WR 0x00
3213
3214    /* Get I2C handle from channel handle */
3215    hDev = hChn->hI2c;
3216    hReg = hDev->hRegister;
3217
3218    sun_top_scl = BI2C_P_SunTopScl(0);
3219    sun_top_sda = BI2C_P_SunTopSda(0);
3220
3221    /* Set open drain output */
3222    oden_scl = BI2C_P_OdenScl(1);
3223    oden_sda = BI2C_P_OdenSda(1);
3224
3225    #ifdef RMW_METHOD
3226    /* reset CLOCK and DATA */
3227    BI2C_P_ClkSet(1);
3228    BI2C_P_DataSet(1);
3229
3230    /* Set gpio as output */
3231    iodir_scl = BI2C_P_IodirScl(0);
3232    iodir_sda = BI2C_P_IodirSda(0);
3233    #else
3234    /* Set iodir to output so we can change data */
3235    iodir_scl = BI2C_P_IodirScl(0);
3236    iodir_sda = BI2C_P_IodirSda(0);
3237
3238    /* Set data low for using iodir to control output */
3239    BI2C_P_DataScl(0);
3240    BI2C_P_DataSda(0);
3241
3242    /* Set iodir to input so we can start with SCL and SDA high */
3243    BI2C_P_IodirScl(1);
3244    BI2C_P_IodirSda(1);
3245        #endif
3246
3247    /* generate start condition */
3248    BI2C_P_DataSet(0);
3249
3250    if (eddc)
3251    {
3252        if (segment)
3253        {
3254            /* program slave device's (id) */
3255            /* BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), (uint32_t)EDDC_SEGMENT_CHIP_ADDR ); */
3256            if ((rc = BI2C_P_ByteWrite((unsigned char)(EDDC_SEGMENT_CHIP_ADDR), &ret_ack)) != BERR_SUCCESS) goto no_success;
3257            if (ret_ack != I2C_ACK)
3258            {
3259                /*
3260                BDBG_ERR(("ignore no ack!\n"));
3261                no_ack = 1;
3262                */
3263            }
3264
3265            /* write segment pointer into fifo */
3266            /* BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_IN0), (uint32_t)segment ); */
3267            if ((rc = BI2C_P_ByteWrite((unsigned char)(segment), &ret_ack)) != BERR_SUCCESS) goto no_success;
3268            if (ret_ack != I2C_ACK)
3269            {
3270                BDBG_ERR(("no ack!\n"));
3271                no_ack = 1;
3272                goto no_ack_detected;
3273            }
3274
3275            /* generate repeated start condition */
3276            BI2C_P_DataSet(1);
3277            BI2C_P_ClkSet(1);
3278            BI2C_P_DataSet(0);
3279        }
3280    }
3281
3282    if (numSubAddrBytes)
3283    {
3284        /* Send out the chip address with a write */
3285        if (chipAddr & 0x0380)              /* 10-bit chip address */
3286        {
3287            /* Send bits 9 and 8 */
3288            lval = ((chipAddr & 0x0300) >> 7) | 0xF0;
3289            if ((rc = BI2C_P_ByteWrite(lval | WR, &ret_ack)) != BERR_SUCCESS) goto no_success;
3290            if (ret_ack != I2C_ACK)
3291            {
3292                BDBG_ERR(("no ack!\n"));
3293                no_ack = 1;
3294                goto no_ack_detected;
3295            }
3296            /* Send the rest of the bits */
3297            lval = chipAddr & 0xff;
3298            if ((rc = BI2C_P_ByteWrite(lval, &ret_ack)) != BERR_SUCCESS) goto no_success;
3299            if (checkForAck)
3300            {
3301                if (ret_ack != I2C_ACK)
3302                {
3303                    BDBG_ERR(("no ack!\n"));
3304                    no_ack = 1;
3305                    goto no_ack_detected;
3306                }
3307            }
3308        }
3309        else
3310        {
3311            lval = (chipAddr & 0x7f) << 1;
3312            if ((rc = BI2C_P_ByteWrite(lval | WR, &ret_ack)) != BERR_SUCCESS) goto no_success;
3313            if (checkForAck)
3314            {
3315                if (ret_ack != I2C_ACK)
3316                {
3317                    BDBG_ERR(("no ack!\n"));
3318                    no_ack = 1;
3319                    goto no_ack_detected;
3320                }
3321            }
3322        }
3323
3324        if (numSubAddrBytes==3)
3325        {
3326            uint32_t subAddr32 = subAddr = *((uint32_t *)pSubAddr);
3327            lval = (uint8_t)((subAddr32 >> 16) & 0xff);
3328            if ((rc = BI2C_P_ByteWrite(lval, &ret_ack)) != BERR_SUCCESS) goto no_success;
3329            if (checkForAck)
3330            {
3331                if (ret_ack != I2C_ACK)
3332                {
3333                    BDBG_ERR(("no ack!\n"));
3334                    no_ack = 1;
3335                    goto no_ack_detected;
3336                }
3337            }
3338            lval = (uint8_t)((subAddr32 >> 8) & 0xff);
3339            if ((rc = BI2C_P_ByteWrite(lval, &ret_ack)) != BERR_SUCCESS) goto no_success;
3340            if (checkForAck)
3341            {
3342                if (ret_ack != I2C_ACK)
3343                {
3344                    BDBG_ERR(("no ack!\n"));
3345                    no_ack = 1;
3346                    goto no_ack_detected;
3347                }
3348            }
3349            lval = (uint8_t)(subAddr32 & 0xff);
3350            if ((rc = BI2C_P_ByteWrite(lval, &ret_ack)) != BERR_SUCCESS) goto no_success;
3351            if (checkForAck)
3352            {
3353                if (ret_ack != I2C_ACK)
3354                {
3355                    BDBG_ERR(("no ack!\n"));
3356                    no_ack = 1;
3357                    goto no_ack_detected;
3358                }
3359            }
3360        }
3361        else if (numSubAddrBytes==2)
3362        {
3363            uint16_t subAddr16 = subAddr = *((uint16_t *)pSubAddr);
3364            lval = (uint8_t)((subAddr16 >> 8) & 0xff);
3365            if ((rc = BI2C_P_ByteWrite(lval, &ret_ack)) != BERR_SUCCESS) goto no_success;
3366            if (checkForAck)
3367            {
3368                if (ret_ack != I2C_ACK)
3369                {
3370                    BDBG_ERR(("no ack!\n"));
3371                    no_ack = 1;
3372                    goto no_ack_detected;
3373                }
3374            }
3375            lval = (uint8_t)(subAddr16 & 0xff);
3376            if ((rc = BI2C_P_ByteWrite(lval, &ret_ack)) != BERR_SUCCESS) goto no_success;
3377            if (checkForAck)
3378            {
3379                if (ret_ack != I2C_ACK)
3380                {
3381                    BDBG_ERR(("no ack!\n"));
3382                    no_ack = 1;
3383                    goto no_ack_detected;
3384                }
3385            }
3386        }
3387        else if (numSubAddrBytes==1)
3388        {
3389            uint8_t subAddr8 = subAddr = *((uint8_t *)pSubAddr);
3390            lval = (uint8_t)(subAddr8 & 0xff);
3391            if ((rc = BI2C_P_ByteWrite(lval, &ret_ack)) != BERR_SUCCESS) goto no_success;
3392            if (checkForAck)
3393            {
3394                if (ret_ack != I2C_ACK)
3395                {
3396                    BDBG_ERR(("no ack!\n"));
3397                    no_ack = 1;
3398                    goto no_ack_detected;
3399                }
3400            }
3401        }
3402
3403        /* generate repeated start condition */
3404        BI2C_P_DataSet(1);
3405        BI2C_P_ClkSet(1);
3406        BI2C_P_DataSet(0);
3407    }
3408
3409    /* Start the read transaction.  Must send out the address again. */
3410    if (chipAddr & 0x0380)              /* 10-bit chip address */
3411    {
3412        /* Send bits 9 and 8.  Do not need to send the rest of the 10 bit address. */
3413        lval = ((chipAddr & 0x0300) >> 7) | 0xF0;
3414        if ((rc = BI2C_P_ByteWrite(lval | RD, &ret_ack)) != BERR_SUCCESS) goto no_success;
3415        if (checkForAck)
3416        {
3417            if (ret_ack != I2C_ACK)
3418            {
3419                BDBG_ERR(("no ack!\n"));
3420                no_ack = 1;
3421                goto no_ack_detected;
3422            }
3423        }
3424    }
3425    else
3426    {
3427        lval = (chipAddr & 0x7f) << 1;
3428        if ((rc = BI2C_P_ByteWrite(lval | RD, &ret_ack)) != BERR_SUCCESS) goto no_success;
3429        if (checkForAck)
3430        {
3431            if (ret_ack != I2C_ACK)
3432            {
3433                BDBG_ERR(("no ack!\n"));
3434                no_ack = 1;
3435                goto no_ack_detected;
3436            }
3437        }
3438    }
3439
3440    for (i = 0; i < (numBytes-1); i++)
3441    {
3442        if ((rc = BI2C_P_ByteRead(1, &ret_data) != BERR_SUCCESS)) goto no_success;
3443        pData[i] = ret_data;
3444    }
3445    if ((rc = BI2C_P_ByteRead(0, &ret_data) != BERR_SUCCESS)) goto no_success;
3446    pData[i] = ret_data;
3447
3448no_success:
3449no_ack_detected:
3450    /* generate stop condition */
3451    BI2C_P_ClkSet(1);
3452    BI2C_P_DataSet(1);
3453
3454    /* restore iodir */
3455    BI2C_P_IodirScl(iodir_scl);
3456    BI2C_P_IodirSda(iodir_sda);
3457
3458    /* restore open drain output */
3459    BI2C_P_OdenScl(oden_scl);
3460    BI2C_P_OdenSda(oden_sda);
3461
3462    /* restore sun top */
3463    BI2C_P_SunTopScl(sun_top_scl);
3464    BI2C_P_SunTopSda(sun_top_sda);
3465
3466    BDBG_MSG(("BI2C_P_ReadSwCmd:  ch=%d, clkRate=%d, chipAddr=0x%x, numSubAddrBytes=%d, subAddr=0x%x, numBytes=%d, pData=0x%x\n", hChn->chnNo, hChn->clkRate, chipAddr, numSubAddrBytes, numSubAddrBytes ? subAddr : 0, numBytes, *(uint8_t *)pData));
3467
3468    if (no_ack) return BI2C_ERR_NO_ACK;
3469    else return BERR_SUCCESS;
3470    #else
3471    BSTD_UNUSED( hChn );
3472    BSTD_UNUSED( chipAddr );
3473    BSTD_UNUSED( pSubAddr );
3474    BSTD_UNUSED( numSubAddrBytes );
3475    BSTD_UNUSED( pData );
3476    BSTD_UNUSED( numBytes );
3477    BSTD_UNUSED( eddc );
3478    BSTD_UNUSED( segment);
3479        BSTD_UNUSED( checkForAck );
3480
3481    BDBG_ERR(("BI2C_P_ReadSwCmd called, but not currently supported.  Make sure the function BI2C_P_GpioInit() is setup properly for this chip.\n"));
3482    return BERR_NOT_SUPPORTED;
3483    #endif
3484}
3485
3486/***********************************************************************func
3487 * Name: BI2C_P_ReadCmd
3488 *   - Read data from i2c slave device.
3489 *       write (1 byte of slave device register's address, subAddr)
3490 *   and read  (0-8 bytes of data)
3491 *   Using i2c Write.& Read
3492 *
3493 * NOTE: This function will be called by BI2C_P_Read, BI2C_P_ReadA16, BI2C_P_ReadNoAddr
3494 ***************************************************************************/
3495BERR_Code BI2C_P_ReadCmd
3496(
3497    BI2C_ChannelHandle  hChn,           /* Device channel handle */
3498    uint16_t        chipAddr,           /* i2c chip address.  this is unshifted */
3499    void            *pSubAddr,          /* pointer to register address */
3500    uint8_t         numSubAddrBytes,    /* number of bytes in register address */
3501    uint8_t         *pData,             /* storage */
3502    size_t          numBytes,           /* number of bytes to read */
3503    bool            mutex,              /* protect with a mutex */
3504    bool            ack                 /* check for ack? */
3505)
3506{
3507    BI2C_Handle         hDev;
3508    BERR_Code           retCode = BERR_SUCCESS;
3509#if 0
3510    BERR_Code           rc = BERR_SUCCESS;
3511#endif
3512    uint8_t             numWriteBytes = 0;
3513    uint32_t            subAddr24;
3514    uint16_t            subAddr16;
3515    uint8_t             subAddr8;
3516#if !BI2C_MSB_FIX
3517    uint32_t            bscRegAddr, readCmdWord, bufferIndex, lval = 0, i;
3518#else
3519    uint32_t            bscRegAddr, bufferIndex, lval = 0, i;
3520#endif
3521    size_t              cnt;
3522#if (BCHP_CHIP==3563)
3523    BI2C_Clk            eClkRate;
3524#endif
3525    BDBG_ASSERT( hChn );
3526    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
3527    BDBG_ASSERT( pData );
3528
3529    /* Get I2C handle from channel handle */
3530    hDev = hChn->hI2c;
3531
3532#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
3533    BI2C_P_ACQUIRE_MUTEX( hDev );
3534    /* Now, resource is lock, so work can begin, first config. IO ports */
3535    {
3536        int muxReg;
3537#if (BCHP_CHIP==3563)
3538        eClkRate= BI2C_GetClk(hChn);
3539        BI2C_SetClk(hChn, eClkRate);
3540#endif
3541        muxReg = BREG_Read32( hDev->hRegister, BCHP_PM_CONFIG );
3542        muxReg &= ~BCHP_MASK( PM_CONFIG, bsc_port_sel );
3543        muxReg |= BCHP_FIELD_DATA( PM_CONFIG, bsc_port_sel, hChn->chnNo );
3544        BREG_Write32( hDev->hRegister, BCHP_PM_CONFIG, muxReg );
3545    }
3546    /* Always use the first channel when configured for single I2C Master configuration */
3547    hChn = hDev->hI2cChn[0];
3548#else   
3549    if (mutex)
3550        BI2C_P_ACQUIRE_MUTEX( hChn );
3551#endif
3552
3553    /* program slave device's (id) */
3554    if (chipAddr & 0x0380)              /* 10-bit chip address */
3555    {
3556        lval = ((chipAddr & 0x0300) >> 7) | 0xF0;
3557        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), lval );
3558        lval = (uint32_t)(chipAddr & 0xff);
3559        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_IN0), lval );
3560        bscRegAddr = BCHP_BSCA_DATA_IN1;
3561        numWriteBytes++;
3562    }
3563    else
3564    {
3565        lval = (uint32_t) ((chipAddr & 0x7f) << 1);
3566        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), lval );
3567        bscRegAddr = BCHP_BSCA_DATA_IN0;
3568    }
3569
3570    if (numSubAddrBytes)    /* read with sub addr, must issue a write */
3571    {
3572        /* program slave device's register address */
3573        if (numSubAddrBytes == 3)
3574        {
3575            subAddr24 = *((uint32_t *)pSubAddr);
3576            lval = (uint32_t)(subAddr24 >> 16);
3577            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
3578            bscRegAddr += 4;
3579            lval = (uint32_t)((subAddr24 >> 8) & 0xff);
3580            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
3581            bscRegAddr += 4;
3582            lval = (uint32_t)(subAddr24 & 0xff);
3583            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
3584            bscRegAddr += 4;
3585            numWriteBytes += 3;
3586        }
3587        else if (numSubAddrBytes == 2)
3588        {
3589            subAddr16 = *((uint16_t *)pSubAddr);
3590            lval = (uint32_t)(subAddr16 >> 8);
3591            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
3592            bscRegAddr += 4;
3593            lval = (uint32_t)(subAddr16 & 0xff);
3594            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
3595            bscRegAddr += 4;
3596            numWriteBytes += 2;
3597        }
3598        else if (numSubAddrBytes == 1)
3599        {
3600            subAddr8 = *((uint8_t *)pSubAddr);
3601            lval = (uint32_t)(subAddr8 & 0xff);
3602            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
3603            bscRegAddr += 4;
3604            numWriteBytes++;
3605        }
3606
3607        /* program amount of bytes to write/read */
3608        lval = (uint32_t)(numWriteBytes & 0x0f);
3609        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), lval );
3610
3611        /* program data transfer type */
3612        lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
3613        lval &= ~(BCHP_BSCA_CTL_REG_reserved0_MASK | BCHP_BSCA_CTL_REG_DTF_MASK);
3614        lval |= BI2C_P_eWriteOnly ;
3615        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), lval );
3616
3617        if (!ack)
3618        {
3619            /* Mao Neil: ignore ack */
3620            /* printf("Disable the acknowledge!\n\n"); */
3621            lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG));
3622            lval |= 0x2;
3623            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG), lval );
3624        }
3625
3626        /* start the write command */
3627        lval = (BCHP_BSCA_IIC_ENABLE_RESTART_MASK | BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK |
3628                BCHP_BSCA_IIC_ENABLE_ENABLE_MASK);
3629        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE), lval );
3630
3631        retCode = BI2C_P_WaitForCompletion(hChn, numWriteBytes);
3632        if (retCode != BERR_SUCCESS)
3633        {
3634            /* We will have to quit.  But if no ack, at least send the stop condition. */
3635            if (retCode == BI2C_ERR_NO_ACK)
3636            {
3637                #if 0
3638                /* Finish the transaction and then quit */
3639                BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), 0 );
3640                BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
3641                            (BCHP_BSCA_IIC_ENABLE_NO_START_MASK | BCHP_BSCA_IIC_ENABLE_ENABLE_MASK));
3642                rc = BI2C_P_WaitForCompletion(hChn, 1);
3643                if (rc != BERR_SUCCESS)
3644                    goto done;
3645                #endif
3646            }
3647            goto done;
3648        }
3649    }
3650
3651    /*
3652     * Now perform the read portion
3653     */
3654
3655    /* program data transfer type */
3656    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
3657    lval &= ~(BCHP_BSCA_CTL_REG_reserved0_MASK | BCHP_BSCA_CTL_REG_DTF_MASK);
3658    lval |= BI2C_P_eReadOnly;
3659    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), lval );
3660
3661#if !BI2C_MSB_FIX
3662    readCmdWord = 0;
3663#endif
3664    cnt = numBytes;
3665    bufferIndex = 0;
3666
3667#if !BI2C_MSB_FIX
3668    while (cnt)
3669    {
3670        if (cnt <= MAX_I2C_READ_REQUEST)
3671        {
3672            /* program amount of bytes to read */
3673            lval = cnt;
3674            cnt = 0;
3675            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), lval );
3676        }
3677        else
3678        {
3679            /* program amount of bytes to read */
3680            lval = MAX_I2C_READ_REQUEST;
3681            cnt -= MAX_I2C_READ_REQUEST;
3682            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), lval );
3683
3684            readCmdWord |= BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK;
3685
3686        }
3687        /* start the read command */
3688        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
3689                    (readCmdWord | BCHP_BSCA_IIC_ENABLE_ENABLE_MASK));
3690
3691        retCode = BI2C_P_WaitForCompletion(hChn, lval);
3692        if (retCode != BERR_SUCCESS)
3693        {
3694            #if 0
3695            /* We will have to quit.  But if no ack, at least send the stop condition. */
3696            if ((retCode == BI2C_ERR_NO_ACK) && (readCmdWord & BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK))
3697            {
3698                /* Finish the transaction and then quit */
3699                BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), 0 );
3700                BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
3701                            (BCHP_BSCA_IIC_ENABLE_NO_START_MASK | BCHP_BSCA_IIC_ENABLE_ENABLE_MASK));
3702                rc = BI2C_P_WaitForCompletion(hChn, 1);
3703                if (rc != BERR_SUCCESS)
3704                    goto done;
3705            }
3706            #endif
3707            goto done;
3708        }
3709
3710        /* copy data to buffer */
3711        for(i = 0; i < lval; i++)
3712        {
3713            pData[bufferIndex++] = (uint8_t)(BREG_Read32 (hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_OUT0 + (i * 4))));
3714        }
3715
3716        if (cnt)
3717        {
3718            readCmdWord = BCHP_BSCA_IIC_ENABLE_NO_START_MASK;
3719        }
3720    }
3721#else
3722    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), 0 );
3723    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
3724                (BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK | BCHP_BSCA_IIC_ENABLE_ENABLE_MASK));
3725    retCode = BI2C_P_WaitForCompletion(hChn, 1);
3726
3727    if (retCode != BERR_SUCCESS)
3728    {
3729        #if 0
3730        /* We will have to quit.  But if no ack, at least send the stop condition. */
3731        if (retCode == BI2C_ERR_NO_ACK)
3732        {
3733            /* Finish the transaction and then quit */
3734            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), 0 );
3735            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
3736                        (BCHP_BSCA_IIC_ENABLE_NO_START_MASK | BCHP_BSCA_IIC_ENABLE_ENABLE_MASK));
3737            BI2C_P_WaitForCompletion(hChn, 1);
3738            /* don't need to check return code here, if timeout, we have to goto done anyways. */
3739        }
3740        #endif
3741        goto done;
3742    }
3743    else
3744    {
3745        do
3746        {
3747            if (cnt <= MAX_I2C_READ_REQUEST)
3748            {
3749                /* program amount of bytes to read */
3750                lval = cnt;
3751                cnt = 0;
3752                BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), lval );
3753                BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
3754                            (BCHP_BSCA_IIC_ENABLE_NO_START_MASK | BCHP_BSCA_IIC_ENABLE_ENABLE_MASK));
3755            }
3756            else
3757            {
3758                /* program amount of bytes to read */
3759                lval = MAX_I2C_READ_REQUEST;
3760                cnt -= MAX_I2C_READ_REQUEST;
3761                BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), lval );
3762                BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
3763                            (BCHP_BSCA_IIC_ENABLE_NO_START_MASK | BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK | BCHP_BSCA_IIC_ENABLE_ENABLE_MASK));
3764            }
3765
3766            retCode = BI2C_P_WaitForCompletion(hChn, lval);
3767            if (retCode != BERR_SUCCESS)
3768                goto done;
3769
3770            /* copy data to buffer */
3771            for(i = 0; i < lval; i++)
3772            {
3773                pData[bufferIndex++] = (uint8_t)(BREG_Read32 (hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_OUT0 + (i * 4))));
3774            }
3775        }
3776        while (cnt);
3777    }
3778#endif
3779
3780done:
3781#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
3782    BI2C_P_RELEASE_MUTEX( hDev );
3783#else   
3784    if (mutex)
3785        BI2C_P_RELEASE_MUTEX( hChn );
3786#endif
3787    BDBG_MSG(("BI2C_P_ReadCmd:  ch=%d, clkRate=%d, chipAddr=0x%x, numSubAddrBytes=%d SubAddr=0x%x, numBytes=%d, pData=0x%x", hChn->chnNo, hChn->clkRate, chipAddr, numSubAddrBytes, numSubAddrBytes ? *(uint8_t *)pSubAddr : 0, numBytes, *(uint8_t *)pData));
3788    #ifdef BI2C_DEBUG
3789    {
3790        int i;
3791        for (i=0; i<(int)numBytes; i++)
3792            BDBG_MSG(("%d:  0x%x", i, *(pData+i)));
3793    }
3794    #endif
3795
3796    return retCode;
3797}
3798
3799BERR_Code BI2C_P_BurstReadCmd
3800(
3801    BI2C_ChannelHandle  hChn,           /* Device channel handle */
3802    uint16_t        chipAddr,           /* i2c chip address.  this is unshifted */
3803    void            *pSubAddr,          /* pointer to register address */
3804    uint8_t         numSubAddrBytes,    /* number of bytes in register address */
3805    uint8_t         *pData,             /* storage */
3806    size_t          numBytes            /* number of bytes to read */
3807)
3808{
3809    BI2C_Handle     hDev;
3810    BERR_Code       retCode = BERR_SUCCESS;
3811    uint8_t         numWriteBytes = 0;
3812    uint32_t        subAddr24;
3813    uint16_t        subAddr16;
3814    uint8_t         subAddr8;
3815#if !BI2C_MSB_FIX
3816    uint32_t        bscRegAddr, readCmdWord, bufferIndex, lval = 0, rval, i;
3817#else
3818    uint32_t        bscRegAddr, bufferIndex, lval = 0;
3819#endif
3820    size_t          cnt;
3821#if (BI2C_MAX_I2C_MSTR_CHANNELS == 1) && (BI2C_MAX_I2C_CHANNELS != 1)
3822    BI2C_Clk            eClkRate;
3823#endif
3824
3825    BSTD_UNUSED( pData );
3826    BDBG_ASSERT( hChn );
3827    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
3828    BDBG_ASSERT( numBytes <= MAX_I2C_READ_REQUEST );
3829        BDBG_ASSERT( pData );
3830
3831    /* Get I2C handle from channel handle */
3832    hDev = hChn->hI2c;
3833
3834#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
3835    BI2C_P_ACQUIRE_MUTEX( hDev );
3836    {
3837        uint32_t            muxReg;
3838        eClkRate = BI2C_GetClk(hChn);
3839        BI2C_SetClk(hChn, eClkRate);
3840        /* Now, resource is lock, so work can begin, first config. IO ports */
3841        muxReg = BREG_Read32( hDev->hRegister, BCHP_PM_CONFIG );
3842        muxReg &= ~BCHP_MASK( PM_CONFIG, bsc_port_sel );
3843        muxReg |= BCHP_FIELD_DATA( PM_CONFIG, bsc_port_sel, hChn->chnNo );
3844        BREG_Write32( hDev->hRegister, BCHP_PM_CONFIG, muxReg );
3845        /* Always use the first channel when configured for single I2C Master configuration */
3846        hChn = hDev->hI2cChn[0];
3847    }
3848#else   
3849    BI2C_P_ACQUIRE_MUTEX( hChn );
3850#endif
3851
3852    /* program slave device's (id) */
3853    if (chipAddr & 0x0380)              /* 10-bit chip address */
3854    {
3855        lval = ((chipAddr & 0x0300) >> 7) | 0xF0;
3856        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), lval );
3857        lval = (uint32_t)(chipAddr & 0xff);
3858        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_IN0), lval );
3859        bscRegAddr = BCHP_BSCA_DATA_IN1;
3860        numWriteBytes++;
3861    }
3862    else
3863    {
3864        lval = (uint32_t) ((chipAddr & 0x7f) << 1);
3865        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), lval );
3866        bscRegAddr = BCHP_BSCA_DATA_IN0;
3867    }
3868
3869    /* Reset i2c enable register */
3870    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE), 0 );
3871
3872    /* program data transfer type */
3873    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
3874    lval &= ~(BCHP_BSCA_CTL_REG_reserved0_MASK | BCHP_BSCA_CTL_REG_DTF_MASK);
3875    lval |= BI2C_P_eWriteRead ;
3876    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), lval );
3877
3878    if (numSubAddrBytes)    /* read with sub addr, must fill subaddr to transmiting register */
3879    {
3880        /* program slave device's register address */
3881        if (numSubAddrBytes == 3)
3882        {
3883            subAddr24 = *((uint32_t *)pSubAddr);
3884            lval = (uint32_t)(subAddr24 >> 16);
3885            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
3886            bscRegAddr += 4;
3887            lval = (uint32_t)((subAddr24 >> 8) & 0xff);
3888            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
3889            bscRegAddr += 4;
3890            lval = (uint32_t)(subAddr24 & 0xff);
3891            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
3892            bscRegAddr += 4;
3893            numWriteBytes += 3;
3894        }
3895        else if (numSubAddrBytes == 2)
3896        {
3897            subAddr16 = *((uint16_t *)pSubAddr);
3898            lval = (uint32_t)(subAddr16 >> 8);
3899            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
3900            bscRegAddr += 4;
3901            lval = (uint32_t)(subAddr16 & 0xff);
3902            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
3903            bscRegAddr += 4;
3904            numWriteBytes += 2;
3905        }
3906        else if (numSubAddrBytes == 1)
3907        {
3908            subAddr8 = *((uint8_t *)pSubAddr);
3909            lval = (uint32_t)(subAddr8 & 0xff);
3910            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
3911            bscRegAddr += 4;
3912            numWriteBytes++;
3913        }
3914
3915        /* program amount of subaddr bytes to conter register */
3916        lval = (uint32_t)(numWriteBytes & 0x0f);
3917        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), lval );
3918    }
3919
3920#if !BI2C_MSB_FIX
3921    readCmdWord = 0;
3922#endif
3923    cnt = numBytes;
3924    bufferIndex = 0;
3925#if !BI2C_MSB_FIX
3926    {
3927        if (cnt <= MAX_I2C_READ_REQUEST)
3928        {
3929            /* program amount of bytes to read */
3930            lval = cnt;
3931            cnt = 0;
3932            rval = BREG_Read32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG));
3933            rval &= 0x0f;
3934            rval |= (lval << 4);
3935            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), rval );
3936        }
3937
3938        /* start the burst read command */
3939        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
3940                    BCHP_BSCA_IIC_ENABLE_ENABLE_MASK);
3941
3942        retCode = BI2C_P_WaitForCompletion(hChn, lval+ (uint32_t)(numWriteBytes & 0x0f));
3943        if (retCode != BERR_SUCCESS)
3944            goto done;
3945
3946        /* copy data to buffer */
3947        for(i = 0; i < lval; i++)
3948        {
3949            pData[bufferIndex++] = (uint8_t)(BREG_Read32 (hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_OUT0 + (i * 4))));
3950        }
3951    }
3952
3953#else
3954    /* No implentment for MSB FIX branch of 7038 earlier version*/
3955#endif
3956
3957#if !BI2C_MSB_FIX
3958done:
3959#endif
3960#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
3961    BI2C_P_RELEASE_MUTEX( hDev);
3962#else
3963    BI2C_P_RELEASE_MUTEX( hChn);
3964#endif
3965    return retCode;
3966}
3967
3968BERR_Code BI2C_P_BurstReadCmdNoAck
3969(
3970    BI2C_ChannelHandle  hChn,           /* Device channel handle */
3971    uint16_t        chipAddr,           /* i2c chip address.  this is unshifted */
3972    void            *pSubAddr,          /* pointer to register address */
3973    uint8_t         numSubAddrBytes,    /* number of bytes in register address */
3974    uint8_t         *pData,             /* storage */
3975    size_t          numBytes            /* number of bytes to read */
3976)
3977{
3978    BI2C_Handle         hDev;
3979    BERR_Code           retCode = BERR_SUCCESS;
3980    uint8_t             numWriteBytes = 0;
3981    uint32_t            subAddr24;
3982    uint16_t            subAddr16;
3983    uint8_t             subAddr8;
3984    uint32_t            bscRegAddr, bufferIndex, lval = 0, rval, i;
3985    size_t              cnt;
3986#if (BCHP_CHIP==3563)
3987    BI2C_Clk            eClkRate;
3988#endif
3989    BDBG_ASSERT( hChn );
3990    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
3991    BDBG_ASSERT( numBytes <= MAX_I2C_READ_REQUEST );
3992    BDBG_ASSERT( pData );
3993
3994    /* Get I2C handle from channel handle */
3995    hDev = hChn->hI2c;
3996
3997#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
3998    BI2C_P_ACQUIRE_MUTEX( hDev );
3999    /* Now, resource is lock, so work can begin, first config. IO ports */
4000    {
4001        int muxReg;
4002
4003#if (BCHP_CHIP==3563)
4004        eClkRate= BI2C_GetClk(hChn);
4005        BI2C_SetClk(hChn, eClkRate);
4006#endif
4007        muxReg = BREG_Read32( hDev->hRegister, BCHP_PM_CONFIG );
4008        muxReg &= ~BCHP_MASK( PM_CONFIG, bsc_port_sel );
4009        muxReg |= BCHP_FIELD_DATA( PM_CONFIG, bsc_port_sel, hChn->chnNo );
4010        BREG_Write32( hDev->hRegister, BCHP_PM_CONFIG, muxReg );
4011    }
4012    /* Always use the first channel when configured for single I2C Master configuration */
4013    hChn = hDev->hI2cChn[0];
4014#else   
4015    BI2C_P_ACQUIRE_MUTEX( hChn );
4016#endif
4017
4018    /* program slave device's (id) */
4019    if (chipAddr & 0x0380)              /* 10-bit chip address */
4020    {
4021        lval = ((chipAddr & 0x0300) >> 7) | 0xF0;
4022        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), lval );
4023        lval = (uint32_t)(chipAddr & 0xff);
4024        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_IN0), lval );
4025        bscRegAddr = BCHP_BSCA_DATA_IN1;
4026        numWriteBytes++;
4027    }
4028    else
4029    {
4030        lval = (uint32_t) ((chipAddr & 0x7f) << 1);
4031        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), lval );
4032        bscRegAddr = BCHP_BSCA_DATA_IN0;
4033    }
4034
4035    /* Reset i2c enable register */
4036    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE), 0 );
4037
4038    /* program data transfer type */
4039    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
4040    lval &= ~(BCHP_BSCA_CTL_REG_reserved0_MASK | BCHP_BSCA_CTL_REG_DTF_MASK);
4041    lval |= BI2C_P_eWriteRead ;
4042    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), lval );
4043
4044    if (numSubAddrBytes)    /* read with sub addr, must issue a write */
4045    {
4046        /* program slave device's register address */
4047        if (numSubAddrBytes == 3)
4048        {
4049            subAddr24 = *((uint32_t *)pSubAddr);
4050            lval = (uint32_t)(subAddr24 >> 16);
4051            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4052            bscRegAddr += 4;
4053            lval = (uint32_t)((subAddr24 >> 8) & 0xff);
4054            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4055            bscRegAddr += 4;
4056            lval = (uint32_t)(subAddr24 & 0xff);
4057            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4058            bscRegAddr += 4;
4059            numWriteBytes += 3;
4060        }
4061        else if (numSubAddrBytes == 2)
4062        {
4063            subAddr16 = *((uint16_t *)pSubAddr);
4064            lval = (uint32_t)(subAddr16 >> 8);
4065            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4066            bscRegAddr += 4;
4067            lval = (uint32_t)(subAddr16 & 0xff);
4068            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4069            bscRegAddr += 4;
4070            numWriteBytes += 2;
4071        }
4072        else if (numSubAddrBytes == 1)
4073        {
4074            subAddr8 = *((uint8_t *)pSubAddr);
4075            lval = (uint32_t)(subAddr8 & 0xff);
4076            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4077            bscRegAddr += 4;
4078            numWriteBytes++;
4079        }
4080
4081        /* program amount of subaddr bytes to conter register */
4082        lval = (uint32_t)(numWriteBytes & 0x0f);
4083        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), lval );
4084
4085        /* ignore ack */
4086        lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG));
4087        lval |= 0x2;
4088        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG), lval );
4089    }
4090
4091    /*
4092     * Now perform the read portion
4093     */
4094
4095    cnt = numBytes;
4096    bufferIndex = 0;
4097    {
4098        if (cnt <= MAX_I2C_READ_REQUEST)
4099        {
4100            /* program amount of bytes to read */
4101            lval = cnt;
4102            cnt = 0;
4103            rval = BREG_Read32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG));
4104            rval &= 0x0f;
4105            rval |= (lval << 4);
4106            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), rval );
4107        }
4108
4109        /* start the burst read command */
4110        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
4111                    BCHP_BSCA_IIC_ENABLE_ENABLE_MASK);
4112
4113        retCode = BI2C_P_WaitForCompletion(hChn, lval+ (uint32_t)(numWriteBytes & 0x0f));
4114        if (retCode != BERR_SUCCESS)
4115            goto done;
4116
4117        /* copy data to buffer */
4118        for(i = 0; i < lval; i++)
4119        {
4120            pData[bufferIndex++] = (uint8_t)(BREG_Read32 (hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_OUT0 + (i * 4))));
4121        }
4122    }
4123
4124done:
4125#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
4126    BI2C_P_RELEASE_MUTEX( hDev );
4127#else
4128    BI2C_P_RELEASE_MUTEX( hChn );
4129#endif
4130    return retCode;
4131}
4132
4133#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
4134/***********************************************************************func
4135 * Name: BI2C_P_ReadBy4BytesCmd
4136 *   - Read data from i2c slave device.
4137 *       write (1 byte of slave device register's address, subAddr)
4138 *   and read  (0-8 bytes of data)
4139 *   Using i2c Write.& Read
4140 *
4141 * NOTE: This function will be called by BI2C_P_Read, BI2C_P_ReadA16, BI2C_P_ReadNoAddr
4142 ***************************************************************************/
4143BERR_Code BI2C_P_ReadBy4BytesCmd
4144(
4145    BI2C_ChannelHandle  hChn,           /* Device channel handle */
4146    uint16_t        chipAddr,           /* i2c chip address.  this is unshifted */
4147    void            *pSubAddr,          /* pointer to register address */
4148    uint8_t         numSubAddrBytes,    /* number of bytes in register address */
4149    uint8_t         *pData,             /* storage */
4150    size_t          numBytes,           /* number of bytes to read */
4151    bool            mutex,              /* protect with a mutex */
4152    bool            ack                 /* check for ack? */
4153)
4154{
4155    BI2C_Handle         hDev;
4156    BERR_Code           retCode = BERR_SUCCESS;
4157    uint8_t             numWriteBytes = 0;
4158    uint32_t            subAddr24;
4159    uint16_t            subAddr16;
4160    uint8_t             subAddr8;
4161    uint8_t             maxReadBytes;
4162    uint8_t             numReadBytes;
4163    uint32_t            tempData;
4164    uint32_t            bscRegAddr, readCmdWord, bufferIndex, lval = 0, i;
4165    size_t              cnt;
4166
4167    BDBG_ASSERT( hChn );
4168    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
4169
4170    /* Get I2C handle from channel handle */
4171    hDev = hChn->hI2c;
4172
4173#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 0)
4174    if (mutex)
4175        BI2C_P_ACQUIRE_MUTEX( hChn );
4176#endif
4177
4178    maxReadBytes = MAX_I2C_READ_REQUEST*4;
4179
4180    /* program slave device's (id) */
4181    if (chipAddr & 0x0380)              /* 10-bit chip address */
4182    {
4183        lval = ((chipAddr & 0x0300) >> 7) | 0xF0;
4184        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), lval );
4185        lval = (uint32_t)(chipAddr & 0xff);
4186        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_IN0), lval );
4187
4188        /* There are still 3 bytes we can write in BCHP_BSCA_DATA_IN0 */
4189        bscRegAddr = BCHP_BSCA_DATA_IN0;
4190        numWriteBytes++;
4191    }
4192    else
4193    {
4194        lval = (uint32_t) ((chipAddr & 0x7f) << 1);
4195        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), lval );
4196        bscRegAddr = BCHP_BSCA_DATA_IN0;
4197    }
4198
4199    if (numSubAddrBytes)    /* read with sub addr, must issue a write */
4200    {
4201        /* Each BCHP_BSCA_DATA_IN register has 4 bytes */
4202        if (numSubAddrBytes == 3)
4203        {
4204            subAddr24 = *((uint32_t *)pSubAddr);
4205
4206            if (numWriteBytes == 0)
4207            {
4208                lval = (uint32_t)subAddr24;
4209            }
4210            else
4211            {
4212                /* byte 0 contains part of chip address. */
4213                lval = (uint32_t)((chipAddr & 0xff) | (subAddr24 << 8));
4214            }
4215            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4216            bscRegAddr += 4;
4217            numWriteBytes += 3;
4218        }
4219        else if (numSubAddrBytes == 2)
4220        {
4221            subAddr16 = *((uint16_t *)pSubAddr);
4222            if (numWriteBytes == 0)
4223            {
4224                lval = (uint32_t)(subAddr16);
4225            }
4226            else
4227            {
4228                /* byte 0 contains part of chip address. */
4229                lval = (uint32_t)((chipAddr & 0xff) | (subAddr16 << 8));
4230            }
4231            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4232            numWriteBytes += 2;
4233        }
4234        else if (numSubAddrBytes == 1)
4235        {
4236            subAddr8 = *((uint8_t *)pSubAddr);
4237            if (numWriteBytes == 0)
4238            {
4239                lval = (uint32_t)(subAddr8);
4240            }
4241            else
4242            {
4243                /* byte 0 contains part of chip address. */
4244                lval = (uint32_t)((chipAddr & 0xff) | (subAddr8 << 8));
4245            }
4246            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4247            numWriteBytes++;
4248        }
4249
4250        /* program amount of bytes to write/read */
4251        lval = (uint32_t)(numWriteBytes & 0x0f);
4252        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), lval );
4253
4254        /* program data transfer type */
4255        lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
4256        lval &= ~(BCHP_BSCA_CTL_REG_reserved0_MASK | BCHP_BSCA_CTL_REG_DTF_MASK);
4257        lval |= BI2C_P_eWriteOnly ;
4258        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), lval );
4259
4260        if (!ack)
4261        {
4262            /* Mao Neil: ignore ack */
4263            /* printf("Disable the acknowledge!\n\n"); */
4264            lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG));
4265            lval |= BCHP_BSCA_CTLHI_REG_IGNORE_ACK_MASK;
4266            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG), lval );
4267        }
4268
4269        /* start the write command */
4270        lval = (BCHP_BSCA_IIC_ENABLE_RESTART_MASK | BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK |
4271                BCHP_BSCA_IIC_ENABLE_ENABLE_MASK);
4272        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE), lval );
4273
4274        retCode = BI2C_P_WaitForCompletion(hChn, numWriteBytes);
4275        if (retCode != BERR_SUCCESS)
4276            goto done;
4277    }
4278
4279    /*
4280     * Now perform the read portion
4281     */
4282
4283    /* program data transfer type */
4284    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
4285    lval &= ~(BCHP_BSCA_CTL_REG_reserved0_MASK | BCHP_BSCA_CTL_REG_DTF_MASK);
4286    lval |= BI2C_P_eReadOnly;
4287    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), lval );
4288
4289    readCmdWord = 0;
4290    cnt = numBytes;
4291    bufferIndex = 0;
4292
4293    while (cnt)
4294    {
4295        if (cnt <= maxReadBytes)
4296        {
4297            /* program amount of bytes to read */
4298            lval = cnt;
4299            cnt = 0;
4300            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), lval );
4301        }
4302        else
4303        {
4304            /* program amount of bytes to read */
4305            lval = maxReadBytes;
4306            cnt -= maxReadBytes;
4307            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), lval );
4308
4309            readCmdWord |= BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK;
4310
4311        }
4312        /* start the read command */
4313        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
4314                    (readCmdWord | BCHP_BSCA_IIC_ENABLE_ENABLE_MASK));
4315
4316        retCode = BI2C_P_WaitForCompletion(hChn, lval);
4317        if (retCode != BERR_SUCCESS)
4318            goto done;
4319
4320        /* copy data to buffer */
4321        /* Read operation is by 4 bytes */
4322        for(i = 0; i < ((lval-1)/4)+1; i++)
4323        {
4324            tempData = BREG_Read32 (hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_OUT0 + (i * 4)));
4325
4326            if (i == ((lval-1)/4))
4327            {
4328                numReadBytes = ((lval-1)%4) + 1; /* last read may have less than 4 bytes */
4329            }
4330            else
4331            {
4332                numReadBytes = 4;
4333            }
4334
4335            pData[bufferIndex++] = (uint8_t)(tempData & 0x000000FF);
4336            if ((numReadBytes == 2) || (numReadBytes == 3) || (numReadBytes == 4))
4337            {
4338                pData[bufferIndex++] = (uint8_t)((tempData & 0x0000FF00) >> 8);
4339            }
4340            if ((numReadBytes == 3) || (numReadBytes == 4))
4341            {
4342                pData[bufferIndex++] = (uint8_t)((tempData & 0x00FF0000) >> 16);
4343            }
4344            if (numReadBytes == 4)
4345            {
4346                pData[bufferIndex++] = (uint8_t)((tempData & 0xFF000000) >> 24);
4347            }
4348        }
4349
4350        if (cnt)
4351        {
4352            readCmdWord = BCHP_BSCA_IIC_ENABLE_NO_START_MASK;
4353        }
4354    }
4355
4356done:
4357#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 0)
4358    if (mutex)
4359        BI2C_P_RELEASE_MUTEX( hChn );
4360#endif
4361
4362    BDBG_MSG(("BI2C_P_ReadBy4BytesCmd:  ch=%d, clkRate=%d, chipAddr=0x%x, numSubAddrBytes=%d SubAddr=0x%x, numBytes=%d, pData=0x%x", hChn->chnNo, hChn->clkRate, chipAddr, numSubAddrBytes, numSubAddrBytes ? *(uint8_t *)pSubAddr : 0, numBytes, *(uint8_t *)pData));
4363    #ifdef BI2C_DEBUG
4364    {
4365        int i;
4366        for (i=0; i<(int)numBytes; i++)
4367            BDBG_MSG(("%d:  0x%x", i, *(pData+i)));
4368    }
4369    #endif
4370
4371    return retCode;
4372}
4373#endif
4374
4375/***********************************************************************func
4376* Name: BI2C_P_WaitForNVMToAcknowledge
4377 *   -
4378 *
4379 *
4380 ***************************************************************************/
4381BERR_Code BI2C_P_WaitForNVMToAcknowledge
4382(
4383    BI2C_ChannelHandle  hChn,                 /* Device channel handle */
4384    uint16_t                 chipAddr,            /* i2c chip address.  this is unshifted */
4385    void                     *pSubAddr,       /* pointer to register address */
4386    uint8_t                  numSubAddrBytes,   /* number of bytes in register address */
4387    size_t                numBytes            /* number of bytes to write */
4388   )
4389{
4390    BERR_Code   retCode   = BERR_SUCCESS;
4391    uint32_t        lval      = 0;
4392   uint32_t     timeoutMs = 0;
4393   uint32_t     loopCnt   = 0;
4394   uint8_t     myData[1] = { 0 };
4395
4396   /*
4397    * method
4398    * 1) Set up timout values as appropriate
4399    * 2) Make a call to Read, reading some abitrary address
4400    * 3) If Read fails, check timeout hasn't been reached.
4401    * 4) If not timeout, then re-call Read.
4402   */
4403
4404    /* Calculate the timeout value */
4405    numBytes++;                         /* add 1 for chip ID */
4406    lval      = numBytes * 4000;    /* number of clks, 4000 clks per byte worst case scenario */
4407    timeoutMs = BI2C_P_CALCULATE_TIMEOUT(lval, hChn->clkRate);
4408
4409#ifdef CK_DEBUG
4410   ATE_printf( "numbytes  = %d\n\r", numBytes );
4411   ATE_printf( "lval      = %d\n\r", lval );
4412   ATE_printf( "timeoutMs = %d\n\r", timeoutMs );
4413#endif
4414
4415   loopCnt = ((timeoutMs * 1000) / I2C_POLLING_INTERVAL) + 1;
4416
4417   hChn->nvramAck = 1;
4418
4419   while (1)
4420   {
4421      retCode = BI2C_P_ReadCmd( hChn, chipAddr, pSubAddr, numSubAddrBytes, &myData[0], 1, true /*mutex*/, true /*ack*/);
4422
4423      if ( retCode != BERR_SUCCESS )
4424      {
4425         BKNI_Delay( I2C_POLLING_INTERVAL );
4426
4427         loopCnt--;
4428
4429         if (loopCnt == 0)
4430         {
4431            retCode = BERR_TRACE( BERR_TIMEOUT );
4432            break;
4433         }
4434      }
4435      else
4436      {
4437         /* NVM chip responded so it is no longer in its internal
4438          * write cycle. Can now finish
4439          */
4440         break;
4441      }
4442   }
4443
4444   hChn->nvramAck = 0;
4445
4446   return retCode;
4447}
4448
4449BERR_Code BI2C_P_WaitForDataToLeaveFIFO
4450(
4451    BI2C_ChannelHandle  hChn,                           /* Device channel handle */
4452    uint32_t                 numBytes                       /* number of bytes to transfer */
4453)
4454{
4455    BI2C_Handle hDev      = hChn->hI2c;
4456    BERR_Code   retCode   = BERR_SUCCESS;
4457    uint32_t        lval      = 0;
4458    uint32_t    timeoutMs = 0;
4459    uint32_t    loopCnt   = 0;
4460
4461    /* Calculate the timeout value */
4462
4463    numBytes++;                         /* add 1 for chip ID */
4464
4465    lval = numBytes * 4000;         /* number of clks, 4000 clks per byte worst case scenario */
4466
4467    timeoutMs = BI2C_P_CALCULATE_TIMEOUT(lval, hChn->clkRate);
4468
4469    loopCnt = ((timeoutMs * 1000) / I2C_POLLING_INTERVAL) + 1;
4470
4471    while (1)
4472    {
4473        lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE));
4474
4475        if (lval & BCHP_BSCA_IIC_ENABLE_INTRP_MASK)
4476        {
4477         /* Ladies and gentleman, DATA HAS NOW LEFT THE FIFO!!!!
4478          * We can now finish
4479          */
4480            break;
4481        }
4482
4483        if (loopCnt == 0)
4484        {
4485            retCode = BERR_TRACE (BERR_TIMEOUT);
4486            break;
4487        }
4488
4489        BKNI_Delay(I2C_POLLING_INTERVAL);
4490
4491        loopCnt--;
4492   }
4493
4494   /* With respect to the NVM, we do not want to check if there has been
4495    * an ack to the data leaving the FIFO, because there probably wont be */
4496
4497    /* stop execution */
4498
4499    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE));
4500
4501    lval &= ~(BCHP_BSCA_IIC_ENABLE_ENABLE_MASK);
4502
4503    BREG_Write32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE), lval);
4504
4505    return retCode;
4506}
4507
4508/***********************************************************************func
4509 * Name: BI2C_SwReset
4510 *   - Perform a software reset.
4511 *
4512 ***************************************************************************/
4513BERR_Code BI2C_SwReset
4514(
4515    BI2C_ChannelHandle  hChn           /* Device channel handle */
4516)
4517{
4518    #if (BI2C_SUPPORT_I2C_VIA_GPIO == 1)
4519    uint16_t i;
4520    uint8_t oden_scl, oden_sda;
4521    uint8_t iodir_scl, iodir_sda;
4522    uint8_t sun_top_sda, sun_top_scl;
4523    int no_ack = 0;
4524    int ch = hChn->chnNo;
4525    BI2C_Handle hDev;
4526    BREG_Handle hReg;
4527    BI2C_Clk rate = hChn->clkRate;
4528
4529    BDBG_ASSERT( hChn );
4530    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
4531
4532    /* Get I2C handle from channel handle */
4533    hDev = hChn->hI2c;
4534    hReg = hDev->hRegister;
4535
4536    sun_top_scl = BI2C_P_SunTopScl(0);
4537    sun_top_sda = BI2C_P_SunTopSda(0);
4538
4539    /* Set open drain output */
4540    oden_scl = BI2C_P_OdenScl(1);
4541    oden_sda = BI2C_P_OdenSda(1);
4542
4543    /* reset CLOCK and DATA */
4544    BI2C_P_ClkSet(1);
4545    BI2C_P_DataSet(1);
4546
4547    /* Set gpio as output */
4548    iodir_scl = BI2C_P_IodirScl(0);
4549    iodir_sda = BI2C_P_IodirSda(0);
4550
4551    /* generate start condition */
4552    BI2C_P_DataSet(0);
4553    BI2C_P_ClkSet(0);
4554    BI2C_P_DataSet(1);
4555
4556    /* dummy clock cycles 1 through 9 */
4557    for (i=0; i<9; i++)
4558    {
4559        BI2C_P_ClkSet(1);
4560        BI2C_P_ClkSet(0);
4561    }
4562
4563    /* start condition */
4564    BI2C_P_ClkSet(1);
4565    BI2C_P_DataSet(0);
4566
4567    /* stop condition */
4568    BI2C_P_ClkSet(0);
4569    BI2C_P_ClkSet(1);
4570    BI2C_P_DataSet(1);
4571    BI2C_P_ClkSet(0);   /* Needed ????*/
4572
4573    /* restore iodir */
4574    BI2C_P_IodirScl(iodir_scl);
4575    BI2C_P_IodirSda(iodir_sda);
4576
4577    /* restore open drain output */
4578    BI2C_P_OdenScl(oden_scl);
4579    BI2C_P_OdenSda(oden_sda);
4580
4581    /* restore sun top */
4582    BI2C_P_SunTopScl(sun_top_scl);
4583    BI2C_P_SunTopSda(sun_top_sda);
4584
4585    if (no_ack) return BI2C_ERR_NO_ACK;
4586    else return BERR_SUCCESS;
4587    #else
4588    BSTD_UNUSED( hChn );
4589    BDBG_ERR(("BI2C_P_WriteSwCmd called, but not currently supported.  Make sure the function BI2C_P_GpioInit() is setup properly for this chip.\n"));
4590    return BERR_NOT_SUPPORTED;
4591    #endif
4592}
4593
4594/***********************************************************************func
4595 * Name: BI2C_P_Write
4596 *   - Write data to an i2c slave device.
4597 *
4598 * NOTE: This function will be called by BI2C_P_Write, BI2C_P_WriteA16, BI2C_P_WriteNoAddr
4599 ***************************************************************************/
4600BERR_Code BI2C_P_WriteSwCmd
4601(
4602    BI2C_ChannelHandle  hChn,           /* Device channel handle */
4603    uint16_t            chipAddr,       /* i2c chip address.  this is unshifted */
4604    void                *pSubAddr,      /* pointer to register address */
4605    uint8_t             numSubAddrBytes,    /* number of bytes in register address */
4606    const uint8_t       *pData,     /* storage */
4607    size_t              numBytes,       /* number of bytes to write */
4608    bool                isNvram         /* is this a nvram access? */
4609)
4610{
4611    #if (BI2C_SUPPORT_I2C_VIA_GPIO == 1)
4612    uint16_t i;
4613    uint8_t oden_scl, oden_sda;
4614    uint8_t iodir_scl, iodir_sda;
4615    uint8_t sun_top_sda, sun_top_scl;
4616    int no_ack = 0;
4617    int ch = hChn->chnNo;
4618    BI2C_Handle hDev;
4619    BREG_Handle hReg;
4620    BI2C_Clk rate = hChn->clkRate;
4621    int ret_ack;
4622    BERR_Code rc;
4623    uint32_t subAddr24;
4624    uint16_t subAddr16;
4625    uint8_t subAddr8;
4626    uint32_t lval = 0;
4627
4628    BDBG_MSG(("BI2C_P_WriteSwCmd:  ch=%d, clkRate=%d, chipAddr=0x%x, numSubAddrBytes=%d, subAddr=0x%x, numBytes=%d, pData=0x%x\n", hChn->chnNo, hChn->clkRate, chipAddr, numSubAddrBytes, numSubAddrBytes ? *(int *)pSubAddr : 0, numBytes, *(uint8_t *)pData));
4629
4630    BSTD_UNUSED( isNvram );
4631    BDBG_ASSERT( hChn );
4632    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
4633    BDBG_ASSERT( pData );
4634
4635    /* Get I2C handle from channel handle */
4636    hDev = hChn->hI2c;
4637    hReg = hDev->hRegister;
4638
4639    sun_top_scl = BI2C_P_SunTopScl(0);
4640    sun_top_sda = BI2C_P_SunTopSda(0);
4641
4642    /* Set open drain output */
4643    oden_scl = BI2C_P_OdenScl(1);
4644    oden_sda = BI2C_P_OdenSda(1);
4645
4646        #ifdef RMW_METHOD
4647    /* reset CLOCK and DATA */
4648    BI2C_P_ClkSet(1);
4649    BI2C_P_DataSet(1);
4650
4651    /* Set gpio as output */
4652    iodir_scl = BI2C_P_IodirScl(0);
4653    iodir_sda = BI2C_P_IodirSda(0);
4654    #else
4655    /* Set iodir to output so we can change data */
4656    iodir_scl = BI2C_P_IodirScl(0);
4657    iodir_sda = BI2C_P_IodirSda(0);
4658
4659    /* Set data low for using iodir to control output */
4660    BI2C_P_DataScl(0);
4661    BI2C_P_DataSda(0);
4662
4663    /* Set iodir to input so we can start with SCL and SDA high */
4664    BI2C_P_IodirScl(1);
4665    BI2C_P_IodirSda(1);
4666    #endif
4667
4668    /* Don't support 10 bit chip addr yet */
4669    if (chipAddr & 0x0380)              /* 10-bit chip address */
4670    {
4671        BDBG_ERR(("not supported yet...\n"));
4672        while(1);
4673    }
4674
4675#if 0
4676    /* Don't support sub address bytes yet */
4677    if (numSubAddrBytes > 1)
4678    {
4679        BDBG_ERR(("not supported yet...\n"));
4680        while(1);
4681    }
4682#endif
4683
4684    chipAddr = (chipAddr & 0x7f) << 1;
4685
4686    /* generate start condition */
4687    BI2C_P_DataSet(0);
4688
4689    if ((rc = BI2C_P_ByteWrite(chipAddr & 0xfe, &ret_ack)) != BERR_SUCCESS) goto no_success;
4690    if (ret_ack != I2C_ACK)
4691    {
4692        BDBG_ERR(("no ack!\n"));
4693        no_ack = 1;
4694        goto no_ack_detected;
4695    }
4696
4697#if 0
4698    if (numSubAddrBytes==1)
4699    {
4700        if ((rc = BI2C_P_ByteWrite(*((uint8_t *)pSubAddr), &ret_ack)) != BERR_SUCCESS) goto no_success;
4701        if (ret_ack != I2C_ACK)
4702        {
4703            BDBG_ERR(("no ack!\n"));
4704            no_ack = 1;
4705            goto no_ack_detected;
4706        }
4707    }
4708#else
4709    if (numSubAddrBytes)    /* read with sub addr, must issue a write */
4710    {
4711        /* program slave device's register address */
4712        if (numSubAddrBytes == 3)
4713        {
4714            subAddr24 = *((uint32_t *)pSubAddr);
4715            lval = (uint32_t)(subAddr24 >> 16);
4716            if ((rc = BI2C_P_ByteWrite(lval, &ret_ack)) != BERR_SUCCESS) goto no_success;
4717            if (ret_ack != I2C_ACK)
4718            {
4719                BDBG_ERR(("no ack!\n"));
4720                no_ack = 1;
4721                goto no_ack_detected;
4722            }
4723            lval = (uint32_t)((subAddr24 >> 8) & 0xff);
4724            if ((rc = BI2C_P_ByteWrite(lval, &ret_ack)) != BERR_SUCCESS) goto no_success;
4725            if (ret_ack != I2C_ACK)
4726            {
4727                BDBG_ERR(("no ack!\n"));
4728                no_ack = 1;
4729                goto no_ack_detected;
4730            }
4731            lval = (uint32_t)(subAddr24 & 0xff);
4732            if ((rc = BI2C_P_ByteWrite(lval, &ret_ack)) != BERR_SUCCESS) goto no_success;
4733            if (ret_ack != I2C_ACK)
4734            {
4735                BDBG_ERR(("no ack!\n"));
4736                no_ack = 1;
4737                goto no_ack_detected;
4738            }
4739        }
4740        else if (numSubAddrBytes == 2)
4741        {
4742            subAddr16 = *((uint16_t *)pSubAddr);
4743            lval = (uint32_t)(subAddr16 >> 8);
4744            if ((rc = BI2C_P_ByteWrite(lval, &ret_ack)) != BERR_SUCCESS) goto no_success;
4745            if (ret_ack != I2C_ACK)
4746            {
4747                BDBG_ERR(("no ack!\n"));
4748                no_ack = 1;
4749                goto no_ack_detected;
4750            }
4751            lval = (uint32_t)(subAddr16 & 0xff);
4752            if ((rc = BI2C_P_ByteWrite(lval, &ret_ack)) != BERR_SUCCESS) goto no_success;
4753            if (ret_ack != I2C_ACK)
4754            {
4755                BDBG_ERR(("no ack!\n"));
4756                no_ack = 1;
4757                goto no_ack_detected;
4758            }
4759        }
4760        else if (numSubAddrBytes == 1)
4761        {
4762            subAddr8 = *((uint8_t *)pSubAddr);
4763            lval = (uint32_t)(subAddr8 & 0xff);
4764            if ((rc = BI2C_P_ByteWrite(lval, &ret_ack)) != BERR_SUCCESS) goto no_success;
4765            if (ret_ack != I2C_ACK)
4766            {
4767                BDBG_ERR(("no ack!\n"));
4768                no_ack = 1;
4769                goto no_ack_detected;
4770            }
4771        }
4772    }
4773#endif
4774
4775    for (i = 0; i < numBytes; i++)
4776    {
4777        if ((rc = BI2C_P_ByteWrite(pData[i], &ret_ack) != BERR_SUCCESS)) goto no_success;
4778        if (ret_ack != I2C_ACK)
4779        {
4780            BDBG_ERR(("no ack!\n"));
4781            no_ack = 1;
4782            goto no_ack_detected;
4783        }
4784    }
4785
4786no_success:
4787no_ack_detected:
4788    /* generate stop condition */
4789    BI2C_P_ClkSet(1);
4790    BI2C_P_DataSet(1);
4791
4792    /* restore iodir */
4793    BI2C_P_IodirScl(iodir_scl);
4794    BI2C_P_IodirSda(iodir_sda);
4795
4796    /* restore open drain output */
4797    BI2C_P_OdenScl(oden_scl);
4798    BI2C_P_OdenSda(oden_sda);
4799
4800    /* restore sun top */
4801    BI2C_P_SunTopScl(sun_top_scl);
4802    BI2C_P_SunTopSda(sun_top_sda);
4803
4804    if (no_ack) return BI2C_ERR_NO_ACK;
4805    else return BERR_SUCCESS;
4806    #else
4807    BSTD_UNUSED( hChn );
4808    BSTD_UNUSED( chipAddr );
4809    BSTD_UNUSED( pSubAddr );
4810    BSTD_UNUSED( numSubAddrBytes );
4811    BSTD_UNUSED( pData );
4812    BSTD_UNUSED( numBytes );
4813    BSTD_UNUSED( isNvram );
4814    BDBG_ERR(("BI2C_P_WriteSwCmd called, but not currently supported.  Make sure the function BI2C_P_GpioInit() is setup properly for this chip.\n"));
4815    return BERR_NOT_SUPPORTED;
4816    #endif
4817}
4818
4819/***********************************************************************func
4820 * Name: BI2C_P_Write
4821 *   - Write data to an i2c slave device.
4822 *
4823 * NOTE: This function will be called by BI2C_P_Write, BI2C_P_WriteA16, BI2C_P_WriteNoAddr
4824 ***************************************************************************/
4825BERR_Code BI2C_P_WriteCmd
4826(
4827    BI2C_ChannelHandle  hChn,           /* Device channel handle */
4828    uint16_t            chipAddr,       /* i2c chip address.  this is unshifted */
4829    uint32_t            subAddr,      /* pointer to register address */
4830    uint8_t             numSubAddrBytes,    /* number of bytes in register address */
4831    const uint8_t       *pData,     /* storage */
4832    size_t              numBytes,       /* number of bytes to write */
4833    bool                isNvram,         /* is this a nvram access? */
4834    bool                mutex,           /* protect with a mutex */
4835    bool                ack              /* check for ack? */
4836)
4837{
4838    BI2C_Handle         hDev;
4839    BERR_Code           retCode = BERR_SUCCESS;
4840    BERR_Code           rc = BERR_SUCCESS;
4841    uint8_t             numWriteBytes = 0;
4842    uint32_t            bscRegAddr, writeCmdWord, bufferIndex, maxTxfrSize, lval = 0, i;
4843    size_t              cnt;
4844#if (BCHP_CHIP==3563)
4845    BI2C_Clk            eClkRate;
4846#endif
4847
4848    BDBG_MSG(("BI2C_P_WriteCmd:  ch=%d, clkRate=%d, chipAddr=0x%x, numSubAddrBytes=%d SubAddr=0x%x, numBytes=%d, pData=0x%x", hChn->chnNo, hChn->clkRate, chipAddr, numSubAddrBytes, subAddr, numBytes, *(uint8_t *)pData));
4849    #ifdef BI2C_DEBUG
4850    {
4851        int i;
4852        for (i=0; i<(int)numBytes; i++)
4853            BDBG_MSG(("%d:  0x%x", i, *(pData+i)));
4854    }
4855    #endif
4856
4857    BDBG_ASSERT( hChn );
4858    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
4859    BDBG_ASSERT( pData );
4860
4861    /* Get I2C handle from channel handle */
4862    hDev = hChn->hI2c;
4863
4864#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
4865    BI2C_P_ACQUIRE_MUTEX( hDev );
4866    /* Now, resource is lock, so work can begin, first config. IO ports */
4867    {
4868        int muxReg;
4869
4870#if (BCHP_CHIP==3563)
4871        eClkRate= BI2C_GetClk(hChn);
4872        BI2C_SetClk(hChn, eClkRate);
4873#endif
4874        muxReg = BREG_Read32( hDev->hRegister, BCHP_PM_CONFIG );
4875        muxReg &= ~BCHP_MASK( PM_CONFIG, bsc_port_sel );
4876        muxReg |= BCHP_FIELD_DATA( PM_CONFIG, bsc_port_sel, hChn->chnNo );
4877        BREG_Write32( hDev->hRegister, BCHP_PM_CONFIG, muxReg );
4878    }
4879    /* Always use the first channel when configured for single I2C Master configuration */
4880    hChn = hDev->hI2cChn[0];
4881#else   
4882    if (mutex)
4883        BI2C_P_ACQUIRE_MUTEX( hChn );
4884#endif
4885
4886    /* program slave device's (id) */
4887    if (chipAddr & 0x0380)              /* 10-bit chip address */
4888    {
4889        lval = ((chipAddr & 0x0300) >> 7) | 0xF0;
4890        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), lval );
4891        lval = (uint32_t)(chipAddr & 0xff);
4892        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_DATA_IN0), lval );
4893        bscRegAddr = BCHP_BSCA_DATA_IN1;
4894        numWriteBytes++;
4895    }
4896    else
4897    {
4898        lval = (uint32_t) ((chipAddr & 0x7f) << 1);
4899        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), lval );
4900        bscRegAddr = BCHP_BSCA_DATA_IN0;
4901    }
4902
4903    if (numSubAddrBytes)    /* read with sub addr, must issue a write */
4904    {
4905        /* program slave device's register address */
4906        if (numSubAddrBytes == 3)
4907        {
4908            lval = (subAddr >> 16) & 0xff;
4909            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4910            bscRegAddr += 4;
4911            lval = (subAddr >> 8) & 0xff;
4912            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4913            bscRegAddr += 4;
4914            lval = subAddr & 0xff;
4915            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4916            bscRegAddr += 4;
4917            numWriteBytes += 3;
4918        }
4919        else if (numSubAddrBytes == 2)
4920        {
4921            lval = (subAddr >> 8) & 0xff;
4922            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4923            bscRegAddr += 4;
4924            lval = subAddr & 0xff;
4925            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4926            bscRegAddr += 4;
4927            numWriteBytes += 2;
4928        }
4929        else if (numSubAddrBytes == 1)
4930        {
4931            lval = subAddr & 0xff;
4932            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr), lval );
4933            bscRegAddr += 4;
4934            numWriteBytes++;
4935        }
4936    }
4937
4938    /* program data transfer type */
4939    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
4940    lval &= ~(BCHP_BSCA_CTL_REG_reserved0_MASK | BCHP_BSCA_CTL_REG_DTF_MASK);
4941    lval |= BI2C_P_eWriteOnly ;
4942    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), lval );
4943
4944    maxTxfrSize = MAX_I2C_WRITE_REQUEST - numWriteBytes;
4945    writeCmdWord = 0;
4946    cnt = numBytes;
4947    bufferIndex = 0;
4948
4949    do
4950    {
4951        if (cnt <= maxTxfrSize)
4952        {
4953            lval = cnt;
4954            cnt = 0;
4955            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), (lval + numWriteBytes) );
4956        }
4957        else
4958        {
4959            lval = maxTxfrSize;
4960            cnt -= maxTxfrSize;
4961            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), (lval + numWriteBytes) );
4962
4963            writeCmdWord |= BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK;
4964
4965        }
4966
4967        /* copy data from buffer */
4968        for(i = 0; i < lval; i++)       /* lval is number of actual user data bytes to send */
4969        {
4970            BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr ), (uint32_t)(pData[bufferIndex++]));
4971            bscRegAddr += 4;
4972        }
4973
4974        if (!ack)
4975        {
4976            /* Mao Neil: ignore ack */
4977            /* printf("Disable the acknowledge!\n\n"); */
4978            lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG));
4979            lval |= 0x2;
4980            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG), lval );
4981        }
4982
4983        /* start the write command */
4984        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
4985                    (writeCmdWord | BCHP_BSCA_IIC_ENABLE_ENABLE_MASK));
4986
4987        if (isNvram)
4988        {
4989            retCode = BI2C_P_WaitForDataToLeaveFIFO(hChn, (lval + numWriteBytes));
4990
4991            if ( writeCmdWord & BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK )
4992            {
4993                /* There is a no stop */
4994            }
4995            else
4996            {
4997                /* If the master is sending the stop command, then
4998                 * this signals the nvm device to begin its internal write
4999                 * cylce. Now would be a good time to poll for its
5000                 * completion
5001                 */
5002
5003                retCode = BI2C_P_WaitForNVMToAcknowledge( hChn,
5004                                                                chipAddr,
5005                                                                &subAddr,
5006                                                                numSubAddrBytes,
5007                                                                numBytes );
5008            }
5009            if (retCode != BERR_SUCCESS)
5010                goto done;
5011        }
5012        else
5013        {
5014            retCode = BI2C_P_WaitForCompletion(hChn, (lval + numWriteBytes));
5015            if (retCode != BERR_SUCCESS)
5016            {
5017                #if 0
5018                /* We will have to quit.  But if no ack, at least send the stop condition. */
5019                if (((retCode == BI2C_ERR_NO_ACK) || (retCode == BERR_OS_ERROR)) && (writeCmdWord & BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK))
5020                {
5021                    /* Finish the transaction and then quit */
5022                    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), 0 );
5023                    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
5024                                (BCHP_BSCA_IIC_ENABLE_NO_START_MASK | BCHP_BSCA_IIC_ENABLE_ENABLE_MASK));
5025                    rc = BI2C_P_WaitForCompletion(hChn, 1);
5026                    if (rc != BERR_SUCCESS)
5027                        goto done;
5028                }
5029                #else
5030                if (retCode == BERR_OS_ERROR)
5031                {
5032                    /* Finish the transaction and then quit */
5033                    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), 0 );
5034                    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
5035                                (BCHP_BSCA_IIC_ENABLE_NO_START_MASK | BCHP_BSCA_IIC_ENABLE_ENABLE_MASK));
5036                    rc = BI2C_P_WaitForCompletion(hChn, 1);
5037                    if (rc != BERR_SUCCESS)
5038                        goto done;
5039                }
5040                #endif
5041                goto done;
5042            }
5043        }
5044
5045        if (cnt)
5046        {
5047            writeCmdWord = BCHP_BSCA_IIC_ENABLE_NO_START_MASK;
5048            bscRegAddr = BCHP_BSCA_DATA_IN0;
5049            maxTxfrSize = MAX_I2C_WRITE_REQUEST;
5050            numWriteBytes  = 0;
5051        }
5052    }
5053    while (cnt);
5054
5055done:
5056#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 1)
5057    BI2C_P_RELEASE_MUTEX( hDev );
5058#else   
5059    if (mutex)
5060        BI2C_P_RELEASE_MUTEX( hChn );
5061#endif
5062    return retCode;
5063}
5064
5065#ifdef BI2C_SUPPORT_4_BYTE_XFR_MODE
5066/***********************************************************************func
5067 * Name: BI2C_P_WriteBy4BytesCmd
5068 *   - Write data to an i2c slave device.
5069 *
5070 * NOTE: This function will be called by BI2C_P_Write, BI2C_P_WriteA16, BI2C_P_WriteNoAddr
5071 ***************************************************************************/
5072BERR_Code BI2C_P_WriteBy4BytesCmd
5073(
5074    BI2C_ChannelHandle  hChn,           /* Device channel handle */
5075    uint16_t            chipAddr,       /* i2c chip address.  this is unshifted */
5076    uint32_t            subAddr,        /* sub address */
5077    uint8_t             numSubAddrBytes,    /* number of bytes in register address */
5078    const uint8_t       *pData,         /* storage */
5079    size_t              numBytes,       /* number of bytes to write */
5080    bool                isNvram,        /* is this a nvram access? */
5081    bool                mutex,           /* protect with a mutex */
5082    bool                ack             /* check for ack? */
5083)
5084{
5085    BI2C_Handle         hDev;
5086    BERR_Code           retCode = BERR_SUCCESS;
5087    uint8_t             numWriteBytes = 0;
5088    uint8_t             maxWriteBytes;
5089    uint32_t            bscRegAddr, writeCmdWord, bufferIndex, lval = 0, i, tempData=0;
5090    size_t              cnt;
5091
5092    BDBG_ASSERT( hChn );
5093    BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
5094
5095    BDBG_MSG(("BI2C_P_WriteBy4BytesCmd:  ch=%d, clkRate=%d, chipAddr=0x%x, numSubAddrBytes=%d SubAddr=0x%x, numBytes=%d, pData=0x%x", hChn->chnNo, hChn->clkRate, chipAddr, numSubAddrBytes, subAddr, numBytes, *(uint8_t *)pData));
5096    #ifdef BI2C_DEBUG
5097    {
5098        int i;
5099        for (i=0; i<(int)numBytes; i++)
5100            BDBG_MSG(("%d:  0x%x", i, *(pData+i)));
5101    }
5102    #endif
5103
5104    /* Get I2C handle from channel handle */
5105    hDev = hChn->hI2c;
5106
5107#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 0)
5108    if (mutex)
5109        BI2C_P_ACQUIRE_MUTEX( hChn );
5110#endif
5111
5112    maxWriteBytes = MAX_I2C_WRITE_REQUEST*4;
5113
5114    /* program slave device's (id) */
5115    if (chipAddr & 0x0380)              /* 10-bit chip address */
5116    {
5117        lval = ((chipAddr & 0x0300) >> 7) | 0xF0;
5118        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), lval );
5119        numWriteBytes++;
5120    }
5121    else
5122    {
5123        lval = (uint32_t) ((chipAddr & 0x7f) << 1);
5124        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CHIP_ADDRESS), lval );
5125    }
5126
5127    numWriteBytes += numSubAddrBytes;
5128
5129    /* program data transfer type */
5130    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
5131    lval &= ~(BCHP_BSCA_CTL_REG_reserved0_MASK | BCHP_BSCA_CTL_REG_DTF_MASK);
5132    lval |= BI2C_P_eWriteOnly ;
5133    BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), lval );
5134
5135    writeCmdWord = 0;
5136    cnt = numBytes;
5137    bufferIndex = 0;
5138    bscRegAddr = BCHP_BSCA_DATA_IN0;
5139
5140    do
5141    {
5142        if (cnt+numWriteBytes <= maxWriteBytes)
5143        {
5144            lval = cnt+numWriteBytes;
5145            cnt = 0;
5146            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), lval );
5147        }
5148        else
5149        {
5150            lval = maxWriteBytes;
5151            cnt -= (maxWriteBytes-numWriteBytes);
5152            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), lval );
5153
5154            writeCmdWord |= BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK;
5155
5156        }
5157
5158        /* copy data from buffer */
5159        if (lval) /* lval may be zero because of a zero byte write */
5160        {
5161            for(i = 0; i < ((lval-1)/4)+1; i++)
5162            {
5163                /* Since pTotalData is padded with extra 0's, even last non 4byte-aligned data
5164                 * can be handled the same way.
5165                 */
5166                switch (numWriteBytes)
5167                {
5168                    case 0:
5169                        tempData = (uint32_t)((pData[bufferIndex])       |
5170                                              (pData[bufferIndex+1]<<8)  |
5171                                              (pData[bufferIndex+2]<<16) |
5172                                              (pData[bufferIndex+3]<<24));
5173                        bufferIndex += 4;
5174                        break;
5175                    case 1:
5176                        if (chipAddr & 0x0380)              /* 10-bit chip address */
5177                        {
5178                            tempData = (uint32_t)(chipAddr & 0xff);
5179                        }
5180                        else
5181                        {
5182                            tempData = subAddr;
5183                        }
5184                        tempData |= (pData[bufferIndex] << 8);
5185                        tempData |= (pData[bufferIndex+1] << 16);
5186                        tempData |= (pData[bufferIndex+2] << 24);
5187                        bufferIndex += 3;
5188                        break;
5189                    case 2:
5190                        if (chipAddr & 0x0380)              /* 10-bit chip address */
5191                        {
5192                            tempData = (uint32_t)(chipAddr & 0x000000ff);
5193                            tempData |= ((subAddr << 8)    & 0x0000ff00);
5194                        }
5195                        else
5196                        {
5197                            tempData = (subAddr >> 8)      & 0x000000ff;
5198                            tempData |= ((subAddr << 8)    & 0x0000ff00);
5199                        }
5200                        tempData |= (pData[bufferIndex] << 16);
5201                        tempData |= (pData[bufferIndex+1] << 24);
5202                        bufferIndex += 2;
5203                        break;
5204                    case 3:
5205                        if (chipAddr & 0x0380)              /* 10-bit chip address */
5206                        {
5207                            tempData = (uint32_t)(chipAddr & 0x000000ff);
5208                            tempData |= (subAddr)          & 0x0000ff00;
5209                            tempData |= (subAddr << 16)    & 0x00ff0000;
5210                        }
5211                        else
5212                        {
5213                            tempData = ((subAddr >> 16)    & 0x000000ff);
5214                            tempData |= (subAddr           & 0x0000ff00);
5215                            tempData |= (subAddr << 16)    & 0x00ff0000;
5216                        }
5217                        tempData |= (pData[bufferIndex] << 24);
5218                        bufferIndex += 1;
5219                        break;
5220                    case 4:
5221                        if (chipAddr & 0x0380)              /* 10-bit chip address */
5222                        {
5223                            tempData = (uint32_t)(chipAddr & 0x000000ff);
5224                            tempData |= ((subAddr >> 8)    & 0x0000ff00);
5225                            tempData |= ((subAddr << 8)    & 0x00ff0000);
5226                            tempData |= ((subAddr << 24)   & 0xff000000);
5227                        }
5228                        break;
5229                    default:
5230                        break;
5231                }
5232                numWriteBytes=0; /* done taking care of sub address */
5233                BREG_Write32( hDev->hRegister, (hChn->coreOffset + bscRegAddr ), tempData);
5234                bscRegAddr += 4;
5235            }
5236        }
5237
5238        if (!ack)
5239        {
5240            /* Mao Neil: ignore ack */
5241            /* printf("Disable the acknowledge!\n\n"); */
5242            lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG));
5243            lval |= BCHP_BSCA_CTLHI_REG_IGNORE_ACK_MASK;
5244            BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTLHI_REG), lval );
5245        }
5246
5247        /* start the write command */
5248        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE),
5249                    (writeCmdWord | BCHP_BSCA_IIC_ENABLE_ENABLE_MASK));
5250
5251        if (isNvram)
5252        {
5253            retCode = BI2C_P_WaitForDataToLeaveFIFO(hChn, lval);
5254
5255            if ( writeCmdWord & BCHP_BSCA_IIC_ENABLE_NO_STOP_MASK )
5256            {
5257                /* There is a no stop */
5258
5259            }
5260            else
5261            {
5262                /* If the master is sending the stop command, then
5263                 * this signals the nvm device to begin its internal write
5264                 * cylce. Now would be a good time to poll for its
5265                 * completion
5266                 */
5267
5268                retCode = BI2C_P_WaitForNVMToAcknowledge( hChn,
5269                                                                chipAddr,
5270                                                                &subAddr,
5271                                                                numSubAddrBytes,
5272                                                                numBytes );
5273             }
5274
5275        }
5276        else
5277        {
5278            retCode = BI2C_P_WaitForCompletion(hChn, lval);
5279        }
5280
5281        if (retCode != BERR_SUCCESS)
5282            goto done;
5283
5284        if (cnt)
5285        {
5286            writeCmdWord = BCHP_BSCA_IIC_ENABLE_NO_START_MASK;
5287            bscRegAddr = BCHP_BSCA_DATA_IN0;
5288        }
5289    }
5290    while (cnt);
5291
5292done:
5293#if (BI2C_SERIALIZE_SINGLE_SHARED_MASTER == 0)
5294    if (mutex)
5295        BI2C_P_RELEASE_MUTEX( hChn );
5296#endif
5297    return retCode;
5298}
5299#endif
5300
5301BERR_Code BI2C_P_WaitForCompletion
5302(
5303    BI2C_ChannelHandle  hChn,                           /* Device channel handle */
5304    uint32_t            numBytes                        /* number of bytes to transfer */
5305)
5306{
5307    BI2C_Handle         hDev;
5308    BERR_Code           retCode = BERR_SUCCESS;
5309    uint32_t            lval, timeoutMs, loopCnt;
5310
5311    hDev = hChn->hI2c;
5312
5313    if (hChn->timeoutMs == BI2C_TimeoutBasedOnClkSpeed)
5314    {
5315        /* Calculate the timeout value */
5316        numBytes++;                         /* add 1 for chip ID */
5317        lval = numBytes * 9;                /* number of clks, 9 clks per byte */
5318        timeoutMs = BI2C_P_CALCULATE_TIMEOUT(lval, hChn->clkRate);
5319    }
5320    else
5321    {
5322        /* Use hardcoded value */
5323        timeoutMs = hChn->timeoutMs;
5324    }
5325
5326    if (hChn->intMode)
5327    {
5328        /*
5329         * Wait for event, set by ISR
5330         */
5331        BI2C_CHK_RETCODE (retCode, BKNI_WaitForEvent(hChn->hChnEvent, timeoutMs));
5332        if (hChn->noAck)
5333        {
5334            BDBG_MSG(("BI2C_P_WaitForCompletion: BI2C_ERR_NO_ACK(0x110001) at line=%d", __LINE__));
5335            retCode = BI2C_ERR_NO_ACK;
5336            goto done;
5337        }
5338    }
5339    else
5340    {
5341        /*
5342         * Polling mode
5343         */
5344        loopCnt = ((timeoutMs * 1000) / I2C_POLLING_INTERVAL) + 1;
5345        while (1)
5346        {
5347            lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE));
5348            if (lval & BCHP_BSCA_IIC_ENABLE_INTRP_MASK)
5349                break;
5350
5351            if (loopCnt == 0)
5352            {
5353                retCode = BERR_TRACE (BERR_TIMEOUT);
5354                goto done;
5355            }
5356            BKNI_Delay(I2C_POLLING_INTERVAL);
5357            loopCnt--;
5358        }
5359    }
5360
5361    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE));
5362    if (lval & BCHP_BSCA_IIC_ENABLE_NO_ACK_MASK)
5363    {
5364        if ( hChn->nvramAck == 0 )
5365        {
5366            BDBG_MSG(("BI2C_P_WaitForCompletion: BI2C_ERR_NO_ACK(0x110001) at line=%d", __LINE__));
5367            retCode = BI2C_ERR_NO_ACK;
5368        }
5369        else
5370        {
5371            /* If we are waiting for the NVM to acknowledge, then we DO NOT
5372             * want to trace an error message, however, we do need to
5373             * tell the caller that it has still not acked.
5374             */
5375            BDBG_MSG(("BI2C_P_WaitForCompletion: BI2C_ERR_NO_ACK(0x110001) at line=%d", __LINE__));
5376            retCode = BI2C_ERR_NO_ACK;
5377        }
5378    }
5379
5380done:
5381    /* stop execution */
5382    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE));
5383    lval &= ~(BCHP_BSCA_IIC_ENABLE_ENABLE_MASK);
5384    BREG_Write32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE), lval);
5385
5386
5387    return retCode;
5388}
5389
5390static void BI2C_P_HandleInterrupt_Isr
5391(
5392    void *pParam1,                      /* Device channel handle */
5393    int parm2                           /* not used */
5394)
5395{
5396    BI2C_ChannelHandle  hChn;
5397    BI2C_Handle         hDev;
5398    uint32_t            lval;
5399
5400    hChn = (BI2C_ChannelHandle) pParam1;
5401    BDBG_ASSERT( hChn );
5402
5403    BSTD_UNUSED(parm2);
5404
5405    hDev = hChn->hI2c;
5406    lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE));
5407
5408    hChn->noAck = (lval & BCHP_BSCA_IIC_ENABLE_NO_ACK_MASK) ? true : false; /* save no ack status */
5409    lval &= ~(BCHP_BSCA_IIC_ENABLE_ENABLE_MASK);
5410    BREG_Write32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_IIC_ENABLE), lval);
5411
5412    BKNI_SetEvent( hChn->hChnEvent );
5413
5414    return;
5415}
5416
5417
5418#if ((BCHP_CHIP==7601) && (BCHP_VER >= BCHP_VER_B0)) || (BCHP_CHIP==7635) || (BCHP_CHIP == 7630) \
5419    || (BCHP_CHIP == 7420) || (BCHP_CHIP == 7125) || (BCHP_CHIP == 7340) || (BCHP_CHIP == 7342) \
5420    || (BCHP_CHIP == 7550) || (BCHP_CHIP == 7408) || (BCHP_CHIP == 7468) || (BCHP_CHIP == 7208) \
5421    || (BCHP_CHIP == 7422) || (BCHP_CHIP==7425) || (BCHP_CHIP==7435)
5422
5423BERR_Code BI2C_P_SetupHdmiHwAccess(
5424    void *context,                      /* Device channel handle */
5425    uint32_t dataTransferFormat,        /* Data Transfer Format */
5426    uint32_t cnt1,                      /* Counter 1 value */
5427    uint32_t cnt2                       /* Counter 2 value */
5428)
5429{
5430    BI2C_ChannelHandle hChn;
5431    BI2C_Handle hDev;
5432    uint32_t lval;
5433    BERR_Code rc = BERR_SUCCESS;
5434
5435    if (context == NULL)
5436    {
5437        BDBG_ERR(("Invalid I2C handle\n"));
5438        rc = BERR_INVALID_PARAMETER;
5439        BSTD_UNUSED(dataTransferFormat);
5440        BSTD_UNUSED(cnt1);
5441        BSTD_UNUSED(cnt1);
5442    }
5443    else
5444    {
5445        hChn = (BI2C_ChannelHandle)context;
5446        BDBG_ASSERT( hChn->magicId == DEV_MAGIC_ID );
5447
5448        /* Get I2C handle from channel handle */
5449        hDev = hChn->hI2c;
5450
5451        lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG));
5452        lval &= ~BCHP_BSCA_CTL_REG_DTF_MASK;
5453        lval |= dataTransferFormat << BCHP_BSCA_CTL_REG_DTF_SHIFT;
5454        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CTL_REG), lval );
5455
5456        lval = BREG_Read32(hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG));
5457        lval &= ~(BCHP_BSCA_CNT_REG_CNT_REG1_MASK | BCHP_BSCA_CNT_REG_CNT_REG2_MASK);
5458        lval |= cnt1 << BCHP_BSCA_CNT_REG_CNT_REG1_SHIFT;
5459        lval |= cnt2 << BCHP_BSCA_CNT_REG_CNT_REG2_SHIFT;
5460        BREG_Write32( hDev->hRegister, (hChn->coreOffset + BCHP_BSCA_CNT_REG), lval );
5461    }
5462
5463    return rc;
5464}
5465
5466#else
5467
5468BERR_Code BI2C_P_SetupHdmiHwAccess(
5469    void *context,                      /* Device channel handle */
5470    uint32_t dataTransferFormat,        /* Data Transfer Format */
5471    uint32_t cnt1,                      /* Counter 1 value */
5472    uint32_t cnt2                       /* Counter 2 value */
5473    )
5474{
5475    BSTD_UNUSED(context);
5476    BSTD_UNUSED(dataTransferFormat);
5477    BSTD_UNUSED(cnt1);
5478    BSTD_UNUSED(cnt2);
5479
5480    BDBG_ERR(("%s: Not Supported", __FUNCTION__));
5481    return BERR_NOT_SUPPORTED;
5482}
5483#endif
5484
5485
5486/* End of file */
Note: See TracBrowser for help on using the repository browser.