spi.c 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037
  1. /* Driver for Realtek PCI-Express card reader
  2. *
  3. * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2, or (at your option) any
  8. * later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, see <http://www.gnu.org/licenses/>.
  17. *
  18. * Author:
  19. * Wei WANG (wei_wang@realsil.com.cn)
  20. * Micky Ching (micky_ching@realsil.com.cn)
  21. */
  22. #include <linux/blkdev.h>
  23. #include <linux/kthread.h>
  24. #include <linux/sched.h>
  25. #include "rtsx.h"
  26. #include "spi.h"
  27. static inline void spi_set_err_code(struct rtsx_chip *chip, u8 err_code)
  28. {
  29. struct spi_info *spi = &(chip->spi);
  30. spi->err_code = err_code;
  31. }
  32. static int spi_init(struct rtsx_chip *chip)
  33. {
  34. int retval;
  35. retval = rtsx_write_register(chip, SPI_CONTROL, 0xFF,
  36. CS_POLARITY_LOW | DTO_MSB_FIRST | SPI_MASTER | SPI_MODE0 | SPI_AUTO);
  37. if (retval) {
  38. rtsx_trace(chip);
  39. return retval;
  40. }
  41. retval = rtsx_write_register(chip, SPI_TCTL, EDO_TIMING_MASK,
  42. SAMPLE_DELAY_HALF);
  43. if (retval) {
  44. rtsx_trace(chip);
  45. return retval;
  46. }
  47. return STATUS_SUCCESS;
  48. }
  49. static int spi_set_init_para(struct rtsx_chip *chip)
  50. {
  51. struct spi_info *spi = &(chip->spi);
  52. int retval;
  53. retval = rtsx_write_register(chip, SPI_CLK_DIVIDER1, 0xFF,
  54. (u8)(spi->clk_div >> 8));
  55. if (retval) {
  56. rtsx_trace(chip);
  57. return retval;
  58. }
  59. retval = rtsx_write_register(chip, SPI_CLK_DIVIDER0, 0xFF,
  60. (u8)(spi->clk_div));
  61. if (retval) {
  62. rtsx_trace(chip);
  63. return retval;
  64. }
  65. retval = switch_clock(chip, spi->spi_clock);
  66. if (retval != STATUS_SUCCESS) {
  67. rtsx_trace(chip);
  68. return STATUS_FAIL;
  69. }
  70. retval = select_card(chip, SPI_CARD);
  71. if (retval != STATUS_SUCCESS) {
  72. rtsx_trace(chip);
  73. return STATUS_FAIL;
  74. }
  75. retval = rtsx_write_register(chip, CARD_CLK_EN, SPI_CLK_EN,
  76. SPI_CLK_EN);
  77. if (retval) {
  78. rtsx_trace(chip);
  79. return retval;
  80. }
  81. retval = rtsx_write_register(chip, CARD_OE, SPI_OUTPUT_EN,
  82. SPI_OUTPUT_EN);
  83. if (retval) {
  84. rtsx_trace(chip);
  85. return retval;
  86. }
  87. wait_timeout(10);
  88. retval = spi_init(chip);
  89. if (retval != STATUS_SUCCESS) {
  90. rtsx_trace(chip);
  91. return STATUS_FAIL;
  92. }
  93. return STATUS_SUCCESS;
  94. }
  95. static int sf_polling_status(struct rtsx_chip *chip, int msec)
  96. {
  97. int retval;
  98. rtsx_init_cmd(chip);
  99. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, SPI_RDSR);
  100. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  101. SPI_TRANSFER0_START | SPI_POLLING_MODE0);
  102. rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
  103. SPI_TRANSFER0_END);
  104. retval = rtsx_send_cmd(chip, 0, msec);
  105. if (retval < 0) {
  106. rtsx_clear_spi_error(chip);
  107. spi_set_err_code(chip, SPI_BUSY_ERR);
  108. rtsx_trace(chip);
  109. return STATUS_FAIL;
  110. }
  111. return STATUS_SUCCESS;
  112. }
  113. static int sf_enable_write(struct rtsx_chip *chip, u8 ins)
  114. {
  115. struct spi_info *spi = &(chip->spi);
  116. int retval;
  117. if (!spi->write_en)
  118. return STATUS_SUCCESS;
  119. rtsx_init_cmd(chip);
  120. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
  121. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
  122. SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
  123. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  124. SPI_TRANSFER0_START | SPI_C_MODE0);
  125. rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
  126. SPI_TRANSFER0_END);
  127. retval = rtsx_send_cmd(chip, 0, 100);
  128. if (retval < 0) {
  129. rtsx_clear_spi_error(chip);
  130. spi_set_err_code(chip, SPI_HW_ERR);
  131. rtsx_trace(chip);
  132. return STATUS_FAIL;
  133. }
  134. return STATUS_SUCCESS;
  135. }
  136. static int sf_disable_write(struct rtsx_chip *chip, u8 ins)
  137. {
  138. struct spi_info *spi = &(chip->spi);
  139. int retval;
  140. if (!spi->write_en)
  141. return STATUS_SUCCESS;
  142. rtsx_init_cmd(chip);
  143. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
  144. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
  145. SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
  146. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  147. SPI_TRANSFER0_START | SPI_C_MODE0);
  148. rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
  149. SPI_TRANSFER0_END);
  150. retval = rtsx_send_cmd(chip, 0, 100);
  151. if (retval < 0) {
  152. rtsx_clear_spi_error(chip);
  153. spi_set_err_code(chip, SPI_HW_ERR);
  154. rtsx_trace(chip);
  155. return STATUS_FAIL;
  156. }
  157. return STATUS_SUCCESS;
  158. }
  159. static void sf_program(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr,
  160. u16 len)
  161. {
  162. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
  163. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
  164. SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
  165. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)len);
  166. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(len >> 8));
  167. if (addr_mode) {
  168. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
  169. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF,
  170. (u8)(addr >> 8));
  171. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF,
  172. (u8)(addr >> 16));
  173. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  174. SPI_TRANSFER0_START | SPI_CADO_MODE0);
  175. } else {
  176. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  177. SPI_TRANSFER0_START | SPI_CDO_MODE0);
  178. }
  179. rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
  180. SPI_TRANSFER0_END);
  181. }
  182. static int sf_erase(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr)
  183. {
  184. int retval;
  185. rtsx_init_cmd(chip);
  186. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
  187. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
  188. SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
  189. if (addr_mode) {
  190. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
  191. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF,
  192. (u8)(addr >> 8));
  193. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF,
  194. (u8)(addr >> 16));
  195. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  196. SPI_TRANSFER0_START | SPI_CA_MODE0);
  197. } else {
  198. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  199. SPI_TRANSFER0_START | SPI_C_MODE0);
  200. }
  201. rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
  202. SPI_TRANSFER0_END);
  203. retval = rtsx_send_cmd(chip, 0, 100);
  204. if (retval < 0) {
  205. rtsx_clear_spi_error(chip);
  206. spi_set_err_code(chip, SPI_HW_ERR);
  207. rtsx_trace(chip);
  208. return STATUS_FAIL;
  209. }
  210. return STATUS_SUCCESS;
  211. }
  212. static int spi_init_eeprom(struct rtsx_chip *chip)
  213. {
  214. int retval;
  215. int clk;
  216. if (chip->asic_code)
  217. clk = 30;
  218. else
  219. clk = CLK_30;
  220. retval = rtsx_write_register(chip, SPI_CLK_DIVIDER1, 0xFF, 0x00);
  221. if (retval) {
  222. rtsx_trace(chip);
  223. return retval;
  224. }
  225. retval = rtsx_write_register(chip, SPI_CLK_DIVIDER0, 0xFF, 0x27);
  226. if (retval) {
  227. rtsx_trace(chip);
  228. return retval;
  229. }
  230. retval = switch_clock(chip, clk);
  231. if (retval != STATUS_SUCCESS) {
  232. rtsx_trace(chip);
  233. return STATUS_FAIL;
  234. }
  235. retval = select_card(chip, SPI_CARD);
  236. if (retval != STATUS_SUCCESS) {
  237. rtsx_trace(chip);
  238. return STATUS_FAIL;
  239. }
  240. retval = rtsx_write_register(chip, CARD_CLK_EN, SPI_CLK_EN,
  241. SPI_CLK_EN);
  242. if (retval) {
  243. rtsx_trace(chip);
  244. return retval;
  245. }
  246. retval = rtsx_write_register(chip, CARD_OE, SPI_OUTPUT_EN,
  247. SPI_OUTPUT_EN);
  248. if (retval) {
  249. rtsx_trace(chip);
  250. return retval;
  251. }
  252. wait_timeout(10);
  253. retval = rtsx_write_register(chip, SPI_CONTROL, 0xFF,
  254. CS_POLARITY_HIGH | SPI_EEPROM_AUTO);
  255. if (retval) {
  256. rtsx_trace(chip);
  257. return retval;
  258. }
  259. retval = rtsx_write_register(chip, SPI_TCTL, EDO_TIMING_MASK,
  260. SAMPLE_DELAY_HALF);
  261. if (retval) {
  262. rtsx_trace(chip);
  263. return retval;
  264. }
  265. return STATUS_SUCCESS;
  266. }
  267. static int spi_eeprom_program_enable(struct rtsx_chip *chip)
  268. {
  269. int retval;
  270. rtsx_init_cmd(chip);
  271. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x86);
  272. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x13);
  273. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  274. SPI_TRANSFER0_START | SPI_CA_MODE0);
  275. rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
  276. SPI_TRANSFER0_END);
  277. retval = rtsx_send_cmd(chip, 0, 100);
  278. if (retval < 0) {
  279. rtsx_trace(chip);
  280. return STATUS_FAIL;
  281. }
  282. return STATUS_SUCCESS;
  283. }
  284. int spi_erase_eeprom_chip(struct rtsx_chip *chip)
  285. {
  286. int retval;
  287. retval = spi_init_eeprom(chip);
  288. if (retval != STATUS_SUCCESS) {
  289. rtsx_trace(chip);
  290. return STATUS_FAIL;
  291. }
  292. retval = spi_eeprom_program_enable(chip);
  293. if (retval != STATUS_SUCCESS) {
  294. rtsx_trace(chip);
  295. return STATUS_FAIL;
  296. }
  297. rtsx_init_cmd(chip);
  298. rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
  299. rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
  300. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x12);
  301. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x84);
  302. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  303. SPI_TRANSFER0_START | SPI_CA_MODE0);
  304. rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
  305. SPI_TRANSFER0_END);
  306. retval = rtsx_send_cmd(chip, 0, 100);
  307. if (retval < 0) {
  308. rtsx_trace(chip);
  309. return STATUS_FAIL;
  310. }
  311. retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01);
  312. if (retval) {
  313. rtsx_trace(chip);
  314. return retval;
  315. }
  316. return STATUS_SUCCESS;
  317. }
  318. int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr)
  319. {
  320. int retval;
  321. retval = spi_init_eeprom(chip);
  322. if (retval != STATUS_SUCCESS) {
  323. rtsx_trace(chip);
  324. return STATUS_FAIL;
  325. }
  326. retval = spi_eeprom_program_enable(chip);
  327. if (retval != STATUS_SUCCESS) {
  328. rtsx_trace(chip);
  329. return STATUS_FAIL;
  330. }
  331. rtsx_init_cmd(chip);
  332. rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
  333. rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
  334. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x07);
  335. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
  336. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
  337. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46);
  338. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  339. SPI_TRANSFER0_START | SPI_CA_MODE0);
  340. rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
  341. SPI_TRANSFER0_END);
  342. retval = rtsx_send_cmd(chip, 0, 100);
  343. if (retval < 0) {
  344. rtsx_trace(chip);
  345. return STATUS_FAIL;
  346. }
  347. retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01);
  348. if (retval) {
  349. rtsx_trace(chip);
  350. return retval;
  351. }
  352. return STATUS_SUCCESS;
  353. }
  354. int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val)
  355. {
  356. int retval;
  357. u8 data;
  358. retval = spi_init_eeprom(chip);
  359. if (retval != STATUS_SUCCESS) {
  360. rtsx_trace(chip);
  361. return STATUS_FAIL;
  362. }
  363. rtsx_init_cmd(chip);
  364. rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
  365. rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
  366. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x06);
  367. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
  368. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
  369. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46);
  370. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1);
  371. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  372. SPI_TRANSFER0_START | SPI_CADI_MODE0);
  373. rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
  374. SPI_TRANSFER0_END);
  375. retval = rtsx_send_cmd(chip, 0, 100);
  376. if (retval < 0) {
  377. rtsx_trace(chip);
  378. return STATUS_FAIL;
  379. }
  380. wait_timeout(5);
  381. retval = rtsx_read_register(chip, SPI_DATA, &data);
  382. if (retval) {
  383. rtsx_trace(chip);
  384. return retval;
  385. }
  386. if (val)
  387. *val = data;
  388. retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01);
  389. if (retval) {
  390. rtsx_trace(chip);
  391. return retval;
  392. }
  393. return STATUS_SUCCESS;
  394. }
  395. int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val)
  396. {
  397. int retval;
  398. retval = spi_init_eeprom(chip);
  399. if (retval != STATUS_SUCCESS) {
  400. rtsx_trace(chip);
  401. return STATUS_FAIL;
  402. }
  403. retval = spi_eeprom_program_enable(chip);
  404. if (retval != STATUS_SUCCESS) {
  405. rtsx_trace(chip);
  406. return STATUS_FAIL;
  407. }
  408. rtsx_init_cmd(chip);
  409. rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
  410. rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
  411. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x05);
  412. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, val);
  413. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr);
  414. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8));
  415. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x4E);
  416. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  417. SPI_TRANSFER0_START | SPI_CA_MODE0);
  418. rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
  419. SPI_TRANSFER0_END);
  420. retval = rtsx_send_cmd(chip, 0, 100);
  421. if (retval < 0) {
  422. rtsx_trace(chip);
  423. return STATUS_FAIL;
  424. }
  425. retval = rtsx_write_register(chip, CARD_GPIO_DIR, 0x01, 0x01);
  426. if (retval) {
  427. rtsx_trace(chip);
  428. return retval;
  429. }
  430. return STATUS_SUCCESS;
  431. }
  432. int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
  433. {
  434. struct spi_info *spi = &(chip->spi);
  435. dev_dbg(rtsx_dev(chip), "spi_get_status: err_code = 0x%x\n",
  436. spi->err_code);
  437. rtsx_stor_set_xfer_buf(&(spi->err_code),
  438. min_t(int, scsi_bufflen(srb), 1), srb);
  439. scsi_set_resid(srb, scsi_bufflen(srb) - 1);
  440. return STATUS_SUCCESS;
  441. }
  442. int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip)
  443. {
  444. struct spi_info *spi = &(chip->spi);
  445. spi_set_err_code(chip, SPI_NO_ERR);
  446. if (chip->asic_code)
  447. spi->spi_clock = ((u16)(srb->cmnd[8]) << 8) | srb->cmnd[9];
  448. else
  449. spi->spi_clock = srb->cmnd[3];
  450. spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
  451. spi->write_en = srb->cmnd[6];
  452. dev_dbg(rtsx_dev(chip), "spi_set_parameter: spi_clock = %d, clk_div = %d, write_en = %d\n",
  453. spi->spi_clock, spi->clk_div, spi->write_en);
  454. return STATUS_SUCCESS;
  455. }
  456. int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip)
  457. {
  458. int retval;
  459. u16 len;
  460. u8 *buf;
  461. spi_set_err_code(chip, SPI_NO_ERR);
  462. len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
  463. if (len > 512) {
  464. spi_set_err_code(chip, SPI_INVALID_COMMAND);
  465. rtsx_trace(chip);
  466. return STATUS_FAIL;
  467. }
  468. retval = spi_set_init_para(chip);
  469. if (retval != STATUS_SUCCESS) {
  470. spi_set_err_code(chip, SPI_HW_ERR);
  471. rtsx_trace(chip);
  472. return STATUS_FAIL;
  473. }
  474. rtsx_init_cmd(chip);
  475. rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01,
  476. PINGPONG_BUFFER);
  477. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, srb->cmnd[3]);
  478. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, srb->cmnd[4]);
  479. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, srb->cmnd[5]);
  480. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, srb->cmnd[6]);
  481. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
  482. SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
  483. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, srb->cmnd[7]);
  484. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, srb->cmnd[8]);
  485. if (len == 0) {
  486. if (srb->cmnd[9]) {
  487. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0,
  488. 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
  489. } else {
  490. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0,
  491. 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0);
  492. }
  493. } else {
  494. if (srb->cmnd[9]) {
  495. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  496. SPI_TRANSFER0_START | SPI_CADI_MODE0);
  497. } else {
  498. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  499. SPI_TRANSFER0_START | SPI_CDI_MODE0);
  500. }
  501. }
  502. rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
  503. SPI_TRANSFER0_END);
  504. retval = rtsx_send_cmd(chip, 0, 100);
  505. if (retval < 0) {
  506. rtsx_clear_spi_error(chip);
  507. spi_set_err_code(chip, SPI_HW_ERR);
  508. rtsx_trace(chip);
  509. return STATUS_FAIL;
  510. }
  511. if (len) {
  512. buf = kmalloc(len, GFP_KERNEL);
  513. if (!buf) {
  514. rtsx_trace(chip);
  515. return STATUS_ERROR;
  516. }
  517. retval = rtsx_read_ppbuf(chip, buf, len);
  518. if (retval != STATUS_SUCCESS) {
  519. spi_set_err_code(chip, SPI_READ_ERR);
  520. kfree(buf);
  521. rtsx_trace(chip);
  522. return STATUS_FAIL;
  523. }
  524. rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb);
  525. scsi_set_resid(srb, 0);
  526. kfree(buf);
  527. }
  528. return STATUS_SUCCESS;
  529. }
  530. int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
  531. {
  532. int retval;
  533. unsigned int index = 0, offset = 0;
  534. u8 ins, slow_read;
  535. u32 addr;
  536. u16 len;
  537. u8 *buf;
  538. spi_set_err_code(chip, SPI_NO_ERR);
  539. ins = srb->cmnd[3];
  540. addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5])
  541. << 8) | srb->cmnd[6];
  542. len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
  543. slow_read = srb->cmnd[9];
  544. retval = spi_set_init_para(chip);
  545. if (retval != STATUS_SUCCESS) {
  546. spi_set_err_code(chip, SPI_HW_ERR);
  547. rtsx_trace(chip);
  548. return STATUS_FAIL;
  549. }
  550. buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL);
  551. if (buf == NULL) {
  552. rtsx_trace(chip);
  553. return STATUS_ERROR;
  554. }
  555. while (len) {
  556. u16 pagelen = SF_PAGE_LEN - (u8)addr;
  557. if (pagelen > len)
  558. pagelen = len;
  559. rtsx_init_cmd(chip);
  560. trans_dma_enable(DMA_FROM_DEVICE, chip, 256, DMA_256);
  561. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
  562. if (slow_read) {
  563. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF,
  564. (u8)addr);
  565. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF,
  566. (u8)(addr >> 8));
  567. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF,
  568. (u8)(addr >> 16));
  569. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
  570. SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
  571. } else {
  572. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF,
  573. (u8)addr);
  574. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF,
  575. (u8)(addr >> 8));
  576. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR3, 0xFF,
  577. (u8)(addr >> 16));
  578. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
  579. SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_32);
  580. }
  581. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF,
  582. (u8)(pagelen >> 8));
  583. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF,
  584. (u8)pagelen);
  585. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  586. SPI_TRANSFER0_START | SPI_CADI_MODE0);
  587. rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0,
  588. SPI_TRANSFER0_END, SPI_TRANSFER0_END);
  589. rtsx_send_cmd_no_wait(chip);
  590. retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0,
  591. DMA_FROM_DEVICE, 10000);
  592. if (retval < 0) {
  593. kfree(buf);
  594. rtsx_clear_spi_error(chip);
  595. spi_set_err_code(chip, SPI_HW_ERR);
  596. rtsx_trace(chip);
  597. return STATUS_FAIL;
  598. }
  599. rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset,
  600. TO_XFER_BUF);
  601. addr += pagelen;
  602. len -= pagelen;
  603. }
  604. scsi_set_resid(srb, 0);
  605. kfree(buf);
  606. return STATUS_SUCCESS;
  607. }
  608. int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
  609. {
  610. int retval;
  611. u8 ins, program_mode;
  612. u32 addr;
  613. u16 len;
  614. u8 *buf;
  615. unsigned int index = 0, offset = 0;
  616. spi_set_err_code(chip, SPI_NO_ERR);
  617. ins = srb->cmnd[3];
  618. addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5])
  619. << 8) | srb->cmnd[6];
  620. len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
  621. program_mode = srb->cmnd[9];
  622. retval = spi_set_init_para(chip);
  623. if (retval != STATUS_SUCCESS) {
  624. spi_set_err_code(chip, SPI_HW_ERR);
  625. rtsx_trace(chip);
  626. return STATUS_FAIL;
  627. }
  628. if (program_mode == BYTE_PROGRAM) {
  629. buf = kmalloc(4, GFP_KERNEL);
  630. if (!buf) {
  631. rtsx_trace(chip);
  632. return STATUS_ERROR;
  633. }
  634. while (len) {
  635. retval = sf_enable_write(chip, SPI_WREN);
  636. if (retval != STATUS_SUCCESS) {
  637. kfree(buf);
  638. rtsx_trace(chip);
  639. return STATUS_FAIL;
  640. }
  641. rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset,
  642. FROM_XFER_BUF);
  643. rtsx_init_cmd(chip);
  644. rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
  645. 0x01, PINGPONG_BUFFER);
  646. rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF,
  647. buf[0]);
  648. sf_program(chip, ins, 1, addr, 1);
  649. retval = rtsx_send_cmd(chip, 0, 100);
  650. if (retval < 0) {
  651. kfree(buf);
  652. rtsx_clear_spi_error(chip);
  653. spi_set_err_code(chip, SPI_HW_ERR);
  654. rtsx_trace(chip);
  655. return STATUS_FAIL;
  656. }
  657. retval = sf_polling_status(chip, 100);
  658. if (retval != STATUS_SUCCESS) {
  659. kfree(buf);
  660. rtsx_trace(chip);
  661. return STATUS_FAIL;
  662. }
  663. addr++;
  664. len--;
  665. }
  666. kfree(buf);
  667. } else if (program_mode == AAI_PROGRAM) {
  668. int first_byte = 1;
  669. retval = sf_enable_write(chip, SPI_WREN);
  670. if (retval != STATUS_SUCCESS) {
  671. rtsx_trace(chip);
  672. return STATUS_FAIL;
  673. }
  674. buf = kmalloc(4, GFP_KERNEL);
  675. if (!buf) {
  676. rtsx_trace(chip);
  677. return STATUS_ERROR;
  678. }
  679. while (len) {
  680. rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset,
  681. FROM_XFER_BUF);
  682. rtsx_init_cmd(chip);
  683. rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE,
  684. 0x01, PINGPONG_BUFFER);
  685. rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF,
  686. buf[0]);
  687. if (first_byte) {
  688. sf_program(chip, ins, 1, addr, 1);
  689. first_byte = 0;
  690. } else {
  691. sf_program(chip, ins, 0, 0, 1);
  692. }
  693. retval = rtsx_send_cmd(chip, 0, 100);
  694. if (retval < 0) {
  695. kfree(buf);
  696. rtsx_clear_spi_error(chip);
  697. spi_set_err_code(chip, SPI_HW_ERR);
  698. rtsx_trace(chip);
  699. return STATUS_FAIL;
  700. }
  701. retval = sf_polling_status(chip, 100);
  702. if (retval != STATUS_SUCCESS) {
  703. kfree(buf);
  704. rtsx_trace(chip);
  705. return STATUS_FAIL;
  706. }
  707. len--;
  708. }
  709. kfree(buf);
  710. retval = sf_disable_write(chip, SPI_WRDI);
  711. if (retval != STATUS_SUCCESS) {
  712. rtsx_trace(chip);
  713. return STATUS_FAIL;
  714. }
  715. retval = sf_polling_status(chip, 100);
  716. if (retval != STATUS_SUCCESS) {
  717. rtsx_trace(chip);
  718. return STATUS_FAIL;
  719. }
  720. } else if (program_mode == PAGE_PROGRAM) {
  721. buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL);
  722. if (!buf) {
  723. rtsx_trace(chip);
  724. return STATUS_NOMEM;
  725. }
  726. while (len) {
  727. u16 pagelen = SF_PAGE_LEN - (u8)addr;
  728. if (pagelen > len)
  729. pagelen = len;
  730. retval = sf_enable_write(chip, SPI_WREN);
  731. if (retval != STATUS_SUCCESS) {
  732. kfree(buf);
  733. rtsx_trace(chip);
  734. return STATUS_FAIL;
  735. }
  736. rtsx_init_cmd(chip);
  737. trans_dma_enable(DMA_TO_DEVICE, chip, 256, DMA_256);
  738. sf_program(chip, ins, 1, addr, pagelen);
  739. rtsx_send_cmd_no_wait(chip);
  740. rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index,
  741. &offset, FROM_XFER_BUF);
  742. retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0,
  743. DMA_TO_DEVICE, 100);
  744. if (retval < 0) {
  745. kfree(buf);
  746. rtsx_clear_spi_error(chip);
  747. spi_set_err_code(chip, SPI_HW_ERR);
  748. rtsx_trace(chip);
  749. return STATUS_FAIL;
  750. }
  751. retval = sf_polling_status(chip, 100);
  752. if (retval != STATUS_SUCCESS) {
  753. kfree(buf);
  754. rtsx_trace(chip);
  755. return STATUS_FAIL;
  756. }
  757. addr += pagelen;
  758. len -= pagelen;
  759. }
  760. kfree(buf);
  761. } else {
  762. spi_set_err_code(chip, SPI_INVALID_COMMAND);
  763. rtsx_trace(chip);
  764. return STATUS_FAIL;
  765. }
  766. return STATUS_SUCCESS;
  767. }
  768. int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
  769. {
  770. int retval;
  771. u8 ins, erase_mode;
  772. u32 addr;
  773. spi_set_err_code(chip, SPI_NO_ERR);
  774. ins = srb->cmnd[3];
  775. addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5])
  776. << 8) | srb->cmnd[6];
  777. erase_mode = srb->cmnd[9];
  778. retval = spi_set_init_para(chip);
  779. if (retval != STATUS_SUCCESS) {
  780. spi_set_err_code(chip, SPI_HW_ERR);
  781. rtsx_trace(chip);
  782. return STATUS_FAIL;
  783. }
  784. if (erase_mode == PAGE_ERASE) {
  785. retval = sf_enable_write(chip, SPI_WREN);
  786. if (retval != STATUS_SUCCESS) {
  787. rtsx_trace(chip);
  788. return STATUS_FAIL;
  789. }
  790. retval = sf_erase(chip, ins, 1, addr);
  791. if (retval != STATUS_SUCCESS) {
  792. rtsx_trace(chip);
  793. return STATUS_FAIL;
  794. }
  795. } else if (erase_mode == CHIP_ERASE) {
  796. retval = sf_enable_write(chip, SPI_WREN);
  797. if (retval != STATUS_SUCCESS) {
  798. rtsx_trace(chip);
  799. return STATUS_FAIL;
  800. }
  801. retval = sf_erase(chip, ins, 0, 0);
  802. if (retval != STATUS_SUCCESS) {
  803. rtsx_trace(chip);
  804. return STATUS_FAIL;
  805. }
  806. } else {
  807. spi_set_err_code(chip, SPI_INVALID_COMMAND);
  808. rtsx_trace(chip);
  809. return STATUS_FAIL;
  810. }
  811. return STATUS_SUCCESS;
  812. }
  813. int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
  814. {
  815. int retval;
  816. u8 ins, status, ewsr;
  817. ins = srb->cmnd[3];
  818. status = srb->cmnd[4];
  819. ewsr = srb->cmnd[5];
  820. retval = spi_set_init_para(chip);
  821. if (retval != STATUS_SUCCESS) {
  822. spi_set_err_code(chip, SPI_HW_ERR);
  823. rtsx_trace(chip);
  824. return STATUS_FAIL;
  825. }
  826. retval = sf_enable_write(chip, ewsr);
  827. if (retval != STATUS_SUCCESS) {
  828. rtsx_trace(chip);
  829. return STATUS_FAIL;
  830. }
  831. rtsx_init_cmd(chip);
  832. rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01,
  833. PINGPONG_BUFFER);
  834. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
  835. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF,
  836. SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
  837. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, 0);
  838. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1);
  839. rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, status);
  840. rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF,
  841. SPI_TRANSFER0_START | SPI_CDO_MODE0);
  842. rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END,
  843. SPI_TRANSFER0_END);
  844. retval = rtsx_send_cmd(chip, 0, 100);
  845. if (retval != STATUS_SUCCESS) {
  846. rtsx_clear_spi_error(chip);
  847. spi_set_err_code(chip, SPI_HW_ERR);
  848. rtsx_trace(chip);
  849. return STATUS_FAIL;
  850. }
  851. return STATUS_SUCCESS;
  852. }