[mipi][sherlock] Adding proxy for ZX_PROTOCOL_MIPI_CSI
- This is the first step towards converting camera driver
to composite devices
- This is not yet tested
Test: Compiles & boot up on sherlock
Change-Id: I2b350119f9c86ce20fd566ad8c11129020aae884
diff --git a/zircon/system/core/devmgr/component/BUILD.gn b/zircon/system/core/devmgr/component/BUILD.gn
index 2228772..6fab0fc 100644
--- a/zircon/system/core/devmgr/component/BUILD.gn
+++ b/zircon/system/core/devmgr/component/BUILD.gn
@@ -15,6 +15,7 @@
"$zx/system/banjo/ddk-protocol-ethernet-board",
"$zx/system/banjo/ddk-protocol-gpio",
"$zx/system/banjo/ddk-protocol-i2c",
+ "$zx/system/banjo/ddk-protocol-mipicsi",
"$zx/system/banjo/ddk-protocol-platform-device",
"$zx/system/banjo/ddk-protocol-power",
"$zx/system/banjo/ddk-protocol-sysmem",
@@ -39,6 +40,7 @@
"$zx/system/banjo/ddk-protocol-ethernet-board",
"$zx/system/banjo/ddk-protocol-gpio",
"$zx/system/banjo/ddk-protocol-i2c",
+ "$zx/system/banjo/ddk-protocol-mipicsi",
"$zx/system/banjo/ddk-protocol-platform-device",
"$zx/system/banjo/ddk-protocol-power",
"$zx/system/banjo/ddk-protocol-sysmem",
diff --git a/zircon/system/core/devmgr/component/component-proxy.cpp b/zircon/system/core/devmgr/component/component-proxy.cpp
index 66fad91..3786a29 100644
--- a/zircon/system/core/devmgr/component/component-proxy.cpp
+++ b/zircon/system/core/devmgr/component/component-proxy.cpp
@@ -43,6 +43,9 @@
case ZX_PROTOCOL_I2C:
proto->ops = &i2c_protocol_ops_;
return ZX_OK;
+ case ZX_PROTOCOL_MIPI_CSI:
+ proto->ops = &mipi_csi_protocol_ops_;
+ return ZX_OK;
case ZX_PROTOCOL_PDEV:
proto->ops = &pdev_protocol_ops_;
return ZX_OK;
@@ -117,8 +120,8 @@
}
zx_status_t ComponentProxy::AmlogicCanvasConfig(zx::vmo vmo, size_t offset,
- const canvas_info_t* info,
- uint8_t* out_canvas_idx) {
+ const canvas_info_t* info,
+ uint8_t* out_canvas_idx) {
AmlogicCanvasProxyRequest req = {};
AmlogicCanvasProxyResponse resp = {};
req.header.proto_id = ZX_PROTOCOL_AMLOGIC_CANVAS;
@@ -175,6 +178,27 @@
return Rpc(&req.header, sizeof(req), &resp, sizeof(resp));
}
+zx_status_t ComponentProxy::MipiCsiInit(const mipi_info_t* mipi_info,
+ const mipi_adap_info_t* adap_info) {
+ MipiCsiProxyRequest req = {};
+ ProxyResponse resp = {};
+ req.header.proto_id = ZX_PROTOCOL_MIPI_CSI;
+ req.op = MipiCsiOp::INIT;
+ req.mipi_info = *mipi_info;
+ req.adap_info = *adap_info;
+
+ return Rpc(&req.header, sizeof(req), &resp, sizeof(resp));
+}
+
+zx_status_t ComponentProxy::MipiCsiDeInit() {
+ MipiCsiProxyRequest req = {};
+ ProxyResponse resp = {};
+ req.header.proto_id = ZX_PROTOCOL_MIPI_CSI;
+ req.op = MipiCsiOp::DEINIT;
+
+ return Rpc(&req.header, sizeof(req), &resp, sizeof(resp));
+}
+
zx_status_t ComponentProxy::GpioConfigIn(uint32_t flags) {
GpioProxyRequest req = {};
GpioProxyResponse resp = {};
@@ -311,8 +335,8 @@
auto* rsp = reinterpret_cast<I2cProxyResponse*>(resp_buffer);
size_t actual;
auto status = Rpc(&req->header, static_cast<uint32_t>(req_length),
- &rsp->header, static_cast<uint32_t>(resp_length), nullptr, 0, nullptr,
- 0, &actual);
+ &rsp->header, static_cast<uint32_t>(resp_length), nullptr, 0, nullptr,
+ 0, &actual);
if (status != ZX_OK) {
callback(cookie, status, nullptr, 0);
return;
diff --git a/zircon/system/core/devmgr/component/component-proxy.h b/zircon/system/core/devmgr/component/component-proxy.h
index 5e92362..7ebbdfc 100644
--- a/zircon/system/core/devmgr/component/component-proxy.h
+++ b/zircon/system/core/devmgr/component/component-proxy.h
@@ -13,6 +13,7 @@
#include <ddktl/protocol/ethernet/board.h>
#include <ddktl/protocol/gpio.h>
#include <ddktl/protocol/i2c.h>
+#include <ddktl/protocol/mipicsi.h>
#include <ddktl/protocol/platform/device.h>
#include <ddktl/protocol/power.h>
#include <ddktl/protocol/sysmem.h>
@@ -32,6 +33,7 @@
public ddk::EthBoardProtocol<ComponentProxy>,
public ddk::GpioProtocol<ComponentProxy>,
public ddk::I2cProtocol<ComponentProxy>,
+ public ddk::MipiCsiProtocol<ComponentProxy>,
public ddk::PDevProtocol<ComponentProxy>,
public ddk::PowerProtocol<ComponentProxy>,
public ddk::SysmemProtocol<ComponentProxy>,
@@ -92,6 +94,9 @@
zx_status_t PowerWritePmicCtrlReg(uint32_t reg_addr, uint32_t value);
zx_status_t PowerReadPmicCtrlReg(uint32_t reg_addr, uint32_t* out_value);
zx_status_t SysmemConnect(zx::channel allocator2_request);
+ zx_status_t MipiCsiInit(const mipi_info_t* mipi_info,
+ const mipi_adap_info_t* adap_info);
+ zx_status_t MipiCsiDeInit();
// USB Mode Switch
zx_status_t UsbModeSwitchSetMode(usb_mode_t mode);
diff --git a/zircon/system/core/devmgr/component/component.cpp b/zircon/system/core/devmgr/component/component.cpp
index e5c3bfb..a5af246 100644
--- a/zircon/system/core/devmgr/component/component.cpp
+++ b/zircon/system/core/devmgr/component/component.cpp
@@ -14,7 +14,7 @@
namespace component {
Component::Component(zx_device_t* parent)
- : ComponentBase(parent) {
+ : ComponentBase(parent) {
// These protocols are all optional, so no error checking is necessary here.
device_get_protocol(parent, ZX_PROTOCOL_AMLOGIC_CANVAS, &canvas_);
@@ -22,6 +22,7 @@
device_get_protocol(parent, ZX_PROTOCOL_ETH_BOARD, ð_board_);
device_get_protocol(parent, ZX_PROTOCOL_GPIO, &gpio_);
device_get_protocol(parent, ZX_PROTOCOL_I2C, &i2c_);
+ device_get_protocol(parent, ZX_PROTOCOL_MIPI_CSI, &mipicsi_);
device_get_protocol(parent, ZX_PROTOCOL_PDEV, &pdev_);
device_get_protocol(parent, ZX_PROTOCOL_POWER, &power_);
device_get_protocol(parent, ZX_PROTOCOL_SYSMEM, &sysmem_);
@@ -47,7 +48,7 @@
uint32_t* out_resp_size, const zx_handle_t* req_handles,
uint32_t req_handle_count, zx_handle_t* resp_handles,
uint32_t* resp_handle_count) {
- if (canvas_.ops == nullptr) {
+ if (canvas_.ops == nullptr) {
return ZX_ERR_NOT_SUPPORTED;
}
auto* req = reinterpret_cast<const AmlogicCanvasProxyRequest*>(req_buf);
@@ -65,7 +66,7 @@
return ZX_ERR_INTERNAL;
}
return amlogic_canvas_config(&canvas_, req_handles[0], req->offset, &req->info,
- &resp->canvas_idx);
+ &resp->canvas_idx);
case AmlogicCanvasOp::FREE:
if (req_handle_count != 0) {
zxlogf(ERROR, "%s received %u handles, expecting 0\n", __func__, req_handle_count);
@@ -82,7 +83,7 @@
uint32_t* out_resp_size, const zx_handle_t* req_handles,
uint32_t req_handle_count, zx_handle_t* resp_handles,
uint32_t* resp_handle_count) {
- if (clock_.ops == nullptr) {
+ if (clock_.ops == nullptr) {
return ZX_ERR_NOT_SUPPORTED;
}
auto* req = reinterpret_cast<const ClockProxyRequest*>(req_buf);
@@ -337,7 +338,7 @@
case PowerOp::WRITE_PMIC_CTRL_REG:
return power_write_pmic_ctrl_reg(&power_, req->reg_addr, req->reg_value);
case PowerOp::READ_PMIC_CTRL_REG:
- return power_read_pmic_ctrl_reg(&power_,req->reg_addr, &resp->reg_value);
+ return power_read_pmic_ctrl_reg(&power_, req->reg_addr, &resp->reg_value);
default:
zxlogf(ERROR, "%s: unknown Power op %u\n", __func__, static_cast<uint32_t>(req->op));
return ZX_ERR_INTERNAL;
@@ -396,6 +397,35 @@
}
}
+zx_status_t Component::RpcMipiCsi(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
+ uint32_t* out_resp_size, const zx_handle_t* req_handles,
+ uint32_t req_handle_count, zx_handle_t* resp_handles,
+ uint32_t* resp_handle_count) {
+ if (mipicsi_.ops == nullptr) {
+ return ZX_ERR_NOT_SUPPORTED;
+ }
+
+ ddk::MipiCsiProtocolClient mipicsi(&mipicsi_);
+
+ auto* req = reinterpret_cast<const MipiCsiProxyRequest*>(req_buf);
+ if (req_size < sizeof(*req)) {
+ zxlogf(ERROR, "%s received %u, expecting %zu\n", __func__, req_size, sizeof(*req));
+ return ZX_ERR_INTERNAL;
+ }
+ auto* resp = reinterpret_cast<ProxyResponse*>(resp_buf);
+ *out_resp_size = sizeof(*resp);
+
+ switch (req->op) {
+ case MipiCsiOp::INIT:
+ return mipicsi.Init(&req->mipi_info, &req->adap_info);
+ case MipiCsiOp::DEINIT:
+ return mipicsi.DeInit();
+ default:
+ zxlogf(ERROR, "%s: unknown MIPI_CSI op %u\n", __func__, static_cast<uint32_t>(req->op));
+ return ZX_ERR_INTERNAL;
+ }
+}
+
zx_status_t Component::DdkRxrpc(zx_handle_t raw_channel) {
zx::unowned_channel channel(raw_channel);
if (!channel->is_valid()) {
@@ -442,7 +472,7 @@
break;
case ZX_PROTOCOL_I2C:
status = RpcI2c(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
- resp_handles, &resp_handle_count);
+ resp_handles, &resp_handle_count);
break;
case ZX_PROTOCOL_PDEV:
status = RpcPdev(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
@@ -460,6 +490,10 @@
status = RpcUms(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
resp_handles, &resp_handle_count);
break;
+ case ZX_PROTOCOL_MIPI_CSI:
+ status = RpcMipiCsi(req_buf, actual, resp_buf, &resp_len, req_handles, req_handle_count,
+ resp_handles, &resp_handle_count);
+ break;
default:
zxlogf(ERROR, "%s: unknown protocol %u\n", __func__, req_header->proto_id);
return ZX_ERR_INTERNAL;
diff --git a/zircon/system/core/devmgr/component/component.h b/zircon/system/core/devmgr/component/component.h
index c6ef9b0..0494048 100644
--- a/zircon/system/core/devmgr/component/component.h
+++ b/zircon/system/core/devmgr/component/component.h
@@ -17,6 +17,7 @@
#include <ddk/protocol/sysmem.h>
#include <ddk/protocol/usb/modeswitch.h>
#include <ddktl/device.h>
+#include <ddktl/protocol/mipicsi.h>
#include <lib/sync/completion.h>
#include <lib/zx/channel.h>
@@ -76,9 +77,13 @@
uint32_t req_handle_count, zx_handle_t* resp_handles,
uint32_t* resp_handle_count);
zx_status_t RpcUms(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
- uint32_t* out_resp_size, const zx_handle_t* req_handles,
- uint32_t req_handle_count, zx_handle_t* resp_handles,
- uint32_t* resp_handle_count);
+ uint32_t* out_resp_size, const zx_handle_t* req_handles,
+ uint32_t req_handle_count, zx_handle_t* resp_handles,
+ uint32_t* resp_handle_count);
+ zx_status_t RpcMipiCsi(const uint8_t* req_buf, uint32_t req_size, uint8_t* resp_buf,
+ uint32_t* out_resp_size, const zx_handle_t* req_handles,
+ uint32_t req_handle_count, zx_handle_t* resp_handles,
+ uint32_t* resp_handle_count);
static void I2cTransactCallback(void* cookie, zx_status_t status, const i2c_op_t* op_list,
size_t op_count);
@@ -88,6 +93,7 @@
eth_board_protocol_t eth_board_ = {};
gpio_protocol_t gpio_ = {};
i2c_protocol_t i2c_ = {};
+ mipi_csi_protocol_t mipicsi_ = {};
pdev_protocol_t pdev_ = {};
power_protocol_t power_ = {};
sysmem_protocol_t sysmem_ = {};
diff --git a/zircon/system/core/devmgr/component/proxy-protocol.h b/zircon/system/core/devmgr/component/proxy-protocol.h
index ec540ab..7868593 100644
--- a/zircon/system/core/devmgr/component/proxy-protocol.h
+++ b/zircon/system/core/devmgr/component/proxy-protocol.h
@@ -56,6 +56,19 @@
uint8_t metadata[PROXY_MAX_METADATA_SIZE];
};
+// ZX_PROTOCOL_MIPI_CSI proxy support.
+enum class MipiCsiOp {
+ INIT,
+ DEINIT,
+};
+
+struct MipiCsiProxyRequest {
+ ProxyRequest header;
+ MipiCsiOp op;
+ mipi_info_t mipi_info;
+ mipi_adap_info_t adap_info;
+};
+
// ZX_PROTOCOL_GPIO proxy support.
enum class GpioOp {
CONFIG_IN,