-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
DSO-18376 D4XX HWMC UVC LibRealSense compatibility
- added new volatile CID (offset 32) for set/get HWMC - Addressing https://rsjira.intel.com/browse/DSO-18376 [D457][MIPI] Make HWMC work in USB-compatible manner Signed-off-by: Dmitry Perchanov <dmitry.perchanov@intel.com>
- Loading branch information
Showing
1 changed file
with
164 additions
and
0 deletions.
There are no files selected for viewing
164 changes: 164 additions & 0 deletions
164
kernel/nvidia/0066-DSO-18376-D4XX-HWMC-UVC-LRS-compat.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
From 4db28072d081cb50b855a724b63d3d40468d5169 Mon Sep 17 00:00:00 2001 | ||
From: Dmitry Perchanov <dmitry.perchanov@intel.com> | ||
Date: Tue, 2 Aug 2022 15:02:42 +0300 | ||
Subject: [PATCH] D4XX: HWMC add separate Read/Write CID | ||
|
||
Signed-off-by: Dmitry Perchanov <dmitry.perchanov@intel.com> | ||
--- | ||
drivers/media/i2c/d4xx.c | 98 +++++++++++++++++++++++++++++++++++++++- | ||
1 file changed, 96 insertions(+), 2 deletions(-) | ||
|
||
diff --git a/drivers/media/i2c/d4xx.c b/drivers/media/i2c/d4xx.c | ||
index 7d5a319..e1ec378 100644 | ||
--- a/drivers/media/i2c/d4xx.c | ||
+++ b/drivers/media/i2c/d4xx.c | ||
@@ -1299,6 +1299,9 @@ static int ds5_hw_set_exposure(struct ds5 *state, u32 base, s32 val) | ||
#define DS5_CAMERA_CID_ERB (DS5_CAMERA_CID_BASE+13) | ||
#define DS5_CAMERA_CID_EWB (DS5_CAMERA_CID_BASE+14) | ||
#define DS5_CAMERA_CID_HWMC (DS5_CAMERA_CID_BASE+15) | ||
+/* the HWMC will remain for legacy tools compatibility, | ||
+ * HWMC_RW used for UVC compatibility*/ | ||
+#define DS5_CAMERA_CID_HWMC_RW (DS5_CAMERA_CID_BASE+32) | ||
|
||
static int ds5_send_hwmc(struct ds5 *state, u16 cmdLen, struct hwm_cmd *cmd, | ||
bool isRead, u16 *dataLen) | ||
@@ -1348,6 +1351,72 @@ static int ds5_send_hwmc(struct ds5 *state, u16 cmdLen, struct hwm_cmd *cmd, | ||
return 0; | ||
} | ||
|
||
+#define DS5_HWMC_DATA 0x4900 | ||
+#define DS5_HWMC_STATUS 0x4904 | ||
+#define DS5_HWMC_RESP_LEN 0x4908 | ||
+#define DS5_HWMC_EXEC 0x490C | ||
+ | ||
+#define DS5_HWMC_STATUS_OK 0 | ||
+#define DS5_HWMC_STATUS_ERR 1 | ||
+#define DS5_HWMC_STATUS_WIP 2 | ||
+#define DS5_HWMC_BUFFER_SIZE 1024 | ||
+ | ||
+static int ds5_get_hwmc(struct ds5 *state, unsigned char *data) | ||
+{ | ||
+ int ret = 0; | ||
+ u16 status = DS5_HWMC_STATUS_WIP; | ||
+ int retries = 100; | ||
+ int errorCode; | ||
+ u16 tmp_len = 0; | ||
+ const int SIZE_OF_HW_MONITOR_HEADER = 4; | ||
+ | ||
+ memset(data, 0, DS5_HWMC_BUFFER_SIZE); | ||
+ | ||
+ do { | ||
+ if (retries != 100) | ||
+ msleep_range(1); | ||
+ ret = ds5_read(state, DS5_HWMC_STATUS, &status); | ||
+ } while (!ret && retries-- && status != DS5_HWMC_STATUS_OK); | ||
+ | ||
+ if (ret || status != DS5_HWMC_STATUS_OK) { | ||
+ if (status == DS5_HWMC_STATUS_ERR) { | ||
+ ds5_raw_read(state, DS5_HWMC_DATA, &errorCode, sizeof(errorCode)); | ||
+ dev_err(&state->client->dev, | ||
+ "%s(): HWMC failed, ret: %d, error code: %d\n", | ||
+ __func__, ret, errorCode); | ||
+ } else { | ||
+ dev_err(&state->client->dev, | ||
+ "%s(): HWMC failed because of timeout, ret: %d\n", | ||
+ __func__, ret); | ||
+ } | ||
+ return -EAGAIN; | ||
+ } | ||
+ | ||
+ ret = regmap_raw_read(state->regmap, DS5_HWMC_RESP_LEN, | ||
+ &tmp_len, sizeof(tmp_len)); | ||
+ if (ret) | ||
+ return -EAGAIN; | ||
+ | ||
+ if (tmp_len > DS5_HWMC_BUFFER_SIZE) | ||
+ return -ENOBUFS; | ||
+ | ||
+ dev_info(&state->client->dev, | ||
+ "%s(): HWMC read len: %d, lrs_len: %d\n", | ||
+ __func__, tmp_len, tmp_len - SIZE_OF_HW_MONITOR_HEADER); | ||
+ | ||
+ ds5_raw_read_with_check(state, DS5_HWMC_DATA, data, tmp_len); | ||
+ | ||
+ /* This is needed for librealsense, to align there code with UVC, | ||
+ * last word is length - 4 bytes header length */ | ||
+ tmp_len -= SIZE_OF_HW_MONITOR_HEADER; | ||
+ data[DS5_HWMC_BUFFER_SIZE - 4] = (unsigned char)(tmp_len & 0x00FF); | ||
+ data[DS5_HWMC_BUFFER_SIZE - 3] = (unsigned char)((tmp_len & 0xFF00) >> 8); | ||
+ data[DS5_HWMC_BUFFER_SIZE - 2] = 0; | ||
+ data[DS5_HWMC_BUFFER_SIZE - 1] = 0; | ||
+ | ||
+ return 0; | ||
+} | ||
+ | ||
static int ds5_set_calibration_data(struct ds5 *state, struct hwm_cmd *cmd, u16 length) | ||
{ | ||
int ret; | ||
@@ -1554,6 +1623,14 @@ static int ds5_s_ctrl(struct v4l2_ctrl *ctrl) | ||
ret = ds5_send_hwmc(state, size + 4, (struct hwm_cmd *)ctrl->p_new.p_u8, true, &dataLen); | ||
} | ||
break; | ||
+ case DS5_CAMERA_CID_HWMC_RW: | ||
+ if (ctrl->p_new.p_u8) { | ||
+ u16 size = *((u8*)ctrl->p_new.p_u8 + 1) << 8; | ||
+ size |= *((u8*)ctrl->p_new.p_u8 + 0); | ||
+ ret = ds5_send_hwmc(state, size + 4, | ||
+ (struct hwm_cmd *)ctrl->p_new.p_u8, false, NULL); | ||
+ } | ||
+ break; | ||
} | ||
|
||
mutex_unlock(&state->lock); | ||
@@ -1773,6 +1850,9 @@ static int ds5_g_volatile_ctrl(struct v4l2_ctrl *ctrl) | ||
devm_kfree(&state->client->dev, ae_setpoint_cmd); | ||
} | ||
break; | ||
+ case DS5_CAMERA_CID_HWMC_RW: | ||
+ ds5_get_hwmc(state, ctrl->p_new.p_u8); | ||
+ break; | ||
} | ||
|
||
return ret; | ||
@@ -1965,7 +2045,7 @@ static const struct v4l2_ctrl_config ds5_ctrl_hwmc = { | ||
.id = DS5_CAMERA_CID_HWMC, | ||
.name = "HWMC", | ||
.type = V4L2_CTRL_TYPE_U8, | ||
- .dims = {1028}, | ||
+ .dims = {DS5_HWMC_BUFFER_SIZE + 4}, | ||
.elem_size = sizeof(u8), | ||
.min = 0, | ||
.max = 0xFFFFFFFF, | ||
@@ -1974,6 +2054,20 @@ static const struct v4l2_ctrl_config ds5_ctrl_hwmc = { | ||
.step = 1, | ||
}; | ||
|
||
+static const struct v4l2_ctrl_config ds5_ctrl_hwmc_rw = { | ||
+ .ops = &ds5_ctrl_ops, | ||
+ .id = DS5_CAMERA_CID_HWMC_RW, | ||
+ .name = "HWMC_RW", | ||
+ .type = V4L2_CTRL_TYPE_U8, | ||
+ .dims = {DS5_HWMC_BUFFER_SIZE}, | ||
+ .elem_size = sizeof(u8), | ||
+ .min = 0, | ||
+ .max = 0xFFFFFFFF, | ||
+ .def = 240, | ||
+ .step = 1, | ||
+ .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_EXECUTE_ON_WRITE, | ||
+}; | ||
+ | ||
static int ds5_mux_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | ||
{ | ||
struct ds5 *state = v4l2_get_subdevdata(sd); | ||
@@ -2100,7 +2194,7 @@ static int ds5_ctrl_init(struct ds5 *state) | ||
ctrls->erb = v4l2_ctrl_new_custom(hdl, &ds5_ctrl_erb, NULL); | ||
ctrls->ewb = v4l2_ctrl_new_custom(hdl, &ds5_ctrl_ewb, NULL); | ||
ctrls->hwmc = v4l2_ctrl_new_custom(hdl, &ds5_ctrl_hwmc, NULL); | ||
- | ||
+ v4l2_ctrl_new_custom(hdl, &ds5_ctrl_hwmc_rw, NULL); | ||
state->mux.sd.subdev.ctrl_handler = hdl; | ||
|
||
return 0; | ||
-- | ||
2.37.1 | ||
|