summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2011-07-22 15:45:58 +0000
committerAmaury Pouly <pamaury@rockbox.org>2011-07-22 15:45:58 +0000
commit82f70b8efdbff01a9b76e31f46300465b076f158 (patch)
tree056fd25a11b7fd29c5f8259c7531bd8623deed70 /firmware/target
parent85c32dbd12108fc570afdec450b7d73684f37a2d (diff)
downloadrockbox-82f70b8efdbff01a9b76e31f46300465b076f158.tar.gz
rockbox-82f70b8efdbff01a9b76e31f46300465b076f158.zip
imx233/fuze+: add SD detection supportbootloader_ams_v4
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30196 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/imx233/mmc-imx233.c7
-rw-r--r--firmware/target/arm/imx233/sd-imx233.c53
-rw-r--r--firmware/target/arm/imx233/ssp-imx233.c102
-rw-r--r--firmware/target/arm/imx233/ssp-imx233.h10
4 files changed, 154 insertions, 18 deletions
diff --git a/firmware/target/arm/imx233/mmc-imx233.c b/firmware/target/arm/imx233/mmc-imx233.c
index b0f1f36c26..889ba0cb82 100644
--- a/firmware/target/arm/imx233/mmc-imx233.c
+++ b/firmware/target/arm/imx233/mmc-imx233.c
@@ -25,7 +25,6 @@
25#include "storage.h" 25#include "storage.h"
26#include "ssp-imx233.h" 26#include "ssp-imx233.h"
27#include "pinctrl-imx233.h" 27#include "pinctrl-imx233.h"
28#include "button-target.h"
29 28
30/** 29/**
31 * This code assumes a single eMMC internal flash 30 * This code assumes a single eMMC internal flash
@@ -216,3 +215,9 @@ int mmc_write_sectors(IF_MD2(int drive,) unsigned long start, int count, const v
216 (void) buf; 215 (void) buf;
217 return -1; 216 return -1;
218} 217}
218
219bool mmc_present(IF_MD(int drive))
220{
221 IF_MD((void) drive);
222 return true;
223}
diff --git a/firmware/target/arm/imx233/sd-imx233.c b/firmware/target/arm/imx233/sd-imx233.c
index ccd8bf35c1..5e9f2cf030 100644
--- a/firmware/target/arm/imx233/sd-imx233.c
+++ b/firmware/target/arm/imx233/sd-imx233.c
@@ -22,9 +22,54 @@
22#include "system.h" 22#include "system.h"
23#include "sd.h" 23#include "sd.h"
24#include "sdmmc.h" 24#include "sdmmc.h"
25#include "ssp-imx233.h"
26#include "pinctrl-imx233.h"
27#include "button-target.h"
28
29/**
30 * This code assumes a single SD card slot
31 */
32
33#ifdef SANSA_FUZEPLUS
34#define SD_SSP 1
35#else
36#error You need to configure the ssp to use
37#endif
38
39static tCardInfo card_info;
40static struct mutex sd_mutex;
41
42static void sd_detect_callback(int ssp)
43{
44 (void)ssp;
45
46 /* This is called only if the state was stable for 300ms - check state
47 * and post appropriate event. */
48 if(imx233_ssp_sdmmc_detect(SD_SSP))
49 queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
50 else
51 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
52 printf("sd_detect_callback(%d)", imx233_ssp_sdmmc_detect(SD_SSP));
53 imx233_ssp_sdmmc_setup_detect(SD_SSP, true, sd_detect_callback);
54}
25 55
26int sd_init(void) 56int sd_init(void)
27{ 57{
58 mutex_init(&sd_mutex);
59
60 imx233_ssp_start(SD_SSP);
61 imx233_ssp_softreset(SD_SSP);
62 imx233_ssp_set_mode(SD_SSP, HW_SSP_CTRL1__SSP_MODE__SD_MMC);
63 #ifdef SANSA_FUZEPLUS
64 imx233_ssp_setup_ssp1_sd_mmc_pins(true, 4, PINCTRL_DRIVE_8mA, false);
65 #endif
66 imx233_ssp_sdmmc_setup_detect(SD_SSP, true, sd_detect_callback);
67 /* SSPCLK @ 96MHz
68 * gives bitrate of 96000 / 240 / 1 = 400kHz */
69 imx233_ssp_set_timings(SD_SSP, 240, 0, 0xffff);
70 imx233_ssp_set_bus_width(SD_SSP, 1);
71 imx233_ssp_set_block_size(SD_SSP, 9);
72
28 return 0; 73 return 0;
29} 74}
30 75
@@ -57,6 +102,12 @@ tCardInfo *card_get_info_target(int card_no)
57int sd_num_drives(int first_drive) 102int sd_num_drives(int first_drive)
58{ 103{
59 (void) first_drive; 104 (void) first_drive;
60 return 0; 105 return 1;
106}
107
108bool sd_present(IF_MD(int drive))
109{
110 IF_MD((void) drive);
111 return imx233_ssp_sdmmc_detect(SD_SSP);
61} 112}
62 113
diff --git a/firmware/target/arm/imx233/ssp-imx233.c b/firmware/target/arm/imx233/ssp-imx233.c
index 59405bbdc2..c3ce8a8f58 100644
--- a/firmware/target/arm/imx233/ssp-imx233.c
+++ b/firmware/target/arm/imx233/ssp-imx233.c
@@ -44,6 +44,7 @@ static struct semaphore ssp_sema[2];
44static struct ssp_dma_command_t ssp_dma_cmd[2]; 44static struct ssp_dma_command_t ssp_dma_cmd[2];
45static uint32_t ssp_bus_width[2]; 45static uint32_t ssp_bus_width[2];
46static unsigned ssp_log_block_size[2]; 46static unsigned ssp_log_block_size[2];
47static ssp_detect_cb_t ssp_detect_cb[2];
47 48
48void INT_SSP(int ssp) 49void INT_SSP(int ssp)
49{ 50{
@@ -146,22 +147,7 @@ static void setup_ssp_sd_pins(int ssp)
146 147
147 if(ssp == 1) 148 if(ssp == 1)
148 { 149 {
149 /* SSP_SCK: drive 8mA */ 150
150 imx233_set_pin_drive_strength(2, 6, PINCTRL_DRIVE_8mA);
151 /* SSP_{SCK,DATA{3,2,1,0},DETECT,CMD} */
152 imx233_set_pin_function(2, 6, PINCTRL_FUNCTION_MAIN);
153 imx233_set_pin_function(2, 5, PINCTRL_FUNCTION_MAIN);
154 imx233_set_pin_function(2, 4, PINCTRL_FUNCTION_MAIN);
155 imx233_set_pin_function(2, 3, PINCTRL_FUNCTION_MAIN);
156 imx233_set_pin_function(2, 2, PINCTRL_FUNCTION_MAIN);
157 imx233_set_pin_function(2, 1, PINCTRL_FUNCTION_MAIN);
158 imx233_set_pin_function(2, 0, PINCTRL_FUNCTION_MAIN);
159 /* SSP_CMD: pullup */
160 imx233_enable_pin_pullup(2, 0, true);
161 imx233_enable_pin_pullup(2, 2, true);
162 imx233_enable_pin_pullup(2, 3, true);
163 imx233_enable_pin_pullup(2, 4, true);
164 imx233_enable_pin_pullup(2, 5, true);
165 } 151 }
166 else 152 else
167 { 153 {
@@ -170,6 +156,41 @@ static void setup_ssp_sd_pins(int ssp)
170} 156}
171#endif 157#endif
172 158
159void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width,
160 unsigned drive_strength, bool use_alt)
161{
162 /* SSP_{CMD,SCK} */
163 imx233_set_pin_drive_strength(2, 0, drive_strength);
164 imx233_set_pin_drive_strength(2, 6, drive_strength);
165 imx233_set_pin_function(2, 0, PINCTRL_FUNCTION_MAIN);
166 imx233_set_pin_function(2, 6, PINCTRL_FUNCTION_MAIN);
167 imx233_enable_pin_pullup(2, 0, enable_pullups);
168 /* SSP_DATA{0-3} */
169 for(unsigned i = 0; i < MIN(bus_width, 4); i++)
170 {
171 imx233_set_pin_drive_strength(2, 2 + i, drive_strength);
172 imx233_set_pin_function(2, 2 + i, PINCTRL_FUNCTION_MAIN);
173 imx233_enable_pin_pullup(2, 2 + i, enable_pullups);
174 }
175
176 /* SSP_DATA{4-7} */
177 for(unsigned i = 4; i < bus_width; i++)
178 {
179 if(use_alt)
180 {
181 imx233_set_pin_drive_strength(0, 22 + i, drive_strength);
182 imx233_set_pin_function(0, 22 + i, PINCTRL_FUNCTION_ALT2);
183 imx233_enable_pin_pullup(0, 22 + i, enable_pullups);
184 }
185 else
186 {
187 imx233_set_pin_drive_strength(0, 4 + i, drive_strength);
188 imx233_set_pin_function(0, 4 + i, PINCTRL_FUNCTION_ALT2);
189 imx233_enable_pin_pullup(0, 4 + i, enable_pullups);
190 }
191 }
192}
193
173void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, 194void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width,
174 unsigned drive_strength) 195 unsigned drive_strength)
175{ 196{
@@ -301,3 +322,52 @@ void imx233_ssp_sd_mmc_power_up_sequence(int ssp)
301 mdelay(1); 322 mdelay(1);
302 __REG_CLR(HW_SSP_CMD0(ssp)) = HW_SSP_CMD0__CONT_CLKING_EN; 323 __REG_CLR(HW_SSP_CMD0(ssp)) = HW_SSP_CMD0__CONT_CLKING_EN;
303} 324}
325
326static int ssp_detect_oneshot_callback(int ssp)
327{
328 printf("ssp_detect_oneshot_callback(%d)", ssp);
329 if(ssp_detect_cb[ssp - 1])
330 ssp_detect_cb[ssp - 1](ssp);
331
332 return 0;
333}
334
335static int ssp1_detect_oneshot_callback(struct timeout *tmo)
336{
337 (void) tmo;
338 return ssp_detect_oneshot_callback(1);
339}
340
341static int ssp2_detect_oneshot_callback(struct timeout *tmo)
342{
343 (void) tmo;
344 return ssp_detect_oneshot_callback(2);
345}
346
347static void detect_irq(int bank, int pin)
348{
349 static struct timeout ssp1_detect_oneshot;
350 static struct timeout ssp2_detect_oneshot;
351 if(bank == 2 && pin == 1)
352 timeout_register(&ssp1_detect_oneshot, ssp1_detect_oneshot_callback, (3*HZ/10), 0);
353 else if(bank == 0 && pin == 19)
354 timeout_register(&ssp2_detect_oneshot, ssp2_detect_oneshot_callback, (3*HZ/10), 0);
355}
356
357void imx233_ssp_sdmmc_setup_detect(int ssp, bool enable, ssp_detect_cb_t fn)
358{
359 int bank = ssp == 1 ? 2 : 0;
360 int pin = ssp == 1 ? 1 : 19;
361 ssp_detect_cb[ssp - 1] = fn;
362 if(enable)
363 {
364 imx233_set_pin_function(bank, pin, PINCTRL_FUNCTION_GPIO);
365 imx233_enable_gpio_output(bank, pin, false);
366 }
367 imx233_setup_pin_irq(bank, pin, enable, true, !imx233_ssp_sdmmc_detect(ssp), detect_irq);
368}
369
370bool imx233_ssp_sdmmc_detect(int ssp)
371{
372 return !!(HW_SSP_STATUS(ssp) & HW_SSP_STATUS__CARD_DETECT);
373}
diff --git a/firmware/target/arm/imx233/ssp-imx233.h b/firmware/target/arm/imx233/ssp-imx233.h
index c7c891ec0b..c9083d8d75 100644
--- a/firmware/target/arm/imx233/ssp-imx233.h
+++ b/firmware/target/arm/imx233/ssp-imx233.h
@@ -27,6 +27,7 @@
27#include "cpu.h" 27#include "cpu.h"
28#include "system.h" 28#include "system.h"
29#include "system-target.h" 29#include "system-target.h"
30#include "pinctrl-imx233.h"
30 31
31/* ssp can value 1 or 2 */ 32/* ssp can value 1 or 2 */
32#define __SSP_SELECT(ssp, ssp1, ssp2) ((ssp) == 1 ? (ssp1) : (ssp2)) 33#define __SSP_SELECT(ssp, ssp1, ssp2) ((ssp) == 1 ? (ssp1) : (ssp2))
@@ -122,6 +123,7 @@
122#define HW_SSP_STATUS__RESP_TIMEOUT (1 << 14) 123#define HW_SSP_STATUS__RESP_TIMEOUT (1 << 14)
123#define HW_SSP_STATUS__RESP_ERR (1 << 15) 124#define HW_SSP_STATUS__RESP_ERR (1 << 15)
124#define HW_SSP_STATUS__RESP_CRC_ERR (1 << 16) 125#define HW_SSP_STATUS__RESP_CRC_ERR (1 << 16)
126#define HW_SSP_STATUS__CARD_DETECT (1 << 28)
125#define HW_SSP_STATUS__ALL_ERRORS 0x1f800 127#define HW_SSP_STATUS__ALL_ERRORS 0x1f800
126 128
127#define HW_SSP_DEBUG(ssp) (*(volatile uint32_t *)(HW_SSP_BASE(ssp) + 0x100)) 129#define HW_SSP_DEBUG(ssp) (*(volatile uint32_t *)(HW_SSP_BASE(ssp) + 0x100))
@@ -142,6 +144,8 @@ enum imx233_ssp_resp_t
142 SSP_LONG_RESP 144 SSP_LONG_RESP
143}; 145};
144 146
147typedef void (*ssp_detect_cb_t)(int ssp);
148
145void imx233_ssp_init(void); 149void imx233_ssp_init(void);
146void imx233_ssp_start(int ssp); 150void imx233_ssp_start(int ssp);
147void imx233_ssp_stop(int ssp); 151void imx233_ssp_stop(int ssp);
@@ -156,8 +160,14 @@ void imx233_ssp_set_block_size(int ssp, unsigned log_block_size);
156enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd, 160enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd,
157 uint32_t cmd_arg, enum imx233_ssp_resp_t resp, void *buffer, unsigned block_count, 161 uint32_t cmd_arg, enum imx233_ssp_resp_t resp, void *buffer, unsigned block_count,
158 bool wait4irq, bool read, uint32_t *resp_ptr); 162 bool wait4irq, bool read, uint32_t *resp_ptr);
163void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width,
164 unsigned drive_strength, bool use_alt);
159void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, 165void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width,
160 unsigned drive_strength); 166 unsigned drive_strength);
167/* after callback is fired, imx233_ssp_sdmmc_setup_detect needs to be called
168 * to enable detection again */
169void imx233_ssp_sdmmc_setup_detect(int ssp, bool enable, ssp_detect_cb_t fn);
170bool imx233_ssp_sdmmc_detect(int ssp);
161/* SD/MMC requires that the card be provided the clock during an init sequence of 171/* SD/MMC requires that the card be provided the clock during an init sequence of
162 * at least 1msec (or 74 clocks). Does NOT touch the clock so it has to be correct. */ 172 * at least 1msec (or 74 clocks). Does NOT touch the clock so it has to be correct. */
163void imx233_ssp_sd_mmc_power_up_sequence(int ssp); 173void imx233_ssp_sd_mmc_power_up_sequence(int ssp);