blob: dcc9739b12206985b96fe1b022e96c86d1d6368f [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 <ddk/platform-defs.h>
#include <ddktl/device.h>
#include <ddktl/i2c-channel.h>
#include <ddktl/pdev.h>
#include <ddktl/protocol/camerasensor.h>
#include <ddktl/protocol/clock.h>
#include <ddktl/protocol/composite.h>
#include <ddktl/protocol/empty-protocol.h>
#include <ddktl/protocol/gpio.h>
#include <ddktl/protocol/mipicsi.h>
namespace camera {
typedef struct sensor_context {
// TODO(braval): Add details for each one of these
// and also remove unused ones.
uint32_t again_limit;
uint32_t int_max;
uint32_t dgain_limit;
uint32_t wdr_mode;
uint32_t gain_cnt;
uint32_t t_height;
uint32_t int_time_limit;
uint32_t t_height_old;
uint16_t int_time;
uint16_t VMAX;
uint16_t HMAX;
uint16_t dgain_old;
uint16_t int_time_min;
uint16_t again_old;
uint16_t dgain[2];
uint16_t again[2];
uint8_t seq_width;
uint8_t streaming_flag;
uint8_t again_delay;
uint8_t again_change;
uint8_t dgain_delay;
uint8_t dgain_change;
uint8_t change_flag;
uint8_t hdr_flag;
sensor_info_t param;
} sensor_context_t;
class Imx227Device;
using DeviceType = ddk::Device<Imx227Device, ddk::Unbindable>;
class Imx227Device : public DeviceType,
public ddk::CameraSensorProtocol<Imx227Device, ddk::base_protocol> {
public:
enum {
COMPONENT_I2C,
COMPONENT_GPIO_VANA,
COMPONENT_GPIO_VDIG,
COMPONENT_GPIO_CAM_RST,
COMPONENT_CLK24,
COMPONENT_MIPICSI,
COMPONENT_COUNT,
};
static zx_status_t Create(void* ctx, zx_device_t* parent);
Imx227Device(zx_device_t* device,
zx_device_t* i2c,
zx_device_t* gpio_vana,
zx_device_t* gpio_vdig,
zx_device_t* gpio_cam_rst,
zx_device_t* clk24,
zx_device_t* mipicsi)
: DeviceType(device), i2c_(i2c), gpio_vana_enable_(gpio_vana),
gpio_vdig_enable_(gpio_vdig), gpio_cam_rst_(gpio_cam_rst),
clk24_(clk24), mipi_(mipicsi) {}
static zx_status_t Setup(void* ctx,
zx_device_t* parent,
std::unique_ptr<Imx227Device>* device);
// Methods required by the ddk mixins.
void DdkUnbind();
void DdkRelease();
// Testing interface will need to use this to check
// the status of the sensor.
bool IsSensorInitialized() { return initialized_; }
// Methods for ZX_PROTOCOL_CAMERA_SENSOR.
zx_status_t CameraSensorInit();
void CameraSensorDeInit();
zx_status_t CameraSensorSetMode(uint8_t mode);
zx_status_t CameraSensorStartStreaming();
zx_status_t CameraSensorStopStreaming();
int32_t CameraSensorSetAnalogGain(int32_t gain);
int32_t CameraSensorSetDigitalGain(int32_t gain);
zx_status_t CameraSensorSetIntegrationTime(int32_t int_time);
zx_status_t CameraSensorUpdate();
zx_status_t CameraSensorGetInfo(sensor_info_t* out_info);
zx_status_t CameraSensorGetSupportedModes(sensor_mode_t* out_modes_list,
size_t modes_count,
size_t* out_modes_actual);
private:
friend class Imx227DeviceTester;
// Sensor Context
sensor_context_t ctx_;
// Protocols.
ddk::I2cChannel i2c_;
ddk::GpioProtocolClient gpio_vana_enable_;
ddk::GpioProtocolClient gpio_vdig_enable_;
ddk::GpioProtocolClient gpio_cam_rst_;
ddk::ClockProtocolClient clk24_;
ddk::MipiCsiProtocolClient mipi_;
// Sensor Status.
bool initialized_ = false;
// I2C Helpers.
uint8_t ReadReg(uint16_t addr);
void WriteReg(uint16_t addr, uint8_t val);
zx_status_t InitPdev(zx_device_t* parent);
zx_status_t InitSensor(uint8_t idx);
void ShutDown();
bool ValidateSensorID();
};
} // namespace camera