blob: e817e7c3815b2f8c17a830b1df3d55a6d36c4da4 [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>
AppaRao Pulic532f552019-07-05 15:23:50 +053021#include <stdio.h>
AppaRao Puli67d184c2020-05-29 00:48:33 +053022#include <sys/ioctl.h>
AppaRao Pulidcf13122020-05-28 01:21:39 +053023#include <unistd.h>
AppaRao Puli67d184c2020-05-29 00:48:33 +053024
AppaRao Pulic532f552019-07-05 15:23:50 +053025#include <phosphor-logging/log.hpp>
26
AppaRao Puli67d184c2020-05-29 00:48:33 +053027#include <experimental/filesystem>
28
29extern "C"
30{
AppaRao Pulic532f552019-07-05 15:23:50 +053031#include <i2c/smbus.h>
32#include <linux/i2c-dev.h>
33}
34
AppaRao Pulic532f552019-07-05 15:23:50 +053035namespace pfr
36{
37
38/** @class I2CFile
39 * @brief Responsible for handling file pointer
40 */
41class I2CFile
42{
43 private:
44 /** @brief handler for operating on file */
45 int fd;
46
47 public:
48 I2CFile() = delete;
49 I2CFile(const I2CFile&) = delete;
50 I2CFile& operator=(const I2CFile&) = delete;
51 I2CFile(I2CFile&&) = delete;
52 I2CFile& operator=(I2CFile&&) = delete;
53
54 /** @brief Opens i2c device file and sets slave
55 *
56 * @param[in] i2cBus - I2C bus number
57 * @param[in] slaveAddr - I2C slave address
58 * @param[in] flags - Flags
59 */
60 I2CFile(const int& i2cBus, const int& slaveAddr, const int& flags)
61 {
62 std::string i2cDev = "/dev/i2c-" + std::to_string(i2cBus);
63
64 fd = open(i2cDev.c_str(), flags);
65 if (fd < 0)
66 {
67 throw std::runtime_error("Unable to open i2c device.");
68 }
69
70 if (ioctl(fd, I2C_SLAVE_FORCE, slaveAddr) < 0)
71 {
72 close(fd);
73 fd = -1;
74 throw std::runtime_error("Unable to set i2c slave address.");
75 }
76 }
77
78 /** @brief Reads the byte data from I2C dev
79 *
80 * @param[in] Offset - Offset value
81 * @param[out] byte data - Offset value
82 */
83 uint8_t i2cReadByteData(const uint8_t& offset)
84 {
85 uint8_t value = i2c_smbus_read_byte_data(fd, offset);
86
87 if (value < 0)
88 {
89 throw std::runtime_error("i2c_smbus_read_byte_data() failed");
90 }
91 return value;
92 }
93
AppaRao Puli46cead92019-07-22 16:50:09 +053094 /** @brief Writes the byte data to I2C dev
95 *
96 * @param[in] Offset - Offset value
97 * @param[in] Byte data - Data
98 */
99 void i2cWriteByteData(const uint8_t offset, const uint8_t value)
100 {
101 int retries = 3;
102 while (i2c_smbus_write_byte_data(fd, offset, value) < 0)
103 {
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530104 phosphor::logging::log<phosphor::logging::level::WARNING>(
105 "PFR: I2c write failed, retrying....",
106 phosphor::logging::entry("COUNT=%d", retries));
AppaRao Puli46cead92019-07-22 16:50:09 +0530107 if (!retries--)
108 {
109 throw std::runtime_error("i2c_smbus_write_byte_data() failed");
110 }
111 std::this_thread::sleep_for(std::chrono::milliseconds(10));
112 }
113 return;
114 }
115
AppaRao Pulic532f552019-07-05 15:23:50 +0530116 ~I2CFile()
117 {
118 if (!(fd < 0))
119 {
120 close(fd);
121 }
122 }
123
124 auto operator()()
125 {
126 return fd;
127 }
128};
129
130} // namespace pfr