i2c.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. /*
  2. * (C) Copyright 2000
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. *
  23. * Hacked for the DB64360 board by Ingo.Assmus@keymile.com
  24. * extra improvments by Brain Waite
  25. * for cpci750 by reinhard.arlt@esd-electronics.com
  26. */
  27. #include <common.h>
  28. #include <mpc8xx.h>
  29. #include <malloc.h>
  30. #include "../../Marvell/include/mv_gen_reg.h"
  31. #include "../../Marvell/include/core.h"
  32. #define I2C_DELAY 100
  33. #undef DEBUG_I2C
  34. #ifdef DEBUG_I2C
  35. #define DP(x) x
  36. #else
  37. #define DP(x)
  38. #endif
  39. /* Assuming that there is only one master on the bus (us) */
  40. static void i2c_init (int speed, int slaveaddr)
  41. {
  42. unsigned int n, m, freq, margin, power;
  43. unsigned int actualN = 0, actualM = 0;
  44. unsigned int minMargin = 0xffffffff;
  45. unsigned int tclk = CFG_TCLK;
  46. unsigned int i2cFreq = speed; /* 100000 max. Fast mode not supported */
  47. DP (puts ("i2c_init\n"));
  48. /* gtI2cMasterInit */
  49. for (n = 0; n < 8; n++) {
  50. for (m = 0; m < 16; m++) {
  51. power = 2 << n; /* power = 2^(n+1) */
  52. freq = tclk / (10 * (m + 1) * power);
  53. if (i2cFreq > freq)
  54. margin = i2cFreq - freq;
  55. else
  56. margin = freq - i2cFreq;
  57. if (margin < minMargin) {
  58. minMargin = margin;
  59. actualN = n;
  60. actualM = m;
  61. }
  62. }
  63. }
  64. DP (puts ("setup i2c bus\n"));
  65. /* Setup bus */
  66. /* gtI2cReset */
  67. GT_REG_WRITE (I2C_SOFT_RESET, 0);
  68. asm(" sync");
  69. GT_REG_WRITE (I2C_CONTROL, 0);
  70. asm(" sync");
  71. DP (puts ("set baudrate\n"));
  72. GT_REG_WRITE (I2C_STATUS_BAUDE_RATE, (actualM << 3) | actualN);
  73. asm(" sync");
  74. DP (puts ("udelay...\n"));
  75. udelay (I2C_DELAY);
  76. GT_REG_WRITE (I2C_CONTROL, (0x1 << 2) | (0x1 << 6));
  77. asm(" sync");
  78. }
  79. static uchar i2c_select_device (uchar dev_addr, uchar read, int ten_bit)
  80. {
  81. unsigned int status, data, bits = 7;
  82. unsigned int control;
  83. int count = 0;
  84. DP (puts ("i2c_select_device\n"));
  85. /* Output slave address */
  86. if (ten_bit) {
  87. bits = 10;
  88. }
  89. GT_REG_READ (I2C_CONTROL, &control);
  90. control |= (0x1 << 2);
  91. GT_REG_WRITE (I2C_CONTROL, control);
  92. asm(" sync");
  93. GT_REG_READ (I2C_CONTROL, &control);
  94. control |= (0x1 << 5); /* generate the I2C_START_BIT */
  95. GT_REG_WRITE (I2C_CONTROL, control);
  96. asm(" sync");
  97. RESET_REG_BITS (I2C_CONTROL, (0x01 << 3));
  98. asm(" sync");
  99. GT_REG_READ (I2C_CONTROL, &status);
  100. while ((status & 0x08) != 0x08) {
  101. GT_REG_READ (I2C_CONTROL, &status);
  102. }
  103. count = 0;
  104. GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
  105. while (((status & 0xff) != 0x08) && ((status & 0xff) != 0x10)){
  106. if (count > 200) {
  107. #ifdef DEBUG_I2C
  108. printf ("Failed to set startbit: 0x%02x\n", status);
  109. #endif
  110. GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
  111. asm(" sync");
  112. return (status);
  113. }
  114. GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
  115. count++;
  116. }
  117. DP (puts ("i2c_select_device:write addr byte\n"));
  118. /* assert the address */
  119. data = (dev_addr << 1);
  120. /* set the read bit */
  121. data |= read;
  122. GT_REG_WRITE (I2C_DATA, data);
  123. asm(" sync");
  124. RESET_REG_BITS (I2C_CONTROL, BIT3);
  125. asm(" sync");
  126. GT_REG_READ (I2C_CONTROL, &status);
  127. while ((status & 0x08) != 0x08) {
  128. GT_REG_READ (I2C_CONTROL, &status);
  129. }
  130. GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
  131. count = 0;
  132. while (((status & 0xff) != 0x40) && ((status & 0xff) != 0x18)) {
  133. if (count > 200) {
  134. #ifdef DEBUG_I2C
  135. printf ("Failed to write address: 0x%02x\n", status);
  136. #endif
  137. GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
  138. return (status);
  139. }
  140. GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
  141. asm(" sync");
  142. count++;
  143. }
  144. if (bits == 10) {
  145. printf ("10 bit I2C addressing not yet implemented\n");
  146. return (0xff);
  147. }
  148. return (0);
  149. }
  150. static uchar i2c_get_data (uchar * return_data, int len)
  151. {
  152. unsigned int data, status;
  153. int count = 0;
  154. DP (puts ("i2c_get_data\n"));
  155. while (len) {
  156. RESET_REG_BITS (I2C_CONTROL, BIT3);
  157. asm(" sync");
  158. /* Get and return the data */
  159. GT_REG_READ (I2C_CONTROL, &status);
  160. while ((status & 0x08) != 0x08) {
  161. GT_REG_READ (I2C_CONTROL, &status);
  162. }
  163. GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
  164. count++;
  165. while ((status & 0xff) != 0x50) {
  166. if (count > 20) {
  167. #ifdef DEBUG_I2C
  168. printf ("Failed to get data len status: 0x%02x\n", status);
  169. #endif
  170. GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
  171. asm(" sync");
  172. return 0;
  173. }
  174. GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
  175. count++;
  176. }
  177. GT_REG_READ (I2C_DATA, &data);
  178. len--;
  179. *return_data = (uchar) data;
  180. return_data++;
  181. }
  182. RESET_REG_BITS (I2C_CONTROL, BIT2 | BIT3);
  183. asm(" sync");
  184. count = 0;
  185. GT_REG_READ (I2C_CONTROL, &status);
  186. while ((status & 0x08) != 0x08) {
  187. GT_REG_READ (I2C_CONTROL, &status);
  188. }
  189. while ((status & 0xff) != 0x58) {
  190. if (count > 2000) {
  191. GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
  192. return (status);
  193. }
  194. GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
  195. count++;
  196. }
  197. GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /* stop */
  198. asm(" sync");
  199. RESET_REG_BITS (I2C_CONTROL, (0x1 << 3));
  200. asm(" sync");
  201. return (0);
  202. }
  203. static uchar i2c_write_data (unsigned int *data, int len)
  204. {
  205. unsigned int status;
  206. int count;
  207. unsigned int temp;
  208. unsigned int *temp_ptr = data;
  209. DP (puts ("i2c_write_data\n"));
  210. while (len) {
  211. count = 0;
  212. temp = (unsigned int) (*temp_ptr);
  213. GT_REG_WRITE (I2C_DATA, temp);
  214. asm(" sync");
  215. RESET_REG_BITS (I2C_CONTROL, (0x1 << 3));
  216. asm(" sync");
  217. GT_REG_READ (I2C_CONTROL, &status);
  218. while ((status & 0x08) != 0x08) {
  219. GT_REG_READ (I2C_CONTROL, &status);
  220. }
  221. GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
  222. count++;
  223. while ((status & 0xff) != 0x28) {
  224. if (count > 200) {
  225. GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
  226. asm(" sync");
  227. return (status);
  228. }
  229. GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
  230. count++;
  231. }
  232. len--;
  233. temp_ptr++;
  234. }
  235. return (0);
  236. }
  237. static uchar i2c_write_byte (unsigned char *data, int len)
  238. {
  239. unsigned int status;
  240. int count;
  241. unsigned int temp;
  242. unsigned char *temp_ptr = data;
  243. DP (puts ("i2c_write_byte\n"));
  244. while (len) {
  245. count = 0;
  246. /* Set and assert the data */
  247. temp = *temp_ptr;
  248. GT_REG_WRITE (I2C_DATA, temp);
  249. asm(" sync");
  250. RESET_REG_BITS (I2C_CONTROL, (0x1 << 3));
  251. asm(" sync");
  252. GT_REG_READ (I2C_CONTROL, &status);
  253. while ((status & 0x08) != 0x08) {
  254. GT_REG_READ (I2C_CONTROL, &status);
  255. }
  256. GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
  257. count++;
  258. while ((status & 0xff) != 0x28) {
  259. if (count > 200) {
  260. GT_REG_WRITE (I2C_CONTROL, (0x1 << 4)); /*stop */
  261. asm(" sync");
  262. return (status);
  263. }
  264. GT_REG_READ (I2C_STATUS_BAUDE_RATE, &status);
  265. count++;
  266. }
  267. len--;
  268. temp_ptr++;
  269. }
  270. return (0);
  271. }
  272. static uchar
  273. i2c_set_dev_offset (uchar dev_addr, unsigned int offset, int ten_bit,
  274. int alen)
  275. {
  276. uchar status;
  277. unsigned int table[2];
  278. table[1] = (offset ) & 0x0ff; /* low byte */
  279. table[0] = (offset >> 8) & 0x0ff; /* high byte */
  280. DP (puts ("i2c_set_dev_offset\n"));
  281. status = i2c_select_device (dev_addr, 0, ten_bit);
  282. if (status) {
  283. #ifdef DEBUG_I2C
  284. 22 printf ("Failed to select device setting offset: 0x%02x\n",
  285. status);
  286. #endif
  287. return status;
  288. }
  289. /* check the address offset length */
  290. if (alen == 0)
  291. /* no address offset */
  292. return (0);
  293. else if (alen == 1) {
  294. /* 1 byte address offset */
  295. status = i2c_write_data (&offset, 1);
  296. if (status) {
  297. #ifdef DEBUG_I2C
  298. printf ("Failed to write data: 0x%02x\n", status);
  299. #endif
  300. return status;
  301. }
  302. } else if (alen == 2) {
  303. /* 2 bytes address offset */
  304. status = i2c_write_data (table, 2);
  305. if (status) {
  306. #ifdef DEBUG_I2C
  307. printf ("Failed to write data: 0x%02x\n", status);
  308. #endif
  309. return status;
  310. }
  311. } else {
  312. /* address offset unknown or not supported */
  313. printf ("Address length offset %d is not supported\n", alen);
  314. return 1;
  315. }
  316. return 0; /* sucessful completion */
  317. }
  318. uchar
  319. i2c_read (uchar dev_addr, unsigned int offset, int alen, uchar * data,
  320. int len)
  321. {
  322. uchar status = 0;
  323. unsigned int i2cFreq = CFG_I2C_SPEED;
  324. DP (puts ("i2c_read\n"));
  325. i2c_init (i2cFreq, 0); /* set the i2c frequency */
  326. status = i2c_set_dev_offset (dev_addr, offset, 0, alen); /* send the slave address + offset */
  327. if (status) {
  328. #ifdef DEBUG_I2C
  329. printf ("Failed to set slave address & offset: 0x%02x\n",
  330. status);
  331. #endif
  332. return status;
  333. }
  334. status = i2c_select_device (dev_addr, 1, 0);
  335. if (status) {
  336. #ifdef DEBUG_I2C
  337. printf ("Failed to select device for data read: 0x%02x\n",
  338. status);
  339. #endif
  340. return status;
  341. }
  342. status = i2c_get_data (data, len);
  343. if (status) {
  344. #ifdef DEBUG_I2C
  345. printf ("Data not read: 0x%02x\n", status);
  346. #endif
  347. return status;
  348. }
  349. return 0;
  350. }
  351. void i2c_stop (void)
  352. {
  353. GT_REG_WRITE (I2C_CONTROL, (0x1 << 4));
  354. asm(" sync");
  355. }
  356. uchar
  357. i2c_write (uchar dev_addr, unsigned int offset, int alen, uchar * data,
  358. int len)
  359. {
  360. uchar status = 0;
  361. unsigned int i2cFreq = CFG_I2C_SPEED;
  362. DP (puts ("i2c_write\n"));
  363. i2c_init (i2cFreq, 0); /* set the i2c frequency */
  364. status = i2c_set_dev_offset (dev_addr, offset, 0, alen); /* send the slave address + offset */
  365. if (status) {
  366. #ifdef DEBUG_I2C
  367. printf ("Failed to set slave address & offset: 0x%02x\n",
  368. status);
  369. #endif
  370. return status;
  371. }
  372. status = i2c_write_byte (data, len); /* write the data */
  373. if (status) {
  374. #ifdef DEBUG_I2C
  375. printf ("Data not written: 0x%02x\n", status);
  376. #endif
  377. return status;
  378. }
  379. /* issue a stop bit */
  380. i2c_stop ();
  381. return 0;
  382. }
  383. int i2c_probe (uchar chip)
  384. {
  385. #ifdef DEBUG_I2C
  386. unsigned int i2c_status;
  387. #endif
  388. uchar status = 0;
  389. unsigned int i2cFreq = CFG_I2C_SPEED;
  390. DP (puts ("i2c_probe\n"));
  391. i2c_init (i2cFreq, 0); /* set the i2c frequency */
  392. status = i2c_set_dev_offset (chip, 0, 0, 0); /* send the slave address + no offset */
  393. if (status) {
  394. #ifdef DEBUG_I2C
  395. printf ("Failed to set slave address: 0x%02x\n", status);
  396. #endif
  397. return (int) status;
  398. }
  399. #ifdef DEBUG_I2C
  400. GT_REG_READ (I2C_STATUS_BAUDE_RATE, &i2c_status);
  401. printf ("address %#x returned %#x\n", chip, i2c_status);
  402. #endif
  403. /* issue a stop bit */
  404. i2c_stop ();
  405. return 0; /* successful completion */
  406. }