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
This commit is contained in:
Alexander von Gluck IV 2011-12-08 17:57:22 -06:00
parent 8c01b45a65
commit 247a279283
2 changed files with 107 additions and 3 deletions

View File

@ -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)
{

View File

@ -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);