summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEgbert Eich <eich@freedesktop.org>2008-07-12 11:22:38 +0200
committerEgbert Eich <eich@freedesktop.org>2008-07-12 23:25:36 +0200
commit49b3782ffe4690c26f45db95098aabcbd25c097a (patch)
treebcf4bcb27b5f458d2f9bf66d03a6203ecbd31e0a
parent4b7ce33f71acc3a83361a8088f5435fded0a5e78 (diff)
I2C: Read SDA/SCL mapping for RV620 and up from AtomBIOS GPIO Info block.
-rw-r--r--src/rhd_atombios.c39
-rw-r--r--src/rhd_atombios.h3
-rw-r--r--src/rhd_i2c.c88
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
{