Lines Matching +full:dphy +full:- +full:cfg
1 // SPDX-License-Identifier: GPL-2.0
3 * Rockchip MIPI CSI2 DPHY driver
19 #include <media/media-entity.h>
20 #include <media/v4l2-ctrls.h>
21 #include <media/v4l2-fwnode.h>
22 #include <media/v4l2-subdev.h>
23 #include <media/v4l2-device.h>
25 #include "phy-rockchip-csi2-dphy-common.h"
26 #include "phy-rockchip-samsung-dcphy.h"
56 struct csi2_dphy *dphy = to_csi2_dphy(sd); in get_remote_sensor() local
58 if (dphy->num_sensors == 0) in get_remote_sensor()
60 local = &sd->entity.pads[CSI2_DPHY_RX_PAD_SINK]; in get_remote_sensor()
63 v4l2_warn(sd, "No link between dphy and sensor\n"); in get_remote_sensor()
67 sensor_me = media_entity_remote_pad(local)->entity; in get_remote_sensor()
71 static struct csi2_sensor *sd_to_sensor(struct csi2_dphy *dphy, in sd_to_sensor() argument
76 for (i = 0; i < dphy->num_sensors; ++i) in sd_to_sensor()
77 if (dphy->sensors[i].sd == sd) in sd_to_sensor()
78 return &dphy->sensors[i]; in sd_to_sensor()
85 struct csi2_dphy *dphy = to_csi2_dphy(sd); in csi2_dphy_get_sensor_data_rate() local
92 return -ENODEV; in csi2_dphy_get_sensor_data_rate()
94 link_freq = v4l2_ctrl_find(sensor_sd->ctrl_handler, V4L2_CID_LINK_FREQ); in csi2_dphy_get_sensor_data_rate()
97 return -EPIPE; in csi2_dphy_get_sensor_data_rate()
101 ret = v4l2_querymenu(sensor_sd->ctrl_handler, &qm); in csi2_dphy_get_sensor_data_rate()
109 return -EINVAL; in csi2_dphy_get_sensor_data_rate()
111 dphy->data_rate_mbps = qm.value * 2; in csi2_dphy_get_sensor_data_rate()
112 do_div(dphy->data_rate_mbps, 1000 * 1000); in csi2_dphy_get_sensor_data_rate()
113 v4l2_info(sd, "dphy%d, data_rate_mbps %lld\n", in csi2_dphy_get_sensor_data_rate()
114 dphy->phy_index, dphy->data_rate_mbps); in csi2_dphy_get_sensor_data_rate()
118 static int rockchip_csi2_dphy_attach_hw(struct csi2_dphy *dphy, int csi_idx, int index) in rockchip_csi2_dphy_attach_hw() argument
122 struct v4l2_subdev *sensor_sd = get_remote_sensor(&dphy->sd); in rockchip_csi2_dphy_attach_hw()
127 sensor = sd_to_sensor(dphy, sensor_sd); in rockchip_csi2_dphy_attach_hw()
128 lanes = sensor->lanes; in rockchip_csi2_dphy_attach_hw()
131 if (dphy->drv_data->chip_id == CHIP_ID_RK3568 || in rockchip_csi2_dphy_attach_hw()
132 dphy->drv_data->chip_id == CHIP_ID_RV1106) { in rockchip_csi2_dphy_attach_hw()
133 dphy_hw = dphy->dphy_hw_group[0]; in rockchip_csi2_dphy_attach_hw()
134 mutex_lock(&dphy_hw->mutex); in rockchip_csi2_dphy_attach_hw()
135 dphy_hw->dphy_dev[dphy_hw->dphy_dev_num] = dphy; in rockchip_csi2_dphy_attach_hw()
136 dphy_hw->dphy_dev_num++; in rockchip_csi2_dphy_attach_hw()
137 switch (dphy->phy_index) { in rockchip_csi2_dphy_attach_hw()
139 dphy->lane_mode = PHY_FULL_MODE; in rockchip_csi2_dphy_attach_hw()
140 dphy_hw->lane_mode = LANE_MODE_FULL; in rockchip_csi2_dphy_attach_hw()
143 dphy->lane_mode = PHY_SPLIT_01; in rockchip_csi2_dphy_attach_hw()
144 dphy_hw->lane_mode = LANE_MODE_SPLIT; in rockchip_csi2_dphy_attach_hw()
147 dphy->lane_mode = PHY_SPLIT_23; in rockchip_csi2_dphy_attach_hw()
148 dphy_hw->lane_mode = LANE_MODE_SPLIT; in rockchip_csi2_dphy_attach_hw()
151 dphy->lane_mode = PHY_FULL_MODE; in rockchip_csi2_dphy_attach_hw()
152 dphy_hw->lane_mode = LANE_MODE_FULL; in rockchip_csi2_dphy_attach_hw()
155 dphy->dphy_hw = dphy_hw; in rockchip_csi2_dphy_attach_hw()
156 dphy->phy_hw[index] = (void *)dphy_hw; in rockchip_csi2_dphy_attach_hw()
157 dphy->csi_info.dphy_vendor[index] = PHY_VENDOR_INNO; in rockchip_csi2_dphy_attach_hw()
158 mutex_unlock(&dphy_hw->mutex); in rockchip_csi2_dphy_attach_hw()
159 } else if (dphy->drv_data->chip_id == CHIP_ID_RK3588) { in rockchip_csi2_dphy_attach_hw()
161 dcphy_hw = dphy->samsung_phy_group[csi_idx]; in rockchip_csi2_dphy_attach_hw()
162 mutex_lock(&dcphy_hw->mutex); in rockchip_csi2_dphy_attach_hw()
163 dcphy_hw->dphy_dev_num++; in rockchip_csi2_dphy_attach_hw()
164 mutex_unlock(&dcphy_hw->mutex); in rockchip_csi2_dphy_attach_hw()
165 dphy->samsung_phy = dcphy_hw; in rockchip_csi2_dphy_attach_hw()
166 dphy->phy_hw[index] = (void *)dcphy_hw; in rockchip_csi2_dphy_attach_hw()
167 dphy->dphy_param = rk3588_dcphy_param; in rockchip_csi2_dphy_attach_hw()
168 dphy->csi_info.dphy_vendor[index] = PHY_VENDOR_SAMSUNG; in rockchip_csi2_dphy_attach_hw()
170 dphy_hw = dphy->dphy_hw_group[(csi_idx - 2) / 2]; in rockchip_csi2_dphy_attach_hw()
171 mutex_lock(&dphy_hw->mutex); in rockchip_csi2_dphy_attach_hw()
174 dphy->lane_mode = PHY_FULL_MODE; in rockchip_csi2_dphy_attach_hw()
175 dphy_hw->lane_mode = LANE_MODE_FULL; in rockchip_csi2_dphy_attach_hw()
177 dphy->phy_index = 0; in rockchip_csi2_dphy_attach_hw()
179 dphy->phy_index = 3; in rockchip_csi2_dphy_attach_hw()
181 dphy->lane_mode = PHY_SPLIT_01; in rockchip_csi2_dphy_attach_hw()
182 dphy_hw->lane_mode = LANE_MODE_SPLIT; in rockchip_csi2_dphy_attach_hw()
184 dphy->phy_index = 1; in rockchip_csi2_dphy_attach_hw()
186 dphy->phy_index = 4; in rockchip_csi2_dphy_attach_hw()
190 dev_info(dphy->dev, "%s csi host%d only support PHY_SPLIT_23\n", in rockchip_csi2_dphy_attach_hw()
192 mutex_unlock(&dphy_hw->mutex); in rockchip_csi2_dphy_attach_hw()
193 return -EINVAL; in rockchip_csi2_dphy_attach_hw()
195 dphy->lane_mode = PHY_SPLIT_23; in rockchip_csi2_dphy_attach_hw()
196 dphy_hw->lane_mode = LANE_MODE_SPLIT; in rockchip_csi2_dphy_attach_hw()
198 dphy->phy_index = 2; in rockchip_csi2_dphy_attach_hw()
200 dphy->phy_index = 5; in rockchip_csi2_dphy_attach_hw()
202 dphy_hw->dphy_dev_num++; in rockchip_csi2_dphy_attach_hw()
203 dphy->dphy_hw = dphy_hw; in rockchip_csi2_dphy_attach_hw()
204 dphy->phy_hw[index] = (void *)dphy_hw; in rockchip_csi2_dphy_attach_hw()
205 dphy->csi_info.dphy_vendor[index] = PHY_VENDOR_INNO; in rockchip_csi2_dphy_attach_hw()
206 mutex_unlock(&dphy_hw->mutex); in rockchip_csi2_dphy_attach_hw()
209 dphy_hw = dphy->dphy_hw_group[csi_idx / 2]; in rockchip_csi2_dphy_attach_hw()
210 mutex_lock(&dphy_hw->mutex); in rockchip_csi2_dphy_attach_hw()
213 dphy->lane_mode = PHY_FULL_MODE; in rockchip_csi2_dphy_attach_hw()
214 dphy_hw->lane_mode = LANE_MODE_FULL; in rockchip_csi2_dphy_attach_hw()
216 dphy->phy_index = 0; in rockchip_csi2_dphy_attach_hw()
218 dphy->phy_index = 3; in rockchip_csi2_dphy_attach_hw()
220 dphy->lane_mode = PHY_SPLIT_01; in rockchip_csi2_dphy_attach_hw()
221 dphy_hw->lane_mode = LANE_MODE_SPLIT; in rockchip_csi2_dphy_attach_hw()
223 dphy->phy_index = 1; in rockchip_csi2_dphy_attach_hw()
225 dphy->phy_index = 4; in rockchip_csi2_dphy_attach_hw()
229 dev_info(dphy->dev, "%s csi host%d only support PHY_SPLIT_23\n", in rockchip_csi2_dphy_attach_hw()
231 mutex_unlock(&dphy_hw->mutex); in rockchip_csi2_dphy_attach_hw()
232 return -EINVAL; in rockchip_csi2_dphy_attach_hw()
234 dphy->lane_mode = PHY_SPLIT_23; in rockchip_csi2_dphy_attach_hw()
235 dphy_hw->lane_mode = LANE_MODE_SPLIT; in rockchip_csi2_dphy_attach_hw()
237 dphy->phy_index = 2; in rockchip_csi2_dphy_attach_hw()
239 dphy->phy_index = 5; in rockchip_csi2_dphy_attach_hw()
241 dev_info(dphy->dev, "%s error csi host%d\n", in rockchip_csi2_dphy_attach_hw()
243 mutex_unlock(&dphy_hw->mutex); in rockchip_csi2_dphy_attach_hw()
244 return -EINVAL; in rockchip_csi2_dphy_attach_hw()
246 dphy_hw->dphy_dev[dphy_hw->dphy_dev_num] = dphy; in rockchip_csi2_dphy_attach_hw()
247 dphy->phy_hw[index] = (void *)dphy_hw; in rockchip_csi2_dphy_attach_hw()
248 dphy->csi_info.dphy_vendor[index] = PHY_VENDOR_INNO; in rockchip_csi2_dphy_attach_hw()
249 mutex_unlock(&dphy_hw->mutex); in rockchip_csi2_dphy_attach_hw()
255 static int rockchip_csi2_dphy_detach_hw(struct csi2_dphy *dphy, int csi_idx, int index) in rockchip_csi2_dphy_detach_hw() argument
262 if (dphy->drv_data->chip_id == CHIP_ID_RK3568 || in rockchip_csi2_dphy_detach_hw()
263 dphy->drv_data->chip_id == CHIP_ID_RV1106) { in rockchip_csi2_dphy_detach_hw()
264 dphy_hw = (struct csi2_dphy_hw *)dphy->phy_hw[index]; in rockchip_csi2_dphy_detach_hw()
266 dev_err(dphy->dev, "%s csi_idx %d detach hw failed\n", in rockchip_csi2_dphy_detach_hw()
268 return -EINVAL; in rockchip_csi2_dphy_detach_hw()
270 mutex_lock(&dphy_hw->mutex); in rockchip_csi2_dphy_detach_hw()
271 for (i = 0; i < dphy_hw->dphy_dev_num; i++) { in rockchip_csi2_dphy_detach_hw()
272 csi2_dphy = dphy_hw->dphy_dev[i]; in rockchip_csi2_dphy_detach_hw()
274 csi2_dphy->phy_index == dphy->phy_index) { in rockchip_csi2_dphy_detach_hw()
275 dphy_hw->dphy_dev[i] = NULL; in rockchip_csi2_dphy_detach_hw()
276 dphy_hw->dphy_dev_num--; in rockchip_csi2_dphy_detach_hw()
280 mutex_unlock(&dphy_hw->mutex); in rockchip_csi2_dphy_detach_hw()
281 } else if (dphy->drv_data->chip_id == CHIP_ID_RK3588) { in rockchip_csi2_dphy_detach_hw()
283 dcphy_hw = (struct samsung_mipi_dcphy *)dphy->phy_hw[index]; in rockchip_csi2_dphy_detach_hw()
285 dev_err(dphy->dev, "%s csi_idx %d detach hw failed\n", in rockchip_csi2_dphy_detach_hw()
287 return -EINVAL; in rockchip_csi2_dphy_detach_hw()
289 mutex_lock(&dcphy_hw->mutex); in rockchip_csi2_dphy_detach_hw()
290 dcphy_hw->dphy_dev_num--; in rockchip_csi2_dphy_detach_hw()
291 mutex_unlock(&dcphy_hw->mutex); in rockchip_csi2_dphy_detach_hw()
293 dphy_hw = (struct csi2_dphy_hw *)dphy->phy_hw[index]; in rockchip_csi2_dphy_detach_hw()
295 dev_err(dphy->dev, "%s csi_idx %d detach hw failed\n", in rockchip_csi2_dphy_detach_hw()
297 return -EINVAL; in rockchip_csi2_dphy_detach_hw()
299 mutex_lock(&dphy_hw->mutex); in rockchip_csi2_dphy_detach_hw()
300 dphy_hw->dphy_dev_num--; in rockchip_csi2_dphy_detach_hw()
301 mutex_unlock(&dphy_hw->mutex); in rockchip_csi2_dphy_detach_hw()
304 dphy_hw = (struct csi2_dphy_hw *)dphy->phy_hw[index]; in rockchip_csi2_dphy_detach_hw()
306 dev_err(dphy->dev, "%s csi_idx %d detach hw failed\n", in rockchip_csi2_dphy_detach_hw()
308 return -EINVAL; in rockchip_csi2_dphy_detach_hw()
310 mutex_lock(&dphy_hw->mutex); in rockchip_csi2_dphy_detach_hw()
311 dphy_hw->dphy_dev_num--; in rockchip_csi2_dphy_detach_hw()
312 mutex_unlock(&dphy_hw->mutex); in rockchip_csi2_dphy_detach_hw()
320 struct csi2_dphy *dphy = to_csi2_dphy(sd); in csi2_dphy_update_sensor_mbus() local
327 return -ENODEV; in csi2_dphy_update_sensor_mbus()
328 sensor = sd_to_sensor(dphy, sensor_sd); in csi2_dphy_update_sensor_mbus()
330 return -ENODEV; in csi2_dphy_update_sensor_mbus()
336 sensor->mbus = mbus; in csi2_dphy_update_sensor_mbus()
339 sensor->lanes = 1; in csi2_dphy_update_sensor_mbus()
342 sensor->lanes = 2; in csi2_dphy_update_sensor_mbus()
345 sensor->lanes = 3; in csi2_dphy_update_sensor_mbus()
348 sensor->lanes = 4; in csi2_dphy_update_sensor_mbus()
351 return -EINVAL; in csi2_dphy_update_sensor_mbus()
359 struct csi2_dphy *dphy = to_csi2_dphy(sd); in csi2_dphy_update_config() local
367 for (i = 0; i < dphy->csi_info.csi_num; i++) { in csi2_dphy_update_config()
368 if (dphy->drv_data->chip_id != CHIP_ID_RK3568 && in csi2_dphy_update_config()
369 dphy->drv_data->chip_id != CHIP_ID_RV1106) { in csi2_dphy_update_config()
370 csi_idx = dphy->csi_info.csi_idx[i]; in csi2_dphy_update_config()
371 rockchip_csi2_dphy_attach_hw(dphy, csi_idx, i); in csi2_dphy_update_config()
373 if (dphy->csi_info.dphy_vendor[i] == PHY_VENDOR_INNO) { in csi2_dphy_update_config()
377 dev_info(dphy->dev, "phy_mode %d,lane %d\n", in csi2_dphy_update_config()
380 if (dphy->phy_index % 3 == 2) { in csi2_dphy_update_config()
381 dev_err(dphy->dev, "%s dphy%d only use for PHY_SPLIT_23\n", in csi2_dphy_update_config()
382 __func__, dphy->phy_index); in csi2_dphy_update_config()
383 return -EINVAL; in csi2_dphy_update_config()
385 dphy->lane_mode = PHY_FULL_MODE; in csi2_dphy_update_config()
386 dphy->dphy_hw->lane_mode = LANE_MODE_FULL; in csi2_dphy_update_config()
388 if (dphy->phy_index % 3 == 2) { in csi2_dphy_update_config()
389 dev_err(dphy->dev, "%s dphy%d only use for PHY_SPLIT_23\n", in csi2_dphy_update_config()
390 __func__, dphy->phy_index); in csi2_dphy_update_config()
391 return -EINVAL; in csi2_dphy_update_config()
393 dphy->lane_mode = PHY_SPLIT_01; in csi2_dphy_update_config()
394 dphy->dphy_hw->lane_mode = LANE_MODE_SPLIT; in csi2_dphy_update_config()
396 if (dphy->phy_index % 3 != 2) { in csi2_dphy_update_config()
397 dev_err(dphy->dev, "%s dphy%d not support PHY_SPLIT_23\n", in csi2_dphy_update_config()
398 __func__, dphy->phy_index); in csi2_dphy_update_config()
399 return -EINVAL; in csi2_dphy_update_config()
401 dphy->lane_mode = PHY_SPLIT_23; in csi2_dphy_update_config()
402 dphy->dphy_hw->lane_mode = LANE_MODE_SPLIT; in csi2_dphy_update_config()
411 dphy->dphy_param = dphy_param; in csi2_dphy_update_config()
417 struct csi2_dphy *dphy = to_csi2_dphy(sd); in csi2_dphy_s_stream_start() local
420 for (i = 0; i < dphy->csi_info.csi_num; i++) { in csi2_dphy_s_stream_start()
421 if (dphy->csi_info.dphy_vendor[i] == PHY_VENDOR_SAMSUNG) { in csi2_dphy_s_stream_start()
422 dphy->samsung_phy = (struct samsung_mipi_dcphy *)dphy->phy_hw[i]; in csi2_dphy_s_stream_start()
423 if (dphy->samsung_phy && dphy->samsung_phy->stream_on) in csi2_dphy_s_stream_start()
424 dphy->samsung_phy->stream_on(dphy, sd); in csi2_dphy_s_stream_start()
426 dphy->dphy_hw = (struct csi2_dphy_hw *)dphy->phy_hw[i]; in csi2_dphy_s_stream_start()
427 if (dphy->dphy_hw && dphy->dphy_hw->stream_on) in csi2_dphy_s_stream_start()
428 dphy->dphy_hw->stream_on(dphy, sd); in csi2_dphy_s_stream_start()
432 dphy->is_streaming = true; in csi2_dphy_s_stream_start()
439 struct csi2_dphy *dphy = to_csi2_dphy(sd); in csi2_dphy_s_stream_stop() local
442 for (i = 0; i < dphy->csi_info.csi_num; i++) { in csi2_dphy_s_stream_stop()
443 if (dphy->csi_info.dphy_vendor[i] == PHY_VENDOR_SAMSUNG) { in csi2_dphy_s_stream_stop()
444 dphy->samsung_phy = (struct samsung_mipi_dcphy *)dphy->phy_hw[i]; in csi2_dphy_s_stream_stop()
445 if (dphy->samsung_phy && dphy->samsung_phy->stream_off) in csi2_dphy_s_stream_stop()
446 dphy->samsung_phy->stream_off(dphy, sd); in csi2_dphy_s_stream_stop()
448 dphy->dphy_hw = (struct csi2_dphy_hw *)dphy->phy_hw[i]; in csi2_dphy_s_stream_stop()
449 if (dphy->dphy_hw && dphy->dphy_hw->stream_off) in csi2_dphy_s_stream_stop()
450 dphy->dphy_hw->stream_off(dphy, sd); in csi2_dphy_s_stream_stop()
452 if (dphy->drv_data->chip_id != CHIP_ID_RK3568 && in csi2_dphy_s_stream_stop()
453 dphy->drv_data->chip_id != CHIP_ID_RV1106) in csi2_dphy_s_stream_stop()
454 rockchip_csi2_dphy_detach_hw(dphy, dphy->csi_info.csi_idx[i], i); in csi2_dphy_s_stream_stop()
457 dphy->is_streaming = false; in csi2_dphy_s_stream_stop()
459 dev_info(dphy->dev, "%s stream stop, dphy%d\n", in csi2_dphy_s_stream_stop()
460 __func__, dphy->phy_index); in csi2_dphy_s_stream_stop()
465 static int csi2_dphy_enable_clk(struct csi2_dphy *dphy) in csi2_dphy_enable_clk() argument
472 for (i = 0; i < dphy->csi_info.csi_num; i++) { in csi2_dphy_enable_clk()
473 if (dphy->csi_info.dphy_vendor[i] == PHY_VENDOR_SAMSUNG) { in csi2_dphy_enable_clk()
474 samsung_phy = (struct samsung_mipi_dcphy *)dphy->phy_hw[i]; in csi2_dphy_enable_clk()
476 clk_prepare_enable(samsung_phy->pclk); in csi2_dphy_enable_clk()
478 hw = (struct csi2_dphy_hw *)dphy->phy_hw[i]; in csi2_dphy_enable_clk()
480 ret = clk_bulk_prepare_enable(hw->num_clks, hw->clks_bulk); in csi2_dphy_enable_clk()
482 dev_err(hw->dev, "failed to enable clks\n"); in csi2_dphy_enable_clk()
491 static void csi2_dphy_disable_clk(struct csi2_dphy *dphy) in csi2_dphy_disable_clk() argument
497 for (i = 0; i < dphy->csi_info.csi_num; i++) { in csi2_dphy_disable_clk()
498 if (dphy->csi_info.dphy_vendor[i] == PHY_VENDOR_SAMSUNG) { in csi2_dphy_disable_clk()
499 samsung_phy = (struct samsung_mipi_dcphy *)dphy->phy_hw[i]; in csi2_dphy_disable_clk()
501 clk_disable_unprepare(samsung_phy->pclk); in csi2_dphy_disable_clk()
503 hw = (struct csi2_dphy_hw *)dphy->phy_hw[i]; in csi2_dphy_disable_clk()
505 clk_bulk_disable_unprepare(hw->num_clks, hw->clks_bulk); in csi2_dphy_disable_clk()
512 struct csi2_dphy *dphy = to_csi2_dphy(sd); in csi2_dphy_s_stream() local
515 mutex_lock(&dphy->mutex); in csi2_dphy_s_stream()
517 if (dphy->is_streaming) { in csi2_dphy_s_stream()
518 mutex_unlock(&dphy->mutex); in csi2_dphy_s_stream()
524 mutex_unlock(&dphy->mutex); in csi2_dphy_s_stream()
531 mutex_unlock(&dphy->mutex); in csi2_dphy_s_stream()
535 ret = csi2_dphy_enable_clk(dphy); in csi2_dphy_s_stream()
537 mutex_unlock(&dphy->mutex); in csi2_dphy_s_stream()
542 if (!dphy->is_streaming) { in csi2_dphy_s_stream()
543 mutex_unlock(&dphy->mutex); in csi2_dphy_s_stream()
547 csi2_dphy_disable_clk(dphy); in csi2_dphy_s_stream()
549 mutex_unlock(&dphy->mutex); in csi2_dphy_s_stream()
551 dev_info(dphy->dev, "%s stream on:%d, dphy%d, ret %d\n", in csi2_dphy_s_stream()
552 __func__, on, dphy->phy_index, ret); in csi2_dphy_s_stream()
565 return -EINVAL; in csi2_dphy_g_frame_interval()
572 struct csi2_dphy *dphy = to_csi2_dphy(sd); in csi2_dphy_g_mbus_config() local
577 return -ENODEV; in csi2_dphy_g_mbus_config()
578 sensor = sd_to_sensor(dphy, sensor_sd); in csi2_dphy_g_mbus_config()
580 return -ENODEV; in csi2_dphy_g_mbus_config()
582 *config = sensor->mbus; in csi2_dphy_g_mbus_config()
589 struct csi2_dphy *dphy = to_csi2_dphy(sd); in csi2_dphy_s_power() local
592 return pm_runtime_get_sync(dphy->dev); in csi2_dphy_s_power()
594 return pm_runtime_put(dphy->dev); in csi2_dphy_s_power()
601 struct csi2_dphy *dphy = to_csi2_dphy(sd); in csi2_dphy_runtime_suspend() local
603 if (dphy->is_streaming) { in csi2_dphy_runtime_suspend()
605 dphy->is_streaming = false; in csi2_dphy_runtime_suspend()
616 /* dphy accepts all fmt/size from sensor */
618 struct v4l2_subdev_pad_config *cfg, in csi2_dphy_get_set_fmt() argument
621 struct csi2_dphy *dphy = to_csi2_dphy(sd); in csi2_dphy_get_set_fmt() local
630 return -ENODEV; in csi2_dphy_get_set_fmt()
631 sensor = sd_to_sensor(dphy, sensor_sd); in csi2_dphy_get_set_fmt()
633 return -ENODEV; in csi2_dphy_get_set_fmt()
635 if (!ret && fmt->pad == 0 && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) in csi2_dphy_get_set_fmt()
636 sensor->format = fmt->format; in csi2_dphy_get_set_fmt()
641 struct v4l2_subdev_pad_config *cfg, in csi2_dphy_get_selection() argument
651 struct csi2_dphy *dphy = to_csi2_dphy(sd); in rkcif_csi2_dphy_ioctl() local
656 if (dphy->drv_data->chip_id != CHIP_ID_RK3568 && in rkcif_csi2_dphy_ioctl()
657 dphy->drv_data->chip_id != CHIP_ID_RV1106) in rkcif_csi2_dphy_ioctl()
658 dphy->csi_info = *((struct rkcif_csi_info *)arg); in rkcif_csi2_dphy_ioctl()
661 ret = -ENOIOCTLCMD; in rkcif_csi2_dphy_ioctl()
679 return -EFAULT; in rkcif_csi2_dphy_compat_ioctl32()
684 ret = -ENOIOCTLCMD; in rkcif_csi2_dphy_compat_ioctl32()
724 struct csi2_dphy *dphy = container_of(notifier, in rockchip_csi2_dphy_notifier_bound() local
732 if (dphy->num_sensors == ARRAY_SIZE(dphy->sensors)) in rockchip_csi2_dphy_notifier_bound()
733 return -EBUSY; in rockchip_csi2_dphy_notifier_bound()
735 sensor = &dphy->sensors[dphy->num_sensors++]; in rockchip_csi2_dphy_notifier_bound()
736 sensor->lanes = s_asd->lanes; in rockchip_csi2_dphy_notifier_bound()
737 sensor->mbus = s_asd->mbus; in rockchip_csi2_dphy_notifier_bound()
738 sensor->sd = sd; in rockchip_csi2_dphy_notifier_bound()
740 dev_info(dphy->dev, "dphy%d matches %s:bus type %d\n", in rockchip_csi2_dphy_notifier_bound()
741 dphy->phy_index, sd->name, s_asd->mbus.type); in rockchip_csi2_dphy_notifier_bound()
743 for (pad = 0; pad < sensor->sd->entity.num_pads; pad++) in rockchip_csi2_dphy_notifier_bound()
744 if (sensor->sd->entity.pads[pad].flags & MEDIA_PAD_FL_SOURCE) in rockchip_csi2_dphy_notifier_bound()
747 if (pad == sensor->sd->entity.num_pads) { in rockchip_csi2_dphy_notifier_bound()
748 dev_err(dphy->dev, in rockchip_csi2_dphy_notifier_bound()
750 sensor->sd->name); in rockchip_csi2_dphy_notifier_bound()
752 return -ENXIO; in rockchip_csi2_dphy_notifier_bound()
756 &sensor->sd->entity, pad, in rockchip_csi2_dphy_notifier_bound()
757 &dphy->sd.entity, CSI2_DPHY_RX_PAD_SINK, in rockchip_csi2_dphy_notifier_bound()
758 dphy->num_sensors != 1 ? 0 : MEDIA_LNK_FL_ENABLED); in rockchip_csi2_dphy_notifier_bound()
760 dev_err(dphy->dev, in rockchip_csi2_dphy_notifier_bound()
762 sensor->sd->name); in rockchip_csi2_dphy_notifier_bound()
775 struct csi2_dphy *dphy = container_of(notifier, in rockchip_csi2_dphy_notifier_unbind() local
778 struct csi2_sensor *sensor = sd_to_sensor(dphy, sd); in rockchip_csi2_dphy_notifier_unbind()
781 sensor->sd = NULL; in rockchip_csi2_dphy_notifier_unbind()
796 struct v4l2_mbus_config *config = &s_asd->mbus; in rockchip_csi2_dphy_fwnode_parse()
798 if (vep->base.port != 0) { in rockchip_csi2_dphy_fwnode_parse()
800 return -EINVAL; in rockchip_csi2_dphy_fwnode_parse()
803 if (vep->bus_type == V4L2_MBUS_CSI2_DPHY || in rockchip_csi2_dphy_fwnode_parse()
804 vep->bus_type == V4L2_MBUS_CSI2_CPHY) { in rockchip_csi2_dphy_fwnode_parse()
805 config->type = vep->bus_type; in rockchip_csi2_dphy_fwnode_parse()
806 config->flags = vep->bus.mipi_csi2.flags; in rockchip_csi2_dphy_fwnode_parse()
807 s_asd->lanes = vep->bus.mipi_csi2.num_data_lanes; in rockchip_csi2_dphy_fwnode_parse()
808 } else if (vep->bus_type == V4L2_MBUS_CCP2) { in rockchip_csi2_dphy_fwnode_parse()
809 config->type = V4L2_MBUS_CCP2; in rockchip_csi2_dphy_fwnode_parse()
810 s_asd->lanes = vep->bus.mipi_csi1.data_lane; in rockchip_csi2_dphy_fwnode_parse()
813 return -EINVAL; in rockchip_csi2_dphy_fwnode_parse()
816 switch (s_asd->lanes) { in rockchip_csi2_dphy_fwnode_parse()
818 config->flags |= V4L2_MBUS_CSI2_1_LANE; in rockchip_csi2_dphy_fwnode_parse()
821 config->flags |= V4L2_MBUS_CSI2_2_LANE; in rockchip_csi2_dphy_fwnode_parse()
824 config->flags |= V4L2_MBUS_CSI2_3_LANE; in rockchip_csi2_dphy_fwnode_parse()
827 config->flags |= V4L2_MBUS_CSI2_4_LANE; in rockchip_csi2_dphy_fwnode_parse()
830 return -EINVAL; in rockchip_csi2_dphy_fwnode_parse()
836 static int rockchip_csi2dphy_media_init(struct csi2_dphy *dphy) in rockchip_csi2dphy_media_init() argument
840 dphy->pads[CSI2_DPHY_RX_PAD_SOURCE].flags = in rockchip_csi2dphy_media_init()
842 dphy->pads[CSI2_DPHY_RX_PAD_SINK].flags = in rockchip_csi2dphy_media_init()
844 dphy->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in rockchip_csi2dphy_media_init()
845 ret = media_entity_pads_init(&dphy->sd.entity, in rockchip_csi2dphy_media_init()
846 CSI2_DPHY_RX_PADS_NUM, dphy->pads); in rockchip_csi2dphy_media_init()
850 v4l2_async_notifier_init(&dphy->notifier); in rockchip_csi2dphy_media_init()
853 dphy->dev, &dphy->notifier, in rockchip_csi2dphy_media_init()
859 dphy->sd.subdev_notifier = &dphy->notifier; in rockchip_csi2dphy_media_init()
860 dphy->notifier.ops = &rockchip_csi2_dphy_async_ops; in rockchip_csi2dphy_media_init()
861 ret = v4l2_async_subdev_notifier_register(&dphy->sd, &dphy->notifier); in rockchip_csi2dphy_media_init()
863 dev_err(dphy->dev, in rockchip_csi2dphy_media_init()
865 v4l2_async_notifier_cleanup(&dphy->notifier); in rockchip_csi2dphy_media_init()
869 return v4l2_async_register_subdev(&dphy->sd); in rockchip_csi2dphy_media_init()
902 .compatible = "rockchip,rk3568-csi2-dphy",
906 .compatible = "rockchip,rk3588-csi2-dphy",
910 .compatible = "rockchip,rv1106-csi2-dphy",
914 .compatible = "rockchip,rk3562-csi2-dphy",
921 static int rockchip_csi2_dphy_get_samsung_phy_hw(struct csi2_dphy *dphy) in rockchip_csi2_dphy_get_samsung_phy_hw() argument
924 struct device *dev = dphy->dev; in rockchip_csi2_dphy_get_samsung_phy_hw()
930 for (i = 0; i < dphy->drv_data->num_samsung_phy; i++) { in rockchip_csi2_dphy_get_samsung_phy_hw()
935 dev_err(dphy->dev, "failed to get mipi dcphy: %d\n", ret); in rockchip_csi2_dphy_get_samsung_phy_hw()
939 dphy->samsung_phy_group[i] = dcphy_hw; in rockchip_csi2_dphy_get_samsung_phy_hw()
944 static int rockchip_csi2_dphy_get_inno_phy_hw(struct csi2_dphy *dphy) in rockchip_csi2_dphy_get_inno_phy_hw() argument
947 struct device *dev = dphy->dev; in rockchip_csi2_dphy_get_inno_phy_hw()
952 for (i = 0; i < dphy->drv_data->num_inno_phy; i++) { in rockchip_csi2_dphy_get_inno_phy_hw()
953 np = of_parse_phandle(dev->of_node, "rockchip,hw", i); in rockchip_csi2_dphy_get_inno_phy_hw()
955 dev_err(dphy->dev, in rockchip_csi2_dphy_get_inno_phy_hw()
956 "failed to get dphy%d hw node\n", dphy->phy_index); in rockchip_csi2_dphy_get_inno_phy_hw()
957 return -ENODEV; in rockchip_csi2_dphy_get_inno_phy_hw()
962 dev_err(dphy->dev, in rockchip_csi2_dphy_get_inno_phy_hw()
963 "failed to get dphy%d hw from node\n", in rockchip_csi2_dphy_get_inno_phy_hw()
964 dphy->phy_index); in rockchip_csi2_dphy_get_inno_phy_hw()
965 return -ENODEV; in rockchip_csi2_dphy_get_inno_phy_hw()
969 dev_err(dphy->dev, in rockchip_csi2_dphy_get_inno_phy_hw()
970 "failed attach dphy%d hw\n", in rockchip_csi2_dphy_get_inno_phy_hw()
971 dphy->phy_index); in rockchip_csi2_dphy_get_inno_phy_hw()
972 return -EINVAL; in rockchip_csi2_dphy_get_inno_phy_hw()
974 dphy->dphy_hw_group[i] = dphy_hw; in rockchip_csi2_dphy_get_inno_phy_hw()
979 static int rockchip_csi2_dphy_get_hw(struct csi2_dphy *dphy) in rockchip_csi2_dphy_get_hw() argument
983 if (dphy->drv_data->chip_id == CHIP_ID_RK3588) { in rockchip_csi2_dphy_get_hw()
984 ret = rockchip_csi2_dphy_get_samsung_phy_hw(dphy); in rockchip_csi2_dphy_get_hw()
987 ret = rockchip_csi2_dphy_get_inno_phy_hw(dphy); in rockchip_csi2_dphy_get_hw()
989 ret = rockchip_csi2_dphy_get_inno_phy_hw(dphy); in rockchip_csi2_dphy_get_hw()
996 struct device *dev = &pdev->dev; in rockchip_csi2_dphy_probe()
1005 return -ENOMEM; in rockchip_csi2_dphy_probe()
1006 csi2dphy->dev = dev; in rockchip_csi2_dphy_probe()
1010 return -EINVAL; in rockchip_csi2_dphy_probe()
1011 drv_data = of_id->data; in rockchip_csi2_dphy_probe()
1012 csi2dphy->drv_data = drv_data; in rockchip_csi2_dphy_probe()
1014 csi2dphy->phy_index = of_alias_get_id(dev->of_node, drv_data->dev_name); in rockchip_csi2_dphy_probe()
1015 if (csi2dphy->phy_index < 0 || csi2dphy->phy_index >= PHY_MAX) in rockchip_csi2_dphy_probe()
1016 csi2dphy->phy_index = 0; in rockchip_csi2_dphy_probe()
1020 return -EINVAL; in rockchip_csi2_dphy_probe()
1021 if (csi2dphy->drv_data->chip_id == CHIP_ID_RK3568 || in rockchip_csi2_dphy_probe()
1022 csi2dphy->drv_data->chip_id == CHIP_ID_RV1106) { in rockchip_csi2_dphy_probe()
1023 csi2dphy->csi_info.csi_num = 1; in rockchip_csi2_dphy_probe()
1024 csi2dphy->csi_info.dphy_vendor[0] = PHY_VENDOR_INNO; in rockchip_csi2_dphy_probe()
1027 csi2dphy->csi_info.csi_num = 0; in rockchip_csi2_dphy_probe()
1029 sd = &csi2dphy->sd; in rockchip_csi2_dphy_probe()
1030 mutex_init(&csi2dphy->mutex); in rockchip_csi2_dphy_probe()
1032 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in rockchip_csi2_dphy_probe()
1033 snprintf(sd->name, sizeof(sd->name), in rockchip_csi2_dphy_probe()
1034 "rockchip-csi2-dphy%d", csi2dphy->phy_index); in rockchip_csi2_dphy_probe()
1035 sd->dev = dev; in rockchip_csi2_dphy_probe()
1037 platform_set_drvdata(pdev, &sd->entity); in rockchip_csi2_dphy_probe()
1043 pm_runtime_enable(&pdev->dev); in rockchip_csi2_dphy_probe()
1045 dev_info(dev, "csi2 dphy%d probe successfully!\n", csi2dphy->phy_index); in rockchip_csi2_dphy_probe()
1050 mutex_destroy(&csi2dphy->mutex); in rockchip_csi2_dphy_probe()
1051 return -EINVAL; in rockchip_csi2_dphy_probe()
1058 struct csi2_dphy *dphy = to_csi2_dphy(sd); in rockchip_csi2_dphy_remove() local
1061 for (i = 0; i < dphy->csi_info.csi_num; i++) in rockchip_csi2_dphy_remove()
1062 rockchip_csi2_dphy_detach_hw(dphy, dphy->csi_info.csi_idx[i], i); in rockchip_csi2_dphy_remove()
1063 media_entity_cleanup(&sd->entity); in rockchip_csi2_dphy_remove()
1065 pm_runtime_disable(&pdev->dev); in rockchip_csi2_dphy_remove()
1066 mutex_destroy(&dphy->mutex); in rockchip_csi2_dphy_remove()
1079 .name = "rockchip-csi2-dphy",
1099 MODULE_DESCRIPTION("Rockchip MIPI CSI2 DPHY driver");