unsigned long rtc_time_s3c2410(unsigned base) { struct tm tm; hwi_add_device(HWI_ITEM_BUS_UNKNOWN, HWI_ITEM_DEVCLASS_RTC, "s3c2410", 0); hwi_add_location(base, S3C2410_RTC_SIZE, 0, hwi_find_as(base, 1)); // get the current time from the RTC, and convert it to seconds since epoch chip_access(base, 0, 0, S3C2410_RTC_SIZE); // enable RTC chip_write8(S3C2410_RTCCON, chip_read8(S3C2410_RTCCON) | 1); // convert BCD to binary tm.tm_sec = bcd2bin(chip_read8(S3C2410_BCDSEC) & 0xff); // seconds tm.tm_min = bcd2bin(chip_read8(S3C2410_BCDMIN) & 0xff); // minutes tm.tm_hour = bcd2bin(chip_read8(S3C2410_BCDHOUR) & 0xff); // hours tm.tm_mday = bcd2bin(chip_read8(S3C2410_BCDDAY) & 0xff); // day tm.tm_mon = bcd2bin(chip_read8(S3C2410_BCDMON) & 0xff) -1; // month tm.tm_year = (bcd2bin(chip_read8(S3C2410_BCDYEAR) & 0xff))+100; // year chip_done(); return(calc_time_t(&tm)); }
void init_8250(unsigned channel, const char *init, const char *defaults) { unsigned long baud; unsigned long div; unsigned long clk; paddr_t base; unsigned shift; baud = 0; parse_line(channel, defaults, &baud, &clk, &div); parse_line(channel, init, &baud, &clk, &div); base = dbg_device[channel].base; shift = dbg_device[channel].shift; chip_access(base, shift, 0, REG_MS); // Wait for all pending characters to be output... do { } while(!(chip_read8(REG_LS) & LSR_TSRE)); if(baud != 0) { unsigned count = clk / (baud * div); // Program divisor latch chip_write8(REG_LC, LCR_DLAB); chip_write8(REG_DL0, count & 0xff); chip_write8(REG_DL1, count >> 8); chip_write8(REG_LC, 0x03); }
unsigned long rtc_time_ds1386(paddr_t base, unsigned reg_shift, int mmap, int cent_reg) { struct tm tm; unsigned cent; //Tell Neutrino what kind of chip for 'rtc' utility hwi_add_rtc("ds1386", base, reg_shift, 16, mmap, cent_reg); chip_access(base, reg_shift, mmap, 16); do { // convert BCD to binary tm.tm_sec = bcd2bin(chip_read8(1)); // seconds tm.tm_min = bcd2bin(chip_read8(2)); // minutes tm.tm_hour = bcd2bin(chip_read8(4) & 0x3f); // hours tm.tm_mday = bcd2bin(chip_read8(8)); // day tm.tm_mon = bcd2bin(chip_read8(9) & 0x3f) - 1; // month tm.tm_year = bcd2bin(chip_read8(10)); // year //Loop while time inconsistent } while(tm.tm_sec != bcd2bin(chip_read8(1))); if(cent_reg >= 0) { cent = bcd2bin(chip_read8(cent_reg)); // century if(cent == 20) tm.tm_year += 100; } else if(tm.tm_year < 70) { tm.tm_year += 100; } chip_done(); return(calc_time_t(&tm)); }
unsigned long rtc_time_rtc72423(paddr_t base, unsigned reg_shift, int mmap, int cent_reg) { struct tm tm; unsigned bottom; //Tell Neutrino what kind of chip for 'rtc' utility hwi_add_rtc("rtc72423", base, reg_shift, 16, mmap, cent_reg); chip_access(base, reg_shift, mmap, 16); do { // get the data bottom = chip_read8(0); tm.tm_sec = bcd2bin((chip_read8(1) <<4) | bottom); tm.tm_min = bcd2bin((chip_read8(3) <<4) | chip_read8(2)); tm.tm_hour = bcd2bin(((chip_read8(5) & 3) <<4) | chip_read8(4)); tm.tm_mday = bcd2bin((chip_read8(7) <<4) | chip_read8(6)); tm.tm_mon = bcd2bin((chip_read8(9) <<4) | chip_read8(8)); tm.tm_year = bcd2bin((chip_read8(11) <<4) | chip_read8(10)); //Loop while time inconsistent } while(bottom != chip_read8(0)); chip_done(); if(tm.tm_year < 70) tm.tm_year += 100; return(calc_time_t(&tm)); }
unsigned long rtc_time_omap(unsigned base) { struct tm tm; hwi_add_device(HWI_ITEM_BUS_UNKNOWN, HWI_ITEM_DEVCLASS_RTC, "omap", 0); hwi_add_location(base, OMAP_RTC_SIZE, 0, hwi_find_as(base, 1)); // get the current time from the RTC, and convert it to seconds since epoch chip_access(base, 0, 0, OMAP_RTC_SIZE); // start the RTC, if it's not already running chip_write32(OMAP_RTC_CTRL, 0x01); // convert BCD to binary tm.tm_sec = bcd2bin(chip_read32(OMAP_RTC_SECONDS) & 0xff); // seconds tm.tm_min = bcd2bin(chip_read32(OMAP_RTC_MINUTES) & 0xff); // minutes tm.tm_hour = bcd2bin(chip_read32(OMAP_RTC_HOURS) & 0xff); // hours tm.tm_mday = bcd2bin(chip_read32(OMAP_RTC_DAYS) & 0xff); // day tm.tm_mon = bcd2bin(chip_read32(OMAP_RTC_MONTHS) & 0xff); // month tm.tm_year = (bcd2bin(chip_read32(OMAP_RTC_YEARS) & 0xff))+100; // year chip_done(); return(calc_time_t(&tm)); }
/******************************************************************************* * init_ep93xx_uart * * Initialise UART <channel> * * note that updates to the LNCTRL registers MUST occur as 8 bit writes to * the LOW, MID and finally the HIGH register. This is true even if the * HIGH register value will not change (ie. you must read it out then write * it back). * The Low and Mid registers hold the LSB and MSB of the baudrate divisor. * * The baud rate divisor is caclulated as follows (pg 14-21 of EP93xx Users Guide) * * BAUDDIV = (FUARTCLK / 16 * Baud rate)) – 1 * */ void init_ep93xx_uart(unsigned channel, const char *init, const char *defaults) { unsigned baud = 0; unsigned clk = 0; uint16_t baudrate_div; const unsigned long fuart_clk = ep93xx_get_uartclk(); /* get the baud rate from the defaults string */ parse_line(channel, defaults, &baud, &clk); ASSERT(baud != 0); /* we don't require the 'clk' option but if its passed it must agree with get_fuartclk() */ ASSERT((clk == 0) || (clk == fuart_clk)); /* startup expects UART1 and UART2 for the debug devices (we don't care which is which) */ ASSERT((dbg_device[channel].base == EP93xx_UART1_BASE) || (dbg_device[channel].base == EP93xx_UART2_BASE)); chip_access(dbg_device[channel].base, 0, 1, EP93xx_UART1_SIZE); /* disable the UART */ chip_write32(EP93xx_UART_CTRL, 0); /* figure out the baudrate divisor needed for the selected baud rate */ baudrate_div = (fuart_clk / (16 * baud)) - 1; ASSERT(baudrate_div != 0); // UART won't work if this is the case chip_write32(EP93xx_UART_LNCTRL_L, baudrate_div & 0xFFU); chip_write32(EP93xx_UART_LNCTRL_M, baudrate_div >> 8); /* select 8bit, no-parity, 1 stop bit and no FIFO */ chip_write32(EP93xx_UART_LNCTRL_H, EP93xx_UART_LNCTRL_H_8N1); /* clear any pending interrupts (just in case) */ chip_write32(EP93xx_UART_INTR, 0); /* Enable UART (no interrupts) */ chip_write32(EP93xx_UART_CTRL, EP93xx_UART_CTRL_ENABLE); chip_done(); /* make sure the UART is enabled in the EP93xx_SYSCTRL_DEVICECFG register */ { uint32_t enable_mask = (dbg_device[channel].base == EP93xx_UART1_BASE) ? 0x00040000U : 0x00100000U; chip_access(EP93xx_SYSCTRL_BASE, 0, 1, EP93xx_SYSCTRL_SIZE); chip_write32(EP93xx_SYSCTRL_DEVICECFG, chip_read32(EP93xx_SYSCTRL_DEVICECFG) | enable_mask); chip_done(); } }
/******************************************************************************* * put_ep93xx_uart * * Send a character out the debug_device[0] UART * * Note that we wait for TXFF (Transmit Fifo Full) condition to clear to indicate * that we can write a character as this will work whether the transmit fifo is * enabled or not where as TXFE and BUSY will cause unneccesary delays when the * fifo is enabled */ void put_ep93xx_uart(int c) { paddr_t base = dbg_device[0].base; ASSERT(base != NULL); chip_access(base, 0, 1, EP93xx_UART1_SIZE); while (chip_read32(EP93xx_UART_FLAGS) & EP93xx_UART_FLAGS_TXFF); chip_write32(EP93xx_UART_DATA, (unsigned)c & 0xFFU); chip_done(); }
unsigned long rtc_time_m48t37(paddr_t base, unsigned reg_shift, int mmap, int cent_reg) { struct tm tm; int cent = 0; //Tell Neutrino what kind of chip for 'rtc' utility hwi_add_rtc("m48t37", base, reg_shift, 0x8000, mmap, cent_reg); chip_access(base, reg_shift, mmap, 0x8000); do { tm.tm_sec = rdcmos(M48T37_TIME_REGS + 0x9); tm.tm_min = rdcmos(M48T37_TIME_REGS + 0xa); tm.tm_hour = rdcmos(M48T37_TIME_REGS + 0xb); tm.tm_mday = rdcmos(M48T37_TIME_REGS + 0xd); tm.tm_mon = rdcmos(M48T37_TIME_REGS + 0xe); tm.tm_year = rdcmos(M48T37_TIME_REGS + 0xf); if(cent_reg >= 0) cent = rdcmos(M48T37_TIME_REGS + cent_reg); //Loop while time inconsistent } while(tm.tm_sec != rdcmos(M48T37_TIME_REGS + 0x9)); chip_done(); tm.tm_sec &= ~0x80; tm.tm_sec = bcd2bin(tm.tm_sec); tm.tm_min = bcd2bin(tm.tm_min); tm.tm_hour = bcd2bin(tm.tm_hour); tm.tm_mday = bcd2bin(tm.tm_mday); tm.tm_mon = bcd2bin(tm.tm_mon); tm.tm_year = bcd2bin(tm.tm_year); tm.tm_mon -= 1; if(cent_reg >= 0) { if(cent > 19) tm.tm_year += (bcd2bin(cent)-19) * 100; } else if(tm.tm_year < 70) { tm.tm_year += 100; //21st century. } return(calc_time_t(&tm)); }
unsigned long rtc_time_ds1743(paddr_t base, unsigned reg_shift, int mmap, int cent_reg) { struct tm tm; unsigned cent; unsigned reg; //Tell Neutrino what kind of chip for 'rtc' utility hwi_add_rtc("ds1743", base, reg_shift, DS1743_YEAR+1, mmap, -1); chip_access(base, reg_shift, mmap, DS1743_YEAR+1); // Stop the chip from updating chip_write8(DS1743_CONTROL, chip_read8(DS1743_CONTROL) | DS1743_CONTROL_R); reg = chip_read8(DS1743_SECONDS); if(reg & DS1743_SECONDS_OSC) { // clock oscillator not running chip_write8(DS1743_SECONDS, reg & ~DS1743_SECONDS_OSC); } reg = chip_read8(DS1743_DAY); if(reg & DS1743_DAY_FT) { // need to turn off frequency test mode chip_write8(DS1743_DAY, reg & ~DS1743_DAY_FT); } // convert BCD to binary tm.tm_sec = bcd2bin(chip_read8(DS1743_SECONDS) & DS1743_SECONDS_MASK); tm.tm_min = bcd2bin(chip_read8(DS1743_MINUTES) & DS1743_MINUTES_MASK); tm.tm_hour = bcd2bin(chip_read8(DS1743_HOUR) & DS1743_HOUR_MASK); tm.tm_mday = bcd2bin(chip_read8(DS1743_DATE) & DS1743_DATE_MASK); tm.tm_mon = bcd2bin(chip_read8(DS1743_MONTH) & DS1743_MONTH_MASK) - 1; tm.tm_year = bcd2bin(chip_read8(DS1743_YEAR)); cent = bcd2bin(chip_read8(DS1743_CONTROL) & DS1743_CONTROL_CENT_MASK); // Start the chip updating again chip_write8(DS1743_CONTROL, chip_read8(DS1743_CONTROL) & ~DS1743_CONTROL_R); tm.tm_year += (cent-19) * 100; chip_done(); return(calc_time_t(&tm)); }
void init_omap(unsigned channel, const char *init, const char *defaults) { unsigned long baud; unsigned long div; unsigned long clk; paddr_t base; unsigned shift; baud = 0; parse_line(channel, defaults, &baud, &clk, &div); parse_line(channel, init, &baud, &clk, &div); base = dbg_device[channel].base; shift = dbg_device[channel].shift; chip_access(base, shift, 0, OMAP_UART_SIZE); if (baud != 0) { unsigned count = clk / (baud * div); /* Mask all interrupts causes and disable sleep mode and low power mode. */ set_port(OMAP_UART_IER, shift, 0xff, 0x0); /* Disable UART (default state) */ set_port(OMAP_UART_MDR1, shift, 0xff, 0x07); /* Turn FCR into EFR access */ set_port(OMAP_UART_LCR, shift, 0xff, 0xbf); /* This is EFR since LCR = 0xBF */ set_port(OMAP_UART_FCR, shift, 0x50, 0x50); /* Divisor latch enable, 8N1 */ set_port(OMAP_UART_LCR, shift, 0xff, 0x83); /* Enable access to TCR and TLR registers */ set_port(OMAP_UART_MCR, shift, 0x40, 0x40); /* * Reg#6 ?? only when LCR = 0xBF, else it is TCR * TCR set to default (halt RX at 52 bytes, start RX at 0 bytes) */ set_port(OMAP_UART_XOFF1, shift, 0xff, 0x0d); /* * Reg#7, XOFF2 when LCR = 0xBF, else it is SPR/TLR * TLR set to 48bytes on RX FIFO, 60 on TX FIFO */ set_port(OMAP_UART_TLR, shift, 0xff, 0xcf); /* Disable access to TCR and TLR */ set_port(OMAP_UART_MCR, shift, 0x40, 0x0); /* FCR set to 60/32/TXclear/RXclear/Enable */ set_port(OMAP_UART_FCR, shift, 0xff, 0xe7); set_port(OMAP_UART_DLL, shift, 0xff, count); /* baud rate. lobyte */ set_port(OMAP_UART_DLH, shift, 0xff, (count >> 8)); /* baud rate. hibyte */ set_port(OMAP_UART_LCR, shift, 0xff, 0x03); /* Divisor latch disable, 8N1 */ set_port(OMAP_UART_MDR1, shift, 0xff, 0x00); /* UART mode */ }
unsigned long rtc_time_mc146818(paddr_t base, unsigned reg_shift, int mmap, int cent_reg) { struct tm tm; unsigned save_hour; unsigned reg_b; unsigned cent; unsigned char sra; //Tell Neutrino what kind of chip for 'rtc' utility hwi_add_rtc("mc146818", base, reg_shift, 2, mmap, cent_reg); chip_access(base, reg_shift, mmap, 2); // bail if the clock is not running. sra = rdcmos(MC146818_SRA); if ((sra & 0x60) != 0x20) { chip_write8 (1, (sra | 0x60)); //Check for ATI IXP200 RTC - these bits are reserved if ((rdcmos(MC146818_SRA) & 0x60) != 0) { chip_write8 (1, sra); //restore old value return(0L); } } reg_b = rdcmos(MC146818_SRB); do { tm.tm_sec = rdcmos(0); tm.tm_min = rdcmos(2); tm.tm_hour = rdcmos(4); tm.tm_mday = rdcmos(7); tm.tm_mon = rdcmos(8); tm.tm_year = rdcmos(9); //Loop while time inconsistent } while(tm.tm_sec != rdcmos(0)); chip_done(); save_hour = tm.tm_hour; tm.tm_hour &= ~0x80; if(!(reg_b & MC146818_SRB_DM)) { tm.tm_sec = bcd2bin(tm.tm_sec); tm.tm_min = bcd2bin(tm.tm_min); tm.tm_hour = bcd2bin(tm.tm_hour); tm.tm_mday = bcd2bin(tm.tm_mday); tm.tm_mon = bcd2bin(tm.tm_mon); tm.tm_year = bcd2bin(tm.tm_year); } if(!(reg_b & MC146818_SRB_24_12) && (save_hour & 0x80)) { //12 hour format & past 12pm tm.tm_hour += 12; } tm.tm_mon -= 1; if(cent_reg >= 0) { cent = rdcmos(cent_reg); //century if(!(reg_b & MC146818_SRB_DM)) { cent = bcd2bin(cent_reg); } if(cent == 20) tm.tm_year += 100; } else if(tm.tm_year < 70) { tm.tm_year += 100; //21st century. } return(calc_time_t(&tm)); }