spi.c 24 KB

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