-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drivers: rtc: new maxim ds1307 rtc driver
Added rtc driver for ds1307. It allows to read and set the date and time Signed-off-by: Arunmani Alagarsamy <[email protected]>
- Loading branch information
1 parent
357d6ce
commit b428951
Showing
5 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# Copyright (c) 2023 Arunmani Alagarsamy | ||
# Author: Arunmani Alagarsamy <[email protected]> | ||
|
||
config RTC_DS1307 | ||
bool "MAXIM DS1307 RTC driver" | ||
default y | ||
depends on DT_HAS_MAXIM_DS1307_ENABLED | ||
select I2C | ||
help | ||
Enable the MAXIM DS1307 RTC driver. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* Copyright (c) 2023 Arunmani Alagarsamy | ||
* Author: Arunmani Alagarsamy <[email protected]> | ||
*/ | ||
|
||
#include <zephyr/drivers/gpio.h> | ||
#include <zephyr/drivers/i2c.h> | ||
#include <zephyr/drivers/rtc.h> | ||
#include <zephyr/logging/log.h> | ||
#include <zephyr/pm/device.h> | ||
#include <zephyr/sys/util.h> | ||
|
||
#define DT_DRV_COMPAT maxim_ds1307 | ||
|
||
LOG_MODULE_REGISTER(ds1307, CONFIG_RTC_LOG_LEVEL); | ||
|
||
#define DS1307_I2C_ADDR 0x68 | ||
|
||
/* DS1307 registers */ | ||
#define DS1307_REG_SECONDS 0x00 | ||
#define DS1307_REG_MINUTES 0x01 | ||
#define DS1307_REG_HOURS 0x02 | ||
#define DS1307_REG_DAY 0x03 | ||
#define DS1307_REG_DATE 0x04 | ||
#define DS1307_REG_MONTH 0x05 | ||
#define DS1307_REG_YEAR 0x06 | ||
#define DS1307_REG_CTRL 0x07 | ||
|
||
#define SECONDS_BITS GENMASK(6, 0) | ||
#define MINUTES_BITS GENMASK(7, 0) | ||
#define HOURS_BITS GENMASK(5, 0) | ||
#define DATE_BITS GENMASK(5, 0) | ||
#define MONTHS_BITS GENMASK(4, 0) | ||
#define WEEKDAY_BITS GENMASK(2, 0) | ||
#define YEAR_BITS GENMASK(7, 0) | ||
|
||
struct ds1307_config { | ||
struct i2c_dt_spec i2c_bus; | ||
}; | ||
|
||
struct ds1307_data { | ||
struct k_spinlock lock; | ||
}; | ||
|
||
static int ds1307_set_time(const struct device *dev, const struct rtc_time *tm) | ||
{ | ||
int err; | ||
uint8_t regs[7]; | ||
|
||
struct ds1307_data *data = dev->data; | ||
const struct ds1307_config *config = dev->config; | ||
|
||
k_spinlock_key_t key = k_spin_lock(&data->lock); | ||
|
||
LOG_DBG("set time: year = %d, mon = %d, mday = %d, wday = %d, hour = %d, " | ||
"min = %d, sec = %d", | ||
tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, tm->tm_hour, tm->tm_min, | ||
tm->tm_sec); | ||
|
||
regs[0] = bin2bcd(tm->tm_sec) & SECONDS_BITS; | ||
regs[1] = bin2bcd(tm->tm_min); | ||
regs[2] = bin2bcd(tm->tm_hour); | ||
regs[3] = bin2bcd(tm->tm_wday); | ||
regs[4] = bin2bcd(tm->tm_mday); | ||
regs[5] = bin2bcd(tm->tm_mon); | ||
regs[6] = bin2bcd(tm->tm_year); | ||
|
||
err = i2c_burst_write_dt(&config->i2c_bus, DS1307_REG_SECONDS, regs, sizeof(regs)); | ||
|
||
k_spin_unlock(&data->lock, key); | ||
|
||
return err; | ||
} | ||
|
||
static int ds1307_get_time(const struct device *dev, struct rtc_time *timeptr) | ||
{ | ||
int err; | ||
uint8_t regs[7]; | ||
|
||
struct ds1307_data *data = dev->data; | ||
const struct ds1307_config *config = dev->config; | ||
|
||
k_spinlock_key_t key = k_spin_lock(&data->lock); | ||
|
||
err = i2c_burst_read_dt(&config->i2c_bus, DS1307_REG_SECONDS, regs, sizeof(regs)); | ||
if (err != 0) { | ||
goto unlock; | ||
} | ||
|
||
timeptr->tm_sec = bcd2bin(regs[0] & SECONDS_BITS); | ||
timeptr->tm_min = bcd2bin(regs[1] & MINUTES_BITS); | ||
timeptr->tm_hour = bcd2bin(regs[2] & HOURS_BITS); /* 24hr mode */ | ||
timeptr->tm_wday = bcd2bin(regs[3] & WEEKDAY_BITS); | ||
timeptr->tm_mday = bcd2bin(regs[4] & DATE_BITS); | ||
timeptr->tm_mon = bcd2bin(regs[5] & MONTHS_BITS); | ||
timeptr->tm_year = bcd2bin(regs[6] & YEAR_BITS); | ||
|
||
/* Validate the chip in 24hr mode */ | ||
if (regs[2] & (1 << 6)) { | ||
return -ENODATA; | ||
} | ||
|
||
LOG_DBG("get time: year = %d, mon = %d, mday = %d, wday = %d, hour = %d, " | ||
"min = %d, sec = %d", | ||
timeptr->tm_year, timeptr->tm_mon, timeptr->tm_mday, timeptr->tm_wday, | ||
timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); | ||
|
||
unlock: | ||
k_spin_unlock(&data->lock, key); | ||
|
||
return err; | ||
} | ||
|
||
static const struct rtc_driver_api ds1307_driver_api = { | ||
.set_time = ds1307_set_time, | ||
.get_time = ds1307_get_time, | ||
}; | ||
|
||
static int ds1307_init(const struct device *dev) | ||
{ | ||
int err; | ||
uint8_t tx_buf[2]; | ||
const struct ds1307_config *config = dev->config; | ||
|
||
if (!i2c_is_ready_dt(&config->i2c_bus)) { | ||
LOG_ERR("I2C bus not ready"); | ||
return -ENODEV; | ||
} | ||
|
||
tx_buf[0] = DS1307_REG_CTRL; | ||
tx_buf[1] = 0x00; | ||
|
||
/* Disable squarewave output */ | ||
err = i2c_write_dt(&config->i2c_bus, tx_buf, sizeof(tx_buf)); | ||
if (err < 0) { | ||
LOG_ERR("Error: SQW:%d\n", err); | ||
Check failure on line 138 in drivers/rtc/rtc_ds1307.c GitHub Actions / Run compliance checks on patch series (PR)CODE_INDENT
|
||
} | ||
Check failure on line 139 in drivers/rtc/rtc_ds1307.c GitHub Actions / Run compliance checks on patch series (PR)CODE_INDENT
|
||
|
||
tx_buf[0] = DS1307_REG_SECONDS; | ||
|
||
/* Make clock halt = 0 */ | ||
err = i2c_write_dt(&config->i2c_bus, tx_buf, sizeof(tx_buf)); | ||
if (err < 0) { | ||
LOG_ERR("Error: Set clock halt bit:%d\n", err); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
#define DS1307_INIT(inst) \ | ||
static struct ds1307_data ds1307_data_##inst; \ | ||
static const struct ds1307_config ds1307_config_##inst = { \ | ||
.i2c_bus = I2C_DT_SPEC_INST_GET(inst), \ | ||
}; \ | ||
DEVICE_DT_INST_DEFINE(inst, &ds1307_init, NULL, &ds1307_data_##inst, \ | ||
&ds1307_config_##inst, POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, \ | ||
&ds1307_driver_api); | ||
|
||
DT_INST_FOREACH_STATUS_OKAY(DS1307_INIT) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# Copyright (c) 2023 Arunmani Alagarsamy | ||
# Author: Arunmani Alagarsamy <[email protected]> | ||
|
||
description: MAXIM DS1307 RTC | ||
|
||
compatible: "maxim,ds1307" | ||
|
||
include: | ||
- name: rtc-device.yaml | ||
- name: i2c-device.yaml |