Add a uclass for real-time clocks which support getting the current time, setting it and resetting the chip to a known-working state. Some RTCs have additional registers which can be used to store settings, so also provide an interface to these. Signed-off-by: Simon Glass <sjg@chromium.org>master
parent
94eefdee2f
commit
dbeda5b225
@ -0,0 +1,8 @@ |
||||
config DM_RTC |
||||
bool "Enable Driver Model for RTC drivers" |
||||
depends on DM |
||||
help |
||||
Enable drver model for real-time-clock drivers. The RTC uclass |
||||
then provides the rtc_get()/rtc_set() interface, delegating to |
||||
drivers to perform the actual functions. See rtc.h for a |
||||
description of the API. |
@ -0,0 +1,96 @@ |
||||
/*
|
||||
* (C) Copyright 2015 Google, Inc |
||||
* Written by Simon Glass <sjg@chromium.org> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <dm.h> |
||||
#include <errno.h> |
||||
#include <rtc.h> |
||||
|
||||
int dm_rtc_get(struct udevice *dev, struct rtc_time *time) |
||||
{ |
||||
struct rtc_ops *ops = rtc_get_ops(dev); |
||||
|
||||
assert(ops); |
||||
if (!ops->get) |
||||
return -ENOSYS; |
||||
return ops->get(dev, time); |
||||
} |
||||
|
||||
int dm_rtc_set(struct udevice *dev, struct rtc_time *time) |
||||
{ |
||||
struct rtc_ops *ops = rtc_get_ops(dev); |
||||
|
||||
assert(ops); |
||||
if (!ops->set) |
||||
return -ENOSYS; |
||||
return ops->set(dev, time); |
||||
} |
||||
|
||||
int dm_rtc_reset(struct udevice *dev) |
||||
{ |
||||
struct rtc_ops *ops = rtc_get_ops(dev); |
||||
|
||||
assert(ops); |
||||
if (!ops->reset) |
||||
return -ENOSYS; |
||||
return ops->reset(dev); |
||||
} |
||||
|
||||
int rtc_read8(struct udevice *dev, unsigned int reg) |
||||
{ |
||||
struct rtc_ops *ops = rtc_get_ops(dev); |
||||
|
||||
assert(ops); |
||||
if (!ops->read8) |
||||
return -ENOSYS; |
||||
return ops->read8(dev, reg); |
||||
} |
||||
|
||||
int rtc_write8(struct udevice *dev, unsigned int reg, int val) |
||||
{ |
||||
struct rtc_ops *ops = rtc_get_ops(dev); |
||||
|
||||
assert(ops); |
||||
if (!ops->write8) |
||||
return -ENOSYS; |
||||
return ops->write8(dev, reg, val); |
||||
} |
||||
|
||||
int rtc_read32(struct udevice *dev, unsigned int reg, u32 *valuep) |
||||
{ |
||||
u32 value = 0; |
||||
int ret; |
||||
int i; |
||||
|
||||
for (i = 0; i < sizeof(value); i++) { |
||||
ret = rtc_read8(dev, reg + i); |
||||
if (ret) |
||||
return ret; |
||||
value |= ret << (i << 3); |
||||
} |
||||
|
||||
*valuep = value; |
||||
return 0; |
||||
} |
||||
|
||||
int rtc_write32(struct udevice *dev, unsigned int reg, u32 value) |
||||
{ |
||||
int i, ret; |
||||
|
||||
for (i = 0; i < sizeof(value); i++) { |
||||
ret = rtc_write8(dev, reg + i, (value >> (i << 3)) & 0xff); |
||||
if (ret) |
||||
return ret; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
UCLASS_DRIVER(rtc) = { |
||||
.name = "rtc", |
||||
.id = UCLASS_RTC, |
||||
}; |
Loading…
Reference in new issue