/* * 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 #include #include 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(argp); if (smbus_args->read_write == I2C_SMBUS_WRITE) { uint8_t* data = smbus_args->data->block; std::vector 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 FakeI2cDeviceFactory::NewCharDevice() { return std::unique_ptr(new FakeI2cDevice()); } } // namespace android