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-event.h>
28 #include <media/v4l2-fwnode.h>
29 #include <media/v4l2-mediabus.h>
30 #include <media/v4l2-subdev.h>
121 /* FPD-Link III CSI-2 synchronous mode */
123 /* FPD-Link III CSI-2 non-synchronous mode, external ref clock */
125 /* FPD-Link III CSI-2 non-synchronous mode, internal ref clock */
127 /* FPD-Link III DVP mode */
191 mutex_lock(&priv->reg_lock); in ub953_read()
193 ret = regmap_read(priv->regmap, reg, &v); in ub953_read()
195 dev_err(&priv->client->dev, "Cannot read register 0x%02x: %d\n", in ub953_read()
203 mutex_unlock(&priv->reg_lock); in ub953_read()
212 mutex_lock(&priv->reg_lock); in ub953_write()
214 ret = regmap_write(priv->regmap, reg, val); in ub953_write()
216 dev_err(&priv->client->dev, in ub953_write()
219 mutex_unlock(&priv->reg_lock); in ub953_write()
226 struct device *dev = &priv->client->dev; in ub953_select_ind_reg_block()
229 if (priv->current_indirect_target == block) in ub953_select_ind_reg_block()
232 ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_CTL, block << 2); in ub953_select_ind_reg_block()
239 priv->current_indirect_target = block; in ub953_select_ind_reg_block()
250 mutex_lock(&priv->reg_lock); in ub953_read_ind()
256 ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg); in ub953_read_ind()
258 dev_err(&priv->client->dev, in ub953_read_ind()
264 ret = regmap_read(priv->regmap, UB953_REG_IND_ACC_DATA, &v); in ub953_read_ind()
266 dev_err(&priv->client->dev, in ub953_read_ind()
275 mutex_unlock(&priv->reg_lock); in ub953_read_ind()
285 mutex_lock(&priv->reg_lock); in ub953_write_ind()
291 ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_ADDR, reg); in ub953_write_ind()
293 dev_err(&priv->client->dev, in ub953_write_ind()
299 ret = regmap_write(priv->regmap, UB953_REG_IND_ACC_DATA, val); in ub953_write_ind()
301 dev_err(&priv->client->dev, in ub953_write_ind()
307 mutex_unlock(&priv->reg_lock); in ub953_write_ind()
335 return regmap_update_bits(priv->regmap, UB953_REG_GPIO_INPUT_CTRL, in ub953_gpio_direction_in()
347 ret = regmap_update_bits(priv->regmap, UB953_REG_LOCAL_GPIO_DATA, in ub953_gpio_direction_out()
355 return regmap_update_bits(priv->regmap, UB953_REG_GPIO_INPUT_CTRL, in ub953_gpio_direction_out()
378 regmap_update_bits(priv->regmap, UB953_REG_LOCAL_GPIO_DATA, in ub953_gpio_set()
389 *flags = gpiospec->args[1]; in ub953_gpio_of_xlate()
391 return gpiospec->args[0]; in ub953_gpio_of_xlate()
396 struct device *dev = &priv->client->dev; in ub953_gpiochip_probe()
397 struct gpio_chip *gc = &priv->gpio_chip; in ub953_gpiochip_probe()
409 gc->label = dev_name(dev); in ub953_gpiochip_probe()
410 gc->parent = dev; in ub953_gpiochip_probe()
411 gc->owner = THIS_MODULE; in ub953_gpiochip_probe()
412 gc->base = -1; in ub953_gpiochip_probe()
413 gc->can_sleep = true; in ub953_gpiochip_probe()
414 gc->ngpio = UB953_NUM_GPIOS; in ub953_gpiochip_probe()
415 gc->get_direction = ub953_gpio_get_direction; in ub953_gpiochip_probe()
416 gc->direction_input = ub953_gpio_direction_in; in ub953_gpiochip_probe()
417 gc->direction_output = ub953_gpio_direction_out; in ub953_gpiochip_probe()
418 gc->get = ub953_gpio_get; in ub953_gpiochip_probe()
419 gc->set = ub953_gpio_set; in ub953_gpiochip_probe()
420 gc->of_xlate = ub953_gpio_of_xlate; in ub953_gpiochip_probe()
421 gc->of_gpio_n_cells = 2; in ub953_gpiochip_probe()
434 gpiochip_remove(&priv->gpio_chip); in ub953_gpiochip_remove()
462 if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX) in _ub953_set_routing()
463 return -EINVAL; in _ub953_set_routing()
484 if (which == V4L2_SUBDEV_FORMAT_ACTIVE && priv->enabled_source_streams) in ub953_set_routing()
485 return -EBUSY; in ub953_set_routing()
500 return -EINVAL; in ub953_get_frame_desc()
502 ret = v4l2_subdev_call(priv->source_sd, pad, get_frame_desc, in ub953_get_frame_desc()
503 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_stream_format(state, format->pad, in ub953_set_fmt()
569 format->stream); in ub953_set_fmt()
571 return -EINVAL; in ub953_set_fmt()
573 *fmt = format->format; in ub953_set_fmt()
576 fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad, in ub953_set_fmt()
577 format->stream); in ub953_set_fmt()
579 return -EINVAL; in ub953_set_fmt()
581 *fmt = format->format; in ub953_set_fmt()
610 struct device *dev = &priv->client->dev; in ub953_log_status()
685 ret = v4l2_subdev_enable_streams(priv->source_sd, priv->source_sd_pad, in ub953_enable_streams()
690 priv->enabled_source_streams |= streams_mask; in ub953_enable_streams()
707 ret = v4l2_subdev_disable_streams(priv->source_sd, priv->source_sd_pad, in ub953_disable_streams()
712 priv->enabled_source_streams &= ~streams_mask; in ub953_disable_streams()
746 struct ub953_data *priv = sd_to_ub953(notifier->sd); in ub953_notify_bound()
747 struct device *dev = &priv->client->dev; in ub953_notify_bound()
750 ret = media_entity_get_fwnode_pad(&source_subdev->entity, in ub953_notify_bound()
751 source_subdev->fwnode, in ub953_notify_bound()
755 source_subdev->name); in ub953_notify_bound()
759 priv->source_sd = source_subdev; in ub953_notify_bound()
760 priv->source_sd_pad = ret; in ub953_notify_bound()
762 ret = media_create_pad_link(&source_subdev->entity, priv->source_sd_pad, in ub953_notify_bound()
763 &priv->sd.entity, 0, in ub953_notify_bound()
767 dev_err(dev, "Unable to link %s:%u -> %s:0\n", in ub953_notify_bound()
768 source_subdev->name, priv->source_sd_pad, in ub953_notify_bound()
769 priv->sd.name); in ub953_notify_bound()
782 struct device *dev = &priv->client->dev; in ub953_v4l2_notifier_register()
791 return -ENODEV; in ub953_v4l2_notifier_register()
794 v4l2_async_subdev_nf_init(&priv->notifier, &priv->sd); in ub953_v4l2_notifier_register()
796 asd = v4l2_async_nf_add_fwnode_remote(&priv->notifier, ep_fwnode, in ub953_v4l2_notifier_register()
803 v4l2_async_nf_cleanup(&priv->notifier); in ub953_v4l2_notifier_register()
807 priv->notifier.ops = &ub953_notify_ops; in ub953_v4l2_notifier_register()
809 ret = v4l2_async_nf_register(&priv->notifier); in ub953_v4l2_notifier_register()
812 v4l2_async_nf_cleanup(&priv->notifier); in ub953_v4l2_notifier_register()
821 v4l2_async_nf_unregister(&priv->notifier); in ub953_v4l2_notifier_unregister()
822 v4l2_async_nf_cleanup(&priv->notifier); in ub953_v4l2_notifier_unregister()
837 scl_high = div64_u64((u64)scl_high * ref, 1000000000) - 5; in ub953_i2c_master_init()
838 scl_low = div64_u64((u64)scl_low * ref, 1000000000) - 5; in ub953_i2c_master_init()
853 switch (priv->mode) { in ub953_get_fc_rate()
855 if (priv->hw_data->is_ub971) in ub953_get_fc_rate()
856 return priv->plat_data->bc_rate * 160ull; in ub953_get_fc_rate()
858 return priv->plat_data->bc_rate / 2 * 160ull; in ub953_get_fc_rate()
862 return clk_get_rate(priv->clkin) * 80ull; in ub953_get_fc_rate()
875 * We always use 4 as a pre-divider (HS_CLK_DIV = 2). in ub953_calc_clkout_ub953()
878 * - "HS_CLK_DIV typically should be set to either 16, 8, or 4 (default)." in ub953_calc_clkout_ub953()
879 * - "if it is not possible to have an integer ratio of N/M, it is best to in ub953_calc_clkout_ub953()
895 rational_best_approximation(target, fc_divided, (1 << 5) - 1, in ub953_calc_clkout_ub953()
896 (1 << 8) - 1, &mul, &div); in ub953_calc_clkout_ub953()
919 rational_best_approximation(target, fc_divided, (1 << 5) - 1, in ub953_calc_clkout_ub971()
920 (1 << 8) - 1, &mul, &div); in ub953_calc_clkout_ub971()
934 struct device *dev = &priv->client->dev; in ub953_calc_clkout_params()
940 if (priv->hw_data->is_ub971) { in ub953_calc_clkout_params()
946 clkout_data->m = m; in ub953_calc_clkout_params()
947 clkout_data->n = n; in ub953_calc_clkout_params()
957 clkout_data->hs_div = hs_div; in ub953_calc_clkout_params()
958 clkout_data->m = m; in ub953_calc_clkout_params()
959 clkout_data->n = n; in ub953_calc_clkout_params()
966 clkout_data->rate = clkout_rate; in ub953_calc_clkout_params()
975 if (priv->hw_data->is_ub971) in ub953_write_clkout_regs()
976 clkout_ctrl0 = clkout_data->m; in ub953_write_clkout_regs()
978 clkout_ctrl0 = (__ffs(clkout_data->hs_div) << 5) | in ub953_write_clkout_regs()
979 clkout_data->m; in ub953_write_clkout_regs()
981 clkout_ctrl1 = clkout_data->n; in ub953_write_clkout_regs()
998 struct device *dev = &priv->client->dev; in ub953_clkout_recalc_rate()
1020 if (priv->hw_data->is_ub971) { in ub953_clkout_recalc_rate()
1068 dev_dbg(&priv->client->dev, "%s %lu (requested %lu)\n", __func__, in ub953_clkout_set_rate()
1082 struct device *dev = &priv->client->dev; in ub953_register_clkout()
1085 priv->hw_data->model, dev_name(dev)), in ub953_register_clkout()
1092 return -ENOMEM; in ub953_register_clkout()
1100 priv->clkout_clk_hw.init = &init; in ub953_register_clkout()
1102 ret = devm_clk_hw_register(dev, &priv->clkout_clk_hw); in ub953_register_clkout()
1108 &priv->clkout_clk_hw); in ub953_register_clkout()
1118 struct device *dev = &priv->client->dev; in ub953_add_i2c_adapter()
1126 ret = i2c_atr_add_adapter(priv->plat_data->atr, priv->plat_data->port, in ub953_add_i2c_adapter()
1147 struct device *dev = &priv->client->dev; in ub953_parse_dt()
1158 return dev_err_probe(dev, -ENOENT, "no endpoint found\n"); in ub953_parse_dt()
1170 return dev_err_probe(dev, -EINVAL, in ub953_parse_dt()
1171 "bad number of data-lanes: %u\n", nlanes); in ub953_parse_dt()
1173 priv->num_data_lanes = nlanes; in ub953_parse_dt()
1175 priv->non_continous_clk = vep.bus.mipi_csi2.flags & in ub953_parse_dt()
1183 struct device *dev = &priv->client->dev; in ub953_hw_init()
1193 return dev_err_probe(dev, -EIO, "Mode value not stabilized\n"); in ub953_hw_init()
1199 priv->mode = UB953_MODE_SYNC; in ub953_hw_init()
1202 priv->mode = UB953_MODE_NONSYNC_EXT; in ub953_hw_init()
1205 priv->mode = UB953_MODE_NONSYNC_INT; in ub953_hw_init()
1208 priv->mode = UB953_MODE_DVP; in ub953_hw_init()
1211 return dev_err_probe(dev, -EIO, in ub953_hw_init()
1216 priv->mode); in ub953_hw_init()
1218 if (priv->mode != UB953_MODE_SYNC && in ub953_hw_init()
1219 priv->mode != UB953_MODE_NONSYNC_EXT) in ub953_hw_init()
1220 return dev_err_probe(dev, -ENODEV, in ub953_hw_init()
1222 priv->mode); in ub953_hw_init()
1224 if (priv->mode == UB953_MODE_NONSYNC_EXT && !priv->clkin) in ub953_hw_init()
1225 return dev_err_probe(dev, -EINVAL, in ub953_hw_init()
1226 "clkin required for non-sync ext mode\n"); in ub953_hw_init()
1232 dev_info(dev, "Found %s rev/mask %#04x\n", priv->hw_data->model, v); in ub953_hw_init()
1246 v |= priv->non_continous_clk ? 0 : UB953_REG_GENERAL_CFG_CONT_CLK; in ub953_hw_init()
1247 v |= (priv->num_data_lanes - 1) << in ub953_hw_init()
1260 struct device *dev = &priv->client->dev; in ub953_subdev_init()
1263 v4l2_i2c_subdev_init(&priv->sd, priv->client, &ub953_subdev_ops); in ub953_subdev_init()
1265 priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | in ub953_subdev_init()
1267 priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in ub953_subdev_init()
1268 priv->sd.entity.ops = &ub953_entity_ops; in ub953_subdev_init()
1270 priv->pads[0].flags = MEDIA_PAD_FL_SINK; in ub953_subdev_init()
1271 priv->pads[1].flags = MEDIA_PAD_FL_SOURCE; in ub953_subdev_init()
1273 ret = media_entity_pads_init(&priv->sd.entity, 2, priv->pads); in ub953_subdev_init()
1277 ret = v4l2_subdev_init_finalize(&priv->sd); in ub953_subdev_init()
1288 ret = v4l2_async_register_subdev(&priv->sd); in ub953_subdev_init()
1299 v4l2_subdev_cleanup(&priv->sd); in ub953_subdev_init()
1301 media_entity_cleanup(&priv->sd.entity); in ub953_subdev_init()
1308 v4l2_async_unregister_subdev(&priv->sd); in ub953_subdev_uninit()
1310 v4l2_subdev_cleanup(&priv->sd); in ub953_subdev_uninit()
1311 media_entity_cleanup(&priv->sd.entity); in ub953_subdev_uninit()
1316 struct device *dev = &client->dev; in ub953_probe()
1322 return -ENOMEM; in ub953_probe()
1324 priv->client = client; in ub953_probe()
1326 priv->hw_data = device_get_match_data(dev); in ub953_probe()
1328 priv->plat_data = dev_get_platdata(&client->dev); in ub953_probe()
1329 if (!priv->plat_data) in ub953_probe()
1330 return dev_err_probe(dev, -ENODEV, "Platform data missing\n"); in ub953_probe()
1332 mutex_init(&priv->reg_lock); in ub953_probe()
1338 priv->current_indirect_target = 0xff; in ub953_probe()
1340 priv->regmap = devm_regmap_init_i2c(client, &ub953_regmap_config); in ub953_probe()
1341 if (IS_ERR(priv->regmap)) { in ub953_probe()
1342 ret = PTR_ERR(priv->regmap); in ub953_probe()
1347 priv->clkin = devm_clk_get_optional(dev, "clkin"); in ub953_probe()
1348 if (IS_ERR(priv->clkin)) { in ub953_probe()
1349 ret = PTR_ERR(priv->clkin); in ub953_probe()
1391 mutex_destroy(&priv->reg_lock); in ub953_probe()
1401 i2c_atr_del_adapter(priv->plat_data->atr, priv->plat_data->port); in ub953_remove()
1406 mutex_destroy(&priv->reg_lock); in ub953_remove()
1419 { "ds90ub953-q1", (kernel_ulong_t)&ds90ub953_hw },
1420 { "ds90ub971-q1", (kernel_ulong_t)&ds90ub971_hw },
1426 { .compatible = "ti,ds90ub953-q1", .data = &ds90ub953_hw },
1427 { .compatible = "ti,ds90ub971-q1", .data = &ds90ub971_hw },
1444 MODULE_DESCRIPTION("Texas Instruments FPD-Link III/IV CSI-2 Serializers Driver");