clear-pkgs-linux-iot-lts2018/0970-media-intel-ipu4-enabl...

647 lines
20 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Meng Wei <wei.meng@intel.com>
Date: Mon, 14 Jan 2019 10:29:30 +0800
Subject: [PATCH] media: intel-ipu4: enable OV495 multiport
enable OV495 multiport.
Change-Id: Iaaf9e2efe1ba3bd97472cb79858b19b28c4850ea
Tracked-On: PKT-1691
Signed-off-by: Chen Meng J <meng.j.chen@intel.com>
Signed-off-by: Meng Wei <wei.meng@intel.com>
---
drivers/media/i2c/ti960-reg.h | 24 +++
drivers/media/i2c/ti960.c | 348 +++++++++++++++++++++++++++-------
include/media/ti960.h | 7 +-
3 files changed, 308 insertions(+), 71 deletions(-)
diff --git a/drivers/media/i2c/ti960-reg.h b/drivers/media/i2c/ti960-reg.h
index 260c17884c7d..0f34651aaa03 100644
--- a/drivers/media/i2c/ti960-reg.h
+++ b/drivers/media/i2c/ti960-reg.h
@@ -9,6 +9,11 @@ struct ti960_register_write {
u8 val;
};
+struct ti960_register_devid {
+ u8 reg;
+ u8 val_expected;
+};
+
static const struct ti960_register_write ti960_frame_sync_settings[2][5] = {
{
{0x18, 0x00}, /* Disable frame sync. */
@@ -151,6 +156,9 @@ static const struct ti960_register_write ti960_init_settings_2[] = {
{0xb2, 0x04},
{0xb1, 0x04},
{0xb2, 0x04},
+};
+
+static const struct ti960_register_write ti960_init_settings_3[] = {
{0x4c, 0x01},
{0x32, 0x01},
{0x33, 0x03},
@@ -166,6 +174,15 @@ static const struct ti960_register_write ti953_init_settings_2[] = {
{0x0e, 0xf0},
};
+static const struct ti960_register_devid ti953_FPD3_RX_ID[] = {
+ {0xf0, 0x5f},
+ {0xf1, 0x55},
+ {0xf2, 0x42},
+ {0xf3, 0x39},
+ {0xf4, 0x35},
+ {0xf5, 0x33},
+};
+
/* register definition */
#define TI960_DEVID 0x0
#define TI960_RESET 0x1
@@ -173,12 +190,15 @@ static const struct ti960_register_write ti953_init_settings_2[] = {
#define TI960_FS_CTL 0x18
#define TI960_FWD_CTL1 0x20
#define TI960_RX_PORT_SEL 0x4c
+#define TI960_SER_ALIAS_ID 0x5c
#define TI960_SLAVE_ID0 0x5d
#define TI960_SLAVE_ALIAS_ID0 0x65
#define TI960_PORT_CONFIG 0x6d
#define TI960_BC_GPIO_CTL0 0x6e
+#define TI960_BC_GPIO_CTL1 0x6f
#define TI960_RAW10_ID 0x70
#define TI960_RAW12_ID 0x71
+#define TI960_CSI_VC_MAP 0x72
#define TI960_PORT_CONFIG2 0x7c
#define TI960_CSI_CTL 0x33
@@ -200,6 +220,10 @@ static const struct ti960_register_write ti953_init_settings_2[] = {
#define TI960_GPIO1_FSIN 0xa0
#define TI960_GPIO0_MASK 0x0f
#define TI960_GPIO1_MASK 0xf0
+#define TI960_GPIO2_FSIN 0x0a
+#define TI960_GPIO3_FSIN 0xa0
+#define TI960_GPIO2_MASK 0x0f
+#define TI960_GPIO3_MASK 0xf0
#define TI960_MIPI_800MBPS 0x2
#define TI960_MIPI_1600MBPS 0x0
#define TI960_CSI_ENABLE 0x1
diff --git a/drivers/media/i2c/ti960.c b/drivers/media/i2c/ti960.c
index 531611bb11b1..7ea1d578d1df 100644
--- a/drivers/media/i2c/ti960.c
+++ b/drivers/media/i2c/ti960.c
@@ -25,6 +25,7 @@ struct ti960_subdev {
unsigned short fsin_gpio;
unsigned short phy_i2c_addr;
unsigned short alias_i2c_addr;
+ unsigned short ser_i2c_addr;
char sd_name[16];
};
@@ -76,8 +77,8 @@ static const u8 ti960_op_sys_clock_reg_val[] = {
* orders must be defined.
*/
static const struct ti960_csi_data_format va_csi_data_formats[] = {
- { MEDIA_BUS_FMT_YUYV8_1X16, 16, 16, PIXEL_ORDER_GBRG, 0x1e},
- { MEDIA_BUS_FMT_UYVY8_1X16, 16, 16, PIXEL_ORDER_GBRG, 0X1e},
+ { MEDIA_BUS_FMT_YUYV8_1X16, 16, 16, PIXEL_ORDER_GBRG, 0x1e },
+ { MEDIA_BUS_FMT_UYVY8_1X16, 16, 16, PIXEL_ORDER_GBRG, 0x1e },
{ MEDIA_BUS_FMT_SGRBG16_1X16, 16, 16, PIXEL_ORDER_GRBG, 0x2e },
{ MEDIA_BUS_FMT_SRGGB16_1X16, 16, 16, PIXEL_ORDER_RGGB, 0x2e },
{ MEDIA_BUS_FMT_SBGGR16_1X16, 16, 16, PIXEL_ORDER_BGGR, 0x2e },
@@ -126,13 +127,14 @@ static struct regmap_config ti960_reg_config16 = {
};
static int ti953_reg_write(struct ti960 *va, unsigned short rx_port,
- unsigned char reg, unsigned char val)
+ unsigned short ser_alias, unsigned char reg, unsigned char val)
{
int ret;
int retry, timeout = 10;
struct i2c_client *client = v4l2_get_subdevdata(&va->sd);
- unsigned short ser_alias = va->pdata->subdev_info[rx_port].ser_alias;
+ dev_dbg(va->sd.dev, "%s port %d, ser_alias %x, reg %x, val %x",
+ __func__, rx_port, ser_alias, reg, val);
client->addr = ser_alias;
for (retry = 0; retry < timeout; retry++) {
ret = i2c_smbus_write_byte_data(client, reg, val);
@@ -154,6 +156,56 @@ static int ti953_reg_write(struct ti960 *va, unsigned short rx_port,
return 0;
}
+static int ti953_reg_read(struct ti960 *va, unsigned short rx_port,
+ unsigned short ser_alias, unsigned char reg, unsigned char *val)
+{
+ int retry, timeout = 10;
+ struct i2c_client *client = v4l2_get_subdevdata(&va->sd);
+
+ client->addr = ser_alias;
+ for (retry = 0; retry < timeout; retry++) {
+ *val = i2c_smbus_read_byte_data(client, reg);
+ if (*val < 0)
+ usleep_range(5000, 6000);
+ else
+ break;
+ }
+
+ client->addr = TI960_I2C_ADDRESS;
+ if (retry >= timeout) {
+ dev_err(va->sd.dev,
+ "%s:read reg failed: port=%2x, addr=%2x, reg=%2x\n",
+ __func__, rx_port, ser_alias, reg);
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static bool ti953_detect(struct ti960 *va, unsigned short rx_port, unsigned short ser_alias)
+{
+ bool ret = false;
+ int i;
+ int rval;
+ unsigned char val;
+
+ for (i = 0; i < ARRAY_SIZE(ti953_FPD3_RX_ID); i++) {
+ rval = ti953_reg_read(va, rx_port, ser_alias,
+ ti953_FPD3_RX_ID[i].reg, &val);
+ if (rval) {
+ dev_err(va->sd.dev, "port %d, ti953 write timeout %d\n", rx_port, rval);
+ break;
+ }
+ if (val != ti953_FPD3_RX_ID[i].val_expected)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(ti953_FPD3_RX_ID))
+ ret = true;
+
+ return ret;
+}
+
static int ti960_reg_read(struct ti960 *va, unsigned char reg, unsigned int *val)
{
int ret, retry, timeout = 10;
@@ -221,6 +273,20 @@ static int ti960_map_alias_i2c_addr(struct ti960 *va, unsigned short rx_port,
return regmap_write(va->regmap8, TI960_SLAVE_ALIAS_ID0, addr);
}
+static int ti960_map_ser_alias_addr(struct ti960 *va, unsigned short rx_port,
+ unsigned short ser_alias)
+{
+ int rval;
+
+ dev_dbg(va->sd.dev, "%s port %d, ser_alias %x\n", __func__, rx_port, ser_alias);
+ rval = regmap_write(va->regmap8, TI960_RX_PORT_SEL,
+ (rx_port << 4) + (1 << rx_port));
+ if (rval)
+ return rval;
+
+ return regmap_write(va->regmap8, TI960_SER_ALIAS_ID, ser_alias);
+}
+
static int ti960_fsin_gpio_init(struct ti960 *va, unsigned short rx_port,
unsigned short fsin_gpio)
{
@@ -244,23 +310,48 @@ static int ti960_fsin_gpio_init(struct ti960 *va, unsigned short rx_port,
if (rval)
return rval;
- rval = regmap_read(va->regmap8, TI960_BC_GPIO_CTL0, &reg_val);
- if (rval) {
- dev_dbg(va->sd.dev, "Failed to read gpio status.\n");
- return rval;
- }
+ switch (fsin_gpio) {
+ case 0:
+ case 1:
+ rval = regmap_read(va->regmap8, TI960_BC_GPIO_CTL0, &reg_val);
+ if (rval) {
+ dev_dbg(va->sd.dev, "Failed to read gpio status.\n");
+ return rval;
+ }
- if (fsin_gpio == 0) {
- reg_val &= ~TI960_GPIO0_MASK;
- reg_val |= TI960_GPIO0_FSIN;
- } else {
- reg_val &= ~TI960_GPIO1_MASK;
- reg_val |= TI960_GPIO1_FSIN;
- }
+ if (fsin_gpio == 0) {
+ reg_val &= ~TI960_GPIO0_MASK;
+ reg_val |= TI960_GPIO0_FSIN;
+ } else {
+ reg_val &= ~TI960_GPIO1_MASK;
+ reg_val |= TI960_GPIO1_FSIN;
+ }
- rval = regmap_write(va->regmap8, TI960_BC_GPIO_CTL0, reg_val);
- if (rval)
- dev_dbg(va->sd.dev, "Failed to set gpio.\n");
+ rval = regmap_write(va->regmap8, TI960_BC_GPIO_CTL0, reg_val);
+ if (rval)
+ dev_dbg(va->sd.dev, "Failed to set gpio.\n");
+ break;
+ case 2:
+ case 3:
+ rval = regmap_read(va->regmap8, TI960_BC_GPIO_CTL1, &reg_val);
+ if (rval) {
+ dev_dbg(va->sd.dev, "Failed to read gpio status.\n");
+ return rval;
+ }
+
+ if (fsin_gpio == 2) {
+ reg_val &= ~TI960_GPIO2_MASK;
+ reg_val |= TI960_GPIO2_FSIN;
+ } else {
+ reg_val &= ~TI960_GPIO3_MASK;
+ reg_val |= TI960_GPIO3_FSIN;
+ }
+
+ rval = regmap_write(va->regmap8, TI960_BC_GPIO_CTL1, reg_val);
+ if (rval)
+ dev_dbg(va->sd.dev, "Failed to set gpio.\n");
+ break;
+ }
return rval;
}
@@ -269,14 +360,34 @@ static int ti960_get_routing(struct v4l2_subdev *sd,
struct v4l2_subdev_routing *route)
{
struct ti960 *va = to_ti960(sd);
- int i;
+ int i, j;
- for (i = 0; i < min(va->nstreams, route->num_routes); ++i) {
- route->routes[i].sink_pad = va->ti960_route[i].sink_pad;
- route->routes[i].sink_stream = va->ti960_route[i].sink_stream;
- route->routes[i].source_pad = va->ti960_route[i].source_pad;
- route->routes[i].source_stream = va->ti960_route[i].source_stream;
- route->routes[i].flags = va->ti960_route[i].flags;
+ /* active routing first */
+ j = 0;
+ for (i = 0; i < va->nstreams; ++i) {
+ if (j >= route->num_routes)
+ break;
+ if (!(va->ti960_route[i].flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE))
+ continue;
+ route->routes[j].sink_pad = va->ti960_route[i].sink_pad;
+ route->routes[j].sink_stream = va->ti960_route[i].sink_stream;
+ route->routes[j].source_pad = va->ti960_route[i].source_pad;
+ route->routes[j].source_stream = va->ti960_route[i].source_stream;
+ route->routes[j].flags = va->ti960_route[i].flags;
+ j++;
+ }
+
+ for (i = 0; i < va->nstreams; ++i) {
+ if (j >= route->num_routes)
+ break;
+ if (va->ti960_route[i].flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE)
+ continue;
+ route->routes[j].sink_pad = va->ti960_route[i].sink_pad;
+ route->routes[j].sink_stream = va->ti960_route[i].sink_stream;
+ route->routes[j].source_pad = va->ti960_route[i].source_pad;
+ route->routes[j].source_stream = va->ti960_route[i].source_stream;
+ route->routes[j].flags = va->ti960_route[i].flags;
+ j++;
}
route->num_routes = i;
@@ -538,20 +649,22 @@ static int ti960_registered(struct v4l2_subdev *subdev)
if (k >= va->nsinks)
break;
+ rval = ti960_map_ser_alias_addr(va, info->rx_port,
+ info->ser_alias << 1);
+ if (rval)
+ return rval;
+
+
+ if (!ti953_detect(va, info->rx_port, info->ser_alias))
+ continue;
+
/*
* The sensors should not share the same pdata structure.
* Clone the pdata for each sensor.
*/
memcpy(&va->subdev_pdata[k], pdata, sizeof(*pdata));
- if (va->subdev_pdata[k].xshutdown != 0 &&
- va->subdev_pdata[k].xshutdown != 1) {
- dev_err(va->sd.dev, "xshutdown(%d) must be 0 or 1 to connect.\n",
- va->subdev_pdata[k].xshutdown);
- return -EINVAL;
- }
- /* If 0 is xshutdown, then 1 would be FSIN, vice versa. */
- va->sub_devs[k].fsin_gpio = 1 - va->subdev_pdata[k].xshutdown;
+ va->sub_devs[k].fsin_gpio = va->subdev_pdata[k].fsin;
/* Spin sensor subdev suffix name */
va->subdev_pdata[k].suffix = info->suffix;
@@ -594,6 +707,7 @@ static int ti960_registered(struct v4l2_subdev *subdev)
va->sub_devs[k].rx_port = info->rx_port;
va->sub_devs[k].phy_i2c_addr = info->phy_i2c_addr;
va->sub_devs[k].alias_i2c_addr = info->board_info.addr;
+ va->sub_devs[k].ser_i2c_addr = info->ser_alias;
memcpy(va->sub_devs[k].sd_name,
va->subdev_pdata[k].module_name,
min(sizeof(va->sub_devs[k].sd_name) - 1,
@@ -715,6 +829,8 @@ static bool ti960_broadcast_mode(struct v4l2_subdev *subdev)
static int ti960_rx_port_config(struct ti960 *va, int sink, int rx_port)
{
int rval;
+ int i;
+ unsigned int csi_vc_map;
/* Select RX port. */
rval = regmap_write(va->regmap8, TI960_RX_PORT_SEL,
@@ -732,9 +848,30 @@ static int ti960_rx_port_config(struct ti960 *va, int sink, int rx_port)
}
/*
- * TODO: CSI VC MAPPING.
+ * CSI VC MAPPING.
*/
-
+ rval = regmap_read(va->regmap8, TI960_CSI_VC_MAP, &csi_vc_map);
+ if (rval < 0) {
+ dev_err(va->sd.dev, "960 reg read ret=%x", rval);
+ return rval;
+ }
+ for (i = 0; i < va->nstreams; ++i) {
+ if (!(va->ti960_route[i].flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE))
+ continue;
+ if (rx_port != va->ti960_route[i].sink_pad)
+ continue;
+ csi_vc_map &= ~(0x3 << (va->ti960_route[i].sink_stream & 0x3) * 2);
+ csi_vc_map |= (va->ti960_route[i].source_stream & 0x3)
+ << (va->ti960_route[i].sink_stream & 0x3) * 2;
+ }
+ dev_dbg(va->sd.dev, "%s port %d, csi_vc_map %x",
+ __func__, rx_port, csi_vc_map);
+ rval = regmap_write(va->regmap8, TI960_CSI_VC_MAP,
+ csi_vc_map);
+ if (rval) {
+ dev_err(va->sd.dev, "Failed to set port config.\n");
+ return rval;
+ }
return 0;
}
@@ -777,7 +914,8 @@ static int ti960_set_stream(struct v4l2_subdev *subdev, int enable)
struct v4l2_subdev *sd;
int i, j, rval;
bool broadcast;
- unsigned int rx_port;
+ unsigned short rx_port;
+ unsigned short ser_alias;
int sd_idx = -1;
DECLARE_BITMAP(rx_port_enabled, 32);
@@ -802,6 +940,7 @@ static int ti960_set_stream(struct v4l2_subdev *subdev, int enable)
if (j < 0)
return -EINVAL;
rx_port = va->sub_devs[j].rx_port;
+ ser_alias = va->sub_devs[j].ser_i2c_addr;
rval = ti960_rx_port_config(va, i, rx_port);
if (rval < 0)
return rval;
@@ -837,6 +976,18 @@ static int ti960_set_stream(struct v4l2_subdev *subdev, int enable)
i, enable);
return rval;
}
+ /*
+ * FIXME: workaround for ov495 block issue.
+ * reset Ser TI953, to avoid ov495 block,
+ * only do reset for ov495, then it won't break other sensors.
+ */
+ if (memcmp(va->sub_devs[j].sd_name, "OV495", strlen("OV495")) == 0) {
+ ti953_reg_write(va, rx_port, ser_alias, 0x0e, 0xf0);
+ msleep(50);
+ ti953_reg_write(va, rx_port, ser_alias, 0x0d, 00);
+ msleep(50);
+ ti953_reg_write(va, rx_port, ser_alias, 0x0d, 0x1);
+ }
}
}
@@ -872,6 +1023,20 @@ static int ti960_set_stream(struct v4l2_subdev *subdev, int enable)
"Failed to enable frame sync gpio init.\n");
return rval;
}
+ /*
+ * FIXME: workaround for ov495 block issue.
+ * reset Ser TI953, to avoid ov495 block,
+ * only do reset for ov495, then it won't break other sensors.
+ */
+ if (memcmp(va->sub_devs[i].sd_name, "OV495", strlen("OV495")) == 0) {
+ rx_port = va->sub_devs[i].rx_port;
+ ser_alias = va->sub_devs[i].ser_i2c_addr;
+ ti953_reg_write(va, rx_port, ser_alias, 0x0e, 0xf0);
+ msleep(50);
+ ti953_reg_write(va, rx_port, ser_alias, 0x0d, 00);
+ msleep(50);
+ ti953_reg_write(va, rx_port, ser_alias, 0x0d, 0x1);
+ }
}
}
@@ -967,7 +1132,7 @@ static const struct v4l2_ctrl_config ti960_controls[] = {
.max = ARRAY_SIZE(ti960_op_sys_clock) - 1,
.min = 0,
.step = 0,
- .def = 0,
+ .def = 1,
.qmenu_int = ti960_op_sys_clock,
},
{
@@ -1072,6 +1237,8 @@ static int ti960_init(struct ti960 *va)
unsigned int reset_gpio = va->pdata->reset_gpio;
int i, rval;
unsigned int val;
+ int m;
+ int rx_port = 0;
gpio_set_value(reset_gpio, 1);
usleep_range(2000, 3000);
@@ -1097,6 +1264,10 @@ static int ti960_init(struct ti960 *va)
}
usleep_range(10000, 11000);
+ /*
+ * fixed value of sensor phy, ser_alias, port config for ti960 each port,
+ * not yet known sensor platform data here.
+ */
for (i = 0; i < ARRAY_SIZE(ti960_init_settings); i++) {
rval = regmap_write(va->regmap8,
ti960_init_settings[i].reg,
@@ -1109,45 +1280,37 @@ static int ti960_init(struct ti960 *va)
}
}
- /* wait for ti953 ready */
- usleep_range(200000, 300000);
- for (i = 0; i < ARRAY_SIZE(ti953_init_settings); i++) {
- rval = ti953_reg_write(va, 0,
- ti953_init_settings[i].reg,
- ti953_init_settings[i].val);
+ for (m = 0; m < ARRAY_SIZE(ti960_init_settings_2); m++) {
+ rval = regmap_write(va->regmap8,
+ ti960_init_settings_2[m].reg,
+ ti960_init_settings_2[m].val);
if (rval) {
- dev_err(va->sd.dev, "port %d, ti953 write timeout %d\n", 0, rval);
+ dev_err(va->sd.dev,
+ "Failed to write TI960 init setting 2, reg %2x, val %2x\n",
+ ti960_init_settings_2[m].reg, ti960_init_settings_2[m].val);
break;
}
}
- for (i = 0; i < ARRAY_SIZE(ti960_init_settings_2); i++) {
+ rval = regmap_write(va->regmap8, TI960_RX_PORT_SEL,
+ (rx_port << 4) + (1 << rx_port));
+ if (rval)
+ return rval;
+ for (m = 1; m < ARRAY_SIZE(ti960_init_settings_3); m++) {
rval = regmap_write(va->regmap8,
- ti960_init_settings_2[i].reg,
- ti960_init_settings_2[i].val);
+ ti960_init_settings_3[m].reg,
+ ti960_init_settings_3[m].val);
if (rval) {
dev_err(va->sd.dev,
"Failed to write TI960 init setting 2, reg %2x, val %2x\n",
- ti960_init_settings_2[i].reg, ti960_init_settings_2[i].val);
- return rval;
- }
- }
-
- for (i = 0; i < ARRAY_SIZE(ti953_init_settings_2); i++) {
- rval = ti953_reg_write(va, 0,
- ti953_init_settings_2[i].reg,
- ti953_init_settings_2[i].val);
- if (rval) {
- dev_err(va->sd.dev, "port %d, ti953 write timeout %d\n", 0, rval);
+ ti960_init_settings_3[m].reg, ti960_init_settings_3[m].val);
break;
}
}
- /* reset and power for ti953 */
- ti953_reg_write(va, 0, 0x0d, 00);
- usleep_range(50000, 60000);
- ti953_reg_write(va, 0, 0x0d, 0x3);
+ /* wait for Ser ti953 ready */
+ msleep(200);
rval = ti960_map_subdevs_addr(va);
if (rval)
@@ -1158,6 +1321,46 @@ static int ti960_init(struct ti960 *va)
static void ti960_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
+ struct i2c_client *client = to_i2c_client(chip->dev);
+#else
+ struct i2c_client *client = to_i2c_client(chip->parent);
+#endif
+ struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+ struct ti960 *va = to_ti960(subdev);
+ unsigned int reg_val;
+ int rx_port, gpio_port;
+ int ret;
+
+ if (gpio >= NR_OF_TI960_GPIOS)
+ return;
+
+ rx_port = gpio / NR_OF_GPIOS_PER_PORT;
+ gpio_port = gpio % NR_OF_GPIOS_PER_PORT;
+
+ ret = regmap_write(va->regmap8, TI960_RX_PORT_SEL,
+ (rx_port << 4) + (1 << rx_port));
+ if (ret) {
+ dev_dbg(&client->dev, "Failed to select RX port.\n");
+ return;
+ }
+ ret = regmap_read(va->regmap8, TI960_BC_GPIO_CTL0, &reg_val);
+ if (ret) {
+ dev_dbg(&client->dev, "Failed to read gpio status.\n");
+ return;
+ }
+
+ if (gpio_port == 0) {
+ reg_val &= ~TI960_GPIO0_MASK;
+ reg_val |= value ? TI960_GPIO0_HIGH : TI960_GPIO0_LOW;
+ } else {
+ reg_val &= ~TI960_GPIO1_MASK;
+ reg_val |= value ? TI960_GPIO1_HIGH : TI960_GPIO1_LOW;
+ }
+
+ ret = regmap_write(va->regmap8, TI960_BC_GPIO_CTL0, reg_val);
+ if (ret)
+ dev_dbg(&client->dev, "Failed to set gpio.\n");
}
static int ti960_gpio_direction_output(struct gpio_chip *chip,
@@ -1170,7 +1373,7 @@ static int ti960_probe(struct i2c_client *client,
const struct i2c_device_id *devid)
{
struct ti960 *va;
- int i, rval = 0;
+ int i, j, k, l, rval = 0;
if (client->dev.platform_data == NULL)
return -ENODEV;
@@ -1209,12 +1412,17 @@ static int ti960_probe(struct i2c_client *client,
if (!va->ti960_route)
return -ENOMEM;
- for (i = 0; i < va->nstreams; i++) {
- va->ti960_route[i].sink_pad = i;
- va->ti960_route[i].sink_stream = i;
- va->ti960_route[i].source_pad = TI960_PAD_SOURCE;
- va->ti960_route[i].source_stream = i;
-// va->ti960_route[i].flags = MEDIA_PAD_FL_MULTIPLEX;
+ /* routing for virtual channel supports */
+ l = 0;
+ for (i = 0; i < NR_OF_TI960_SINK_PADS; i++)
+ for (j = 0; j < NR_OF_TI960_VCS_PER_SINK_PAD; j++)
+ for (k = 0; k < NR_OF_TI960_VCS_SOURCE_PAD; k++) {
+ va->ti960_route[l].sink_pad = i;
+ va->ti960_route[l].sink_stream = j;
+ va->ti960_route[l].source_pad = TI960_PAD_SOURCE;
+ va->ti960_route[l].source_stream = k;
+ va->ti960_route[l].flags = MEDIA_PAD_FL_MULTIPLEX;
+ l++;
}
va->regmap8 = devm_regmap_init_i2c(client,
diff --git a/include/media/ti960.h b/include/media/ti960.h
index 60e134fce6c5..fe655c216b41 100644
--- a/include/media/ti960.h
+++ b/include/media/ti960.h
@@ -19,11 +19,16 @@
#define PIXEL_ORDER_BGGR 2
#define PIXEL_ORDER_GBRG 3
-#define NR_OF_TI960_STREAMS 4
+#define NR_OF_TI960_VCS_PER_SINK_PAD 2
+#define NR_OF_TI960_VCS_SOURCE_PAD 4
#define NR_OF_TI960_SOURCE_PADS 1
#define NR_OF_TI960_SINK_PADS 4
#define NR_OF_TI960_PADS \
(NR_OF_TI960_SOURCE_PADS + NR_OF_TI960_SINK_PADS)
+/* 4port * 2vc/port * 8 stream total */
+#define NR_OF_TI960_STREAMS \
+ (NR_OF_TI960_SINK_PADS * NR_OF_TI960_VCS_PER_SINK_PAD \
+ * NR_OF_TI960_VCS_SOURCE_PAD)
#define NR_OF_GPIOS_PER_PORT 2
#define NR_OF_TI960_GPIOS \
(NR_OF_TI960_SINK_PADS * NR_OF_GPIOS_PER_PORT)
--
https://clearlinux.org