smbus.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. smbus.c - SMBus level access helper functions
  3. Copyright (C) 1995-1997 Simon G. Vogl
  4. Copyright (C) 1998-1999 Frodo Looijaard <frodol@dds.nl>
  5. Copyright (C) 2012-2013 Jean Delvare <jdelvare@suse.de>
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  17. MA 02110-1301 USA.
  18. */
  19. #include <errno.h>
  20. #include <stddef.h>
  21. #include "smbus.h"
  22. #include <sys/ioctl.h>
  23. #include <linux/types.h>
  24. #include <linux/i2c.h>
  25. #include <linux/i2c-dev.h>
  26. /* Compatibility defines */
  27. #ifndef I2C_SMBUS_I2C_BLOCK_BROKEN
  28. #define I2C_SMBUS_I2C_BLOCK_BROKEN I2C_SMBUS_I2C_BLOCK_DATA
  29. #endif
  30. #ifndef I2C_FUNC_SMBUS_PEC
  31. #define I2C_FUNC_SMBUS_PEC I2C_FUNC_SMBUS_HWPEC_CALC
  32. #endif
  33. __s32 i2c_smbus_access(int file, char read_write, __u8 command,
  34. int size, union i2c_smbus_data *data)
  35. {
  36. struct i2c_smbus_ioctl_data args;
  37. __s32 err;
  38. args.read_write = read_write;
  39. args.command = command;
  40. args.size = size;
  41. args.data = data;
  42. err = ioctl(file, I2C_SMBUS, &args);
  43. if (err == -1)
  44. err = -errno;
  45. return err;
  46. }
  47. __s32 i2c_smbus_write_quick(int file, __u8 value)
  48. {
  49. return i2c_smbus_access(file, value, 0, I2C_SMBUS_QUICK, NULL);
  50. }
  51. __s32 i2c_smbus_read_byte(int file)
  52. {
  53. union i2c_smbus_data data;
  54. int err;
  55. err = i2c_smbus_access(file, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data);
  56. if (err < 0)
  57. return err;
  58. return 0x0FF & data.byte;
  59. }
  60. __s32 i2c_smbus_write_byte(int file, __u8 value)
  61. {
  62. return i2c_smbus_access(file, I2C_SMBUS_WRITE, value,
  63. I2C_SMBUS_BYTE, NULL);
  64. }
  65. __s32 i2c_smbus_read_byte_data(int file, __u8 command)
  66. {
  67. union i2c_smbus_data data;
  68. int err;
  69. err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
  70. I2C_SMBUS_BYTE_DATA, &data);
  71. if (err < 0)
  72. return err;
  73. return 0x0FF & data.byte;
  74. }
  75. __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value)
  76. {
  77. union i2c_smbus_data data;
  78. data.byte = value;
  79. return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
  80. I2C_SMBUS_BYTE_DATA, &data);
  81. }
  82. __s32 i2c_smbus_read_word_data(int file, __u8 command)
  83. {
  84. union i2c_smbus_data data;
  85. int err;
  86. err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
  87. I2C_SMBUS_WORD_DATA, &data);
  88. if (err < 0)
  89. return err;
  90. return 0x0FFFF & data.word;
  91. }
  92. __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value)
  93. {
  94. union i2c_smbus_data data;
  95. data.word = value;
  96. return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
  97. I2C_SMBUS_WORD_DATA, &data);
  98. }
  99. __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
  100. {
  101. union i2c_smbus_data data;
  102. data.word = value;
  103. if (i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
  104. I2C_SMBUS_PROC_CALL, &data))
  105. return -1;
  106. else
  107. return 0x0FFFF & data.word;
  108. }
  109. /* Returns the number of read bytes */
  110. __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values)
  111. {
  112. union i2c_smbus_data data;
  113. int i, err;
  114. err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
  115. I2C_SMBUS_BLOCK_DATA, &data);
  116. if (err < 0)
  117. return err;
  118. for (i = 1; i <= data.block[0]; i++)
  119. values[i-1] = data.block[i];
  120. return data.block[0];
  121. }
  122. __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
  123. const __u8 *values)
  124. {
  125. union i2c_smbus_data data;
  126. int i;
  127. if (length > I2C_SMBUS_BLOCK_MAX)
  128. length = I2C_SMBUS_BLOCK_MAX;
  129. for (i = 1; i <= length; i++)
  130. data.block[i] = values[i-1];
  131. data.block[0] = length;
  132. return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
  133. I2C_SMBUS_BLOCK_DATA, &data);
  134. }
  135. /* Returns the number of read bytes */
  136. /* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
  137. ask for less than 32 bytes, your code will only work with kernels
  138. 2.6.23 and later. */
  139. __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,
  140. __u8 *values)
  141. {
  142. union i2c_smbus_data data;
  143. int i, err;
  144. if (length > I2C_SMBUS_BLOCK_MAX)
  145. length = I2C_SMBUS_BLOCK_MAX;
  146. data.block[0] = length;
  147. err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
  148. length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
  149. I2C_SMBUS_I2C_BLOCK_DATA, &data);
  150. if (err < 0)
  151. return err;
  152. for (i = 1; i <= data.block[0]; i++)
  153. values[i-1] = data.block[i];
  154. return data.block[0];
  155. }
  156. __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, __u8 length,
  157. const __u8 *values)
  158. {
  159. union i2c_smbus_data data;
  160. int i;
  161. if (length > I2C_SMBUS_BLOCK_MAX)
  162. length = I2C_SMBUS_BLOCK_MAX;
  163. for (i = 1; i <= length; i++)
  164. data.block[i] = values[i-1];
  165. data.block[0] = length;
  166. return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
  167. I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
  168. }
  169. /* Returns the number of read bytes */
  170. __s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length,
  171. __u8 *values)
  172. {
  173. union i2c_smbus_data data;
  174. int i, err;
  175. if (length > I2C_SMBUS_BLOCK_MAX)
  176. length = I2C_SMBUS_BLOCK_MAX;
  177. for (i = 1; i <= length; i++)
  178. data.block[i] = values[i-1];
  179. data.block[0] = length;
  180. err = i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
  181. I2C_SMBUS_BLOCK_PROC_CALL, &data);
  182. if (err < 0)
  183. return err;
  184. for (i = 1; i <= data.block[0]; i++)
  185. values[i-1] = data.block[i];
  186. return data.block[0];
  187. }