Lines Matching +full:fpd +full:- +full:link
1 // SPDX-License-Identifier: GPL-2.0
11 #include <linux/clk-provider.h>
16 #include <linux/i2c-atr.h>
26 #include <media/v4l2-ctrls.h>
27 #include <media/v4l2-fwnode.h>
28 #include <media/v4l2-mediabus.h>
29 #include <media/v4l2-subdev.h>
123 /* FPD-Link III CSI-2 synchronous mode */
125 /* FPD-Link III CSI-2 non-synchronous mode, external ref clock */
127 /* FPD-Link III CSI-2 non-synchronous mode, internal ref clock */
129 /* FPD-Link III DVP mode */
193 mutex_lock(&priv->reg_lock); in ub953_read()
195 ret = regmap_read(priv->regmap, reg, &v); in ub953_read()
197 dev_err(&priv->client->dev, "Cannot read register 0x%02x: %d\n", in ub953_read()
205 mutex_unlock(&priv->reg_lock); in ub953_read()
214 mutex_lock(&priv->reg_lock); in ub953_write()
216 ret = regmap_write(priv->regmap, reg, val); in ub953_write()
218 dev_err(&priv->client->dev, in ub953_write()
221 mutex_unlock(&priv->reg_lock); in ub953_write()
228 struct device *dev = &priv->client->dev; in ub953_select_ind_reg_block()
231 if (priv->current_indirect_target == block) in ub953_select_ind_reg_block()
234 ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_CTL, block << 2); in ub953_select_ind_reg_block()
241 priv->current_indirect_target = block; in ub953_select_ind_reg_block()
252 mutex_lock(&priv->reg_lock); in ub953_read_ind()
258 ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg); in ub953_read_ind()
260 dev_err(&priv->client->dev, in ub953_read_ind()
266 ret = regmap_read(priv->regmap, UB953_REG_IND_ACC_DATA, &v); in ub953_read_ind()
268 dev_err(&priv->client->dev, in ub953_read_ind()
277 mutex_unlock(&priv->reg_lock); in ub953_read_ind()
287 mutex_lock(&priv->reg_lock); in ub953_write_ind()
293 ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg); in ub953_write_ind()
295 dev_err(&priv->client->dev, in ub953_write_ind()
301 ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_DATA, val); in ub953_write_ind()
303 dev_err(&priv->client->dev, in ub953_write_ind()
309 mutex_unlock(&priv->reg_lock); in ub953_write_ind()
337 return regmap_update_bits(priv->regmap, UB953_REG_GPIO_INPUT_CTRL, in ub953_gpio_direction_in()
349 ret = regmap_update_bits(priv->regmap, UB953_REG_LOCAL_GPIO_DATA, in ub953_gpio_direction_out()
357 return regmap_update_bits(priv->regmap, UB953_REG_GPIO_INPUT_CTRL, in ub953_gpio_direction_out()
380 regmap_update_bits(priv->regmap, UB953_REG_LOCAL_GPIO_DATA, in ub953_gpio_set()
391 *flags = gpiospec->args[1]; in ub953_gpio_of_xlate()
393 return gpiospec->args[0]; in ub953_gpio_of_xlate()
398 struct device *dev = &priv->client->dev; in ub953_gpiochip_probe()
399 struct gpio_chip *gc = &priv->gpio_chip; in ub953_gpiochip_probe()
411 gc->label = dev_name(dev); in ub953_gpiochip_probe()
412 gc->parent = dev; in ub953_gpiochip_probe()
413 gc->owner = THIS_MODULE; in ub953_gpiochip_probe()
414 gc->base = -1; in ub953_gpiochip_probe()
415 gc->can_sleep = true; in ub953_gpiochip_probe()
416 gc->ngpio = UB953_NUM_GPIOS; in ub953_gpiochip_probe()
417 gc->get_direction = ub953_gpio_get_direction; in ub953_gpiochip_probe()
418 gc->direction_input = ub953_gpio_direction_in; in ub953_gpiochip_probe()
419 gc->direction_output = ub953_gpio_direction_out; in ub953_gpiochip_probe()
420 gc->get = ub953_gpio_get; in ub953_gpiochip_probe()
421 gc->set = ub953_gpio_set; in ub953_gpiochip_probe()
422 gc->of_xlate = ub953_gpio_of_xlate; in ub953_gpiochip_probe()
423 gc->of_gpio_n_cells = 2; in ub953_gpiochip_probe()
436 gpiochip_remove(&priv->gpio_chip); in ub953_gpiochip_remove()
464 if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX) in _ub953_set_routing()
465 return -EINVAL; in _ub953_set_routing()
486 if (which == V4L2_SUBDEV_FORMAT_ACTIVE && priv->enabled_source_streams) in ub953_set_routing()
487 return -EBUSY; in ub953_set_routing()
502 return -EINVAL; in ub953_get_frame_desc()
504 ret = v4l2_subdev_call(priv->source_sd, pad, get_frame_desc, in ub953_get_frame_desc()
505 priv->source_sd_pad, &source_fd); in ub953_get_frame_desc()
509 fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2; in ub953_get_frame_desc()
513 for_each_active_route(&state->routing, route) { in ub953_get_frame_desc()
517 if (route->source_pad != pad) in ub953_get_frame_desc()
521 if (source_fd.entry[i].stream == route->sink_stream) { in ub953_get_frame_desc()
528 dev_err(&priv->client->dev, in ub953_get_frame_desc()
530 ret = -EPIPE; in ub953_get_frame_desc()
534 fd->entry[fd->num_entries].stream = route->source_stream; in ub953_get_frame_desc()
535 fd->entry[fd->num_entries].flags = source_entry->flags; in ub953_get_frame_desc()
536 fd->entry[fd->num_entries].length = source_entry->length; in ub953_get_frame_desc()
537 fd->entry[fd->num_entries].pixelcode = source_entry->pixelcode; in ub953_get_frame_desc()
538 fd->entry[fd->num_entries].bus.csi2.vc = in ub953_get_frame_desc()
539 source_entry->bus.csi2.vc; in ub953_get_frame_desc()
540 fd->entry[fd->num_entries].bus.csi2.dt = in ub953_get_frame_desc()
541 source_entry->bus.csi2.dt; in ub953_get_frame_desc()
543 fd->num_entries++; in ub953_get_frame_desc()
559 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE && in ub953_set_fmt()
560 priv->enabled_source_streams) in ub953_set_fmt()
561 return -EBUSY; in ub953_set_fmt()
564 if (format->pad == UB953_PAD_SOURCE) in ub953_set_fmt()
568 fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream); in ub953_set_fmt()
570 return -EINVAL; in ub953_set_fmt()
572 *fmt = format->format; in ub953_set_fmt()
575 fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad, in ub953_set_fmt()
576 format->stream); in ub953_set_fmt()
578 return -EINVAL; in ub953_set_fmt()
580 *fmt = format->format; in ub953_set_fmt()
609 struct device *dev = &priv->client->dev; in ub953_log_status()
631 regmap_update_bits(priv->regmap, UB953_REG_BC_CTRL, in ub953_log_status()
690 ret = v4l2_subdev_enable_streams(priv->source_sd, priv->source_sd_pad, in ub953_enable_streams()
695 priv->enabled_source_streams |= streams_mask; in ub953_enable_streams()
712 ret = v4l2_subdev_disable_streams(priv->source_sd, priv->source_sd_pad, in ub953_disable_streams()
717 priv->enabled_source_streams &= ~streams_mask; in ub953_disable_streams()
752 struct ub953_data *priv = sd_to_ub953(notifier->sd); in ub953_notify_bound()
753 struct device *dev = &priv->client->dev; in ub953_notify_bound()
756 ret = media_entity_get_fwnode_pad(&source_subdev->entity, in ub953_notify_bound()
757 source_subdev->fwnode, in ub953_notify_bound()
761 source_subdev->name); in ub953_notify_bound()
765 priv->source_sd = source_subdev; in ub953_notify_bound()
766 priv->source_sd_pad = ret; in ub953_notify_bound()
768 ret = media_create_pad_link(&source_subdev->entity, priv->source_sd_pad, in ub953_notify_bound()
769 &priv->sd.entity, 0, in ub953_notify_bound()
773 dev_err(dev, "Unable to link %s:%u -> %s:0\n", in ub953_notify_bound()
774 source_subdev->name, priv->source_sd_pad, in ub953_notify_bound()
775 priv->sd.name); in ub953_notify_bound()
788 struct device *dev = &priv->client->dev; in ub953_v4l2_notifier_register()
797 return -ENODEV; in ub953_v4l2_notifier_register()
800 v4l2_async_subdev_nf_init(&priv->notifier, &priv->sd); in ub953_v4l2_notifier_register()
802 asd = v4l2_async_nf_add_fwnode_remote(&priv->notifier, ep_fwnode, in ub953_v4l2_notifier_register()
809 v4l2_async_nf_cleanup(&priv->notifier); in ub953_v4l2_notifier_register()
813 priv->notifier.ops = &ub953_notify_ops; in ub953_v4l2_notifier_register()
815 ret = v4l2_async_nf_register(&priv->notifier); in ub953_v4l2_notifier_register()
818 v4l2_async_nf_cleanup(&priv->notifier); in ub953_v4l2_notifier_register()
827 v4l2_async_nf_unregister(&priv->notifier); in ub953_v4l2_notifier_unregister()
828 v4l2_async_nf_cleanup(&priv->notifier); in ub953_v4l2_notifier_unregister()
843 scl_high = div64_u64((u64)scl_high * ref, 1000000000) - 5; in ub953_i2c_master_init()
844 scl_low = div64_u64((u64)scl_low * ref, 1000000000) - 5; in ub953_i2c_master_init()
859 switch (priv->mode) { in ub953_get_fc_rate()
861 if (priv->hw_data->is_ub971) in ub953_get_fc_rate()
862 return priv->plat_data->bc_rate * 160ull; in ub953_get_fc_rate()
864 return priv->plat_data->bc_rate / 2 * 160ull; in ub953_get_fc_rate()
868 return clk_get_rate(priv->clkin) * 80ull; in ub953_get_fc_rate()
881 * We always use 4 as a pre-divider (HS_CLK_DIV = 2). in ub953_calc_clkout_ub953()
884 * - "HS_CLK_DIV typically should be set to either 16, 8, or 4 (default)." in ub953_calc_clkout_ub953()
885 * - "if it is not possible to have an integer ratio of N/M, it is best to in ub953_calc_clkout_ub953()
901 rational_best_approximation(target, fc_divided, (1 << 5) - 1, in ub953_calc_clkout_ub953()
902 (1 << 8) - 1, &mul, &div); in ub953_calc_clkout_ub953()
925 rational_best_approximation(target, fc_divided, (1 << 5) - 1, in ub953_calc_clkout_ub971()
926 (1 << 8) - 1, &mul, &div); in ub953_calc_clkout_ub971()
940 struct device *dev = &priv->client->dev; in ub953_calc_clkout_params()
946 if (priv->hw_data->is_ub971) { in ub953_calc_clkout_params()
952 clkout_data->m = m; in ub953_calc_clkout_params()
953 clkout_data->n = n; in ub953_calc_clkout_params()
963 clkout_data->hs_div = hs_div; in ub953_calc_clkout_params()
964 clkout_data->m = m; in ub953_calc_clkout_params()
965 clkout_data->n = n; in ub953_calc_clkout_params()
972 clkout_data->rate = clkout_rate; in ub953_calc_clkout_params()
981 if (priv->hw_data->is_ub971) in ub953_write_clkout_regs()
982 clkout_ctrl0 = clkout_data->m; in ub953_write_clkout_regs()
984 clkout_ctrl0 = (__ffs(clkout_data->hs_div) << 5) | in ub953_write_clkout_regs()
985 clkout_data->m; in ub953_write_clkout_regs()
987 clkout_ctrl1 = clkout_data->n; in ub953_write_clkout_regs()
1004 struct device *dev = &priv->client->dev; in ub953_clkout_recalc_rate()
1026 if (priv->hw_data->is_ub971) { in ub953_clkout_recalc_rate()
1074 dev_dbg(&priv->client->dev, "%s %lu (requested %lu)\n", __func__, in ub953_clkout_set_rate()
1088 struct device *dev = &priv->client->dev; in ub953_register_clkout()
1091 priv->hw_data->model, dev_name(dev)), in ub953_register_clkout()
1098 return -ENOMEM; in ub953_register_clkout()
1106 priv->clkout_clk_hw.init = &init; in ub953_register_clkout()
1108 ret = devm_clk_hw_register(dev, &priv->clkout_clk_hw); in ub953_register_clkout()
1114 &priv->clkout_clk_hw); in ub953_register_clkout()
1124 struct device *dev = &priv->client->dev; in ub953_add_i2c_adapter()
1132 ret = i2c_atr_add_adapter(priv->plat_data->atr, priv->plat_data->port, in ub953_add_i2c_adapter()
1153 struct device *dev = &priv->client->dev; in ub953_parse_dt()
1164 return dev_err_probe(dev, -ENOENT, "no endpoint found\n"); in ub953_parse_dt()
1176 return dev_err_probe(dev, -EINVAL, in ub953_parse_dt()
1177 "bad number of data-lanes: %u\n", nlanes); in ub953_parse_dt()
1179 priv->num_data_lanes = nlanes; in ub953_parse_dt()
1181 priv->non_continous_clk = vep.bus.mipi_csi2.flags & in ub953_parse_dt()
1189 struct device *dev = &priv->client->dev; in ub953_hw_init()
1199 return dev_err_probe(dev, -EIO, "Mode value not stabilized\n"); in ub953_hw_init()
1205 priv->mode = UB953_MODE_SYNC; in ub953_hw_init()
1208 priv->mode = UB953_MODE_NONSYNC_EXT; in ub953_hw_init()
1211 priv->mode = UB953_MODE_NONSYNC_INT; in ub953_hw_init()
1214 priv->mode = UB953_MODE_DVP; in ub953_hw_init()
1217 return dev_err_probe(dev, -EIO, in ub953_hw_init()
1222 priv->mode); in ub953_hw_init()
1224 if (priv->mode != UB953_MODE_SYNC && in ub953_hw_init()
1225 priv->mode != UB953_MODE_NONSYNC_EXT) in ub953_hw_init()
1226 return dev_err_probe(dev, -ENODEV, in ub953_hw_init()
1228 priv->mode); in ub953_hw_init()
1230 if (priv->mode == UB953_MODE_NONSYNC_EXT && !priv->clkin) in ub953_hw_init()
1231 return dev_err_probe(dev, -EINVAL, in ub953_hw_init()
1232 "clkin required for non-sync ext mode\n"); in ub953_hw_init()
1238 dev_info(dev, "Found %s rev/mask %#04x\n", priv->hw_data->model, v); in ub953_hw_init()
1252 v |= priv->non_continous_clk ? 0 : UB953_REG_GENERAL_CFG_CONT_CLK; in ub953_hw_init()
1253 v |= (priv->num_data_lanes - 1) << in ub953_hw_init()
1266 struct device *dev = &priv->client->dev; in ub953_subdev_init()
1269 v4l2_i2c_subdev_init(&priv->sd, priv->client, &ub953_subdev_ops); in ub953_subdev_init()
1270 priv->sd.internal_ops = &ub953_internal_ops; in ub953_subdev_init()
1272 priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | in ub953_subdev_init()
1274 priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in ub953_subdev_init()
1275 priv->sd.entity.ops = &ub953_entity_ops; in ub953_subdev_init()
1277 priv->pads[0].flags = MEDIA_PAD_FL_SINK; in ub953_subdev_init()
1278 priv->pads[1].flags = MEDIA_PAD_FL_SOURCE; in ub953_subdev_init()
1280 ret = media_entity_pads_init(&priv->sd.entity, 2, priv->pads); in ub953_subdev_init()
1284 ret = v4l2_subdev_init_finalize(&priv->sd); in ub953_subdev_init()
1295 ret = v4l2_async_register_subdev(&priv->sd); in ub953_subdev_init()
1306 v4l2_subdev_cleanup(&priv->sd); in ub953_subdev_init()
1308 media_entity_cleanup(&priv->sd.entity); in ub953_subdev_init()
1315 v4l2_async_unregister_subdev(&priv->sd); in ub953_subdev_uninit()
1317 v4l2_subdev_cleanup(&priv->sd); in ub953_subdev_uninit()
1318 media_entity_cleanup(&priv->sd.entity); in ub953_subdev_uninit()
1323 struct device *dev = &client->dev; in ub953_probe()
1329 return -ENOMEM; in ub953_probe()
1331 priv->client = client; in ub953_probe()
1333 priv->hw_data = device_get_match_data(dev); in ub953_probe()
1335 priv->plat_data = dev_get_platdata(&client->dev); in ub953_probe()
1336 if (!priv->plat_data) in ub953_probe()
1337 return dev_err_probe(dev, -ENODEV, "Platform data missing\n"); in ub953_probe()
1339 mutex_init(&priv->reg_lock); in ub953_probe()
1345 priv->current_indirect_target = 0xff; in ub953_probe()
1347 priv->regmap = devm_regmap_init_i2c(client, &ub953_regmap_config); in ub953_probe()
1348 if (IS_ERR(priv->regmap)) { in ub953_probe()
1349 ret = PTR_ERR(priv->regmap); in ub953_probe()
1354 priv->clkin = devm_clk_get_optional(dev, "clkin"); in ub953_probe()
1355 if (IS_ERR(priv->clkin)) { in ub953_probe()
1356 ret = PTR_ERR(priv->clkin); in ub953_probe()
1398 mutex_destroy(&priv->reg_lock); in ub953_probe()
1408 i2c_atr_del_adapter(priv->plat_data->atr, priv->plat_data->port); in ub953_remove()
1413 mutex_destroy(&priv->reg_lock); in ub953_remove()
1426 { "ds90ub953-q1", (kernel_ulong_t)&ds90ub953_hw },
1427 { "ds90ub971-q1", (kernel_ulong_t)&ds90ub971_hw },
1433 { .compatible = "ti,ds90ub953-q1", .data = &ds90ub953_hw },
1434 { .compatible = "ti,ds90ub971-q1", .data = &ds90ub971_hw },
1451 MODULE_DESCRIPTION("Texas Instruments FPD-Link III/IV CSI-2 Serializers Driver");