| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "fake_i2c_devices.h" |
| |
| #include <base/logging.h> |
| #include <linux/i2c-dev.h> |
| #include <linux/i2c.h> |
| |
| namespace android { |
| |
| FakeI2cDevice::FakeI2cDevice() {} |
| FakeI2cDevice::~FakeI2cDevice() {} |
| |
| int FakeI2cDevice::Open(const char* pathname, int flags) { |
| return 1; |
| } |
| |
| int FakeI2cDevice::Close(int fd) { |
| return 0; |
| } |
| |
| int FakeI2cDevice::Ioctl(int fd, int request, void* argp) { |
| if (request == I2C_SMBUS) { |
| struct i2c_smbus_ioctl_data* smbus_args = |
| reinterpret_cast<struct i2c_smbus_ioctl_data*>(argp); |
| |
| if (smbus_args->read_write == I2C_SMBUS_WRITE) { |
| uint8_t* data = smbus_args->data->block; |
| std::vector<uint8_t> temp; |
| if (smbus_args->size == I2C_SMBUS_I2C_BLOCK_DATA) { |
| temp.assign(data + 1, data + data[0] + 1); |
| } else if (smbus_args->size == I2C_SMBUS_WORD_DATA) { |
| temp.assign(data, data + 2); |
| } else if (smbus_args->size == I2C_SMBUS_BYTE_DATA) { |
| temp.assign(data, data + 1); |
| } |
| |
| registers_.emplace(smbus_args->command, temp); |
| LOG(INFO) << "writing " << temp.size() << " elements in " |
| << smbus_args->command; |
| return 0; |
| } else if (smbus_args->read_write == I2C_SMBUS_READ) { |
| if (!registers_.count(smbus_args->command)) { |
| LOG(INFO) << "no such register"; |
| return -1; |
| } |
| auto reg = registers_.find(smbus_args->command); |
| LOG(INFO) << "reading register " << smbus_args->command << " that has " |
| << reg->second.size() << " elements"; |
| |
| if (smbus_args->size == I2C_SMBUS_I2C_BLOCK_DATA) { |
| memcpy(smbus_args->data->block + 1, |
| reg->second.data(), |
| smbus_args->data->block[0]); |
| } else if (smbus_args->size == I2C_SMBUS_WORD_DATA) { |
| memcpy(smbus_args->data->block, reg->second.data(), 2); |
| } else if (smbus_args->size == I2C_SMBUS_BYTE_DATA) { |
| memcpy(smbus_args->data->block, reg->second.data(), 1); |
| } |
| return 0; |
| } |
| } else if (request == I2C_SLAVE) { |
| return 0; |
| } |
| |
| return -1; |
| } |
| |
| ssize_t FakeI2cDevice::Read(int fd, void* buf, size_t count) { |
| return count; |
| } |
| |
| ssize_t FakeI2cDevice::Write(int fd, const void* buf, size_t count) { |
| return count; |
| } |
| |
| int FakeI2cDevice::Poll(struct pollfd* fds, nfds_t nfds, int timeout) { |
| return 0; |
| } |
| |
| FakeI2cDeviceFactory::FakeI2cDeviceFactory() {} |
| |
| FakeI2cDeviceFactory::~FakeI2cDeviceFactory() {} |
| |
| std::unique_ptr<CharDeviceInterface> FakeI2cDeviceFactory::NewCharDevice() { |
| return std::unique_ptr<CharDeviceInterface>(new FakeI2cDevice()); |
| } |
| |
| } // namespace android |