diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/config/sansafuzeplus.h | 10 | ||||
-rw-r--r-- | firmware/target/arm/imx233/mmc-imx233.c | 7 | ||||
-rw-r--r-- | firmware/target/arm/imx233/sd-imx233.c | 53 | ||||
-rw-r--r-- | firmware/target/arm/imx233/ssp-imx233.c | 102 | ||||
-rw-r--r-- | firmware/target/arm/imx233/ssp-imx233.h | 10 |
5 files changed, 157 insertions, 25 deletions
diff --git a/firmware/export/config/sansafuzeplus.h b/firmware/export/config/sansafuzeplus.h index e0dc76a766..4c3cd6014b 100644 --- a/firmware/export/config/sansafuzeplus.h +++ b/firmware/export/config/sansafuzeplus.h | |||
@@ -118,13 +118,9 @@ | |||
118 | #define HAVE_FLASH_STORAGE | 118 | #define HAVE_FLASH_STORAGE |
119 | 119 | ||
120 | /* define this if the flash memory uses the SecureDigital Memory Card protocol */ | 120 | /* define this if the flash memory uses the SecureDigital Memory Card protocol */ |
121 | #ifdef BOOTLOADER | 121 | #define CONFIG_STORAGE (STORAGE_SD | STORAGE_MMC) |
122 | # define CONFIG_STORAGE STORAGE_MMC | 122 | #define NUM_DRIVES 2 |
123 | #else | 123 | #define HAVE_HOTSWAP |
124 | # define CONFIG_STORAGE (STORAGE_SD | STORAGE_MMC) | ||
125 | # define NUM_DRIVES 2 | ||
126 | # define HAVE_HOTSWAP | ||
127 | #endif | ||
128 | 124 | ||
129 | /* todo */ | 125 | /* todo */ |
130 | #define BATTERY_CAPACITY_DEFAULT 550 /* default battery capacity */ | 126 | #define BATTERY_CAPACITY_DEFAULT 550 /* default battery capacity */ |
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 | |||
219 | bool 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 | |||
39 | static tCardInfo card_info; | ||
40 | static struct mutex sd_mutex; | ||
41 | |||
42 | static 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 | ||
26 | int sd_init(void) | 56 | int 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) | |||
57 | int sd_num_drives(int first_drive) | 102 | int sd_num_drives(int first_drive) |
58 | { | 103 | { |
59 | (void) first_drive; | 104 | (void) first_drive; |
60 | return 0; | 105 | return 1; |
106 | } | ||
107 | |||
108 | bool 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]; | |||
44 | static struct ssp_dma_command_t ssp_dma_cmd[2]; | 44 | static struct ssp_dma_command_t ssp_dma_cmd[2]; |
45 | static uint32_t ssp_bus_width[2]; | 45 | static uint32_t ssp_bus_width[2]; |
46 | static unsigned ssp_log_block_size[2]; | 46 | static unsigned ssp_log_block_size[2]; |
47 | static ssp_detect_cb_t ssp_detect_cb[2]; | ||
47 | 48 | ||
48 | void INT_SSP(int ssp) | 49 | void 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 | ||
159 | void 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 | |||
173 | void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, | 194 | void 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 | |||
326 | static 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 | |||
335 | static int ssp1_detect_oneshot_callback(struct timeout *tmo) | ||
336 | { | ||
337 | (void) tmo; | ||
338 | return ssp_detect_oneshot_callback(1); | ||
339 | } | ||
340 | |||
341 | static int ssp2_detect_oneshot_callback(struct timeout *tmo) | ||
342 | { | ||
343 | (void) tmo; | ||
344 | return ssp_detect_oneshot_callback(2); | ||
345 | } | ||
346 | |||
347 | static 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 | |||
357 | void 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 | |||
370 | bool 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 | ||
147 | typedef void (*ssp_detect_cb_t)(int ssp); | ||
148 | |||
145 | void imx233_ssp_init(void); | 149 | void imx233_ssp_init(void); |
146 | void imx233_ssp_start(int ssp); | 150 | void imx233_ssp_start(int ssp); |
147 | void imx233_ssp_stop(int ssp); | 151 | void imx233_ssp_stop(int ssp); |
@@ -156,8 +160,14 @@ void imx233_ssp_set_block_size(int ssp, unsigned log_block_size); | |||
156 | enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd, | 160 | enum 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); |
163 | void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width, | ||
164 | unsigned drive_strength, bool use_alt); | ||
159 | void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, | 165 | void 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 */ | ||
169 | void imx233_ssp_sdmmc_setup_detect(int ssp, bool enable, ssp_detect_cb_t fn); | ||
170 | bool 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. */ |
163 | void imx233_ssp_sd_mmc_power_up_sequence(int ssp); | 173 | void imx233_ssp_sd_mmc_power_up_sequence(int ssp); |