Skip to content

Commit afaa37b

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 1fb1738 commit afaa37b

File tree

2 files changed

+76
-66
lines changed

2 files changed

+76
-66
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: 75 additions & 66 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,6 +203,7 @@ 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;
@@ -229,29 +217,28 @@ static int rtc_mc146818_get_time(const struct device *dev, struct rtc_time *tim
229217
goto out;
230218
}
231219

232-
if (!(rtc_read(RTC_REG_D) & RTC_VRT_BIT)) {
220+
if (!(mfd_mc146818_std_read(config->mfd, RTC_REG_D) & RTC_VRT_BIT)) {
233221
ret = -ENODATA;
234222
goto out;
235223
}
236224

237-
while (rtc_read(RTC_UIP) & RTC_UIP_BIT) {
225+
while (mfd_mc146818_std_read(config->mfd, RTC_UIP) & RTC_UIP_BIT) {
238226
continue;
239227
}
240228

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);
229+
cent = mfd_mc146818_std_read(config->mfd, RTC_CENTURY);
230+
year = mfd_mc146818_std_read(config->mfd, RTC_YEAR);
231+
timeptr->tm_mon = mfd_mc146818_std_read(config->mfd, RTC_MONTH) - 1;
232+
timeptr->tm_mday = mfd_mc146818_std_read(config->mfd, RTC_MDAY);
233+
timeptr->tm_wday = mfd_mc146818_std_read(config->mfd, RTC_WDAY) - 1;
234+
timeptr->tm_hour = mfd_mc146818_std_read(config->mfd, RTC_HOUR);
235+
timeptr->tm_min = mfd_mc146818_std_read(config->mfd, RTC_MIN);
236+
timeptr->tm_sec = mfd_mc146818_std_read(config->mfd, RTC_SEC);
249237

250238
timeptr->tm_year = 100 * (int)cent + year - 1900;
251239

252240
timeptr->tm_nsec = 0;
253241
timeptr->tm_yday = 0;
254-
value = rtc_read(RTC_DATA);
255242

256243
/* Check time valid */
257244
if (!rtc_mc146818_validate_time(timeptr)) {
@@ -305,6 +292,7 @@ static int rtc_mc146818_alarm_set_time(const struct device *dev, uint16_t id, ui
305292
const struct rtc_time *timeptr)
306293
{
307294
struct rtc_mc146818_data * const dev_data = dev->data;
295+
const struct rtc_mc146818_config *config = dev->config;
308296
int ret;
309297

310298
k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
@@ -326,23 +314,24 @@ static int rtc_mc146818_alarm_set_time(const struct device *dev, uint16_t id, ui
326314
}
327315

328316
if (mask & RTC_ALARM_TIME_MASK_SECOND) {
329-
rtc_write(RTC_ALARM_SEC, timeptr->tm_sec);
317+
mfd_mc146818_std_write(config->mfd, RTC_ALARM_SEC, timeptr->tm_sec);
330318
} else {
331-
rtc_write(RTC_ALARM_SEC, RTC_ALARM_DC);
319+
mfd_mc146818_std_write(config->mfd, RTC_ALARM_SEC, RTC_ALARM_DC);
332320
}
333321

334322
if (mask & RTC_ALARM_TIME_MASK_MINUTE) {
335-
rtc_write(RTC_ALARM_MIN, timeptr->tm_min);
323+
mfd_mc146818_std_write(config->mfd, RTC_ALARM_MIN, timeptr->tm_min);
336324
} else {
337-
rtc_write(RTC_ALARM_SEC, RTC_ALARM_DC);
325+
mfd_mc146818_std_write(config->mfd, RTC_ALARM_SEC, RTC_ALARM_DC);
338326
}
339327
if (mask & RTC_ALARM_TIME_MASK_HOUR) {
340-
rtc_write(RTC_ALARM_HOUR, timeptr->tm_hour);
328+
mfd_mc146818_std_write(config->mfd, RTC_ALARM_HOUR, timeptr->tm_hour);
341329
} else {
342-
rtc_write(RTC_ALARM_SEC, RTC_ALARM_DC);
330+
mfd_mc146818_std_write(config->mfd, RTC_ALARM_SEC, RTC_ALARM_DC);
343331
}
344332

345-
rtc_write(RTC_DATA, rtc_read(RTC_DATA) | RTC_AIE_BIT);
333+
mfd_mc146818_std_write(config->mfd, RTC_DATA,
334+
mfd_mc146818_std_read(config->mfd, RTC_DATA) | RTC_AIE_BIT);
346335
ret = 0;
347336
out:
348337
k_spin_unlock(&dev_data->lock, key);
@@ -353,6 +342,7 @@ static int rtc_mc146818_alarm_get_time(const struct device *dev, uint16_t id, ui
353342
struct rtc_time *timeptr)
354343
{
355344
struct rtc_mc146818_data * const dev_data = dev->data;
345+
const struct rtc_mc146818_config *config = dev->config;
356346
uint8_t value;
357347
int ret;
358348

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

371361
(*mask) = 0;
372362

373-
value = rtc_read(RTC_ALARM_SEC);
363+
value = mfd_mc146818_std_read(config->mfd, RTC_ALARM_SEC);
374364
if (value <= MAX_SEC) {
375365
timeptr->tm_sec = value;
376366
(*mask) |= RTC_ALARM_TIME_MASK_SECOND;
377367
}
378368

379-
value = rtc_read(RTC_ALARM_MIN);
369+
value = mfd_mc146818_std_read(config->mfd, RTC_ALARM_MIN);
380370
if (value <= MAX_MIN) {
381371
timeptr->tm_min = value;
382372
(*mask) |= RTC_ALARM_TIME_MASK_MINUTE;
383373
}
384374

385-
value = rtc_read(RTC_ALARM_HOUR);
375+
value = mfd_mc146818_std_read(config->mfd, RTC_ALARM_HOUR);
386376
if (value <= MAX_HOUR) {
387377
timeptr->tm_hour = value;
388378
(*mask) |= RTC_ALARM_TIME_MASK_HOUR;
@@ -398,6 +388,7 @@ static int rtc_mc146818_alarm_set_callback(const struct device *dev, uint16_t id
398388
rtc_alarm_callback callback, void *user_data)
399389
{
400390
struct rtc_mc146818_data * const dev_data = dev->data;
391+
const struct rtc_mc146818_config *config = dev->config;
401392

402393
if (id != 0) {
403394
return -EINVAL;
@@ -410,10 +401,14 @@ static int rtc_mc146818_alarm_set_callback(const struct device *dev, uint16_t id
410401

411402
if (callback != NULL) {
412403
/* Enable Alarm callback */
413-
rtc_write(RTC_DATA, (rtc_read(RTC_DATA) | RTC_AIE_BIT));
404+
mfd_mc146818_std_write(config->mfd, RTC_DATA,
405+
(mfd_mc146818_std_read(config->mfd,
406+
RTC_DATA) | RTC_AIE_BIT));
414407
} else {
415408
/* Disable Alarm callback */
416-
rtc_write(RTC_DATA, (rtc_read(RTC_DATA) & (~RTC_AIE_BIT)));
409+
mfd_mc146818_std_write(config->mfd, RTC_DATA,
410+
(mfd_mc146818_std_read(config->mfd,
411+
RTC_DATA) & (~RTC_AIE_BIT)));
417412
}
418413

419414
k_spin_unlock(&dev_data->lock, key);
@@ -444,6 +439,7 @@ static int rtc_mc146818_update_set_callback(const struct device *dev,
444439
rtc_update_callback callback, void *user_data)
445440
{
446441
struct rtc_mc146818_data * const dev_data = dev->data;
442+
const struct rtc_mc146818_config *config = dev->config;
447443

448444
k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
449445

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

453449
if (callback != NULL) {
454450
/* Enable update callback */
455-
rtc_write(RTC_DATA, (rtc_read(RTC_DATA) | RTC_UIE_BIT));
451+
mfd_mc146818_std_write(config->mfd, RTC_DATA,
452+
(mfd_mc146818_std_read(config->mfd,
453+
RTC_DATA) | RTC_UIE_BIT));
456454
} else {
457455
/* Disable update callback */
458-
rtc_write(RTC_DATA, (rtc_read(RTC_DATA) & (~RTC_UIE_BIT)));
456+
mfd_mc146818_std_write(config->mfd, RTC_DATA,
457+
(mfd_mc146818_std_read(config->mfd,
458+
RTC_DATA) & (~RTC_UIE_BIT)));
459459
}
460460

461461

@@ -468,12 +468,13 @@ static int rtc_mc146818_update_set_callback(const struct device *dev,
468468
static void rtc_mc146818_isr(const struct device *dev)
469469
{
470470
struct rtc_mc146818_data * const dev_data = dev->data;
471+
const struct rtc_mc146818_config *config = dev->config;
471472
uint8_t regc;
472473

473474
ARG_UNUSED(dev_data);
474475

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

478479
#if defined(CONFIG_RTC_ALARM)
479480
if (regc & RTC_AF_BIT) {
@@ -514,11 +515,17 @@ static DEVICE_API(rtc, rtc_mc146818_driver_api) = {
514515
#define RTC_MC146818_INIT_FN_DEFINE(n) \
515516
static int rtc_mc146818_init##n(const struct device *dev) \
516517
{ \
517-
rtc_write(RTC_REG_A, \
518+
const struct rtc_mc146818_config *config = dev->config; \
519+
\
520+
if (!device_is_ready(config->mfd)) { \
521+
return -ENODEV; \
522+
} \
523+
mfd_mc146818_std_write(config->mfd, RTC_REG_A, \
518524
_CONCAT(RTC_IN_CLK_DIV_BITS_, \
519525
DT_INST_PROP(n, clock_frequency))); \
520526
\
521-
rtc_write(RTC_REG_B, RTC_DMODE_BIT | RTC_HFORMAT_BIT); \
527+
mfd_mc146818_std_write(config->mfd, \
528+
RTC_REG_B, RTC_DMODE_BIT | RTC_HFORMAT_BIT); \
522529
\
523530
IRQ_CONNECT(DT_INST_IRQN(0), \
524531
DT_INST_IRQ(0, priority), \
@@ -530,14 +537,16 @@ static DEVICE_API(rtc, rtc_mc146818_driver_api) = {
530537
return 0; \
531538
}
532539

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); \
540+
#define RTC_MC146818_DEV_CFG(inst) \
541+
static struct rtc_mc146818_data rtc_mc146818_data##inst; \
542+
\
543+
static const struct rtc_mc146818_config rtc_mc146818_config##inst = { \
544+
.mfd = DEVICE_DT_GET(DT_INST_PARENT(inst))}; \
545+
\
546+
RTC_MC146818_INIT_FN_DEFINE(inst) \
547+
DEVICE_DT_INST_DEFINE(inst, &rtc_mc146818_init##inst, NULL, \
548+
&rtc_mc146818_data##inst, &rtc_mc146818_config##inst,\
549+
POST_KERNEL, CONFIG_RTC_INIT_PRIORITY, \
550+
&rtc_mc146818_driver_api); \
542551

543552
DT_INST_FOREACH_STATUS_OKAY(RTC_MC146818_DEV_CFG)

0 commit comments

Comments
 (0)