hrev43443 adds 1 changeset to branch 'master' old head: 8c01b45a65603a60a32d4638a432d7f2aae2cdfc new head: 247a279283f56743b5ffbb7092baece66eb7a49f ---------------------------------------------------------------------------- 247a279: Add calls to read and write data from AUX connector * clean up previously changed error returns in 8c01b4. For some reason I thought B_ERROR was the only non-positive status. * add VESA DisplayPort defines. Only a subset so it's local to radeon_hd for now. * this completes basic AUX transaction code, still untested [ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev43443 Commit: 247a279283f56743b5ffbb7092baece66eb7a49f URL: http://cgit.haiku-os.org/haiku/commit/?id=247a279 Author: Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> Date: Thu Dec 8 23:57:22 2011 UTC ---------------------------------------------------------------------------- 2 files changed, 107 insertions(+), 3 deletions(-) src/add-ons/accelerants/radeon_hd/connector.cpp | 85 ++++++++++++++++++- src/add-ons/accelerants/radeon_hd/connector.h | 25 ++++++ ---------------------------------------------------------------------------- diff --git a/src/add-ons/accelerants/radeon_hd/connector.cpp b/src/add-ons/accelerants/radeon_hd/connector.cpp index a1fc565..8ea32e5 100644 --- a/src/add-ons/accelerants/radeon_hd/connector.cpp +++ b/src/add-ons/accelerants/radeon_hd/connector.cpp @@ -70,13 +70,13 @@ dp_aux_speak(uint8 connectorIndex, uint8 *send, int sendBytes, switch(args.v1.ucReplyStatus) { case 1: ERROR("%s: dp_aux_ch timeout!\n", __func__); - return B_ERROR; + return B_TIMED_OUT; case 2: ERROR("%s: dp_aux_ch flags not zero!\n", __func__); - return B_ERROR; + return B_BUSY; case 3: ERROR("%s: dp_aux_ch error!\n", __func__); - return B_ERROR; + return B_IO_ERROR; } int recvLength = args.v1.ucDataOutLen; @@ -90,6 +90,85 @@ dp_aux_speak(uint8 connectorIndex, uint8 *send, int sendBytes, } +int +dp_aux_write(uint32 connectorIndex, uint16 address, + uint8 *send, uint8 sendBytes, uint8 delay) +{ + uint8 auxMessage[20]; + int auxMessageBytes = sendBytes + 4; + + if (sendBytes > 16) + return -1; + + auxMessage[0] = address; + auxMessage[1] = address >> 8; + auxMessage[2] = AUX_NATIVE_WRITE << 4; + auxMessage[3] = (auxMessageBytes << 4) | (sendBytes - 1); + memcpy(&auxMessage[4], send, sendBytes); + + int ret; + uint8 retry; + uint8 ack; + for (retry = 0; retry < 4; retry++) { + + ret = dp_aux_speak(connectorIndex, auxMessage, auxMessageBytes, + NULL, 0, delay, &ack); + + if (ret == B_BUSY) + continue; + else if (ret < B_OK) + return ret; + + if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) + return sendBytes; + else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) + snooze(400); + else + return B_IO_ERROR; + } + + return B_IO_ERROR; +} + + +int +dp_aux_read(uint32 connectorIndex, uint16 address, + uint8 *recv, int recvBytes, uint8 delay) +{ + uint8 auxMessage[4]; + int auxMessageBytes = 4; + + auxMessage[0] = address; + auxMessage[1] = address >> 8; + auxMessage[2] = AUX_NATIVE_READ << 4; + auxMessage[3] = (auxMessageBytes << 4) | (recvBytes - 1); + + int ret; + uint8 retry; + uint8 ack; + for (retry = 0; retry < 4; retry++) { + ret = dp_aux_speak(connectorIndex, auxMessage, auxMessageBytes, + recv, recvBytes, delay, &ack); + + if (ret == B_BUSY) + continue; + else if (ret < B_OK) + return ret; + + if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) + return ret; + else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) + snooze(400); + else if (ret == 0) + return -EPROTO; + else + return B_IO_ERROR; + } + + return B_IO_ERROR; +} + + static void gpio_lock_i2c(void* cookie, bool lock) { diff --git a/src/add-ons/accelerants/radeon_hd/connector.h b/src/add-ons/accelerants/radeon_hd/connector.h index 28738af..108e59f 100644 --- a/src/add-ons/accelerants/radeon_hd/connector.h +++ b/src/add-ons/accelerants/radeon_hd/connector.h @@ -12,6 +12,26 @@ #include <video_configuration.h> +// From the VESA DisplayPort spec +// TODO: may want to move these into common code +#define AUX_NATIVE_WRITE 0x8 +#define AUX_NATIVE_READ 0x9 +#define AUX_I2C_WRITE 0x0 +#define AUX_I2C_READ 0x1 +#define AUX_I2C_STATUS 0x2 +#define AUX_I2C_MOT 0x4 + +#define AUX_NATIVE_REPLY_ACK (0x0 << 4) +#define AUX_NATIVE_REPLY_NACK (0x1 << 4) +#define AUX_NATIVE_REPLY_DEFER (0x2 << 4) +#define AUX_NATIVE_REPLY_MASK (0x3 << 4) + +#define AUX_I2C_REPLY_ACK (0x0 << 6) +#define AUX_I2C_REPLY_NACK (0x1 << 6) +#define AUX_I2C_REPLY_DEFER (0x2 << 6) +#define AUX_I2C_REPLY_MASK (0x3 << 6) + + // convert radeon connector to common connector type const int connector_convert_legacy[] = { VIDEO_CONNECTOR_UNKNOWN, @@ -60,6 +80,11 @@ const int connector_convert[] = { int dp_aux_speak(uint8 connectorIndex, uint8 *send, int sendBytes, uint8 *recv, int recvBytes, uint8 delay, uint8 *ack); +int dp_aux_write(uint32 connectorIndex, uint16 address, uint8 *send, + uint8 sendBytes, uint8 delay); +int dp_aux_read(uint32 connectorIndex, uint16 address, uint8 *recv, + int recvBytes, uint8 delay); + status_t gpio_probe(); status_t connector_attach_gpio(uint32 id, uint8 hw_line); bool connector_read_edid(uint32 connector, edid1_info *edid);