blob: 7e8d968c1e2e8fbe78a787973cba204567dc3561 [file] [log] [blame]
Tony Lee6c595012019-06-19 10:54:59 +08001#include "smbus.hpp"
2
3#include <errno.h>
4#include <fcntl.h>
5#include <stdint.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <sys/ioctl.h>
10#include <unistd.h>
11
12#include <iostream>
13#include <mutex>
14
15#include "i2c.h"
16
17#define MAX_I2C_BUS 30
18static constexpr bool DEBUG = false;
19
20static int fd[MAX_I2C_BUS] = {0};
21
22namespace phosphor
23{
24namespace smbus
25{
26
27std::mutex gMutex;
28
29int phosphor::smbus::Smbus::openI2cDev(int i2cbus, char* filename, size_t size,
30 int quiet)
31{
32 int file;
33
34 snprintf(filename, size, "/dev/i2c/%d", i2cbus);
35 filename[size - 1] = '\0';
36 file = open(filename, O_RDWR);
37
38 if (file < 0 && (errno == ENOENT || errno == ENOTDIR))
39 {
40 sprintf(filename, "/dev/i2c-%d", i2cbus);
41 file = open(filename, O_RDWR);
42 }
43
44 if (DEBUG)
45 {
46 if (file < 0 && !quiet)
47 {
48 if (errno == ENOENT)
49 {
50 fprintf(stderr,
51 "Error: Could not open file "
52 "`/dev/i2c-%d' or `/dev/i2c/%d': %s\n",
53 i2cbus, i2cbus, strerror(ENOENT));
54 }
55 else
56 {
57 fprintf(stderr,
58 "Error: Could not open file "
59 "`%s': %s\n",
60 filename, strerror(errno));
61 if (errno == EACCES)
62 fprintf(stderr, "Run as root?\n");
63 }
64 }
65 }
66
67 return file;
68}
69
70int phosphor::smbus::Smbus::smbusInit(int smbus_num)
71{
72 int res = 0;
73 char filename[20];
74
75 gMutex.lock();
76
77 fd[smbus_num] = openI2cDev(smbus_num, filename, sizeof(filename), 0);
78 if (fd[smbus_num] < 0)
79 {
80 gMutex.unlock();
81
82 return -1;
83 }
84
85 res = fd[smbus_num];
86
87 gMutex.unlock();
88
89 return res;
90}
91
92void phosphor::smbus::Smbus::smbusClose(int smbus_num)
93{
94 close(fd[smbus_num]);
95}
96
97int phosphor::smbus::Smbus::SendSmbusRWBlockCmdRAW(int smbus_num,
98 int8_t device_addr,
99 uint8_t* tx_data,
100 uint8_t tx_len,
101 uint8_t* rsp_data)
102{
103 int res, res_len;
104 unsigned char Rx_buf[I2C_DATA_MAX] = {0};
105
106 Rx_buf[0] = 1;
107
108 gMutex.lock();
109
110 res = i2c_read_after_write(fd[smbus_num], device_addr, tx_len,
111 (unsigned char*)tx_data, I2C_DATA_MAX,
112 (unsigned char*)Rx_buf);
113
114 if (res < 0)
115 {
116 fprintf(stderr, "Error: SendSmbusRWBlockCmdRAW failed\n");
117 }
118
119 res_len = Rx_buf[0] + 1;
120
121 memcpy(rsp_data, Rx_buf, res_len);
122
123 gMutex.unlock();
124
125 return res;
126}
127
128} // namespace smbus
129} // namespace phosphor