via_i2c.c revision 963d66ac
17e6fb56fSmrg/* 27e6fb56fSmrg * Copyright 2004 The Unichrome Project [unichrome.sf.net] 37e6fb56fSmrg * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. 47e6fb56fSmrg * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. 57e6fb56fSmrg * 67e6fb56fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 77e6fb56fSmrg * copy of this software and associated documentation files (the "Software"), 87e6fb56fSmrg * to deal in the Software without restriction, including without limitation 97e6fb56fSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license, 107e6fb56fSmrg * and/or sell copies of the Software, and to permit persons to whom the 117e6fb56fSmrg * Software is furnished to do so, subject to the following conditions: 127e6fb56fSmrg * 137e6fb56fSmrg * The above copyright notice and this permission notice (including the 147e6fb56fSmrg * next paragraph) shall be included in all copies or substantial portions 157e6fb56fSmrg * of the Software. 167e6fb56fSmrg * 177e6fb56fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 187e6fb56fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 197e6fb56fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 207e6fb56fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 217e6fb56fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 227e6fb56fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 237e6fb56fSmrg * DEALINGS IN THE SOFTWARE. 247e6fb56fSmrg */ 257e6fb56fSmrg 267e6fb56fSmrg/* 27963d66acSmrg * Implements three I2C buses through registers SR26, SR2C, and SR31. 287e6fb56fSmrg */ 297e6fb56fSmrg 307e6fb56fSmrg#ifdef HAVE_CONFIG_H 317e6fb56fSmrg#include "config.h" 327e6fb56fSmrg#endif 337e6fb56fSmrg 347e6fb56fSmrg#include "via_driver.h" 357e6fb56fSmrg 367e6fb56fSmrg#define SDA_READ 0x04 377e6fb56fSmrg#define SCL_READ 0x08 387e6fb56fSmrg#define SDA_WRITE 0x10 397e6fb56fSmrg#define SCL_WRITE 0x20 407e6fb56fSmrg 417e6fb56fSmrg/* 42963d66acSmrg * First I2C Bus: Typically used for detecting a VGA monitor. 437e6fb56fSmrg */ 447e6fb56fSmrgstatic void 457e6fb56fSmrgViaI2C1PutBits(I2CBusPtr Bus, int clock, int data) 467e6fb56fSmrg{ 4790b17f1bSmrg vgaHWPtr hwp = Bus->DriverPrivate.ptr; 487e6fb56fSmrg CARD8 value = 0x01; /* Enable */ 497e6fb56fSmrg 507e6fb56fSmrg if (clock) 517e6fb56fSmrg value |= SCL_WRITE; 527e6fb56fSmrg 537e6fb56fSmrg if (data) 547e6fb56fSmrg value |= SDA_WRITE; 557e6fb56fSmrg 567e6fb56fSmrg ViaSeqMask(hwp, 0x26, value, 0x01 | SCL_WRITE | SDA_WRITE); 577e6fb56fSmrg} 587e6fb56fSmrg 597e6fb56fSmrgstatic void 607e6fb56fSmrgViaI2C1GetBits(I2CBusPtr Bus, int *clock, int *data) 617e6fb56fSmrg{ 6290b17f1bSmrg vgaHWPtr hwp = Bus->DriverPrivate.ptr; 637e6fb56fSmrg CARD8 value = hwp->readSeq(hwp, 0x26); 647e6fb56fSmrg 657e6fb56fSmrg *clock = (value & SCL_READ) != 0; 667e6fb56fSmrg *data = (value & SDA_READ) != 0; 677e6fb56fSmrg} 687e6fb56fSmrg 697e6fb56fSmrgstatic I2CBusPtr 7090b17f1bSmrgViaI2CBus1Init(ScrnInfoPtr pScrn) 717e6fb56fSmrg{ 72963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 73963d66acSmrg "Entered ViaI2CBus1Init.\n")); 74963d66acSmrg 757e6fb56fSmrg I2CBusPtr pI2CBus = xf86CreateI2CBusRec(); 7690b17f1bSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 777e6fb56fSmrg 78963d66acSmrg if (!pI2CBus) { 79963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 80963d66acSmrg "xf86CreateI2CBusRec failed.\n")); 81963d66acSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 82963d66acSmrg "Initialization of I2C Bus 1 failed.\n"); 83963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 84963d66acSmrg "Exiting ViaI2CBus1Init.\n")); 857e6fb56fSmrg return NULL; 86963d66acSmrg } 877e6fb56fSmrg 88963d66acSmrg pI2CBus->BusName = "I2C Bus 1"; 8990b17f1bSmrg pI2CBus->scrnIndex = pScrn->scrnIndex; 907e6fb56fSmrg pI2CBus->I2CPutBits = ViaI2C1PutBits; 917e6fb56fSmrg pI2CBus->I2CGetBits = ViaI2C1GetBits; 9290b17f1bSmrg pI2CBus->DriverPrivate.ptr = hwp; 9390b17f1bSmrg pI2CBus->ByteTimeout = 2200; 9490b17f1bSmrg pI2CBus->StartTimeout = 550; 9590b17f1bSmrg pI2CBus->HoldTime = 40; 9690b17f1bSmrg pI2CBus->BitTimeout = 40; 977e6fb56fSmrg 987e6fb56fSmrg if (!xf86I2CBusInit(pI2CBus)) { 99963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 100963d66acSmrg "xf86I2CBusInit failed.\n")); 1017e6fb56fSmrg xf86DestroyI2CBusRec(pI2CBus, TRUE, FALSE); 102963d66acSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 103963d66acSmrg "Initialization of I2C Bus 1 failed.\n"); 104963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 105963d66acSmrg "Exiting ViaI2CBus1Init.\n")); 1067e6fb56fSmrg return NULL; 1077e6fb56fSmrg } 108963d66acSmrg 109963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 110963d66acSmrg "Exiting ViaI2CBus1Init.\n")); 1117e6fb56fSmrg return pI2CBus; 1127e6fb56fSmrg} 1137e6fb56fSmrg 1147e6fb56fSmrg/* 115963d66acSmrg * Second I2C Bus: Used to detect a DVI monitor, VGA monitor via 116963d66acSmrg * a DVI-I connector, or TV encoders. 1177e6fb56fSmrg */ 1187e6fb56fSmrgstatic void 1197e6fb56fSmrgViaI2C2PutBits(I2CBusPtr Bus, int clock, int data) 1207e6fb56fSmrg{ 12190b17f1bSmrg vgaHWPtr hwp = Bus->DriverPrivate.ptr; 1227e6fb56fSmrg CARD8 value = 0x01; /* Enable */ 1237e6fb56fSmrg 1247e6fb56fSmrg if (clock) 1257e6fb56fSmrg value |= SCL_WRITE; 1267e6fb56fSmrg 1277e6fb56fSmrg if (data) 1287e6fb56fSmrg value |= SDA_WRITE; 1297e6fb56fSmrg 1307e6fb56fSmrg ViaSeqMask(hwp, 0x31, value, 0x01 | SCL_WRITE | SDA_WRITE); 1317e6fb56fSmrg} 1327e6fb56fSmrg 1337e6fb56fSmrgstatic void 1347e6fb56fSmrgViaI2C2GetBits(I2CBusPtr Bus, int *clock, int *data) 1357e6fb56fSmrg{ 13690b17f1bSmrg vgaHWPtr hwp = Bus->DriverPrivate.ptr; 1377e6fb56fSmrg CARD8 value = hwp->readSeq(hwp, 0x31); 1387e6fb56fSmrg 1397e6fb56fSmrg *clock = (value & SCL_READ) != 0; 1407e6fb56fSmrg *data = (value & SDA_READ) != 0; 1417e6fb56fSmrg} 1427e6fb56fSmrg 1437e6fb56fSmrgstatic I2CBusPtr 14490b17f1bSmrgViaI2CBus2Init(ScrnInfoPtr pScrn) 1457e6fb56fSmrg{ 146963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 147963d66acSmrg "Entered ViaI2CBus2Init.\n")); 148963d66acSmrg 1497e6fb56fSmrg I2CBusPtr pI2CBus = xf86CreateI2CBusRec(); 15090b17f1bSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 1517e6fb56fSmrg 152963d66acSmrg if (!pI2CBus) { 153963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 154963d66acSmrg "xf86CreateI2CBusRec failed.\n")); 155963d66acSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 156963d66acSmrg "Initialization of I2C Bus 2 failed.\n"); 157963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 158963d66acSmrg "Exiting ViaI2CBus2Init.\n")); 1597e6fb56fSmrg return NULL; 160963d66acSmrg } 1617e6fb56fSmrg 162963d66acSmrg pI2CBus->BusName = "I2C Bus 2"; 16390b17f1bSmrg pI2CBus->scrnIndex = pScrn->scrnIndex; 1647e6fb56fSmrg pI2CBus->I2CPutBits = ViaI2C2PutBits; 1657e6fb56fSmrg pI2CBus->I2CGetBits = ViaI2C2GetBits; 16690b17f1bSmrg pI2CBus->DriverPrivate.ptr = hwp; 1677e6fb56fSmrg 1687e6fb56fSmrg if (!xf86I2CBusInit(pI2CBus)) { 169963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 170963d66acSmrg "xf86I2CBusInit failed.\n")); 1717e6fb56fSmrg xf86DestroyI2CBusRec(pI2CBus, TRUE, FALSE); 172963d66acSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 173963d66acSmrg "Initialization of I2C Bus 2 failed.\n"); 174963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 175963d66acSmrg "Exiting ViaI2CBus2Init.\n")); 1767e6fb56fSmrg return NULL; 1777e6fb56fSmrg } 178963d66acSmrg 179963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 180963d66acSmrg "Exiting ViaI2CBus2Init.\n")); 1817e6fb56fSmrg return pI2CBus; 1827e6fb56fSmrg} 1837e6fb56fSmrg 1847e6fb56fSmrg/* 185963d66acSmrg * Third I2C Bus: Implemented via manipulation of GPIO (General 186963d66acSmrg * Purpose I/O) pins. 1877e6fb56fSmrg */ 1887e6fb56fSmrgstatic Bool 1897e6fb56fSmrgViaI2C3Start(I2CBusPtr b, int timeout) 1907e6fb56fSmrg{ 19190b17f1bSmrg vgaHWPtr hwp = b->DriverPrivate.ptr; 1927e6fb56fSmrg 1937e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0xF0, 0xF0); 1947e6fb56fSmrg b->I2CUDelay(b, b->RiseFallTime); 1957e6fb56fSmrg 1967e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x00, 0x10); 1977e6fb56fSmrg b->I2CUDelay(b, b->HoldTime); 1987e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x00, 0x20); 1997e6fb56fSmrg b->I2CUDelay(b, b->HoldTime); 2007e6fb56fSmrg 2017e6fb56fSmrg return TRUE; 2027e6fb56fSmrg} 2037e6fb56fSmrg 2047e6fb56fSmrgstatic Bool 2057e6fb56fSmrgViaI2C3Address(I2CDevPtr d, I2CSlaveAddr addr) 2067e6fb56fSmrg{ 2077e6fb56fSmrg I2CBusPtr b = d->pI2CBus; 2087e6fb56fSmrg 2097e6fb56fSmrg#ifdef X_NEED_I2CSTART 2107e6fb56fSmrg if (b->I2CStart(d->pI2CBus, d->StartTimeout)) { 2117e6fb56fSmrg#else 2127e6fb56fSmrg if (ViaI2C3Start(d->pI2CBus, d->StartTimeout)) { 2137e6fb56fSmrg#endif 2147e6fb56fSmrg if (b->I2CPutByte(d, addr & 0xFF)) { 2157e6fb56fSmrg if ((addr & 0xF8) != 0xF0 && (addr & 0xFE) != 0x00) 2167e6fb56fSmrg return TRUE; 2177e6fb56fSmrg 2187e6fb56fSmrg if (b->I2CPutByte(d, (addr >> 8) & 0xFF)) 2197e6fb56fSmrg return TRUE; 2207e6fb56fSmrg } 2217e6fb56fSmrg 2227e6fb56fSmrg b->I2CStop(d); 2237e6fb56fSmrg } 2247e6fb56fSmrg return FALSE; 2257e6fb56fSmrg} 2267e6fb56fSmrg 2277e6fb56fSmrgstatic void 2287e6fb56fSmrgViaI2C3Stop(I2CDevPtr d) 2297e6fb56fSmrg{ 2307e6fb56fSmrg I2CBusPtr b = d->pI2CBus; 23190b17f1bSmrg vgaHWPtr hwp = b->DriverPrivate.ptr; 2327e6fb56fSmrg 2337e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0xC0, 0xF0); 2347e6fb56fSmrg b->I2CUDelay(b, b->RiseFallTime); 2357e6fb56fSmrg 2367e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x20, 0x20); 2377e6fb56fSmrg b->I2CUDelay(b, b->HoldTime); 2387e6fb56fSmrg 2397e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x10, 0x10); 2407e6fb56fSmrg b->I2CUDelay(b, b->HoldTime); 2417e6fb56fSmrg 2427e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x00, 0x20); 2437e6fb56fSmrg b->I2CUDelay(b, b->HoldTime); 2447e6fb56fSmrg} 2457e6fb56fSmrg 2467e6fb56fSmrgstatic void 2477e6fb56fSmrgViaI2C3PutBit(I2CBusPtr b, Bool sda, int timeout) 2487e6fb56fSmrg{ 24990b17f1bSmrg vgaHWPtr hwp = b->DriverPrivate.ptr; 2507e6fb56fSmrg 2517e6fb56fSmrg if (sda) 2527e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x50, 0x50); 2537e6fb56fSmrg else 2547e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x40, 0x50); 2557e6fb56fSmrg b->I2CUDelay(b, b->RiseFallTime / 5); 2567e6fb56fSmrg 2577e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0); 2587e6fb56fSmrg b->I2CUDelay(b, b->HoldTime); 2597e6fb56fSmrg b->I2CUDelay(b, timeout); 2607e6fb56fSmrg 2617e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x80, 0xA0); 2627e6fb56fSmrg b->I2CUDelay(b, b->RiseFallTime / 5); 2637e6fb56fSmrg} 2647e6fb56fSmrg 2657e6fb56fSmrgstatic Bool 2667e6fb56fSmrgViaI2C3PutByte(I2CDevPtr d, I2CByte data) 2677e6fb56fSmrg{ 2687e6fb56fSmrg I2CBusPtr b = d->pI2CBus; 26990b17f1bSmrg vgaHWPtr hwp = b->DriverPrivate.ptr; 2707e6fb56fSmrg Bool ret; 2717e6fb56fSmrg int i; 2727e6fb56fSmrg 2737e6fb56fSmrg for (i = 7; i >= 0; i--) 2747e6fb56fSmrg ViaI2C3PutBit(b, (data >> i) & 0x01, b->BitTimeout); 2757e6fb56fSmrg 2767e6fb56fSmrg /* Raise first to avoid false positives. */ 2777e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x50, 0x50); 2787e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x00, 0x40); 2797e6fb56fSmrg b->I2CUDelay(b, b->RiseFallTime); 2807e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0); 2817e6fb56fSmrg 2827e6fb56fSmrg if (hwp->readSeq(hwp, 0x2C) & 0x04) 2837e6fb56fSmrg ret = FALSE; 2847e6fb56fSmrg else 2857e6fb56fSmrg ret = TRUE; 2867e6fb56fSmrg 2877e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x80, 0xA0); 2887e6fb56fSmrg b->I2CUDelay(b, b->RiseFallTime); 2897e6fb56fSmrg 2907e6fb56fSmrg return ret; 2917e6fb56fSmrg} 2927e6fb56fSmrg 2937e6fb56fSmrgstatic Bool 2947e6fb56fSmrgViaI2C3GetBit(I2CBusPtr b, int timeout) 2957e6fb56fSmrg{ 29690b17f1bSmrg vgaHWPtr hwp = b->DriverPrivate.ptr; 2977e6fb56fSmrg Bool ret; 2987e6fb56fSmrg 2997e6fb56fSmrg ViaSeqMask(hwp, 0x2c, 0x80, 0xC0); 3007e6fb56fSmrg b->I2CUDelay(b, b->RiseFallTime / 5); 3017e6fb56fSmrg ViaSeqMask(hwp, 0x2c, 0xA0, 0xA0); 3027e6fb56fSmrg b->I2CUDelay(b, 3 * b->HoldTime); 3037e6fb56fSmrg b->I2CUDelay(b, timeout); 3047e6fb56fSmrg 3057e6fb56fSmrg if (hwp->readSeq(hwp, 0x2C) & 0x04) 3067e6fb56fSmrg ret = TRUE; 3077e6fb56fSmrg else 3087e6fb56fSmrg ret = FALSE; 3097e6fb56fSmrg 3107e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x80, 0xA0); 3117e6fb56fSmrg b->I2CUDelay(b, b->HoldTime); 3127e6fb56fSmrg b->I2CUDelay(b, b->RiseFallTime / 5); 3137e6fb56fSmrg 3147e6fb56fSmrg return ret; 3157e6fb56fSmrg} 3167e6fb56fSmrg 3177e6fb56fSmrgstatic Bool 3187e6fb56fSmrgViaI2C3GetByte(I2CDevPtr d, I2CByte * data, Bool last) 3197e6fb56fSmrg{ 3207e6fb56fSmrg I2CBusPtr b = d->pI2CBus; 32190b17f1bSmrg vgaHWPtr hwp = b->DriverPrivate.ptr; 3227e6fb56fSmrg int i; 3237e6fb56fSmrg 3247e6fb56fSmrg *data = 0x00; 3257e6fb56fSmrg 3267e6fb56fSmrg for (i = 7; i >= 0; i--) 3277e6fb56fSmrg if (ViaI2C3GetBit(b, b->BitTimeout)) 3287e6fb56fSmrg *data |= 0x01 << i; 3297e6fb56fSmrg 3307e6fb56fSmrg if (last) /* send NACK */ 3317e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x50, 0x50); 3327e6fb56fSmrg else /* send ACK */ 3337e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x40, 0x50); 3347e6fb56fSmrg 3357e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0xA0, 0xA0); 3367e6fb56fSmrg b->I2CUDelay(b, b->HoldTime); 3377e6fb56fSmrg 3387e6fb56fSmrg ViaSeqMask(hwp, 0x2C, 0x80, 0xA0); 3397e6fb56fSmrg 3407e6fb56fSmrg return TRUE; 3417e6fb56fSmrg} 3427e6fb56fSmrg 343963d66acSmrgstatic void 344963d66acSmrgViaI2C3SimplePutBits(I2CBusPtr Bus, int clock, int data) 345963d66acSmrg{ 346963d66acSmrg vgaHWPtr hwp = Bus->DriverPrivate.ptr; 347963d66acSmrg CARD8 value = 0xC0; 348963d66acSmrg 349963d66acSmrg if (clock) 350963d66acSmrg value |= SCL_WRITE; 351963d66acSmrg 352963d66acSmrg if (data) 353963d66acSmrg value |= SDA_WRITE; 354963d66acSmrg 355963d66acSmrg ViaSeqMask(hwp, 0x2C, value, 0xC0 | SCL_WRITE | SDA_WRITE); 356963d66acSmrg} 357963d66acSmrg 358963d66acSmrgstatic void 359963d66acSmrgViaI2C3SimpleGetBits(I2CBusPtr Bus, int *clock, int *data) 360963d66acSmrg{ 361963d66acSmrg vgaHWPtr hwp = Bus->DriverPrivate.ptr; 362963d66acSmrg CARD8 value = hwp->readSeq(hwp, 0x2C); 363963d66acSmrg 364963d66acSmrg *clock = (value & SCL_READ) != 0; 365963d66acSmrg *data = (value & SDA_READ) != 0; 366963d66acSmrg} 367963d66acSmrg 3687e6fb56fSmrgstatic I2CBusPtr 36990b17f1bSmrgViaI2CBus3Init(ScrnInfoPtr pScrn) 3707e6fb56fSmrg{ 371963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 372963d66acSmrg "Entered ViaI2CBus3Init.\n")); 373963d66acSmrg 3747e6fb56fSmrg I2CBusPtr pI2CBus = xf86CreateI2CBusRec(); 37590b17f1bSmrg vgaHWPtr hwp = VGAHWPTR(pScrn); 376963d66acSmrg VIAPtr pVia = VIAPTR(pScrn); 3777e6fb56fSmrg 378963d66acSmrg if (!pI2CBus) { 379963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 380963d66acSmrg "xf86CreateI2CBusRec failed.\n")); 381963d66acSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 382963d66acSmrg "Initialization of I2C Bus 3 failed.\n"); 383963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 384963d66acSmrg "Exiting ViaI2CBus3Init.\n")); 3857e6fb56fSmrg return NULL; 386963d66acSmrg } 3877e6fb56fSmrg 388963d66acSmrg pI2CBus->BusName = "I2C Bus 3"; 38990b17f1bSmrg pI2CBus->scrnIndex = pScrn->scrnIndex; 39090b17f1bSmrg pI2CBus->DriverPrivate.ptr = hwp; 3917e6fb56fSmrg 392963d66acSmrg switch (pVia->Chipset) { 393963d66acSmrg case VIA_P4M800PRO: 394963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 395963d66acSmrg "using alternative PutBits/GetBits functions for I2C Bus 3\n")); 396963d66acSmrg pI2CBus->I2CPutBits = ViaI2C3SimplePutBits; 397963d66acSmrg pI2CBus->I2CGetBits = ViaI2C3SimpleGetBits; 398963d66acSmrg break; 399963d66acSmrg default: 400963d66acSmrg pI2CBus->I2CAddress = ViaI2C3Address; 401963d66acSmrg#ifdef X_NEED_I2CSTART 402963d66acSmrg pI2CBus->I2CStart = ViaI2C3Start; 403963d66acSmrg#endif 404963d66acSmrg pI2CBus->I2CStop = ViaI2C3Stop; 405963d66acSmrg pI2CBus->I2CPutByte = ViaI2C3PutByte; 406963d66acSmrg pI2CBus->I2CGetByte = ViaI2C3GetByte; 407963d66acSmrg pI2CBus->DriverPrivate.ptr = hwp; 408963d66acSmrg 409963d66acSmrg pI2CBus->BitTimeout = 10; 410963d66acSmrg pI2CBus->ByteTimeout = 10; 411963d66acSmrg pI2CBus->HoldTime = 10; 412963d66acSmrg pI2CBus->StartTimeout = 10; 413963d66acSmrg break; 414963d66acSmrg } 4157e6fb56fSmrg 4167e6fb56fSmrg if (!xf86I2CBusInit(pI2CBus)) { 417963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 418963d66acSmrg "xf86I2CBusInit failed.\n")); 4197e6fb56fSmrg xf86DestroyI2CBusRec(pI2CBus, TRUE, FALSE); 420963d66acSmrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 421963d66acSmrg "Initialization of I2C Bus 3 failed.\n"); 422963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 423963d66acSmrg "Exiting ViaI2CBus3Init.\n")); 4247e6fb56fSmrg return NULL; 4257e6fb56fSmrg } 426963d66acSmrg 427963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 428963d66acSmrg "Exiting ViaI2CBus3Init.\n")); 4297e6fb56fSmrg return pI2CBus; 4307e6fb56fSmrg} 4317e6fb56fSmrg 4327e6fb56fSmrg#ifdef HAVE_DEBUG 4337e6fb56fSmrgstatic void 4347e6fb56fSmrgViaI2CScan(I2CBusPtr Bus) 4357e6fb56fSmrg{ 4367e6fb56fSmrg CARD8 i; 4377e6fb56fSmrg 438963d66acSmrg DEBUG(xf86DrvMsg(Bus->scrnIndex, X_INFO, 439963d66acSmrg "Entered ViaI2CScan.\n")); 440963d66acSmrg 441963d66acSmrg xf86DrvMsg(Bus->scrnIndex, X_INFO, "Scanning %s.\n", 4427e6fb56fSmrg Bus->BusName); 4437e6fb56fSmrg 4447e6fb56fSmrg for (i = 0x10; i < 0xF0; i += 2) 4457e6fb56fSmrg if (xf86I2CProbeAddress(Bus, i)) 4467e6fb56fSmrg xf86DrvMsg(Bus->scrnIndex, X_PROBED, "Found slave on %s " 447963d66acSmrg "- 0x%02X.\n", Bus->BusName, i); 448963d66acSmrg 449963d66acSmrg DEBUG(xf86DrvMsg(Bus->scrnIndex, X_INFO, 450963d66acSmrg "Exiting ViaI2CScan.\n")); 4517e6fb56fSmrg} 4527e6fb56fSmrg#endif /* HAVE_DEBUG */ 4537e6fb56fSmrg 4547e6fb56fSmrgvoid 4557e6fb56fSmrgViaI2CInit(ScrnInfoPtr pScrn) 4567e6fb56fSmrg{ 4577e6fb56fSmrg VIAPtr pVia = VIAPTR(pScrn); 4587e6fb56fSmrg 459963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 460963d66acSmrg "Entered ViaI2CInit.\n")); 4617e6fb56fSmrg 46290b17f1bSmrg if (pVia->I2CDevices & VIA_I2C_BUS1) 46390b17f1bSmrg pVia->pI2CBus1 = ViaI2CBus1Init(pScrn); 46490b17f1bSmrg if (pVia->I2CDevices & VIA_I2C_BUS2) 46590b17f1bSmrg pVia->pI2CBus2 = ViaI2CBus2Init(pScrn); 46690b17f1bSmrg if (pVia->I2CDevices & VIA_I2C_BUS3) 46790b17f1bSmrg pVia->pI2CBus3 = ViaI2CBus3Init(pScrn); 4687e6fb56fSmrg 4697e6fb56fSmrg#ifdef HAVE_DEBUG 4707e6fb56fSmrg if (pVia->I2CScan) { 4717e6fb56fSmrg if (pVia->pI2CBus2) 4727e6fb56fSmrg ViaI2CScan(pVia->pI2CBus2); 4737e6fb56fSmrg if (pVia->pI2CBus3) 4747e6fb56fSmrg ViaI2CScan(pVia->pI2CBus3); 4757e6fb56fSmrg } 4767e6fb56fSmrg#endif 477963d66acSmrg 478963d66acSmrg DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, 479963d66acSmrg "Exiting ViaI2CInit.\n")); 4807e6fb56fSmrg} 481