diff options
Diffstat (limited to 'firmware/target/arm/imx233/ssp-imx233.c')
-rw-r--r-- | firmware/target/arm/imx233/ssp-imx233.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/firmware/target/arm/imx233/ssp-imx233.c b/firmware/target/arm/imx233/ssp-imx233.c index 1dd2d767ba..21dcba67aa 100644 --- a/firmware/target/arm/imx233/ssp-imx233.c +++ b/firmware/target/arm/imx233/ssp-imx233.c | |||
@@ -28,6 +28,13 @@ | |||
28 | #include "pinctrl-imx233.h" | 28 | #include "pinctrl-imx233.h" |
29 | #include "dma-imx233.h" | 29 | #include "dma-imx233.h" |
30 | 30 | ||
31 | /* for debug purpose */ | ||
32 | #if 0 | ||
33 | #define ASSERT_SSP(ssp) if(ssp < 1 || ssp > 2) panicf("ssp=%d in %s", ssp, __func__); | ||
34 | #else | ||
35 | #define ASSERT_SSP(ssp) | ||
36 | #endif | ||
37 | |||
31 | /* Used for DMA */ | 38 | /* Used for DMA */ |
32 | struct ssp_dma_command_t | 39 | struct ssp_dma_command_t |
33 | { | 40 | { |
@@ -46,6 +53,7 @@ static struct ssp_dma_command_t ssp_dma_cmd[2]; | |||
46 | static uint32_t ssp_bus_width[2]; | 53 | static uint32_t ssp_bus_width[2]; |
47 | static unsigned ssp_log_block_size[2]; | 54 | static unsigned ssp_log_block_size[2]; |
48 | static ssp_detect_cb_t ssp_detect_cb[2]; | 55 | static ssp_detect_cb_t ssp_detect_cb[2]; |
56 | static bool ssp_detect_invert[2]; | ||
49 | 57 | ||
50 | void INT_SSP(int ssp) | 58 | void INT_SSP(int ssp) |
51 | { | 59 | { |
@@ -93,6 +101,7 @@ void imx233_ssp_init(void) | |||
93 | 101 | ||
94 | void imx233_ssp_start(int ssp) | 102 | void imx233_ssp_start(int ssp) |
95 | { | 103 | { |
104 | ASSERT_SSP(ssp) | ||
96 | if(ssp_in_use[ssp - 1]) | 105 | if(ssp_in_use[ssp - 1]) |
97 | return; | 106 | return; |
98 | ssp_in_use[ssp - 1] = true; | 107 | ssp_in_use[ssp - 1] = true; |
@@ -117,6 +126,7 @@ void imx233_ssp_start(int ssp) | |||
117 | 126 | ||
118 | void imx233_ssp_stop(int ssp) | 127 | void imx233_ssp_stop(int ssp) |
119 | { | 128 | { |
129 | ASSERT_SSP(ssp) | ||
120 | if(!ssp_in_use[ssp - 1]) | 130 | if(!ssp_in_use[ssp - 1]) |
121 | return; | 131 | return; |
122 | ssp_in_use[ssp - 1] = false; | 132 | ssp_in_use[ssp - 1] = false; |
@@ -135,11 +145,13 @@ void imx233_ssp_stop(int ssp) | |||
135 | 145 | ||
136 | void imx233_ssp_softreset(int ssp) | 146 | void imx233_ssp_softreset(int ssp) |
137 | { | 147 | { |
148 | ASSERT_SSP(ssp) | ||
138 | imx233_reset_block(&HW_SSP_CTRL0(ssp)); | 149 | imx233_reset_block(&HW_SSP_CTRL0(ssp)); |
139 | } | 150 | } |
140 | 151 | ||
141 | void imx233_ssp_set_timings(int ssp, int divide, int rate, int timeout) | 152 | void imx233_ssp_set_timings(int ssp, int divide, int rate, int timeout) |
142 | { | 153 | { |
154 | ASSERT_SSP(ssp) | ||
143 | HW_SSP_TIMING(ssp) = divide << HW_SSP_TIMING__CLOCK_DIVIDE_BP | rate | | 155 | HW_SSP_TIMING(ssp) = divide << HW_SSP_TIMING__CLOCK_DIVIDE_BP | rate | |
144 | timeout << HW_SSP_TIMING__CLOCK_TIMEOUT_BP; | 156 | timeout << HW_SSP_TIMING__CLOCK_TIMEOUT_BP; |
145 | } | 157 | } |
@@ -209,6 +221,7 @@ void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width, | |||
209 | 221 | ||
210 | void imx233_ssp_set_mode(int ssp, unsigned mode) | 222 | void imx233_ssp_set_mode(int ssp, unsigned mode) |
211 | { | 223 | { |
224 | ASSERT_SSP(ssp) | ||
212 | switch(mode) | 225 | switch(mode) |
213 | { | 226 | { |
214 | case HW_SSP_CTRL1__SSP_MODE__SD_MMC: | 227 | case HW_SSP_CTRL1__SSP_MODE__SD_MMC: |
@@ -226,6 +239,7 @@ void imx233_ssp_set_mode(int ssp, unsigned mode) | |||
226 | 239 | ||
227 | void imx233_ssp_set_bus_width(int ssp, unsigned width) | 240 | void imx233_ssp_set_bus_width(int ssp, unsigned width) |
228 | { | 241 | { |
242 | ASSERT_SSP(ssp) | ||
229 | switch(width) | 243 | switch(width) |
230 | { | 244 | { |
231 | case 1: ssp_bus_width[ssp - 1] = HW_SSP_CTRL0__BUS_WIDTH__ONE_BIT; break; | 245 | case 1: ssp_bus_width[ssp - 1] = HW_SSP_CTRL0__BUS_WIDTH__ONE_BIT; break; |
@@ -236,6 +250,7 @@ void imx233_ssp_set_bus_width(int ssp, unsigned width) | |||
236 | 250 | ||
237 | void imx233_ssp_set_block_size(int ssp, unsigned log_block_size) | 251 | void imx233_ssp_set_block_size(int ssp, unsigned log_block_size) |
238 | { | 252 | { |
253 | ASSERT_SSP(ssp) | ||
239 | ssp_log_block_size[ssp - 1] = log_block_size; | 254 | ssp_log_block_size[ssp - 1] = log_block_size; |
240 | } | 255 | } |
241 | 256 | ||
@@ -243,6 +258,7 @@ enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd, | |||
243 | uint32_t cmd_arg, enum imx233_ssp_resp_t resp, void *buffer, unsigned block_count, | 258 | uint32_t cmd_arg, enum imx233_ssp_resp_t resp, void *buffer, unsigned block_count, |
244 | bool wait4irq, bool read, uint32_t *resp_ptr) | 259 | bool wait4irq, bool read, uint32_t *resp_ptr) |
245 | { | 260 | { |
261 | ASSERT_SSP(ssp) | ||
246 | mutex_lock(&ssp_mutex[ssp - 1]); | 262 | mutex_lock(&ssp_mutex[ssp - 1]); |
247 | /* Enable all interrupts */ | 263 | /* Enable all interrupts */ |
248 | imx233_icoll_enable_interrupt(INT_SRC_SSP_DMA(ssp), true); | 264 | imx233_icoll_enable_interrupt(INT_SRC_SSP_DMA(ssp), true); |
@@ -312,6 +328,7 @@ enum imx233_ssp_error_t imx233_ssp_sd_mmc_transfer(int ssp, uint8_t cmd, | |||
312 | 328 | ||
313 | void imx233_ssp_sd_mmc_power_up_sequence(int ssp) | 329 | void imx233_ssp_sd_mmc_power_up_sequence(int ssp) |
314 | { | 330 | { |
331 | ASSERT_SSP(ssp) | ||
315 | __REG_CLR(HW_SSP_CMD0(ssp)) = HW_SSP_CMD0__SLOW_CLKING_EN; | 332 | __REG_CLR(HW_SSP_CMD0(ssp)) = HW_SSP_CMD0__SLOW_CLKING_EN; |
316 | __REG_SET(HW_SSP_CMD0(ssp)) = HW_SSP_CMD0__CONT_CLKING_EN; | 333 | __REG_SET(HW_SSP_CMD0(ssp)) = HW_SSP_CMD0__CONT_CLKING_EN; |
317 | mdelay(1); | 334 | mdelay(1); |
@@ -320,6 +337,7 @@ void imx233_ssp_sd_mmc_power_up_sequence(int ssp) | |||
320 | 337 | ||
321 | static int ssp_detect_oneshot_callback(int ssp) | 338 | static int ssp_detect_oneshot_callback(int ssp) |
322 | { | 339 | { |
340 | ASSERT_SSP(ssp) | ||
323 | if(ssp_detect_cb[ssp - 1]) | 341 | if(ssp_detect_cb[ssp - 1]) |
324 | ssp_detect_cb[ssp - 1](ssp); | 342 | ssp_detect_cb[ssp - 1](ssp); |
325 | 343 | ||
@@ -348,11 +366,14 @@ static void detect_irq(int bank, int pin) | |||
348 | timeout_register(&ssp2_detect_oneshot, ssp2_detect_oneshot_callback, (3*HZ/10), 0); | 366 | timeout_register(&ssp2_detect_oneshot, ssp2_detect_oneshot_callback, (3*HZ/10), 0); |
349 | } | 367 | } |
350 | 368 | ||
351 | void imx233_ssp_sdmmc_setup_detect(int ssp, bool enable, ssp_detect_cb_t fn, bool first_time) | 369 | void imx233_ssp_sdmmc_setup_detect(int ssp, bool enable, ssp_detect_cb_t fn, |
370 | bool first_time, bool invert) | ||
352 | { | 371 | { |
372 | ASSERT_SSP(ssp) | ||
353 | int bank = ssp == 1 ? 2 : 0; | 373 | int bank = ssp == 1 ? 2 : 0; |
354 | int pin = ssp == 1 ? 1 : 19; | 374 | int pin = ssp == 1 ? 1 : 19; |
355 | ssp_detect_cb[ssp - 1] = fn; | 375 | ssp_detect_cb[ssp - 1] = fn; |
376 | ssp_detect_invert[ssp - 1] = invert; | ||
356 | if(enable) | 377 | if(enable) |
357 | { | 378 | { |
358 | imx233_pinctrl_acquire_pin(bank, pin, ssp == 1 ? "ssp1 detect" : "ssp2 detect"); | 379 | imx233_pinctrl_acquire_pin(bank, pin, ssp == 1 ? "ssp1 detect" : "ssp2 detect"); |
@@ -361,10 +382,23 @@ void imx233_ssp_sdmmc_setup_detect(int ssp, bool enable, ssp_detect_cb_t fn, boo | |||
361 | } | 382 | } |
362 | if(first_time && imx233_ssp_sdmmc_detect(ssp)) | 383 | if(first_time && imx233_ssp_sdmmc_detect(ssp)) |
363 | detect_irq(bank, pin); | 384 | detect_irq(bank, pin); |
364 | imx233_setup_pin_irq(bank, pin, enable, true, !imx233_ssp_sdmmc_detect(ssp), detect_irq); | 385 | imx233_setup_pin_irq(bank, pin, enable, true, !imx233_ssp_sdmmc_detect_raw(ssp), detect_irq); |
365 | } | 386 | } |
366 | 387 | ||
367 | bool imx233_ssp_sdmmc_detect(int ssp) | 388 | bool imx233_ssp_sdmmc_is_detect_inverted(int ssp) |
389 | { | ||
390 | ASSERT_SSP(ssp) | ||
391 | return ssp_detect_invert[ssp - 1]; | ||
392 | } | ||
393 | |||
394 | bool imx233_ssp_sdmmc_detect_raw(int ssp) | ||
368 | { | 395 | { |
396 | ASSERT_SSP(ssp) | ||
369 | return !!(HW_SSP_STATUS(ssp) & HW_SSP_STATUS__CARD_DETECT); | 397 | return !!(HW_SSP_STATUS(ssp) & HW_SSP_STATUS__CARD_DETECT); |
370 | } | 398 | } |
399 | |||
400 | bool imx233_ssp_sdmmc_detect(int ssp) | ||
401 | { | ||
402 | ASSERT_SSP(ssp) | ||
403 | return imx233_ssp_sdmmc_detect_raw(ssp) != ssp_detect_invert[ssp - 1]; | ||
404 | } | ||