| .. | .. |
|---|
| 750 | 750 | struct v4l2_querymenu qm = { .id = V4L2_CID_LINK_FREQ, }; |
|---|
| 751 | 751 | int ret; |
|---|
| 752 | 752 | |
|---|
| 753 | + if (!sensor_sd) |
|---|
| 754 | + return -ENODEV; |
|---|
| 755 | + |
|---|
| 753 | 756 | link_freq = v4l2_ctrl_find(sensor_sd->ctrl_handler, V4L2_CID_LINK_FREQ); |
|---|
| 754 | 757 | if (!link_freq) { |
|---|
| 755 | 758 | v4l2_warn(sd, "No pixel rate control in subdev\n"); |
|---|
| .. | .. |
|---|
| 777 | 780 | { |
|---|
| 778 | 781 | struct mipidphy_priv *priv = to_dphy_priv(sd); |
|---|
| 779 | 782 | struct v4l2_subdev *sensor_sd = get_remote_sensor(sd); |
|---|
| 780 | | - struct mipidphy_sensor *sensor = sd_to_sensor(priv, sensor_sd); |
|---|
| 783 | + struct mipidphy_sensor *sensor; |
|---|
| 781 | 784 | struct v4l2_mbus_config mbus; |
|---|
| 782 | 785 | int ret; |
|---|
| 783 | 786 | |
|---|
| 784 | | - ret = v4l2_subdev_call(sensor_sd, video, g_mbus_config, &mbus); |
|---|
| 787 | + if (!sensor_sd) |
|---|
| 788 | + return -ENODEV; |
|---|
| 789 | + sensor = sd_to_sensor(priv, sensor_sd); |
|---|
| 790 | + if (!sensor) |
|---|
| 791 | + return -ENODEV; |
|---|
| 792 | + ret = v4l2_subdev_call(sensor_sd, pad, get_mbus_config, 0, &mbus); |
|---|
| 785 | 793 | if (ret) |
|---|
| 786 | 794 | return ret; |
|---|
| 787 | 795 | |
|---|
| .. | .. |
|---|
| 899 | 907 | return -EINVAL; |
|---|
| 900 | 908 | } |
|---|
| 901 | 909 | |
|---|
| 902 | | -static int mipidphy_g_mbus_config(struct v4l2_subdev *sd, |
|---|
| 910 | +static int mipidphy_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id, |
|---|
| 903 | 911 | struct v4l2_mbus_config *config) |
|---|
| 904 | 912 | { |
|---|
| 905 | 913 | struct mipidphy_priv *priv = to_dphy_priv(sd); |
|---|
| .. | .. |
|---|
| 909 | 917 | if (!sensor_sd) |
|---|
| 910 | 918 | return -ENODEV; |
|---|
| 911 | 919 | sensor = sd_to_sensor(priv, sensor_sd); |
|---|
| 920 | + if (!sensor) |
|---|
| 921 | + return -ENODEV; |
|---|
| 912 | 922 | mipidphy_update_sensor_mbus(sd); |
|---|
| 913 | 923 | *config = sensor->mbus; |
|---|
| 914 | 924 | |
|---|
| .. | .. |
|---|
| 925 | 935 | return pm_runtime_put(priv->dev); |
|---|
| 926 | 936 | } |
|---|
| 927 | 937 | |
|---|
| 928 | | -static int mipidphy_runtime_suspend(struct device *dev) |
|---|
| 938 | +static int __maybe_unused mipidphy_runtime_suspend(struct device *dev) |
|---|
| 929 | 939 | { |
|---|
| 930 | 940 | struct media_entity *me = dev_get_drvdata(dev); |
|---|
| 931 | 941 | struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(me); |
|---|
| .. | .. |
|---|
| 940 | 950 | return 0; |
|---|
| 941 | 951 | } |
|---|
| 942 | 952 | |
|---|
| 943 | | -static int mipidphy_runtime_resume(struct device *dev) |
|---|
| 953 | +static int __maybe_unused mipidphy_runtime_resume(struct device *dev) |
|---|
| 944 | 954 | { |
|---|
| 945 | 955 | struct media_entity *me = dev_get_drvdata(dev); |
|---|
| 946 | 956 | struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(me); |
|---|
| .. | .. |
|---|
| 970 | 980 | { |
|---|
| 971 | 981 | struct mipidphy_priv *priv = to_dphy_priv(sd); |
|---|
| 972 | 982 | struct v4l2_subdev *sensor_sd = get_remote_sensor(sd); |
|---|
| 973 | | - struct mipidphy_sensor *sensor = sd_to_sensor(priv, sensor_sd); |
|---|
| 983 | + struct mipidphy_sensor *sensor; |
|---|
| 974 | 984 | int ret; |
|---|
| 975 | 985 | /* |
|---|
| 976 | 986 | * Do not allow format changes and just relay whatever |
|---|
| 977 | 987 | * set currently in the sensor. |
|---|
| 978 | 988 | */ |
|---|
| 979 | 989 | if (!sensor_sd) |
|---|
| 990 | + return -ENODEV; |
|---|
| 991 | + sensor = sd_to_sensor(priv, sensor_sd); |
|---|
| 992 | + if (!sensor) |
|---|
| 980 | 993 | return -ENODEV; |
|---|
| 981 | 994 | ret = v4l2_subdev_call(sensor_sd, pad, get_fmt, NULL, fmt); |
|---|
| 982 | 995 | if (!ret && fmt->pad == 0) |
|---|
| .. | .. |
|---|
| 997 | 1010 | .set_fmt = mipidphy_get_set_fmt, |
|---|
| 998 | 1011 | .get_fmt = mipidphy_get_set_fmt, |
|---|
| 999 | 1012 | .get_selection = mipidphy_get_selection, |
|---|
| 1013 | + .get_mbus_config = mipidphy_g_mbus_config, |
|---|
| 1000 | 1014 | }; |
|---|
| 1001 | 1015 | |
|---|
| 1002 | 1016 | static const struct v4l2_subdev_core_ops mipidphy_core_ops = { |
|---|
| .. | .. |
|---|
| 1005 | 1019 | |
|---|
| 1006 | 1020 | static const struct v4l2_subdev_video_ops mipidphy_video_ops = { |
|---|
| 1007 | 1021 | .g_frame_interval = mipidphy_g_frame_interval, |
|---|
| 1008 | | - .g_mbus_config = mipidphy_g_mbus_config, |
|---|
| 1009 | 1022 | .s_stream = mipidphy_s_stream, |
|---|
| 1010 | 1023 | }; |
|---|
| 1011 | 1024 | |
|---|
| .. | .. |
|---|
| 1146 | 1159 | struct v4l2_subdev *sd) |
|---|
| 1147 | 1160 | { |
|---|
| 1148 | 1161 | struct v4l2_subdev *sensor_sd = get_remote_sensor(sd); |
|---|
| 1149 | | - struct mipidphy_sensor *sensor = sd_to_sensor(priv, sensor_sd); |
|---|
| 1162 | + struct mipidphy_sensor *sensor; |
|---|
| 1150 | 1163 | const struct dphy_drv_data *drv_data = priv->drv_data; |
|---|
| 1151 | 1164 | const struct hsfreq_range *hsfreq_ranges = drv_data->hsfreq_ranges; |
|---|
| 1152 | 1165 | int num_hsfreq_ranges = drv_data->num_hsfreq_ranges; |
|---|
| 1153 | 1166 | int i, hsfreq = 0; |
|---|
| 1167 | + |
|---|
| 1168 | + if (!sensor_sd) |
|---|
| 1169 | + return -ENODEV; |
|---|
| 1170 | + sensor = sd_to_sensor(priv, sensor_sd); |
|---|
| 1171 | + if (!sensor) |
|---|
| 1172 | + return -ENODEV; |
|---|
| 1154 | 1173 | |
|---|
| 1155 | 1174 | for (i = 0; i < num_hsfreq_ranges; i++) { |
|---|
| 1156 | 1175 | if (hsfreq_ranges[i].range_h >= priv->data_rate_mbps) { |
|---|
| .. | .. |
|---|
| 1237 | 1256 | struct v4l2_subdev *sd) |
|---|
| 1238 | 1257 | { |
|---|
| 1239 | 1258 | struct v4l2_subdev *sensor_sd = get_remote_sensor(sd); |
|---|
| 1240 | | - struct mipidphy_sensor *sensor = sd_to_sensor(priv, sensor_sd); |
|---|
| 1259 | + struct mipidphy_sensor *sensor; |
|---|
| 1241 | 1260 | const struct dphy_drv_data *drv_data = priv->drv_data; |
|---|
| 1242 | 1261 | const struct hsfreq_range *hsfreq_ranges = drv_data->hsfreq_ranges; |
|---|
| 1243 | 1262 | int num_hsfreq_ranges = drv_data->num_hsfreq_ranges; |
|---|
| 1244 | 1263 | int i, hsfreq = 0; |
|---|
| 1264 | + |
|---|
| 1265 | + if (!sensor_sd) |
|---|
| 1266 | + return -ENODEV; |
|---|
| 1267 | + sensor = sd_to_sensor(priv, sensor_sd); |
|---|
| 1268 | + if (!sensor) |
|---|
| 1269 | + return -ENODEV; |
|---|
| 1245 | 1270 | |
|---|
| 1246 | 1271 | for (i = 0; i < num_hsfreq_ranges; i++) { |
|---|
| 1247 | 1272 | if (hsfreq_ranges[i].range_h >= priv->data_rate_mbps) { |
|---|
| .. | .. |
|---|
| 1356 | 1381 | struct v4l2_subdev *sd) |
|---|
| 1357 | 1382 | { |
|---|
| 1358 | 1383 | struct v4l2_subdev *sensor_sd = get_remote_sensor(sd); |
|---|
| 1359 | | - struct mipidphy_sensor *sensor = sd_to_sensor(priv, sensor_sd); |
|---|
| 1384 | + struct mipidphy_sensor *sensor; |
|---|
| 1360 | 1385 | const struct dphy_drv_data *drv_data = priv->drv_data; |
|---|
| 1361 | 1386 | const struct hsfreq_range *hsfreq_ranges = drv_data->hsfreq_ranges; |
|---|
| 1362 | 1387 | int num_hsfreq_ranges = drv_data->num_hsfreq_ranges; |
|---|
| 1363 | 1388 | int i, hsfreq = 0; |
|---|
| 1364 | 1389 | u32 val = 0; |
|---|
| 1365 | 1390 | u32 clk_mode = 0x03; |
|---|
| 1391 | + |
|---|
| 1392 | + if (!sensor_sd) |
|---|
| 1393 | + return -ENODEV; |
|---|
| 1394 | + sensor = sd_to_sensor(priv, sensor_sd); |
|---|
| 1395 | + if (!sensor) |
|---|
| 1396 | + return -ENODEV; |
|---|
| 1366 | 1397 | |
|---|
| 1367 | 1398 | write_grf_reg(priv, GRF_DVP_V18SEL, 0x1); |
|---|
| 1368 | 1399 | |
|---|
| .. | .. |
|---|
| 1378 | 1409 | write_csiphy_reg(priv, CSIPHY_CTRL_PWRCTL, 0xe0); |
|---|
| 1379 | 1410 | usleep_range(500, 1000); |
|---|
| 1380 | 1411 | |
|---|
| 1381 | | - if (sensor->mbus.type == V4L2_MBUS_CSI2) { |
|---|
| 1412 | + if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) { |
|---|
| 1382 | 1413 | /* Reset dphy digital part */ |
|---|
| 1383 | 1414 | write_csiphy_reg(priv, CSIPHY_CTRL_DIG_RST, 0x1e); |
|---|
| 1384 | 1415 | write_csiphy_reg(priv, CSIPHY_CTRL_DIG_RST, 0x1f); |
|---|
| .. | .. |
|---|
| 1652 | 1683 | notifier); |
|---|
| 1653 | 1684 | struct mipidphy_sensor *sensor = sd_to_sensor(priv, sd); |
|---|
| 1654 | 1685 | |
|---|
| 1655 | | - sensor->sd = NULL; |
|---|
| 1686 | + if (sensor) |
|---|
| 1687 | + sensor->sd = NULL; |
|---|
| 1656 | 1688 | } |
|---|
| 1657 | 1689 | |
|---|
| 1658 | 1690 | static const struct |
|---|
| .. | .. |
|---|
| 1674 | 1706 | return -EINVAL; |
|---|
| 1675 | 1707 | } |
|---|
| 1676 | 1708 | |
|---|
| 1677 | | - if (vep->bus_type == V4L2_MBUS_CSI2) { |
|---|
| 1678 | | - config->type = V4L2_MBUS_CSI2; |
|---|
| 1709 | + if (vep->bus_type == V4L2_MBUS_CSI2_DPHY) { |
|---|
| 1710 | + config->type = V4L2_MBUS_CSI2_DPHY; |
|---|
| 1679 | 1711 | config->flags = vep->bus.mipi_csi2.flags; |
|---|
| 1680 | 1712 | s_asd->lanes = vep->bus.mipi_csi2.num_data_lanes; |
|---|
| 1681 | 1713 | } else if (vep->bus_type == V4L2_MBUS_CCP2) { |
|---|
| .. | .. |
|---|
| 1721 | 1753 | if (ret < 0) |
|---|
| 1722 | 1754 | return ret; |
|---|
| 1723 | 1755 | |
|---|
| 1756 | + v4l2_async_notifier_init(&priv->notifier); |
|---|
| 1757 | + |
|---|
| 1724 | 1758 | ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port( |
|---|
| 1725 | 1759 | priv->dev, &priv->notifier, |
|---|
| 1726 | 1760 | sizeof(struct sensor_async_subdev), 0, |
|---|
| 1727 | 1761 | rockchip_mipidphy_fwnode_parse); |
|---|
| 1728 | 1762 | if (ret < 0) |
|---|
| 1729 | 1763 | return ret; |
|---|
| 1730 | | - |
|---|
| 1731 | | - if (!priv->notifier.num_subdevs) |
|---|
| 1732 | | - return -ENODEV; /* no endpoint */ |
|---|
| 1733 | 1764 | |
|---|
| 1734 | 1765 | priv->sd.subdev_notifier = &priv->notifier; |
|---|
| 1735 | 1766 | priv->notifier.ops = &rockchip_mipidphy_async_ops; |
|---|