1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * Xicor RTC driver File: dev_sb1250_x1241clock.c 5 * 6 * This module contains a CFE driver for a Xicor X1241 SMBus 7 * real-time-clock. 8 * 9 * Author: Mitch Lichtenberg (mpl@broadcom.com) and Binh Vo 10 * 11 ********************************************************************* 12 * 13 * Copyright 2000,2001,2002,2003 14 * Broadcom Corporation. All rights reserved. 15 * 16 * This software is furnished under license and may be used and 17 * copied only in accordance with the following terms and 18 * conditions. Subject to these conditions, you may download, 19 * copy, install, use, modify and distribute modified or unmodified 20 * copies of this software in source and/or binary form. No title 21 * or ownership is transferred hereby. 22 * 23 * 1) Any source code used, modified or distributed must reproduce 24 * and retain this copyright notice and list of conditions 25 * as they appear in the source file. 26 * 27 * 2) No right is granted to use any trade name, trademark, or 28 * logo of Broadcom Corporation. The "Broadcom Corporation" 29 * name may not be used to endorse or promote products derived 30 * from this software without the prior written permission of 31 * Broadcom Corporation. 32 * 33 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 34 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 35 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 36 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 37 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 38 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 40 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 41 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 43 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 44 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 45 * THE POSSIBILITY OF SUCH DAMAGE. 46 ********************************************************************* */ 47 48#include "sbmips.h" 49#include "lib_types.h" 50#include "lib_malloc.h" 51#include "lib_printf.h" 52 53#include "cfe_iocb.h" 54#include "cfe_device.h" 55#include "cfe_ioctl.h" 56#include "cfe_timer.h" 57 58#include "sb1250_defs.h" 59#include "sb1250_regs.h" 60#include "sb1250_smbus.h" 61 62 63/* ********************************************************************* 64 * Constants 65 ********************************************************************* */ 66 67/* 68 * Register bits 69 */ 70 71#define X1241REG_SR_BAT 0x80 /* currently on battery power */ 72#define X1241REG_SR_RWEL 0x04 /* r/w latch is enabled, can write RTC */ 73#define X1241REG_SR_WEL 0x02 /* r/w latch is unlocked, can enable r/w now */ 74#define X1241REG_SR_RTCF 0x01 /* clock failed */ 75#define X1241REG_BL_BP2 0x80 /* block protect 2 */ 76#define X1241REG_BL_BP1 0x40 /* block protect 1 */ 77#define X1241REG_BL_BP0 0x20 /* block protect 0 */ 78#define X1241REG_BL_WD1 0x10 79#define X1241REG_BL_WD0 0x08 80#define X1241REG_HR_MIL 0x80 /* military time format */ 81 82/* 83 * Register numbers 84 */ 85 86#define X1241REG_BL 0x10 /* block protect bits */ 87#define X1241REG_INT 0x11 /* */ 88#define X1241REG_SC 0x30 /* Seconds */ 89#define X1241REG_MN 0x31 /* Minutes */ 90#define X1241REG_HR 0x32 /* Hours */ 91#define X1241REG_DT 0x33 /* Day of month */ 92#define X1241REG_MO 0x34 /* Month */ 93#define X1241REG_YR 0x35 /* Year */ 94#define X1241REG_DW 0x36 /* Day of Week */ 95#define X1241REG_Y2K 0x37 /* Year 2K */ 96#define X1241REG_SR 0x3F /* Status register */ 97 98#define X1241_CCR_ADDRESS 0x6F 99#define X1241_ARRAY_ADDRESS 0x57 100 101#define X1241_EEPROM_SIZE 2048 102 103#define BCD(x) (((x) % 10) + (((x) / 10) << 4)) 104#define SET_TIME 0x00 105#define SET_DATE 0x01 106 107/* ********************************************************************* 108 * Forward declarations 109 ********************************************************************* */ 110 111static void x1241_clock_probe(cfe_driver_t *drv, 112 unsigned long probe_a, unsigned long probe_b, 113 void *probe_ptr); 114 115static int x1241_clock_open(cfe_devctx_t *ctx); 116static int x1241_clock_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 117static int x1241_clock_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat); 118static int x1241_clock_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 119static int x1241_clock_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer); 120static int x1241_clock_close(cfe_devctx_t *ctx); 121 122 123/* ********************************************************************* 124 * Device dispatch 125 ********************************************************************* */ 126 127const static cfe_devdisp_t x1241_clock_dispatch = { 128 x1241_clock_open, 129 x1241_clock_read, 130 x1241_clock_inpstat, 131 x1241_clock_write, 132 x1241_clock_ioctl, 133 x1241_clock_close, 134 NULL, 135 NULL 136}; 137 138const cfe_driver_t x1241_clock = { 139 "Xicor X1241 RTC", 140 "clock", 141 CFE_DEV_CLOCK, 142 &x1241_clock_dispatch, 143 x1241_clock_probe 144}; 145 146 147/* ********************************************************************* 148 * Structures 149 ********************************************************************* */ 150typedef struct x1241_clock_s { 151 int smbus_channel; 152} x1241_clock_t; 153 154/* ********************************************************************* 155 * time_smbus_init(chan) 156 * 157 * Initialize the specified SMBus channel for the temp sensor 158 * 159 * Input parameters: 160 * chan - channel # (0 or 1) 161 * 162 * Return value: 163 * nothing 164 ********************************************************************* */ 165 166static void time_smbus_init(int chan) 167{ 168 uintptr_t reg; 169 170 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_FREQ)); 171 172 SBWRITECSR(reg,K_SMB_FREQ_100KHZ); /* 100KHz clock */ 173 174 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_CONTROL)); 175 176 SBWRITECSR(reg,0); /* not in direct mode, no interrupts, will poll */ 177 178} 179 180/* ********************************************************************* 181 * time_waitready(chan) 182 * 183 * Wait until the SMBus channel is ready. We simply poll 184 * the busy bit until it clears. 185 * 186 * Input parameters: 187 * chan - channel (0 or 1) 188 * 189 * Return value: 190 * nothing 191 ********************************************************************* */ 192static int time_waitready(int chan) 193{ 194 uintptr_t reg; 195 uint64_t status; 196 197 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_STATUS)); 198 199 for (;;) { 200 status = SBREADCSR(reg); 201 if (status & M_SMB_BUSY) continue; 202 break; 203 } 204 205 if (status & M_SMB_ERROR) { 206 207 SBWRITECSR(reg,(status & M_SMB_ERROR)); 208 return -1; 209 } 210 return 0; 211} 212 213/* ********************************************************************* 214 * time_readrtc(chan,slaveaddr,devaddr) 215 * 216 * Read a byte from the chip. The 'slaveaddr' parameter determines 217 * whether we're reading from the RTC section or the EEPROM section. 218 * 219 * Input parameters: 220 * chan - SMBus channel 221 * slaveaddr - SMBus slave address 222 * devaddr - byte with in the X1240 device to read 223 * 224 * Return value: 225 * 0 if ok 226 * else -1 227 ********************************************************************* */ 228 229static int time_readrtc(int chan,int slaveaddr,int devaddr) 230{ 231 uintptr_t reg; 232 int err; 233 234 /* 235 * Make sure the bus is idle (probably should 236 * ignore error here) 237 */ 238 239 if (time_waitready(chan) < 0) return -1; 240 241 /* 242 * Write the device address to the controller. There are two 243 * parts, the high part goes in the "CMD" field, and the 244 * low part is the data field. 245 */ 246 247 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_CMD)); 248 SBWRITECSR(reg,((devaddr >> 8) & 0x7)); 249 250 /* 251 * Write the data to the controller 252 */ 253 254 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_DATA)); 255 SBWRITECSR(reg,((devaddr & 0xFF) & 0xFF)); 256 257 /* 258 * Start the command 259 */ 260 261 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_START)); 262 SBWRITECSR(reg,V_SMB_TT(K_SMB_TT_WR2BYTE) | slaveaddr); 263 264 /* 265 * Wait till done 266 */ 267 268 err = time_waitready(chan); 269 if (err < 0) return err; 270 271 /* 272 * Read the data byte 273 */ 274 275 SBWRITECSR(reg,V_SMB_TT(K_SMB_TT_RD1BYTE) | slaveaddr); 276 277 err = time_waitready(chan); 278 if (err < 0) return err; 279 280 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_DATA)); 281 err = SBREADCSR(reg); 282 283 return (err & 0xFF); 284} 285 286/* ********************************************************************* 287 * time_writertc(chan,slaveaddr,devaddr,b) 288 * 289 * write a byte from the chip. The 'slaveaddr' parameter determines 290 * whethe we're writing to the RTC section or the EEPROM section. 291 * 292 * Input parameters: 293 * chan - SMBus channel 294 * slaveaddr - SMBus slave address 295 * devaddr - byte with in the X1240 device to read 296 * b - byte to write 297 * 298 * Return value: 299 * 0 if ok 300 * else -1 301 ********************************************************************* */ 302 303static int time_writertc(int chan,int slaveaddr,int devaddr,int b) 304{ 305 uintptr_t reg; 306 int err; 307 int64_t timer; 308 309 /* 310 * Make sure the bus is idle (probably should 311 * ignore error here) 312 */ 313 314 if (time_waitready(chan) < 0) return -1; 315 316 /* 317 * Write the device address to the controller. There are two 318 * parts, the high part goes in the "CMD" field, and the 319 * low part is the data field. 320 */ 321 322 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_CMD)); 323 SBWRITECSR(reg,((devaddr >> 8) & 0x7)); 324 325 /* 326 * Write the data to the controller 327 */ 328 329 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_DATA)); 330 SBWRITECSR(reg,((devaddr & 0xFF) | ((b & 0xFF) << 8))); 331 332 /* 333 * Start the command. Keep pounding on the device until it 334 * submits or the timer expires, whichever comes first. The 335 * datasheet says writes can take up to 10ms, so we'll give it 500. 336 */ 337 338 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_START)); 339 SBWRITECSR(reg,V_SMB_TT(K_SMB_TT_WR3BYTE) | slaveaddr); 340 341 /* 342 * Wait till the SMBus interface is done 343 */ 344 345 err = time_waitready(chan); 346 if (err < 0) return err; 347 348 /* 349 * Pound on the device with a current address read 350 * to poll for the write complete 351 */ 352 353 TIMER_SET(timer,50); 354 err = -1; 355 356 while (!TIMER_EXPIRED(timer)) { 357 POLL(); 358 359 SBWRITECSR(reg,V_SMB_TT(K_SMB_TT_RD1BYTE) | slaveaddr); 360 361 err = time_waitready(chan); 362 if (err == 0) break; 363 } 364 365 return err; 366} 367 368 369/* ********************************************************************* 370 * x1241_clock_probe(drv,a,b,ptr) 371 * 372 * Probe routine for this driver. This routine creates the 373 * local device context and attaches it to the driver list 374 * within CFE. 375 * 376 * Input parameters: 377 * drv - driver handle 378 * a,b - probe hints (longs) 379 * ptr - probe hint (pointer) 380 * 381 * Return value: 382 * nothing 383 ********************************************************************* */ 384 385static void x1241_clock_probe(cfe_driver_t *drv, 386 unsigned long probe_a, unsigned long probe_b, 387 void *probe_ptr) 388{ 389 x1241_clock_t *softc; 390 char descr[80]; 391 392 softc = (x1241_clock_t *) KMALLOC(sizeof(x1241_clock_t),0); 393 394 /* 395 * Probe_a is the SMBus channel number 396 * Probe_b is unused. 397 * Probe_ptr is unused. 398 */ 399 400 softc->smbus_channel = (int)probe_a; 401 402 xsprintf(descr,"%s on SMBus channel %d", 403 drv->drv_description,probe_a); 404 cfe_attach(drv,softc,NULL,descr); 405} 406 407 408 409/* ********************************************************************* 410 * x1241_clock_open(ctx) 411 * 412 * Open this device. For the X1241, we do a quick test 413 * read to be sure the device is out there. 414 * 415 * Input parameters: 416 * ctx - device context (can obtain our softc here) 417 * 418 * Return value: 419 * 0 if ok 420 * else error code 421 ********************************************************************* */ 422 423static int x1241_clock_open(cfe_devctx_t *ctx) 424{ 425 x1241_clock_t *softc = ctx->dev_softc; 426 int b; 427 int64_t timer; 428 int chan = softc->smbus_channel; 429 430 /* 431 * Try to read byte 0 from the device. If it does not 432 * respond, fail the open. We may need to do this for 433 * up to 300ms in case the X1241 is busy wiggling its 434 * RESET line. 435 */ 436 437 time_smbus_init(chan); 438 439 TIMER_SET(timer,300); 440 while (!TIMER_EXPIRED(timer)) { 441 POLL(); 442 b = time_readrtc(chan,X1241_CCR_ADDRESS,0); 443 if (b >= 0) break; /* read is ok */ 444 } 445 446 /* 447 * See if the watchdog is enabled. If it is, turn it off. 448 */ 449 450 b = time_readrtc(chan,X1241_CCR_ADDRESS,X1241REG_BL); 451 452 if (b != (X1241REG_BL_WD1 | X1241REG_BL_WD0)) { 453 454 time_writertc(chan, 455 X1241_CCR_ADDRESS, 456 X1241REG_SR, 457 X1241REG_SR_WEL); 458 459 time_writertc(chan, 460 X1241_CCR_ADDRESS, 461 X1241REG_SR, 462 X1241REG_SR_WEL | X1241REG_SR_RWEL); 463 464 time_writertc(chan, 465 X1241_CCR_ADDRESS, 466 X1241REG_BL, 467 (X1241REG_BL_WD1 | X1241REG_BL_WD0)); 468 469 time_writertc(chan, 470 X1241_CCR_ADDRESS, 471 X1241REG_SR, 472 0); 473 } 474 475 return (b < 0) ? -1 : 0; 476} 477 478/* ********************************************************************* 479 * x1241_clock_read(ctx,buffer) 480 * 481 * Read time/date from the RTC. Read a total of 8 bytes in this format: 482 * hour-minute-second-month-day-year1-year2 483 * 484 * Input parameters: 485 * ctx - device context (can obtain our softc here) 486 * buffer - buffer descriptor (target buffer, length, offset) 487 * 488 * Return value: 489 * number of bytes read 490 * -1 if an error occured 491 ********************************************************************* */ 492 493static int x1241_clock_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer) 494{ 495 496 x1241_clock_t *softc = ctx->dev_softc; 497 uint8_t byte; 498 unsigned char *bptr; 499 int chan = softc->smbus_channel; 500 501 bptr = buffer->buf_ptr; 502 503 byte = (uint8_t) time_readrtc(chan,X1241_CCR_ADDRESS,X1241REG_HR); 504 byte &= ~X1241REG_HR_MIL; 505 *bptr++ = (unsigned char) byte; 506 507 byte = (uint8_t) time_readrtc(chan,X1241_CCR_ADDRESS,X1241REG_MN); 508 *bptr++ = (unsigned char) byte; 509 510 byte = (uint8_t) time_readrtc(chan,X1241_CCR_ADDRESS,X1241REG_SC); 511 *bptr++ = (unsigned char) byte; 512 513 byte = (uint8_t) time_readrtc(chan,X1241_CCR_ADDRESS,X1241REG_MO); 514 *bptr++ = (unsigned char) byte; 515 516 byte = (uint8_t) time_readrtc(chan,X1241_CCR_ADDRESS,X1241REG_DT); 517 *bptr++ = (unsigned char) byte; 518 519 byte = (uint8_t) time_readrtc(chan,X1241_CCR_ADDRESS,X1241REG_YR); 520 *bptr++ = (unsigned char) byte; 521 522 byte = (uint8_t) time_readrtc(chan,X1241_CCR_ADDRESS,X1241REG_Y2K); 523 *bptr = (unsigned char) byte; 524 525 byte = (uint8_t) time_readrtc(chan,X1241_CCR_ADDRESS,X1241REG_SR); 526 527 /*Last byte is status of battery*/ 528 if (byte & X1241REG_SR_RTCF) 529 { 530 printf("Warning: Battery has failed. Clock setting is not accurate.\n"); 531 } 532 533 buffer->buf_retlen = 8; 534 return 0; 535} 536 537/* ********************************************************************* 538 * x1241_clock_write(ctx,buffer) 539 * 540 * Write time/date to the RTC. Write in this format: 541 * hour-minute-second-month-day-year1-year2-(time/date flag) 542 * 543 * Input parameters: 544 * ctx - device context (can obtain our softc here) 545 * buffer - buffer descriptor (target buffer, length, offset) 546 * 547 * Return value: 548 * number of bytes written 549 * -1 if an error occured 550 ********************************************************************* */ 551 552static int x1241_clock_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer) 553{ 554 x1241_clock_t *softc = ctx->dev_softc; 555 unsigned char *bptr; 556 uint8_t hr,min,sec; 557 uint8_t mo,day,yr,y2k; 558 uint8_t timeDateFlag; 559 int chan = softc->smbus_channel; 560 561 bptr = buffer->buf_ptr; 562 timeDateFlag = *(bptr + 7); 563 564 /* unlock writes to the CCR */ 565 time_writertc(chan,X1241_CCR_ADDRESS,X1241REG_SR,X1241REG_SR_WEL); 566 time_writertc(chan,X1241_CCR_ADDRESS,X1241REG_SR, 567 X1241REG_SR_WEL | X1241REG_SR_RWEL); 568 569 /* write time or date */ 570 if(timeDateFlag == SET_TIME) { 571 572 hr = (uint8_t) *bptr; 573 time_writertc(chan,X1241_CCR_ADDRESS,X1241REG_HR, BCD(hr) | X1241REG_HR_MIL); 574 575 min = (uint8_t) *(bptr+1); 576 time_writertc(chan,X1241_CCR_ADDRESS,X1241REG_MN, BCD(min) ); 577 578 sec = (uint8_t) *(bptr+2); 579 time_writertc(chan,X1241_CCR_ADDRESS,X1241REG_SC, BCD(sec) ); 580 581 buffer->buf_retlen = 3; 582 } 583 else if(timeDateFlag == SET_DATE) { 584 585 mo = (uint8_t) *(bptr+3); 586 time_writertc(chan,X1241_CCR_ADDRESS,X1241REG_MO, BCD(mo) ); 587 588 day = (uint8_t) *(bptr+4); 589 time_writertc(chan,X1241_CCR_ADDRESS,X1241REG_DT, BCD(day) ); 590 591 yr = (uint8_t) *(bptr+5); 592 time_writertc(chan,X1241_CCR_ADDRESS,X1241REG_YR, BCD(yr) ); 593 594 y2k = (uint8_t) *(bptr+6); 595 time_writertc(chan,X1241_CCR_ADDRESS,X1241REG_Y2K, BCD(y2k) ); 596 597 buffer->buf_retlen = 4; 598 } 599 else { 600 return -1; 601 } 602 603 /* lock writes again */ 604 time_writertc(chan,X1241_CCR_ADDRESS,X1241REG_SR,0); 605 606 return 0; 607} 608 609/* ********************************************************************* 610 * x1241_clock_inpstat(ctx,inpstat) 611 * 612 * Test input (read) status for the device 613 * 614 * Input parameters: 615 * ctx - device context (can obtain our softc here) 616 * inpstat - input status descriptor to receive value 617 * 618 * Return value: 619 * 0 if ok 620 * -1 if an error occured 621 ********************************************************************* */ 622 623static int x1241_clock_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat) 624{ 625 inpstat->inp_status = 1; 626 627 return 0; 628} 629 630/* ********************************************************************* 631 * x1241_clock_ioctl(ctx,buffer) 632 * 633 * Perform miscellaneous I/O control operations on the device. 634 * 635 * Input parameters: 636 * ctx - device context (can obtain our softc here) 637 * buffer - buffer descriptor (target buffer, length, offset) 638 * 639 * Return value: 640 * number of bytes read 641 * -1 if an error occured 642 ********************************************************************* */ 643 644static int x1241_clock_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer) 645{ 646 return 0; 647} 648 649/* ********************************************************************* 650 * x1241_clock_close(ctx,buffer) 651 * 652 * Close the device. 653 * 654 * Input parameters: 655 * ctx - device context (can obtain our softc here) 656 * 657 * Return value: 658 * 0 if ok 659 * -1 if an error occured 660 ********************************************************************* */ 661 662static int x1241_clock_close(cfe_devctx_t *ctx) 663{ 664 return 0; 665} 666 667 668 669 670 671 672 673 674