i2c: try to call ioctl() to test i2c-stub when read()/write() is failed 37/148037/5 accepted/tizen/unified/20171013.193401 submit/tizen/20171013.100446
authorkibak.yoon <kibak.yoon@samsung.com>
Wed, 6 Sep 2017 10:29:56 +0000 (19:29 +0900)
committerkibak.yoon <kibak.yoon@samsung.com>
Fri, 13 Oct 2017 09:45:14 +0000 (18:45 +0900)
Change-Id: Idadb56f4da5b4ed17fef47ba316524462b0c50c5
Signed-off-by: kibak.yoon <kibak.yoon@samsung.com>
data/pio_board_artik710.ini
data/pio_board_rp3_b.ini
src/daemon/peripheral_bus_i2c.c

index 48ee3a5..11b972b 100644 (file)
@@ -12,6 +12,7 @@ gpio27                = 22
 
 [i2c]
 i2c-1          = 13, 15
+i2c-11         = 100, 101
 
 [pwm]
 pwmchip0/pwm2  = 30
index 1344001..c1bf815 100644 (file)
@@ -18,6 +18,7 @@ gpio27        = 12
 
 [i2c]
 i2c-1  = 5, 3
+i2c-4  = 100, 101
 
 [pwm]
 
index b0a8899..46d0640 100644 (file)
@@ -129,6 +129,48 @@ int peripheral_bus_i2c_close(pb_data_h handle)
        return ret;
 }
 
+int peripheral_bus_i2c_smbus_ioctl(pb_data_h handle, uint8_t read_write, uint8_t command, uint32_t size, uint16_t data_in, uint16_t *data_out)
+{
+       peripheral_bus_i2c_s *i2c = &handle->dev.i2c;
+       struct i2c_smbus_ioctl_data data_arg;
+       union i2c_smbus_data data;
+       int ret;
+
+       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)
+               _E("Ioctl failed, bus : %d, address : 0x%x", i2c->bus, i2c->address);
+
+       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_read(pb_data_h handle, int length, GVariant **data_array)
 {
        peripheral_bus_i2c_s *i2c = &handle->dev.i2c;
@@ -153,10 +195,18 @@ int peripheral_bus_i2c_read(pb_data_h handle, int length, GVariant **data_array)
        }
 
        ret = i2c_read(i2c->fd, i2c->buffer, length);
-       if (ret < 0)
-               _E("Read Failed, bus : %d, address : 0x%x", i2c->bus, i2c->address);
 
-       *data_array = peripheral_bus_build_variant_ay(i2c->buffer, length);
+       /* If read() is failed, try to call ioctl with SMBus */
+       if (ret < 0) {
+               _D("Try to call ioctl() instead of read(), bus : %d, address : 0x%x",
+                               i2c->bus, i2c->address);
+               ret = peripheral_bus_i2c_smbus_ioctl(handle, I2C_SMBUS_READ,
+                               0x0, I2C_SMBUS_BYTE, 0x0, (uint16_t *)&i2c->buffer[0]);
+               if (ret < 0)
+                       _E("Read Failed, bus : %d, address : 0x%x", i2c->bus, i2c->address);
+       }
+
+       *data_array = peripheral_bus_build_variant_ay(i2c->buffer, I2C_SMBUS_BYTE);
 
        return ret;
 
@@ -192,50 +242,17 @@ int peripheral_bus_i2c_write(pb_data_h handle, int length, GVariant *data_array)
        g_variant_iter_free(iter);
 
        ret = i2c_write(i2c->fd, i2c->buffer, length);
-       if (ret < 0)
-               _E("Write Failed, bus : %d, address : 0x%x", i2c->bus, i2c->address);
-
-       return ret;
-}
-
-int peripheral_bus_i2c_smbus_ioctl(pb_data_h handle, uint8_t read_write, uint8_t command, uint32_t size, uint16_t data_in, uint16_t *data_out)
-{
-       peripheral_bus_i2c_s *i2c = &handle->dev.i2c;
-       struct i2c_smbus_ioctl_data data_arg;
-       union i2c_smbus_data data;
-       int ret;
-
-       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)
-               _E("Ioctl failed, bus : %d, address : 0x%x", i2c->bus, i2c->address);
-
-       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;
+       /* If write() is failed, try to call ioctl with SMBus */
+       if (ret < 0) {
+               _D("Try to call ioctl() instead of write(), bus : %d, address : 0x%x",
+                               i2c->bus, i2c->address);
+               ret = peripheral_bus_i2c_smbus_ioctl(handle, I2C_SMBUS_WRITE,
+                               0x0, I2C_SMBUS_BYTE, i2c->buffer[0], NULL);
+               if (ret < 0)
+                       _E("Write Failed, bus : %d, address : 0x%x", i2c->bus, i2c->address);
        }
 
        return ret;
 }
+