@@ -1570,7 +1570,9 @@ int rvin_dma_register(struct rvin_dev *vin, int irq)
*/
int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel)
{
- u32 ifmd, vnmc;
+ const struct rvin_group_route *route;
+ u32 ifmd = 0;
+ u32 vnmc;
int ret;
ret = pm_runtime_get_sync(vin->dev);
@@ -1583,9 +1585,26 @@ int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel)
vnmc = rvin_read(vin, VNMC_REG);
rvin_write(vin, vnmc & ~VNMC_VUP, VNMC_REG);
- ifmd = VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0 | VNCSI_IFMD_CSI_CHSEL(chsel);
+ /*
+ * Set data expansion mode to "pad with 0s" by inspecting the routes
+ * table to find out which bit fields are available in the IFMD
+ * register. IFMD_DES1 controls data expansion mode for CSI20/21,
+ * IFMD_DES0 controls data expansion mode for CSI40/41.
+ */
+ for (route = vin->info->routes; route->mask; route++) {
+ if (route->csi == RVIN_CSI20 || route->csi == RVIN_CSI21)
+ ifmd |= VNCSI_IFMD_DES1;
+ else
+ ifmd |= VNCSI_IFMD_DES0;
+
+ if (ifmd == (VNCSI_IFMD_DES0 | VNCSI_IFMD_DES1))
+ break;
+ }
- rvin_write(vin, ifmd, VNCSI_IFMD_REG);
+ if (ifmd) {
+ ifmd |= VNCSI_IFMD_CSI_CHSEL(chsel);
+ rvin_write(vin, ifmd, VNCSI_IFMD_REG);
+ }
vin_dbg(vin, "Set IFMD 0x%x\n", ifmd);