Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DSO-18376 D4XX HWMC UVC LibRealSense compatibility #120

Merged
merged 1 commit into from
Aug 9, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 164 additions & 0 deletions kernel/nvidia/0066-DSO-18376-D4XX-HWMC-UVC-LRS-compat.patch
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);
dmipx marked this conversation as resolved.
Show resolved Hide resolved
+ } 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,
dmipx marked this conversation as resolved.
Show resolved Hide resolved
+ "%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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines could have been exported to a separate function, in order to make it reusable, and to make the code more readable - but up to you to export it or let it this way.

+ * 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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment for the "<<8" - changing the "8" to some const could be also better.

+ size |= *((u8*)ctrl->p_new.p_u8 + 0);
dmipx marked this conversation as resolved.
Show resolved Hide resolved
+ ret = ds5_send_hwmc(state, size + 4,
dmipx marked this conversation as resolved.
Show resolved Hide resolved
+ (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},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some comment for the "size+4" - consider changing the "4" to a const number - its name could be self-explained and avoid the comment.

.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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some comment for the "def = 240" - consider changing the "240" to a const number - its name could be self-explained and avoid the comment.

+ .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