-
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
161 additions
and
0 deletions.
There are no files selected for viewing
161 changes: 161 additions & 0 deletions
161
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,161 @@ | ||
From bd5ffbcf99e977e55f6a8622ba41a1dacf43e7f1 Mon Sep 17 00:00:00 2001 | ||
From: Dmitry Perchanov <dmitry.perchanov@intel.com> | ||
Date: Tue, 19 Jul 2022 16:39:06 +0300 | ||
Subject: [PATCH] D4XX: HWMC add separate Read/Write CID | ||
|
||
Signed-off-by: Dmitry Perchanov <dmitry.perchanov@intel.com> | ||
--- | ||
drivers/media/i2c/d4xx.c | 95 +++++++++++++++++++++++++++++++++++++++- | ||
1 file changed, 93 insertions(+), 2 deletions(-) | ||
|
||
diff --git a/drivers/media/i2c/d4xx.c b/drivers/media/i2c/d4xx.c | ||
index 7d5a319..43f149a 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,69 @@ 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; | ||
+ | ||
+ memset(data, 0, DS5_HWMC_BUFFER_SIZE); | ||
+ | ||
+ do { | ||
+ msleep_range(1); | ||
+ ret = ds5_read(state, DS5_HWMC_STATUS, &status); | ||
+ } while (!ret && retries-- && status != DS5_HWMC_STATUS_WIP); | ||
+ | ||
+ 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); | ||
+ } | ||
+ ret = -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\n", | ||
+ __func__, tmp_len); | ||
+ | ||
+ 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 */ | ||
+ 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 +1620,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 +1847,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 +2042,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 +2051,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 +2191,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.17.1 | ||
|