mp1000-seprom.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*`
  2. * mp1000-seprom.c
  3. *
  4. * This file contains the Serial EEPROM code for the MP1000 board
  5. *
  6. * Copyright (C) 2005 Comdial Corporation
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (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, MA 02111-1307 USA
  21. *
  22. */
  23. #include <linux/kernel.h>
  24. #include <linux/init.h>
  25. #include <asm/hardware.h>
  26. #include <asm/hardware/clps7111.h>
  27. #include <asm/arch/mp1000-seprom.h>
  28. /* If SepromInit() can initialize and checksum the seprom successfully, */
  29. /* then it will point seprom_data_ptr at the shadow copy. */
  30. static eeprom_struct seprom_data; /* shadow copy of seprom content */
  31. eeprom_struct *seprom_data_ptr = 0; /* 0 => not initialized */
  32. /*
  33. * Port D Bit 5 is Chip Select for EEPROM
  34. * Port E Bit 0 is Input, Data out from EEPROM
  35. * Port E Bit 1 is Output, Data in to EEPROM
  36. * Port E Bit 2 is Output, CLK to EEPROM
  37. */
  38. static char *port_d_ptr = (char *)(CLPS7111_VIRT_BASE + PDDR);
  39. static char *port_e_ptr = (char *)(CLPS7111_VIRT_BASE + PEDR);
  40. #define NO_OF_SHORTS 64 // Device is 64 x 16 bits
  41. #define ENABLE_RW 0
  42. #define DISABLE_RW 1
  43. static inline void toggle_seprom_clock(void)
  44. {
  45. *port_e_ptr |= HwPortESepromCLK;
  46. *port_e_ptr &= ~(HwPortESepromCLK);
  47. }
  48. static inline void select_eeprom(void)
  49. {
  50. *port_d_ptr |= HwPortDEECS;
  51. *port_e_ptr &= ~(HwPortESepromCLK);
  52. }
  53. static inline void deselect_eeprom(void)
  54. {
  55. *port_d_ptr &= ~(HwPortDEECS);
  56. *port_e_ptr &= ~(HwPortESepromDIn);
  57. }
  58. /*
  59. * GetSepromDataPtr - returns pointer to shadow (RAM) copy of seprom
  60. * and returns 0 if seprom is not initialized or
  61. * has a checksum error.
  62. */
  63. eeprom_struct* get_seprom_ptr(void)
  64. {
  65. return seprom_data_ptr;
  66. }
  67. unsigned char* get_eeprom_mac_address(void)
  68. {
  69. return seprom_data_ptr->variant.eprom_struct.mac_Address;
  70. }
  71. /*
  72. * ReadSProm, Physically reads data from the Serial PROM
  73. */
  74. static void read_sprom(short address, int length, eeprom_struct *buffer)
  75. {
  76. short data = COMMAND_READ | (address & 0x3F);
  77. short bit;
  78. int i;
  79. select_eeprom();
  80. // Clock in 9 bits of the command
  81. for (i = 0, bit = 0x100; i < 9; i++, bit >>= 1) {
  82. if (data & bit)
  83. *port_e_ptr |= HwPortESepromDIn;
  84. else
  85. *port_e_ptr &= ~(HwPortESepromDIn);
  86. toggle_seprom_clock();
  87. }
  88. //
  89. // Now read one or more shorts of data from the Seprom
  90. //
  91. while (length-- > 0) {
  92. data = 0;
  93. // Read 16 bits at a time
  94. for (i = 0; i < 16; i++) {
  95. data <<= 1;
  96. toggle_seprom_clock();
  97. data |= *port_e_ptr & HwPortESepromDOut;
  98. }
  99. buffer->variant.eprom_short_data[address++] = data;
  100. }
  101. deselect_eeprom();
  102. return;
  103. }
  104. /*
  105. * ReadSerialPROM
  106. *
  107. * Input: Pointer to array of 64 x 16 Bits
  108. *
  109. * Output: if no problem reading data is filled in
  110. */
  111. static void read_serial_prom(eeprom_struct *data)
  112. {
  113. read_sprom(0, 64, data);
  114. }
  115. //
  116. // Compute Serial EEPROM checksum
  117. //
  118. // Input: Pointer to struct with Eprom data
  119. //
  120. // Output: The computed Eprom checksum
  121. //
  122. static short compute_seprom_checksum(eeprom_struct *data)
  123. {
  124. short checksum = 0;
  125. int i;
  126. for (i = 0; i < 126; i++) {
  127. checksum += (short)data->variant.eprom_byte_data[i];
  128. }
  129. return((short)(0x5555 - (checksum & 0xFFFF)));
  130. }
  131. //
  132. // Make sure the data port bits for the SEPROM are correctly initialised
  133. //
  134. void __init seprom_init(void)
  135. {
  136. short checksum;
  137. // Init Port D
  138. *(char *)(CLPS7111_VIRT_BASE + PDDDR) = 0x0;
  139. *(char *)(CLPS7111_VIRT_BASE + PDDR) = 0x15;
  140. // Init Port E
  141. *(int *)(CLPS7111_VIRT_BASE + PEDDR) = 0x06;
  142. *(int *)(CLPS7111_VIRT_BASE + PEDR) = 0x04;
  143. //
  144. // Make sure that EEPROM struct size never exceeds 128 bytes
  145. //
  146. if (sizeof(eeprom_struct) > 128) {
  147. panic("Serial PROM struct size > 128, aborting read\n");
  148. }
  149. read_serial_prom(&seprom_data);
  150. checksum = compute_seprom_checksum(&seprom_data);
  151. if (checksum != seprom_data.variant.eprom_short_data[63]) {
  152. panic("Serial EEPROM checksum failed\n");
  153. }
  154. seprom_data_ptr = &seprom_data;
  155. }