Skip to content

Commit 008e0aa

Browse files
committed
drivers: bbram: Enables bbram driver for motorola, mc146818
Enables bbram driver for motorola, mc146818 under its MFD to access the RAM of the RTC. Signed-off-by: Anisetti Avinash Krishna <anisetti.avinash.krishna@intel.com>
1 parent 72ebd04 commit 008e0aa

File tree

5 files changed

+185
-0
lines changed

5 files changed

+185
-0
lines changed

drivers/bbram/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ zephyr_library_sources_ifdef(CONFIG_BBRAM_MICROCHIP_MCP7940N_EMUL bbram_microchi
1818
zephyr_library_sources_ifdef(CONFIG_BBRAM_XEC bbram_xec.c)
1919
zephyr_library_sources_ifdef(CONFIG_BBRAM_STM32 bbram_stm32.c)
2020
zephyr_library_sources_ifdef(CONFIG_BBRAM_RTS5912 bbram_rts5912.c)
21+
zephyr_library_sources_ifdef(CONFIG_BBRAM_MOTOROLA_MC146818 bbram_mc146818.c)

drivers/bbram/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,6 @@ source "drivers/bbram/Kconfig.stm32"
4444

4545
source "drivers/bbram/Kconfig.rts5912"
4646

47+
source "drivers/bbram/Kconfig.mc146818"
48+
4749
endif # BBRAM

drivers/bbram/Kconfig.mc146818

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Intel SoC BBRAM configuration options
2+
3+
# Copyright (c) 2025 Intel Corporation
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
config BBRAM_MOTOROLA_MC146818
7+
bool "BBRAM driver for x86 CMOS/RTC clock's bbram"
8+
default y if !COUNTER
9+
select MFD
10+
depends on DT_HAS_MOTOROLA_MC146818_BBRAM_ENABLED
11+
help
12+
Enable driver for Motorola mc146818 BBRAM.

drivers/bbram/bbram_mc146818.c

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/*
2+
* Copyright (c) 2025 Intel Corporation.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*
8+
* Read and Write access to offset ranges 0x2A(42)-0x31(49) and 0xAA(170)-0xB1(177)
9+
* are lockable through BIOS setting. To access the memory in those offsets,
10+
* disable the Lock in BIOS through following steps.
11+
* Intel Advanced Menu -> PCH-IO Configuration -> Security Configuration ->
12+
* RTC Memory Lock -> Disable
13+
*/
14+
15+
#define DT_DRV_COMPAT motorola_mc146818_bbram
16+
17+
#include <zephyr/device.h>
18+
#include <zephyr/kernel.h>
19+
#include <zephyr/init.h>
20+
#include <zephyr/sys/util.h>
21+
#include <zephyr/devicetree.h>
22+
#include <zephyr/drivers/bbram.h>
23+
#include <zephyr/sys/sys_io.h>
24+
#include <zephyr/spinlock.h>
25+
#include <zephyr/drivers/mfd/mc146818.h>
26+
27+
#define MIN_SIZE 1 /* Minimum size to write */
28+
#define MIN_OFFSET 0x0E /* Starting offset of memory */
29+
#define MAX_STD 0x7F /* Last offset of Standard memory bank */
30+
#define RTC_CENT 0x32 /* Offset for RTC Century Byte */
31+
32+
struct bbram_mc146818_config {
33+
const struct device *mfd;
34+
size_t mem_size;
35+
};
36+
37+
struct bbram_mc146818_data {
38+
struct k_spinlock lock;
39+
};
40+
41+
static int bbram_mc146818_read(const struct device *dev, size_t offset,
42+
size_t size, uint8_t *data)
43+
{
44+
const struct bbram_mc146818_config *config = dev->config;
45+
struct bbram_mc146818_data *dev_data = dev->data;
46+
47+
if (size < MIN_SIZE || offset + size > config->mem_size
48+
|| data == NULL) {
49+
return -EFAULT;
50+
}
51+
52+
offset += MIN_OFFSET;
53+
54+
k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
55+
56+
for (size_t i = 0; i < size; i++) {
57+
if (offset < MAX_STD) {
58+
if (offset >= RTC_CENT) {
59+
60+
/* RTC_CENT byte is used to store Century data for the
61+
* RTC time and date, so skipping read/write operation
62+
* to this byte.
63+
*/
64+
65+
*(data + i) = mfd_mc146818_std_read(config->mfd, offset+1);
66+
} else {
67+
*(data + i) = mfd_mc146818_std_read(config->mfd, offset);
68+
}
69+
} else {
70+
*(data + i) = mfd_mc146818_ext_read(config->mfd, offset+1);
71+
}
72+
offset++;
73+
}
74+
75+
k_spin_unlock(&dev_data->lock, key);
76+
return 0;
77+
}
78+
79+
static int bbram_mc146818_write(const struct device *dev, size_t offset,
80+
size_t size, const uint8_t *data)
81+
{
82+
const struct bbram_mc146818_config *config = dev->config;
83+
struct bbram_mc146818_data *dev_data = dev->data;
84+
85+
if (size < MIN_SIZE || offset + size > config->mem_size
86+
|| data == NULL) {
87+
return -EFAULT;
88+
}
89+
90+
offset += MIN_OFFSET;
91+
92+
k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
93+
94+
for (size_t i = 0; i < size; i++) {
95+
if (offset < MAX_STD) {
96+
if (offset >= RTC_CENT) {
97+
98+
/* RTC_CENT byte is used to store Century data for the
99+
* RTC time and date, so skipping read/write operation
100+
* to this byte.
101+
*/
102+
103+
mfd_mc146818_std_write(config->mfd, offset+1, *(data + i));
104+
} else {
105+
mfd_mc146818_std_write(config->mfd, offset, *(data + i));
106+
}
107+
} else {
108+
mfd_mc146818_ext_write(config->mfd, offset+1, *(data + i));
109+
}
110+
offset++;
111+
}
112+
113+
k_spin_unlock(&dev_data->lock, key);
114+
return 0;
115+
}
116+
117+
static int bbram_mc146818_get_size(const struct device *dev, size_t *size)
118+
{
119+
const struct bbram_mc146818_config *config = dev->config;
120+
121+
*size = config->mem_size;
122+
123+
return 0;
124+
}
125+
126+
static const struct bbram_driver_api bbram_mc146818_api = {
127+
.read = bbram_mc146818_read,
128+
.write = bbram_mc146818_write,
129+
.get_size = bbram_mc146818_get_size,
130+
};
131+
132+
static int bbram_mc146818_init(const struct device *dev)
133+
{
134+
const struct bbram_mc146818_config *config = dev->config;
135+
136+
if (!device_is_ready(config->mfd)) {
137+
return -ENODEV;
138+
}
139+
140+
return 0;
141+
}
142+
143+
#define BBRAM_MC146818_DEV_CFG(n) \
144+
static const struct bbram_mc146818_config bbram_config_##n = { \
145+
.mfd = DEVICE_DT_GET(DT_INST_PARENT(n)), \
146+
.mem_size = DT_INST_PROP(n, size), \
147+
}; \
148+
static struct bbram_mc146818_data bbram_data_##n; \
149+
DEVICE_DT_INST_DEFINE(n, &bbram_mc146818_init, NULL, \
150+
&bbram_data_##n, &bbram_config_##n, \
151+
POST_KERNEL, \
152+
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \
153+
&bbram_mc146818_api); \
154+
155+
DT_INST_FOREACH_STATUS_OKAY(BBRAM_MC146818_DEV_CFG)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright (c) 2025, Intel Corporation
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
description: Motorola MC146818 compatible Real Timer Clock Battery Backed RAM
6+
7+
compatible: "motorola,mc146818-bbram"
8+
9+
include: base.yaml
10+
11+
properties:
12+
size:
13+
type: int
14+
required: true
15+
description: Memory capacity in bytes.

0 commit comments

Comments
 (0)