blob: 1fbc62a84774ac361e769be8cd4484ee2afae3fa [file] [log] [blame]
AppaRao Pulic532f552019-07-05 15:23:50 +05301/*
2// Copyright (c) 2019 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16
17#pragma once
18
19#include <errno.h>
20#include <fcntl.h>
21#include <sys/ioctl.h>
22#include <stdio.h>
23#include <experimental/filesystem>
24#include <phosphor-logging/log.hpp>
25
26extern "C" {
27#include <i2c/smbus.h>
28#include <linux/i2c-dev.h>
29}
30
31namespace intel
32{
33namespace pfr
34{
35
36/** @class I2CFile
37 * @brief Responsible for handling file pointer
38 */
39class I2CFile
40{
41 private:
42 /** @brief handler for operating on file */
43 int fd;
44
45 public:
46 I2CFile() = delete;
47 I2CFile(const I2CFile&) = delete;
48 I2CFile& operator=(const I2CFile&) = delete;
49 I2CFile(I2CFile&&) = delete;
50 I2CFile& operator=(I2CFile&&) = delete;
51
52 /** @brief Opens i2c device file and sets slave
53 *
54 * @param[in] i2cBus - I2C bus number
55 * @param[in] slaveAddr - I2C slave address
56 * @param[in] flags - Flags
57 */
58 I2CFile(const int& i2cBus, const int& slaveAddr, const int& flags)
59 {
60 std::string i2cDev = "/dev/i2c-" + std::to_string(i2cBus);
61
62 fd = open(i2cDev.c_str(), flags);
63 if (fd < 0)
64 {
65 throw std::runtime_error("Unable to open i2c device.");
66 }
67
68 if (ioctl(fd, I2C_SLAVE_FORCE, slaveAddr) < 0)
69 {
70 close(fd);
71 fd = -1;
72 throw std::runtime_error("Unable to set i2c slave address.");
73 }
74 }
75
76 /** @brief Reads the byte data from I2C dev
77 *
78 * @param[in] Offset - Offset value
79 * @param[out] byte data - Offset value
80 */
81 uint8_t i2cReadByteData(const uint8_t& offset)
82 {
83 uint8_t value = i2c_smbus_read_byte_data(fd, offset);
84
85 if (value < 0)
86 {
87 throw std::runtime_error("i2c_smbus_read_byte_data() failed");
88 }
89 return value;
90 }
91
AppaRao Puli46cead92019-07-22 16:50:09 +053092 /** @brief Writes the byte data to I2C dev
93 *
94 * @param[in] Offset - Offset value
95 * @param[in] Byte data - Data
96 */
97 void i2cWriteByteData(const uint8_t offset, const uint8_t value)
98 {
99 int retries = 3;
100 while (i2c_smbus_write_byte_data(fd, offset, value) < 0)
101 {
102 if (!retries--)
103 {
104 throw std::runtime_error("i2c_smbus_write_byte_data() failed");
105 }
106 std::this_thread::sleep_for(std::chrono::milliseconds(10));
107 }
108 return;
109 }
110
AppaRao Pulic532f552019-07-05 15:23:50 +0530111 ~I2CFile()
112 {
113 if (!(fd < 0))
114 {
115 close(fd);
116 }
117 }
118
119 auto operator()()
120 {
121 return fd;
122 }
123};
124
125} // namespace pfr
126} // namespace intel