i2c: add acquire_bus/release_bus hooks
Change-Id: I9f55bb824f264175ae5830a2853a1897e3a00139 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2470 Reviewed-by: Jérôme Duval <[email protected]>
This commit is contained in:
@@ -53,7 +53,8 @@ typedef struct {
|
|||||||
status_t (*exec_command)(i2c_device cookie, i2c_op op,
|
status_t (*exec_command)(i2c_device cookie, i2c_op op,
|
||||||
const void *cmdBuffer, size_t cmdLength, void* dataBuffer,
|
const void *cmdBuffer, size_t cmdLength, void* dataBuffer,
|
||||||
size_t dataLength);
|
size_t dataLength);
|
||||||
|
status_t (*acquire_bus)(i2c_device cookie);
|
||||||
|
void (*release_bus)(i2c_device cookie);
|
||||||
} i2c_device_interface;
|
} i2c_device_interface;
|
||||||
|
|
||||||
|
|
||||||
@@ -76,6 +77,8 @@ typedef struct {
|
|||||||
status_t (*exec_command)(i2c_bus cookie, i2c_op op, i2c_addr slaveAddress,
|
status_t (*exec_command)(i2c_bus cookie, i2c_op op, i2c_addr slaveAddress,
|
||||||
const void *cmdBuffer, size_t cmdLength, void* dataBuffer,
|
const void *cmdBuffer, size_t cmdLength, void* dataBuffer,
|
||||||
size_t dataLength);
|
size_t dataLength);
|
||||||
|
status_t (*acquire_bus)(i2c_bus cookie);
|
||||||
|
void (*release_bus)(i2c_bus cookie);
|
||||||
} i2c_bus_interface;
|
} i2c_bus_interface;
|
||||||
|
|
||||||
|
|
||||||
@@ -119,12 +122,14 @@ typedef struct {
|
|||||||
|
|
||||||
status_t (*scan_bus)(i2c_bus_cookie cookie);
|
status_t (*scan_bus)(i2c_bus_cookie cookie);
|
||||||
|
|
||||||
|
status_t (*acquire_bus)(i2c_bus_cookie cookie);
|
||||||
|
void (*release_bus)(i2c_bus_cookie cookie);
|
||||||
|
|
||||||
status_t (*install_interrupt_handler)(i2c_bus_cookie cookie,
|
status_t (*install_interrupt_handler)(i2c_bus_cookie cookie,
|
||||||
i2c_intr_cookie intrCookie, interrupt_handler handler, void* data);
|
i2c_intr_cookie intrCookie, interrupt_handler handler, void* data);
|
||||||
|
|
||||||
status_t (*uninstall_interrupt_handler)(i2c_bus_cookie cookie,
|
status_t (*uninstall_interrupt_handler)(i2c_bus_cookie cookie,
|
||||||
i2c_intr_cookie intrCookie);
|
i2c_intr_cookie intrCookie);
|
||||||
|
|
||||||
} i2c_sim_interface;
|
} i2c_sim_interface;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -83,12 +83,31 @@ status_t
|
|||||||
I2CBus::Scan()
|
I2CBus::Scan()
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
if (fController->scan_bus != NULL)
|
||||||
fController->scan_bus(fCookie);
|
fController->scan_bus(fCookie);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
I2CBus::AcquireBus()
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
if (fController->acquire_bus != NULL)
|
||||||
|
return fController->acquire_bus(fCookie);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
I2CBus::ReleaseBus()
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
if (fController->release_bus != NULL)
|
||||||
|
fController->release_bus(fCookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
i2c_init_bus(device_node *node, void **_bus)
|
i2c_init_bus(device_node *node, void **_bus)
|
||||||
{
|
{
|
||||||
@@ -127,7 +146,7 @@ i2c_uninit_bus(void *_bus)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
static status_t
|
||||||
i2c_scan_bus(void *_bus)
|
i2c_scan_bus(void *_bus)
|
||||||
{
|
{
|
||||||
I2CBus *bus = (I2CBus *)_bus;
|
I2CBus *bus = (I2CBus *)_bus;
|
||||||
@@ -147,6 +166,24 @@ i2c_bus_exec_command(void* _bus, i2c_op op, i2c_addr slaveAddress,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
i2c_bus_acquire_bus(void* _bus)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
I2CBus* bus = (I2CBus*)_bus;
|
||||||
|
return bus->AcquireBus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
i2c_bus_release_bus(void* _bus)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
I2CBus* bus = (I2CBus*)_bus;
|
||||||
|
return bus->ReleaseBus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
std_ops(int32 op, ...)
|
std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
@@ -179,6 +216,8 @@ i2c_bus_interface gI2CBusModule = {
|
|||||||
NULL, // rescan
|
NULL, // rescan
|
||||||
},
|
},
|
||||||
|
|
||||||
i2c_bus_exec_command
|
i2c_bus_exec_command,
|
||||||
|
i2c_bus_acquire_bus,
|
||||||
|
i2c_bus_release_bus,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,21 @@ I2CDevice::ExecCommand(i2c_op op, const void *cmdBuffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
I2CDevice::AcquireBus()
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
return fBus->AcquireBus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
I2CDevice::ReleaseBus()
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
fBus->ReleaseBus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
i2c_init_device(device_node *node, void **_device)
|
i2c_init_device(device_node *node, void **_device)
|
||||||
@@ -101,6 +116,22 @@ i2c_exec_command(i2c_device _device, i2c_op op, const void *cmdBuffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
i2c_acquire_bus(i2c_device _device)
|
||||||
|
{
|
||||||
|
I2CDevice *device = (I2CDevice *)_device;
|
||||||
|
return device->AcquireBus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
i2c_release_bus(i2c_device _device)
|
||||||
|
{
|
||||||
|
I2CDevice *device = (I2CDevice *)_device;
|
||||||
|
return device->ReleaseBus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
std_ops(int32 op, ...)
|
std_ops(int32 op, ...)
|
||||||
{
|
{
|
||||||
@@ -140,4 +171,6 @@ i2c_device_interface gI2CDeviceModule = {
|
|||||||
(void (*)(void *)) i2c_device_removed
|
(void (*)(void *)) i2c_device_removed
|
||||||
},
|
},
|
||||||
i2c_exec_command,
|
i2c_exec_command,
|
||||||
|
i2c_acquire_bus,
|
||||||
|
i2c_release_bus,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ public:
|
|||||||
status_t ExecCommand(i2c_op op, const void *cmdBuffer,
|
status_t ExecCommand(i2c_op op, const void *cmdBuffer,
|
||||||
size_t cmdLength, void* dataBuffer,
|
size_t cmdLength, void* dataBuffer,
|
||||||
size_t dataLength);
|
size_t dataLength);
|
||||||
|
status_t AcquireBus();
|
||||||
|
void ReleaseBus();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
device_node* fNode;
|
device_node* fNode;
|
||||||
@@ -73,6 +75,8 @@ public:
|
|||||||
status_t RegisterDevice(i2c_addr slaveAddress,
|
status_t RegisterDevice(i2c_addr slaveAddress,
|
||||||
char* hid, char** cid,
|
char* hid, char** cid,
|
||||||
acpi_handle acpiHandle);
|
acpi_handle acpiHandle);
|
||||||
|
status_t AcquireBus();
|
||||||
|
void ReleaseBus();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
device_node* fNode;
|
device_node* fNode;
|
||||||
|
|||||||
@@ -87,9 +87,15 @@ i2c_bus_raw_control(void *_cookie, uint32 op, void *data, size_t length)
|
|||||||
exec.buffer = buffer;
|
exec.buffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t status = bus->ExecCommand(exec.op, exec.addr,
|
status_t status = bus->AcquireBus();
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = bus->ExecCommand(exec.op, exec.addr,
|
||||||
&exec.cmdBuffer, exec.cmdLength, exec.buffer,
|
&exec.cmdBuffer, exec.cmdLength, exec.buffer,
|
||||||
exec.bufferLength);
|
exec.bufferLength);
|
||||||
|
bus->ReleaseBus();
|
||||||
|
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|||||||
@@ -370,6 +370,24 @@ scan_bus(i2c_bus_cookie cookie)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
acquire_bus(i2c_bus_cookie cookie)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
pch_i2c_sim_info* bus = (pch_i2c_sim_info*)cookie;
|
||||||
|
return mutex_lock(&bus->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
release_bus(i2c_bus_cookie cookie)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
pch_i2c_sim_info* bus = (pch_i2c_sim_info*)cookie;
|
||||||
|
mutex_unlock(&bus->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -467,6 +485,7 @@ init_bus(device_node* node, void** bus_cookie)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_init(&bus->lock, "pch_i2c");
|
||||||
*bus_cookie = bus;
|
*bus_cookie = bus;
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -482,6 +501,7 @@ uninit_bus(void* bus_cookie)
|
|||||||
{
|
{
|
||||||
pch_i2c_sim_info* bus = (pch_i2c_sim_info*)bus_cookie;
|
pch_i2c_sim_info* bus = (pch_i2c_sim_info*)bus_cookie;
|
||||||
|
|
||||||
|
mutex_destroy(&bus->lock);
|
||||||
remove_io_interrupt_handler(bus->irq,
|
remove_io_interrupt_handler(bus->irq,
|
||||||
(interrupt_handler)pch_i2c_interrupt_handler, bus);
|
(interrupt_handler)pch_i2c_interrupt_handler, bus);
|
||||||
if (bus->registersArea >= 0)
|
if (bus->registersArea >= 0)
|
||||||
@@ -521,6 +541,8 @@ static i2c_sim_interface sPchI2cDeviceModule = {
|
|||||||
set_sim,
|
set_sim,
|
||||||
exec_command,
|
exec_command,
|
||||||
scan_bus,
|
scan_bus,
|
||||||
|
acquire_bus,
|
||||||
|
release_bus,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include <i2c.h>
|
#include <i2c.h>
|
||||||
|
#include <lock.h>
|
||||||
|
|
||||||
|
|
||||||
//#define TRACE_PCH_I2C
|
//#define TRACE_PCH_I2C
|
||||||
@@ -105,6 +106,7 @@ typedef struct {
|
|||||||
uint32 flags;
|
uint32 flags;
|
||||||
int32 error;
|
int32 error;
|
||||||
|
|
||||||
|
mutex lock;
|
||||||
status_t (*scan_bus)(i2c_bus_cookie cookie);
|
status_t (*scan_bus)(i2c_bus_cookie cookie);
|
||||||
} pch_i2c_sim_info;
|
} pch_i2c_sim_info;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user