mirror of
https://github.com/openharmony/drivers_adapter_khdf_linux.git
synced 2026-07-20 19:47:03 -04:00
238 lines
6.1 KiB
C
238 lines
6.1 KiB
C
/*
|
|
* rtc_adapter.c
|
|
*
|
|
* rtc driver adapter of linux
|
|
*
|
|
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
|
*
|
|
* This software is licensed under the terms of the GNU General Public
|
|
* License version 2, as published by the Free Software Foundation, and
|
|
* may be copied, distributed, and modified under those terms.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
|
|
#include <linux/rtc.h>
|
|
#include "device_resource_if.h"
|
|
#include "hdf_device_desc.h"
|
|
#include "hdf_log.h"
|
|
#include "rtc_core.h"
|
|
|
|
#define HDF_LOG_TAG RTC_ADAPTER
|
|
#define MONTH_DIFF 1
|
|
#define YEAR_BASE 1900
|
|
|
|
static inline void HdfTimeToLinuxTime(const struct RtcTime *hdfTime, struct rtc_time *linuxTime)
|
|
{
|
|
linuxTime->tm_sec = hdfTime->second;
|
|
linuxTime->tm_min = hdfTime->minute;
|
|
linuxTime->tm_hour = hdfTime->hour;
|
|
linuxTime->tm_mday = hdfTime->day;
|
|
linuxTime->tm_mon = hdfTime->month - MONTH_DIFF;
|
|
linuxTime->tm_year = hdfTime->year - YEAR_BASE;
|
|
linuxTime->tm_wday = hdfTime->weekday;
|
|
linuxTime->tm_yday = rtc_year_days(linuxTime->tm_mday, linuxTime->tm_mon, linuxTime->tm_year);
|
|
}
|
|
|
|
static inline void LinuxTimeToHdfTime(struct RtcTime *hdfTime, const struct rtc_time *linuxTime)
|
|
{
|
|
hdfTime->second = linuxTime->tm_sec;
|
|
hdfTime->minute = linuxTime->tm_min;
|
|
hdfTime->hour = linuxTime->tm_hour;
|
|
hdfTime->day = linuxTime->tm_mday;
|
|
hdfTime->month = linuxTime->tm_mon + MONTH_DIFF;
|
|
hdfTime->year = linuxTime->tm_year + YEAR_BASE;
|
|
hdfTime->weekday = linuxTime->tm_wday;
|
|
}
|
|
|
|
static inline struct rtc_device *HdfGetRtcDevice(void)
|
|
{
|
|
struct rtc_device *dev = rtc_class_open(CONFIG_RTC_SYSTOHC_DEVICE);
|
|
|
|
if (dev == NULL) {
|
|
HDF_LOGE("%s: failed to get rtc device", __func__);
|
|
}
|
|
return dev;
|
|
}
|
|
|
|
static inline void HdfPutRtcDevice(struct rtc_device *dev)
|
|
{
|
|
rtc_class_close(dev);
|
|
}
|
|
|
|
static int32_t HiRtcReadTime(struct RtcHost *host, struct RtcTime *hdfTime)
|
|
{
|
|
int32_t ret;
|
|
struct rtc_time linuxTime = {0};
|
|
struct rtc_device *dev = HdfGetRtcDevice();
|
|
|
|
(void)host;
|
|
if (dev == NULL) {
|
|
return HDF_FAILURE;
|
|
}
|
|
ret = rtc_read_time(dev, &linuxTime);
|
|
if (ret < 0) {
|
|
HDF_LOGE("%s: rtc_read_time error, ret is %d", __func__, ret);
|
|
return ret;
|
|
}
|
|
HdfPutRtcDevice(dev);
|
|
LinuxTimeToHdfTime(hdfTime, &linuxTime);
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static int32_t HiRtcWriteTime(struct RtcHost *host, const struct RtcTime *hdfTime)
|
|
{
|
|
int32_t ret;
|
|
struct rtc_time linuxTime = {0};
|
|
struct rtc_device *dev = HdfGetRtcDevice();
|
|
|
|
(void)host;
|
|
if (dev == NULL) {
|
|
return HDF_FAILURE;
|
|
}
|
|
HdfTimeToLinuxTime(hdfTime, &linuxTime);
|
|
ret = rtc_set_time(dev, &linuxTime);
|
|
if (ret < 0) {
|
|
HDF_LOGE("%s: rtc_set_time error, ret is %d", __func__, ret);
|
|
return ret;
|
|
}
|
|
|
|
HdfPutRtcDevice(dev);
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static int32_t HiReadAlarm(struct RtcHost *host, enum RtcAlarmIndex alarmIndex, struct RtcTime *hdfTime)
|
|
{
|
|
int32_t ret;
|
|
struct rtc_wkalrm alarm = {0};
|
|
struct rtc_device *dev = HdfGetRtcDevice();
|
|
|
|
(void)host;
|
|
(void)alarmIndex;
|
|
if (dev == NULL) {
|
|
return HDF_FAILURE;
|
|
}
|
|
ret = rtc_read_alarm(dev, &alarm);
|
|
if (ret < 0) {
|
|
HDF_LOGE("%s: rtc_read_alarm error, ret is %d", __func__, ret);
|
|
return ret;
|
|
}
|
|
|
|
LinuxTimeToHdfTime(hdfTime, &(alarm.time));
|
|
HdfPutRtcDevice(dev);
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static int32_t HiWriteAlarm(struct RtcHost *host, enum RtcAlarmIndex alarmIndex, const struct RtcTime *hdfTime)
|
|
{
|
|
int32_t ret;
|
|
struct rtc_wkalrm alarm = {0};
|
|
struct rtc_device *dev = HdfGetRtcDevice();
|
|
|
|
(void)host;
|
|
(void)alarmIndex;
|
|
if (dev == NULL) {
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
HdfTimeToLinuxTime(hdfTime, &(alarm.time));
|
|
alarm.enabled = 0;
|
|
ret = rtc_set_alarm(dev, &alarm);
|
|
if (ret < 0) {
|
|
HDF_LOGE("%s: rtc_read_alarm error, ret is %d", __func__, ret);
|
|
return ret;
|
|
}
|
|
|
|
HdfPutRtcDevice(dev);
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static int32_t HiAlarmInterruptEnable(struct RtcHost *host, enum RtcAlarmIndex alarmIndex, uint8_t enable)
|
|
{
|
|
int32_t ret;
|
|
struct rtc_device *dev = HdfGetRtcDevice();
|
|
|
|
(void)host;
|
|
(void)alarmIndex;
|
|
if (dev == NULL) {
|
|
return HDF_FAILURE;
|
|
}
|
|
ret = rtc_alarm_irq_enable(dev, enable);
|
|
if (ret < 0) {
|
|
HDF_LOGE("%s: rtc_read_alarm error, ret is %d", __func__, ret);
|
|
return ret;
|
|
}
|
|
|
|
HdfPutRtcDevice(dev);
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static struct RtcMethod g_method = {
|
|
.ReadTime = HiRtcReadTime,
|
|
.WriteTime = HiRtcWriteTime,
|
|
.ReadAlarm = HiReadAlarm,
|
|
.WriteAlarm = HiWriteAlarm,
|
|
.RegisterAlarmCallback = NULL,
|
|
.AlarmInterruptEnable = HiAlarmInterruptEnable,
|
|
.GetFreq = NULL,
|
|
.SetFreq = NULL,
|
|
.Reset = NULL,
|
|
.ReadReg = NULL,
|
|
.WriteReg = NULL,
|
|
};
|
|
|
|
static int32_t HiRtcBind(struct HdfDeviceObject *device)
|
|
{
|
|
struct RtcHost *host = NULL;
|
|
|
|
host = RtcHostCreate(device);
|
|
if (host == NULL) {
|
|
HDF_LOGE("%s: create host fail", __func__);
|
|
return HDF_ERR_INVALID_OBJECT;
|
|
}
|
|
|
|
host->device = device;
|
|
device->service = &host->service;
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static int32_t HiRtcInit(struct HdfDeviceObject *device)
|
|
{
|
|
struct RtcHost *host = NULL;
|
|
|
|
if (device == NULL) {
|
|
HDF_LOGE("%s: err, device is null", __func__);
|
|
return HDF_ERR_INVALID_OBJECT;
|
|
}
|
|
host = RtcHostFromDevice(device);
|
|
host->method = &g_method;
|
|
HDF_LOGI("%s: Hdf dev service:%s init success", __func__, HdfDeviceGetServiceName(device));
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static void HiRtcRelease(struct HdfDeviceObject *device)
|
|
{
|
|
struct RtcHost *host = NULL;
|
|
|
|
if (device == NULL) {
|
|
return;
|
|
}
|
|
|
|
host = RtcHostFromDevice(device);
|
|
RtcHostDestroy(host);
|
|
}
|
|
|
|
struct HdfDriverEntry g_rtcDriverEntry = {
|
|
.moduleVersion = 1,
|
|
.Bind = HiRtcBind,
|
|
.Init = HiRtcInit,
|
|
.Release = HiRtcRelease,
|
|
.moduleName = "HDF_PLATFORM_RTC",
|
|
};
|
|
|
|
HDF_INIT(g_rtcDriverEntry);
|