On Fri, Feb 16, 2018 at 02:20:15PM +0530, Meenakshi wrote:
> From: Vabhav <[email protected]>
> 
> Library to provide functions for NXP pcf2129 real time clock library
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Vabhav <[email protected]>
> ---
>  Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129Rtc.h     |  43 +++
>  Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.c  | 330 
> +++++++++++++++++++++
>  .../NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.inf    |  47 +++
>  3 files changed, 420 insertions(+)
>  create mode 100644 Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129Rtc.h
>  create mode 100644 Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.c
>  create mode 100644 Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.inf
> 
> diff --git a/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129Rtc.h 
> b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129Rtc.h
> new file mode 100644
> index 0000000..735f697
> --- /dev/null
> +++ b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129Rtc.h
> @@ -0,0 +1,43 @@
> +/** Pcf2129Rtc.h
> +*
> +*  Copyright 2017 NXP
> +*
> +*  This program and the accompanying materials
> +*  are licensed and made available under the terms and conditions of the BSD 
> License
> +*  which accompanies this distribution.  The full text of the license may be 
> found at
> +*  http://opensource.org/licenses/bsd-license.php
> +*
> +*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
> IMPLIED.
> +*
> +**/
> +
> +#ifndef __PCF2129RTC_H__
> +#define __PCF2129RTC_H__
> +
> +/*
> + * RTC register addresses
> + */
> +#define PCF2129_CTRL1_REG_ADDR      0x00  // Control Register 1
> +#define PCF2129_CTRL2_REG_ADDR      0x01  // Control Register 2
> +#define PCF2129_CTRL3_REG_ADDR      0x02  // Control Register 3
> +#define PCF2129_SEC_REG_ADDR        0x03
> +#define PCF2129_MIN_REG_ADDR        0x04
> +#define PCF2129_HR_REG_ADDR         0x05
> +#define PCF2129_DAY_REG_ADDR        0x06
> +#define PCF2129_WEEKDAY_REG_ADDR    0x07
> +#define PCF2129_MON_REG_ADDR        0x08
> +#define PCF2129_YR_REG_ADDR         0x09
> +
> +#define PCF2129_CTRL3_BIT_BLF       BIT2    /* Battery Low Flag*/
> +
> +// Define EPOCH (1998-JANUARY-01) in the Julian Date representation
> +#define EPOCH_JULIAN_DATE           2450815
> +
> +typedef struct {
> +  UINTN                           OperationCount;
> +  EFI_I2C_OPERATION               SetAddressOp;
> +  EFI_I2C_OPERATION               GetSetDateTimeOp;
> +} RTC_I2C_REQUEST;
> +
> +#endif // __PCF2129RTC_H__
> diff --git a/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.c 
> b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.c
> new file mode 100644
> index 0000000..2e21014
> --- /dev/null
> +++ b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.c
> @@ -0,0 +1,330 @@
> +/** @PCF2129RtcLib.c
> +  Implement EFI RealTimeClock with runtime services via RTC Lib for PCF2129 
> RTC.
> +
> +  Based on RTC implementation available in
> +  EmbeddedPkg/Library/TemplateRealTimeClockLib/RealTimeClockLib.c
> +
> +  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
> +  Copyright 2017 NXP
> +
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD 
> License
> +  which accompanies this distribution.  The full text of the license may be 
> found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
> IMPLIED.
> +
> +**/
> +
> +#include <PiDxe.h>
> +#include <Base.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/RealTimeClockLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Protocol/I2cMaster.h>
> +
> +#include "Pcf2129Rtc.h"
> +
> +STATIC EFI_I2C_MASTER_PROTOCOL    *mI2cMaster;
> +
> +/**
> +  returns Day of the week [0-6] 0=Sunday
> +  Don't try to provide a Year that's before 1998, please !

(You should probably add an assert for that, in that case.)

> + **/
> +UINTN
> +EfiTimeToWday (

This looks like a completely generic function. Could it be submitted
to edk2 EmbeddedPkg/Library/TimeBaseLib?

> +  IN  EFI_TIME  *Time
> +  )
> +{
> +  UINTN MonthDiff;
> +  UINTN Year;
> +  UINTN Month;
> +  UINTN JulianDate;  // Absolute Julian Date representation of the supplied 
> Time
> +  UINTN EpochDays;   // Number of days elapsed since EPOCH_JULIAN_DAY
> +
> +  MonthDiff = (14 - Time->Month) / 12 ;
> +  Year = Time->Year + 4800 - MonthDiff;
> +  Month = Time->Month + (12*MonthDiff) - 3;
> +
> +  JulianDate = Time->Day + ((153*Month + 2)/5) + (365*Year) + (Year/4) - 
> (Year/100) + (Year/400) - 32045;
> +
> +  ASSERT (JulianDate >= EPOCH_JULIAN_DATE);
> +  EpochDays = JulianDate - EPOCH_JULIAN_DATE;
> +
> +   // 4=1/1/1998 was a Thursday

Extra space in indentation.

> +
> +  return (EpochDays + 4) % 7;
> +}
> +
> +/**
> +  Write RTC register.
> +
> +  @param  RtcRegAddr       Register offset of RTC to write.
> +  @param  Val              Value to be written
> +
> +**/
> +
> +STATIC
> +VOID
> +RtcWrite (
> +  IN  UINT8                RtcRegAddr,
> +  IN  UINT8                Val
> +  )
> +{
> +  RTC_I2C_REQUEST          Req;
> +  EFI_STATUS               Status;
> +
> +  Req.OperationCount = 2;
> +
> +  Req.SetAddressOp.Flags = 0;
> +  Req.SetAddressOp.LengthInBytes = 0;
> +  Req.SetAddressOp.Buffer = &RtcRegAddr;
> +
> +  Req.GetSetDateTimeOp.Flags = 0;
> +  Req.GetSetDateTimeOp.LengthInBytes = sizeof (Val);
> +  Req.GetSetDateTimeOp.Buffer = &Val;
> +
> +  Status = mI2cMaster->StartRequest (mI2cMaster, FixedPcdGet8 
> (PcdI2cSlaveAddress),
> +                                     (VOID *)&Req,
> +                                     NULL,  NULL);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "RTC write error at Addr:0x%x\n", RtcRegAddr));
> +  }
> +
> +}
> +
> +/**
> +  Returns the current time and date information, and the time-keeping 
> capabilities
> +  of the hardware platform.
> +
> +  @param  Time                  A pointer to storage to receive a snapshot 
> of the current time.
> +  @param  Capabilities          An optional pointer to a buffer to receive 
> the real time clock
> +                                device's capabilities.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_INVALID_PARAMETER Time is NULL.
> +  @retval EFI_DEVICE_ERROR      The time could not be retrieved due to 
> hardware error.
> +
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +LibGetTime (
> +  OUT EFI_TIME                *Time,
> +  OUT  EFI_TIME_CAPABILITIES  *Capabilities
> +  )
> +{
> +  EFI_STATUS      Status;
> +  UINT8           Buffer[10];
> +  RTC_I2C_REQUEST Req;
> +  UINT8           RtcRegAddr;
> +
> +  Status = EFI_SUCCESS;
> +  RtcRegAddr = PCF2129_CTRL1_REG_ADDR;
> +  Buffer[0] = 0;
> +
> +  if (mI2cMaster == NULL) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  RtcWrite (PCF2129_CTRL1_REG_ADDR, Buffer[0]);
> +
> +  if (Time == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Req.OperationCount = 2;
> +
> +  Req.SetAddressOp.Flags = 0;
> +  Req.SetAddressOp.LengthInBytes = 0;
> +  Req.SetAddressOp.Buffer = &RtcRegAddr;
> +
> +  Req.GetSetDateTimeOp.Flags = I2C_FLAG_READ;
> +  Req.GetSetDateTimeOp.LengthInBytes = sizeof (Buffer);
> +  Req.GetSetDateTimeOp.Buffer = Buffer;
> +
> +  Status = mI2cMaster->StartRequest (mI2cMaster, FixedPcdGet8 
> (PcdI2cSlaveAddress),
> +                                     (VOID *)&Req,
> +                                     NULL,  NULL);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "RTC read error at Addr:0x%x\n", RtcRegAddr));
> +  }
> +
> +  if (Buffer[PCF2129_CTRL3_REG_ADDR] & PCF2129_CTRL3_BIT_BLF) {
> +    DEBUG((DEBUG_INFO, "### Warning: RTC battery status low, check/replace 
> RTC battery.\n"));
> +  }
> +
> +  Time->Nanosecond = 0;
> +  Time->Second  = BcdToDecimal8 (Buffer[PCF2129_SEC_REG_ADDR] & 0x7F);
> +  Time->Minute  = BcdToDecimal8 (Buffer[PCF2129_MIN_REG_ADDR] & 0x7F);
> +  Time->Hour = BcdToDecimal8 (Buffer[PCF2129_HR_REG_ADDR] & 0x3F);
> +  Time->Day = BcdToDecimal8 (Buffer[PCF2129_DAY_REG_ADDR] & 0x3F);
> +  Time->Month  = BcdToDecimal8 (Buffer[PCF2129_MON_REG_ADDR] & 0x1F);

Ideally, I would like to see #defines for these masks.

> +  Time->Year = BcdToDecimal8 (Buffer[PCF2129_YR_REG_ADDR]) + ( BcdToDecimal8 
> (Buffer[PCF2129_YR_REG_ADDR]) >= 98 ? 1900 : 2000);

That is a very long line.
It could be shortened substantially by using a temporary variable for
BcdToDecimal8 (Buffer[PCF2129_YR_REG_ADDR]).

> +
> +  return Status;
> +}
> +
> +/**
> +  Sets the current local time and date information.
> +
> +  @param  Time                  A pointer to the current time.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_INVALID_PARAMETER A time field is out of range.
> +  @retval EFI_DEVICE_ERROR      The time could not be set due due to 
> hardware error.
> +
> +**/
> +
> +EFI_STATUS
> +EFIAPI
> +LibSetTime (
> +  IN EFI_TIME                *Time
> +  )
> +{
> +  UINT8           Buffer[8];
> +  UINT8           Index;
> +  EFI_STATUS      Status;
> +  RTC_I2C_REQUEST Req;
> +  UINT8           RtcRegAddr;
> +
> +  Index = 0;
> +  Status = EFI_SUCCESS;
> +  RtcRegAddr = PCF2129_CTRL1_REG_ADDR;
> +
> +  if (mI2cMaster == NULL) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  // start register address
> +  Buffer[Index++] = PCF2129_SEC_REG_ADDR;
> +
> +  // hours, minutes and seconds
> +  Buffer[Index++] = DecimalToBcd8 (Time->Second);
> +  Buffer[Index++] = DecimalToBcd8 (Time->Minute);
> +  Buffer[Index++] = DecimalToBcd8 (Time->Hour);
> +  Buffer[Index++] = DecimalToBcd8 (Time->Day);
> +  Buffer[Index++] = EfiTimeToWday (Time) & 0x07;

Why mask at the call site?

/
    Leif

> +  Buffer[Index++] = DecimalToBcd8 (Time->Month);
> +  Buffer[Index++] = DecimalToBcd8 (Time->Year % 100);
> +
> +  Req.OperationCount = 2;
> +  Req.SetAddressOp.Flags = 0;
> +  Req.SetAddressOp.LengthInBytes = 0;
> +  Req.SetAddressOp.Buffer = &RtcRegAddr;
> +
> +  Req.GetSetDateTimeOp.Flags = 0;
> +  Req.GetSetDateTimeOp.LengthInBytes = sizeof (Buffer);
> +  Req.GetSetDateTimeOp.Buffer = Buffer;
> +
> +  Status = mI2cMaster->StartRequest (mI2cMaster, FixedPcdGet8 
> (PcdI2cSlaveAddress),
> +                                     (VOID *)&Req,
> +                                     NULL,  NULL);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "RTC write error at Addr:0x%x\n", RtcRegAddr));
> +    return Status;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Returns the current wakeup alarm clock setting.
> +
> +  @param  Enabled               Indicates if the alarm is currently enabled 
> or disabled.
> +  @param  Pending               Indicates if the alarm signal is pending and 
> requires acknowledgement.
> +  @param  Time                  The current alarm setting.
> +
> +  @retval EFI_SUCCESS           The alarm settings were returned.
> +  @retval EFI_INVALID_PARAMETER Any parameter is NULL.
> +  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due 
> to a hardware error.
> +  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this 
> platform.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LibGetWakeupTime (
> +  OUT BOOLEAN     *Enabled,
> +  OUT BOOLEAN     *Pending,
> +  OUT EFI_TIME    *Time
> +  )
> +{
> +  // Not a required feature
> +  return EFI_UNSUPPORTED;
> +}
> +
> +
> +/**
> +  Sets the system wakeup alarm clock time.
> +
> +  @param  Enabled               Enable or disable the wakeup alarm.
> +  @param  Time                  If Enable is TRUE, the time to set the 
> wakeup alarm for.
> +
> +  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was 
> enabled. If
> +                                Enable is FALSE, then the wakeup alarm was 
> disabled.
> +  @retval EFI_INVALID_PARAMETER A time field is out of range.
> +  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a 
> hardware error.
> +  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this 
> platform.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LibSetWakeupTime (
> +  IN BOOLEAN      Enabled,
> +  OUT EFI_TIME    *Time
> +  )
> +{
> +  // Not a required feature
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  This is the declaration of an EFI image entry point. This can be the entry 
> point to an application
> +  written to this specification, an EFI boot service driver, or an EFI 
> runtime driver.
> +
> +  @param  ImageHandle           Handle that identifies the loaded image.
> +  @param  SystemTable           System Table for this image.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_DEVICE_ERROR      The operation could not be started.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +LibRtcInitialize (
> +  IN EFI_HANDLE                            ImageHandle,
> +  IN EFI_SYSTEM_TABLE                      *SystemTable
> +  )
> +{
> +
> +  EFI_STATUS                    Status;
> +  EFI_I2C_MASTER_PROTOCOL       *I2cMaster;
> +  UINTN                         BusFrequency;
> +
> +  Status = gBS->LocateProtocol (&gEfiI2cMasterProtocolGuid, NULL, (VOID 
> **)&I2cMaster);
> +
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = I2cMaster->Reset (I2cMaster);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: I2CMaster->Reset () failed - %r\n",
> +      __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  BusFrequency = FixedPcdGet32 (PcdI2cSpeed);
> +  Status = I2cMaster->SetBusFrequency (I2cMaster, &BusFrequency);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: I2CMaster->SetBusFrequency () failed - %r\n",
> +      __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  mI2cMaster = I2cMaster;
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.inf 
> b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.inf
> new file mode 100644
> index 0000000..873bcea
> --- /dev/null
> +++ b/Silicon/NXP/Library/Pcf2129RtcLib/Pcf2129RtcLib.inf
> @@ -0,0 +1,47 @@
> +#/** @Pcf2129RtcLib.inf
> +#
> +#  Copyright 2017 NXP
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of the BSD 
> License
> +#  which accompanies this distribution. The full text of the license may be 
> found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
> IMPLIED.
> +#
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001A
> +  BASE_NAME                      = Pcf2129RtcLib
> +  FILE_GUID                      = B661E02D-A90B-42AB-A5F9-CF841AAA43D9
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = RealTimeClockLib
> +
> +
> +[Sources.common]
> +  Pcf2129RtcLib.c
> +
> +[Packages]
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/NXP/NxpQoriqLs.dec
> +
> +[LibraryClasses]
> +  DebugLib
> +  UefiBootServicesTableLib
> +  UefiLib
> +
> +[Protocols]
> +  gEfiDriverBindingProtocolGuid        ## CONSUMES
> +  gEfiI2cMasterProtocolGuid            ## CONSUMES
> +
> +[Pcd]
> +  gNxpQoriqLsTokenSpaceGuid.PcdI2cBus
> +  gNxpQoriqLsTokenSpaceGuid.PcdI2cSpeed
> +  gNxpQoriqLsTokenSpaceGuid.PcdI2cSlaveAddress
> +
> +[Depex]
> +  gEfiI2cMasterProtocolGuid
> -- 
> 1.9.1
> 
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to