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;
|
} i2c_timing;
|
||||||
|
|
||||||
|
|
||||||
|
struct i2c_bus;
|
||||||
|
|
||||||
// set signals on bus
|
// set signals on bus
|
||||||
typedef status_t (*i2c_set_signals)(void *cookie, int clock, int data);
|
typedef status_t (*i2c_set_signals)(void *cookie, int clock, int data);
|
||||||
// read signals from bus
|
// read signals from bus
|
||||||
typedef status_t (*i2c_get_signals)(void *cookie, int *clock, int *data);
|
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
|
// i2c bus definition
|
||||||
typedef struct i2c_bus {
|
typedef struct i2c_bus {
|
||||||
void *cookie; // user-defined cookie
|
void *cookie; // user-defined cookie
|
||||||
|
// low-level
|
||||||
i2c_timing timing;
|
i2c_timing timing;
|
||||||
i2c_set_signals set_signals; // callback to set signals
|
i2c_set_signals set_signals; // callback to set signals
|
||||||
i2c_get_signals get_signals; // callback to detect signals
|
i2c_get_signals get_signals; // callback to detect signals
|
||||||
|
// high-level
|
||||||
|
i2c_send_receive send_receive;
|
||||||
} i2c_bus;
|
} i2c_bus;
|
||||||
|
|
||||||
|
|
||||||
@@ -54,7 +63,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// send and receive data via i2c bus
|
// 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,
|
const uint8 *writeBuffer, size_t writeLength, uint8 *readBuffer,
|
||||||
size_t readLength);
|
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
|
//! Read ddc2 data from monitor
|
||||||
static status_t
|
static status_t
|
||||||
ddc2_read(const i2c_bus *bus, int start, uint8 *buffer, size_t length)
|
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;
|
writeBuffer[1] = (start >> 8) & 0xff;
|
||||||
|
|
||||||
for (i = 0; i < READ_RETRIES; ++i) {
|
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);
|
start < 0x100 ? 1 : 2, buffer, length);
|
||||||
|
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
@@ -135,6 +148,8 @@ ddc2_read_vdif(const i2c_bus *bus, int start,
|
|||||||
void
|
void
|
||||||
ddc2_init_timing(i2c_bus *bus)
|
ddc2_init_timing(i2c_bus *bus)
|
||||||
{
|
{
|
||||||
|
bus->send_receive = NULL;
|
||||||
|
|
||||||
i2c_get100k_timing(&bus->timing);
|
i2c_get100k_timing(&bus->timing);
|
||||||
|
|
||||||
// VESA standard
|
// 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
|
//! Send slave address, obeying 10-bit addresses and general call addresses
|
||||||
static status_t
|
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;
|
status_t status;
|
||||||
|
|
||||||
@@ -400,10 +400,17 @@ receive_bytes(const i2c_bus *bus, uint8 *readBuffer, ssize_t readLength)
|
|||||||
|
|
||||||
//! Combined i2c send+receive format
|
//! Combined i2c send+receive format
|
||||||
status_t
|
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)
|
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)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|||||||
@@ -208,20 +208,9 @@ Port::GetEDID(edid1_info* edid, bool forceRead)
|
|||||||
if (fEDIDState == B_NO_INIT || forceRead) {
|
if (fEDIDState == B_NO_INIT || forceRead) {
|
||||||
TRACE("%s: trying to read EDID\n", PortName());
|
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;
|
i2c_bus bus;
|
||||||
bus.cookie = (void*)ddcRegister;
|
if (SetupI2c(&bus) != B_OK)
|
||||||
bus.set_signals = &_SetI2CSignals;
|
return fEDIDState;
|
||||||
bus.get_signals = &_GetI2CSignals;
|
|
||||||
ddc2_init_timing(&bus);
|
|
||||||
|
|
||||||
fEDIDState = ddc2_read_edid1(&bus, &fEDIDInfo, NULL, NULL);
|
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
|
status_t
|
||||||
Port::GetPLLLimits(pll_limits& limits)
|
Port::GetPLLLimits(pll_limits& limits)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#define MAX_PORTS 20 // a generous upper bound
|
#define MAX_PORTS 20 // a generous upper bound
|
||||||
|
|
||||||
struct pll_limits;
|
struct pll_limits;
|
||||||
|
struct i2c_bus;
|
||||||
|
|
||||||
enum port_type {
|
enum port_type {
|
||||||
INTEL_PORT_TYPE_ANY, // wildcard for lookup functions
|
INTEL_PORT_TYPE_ANY, // wildcard for lookup functions
|
||||||
@@ -57,6 +58,7 @@ virtual status_t Power(bool enabled);
|
|||||||
bool HasEDID();
|
bool HasEDID();
|
||||||
virtual status_t GetEDID(edid1_info* edid,
|
virtual status_t GetEDID(edid1_info* edid,
|
||||||
bool forceRead = false);
|
bool forceRead = false);
|
||||||
|
virtual status_t SetupI2c(struct i2c_bus *bus);
|
||||||
|
|
||||||
virtual status_t GetPLLLimits(pll_limits& limits);
|
virtual status_t GetPLLLimits(pll_limits& limits);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user