A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

Ingenic Jz4740: simplify RTC driver (you will need to re-set the clock)

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24201 a1c6a512-1295-4272-9138-f99709370657

+38 -251
+38 -251
firmware/drivers/rtc/rtc_jz4740.c
··· 30 30 #include "timefuncs.h" 31 31 #include "logf.h" 32 32 33 - static const unsigned int yearday[5] = {0, 366, 366+365, 366+365*2, 366+365*3}; 34 - static const unsigned int sweekday = 6; 35 - static const unsigned int sum_monthday[13] = { 36 - 0, 37 - 31, 38 - 31+28, 39 - 31+28+31, 40 - 31+28+31+30, 41 - 31+28+31+30+31, 42 - 31+28+31+30+31+30, 43 - 31+28+31+30+31+30+31, 44 - 31+28+31+30+31+30+31+31, 45 - 31+28+31+30+31+30+31+31+30, 46 - 31+28+31+30+31+30+31+31+30+31, 47 - 31+28+31+30+31+30+31+31+30+31+30, 48 - 365 49 - }; 50 - 51 - static unsigned int jz_mktime(int year, int mon, int day, int hour, int min, 52 - int sec) 33 + /* Stolen from dietlibc-0.29/libugly/gmtime_r.c (GPLv2) */ 34 + #define SPD (24*60*60) 35 + #define ISLEAP(year) (!(year%4) && ((year%100) || !(year%400))) 36 + static void _localtime(const time_t t, struct tm *r) 53 37 { 54 - unsigned int seccounter; 38 + time_t i; 39 + register time_t work = t % SPD; 40 + static int m_to_d[12] = /* This could be shared with mktime() */ 41 + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; 55 42 56 - if (year < 2000) 57 - year = 2000; 58 - year -= 2000; 59 - seccounter = (year/4)*(365*3+366); 60 - seccounter += yearday[year%4]; 61 - if (year%4) 62 - seccounter += sum_monthday[mon-1]; 63 - else 64 - if (mon >= 3) 65 - seccounter += sum_monthday[mon-1]+1; 66 - else 67 - seccounter += sum_monthday[mon-1]; 68 - seccounter += day-1; 69 - seccounter *= 24; 70 - seccounter += hour; 71 - seccounter *= 60; 72 - seccounter += min; 73 - seccounter *= 60; 74 - seccounter += sec; 43 + r->tm_sec = work % 60; 44 + work /= 60; 45 + r->tm_min = work % 60; 46 + r->tm_hour = work / 60; 47 + work = t / SPD; 48 + r->tm_wday = (4 + work) % 7; 75 49 76 - return seccounter; 77 - } 78 - 79 - static void jz_gettime(unsigned int rtc, int *year, int *mon, int *day, 80 - int *hour, int *min, int *sec, int *weekday) 81 - { 82 - unsigned int tday, tsec, i, tmp; 83 - 84 - tday = rtc/(24*3600); 85 - *weekday = ((tday % 7) + sweekday) % 7; 86 - *year = (tday/(366+365*3)) * 4; 87 - tday = tday%(366+365*3); 88 - for (i=0;i<5;i++) 50 + for (i=1970; ; ++i) 89 51 { 90 - if (tday<yearday[i]) 91 - { 92 - *year += i-1; 93 - tday -= yearday[i-1]; 52 + register time_t k = ISLEAP(i) ? 366 : 365; 53 + 54 + if (work >= k) 55 + work -= k; 56 + else 94 57 break; 95 - } 96 58 } 97 - for (i=0;i<13;i++) 59 + 60 + r->tm_year = i - 1900; 61 + r->tm_yday = work; 62 + 63 + r->tm_mday = 1; 64 + if (ISLEAP(i) && (work>58)) 98 65 { 99 - tmp = sum_monthday[i]; 100 - if (((*year%4) == 0) && (i>=2)) 101 - tmp += 1; 102 - if (tday<tmp) 103 - { 104 - *mon = i; 105 - tmp = sum_monthday[i-1]; 106 - if (((*year%4) == 0) && ((i-1)>=2)) 107 - tmp += 1; 108 - *day = tday - tmp + 1; 109 - break; 110 - } 66 + if (work==59) 67 + r->tm_mday=2; /* 29.2. */ 68 + 69 + work-=1; 111 70 } 112 - tsec = rtc % (24 * 3600); 113 - *hour = tsec / 3600; 114 - *min = (tsec / 60) % 60; 115 - *sec = tsec - *hour*3600 - *min*60; 116 - *year += 2000; 71 + 72 + for (i=11; i && (m_to_d[i] > work); --i); 73 + r->tm_mon = i; 74 + r->tm_mday += work - m_to_d[i]; 117 75 } 118 76 119 77 int rtc_read_datetime(struct tm *tm) 120 78 { 121 - unsigned int sec,mon,mday,wday,year,hour,min; 122 - 123 - /* 124 - * Only the values that we read from the RTC are set. We leave 125 - * tm_wday, tm_yday and tm_isdst untouched. Even though the 126 - * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated 127 - * by the RTC when initially set to a non-zero value. 128 - */ 129 - jz_gettime(REG_RTC_RSR, &year, &mon, &mday, &hour, &min, &sec, &wday); 130 - 131 - year -= 2000; 132 - 133 - tm->tm_sec = sec; 134 - tm->tm_min = min; 135 - tm->tm_hour = hour; 136 - tm->tm_mday = mday; 137 - tm->tm_wday = wday; 138 - /* Don't use centry, but start from year 1970 */ 139 - tm->tm_mon = mon; 140 - if (year <= 69) 141 - year += 100; 142 - tm->tm_year = year; 79 + _localtime(REG_RTC_RSR, tm); 143 80 144 81 return 1; 145 82 } 146 83 147 84 int rtc_write_datetime(const struct tm *tm) 148 85 { 149 - unsigned int year, lval; 150 - 151 - year = tm->tm_year; 152 - /* Don't use centry, but start from year 1970 */ 153 - if (year > 69) 154 - year -= 100; 155 - year += 2000; 156 - 157 - lval = jz_mktime(year, tm->tm_mon, tm->tm_mday, tm->tm_hour, 158 - tm->tm_min, tm->tm_sec); 86 + time_t val = mktime((struct tm*)tm); 159 87 160 88 __cpm_start_rtc(); 161 89 udelay(100); 162 - REG_RTC_RSR = lval; 90 + REG_RTC_RSR = val; 163 91 __cpm_stop_rtc(); 164 - 165 - return 0; 166 - } 167 92 168 - #if 0 169 - void get_rtc_alm_time(struct rtc_time *alm_tm) 170 - { 171 - unsigned int sec,mon,mday,wday,year,hour,min; 172 - unsigned int lval; 173 - unsigned long flags; 174 - /* 175 - * Only the values that we read from the RTC are set. That 176 - * means only tm_hour, tm_min, and tm_sec. 177 - */ 178 - lval = REG_RTC_RSAR; 179 - jz_gettime(lval, &year, &mon, &mday, &hour, &min, &sec, &wday); 180 - 181 - alm_tm->tm_sec = sec; 182 - alm_tm->tm_min = min; 183 - alm_tm->tm_hour = hour; 184 - } 185 - 186 - 187 - int rtc_ioctl(unsigned int cmd,struct rtc_time *val,unsigned int epo) 188 - { 189 - struct rtc_time wtime; 190 - switch (cmd) { 191 - case RTC_ALM_READ: /* Read the present alarm time */ 192 - /* 193 - * This returns a struct rtc_time. Reading >= 0xc0 194 - * means "don't care" or "match all". Only the tm_hour, 195 - * tm_min, and tm_sec values are filled in. 196 - */ 197 - get_rtc_alm_time(val); 198 - break; 199 - case RTC_ALM_SET: /* Store a time into the alarm */ 200 - { 201 - unsigned char ahrs, amin, asec; 202 - unsigned int sec,mon,mday,wday,year,hour,min; 203 - unsigned int lval; 204 - unsigned long flags; 205 - struct rtc_time alm_tm; 206 - 207 - alm_tm = *val; 208 - ahrs = alm_tm.tm_hour; 209 - amin = alm_tm.tm_min; 210 - asec = alm_tm.tm_sec; 211 - 212 - 213 - 214 - if (ahrs >= 24) 215 - return -1; 216 - 217 - if (amin >= 60) 218 - return -1; 219 - 220 - if (asec >= 60) 221 - return -1; 222 - 223 - flags = spin_lock_irqsave(); 224 - lval = REG_RTC_RSR; 225 - jz_gettime(lval, &year, &mon, &mday, &hour, &min, &sec, &wday); 226 - hour = ahrs; 227 - min = amin; 228 - sec = asec; 229 - lval = jz_mktime(year, mon, mday, hour, min, sec); 230 - REG_RTC_RSAR = lval; 231 - spin_unlock_irqrestore(flags); 232 - break; 233 - } 234 - case RTC_RD_TIME: /* Read the time/date from RTC */ 235 - get_rtc_time(val); 236 - break; 237 - case RTC_SET_TIME: /* Set the RTC */ 238 - { 239 - struct rtc_time rtc_tm; 240 - unsigned int mon, day, hrs, min, sec, leap_yr, date; 241 - unsigned int yrs; 242 - unsigned int lval; 243 - unsigned long flags; 244 - 245 - rtc_tm = *val; 246 - yrs = rtc_tm.tm_year;// + 1900; 247 - mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ 248 - day = rtc_tm.tm_wday; 249 - date = rtc_tm.tm_mday; 250 - hrs = rtc_tm.tm_hour; 251 - min = rtc_tm.tm_min; 252 - sec = rtc_tm.tm_sec; 253 - 254 - 255 - if (yrs < 1970) 256 - return -EINVAL; 257 - leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); 258 - 259 - if ((mon > 12) || (date == 0)) 260 - return -EINVAL; 261 - 262 - if (date > (days_in_mo[mon] + ((mon == 2) && leap_yr))) 263 - return -EINVAL; 264 - 265 - if ((hrs >= 24) || (min >= 60) || (sec >= 60)) 266 - return -EINVAL; 267 - 268 - if ((yrs -= epoch) > 255) /* They are unsigned */ 269 - return -EINVAL; 270 - 271 - flags = spin_lock_irqsave(); 272 - /* These limits and adjustments are independant of 273 - * whether the chip is in binary mode or not. 274 - */ 275 - 276 - if (yrs > 169) { 277 - spin_unlock_irqrestore(flags); 278 - return -EINVAL; 279 - } 280 - 281 - yrs += epoch; 282 - lval = jz_mktime(yrs, mon, date, hrs, min, sec); 283 - REG_RTC_RSR = lval; 284 - /* FIXME: maybe we need to write alarm register here. */ 285 - spin_unlock_irqrestore(flags); 286 - 287 - return 0; 288 - } 289 - break; 290 - case RTC_EPOCH_READ: /* Read the epoch. */ 291 - epo = epoch; 292 - return 0; 293 - case RTC_EPOCH_SET: /* Set the epoch. */ 294 - /* 295 - * There were no RTC clocks before 1900. 296 - */ 297 - if (epo < 1900) 298 - return -EINVAL; 299 - 300 - epoch = epo; 301 - return 0; 302 - default: 303 - return -EINVAL; 304 - } 305 - return -EINVAL; 93 + return 0; 306 94 } 307 - #endif 308 95 309 96 void rtc_init(void) 310 97 {