intel_extreme: change i2c_send_receive to a hook
common: i2c/ddc uses a 7-bit address for EDID. Change-Id: Ic1bba2a23174c671bd7374104596c22433bd343a Reviewed-on: https://review.haiku-os.org/c/haiku/+/5171 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
5e6e52cfd4
commit
5f90c3726b
@@ -35,17 +35,26 @@ typedef struct i2c_timing {
|
||||
} i2c_timing;
|
||||
|
||||
|
||||
struct i2c_bus;
|
||||
|
||||
// set signals on bus
|
||||
typedef status_t (*i2c_set_signals)(void *cookie, int clock, int data);
|
||||
// read signals from bus
|
||||
typedef status_t (*i2c_get_signals)(void *cookie, int *clock, int *data);
|
||||
// send/receive from bus
|
||||
typedef status_t (*i2c_send_receive)(const struct i2c_bus *bus, uint32 slave_address,
|
||||
const uint8 *writeBuffer, size_t writeLength, uint8 *readBuffer,
|
||||
size_t readLength);
|
||||
|
||||
// i2c bus definition
|
||||
typedef struct i2c_bus {
|
||||
void *cookie; // user-defined cookie
|
||||
// low-level
|
||||
i2c_timing timing;
|
||||
i2c_set_signals set_signals; // callback to set signals
|
||||
i2c_get_signals get_signals; // callback to detect signals
|
||||
// high-level
|
||||
i2c_send_receive send_receive;
|
||||
} i2c_bus;
|
||||
|
||||
|
||||
@@ -54,7 +63,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
// send and receive data via i2c bus
|
||||
status_t i2c_send_receive(const i2c_bus *bus, int slave_address,
|
||||
status_t i2c_send_receive_callback(const i2c_bus *bus, uint32 slave_address,
|
||||
const uint8 *writeBuffer, size_t writeLength, uint8 *readBuffer,
|
||||
size_t readLength);
|
||||
|
||||
|
||||
@@ -54,6 +54,19 @@ verify_checksum(const uint8 *data, size_t len)
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
call_send_receive(const i2c_bus *bus, int slave_address,
|
||||
const uint8 *writeBuffer, size_t writeLength, uint8 *readBuffer,
|
||||
size_t readLength)
|
||||
{
|
||||
i2c_send_receive send_receive = bus->send_receive;
|
||||
if (send_receive == NULL)
|
||||
send_receive = i2c_send_receive_callback;
|
||||
return send_receive(bus, slave_address, writeBuffer, writeLength, readBuffer,
|
||||
readLength);
|
||||
}
|
||||
|
||||
|
||||
//! Read ddc2 data from monitor
|
||||
static status_t
|
||||
ddc2_read(const i2c_bus *bus, int start, uint8 *buffer, size_t length)
|
||||
@@ -66,7 +79,7 @@ ddc2_read(const i2c_bus *bus, int start, uint8 *buffer, size_t length)
|
||||
writeBuffer[1] = (start >> 8) & 0xff;
|
||||
|
||||
for (i = 0; i < READ_RETRIES; ++i) {
|
||||
status = i2c_send_receive(bus, 0xa0, writeBuffer,
|
||||
status = call_send_receive(bus, 0x50, writeBuffer,
|
||||
start < 0x100 ? 1 : 2, buffer, length);
|
||||
|
||||
if (status != B_OK)
|
||||
@@ -135,6 +148,8 @@ ddc2_read_vdif(const i2c_bus *bus, int start,
|
||||
void
|
||||
ddc2_init_timing(i2c_bus *bus)
|
||||
{
|
||||
bus->send_receive = NULL;
|
||||
|
||||
i2c_get100k_timing(&bus->timing);
|
||||
|
||||
// VESA standard
|
||||
|
||||
@@ -268,7 +268,7 @@ send_byte(const i2c_bus *bus, uint8 byte, bool acknowledge)
|
||||
|
||||
//! Send slave address, obeying 10-bit addresses and general call addresses
|
||||
static status_t
|
||||
send_slave_address(const i2c_bus *bus, int slaveAddress, bool isWrite)
|
||||
send_slave_address(const i2c_bus *bus, uint8 slaveAddress, bool isWrite)
|
||||
{
|
||||
status_t status;
|
||||
|
||||
@@ -400,10 +400,17 @@ receive_bytes(const i2c_bus *bus, uint8 *readBuffer, ssize_t readLength)
|
||||
|
||||
//! Combined i2c send+receive format
|
||||
status_t
|
||||
i2c_send_receive(const i2c_bus *bus, int slaveAddress, const uint8 *writeBuffer,
|
||||
i2c_send_receive_callback(const i2c_bus *bus, uint32 slaveAddress, const uint8 *writeBuffer,
|
||||
size_t writeLength, uint8 *readBuffer, size_t readLength)
|
||||
{
|
||||
status_t status = send_start_condition(bus);
|
||||
status_t status;
|
||||
|
||||
// the address is 7-bit
|
||||
slaveAddress <<= 1;
|
||||
if (slaveAddress > 0xff)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
status = send_start_condition(bus);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
|
||||
@@ -208,20 +208,9 @@ Port::GetEDID(edid1_info* edid, bool forceRead)
|
||||
if (fEDIDState == B_NO_INIT || forceRead) {
|
||||
TRACE("%s: trying to read EDID\n", PortName());
|
||||
|
||||
addr_t ddcRegister = _DDCRegister();
|
||||
if (ddcRegister == 0) {
|
||||
TRACE("%s: no DDC register found\n", PortName());
|
||||
fEDIDState = B_ERROR;
|
||||
return fEDIDState;
|
||||
}
|
||||
|
||||
TRACE("%s: using ddc @ 0x%" B_PRIxADDR "\n", PortName(), ddcRegister);
|
||||
|
||||
i2c_bus bus;
|
||||
bus.cookie = (void*)ddcRegister;
|
||||
bus.set_signals = &_SetI2CSignals;
|
||||
bus.get_signals = &_GetI2CSignals;
|
||||
ddc2_init_timing(&bus);
|
||||
if (SetupI2c(&bus) != B_OK)
|
||||
return fEDIDState;
|
||||
|
||||
fEDIDState = ddc2_read_edid1(&bus, &fEDIDInfo, NULL, NULL);
|
||||
|
||||
@@ -243,6 +232,27 @@ Port::GetEDID(edid1_info* edid, bool forceRead)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Port::SetupI2c(i2c_bus *bus)
|
||||
{
|
||||
addr_t ddcRegister = _DDCRegister();
|
||||
if (ddcRegister == 0) {
|
||||
TRACE("%s: no DDC register found\n", PortName());
|
||||
fEDIDState = B_ERROR;
|
||||
return fEDIDState;
|
||||
}
|
||||
|
||||
TRACE("%s: using ddc @ 0x%" B_PRIxADDR "\n", PortName(), ddcRegister);
|
||||
|
||||
ddc2_init_timing(bus);
|
||||
bus->cookie = (void*)ddcRegister;
|
||||
bus->set_signals = &_SetI2CSignals;
|
||||
bus->get_signals = &_GetI2CSignals;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Port::GetPLLLimits(pll_limits& limits)
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define MAX_PORTS 20 // a generous upper bound
|
||||
|
||||
struct pll_limits;
|
||||
struct i2c_bus;
|
||||
|
||||
enum port_type {
|
||||
INTEL_PORT_TYPE_ANY, // wildcard for lookup functions
|
||||
@@ -57,6 +58,7 @@ virtual status_t Power(bool enabled);
|
||||
bool HasEDID();
|
||||
virtual status_t GetEDID(edid1_info* edid,
|
||||
bool forceRead = false);
|
||||
virtual status_t SetupI2c(struct i2c_bus *bus);
|
||||
|
||||
virtual status_t GetPLLLimits(pll_limits& limits);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user