123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- /**
- * @file hal_sdhost.c
- * @author ALLWINNERTECH IOT WLAN Team
- */
- /*
- * Copyright (C) 2017 ALLWINNERTECH TECHNOLOGY CO., LTD. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of ALLWINNERTECH TECHNOLOGY CO., LTD. nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, )|hhst->sdio_irq_maskPROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include <hal_gpio.h>
- #include <stdio.h>
- #include <stdlib.h>
- #ifndef CONFIG_KERNEL_FREERTOS
- #include <log.h>
- #endif
- #include "_sdhost.h"
- #include "_sd_define.h"
- #ifndef SDC_MAX_PIN_NUM
- #define SDC_MAX_PIN_NUM 13
- #endif
- typedef struct
- {
- uint32_t *pin;
- uint8_t pin_num : 3;
- uint8_t pin_mux : 3;
- uint8_t pin_drv : 2;
- } sdmmc_pin_t;
- static sdmmc_pin_t sunxi_sdmmc_pin[4];
- int32_t sdmmc_pinctl_set_from_cfg(struct mmc_host *host, char *sdc_str, uint32_t pin_num)
- {
- #ifdef HAL_SetPin
- int32_t ret = 0;
- user_gpio_set_t gpiocfg[SDC_MAX_PIN_NUM] = {0};
- int i = 0;
- int gpio_num = 0;
- if (pin_num > SDC_MAX_PIN_NUM) {
- SDC_LOGE("pin num over %d\n", SDC_MAX_PIN_NUM);
- return ret;
- }
- ret = Hal_Cfg_GetGPIOSecData(sdc_str, gpiocfg, pin_num);
- if(ret < 0) {
- SDC_LOGE("%s not has pin setting on sys_config.fex\n", sdc_str);
- return ret;
- }
- for (i = 0;i < pin_num; i++) {
- SDC_LOGD("name %s,port %d,port_num %d,mul_sel %d, pull %d, drv_level %d\n",\
- gpiocfg[i].gpio_name, gpiocfg[i].port, gpiocfg[i].port_num, \
- gpiocfg[i].mul_sel, gpiocfg[i].pull, gpiocfg[i].drv_level);
- }
- for(i = 0; i< pin_num; i++ ) {
- gpio_num = (gpiocfg[i].port - 1) * PINS_PER_BANK + gpiocfg[i].port_num;
- ret = hal_gpio_pinmux_set_function(gpio_num, gpiocfg[i].mul_sel);
- if (ret) {
- SDC_LOGE(
- "[sdmmc %s] PIN%lu set function failed! return %d\n",
- sdc_str, gpio_num, ret);
- return -1;
- }
- ret = hal_gpio_set_driving_level(gpio_num, gpiocfg[i].drv_level);
- if (ret) {
- SDC_LOGE(
- "[sdmmc %s] PIN%lu set driving level failed! return %d\n",
- sdc_str, gpio_num, ret);
- return -1;
- }
- ret = hal_gpio_set_pull(gpio_num, gpiocfg[i].pull);
- if (ret) {
- SDC_LOGE(
- "[sdmmc %s] PIN%lu set driving level failed! return %d\n",
- sdc_str, gpio_num, ret);
- return -1;
- }
- }
- return ret;
- #else
- SDC_LOGN("unsupport sys fex %d\n");
- return -1;
- #endif
- }
- uint32_t sdmmc_pinctrl_init(struct mmc_host *host)
- {
- uint8_t i;
- uint32_t flags = 0;
- int ret;
- uint32_t host_id = host->sdc_id;
- switch (host_id) {
- case 0:
- ret = sdmmc_pinctl_set_from_cfg(host, "sdc0", SDC0_NUM);
- if(ret < 0) {
- sunxi_sdmmc_pin[host_id].pin_num = SDC0_NUM;
- sunxi_sdmmc_pin[host_id].pin_mux = SDMMC_MUXSEL;
- sunxi_sdmmc_pin[host_id].pin_drv = SDMMC_DRVSEL;
- sunxi_sdmmc_pin[host_id].pin = malloc(sizeof(uint32_t) * SDC0_NUM);
- sunxi_sdmmc_pin[host_id].pin[0] = SDC0_CLK;
- sunxi_sdmmc_pin[host_id].pin[1] = SDC0_CMD;
- sunxi_sdmmc_pin[host_id].pin[2] = SDC0_D0;
- sunxi_sdmmc_pin[host_id].pin[3] = SDC0_D1;
- sunxi_sdmmc_pin[host_id].pin[4] = SDC0_D2;
- sunxi_sdmmc_pin[host_id].pin[5] = SDC0_D3;
- SDC_LOGE("sdmmc%ld use default pin setting\n", host_id);
- } else {
- SDC_LOGD("sdmmc%ld use pin setting on sys_config.fex\n", host_id);
- goto out;
- }
- break;
- case 1:
- if (host->param.pwr_mode == POWER_MODE_330) {
- hal_gpio_sel_vol_mode(SDC1_D0, POWER_MODE_330);
- } else {
- hal_gpio_sel_vol_mode(SDC1_D0, POWER_MODE_180);
- }
- ret = sdmmc_pinctl_set_from_cfg(host, "sdc1", SDC1_NUM);
- if(ret < 0) {
- sunxi_sdmmc_pin[host_id].pin_num = SDC1_NUM;
- sunxi_sdmmc_pin[host_id].pin_mux = SDMMC_MUXSEL;
- sunxi_sdmmc_pin[host_id].pin_drv = SDMMC_DRVSEL;
- sunxi_sdmmc_pin[host_id].pin = malloc(sizeof(uint32_t) * SDC1_NUM);
- sunxi_sdmmc_pin[host_id].pin[0] = SDC1_CLK;
- sunxi_sdmmc_pin[host_id].pin[1] = SDC1_CMD;
- sunxi_sdmmc_pin[host_id].pin[2] = SDC1_D0;
- // sunxi_sdmmc_pin[host_id].pin[3] = SDC1_D1;
- // sunxi_sdmmc_pin[host_id].pin[4] = SDC1_D2;
- // sunxi_sdmmc_pin[host_id].pin[5] = SDC1_D3;
- SDC_LOGE("sdmmc%ld use default pin setting\n", host_id);
- } else {
- SDC_LOGD("sdmmc%ld use pin setting on sys_config.fex\n", host_id);
- goto out;
- }
- break;
- default:
- SDC_LOGE("sdmmc%ld is invalid\n", host_id);
- return -1;
- }
- for (i = 0; i < sunxi_sdmmc_pin[host_id].pin_num; i++)
- {
- ret = hal_gpio_pinmux_set_function(sunxi_sdmmc_pin[host_id].pin[i], sunxi_sdmmc_pin[host_id].pin_mux);
- if (ret)
- {
- SDC_LOGE(
- "[sdmmc%ld] PIN%lu set function failed! return %d\n",
- host_id, sunxi_sdmmc_pin[host_id].pin[i], ret);
- return -1;
- }
- ret = hal_gpio_set_driving_level(sunxi_sdmmc_pin[host_id].pin[i], sunxi_sdmmc_pin[host_id].pin_drv);
- if (ret)
- {
- SDC_LOGE(
- "[sdmmc%ld] PIN%lu set driving level failed! return %d\n",
- host_id, sunxi_sdmmc_pin[host_id].pin[i], ret);
- return -1;
- }
- ret = hal_gpio_set_pull(sunxi_sdmmc_pin[host_id].pin[i], GPIO_PULL_UP);
- // ret = drv_gpio_set_pull_state(sunxi_sdmmc_pin[host_id].pin[i], DRV_GPIO_PULL_DOWN_DISABLE);
- }
- out:
- return 0;
- }
- int mmc_gpiod_request_cd_irq(struct mmc_host *host)
- {
- uint32_t irq;
- int ret = 0;
- gpio_pull_status_t pull_state;
- gpio_direction_t gpio_direction;
- gpio_data_t gpio_data;
- host->cd_gpio_pin = SDC0_DET;
- /*set gpio detect-clk 24M*/
- hal_gpio_set_debounce(host->cd_gpio_pin, 1);
- ret = hal_gpio_to_irq(host->cd_gpio_pin, &irq);
- if (ret < 0)
- {
- SDC_LOGE("gpio to irq error, error num: %d\n", ret);
- return ret;
- }
- /*set pin mux*/
- ret = hal_gpio_pinmux_set_function(host->cd_gpio_pin, 0);
- ret = hal_gpio_set_driving_level(host->cd_gpio_pin, 3);
- ret = hal_gpio_set_pull(host->cd_gpio_pin, 1);
- if (ret < 0)
- {
- SDC_LOGE("set pin mux error!\n");
- return -1;
- }
- host->cd_irq = irq;
- ret = hal_gpio_irq_request(irq, host->cd_gpio_isr, IRQ_TYPE_EDGE_BOTH, host);
- if (ret < 0)
- {
- SDC_LOGE("request irq error, irq num:%lu error num: %d\n", (unsigned long)irq, ret);
- return ret;
- }
- #if 0
- ret = drv_gpio_irq_enable(irq);
- if (ret < 0)
- {
- printf("request irq error, error num: %d\n", ret);
- return ret;
- }
- ret = drv_gpio_irq_disable(irq);
- if (ret < 0)
- {
- printf("disable irq error, irq num:%lu,error num: %d\n", irq, ret);
- return ret;
- }
- ret = drv_gpio_irq_free(irq);
- if (ret < 0)
- {
- printf("free irq error, error num: %d\n", ret);
- return ret;
- }
- #endif
- return ret;
- }
|