Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:00

0001 /*
0002  * Copyright 2019-2022 NXP
0003  * All rights reserved.
0004  *
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_lcdifv2.h"
0010 
0011 /*******************************************************************************
0012  * Definitions
0013  ******************************************************************************/
0014 
0015 /* Component ID definition, used by tools. */
0016 #ifndef FSL_COMPONENT_ID
0017 #define FSL_COMPONENT_ID "platform.drivers.lcdifv2"
0018 #endif
0019 
0020 #define LCDIFV2_LUT_MEM(base) \
0021     ((volatile uint32_t *)(((uint32_t)(base)) + (uint32_t)FSL_FEATURE_LCDIFV2_CLUT_RAM_OFFSET))
0022 
0023 /*******************************************************************************
0024  * Prototypes
0025  ******************************************************************************/
0026 
0027 /*!
0028  * @brief Get instance number for LCDIF module.
0029  *
0030  * @param base LCDIF peripheral base address
0031  */
0032 static uint32_t LCDIFV2_GetInstance(const LCDIFV2_Type *base);
0033 
0034 /*!
0035  * @brief Reset register value to default status.
0036  *
0037  * @param base LCDIF peripheral base address
0038  */
0039 static void LCDIFV2_ResetRegister(LCDIFV2_Type *base);
0040 
0041 /*******************************************************************************
0042  * Variables
0043  ******************************************************************************/
0044 
0045 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0046 /*! @brief Pointers to LCDIF clock for each instance. */
0047 static const clock_ip_name_t s_lcdifv2Clocks[] = LCDIFV2_CLOCKS;
0048 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0049 
0050 /*******************************************************************************
0051  * Codes
0052  ******************************************************************************/
0053 static uint32_t LCDIFV2_GetInstance(const LCDIFV2_Type *base)
0054 {
0055     static LCDIFV2_Type *const s_lcdifv2Bases[] = LCDIFV2_BASE_PTRS;
0056 
0057     uint32_t instance;
0058 
0059     /* Find the instance index from base address mappings. */
0060     for (instance = 0; instance < ARRAY_SIZE(s_lcdifv2Bases); instance++)
0061     {
0062         if (s_lcdifv2Bases[instance] == base)
0063         {
0064             break;
0065         }
0066     }
0067 
0068     assert(instance < ARRAY_SIZE(s_lcdifv2Bases));
0069 
0070     return instance;
0071 }
0072 
0073 static void LCDIFV2_ResetRegister(LCDIFV2_Type *base)
0074 {
0075     uint32_t i;
0076 
0077     base->DISP_PARA         = 0U;
0078     base->CTRL              = 0x80000000U;
0079     base->DISP_SIZE         = 0U;
0080     base->HSYN_PARA         = 0x00C01803U;
0081     base->VSYN_PARA         = 0x00C01803U;
0082     base->INT[0].INT_ENABLE = 0U;
0083     base->INT[1].INT_ENABLE = 0U;
0084     base->PDI_PARA          = 0x00001000U;
0085 
0086     for (i = 0; i < (uint32_t)LCDIFV2_LAYER_COUNT; i++)
0087     {
0088         base->LAYER[i].CTRLDESCL5 = 0U;
0089         base->LAYER[i].CTRLDESCL1 = 0U;
0090         base->LAYER[i].CTRLDESCL2 = 0U;
0091         base->LAYER[i].CTRLDESCL3 = 0U;
0092         base->LAYER[i].CTRLDESCL4 = 0U;
0093         base->LAYER[i].CTRLDESCL6 = 0U;
0094     }
0095 
0096     for (i = 0; i < (uint32_t)LCDIFV2_LAYER_CSC_COUNT; i++)
0097     {
0098         base->LAYER[i].CSC_COEF0 = 0x04000000U;
0099         base->LAYER[i].CSC_COEF1 = 0x01230208U;
0100         base->LAYER[i].CSC_COEF2 = 0x076B079CU;
0101     }
0102 
0103     /* Clear interrupt status. */
0104     base->INT[0].INT_STATUS = 0xFFFFFFFFU;
0105     base->INT[1].INT_STATUS = 0xFFFFFFFFU;
0106 }
0107 
0108 /*!
0109  * brief Initializes the LCDIF v2.
0110  *
0111  * This function ungates the LCDIF v2 clock and release the peripheral reset.
0112  *
0113  * param base LCDIF v2 peripheral base address.
0114  */
0115 void LCDIFV2_Init(LCDIFV2_Type *base)
0116 {
0117 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && (0 != FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
0118     uint32_t instance = LCDIFV2_GetInstance(base);
0119     /* Enable the clock. */
0120     CLOCK_EnableClock(s_lcdifv2Clocks[instance]);
0121 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0122 
0123     LCDIFV2_ResetRegister(base);
0124 
0125     /* Out of reset. */
0126     base->CTRL = 0U;
0127 }
0128 
0129 /*!
0130  * brief Deinitializes the LCDIF peripheral.
0131  *
0132  * param base LCDIF peripheral base address.
0133  */
0134 void LCDIFV2_Deinit(LCDIFV2_Type *base)
0135 {
0136     LCDIFV2_ResetRegister(base);
0137 
0138 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && (0 != FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
0139     uint32_t instance = LCDIFV2_GetInstance(base);
0140     /* Disable the clock. */
0141     CLOCK_DisableClock(s_lcdifv2Clocks[instance]);
0142 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0143 }
0144 
0145 /*!
0146  * brief Reset the LCDIF v2.
0147  *
0148  * param base LCDIF peripheral base address.
0149  */
0150 void LCDIFV2_Reset(LCDIFV2_Type *base)
0151 {
0152     LCDIFV2_ResetRegister(base);
0153 
0154     /* Release and ready to work. */
0155     base->CTRL = 0U;
0156 }
0157 
0158 /*!
0159  * brief Gets the LCDIF display default configuration structure.
0160  *
0161  * param config Pointer to the LCDIF configuration structure.
0162  */
0163 void LCDIFV2_DisplayGetDefaultConfig(lcdifv2_display_config_t *config)
0164 {
0165     assert(NULL != config);
0166 
0167     config->panelWidth    = 0U;
0168     config->panelHeight   = 0U;
0169     config->hsw           = 3U;
0170     config->hfp           = 3U;
0171     config->hbp           = 3U;
0172     config->vsw           = 3U;
0173     config->vfp           = 3U;
0174     config->vbp           = 3U;
0175     config->polarityFlags = (uint32_t)kLCDIFV2_VsyncActiveHigh | (uint32_t)kLCDIFV2_HsyncActiveHigh |
0176                             (uint32_t)kLCDIFV2_DataEnableActiveHigh | (uint32_t)kLCDIFV2_DriveDataOnRisingClkEdge |
0177                             (uint32_t)kLCDIFV2_DataActiveHigh;
0178     config->lineOrder = kLCDIFV2_LineOrderRGB;
0179 }
0180 
0181 /*!
0182  * brief Set the LCDIF v2 display configurations.
0183  *
0184  * param base LCDIF peripheral base address.
0185  * param config Pointer to the LCDIF configuration structure.
0186  */
0187 void LCDIFV2_SetDisplayConfig(LCDIFV2_Type *base, const lcdifv2_display_config_t *config)
0188 {
0189     assert(NULL != config);
0190 
0191     /* Configure the parameters. */
0192     base->DISP_SIZE = ((uint32_t)config->panelWidth << LCDIFV2_DISP_SIZE_DELTA_X_SHIFT) |
0193                       ((uint32_t)config->panelHeight << LCDIFV2_DISP_SIZE_DELTA_Y_SHIFT);
0194 
0195     base->HSYN_PARA = ((uint32_t)config->hsw << LCDIFV2_HSYN_PARA_PW_H_SHIFT) |
0196                       ((uint32_t)config->hbp << LCDIFV2_HSYN_PARA_BP_H_SHIFT) |
0197                       ((uint32_t)config->hfp << LCDIFV2_HSYN_PARA_FP_H_SHIFT);
0198 
0199     base->VSYN_PARA = ((uint32_t)config->vsw << LCDIFV2_VSYN_PARA_PW_V_SHIFT) |
0200                       ((uint32_t)config->vbp << LCDIFV2_VSYN_PARA_BP_V_SHIFT) |
0201                       ((uint32_t)config->vfp << LCDIFV2_VSYN_PARA_FP_V_SHIFT);
0202 
0203     base->DISP_PARA = LCDIFV2_DISP_PARA_LINE_PATTERN((uint32_t)config->lineOrder);
0204 
0205     base->CTRL = (uint32_t)(config->polarityFlags);
0206 }
0207 
0208 /*!
0209  * brief Set the color space conversion mode.
0210  *
0211  * Supports YUV2RGB and YCbCr2RGB.
0212  *
0213  * param base LCDIFv2 peripheral base address.
0214  * param layerIndex Index of the layer.
0215  * param mode The conversion mode.
0216  */
0217 void LCDIFV2_SetCscMode(LCDIFV2_Type *base, uint8_t layerIndex, lcdifv2_csc_mode_t mode)
0218 {
0219     assert(layerIndex < (uint32_t)LCDIFV2_LAYER_CSC_COUNT);
0220 
0221     /*
0222      * The equations used for Colorspace conversion are:
0223      *
0224      * R = C0*(Y+Y_OFFSET)                   + C1(V+UV_OFFSET)
0225      * G = C0*(Y+Y_OFFSET) + C3(U+UV_OFFSET) + C2(V+UV_OFFSET)
0226      * B = C0*(Y+Y_OFFSET) + C4(U+UV_OFFSET)
0227      */
0228 
0229     if (kLCDIFV2_CscYUV2RGB == mode)
0230     {
0231         base->LAYER[layerIndex].CSC_COEF0 = LCDIFV2_CSC_COEF0_ENABLE_MASK | LCDIFV2_CSC_COEF0_C0(0x100U) /* 1.00. */
0232                                             | LCDIFV2_CSC_COEF0_Y_OFFSET(0x0U)                           /* 0. */
0233                                             | LCDIFV2_CSC_COEF0_UV_OFFSET(0x0U);                         /* 0. */
0234 
0235         base->LAYER[layerIndex].CSC_COEF1 = LCDIFV2_CSC_COEF1_C1(0x0123U)    /* 1.140. */
0236                                             | LCDIFV2_CSC_COEF1_C4(0x0208U); /* 2.032. */
0237         base->LAYER[layerIndex].CSC_COEF2 = LCDIFV2_CSC_COEF2_C2(0x076BU)    /* -0.851. */
0238                                             | LCDIFV2_CSC_COEF2_C3(0x079BU); /* -0.394. */
0239     }
0240     else if (kLCDIFV2_CscYCbCr2RGB == mode)
0241     {
0242         base->LAYER[layerIndex].CSC_COEF0 = LCDIFV2_CSC_COEF0_ENABLE_MASK | LCDIFV2_CSC_COEF0_YCBCR_MODE_MASK |
0243                                             LCDIFV2_CSC_COEF0_C0(0x12AU)           /* 1.164. */
0244                                             | LCDIFV2_CSC_COEF0_Y_OFFSET(0x1F0U)   /* -16. */
0245                                             | LCDIFV2_CSC_COEF0_UV_OFFSET(0x180U); /* -128. */
0246         base->LAYER[layerIndex].CSC_COEF1 = LCDIFV2_CSC_COEF1_C1(0x0198U)          /* 1.596. */
0247                                             | LCDIFV2_CSC_COEF1_C4(0x0204U);       /* 2.017. */
0248         base->LAYER[layerIndex].CSC_COEF2 = LCDIFV2_CSC_COEF2_C2(0x0730U)          /* -0.813. */
0249                                             | LCDIFV2_CSC_COEF2_C3(0x079CU);       /* -0.392. */
0250     }
0251     else
0252     {
0253         base->LAYER[layerIndex].CSC_COEF0 = 0U;
0254         base->LAYER[layerIndex].CSC_COEF1 = 0U;
0255         base->LAYER[layerIndex].CSC_COEF2 = 0U;
0256     }
0257 }
0258 
0259 /*!
0260  * brief Set the layer source buffer configuration.
0261  *
0262  * param base LCDIFv2 peripheral base address.
0263  * param layerIndex Layer layerIndex.
0264  * param config Pointer to the configuration.
0265  */
0266 void LCDIFV2_SetLayerBufferConfig(LCDIFV2_Type *base, uint8_t layerIndex, const lcdifv2_buffer_config_t *config)
0267 {
0268     assert(NULL != config);
0269     uint32_t reg;
0270 
0271     base->LAYER[layerIndex].CTRLDESCL3 = config->strideBytes;
0272 
0273     reg = base->LAYER[layerIndex].CTRLDESCL5;
0274     reg = (reg & ~(LCDIFV2_CTRLDESCL5_BPP_MASK | LCDIFV2_CTRLDESCL5_YUV_FORMAT_MASK)) | (uint32_t)config->pixelFormat;
0275 
0276     if (0U == (reg & LCDIFV2_CTRLDESCL5_AB_MODE_MASK))
0277     {
0278         reg |= LCDIFV2_CTRLDESCL5_SAFETY_EN_MASK;
0279     }
0280 
0281     base->LAYER[layerIndex].CTRLDESCL5 = reg;
0282 }
0283 
0284 /*!
0285  * brief Set the LUT data.
0286  *
0287  * This function sets the specific layer LUT data, if useShadowLoad is true,
0288  * call LCDIFV2_TriggerLayerShadowLoad after this function, the
0289  * LUT will be loaded to the hardware during next vertical blanking period.
0290  * If useShadowLoad is false, the LUT data is loaded to hardware directly.
0291  *
0292  * param base LCDIF v2 peripheral base address.
0293  * param layerIndex Which layer to set.
0294  * param lutData The LUT data to load.
0295  * param count Count of lutData.
0296  * retval kStatus_Success Set success.
0297  * retval kStatus_Fail Previous LUT data is not loaded to hardware yet.
0298  */
0299 status_t LCDIFV2_SetLut(
0300     LCDIFV2_Type *base, uint8_t layerIndex, const uint32_t *lutData, uint16_t count, bool useShadowLoad)
0301 {
0302     assert(count <= LCDIFV2_LUT_ENTRY_NUM);
0303 
0304     uint16_t i;
0305     status_t status;
0306 
0307     /* Previous setting is not updated. */
0308     if ((base->CLUT_LOAD & LCDIFV2_CLUT_LOAD_CLUT_UPDATE_EN_MASK) != 0U)
0309     {
0310         status = kStatus_Fail;
0311     }
0312     else
0313     {
0314         if (useShadowLoad)
0315         {
0316             base->CLUT_LOAD = LCDIFV2_CLUT_LOAD_SEL_CLUT_NUM(layerIndex) | LCDIFV2_CLUT_LOAD_CLUT_UPDATE_EN_MASK;
0317         }
0318         else
0319         {
0320             base->CLUT_LOAD = LCDIFV2_CLUT_LOAD_SEL_CLUT_NUM(layerIndex);
0321         }
0322 
0323         for (i = 0; i < count; i++)
0324         {
0325             (LCDIFV2_LUT_MEM(base))[i + (LCDIFV2_LUT_ENTRY_NUM * layerIndex)] = lutData[i];
0326         }
0327 
0328         status = kStatus_Success;
0329     }
0330 
0331     return status;
0332 }
0333 
0334 /*!
0335  * brief Set the layer alpha blend mode.
0336  *
0337  * param base LCDIFv2 peripheral base address.
0338  * param layerIndex Index of the CSC unit.
0339  * param config Pointer to the blend configuration.
0340  */
0341 void LCDIFV2_SetLayerBlendConfig(LCDIFV2_Type *base, uint8_t layerIndex, const lcdifv2_blend_config_t *config)
0342 {
0343     assert(NULL != config);
0344 
0345     uint32_t reg;
0346 
0347     reg = base->LAYER[layerIndex].CTRLDESCL5;
0348     reg &= ~(LCDIFV2_CTRLDESCL5_GLOBAL_ALPHA_MASK | LCDIFV2_CTRLDESCL5_AB_MODE_MASK |
0349              LCDIFV2_CTRLDESCL5_PD_FACTOR_MODE_MASK | LCDIFV2_CTRLDESCL5_PD_ALPHA_MODE_MASK |
0350              LCDIFV2_CTRLDESCL5_PD_COLOR_MODE_MASK | LCDIFV2_CTRLDESCL5_PD_GLOBAL_ALPHA_MODE_MASK |
0351              LCDIFV2_CTRLDESCL5_SAFETY_EN_MASK);
0352 
0353     reg |=
0354         (LCDIFV2_CTRLDESCL5_GLOBAL_ALPHA(config->globalAlpha) | LCDIFV2_CTRLDESCL5_AB_MODE(config->alphaMode) |
0355          LCDIFV2_CTRLDESCL5_PD_FACTOR_MODE(config->pdFactorMode) |
0356          LCDIFV2_CTRLDESCL5_PD_ALPHA_MODE(config->pdAlphaMode) | LCDIFV2_CTRLDESCL5_PD_COLOR_MODE(config->pdColorMode) |
0357          LCDIFV2_CTRLDESCL5_PD_GLOBAL_ALPHA_MODE(config->pdGlobalAlphaMode));
0358 
0359     if (config->alphaMode == kLCDIFV2_AlphaDisable)
0360     {
0361         reg |= LCDIFV2_CTRLDESCL5_SAFETY_EN_MASK;
0362     }
0363 
0364     base->LAYER[layerIndex].CTRLDESCL5 = reg;
0365 }
0366 
0367 /*
0368  * brief Get the blend configuration for Porter Duff blend.
0369  *
0370  * This is the basic Porter Duff blend configuration, user still could
0371  * modify the configurations after this function.
0372  *
0373  * param mode Porter Duff blend mode.
0374  * param layer The configuration for source layer or destination layer.
0375  * param config Pointer to the configuration.
0376  * retval kStatus_Success Get the configuration successfully.
0377  * retval kStatus_InvalidArgument The argument is invalid.
0378  */
0379 status_t LCDIFV2_GetPorterDuffConfig(lcdifv2_pd_blend_mode_t mode,
0380                                      lcdifv2_pd_layer_t layer,
0381                                      lcdifv2_blend_config_t *config)
0382 {
0383     static const lcdifv2_pd_factor_mode_t s_lcdifv2PdLayerFactors[][2] = {
0384         /* kLCDIFV2_PD_Src */
0385         {
0386             /* s1_s0_factor_mode. */
0387             kLCDIFV2_PD_FactorZero,
0388 
0389             /* s0_s1_factor_mode. */
0390             kLCDIFV2_PD_FactorOne,
0391         },
0392 
0393         /* kLCDIFV2_PD_Atop */
0394         {kLCDIFV2_PD_FactorInversedAlpha, kLCDIFV2_PD_FactorStraightAlpha},
0395 
0396         /* kLCDIFV2_PD_Over */
0397         {kLCDIFV2_PD_FactorInversedAlpha, kLCDIFV2_PD_FactorOne},
0398 
0399         /* kLCDIFV2_PD_In */
0400         {kLCDIFV2_PD_FactorZero, kLCDIFV2_PD_FactorStraightAlpha},
0401 
0402         /* kLCDIFV2_PD_Out */
0403         {kLCDIFV2_PD_FactorZero, kLCDIFV2_PD_FactorInversedAlpha},
0404 
0405         /* kLCDIFV2_PD_Dst */
0406         {kLCDIFV2_PD_FactorOne, kLCDIFV2_PD_FactorZero},
0407 
0408         /* kLCDIFV2_PD_DstAtop */
0409         {kLCDIFV2_PD_FactorStraightAlpha, kLCDIFV2_PD_FactorInversedAlpha},
0410 
0411         /* kLCDIFV2_PD_DstOver */
0412         {kLCDIFV2_PD_FactorOne, kLCDIFV2_PD_FactorInversedAlpha},
0413 
0414         /* kLCDIFV2_PD_DstIn */
0415         {kLCDIFV2_PD_FactorStraightAlpha, kLCDIFV2_PD_FactorZero},
0416 
0417         /* kLCDIFV2_PD_DstOut */
0418         {kLCDIFV2_PD_FactorInversedAlpha, kLCDIFV2_PD_FactorZero},
0419 
0420         /* kLCDIFV2_PD_Xor */
0421         {kLCDIFV2_PD_FactorInversedAlpha, kLCDIFV2_PD_FactorInversedAlpha},
0422 
0423         /* kLCDIFV2_PD_Clear */
0424         {
0425             kLCDIFV2_PD_FactorZero,
0426             kLCDIFV2_PD_FactorZero,
0427         },
0428     };
0429 
0430     status_t status;
0431 
0432     if ((NULL == config) || (mode >= kLCDIFV2_PD_Max) || (layer >= kLCDIFV2_PD_LayerMax))
0433     {
0434         status = kStatus_InvalidArgument;
0435     }
0436     else
0437     {
0438         config->pdAlphaMode       = kLCDIFV2_PD_AlphaStraight;
0439         config->pdColorMode       = kLCDIFV2_PD_ColorWithAlpha;
0440         config->pdGlobalAlphaMode = kLCDIFV2_PD_LocalAlpha;
0441         config->pdFactorMode      = s_lcdifv2PdLayerFactors[mode][(uint8_t)layer];
0442         config->alphaMode         = kLCDIFV2_AlphaPoterDuff;
0443 
0444         status = kStatus_Success;
0445     }
0446 
0447     return status;
0448 }
0449 
0450 /*
0451  * brief Get the global alpha values for multiple layer blend.
0452  *
0453  * When all layers use the global alpha, the relationship blended alpha
0454  * and global alpha of each layer is:
0455  *
0456  * Layer 7: ba7 = ga7
0457  * Layer 6: ba6 = ga6 * (1-ga7)
0458  * Layer 5: ba5 = ga5 * (1-ga6) * (1-ga7)
0459  * Layer 4: ba4 = ga4 * (1-ga5) * (1-ga6) * (1-ga7)
0460  * Layer 3: ba3 = ga3 * (1-ga4) * (1-ga5) * (1-ga6) * (1-ga7)
0461  * Layer 2: ba2 = ga2 * (1-ga3) * (1-ga4) * (1-ga5) * (1-ga6) * (1-ga7)
0462  * Layer 1: ba1 = ga1 * (1-ga2) * (1-ga3) * (1-ga4) * (1-ga5) * (1-ga6) * (1-ga7)
0463  * Layer 0: ba0 =   1 * (1-ga1) * (1-ga2) * (1-ga3) * (1-ga4) * (1-ga5) * (1-ga6) * (1-ga7)
0464  *
0465  * Here baN is the blended alpha of layer N, gaN is the global alpha configured to layer N.
0466  *
0467  * This function calculates the global alpha based on the blended alpha. The blendedAlpha and
0468  * globalAlpha are all arrays of size layerCount. The first layer is a background layer,
0469  * so blendedAlpha[0] is useless, globalAlpha[0] is always 255.
0470  *
0471  * param blendedAlpha The desired blended alpha value, alpha range 0~255.
0472  * param globalAlpha Calculated global alpha set to each layer register.
0473  * param layerCount Total layer count.
0474  * retval kStatus_Success Get successfully.
0475  * retval kStatus_InvalidArgument The argument is invalid.
0476  */
0477 status_t LCDIFV2_GetMultiLayerGlobalAlpha(const uint8_t blendedAlpha[], uint8_t globalAlpha[], uint8_t layerCount)
0478 {
0479     status_t status  = kStatus_Success;
0480     int16_t curLayer = (int16_t)layerCount - 1;
0481     int left         = 255;
0482     int tmpAlpha;
0483 
0484     assert((layerCount > 1U) && (layerCount <= (uint8_t)LCDIFV2_LAYER_COUNT));
0485 
0486     /*
0487      * Assume the layer counter is 7, and alpha range is 0~1, define:
0488      *
0489      *   left_7 = 1
0490      *   left_i = (1-ga_(i+1)) * ... * (1-ga7)
0491      *
0492      * Then:
0493      *   ba_i   = ga_i * left_i
0494      *   left_i = left_(i+1) - ba_i
0495      *   ga_i = ba_i / left_i
0496      *
0497      * Now change alpha range to 0~255, then:
0498      *
0499      *   ga_i   = ba_i * 255 / left_i
0500      *   left_i = left_(i+1) - ba_i
0501      */
0502 
0503     globalAlpha[0] = 255U;
0504 
0505     while (curLayer > 0)
0506     {
0507         tmpAlpha = (int)blendedAlpha[curLayer] * 255 / left;
0508         if (tmpAlpha > 255)
0509         {
0510             status = kStatus_InvalidArgument;
0511             break;
0512         }
0513 
0514         globalAlpha[curLayer] = (uint8_t)tmpAlpha;
0515         left -= (int)blendedAlpha[curLayer];
0516 
0517         if (left <= 0)
0518         {
0519             status = kStatus_InvalidArgument;
0520             break;
0521         }
0522 
0523         curLayer--;
0524     }
0525 
0526     return status;
0527 }