static int rvin_parse_dt(struct rvin_dev *vin) { const struct of_device_id *match; struct v4l2_of_endpoint ep; struct device_node *np; int ret; match = of_match_device(of_match_ptr(rvin_of_id_table), vin->dev); if (!match) return -ENODEV; vin->chip = (enum chip_id)match->data; np = of_graph_get_next_endpoint(vin->dev->of_node, NULL); if (!np) { vin_err(vin, "Could not find endpoint\n"); return -EINVAL; } ret = v4l2_of_parse_endpoint(np, &ep); if (ret) { vin_err(vin, "Could not parse endpoint\n"); return ret; } of_node_put(np); vin->mbus_cfg.type = ep.bus_type; switch (vin->mbus_cfg.type) { case V4L2_MBUS_PARALLEL: vin->mbus_cfg.flags = ep.bus.parallel.flags; break; case V4L2_MBUS_BT656: vin->mbus_cfg.flags = 0; break; default: vin_err(vin, "Unknown media bus type\n"); return -EINVAL; } return 0; }
/* Parse port node and register as a sub-device any sensor specified there. */ static int fimc_md_parse_port_node(struct fimc_md *fmd, struct device_node *port, unsigned int index) { struct device_node *rem, *ep, *np; struct fimc_source_info *pd; struct v4l2_of_endpoint endpoint; int ret; u32 val; pd = &fmd->sensor[index].pdata; /* Assume here a port node can have only one endpoint node. */ ep = of_get_next_child(port, NULL); if (!ep) return 0; v4l2_of_parse_endpoint(ep, &endpoint); if (WARN_ON(endpoint.port == 0) || index >= FIMC_MAX_SENSORS) return -EINVAL; pd->mux_id = (endpoint.port - 1) & 0x1; rem = v4l2_of_get_remote_port_parent(ep); of_node_put(ep); if (rem == NULL) { v4l2_info(&fmd->v4l2_dev, "Remote device at %s not found\n", ep->full_name); return 0; } if (!of_property_read_u32(rem, "samsung,camclk-out", &val)) pd->clk_id = val; if (!of_property_read_u32(rem, "clock-frequency", &val)) pd->clk_frequency = val; if (pd->clk_frequency == 0) { v4l2_err(&fmd->v4l2_dev, "Wrong clock frequency at node %s\n", rem->full_name); of_node_put(rem); return -EINVAL; } if (fimc_input_is_parallel(endpoint.port)) { if (endpoint.bus_type == V4L2_MBUS_PARALLEL) pd->sensor_bus_type = FIMC_BUS_TYPE_ITU_601; else pd->sensor_bus_type = FIMC_BUS_TYPE_ITU_656; pd->flags = endpoint.bus.parallel.flags; } else if (fimc_input_is_mipi_csi(endpoint.port)) { /* * MIPI CSI-2: only input mux selection and * the sensor's clock frequency is needed. */ pd->sensor_bus_type = FIMC_BUS_TYPE_MIPI_CSI2; } else { v4l2_err(&fmd->v4l2_dev, "Wrong port id (%u) at node %s\n", endpoint.port, rem->full_name); } /* * For FIMC-IS handled sensors, that are placed under i2c-isp device * node, FIMC is connected to the FIMC-IS through its ISP Writeback * input. Sensors are attached to the FIMC-LITE hostdata interface * directly or through MIPI-CSIS, depending on the external media bus * used. This needs to be handled in a more reliable way, not by just * checking parent's node name. */ np = of_get_parent(rem); if (np && !of_node_cmp(np->name, "i2c-isp")) pd->fimc_bus_type = FIMC_BUS_TYPE_ISP_WRITEBACK; else pd->fimc_bus_type = pd->sensor_bus_type; ret = fimc_md_of_add_sensor(fmd, rem, index); of_node_put(rem); return ret; }