Skip to content

Commit

Permalink
d4xx: realsense engineer release intel#6 (intel#132)
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Perchanov <dmitry.perchanov@intel.com>
  • Loading branch information
dmipx committed Apr 20, 2023
1 parent 2a761cf commit 5f45426
Showing 1 changed file with 139 additions and 95 deletions.
234 changes: 139 additions & 95 deletions drivers/media/i2c/d4xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,22 @@
//#define DS5_DEBUG_VCHAN_N 1
//#define DS5_MOTION_T_VCHAN_N 2

#define D4XX_I2C_ADDRESS_1 0x12
#define MAX9295_REG0 0x0000
#define MAX9295_I2C_4 0x0044
#define MAX9295_I2C_5 0x0045

#define MAX9296_CTRL0 0x0010
#define RESET_LINK (0x1 << 6)
#define RESET_ONESHOT (0x1 << 5)
#define AUTO_LINK (0x1 << 4)
#define DUAL_LINK (0x0)
#define LINK_A (0x1)
#define LINK_B (0x2)
#define SPLITTER (0x3)
#define MAX9296_NUM (4)

#define MAX9295_I2C_ADDR_DEF 0x40
#define D457_I2C_ADDR 0x10

enum ds5_mux_pad {
DS5_MUX_PAD_EXTERNAL,
Expand Down Expand Up @@ -517,6 +532,9 @@ static int max9296_write_8(struct ds5 *state, u16 reg, u8 val)
dev_dbg(&state->client->dev, "%s(): i2c write 0x%04x: 0x%x\n",
__func__, reg, val);

dev_dbg(&state->client->dev, "%s(): (%d), 0x%02x 0x%04x = 0x%02x\n",
__func__, ret, state->client->addr, reg, val);

return ret;
}

Expand All @@ -533,6 +551,9 @@ static int max9296_read_8(struct ds5 *state, u16 reg, u8 *val)
dev_info(&state->client->dev, "%s(): i2c read 0x%04x = 0x%x\n",
__func__, reg, *val);

dev_dbg(&state->client->dev, "%s(): (%d), 0x%02x 0x%04x = 0x%02x\n",
__func__, ret, state->client->addr, reg, *val);

return ret;
}
static int max9295_write_8(struct ds5 *state, u16 reg, u8 val)
Expand All @@ -548,8 +569,31 @@ static int max9295_write_8(struct ds5 *state, u16 reg, u8 val)
dev_info(&state->client->dev, "%s(): i2c write 0x%04x: 0x%x\n",
__func__, reg, val);

dev_dbg(&state->client->dev, "%s(): (%d), 0x%02x 0x%04x = 0x%02x\n",
__func__, ret, state->client->addr, reg, val);

return ret;
}

static int max9295_read_8(struct ds5 *state, u16 reg, u8 *val)
{
int ret;

ret = regmap_raw_read(state->regmap_max9295, reg, val, 1);
if (ret < 0)
dev_err(&state->client->dev, "%s(): i2c read failed %d, 0x%04x\n",
__func__, ret, reg);
else
if (state->dfu_dev.dfu_state_flag == DS5_DFU_IDLE)
dev_info(&state->client->dev, "%s(): i2c read 0x%04x = 0x%x\n",
__func__, reg, *val);

dev_dbg(&state->client->dev, "%s(): (%d), 0x%02x 0x%04x = 0x%02x\n",
__func__, ret, state->client->addr, reg, *val);

return ret;
}

#else
static int ds5_write_8(struct ds5 *state, u16 reg, u8 val)
{
Expand Down Expand Up @@ -953,8 +997,8 @@ static const struct ds5_format ds5_depth_formats_d46x[] = {
}, {
.data_type = GMSL_CSI_DT_RGB_888, /* 24-bit Calibration */
.mbus_code = MEDIA_BUS_FMT_RGB888_1X24, /* FIXME */
.n_resolutions = ARRAY_SIZE(d46x_calibration_sizes),
.resolutions = d46x_calibration_sizes,
.n_resolutions = ARRAY_SIZE(d43x_calibration_sizes),
.resolutions = d43x_calibration_sizes,
},
};

Expand All @@ -965,11 +1009,13 @@ static const struct ds5_format ds5_y_formats_ds5u[] = {
/* First format: default */
.data_type = GMSL_CSI_DT_RAW_8, /* Y8 */
.mbus_code = MEDIA_BUS_FMT_Y8_1X8,
// .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
.n_resolutions = ARRAY_SIZE(y8_sizes),
.resolutions = y8_sizes,
}, {
.data_type = GMSL_CSI_DT_YUV422_8, /* Y8I */
.mbus_code = MEDIA_BUS_FMT_VYUY8_1X16,
// .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
.n_resolutions = ARRAY_SIZE(y8_sizes),
.resolutions = y8_sizes,
}, {
Expand Down Expand Up @@ -3971,22 +4017,18 @@ static int ds5_mux_s_frame_interval(struct v4l2_subdev *sd,
#ifndef CONFIG_VIDEO_D4XX_SERDES
int d4xx_reset_oneshot(struct ds5 *state)
{
struct d4xx_pdata *dpdata = state->client->dev.platform_data;
struct i2c_board_info *deser = dpdata->deser_board_info;

int s_addr = state->client->addr;
int n_addr = 0;
int n_addr = deser->addr;
int ret = 0;

if (s_addr == 0x12)
n_addr = 0x48;
if (s_addr == 0x14)
n_addr = 0x4a;
if (s_addr == 0x16)
n_addr = 0x68;
if (s_addr == 0x18)
n_addr = 0x6c;
if (n_addr) {
state->client->addr = n_addr;
dev_warn(&state->client->dev, "One-shot reset 0x%x enable auto-link\n", n_addr);
ret = max9296_write_8(state, 0x0010, 0x31); // One-shot reset enable auto-link
/* One-shot reset enable auto-link */
ret = max9296_write_8(state, MAX9296_CTRL0, RESET_ONESHOT | AUTO_LINK | LINK_A);
state->client->addr = s_addr;
/* delay to settle link */
msleep(100);
Expand Down Expand Up @@ -5236,83 +5278,82 @@ static const struct regmap_config ds5_regmap_max9295 = {
.val_format_endian = REGMAP_ENDIAN_NATIVE,
};

#define RESET_LINK (0x1 << 6)
#define RESET_ONESHOT (0x1 << 5)
#define AUTO_LINK (0x1 << 4)
#define DUAL_LINK (0x0)
#define LINK_A (0x1)
#define LINK_B (0x2)
#define SPLITTER (0x3)
static int ds5_i2c_addr_setting(struct i2c_client *c, struct ds5 *state)
{
int curr_max9296 = c->addr;
int max9296_addrs[MAX9296_NUM] = {0x48, 0x4a, 0x68, 0x6c};
int i;
u8 val;
int ret;

state->regmap_max9296 = devm_regmap_init_i2c(c, &ds5_regmap_max9296);
if (IS_ERR(state->regmap_max9296)) {
ret = PTR_ERR(state->regmap_max9296);
dev_err(&c->dev, "regmap max9296 init failed: %d\n", ret);
return ret;
}

state->regmap_max9295 = devm_regmap_init_i2c(c, &ds5_regmap_max9295);
if (IS_ERR(state->regmap_max9295)) {
ret = PTR_ERR(state->regmap_max9295);
dev_err(&c->dev, "regmap max9295 init failed: %d\n", ret);
return ret;
struct d4xx_pdata *dpdata = c->dev.platform_data;
unsigned short ser_alias;
unsigned short sensor_alias;

/* TODO: 2x D457 subdev connect to MAX9296 */
if (dpdata->subdev_num >= 1) {
curr_max9296 = c->addr;
sensor_alias = dpdata->subdev_info[0].board_info.addr;
ser_alias = dpdata->subdev_info[0].ser_alias;
} else {
dev_err(&c->dev, "no subdev found!\n");
return -EINVAL;
}

c->addr = 0x48;
max9296_write_8(state, 0x0010, 0x40);
c->addr = 0x4a;
max9296_write_8(state, 0x0010, 0x40);
c->addr = 0x68;
max9296_write_8(state, 0x0010, 0x40);
c->addr = 0x6c;
max9296_write_8(state, 0x0010, 0x40);

c->addr = 0x6c;
max9296_write_8(state, 0x0010, 0x32);
msleep_range(1000);

c->addr = 0x40;
max9295_write_8(state, 0x0000, 0xc8); // 0x64
c->addr = 0x64;
msleep_range(1000);

max9295_write_8(state, 0x0044, 0x30); // 0x18
max9295_write_8(state, 0x0045, 0x20);
dev_dbg(&c->dev, "curr_max9296 0x%02x, sensor_alias 0x%02x, ser_alias 0x%02x\n",
curr_max9296, sensor_alias, ser_alias);

c->addr = 0x68;
max9296_write_8(state, 0x0010, 0x32);
msleep_range(1000);

c->addr = 0x40;
max9295_write_8(state, 0x0000, 0xc4); // 0x62
c->addr = 0x62;
max9295_write_8(state, 0x0044, 0x2c); // 0x16
max9295_write_8(state, 0x0045, 0x20);

c->addr = 0x4a;
max9296_write_8(state, 0x0010, 0x32);
msleep_range(1000);
/*
* don't reset link,
* check max9296 i2c addr + 1,
* max9295 i2c addr reassigned already.
*/
c->addr = curr_max9296 + 1;
ret = max9295_read_8(state, MAX9295_REG0, &val);
if (!ret) {
max9295_write_8(state, MAX9295_REG0, ser_alias << 1);
msleep_range(1000); /* need this? */
c->addr = ser_alias;
max9295_write_8(state, MAX9295_I2C_4, sensor_alias << 1);
max9295_write_8(state, MAX9295_I2C_5, D457_I2C_ADDR << 1);
c->addr = sensor_alias;
return 0;
}

c->addr = 0x40;
max9295_write_8(state, 0x0000, 0x88); // 0x44
c->addr = 0x44;
max9295_write_8(state, 0x0044, 0x28); // 0x14
max9295_write_8(state, 0x0045, 0x20);
/* i2c addr reassignment for all max9295 */
for (i = 0; i < MAX9296_NUM; i++) {
c->addr = max9296_addrs[i];
max9296_write_8(state, MAX9296_CTRL0, RESET_LINK);
}

c->addr = 0x48;
max9296_write_8(state, 0x0010, 0x32);
msleep_range(1000);
for (i = 0; i < MAX9296_NUM; i++) {
/* release reset */
c->addr = max9296_addrs[i];
max9296_write_8(state, MAX9296_CTRL0, AUTO_LINK | LINK_A);
msleep_range(1000);

if (curr_max9296 == max9296_addrs[i]) {
c->addr = MAX9295_I2C_ADDR_DEF;
ret = max9295_read_8(state, MAX9295_REG0, &val);
if (ret < 0) {
dev_err(&c->dev, "no max9295 found for max9296 %x\n", curr_max9296);
continue;
}
max9295_write_8(state, MAX9295_REG0, ser_alias << 1);
msleep_range(1000); // need this?
c->addr = ser_alias;
max9295_write_8(state, MAX9295_I2C_4, sensor_alias << 1);
max9295_write_8(state, MAX9295_I2C_5, D457_I2C_ADDR << 1);
continue;
}

c->addr = 0x40;
max9295_write_8(state, 0x0000, 0x84); // 0x42
c->addr = 0x42;
max9295_write_8(state, 0x0044, 0x24); // 0x12
max9295_write_8(state, 0x0045, 0x20);
c->addr = MAX9295_I2C_ADDR_DEF;
ret = max9295_read_8(state, MAX9295_REG0, &val);
if (ret < 0)
continue;
max9295_write_8(state, MAX9295_REG0, (max9296_addrs[i] + 1) << 1);
}

c->addr = 0x12;
c->addr = sensor_alias;

return 0;
}
Expand Down Expand Up @@ -5365,21 +5406,24 @@ static int ds5_probe(struct i2c_client *c, const struct i2c_device_id *id)
#endif

#ifndef CONFIG_VIDEO_D4XX_SERDES
if (c->addr == 0x48)
c->addr = 0x12;
if (c->addr == 0x4a)
c->addr = 0x14;
if (c->addr == 0x68)
c->addr = 0x16;
if (c->addr == 0x6c)
c->addr = 0x18;

if (c->addr == 0x12) {
ret = ds5_i2c_addr_setting(c, state);
if (ret) {
dev_err(&c->dev, "failed apply i2c addr setting\n");
return ret;
}
state->regmap_max9296 = devm_regmap_init_i2c(c, &ds5_regmap_max9296);
if (IS_ERR(state->regmap_max9296)) {
ret = PTR_ERR(state->regmap_max9296);
dev_err(&c->dev, "regmap max9296 init failed: %d\n", ret);
return ret;
}

state->regmap_max9295 = devm_regmap_init_i2c(c, &ds5_regmap_max9295);
if (IS_ERR(state->regmap_max9295)) {
ret = PTR_ERR(state->regmap_max9295);
dev_err(&c->dev, "regmap max9295 init failed: %d\n", ret);
return ret;
}

ret = ds5_i2c_addr_setting(c, state);
if (ret) {
dev_err(&c->dev, "failed apply i2c addr setting\n");
return ret;
}
#endif

Expand Down

0 comments on commit 5f45426

Please sign in to comment.