Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

RTC s35380a - cleanup and more comments

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

+77 -39
+77 -39
firmware/drivers/rtc/rtc_s35380a.c
··· 42 42 #define CLOCK_CORR_REG 6 43 43 #define FREE_REG 7 44 44 45 - /* STATUS_REG1 flags 46 - * bits order is reversed 47 - */ 48 - #define STATUS_REG1_POC 0x01 49 - #define STATUS_REG1_BLD 0x02 50 - #define STATUS_REG1_INT2 0x04 51 - #define STATUS_REG1_INT1 0x08 52 - #define STATUS_REG1_SC1 0x10 53 - #define STATUS_REG1_SC0 0x20 54 - #define STATUS_REG1_H1224 0x40 55 - #define STATUS_REG1_RESET 0x80 45 + /* STATUS_REG1 flags */ 46 + #define STATUS_REG1_POC 0x80 47 + #define STATUS_REG1_BLD 0x40 48 + #define STATUS_REG1_INT2 0x20 49 + #define STATUS_REG1_INT1 0x10 50 + #define STATUS_REG1_SC1 0x08 51 + #define STATUS_REG1_SC0 0x04 52 + #define STATUS_REG1_H1224 0x02 53 + #define STATUS_REG1_RESET 0x01 56 54 57 - /* STATUS_REG2 flags 58 - * bits order is reversed 59 - */ 60 - #define STATUS_REG2_TEST 0x01 61 - #define STATUS_REG2_INT2AE 0x02 62 - #define STATUS_REG2_INT2ME 0x04 63 - #define STATUS_REG2_INT2FE 0x08 64 - #define STATUS_REG2_32kE 0x10 65 - #define STATUS_REG2_INT1AE 0x20 66 - #define STATUS_REG2_INT1ME 0x40 67 - #define STATUS_REG2_INT1FE 0x80 55 + /* STATUS_REG2 flags */ 56 + #define STATUS_REG2_TEST 0x80 57 + #define STATUS_REG2_INT2AE 0x40 58 + #define STATUS_REG2_INT2ME 0x20 59 + #define STATUS_REG2_INT2FE 0x10 60 + #define STATUS_REG2_32kE 0x08 61 + #define STATUS_REG2_INT1AE 0x04 62 + #define STATUS_REG2_INT1ME 0x02 63 + #define STATUS_REG2_INT1FE 0x01 68 64 69 65 /* REALTIME_DATA register bytes */ 70 66 #define TIME_YEAR 0 ··· 95 91 96 92 static bool int_flag; 97 93 94 + /* s35380a chip has reversed bits order in byte 95 + * This is little helper function to deal with 96 + */ 98 97 static void reverse_bits(unsigned char* v, int size) 99 98 { 100 99 static const unsigned char flipnibble[] = ··· 108 107 } 109 108 } 110 109 110 + /* Read 'size' bytes from RTC 'reg' and put data in 'buf' 111 + * bits are reversed in data bytes afterwards so they appear in regular order 112 + * return i2c transfer code 113 + */ 114 + static int rtc_read(unsigned char reg, unsigned char *buf, int size) 115 + { 116 + int rc; 117 + rc = i2c_read(I2C_IFACE_1, RTC_ADDR|(reg<<1), buf, size); 118 + reverse_bits(buf, size); 119 + return rc; 120 + } 121 + 122 + /* Write 'size' bytes to RTC 'reg' and put data in 'buf' 123 + * bits are reversed in data bytes prior to sending them to RTC 124 + * return i2c transfer code 125 + */ 126 + static int rtc_write(unsigned char reg, unsigned char *buf, int size) 127 + { 128 + int rc; 129 + reverse_bits(buf, size); 130 + rc = i2c_write(I2C_IFACE_1, RTC_ADDR|(reg<<1), buf, size); 131 + return rc; 132 + } 133 + 134 + /* Reset RTC by writing '1' to RESET bit in STATUS_REG1 */ 111 135 static inline void rtc_reset(void) 112 136 { 113 137 unsigned char reg = STATUS_REG1_RESET; 114 - i2c_write(I2C_IFACE_1, RTC_ADDR|(STATUS_REG1<<1), &reg, 1); 138 + rtc_write(STATUS_REG1, &reg, 1); 115 139 } 116 140 141 + /* Initialize RTC (according to scheme outlined in datasheet). 142 + * Configure chip to 24h time format. 143 + */ 117 144 void rtc_init(void) 118 145 { 119 146 unsigned char reg; ··· 122 149 if ( initialized ) 123 150 return; 124 151 125 - i2c_read(I2C_IFACE_1, RTC_ADDR|(STATUS_REG1<<1), &reg, 1); 152 + rtc_read(STATUS_REG1, &reg, 1); 126 153 127 154 /* cache INT1, INT2 flags as reading the register seem to clear 128 155 * this bits (which is not described in datasheet) ··· 133 160 if ( (reg & STATUS_REG1_POC) || (reg & STATUS_REG1_BLD)) 134 161 rtc_reset(); 135 162 136 - i2c_read(I2C_IFACE_1, RTC_ADDR|(STATUS_REG2<<1), &reg, 1); 163 + rtc_read(STATUS_REG2, &reg, 1); 137 164 138 165 /* test TEST flag */ 139 166 if ( reg & STATUS_REG2_TEST ) ··· 141 168 142 169 /* setup 24h time format */ 143 170 reg = STATUS_REG1_H1224; 144 - i2c_write(I2C_IFACE_1, RTC_ADDR|(STATUS_REG1<<1), &reg, 1); 171 + rtc_write(STATUS_REG1, &reg, 1); 145 172 146 173 initialized = true; 147 174 } 148 175 176 + /* Read realtime data register */ 149 177 int rtc_read_datetime(struct tm *tm) 150 178 { 151 179 unsigned char buf[TIME_REG_SIZE]; 152 180 unsigned int i; 153 181 int ret; 154 182 155 - ret = i2c_read(I2C_IFACE_1, RTC_ADDR|(REALTIME_DATA1<<1), buf, sizeof(buf)); 156 - reverse_bits(buf, sizeof(buf)); 183 + ret = rtc_read(REALTIME_DATA1, buf, sizeof(buf)); 157 184 158 185 buf[TIME_HOUR] &= 0x3f; /* mask out p.m. flag */ 159 186 ··· 171 198 return ret; 172 199 } 173 200 201 + /* Write to realtime data register */ 174 202 int rtc_write_datetime(const struct tm *tm) 175 203 { 176 204 unsigned char buf[TIME_REG_SIZE]; ··· 188 216 for (i = 0; i < sizeof(buf); i++) 189 217 buf[i] = DEC2BCD(buf[i]); 190 218 191 - reverse_bits(buf, sizeof(buf)); 192 - ret = i2c_write(I2C_IFACE_1, RTC_ADDR|(REALTIME_DATA1<<1), buf, sizeof(buf)); 219 + ret = rtc_write(REALTIME_DATA1, buf, sizeof(buf)); 193 220 194 221 return ret; 195 222 } 196 223 197 224 #ifdef HAVE_RTC_ALARM 225 + /* Set alarm (INT1) data register */ 198 226 void rtc_set_alarm(int h, int m) 199 227 { 200 228 unsigned char buf[ALARM_REG_SIZE]; ··· 207 235 buf[ALARM_HOUR] = DEC2BCD(h) | A1HE; 208 236 buf[ALARM_WEEKDAY] = 0; 209 237 210 - /* AM/PM flag have to be set properly regardles of 238 + /* AM/PM flag has to be set properly regardles of 211 239 * time format used (H1224 flag in STATUS_REG1) 212 240 * this is not described in datasheet for s35380a 213 241 * but is somehow described in datasheet for s35390a ··· 215 243 if ( h >= 12 ) 216 244 buf[ALARM_HOUR] |= AMPM; 217 245 218 - reverse_bits(buf, sizeof(buf)); 219 - i2c_write(I2C_IFACE_1, RTC_ADDR|(INT1_REG<<1), buf, sizeof(buf)); 246 + rtc_write(INT1_REG, buf, sizeof(buf)); 220 247 } 221 248 249 + /* Read alarm (INT1) data register */ 222 250 void rtc_get_alarm(int *h, int *m) 223 251 { 224 252 unsigned char buf[ALARM_REG_SIZE]; ··· 227 255 rtc_enable_alarm(true); 228 256 229 257 /* read the content of INT1 register */ 230 - i2c_read(I2C_IFACE_1, RTC_ADDR|(INT1_REG<<1), buf, sizeof(buf)); 231 - reverse_bits(buf, sizeof(buf)); 258 + rtc_read(INT1_REG, buf, sizeof(buf)); 232 259 233 - *h = BCD2DEC(buf[ALARM_HOUR] & 0x3f); /* mask out A1HE and PM/AM flag */ 234 - *m = BCD2DEC(buf[ALARM_MINUTE] & 0x7f); /* mask out A1mE */ 260 + *h = BCD2DEC(buf[ALARM_HOUR] & 0x3f); /* mask out A1HE and PM/AM bits */ 261 + *m = BCD2DEC(buf[ALARM_MINUTE] & 0x7f); /* mask out A1mE bit */ 235 262 263 + /* Disable alarm - this is not strictly needed in rockbox 264 + * as after rtc_get_alarm() rtc_set_alarm() or rtc_enable_alarm(false) 265 + * are called. I just found this weird that simple reading register 266 + * changes alarm settings. 267 + */ 236 268 rtc_enable_alarm(false); 237 269 } 238 270 271 + /* Check if we just triggered alarm. 272 + * We check both INT1 and INT2. Rockbox uses only INT1 but 273 + * OF in MPIO HD300 uses both 274 + */ 239 275 bool rtc_check_alarm_flag(void) 240 276 { 241 277 unsigned char reg; 242 - i2c_read(I2C_IFACE_1, RTC_ADDR|(STATUS_REG1<<1), &reg, 1); 278 + rtc_read(STATUS_REG1, &reg, 1); 243 279 244 280 return ((reg & STATUS_REG1_INT1) || (reg & STATUS_REG1_INT2)); 245 281 } 246 282 283 + /* Enable/disable alarm function */ 247 284 void rtc_enable_alarm(bool enable) 248 285 { 249 286 unsigned char reg = 0; ··· 251 288 if (enable) 252 289 reg = STATUS_REG2_INT1AE; 253 290 254 - i2c_write(I2C_IFACE_1, RTC_ADDR|(STATUS_REG2<<1), &reg, 1); 291 + rtc_write(STATUS_REG2, &reg, 1); 255 292 } 256 293 294 + /* Return true if wakeup is due to RTC alarm */ 257 295 bool rtc_check_alarm_started(bool release_alarm) 258 296 { 259 297 static bool run_before;