This patch support below peripheral-io APIs.
- peripheral_i2c_read_register_byte()
- peripheral_i2c_write_register_byte()
- peripheral_i2c_read_register_word()
- peripheral_i2c_write_register_word()
Below APIs already existed, but they are changed to use SMBUS ioctl in
this patch.
- peripheral_i2c_read_byte()
- peripheral_i2c_write_byte()
Change-Id: Ie22dd237fce9b731c7ecbbd904ec0f5219b005e1
Signed-off-by: Hyeongsik Min <hyeongsik.min@samsung.com>
return true;
}
+gboolean handle_i2c_smbus_ioctl(
+ PeripheralIoGdbusI2c *i2c,
+ GDBusMethodInvocation *invocation,
+ gint handle,
+ guchar read_write,
+ guchar command,
+ guint size,
+ guint16 data_in,
+ gpointer user_data)
+{
+ peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+ pb_i2c_data_h i2c_handle = GUINT_TO_POINTER(handle);
+ const gchar *id;
+ uint16_t data;
+
+ /* Handle validation */
+ if (!i2c_handle || !i2c_handle->client_info.id) {
+ _E("i2c handle is not valid");
+ ret = PERIPHERAL_ERROR_UNKNOWN;
+ goto out;
+ }
+ id = g_dbus_method_invocation_get_sender(invocation);
+ if (strcmp(i2c_handle->client_info.id, id)) {
+ _E("Invalid access, handle id : %s, current id : %s", i2c_handle->client_info.id, id);
+ ret = PERIPHERAL_ERROR_INVALID_OPERATION;
+ goto out;
+ }
+
+ ret = peripheral_bus_i2c_smbus_ioctl(i2c_handle, read_write, command, size, data_in, &data);
+out:
+ peripheral_io_gdbus_i2c_complete_smbus_ioctl(i2c, invocation, data, ret);
+
+ return true;
+}
+
gboolean handle_pwm_open(
PeripheralIoGdbusPwm *pwm,
GDBusMethodInvocation *invocation,
"handle-write",
G_CALLBACK(handle_i2c_write),
pb_data);
+ g_signal_connect(pb_data->i2c_skeleton,
+ "handle-smbus-ioctl",
+ G_CALLBACK(handle_i2c_smbus_ioctl),
+ pb_data);
manager = g_dbus_object_manager_server_new(PERIPHERAL_GDBUS_I2C_PATH);
return i2c_write(i2c->fd, i2c->buffer, length);
}
+
+int peripheral_bus_i2c_smbus_ioctl(pb_i2c_data_h i2c, uint8_t read_write, uint8_t command, uint32_t size, uint16_t data_in, uint16_t *data_out)
+{
+ struct i2c_smbus_ioctl_data data_arg;
+ union i2c_smbus_data data;
+ int ret;
+
+ memset(&data_arg, 0x0, sizeof(struct i2c_smbus_ioctl_data));
+ memset(&data, 0x0, sizeof(data.block));
+
+ data_arg.read_write = read_write;
+ data_arg.size = size;
+ data_arg.data = &data;
+
+ RETV_IF(size < I2C_SMBUS_BYTE || size > I2C_SMBUS_WORD_DATA, PERIPHERAL_ERROR_INVALID_PARAMETER);
+ RETV_IF(read_write > I2C_SMBUS_READ, PERIPHERAL_ERROR_INVALID_PARAMETER);
+
+ if (read_write == I2C_SMBUS_WRITE) {
+ data_arg.command = command;
+ if (size == I2C_SMBUS_BYTE_DATA)
+ data.byte = (uint8_t)data_in;
+ else if (size == I2C_SMBUS_WORD_DATA)
+ data.word = data_in;
+ else if (size == I2C_SMBUS_BYTE)
+ data_arg.command = (uint8_t)data_in; // Data should be set to command.
+ } else if (read_write == I2C_SMBUS_READ && size != I2C_SMBUS_BYTE) {
+ data_arg.command = command;
+ }
+
+ ret = i2c_smbus_ioctl(i2c->fd, &data_arg);
+
+ if (ret == 0 && read_write == I2C_SMBUS_READ) {
+ if (size == I2C_SMBUS_BYTE_DATA || size == I2C_SMBUS_BYTE)
+ *data_out = (uint8_t)data.byte;
+ else if (size == I2C_SMBUS_WORD_DATA)
+ *data_out = data.word;
+ }
+
+ return ret;
+}
int peripheral_bus_i2c_close(pb_i2c_data_h i2c);
int peripheral_bus_i2c_read(pb_i2c_data_h i2c, int length, GVariant **data_array);
int peripheral_bus_i2c_write(pb_i2c_data_h i2c, int length, GVariant *data_array);
+int peripheral_bus_i2c_smbus_ioctl(pb_i2c_data_h i2c, uint8_t read_write, uint8_t command, uint32_t size, uint16_t data_in, uint16_t *data_out);
#endif /* __PERIPHERAL_BUS_I2C_H__ */
</arg>
<arg type="i" name="result" direction="out"/>
</method>
+ <method name="SmbusIoctl">
+ <arg type="u" name="handle" direction="in"/>
+ <arg type="y" name="read_write" direction="in"/>
+ <arg type="y" name="command" direction="in"/>
+ <arg type="u" name="size" direction="in"/>
+ <arg type="q" name="data_in" direction="in"/>
+ <arg type="q" name="data_out" direction="out"/>
+ <arg type="i" name="result" direction="out"/>
+ </method>
</interface>
<interface name="org.tizen.peripheral_io.pwm">
<method name="Open">
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
-#include <linux/i2c.h>
#include "i2c.h"
#include "peripheral_common.h"
strerror_r(errno, errmsg, MAX_ERR_LEN);
_E("i2c_read failed : %s", errmsg);
return -EIO;
- } else
- _D("[SUCCESS] data : [%02x][%02x]", data[0], data[1]);
+ }
return 0;
}
return 0;
}
+
+int i2c_smbus_ioctl(int fd, struct i2c_smbus_ioctl_data *data)
+{
+ int status;
+
+ _D("fd : %d", fd);
+ status = ioctl(fd, I2C_SMBUS, data);
+ if (status < 0) {
+ char errmsg[MAX_ERR_LEN];
+ strerror_r(errno, errmsg, MAX_ERR_LEN);
+ _E("i2c write failed : %s\n", errmsg);
+ return -EIO;
+ }
+
+ return 0;
+}
#ifndef __I2C_H__
#define __I2C_H__
+#include <stdint.h>
+
#define SYSFS_I2C_DIR "/dev/i2c"
#define I2C_BUFFER_MAX 64
-#define I2C_SLAVE 0x0703
+
+#define I2C_SLAVE 0x0703 /* Use this slave address */
+#define I2C_SMBUS 0x0720 /* SMBus transfer */
+
+/* i2c_smbus_xfer read or write markers */
+#define I2C_SMBUS_READ 1
+#define I2C_SMBUS_WRITE 0
+
+/* SMBus transaction types */
+#define I2C_SMBUS_QUICK 0
+#define I2C_SMBUS_BYTE 1
+#define I2C_SMBUS_BYTE_DATA 2
+#define I2C_SMBUS_WORD_DATA 3
+
+/*
+ * Data for SMBus Messages
+ */
+#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */
+
+union i2c_smbus_data {
+ uint8_t byte;
+ uint16_t word;
+ uint8_t block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
+ /* and one more for user-space compatibility */
+};
+
+/* This is the structure as used in the I2C_SMBUS ioctl call */
+struct i2c_smbus_ioctl_data {
+ uint8_t read_write;
+ uint8_t command;
+ uint32_t size;
+ union i2c_smbus_data *data;
+};
int i2c_open(int bus, int *fd);
int i2c_close(int fd);
int i2c_set_address(int fd, int address);
int i2c_read(int fd, unsigned char *data, int length);
int i2c_write(int fd, const unsigned char *data, int length);
+int i2c_smbus_ioctl(int fd, struct i2c_smbus_ioctl_data *data);
#endif/* __I2C_H__ */