uboot/test/dm/rtc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2015 Google, Inc
   4 * Written by Simon Glass <sjg@chromium.org>
   5 */
   6
   7#include <common.h>
   8#include <console.h>
   9#include <dm.h>
  10#include <i2c.h>
  11#include <log.h>
  12#include <rtc.h>
  13#include <asm/io.h>
  14#include <asm/rtc.h>
  15#include <asm/test.h>
  16#include <dm/test.h>
  17#include <test/test.h>
  18#include <test/ut.h>
  19
  20/* Simple RTC sanity check */
  21static int dm_test_rtc_base(struct unit_test_state *uts)
  22{
  23        struct udevice *dev;
  24
  25        ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_RTC, 2, &dev));
  26        ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
  27        ut_assertok(uclass_get_device(UCLASS_RTC, 1, &dev));
  28
  29        return 0;
  30}
  31DM_TEST(dm_test_rtc_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
  32
  33static void show_time(const char *msg, struct rtc_time *time)
  34{
  35        printf("%s: %02d/%02d/%04d %02d:%02d:%02d\n", msg,
  36               time->tm_mday, time->tm_mon, time->tm_year,
  37               time->tm_hour, time->tm_min, time->tm_sec);
  38}
  39
  40static int cmp_times(struct rtc_time *expect, struct rtc_time *time, bool show)
  41{
  42        bool same;
  43
  44        same = expect->tm_sec == time->tm_sec;
  45        same &= expect->tm_min == time->tm_min;
  46        same &= expect->tm_hour == time->tm_hour;
  47        same &= expect->tm_mday == time->tm_mday;
  48        same &= expect->tm_mon == time->tm_mon;
  49        same &= expect->tm_year == time->tm_year;
  50        if (!same && show) {
  51                show_time("expected", expect);
  52                show_time("actual", time);
  53        }
  54
  55        return same ? 0 : -EINVAL;
  56}
  57
  58/* Set and get the time */
  59static int dm_test_rtc_set_get(struct unit_test_state *uts)
  60{
  61        struct rtc_time now, time, cmp;
  62        struct udevice *dev, *emul;
  63        long offset, old_offset, old_base_time;
  64
  65        ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
  66        ut_assertok(dm_rtc_get(dev, &now));
  67
  68        ut_assertok(i2c_emul_find(dev, &emul));
  69        ut_assert(emul != NULL);
  70
  71        /* Tell the RTC to go into manual mode */
  72        old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0);
  73        old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1);
  74
  75        memset(&time, '\0', sizeof(time));
  76        time.tm_mday = 3;
  77        time.tm_mon = 6;
  78        time.tm_year = 2004;
  79        time.tm_sec = 0;
  80        time.tm_min = 18;
  81        time.tm_hour = 18;
  82        ut_assertok(dm_rtc_set(dev, &time));
  83
  84        memset(&cmp, '\0', sizeof(cmp));
  85        ut_assertok(dm_rtc_get(dev, &cmp));
  86        ut_assertok(cmp_times(&time, &cmp, true));
  87
  88        memset(&time, '\0', sizeof(time));
  89        time.tm_mday = 31;
  90        time.tm_mon = 8;
  91        time.tm_year = 2004;
  92        time.tm_sec = 0;
  93        time.tm_min = 18;
  94        time.tm_hour = 18;
  95        ut_assertok(dm_rtc_set(dev, &time));
  96
  97        memset(&cmp, '\0', sizeof(cmp));
  98        ut_assertok(dm_rtc_get(dev, &cmp));
  99        ut_assertok(cmp_times(&time, &cmp, true));
 100
 101        /* Increment by 1 second */
 102        offset = sandbox_i2c_rtc_set_offset(emul, false, 0);
 103        sandbox_i2c_rtc_set_offset(emul, false, offset + 1);
 104
 105        memset(&cmp, '\0', sizeof(cmp));
 106        ut_assertok(dm_rtc_get(dev, &cmp));
 107        ut_asserteq(1, cmp.tm_sec);
 108
 109        /* Check against original offset */
 110        sandbox_i2c_rtc_set_offset(emul, false, old_offset);
 111        ut_assertok(dm_rtc_get(dev, &cmp));
 112        ut_assertok(cmp_times(&now, &cmp, true));
 113
 114        /* Back to the original offset */
 115        sandbox_i2c_rtc_set_offset(emul, false, 0);
 116        memset(&cmp, '\0', sizeof(cmp));
 117        ut_assertok(dm_rtc_get(dev, &cmp));
 118        ut_assertok(cmp_times(&now, &cmp, true));
 119
 120        /* Increment the base time by 1 emul */
 121        sandbox_i2c_rtc_get_set_base_time(emul, old_base_time + 1);
 122        memset(&cmp, '\0', sizeof(cmp));
 123        ut_assertok(dm_rtc_get(dev, &cmp));
 124        if (now.tm_sec == 59) {
 125                ut_asserteq(0, cmp.tm_sec);
 126        } else {
 127                ut_asserteq(now.tm_sec + 1, cmp.tm_sec);
 128        }
 129
 130        old_offset = sandbox_i2c_rtc_set_offset(emul, true, 0);
 131
 132        return 0;
 133}
 134DM_TEST(dm_test_rtc_set_get, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 135
 136static int dm_test_rtc_read_write(struct unit_test_state *uts)
 137{
 138        struct rtc_time time;
 139        struct udevice *dev, *emul;
 140        long old_offset;
 141        u8 buf[4], reg;
 142
 143        ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
 144
 145        memcpy(buf, "car", 4);
 146        ut_assertok(dm_rtc_write(dev, REG_AUX0, buf, 4));
 147        memset(buf, '\0', sizeof(buf));
 148        ut_assertok(dm_rtc_read(dev, REG_AUX0, buf, 4));
 149        ut_asserteq(memcmp(buf, "car", 4), 0);
 150
 151        reg = 'b';
 152        ut_assertok(dm_rtc_write(dev, REG_AUX0, &reg, 1));
 153        memset(buf, '\0', sizeof(buf));
 154        ut_assertok(dm_rtc_read(dev, REG_AUX0, buf, 4));
 155        ut_asserteq(memcmp(buf, "bar", 4), 0);
 156
 157        reg = 't';
 158        ut_assertok(dm_rtc_write(dev, REG_AUX2, &reg, 1));
 159        memset(buf, '\0', sizeof(buf));
 160        ut_assertok(dm_rtc_read(dev, REG_AUX1, buf, 3));
 161        ut_asserteq(memcmp(buf, "at", 3), 0);
 162
 163        ut_assertok(i2c_emul_find(dev, &emul));
 164        ut_assert(emul != NULL);
 165
 166        old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0);
 167        ut_assertok(dm_rtc_get(dev, &time));
 168
 169        ut_assertok(dm_rtc_read(dev, REG_SEC, &reg, 1));
 170        ut_asserteq(time.tm_sec, reg);
 171        ut_assertok(dm_rtc_read(dev, REG_MDAY, &reg, 1));
 172        ut_asserteq(time.tm_mday, reg);
 173
 174        sandbox_i2c_rtc_set_offset(emul, true, old_offset);
 175
 176        return 0;
 177}
 178DM_TEST(dm_test_rtc_read_write, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 179
 180/* Test 'rtc list' command */
 181static int dm_test_rtc_cmd_list(struct unit_test_state *uts)
 182{
 183        console_record_reset();
 184
 185        run_command("rtc list", 0);
 186        ut_assert_nextline("RTC #0 - rtc@43");
 187        ut_assert_nextline("RTC #1 - rtc@61");
 188        ut_assert_console_end();
 189
 190        return 0;
 191}
 192DM_TEST(dm_test_rtc_cmd_list, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 193
 194/* Test 'rtc read' and 'rtc write' commands */
 195static int dm_test_rtc_cmd_rw(struct unit_test_state *uts)
 196{
 197        console_record_reset();
 198
 199        run_command("rtc dev 0", 0);
 200        ut_assert_nextline("RTC #0 - rtc@43");
 201        ut_assert_console_end();
 202
 203        run_command("rtc write 0x30 aabb", 0);
 204        ut_assert_console_end();
 205
 206        run_command("rtc read 0x30 2", 0);
 207        ut_assert_nextline("00000030: aa bb                                              ..");
 208        ut_assert_console_end();
 209
 210        run_command("rtc dev 1", 0);
 211        ut_assert_nextline("RTC #1 - rtc@61");
 212        ut_assert_console_end();
 213
 214        run_command("rtc write 0x30 ccdd", 0);
 215        ut_assert_console_end();
 216
 217        run_command("rtc read 0x30 2", 0);
 218        ut_assert_nextline("00000030: cc dd                                              ..");
 219        ut_assert_console_end();
 220
 221        /*
 222         * Switch back to device #0, check that its aux registers
 223         * still have the same values.
 224         */
 225        run_command("rtc dev 0", 0);
 226        ut_assert_nextline("RTC #0 - rtc@43");
 227        ut_assert_console_end();
 228
 229        run_command("rtc read 0x30 2", 0);
 230        ut_assert_nextline("00000030: aa bb                                              ..");
 231        ut_assert_console_end();
 232
 233        return 0;
 234}
 235DM_TEST(dm_test_rtc_cmd_rw, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 236
 237/* Reset the time */
 238static int dm_test_rtc_reset(struct unit_test_state *uts)
 239{
 240        struct rtc_time now;
 241        struct udevice *dev, *emul;
 242        long old_base_time, base_time;
 243
 244        ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev));
 245        ut_assertok(dm_rtc_get(dev, &now));
 246
 247        ut_assertok(i2c_emul_find(dev, &emul));
 248        ut_assert(emul != NULL);
 249
 250        old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, 0);
 251
 252        ut_asserteq(0, sandbox_i2c_rtc_get_set_base_time(emul, -1));
 253
 254        /* Resetting the RTC should put he base time back to normal */
 255        ut_assertok(dm_rtc_reset(dev));
 256        base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1);
 257        ut_asserteq(old_base_time, base_time);
 258
 259        return 0;
 260}
 261DM_TEST(dm_test_rtc_reset, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 262
 263/* Check that two RTC devices can be used independently */
 264static int dm_test_rtc_dual(struct unit_test_state *uts)
 265{
 266        struct rtc_time now1, now2, cmp;
 267        struct udevice *dev1, *dev2;
 268        struct udevice *emul1, *emul2;
 269        long offset;
 270
 271        ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev1));
 272        ut_assertok(dm_rtc_get(dev1, &now1));
 273        ut_assertok(uclass_get_device(UCLASS_RTC, 1, &dev2));
 274        ut_assertok(dm_rtc_get(dev2, &now2));
 275
 276        ut_assertok(i2c_emul_find(dev1, &emul1));
 277        ut_assert(emul1 != NULL);
 278        ut_assertok(i2c_emul_find(dev2, &emul2));
 279        ut_assert(emul2 != NULL);
 280
 281        offset = sandbox_i2c_rtc_set_offset(emul1, false, -1);
 282        sandbox_i2c_rtc_set_offset(emul2, false, offset + 1);
 283        memset(&cmp, '\0', sizeof(cmp));
 284        ut_assertok(dm_rtc_get(dev2, &cmp));
 285        ut_asserteq(-EINVAL, cmp_times(&now1, &cmp, false));
 286
 287        memset(&cmp, '\0', sizeof(cmp));
 288        ut_assertok(dm_rtc_get(dev1, &cmp));
 289        ut_assertok(cmp_times(&now1, &cmp, true));
 290
 291        return 0;
 292}
 293DM_TEST(dm_test_rtc_dual, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 294