Lines Matching +full:tx +full:- +full:enable
1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for Analog Devices ADV748X CSI-2 Transmitter
11 #include <media/v4l2-ctrls.h>
12 #include <media/v4l2-device.h>
13 #include <media/v4l2-ioctl.h>
17 static int adv748x_csi2_set_virtual_channel(struct adv748x_csi2 *tx, in adv748x_csi2_set_virtual_channel() argument
20 return tx_write(tx, ADV748X_CSI_VC_REF, vc << ADV748X_CSI_VC_REF_SHIFT); in adv748x_csi2_set_virtual_channel()
26 * @tx: CSI2 private entity
29 * @src_pad: Pad number of source to link to this @tx
30 * @enable: Link enabled flag
35 static int adv748x_csi2_register_link(struct adv748x_csi2 *tx, in adv748x_csi2_register_link() argument
39 bool enable) in adv748x_csi2_register_link() argument
43 if (!src->v4l2_dev) { in adv748x_csi2_register_link()
49 ret = media_create_pad_link(&src->entity, src_pad, in adv748x_csi2_register_link()
50 &tx->sd.entity, ADV748X_CSI2_SINK, in adv748x_csi2_register_link()
51 enable ? MEDIA_LNK_FL_ENABLED : 0); in adv748x_csi2_register_link()
55 if (enable) in adv748x_csi2_register_link()
56 tx->src = src; in adv748x_csi2_register_link()
61 /* -----------------------------------------------------------------------------
71 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); in adv748x_csi2_registered() local
72 struct adv748x_state *state = tx->state; in adv748x_csi2_registered()
75 adv_dbg(state, "Registered %s (%s)", is_txa(tx) ? "TXA":"TXB", in adv748x_csi2_registered()
76 sd->name); in adv748x_csi2_registered()
82 * The HDMI->TXA link is enabled by default, as is the AFE->TXB one. in adv748x_csi2_registered()
85 ret = adv748x_csi2_register_link(tx, sd->v4l2_dev, in adv748x_csi2_registered()
86 &state->afe.sd, in adv748x_csi2_registered()
88 is_txb(tx)); in adv748x_csi2_registered()
93 if (is_txb(tx)) in adv748x_csi2_registered()
94 state->afe.tx = tx; in adv748x_csi2_registered()
98 if (is_txb(tx) || !is_hdmi_enabled(state)) in adv748x_csi2_registered()
101 ret = adv748x_csi2_register_link(tx, sd->v4l2_dev, &state->hdmi.sd, in adv748x_csi2_registered()
107 state->hdmi.tx = tx; in adv748x_csi2_registered()
116 /* -----------------------------------------------------------------------------
120 static int adv748x_csi2_s_stream(struct v4l2_subdev *sd, int enable) in adv748x_csi2_s_stream() argument
122 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); in adv748x_csi2_s_stream() local
125 src = adv748x_get_remote_sd(&tx->pads[ADV748X_CSI2_SINK]); in adv748x_csi2_s_stream()
127 return -EPIPE; in adv748x_csi2_s_stream()
129 return v4l2_subdev_call(src, video, s_stream, enable); in adv748x_csi2_s_stream()
136 /* -----------------------------------------------------------------------------
148 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); in adv748x_csi2_get_pad_format() local
153 return &tx->format; in adv748x_csi2_get_pad_format()
160 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); in adv748x_csi2_get_format() local
161 struct adv748x_state *state = tx->state; in adv748x_csi2_get_format()
164 mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad, in adv748x_csi2_get_format()
165 sdformat->which); in adv748x_csi2_get_format()
167 return -EINVAL; in adv748x_csi2_get_format()
169 mutex_lock(&state->mutex); in adv748x_csi2_get_format()
171 sdformat->format = *mbusformat; in adv748x_csi2_get_format()
173 mutex_unlock(&state->mutex); in adv748x_csi2_get_format()
182 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); in adv748x_csi2_set_format() local
183 struct adv748x_state *state = tx->state; in adv748x_csi2_set_format()
187 mbusformat = adv748x_csi2_get_pad_format(sd, cfg, sdformat->pad, in adv748x_csi2_set_format()
188 sdformat->which); in adv748x_csi2_set_format()
190 return -EINVAL; in adv748x_csi2_set_format()
192 mutex_lock(&state->mutex); in adv748x_csi2_set_format()
194 if (sdformat->pad == ADV748X_CSI2_SOURCE) { in adv748x_csi2_set_format()
199 sdformat->which); in adv748x_csi2_set_format()
202 ret = -EINVAL; in adv748x_csi2_set_format()
206 sdformat->format = *sink_fmt; in adv748x_csi2_set_format()
209 *mbusformat = sdformat->format; in adv748x_csi2_set_format()
212 mutex_unlock(&state->mutex); in adv748x_csi2_set_format()
220 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); in adv748x_csi2_get_mbus_config() local
223 return -EINVAL; in adv748x_csi2_get_mbus_config()
225 config->type = V4L2_MBUS_CSI2_DPHY; in adv748x_csi2_get_mbus_config()
226 switch (tx->active_lanes) { in adv748x_csi2_get_mbus_config()
228 config->flags = V4L2_MBUS_CSI2_1_LANE; in adv748x_csi2_get_mbus_config()
232 config->flags = V4L2_MBUS_CSI2_2_LANE; in adv748x_csi2_get_mbus_config()
236 config->flags = V4L2_MBUS_CSI2_3_LANE; in adv748x_csi2_get_mbus_config()
240 config->flags = V4L2_MBUS_CSI2_4_LANE; in adv748x_csi2_get_mbus_config()
253 /* -----------------------------------------------------------------------------
262 /* -----------------------------------------------------------------------------
268 struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd); in adv748x_csi2_set_pixelrate() local
270 if (!tx->pixel_rate) in adv748x_csi2_set_pixelrate()
271 return -EINVAL; in adv748x_csi2_set_pixelrate()
273 return v4l2_ctrl_s_ctrl_int64(tx->pixel_rate, rate); in adv748x_csi2_set_pixelrate()
278 switch (ctrl->id) { in adv748x_csi2_s_ctrl()
282 return -EINVAL; in adv748x_csi2_s_ctrl()
290 static int adv748x_csi2_init_controls(struct adv748x_csi2 *tx) in adv748x_csi2_init_controls() argument
293 v4l2_ctrl_handler_init(&tx->ctrl_hdl, 1); in adv748x_csi2_init_controls()
295 tx->pixel_rate = v4l2_ctrl_new_std(&tx->ctrl_hdl, in adv748x_csi2_init_controls()
300 tx->sd.ctrl_handler = &tx->ctrl_hdl; in adv748x_csi2_init_controls()
301 if (tx->ctrl_hdl.error) { in adv748x_csi2_init_controls()
302 v4l2_ctrl_handler_free(&tx->ctrl_hdl); in adv748x_csi2_init_controls()
303 return tx->ctrl_hdl.error; in adv748x_csi2_init_controls()
306 return v4l2_ctrl_handler_setup(&tx->ctrl_hdl); in adv748x_csi2_init_controls()
309 int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) in adv748x_csi2_init() argument
313 if (!is_tx_enabled(tx)) in adv748x_csi2_init()
317 adv748x_csi2_set_virtual_channel(tx, 0); in adv748x_csi2_init()
319 adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops, in adv748x_csi2_init()
321 is_txa(tx) ? "txa" : "txb"); in adv748x_csi2_init()
324 tx->sd.fwnode = of_fwnode_handle(state->endpoints[tx->port]); in adv748x_csi2_init()
327 tx->sd.internal_ops = &adv748x_csi2_internal_ops; in adv748x_csi2_init()
329 tx->pads[ADV748X_CSI2_SINK].flags = MEDIA_PAD_FL_SINK; in adv748x_csi2_init()
330 tx->pads[ADV748X_CSI2_SOURCE].flags = MEDIA_PAD_FL_SOURCE; in adv748x_csi2_init()
332 ret = media_entity_pads_init(&tx->sd.entity, ADV748X_CSI2_NR_PADS, in adv748x_csi2_init()
333 tx->pads); in adv748x_csi2_init()
337 ret = adv748x_csi2_init_controls(tx); in adv748x_csi2_init()
341 ret = v4l2_async_register_subdev(&tx->sd); in adv748x_csi2_init()
348 v4l2_ctrl_handler_free(&tx->ctrl_hdl); in adv748x_csi2_init()
350 media_entity_cleanup(&tx->sd.entity); in adv748x_csi2_init()
355 void adv748x_csi2_cleanup(struct adv748x_csi2 *tx) in adv748x_csi2_cleanup() argument
357 if (!is_tx_enabled(tx)) in adv748x_csi2_cleanup()
360 v4l2_async_unregister_subdev(&tx->sd); in adv748x_csi2_cleanup()
361 media_entity_cleanup(&tx->sd.entity); in adv748x_csi2_cleanup()
362 v4l2_ctrl_handler_free(&tx->ctrl_hdl); in adv748x_csi2_cleanup()