diff options
Diffstat (limited to 'firmware/target/arm/imx233/ssp-imx233.c')
-rw-r--r-- | firmware/target/arm/imx233/ssp-imx233.c | 102 |
1 files changed, 86 insertions, 16 deletions
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 | } | ||