/* Return 1 if vol_up pressed */ static int target_volume_up() { uint8_t status = 0; struct pm8x41_gpio gpio; /* CDP vol_up seems to be always grounded. So gpio status is read as 0, * whether key is pressed or not. * Ignore volume_up key on CDP for now. */ if (board_hardware_id() == HW_PLATFORM_SURF) return 0; /* Configure the GPIO */ gpio.direction = PM_GPIO_DIR_IN; gpio.function = 0; gpio.pull = PM_GPIO_PULL_UP_30; gpio.vin_sel = 2; pm8x41_gpio_config(5, &gpio); /* Get status of P_GPIO_5 */ pm8x41_gpio_get(5, &status); return !status; /* active low */ }
/* Return 1 if vol_up pressed */ int target_volume_up() { static uint8_t first_time = 0; uint8_t status = 0; struct pm8x41_gpio gpio; if (!first_time) { /* Configure the GPIO */ gpio.direction = PM_GPIO_DIR_IN; gpio.function = 0; gpio.pull = PM_GPIO_PULL_UP_30; gpio.vin_sel = 2; pm8x41_gpio_config(3, &gpio); /* Wait for the pmic gpio config to take effect */ udelay(10000); first_time = 1; } /* Get status of P_GPIO_5 */ pm8x41_gpio_get(3, &status); return !status; /* active low */ }
static int msm8226_pwm_backlight_ctrl(int gpio_num, int lpg_chan, int enable) { struct pm8x41_gpio gpio_param = { .direction = PM_GPIO_DIR_OUT, .function = PM_GPIO_FUNC_2, .vin_sel = 2, /* VIN_2 */ .pull = PM_GPIO_PULL_UP_1_5 | PM_GPIO_PULLDOWN_10, .output_buffer = PM_GPIO_OUT_CMOS, .out_strength = PM_GPIO_OUT_DRIVE_HIGH, }; dprintf(SPEW, "%s: gpio=%d lpg=%d enable=%d\n", __func__, gpio_num, lpg_chan, enable); if (enable) { pm8x41_gpio_config(gpio_num, &gpio_param); pm8x41_lpg_write(lpg_chan, 0x41, 0x33); /* LPG_PWM_SIZE_CLK, */ pm8x41_lpg_write(lpg_chan, 0x42, 0x01); /* LPG_PWM_FREQ_PREDIV */ pm8x41_lpg_write(lpg_chan, 0x43, 0x20); /* LPG_PWM_TYPE_CONFIG */ pm8x41_lpg_write(lpg_chan, 0x44, 0xb2); /* LPG_VALUE_LSB */ pm8x41_lpg_write(lpg_chan, 0x45, 0x01); /* LPG_VALUE_MSB */ pm8x41_lpg_write(lpg_chan, 0x46, 0xe4); /* LPG_ENABLE_CONTROL */ } else { pm8x41_lpg_write(lpg_chan, 0x46, 0x00); } return NO_ERROR; } int target_backlight_ctrl(struct backlight *bl, uint8_t enable) { uint32_t ret = NO_ERROR; dprintf(SPEW, "target_backlight_ctrl\n"); if (!bl) { dprintf(CRITICAL, "backlight structure is not available\n"); return ERR_INVALID_ARGS; } switch (bl->bl_interface_type) { case BL_WLED: ret = msm8226_wled_backlight_ctrl(enable); break; case BL_PWM: ret = msm8226_pwm_backlight_ctrl(pwm_gpio.pin_id, PWM_BL_LPG_CHAN_ID, enable); break; default: dprintf(CRITICAL, "backlight type:%d not supported\n", bl->bl_interface_type); return ERR_NOT_SUPPORTED; } return ret; }
/* Pull DISP_RST_N high to get panel out of reset */ int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq, struct msm_panel_info *pinfo) { uint32_t rst_gpio = reset_gpio.pin_id; uint32_t platform_id = board_platform_id(); uint32_t hardware_id = board_hardware_id(); struct pm8x41_gpio resetgpio_param = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_CMOS, .out_strength = PM_GPIO_OUT_DRIVE_MED, }; if (platform_id == MSM8974AC) if ((hardware_id == HW_PLATFORM_MTP) || (hardware_id == HW_PLATFORM_LIQUID)) rst_gpio = 20; dprintf(SPEW, "platform_id: %u, rst_gpio: %u\n", platform_id, rst_gpio); pm8x41_gpio_config(rst_gpio, &resetgpio_param); if (enable) { gpio_tlmm_config(enable_gpio.pin_id, 0, enable_gpio.pin_direction, enable_gpio.pin_pull, enable_gpio.pin_strength, enable_gpio.pin_state); gpio_set(enable_gpio.pin_id, resetseq->pin_direction); pm8x41_gpio_set(rst_gpio, resetseq->pin_state[0]); mdelay(resetseq->sleep[0]); pm8x41_gpio_set(rst_gpio, resetseq->pin_state[1]); mdelay(resetseq->sleep[1]); pm8x41_gpio_set(rst_gpio, resetseq->pin_state[2]); mdelay(resetseq->sleep[2]); } else { resetgpio_param.out_strength = PM_GPIO_OUT_DRIVE_LOW; pm8x41_gpio_config(rst_gpio, &resetgpio_param); pm8x41_gpio_set(rst_gpio, PM_GPIO_FUNC_LOW); gpio_set(enable_gpio.pin_id, resetseq->pin_direction); } return NO_ERROR; }
/* Return 1 if vol_up pressed */ static int target_volume_up() { uint8_t status = 0; struct pm8x41_gpio gpio; /* Configure the GPIO */ gpio.direction = PM_GPIO_DIR_IN; gpio.function = 0; gpio.pull = PM_GPIO_PULL_UP_30; gpio.vin_sel = 2; pm8x41_gpio_config(3, &gpio); /* Wait for the pmic gpio config to take effect */ thread_sleep(1); /* Get status of P_GPIO_5 */ pm8x41_gpio_get(3, &status); return !status; /* active low */ }
int target_backlight_ctrl(uint8_t enable) { struct pm8x41_gpio pwmgpio_param = { .direction = PM_GPIO_DIR_OUT, .function = PM_GPIO_FUNC_1, .vin_sel = 2, /* VIN_2 */ .pull = PM_GPIO_PULL_UP_1_5 | PM_GPIO_PULLDOWN_10, .output_buffer = PM_GPIO_OUT_CMOS, .out_strength = 0x03, }; if (enable) { pm8x41_gpio_config(7, &pwmgpio_param); /* lpg channel 2 */ pm8x41_lpg_write(3, 0x41, 0x33); /* LPG_PWM_SIZE_CLK, */ pm8x41_lpg_write(3, 0x42, 0x01); /* LPG_PWM_FREQ_PREDIV */ pm8x41_lpg_write(3, 0x43, 0x20); /* LPG_PWM_TYPE_CONFIG */ pm8x41_lpg_write(3, 0x44, 0xcc); /* LPG_VALUE_LSB */ pm8x41_lpg_write(3, 0x45, 0x00); /* LPG_VALUE_MSB */ pm8x41_lpg_write(3, 0x46, 0xe4); /* LPG_ENABLE_CONTROL */ } else { pm8x41_lpg_write(3, 0x46, 0x0); /* LPG_ENABLE_CONTROL */ } return NO_ERROR; } int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo) { struct mdss_dsi_pll_config *pll_data; uint32_t dual_dsi = pinfo->mipi.dual_dsi; dprintf(SPEW, "target_panel_clock\n"); pll_data = pinfo->mipi.dsi_pll_config; if (enable) { mdp_gdsc_ctrl(enable); mmss_bus_clock_enable(); mdp_clock_enable(); mdss_dsi_auto_pll_config(MIPI_DSI0_BASE, pll_data); dsi_pll_enable_seq(MIPI_DSI0_BASE); if (pinfo->mipi.dual_dsi && !(pinfo->mipi.broadcast)) { mdss_dsi_auto_pll_config(MIPI_DSI1_BASE, pll_data); dsi_pll_enable_seq(MIPI_DSI1_BASE); } mmss_dsi_clock_enable(DSI0_PHY_PLL_OUT, dual_dsi, pll_data->pclk_m, pll_data->pclk_n, pll_data->pclk_d); } else if(!target_cont_splash_screen()) { /* Disable clocks if continuous splash off */ mmss_dsi_clock_disable(dual_dsi); mdp_clock_disable(); mmss_bus_clock_disable(); mdp_gdsc_ctrl(enable); } return NO_ERROR; } /* Pull DISP_RST_N high to get panel out of reset */ int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq, struct msm_panel_info *pinfo) { uint32_t i = 0; if (enable) { gpio_tlmm_config(reset_gpio.pin_id, 0, reset_gpio.pin_direction, reset_gpio.pin_pull, reset_gpio.pin_strength, reset_gpio.pin_state); gpio_tlmm_config(enable_gpio.pin_id, 0, enable_gpio.pin_direction, enable_gpio.pin_pull, enable_gpio.pin_strength, enable_gpio.pin_state); gpio_tlmm_config(bkl_gpio.pin_id, 0, bkl_gpio.pin_direction, bkl_gpio.pin_pull, bkl_gpio.pin_strength, bkl_gpio.pin_state); gpio_set(enable_gpio.pin_id, 2); gpio_set(bkl_gpio.pin_id, 2); /* reset */ for (i = 0; i < RESET_GPIO_SEQ_LEN; i++) { if (resetseq->pin_state[i] == GPIO_STATE_LOW) gpio_set(reset_gpio.pin_id, GPIO_STATE_LOW); else gpio_set(reset_gpio.pin_id, GPIO_STATE_HIGH); mdelay(resetseq->sleep[i]); } } else { gpio_set(reset_gpio.pin_id, 0); gpio_set(enable_gpio.pin_id, 0); gpio_set(bkl_gpio.pin_id, 0); } return NO_ERROR; }
static int msm8974_backlight_on() { static struct pm8x41_wled_data wled_ctrl = { .mod_scheme = 0xC3, .led1_brightness = (0x0F << 8) | 0xEF, .led2_brightness = (0x0F << 8) | 0xEF, .led3_brightness = (0x0F << 8) | 0xEF, .max_duty_cycle = 0x01, }; pm8x41_wled_config(&wled_ctrl); pm8x41_wled_sink_control(1); pm8x41_wled_iled_sync_control(1); pm8x41_wled_enable(1); return 0; } static int msm8974_mdss_dsi_panel_clock(uint8_t enable) { if (enable) { mdp_gdsc_ctrl(enable); mdp_clock_init(); mdss_dsi_uniphy_pll_config(); mmss_clock_init(); } else if(!target_cont_splash_screen()) { // * Add here for continuous splash * mmss_clock_disable(); mdp_clock_disable(); mdp_gdsc_ctrl(enable); } return 0; } /* Pull DISP_RST_N high to get panel out of reset */ static void msm8974_mdss_mipi_panel_reset(uint8_t enable) { struct pm8x41_gpio gpio19_param = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_CMOS, .out_strength = PM_GPIO_OUT_DRIVE_MED, }; pm8x41_gpio_config(19, &gpio19_param); if (enable) { gpio_tlmm_config(58, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA, GPIO_DISABLE); pm8x41_gpio_set(19, PM_GPIO_FUNC_HIGH); mdelay(2); pm8x41_gpio_set(19, PM_GPIO_FUNC_LOW); mdelay(5); pm8x41_gpio_set(19, PM_GPIO_FUNC_HIGH); mdelay(2); gpio_set(58, 2); } else { gpio19_param.out_strength = PM_GPIO_OUT_DRIVE_LOW; pm8x41_gpio_config(19, &gpio19_param); pm8x41_gpio_set(19, PM_GPIO_FUNC_LOW); gpio_set(58, 2); } } static int msm8974_mipi_panel_power(uint8_t enable) { if (enable) { /* Enable backlight */ msm8974_backlight_on(); /* Turn on LDO8 for lcd1 mipi vdd */ dprintf(SPEW, " Setting LDO22\n"); pm8x41_ldo_set_voltage("LDO22", 3000000); pm8x41_ldo_control("LDO22", enable); dprintf(SPEW, " Setting LDO12\n"); /* Turn on LDO23 for lcd1 mipi vddio */ pm8x41_ldo_set_voltage("LDO12", 1800000); pm8x41_ldo_control("LDO12", enable); dprintf(SPEW, " Setting LDO2\n"); /* Turn on LDO2 for vdda_mipi_dsi */ pm8x41_ldo_set_voltage("LDO2", 1200000); pm8x41_ldo_control("LDO2", enable); dprintf(SPEW, " Panel Reset \n"); /* Panel Reset */ msm8974_mdss_mipi_panel_reset(enable); dprintf(SPEW, " Panel Reset Done\n"); } else { msm8974_mdss_mipi_panel_reset(enable); pm8x41_wled_enable(enable); pm8x41_ldo_control("LDO2", enable); pm8x41_ldo_control("LDO22", enable); } return 0; } void display_init(void) { uint32_t hw_id = board_hardware_id(); uint32_t soc_ver = board_soc_version(); dprintf(INFO, "display_init(),target_id=%d.\n", hw_id); switch (hw_id) { case HW_PLATFORM_MTP: case HW_PLATFORM_FLUID: case HW_PLATFORM_SURF: mipi_toshiba_video_720p_init(&(panel.panel_info)); panel.clk_func = msm8974_mdss_dsi_panel_clock; panel.power_func = msm8974_mipi_panel_power; panel.fb.base = MIPI_FB_ADDR; panel.fb.width = panel.panel_info.xres; panel.fb.height = panel.panel_info.yres; panel.fb.stride = panel.panel_info.xres; panel.fb.bpp = panel.panel_info.bpp; panel.fb.format = FB_FORMAT_RGB888; panel.mdp_rev = MDP_REV_50; break; default: return; }; if (msm_display_init(&panel)) { dprintf(CRITICAL, "Display init failed!\n"); return; } display_enable = 1; }
int target_backlight_ctrl(struct backlight *bl, uint8_t enable) { struct pm8x41_gpio pwmgpio_param = { .direction = PM_GPIO_DIR_OUT, .function = PM_GPIO_FUNC_1, .vin_sel = 2, /* VIN_2 */ .pull = PM_GPIO_PULL_UP_1_5 | PM_GPIO_PULLDOWN_10, .output_buffer = PM_GPIO_OUT_CMOS, .out_strength = 0x03, }; if (enable) { pm8x41_gpio_config(pwm_gpio.pin_id, &pwmgpio_param); /* lpg channel 3 */ pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x41, 0x33); /* LPG_PWM_SIZE_CLK, */ pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x42, 0x01); /* LPG_PWM_FREQ_PREDIV */ pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x43, 0x20); /* LPG_PWM_TYPE_CONFIG */ pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x44, 0xcc); /* LPG_VALUE_LSB */ pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x45, 0x00); /* LPG_VALUE_MSB */ pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x46, 0xe4); /* LPG_ENABLE_CONTROL */ } else { pm8x41_lpg_write(PWM_BL_LPG_CHAN_ID, 0x46, 0x0); /* LPG_ENABLE_CONTROL */ } return NO_ERROR; } int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo) { uint32_t ret; struct mdss_dsi_pll_config *pll_data; uint32_t dual_dsi = pinfo->mipi.dual_dsi; dprintf(SPEW, "target_panel_clock\n"); pll_data = pinfo->mipi.dsi_pll_config; if (enable) { mdp_gdsc_ctrl(enable); mmss_bus_clock_enable(); mdp_clock_enable(); ret = restore_secure_cfg(SECURE_DEVICE_MDSS); if (ret) { dprintf(CRITICAL, "%s: Failed to restore MDP security configs", __func__); mdp_clock_disable(); mmss_bus_clock_disable(); mdp_gdsc_ctrl(0); return ret; } mdss_dsi_auto_pll_config(DSI0_PLL_BASE, MIPI_DSI0_BASE, pll_data); dsi_pll_enable_seq(DSI0_PLL_BASE); mmss_dsi_clock_enable(DSI0_PHY_PLL_OUT, dual_dsi, pll_data->pclk_m, pll_data->pclk_n, pll_data->pclk_d); } else if(!target_cont_splash_screen()) { /* Disable clocks if continuous splash off */ mmss_dsi_clock_disable(dual_dsi); mdp_clock_disable(); mmss_bus_clock_disable(); mdp_gdsc_ctrl(enable); } return NO_ERROR; }