1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <ddk/platform-defs.h>
6 #include <ddktl/device.h>
7 #include <ddktl/i2c-channel.h>
8 #include <ddktl/pdev.h>
9 #include <ddktl/protocol/clk.h>
10 #include <ddktl/protocol/empty-protocol.h>
11 #include <ddktl/protocol/gpio.h>
12 #include <ddktl/protocol/mipicsi.h>
13 #include <fuchsia/hardware/camera/c/fidl.h>
14 
15 namespace camera {
16 
17 typedef struct sensor_context {
18     // TODO(braval): Add details for each one of these
19     //               and also remove unused ones.
20     uint32_t again_limit;
21     uint32_t int_max;
22     uint32_t dgain_limit;
23     uint32_t wdr_mode;
24     uint32_t gain_cnt;
25     uint32_t t_height;
26     uint32_t int_time_limit;
27     uint32_t t_height_old;
28     uint16_t int_time;
29     uint16_t VMAX;
30     uint16_t HMAX;
31     uint16_t dgain_old;
32     uint16_t int_time_min;
33     uint16_t again_old;
34     uint16_t dgain[2];
35     uint16_t again[2];
36     uint8_t seq_width;
37     uint8_t streaming_flag;
38     uint8_t again_delay;
39     uint8_t again_change;
40     uint8_t dgain_delay;
41     uint8_t dgain_change;
42     uint8_t change_flag;
43     uint8_t hdr_flag;
44     fuchsia_hardware_camera_SensorInfo param;
45 } sensor_context_t;
46 
47 class Imx227Device;
48 using DeviceType = ddk::Device<Imx227Device,
49                                ddk::Unbindable,
50                                ddk::Ioctlable,
51                                ddk::Messageable>;
52 
53 class Imx227Device : public DeviceType,
54                      public ddk::EmptyProtocol<ZX_PROTOCOL_CAMERA> {
55 public:
56     // GPIO Indexes.
57     enum {
58         VANA_ENABLE,
59         VDIG_ENABLE,
60         CAM_SENSOR_RST,
61         GPIO_COUNT,
62     };
63 
64     static zx_status_t Create(zx_device_t* parent);
Imx227Device(zx_device_t * device)65     Imx227Device(zx_device_t* device)
66         : DeviceType(device), pdev_(device), i2c_(device), clk_(device), mipi_(device) {}
67 
68     // Methods required by the ddk mixins.
69     void DdkUnbind();
70     void DdkRelease();
71     zx_status_t DdkIoctl(uint32_t op, const void* in_buf, size_t in_len,
72                          void* out_buf, size_t out_len, size_t* out_actual);
73     zx_status_t DdkMessage(fidl_msg_t* msg, fidl_txn_t* txn);
74 
75     // Methods for IOCTLs.
76     zx_status_t GetInfo(fuchsia_hardware_camera_SensorInfo* out_info);
77     void GetSupportedModes(void* out_buf, size_t* out_actual);
78 
79     // Methods for FIDL Message.
80     zx_status_t Init();
81     void DeInit();
82     zx_status_t SetMode(uint8_t mode);
83     void StartStreaming();
84     void StopStreaming();
85     int32_t SetAnalogGain(int32_t gain);
86     int32_t SetDigitalGain(int32_t gain);
87     void SetIntegrationTime(int32_t int_time, int32_t int_time_M, int32_t int_time_L);
88     void Update();
89 
90 private:
91     // Sensor Context
92     sensor_context_t ctx_;
93 
94     // Protocols.
95     ddk::PDev pdev_;
96     ddk::I2cChannel i2c_;
97     ddk::GpioProtocolClient gpios_[GPIO_COUNT];
98     ddk::ClkProtocolClient clk_;
99     ddk::MipiCsiProtocolClient mipi_;
100 
101     // I2C Helpers.
102     uint8_t ReadReg(uint16_t addr);
103     void WriteReg(uint16_t addr, uint8_t val);
104 
105     zx_status_t InitPdev(zx_device_t* parent);
106     zx_status_t InitSensor(uint8_t idx);
107     void ShutDown();
108     bool ValidateSensorID();
109 };
110 
111 } // namespace camera
112