/* * Copyright (C) 2013-2015 Apple Inc. All rights reserved. * * This document is the property of Apple Inc. * It is considered confidential and proprietary. * * This document may not be reproduced or transmitted in any form, * in whole or in part, without the express written permission of * Apple Inc. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #if WITH_HW_DISPLAY_PMU #include #endif #if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) #include #endif // Board rev encodings. The voltages are treated as active // low (so 1.8V is a binary 1 and 0 V is a binary 0) so that // the numbers count naturally #define BOARD_REV_AP_PROTO1 0x0 #define BOARD_REV_AP_PROTO2 0x1 #define BOARD_REV_AP_EVT 0x2 #define BOARD_REV_AP_EVT_MD 0x3 #define BOARD_REV_AP_CARRIER1 0x4 #define BOARD_REV_AP_CARRIER2 0x5 #define BOARD_REV_AP_DVT_N66 0x6 #define BOARD_REV_DEV1 0x0 #define BOARD_REV_DEV2 0x1 #define BOARD_REV_DEV3 0x2 static uint32_t iphone8_get_board_rev(void); static void iphone8_assert_display_type(void); #if WITH_HW_LM3534 static void iphone8_get_backlight_i2c_address(uint32_t oid __unused, void *arg __unused, void *data); MIB_CONSTANT(kMIBTargetBacklight0I2CBus, kOIDTypeUInt32, 0); MIB_FUNCTION(kMIBTargetBacklight0I2CAddress, kOIDTypeUInt32, iphone8_get_backlight_i2c_address, NULL); #if TARGET_DISPLAY_D620 MIB_CONSTANT(kMIBTargetBacklight1I2CBus, kOIDTypeUInt32, 2); MIB_FUNCTION(kMIBTargetBacklight1I2CAddress, kOIDTypeUInt32, iphone8_get_backlight_i2c_address, NULL); #endif #endif #if TARGET_DISPLAY_D620 MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 3); #else MIB_CONSTANT(kMIBTargetOsPictureScale, kOIDTypeUInt32, 2); #endif MIB_CONSTANT(kMIBTargetPictureRotate, kOIDTypeInt32, 0); /* Used to indicate to lm3534 driver to over-ride auto-frequency threshold */ MIB_CONSTANT(kMIBTargetBacklightAutoFreqThresh, kOIDTypeUInt32, 0xc8); // This will change threshold from 8mA to 6.592mA static bool gpio_board_rev_valid; static uint32_t gpio_board_rev; #if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) static mipi_t display_panel_configurations = { #if TARGET_DISPLAY_D520 .lanes = 2, .esc_div = 8, .pll_n = 0x0, .pll_m = 0x30, .pll_p = 0x0, .hsfreq = 0x1b, .target_phy_settings = { 4, {{0x44, 1, {0x36}}, {0x30, 1, {0x3F}}, {0x20, 1, {0x45}}, {0x32, 1, {0x28}}}}, //1200 Mhz #elif TARGET_DISPLAY_D620 .lanes = 4, .esc_div = 8, .pll_n = 0x0, .pll_m = 0x30, .pll_p = 0x0, .hsfreq = 0x1b, .target_phy_settings = { 4, {{0x44, 1, {0x36}}, {0x30, 1, {0x3F}}, {0x20, 1, {0x45}}, {0x32, 1, {0x28}}}}, //1200 Mhz #endif }; #endif // Read the board rev GPIOs. Note that the encoding is done // with active-low GPIOs, so we need to invert the values // we read from the GPIOs static uint32_t iphone8_get_board_rev(void) { if (!gpio_board_rev_valid) { gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_IN); gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_IN); gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_IN); gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_IN); gpio_configure_pupdn(GPIO_BOARD_REV0, GPIO_PDN); gpio_configure_pupdn(GPIO_BOARD_REV1, GPIO_PDN); gpio_configure_pupdn(GPIO_BOARD_REV2, GPIO_PDN); gpio_configure_pupdn(GPIO_BOARD_REV3, GPIO_PDN); spin(100); // Wait 100us gpio_board_rev = (gpio_read(GPIO_BOARD_REV3) << 3) | (gpio_read(GPIO_BOARD_REV2) << 2) | (gpio_read(GPIO_BOARD_REV1) << 1) | (gpio_read(GPIO_BOARD_REV0) << 0); // Invert gpio_board_rev ^= 0xf; gpio_configure(GPIO_BOARD_REV0, GPIO_CFG_DFLT); gpio_configure(GPIO_BOARD_REV1, GPIO_CFG_DFLT); gpio_configure(GPIO_BOARD_REV2, GPIO_CFG_DFLT); gpio_configure(GPIO_BOARD_REV3, GPIO_CFG_DFLT); gpio_board_rev_valid = true; #if WITH_ENV env_set_uint("board-rev", gpio_board_rev, 0); #endif } return gpio_board_rev; } #define TRISTATE_PULLDN (0) #define TRISTATE_FLOAT (1) #define TRISTATE_PULLUP (2) // reads a gpio that could be pulled up, pulled down, or floating static uint32_t iphone8_read_tristate(gpio_t gpio) { uint32_t val1; uint32_t val2; gpio_configure(gpio, GPIO_CFG_IN); gpio_configure_pupdn(gpio, GPIO_PDN); spin(100); // Wait 100us val1 = gpio_read(gpio); gpio_configure_pupdn(gpio, GPIO_PUP); spin(100); // Wait 100us val2 = gpio_read(gpio); gpio_configure(gpio, GPIO_CFG_DFLT); if (val1 == 0 && val2 == 0) return TRISTATE_PULLDN; // pulled down else if (val1 == 0 && val2 == 1) return TRISTATE_FLOAT; // floating else if (val1 == 1 && val2 == 1) return TRISTATE_PULLUP; // pulled up else panic("unexpected result from gpio %u tristate read %u, %u", gpio, val1, val2); } // Display IDs are constructed with the formula (ID1 << 4 | ID0) where // ID is 0 for grounded, 1 for floating, and 2 for pulled up // Both pins floating means no card is connected #define IPHONE8_DISPLAY_ID_TOF_PROX (1 << 8) #define IPHONE8_DISPLAY_ID_EMPTY (TRISTATE_FLOAT << 4 | TRISTATE_FLOAT << 0) #define IPHONE8_DISPLAY_ID_N71_P1 (TRISTATE_PULLDN << 4 | TRISTATE_PULLDN << 0) #define IPHONE8_DISPLAY_ID_N71_P1_MUON (TRISTATE_PULLUP << 4 | TRISTATE_PULLDN << 0) #define IPHONE8_DISPLAY_ID_N71 (TRISTATE_FLOAT << 4 | TRISTATE_PULLUP << 0) #define IPHONE8_DISPLAY_ID_N71_TOF_PROX (IPHONE8_DISPLAY_ID_TOF_PROX | IPHONE8_DISPLAY_ID_N71) #define IPHONE8_DISPLAY_ID_N66_P1 (TRISTATE_PULLUP << 4 | TRISTATE_PULLUP << 0) #define IPHONE8_DISPLAY_ID_N66 (TRISTATE_PULLUP << 4 | TRISTATE_FLOAT << 0) #define IPHONE8_DISPLAY_ID_N66_TOF_PROX (IPHONE8_DISPLAY_ID_TOF_PROX | IPHONE8_DISPLAY_ID_N66) #if TARGET_DISPLAY_D520 #define IPHONE8_DISPLAY_ID_DEFAULT_P1 IPHONE8_DISPLAY_ID_N71_P1 #define IPHONE8_DISPLAY_ID_DEFAULT IPHONE8_DISPLAY_ID_N71 #elif TARGET_DISPLAY_D620 #define IPHONE8_DISPLAY_ID_DEFAULT_P1 IPHONE8_DISPLAY_ID_N66_P1 #define IPHONE8_DISPLAY_ID_DEFAULT IPHONE8_DISPLAY_ID_N66 #else #error "Unknown display type" #endif static const char* iphone8_get_display_id_pull(uint32_t id) { switch (id) { case TRISTATE_PULLDN: return "pd"; case TRISTATE_FLOAT: return "op"; case TRISTATE_PULLUP: return "pu"; default: return "?"; } } static uint32_t iphone8_get_display_type(void) { static bool display_id_valid = false; static uint32_t display_id; uint32_t prox; uint32_t board_rev = iphone8_get_board_rev(); uint32_t id0, id1; if (!display_id_valid) { // for now, all proto hardware will have D520/D620. if (target_config_ap()) { // Display types for form-factor devices are determined // by the board id and rev and the PROX_SELECT GPIO. if (board_rev < BOARD_REV_AP_PROTO2) { display_id = IPHONE8_DISPLAY_ID_DEFAULT_P1; dprintf(DEBUG_INFO, "Display ID: 0x%x\n", display_id); } else { prox = iphone8_read_tristate(GPIO_PROX_SELECT); // PROX_SELECT must be pulled up (analog prox) or // floating (Doppler prox). It cannot be pulled down. ASSERT(prox != TRISTATE_PULLDN); display_id = IPHONE8_DISPLAY_ID_DEFAULT; if (prox == TRISTATE_FLOAT) { display_id |= IPHONE8_DISPLAY_ID_TOF_PROX; } dprintf(DEBUG_INFO, "Display ID: 0x%x (prox=%s)\n", display_id, iphone8_get_display_id_pull(prox)); } } else { id0 = iphone8_read_tristate(GPIO_DISPLAY_ID0); id1 = iphone8_read_tristate(GPIO_DISPLAY_ID1); display_id = (id1 << 4) | id0; dprintf(DEBUG_INFO, "Display ID: 0x%x (id1/id0=%s/%s)\n", display_id, iphone8_get_display_id_pull(id1), iphone8_get_display_id_pull(id0)); switch (display_id) { // No display is always supported case IPHONE8_DISPLAY_ID_EMPTY: display_id = IPHONE8_DISPLAY_ID_DEFAULT; break; #if TARGET_DISPLAY_D520 // D500 and D520 displays are only supported on targets that support D520 (N71, basically) case IPHONE8_DISPLAY_ID_N71_P1: case IPHONE8_DISPLAY_ID_N71_P1_MUON: case IPHONE8_DISPLAY_ID_N71: break; #elif TARGET_DISPLAY_D620 // D600 and D620 displays are only supported on targets that support D620 (N66, basically) case IPHONE8_DISPLAY_ID_N66_P1: case IPHONE8_DISPLAY_ID_N66: break; #endif default: panic("unsupported display ID 0x%x (id1/id0=%s/%s)", display_id, iphone8_get_display_id_pull(id1), iphone8_get_display_id_pull(id0)); } } display_id_valid = true; } return display_id; } int target_get_boot_battery_capacity(void) { int temp=0; #if WITH_HW_GASGAUGE if ( gasgauge_read_temperature(&temp) != 0 ) temp=0; // defensive #endif const uint32_t charge_current=power_get_available_charge_current(); if ( temp>500 && charge_current>500 ) return 0; // rely on SOC1 clear only return 50; // @see rdar://16587240 } int target_precharge_gg_flag_mask(void) { #if (PRODUCT_IBSS || PRODUCT_LLB) return kHDQRegFlagsMaskSOC1; // not available in iBSS or LLB (env is not there) #else static int gg_flag_mask=0; if ( gg_flag_mask==0 ) { const char *boot_args = env_get("boot-args"); if ( boot_args == NULL ) { // nothing to do... } else { char *arg_str= strstr(boot_args, "precharge-gg-flag-mask="); if ( arg_str != NULL ) { while ( *arg_str!='=' ) arg_str++; gg_flag_mask=strtoul( arg_str+1, NULL, 0 ); if ( gg_flag_mask==0 ) gg_flag_mask=kHDQRegFlagsMaskSOC1; } } } return gg_flag_mask; #endif } void target_early_init(void) { } void target_late_init(void) { iphone8_get_board_rev(); if (target_config_ap() && iphone8_get_board_rev() < BOARD_REV_AP_PROTO2) { dprintf(DEBUG_INFO, "Proto1 is deprecated\n"); platform_not_supported(); } if (target_config_dev() && iphone8_get_board_rev() < BOARD_REV_DEV3) { dprintf(DEBUG_INFO, "Dev1 and Dev2 are deprecated\n"); platform_not_supported(); } power_set_gpio(GPIO_PMU_NAND_LOW_POWER_MODE, 1, 1); } bool iphone8_use_stockholm_gpio(void) { #if SUB_TARGET_N71 if (target_config_ap() && iphone8_get_board_rev() < BOARD_REV_AP_PROTO2) return true; #endif return false; } void target_init(void) { uint32_t board_rev = iphone8_get_board_rev(); #if WITH_HW_FLASH_NOR flash_nor_init(SPI_NOR0); #endif dprintf(DEBUG_INFO, "board rev 0x%x (raw 0x%x)\n", board_rev, board_rev ^ 0xf); iphone8_get_display_type(); // All devboards and N71 Proto1 use a GPIO to enable Stockholm #if (PRODUCT_IBSS || PRODUCT_LLB) bool use_stockholm_gpio = iphone8_use_stockholm_gpio(); if (use_stockholm_gpio) { static const uint32_t fixup_list[] = { GPIO_ID(151), CFG_IN | PULL_DOWN | SLOW_SLEW, // 151 : GPIO[42] -> AP_TO_STOCKHOLM_EN UINT32_MAX, UINT32_MAX }; dprintf(DEBUG_INFO, "Fixing up GPIOs for DEV/pre-PROTO2 devices\n"); gpio_fixup_pinconfig(fixup_list); } if(target_config_dev() || iphone8_get_board_rev() < BOARD_REV_AP_EVT_MD) { /* GPIO 42 is OFF for pre-EVT-MD revisions */ static const uint32_t fixup_list[] = { GPIO_ID(151), CFG_OUT_0 | SLOW_SLEW, // 151 : GPIO[42] (controls new external Orb LDO, replacement of LDO8) UINT32_MAX, UINT32_MAX }; dprintf(DEBUG_INFO, "Disabling LDO via GPIO42\n"); gpio_fixup_pinconfig(fixup_list); } else { /* EVT-MD and Future will turn off LDO8 */ #if WITH_HW_POWER int pmu_set_data(int dev, uint16_t reg, uint8_t byte, bool do_confirm); // in addition we need to disable LDO8 now that no one is using it [N71/N66] turn off LDO8 for EVT-MD int rc=pmu_set_data(0, 0x0310, 0 , 1); if ( rc<0 ) dprintf(DEBUG_INFO, "cannot change kD2255_PWRONOFF_LDO8_EN (%d)\n", rc); #endif } #if SUB_TARGET_N66 || SUB_TARGET_N66M if(target_config_ap() && iphone8_get_board_rev() < BOARD_REV_AP_DVT_N66) { /* N66 IO Spreadsheet v27a (for N66 DVT and older only) */ static const uint32_t fixup_list[] = { GPIO_ID(41), CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, GPIO_ID(42), CFG_FUNC0 | PULL_DOWN | DRIVE_X4 | SLOW_SLEW, UINT32_MAX, UINT32_MAX }; dprintf(DEBUG_INFO, "Applying SPI2 workaround from v27a\n"); gpio_fixup_pinconfig(fixup_list); } #endif #endif } void target_quiesce_hardware(void) { } void target_poweroff(void) { } int target_bootprep(enum boot_target target) { return 0; } bool target_should_recover(void) { return platform_get_request_dfu2() && power_has_usb(); } bool target_should_poweron(bool *cold_button_boot) { #if WITH_HW_POWER if (power_get_boot_flag() == kPowerBootFlagColdButton) *cold_button_boot = true; #else *cold_button_boot = false; #endif // WITH_HW_POWER return !*cold_button_boot || platform_get_request_dfu1(); } bool target_should_poweroff(bool at_boot) { return platform_get_request_dfu1() && (!at_boot || !power_has_usb()); } void * target_get_display_configuration(void) { #if (APPLICATION_IBOOT && (PRODUCT_IBOOT || PRODUCT_IBEC)) return ((void *)(&display_panel_configurations)); #else return NULL; #endif } #if WITH_ENV void target_setup_default_environment(void) { // boot-device is set in platform's init.c env_set("display-color-space","RGB888", 0); #if TARGET_DISPLAY_D520 env_set("display-timing", "D520", 0); env_set("adbe-tunables", "D520", 0); env_set("adfe-tunables", "D520", 0); #elif TARGET_DISPLAY_D620 env_set("display-timing", "D620", 0); env_set("adbe-tunables", "D620", 0); env_set("adfe-tunables", "D620", 0); #endif } #endif #if WITH_HW_CHESTNUT uint8_t target_get_lcm_ldos(void) { return (DISPLAY_PMU_LDO(0) | DISPLAY_PMU_LDO(1)); } #endif #if WITH_HW_LM3534 // Do we use the legacy LM3534 (Meson) backlight, or the POR LM3539 (Muon) one? static bool iphone8_use_lm3534(void) { if (target_config_dev()) { switch (iphone8_get_display_type()) { case IPHONE8_DISPLAY_ID_N66_P1: case IPHONE8_DISPLAY_ID_N71_P1: // LM3534 return true; default: // LM3539 return false; } } else { if (iphone8_get_board_rev() < BOARD_REV_AP_EVT) { return true; } else { return false; } } } static void iphone8_get_backlight_i2c_address(uint32_t oid __unused, void *arg __unused, void *data) { uint32_t *resptr = (uint32_t *)data; if (iphone8_use_lm3534()) { *resptr = 0xc6; } else { *resptr = 0xc4; } } uint8_t target_lm3534_gpr(uint32_t ctlr) { // auto mode, ramp disable, chip enable uint8_t gpr = (1 << 4) | (1 << 1) | (1 << 0); return gpr; } #endif #if WITH_DEVICETREE int target_update_device_tree(void) { #if WITH_HW_DISPLAY_PINOT DTNode *disp0_node, *backlight_node; #endif DTNode *node; uint32_t propSize; char *propName; void *propData; // Start with hacks for prototypes and devboard, POR stuff is below the hacks if (FindNode(0, "arm-io/uart3/stockholm", &node)) { propName = "function-enable"; if (FindProperty(node, &propName, &propData, &propSize)) { char *propName_gpio; void *propData_gpio; uint32_t propSize_gpio; propName_gpio = "function-enable-gpio"; if (FindProperty(node, &propName_gpio, &propData_gpio, &propSize_gpio)) { bool use_stockholm_gpio = iphone8_use_stockholm_gpio(); if (use_stockholm_gpio) { // Fixup AP_TO_STOCKHOLM_EN for older boards. propName[0] = '~'; propName_gpio[15] = 0; } else { propName_gpio[0] = '~'; } } } } // GPIO[42] is an additional enable for the rear camera's AVDD LDO on some // configs of Proto2 and newer. On Proto1 it was the stockholm enable GPIO // // // Additionally, this GPIO is repurposed for a DOE () // For this DOE, we remove this function from the camera as well, // and drive GPIO42 high at boot (see target_init()) if (target_config_dev() || iphone8_get_board_rev() < BOARD_REV_AP_PROTO2) { if (FindNode(0, "arm-io/isp", &node)) { propName = "function-cam_avdd_gpio"; if (FindProperty(node, &propName, &propData, &propSize)) { propName[0] = '~'; } } } /* Based on , BOARD_REV_AP_PROTO2 needs to keep function-cam_avdd_gpio */ if(target_config_ap() && (iphone8_get_board_rev() == BOARD_REV_AP_PROTO2 || iphone8_get_board_rev() == BOARD_REV_AP_EVT)) { if (FindNode(0, "arm-io/isp", &node)) { propName = "function-cam_avdd_gpio"; if (FindProperty(node, &propName, &propData, &propSize)) { // [0-7]: String // [8-11]: GPIO number // [12-15]: GPIO pin setting ((uint8_t*)propData)[8] = 151; } } } #if TARGET_DISPLAY_D520 // This mess is dictated by Update Merge Personalities for N71 // See also Implement compatible field updates for N66 doppler prox // See also XXX new radar here if (FindNode(0, "arm-io/spi2/multi-touch", &node)) { uint32_t display_type = iphone8_get_display_type(); propName = "compatible"; if (FindProperty(node, &propName, &propData, &propSize)) { if (display_type == IPHONE8_DISPLAY_ID_N71_P1) { strlcpy(propData, "multi-touch,t162", propSize); } else if (display_type == IPHONE8_DISPLAY_ID_N71_P1_MUON) { strlcpy(propData, "multi-touch,t162", propSize); } else if (display_type == IPHONE8_DISPLAY_ID_N71) { strlcpy(propData, "multi-touch,n71", propSize); } else if (display_type == IPHONE8_DISPLAY_ID_N71_TOF_PROX) { strlcpy(propData, "multi-touch,n71,2", propSize); } else { panic("Unknown/unsupported display 0x%x", display_type); } } } #endif #if TARGET_DISPLAY_D620 // Implement compatible field updates for N66 doppler prox if (FindNode(0, "arm-io/spi2/multi-touch", &node)) { uint32_t display_type = iphone8_get_display_type(); propName = "compatible"; if (FindProperty(node, &propName, &propData, &propSize)) { if (display_type == IPHONE8_DISPLAY_ID_N66_P1) { strlcpy(propData, "multi-touch,n66-p1", propSize); } else if (display_type == IPHONE8_DISPLAY_ID_N66) { strlcpy(propData, "multi-touch,n66", propSize); } else if (display_type == IPHONE8_DISPLAY_ID_N66_TOF_PROX) { strlcpy(propData, "multi-touch,n66,2", propSize); } else { panic("Unknown/unsupported display 0x%x", display_type); } } } #endif if (iphone8_use_lm3534()) { if (dt_find_node(0, "arm-io/i2c0/lm3539", &node)) { if (dt_has_prop(node, "reg-lm3534")) { dt_remove_prop(node, "reg"); dt_remove_prop(node, "compatible"); dt_rename_prop(node, "reg-lm3534", "reg"); dt_rename_prop(node, "compatible-lm3534", "compatible"); dt_set_prop_str(node, "name", "lm3534"); } } #if SUB_TARGET_N66 || SUB_TARGET_N66M if (dt_find_node(0, "arm-io/i2c1/lm3539-1", &node)) { if (dt_has_prop(node, "reg-lm3534")) { dt_remove_prop(node, "reg"); dt_remove_prop(node, "compatible"); dt_rename_prop(node, "reg-lm3534", "reg"); dt_rename_prop(node, "compatible-lm3534", "compatible"); dt_set_prop_str(node, "name", "lm3534-1"); } } if (dt_find_node(0, "arm-io/i2c2/lm3539-1", &node)) { if (dt_has_prop(node, "reg-lm3534")) { dt_remove_prop(node, "reg"); dt_remove_prop(node, "compatible"); dt_rename_prop(node, "reg-lm3534", "reg"); dt_rename_prop(node, "compatible-lm3534", "compatible"); dt_set_prop_str(node, "name", "lm3534-1"); } } #endif } // POR stuff below #if WITH_HW_DISPLAY_PINOT // Find the DISP0 (display-subsystem 0) node FindNode(0, "arm-io/disp0", &disp0_node); if (FindNode(0, "arm-io/mipi-dsim/lcd", &node)) { extern int pinot_update_device_tree(DTNode *pinot_node, DTNode *clcd_node, DTNode *backlight_node); FindNode(0, "backlight", &backlight_node); pinot_update_device_tree(node, disp0_node, backlight_node); } #endif #if WITH_HW_MIPI_DSIM // Find the mipi node if (FindNode(0, "arm-io/mipi-dsim", &node)) { extern int mipi_update_device_tree(DTNode *mipi_node); mipi_update_device_tree(node); } #endif // Update the speaker calibration data if (FindNode(0, "arm-io/i2c1/audio-speaker", &node)) { propName = "speaker-rdc"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('SRdc', propData, propSize); } propName = "speaker-calib"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('SpCl', propData, propSize); } propName = "speaker-config"; if (FindProperty(node, &propName, &propData, &propSize)) { /* VBCA Value: 0x00000009 0x0000000A 0x00000005 0x00000009 0x00000001 */ uint8_t vbca[20]; if (syscfgCopyDataForTag('VBCA', vbca, sizeof(vbca)) == sizeof(vbca)) { ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | ( (vbca[4]) & 0x1f); // Spkr VPBR ((uint8_t *)propData)[16] = vbca[0]; // Spkr VBST } } propName = "acoustic-trim-gains"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('ATGa', propData, propSize); } } if (FindNode(0, "arm-io/i2c1/audio-actuator", &node)) { propName = "actuator-calibration"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('TCal', propData, propSize); } propName = "speaker-config"; if (FindProperty(node, &propName, &propData, &propSize)) { /* VBCA Value: 0x00000009 0x0000000A 0x00000005 0x00000009 0x00000001 */ uint8_t vbca[20]; if (syscfgCopyDataForTag('VBCA', vbca, sizeof(vbca)) == sizeof(vbca)) { ((uint8_t *)propData)[12] = (((uint8_t *)propData)[12] & ~0x1f) | (vbca[12] & 0x1f); // Arc VPBR ((uint8_t *)propData)[16] = vbca[8]; // Arc VBST } } } // Update the codec with acoustic transducer scale data if (FindNode(0, "arm-io/spi1/audio-codec", &node)) { propName = "acoustic-trim-gains"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('ATGa', propData, propSize); } if (target_config_dev() || iphone8_get_board_rev() < BOARD_REV_AP_EVT) { // For DEV and pre-EVT AP, switch in the old device tree properties if (dt_remove_prop(node, "smic-mic")) { dt_rename_prop(node, "smic-mic-preevt", "smic-mic"); } if (dt_remove_prop(node, "lmic-mic")) { dt_rename_prop(node, "lmic-mic-preevt", "lmic-mic"); } if (dt_remove_prop(node, "smic-micbias")) { dt_rename_prop(node, "smic-micbias-preevt", "smic-micbias"); } if (dt_remove_prop(node, "lmic-micbias")) { dt_rename_prop(node, "lmic-micbias-preevt", "lmic-micbias"); } } else { // For EVT+ AP, delete pre-evt device tree properties dt_remove_prop(node, "smic-mic-preevt"); dt_remove_prop(node, "lmic-mic-preevt"); dt_remove_prop(node, "smic-micbias-preevt"); dt_remove_prop(node, "lmic-micbias-preevt"); } } // Update the als calibration data if (FindNode(0, "arm-io/i2c2/als", &node)) { propName = "alsCalibration"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('LSCI', propData, propSize); } } // Update the backlight calibration data if (FindNode(0, "backlight", &node)) { propName = "backlight-calibration"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('BLCl', propData, propSize); } } // Update the compass calibration data if (FindNode(0, "arm-io/aop/iop-aop-nub/compass", &node)) { propName = "compass-calibration"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('CPAS', propData, propSize); } propName = "compass-orientation"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('CRot', propData, propSize); } } // Update the gyro calibration data if (FindNode(0, "arm-io/aop/iop-aop-nub/gyro", &node)) { propName = "gyro-orientation"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('GRot', propData, propSize); } propName = "gyro-sensitivity-calibration"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('GSCl', propData, propSize); } propName = "gyro-temp-table"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('GYTT', propData, propSize); } propName = "gyro-interrupt-calibration"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('GICl', propData, propSize); } } // Update accelerometer calibration data if (FindNode(0, "arm-io/aop/iop-aop-nub/accel", &node)) { propName = "accel-orientation"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('ARot', propData, propSize); } propName = "low-temp-accel-offset"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('LTAO', propData, propSize); } propName = "accel-sensitivity-calibration"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('ASCl', propData, propSize); } propName = "accel-interrupt-calibration"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('AICl', propData, propSize); } } // Update pressure sensor calibration data if (FindNode(0, "arm-io/aop/iop-aop-nub/pressure", &node)) { propName = "pressure-offset-calibration"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('SPPO', propData, propSize); } } // Update prox calibration data if (FindNode(0, "arm-io/spi2/multi-touch", &node)) { propName = "prox-calibration"; if (FindProperty(node, &propName, &propData, &propSize)) syscfgCopyDataForTag('PxCl', propData, propSize); propName = "orb-gap-cal"; if (FindProperty(node, &propName, &propData, &propSize)) syscfgCopyDataForTag('OrbG', propData, propSize); propName = "orb-accel-cal"; if (FindProperty(node, &propName, &propData, &propSize)) syscfgCopyDataForTag('OICo', propData, propSize); propName = "orb-force-cal"; if (FindProperty(node, &propName, &propData, &propSize)) syscfgCopyDataForTag('OFCl', propData, propSize); propName = "orb-dynamic-accel-cal"; if (FindProperty(node, &propName, &propData, &propSize)) syscfgCopyDataForTag('FDAC', propData, propSize); } // Stockholm calibration if (FindNode(0, "arm-io/uart3/stockholm", &node)) { propName = "calibration"; if (FindProperty(node, &propName, &propData, &propSize)) syscfgCopyDataForTag('NFCl', propData, propSize); } // Update the X162 calibration data if (FindNode(0, "arm-io/spi3/mesa", &node)) { propName = "calibration-blob"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('FSCl', propData, propSize); } propName = "modulation-ratio"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('NvMR', propData, propSize); } } #if SUB_TARGET_N66 || SUB_TARGET_N66M // Update rear camera tilt and rotation data if (FindNode(0, "arm-io/isp", &node)) { propName = "back-camera-tilt-and-rotation"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('BCTR', propData, propSize); } } #endif // Update cover glass type if (FindNode(0, "product", &node)) { propName = "cover-glass"; if (FindProperty(node, &propName, &propData, &propSize)) { syscfgCopyDataForTag('CGSp', propData, propSize); } } // Update charger calibration data if (FindNode(0, "charger", &node)) { propName = "usb-input-limit-calibration"; if (FindProperty(node, &propName, &propData, &propSize)) syscfgCopyDataForTag('CBAT', propData, propSize); } // Update Vibe calibration data if (FindNode(0, "arm-io/i2c1/vib-pwm", &node)) { propName = "calibration-data"; if (FindProperty(node, &propName, &propData, &propSize)) { const uint32_t count=syscfgCopyDataForTag('VbCl', propData, propSize); if ( count!=propSize ) *((uint32_t*)propData)=0x00a46d0d; } } #if WITH_HW_DISPLAY_PMU display_pmu_update_device_tree("arm-io/i2c0/display-pmu"); #endif return 0; } #endif // WITH_DEVICETREE #if WITH_PAINT // The default background is expected to to be black and the artwork is expected // to be white. This arrangement will be inverted depending upon the cover glass // color of the device. // Sample DClr_override values for testing devices without DClr syscfg entries (enclosure/cover glass): // gray/black: setenv DClr_override 00020000B9B5B4003C3B3B0000000000 // gold/white: setenv DClr_override 00020000B5CCE100E3E4E10000000000 // silver/white: setenv DClr_override 00020000D8D9D700E3E4E10000000000 static color_policy_invert_t target_cover_glass_color_table[] = { { RGB( 39, 39, 40), false }, // Blacker - black background, white logo { RGB(228, 231, 232), true }, // Whiter - white background, black logo { RGB( 59, 59, 60), false }, // Black - black background, white logo { RGB(225, 228, 227), true }, // White - white background, black logo }; color_policy_t *target_color_map_init(enum colorspace cs, color_policy_t *color_policy) { // Must have a color policy structure passed in. if (color_policy == NULL) goto fail; // We only support the RGB888 colorspace. if (cs != CS_RGB888) goto fail; color_policy->policy_type = COLOR_MAP_POLICY_INVERT; color_policy->color_table = (void *)target_cover_glass_color_table; color_policy->color_count = ARRAY_SIZE(target_cover_glass_color_table); color_policy->map_color = NULL; // Use standard remapper return color_policy; fail: return NULL; } #endif // WITH_PAINT #if !WITH_HW_POWER bool power_needs_precharge(void) { return false; } void power_cancel_buttonwait(void) { } bool power_do_chargetrap(void) { return false; } bool power_is_suspended(void) { return false; } void power_will_resume(void) { } bool power_has_usb(void) { return false; } int power_read_dock_id(unsigned *id) { return -1; } bool power_get_diags_dock(void) { return false; } uint32_t power_get_boot_battery_level(void) { return 0; } int power_get_nvram(uint8_t key, uint8_t *data) { return -1; } int power_set_nvram(uint8_t key, uint8_t data) { return -1; } int power_set_soc_voltage(unsigned mv, int override) { return -1; } bool force_usb_power = false; void power_set_usb_state(bool configured, bool suspended) { } int power_backlight_enable(uint32_t backlight_level) { return 0; } #endif /* ! WITH_HW_POWER */