Add functions to i2c_smbus for pure i2c block transactions
Commit amended to rework API and change for code style by Adam Honse <calcprogrammer1@gmail.com>
This commit is contained in:
parent
aaa60d7d6f
commit
e36b52136c
14 changed files with 152 additions and 12 deletions
|
|
@ -164,8 +164,9 @@ s32 i2c_smbus_interface::i2c_smbus_xfer_call(u8 addr, char read_write, u8 comman
|
|||
i2c_addr = addr;
|
||||
i2c_read_write = read_write;
|
||||
i2c_command = command;
|
||||
i2c_size = size;
|
||||
i2c_data = data;
|
||||
i2c_size_smbus = size;
|
||||
i2c_data_smbus = data;
|
||||
smbus_xfer = true;
|
||||
|
||||
std::unique_lock<std::mutex> start_lock(i2c_smbus_start_mutex);
|
||||
i2c_smbus_start = true;
|
||||
|
|
@ -182,6 +183,41 @@ s32 i2c_smbus_interface::i2c_smbus_xfer_call(u8 addr, char read_write, u8 comman
|
|||
return(i2c_ret);
|
||||
}
|
||||
|
||||
s32 i2c_smbus_interface::i2c_xfer_call(u8 addr, char read_write, int* size, u8 *data)
|
||||
{
|
||||
i2c_smbus_xfer_mutex.lock();
|
||||
|
||||
i2c_addr = addr;
|
||||
i2c_read_write = read_write;
|
||||
i2c_size = size;
|
||||
i2c_data = data;
|
||||
smbus_xfer = false;
|
||||
|
||||
std::unique_lock<std::mutex> start_lock(i2c_smbus_start_mutex);
|
||||
i2c_smbus_start = true;
|
||||
i2c_smbus_start_cv.notify_all();
|
||||
start_lock.unlock();
|
||||
|
||||
std::unique_lock<std::mutex> done_lock(i2c_smbus_done_mutex);
|
||||
|
||||
i2c_smbus_done_cv.wait(done_lock, [this]{ return i2c_smbus_done.load(); });
|
||||
i2c_smbus_done = false;
|
||||
|
||||
i2c_smbus_xfer_mutex.unlock();
|
||||
|
||||
return(i2c_ret);
|
||||
}
|
||||
|
||||
s32 i2c_smbus_interface::i2c_read_block(u8 addr, int* size, u8* data)
|
||||
{
|
||||
return i2c_xfer_call(addr, I2C_SMBUS_READ, size, data);
|
||||
}
|
||||
|
||||
s32 i2c_smbus_interface::i2c_write_block(u8 addr, int size, u8 *data)
|
||||
{
|
||||
return i2c_xfer_call(addr, I2C_SMBUS_WRITE, &size, data);
|
||||
}
|
||||
|
||||
void i2c_smbus_interface::i2c_smbus_thread_function()
|
||||
{
|
||||
while(1)
|
||||
|
|
@ -196,11 +232,18 @@ void i2c_smbus_interface::i2c_smbus_thread_function()
|
|||
break;
|
||||
}
|
||||
|
||||
i2c_ret = i2c_smbus_xfer(i2c_addr, i2c_read_write, i2c_command, i2c_size, i2c_data);
|
||||
if(smbus_xfer)
|
||||
{
|
||||
i2c_ret = i2c_smbus_xfer(i2c_addr, i2c_read_write, i2c_command, i2c_size_smbus, i2c_data_smbus);
|
||||
}
|
||||
else
|
||||
{
|
||||
i2c_ret = i2c_xfer(i2c_addr, i2c_read_write, i2c_size, i2c_data);
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> done_lock(i2c_smbus_done_mutex);
|
||||
i2c_smbus_done = true;
|
||||
i2c_smbus_done_cv.notify_all();
|
||||
done_lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -70,6 +70,7 @@ union i2c_smbus_data
|
|||
#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
|
||||
#define I2C_SMBUS_I2C_BLOCK_DATA 8
|
||||
|
||||
|
||||
class i2c_smbus_interface
|
||||
{
|
||||
public:
|
||||
|
|
@ -99,10 +100,16 @@ public:
|
|||
s32 i2c_smbus_read_i2c_block_data(u8 addr, u8 command, u8 length, u8 *values);
|
||||
s32 i2c_smbus_write_i2c_block_data(u8 addr, u8 command, u8 length, const u8 *values);
|
||||
|
||||
s32 i2c_smbus_xfer_call(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
|
||||
//Addtional functions added for pure I2C block operations
|
||||
s32 i2c_read_block(u8 addr, int* size, u8* data);
|
||||
s32 i2c_write_block(u8 addr, int size, u8* data);
|
||||
|
||||
//Handle SMBus and I2C transfer calls in a single thread
|
||||
s32 i2c_smbus_xfer_call(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
|
||||
s32 i2c_xfer_call(u8 addr, char read_write, int* size, u8 *data);
|
||||
|
||||
//Virtual function to be implemented by the driver
|
||||
virtual s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data) = 0;
|
||||
virtual s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data) = 0;
|
||||
|
||||
private:
|
||||
std::thread * i2c_smbus_thread;
|
||||
|
|
@ -121,9 +128,12 @@ private:
|
|||
u8 i2c_addr;
|
||||
char i2c_read_write;
|
||||
u16 i2c_command;
|
||||
int i2c_size;
|
||||
i2c_smbus_data* i2c_data;
|
||||
int i2c_size_smbus;
|
||||
int* i2c_size;
|
||||
i2c_smbus_data* i2c_data_smbus;
|
||||
u8* i2c_data;
|
||||
s32 i2c_ret;
|
||||
bool smbus_xfer;
|
||||
};
|
||||
|
||||
#endif /* I2C_SMBUS_H */
|
||||
|
|
|
|||
|
|
@ -194,6 +194,11 @@ s32 i2c_smbus_amdadl::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int s
|
|||
return (ret);
|
||||
};
|
||||
|
||||
s32 i2c_smbus_amdadl::i2c_xfer(u8 addr, char read_write, int* size, u8* data)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#include "Detector.h"
|
||||
|
||||
bool i2c_smbus_amdadl_detect()
|
||||
|
|
|
|||
|
|
@ -30,5 +30,6 @@ public:
|
|||
|
||||
private:
|
||||
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
|
||||
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
|
||||
ADL_CONTEXT_HANDLE context = NULL;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -484,6 +484,11 @@ s32 i2c_smbus_i801::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int siz
|
|||
return i801_access(addr, read_write, command, size, data);
|
||||
}
|
||||
|
||||
s32 i2c_smbus_i801::i2c_xfer(u8 addr, char read_write, int* size, u8* data)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#include "Detector.h"
|
||||
#include "wmi.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -92,5 +92,5 @@ private:
|
|||
int i801_wait_byte_done();
|
||||
int i801_wait_intr();
|
||||
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
|
||||
|
||||
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
|
||||
};
|
||||
|
|
@ -12,9 +12,11 @@
|
|||
#include <linux/i2c-dev.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <cstring>
|
||||
|
||||
s32 i2c_smbus_linux::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, union i2c_smbus_data* data)
|
||||
{
|
||||
|
||||
struct i2c_smbus_ioctl_data args;
|
||||
|
||||
//Tell I2C host which slave address to transfer to
|
||||
|
|
@ -28,6 +30,24 @@ s32 i2c_smbus_linux::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int si
|
|||
return ioctl(handle, I2C_SMBUS, &args);
|
||||
}
|
||||
|
||||
s32 i2c_smbus_linux::i2c_xfer(u8 addr, char read_write, int* size, u8* data)
|
||||
{
|
||||
i2c_rdwr_ioctl_data rdwr;
|
||||
i2c_msg msg;
|
||||
|
||||
msg.addr = addr;
|
||||
msg.flags = read_write;
|
||||
msg.len = *size;
|
||||
msg.buf = (u8*)malloc(*size);
|
||||
memcpy(&msg.buf, &data, *size);
|
||||
|
||||
rdwr.msgs = &msg;
|
||||
rdwr.nmsgs = 1;
|
||||
|
||||
ioctl(handle, I2C_SLAVE, addr);
|
||||
return ioctl(handle, I2C_RDWR, &rdwr);
|
||||
}
|
||||
|
||||
#include "Detector.h"
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
|
|
|||
|
|
@ -16,4 +16,5 @@ public:
|
|||
|
||||
private:
|
||||
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
|
||||
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -189,6 +189,11 @@ s32 i2c_smbus_nct6775::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int
|
|||
return nct6775_access(addr, read_write, command, size, data);
|
||||
}
|
||||
|
||||
s32 i2c_smbus_nct6775::i2c_xfer(u8 addr, char read_write, int* size, u8* data)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#include "Detector.h"
|
||||
#include "super_io.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -53,5 +53,6 @@ public:
|
|||
private:
|
||||
s32 nct6775_access(u16 addr, char read_write, u8 command, int size, i2c_smbus_data *data);
|
||||
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
|
||||
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ s32 i2c_smbus_nvapi::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int mo
|
|||
NV_I2C_INFO_V3 i2c_data;
|
||||
uint8_t data_buf[I2C_SMBUS_BLOCK_MAX];
|
||||
uint8_t chip_addr;
|
||||
|
||||
|
||||
// Set up chip register address to command, one byte in length
|
||||
chip_addr = command;
|
||||
i2c_data.i2c_reg_address = &chip_addr;
|
||||
|
|
@ -114,7 +114,48 @@ s32 i2c_smbus_nvapi::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int mo
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
s32 i2c_smbus_nvapi::i2c_xfer(u8 addr, char read_write, int* size, u8* data)
|
||||
{
|
||||
NV_STATUS ret;
|
||||
unsigned int unknown = 0;
|
||||
NV_I2C_INFO_V3 i2c_data;
|
||||
|
||||
i2c_data.i2c_reg_address = NULL;
|
||||
i2c_data.reg_addr_size = 0;
|
||||
|
||||
// Set up data buffer, zero bytes in length
|
||||
i2c_data.data = data;
|
||||
i2c_data.size = *size;
|
||||
|
||||
// Always use GPU port 1 - this is where RGB controllers are attached
|
||||
i2c_data.is_ddc_port = 0;
|
||||
i2c_data.port_id = 1;
|
||||
i2c_data.is_port_id_set = 1;
|
||||
|
||||
// Use default speed
|
||||
i2c_data.i2c_speed = 0xFFFF;
|
||||
i2c_data.i2c_speed_khz = NV_I2C_SPEED::NVAPI_I2C_SPEED_DEFAULT;
|
||||
|
||||
// Load device address
|
||||
i2c_data.i2c_dev_address = (addr << 1);
|
||||
|
||||
// Perform read or write
|
||||
if(read_write == I2C_SMBUS_WRITE)
|
||||
{
|
||||
ret = NvAPI_I2CWriteEx(handle, &i2c_data, &unknown);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NvAPI_I2CReadEx(handle, &i2c_data, &unknown);
|
||||
|
||||
*size = i2c_data.size;
|
||||
memcpy(data, i2c_data.data, i2c_data.size);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,11 @@ class i2c_smbus_nvapi : public i2c_smbus_interface
|
|||
{
|
||||
public:
|
||||
i2c_smbus_nvapi(NV_PHYSICAL_GPU_HANDLE handle);
|
||||
s32 i2c_read_block_data(u8 addr, u8 length, u8 *values);
|
||||
s32 i2c_write_block_data(u8 addr, u8 length, u8 *values);
|
||||
|
||||
private:
|
||||
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int mode, i2c_smbus_data* data);
|
||||
|
||||
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
|
||||
NV_PHYSICAL_GPU_HANDLE handle;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -178,6 +178,11 @@ s32 i2c_smbus_piix4::i2c_smbus_xfer(u8 addr, char read_write, u8 command, int si
|
|||
return piix4_access(addr, read_write, command, size, data);
|
||||
}
|
||||
|
||||
s32 i2c_smbus_piix4::i2c_xfer(u8 addr, char read_write, int* size, u8* data)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#include "Detector.h"
|
||||
#include "wmi.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -45,4 +45,5 @@ private:
|
|||
int piix4_transaction();
|
||||
s32 piix4_access(u16 addr, char read_write, u8 command, int size, i2c_smbus_data *data);
|
||||
s32 i2c_smbus_xfer(u8 addr, char read_write, u8 command, int size, i2c_smbus_data* data);
|
||||
s32 i2c_xfer(u8 addr, char read_write, int* size, u8* data);
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue