Lines Matching +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0-only
3 * TI Camera Access Layer (CAL) - CAMERARX
5 * Copyright (c) 2015-2020 Texas Instruments Inc.
21 #include <media/v4l2-ctrls.h>
22 #include <media/v4l2-fwnode.h>
23 #include <media/v4l2-subdev.h>
28 /* ------------------------------------------------------------------
30 * ------------------------------------------------------------------
33 static inline u32 camerarx_read(struct cal_camerarx *phy, u32 offset) in camerarx_read() argument
35 return ioread32(phy->base + offset); in camerarx_read()
38 static inline void camerarx_write(struct cal_camerarx *phy, u32 offset, u32 val) in camerarx_write() argument
40 iowrite32(val, phy->base + offset); in camerarx_write()
43 /* ------------------------------------------------------------------
45 * ------------------------------------------------------------------
48 static s64 cal_camerarx_get_ext_link_freq(struct cal_camerarx *phy) in cal_camerarx_get_ext_link_freq() argument
50 struct v4l2_mbus_config_mipi_csi2 *mipi_csi2 = &phy->endpoint.bus.mipi_csi2; in cal_camerarx_get_ext_link_freq()
51 u32 num_lanes = mipi_csi2->num_data_lanes; in cal_camerarx_get_ext_link_freq()
56 fmtinfo = cal_format_by_code(phy->formats[CAL_CAMERARX_PAD_SINK].code); in cal_camerarx_get_ext_link_freq()
58 return -EINVAL; in cal_camerarx_get_ext_link_freq()
60 bpp = fmtinfo->bpp; in cal_camerarx_get_ext_link_freq()
62 freq = v4l2_get_link_freq(phy->source->ctrl_handler, bpp, 2 * num_lanes); in cal_camerarx_get_ext_link_freq()
64 phy_err(phy, "failed to get link freq for subdev '%s'\n", in cal_camerarx_get_ext_link_freq()
65 phy->source->name); in cal_camerarx_get_ext_link_freq()
69 phy_dbg(3, phy, "Source Link Freq: %llu\n", freq); in cal_camerarx_get_ext_link_freq()
74 static void cal_camerarx_lane_config(struct cal_camerarx *phy) in cal_camerarx_lane_config() argument
76 u32 val = cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance)); in cal_camerarx_lane_config()
80 &phy->endpoint.bus.mipi_csi2; in cal_camerarx_lane_config()
83 cal_set_field(&val, mipi_csi2->clock_lane + 1, lane_mask); in cal_camerarx_lane_config()
84 cal_set_field(&val, mipi_csi2->lane_polarities[0], polarity_mask); in cal_camerarx_lane_config()
85 for (lane = 0; lane < mipi_csi2->num_data_lanes; lane++) { in cal_camerarx_lane_config()
92 cal_set_field(&val, mipi_csi2->data_lanes[lane] + 1, lane_mask); in cal_camerarx_lane_config()
93 cal_set_field(&val, mipi_csi2->lane_polarities[lane + 1], in cal_camerarx_lane_config()
97 cal_write(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance), val); in cal_camerarx_lane_config()
98 phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x\n", in cal_camerarx_lane_config()
99 phy->instance, val); in cal_camerarx_lane_config()
102 static void cal_camerarx_enable(struct cal_camerarx *phy) in cal_camerarx_enable() argument
104 u32 num_lanes = phy->cal->data->camerarx[phy->instance].num_lanes; in cal_camerarx_enable()
106 regmap_field_write(phy->fields[F_CAMMODE], 0); in cal_camerarx_enable()
107 /* Always enable all lanes at the phy control level */ in cal_camerarx_enable()
108 regmap_field_write(phy->fields[F_LANEENABLE], (1 << num_lanes) - 1); in cal_camerarx_enable()
110 if (phy->fields[F_CSI_MODE]) in cal_camerarx_enable()
111 regmap_field_write(phy->fields[F_CSI_MODE], 1); in cal_camerarx_enable()
112 regmap_field_write(phy->fields[F_CTRLCLKEN], 1); in cal_camerarx_enable()
115 void cal_camerarx_disable(struct cal_camerarx *phy) in cal_camerarx_disable() argument
117 regmap_field_write(phy->fields[F_CTRLCLKEN], 0); in cal_camerarx_disable()
127 static void cal_camerarx_config(struct cal_camerarx *phy, s64 link_freq) in cal_camerarx_config() argument
136 phy_dbg(1, phy, "ths_term: %d (0x%02x)\n", ths_term, ths_term); in cal_camerarx_config()
140 phy_dbg(1, phy, "ths_settle: %d (0x%02x)\n", ths_settle, ths_settle); in cal_camerarx_config()
142 reg0 = camerarx_read(phy, CAL_CSI2_PHY_REG0); in cal_camerarx_config()
148 phy_dbg(1, phy, "CSI2_%d_REG0 = 0x%08x\n", phy->instance, reg0); in cal_camerarx_config()
149 camerarx_write(phy, CAL_CSI2_PHY_REG0, reg0); in cal_camerarx_config()
151 reg1 = camerarx_read(phy, CAL_CSI2_PHY_REG1); in cal_camerarx_config()
158 phy_dbg(1, phy, "CSI2_%d_REG1 = 0x%08x\n", phy->instance, reg1); in cal_camerarx_config()
159 camerarx_write(phy, CAL_CSI2_PHY_REG1, reg1); in cal_camerarx_config()
162 static void cal_camerarx_power(struct cal_camerarx *phy, bool enable) in cal_camerarx_power() argument
170 cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance), in cal_camerarx_power()
176 current_state = cal_read_field(phy->cal, in cal_camerarx_power()
177 CAL_CSI2_COMPLEXIO_CFG(phy->instance), in cal_camerarx_power()
187 phy_err(phy, "Failed to power %s complexio\n", in cal_camerarx_power()
191 static void cal_camerarx_wait_reset(struct cal_camerarx *phy) in cal_camerarx_wait_reset() argument
197 if (cal_read_field(phy->cal, in cal_camerarx_wait_reset()
198 CAL_CSI2_COMPLEXIO_CFG(phy->instance), in cal_camerarx_wait_reset()
205 if (cal_read_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance), in cal_camerarx_wait_reset()
208 phy_err(phy, "Timeout waiting for Complex IO reset done\n"); in cal_camerarx_wait_reset()
211 static void cal_camerarx_wait_stop_state(struct cal_camerarx *phy) in cal_camerarx_wait_stop_state() argument
217 if (cal_read_field(phy->cal, in cal_camerarx_wait_stop_state()
218 CAL_CSI2_TIMING(phy->instance), in cal_camerarx_wait_stop_state()
224 if (cal_read_field(phy->cal, CAL_CSI2_TIMING(phy->instance), in cal_camerarx_wait_stop_state()
226 phy_err(phy, "Timeout waiting for stop state\n"); in cal_camerarx_wait_stop_state()
229 static void cal_camerarx_enable_irqs(struct cal_camerarx *phy) in cal_camerarx_enable_irqs() argument
247 cal_write(phy->cal, CAL_HL_IRQENABLE_SET(0), in cal_camerarx_enable_irqs()
248 CAL_HL_IRQ_CIO_MASK(phy->instance) | in cal_camerarx_enable_irqs()
249 CAL_HL_IRQ_VC_MASK(phy->instance)); in cal_camerarx_enable_irqs()
250 cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance), in cal_camerarx_enable_irqs()
252 cal_write(phy->cal, CAL_CSI2_VC_IRQENABLE(phy->instance), in cal_camerarx_enable_irqs()
256 static void cal_camerarx_disable_irqs(struct cal_camerarx *phy) in cal_camerarx_disable_irqs() argument
259 cal_write(phy->cal, CAL_HL_IRQENABLE_CLR(0), in cal_camerarx_disable_irqs()
260 CAL_HL_IRQ_CIO_MASK(phy->instance) | in cal_camerarx_disable_irqs()
261 CAL_HL_IRQ_VC_MASK(phy->instance)); in cal_camerarx_disable_irqs()
262 cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance), 0); in cal_camerarx_disable_irqs()
263 cal_write(phy->cal, CAL_CSI2_VC_IRQENABLE(phy->instance), 0); in cal_camerarx_disable_irqs()
266 static void cal_camerarx_ppi_enable(struct cal_camerarx *phy) in cal_camerarx_ppi_enable() argument
268 cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance), in cal_camerarx_ppi_enable()
271 cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance), in cal_camerarx_ppi_enable()
275 static void cal_camerarx_ppi_disable(struct cal_camerarx *phy) in cal_camerarx_ppi_disable() argument
277 cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance), in cal_camerarx_ppi_disable()
281 static int cal_camerarx_start(struct cal_camerarx *phy) in cal_camerarx_start() argument
288 if (phy->enable_count > 0) { in cal_camerarx_start()
289 phy->enable_count++; in cal_camerarx_start()
293 link_freq = cal_camerarx_get_ext_link_freq(phy); in cal_camerarx_start()
297 ret = v4l2_subdev_call(phy->source, core, s_power, 1); in cal_camerarx_start()
298 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) { in cal_camerarx_start()
299 phy_err(phy, "power on failed in subdev\n"); in cal_camerarx_start()
303 cal_camerarx_enable_irqs(phy); in cal_camerarx_start()
306 * CSI-2 PHY Link Initialization Sequence, according to the DRA74xP / in cal_camerarx_start()
312 * 1. Configure all CSI-2 low level protocol registers to be ready to in cal_camerarx_start()
313 * receive signals/data from the CSI-2 PHY. in cal_camerarx_start()
315 * i.-v. Configure the lanes position and polarity. in cal_camerarx_start()
317 cal_camerarx_lane_config(phy); in cal_camerarx_start()
320 * vi.-vii. Configure D-PHY mode, enable the required lanes and in cal_camerarx_start()
323 cal_camerarx_enable(phy); in cal_camerarx_start()
326 * 2. CSI PHY and link initialization sequence. in cal_camerarx_start()
328 * a. Deassert the CSI-2 PHY reset. Do not wait for reset completion in cal_camerarx_start()
330 * CSI-2 HS clock. in cal_camerarx_start()
332 cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance), in cal_camerarx_start()
335 phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x De-assert Complex IO Reset\n", in cal_camerarx_start()
336 phy->instance, in cal_camerarx_start()
337 cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance))); in cal_camerarx_start()
340 camerarx_read(phy, CAL_CSI2_PHY_REG0); in cal_camerarx_start()
342 /* Program the PHY timing parameters. */ in cal_camerarx_start()
343 cal_camerarx_config(phy, link_freq); in cal_camerarx_start()
348 * The stop-state-counter is based on fclk cycles, and we always use in cal_camerarx_start()
349 * the x16 and x4 settings, so stop-state-timeout = in cal_camerarx_start()
350 * fclk-cycle * 16 * 4 * counter. in cal_camerarx_start()
352 * Stop-state-timeout must be more than 100us as per CSI-2 spec, so we in cal_camerarx_start()
355 sscounter = DIV_ROUND_UP(clk_get_rate(phy->cal->fclk), 10000 * 16 * 4); in cal_camerarx_start()
357 val = cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance)); in cal_camerarx_start()
362 cal_write(phy->cal, CAL_CSI2_TIMING(phy->instance), val); in cal_camerarx_start()
363 phy_dbg(3, phy, "CAL_CSI2_TIMING(%d) = 0x%08x Stop States\n", in cal_camerarx_start()
364 phy->instance, in cal_camerarx_start()
365 cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance))); in cal_camerarx_start()
368 cal_write_field(phy->cal, CAL_CSI2_TIMING(phy->instance), in cal_camerarx_start()
370 phy_dbg(3, phy, "CAL_CSI2_TIMING(%d) = 0x%08x Force RXMODE\n", in cal_camerarx_start()
371 phy->instance, in cal_camerarx_start()
372 cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance))); in cal_camerarx_start()
375 * c. Connect pull-down on CSI-2 PHY link (using pad control). in cal_camerarx_start()
382 * d. Power up the CSI-2 PHY. in cal_camerarx_start()
385 cal_camerarx_power(phy, true); in cal_camerarx_start()
388 * Start the source to enable the CSI-2 HS clock. We can now wait for in cal_camerarx_start()
389 * CSI-2 PHY reset to complete. in cal_camerarx_start()
391 ret = v4l2_subdev_call(phy->source, video, s_stream, 1); in cal_camerarx_start()
393 v4l2_subdev_call(phy->source, core, s_power, 0); in cal_camerarx_start()
394 cal_camerarx_disable_irqs(phy); in cal_camerarx_start()
395 phy_err(phy, "stream on failed in subdev\n"); in cal_camerarx_start()
399 cal_camerarx_wait_reset(phy); in cal_camerarx_start()
402 cal_camerarx_wait_stop_state(phy); in cal_camerarx_start()
404 phy_dbg(1, phy, "CSI2_%u_REG1 = 0x%08x (bits 31-28 should be set)\n", in cal_camerarx_start()
405 phy->instance, camerarx_read(phy, CAL_CSI2_PHY_REG1)); in cal_camerarx_start()
408 * g. Disable pull-down on CSI-2 PHY link (using pad control). in cal_camerarx_start()
414 /* Finally, enable the PHY Protocol Interface (PPI). */ in cal_camerarx_start()
415 cal_camerarx_ppi_enable(phy); in cal_camerarx_start()
417 phy->enable_count++; in cal_camerarx_start()
422 static void cal_camerarx_stop(struct cal_camerarx *phy) in cal_camerarx_stop() argument
426 if (--phy->enable_count > 0) in cal_camerarx_stop()
429 cal_camerarx_ppi_disable(phy); in cal_camerarx_stop()
431 cal_camerarx_disable_irqs(phy); in cal_camerarx_stop()
433 cal_camerarx_power(phy, false); in cal_camerarx_stop()
436 cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance), in cal_camerarx_stop()
440 phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x Complex IO in Reset\n", in cal_camerarx_stop()
441 phy->instance, in cal_camerarx_stop()
442 cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance))); in cal_camerarx_stop()
444 /* Disable the phy */ in cal_camerarx_stop()
445 cal_camerarx_disable(phy); in cal_camerarx_stop()
447 if (v4l2_subdev_call(phy->source, video, s_stream, 0)) in cal_camerarx_stop()
448 phy_err(phy, "stream off failed in subdev\n"); in cal_camerarx_stop()
450 ret = v4l2_subdev_call(phy->source, core, s_power, 0); in cal_camerarx_stop()
451 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) in cal_camerarx_stop()
452 phy_err(phy, "power off failed in subdev\n"); in cal_camerarx_stop()
459 * LDOs on the device are disabled if CSI-2 module is powered on
464 * Errata does not apply when CSI-2 module is powered off
474 void cal_camerarx_i913_errata(struct cal_camerarx *phy) in cal_camerarx_i913_errata() argument
476 u32 reg10 = camerarx_read(phy, CAL_CSI2_PHY_REG10); in cal_camerarx_i913_errata()
480 phy_dbg(1, phy, "CSI2_%d_REG10 = 0x%08x\n", phy->instance, reg10); in cal_camerarx_i913_errata()
481 camerarx_write(phy, CAL_CSI2_PHY_REG10, reg10); in cal_camerarx_i913_errata()
485 struct cal_camerarx *phy) in cal_camerarx_regmap_init() argument
490 if (!cal->data) in cal_camerarx_regmap_init()
491 return -EINVAL; in cal_camerarx_regmap_init()
493 phy_data = &cal->data->camerarx[phy->instance]; in cal_camerarx_regmap_init()
497 .reg = cal->syscon_camerrx_offset, in cal_camerarx_regmap_init()
498 .lsb = phy_data->fields[i].lsb, in cal_camerarx_regmap_init()
499 .msb = phy_data->fields[i].msb, in cal_camerarx_regmap_init()
506 phy->fields[i] = devm_regmap_field_alloc(cal->dev, in cal_camerarx_regmap_init()
507 cal->syscon_camerrx, in cal_camerarx_regmap_init()
509 if (IS_ERR(phy->fields[i])) { in cal_camerarx_regmap_init()
511 return PTR_ERR(phy->fields[i]); in cal_camerarx_regmap_init()
518 static int cal_camerarx_parse_dt(struct cal_camerarx *phy) in cal_camerarx_parse_dt() argument
520 struct v4l2_fwnode_endpoint *endpoint = &phy->endpoint; in cal_camerarx_parse_dt()
527 * Find the endpoint node for the port corresponding to the PHY in cal_camerarx_parse_dt()
528 * instance, and parse its CSI-2-related properties. in cal_camerarx_parse_dt()
530 ep_node = of_graph_get_endpoint_by_regs(phy->cal->dev->of_node, in cal_camerarx_parse_dt()
531 phy->instance, 0); in cal_camerarx_parse_dt()
534 * The endpoint is not mandatory, not all PHY instances need to in cal_camerarx_parse_dt()
537 phy_dbg(3, phy, "Port has no endpoint\n"); in cal_camerarx_parse_dt()
541 endpoint->bus_type = V4L2_MBUS_CSI2_DPHY; in cal_camerarx_parse_dt()
544 phy_err(phy, "Failed to parse endpoint\n"); in cal_camerarx_parse_dt()
548 for (i = 0; i < endpoint->bus.mipi_csi2.num_data_lanes; i++) { in cal_camerarx_parse_dt()
549 unsigned int lane = endpoint->bus.mipi_csi2.data_lanes[i]; in cal_camerarx_parse_dt()
552 phy_err(phy, "Invalid position %u for data lane %u\n", in cal_camerarx_parse_dt()
554 ret = -EINVAL; in cal_camerarx_parse_dt()
562 data_lanes[i*2-1] = '\0'; in cal_camerarx_parse_dt()
564 phy_dbg(3, phy, in cal_camerarx_parse_dt()
565 "CSI-2 bus: clock lane <%u>, data lanes <%s>, flags 0x%08x\n", in cal_camerarx_parse_dt()
566 endpoint->bus.mipi_csi2.clock_lane, data_lanes, in cal_camerarx_parse_dt()
567 endpoint->bus.mipi_csi2.flags); in cal_camerarx_parse_dt()
570 phy->source_ep_node = of_graph_get_remote_endpoint(ep_node); in cal_camerarx_parse_dt()
571 phy->source_node = of_graph_get_port_parent(phy->source_ep_node); in cal_camerarx_parse_dt()
572 if (!phy->source_node) { in cal_camerarx_parse_dt()
573 phy_dbg(3, phy, "Can't get remote parent\n"); in cal_camerarx_parse_dt()
574 of_node_put(phy->source_ep_node); in cal_camerarx_parse_dt()
575 ret = -EINVAL; in cal_camerarx_parse_dt()
579 phy_dbg(1, phy, "Found connected device %pOFn\n", phy->source_node); in cal_camerarx_parse_dt()
586 int cal_camerarx_get_remote_frame_desc(struct cal_camerarx *phy, in cal_camerarx_get_remote_frame_desc() argument
592 if (!phy->source) in cal_camerarx_get_remote_frame_desc()
593 return -EPIPE; in cal_camerarx_get_remote_frame_desc()
595 pad = media_pad_remote_pad_first(&phy->pads[CAL_CAMERARX_PAD_SINK]); in cal_camerarx_get_remote_frame_desc()
597 return -EPIPE; in cal_camerarx_get_remote_frame_desc()
599 ret = v4l2_subdev_call(phy->source, pad, get_frame_desc, pad->index, in cal_camerarx_get_remote_frame_desc()
604 if (desc->type != V4L2_MBUS_FRAME_DESC_TYPE_CSI2) { in cal_camerarx_get_remote_frame_desc()
605 dev_err(phy->cal->dev, in cal_camerarx_get_remote_frame_desc()
606 "Frame descriptor does not describe CSI-2 link"); in cal_camerarx_get_remote_frame_desc()
607 return -EINVAL; in cal_camerarx_get_remote_frame_desc()
613 /* ------------------------------------------------------------------
615 * ------------------------------------------------------------------
624 cal_camerarx_get_pad_format(struct cal_camerarx *phy, in cal_camerarx_get_pad_format() argument
630 return v4l2_subdev_get_try_format(&phy->subdev, state, pad); in cal_camerarx_get_pad_format()
632 return &phy->formats[pad]; in cal_camerarx_get_pad_format()
640 struct cal_camerarx *phy = to_cal_camerarx(sd); in cal_camerarx_sd_s_stream() local
643 mutex_lock(&phy->mutex); in cal_camerarx_sd_s_stream()
646 ret = cal_camerarx_start(phy); in cal_camerarx_sd_s_stream()
648 cal_camerarx_stop(phy); in cal_camerarx_sd_s_stream()
650 mutex_unlock(&phy->mutex); in cal_camerarx_sd_s_stream()
659 struct cal_camerarx *phy = to_cal_camerarx(sd); in cal_camerarx_sd_enum_mbus_code() local
662 mutex_lock(&phy->mutex); in cal_camerarx_sd_enum_mbus_code()
665 if (cal_rx_pad_is_source(code->pad)) { in cal_camerarx_sd_enum_mbus_code()
668 if (code->index > 0) { in cal_camerarx_sd_enum_mbus_code()
669 ret = -EINVAL; in cal_camerarx_sd_enum_mbus_code()
673 fmt = cal_camerarx_get_pad_format(phy, state, in cal_camerarx_sd_enum_mbus_code()
675 code->which); in cal_camerarx_sd_enum_mbus_code()
676 code->code = fmt->code; in cal_camerarx_sd_enum_mbus_code()
678 if (code->index >= cal_num_formats) { in cal_camerarx_sd_enum_mbus_code()
679 ret = -EINVAL; in cal_camerarx_sd_enum_mbus_code()
683 code->code = cal_formats[code->index].code; in cal_camerarx_sd_enum_mbus_code()
687 mutex_unlock(&phy->mutex); in cal_camerarx_sd_enum_mbus_code()
696 struct cal_camerarx *phy = to_cal_camerarx(sd); in cal_camerarx_sd_enum_frame_size() local
700 if (fse->index > 0) in cal_camerarx_sd_enum_frame_size()
701 return -EINVAL; in cal_camerarx_sd_enum_frame_size()
703 mutex_lock(&phy->mutex); in cal_camerarx_sd_enum_frame_size()
706 if (cal_rx_pad_is_source(fse->pad)) { in cal_camerarx_sd_enum_frame_size()
709 fmt = cal_camerarx_get_pad_format(phy, state, in cal_camerarx_sd_enum_frame_size()
711 fse->which); in cal_camerarx_sd_enum_frame_size()
712 if (fse->code != fmt->code) { in cal_camerarx_sd_enum_frame_size()
713 ret = -EINVAL; in cal_camerarx_sd_enum_frame_size()
717 fse->min_width = fmt->width; in cal_camerarx_sd_enum_frame_size()
718 fse->max_width = fmt->width; in cal_camerarx_sd_enum_frame_size()
719 fse->min_height = fmt->height; in cal_camerarx_sd_enum_frame_size()
720 fse->max_height = fmt->height; in cal_camerarx_sd_enum_frame_size()
722 fmtinfo = cal_format_by_code(fse->code); in cal_camerarx_sd_enum_frame_size()
724 ret = -EINVAL; in cal_camerarx_sd_enum_frame_size()
728 fse->min_width = CAL_MIN_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8); in cal_camerarx_sd_enum_frame_size()
729 fse->max_width = CAL_MAX_WIDTH_BYTES * 8 / ALIGN(fmtinfo->bpp, 8); in cal_camerarx_sd_enum_frame_size()
730 fse->min_height = CAL_MIN_HEIGHT_LINES; in cal_camerarx_sd_enum_frame_size()
731 fse->max_height = CAL_MAX_HEIGHT_LINES; in cal_camerarx_sd_enum_frame_size()
735 mutex_unlock(&phy->mutex); in cal_camerarx_sd_enum_frame_size()
744 struct cal_camerarx *phy = to_cal_camerarx(sd); in cal_camerarx_sd_get_fmt() local
747 mutex_lock(&phy->mutex); in cal_camerarx_sd_get_fmt()
749 fmt = cal_camerarx_get_pad_format(phy, state, format->pad, in cal_camerarx_sd_get_fmt()
750 format->which); in cal_camerarx_sd_get_fmt()
751 format->format = *fmt; in cal_camerarx_sd_get_fmt()
753 mutex_unlock(&phy->mutex); in cal_camerarx_sd_get_fmt()
762 struct cal_camerarx *phy = to_cal_camerarx(sd); in cal_camerarx_sd_set_fmt() local
768 if (cal_rx_pad_is_source(format->pad)) in cal_camerarx_sd_set_fmt()
775 fmtinfo = cal_format_by_code(format->format.code); in cal_camerarx_sd_set_fmt()
779 /* Clamp the size, update the code. The colorspace is accepted as-is. */ in cal_camerarx_sd_set_fmt()
780 bpp = ALIGN(fmtinfo->bpp, 8); in cal_camerarx_sd_set_fmt()
782 format->format.width = clamp_t(unsigned int, format->format.width, in cal_camerarx_sd_set_fmt()
785 format->format.height = clamp_t(unsigned int, format->format.height, in cal_camerarx_sd_set_fmt()
788 format->format.code = fmtinfo->code; in cal_camerarx_sd_set_fmt()
789 format->format.field = V4L2_FIELD_NONE; in cal_camerarx_sd_set_fmt()
793 mutex_lock(&phy->mutex); in cal_camerarx_sd_set_fmt()
795 fmt = cal_camerarx_get_pad_format(phy, state, in cal_camerarx_sd_set_fmt()
797 format->which); in cal_camerarx_sd_set_fmt()
798 *fmt = format->format; in cal_camerarx_sd_set_fmt()
800 fmt = cal_camerarx_get_pad_format(phy, state, in cal_camerarx_sd_set_fmt()
802 format->which); in cal_camerarx_sd_set_fmt()
803 *fmt = format->format; in cal_camerarx_sd_set_fmt()
805 mutex_unlock(&phy->mutex); in cal_camerarx_sd_set_fmt()
853 /* ------------------------------------------------------------------
855 * ------------------------------------------------------------------
861 struct platform_device *pdev = to_platform_device(cal->dev); in cal_camerarx_create()
862 struct cal_camerarx *phy; in cal_camerarx_create() local
867 phy = kzalloc(sizeof(*phy), GFP_KERNEL); in cal_camerarx_create()
868 if (!phy) in cal_camerarx_create()
869 return ERR_PTR(-ENOMEM); in cal_camerarx_create()
871 phy->cal = cal; in cal_camerarx_create()
872 phy->instance = instance; in cal_camerarx_create()
874 spin_lock_init(&phy->vc_lock); in cal_camerarx_create()
875 mutex_init(&phy->mutex); in cal_camerarx_create()
877 phy->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, in cal_camerarx_create()
881 phy->base = devm_ioremap_resource(cal->dev, phy->res); in cal_camerarx_create()
882 if (IS_ERR(phy->base)) { in cal_camerarx_create()
884 ret = PTR_ERR(phy->base); in cal_camerarx_create()
888 cal_dbg(1, cal, "ioresource %s at %pa - %pa\n", in cal_camerarx_create()
889 phy->res->name, &phy->res->start, &phy->res->end); in cal_camerarx_create()
891 ret = cal_camerarx_regmap_init(cal, phy); in cal_camerarx_create()
895 ret = cal_camerarx_parse_dt(phy); in cal_camerarx_create()
900 sd = &phy->subdev; in cal_camerarx_create()
902 sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in cal_camerarx_create()
903 sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE; in cal_camerarx_create()
904 snprintf(sd->name, sizeof(sd->name), "CAMERARX%u", instance); in cal_camerarx_create()
905 sd->dev = cal->dev; in cal_camerarx_create()
907 phy->pads[CAL_CAMERARX_PAD_SINK].flags = MEDIA_PAD_FL_SINK; in cal_camerarx_create()
909 phy->pads[i].flags = MEDIA_PAD_FL_SOURCE; in cal_camerarx_create()
910 sd->entity.ops = &cal_camerarx_media_ops; in cal_camerarx_create()
911 ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(phy->pads), in cal_camerarx_create()
912 phy->pads); in cal_camerarx_create()
920 ret = v4l2_device_register_subdev(&cal->v4l2_dev, sd); in cal_camerarx_create()
924 return phy; in cal_camerarx_create()
927 media_entity_cleanup(&phy->subdev.entity); in cal_camerarx_create()
928 kfree(phy); in cal_camerarx_create()
932 void cal_camerarx_destroy(struct cal_camerarx *phy) in cal_camerarx_destroy() argument
934 if (!phy) in cal_camerarx_destroy()
937 v4l2_device_unregister_subdev(&phy->subdev); in cal_camerarx_destroy()
938 media_entity_cleanup(&phy->subdev.entity); in cal_camerarx_destroy()
939 of_node_put(phy->source_ep_node); in cal_camerarx_destroy()
940 of_node_put(phy->source_node); in cal_camerarx_destroy()
941 mutex_destroy(&phy->mutex); in cal_camerarx_destroy()
942 kfree(phy); in cal_camerarx_destroy()