Skip to content

Commit ff34ca5

Browse files
committed
drivers: rtc: Enabled MFD support for RTC mc146818
Enabled support for motorola mc146818 RTC driver. Signed-off-by: Anisetti Avinash Krishna <anisetti.avinash.krishna@intel.com>
1 parent 1112f04 commit ff34ca5

File tree

3 files changed

+79
-67
lines changed

3 files changed

+79
-67
lines changed

drivers/rtc/Kconfig.mc146818

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
config RTC_MOTOROLA_MC146818
77
bool "RTC driver for x86 CMOS/RTC clock"
88
default y if !COUNTER
9+
select MFD
910
depends on DT_HAS_MOTOROLA_MC146818_ENABLED

drivers/rtc/rtc_mc146818.c

Lines changed: 76 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
#include <zephyr/devicetree.h>
1616
#include <zephyr/drivers/rtc.h>
1717
#include <zephyr/sys/sys_io.h>
18-
19-
#define RTC_STD_INDEX (DT_INST_REG_ADDR_BY_IDX(0, 0))
20-
#define RTC_STD_TARGET (DT_INST_REG_ADDR_BY_IDX(0, 1))
18+
#include <zephyr/drivers/mfd/mc146818.h>
2119

2220
/* Time indices in RTC RAM */
2321
#define RTC_SEC 0x00
@@ -127,21 +125,9 @@ struct rtc_mc146818_data {
127125
void *update_cb_data;
128126
};
129127

130-
static uint8_t rtc_read(int reg)
131-
{
132-
uint8_t value;
133-
134-
sys_out8(reg, RTC_STD_INDEX);
135-
value = sys_in8(RTC_STD_TARGET);
136-
137-
return value;
138-
}
139-
140-
static void rtc_write(int reg, uint8_t value)
141-
{
142-
sys_out8(reg, RTC_STD_INDEX);
143-
sys_out8(value, RTC_STD_TARGET);
144-
}
128+
struct rtc_mc146818_config {
129+
const struct device *mfd;
130+
};
145131

146132
static bool rtc_mc146818_validate_time(const struct rtc_time *timeptr)
147133
{
@@ -172,6 +158,7 @@ static bool rtc_mc146818_validate_time(const struct rtc_time *timeptr)
172158
static int rtc_mc146818_set_time(const struct device *dev, const struct rtc_time *timeptr)
173159
{
174160
struct rtc_mc146818_data * const dev_data = dev->data;
161+
const struct rtc_mc146818_config *config = dev->config;
175162
uint8_t value;
176163
int year;
177164
int cent;
@@ -190,23 +177,23 @@ static int rtc_mc146818_set_time(const struct device *dev, const struct rtc_time
190177
goto out;
191178
}
192179

193-
value = rtc_read(RTC_DATA);
194-
rtc_write(RTC_DATA, value | RTC_UCI_BIT);
180+
value = mfd_mc146818_std_read(config->mfd, RTC_DATA);
181+
mfd_mc146818_std_write(config->mfd, RTC_DATA, value | RTC_UCI_BIT);
195182

196183
year = (1900 + timeptr->tm_year) % 100;
197184
cent = (1900 + timeptr->tm_year) / 100;
198185

199-
rtc_write(RTC_SEC, (uint8_t)timeptr->tm_sec);
200-
rtc_write(RTC_MIN, (uint8_t)timeptr->tm_min);
201-
rtc_write(RTC_HOUR, (uint8_t)timeptr->tm_hour);
202-
rtc_write(RTC_WDAY, (uint8_t)timeptr->tm_wday);
203-
rtc_write(RTC_MDAY, (uint8_t)timeptr->tm_mday);
204-
rtc_write(RTC_MONTH, (uint8_t)timeptr->tm_mon + 1);
205-
rtc_write(RTC_YEAR, year);
206-
rtc_write(RTC_CENTURY, cent);
186+
mfd_mc146818_std_write(config->mfd, RTC_SEC, (uint8_t)timeptr->tm_sec);
187+
mfd_mc146818_std_write(config->mfd, RTC_MIN, (uint8_t)timeptr->tm_min);
188+
mfd_mc146818_std_write(config->mfd, RTC_HOUR, (uint8_t)timeptr->tm_hour);
189+
mfd_mc146818_std_write(config->mfd, RTC_WDAY, (uint8_t)timeptr->tm_wday);
190+
mfd_mc146818_std_write(config->mfd, RTC_MDAY, (uint8_t)timeptr->tm_mday);
191+
mfd_mc146818_std_write(config->mfd, RTC_MONTH, (uint8_t)timeptr->tm_mon + 1);
192+
mfd_mc146818_std_write(config->mfd, RTC_YEAR, year);
193+
mfd_mc146818_std_write(config->mfd, RTC_CENTURY, cent);
207194

208195
value &= (~RTC_UCI_BIT);
209-
rtc_write(RTC_DATA, value);
196+
mfd_mc146818_std_write(config->mfd, RTC_DATA, value);
210197
ret = 0;
211198
out:
212199
k_spin_unlock(&dev_data->lock, key);
@@ -216,10 +203,10 @@ static int rtc_mc146818_set_time(const struct device *dev, const struct rtc_time
216203
static int rtc_mc146818_get_time(const struct device *dev, struct rtc_time *timeptr)
217204
{
218205
struct rtc_mc146818_data * const dev_data = dev->data;
206+
const struct rtc_mc146818_config *config = dev->config;
219207
int ret;
220208
uint8_t cent;
221209
uint8_t year;
222-
uint8_t value;
223210

224211
k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
225212

@@ -229,29 +216,28 @@ static int rtc_mc146818_get_time(const struct device *dev, struct rtc_time *tim
229216
goto out;
230217
}
231218

232-
if (!(rtc_read(RTC_REG_D) & RTC_VRT_BIT)) {
219+
if (!(mfd_mc146818_std_read(config->mfd, RTC_REG_D) & RTC_VRT_BIT)) {
233220
ret = -ENODATA;
234221
goto out;
235222
}
236223

237-
while (rtc_read(RTC_UIP) & RTC_UIP_BIT) {
224+
while (mfd_mc146818_std_read(config->mfd, RTC_UIP) & RTC_UIP_BIT) {
238225
continue;
239226
}
240227

241-
cent = rtc_read(RTC_CENTURY);
242-
year = rtc_read(RTC_YEAR);
243-
timeptr->tm_mon = rtc_read(RTC_MONTH) - 1;
244-
timeptr->tm_mday = rtc_read(RTC_MDAY);
245-
timeptr->tm_wday = rtc_read(RTC_WDAY) - 1;
246-
timeptr->tm_hour = rtc_read(RTC_HOUR);
247-
timeptr->tm_min = rtc_read(RTC_MIN);
248-
timeptr->tm_sec = rtc_read(RTC_SEC);
228+
cent = mfd_mc146818_std_read(config->mfd, RTC_CENTURY);
229+
year = mfd_mc146818_std_read(config->mfd, RTC_YEAR);
230+
timeptr->tm_mon = mfd_mc146818_std_read(config->mfd, RTC_MONTH) - 1;
231+
timeptr->tm_mday = mfd_mc146818_std_read(config->mfd, RTC_MDAY);
232+
timeptr->tm_wday = mfd_mc146818_std_read(config->mfd, RTC_WDAY) - 1;
233+
timeptr->tm_hour = mfd_mc146818_std_read(config->mfd, RTC_HOUR);
234+
timeptr->tm_min = mfd_mc146818_std_read(config->mfd, RTC_MIN);
235+
timeptr->tm_sec = mfd_mc146818_std_read(config->mfd, RTC_SEC);
249236

250237
timeptr->tm_year = 100 * (int)cent + year - 1900;
251238

252239
timeptr->tm_nsec = 0;
253240
timeptr->tm_yday = 0;
254-
value = rtc_read(RTC_DATA);
255241

256242
/* Check time valid */
257243
if (!rtc_mc146818_validate_time(timeptr)) {
@@ -305,6 +291,7 @@ static int rtc_mc146818_alarm_set_time(const struct device *dev, uint16_t id, ui
305291
const struct rtc_time *timeptr)
306292
{
307293
struct rtc_mc146818_data * const dev_data = dev->data;
294+
const struct rtc_mc146818_config *config = dev->config;
308295
int ret;
309296

310297
k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
@@ -326,23 +313,24 @@ static int rtc_mc146818_alarm_set_time(const struct device *dev, uint16_t id, ui
326313
}
327314

328315
if (mask & RTC_ALARM_TIME_MASK_SECOND) {
329-
rtc_write(RTC_ALARM_SEC, timeptr->tm_sec);
316+
mfd_mc146818_std_write(config->mfd, RTC_ALARM_SEC, timeptr->tm_sec);
330317
} else {
331-
rtc_write(RTC_ALARM_SEC, RTC_ALARM_DC);
318+
mfd_mc146818_std_write(config->mfd, RTC_ALARM_SEC, RTC_ALARM_DC);
332319
}
333320

334321
if (mask & RTC_ALARM_TIME_MASK_MINUTE) {
335-
rtc_write(RTC_ALARM_MIN, timeptr->tm_min);
322+
mfd_mc146818_std_write(config->mfd, RTC_ALARM_MIN, timeptr->tm_min);
336323
} else {
337-
rtc_write(RTC_ALARM_SEC, RTC_ALARM_DC);
324+
mfd_mc146818_std_write(config->mfd, RTC_ALARM_SEC, RTC_ALARM_DC);
338325
}
339326
if (mask & RTC_ALARM_TIME_MASK_HOUR) {
340-
rtc_write(RTC_ALARM_HOUR, timeptr->tm_hour);
327+
mfd_mc146818_std_write(config->mfd, RTC_ALARM_HOUR, timeptr->tm_hour);
341328
} else {
342-
rtc_write(RTC_ALARM_SEC, RTC_ALARM_DC);
329+
mfd_mc146818_std_write(config->mfd, RTC_ALARM_SEC, RTC_ALARM_DC);
343330
}
344331

345-
rtc_write(RTC_DATA, rtc_read(RTC_DATA) | RTC_AIE_BIT);
332+
mfd_mc146818_std_write(config->mfd, RTC_DATA,
333+
mfd_mc146818_std_read(config->mfd, RTC_DATA) | RTC_AIE_BIT);
346334
ret = 0;
347335
out:
348336
k_spin_unlock(&dev_data->lock, key);
@@ -353,6 +341,7 @@ static int rtc_mc146818_alarm_get_time(const struct device *dev, uint16_t id, ui
353341
struct rtc_time *timeptr)
354342
{
355343
struct rtc_mc146818_data * const dev_data = dev->data;
344+
const struct rtc_mc146818_config *config = dev->config;
356345
uint8_t value;
357346
int ret;
358347

@@ -370,19 +359,19 @@ static int rtc_mc146818_alarm_get_time(const struct device *dev, uint16_t id, ui
370359

371360
(*mask) = 0;
372361

373-
value = rtc_read(RTC_ALARM_SEC);
362+
value = mfd_mc146818_std_read(config->mfd, RTC_ALARM_SEC);
374363
if (value <= MAX_SEC) {
375364
timeptr->tm_sec = value;
376365
(*mask) |= RTC_ALARM_TIME_MASK_SECOND;
377366
}
378367

379-
value = rtc_read(RTC_ALARM_MIN);
368+
value = mfd_mc146818_std_read(config->mfd, RTC_ALARM_MIN);
380369
if (value <= MAX_MIN) {
381370
timeptr->tm_min = value;
382371
(*mask) |= RTC_ALARM_TIME_MASK_MINUTE;
383372
}
384373

385-
value = rtc_read(RTC_ALARM_HOUR);
374+
value = mfd_mc146818_std_read(config->mfd, RTC_ALARM_HOUR);
386375
if (value <= MAX_HOUR) {
387376
timeptr->tm_hour = value;
388377
(*mask) |= RTC_ALARM_TIME_MASK_HOUR;
@@ -398,6 +387,7 @@ static int rtc_mc146818_alarm_set_callback(const struct device *dev, uint16_t id
398387
rtc_alarm_callback callback, void *user_data)
399388
{
400389
struct rtc_mc146818_data * const dev_data = dev->data;
390+
const struct rtc_mc146818_config *config = dev->config;
401391

402392
if (id != 0) {
403393
return -EINVAL;
@@ -410,10 +400,14 @@ static int rtc_mc146818_alarm_set_callback(const struct device *dev, uint16_t id
410400

411401
if (callback != NULL) {
412402
/* Enable Alarm callback */
413-
rtc_write(RTC_DATA, (rtc_read(RTC_DATA) | RTC_AIE_BIT));
403+
mfd_mc146818_std_write(config->mfd, RTC_DATA,
404+
(mfd_mc146818_std_read(config->mfd,
405+
RTC_DATA) | RTC_AIE_BIT));
414406
} else {
415407
/* Disable Alarm callback */
416-
rtc_write(RTC_DATA, (rtc_read(RTC_DATA) & (~RTC_AIE_BIT)));
408+
mfd_mc146818_std_write(config->mfd, RTC_DATA,
409+
(mfd_mc146818_std_read(config->mfd,
410+
RTC_DATA) & (~RTC_AIE_BIT)));
417411
}
418412

419413
k_spin_unlock(&dev_data->lock, key);
@@ -444,6 +438,7 @@ static int rtc_mc146818_update_set_callback(const struct device *dev,
444438
rtc_update_callback callback, void *user_data)
445439
{
446440
struct rtc_mc146818_data * const dev_data = dev->data;
441+
const struct rtc_mc146818_config *config = dev->config;
447442

448443
k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
449444

@@ -452,10 +447,14 @@ static int rtc_mc146818_update_set_callback(const struct device *dev,
452447

453448
if (callback != NULL) {
454449
/* Enable update callback */
455-
rtc_write(RTC_DATA, (rtc_read(RTC_DATA) | RTC_UIE_BIT));
450+
mfd_mc146818_std_write(config->mfd, RTC_DATA,
451+
(mfd_mc146818_std_read(config->mfd,
452+
RTC_DATA) | RTC_UIE_BIT));
456453
} else {
457454
/* Disable update callback */
458-
rtc_write(RTC_DATA, (rtc_read(RTC_DATA) & (~RTC_UIE_BIT)));
455+
mfd_mc146818_std_write(config->mfd, RTC_DATA,
456+
(mfd_mc146818_std_read(config->mfd,
457+
RTC_DATA) & (~RTC_UIE_BIT)));
459458
}
460459

461460

@@ -468,12 +467,13 @@ static int rtc_mc146818_update_set_callback(const struct device *dev,
468467
static void rtc_mc146818_isr(const struct device *dev)
469468
{
470469
struct rtc_mc146818_data * const dev_data = dev->data;
470+
const struct rtc_mc146818_config *config = dev->config;
471471
uint8_t regc;
472472

473473
ARG_UNUSED(dev_data);
474474

475475
/* Read register, which clears the register */
476-
regc = rtc_read(RTC_FLAG);
476+
regc = mfd_mc146818_std_read(config->mfd, RTC_FLAG);
477477

478478
#if defined(CONFIG_RTC_ALARM)
479479
if (regc & RTC_AF_BIT) {
@@ -514,11 +514,17 @@ static DEVICE_API(rtc, rtc_mc146818_driver_api) = {
514514
#define RTC_MC146818_INIT_FN_DEFINE(n) \
515515
static int rtc_mc146818_init##n(const struct device *dev) \
516516
{ \
517-
rtc_write(RTC_REG_A, \
517+
const struct rtc_mc146818_config *config = dev->config; \
518+
\
519+
if (!device_is_ready(config->mfd)) { \
520+
return -ENODEV; \
521+
} \
522+
mfd_mc146818_std_write(config->mfd, RTC_REG_A, \
518523
_CONCAT(RTC_IN_CLK_DIV_BITS_, \
519524
DT_INST_PROP(n, clock_frequency))); \
520525
\
521-
rtc_write(RTC_REG_B, RTC_DMODE_BIT | RTC_HFORMAT_BIT); \
526+
mfd_mc146818_std_write(config->mfd, \
527+
RTC_REG_B, RTC_DMODE_BIT | RTC_HFORMAT_BIT); \
522528
\
523529
IRQ_CONNECT(DT_INST_IRQN(0), \
524530
DT_INST_IRQ(0, priority), \
@@ -530,14 +536,17 @@ static DEVICE_API(rtc, rtc_mc146818_driver_api) = {
530536
return 0; \
531537
}
532538

533-
#define RTC_MC146818_DEV_CFG(inst) \
534-
struct rtc_mc146818_data rtc_mc146818_data##inst; \
535-
\
536-
RTC_MC146818_INIT_FN_DEFINE(inst) \
537-
\
538-
DEVICE_DT_INST_DEFINE(inst, &rtc_mc146818_init##inst, NULL, \
539-
&rtc_mc146818_data##inst, NULL, POST_KERNEL, \
540-
CONFIG_RTC_INIT_PRIORITY, \
541-
&rtc_mc146818_driver_api); \
539+
#define RTC_MC146818_DEV_CFG(inst) \
540+
static struct rtc_mc146818_data rtc_mc146818_data##inst; \
541+
\
542+
static const struct rtc_mc146818_config rtc_mc146818_config##inst = { \
543+
.mfd = DEVICE_DT_GET(DT_INST_PARENT(inst))}; \
544+
\
545+
RTC_MC146818_INIT_FN_DEFINE(inst) \
546+
DEVICE_DT_INST_DEFINE(inst, &rtc_mc146818_init##inst, NULL, \
547+
&rtc_mc146818_data##inst, &rtc_mc146818_config##inst,\
548+
POST_KERNEL, \
549+
UTIL_INC(CONFIG_MFD_MOTOROLA_MC146818_INIT_PRIORITY),\
550+
&rtc_mc146818_driver_api); \
542551

543552
DT_INST_FOREACH_STATUS_OKAY(RTC_MC146818_DEV_CFG)

dts/bindings/rtc/motorola,mc146818.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ compatible: "motorola,mc146818"
88

99
include: [rtc-device.yaml, acpi.yaml]
1010

11+
on-bus: mc146818-mfd
12+
1113
properties:
1214
clock-frequency:
1315
type: int

0 commit comments

Comments
 (0)