blob: a01571441011a626e06e788e1731c6396011fcb3 [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
George Hung92a15ba2020-09-14 17:14:52 +080097int phosphor::smbus::Smbus::SendSmbusRWCmdRAW(int smbus_num, int8_t device_addr,
98 uint8_t* tx_data, uint8_t tx_len,
99 uint8_t* rsp_data, uint8_t rx_len)
Tony Lee6c595012019-06-19 10:54:59 +0800100{
101 int res, res_len;
102 unsigned char Rx_buf[I2C_DATA_MAX] = {0};
103
Tony Lee6c595012019-06-19 10:54:59 +0800104 gMutex.lock();
105
106 res = i2c_read_after_write(fd[smbus_num], device_addr, tx_len,
George Hung92a15ba2020-09-14 17:14:52 +0800107 (unsigned char*)tx_data, rx_len,
Tony Lee6c595012019-06-19 10:54:59 +0800108 (unsigned char*)Rx_buf);
109
110 if (res < 0)
111 {
George Hung92a15ba2020-09-14 17:14:52 +0800112 fprintf(stderr, "Error: SendSmbusRWCmdRAW failed\n");
Tony Lee6c595012019-06-19 10:54:59 +0800113 }
114
115 res_len = Rx_buf[0] + 1;
116
117 memcpy(rsp_data, Rx_buf, res_len);
118
119 gMutex.unlock();
120
121 return res;
122}
123
124} // namespace smbus
125} // namespace phosphor