blob: df180950fbe2ac24e8b8a8837b094c76b2076617 [file] [log] [blame]
/* Copyright 2019 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "hal/usb/sensor_handler_monocle.h"
#include <string>
#include <base/files/file_util.h>
#include <rts_read_sensor.h>
#include "cros-camera/common.h"
#include "hal/usb/quirks.h"
// The sensor registers to export exposure time.
static constexpr uint32_t kExposureTimeRegisters[] = {0x3500, 0x3501, 0x3502};
namespace cros {
SensorHandlerMonocle::SensorHandlerMonocle(
const DeviceInfo& device_info, const SupportedFormats& supported_formats)
: handle_(nullptr) {
if (!(device_info.quirks & kQuirkMonocle)) {
return;
}
base::FilePath target;
std::string device_path;
// SDK supposes the device path should be /dev/videoX.
if (base::ReadSymbolicLink(base::FilePath(device_info.device_path),
&target)) {
device_path = "/dev/" + target.BaseName().value();
} else {
device_path = device_info.device_path;
}
handle_ = rts_uvc_open(device_path.c_str());
if (handle_ == nullptr) {
LOGF(ERROR) << "Cannot open device to read sensor data: " << device_path;
}
InitSensorParameters(device_info, supported_formats);
}
SensorHandlerMonocle::~SensorHandlerMonocle() {
if (handle_)
rts_uvc_close(handle_);
}
void SensorHandlerMonocle::InitSensorParameters(
const DeviceInfo& device_info, const SupportedFormats& supported_formats) {
// TODO(henryhsu): Move to a config file.
if (device_info.usb_vid == "0bda" && device_info.usb_pid == "5647") {
// These parameters are from OV8856 specification.
// Initial exposure time parameters
SensorParameters param;
for (const auto& supported_format : supported_formats) {
if (supported_format.width == 3264 && supported_format.height == 2448) {
param.line_pixel_width = 3864;
param.line_count = 2452;
} else if (supported_format.width == 1920 &&
supported_format.height == 1080) {
param.line_pixel_width = 3200;
param.line_count = 1840;
} else {
param.line_pixel_width = 3864;
param.line_count = 1224;
}
param.readout_time = param.line_pixel_width * param.line_count *
1'000'000'000 / kPixelClock_;
param.line_duration =
param.line_pixel_width * 1'000'000'000 / kPixelClock_;
Size resolution(supported_format.width, supported_format.height);
sensor_parameters_[resolution] = param;
}
}
}
int64_t SensorHandlerMonocle::GetRollingShutterSkew(const Size& resolution) {
if (sensor_parameters_.find(resolution) == sensor_parameters_.end()) {
return 33'300'000;
}
return sensor_parameters_[resolution].readout_time;
}
int64_t SensorHandlerMonocle::GetExposureTime(const Size& resolution) {
if (handle_ == nullptr ||
sensor_parameters_.find(resolution) == sensor_parameters_.end()) {
return 16'600'000;
}
uint64_t line_count = 0;
for (const auto& addr : kExposureTimeRegisters) {
uint16_t value;
rts_read_sensor_reg(handle_, addr, &value);
line_count = (line_count << 8) | value;
}
line_count >>= kExposureTimeFractionBits_;
return sensor_parameters_[resolution].line_duration * line_count;
}
} // namespace cros