i2c.cc 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "common/i2c.h"
  2. #include <fcntl.h>
  3. #include <sys/ioctl.h>
  4. #include <unistd.h>
  5. #include <cassert>
  6. #include <cstdio>
  7. #include <stdexcept>
  8. #include "common/swaglog.h"
  9. #include "common/util.h"
  10. #define UNUSED(x) (void)(x)
  11. #ifdef QCOM2
  12. // TODO: decide if we want to install libi2c-dev everywhere
  13. extern "C" {
  14. #include <linux/i2c-dev.h>
  15. #include <i2c/smbus.h>
  16. }
  17. I2CBus::I2CBus(uint8_t bus_id) {
  18. char bus_name[20];
  19. snprintf(bus_name, 20, "/dev/i2c-%d", bus_id);
  20. i2c_fd = HANDLE_EINTR(open(bus_name, O_RDWR));
  21. if (i2c_fd < 0) {
  22. throw std::runtime_error("Failed to open I2C bus");
  23. }
  24. }
  25. I2CBus::~I2CBus() {
  26. if (i2c_fd >= 0) {
  27. close(i2c_fd);
  28. }
  29. }
  30. int I2CBus::read_register(uint8_t device_address, uint register_address, uint8_t *buffer, uint8_t len) {
  31. std::lock_guard lk(m);
  32. int ret = 0;
  33. ret = HANDLE_EINTR(ioctl(i2c_fd, I2C_SLAVE, device_address));
  34. if (ret < 0) { goto fail; }
  35. ret = i2c_smbus_read_i2c_block_data(i2c_fd, register_address, len, buffer);
  36. if ((ret < 0) || (ret != len)) { goto fail; }
  37. fail:
  38. return ret;
  39. }
  40. int I2CBus::set_register(uint8_t device_address, uint register_address, uint8_t data) {
  41. std::lock_guard lk(m);
  42. int ret = 0;
  43. ret = HANDLE_EINTR(ioctl(i2c_fd, I2C_SLAVE, device_address));
  44. if (ret < 0) { goto fail; }
  45. ret = i2c_smbus_write_byte_data(i2c_fd, register_address, data);
  46. if (ret < 0) { goto fail; }
  47. fail:
  48. return ret;
  49. }
  50. #else
  51. I2CBus::I2CBus(uint8_t bus_id) {
  52. UNUSED(bus_id);
  53. i2c_fd = -1;
  54. }
  55. I2CBus::~I2CBus() {}
  56. int I2CBus::read_register(uint8_t device_address, uint register_address, uint8_t *buffer, uint8_t len) {
  57. UNUSED(device_address);
  58. UNUSED(register_address);
  59. UNUSED(buffer);
  60. UNUSED(len);
  61. return -1;
  62. }
  63. int I2CBus::set_register(uint8_t device_address, uint register_address, uint8_t data) {
  64. UNUSED(device_address);
  65. UNUSED(register_address);
  66. UNUSED(data);
  67. return -1;
  68. }
  69. #endif