Guest User

Untitled

a guest
Dec 9th, 2011
58
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /***************************************************************************
  2. * __________ __ ___.
  3. * Open \______ \ ____ ____ | | _\_ |__ _______ ___
  4. * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
  5. * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
  6. * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
  7. * \/ \/ \/ \/ \/
  8. * $Id$
  9. *
  10. * Copyright (C) 2011 by Amaury Pouly
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License
  14. * as published by the Free Software Foundation; either version 2
  15. * of the License, or (at your option) any later version.
  16. *
  17. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  18. * KIND, either express or implied.
  19. *
  20. ****************************************************************************/
  21. #include "config.h"
  22. #include "system.h"
  23. #include "sd.h"
  24. #include "sdmmc.h"
  25. #include "ssp-imx233.h"
  26. #include "pinctrl-imx233.h"
  27. #include "button-target.h"
  28. #include "fat.h"
  29. #include "disk.h"
  30. #include "usb.h"
  31. #include "debug.h"
  32.  
  33. /**
  34. * This code assumes a single SD card slot
  35. */
  36.  
  37. #ifdef SANSA_FUZEPLUS
  38. #define SD_SSP 1
  39. #else
  40. #error You need to configure the ssp to use
  41. #endif
  42.  
  43. static tCardInfo card_info;
  44. static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
  45. static struct mutex sd_mutex;
  46. static const char sd_thread_name[] = "sd";
  47. static struct event_queue sd_queue;
  48. static int sd_first_drive;
  49. static int last_disk_activity;
  50.  
  51. static void sd_detect_callback(int ssp)
  52. {
  53. (void)ssp;
  54.  
  55. /* This is called only if the state was stable for 300ms - check state
  56. * and post appropriate event. */
  57. if(imx233_ssp_sdmmc_detect(SD_SSP))
  58. queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
  59. else
  60. queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
  61. imx233_ssp_sdmmc_setup_detect(SD_SSP, true, sd_detect_callback);
  62. }
  63.  
  64. void sd_power(bool on)
  65. {
  66. #ifdef SANSA_FUZEPLUS
  67. /* The Fuze+ uses pin B0P8 for whatever reason, power ? */
  68. imx233_set_pin_function(0, 8, PINCTRL_FUNCTION_GPIO);
  69. imx233_enable_gpio_output(0, 8, true);
  70. imx233_set_gpio_output(0, 8, !on);
  71. /* disable pull ups when not needed to save power */
  72. imx233_ssp_setup_ssp1_sd_mmc_pins(on, 4, PINCTRL_DRIVE_4mA, false);
  73. /* It also setups pin B1P30, unknown purpose */
  74. imx233_set_pin_function(1, 30, PINCTRL_FUNCTION_GPIO);
  75. imx233_enable_gpio_output(1, 30, false);
  76. #endif
  77. }
  78.  
  79. void sd_enable(bool on)
  80. {
  81. static bool sd_enable = false;
  82. if(sd_enable == on)
  83. return;
  84.  
  85. sd_enable = on;
  86. }
  87.  
  88. #define MCI_NO_RESP 0
  89. #define MCI_RESP (1<<0)
  90. #define MCI_LONG_RESP (1<<1)
  91. #define MCI_ACMD (1<<2)
  92. #define MCI_NOCRC (1<<3)
  93.  
  94. static bool send_cmd(uint8_t cmd, uint32_t arg, uint32_t flags, uint32_t *resp)
  95. {
  96. if((flags & MCI_ACMD) && !send_cmd(SD_APP_CMD, card_info.rca, MCI_RESP, resp))
  97. return false;
  98.  
  99. enum imx233_ssp_resp_t resp_type = (flags & MCI_LONG_RESP) ? SSP_LONG_RESP :
  100. (flags & MCI_RESP) ? SSP_SHORT_RESP : SSP_NO_RESP;
  101. enum imx233_ssp_error_t ret = imx233_ssp_sd_mmc_transfer(SD_SSP, cmd, arg,
  102. resp_type, NULL, 0, false, false, resp);
  103. return ret == SSP_SUCCESS;
  104. }
  105.  
  106. static int sd_wait_for_tran_state(void)
  107. {
  108. unsigned long response;
  109. unsigned int timeout = current_tick + 5*HZ;
  110. int cmd_retry = 10;
  111.  
  112. while (1)
  113. {
  114. while(!send_cmd(SD_SEND_STATUS, card_info.rca, SSP_SHORT_RESP, &response) && cmd_retry > 0)
  115. cmd_retry--;
  116.  
  117. if(cmd_retry <= 0)
  118. return -1;
  119.  
  120. if(((response >> 9) & 0xf) == SD_TRAN)
  121. return 0;
  122.  
  123. if(TIME_AFTER(current_tick, timeout))
  124. return -10 * ((response >> 9) & 0xf);
  125.  
  126. last_disk_activity = current_tick;
  127. }
  128. }
  129.  
  130. static int sd_init_card(void)
  131. {
  132. imx233_ssp_start(SD_SSP);
  133. imx233_ssp_softreset(SD_SSP);
  134. imx233_ssp_set_mode(SD_SSP, HW_SSP_CTRL1__SSP_MODE__SD_MMC);
  135. /* SSPCLK @ 96MHz
  136. * gives bitrate of 96000 / 240 / 1 = 400kHz */
  137. imx233_ssp_set_timings(SD_SSP, 240, 0, 0xffff);
  138.  
  139. imx233_ssp_sd_mmc_power_up_sequence(SD_SSP);
  140. imx233_ssp_set_bus_width(SD_SSP, 1);
  141. imx233_ssp_set_block_size(SD_SSP, 9);
  142.  
  143. card_info.rca = 0;
  144. bool sd_v2 = false;
  145. uint32_t resp;
  146. long init_timeout;
  147. /* go to idle state */
  148. if(!send_cmd(SD_GO_IDLE_STATE, 0, MCI_NO_RESP, NULL))
  149. return -1;
  150. /* CMD8 Check for v2 sd card. Must be sent before using ACMD41
  151. Non v2 cards will not respond to this command */
  152. if(send_cmd(SD_SEND_IF_COND, 0x1AA, MCI_RESP, &resp))
  153. if((resp & 0xFFF) == 0x1AA)
  154. sd_v2 = true;
  155. /* timeout for initialization is 1sec, from SD Specification 2.00 */
  156. init_timeout = current_tick + HZ;
  157. do
  158. {
  159. /* this timeout is the only valid error for this loop*/
  160. if(TIME_AFTER(current_tick, init_timeout))
  161. return -2;
  162.  
  163. /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */
  164. if(!send_cmd(SD_APP_OP_COND, (0x00FF8000 | (sd_v2 ? 1<<30 : 0)),
  165. MCI_ACMD|MCI_NOCRC|MCI_RESP, &card_info.ocr))
  166. return -100;
  167. } while(!(card_info.ocr & (1<<31)));
  168.  
  169. /* CMD2 send CID */
  170. if(!send_cmd(SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP, card_info.cid))
  171. return -3;
  172.  
  173. /* CMD3 send RCA */
  174. if(!send_cmd(SD_SEND_RELATIVE_ADDR, 0, MCI_RESP, &card_info.rca))
  175. return -4;
  176.  
  177. /* Try to switch V2 cards to HS timings, non HS seem to ignore this */
  178. if(sd_v2)
  179. {
  180. /* CMD7 w/rca: Select card to put it in TRAN state */
  181. if(!send_cmd(SD_SELECT_CARD, card_info.rca, MCI_RESP, NULL))
  182. return -5;
  183.  
  184. if(sd_wait_for_tran_state())
  185. return -6;
  186.  
  187. /* CMD6 */
  188. if(!send_cmd(SD_SWITCH_FUNC, 0x80fffff1, MCI_NO_RESP, NULL))
  189. return -7;
  190. sleep(HZ/10);
  191.  
  192. /* go back to STBY state so we can read csd */
  193. /* CMD7 w/rca=0: Deselect card to put it in STBY state */
  194. if(!send_cmd(SD_DESELECT_CARD, 0, MCI_NO_RESP, NULL))
  195. return -8;
  196. }
  197.  
  198. /* CMD9 send CSD */
  199. if(!send_cmd(SD_SEND_CSD, card_info.rca, MCI_RESP|MCI_LONG_RESP, card_info.csd))
  200. return -9;
  201.  
  202. sd_parse_csd(&card_info);
  203.  
  204. /* SSPCLK @ 96MHz
  205. * gives bitrate of 96 / 4 / 1 = 24MHz */
  206. imx233_ssp_set_timings(SD_SSP, 4, 0, 0xffff);
  207.  
  208. /* CMD7 w/rca: Select card to put it in TRAN state */
  209. if(!send_cmd(SD_SELECT_CARD, card_info.rca, MCI_RESP, &resp))
  210. return -12;
  211. if(sd_wait_for_tran_state() < 0)
  212. return -13;
  213.  
  214. /* ACMD6: set bus width to 4-bit */
  215. if(!send_cmd(SD_SET_BUS_WIDTH, 2, MCI_RESP|MCI_ACMD, &resp))
  216. return -15;
  217. /* ACMD42: disconnect the pull-up resistor on CD/DAT3 */
  218. if(!send_cmd(SD_SET_CLR_CARD_DETECT, 0, MCI_RESP|MCI_ACMD, &resp))
  219. return -17;
  220.  
  221. /* Switch to 4-bit */
  222. imx233_ssp_set_bus_width(SD_SSP, 4);
  223.  
  224. card_info.initialized = 1;
  225.  
  226. return 0;
  227. }
  228.  
  229. static void sd_thread(void) NORETURN_ATTR;
  230. static void sd_thread(void)
  231. {
  232. struct queue_event ev;
  233.  
  234. while (1)
  235. {
  236. queue_wait_w_tmo(&sd_queue, &ev, HZ);
  237.  
  238. switch(ev.id)
  239. {
  240. case SYS_HOTSWAP_INSERTED:
  241. case SYS_HOTSWAP_EXTRACTED:
  242. {
  243. int microsd_init = 1;
  244. fat_lock(); /* lock-out FAT activity first -
  245. prevent deadlocking via disk_mount that
  246. would cause a reverse-order attempt with
  247. another thread */
  248. mutex_lock(&sd_mutex); /* lock-out card activity - direct calls
  249. into driver that bypass the fat cache */
  250.  
  251. /* We now have exclusive control of fat cache and sd */
  252.  
  253. disk_unmount(sd_first_drive); /* release "by force", ensure file
  254. descriptors aren't leaked and any busy
  255. ones are invalid if mounting */
  256. /* Force card init for new card, re-init for re-inserted one or
  257. * clear if the last attempt to init failed with an error. */
  258. card_info.initialized = 0;
  259.  
  260. if(ev.id == SYS_HOTSWAP_INSERTED)
  261. {
  262. sd_power(true);
  263. sd_enable(true);
  264. microsd_init = sd_init_card();
  265. _logf("sd_init_card: %d", microsd_init);
  266. if(microsd_init == 0)
  267. microsd_init = disk_mount(sd_first_drive); /* 0 if fail */
  268. else
  269. DEBUGF("sd_init_card failed: %d", ret);
  270. }
  271. else
  272. sd_power(false);
  273. panicf("ok");
  274. /*
  275. * Mount succeeded, or this was an EXTRACTED event,
  276. * in both cases notify the system about the changed filesystems
  277. */
  278. if(microsd_init)
  279. queue_broadcast(SYS_FS_CHANGED, 0);
  280.  
  281. sd_enable(false);
  282. /* Access is now safe */
  283. mutex_unlock(&sd_mutex);
  284. fat_unlock();
  285. break;
  286. }
  287. case SYS_TIMEOUT:
  288. if(!TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
  289. sd_enable(false);
  290. break;
  291. case SYS_USB_CONNECTED:
  292. usb_acknowledge(SYS_USB_CONNECTED_ACK);
  293. /* Wait until the USB cable is extracted again */
  294. usb_wait_for_disconnect(&sd_queue);
  295. break;
  296. }
  297. }
  298. }
  299.  
  300. int sd_init(void)
  301. {
  302. mutex_init(&sd_mutex);
  303. queue_init(&sd_queue, true);
  304. create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
  305. sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
  306.  
  307. imx233_ssp_sdmmc_setup_detect(SD_SSP, true, sd_detect_callback);
  308.  
  309. if(imx233_ssp_sdmmc_detect(SD_SSP))
  310. queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
  311.  
  312. return 0;
  313. }
  314.  
  315. static int transfer_sectors(IF_MD2(int drive,) unsigned long start, int count, void *buf, bool read)
  316. {
  317. IF_MD((void) drive);
  318. int ret = 0;
  319. uint32_t resp;
  320.  
  321. last_disk_activity = current_tick;
  322.  
  323. mutex_lock(&sd_mutex);
  324. mutex_unlock(&sd_mutex);
  325. return -1;
  326.  
  327. mutex_lock(&sd_mutex);
  328. sd_enable(true);
  329.  
  330. ret = -1;
  331. goto Lend;
  332.  
  333. if(card_info.initialized <= 0)
  334. {
  335. ret = sd_init_card();
  336. if(!(card_info.initialized))
  337. goto Lend;
  338. }
  339.  
  340. if(!send_cmd(SD_SELECT_CARD, card_info.rca, SSP_NO_RESP, NULL))
  341. {
  342. _logf("sd: can't select card");
  343. ret = -20;
  344. goto Lend;
  345. }
  346. ret = sd_wait_for_tran_state();
  347. if(ret < 0)
  348. {
  349. _logf("sd: wait for tran: %d", ret);
  350. goto Ldeselect;
  351. }
  352.  
  353. while(count != 0)
  354. {
  355. int this_count = MIN(count, IMX233_MAX_SSP_XFER_SIZE / 512);
  356. ret = imx233_ssp_sd_mmc_transfer(SD_SSP, read ? SD_READ_MULTIPLE_BLOCK : SD_WRITE_MULTIPLE_BLOCK,
  357. start, SSP_SHORT_RESP, buf, this_count, false, read, &resp);
  358. if(ret != SSP_SUCCESS)
  359. {
  360. _logf("sd: read: %d", ret);
  361. break;
  362. }
  363. if(!send_cmd(SD_STOP_TRANSMISSION, 0, SSP_SHORT_RESP, &resp))
  364. {
  365. _logf("sd: stop: %d", ret);
  366. break;
  367. }
  368. count -= this_count;
  369. start += this_count;
  370. buf += this_count * 512;
  371. }
  372.  
  373. Ldeselect:
  374. /* CMD lines are separate, not common, so we need to actively deselect */
  375. /* CMD7 w/rca =0 : deselects card & puts it in STBY state */
  376. if(!send_cmd(SD_DESELECT_CARD, 0, SSP_NO_RESP, NULL))
  377. ret = -23;
  378.  
  379. Lend:
  380. mutex_unlock(&sd_mutex);
  381. return ret;
  382. }
  383.  
  384. int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
  385. void* buf)
  386. {
  387. return transfer_sectors(IF_MD2(drive,) start, count, buf, true);
  388. }
  389.  
  390. int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
  391. const void* buf)
  392. {
  393. //return transfer_sectors(IF_MD2(drive,) start, count, (void *)buf, false);
  394. return -1;
  395. }
  396.  
  397. tCardInfo *card_get_info_target(int card_no)
  398. {
  399. (void)card_no;
  400. return &card_info;
  401. }
  402.  
  403. int sd_num_drives(int first_drive)
  404. {
  405. sd_first_drive = first_drive;
  406. return 1;
  407. }
  408.  
  409. bool sd_present(IF_MD(int drive))
  410. {
  411. IF_MD((void) drive);
  412. return imx233_ssp_sdmmc_detect(SD_SSP);
  413. }
  414.  
  415. bool sd_removable(IF_MD(int drive))
  416. {
  417. IF_MD((void) drive);
  418. return true;
  419. }
  420.  
  421. long sd_last_disk_activity(void)
  422. {
  423. return last_disk_activity;
  424. }
  425.  
  426.  
  427.  
RAW Paste Data