ee_access.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /* Module for handling DALLAS DS2438, smart battery monitor
  2. Chip can store up to 40 bytes of user data in EEPROM,
  3. perform temp, voltage and current measurements.
  4. Chip also contains a unique serial number.
  5. Always read/write LSb first
  6. For documentaion, see data sheet for DS2438, 2438.pdf
  7. By Thomas.Lange@corelatus.com 001025
  8. Copyright (C) 2000-2005 Corelatus AB */
  9. /* This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation; either version 2 of
  12. * the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22. * MA 02111-1307 USA
  23. */
  24. #include <common.h>
  25. #include <command.h>
  26. #include <asm/au1x00.h>
  27. #include <asm/io.h>
  28. #include "ee_dev.h"
  29. #include "ee_access.h"
  30. /* static int Debug = 1; */
  31. #undef E_DEBUG
  32. #define E_DEBUG(fmt,args...) /* */
  33. /* #define E_DEBUG(fmt,args...) printk("EEA:"fmt,##args); */
  34. /* We dont have kernel functions */
  35. #define printk printf
  36. #define KERN_DEBUG
  37. #define KERN_ERR
  38. #define EIO 1
  39. #ifndef TRUE
  40. #define TRUE 1
  41. #endif
  42. #ifndef FALSE
  43. #define FALSE 0
  44. #endif
  45. /* lookup table ripped from DS app note 17, understanding and using cyclic redundancy checks... */
  46. static u8 crc_lookup[256] = {
  47. 0, 94, 188, 226, 97, 63, 221, 131,
  48. 194, 156, 126, 32, 163, 253, 31, 65,
  49. 157, 195, 33, 127, 252, 162, 64, 30,
  50. 95, 1, 227, 189, 62, 96, 130, 220,
  51. 35, 125, 159, 193, 66, 28, 254, 160,
  52. 225, 191, 93, 3, 128, 222, 60, 98,
  53. 190, 224, 2, 92, 223, 129, 99, 61,
  54. 124, 34, 192, 158, 29, 67, 161, 255,
  55. 70, 24, 250, 164, 39, 121, 155, 197,
  56. 132, 218, 56, 102, 229, 187, 89, 7,
  57. 219, 133, 103, 57, 186, 228, 6, 88,
  58. 25, 71, 165, 251, 120, 38, 196, 154,
  59. 101, 59, 217, 135, 4, 90, 184, 230,
  60. 167, 249, 27, 69, 198, 152, 122, 36,
  61. 248, 166, 68, 26, 153, 199, 37, 123,
  62. 58, 100, 134, 216, 91, 5, 231, 185,
  63. 140, 210, 48, 110, 237, 179, 81, 15,
  64. 78, 16, 242, 172, 47, 113, 147, 205,
  65. 17, 79, 173, 243, 112, 46, 204, 146,
  66. 211, 141, 111, 49, 178, 236, 14, 80,
  67. 175, 241, 19, 77, 206, 144, 114, 44,
  68. 109, 51, 209, 143, 12, 82, 176, 238,
  69. 50, 108, 142, 208, 83, 13, 239, 177,
  70. 240, 174, 76, 18, 145, 207, 45, 115,
  71. 202, 148, 118, 40, 171, 245, 23, 73,
  72. 8, 86, 180, 234, 105, 55, 213, 139,
  73. 87, 9, 235, 181, 54, 104, 138, 212,
  74. 149, 203, 41, 119, 244, 170, 72, 22,
  75. 233, 183, 85, 11, 136, 214, 52, 106,
  76. 43, 117, 151, 201, 74, 20, 246, 168,
  77. 116, 42, 200, 150, 21, 75, 169, 247,
  78. 182, 232, 10, 84, 215, 137, 107, 53
  79. };
  80. static void
  81. write_gpio_data(int value ){
  82. if(value){
  83. /* Tristate */
  84. gpio_tristate(GPIO_EEDQ);
  85. }
  86. else{
  87. /* Drive 0 */
  88. gpio_clear(GPIO_EEDQ);
  89. }
  90. }
  91. static u8 make_new_crc( u8 Old_crc, u8 New_value ){
  92. /* Compute a new checksum with new byte, using previous checksum as input
  93. See DS app note 17, understanding and using cyclic redundancy checks...
  94. Also see DS2438, page 11 */
  95. return( crc_lookup[Old_crc ^ New_value ]);
  96. }
  97. int ee_crc_ok( u8 *Buffer, int Len, u8 Crc ){
  98. /* Check if the checksum for this buffer is correct */
  99. u8 Curr_crc=0;
  100. int i;
  101. u8 *Curr_byte = Buffer;
  102. for(i=0;i<Len;i++){
  103. Curr_crc = make_new_crc( Curr_crc, *Curr_byte);
  104. Curr_byte++;
  105. }
  106. E_DEBUG("Calculated CRC = 0x%x, read = 0x%x\n", Curr_crc, Crc);
  107. if(Curr_crc == Crc){
  108. /* Good */
  109. return(TRUE);
  110. }
  111. printk(KERN_ERR"EE checksum error, Calculated CRC = 0x%x, read = 0x%x\n", Curr_crc, Crc);
  112. return(FALSE);
  113. }
  114. static void
  115. set_idle(void){
  116. /* Send idle and keep start time
  117. Continous 1 is idle */
  118. WRITE_PORT(1);
  119. }
  120. static int
  121. do_cpu_reset(void){
  122. /* Release reset and verify that chip responds with presence pulse */
  123. int Retries=0;
  124. while(Retries<15){
  125. udelay(RESET_LOW_TIME);
  126. /* Send reset */
  127. WRITE_PORT(0);
  128. udelay(RESET_LOW_TIME);
  129. /* Release reset */
  130. WRITE_PORT(1);
  131. /* Wait for EEPROM to drive output */
  132. udelay(PRESENCE_TIMEOUT);
  133. if(!READ_PORT){
  134. /* Ok, EEPROM is driving a 0 */
  135. E_DEBUG("Presence detected\n");
  136. if(Retries){
  137. E_DEBUG("Retries %d\n",Retries);
  138. }
  139. /* Make sure chip releases pin */
  140. udelay(PRESENCE_LOW_TIME);
  141. return 0;
  142. }
  143. Retries++;
  144. }
  145. printk(KERN_ERR"eeprom did not respond when releasing reset\n");
  146. /* Make sure chip releases pin */
  147. udelay(PRESENCE_LOW_TIME);
  148. /* Set to idle again */
  149. set_idle();
  150. return(-EIO);
  151. }
  152. static u8
  153. read_cpu_byte(void){
  154. /* Read a single byte from EEPROM
  155. Read LSb first */
  156. int i;
  157. int Value;
  158. u8 Result=0;
  159. u32 Flags;
  160. E_DEBUG("Reading byte\n");
  161. for(i=0;i<8;i++){
  162. /* Small delay between pulses */
  163. udelay(1);
  164. #ifdef __KERNEL__
  165. /* Disable irq */
  166. save_flags(Flags);
  167. cli();
  168. #endif
  169. /* Pull down pin short time to start read
  170. See page 26 in data sheet */
  171. WRITE_PORT(0);
  172. udelay(READ_LOW);
  173. WRITE_PORT(1);
  174. /* Wait for chip to drive pin */
  175. udelay(READ_TIMEOUT);
  176. Value = READ_PORT;
  177. if(Value)
  178. Value=1;
  179. #ifdef __KERNEL__
  180. /* Enable irq */
  181. restore_flags(Flags);
  182. #endif
  183. /* Wait for chip to release pin */
  184. udelay(TOTAL_READ_LOW-READ_TIMEOUT);
  185. /* LSb first */
  186. Result|=Value<<i;
  187. /* E_DEBUG("Read %d\n",Value); */
  188. }
  189. E_DEBUG("Read byte 0x%x\n",Result);
  190. return(Result);
  191. }
  192. static void
  193. write_cpu_byte(u8 Byte){
  194. /* Write a single byte to EEPROM
  195. Write LSb first */
  196. int i;
  197. int Value;
  198. u32 Flags;
  199. E_DEBUG("Writing byte 0x%x\n",Byte);
  200. for(i=0;i<8;i++){
  201. /* Small delay between pulses */
  202. udelay(1);
  203. Value = Byte&1;
  204. #ifdef __KERNEL__
  205. /* Disable irq */
  206. save_flags(Flags);
  207. cli();
  208. #endif
  209. /* Pull down pin short time for a 1, long time for a 0
  210. See page 26 in data sheet */
  211. WRITE_PORT(0);
  212. if(Value){
  213. /* Write a 1 */
  214. udelay(WRITE_1_LOW);
  215. }
  216. else{
  217. /* Write a 0 */
  218. udelay(WRITE_0_LOW);
  219. }
  220. WRITE_PORT(1);
  221. #ifdef __KERNEL__
  222. /* Enable irq */
  223. restore_flags(Flags);
  224. #endif
  225. if(Value)
  226. /* Wait for chip to read the 1 */
  227. udelay(TOTAL_WRITE_LOW-WRITE_1_LOW);
  228. /* E_DEBUG("Wrote %d\n",Value); */
  229. Byte>>=1;
  230. }
  231. }
  232. int ee_do_cpu_command( u8 *Tx, int Tx_len, u8 *Rx, int Rx_len, int Send_skip ){
  233. /* Execute this command string, including
  234. giving reset and setting to idle after command
  235. if Rx_len is set, we read out data from EEPROM */
  236. int i;
  237. E_DEBUG("Command, Tx_len %d, Rx_len %d\n", Tx_len, Rx_len );
  238. if(do_cpu_reset()){
  239. /* Failed! */
  240. return(-EIO);
  241. }
  242. if(Send_skip)
  243. /* Always send SKIP_ROM first to tell chip we are sending a command,
  244. except when we read out rom data for chip */
  245. write_cpu_byte(SKIP_ROM);
  246. /* Always have Tx data */
  247. for(i=0;i<Tx_len;i++){
  248. write_cpu_byte(Tx[i]);
  249. }
  250. if(Rx_len){
  251. for(i=0;i<Rx_len;i++){
  252. Rx[i]=read_cpu_byte();
  253. }
  254. }
  255. set_idle();
  256. E_DEBUG("Command done\n");
  257. return(0);
  258. }
  259. int ee_init_cpu_data(void){
  260. int i;
  261. u8 Tx[10];
  262. /* Leave it floting since altera is driving the same pin */
  263. set_idle();
  264. /* Copy all User EEPROM data to scratchpad */
  265. for(i=0;i<USER_PAGES;i++){
  266. Tx[0]=RECALL_MEMORY;
  267. Tx[1]=EE_USER_PAGE_0+i;
  268. if(ee_do_cpu_command(Tx,2,NULL,0,TRUE)) return(-EIO);
  269. }
  270. /* Make sure chip doesnt store measurements in NVRAM */
  271. Tx[0]=WRITE_SCRATCHPAD;
  272. Tx[1]=0; /* Page */
  273. Tx[2]=9;
  274. if(ee_do_cpu_command(Tx,3,NULL,0,TRUE)) return(-EIO);
  275. Tx[0]=COPY_SCRATCHPAD;
  276. if(ee_do_cpu_command(Tx,2,NULL,0,TRUE)) return(-EIO);
  277. for(i=0;i<10;i++){
  278. udelay(1000);
  279. }
  280. return(0);
  281. }