Symbian3/PDK/Source/GUID-6A4FE3A3-2E5D-51BB-8272-5995586291E9.dita
changeset 1 25a17d01db0c
child 3 46218c8b8afa
equal deleted inserted replaced
0:89d6a7a84779 1:25a17d01db0c
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-6A4FE3A3-2E5D-51BB-8272-5995586291E9" xml:lang="en"><title>LCD
       
    13 Extension Implementation Tutorial</title><shortdesc/><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    14 <p>This topic describes how to create an LCD Extension. </p>
       
    15 <p>The topic uses a reference board port named <filepath>template_variant</filepath> as
       
    16 an example implementation. </p>
       
    17 <section id="GUID-7DDD91D2-A69F-4940-AA58-74EB2A989E55"><title>Build environment</title> <p>In the template reference board
       
    18 port, the <filepath>.mmp</filepath> file for the LCD Extension is <filepath>...\template_variant\lcdtemplate.mmp</filepath>.
       
    19 This is one of the <codeph>PRJ_MMPFILES</codeph> referenced in the template
       
    20 variant's <filepath>bld.inf</filepath> file in the <filepath>...\template_variant\...</filepath> directory,
       
    21 and means that the LCD Extension is built as part of the Variant. </p> <p>The
       
    22 source for the driver is contained entirely within <filepath>...\template_variant\specific\lcd.cpp</filepath>. </p> <p>The
       
    23 driver is defined as a kernel extension and is loaded early in the boot sequence. </p> </section>
       
    24 <section id="GUID-FC49B296-5DFA-4C19-BEDE-F641D70E5ED9"><title>Initialization</title> <p>The driver functionality is almost
       
    25 entirely encapsulated by the <codeph>DLcdPowerHandler</codeph> class. This
       
    26 is a power handler class derived from <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita"><apiname>DPowerHandler</apiname></xref>. An
       
    27 instance of <codeph>DLcdPowerHandler</codeph> is created when the extension
       
    28 is loaded. </p> <p> <codeph>DLcdPowerHandler</codeph> is defined within the
       
    29 source file itself <filepath>...\template_variant\specific\lcd.cpp</filepath>. </p> <p>As
       
    30 the driver is a kernel extension, it must have a <codeph>DECLARE_STANDARD_EXTENSION()</codeph> statement.
       
    31 In the template port, this is implemented as follows: </p> <codeblock id="GUID-BB93E7E7-06DA-5A12-ABA1-D07AA246D6FC" xml:space="preserve">DECLARE_STANDARD_EXTENSION()
       
    32     {
       
    33     __KTRACE_OPT(KPOWER,Kern::Printf("Starting LCD power manager"));
       
    34     
       
    35     // create LCD power handler
       
    36     TInt r=KErrNoMemory;
       
    37     DLcdPowerHandler* pH=new DLcdPowerHandler;
       
    38     if (pH)
       
    39         r=pH-&gt;Create();
       
    40     
       
    41     __KTRACE_OPT(KPOWER,Kern::Printf("Returns %d",r));
       
    42     return r;
       
    43     }
       
    44 </codeblock> <p>This simply creates an instance of the <codeph>DLcdPowerHandler</codeph> class
       
    45 and then calls its <codeph>Create()</codeph> function which implements the
       
    46 display setup. This function should do the following: </p> <ul>
       
    47 <li id="GUID-4D3B36C6-C782-5B3F-8244-7FD33B9976C6"><p>map the video RAM </p> </li>
       
    48 <li id="GUID-B693BD2B-50FF-554D-AF2B-1992A472F586"><p>setup the video info
       
    49 structure </p> </li>
       
    50 <li id="GUID-1DF67FC0-90FA-5853-88C2-6DBA5C60F377"><p>install the HAL handler </p> </li>
       
    51 <li id="GUID-2B8080C4-2A9F-5AA2-B609-3DC8F5759DDE"><p>install the power handler. </p> </li>
       
    52 </ul> <p><b> Map
       
    53 the video RAM</b> </p> <p>The frame buffer is a <xref href="GUID-2A34A3DD-A7FE-34A0-B0B7-BB0A4F04B098.dita"><apiname>DPlatChunkHw</apiname></xref> object,
       
    54 and should be mapped as globally accessible, readable and writeable. It should <i>not</i> be
       
    55 mapped as writeback cached, it should be either not-cached or write-through.
       
    56 The advantage of write through is that it allows the use of the write buffer. </p> <codeblock id="GUID-148795D9-45A2-526B-A2F7-57B5B2AAC8AB" xml:space="preserve">TInt DLcdPowerHandler::Create()
       
    57     {
       
    58     ...
       
    59 
       
    60     // map the video RAM
       
    61     TInt vSize = ((TemplateAssp*)Arch::TheAsic())-&gt;VideoRamSize();
       
    62     ivRamPhys = TTemplate::VideoRamPhys();                // EXAMPLE ONLY: assume TTemplate interface class
       
    63     TInt r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC);
       
    64     if ® != KErrNone)
       
    65         return r;
       
    66  ...
       
    67 </codeblock> <p>If the frame buffer resides in main RAM and there is no restriction
       
    68 on which physical addresses may be used for it, physical RAM for the frame
       
    69 buffer should be reserved by using <xref href="GUID-3DC7B5F2-512E-3FF3-BC08-945DDE2AE680.dita#GUID-3DC7B5F2-512E-3FF3-BC08-945DDE2AE680/GUID-B506D835-505D-3D89-A840-475F291908DC"><apiname>Epoc::AllocPhysicalRam()</apiname></xref>. </p> <p>If
       
    70 the frame buffer does not reside in main RAM, there is no problem about reserving
       
    71 it. </p> <p>If the frame buffer must reside at a specific address in main
       
    72 RAM, there are two strategies available for reserving it: </p> <ul>
       
    73 <li id="GUID-29D3BF5F-442B-5912-A8B9-4F1F76C1879E"><p>If no conflicts are
       
    74 permitted between the frame buffer and memory allocations made during the
       
    75 kernel boot (for example, if the frame buffer must reside at the end of main
       
    76 memory), simply use <xref href="GUID-3DC7B5F2-512E-3FF3-BC08-945DDE2AE680.dita#GUID-3DC7B5F2-512E-3FF3-BC08-945DDE2AE680/GUID-78F136DC-023B-30AB-A1AB-34D6BC4F1B3E"><apiname>Epoc::ClaimPhysicalRam()</apiname></xref>. This function
       
    77 just marks a region of physical RAM as allocated, returning an error if any
       
    78 part of the region has already been used. </p> </li>
       
    79 <li id="GUID-F2C5ED3A-767A-58CA-BDC6-78D3C1820C80"><p>The required physical
       
    80 RAM region can be reserved in the bootstrap. The correct place to do this
       
    81 is in the implementation of the boot table function <xref href="GUID-B3F6FC45-3BF0-5F92-8325-44C705BA47AE.dita#GUID-B3F6FC45-3BF0-5F92-8325-44C705BA47AE/GUID-B3C6ACE9-A803-59D4-8EBD-314363905427">BTF_Reserve</xref> when writing platform-specific source code for the bootstrap.
       
    82 See the Bootstrap <xref href="GUID-5EB03086-A87D-5588-8927-7A7F8DB38366.dita">Port
       
    83 Implementation Tutorial</xref> for more detail and look at <filepath>...\template_variant\bootstrap\template.s</filepath> for
       
    84 a concrete example. </p> </li>
       
    85 </ul> <p>Note that all Symbian platform base ports currently create a second
       
    86 frame buffer for a secure screen. However, as platform security is not yet
       
    87 implemented, this is wasteful of RAM and should be omitted. </p> <p id="GUID-57223C8C-0381-51AC-8E8A-771434136A5C"><b> Set up the video information
       
    88 structure</b> </p> <p>The video information structure is used to define several
       
    89 aspects of the display including display size, bits per pixel and address
       
    90 of the frame buffer. This structure is the class <xref href="GUID-C4712A78-6C58-39ED-AF84-11038DB8571D.dita"><apiname>TVideoInfoV01</apiname></xref> defined
       
    91 in the header file <filepath>...\eka\include\videodriver.h</filepath> and
       
    92 exported to <filepath>...\epoc32\include</filepath>. </p> <codeblock id="GUID-0680E467-9552-5FD6-BBDE-60AE95F0B941" xml:space="preserve">TInt DLcdPowerHandler::Create()
       
    93     {
       
    94        ...
       
    95        // setup the video info structure, this will be used to remember the video settings
       
    96        iVideoInfo.iDisplayMode = KConfigLcdInitialDisplayMode;
       
    97        iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetToFirstVideoBuffer;
       
    98        iVideoInfo.iIsPalettized = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iIsPalettized;
       
    99        iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetBetweenLines;
       
   100        iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iBitsPerPixel;
       
   101 
       
   102        iVideoInfo.iSizeInPixels.iWidth = KConfigLcdWidth;
       
   103        iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight;
       
   104        iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips;
       
   105        iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips;
       
   106        iVideoInfo.iIsMono = KConfigLcdIsMono;
       
   107        iVideoInfo.iVideoAddress=(TInt)pV;
       
   108        iVideoInfo.iIsPixelOrderLandscape = KConfigLcdPixelOrderLandscape;
       
   109        iVideoInfo.iIsPixelOrderRGB = KConfigLcdPixelOrderRGB;
       
   110     ...
       
   111     }</codeblock> <p><b> Install
       
   112 the HAL handler</b> </p> <p>Control of the display is done by using the HAL,
       
   113 the Hardware Abstraction Layer. </p> <p>The <codeph>DLcdPowerHandler</codeph> class
       
   114 provides the implementation for the HAL handler for the HAL function group <xref href="GUID-7F299BFC-D8A5-3A5A-B8DA-39BF42C99DC6.dita"><apiname>EHalGroupDisplay</apiname></xref> and
       
   115 this needs to be registered with the kernel by calling <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-8C8DCE9D-0094-3909-8FDA-2F3134D0BC88"><apiname>Kern::AddHalEntry()</apiname></xref>. </p> <codeblock id="GUID-F9E86404-742D-5931-BA77-DA246A3975E5" xml:space="preserve">TInt DLcdPowerHandler::Create()
       
   116     {
       
   117        ...
       
   118        // install the HAL function
       
   119        r=Kern::AddHalEntry(EHalGroupDisplay, halFunction, this);
       
   120        if (r!=KErrNone)
       
   121               return r;
       
   122     ...
       
   123     }</codeblock> <p>See <xref href="GUID-2D977A02-5928-5441-8AE7-42A722F2A4B8.dita#GUID-2D977A02-5928-5441-8AE7-42A722F2A4B8/GUID-4DA41221-40B9-5BC7-B2C6-7C6EB4522508">User-Side
       
   124 Hardware Abstraction</xref> for more detailed information on the HAL. </p> <p><b> Install the power handler</b> </p> <p>A call must be made to the <codeph>Add()</codeph> function,
       
   125 which is supplied by the <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita"><apiname>DPowerHandler</apiname></xref> base class of <codeph>DLcdPowerHandler</codeph>,
       
   126 to register the handler with the power manager. </p> <codeblock id="GUID-9286C3A2-DC2B-54F1-9F28-4EBE085AEE84" xml:space="preserve">TInt DLcdPowerHandler::Create()
       
   127     {
       
   128        ...
       
   129         // install the power handler
       
   130         // power up the screen
       
   131         Add();
       
   132     ...
       
   133     }</codeblock> </section>
       
   134 <section id="GUID-85B93308-2EDF-462C-8F64-6AE40B8B16B6"><title>HAL handler implementation</title> <p>Requests to get and
       
   135 set hardware attributes are made through calls to <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-573C49D6-7763-37AE-B2B2-4C8FB1327E21"><apiname>HAL::Get()</apiname></xref> and <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-9454F1B2-D525-3D6D-A872-C6457CACD4FC"><apiname>HAL::Set()</apiname></xref>.
       
   136 These two HAL functions take a value that identifies a hardware attribute,
       
   137 one of the <xref href="GUID-8BE90160-2C60-3582-82C8-4A108C7C0317.dita#GUID-8BE90160-2C60-3582-82C8-4A108C7C0317/GUID-1959915A-BA99-3F94-AFD4-FD1AA540BFBF"><apiname>HALData::TAttribute</apiname></xref> values. </p> <p>For the
       
   138 LCD Extension, the relevant hardware attributes are: <codeph>EDisplayMode</codeph>, <codeph>EDisplayBitsPerPixel</codeph>, <codeph>EDisplayIsPalettized</codeph>, <codeph>EDisplayIsMono</codeph>, <codeph>EDisplayMemoryAddress</codeph>, <codeph>EDisplayMemoryHandle</codeph>, <codeph>EDisplayOffsetToFirstPixel</codeph>, <codeph>EDisplayOffsetBetweenLines</codeph>, <codeph>EDisplayXPixels</codeph>, <codeph>EDisplayYPixels</codeph>, <codeph>EDisplayPaletteEntry</codeph> and <codeph>EDisplayOffsetBetweenLines</codeph>. </p> <p>The HAL handler
       
   139 is registered with the kernel as the handler for the <xref href="GUID-66A851A0-2A0C-3624-AEC1-22F6629FABF7.dita#GUID-66A851A0-2A0C-3624-AEC1-22F6629FABF7/GUID-950EA0D3-747F-305E-92EA-1579023A111E"><apiname>THalFunctionGroup::EHalGroupDisplay</apiname></xref> group.
       
   140 The HAL handler itself takes a function ID, which is one of the <xref href="GUID-BB011D9B-105F-345C-9FC0-39B0BA509394.dita"><apiname>TDisplayHalFunction</apiname></xref> enumerators. </p> <p>A
       
   141 call to <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-573C49D6-7763-37AE-B2B2-4C8FB1327E21"><apiname>HAL::Get()</apiname></xref> and <xref href="GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8.dita#GUID-BD00E7FC-C234-3111-87A5-10F79EB0F2B8/GUID-9454F1B2-D525-3D6D-A872-C6457CACD4FC"><apiname>HAL::Set()</apiname></xref> that
       
   142 takes one of the hardware attributes relevant to the LCD Extension is ultimately
       
   143 routed to a call to this HAL handler function passing an appropriate function
       
   144 ID. The association between the hardware attribute and the function ID is
       
   145 the responsibility of the accessor functions. </p> <p>See <xref href="GUID-2D977A02-5928-5441-8AE7-42A722F2A4B8.dita#GUID-2D977A02-5928-5441-8AE7-42A722F2A4B8/GUID-4DA41221-40B9-5BC7-B2C6-7C6EB4522508">User-Side Hardware Abstraction</xref> for more information on the way this
       
   146 works in general. </p> <p>The HAL handler is implemented as a case statement,
       
   147 switching on the function ID. For example, the following code fragment taken
       
   148 from <codeph>DLcdPowerHandler::HalFunction()</codeph> gets and sets the brightness: </p> <codeblock id="GUID-41D5153A-107A-5FCC-9E51-C6250857F3AC" xml:space="preserve">TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2)
       
   149     {
       
   150     TInt r=KErrNone;
       
   151     switch(aFunction)
       
   152         {
       
   153     
       
   154         ...
       
   155          case EDisplayHalSetDisplayBrightness:
       
   156              if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,
       
   157        __PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayBrightness")))
       
   158                        return KErrPermissionDenied;
       
   159              r=SetBrightness(TInt(a1));
       
   160              break;
       
   161             
       
   162          case EDisplayHalDisplayBrightness:
       
   163              kumemput32(a1,&amp;iBrightness,sizeof(iBrightness));
       
   164              break;
       
   165         ...
       
   166 </codeblock> <p>where <codeph>SetBrightness()</codeph> is implemented as: </p> <codeblock id="GUID-82F38251-19A9-54BC-A066-80ED5AC549AF" xml:space="preserve">TInt DLcdPowerHandler::SetBrightness(TInt aValue)
       
   167     {
       
   168      __KTRACE_OPT(KEXTENSION,Kern::Printf("SetBrightness(%d)", aValue));
       
   169 
       
   170      if (aValue &gt;= KConfigLcdMinDisplayBrightness &amp;&amp; aValue &lt;= KConfigLcdMaxDisplayBrightness)
       
   171          {
       
   172          iBrightness=aValue;
       
   173     
       
   174          // TO DO: (mandatory)
       
   175          // set the brightness
       
   176          //
       
   177          return KErrNone;
       
   178          }
       
   179     return KErrArgument;
       
   180     }
       
   181 </codeblock> <p>If an attribute does not have an implementation, the HAL handler
       
   182 function should return <xref href="GUID-F89DA3F0-2A48-3F9B-8F08-29350E92D0E4.dita"><apiname>KErrNotSupported</apiname></xref>. </p> <p>For platform
       
   183 security, the code only allows the attribute to be set if the current thread
       
   184 has been authorized to write system data. Otherwise, it returns <xref href="GUID-213DE05E-24F7-3E94-9B35-F4A72B3EBFD8.dita"><apiname>KErrPermissionDenied</apiname></xref>. </p> <p><b>Switch on and switch off operations</b> </p> <p>All of the HAL operations
       
   185 are seen to be synchronous by the user side. However there are some operations
       
   186 such as turning the display on and off which may need to be implemented asynchronously. </p> <p>The
       
   187 display on/off code is implemented using synchronous kernel-side messages.
       
   188 There is only one message per thread and the thread always blocks while a
       
   189 message is outstanding. This means it is possible to make an asynchronous
       
   190 operation appear synchronous. </p> <p>When turning on the screen the kernel-side
       
   191 message is queued and this thread is blocked until the message is completed,
       
   192 which happens when the display has been turned on. </p> <p>If a display needs
       
   193 to be turned on and off truly asynchronously (for example, if millisecond
       
   194 timer waits are required during the process of turning on the display), the
       
   195 above functionality must be changed so that the complete occurs when the display
       
   196 is truly on. </p> <p><b>Accessing
       
   197 the video information structure</b> </p> <p>When any part of the <xref href="GUID-6A4FE3A3-2E5D-51BB-8272-5995586291E9.dita#GUID-6A4FE3A3-2E5D-51BB-8272-5995586291E9/GUID-57223C8C-0381-51AC-8E8A-771434136A5C">video information structure</xref> is read or written to, this must be done
       
   198 within a critical section to prevent potential collisions with other threads
       
   199 attempting to access the structure concurrently. A fast mutex is used to ensure
       
   200 that only one thread can access the video information at any one time, as
       
   201 the code segment below shows. </p> <codeblock id="GUID-E30D9790-109C-541F-A534-C92CBD4E1706" xml:space="preserve">TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01&amp; aInfo, TBool aSecure)
       
   202     {
       
   203      __KTRACE_OPT(KEXTENSION,Kern::Printf("GetCurrentDisplayModeInfo"));
       
   204      NKern::FMWait(&amp;iLock);
       
   205      if (aSecure)
       
   206           aInfo = iSecureVideoInfo;
       
   207      else
       
   208          aInfo = iVideoInfo;
       
   209      NKern::FMSignal(&amp;iLock);
       
   210      return KErrNone;
       
   211      }
       
   212 </codeblock> </section>
       
   213 <section id="GUID-04C06DAE-EE8E-4EE9-940F-807F82FBACD1"><title>Power handler implementation</title> <p>The <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita"><apiname>DPowerHandler</apiname></xref> class
       
   214 defines the interface that the driver must implement to provide power handling
       
   215 behaviour. For the template reference board, the LCD Extension defines and
       
   216 implements the <codeph>DLcdPowerHandler</codeph> class derived from <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita"><apiname>DPowerHandler</apiname></xref>. </p> <p> <b>Note</b>: </p> <ul>
       
   217 <li id="GUID-32D95977-F46B-50E0-B575-BE7369C05F62"><p> <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-578DB5FB-731D-36B2-A459-AAC7F250D726"><apiname>DPowerHandler::PowerDown()</apiname></xref> and <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-DDC564B4-BD12-30E9-B04A-DBA6CFAF8743"><apiname>DPowerHandler::PowerUp()</apiname></xref>  </p> <p>These functions are called in the context of the thread that initiates
       
   218 power down or power up, and synchronization is required, typically by means
       
   219 of power up and power down DFCs. </p> </li>
       
   220 <li id="GUID-7DC988A6-C60E-5951-9DD7-82DA129A8CB6"><p> <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-038F9D7D-7DA0-3299-8AA2-85F175206887"><apiname>DPowerHandler::PowerUpLcd()</apiname></xref> and <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-6EAF00D1-3CBA-3BC0-BAD9-7301EE5F9E12"><apiname>DPowerHandler::PowerDownLcd()</apiname></xref>  </p> <p>These functions generally queue DFCs which then call platform-specific
       
   221 functions to power the display up and down. </p> </li>
       
   222 <li id="GUID-51152EA7-C1A5-5AB3-8ACD-6FF6F16A255D"><p> <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-BF62042B-FB7B-3D5B-8379-490FBA284A7A"><apiname>DPowerHandler::PowerUpDone()</apiname></xref> and <xref href="GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7.dita#GUID-761AE02B-41A6-35EA-AA9F-0AEEFF67A6F7/GUID-EBE8CFF8-50BD-3AC3-A4C8-47094DA5674D"><apiname>DPowerHandler::PowerDownDone()</apiname></xref>  </p> <p>When power up or down is complete, the interface supplies a set
       
   223 of acknowledgment functions which must be called when the change of state
       
   224 has taken place. </p> </li>
       
   225 </ul> </section>
       
   226 </conbody><related-links>
       
   227 <link href="GUID-0C3A4156-E5CF-55F9-91A0-A7961FDEE030.dita"><linktext>LCD Extension
       
   228 Architecture</linktext></link>
       
   229 <link href="GUID-8DF46A11-874A-52E5-9298-C083EA633BA0.dita"><linktext>Implementing
       
   230 Dynamic DSA                 Allocation</linktext></link>
       
   231 </related-links></concept>