blob: dcef067aa423c19aa822776b4c2d69e56327df0c [file] [log] [blame]
Ed Tanousf61ca6f2019-08-15 15:09:05 -07001/*
2// Copyright (c) 2018 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#include "i2c.hpp"
18
19#include <fcntl.h>
20#include <sys/ioctl.h>
21#include <unistd.h>
22
23#include <phosphor-logging/elog-errors.hpp>
24#include <xyz/openbmc_project/Common/error.hpp>
25
26// TODO Add 16-bit I2C support in the furture
27int i2cSet(uint8_t bus, uint8_t slaveAddr, uint8_t regAddr, uint8_t value)
28{
29 unsigned long funcs = 0;
30 std::string devPath = "/dev/i2c-" + std::to_string(bus);
31
32 int fd = ::open(devPath.c_str(), O_RDWR);
33 if (fd < 0)
34 {
35 phosphor::logging::log<phosphor::logging::level::ERR>(
36 "Error in open!",
37 phosphor::logging::entry("PATH=%s", devPath.c_str()),
38 phosphor::logging::entry("SLAVEADDR=0x%x", slaveAddr));
39 return -1;
40 }
41
42 if (::ioctl(fd, I2C_FUNCS, &funcs) < 0)
43 {
44 phosphor::logging::log<phosphor::logging::level::ERR>(
45 "Error in I2C_FUNCS!",
46 phosphor::logging::entry("PATH=%s", devPath.c_str()),
47 phosphor::logging::entry("SLAVEADDR=0x%x", slaveAddr));
48
49 ::close(fd);
50 return -1;
51 }
52
53 if (!(funcs & I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
54 {
55
56 phosphor::logging::log<phosphor::logging::level::ERR>(
57 "i2c bus does not support write!",
58 phosphor::logging::entry("PATH=%s", devPath.c_str()),
59 phosphor::logging::entry("SLAVEADDR=0x%x", slaveAddr));
60 ::close(fd);
61 return -1;
62 }
63
64 if (::ioctl(fd, I2C_SLAVE_FORCE, slaveAddr) < 0)
65 {
66 phosphor::logging::log<phosphor::logging::level::ERR>(
67 "Error in I2C_SLAVE_FORCE!",
68 phosphor::logging::entry("PATH=%s", devPath.c_str()),
69 phosphor::logging::entry("SLAVEADDR=0x%x", slaveAddr));
70 ::close(fd);
71 return -1;
72 }
73
74 if (::i2c_smbus_write_byte_data(fd, regAddr, value) < 0)
75 {
76 phosphor::logging::log<phosphor::logging::level::ERR>(
77 "Error in i2c write!",
78 phosphor::logging::entry("PATH=%s", devPath.c_str()),
79 phosphor::logging::entry("SLAVEADDR=0x%x", slaveAddr));
80 ::close(fd);
81 return -1;
82 }
83
84 // TODO For testing, will remove the below debug loging in the future
85 phosphor::logging::log<phosphor::logging::level::DEBUG>(
86 "i2cset successfully",
87 phosphor::logging::entry("PATH=%s", devPath.c_str()),
88 phosphor::logging::entry("SLAVEADDR=0x%x", slaveAddr),
89 phosphor::logging::entry("REGADDR=0x%x", regAddr),
90 phosphor::logging::entry("VALUE=0x%x", value));
91 ::close(fd);
92 return 0;
93}