diff options
author | Egbert Eich <eich@freedesktop.org> | 2008-07-12 11:22:38 +0200 |
---|---|---|
committer | Egbert Eich <eich@freedesktop.org> | 2008-07-12 23:25:36 +0200 |
commit | 49b3782ffe4690c26f45db95098aabcbd25c097a (patch) | |
tree | bcf4bcb27b5f458d2f9bf66d03a6203ecbd31e0a | |
parent | 4b7ce33f71acc3a83361a8088f5435fded0a5e78 (diff) |
I2C: Read SDA/SCL mapping for RV620 and up from AtomBIOS GPIO Info block.
-rw-r--r-- | src/rhd_atombios.c | 39 | ||||
-rw-r--r-- | src/rhd_atombios.h | 3 | ||||
-rw-r--r-- | src/rhd_i2c.c | 88 |
3 files changed, 114 insertions, 16 deletions
diff --git a/src/rhd_atombios.c b/src/rhd_atombios.c index cd6a84a..1209a2d 100644 --- a/src/rhd_atombios.c +++ b/src/rhd_atombios.c @@ -202,6 +202,12 @@ struct atomBIOSRequests { "LVDS 24Bit", MSG_FORMAT_HEX}, {ATOM_GPIO_I2C_CLK_MASK, rhdAtomGPIOI2CInfoQuery, "GPIO_I2C_Clk_Mask", MSG_FORMAT_HEX}, + {ATOM_GPIO_I2C_CLK_MASK_SHIFT, rhdAtomGPIOI2CInfoQuery, + "GPIO_I2C_Clk_Mask_Shift", MSG_FORMAT_HEX}, + {ATOM_GPIO_I2C_DATA_MASK, rhdAtomGPIOI2CInfoQuery, + "GPIO_I2C_Data_Mask", MSG_FORMAT_HEX}, + {ATOM_GPIO_I2C_DATA_MASK_SHIFT, rhdAtomGPIOI2CInfoQuery, + "GPIO_I2C_Data_Mask_Shift", MSG_FORMAT_HEX}, {ATOM_DAC1_BG_ADJ, rhdAtomCompassionateDataQuery, "DAC1 BG Adjustment", MSG_FORMAT_HEX}, {ATOM_DAC1_DAC_ADJ, rhdAtomCompassionateDataQuery, @@ -1660,21 +1666,36 @@ rhdAtomGPIOI2CInfoQuery(atomBiosHandlePtr handle, return ATOM_FAILED; } + if ((sizeof(ATOM_COMMON_TABLE_HEADER) + + (*val * sizeof(ATOM_GPIO_I2C_ASSIGMENT))) > size) { + xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: GPIO_I2C Device " + "num %lu exeeds table size %u\n",__func__, + (unsigned long)val, + size); + return ATOM_FAILED; + } + switch (func) { - case ATOM_GPIO_I2C_CLK_MASK: - if ((sizeof(ATOM_COMMON_TABLE_HEADER) - + (*val * sizeof(ATOM_GPIO_I2C_ASSIGMENT))) > size) { - xf86DrvMsg(handle->scrnIndex, X_ERROR, "%s: GPIO_I2C Device " - "num %lu exeeds table size %u\n",__func__, - (unsigned long)val, - size); - return ATOM_FAILED; - } + case ATOM_GPIO_I2C_DATA_MASK: + *val = atomDataPtr->GPIO_I2C_Info->asGPIO_Info[*val] + .usDataMaskRegisterIndex; + break; + + case ATOM_GPIO_I2C_DATA_MASK_SHIFT: + *val = atomDataPtr->GPIO_I2C_Info->asGPIO_Info[*val] + .ucDataMaskShift; + break; + case ATOM_GPIO_I2C_CLK_MASK: *val = atomDataPtr->GPIO_I2C_Info->asGPIO_Info[*val] .usClkMaskRegisterIndex; break; + case ATOM_GPIO_I2C_CLK_MASK_SHIFT: + *val = atomDataPtr->GPIO_I2C_Info->asGPIO_Info[*val] + .ucClkMaskShift; + break; + default: return ATOM_NOT_IMPLEMENTED; } diff --git a/src/rhd_atombios.h b/src/rhd_atombios.h index 3c3da06..0217446 100644 --- a/src/rhd_atombios.h +++ b/src/rhd_atombios.h @@ -67,6 +67,9 @@ typedef enum _AtomBiosRequestID { ATOM_LVDS_FPDI, ATOM_GPIO_QUERIES, ATOM_GPIO_I2C_CLK_MASK, + ATOM_GPIO_I2C_CLK_MASK_SHIFT, + ATOM_GPIO_I2C_DATA_MASK, + ATOM_GPIO_I2C_DATA_MASK_SHIFT, ATOM_DAC1_BG_ADJ, ATOM_DAC1_DAC_ADJ, ATOM_DAC1_FORCE, diff --git a/src/rhd_i2c.c b/src/rhd_i2c.c index 2e9ae9e..06dde99 100644 --- a/src/rhd_i2c.c +++ b/src/rhd_i2c.c @@ -219,8 +219,10 @@ enum rv620I2CBits { RV62_GENERIC_I2C_INDEX = (0xf << 16), RV62_GENERIC_I2C_INDEX_WRITE = (0x1 << 31), /* GENERIC_I2C_PIN_SELECTION */ - RV62_GENERIC_I2C_SCL_PIN_SEL = (0x7f << 0), - RV62_GENERIC_I2C_SDA_PIN_SEL = (0x7f << 8) + RV62_GENERIC_I2C_SCL_PIN_SEL_SHIFT = 0, + RV62_GENERIC_I2C_SCL_PIN_SEL = (0x7f << RV62_GENERIC_I2C_SCL_PIN_SEL_SHIFT), + RV62_GENERIC_I2C_SDA_PIN_SEL_SHIFT = 8, + RV62_GENERIC_I2C_SDA_PIN_SEL = (0x7f << RV62_GENERIC_I2C_SDA_PIN_SEL_SHIFT) }; /* R5xx */ @@ -792,6 +794,44 @@ rhdRV620I2CStatus(I2CBusPtr I2CPtr) return TRUE; /* 1 */ } +/* + * + */ +int +getDDCLineFromGPIO(CARD32 gpio, int shift) +{ + switch (gpio) { + case 0x1f90: + switch (shift) { + case 0: + return 1; /* ddc1 clk */ + case 8: + return 0; /* ddc1 data */ + } + break; + case 0x1f94: /* ddc2 */ + switch (shift) { + case 0: + return 3; /* ddc2 clk */ + case 8: + return 2; /* ddc2 data */ + } + break; + case 0x1f98: /* ddc3 */ + switch (shift) { + case 0: + return 5; /* ddc3 clk */ + case 8: + return 4; /* ddc3 data */ + } + break; + } + return -1; +} + +/* + * + */ static Bool rhdRV620I2CSetupStatus(I2CBusPtr I2CPtr, int line, int prescale) { @@ -799,6 +839,13 @@ rhdRV620I2CSetupStatus(I2CBusPtr I2CPtr, int line, int prescale) #ifdef ATOM_BIOS RHDPtr rhdPtr = RHDPTRI(I2CPtr); AtomBiosArgRec data; + + RHDFUNC(I2CPtr); + + if (line > 3) + return FALSE; + { +#if 0 int i = 0; struct atomGPIOTable { unsigned char line; @@ -806,11 +853,6 @@ rhdRV620I2CSetupStatus(I2CBusPtr I2CPtr, int line, int prescale) unsigned short reg_7d9c; } *table; - RHDFUNC(I2CPtr); - - if (line > 3) - return FALSE; - data.val = 0x36; if (RHDAtomBiosFunc(I2CPtr->scrnIndex, rhdPtr->atomBIOS, @@ -831,7 +873,39 @@ rhdRV620I2CSetupStatus(I2CBusPtr I2CPtr, int line, int prescale) } i++; } +#else + int scl = -1, sda = -1; + + if (RHDAtomBiosFunc(I2CPtr->scrnIndex, + rhdPtr->atomBIOS, + ATOM_GPIO_I2C_CLK_MASK, + &data) == ATOM_SUCCESS) { + CARD32 gpio = data.val; + if (RHDAtomBiosFunc(I2CPtr->scrnIndex, + rhdPtr->atomBIOS, + ATOM_GPIO_I2C_CLK_MASK_SHIFT, + &data) == ATOM_SUCCESS) { + scl = getDDCLineFromGPIO(gpio, data.val); + if (RHDAtomBiosFunc(I2CPtr->scrnIndex, + rhdPtr->atomBIOS, + ATOM_GPIO_I2C_DATA_MASK, + &data) == ATOM_SUCCESS) { + gpio = data.val; + if (RHDAtomBiosFunc(I2CPtr->scrnIndex, + rhdPtr->atomBIOS, + ATOM_GPIO_I2C_DATA_MASK, + &data) == ATOM_SUCCESS) { + sda = getDDCLineFromGPIO(gpio, data.val); + if (scl >= 0 && sda >= 0) + reg_7d9c = (scl << RV62_GENERIC_I2C_SCL_PIN_SEL_SHIFT) + | (sda << RV62_GENERIC_I2C_SDA_PIN_SEL_SHIFT); + } + } + } + } +#endif } + if (!reg_7d9c) #endif { |