at93c.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * Atmel AT93C46 serial eeprom driver
  3. *
  4. * Brian Murphy <brian.murphy@eicon.com>
  5. *
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/delay.h>
  9. #include <asm/lasat/lasat.h>
  10. #include <linux/module.h>
  11. #include "at93c.h"
  12. #define AT93C_ADDR_SHIFT 7
  13. #define AT93C_ADDR_MAX ((1 << AT93C_ADDR_SHIFT) - 1)
  14. #define AT93C_RCMD (0x6 << AT93C_ADDR_SHIFT)
  15. #define AT93C_WCMD (0x5 << AT93C_ADDR_SHIFT)
  16. #define AT93C_WENCMD 0x260
  17. #define AT93C_WDSCMD 0x200
  18. struct at93c_defs *at93c;
  19. static void at93c_reg_write(u32 val)
  20. {
  21. *at93c->reg = val;
  22. }
  23. static u32 at93c_reg_read(void)
  24. {
  25. u32 tmp = *at93c->reg;
  26. return tmp;
  27. }
  28. static u32 at93c_datareg_read(void)
  29. {
  30. u32 tmp = *at93c->rdata_reg;
  31. return tmp;
  32. }
  33. static void at93c_cycle_clk(u32 data)
  34. {
  35. at93c_reg_write(data | at93c->clk);
  36. lasat_ndelay(250);
  37. at93c_reg_write(data & ~at93c->clk);
  38. lasat_ndelay(250);
  39. }
  40. static void at93c_write_databit(u8 bit)
  41. {
  42. u32 data = at93c_reg_read();
  43. if (bit)
  44. data |= 1 << at93c->wdata_shift;
  45. else
  46. data &= ~(1 << at93c->wdata_shift);
  47. at93c_reg_write(data);
  48. lasat_ndelay(100);
  49. at93c_cycle_clk(data);
  50. }
  51. static unsigned int at93c_read_databit(void)
  52. {
  53. u32 data;
  54. at93c_cycle_clk(at93c_reg_read());
  55. data = (at93c_datareg_read() >> at93c->rdata_shift) & 1;
  56. return data;
  57. }
  58. static u8 at93c_read_byte(void)
  59. {
  60. int i;
  61. u8 data = 0;
  62. for (i = 0; i <= 7; i++) {
  63. data <<= 1;
  64. data |= at93c_read_databit();
  65. }
  66. return data;
  67. }
  68. static void at93c_write_bits(u32 data, int size)
  69. {
  70. int i;
  71. int shift = size - 1;
  72. u32 mask = (1 << shift);
  73. for (i = 0; i < size; i++) {
  74. at93c_write_databit((data & mask) >> shift);
  75. data <<= 1;
  76. }
  77. }
  78. static void at93c_init_op(void)
  79. {
  80. at93c_reg_write((at93c_reg_read() | at93c->cs) &
  81. ~at93c->clk & ~(1 << at93c->rdata_shift));
  82. lasat_ndelay(50);
  83. }
  84. static void at93c_end_op(void)
  85. {
  86. at93c_reg_write(at93c_reg_read() & ~at93c->cs);
  87. lasat_ndelay(250);
  88. }
  89. static void at93c_wait(void)
  90. {
  91. at93c_init_op();
  92. while (!at93c_read_databit())
  93. ;
  94. at93c_end_op();
  95. };
  96. static void at93c_disable_wp(void)
  97. {
  98. at93c_init_op();
  99. at93c_write_bits(AT93C_WENCMD, 10);
  100. at93c_end_op();
  101. }
  102. static void at93c_enable_wp(void)
  103. {
  104. at93c_init_op();
  105. at93c_write_bits(AT93C_WDSCMD, 10);
  106. at93c_end_op();
  107. }
  108. u8 at93c_read(u8 addr)
  109. {
  110. u8 byte;
  111. at93c_init_op();
  112. at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_RCMD, 10);
  113. byte = at93c_read_byte();
  114. at93c_end_op();
  115. return byte;
  116. }
  117. void at93c_write(u8 addr, u8 data)
  118. {
  119. at93c_disable_wp();
  120. at93c_init_op();
  121. at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_WCMD, 10);
  122. at93c_write_bits(data, 8);
  123. at93c_end_op();
  124. at93c_wait();
  125. at93c_enable_wp();
  126. }