| #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 |