pony_spi.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * This file is part of the flashrom project.
  3. *
  4. * Copyright (C) 2012 Virgil-Adrian Teaca
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; version 2 of the License.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18. */
  19. /* Driver for serial programmers compatible with SI-Prog or AJAWe.
  20. *
  21. * See http://www.lancos.com/siprogsch.html for SI-Prog schematics and instructions.
  22. * See http://www.ajawe.pl/ajawe0208.htm for AJAWe serial programmer documentation.
  23. *
  24. * Pin layout for SI-Prog-like hardware:
  25. *
  26. * MOSI <-------< DTR
  27. * MISO >-------> CTS
  28. * SCK <---+---< RTS
  29. * +---> DSR
  30. * CS# <-------< TXD
  31. *
  32. * and for the AJAWe serial programmer:
  33. *
  34. * MOSI <-------< DTR
  35. * MISO >-------> CTS
  36. * SCK <-------< RTS
  37. * CS# <-------< TXD
  38. *
  39. * DCE >-------> DSR
  40. */
  41. #include <stdlib.h>
  42. #include <strings.h>
  43. #include <string.h>
  44. #include "flash.h"
  45. #include "programmer.h"
  46. enum pony_type {
  47. TYPE_SI_PROG,
  48. TYPE_SERBANG,
  49. TYPE_AJAWE
  50. };
  51. /* Pins for master->slave direction */
  52. static int pony_negate_cs = 1;
  53. static int pony_negate_sck = 0;
  54. static int pony_negate_mosi = 0;
  55. /* Pins for slave->master direction */
  56. static int pony_negate_miso = 0;
  57. static void pony_bitbang_set_cs(int val)
  58. {
  59. if (pony_negate_cs)
  60. val ^= 1;
  61. sp_set_pin(PIN_TXD, val);
  62. }
  63. static void pony_bitbang_set_sck(int val)
  64. {
  65. if (pony_negate_sck)
  66. val ^= 1;
  67. sp_set_pin(PIN_RTS, val);
  68. }
  69. static void pony_bitbang_set_mosi(int val)
  70. {
  71. if (pony_negate_mosi)
  72. val ^= 1;
  73. sp_set_pin(PIN_DTR, val);
  74. }
  75. static int pony_bitbang_get_miso(void)
  76. {
  77. int tmp = sp_get_pin(PIN_CTS);
  78. if (pony_negate_miso)
  79. tmp ^= 1;
  80. return tmp;
  81. }
  82. static const struct bitbang_spi_master bitbang_spi_master_pony = {
  83. .type = BITBANG_SPI_MASTER_PONY,
  84. .set_cs = pony_bitbang_set_cs,
  85. .set_sck = pony_bitbang_set_sck,
  86. .set_mosi = pony_bitbang_set_mosi,
  87. .get_miso = pony_bitbang_get_miso,
  88. .half_period = 0,
  89. };
  90. static int pony_spi_shutdown(void *data)
  91. {
  92. /* Shut down serial port communication */
  93. int ret = serialport_shutdown(NULL);
  94. if (ret)
  95. msg_pdbg("Pony SPI shutdown failed.\n");
  96. else
  97. msg_pdbg("Pony SPI shutdown completed.\n");
  98. return ret;
  99. }
  100. int pony_spi_init(void)
  101. {
  102. int i, data_out;
  103. char *arg = NULL;
  104. enum pony_type type = TYPE_SI_PROG;
  105. char *name;
  106. int have_device = 0;
  107. int have_prog = 0;
  108. /* The parameter is in format "dev=/dev/device,type=serbang" */
  109. arg = extract_programmer_param("dev");
  110. if (arg && strlen(arg)) {
  111. sp_fd = sp_openserport(arg, 9600);
  112. if (sp_fd == SER_INV_FD) {
  113. free(arg);
  114. return 1;
  115. }
  116. if (register_shutdown(pony_spi_shutdown, NULL) != 0) {
  117. free(arg);
  118. serialport_shutdown(NULL);
  119. return 1;
  120. }
  121. have_device++;
  122. }
  123. free(arg);
  124. if (!have_device) {
  125. msg_perr("Error: No valid device specified.\n"
  126. "Use flashrom -p pony_spi:dev=/dev/device[,type=name]\n");
  127. return 1;
  128. }
  129. arg = extract_programmer_param("type");
  130. if (arg && !strcasecmp(arg, "serbang")) {
  131. type = TYPE_SERBANG;
  132. } else if (arg && !strcasecmp(arg, "si_prog")) {
  133. type = TYPE_SI_PROG;
  134. } else if (arg && !strcasecmp( arg, "ajawe")) {
  135. type = TYPE_AJAWE;
  136. } else if (arg && !strlen(arg)) {
  137. msg_perr("Error: Missing argument for programmer type.\n");
  138. free(arg);
  139. return 1;
  140. } else if (arg){
  141. msg_perr("Error: Invalid programmer type specified.\n");
  142. free(arg);
  143. return 1;
  144. }
  145. free(arg);
  146. /*
  147. * Configure the serial port pins, depending on the used programmer.
  148. */
  149. switch (type) {
  150. case TYPE_AJAWE:
  151. pony_negate_cs = 1;
  152. pony_negate_sck = 1;
  153. pony_negate_mosi = 1;
  154. pony_negate_miso = 1;
  155. name = "AJAWe";
  156. break;
  157. case TYPE_SERBANG:
  158. pony_negate_cs = 0;
  159. pony_negate_sck = 0;
  160. pony_negate_mosi = 0;
  161. pony_negate_miso = 1;
  162. name = "serbang";
  163. break;
  164. default:
  165. case TYPE_SI_PROG:
  166. pony_negate_cs = 1;
  167. pony_negate_sck = 0;
  168. pony_negate_mosi = 0;
  169. pony_negate_miso = 0;
  170. name = "SI-Prog";
  171. break;
  172. }
  173. msg_pdbg("Using %s programmer pinout.\n", name);
  174. /*
  175. * Detect if there is a compatible hardware programmer connected.
  176. */
  177. pony_bitbang_set_cs(1);
  178. pony_bitbang_set_sck(1);
  179. pony_bitbang_set_mosi(1);
  180. switch (type) {
  181. case TYPE_AJAWE:
  182. have_prog = 1;
  183. break;
  184. case TYPE_SI_PROG:
  185. case TYPE_SERBANG:
  186. default:
  187. have_prog = 1;
  188. /* We toggle RTS/SCK a few times and see if DSR changes too. */
  189. for (i = 1; i <= 10; i++) {
  190. data_out = i & 1;
  191. sp_set_pin(PIN_RTS, data_out);
  192. programmer_delay(1000);
  193. /* If DSR does not change, we are not connected to what we think */
  194. if (data_out != sp_get_pin(PIN_DSR)) {
  195. have_prog = 0;
  196. break;
  197. }
  198. }
  199. break;
  200. }
  201. if (!have_prog) {
  202. msg_perr("No programmer compatible with %s detected.\n", name);
  203. return 1;
  204. }
  205. if (register_spi_bitbang_master(&bitbang_spi_master_pony)) {
  206. return 1;
  207. }
  208. return 0;
  209. }