driver_pcal6416a.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <unistd.h>
  7. #include <fcntl.h>
  8. #include <errno.h>
  9. #include <sys/select.h>
  10. #include <linux/input.h>
  11. #include "read_conf_file.h"
  12. #include <assert.h>
  13. #include <linux/i2c.h>
  14. #include <linux/i2c-dev.h>
  15. #include "smbus.h"
  16. #include "driver_pcal6416a.h"
  17. /****************************************************************
  18. * Defines
  19. ****************************************************************/
  20. #define DEBUG_PCAL6416A_PRINTF (0)
  21. #if (DEBUG_PCAL6416A_PRINTF)
  22. #define DEBUG_PRINTF(...) printf(__VA_ARGS__);
  23. #else
  24. #define DEBUG_PRINTF(...)
  25. #endif
  26. /****************************************************************
  27. * Static variables
  28. ****************************************************************/
  29. static int fd_i2c_expander;
  30. static unsigned int i2c_expander_addr;
  31. static char i2c0_sysfs_filename[] = "/dev/i2c-0";
  32. /****************************************************************
  33. * Static functions
  34. ****************************************************************/
  35. /****************************************************************
  36. * Public functions
  37. ****************************************************************/
  38. bool pcal6416a_init(void) {
  39. if ((fd_i2c_expander = open(i2c0_sysfs_filename,O_RDWR)) < 0) {
  40. printf("Failed to open the I2C bus %s", i2c0_sysfs_filename);
  41. // ERROR HANDLING; you can check errno to see what went wrong
  42. return false;
  43. }
  44. i2c_expander_addr = 0;
  45. /// Probing PCAL9539A chip
  46. if (ioctl(fd_i2c_expander, I2C_SLAVE_FORCE, PCAL9539A_I2C_ADDR) < 0 ||
  47. pcal6416a_read_mask_interrupts() < 0) {
  48. printf("In %s - Failed to acquire bus access and/or talk to slave PCAL9539A_I2C_ADDR 0x%02X.\n",
  49. __func__, PCAL9539A_I2C_ADDR);
  50. /// Probing PCAL6416A chip
  51. if (ioctl(fd_i2c_expander, I2C_SLAVE_FORCE, PCAL6416A_I2C_ADDR) < 0 ||
  52. pcal6416a_read_mask_interrupts() < 0) {
  53. printf("In %s - Failed to acquire bus access and/or talk to slave PCAL6416A_I2C_ADDR 0x%02X.\n",
  54. __func__, PCAL6416A_I2C_ADDR);
  55. } else {
  56. DEBUG_PRINTF("Found I2C gpio expander chip: PCAL6416A\n");
  57. i2c_expander_addr = PCAL6416A_I2C_ADDR;
  58. }
  59. } else{
  60. DEBUG_PRINTF("Found I2C gpio expander chip: PCAL9539A\n");
  61. i2c_expander_addr = PCAL9539A_I2C_ADDR;
  62. }
  63. /// GPIO expander chip found?
  64. if(!i2c_expander_addr){
  65. printf("In %s - Failed to acquire bus access and/or talk to slave, exit\n", __func__);
  66. return false;
  67. }
  68. uint16_t val_enable_direction = 0xffff;
  69. i2c_smbus_write_word_data ( fd_i2c_expander , PCAL6416A_CONFIG , val_enable_direction );
  70. uint16_t val_enable_latch = 0x0000;
  71. i2c_smbus_write_word_data ( fd_i2c_expander , PCAL6416A_INPUT_LATCH , val_enable_latch );
  72. uint16_t val_enable_pullups = 0xffff;
  73. i2c_smbus_write_word_data ( fd_i2c_expander , PCAL6416A_EN_PULLUPDOWN , val_enable_pullups );
  74. uint16_t val_sel_pullups = 0xffff;
  75. i2c_smbus_write_word_data ( fd_i2c_expander , PCAL6416A_SEL_PULLUPDOWN , val_sel_pullups );
  76. //uint16_t val_enable_interrupts = 0x0000;
  77. uint16_t val_enable_interrupts = 0x0320;
  78. i2c_smbus_write_word_data ( fd_i2c_expander , PCAL6416A_INT_MASK , val_enable_interrupts );
  79. return true;
  80. }
  81. bool pcal6416a_deinit(void) {
  82. // Close I2C open interface
  83. close(fd_i2c_expander);
  84. return true;
  85. }
  86. int pcal6416a_read_mask_interrupts(void){
  87. int val_int = i2c_smbus_read_word_data ( fd_i2c_expander , PCAL6416A_INT_STATUS );
  88. if(val_int < 0){
  89. return val_int;
  90. }
  91. uint16_t val = val_int & 0xFFFF;
  92. DEBUG_PRINTF("READ PCAL6416A_INT_STATUS : 0x%04X\n",val);
  93. return (int) val;
  94. }
  95. int pcal6416a_read_mask_active_GPIOs(void){
  96. int val_int = i2c_smbus_read_word_data ( fd_i2c_expander , PCAL6416A_INPUT );
  97. if(val_int < 0){
  98. return val_int;
  99. }
  100. uint16_t val = val_int & 0xFFFF;
  101. val = 0xFFFF-val;
  102. DEBUG_PRINTF("READ PCAL6416A_INPUT (active GPIOs) : 0x%04X\n",val);
  103. return (int) val;
  104. }