blob: 8b8c6a02eabdb1a990e3a46063dc2588e9dbb57d [file] [log] [blame]
#include <stdio.h>
#include <linux/types.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include "mbtk_log.h"
#include "ql/ql_i2c.h"
int Ql_I2C_Init(char *dev_name)
{
int fd = open(dev_name, O_RDWR);
if(fd <= 0) {
LOGE("open (%s) fail:errno - %d", dev_name, errno);
return -1;
}
return fd;
}
int Ql_I2C_Read(int fd, unsigned short slaveAddr, unsigned char ofstAddr, unsigned char* ptrBuff, unsigned short length)
{
uint8_t outbuf[1];
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[2];
outbuf[0] = ofstAddr;
messages[0].addr = slaveAddr;
messages[0].flags = 0;
messages[0].len = sizeof(outbuf);
messages[0].buf = outbuf;
/* The data will get returned in this structure */
messages[1].addr = slaveAddr;
messages[1].flags = I2C_M_RD/* | I2C_M_NOSTART*/;
messages[1].len = length;
messages[1].buf = ptrBuff;
/* Send the request to the kernel and get the result back */
packets.msgs = messages;
packets.nmsgs = 2;
if(ioctl(fd, I2C_RDWR, &packets) < 0)
{
LOGE("Error: Unable to send data");
return -1;
}
return 0;
}
int Ql_I2C_Write(int fd, unsigned short slaveAddr, unsigned char ofstAddr, unsigned char* ptrData, unsigned short length)
{
uint8_t *outbuf = NULL;
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[1];
outbuf = malloc(length + 1);
if (!outbuf) {
printf("Error: No memory for buffer\n");
return -1;
}
outbuf[0] = ofstAddr;
memcpy(outbuf + 1, ptrData, length);
messages[0].addr = slaveAddr;
messages[0].flags = 0;
messages[0].len = length + 1;
messages[0].buf = outbuf;
/* Transfer the i2c packets to the kernel and verify it worked */
packets.msgs = messages;
packets.nmsgs = 1;
if(ioctl(fd, I2C_RDWR, &packets) < 0)
{
printf("Error: Unable to send data");
free(outbuf);
return -1;
}
free(outbuf);
return 0;
}
int Ql_I2C_Deinit(int fd)
{
if (fd <= 0)
return -1;
close(fd);
return 0;
}
#if 0
int open_i2c_dev(int i2cbus, char *filename, size_t size, int quiet)
{
int file, len;
len = snprintf(filename, size, "/dev/i2c/%d", i2cbus);
if (len >= (int)size) {
fprintf(stderr, "%s: path truncated\n", filename);
return -EOVERFLOW;
}
file = open(filename, O_RDWR);
if (file < 0 && (errno == ENOENT || errno == ENOTDIR)) {
len = snprintf(filename, size, "/dev/i2c-%d", i2cbus);
if (len >= (int)size) {
fprintf(stderr, "%s: path truncated\n", filename);
return -EOVERFLOW;
}
file = open(filename, O_RDWR);
}
...
return file;
}
static int i2c_read_bytes(int fd, uint8_t slave_addr, uint8_t reg_addr, uint8_t *values, uint8_t len)
{
uint8_t outbuf[1];
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[2];
outbuf[0] = reg_addr;
messages[0].addr = slave_addr;
messages[0].flags = 0;
messages[0].len = sizeof(outbuf);
messages[0].buf = outbuf;
/* The data will get returned in this structure */
messages[1].addr = slave_addr;
messages[1].flags = I2C_M_RD/* | I2C_M_NOSTART*/;
messages[1].len = len;
messages[1].buf = values;
/* Send the request to the kernel and get the result back */
packets.msgs = messages;
packets.nmsgs = 2;
if(ioctl(fd, I2C_RDWR, &packets) < 0)
{
printf("Error: Unable to send data");
return -1;
}
return 0;
}
static int i2c_write_bytes(int fd, uint8_t slave_addr, uint8_t reg_addr, uint8_t *values, uint8_t len)
{
uint8_t *outbuf = NULL;
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[1];
outbuf = malloc(len + 1);
if (!outbuf) {
printf("Error: No memory for buffer\n");
return -1;
}
outbuf[0] = reg_addr;
memcpy(outbuf + 1, values, len);
messages[0].addr = slave_addr;
messages[0].flags = 0;
messages[0].len = len + 1;
messages[0].buf = outbuf;
/* Transfer the i2c packets to the kernel and verify it worked */
packets.msgs = messages;
packets.nmsgs = 1;
if(ioctl(fd, I2C_RDWR, &packets) < 0)
{
printf("Error: Unable to send data");
free(outbuf);
return -1;
}
free(outbuf);
return 0;
}
int set_slave_addr(int file, int address, int force)
{
/* With force, let the user read from/write to the registers
even when a driver is also running */
if (ioctl(file, force ? I2C_SLAVE_FORCE : I2C_SLAVE, address) < 0) {
fprintf(stderr,
"Error: Could not set address to 0x%02x: %s\n",
address, strerror(errno));
return -errno;
}
return 0;
}
int main(void)
{
int fd = -1;
char send_data[64] = {0};
send_data[0] = 0x55;
send_data[1] = 0x00;
send_data[2] = 0x84;
fd= open_i2c_dev(0, "i2c_test", 5, 0);
i2c_write_bytes(fd, 0x12, 0x10,send_data, 3)
}
#endif