From 6d914b8a0cb1de8cf9464fbcd95874f1c1e4cfa8 Mon Sep 17 00:00:00 2001 From: kfx Date: Mon, 23 Jul 2012 14:20:22 +0800 Subject: [PATCH] rk2928: add sdmmc support --- arch/arm/mach-rk2928/board-rk2928-fpga.c | 511 +++++++++++++++++- arch/arm/mach-rk2928/board-rk2928-sdk-sdmmc.c | 441 +++++++++++++++ arch/arm/mach-rk2928/devices.c | 60 ++ drivers/mmc/host/rk29_sdmmc.c | 54 +- drivers/mmc/host/rk29_sdmmc.h | 6 +- 5 files changed, 1044 insertions(+), 28 deletions(-) create mode 100644 arch/arm/mach-rk2928/board-rk2928-sdk-sdmmc.c diff --git a/arch/arm/mach-rk2928/board-rk2928-fpga.c b/arch/arm/mach-rk2928/board-rk2928-fpga.c index 8b9a4c90df17..7fd99583b24c 100755 --- a/arch/arm/mach-rk2928/board-rk2928-fpga.c +++ b/arch/arm/mach-rk2928/board-rk2928-fpga.c @@ -47,13 +47,13 @@ /*---------------- Camera Sensor Macro Define Begin ------------------------*/ /*---------------- Camera Sensor Configuration Macro Begin ------------------------*/ #define CONFIG_SENSOR_0 RK29_CAM_SENSOR_OV5642 /* back camera sensor */ -#define CONFIG_SENSOR_IIC_ADDR_0 0x78 +#define CONFIG_SENSOR_IIC_ADDR_0 0 #define CONFIG_SENSOR_IIC_ADAPTER_ID_0 4 #define CONFIG_SENSOR_CIF_INDEX_0 0 #define CONFIG_SENSOR_ORIENTATION_0 90 #define CONFIG_SENSOR_POWER_PIN_0 INVALID_GPIO #define CONFIG_SENSOR_RESET_PIN_0 INVALID_GPIO -#define CONFIG_SENSOR_POWERDN_PIN_0 RK30_PIN1_PD6 +#define CONFIG_SENSOR_POWERDN_PIN_0 RK2928_PIN1_PD6 #define CONFIG_SENSOR_FALSH_PIN_0 INVALID_GPIO #define CONFIG_SENSOR_POWERACTIVE_LEVEL_0 RK29_CAM_POWERACTIVE_L #define CONFIG_SENSOR_RESETACTIVE_LEVEL_0 RK29_CAM_RESETACTIVE_L @@ -76,7 +76,7 @@ #define CONFIG_SENSOR_ORIENTATION_01 90 #define CONFIG_SENSOR_POWER_PIN_01 INVALID_GPIO #define CONFIG_SENSOR_RESET_PIN_01 INVALID_GPIO -#define CONFIG_SENSOR_POWERDN_PIN_01 RK30_PIN1_PD6 +#define CONFIG_SENSOR_POWERDN_PIN_01 RK2928_PIN1_PD6 #define CONFIG_SENSOR_FALSH_PIN_01 INVALID_GPIO #define CONFIG_SENSOR_POWERACTIVE_LEVEL_01 RK29_CAM_POWERACTIVE_L #define CONFIG_SENSOR_RESETACTIVE_LEVEL_01 RK29_CAM_RESETACTIVE_L @@ -99,7 +99,7 @@ #define CONFIG_SENSOR_ORIENTATION_02 90 #define CONFIG_SENSOR_POWER_PIN_02 INVALID_GPIO #define CONFIG_SENSOR_RESET_PIN_02 INVALID_GPIO -#define CONFIG_SENSOR_POWERDN_PIN_02 RK30_PIN1_PD6 +#define CONFIG_SENSOR_POWERDN_PIN_02 RK2928_PIN1_PD6 #define CONFIG_SENSOR_FALSH_PIN_02 INVALID_GPIO #define CONFIG_SENSOR_POWERACTIVE_LEVEL_02 RK29_CAM_POWERACTIVE_L #define CONFIG_SENSOR_RESETACTIVE_LEVEL_02 RK29_CAM_RESETACTIVE_L @@ -117,12 +117,12 @@ #define CONFIG_SENSOR_1 RK29_CAM_SENSOR_OV2659 /* front camera sensor 0 */ #define CONFIG_SENSOR_IIC_ADDR_1 0x60 -#define CONFIG_SENSOR_IIC_ADAPTER_ID_1 3 +#define CONFIG_SENSOR_IIC_ADAPTER_ID_1 1 #define CONFIG_SENSOR_CIF_INDEX_1 0 #define CONFIG_SENSOR_ORIENTATION_1 270 #define CONFIG_SENSOR_POWER_PIN_1 INVALID_GPIO #define CONFIG_SENSOR_RESET_PIN_1 INVALID_GPIO -#define CONFIG_SENSOR_POWERDN_PIN_1 RK30_PIN1_PB7 +#define CONFIG_SENSOR_POWERDN_PIN_1 RK2928_PIN1_PB7 #define CONFIG_SENSOR_FALSH_PIN_1 INVALID_GPIO #define CONFIG_SENSOR_POWERACTIVE_LEVEL_1 RK29_CAM_POWERACTIVE_L #define CONFIG_SENSOR_RESETACTIVE_LEVEL_1 RK29_CAM_RESETACTIVE_L @@ -190,6 +190,470 @@ #include "../../../drivers/media/video/rk2928_camera.c" /*---------------- Camera Sensor Macro Define End ---------*/ +#define PMEM_CAM_SIZE PMEM_CAM_NECESSARY +/***************************************************************************************** + * camera devices + * author: ddl@rock-chips.com + *****************************************************************************************/ +#ifdef CONFIG_VIDEO_RK29 +#define CONFIG_SENSOR_POWER_IOCTL_USR 0 //define this refer to your board layout +#define CONFIG_SENSOR_RESET_IOCTL_USR 0 +#define CONFIG_SENSOR_POWERDOWN_IOCTL_USR 0 +#define CONFIG_SENSOR_FLASH_IOCTL_USR 0 + +static void rk_cif_power(int on) +{ + struct regulator *ldo_18,*ldo_28; + ldo_28 = regulator_get(NULL, "ldo7"); // vcc28_cif + ldo_18 = regulator_get(NULL, "ldo1"); // vcc18_cif + if (ldo_28 == NULL || IS_ERR(ldo_28) || ldo_18 == NULL || IS_ERR(ldo_18)){ + printk("get cif ldo failed!\n"); + return; + } + if(on == 0){ + regulator_disable(ldo_28); + regulator_put(ldo_28); + regulator_disable(ldo_18); + regulator_put(ldo_18); + mdelay(500); + } + else{ + regulator_set_voltage(ldo_28, 2800000, 2800000); + regulator_enable(ldo_28); + // printk("%s set ldo7 vcc28_cif=%dmV end\n", __func__, regulator_get_voltage(ldo_28)); + regulator_put(ldo_28); + + regulator_set_voltage(ldo_18, 1800000, 1800000); + // regulator_set_suspend_voltage(ldo, 1800000); + regulator_enable(ldo_18); + // printk("%s set ldo1 vcc18_cif=%dmV end\n", __func__, regulator_get_voltage(ldo_18)); + regulator_put(ldo_18); + } +} + +#if CONFIG_SENSOR_POWER_IOCTL_USR +static int sensor_power_usr_cb (struct rk29camera_gpio_res *res,int on) +{ + //#error "CONFIG_SENSOR_POWER_IOCTL_USR is 1, sensor_power_usr_cb function must be writed!!"; + rk_cif_power(on); +} +#endif + +#if CONFIG_SENSOR_RESET_IOCTL_USR +static int sensor_reset_usr_cb (struct rk29camera_gpio_res *res,int on) +{ + #error "CONFIG_SENSOR_RESET_IOCTL_USR is 1, sensor_reset_usr_cb function must be writed!!"; +} +#endif + +#if CONFIG_SENSOR_POWERDOWN_IOCTL_USR +static int sensor_powerdown_usr_cb (struct rk29camera_gpio_res *res,int on) +{ + #error "CONFIG_SENSOR_POWERDOWN_IOCTL_USR is 1, sensor_powerdown_usr_cb function must be writed!!"; +} +#endif + +#if CONFIG_SENSOR_FLASH_IOCTL_USR +static int sensor_flash_usr_cb (struct rk29camera_gpio_res *res,int on) +{ + #error "CONFIG_SENSOR_FLASH_IOCTL_USR is 1, sensor_flash_usr_cb function must be writed!!"; +} +#endif + +static struct rk29camera_platform_ioctl_cb sensor_ioctl_cb = { + #if CONFIG_SENSOR_POWER_IOCTL_USR + .sensor_power_cb = sensor_power_usr_cb, + #else + .sensor_power_cb = NULL, + #endif + + #if CONFIG_SENSOR_RESET_IOCTL_USR + .sensor_reset_cb = sensor_reset_usr_cb, + #else + .sensor_reset_cb = NULL, + #endif + + #if CONFIG_SENSOR_POWERDOWN_IOCTL_USR + .sensor_powerdown_cb = sensor_powerdown_usr_cb, + #else + .sensor_powerdown_cb = NULL, + #endif + + #if CONFIG_SENSOR_FLASH_IOCTL_USR + .sensor_flash_cb = sensor_flash_usr_cb, + #else + .sensor_flash_cb = NULL, + #endif +}; + +#if CONFIG_SENSOR_IIC_ADDR_0 +static struct reginfo_t rk_init_data_sensor_reg_0[] = +{ + {0x0000, 0x00,0,0} + }; +static struct reginfo_t rk_init_data_sensor_winseqreg_0[] ={ + {0x0000, 0x00,0,0} + }; +#endif + +#if CONFIG_SENSOR_IIC_ADDR_1 +static struct reginfo_t rk_init_data_sensor_reg_1[] = +{ + {0x0000, 0x00,0,0} +}; +static struct reginfo_t rk_init_data_sensor_winseqreg_1[] = +{ + {0x0000, 0x00,0,0} +}; +#endif +#if CONFIG_SENSOR_IIC_ADDR_01 +static struct reginfo_t rk_init_data_sensor_reg_01[] = +{ + {0x0000, 0x00,0,0} +}; +static struct reginfo_t rk_init_data_sensor_winseqreg_01[] = +{ + {0x0000, 0x00,0,0} +}; +#endif +#if CONFIG_SENSOR_IIC_ADDR_02 +static struct reginfo_t rk_init_data_sensor_reg_02[] = +{ + {0x0000, 0x00,0,0} +}; +static struct reginfo_t rk_init_data_sensor_winseqreg_02[] = +{ + {0x0000, 0x00,0,0} +}; +#endif +#if CONFIG_SENSOR_IIC_ADDR_11 +static struct reginfo_t rk_init_data_sensor_reg_11[] = +{ + {0x0000, 0x00,0,0} +}; +static struct reginfo_t rk_init_data_sensor_winseqreg_11[] = +{ + {0x0000, 0x00,0,0} +}; +#endif +#if CONFIG_SENSOR_IIC_ADDR_12 +static struct reginfo_t rk_init_data_sensor_reg_12[] = +{ + {0x0000, 0x00,0,0} +}; +static struct reginfo_t rk_init_data_sensor_winseqreg_12[] = +{ + {0x0000, 0x00,0,0} +}; +#endif +static rk_sensor_user_init_data_s rk_init_data_sensor[RK_CAM_NUM] = +{ + #if CONFIG_SENSOR_IIC_ADDR_0 + { + .rk_sensor_init_width = INVALID_VALUE, + .rk_sensor_init_height = INVALID_VALUE, + .rk_sensor_init_bus_param = INVALID_VALUE, + .rk_sensor_init_pixelcode = INVALID_VALUE, + .rk_sensor_init_data = rk_init_data_sensor_reg_0, + .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_0, + .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_0) / sizeof(struct reginfo_t), + .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_0) / sizeof(struct reginfo_t), + }, + #else + { + .rk_sensor_init_width = INVALID_VALUE, + .rk_sensor_init_height = INVALID_VALUE, + .rk_sensor_init_bus_param = INVALID_VALUE, + .rk_sensor_init_pixelcode = INVALID_VALUE, + .rk_sensor_init_data = NULL, + .rk_sensor_init_winseq = NULL, + .rk_sensor_winseq_size = 0, + .rk_sensor_init_data_size = 0, + }, + #endif + #if CONFIG_SENSOR_IIC_ADDR_1 + { + .rk_sensor_init_width = INVALID_VALUE, + .rk_sensor_init_height = INVALID_VALUE, + .rk_sensor_init_bus_param = INVALID_VALUE, + .rk_sensor_init_pixelcode = INVALID_VALUE, + .rk_sensor_init_data = rk_init_data_sensor_reg_1, + .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_1, + .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_1) / sizeof(struct reginfo_t), + .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_1) / sizeof(struct reginfo_t), + }, + #else + { + .rk_sensor_init_width = INVALID_VALUE, + .rk_sensor_init_height = INVALID_VALUE, + .rk_sensor_init_bus_param = INVALID_VALUE, + .rk_sensor_init_pixelcode = INVALID_VALUE, + .rk_sensor_init_data = NULL, + .rk_sensor_init_winseq = NULL, + .rk_sensor_winseq_size = 0, + .rk_sensor_init_data_size = 0, + }, + #endif + #if CONFIG_SENSOR_IIC_ADDR_01 + { + .rk_sensor_init_width = INVALID_VALUE, + .rk_sensor_init_height = INVALID_VALUE, + .rk_sensor_init_bus_param = INVALID_VALUE, + .rk_sensor_init_pixelcode = INVALID_VALUE, + .rk_sensor_init_data = rk_init_data_sensor_reg_01, + .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_01, + .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_01) / sizeof(struct reginfo_t), + .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_01) / sizeof(struct reginfo_t), + }, + #else + { + .rk_sensor_init_width = INVALID_VALUE, + .rk_sensor_init_height = INVALID_VALUE, + .rk_sensor_init_bus_param = INVALID_VALUE, + .rk_sensor_init_pixelcode = INVALID_VALUE, + .rk_sensor_init_data = NULL, + .rk_sensor_init_winseq = NULL, + .rk_sensor_winseq_size = 0, + .rk_sensor_init_data_size = 0, + }, + #endif + #if CONFIG_SENSOR_IIC_ADDR_02 + { + .rk_sensor_init_width = INVALID_VALUE, + .rk_sensor_init_height = INVALID_VALUE, + .rk_sensor_init_bus_param = INVALID_VALUE, + .rk_sensor_init_pixelcode = INVALID_VALUE, + .rk_sensor_init_data = rk_init_data_sensor_reg_02, + .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_02, + .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_02) / sizeof(struct reginfo_t), + .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_02) / sizeof(struct reginfo_t), + }, + #else + { + .rk_sensor_init_width = INVALID_VALUE, + .rk_sensor_init_height = INVALID_VALUE, + .rk_sensor_init_bus_param = INVALID_VALUE, + .rk_sensor_init_pixelcode = INVALID_VALUE, + .rk_sensor_init_data = NULL, + .rk_sensor_init_winseq = NULL, + .rk_sensor_winseq_size = 0, + .rk_sensor_init_data_size = 0, + }, + #endif + #if CONFIG_SENSOR_IIC_ADDR_11 + { + .rk_sensor_init_width = INVALID_VALUE, + .rk_sensor_init_height = INVALID_VALUE, + .rk_sensor_init_bus_param = INVALID_VALUE, + .rk_sensor_init_pixelcode = INVALID_VALUE, + .rk_sensor_init_data = rk_init_data_sensor_reg_11, + .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_11, + .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_11) / sizeof(struct reginfo_t), + .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_11) / sizeof(struct reginfo_t), + }, + #else + { + .rk_sensor_init_width = INVALID_VALUE, + .rk_sensor_init_height = INVALID_VALUE, + .rk_sensor_init_bus_param = INVALID_VALUE, + .rk_sensor_init_pixelcode = INVALID_VALUE, + .rk_sensor_init_data = NULL, + .rk_sensor_init_winseq = NULL, + .rk_sensor_winseq_size = 0, + .rk_sensor_init_data_size = 0, + }, + #endif + #if CONFIG_SENSOR_IIC_ADDR_12 + { + .rk_sensor_init_width = INVALID_VALUE, + .rk_sensor_init_height = INVALID_VALUE, + .rk_sensor_init_bus_param = INVALID_VALUE, + .rk_sensor_init_pixelcode = INVALID_VALUE, + .rk_sensor_init_data = rk_init_data_sensor_reg_12, + .rk_sensor_init_winseq = rk_init_data_sensor_winseqreg_12, + .rk_sensor_winseq_size = sizeof(rk_init_data_sensor_winseqreg_12) / sizeof(struct reginfo_t), + .rk_sensor_init_data_size = sizeof(rk_init_data_sensor_reg_12) / sizeof(struct reginfo_t), + }, + #else + { + .rk_sensor_init_width = INVALID_VALUE, + .rk_sensor_init_height = INVALID_VALUE, + .rk_sensor_init_bus_param = INVALID_VALUE, + .rk_sensor_init_pixelcode = INVALID_VALUE, + .rk_sensor_init_data = NULL, + .rk_sensor_init_winseq = NULL, + .rk_sensor_winseq_size = 0, + .rk_sensor_init_data_size = 0, + }, + #endif + + }; +#include "../../../drivers/media/video/rk2928_camera.c" + +#endif /* CONFIG_VIDEO_RK29 */ + +/************************************************************************************************** + * SDMMC devices, include the module of SD,MMC,and sdio.noted by xbw at 2012-03-05 +**************************************************************************************************/ +#ifdef CONFIG_SDMMC_RK29 +#include "board-rk2928-sdk-sdmmc.c" + +#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT) +#define SDMMC0_WRITE_PROTECT_PIN RK2928_PIN1_PA7 //According to your own project to set the value of write-protect-pin. +#endif + +#if defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT) +#define SDMMC1_WRITE_PROTECT_PIN RK2928_PIN0_PD5 //According to your own project to set the value of write-protect-pin. +#endif + +#define RK29SDK_WIFI_SDIO_CARD_DETECT_N RK2928_PIN0_PB2 + +#endif //endif ---#ifdef CONFIG_SDMMC_RK29 + +#ifdef CONFIG_SDMMC0_RK29 +static int rk29_sdmmc0_cfg_gpio(void) +{ +#ifdef CONFIG_SDMMC_RK29_OLD + rk30_mux_api_set(GPIO1B7_MMC0_CMD_NAME, GPIO1B_MMC0_CMD); + rk30_mux_api_set(GPIO1C0_MMC0_CLKOUT_NAME, GPIO1C_MMC0_CLKOUT); + rk30_mux_api_set(GPIO1C2_MMC0_D0_NAME, GPIO1C_MMC0_D0); + rk30_mux_api_set(GPIO1C3_MMC0_D1_NAME, GPIO1C_MMC0_D1); + rk30_mux_api_set(GPIO1C4_MMC0_D2_NAME, GPIO1C_MMC0_D2); + rk30_mux_api_set(GPIO1C5_MMC0_D3_NAME, GPIO1C_MMC0_D3); + + rk30_mux_api_set(GPIO1C1_MMC0_DETN_NAME, GPIO1C_MMC0_DETN); + + rk30_mux_api_set(GPIO1B6_MMC0_PWREN_NAME, GPIO1B_MMC0_PWREN); + gpio_request(RK30_PIN3_PA7, "sdmmc-power"); + gpio_direction_output(RK2928_PIN1_PB6, GPIO_LOW); + +#else + rk29_sdmmc_set_iomux(0, 0xFFFF); + + rk30_mux_api_set(GPIO1C1_MMC0_DETN_NAME, GPIO1C_MMC0_DETN); + +#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT) + gpio_request(SDMMC0_WRITE_PROTECT_PIN, "sdmmc-wp"); + gpio_direction_input(SDMMC0_WRITE_PROTECT_PIN); +#endif + +#endif + + return 0; +} + +#define CONFIG_SDMMC0_USE_DMA +struct rk29_sdmmc_platform_data default_sdmmc0_data = { + .host_ocr_avail = + (MMC_VDD_25_26 | MMC_VDD_26_27 | MMC_VDD_27_28 | MMC_VDD_28_29 | + MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | + MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36), + .host_caps = + (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), + .io_init = rk29_sdmmc0_cfg_gpio, + +#if !defined(CONFIG_SDMMC_RK29_OLD) + .set_iomux = rk29_sdmmc_set_iomux, +#endif + + .dma_name = "sd_mmc", +#ifdef CONFIG_SDMMC0_USE_DMA + .use_dma = 1, +#else + .use_dma = 0, +#endif + .detect_irq = RK2928_PIN1_PC1, // INVALID_GPIO + .enable_sd_wakeup = 0, + +#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT) + .write_prt = SDMMC0_WRITE_PROTECT_PIN, +#else + .write_prt = INVALID_GPIO, +#endif +}; +#endif // CONFIG_SDMMC0_RK29 + +#ifdef CONFIG_SDMMC1_RK29 +#define CONFIG_SDMMC1_USE_DMA +static int rk29_sdmmc1_cfg_gpio(void) +{ +#if defined(CONFIG_SDMMC_RK29_OLD) + rk30_mux_api_set(GPIO0B0_MMC1_CMD_NAME, GPIO0B_MMC1_CMD); + rk30_mux_api_set(GPIO0B1_MMC1_CLKOUT_NAME, GPIO0B_MMC1_CLKOUT); + rk30_mux_api_set(GPIO0B3_MMC1_D0_NAME, GPIO0B_MMC1_D0); + rk30_mux_api_set(GPIO0B4_MMC1_D1_NAME, GPIO0B_MMC1_D1); + rk30_mux_api_set(GPIO0B5_MMC1_D2_NAME, GPIO0B_MMC1_D2); + rk30_mux_api_set(GPIO0B6_MMC1_D3_NAME, GPIO0B_MMC1_D3); + //rk30_mux_api_set(GPIO0B2_MMC1_DETN_NAME, GPIO0B_MMC1_DETN); + +#else + +#if defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT) + gpio_request(SDMMC1_WRITE_PROTECT_PIN, "sdio-wp"); + gpio_direction_input(SDMMC1_WRITE_PROTECT_PIN); +#endif + +#endif + + return 0; +} + +struct rk29_sdmmc_platform_data default_sdmmc1_data = { + .host_ocr_avail = + (MMC_VDD_25_26 | MMC_VDD_26_27 | MMC_VDD_27_28 | MMC_VDD_28_29 | + MMC_VDD_29_30 | MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | + MMC_VDD_33_34), + +#if !defined(CONFIG_USE_SDMMC1_FOR_WIFI_DEVELOP_BOARD) + .host_caps = (MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), +#else + .host_caps = + (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), +#endif + + .io_init = rk29_sdmmc1_cfg_gpio, + +#if !defined(CONFIG_SDMMC_RK29_OLD) + .set_iomux = rk29_sdmmc_set_iomux, +#endif + + .dma_name = "sdio", +#ifdef CONFIG_SDMMC1_USE_DMA + .use_dma = 1, +#else + .use_dma = 0, +#endif + +#if !defined(CONFIG_USE_SDMMC1_FOR_WIFI_DEVELOP_BOARD) +#ifdef CONFIG_WIFI_CONTROL_FUNC + .status = rk29sdk_wifi_status, + .register_status_notify = rk29sdk_wifi_status_register, +#endif +#if 0 + .detect_irq = RK29SDK_WIFI_SDIO_CARD_DETECT_N, +#endif + +#if defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT) + .write_prt = SDMMC1_WRITE_PROTECT_PIN, +#else + .write_prt = INVALID_GPIO, +#endif + +#else + .detect_irq = INVALID_GPIO, + .enable_sd_wakeup = 0, +#endif + +}; +#endif //endif--#ifdef CONFIG_SDMMC1_RK29 + +/************************************************************************************************** + * the end of setting for SDMMC devices +**************************************************************************************************/ + + + #define RK2928_FB_MEM_SIZE 3*SZ_1M #ifdef CONFIG_FB_ROCKCHIP @@ -283,7 +747,33 @@ static void __init rk30_i2c_register_board_info(void) static struct spi_board_info board_spi_devices[] = { }; +#ifdef CONFIG_ION +#define ION_RESERVE_SIZE (8 * SZ_1M) +static struct ion_platform_data rk30_ion_pdata = { + .nr = 1, + .heaps = { + { + .type = ION_HEAP_TYPE_CARVEOUT, + .id = ION_NOR_HEAP_ID, + .name = "norheap", + .size = ION_RESERVE_SIZE, + } + }, +}; + +static struct platform_device device_ion = { + .name = "ion-rockchip", + .id = 0, + .dev = { + .platform_data = &rk30_ion_pdata, + }, +}; +#endif + static struct platform_device *devices[] __initdata = { +#ifdef CONFIG_ION + &device_ion, +#endif #ifdef CONFIG_FB_ROCKCHIP &device_fb, #endif @@ -298,6 +788,9 @@ static void __init rk2928_board_init(void) static void __init rk2928_reserve(void) { +#ifdef CONFIG_ION + rk30_ion_pdata.heaps[0].base = board_mem_reserve_add("ion", ION_RESERVE_SIZE); +#endif #ifdef CONFIG_FB_ROCKCHIP resource_fb[0].start = board_mem_reserve_add("fb0", RK2928_FB_MEM_SIZE); resource_fb[0].end = resource_fb[0].start + RK2928_FB_MEM_SIZE - 1; @@ -353,6 +846,12 @@ static struct clk_lookup clks[] = { CLK(NULL, "hclk_lcdc0", &xin24m), CLK(NULL, "aclk_lcdc0", &xin24m), CLK(NULL, "dclk_lcdc0", &xin24m), + + CLK(NULL, "pd_cif0", &xin24m), + CLK(NULL, "aclk_cif0", &xin24m), + CLK(NULL, "hclk_cif0", &xin24m), + CLK(NULL, "cif0_in", &xin24m), + CLK(NULL, "cif0_out", &xin24m), }; void __init rk30_clock_init(void) diff --git a/arch/arm/mach-rk2928/board-rk2928-sdk-sdmmc.c b/arch/arm/mach-rk2928/board-rk2928-sdk-sdmmc.c new file mode 100644 index 000000000000..09395ed49c40 --- /dev/null +++ b/arch/arm/mach-rk2928/board-rk2928-sdk-sdmmc.c @@ -0,0 +1,441 @@ +/* arch/arm/mach-rk30/board-rk30-sdk-sdmmc.c + * + * Copyright (C) 2012 ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifdef CONFIG_SDMMC_RK29 + +#if !defined(CONFIG_SDMMC_RK29_OLD) +static void rk29_sdmmc_gpio_open(int device_id, int on) +{ + switch(device_id) + { + case 0://mmc0 + { + #ifdef CONFIG_SDMMC0_RK29 + if(on) + { + gpio_direction_output(RK2928_PIN1_PC0,GPIO_HIGH);//set mmc0-clk to high + gpio_direction_output(RK2928_PIN1_PB7,GPIO_HIGH);// set mmc0-cmd to high. + gpio_direction_output(RK2928_PIN1_PC2,GPIO_HIGH);//set mmc0-data0 to high. + gpio_direction_output(RK2928_PIN1_PC3,GPIO_HIGH);//set mmc0-data1 to high. + gpio_direction_output(RK2928_PIN1_PC4,GPIO_HIGH);//set mmc0-data2 to high. + gpio_direction_output(RK2928_PIN1_PC5,GPIO_HIGH);//set mmc0-data3 to high. + + mdelay(30); + } + else + { + rk30_mux_api_set(GPIO1C0_MMC0_CLKOUT_NAME, GPIO1C_GPIO1C0); + gpio_request(RK2928_PIN1_PC0, "mmc0-clk"); + gpio_direction_output(RK2928_PIN1_PC0,GPIO_LOW);//set mmc0-clk to low. + + rk30_mux_api_set(GPIO1B7_MMC0_CMD_NAME, GPIO1B_GPIO1B7); + gpio_request(RK2928_PIN1_PB7, "mmc0-cmd"); + gpio_direction_output(RK2928_PIN1_PB7,GPIO_LOW);//set mmc0-cmd to low. + + rk30_mux_api_set(GPIO1C2_MMC0_D0_NAME, GPIO1C_GPIO1C2); + gpio_request(RK2928_PIN1_PC2, "mmc0-data0"); + gpio_direction_output(RK2928_PIN1_PC2,GPIO_LOW);//set mmc0-data0 to low. + + rk30_mux_api_set(GPIO1C3_MMC0_D1_NAME, GPIO1C_GPIO1C3); + gpio_request(RK2928_PIN1_PC3, "mmc0-data1"); + gpio_direction_output(RK2928_PIN1_PC3,GPIO_LOW);//set mmc0-data1 to low. + + rk30_mux_api_set(GPIO1C4_MMC0_D2_NAME, GPIO1C_GPIO1C4); + gpio_request(RK2928_PIN1_PC4, "mmc0-data2"); + gpio_direction_output(RK2928_PIN1_PC4,GPIO_LOW);//set mmc0-data2 to low. + + rk30_mux_api_set(GPIO1C5_MMC0_D3_NAME, GPIO1C_GPIO1C5); + gpio_request(RK2928_PIN1_PC5, "mmc0-data3"); + gpio_direction_output(RK2928_PIN1_PC5,GPIO_LOW);//set mmc0-data3 to low. + + mdelay(30); + } + #endif + } + break; + + case 1://mmc1 + { + #ifdef CONFIG_SDMMC1_RK29 + if(on) + { + gpio_direction_output(RK2928_PIN0_PB1,GPIO_HIGH);//set mmc1-clk to high + gpio_direction_output(RK2928_PIN0_PB0,GPIO_HIGH);//set mmc1-cmd to high. + gpio_direction_output(RK2928_PIN0_PB3,GPIO_HIGH);//set mmc1-data0 to high. + gpio_direction_output(RK2928_PIN0_PB4,GPIO_HIGH);//set mmc1-data1 to high. + gpio_direction_output(RK2928_PIN0_PB5,GPIO_HIGH);//set mmc1-data2 to high. + gpio_direction_output(RK2928_PIN0_PB6,GPIO_HIGH);//set mmc1-data3 to high. + mdelay(100); + } + else + { + rk30_mux_api_set(GPIO0B1_MMC1_CLKOUT_NAME, GPIO0B_GPIO0B1); + gpio_request(RK2928_PIN0_PB1, "mmc1-clk"); + gpio_direction_output(RK2928_PIN0_PB1,GPIO_LOW);//set mmc1-clk to low. + + rk30_mux_api_set(GPIO0B0_MMC1_CMD_NAME, GPIO0B_GPIO0B0); + gpio_request(RK2928_PIN0_PB0, "mmc1-cmd"); + gpio_direction_output(RK2928_PIN0_PB0,GPIO_LOW);//set mmc1-cmd to low. + + rk30_mux_api_set(GPIO0B3_MMC1_D0_NAME, GPIO0B_GPIO0B3); + gpio_request(RK2928_PIN0_PB3, "mmc1-data0"); + gpio_direction_output(RK2928_PIN0_PB3,GPIO_LOW);//set mmc1-data0 to low. + + mdelay(100); + } + #endif + } + break; + + case 2: //mmc2 + break; + + default: + break; + } +} + +static void rk29_sdmmc_set_iomux_mmc0(unsigned int bus_width) +{ + switch (bus_width) + { + + case 1://SDMMC_CTYPE_4BIT: + { + rk30_mux_api_set(GPIO1C3_MMC0_D1_NAME, GPIO1C_MMC0_D1); + rk30_mux_api_set(GPIO1C4_MMC0_D2_NAME, GPIO1C_MMC0_D2); + rk30_mux_api_set(GPIO1C5_MMC0_D3_NAME, GPIO1C_MMC0_D3); + } + break; + + case 0x10000://SDMMC_CTYPE_8BIT: + break; + case 0xFFFF: //gpio_reset + { + rk30_mux_api_set(GPIO1B6_MMC0_PWREN_NAME, GPIO1B_GPIO1B6); + gpio_request(RK2928_PIN1_PB6,"sdmmc-power"); + gpio_direction_output(RK2928_PIN1_PB6,GPIO_HIGH); //power-off + + rk29_sdmmc_gpio_open(0, 0); + + gpio_direction_output(RK2928_PIN1_PB6,GPIO_LOW); //power-on + + rk29_sdmmc_gpio_open(0, 1); + } + break; + + default: //case 0://SDMMC_CTYPE_1BIT: + { + rk30_mux_api_set(GPIO1B7_MMC0_CMD_NAME, GPIO1B_MMC0_CMD); + rk30_mux_api_set(GPIO1C0_MMC0_CLKOUT_NAME, GPIO1C_MMC0_CLKOUT); + rk30_mux_api_set(GPIO1C2_MMC0_D0_NAME, GPIO1C_MMC0_D0); + + rk30_mux_api_set(GPIO1C3_MMC0_D1_NAME, GPIO1C_GPIO1C3); + gpio_request(RK2928_PIN1_PC3, "mmc0-data1"); + gpio_direction_output(RK2928_PIN1_PC3,GPIO_HIGH);//set mmc0-data1 to high. + + rk30_mux_api_set(GPIO1C4_MMC0_D2_NAME, GPIO1C_GPIO1C4); + gpio_request(RK2928_PIN1_PC4, "mmc0-data2"); + gpio_direction_output(RK2928_PIN1_PC4,GPIO_HIGH);//set mmc0-data2 to high. + + rk30_mux_api_set(GPIO1C5_MMC0_D3_NAME, GPIO1C_GPIO1C5); + gpio_request(RK2928_PIN1_PC5, "mmc0-data3"); + gpio_direction_output(RK2928_PIN1_PC5,GPIO_HIGH);//set mmc0-data3 to high. + } + break; + } +} + +static void rk29_sdmmc_set_iomux_mmc1(unsigned int bus_width) +{ + rk30_mux_api_set(GPIO0B0_MMC1_CMD_NAME, GPIO0B_MMC1_CMD); + rk30_mux_api_set(GPIO0B1_MMC1_CLKOUT_NAME, GPIO0B_MMC1_CLKOUT); + rk30_mux_api_set(GPIO0B3_MMC1_D0_NAME, GPIO0B_MMC1_D0); + rk30_mux_api_set(GPIO0B4_MMC1_D1_NAME, GPIO0B_MMC1_D1); + rk30_mux_api_set(GPIO0B5_MMC1_D2_NAME, GPIO0B_MMC1_D2); + rk30_mux_api_set(GPIO0B6_MMC1_D3_NAME, GPIO0B_MMC1_D3); +} + +static void rk29_sdmmc_set_iomux_mmc2(unsigned int bus_width) +{ + ;// +} + +static void rk29_sdmmc_set_iomux(int device_id, unsigned int bus_width) +{ + switch(device_id) + { + case 0: + #ifdef CONFIG_SDMMC0_RK29 + rk29_sdmmc_set_iomux_mmc0(bus_width); + #endif + break; + case 1: + #ifdef CONFIG_SDMMC1_RK29 + rk29_sdmmc_set_iomux_mmc1(bus_width); + #endif + break; + case 2: + rk29_sdmmc_set_iomux_mmc2(bus_width); + break; + default: + break; + } +} + +#endif + + +//int rk29sdk_wifi_power_state = 0; +//int rk29sdk_bt_power_state = 0; + +#ifdef CONFIG_WIFI_CONTROL_FUNC +//#define RK29SDK_WIFI_BT_GPIO_POWER_N RK30_PIN3_PD0 +//#define RK29SDK_WIFI_GPIO_RESET_N RK30_PIN3_PD0 +//#define RK29SDK_BT_GPIO_RESET_N RK30_PIN3_PD1 +#define RK30SDK_WIFI_GPIO_POWER_N RK30_PIN3_PD0 +//#define RK30SDK_BT_GPIO_POWER_N RK30_PIN3_PD1 + +#define PREALLOC_WLAN_SEC_NUM 4 +#define PREALLOC_WLAN_BUF_NUM 160 +#define PREALLOC_WLAN_SECTION_HEADER 24 + +#define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_BUF_NUM * 128) +#define WLAN_SECTION_SIZE_1 (PREALLOC_WLAN_BUF_NUM * 128) +#define WLAN_SECTION_SIZE_2 (PREALLOC_WLAN_BUF_NUM * 512) +#define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_BUF_NUM * 1024) + +#define WLAN_SKB_BUF_NUM 16 + +static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM]; + +struct wifi_mem_prealloc { + void *mem_ptr; + unsigned long size; +}; + +static struct wifi_mem_prealloc wifi_mem_array[PREALLOC_WLAN_SEC_NUM] = { + {NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)}, + {NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)}, + {NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)}, + {NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)} +}; + +static void *rk29sdk_mem_prealloc(int section, unsigned long size) +{ + if (section == PREALLOC_WLAN_SEC_NUM) + return wlan_static_skb; + + if ((section < 0) || (section > PREALLOC_WLAN_SEC_NUM)) + return NULL; + + if (wifi_mem_array[section].size < size) + return NULL; + + return wifi_mem_array[section].mem_ptr; +} + +static int __init rk29sdk_init_wifi_mem(void) +{ + int i; + int j; + + for (i = 0 ; i < WLAN_SKB_BUF_NUM ; i++) { + wlan_static_skb[i] = dev_alloc_skb( + ((i < (WLAN_SKB_BUF_NUM / 2)) ? 4096 : 8192)); + + if (!wlan_static_skb[i]) + goto err_skb_alloc; + } + + for (i = 0 ; i < PREALLOC_WLAN_SEC_NUM ; i++) { + wifi_mem_array[i].mem_ptr = + kmalloc(wifi_mem_array[i].size, GFP_KERNEL); + + if (!wifi_mem_array[i].mem_ptr) + goto err_mem_alloc; + } + return 0; + +err_mem_alloc: + pr_err("Failed to mem_alloc for WLAN\n"); + for (j = 0 ; j < i ; j++) + kfree(wifi_mem_array[j].mem_ptr); + + i = WLAN_SKB_BUF_NUM; + +err_skb_alloc: + pr_err("Failed to skb_alloc for WLAN\n"); + for (j = 0 ; j < i ; j++) + dev_kfree_skb(wlan_static_skb[j]); + + return -ENOMEM; +} + +static int rk29sdk_wifi_cd = 0; /* wifi virtual 'card detect' status */ +static void (*wifi_status_cb)(int card_present, void *dev_id); +static void *wifi_status_cb_devid; + +static int rk29sdk_wifi_status(struct device *dev) +{ + return rk29sdk_wifi_cd; +} + +static int rk29sdk_wifi_status_register(void (*callback)(int card_present, void *dev_id), void *dev_id) +{ + if(wifi_status_cb) + return -EAGAIN; + wifi_status_cb = callback; + wifi_status_cb_devid = dev_id; + return 0; +} + +static int __init rk29sdk_wifi_bt_gpio_control_init(void) +{ + rk29sdk_init_wifi_mem(); + + rk29_mux_api_set(GPIO0D6_MMC1_PWREN_NAME, GPIO0D_GPIO0D6); + + if (gpio_request(RK30SDK_WIFI_GPIO_POWER_N, "wifi_power")) { + pr_info("%s: request wifi power gpio failed\n", __func__); + return -1; + } + + /*if (gpio_request(RK29SDK_WIFI_GPIO_RESET_N, "wifi reset")) { + pr_info("%s: request wifi reset gpio failed\n", __func__); + gpio_free(RK30SDK_WIFI_GPIO_POWER_N); + return -1; + } + + if (gpio_request(RK29SDK_BT_GPIO_RESET_N, "bt reset")) { + pr_info("%s: request bt reset gpio failed\n", __func__); + gpio_free(RK29SDK_WIFI_GPIO_RESET_N); + return -1; + }*/ + + gpio_direction_output(RK30SDK_WIFI_GPIO_POWER_N, GPIO_LOW); + //gpio_direction_output(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW); + //gpio_direction_output(RK29SDK_BT_GPIO_RESET_N, GPIO_LOW); + + #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + + rk29_mux_api_set(GPIO0B4_MMC1_D1_NAME, GPIO0B_GPIO0B4); + gpio_request(RK2928_PIN0_PB4, "mmc1-data1"); + gpio_direction_output(RK2928_PIN0_PB4,GPIO_LOW);//set mmc1-data1 to low. + + rk29_mux_api_set(GPIO0B5_MMC1_D2_NAME, GPIO0B_GPIO0B5); + gpio_request(RK2928_PIN0_PB5, "mmc1-data2"); + gpio_direction_output(RK2928_PIN0_PB5,GPIO_LOW);//set mmc1-data2 to low. + + rk29_mux_api_set(GPIO0B6_MMC1_D3_NAME, GPIO0B_GPIO0B6); + gpio_request(RK2928_PIN0_PB6, "mmc1-data3"); + gpio_direction_output(RK2928_PIN0_PB6,GPIO_LOW);//set mmc1-data3 to low. + + rk29_sdmmc_gpio_open(1, 0); //added by xbw at 2011-10-13 + #endif + pr_info("%s: init finished\n",__func__); + + return 0; +} + +static int rk29sdk_wifi_power(int on) +{ + pr_info("%s: %d\n", __func__, on); + if (on){ + gpio_set_value(RK30SDK_WIFI_GPIO_POWER_N, GPIO_HIGH); + + #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + rk29_sdmmc_gpio_open(1, 1); //added by xbw at 2011-10-13 + #endif + + //gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_HIGH); + mdelay(100); + pr_info("wifi turn on power\n"); + }else{ +// if (!rk29sdk_bt_power_state){ + gpio_set_value(RK30SDK_WIFI_GPIO_POWER_N, GPIO_LOW); + + #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) + rk29_sdmmc_gpio_open(1, 0); //added by xbw at 2011-10-13 + #endif + + mdelay(100); + pr_info("wifi shut off power\n"); +// }else +// { +// pr_info("wifi shouldn't shut off power, bt is using it!\n"); +// } + //gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW); + + } + +// rk29sdk_wifi_power_state = on; + return 0; +} + +static int rk29sdk_wifi_reset_state; +static int rk29sdk_wifi_reset(int on) +{ + pr_info("%s: %d\n", __func__, on); + //gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, on); + //mdelay(100); + rk29sdk_wifi_reset_state = on; + return 0; +} + +int rk29sdk_wifi_set_carddetect(int val) +{ + pr_info("%s:%d\n", __func__, val); + rk29sdk_wifi_cd = val; + if (wifi_status_cb){ + wifi_status_cb(val, wifi_status_cb_devid); + }else { + pr_warning("%s, nobody to notify\n", __func__); + } + return 0; +} +EXPORT_SYMBOL(rk29sdk_wifi_set_carddetect); + +#define WIFI_HOST_WAKE RK30_PIN3_PD2 + +static struct resource resources[] = { + { + .start = WIFI_HOST_WAKE, + .flags = IORESOURCE_IRQ, + .name = "bcmdhd_wlan_irq", + }, +}; + +static struct wifi_platform_data rk29sdk_wifi_control = { + .set_power = rk29sdk_wifi_power, + .set_reset = rk29sdk_wifi_reset, + .set_carddetect = rk29sdk_wifi_set_carddetect, + .mem_prealloc = rk29sdk_mem_prealloc, +}; + +static struct platform_device rk29sdk_wifi_device = { + .name = "bcmdhd_wlan", + .id = 1, + .num_resources = ARRAY_SIZE(resources), + .resource = resources, + .dev = { + .platform_data = &rk29sdk_wifi_control, + }, +}; +#endif + + +#endif // endif --#ifdef CONFIG_SDMMC_RK29 + diff --git a/arch/arm/mach-rk2928/devices.c b/arch/arm/mach-rk2928/devices.c index 21e24335a532..4d9f39826138 100755 --- a/arch/arm/mach-rk2928/devices.c +++ b/arch/arm/mach-rk2928/devices.c @@ -620,6 +620,65 @@ static struct platform_device device_keys = { }, }; #endif + +#ifdef CONFIG_SDMMC0_RK29 +static struct resource resources_sdmmc0[] = { + { + .start = IRQ_SDMMC, + .end = IRQ_SDMMC, + .flags = IORESOURCE_IRQ, + }, + { + .start = RK2928_SDMMC_PHYS, + .end = RK2928_SDMMC_PHYS + RK2928_SDMMC_SIZE -1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device device_sdmmc0 = { + .name = "rk29_sdmmc", + .id = 0, + .num_resources = ARRAY_SIZE(resources_sdmmc0), + .resource = resources_sdmmc0, + .dev = { + .platform_data = &default_sdmmc0_data, + }, +}; +#endif + +#ifdef CONFIG_SDMMC1_RK29 +static struct resource resources_sdmmc1[] = { + { + .start = IRQ_SDIO, + .end = IRQ_SDIO, + .flags = IORESOURCE_IRQ, + }, + { + .start = RK2928_SDIO_PHYS, + .end = RK2928_SDIO_PHYS + RK2928_SDIO_SIZE - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device device_sdmmc1 = { + .name = "rk29_sdmmc", + .id = 1, + .num_resources = ARRAY_SIZE(resources_sdmmc1), + .resource = resources_sdmmc1, + .dev = { + .platform_data = &default_sdmmc1_data, + }, +}; +#endif +static void __init rk2928_init_sdmmc(void) +{ +#ifdef CONFIG_SDMMC0_RK29 + platform_device_register(&device_sdmmc0); +#endif +#ifdef CONFIG_SDMMC1_RK29 + platform_device_register(&device_sdmmc1); +#endif +} static int __init rk2928_init_devices(void) { rk2928_init_dma(); @@ -635,6 +694,7 @@ static int __init rk2928_init_devices(void) #ifdef CONFIG_LCDC_RK2928 platform_device_register(&device_lcdc); #endif + rk2928_init_sdmmc(); #if defined(CONFIG_FIQ_DEBUGGER) && defined(DEBUG_UART_PHYS) rk_serial_debug_init(DEBUG_UART_BASE, IRQ_DEBUG_UART, IRQ_UART_SIGNAL, -1); #endif diff --git a/drivers/mmc/host/rk29_sdmmc.c b/drivers/mmc/host/rk29_sdmmc.c index 57ada8690736..acab9705e8de 100755 --- a/drivers/mmc/host/rk29_sdmmc.c +++ b/drivers/mmc/host/rk29_sdmmc.c @@ -50,6 +50,22 @@ #include "rk29_sdmmc.h" +#if defined(CONFIG_ARCH_RK29) +#define SD_DETECT_PIN RK29_PIN2_PA2 +#define SD_DETECT_NAME GPIO2A2_SDMMC0DETECTN_NAME +#define SD_DETECT_GPIO_MODE GPIO2L_GPIO2A2 +#define SD_DETECT_DET_MODE GPIO2L_SDMMC0_DETECT_N +#elif defined(CONFIG_ARCH_RK30) +#define SD_DETECT_PIN RK30_PIN3_PB6 +#define SD_DETECT_NAME GPIO3B6_SDMMC0DETECTN_NAME +#define SD_DETECT_GPIO_MODE GPIO3B_GPIO3B6 +#define SD_DETECT_DET_MODE GPIO3B_SDMMC_DETECT_N +#elif defined(CONFIG_ARCH_RK2928) +#define SD_DETECT_PIN RK2928_PIN1_PC7 +#define SD_DETECT_NAME GPIO1C1_MMC0_DETN_NAME +#define SD_DETECT_GPIO_MODE GPIO1C_GPIO1C1 +#define SD_DETECT_DET_MODE GPIO1C_MMC0_DETN +#endif #define RK29_SDMMC_xbw_Debug 0 @@ -1103,6 +1119,7 @@ static int rk29_sdmmc_submit_data_dma(struct rk29_sdmmc *host, struct mmc_data * rk29_sdmmc_control_host_dma(host, TRUE);// enable dma ret = rk29_dma_ctrl(host->dma_info.chn, RK29_DMAOP_START); + if(ret < 0) { printk(KERN_WARNING "%s..%d...rk29_dma_ctrl start error![%s]\n", __FUNCTION__, __LINE__, host->dma_name); @@ -1470,7 +1487,7 @@ int rk29_sdmmc_reset_controller(struct rk29_sdmmc *host) /* reset */ #if defined(CONFIG_ARCH_RK29) rk29_sdmmc_write(host->regs, SDMMC_CTRL,(SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET )); -#elif defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31) +#elif defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31) || defined(CONFIG_ARCH_RK2928) rk29_sdmmc_write(host->regs, SDMMC_CTRL,(SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_DMA_RESET)); #endif timeOut = 1000; @@ -3566,7 +3583,6 @@ static int __exit rk29_sdmmc_remove(struct platform_device *pdev) return 0; } - #ifdef CONFIG_PM #if defined(CONFIG_ARCH_RK29) @@ -3574,7 +3590,7 @@ static irqreturn_t det_keys_isr(int irq, void *dev_id) { struct rk29_sdmmc *host = dev_id; dev_info(&host->pdev->dev, "sd det_gpio changed(%s), send wakeup key!\n", - gpio_get_value(RK29_PIN2_PA2)?"removed":"insert"); + gpio_get_value(SD_DETECT_PIN)?"removed":"insert"); rk29_sdmmc_detect_change((unsigned long)dev_id); return IRQ_HANDLED; @@ -3583,13 +3599,13 @@ static irqreturn_t det_keys_isr(int irq, void *dev_id) static int rk29_sdmmc_sdcard_suspend(struct rk29_sdmmc *host) { int ret = 0; - rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_GPIO2A2); - gpio_request(RK29_PIN2_PA2, "sd_detect"); - gpio_direction_input(RK29_PIN2_PA2); + rk29_mux_api_set(SD_DETECT_NAME, SD_DETECT_GPIO_MODE); + gpio_request(SD_DETECT_PIN, "sd_detect"); + gpio_direction_input(SD_DETECT_PIN); - host->gpio_irq = gpio_to_irq(RK29_PIN2_PA2); + host->gpio_irq = gpio_to_irq(SD_DETECT_PIN); ret = request_irq(host->gpio_irq, det_keys_isr, - (gpio_get_value(RK29_PIN2_PA2))?IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING, + (gpio_get_value(SD_DETECT_PIN))?IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING, "sd_detect", host); @@ -3601,16 +3617,16 @@ static void rk29_sdmmc_sdcard_resume(struct rk29_sdmmc *host) { disable_irq_wake(host->gpio_irq); free_irq(host->gpio_irq,host); - gpio_free(RK29_PIN2_PA2); - rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N); + gpio_free(SD_DETECT_PIN); + rk29_mux_api_set(SD_DETECT_NAME, SD_DETECT_DET_MODE); } -#elif defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31) +#elif defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31) || defined(CONFIG_ARCH_RK2928) static irqreturn_t det_keys_isr(int irq, void *dev_id) { struct rk29_sdmmc *host = dev_id; dev_info(&host->pdev->dev, "sd det_gpio changed(%s), send wakeup key!\n", - gpio_get_value(RK30_PIN3_PB6)?"removed":"insert"); + gpio_get_value(SD_DETECT_PIN)?"removed":"insert"); rk29_sdmmc_detect_change((unsigned long)dev_id); return IRQ_HANDLED; @@ -3619,13 +3635,13 @@ static irqreturn_t det_keys_isr(int irq, void *dev_id) static int rk29_sdmmc_sdcard_suspend(struct rk29_sdmmc *host) { int ret = 0; - rk29_mux_api_set(GPIO3B6_SDMMC0DETECTN_NAME, GPIO3B_GPIO3B6); - gpio_request(RK30_PIN3_PB6, "sd_detect"); - gpio_direction_input(RK30_PIN3_PB6); + rk29_mux_api_set(SD_DETECT_NAME, SD_DETECT_GPIO_MODE); + gpio_request(SD_DETECT_PIN, "sd_detect"); + gpio_direction_input(SD_DETECT_PIN); - host->gpio_irq = gpio_to_irq(RK30_PIN3_PB6); + host->gpio_irq = gpio_to_irq(SD_DETECT_PIN); ret = request_irq(host->gpio_irq, det_keys_isr, - (gpio_get_value(RK30_PIN3_PB6))?IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING, + (gpio_get_value(SD_DETECT_PIN))?IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING, "sd_detect", host); @@ -3637,8 +3653,8 @@ static void rk29_sdmmc_sdcard_resume(struct rk29_sdmmc *host) { disable_irq_wake(host->gpio_irq); free_irq(host->gpio_irq,host); - gpio_free(RK30_PIN3_PB6); - rk29_mux_api_set(GPIO3B6_SDMMC0DETECTN_NAME, GPIO3B_SDMMC0_DETECT_N); + gpio_free(SD_DETECT_PIN); + rk29_mux_api_set(SD_DETECT_NAME, SD_DETECT_DET_MODE); } #endif diff --git a/drivers/mmc/host/rk29_sdmmc.h b/drivers/mmc/host/rk29_sdmmc.h index 9360cd3ea85e..17b6d2b209b8 100755 --- a/drivers/mmc/host/rk29_sdmmc.h +++ b/drivers/mmc/host/rk29_sdmmc.h @@ -48,7 +48,7 @@ #if defined(CONFIG_ARCH_RK29) #define SDMMC_DATA (0x100) -#elif defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31) +#elif defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31) || defined(CONFIG_ARCH_RK2928) #define SDMMC_VERID (0x06c) //Version ID register #define SDMMC_UHS_REG (0x074) //UHS-I register #define SDMMC_RST_n (0x078) //Hardware reset register @@ -102,7 +102,7 @@ /* Interrupt status & mask register defines(base+0x24) */ #if defined(CONFIG_ARCH_RK29) #define SDMMC_INT_SDIO RK2818_BIT(16) //SDIO interrupt -#elif defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31) +#elif defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31) || defined(CONFIG_ARCH_RK2928) #define SDMMC_INT_SDIO RK2818_BIT(24) //SDIO interrupt #define SDMMC_INT_UNBUSY RK2818_BIT(16) //data no busy interrupt #endif @@ -181,7 +181,7 @@ #define RX_WMARK (0xF) //RX watermark level set to 15 #define TX_WMARK (0x10) //TX watermark level set to 16 -#elif defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31) +#elif defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK31) || defined(CONFIG_ARCH_RK2928) #define FIFO_DEPTH (0x100) //FIFO depth = 256 word #define RX_WMARK_SHIFT (16) #define TX_WMARK_SHIFT (0) -- 2.34.1