blob: 6cb7d8cae1f1f8df500dc18949d91670ceb368d5 [file] [log] [blame]
/*
* 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