[02733a96] | 1 | /* |
---|
| 2 | * Real Time Clock Driver Wrapper for Libchip |
---|
| 3 | * |
---|
| 4 | * The license and distribution terms for this file may be |
---|
| 5 | * found in the file LICENSE in this distribution or at |
---|
[7050ec70] | 6 | * http://www.rtems.com/license/LICENSE. |
---|
[02733a96] | 7 | * |
---|
| 8 | * $Id$ |
---|
[6128a4a] | 9 | */ |
---|
[02733a96] | 10 | |
---|
| 11 | #include <rtems.h> |
---|
| 12 | #include <libchip/rtc.h> |
---|
| 13 | |
---|
| 14 | /* |
---|
| 15 | * Configuration Information |
---|
| 16 | */ |
---|
| 17 | |
---|
[cbe0357] | 18 | extern size_t RTC_Count; |
---|
[02733a96] | 19 | extern rtems_device_minor_number RTC_Minor; |
---|
| 20 | |
---|
| 21 | int RTC_Present; |
---|
[3758c53c] | 22 | void setRealTimeToRTEMS(void); |
---|
[02733a96] | 23 | |
---|
| 24 | /* |
---|
| 25 | * rtc_initialize |
---|
| 26 | * |
---|
| 27 | * Initialize the RTC driver |
---|
| 28 | */ |
---|
| 29 | |
---|
| 30 | rtems_device_driver rtc_initialize( |
---|
| 31 | rtems_device_major_number major, |
---|
| 32 | rtems_device_minor_number minor_arg, |
---|
| 33 | void *arg |
---|
| 34 | ) |
---|
| 35 | { |
---|
| 36 | rtems_device_minor_number minor; |
---|
| 37 | rtems_status_code status; |
---|
| 38 | |
---|
| 39 | for (minor=0; minor < RTC_Count ; minor++) { |
---|
[6128a4a] | 40 | /* |
---|
[02733a96] | 41 | * First perform the configuration dependent probe, then the |
---|
| 42 | * device dependent probe |
---|
| 43 | */ |
---|
| 44 | |
---|
| 45 | if (RTC_Table[minor].deviceProbe && RTC_Table[minor].deviceProbe(minor)) { |
---|
[6128a4a] | 46 | /* |
---|
[02733a96] | 47 | * Use this device as the primary RTC |
---|
| 48 | */ |
---|
| 49 | RTC_Minor = minor; |
---|
| 50 | RTC_Present = 1; |
---|
| 51 | break; |
---|
| 52 | } |
---|
| 53 | } |
---|
| 54 | |
---|
| 55 | if ( !RTC_Present ) { |
---|
[6128a4a] | 56 | /* |
---|
[02733a96] | 57 | * Failed to find an RTC -- this is not a fatal error. |
---|
| 58 | */ |
---|
| 59 | |
---|
| 60 | return RTEMS_INVALID_NUMBER; |
---|
| 61 | } |
---|
| 62 | |
---|
| 63 | /* |
---|
| 64 | * Register and initialize the primary RTC's |
---|
| 65 | */ |
---|
| 66 | |
---|
| 67 | status = rtems_io_register_name( "/dev/rtc", major, RTC_Minor ); |
---|
| 68 | if (status != RTEMS_SUCCESSFUL) { |
---|
| 69 | rtems_fatal_error_occurred(status); |
---|
| 70 | } |
---|
| 71 | |
---|
| 72 | RTC_Table[minor].pDeviceFns->deviceInitialize( RTC_Minor ); |
---|
| 73 | |
---|
| 74 | /* |
---|
[6128a4a] | 75 | * Now initialize any secondary RTC's |
---|
[02733a96] | 76 | */ |
---|
| 77 | |
---|
| 78 | for ( minor++ ; minor<RTC_Count ; minor++) { |
---|
| 79 | /* |
---|
| 80 | * First perform the configuration dependent probe, then the |
---|
| 81 | * device dependent probe |
---|
| 82 | */ |
---|
| 83 | |
---|
| 84 | if (RTC_Table[minor].deviceProbe && RTC_Table[minor].deviceProbe(minor)) { |
---|
| 85 | status = rtems_io_register_name( |
---|
| 86 | RTC_Table[minor].sDeviceName, |
---|
| 87 | major, |
---|
| 88 | minor ); |
---|
| 89 | if (status != RTEMS_SUCCESSFUL) { |
---|
| 90 | rtems_fatal_error_occurred(status); |
---|
| 91 | } |
---|
| 92 | |
---|
| 93 | /* |
---|
| 94 | * Initialize the hardware device. |
---|
| 95 | */ |
---|
| 96 | |
---|
| 97 | RTC_Table[minor].pDeviceFns->deviceInitialize(minor); |
---|
| 98 | |
---|
| 99 | } |
---|
| 100 | } |
---|
| 101 | |
---|
[3758c53c] | 102 | setRealTimeToRTEMS(); |
---|
[02733a96] | 103 | return RTEMS_SUCCESSFUL; |
---|
| 104 | } |
---|
| 105 | |
---|
| 106 | /*PAGE |
---|
| 107 | * |
---|
| 108 | * This routine copies the time from the real time clock to RTEMS |
---|
[6128a4a] | 109 | * |
---|
[02733a96] | 110 | * Input parameters: NONE |
---|
[6128a4a] | 111 | * |
---|
[02733a96] | 112 | * Output parameters: NONE |
---|
| 113 | * |
---|
| 114 | * Return values: NONE |
---|
| 115 | */ |
---|
| 116 | |
---|
| 117 | void setRealTimeToRTEMS() |
---|
| 118 | { |
---|
| 119 | rtems_time_of_day rtc_tod; |
---|
| 120 | |
---|
| 121 | if (!RTC_Present) |
---|
| 122 | return; |
---|
| 123 | |
---|
| 124 | RTC_Table[RTC_Minor].pDeviceFns->deviceGetTime(RTC_Minor, &rtc_tod); |
---|
| 125 | rtems_clock_set( &rtc_tod ); |
---|
| 126 | } |
---|
| 127 | |
---|
| 128 | /*PAGE |
---|
| 129 | * |
---|
| 130 | * setRealTimeFromRTEMS |
---|
| 131 | * |
---|
| 132 | * This routine copies the time from RTEMS to the real time clock |
---|
[6128a4a] | 133 | * |
---|
[02733a96] | 134 | * Input parameters: NONE |
---|
[6128a4a] | 135 | * |
---|
[02733a96] | 136 | * Output parameters: NONE |
---|
| 137 | * |
---|
| 138 | * Return values: NONE |
---|
| 139 | */ |
---|
| 140 | |
---|
| 141 | void setRealTimeFromRTEMS() |
---|
| 142 | { |
---|
| 143 | rtems_time_of_day rtems_tod; |
---|
| 144 | |
---|
| 145 | if (!RTC_Present) |
---|
| 146 | return; |
---|
| 147 | |
---|
| 148 | rtems_clock_get( RTEMS_CLOCK_GET_TOD, &rtems_tod ); |
---|
| 149 | RTC_Table[RTC_Minor].pDeviceFns->deviceSetTime(RTC_Minor, &rtems_tod); |
---|
| 150 | } |
---|
| 151 | |
---|
[509dc7c1] | 152 | /*PAGE |
---|
| 153 | * |
---|
| 154 | * getRealTime |
---|
| 155 | * |
---|
| 156 | * This routine reads the current time from the RTC. |
---|
[6128a4a] | 157 | * |
---|
[509dc7c1] | 158 | * Input parameters: NONE |
---|
[6128a4a] | 159 | * |
---|
[509dc7c1] | 160 | * Output parameters: NONE |
---|
| 161 | * |
---|
| 162 | * Return values: NONE |
---|
| 163 | */ |
---|
| 164 | |
---|
| 165 | void getRealTime( |
---|
| 166 | rtems_time_of_day *tod |
---|
| 167 | ) |
---|
| 168 | { |
---|
| 169 | |
---|
| 170 | if (!RTC_Present) |
---|
| 171 | return; |
---|
| 172 | |
---|
| 173 | RTC_Table[RTC_Minor].pDeviceFns->deviceGetTime(RTC_Minor, tod); |
---|
| 174 | } |
---|
| 175 | |
---|
| 176 | /*PAGE |
---|
[6128a4a] | 177 | * |
---|
[509dc7c1] | 178 | * setRealTime |
---|
[6128a4a] | 179 | * |
---|
[509dc7c1] | 180 | * This routine sets the RTC. |
---|
[6128a4a] | 181 | * |
---|
[509dc7c1] | 182 | * Input parameters: NONE |
---|
[6128a4a] | 183 | * |
---|
[509dc7c1] | 184 | * Output parameters: NONE |
---|
| 185 | * |
---|
| 186 | * Return values: NONE |
---|
| 187 | */ |
---|
| 188 | |
---|
[6128a4a] | 189 | /* XXX this routine should be part of the public RTEMS interface */ |
---|
[509dc7c1] | 190 | rtems_boolean _TOD_Validate( rtems_time_of_day *tod ); |
---|
| 191 | |
---|
| 192 | int setRealTime( |
---|
| 193 | rtems_time_of_day *tod |
---|
| 194 | ) |
---|
| 195 | { |
---|
[6128a4a] | 196 | |
---|
[509dc7c1] | 197 | if (!RTC_Present) |
---|
| 198 | return -1; |
---|
[6128a4a] | 199 | |
---|
[509dc7c1] | 200 | if ( !_TOD_Validate(tod) ) |
---|
| 201 | return -1; |
---|
| 202 | |
---|
| 203 | RTC_Table[RTC_Minor].pDeviceFns->deviceSetTime(RTC_Minor, tod); |
---|
| 204 | return 0; |
---|
| 205 | } |
---|
| 206 | |
---|
[02733a96] | 207 | /*PAGE |
---|
| 208 | * |
---|
| 209 | * checkRealTime |
---|
| 210 | * |
---|
| 211 | * This routine reads the returns the variance betweent the real time and |
---|
| 212 | * rtems time. |
---|
[6128a4a] | 213 | * |
---|
[02733a96] | 214 | * Input parameters: NONE |
---|
[6128a4a] | 215 | * |
---|
[02733a96] | 216 | * Output parameters: NONE |
---|
| 217 | * |
---|
[6128a4a] | 218 | * Return values: |
---|
[509dc7c1] | 219 | * int The differance between the real time clock and rtems time. |
---|
[02733a96] | 220 | */ |
---|
| 221 | |
---|
[6128a4a] | 222 | /* XXX this routine should be part of the public RTEMS interface */ |
---|
[a2ac7e10] | 223 | uint32_t _TOD_To_seconds( rtems_time_of_day *tod ); |
---|
[509dc7c1] | 224 | |
---|
[02733a96] | 225 | int checkRealTime() |
---|
| 226 | { |
---|
| 227 | rtems_time_of_day rtems_tod; |
---|
| 228 | rtems_time_of_day rtc_tod; |
---|
[a2ac7e10] | 229 | uint32_t rtems_time; |
---|
| 230 | uint32_t rtc_time; |
---|
[02733a96] | 231 | |
---|
| 232 | if (!RTC_Present) |
---|
[509dc7c1] | 233 | return -1; |
---|
[02733a96] | 234 | |
---|
| 235 | rtems_clock_get( RTEMS_CLOCK_GET_TOD, &rtems_tod ); |
---|
| 236 | RTC_Table[RTC_Minor].pDeviceFns->deviceGetTime(RTC_Minor, &rtc_tod); |
---|
| 237 | |
---|
[6128a4a] | 238 | rtems_time = _TOD_To_seconds( &rtems_tod ); |
---|
| 239 | rtc_time = _TOD_To_seconds( &rtc_tod ); |
---|
[509dc7c1] | 240 | |
---|
| 241 | return rtems_time - rtc_time; |
---|
[02733a96] | 242 | } |
---|