Lines Matching +full:b +full:- +full:facing

1 // SPDX-License-Identifier: GPL-2.0
22 #include <linux/rk-camera-module.h>
23 #include <media/media-entity.h>
24 #include <media/v4l2-async.h>
25 #include <media/v4l2-ctrls.h>
26 #include <media/v4l2-subdev.h>
28 #include <linux/rk-preisp.h>
279 msg.addr = client->addr; in tp2855_write_reg()
280 msg.flags = client->flags; in tp2855_write_reg()
284 ret = i2c_transfer(client->adapter, &msg, 1); in tp2855_write_reg()
290 dev_err(&client->dev, in tp2855_write_reg()
305 dev_err(&client->dev, "%s failed !\n", __func__); in tp2855_write_array()
323 msg[0].addr = client->addr; in tp2855_read_reg()
324 msg[0].flags = client->flags; in tp2855_read_reg()
328 msg[1].addr = client->addr; in tp2855_read_reg()
329 msg[1].flags = client->flags | I2C_M_RD; in tp2855_read_reg()
333 ret = i2c_transfer(client->adapter, msg, 2); in tp2855_read_reg()
339 dev_err(&client->dev, "tp2855 read reg(0x%x) failed !\n", reg); in tp2855_read_reg()
347 return abs(mode->width - framefmt->width) + in tp2855_get_reso_dist()
348 abs(mode->height - framefmt->height); in tp2855_get_reso_dist()
355 struct v4l2_mbus_framefmt *framefmt = &fmt->format; in tp2855_find_best_fit()
358 int cur_best_fit_dist = -1; in tp2855_find_best_fit()
361 for (i = 0; i < tp2855->cfg_num; i++) { in tp2855_find_best_fit()
363 if ((cur_best_fit_dist == -1 || dist <= cur_best_fit_dist) && in tp2855_find_best_fit()
364 supported_modes[i].bus_fmt == framefmt->code) { in tp2855_find_best_fit()
381 mutex_lock(&tp2855->mutex); in tp2855_set_fmt()
384 fmt->format.code = mode->bus_fmt; in tp2855_set_fmt()
385 fmt->format.width = mode->width; in tp2855_set_fmt()
386 fmt->format.height = mode->height; in tp2855_set_fmt()
387 fmt->format.field = V4L2_FIELD_NONE; in tp2855_set_fmt()
388 fmt->format.colorspace = V4L2_COLORSPACE_SRGB; in tp2855_set_fmt()
390 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in tp2855_set_fmt()
392 *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; in tp2855_set_fmt()
394 mutex_unlock(&tp2855->mutex); in tp2855_set_fmt()
395 return -ENOTTY; in tp2855_set_fmt()
398 __v4l2_ctrl_s_ctrl(tp2855->link_freq, mode->mipi_freq_idx); in tp2855_set_fmt()
399 pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * TP2855_LANES; in tp2855_set_fmt()
400 __v4l2_ctrl_s_ctrl_int64(tp2855->pixel_rate, pixel_rate); in tp2855_set_fmt()
401 dev_dbg(&tp2855->client->dev, "mipi_freq_idx %d\n", mode->mipi_freq_idx); in tp2855_set_fmt()
402 dev_dbg(&tp2855->client->dev, "pixel_rate %lld\n", pixel_rate); in tp2855_set_fmt()
405 mutex_unlock(&tp2855->mutex); in tp2855_set_fmt()
414 struct i2c_client *client = tp2855->client; in tp2855_get_fmt()
415 const struct tp2855_mode *mode = tp2855->cur_mode; in tp2855_get_fmt()
417 mutex_lock(&tp2855->mutex); in tp2855_get_fmt()
418 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in tp2855_get_fmt()
420 fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); in tp2855_get_fmt()
422 mutex_unlock(&tp2855->mutex); in tp2855_get_fmt()
423 return -ENOTTY; in tp2855_get_fmt()
426 fmt->format.width = mode->width; in tp2855_get_fmt()
427 fmt->format.height = mode->height; in tp2855_get_fmt()
428 fmt->format.code = mode->bus_fmt; in tp2855_get_fmt()
429 fmt->format.field = V4L2_FIELD_NONE; in tp2855_get_fmt()
430 if (fmt->pad < PAD_MAX && fmt->pad >= PAD0) in tp2855_get_fmt()
431 fmt->reserved[0] = mode->vc[fmt->pad]; in tp2855_get_fmt()
433 fmt->reserved[0] = mode->vc[PAD0]; in tp2855_get_fmt()
435 mutex_unlock(&tp2855->mutex); in tp2855_get_fmt()
437 dev_dbg(&client->dev, "%s: %x %dx%d\n", in tp2855_get_fmt()
438 __func__, fmt->format.code, in tp2855_get_fmt()
439 fmt->format.width, fmt->format.height); in tp2855_get_fmt()
451 if (code->index != 0) in tp2855_enum_mbus_code()
452 return -EINVAL; in tp2855_enum_mbus_code()
453 code->code = tp2855->cur_mode->bus_fmt; in tp2855_enum_mbus_code()
463 struct i2c_client *client = tp2855->client; in tp2855_enum_frame_sizes()
465 dev_dbg(&client->dev, "%s:\n", __func__); in tp2855_enum_frame_sizes()
467 if (fse->index >= tp2855->cfg_num) in tp2855_enum_frame_sizes()
468 return -EINVAL; in tp2855_enum_frame_sizes()
470 if (fse->code != supported_modes[fse->index].bus_fmt) in tp2855_enum_frame_sizes()
471 return -EINVAL; in tp2855_enum_frame_sizes()
473 fse->min_width = supported_modes[fse->index].width; in tp2855_enum_frame_sizes()
474 fse->max_width = supported_modes[fse->index].width; in tp2855_enum_frame_sizes()
475 fse->max_height = supported_modes[fse->index].height; in tp2855_enum_frame_sizes()
476 fse->min_height = supported_modes[fse->index].height; in tp2855_enum_frame_sizes()
483 cfg->type = V4L2_MBUS_CSI2; in tp2855_g_mbus_config()
484 cfg->flags = V4L2_MBUS_CSI2_4_LANE | in tp2855_g_mbus_config()
494 strlcpy(inf->base.sensor, TP2855_NAME, sizeof(inf->base.sensor)); in tp2855_get_module_inf()
495 strlcpy(inf->base.module, tp2855->module_name, in tp2855_get_module_inf()
496 sizeof(inf->base.module)); in tp2855_get_module_inf()
497 strlcpy(inf->base.lens, tp2855->len_name, sizeof(inf->base.lens)); in tp2855_get_module_inf()
510 ret = -ENOTTY; in tp2855_ioctl()
530 ret = -ENOMEM; in tp2855_compat_ioctl32()
542 ret = -ENOMEM; in tp2855_compat_ioctl32()
552 ret = -ENOIOCTLCMD; in tp2855_compat_ioctl32()
563 struct i2c_client *client = tp2855->client; in detect_thread_function()
566 tp2855->lost_video_status = true; in detect_thread_function()
568 if (tp2855->power_on) { in detect_thread_function()
573 if (tp2855->lost_video_status != lost_video) { in detect_thread_function()
579 tp2855->lost_video_status = lost_video; in detect_thread_function()
581 dev_err(&client->dev, "tp2855 detect video lost status %d reg26_val %x\n", in detect_thread_function()
593 struct i2c_client *client = tp2855->client; in detect_thread_start()
594 tp2855->detect_thread = kthread_create(detect_thread_function, in detect_thread_start()
596 if (IS_ERR(tp2855->detect_thread)) { in detect_thread_start()
597 dev_err(&client->dev, "kthread_create tp2855_kthread failed\n"); in detect_thread_start()
598 ret = PTR_ERR(tp2855->detect_thread); in detect_thread_start()
599 tp2855->detect_thread = NULL; in detect_thread_start()
602 wake_up_process(tp2855->detect_thread); in detect_thread_start()
607 if (tp2855->detect_thread) in detect_thread_stop()
608 kthread_stop(tp2855->detect_thread); in detect_thread_stop()
609 tp2855->detect_thread = NULL; in detect_thread_stop()
617 struct i2c_client *client = tp2855->client; in __tp2855_start_stream()
619 if (tp2855->cur_mode->global_reg_list == common_setting_594M_1080p_25fps_regs) { in __tp2855_start_stream()
621 } else if (tp2855->cur_mode->global_reg_list == common_setting_297M_720p_25fps_regs) { in __tp2855_start_stream()
624 return -1; in __tp2855_start_stream()
627 ret = tp2855_write_array(tp2855->client, in __tp2855_start_stream()
628 tp2855->cur_mode->global_reg_list, array_size); in __tp2855_start_stream()
630 dev_err(&client->dev, "__tp2855_start_stream global_reg_list faild"); in __tp2855_start_stream()
641 struct i2c_client *client = tp2855->client; in __tp2855_stop_stream()
653 struct i2c_client *client = tp2855->client; in tp2855_stream()
655 dev_dbg(&client->dev, "s_stream: %d. %dx%d\n", on, in tp2855_stream()
656 tp2855->cur_mode->width, in tp2855_stream()
657 tp2855->cur_mode->height); in tp2855_stream()
659 mutex_lock(&tp2855->mutex); in tp2855_stream()
661 if (tp2855->streaming == on) in tp2855_stream()
670 tp2855->streaming = on; in tp2855_stream()
673 mutex_unlock(&tp2855->mutex); in tp2855_stream()
681 struct i2c_client *client = tp2855->client; in tp2855_power()
684 mutex_lock(&tp2855->mutex); in tp2855_power()
686 /* If the power state is not modified - no work to do. */ in tp2855_power()
687 if (tp2855->power_on == !!on) in tp2855_power()
690 dev_dbg(&client->dev, "%s: on %d\n", __func__, on); in tp2855_power()
693 ret = pm_runtime_get_sync(&client->dev); in tp2855_power()
695 pm_runtime_put_noidle(&client->dev); in tp2855_power()
698 tp2855->power_on = true; in tp2855_power()
700 pm_runtime_put(&client->dev); in tp2855_power()
701 tp2855->power_on = false; in tp2855_power()
705 mutex_unlock(&tp2855->mutex); in tp2855_power()
713 struct device *dev = &tp2855->client->dev; in __tp2855_power_on()
717 if (!IS_ERR_OR_NULL(tp2855->pins_default)) { in __tp2855_power_on()
718 ret = pinctrl_select_state(tp2855->pinctrl, in __tp2855_power_on()
719 tp2855->pins_default); in __tp2855_power_on()
724 if (!IS_ERR(tp2855->power_gpio)) { in __tp2855_power_on()
725 gpiod_set_value_cansleep(tp2855->power_gpio, 1); in __tp2855_power_on()
731 ret = clk_set_rate(tp2855->xvclk, TP2855_XVCLK_FREQ); in __tp2855_power_on()
734 if (clk_get_rate(tp2855->xvclk) != TP2855_XVCLK_FREQ) in __tp2855_power_on()
736 ret = clk_prepare_enable(tp2855->xvclk); in __tp2855_power_on()
742 if (!IS_ERR(tp2855->reset_gpio)) { in __tp2855_power_on()
743 gpiod_set_value_cansleep(tp2855->reset_gpio, 1); in __tp2855_power_on()
745 gpiod_set_value_cansleep(tp2855->reset_gpio, 0); in __tp2855_power_on()
754 if (!IS_ERR(tp2855->reset_gpio)) in __tp2855_power_on()
755 gpiod_set_value_cansleep(tp2855->reset_gpio, 0); in __tp2855_power_on()
757 if (!IS_ERR_OR_NULL(tp2855->pins_sleep)) in __tp2855_power_on()
758 pinctrl_select_state(tp2855->pinctrl, tp2855->pins_sleep); in __tp2855_power_on()
766 struct device *dev = &tp2855->client->dev; in __tp2855_power_off()
770 if (!IS_ERR(tp2855->reset_gpio)) in __tp2855_power_off()
771 gpiod_set_value_cansleep(tp2855->reset_gpio, 0); in __tp2855_power_off()
772 clk_disable_unprepare(tp2855->xvclk); in __tp2855_power_off()
774 if (!IS_ERR_OR_NULL(tp2855->pins_sleep)) { in __tp2855_power_off()
775 ret = pinctrl_select_state(tp2855->pinctrl, in __tp2855_power_off()
776 tp2855->pins_sleep); in __tp2855_power_off()
781 if (!IS_ERR(tp2855->power_gpio)) in __tp2855_power_off()
782 gpiod_set_value_cansleep(tp2855->power_gpio, 0); in __tp2855_power_off()
792 handler = &tp2855->ctrl_handler; in tp2855_initialize_controls()
793 mode = tp2855->cur_mode; in tp2855_initialize_controls()
797 handler->lock = &tp2855->mutex; in tp2855_initialize_controls()
799 tp2855->link_freq = v4l2_ctrl_new_int_menu(handler, NULL, in tp2855_initialize_controls()
801 ARRAY_SIZE(link_freq_items) - 1, 0, in tp2855_initialize_controls()
803 __v4l2_ctrl_s_ctrl(tp2855->link_freq, mode->mipi_freq_idx); in tp2855_initialize_controls()
806 pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * TP2855_LANES; in tp2855_initialize_controls()
807 tp2855->pixel_rate = v4l2_ctrl_new_std(handler, NULL, in tp2855_initialize_controls()
812 if (handler->error) { in tp2855_initialize_controls()
813 ret = handler->error; in tp2855_initialize_controls()
814 dev_err(&tp2855->client->dev, in tp2855_initialize_controls()
819 tp2855->subdev.ctrl_handler = handler; in tp2855_initialize_controls()
854 v4l2_subdev_get_try_format(sd, fh->pad, 0); in tp2855_open()
857 dev_dbg(&tp2855->client->dev, "%s\n", __func__); in tp2855_open()
859 mutex_lock(&tp2855->mutex); in tp2855_open()
861 try_fmt->width = def_mode->width; in tp2855_open()
862 try_fmt->height = def_mode->height; in tp2855_open()
863 try_fmt->code = def_mode->bus_fmt; in tp2855_open()
864 try_fmt->field = V4L2_FIELD_NONE; in tp2855_open()
866 mutex_unlock(&tp2855->mutex); in tp2855_open()
906 struct device *dev = &client->dev; in check_chip_id()
911 return -1; in check_chip_id()
919 struct device *dev = &client->dev; in tp2855_probe()
920 struct device_node *node = dev->of_node; in tp2855_probe()
923 __maybe_unused char facing[2]; in tp2855_probe() local
933 return -ENOMEM; in tp2855_probe()
936 &tp2855->module_index); in tp2855_probe()
938 &tp2855->module_facing); in tp2855_probe()
940 &tp2855->module_name); in tp2855_probe()
942 &tp2855->len_name); in tp2855_probe()
945 return -EINVAL; in tp2855_probe()
948 tp2855->client = client; in tp2855_probe()
949 tp2855->cur_mode = &supported_modes[0]; in tp2855_probe()
951 tp2855->xvclk = devm_clk_get(dev, "xvclk"); in tp2855_probe()
952 if (IS_ERR(tp2855->xvclk)) { in tp2855_probe()
954 return -EINVAL; in tp2855_probe()
957 tp2855->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); in tp2855_probe()
958 if (IS_ERR(tp2855->reset_gpio)) in tp2855_probe()
959 dev_warn(dev, "Failed to get reset-gpios\n"); in tp2855_probe()
961 tp2855->power_gpio = devm_gpiod_get(dev, "power", GPIOD_OUT_LOW); in tp2855_probe()
962 if (IS_ERR(tp2855->power_gpio)) in tp2855_probe()
963 dev_warn(dev, "Failed to get power-gpios\n"); in tp2855_probe()
965 tp2855->pinctrl = devm_pinctrl_get(dev); in tp2855_probe()
966 if (!IS_ERR(tp2855->pinctrl)) { in tp2855_probe()
967 tp2855->pins_default = in tp2855_probe()
968 pinctrl_lookup_state(tp2855->pinctrl, in tp2855_probe()
970 if (IS_ERR(tp2855->pins_default)) in tp2855_probe()
973 tp2855->pins_sleep = in tp2855_probe()
974 pinctrl_lookup_state(tp2855->pinctrl, in tp2855_probe()
976 if (IS_ERR(tp2855->pins_sleep)) in tp2855_probe()
982 mutex_init(&tp2855->mutex); in tp2855_probe()
984 sd = &tp2855->subdev; in tp2855_probe()
1005 sd->internal_ops = &tp2855_internal_ops; in tp2855_probe()
1006 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in tp2855_probe()
1010 tp2855->pad.flags = MEDIA_PAD_FL_SOURCE; in tp2855_probe()
1011 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; in tp2855_probe()
1012 ret = media_entity_pads_init(&sd->entity, 1, &tp2855->pad); in tp2855_probe()
1017 memset(facing, 0, sizeof(facing)); in tp2855_probe()
1018 if (strcmp(tp2855->module_facing, "back") == 0) in tp2855_probe()
1019 facing[0] = 'b'; in tp2855_probe()
1021 facing[0] = 'f'; in tp2855_probe()
1023 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s", in tp2855_probe()
1024 tp2855->module_index, facing, in tp2855_probe()
1025 TP2855_NAME, dev_name(sd->dev)); in tp2855_probe()
1041 media_entity_cleanup(&sd->entity); in tp2855_probe()
1046 v4l2_ctrl_handler_free(&tp2855->ctrl_handler); in tp2855_probe()
1048 mutex_destroy(&tp2855->mutex); in tp2855_probe()
1060 media_entity_cleanup(&sd->entity); in tp2855_remove()
1062 v4l2_ctrl_handler_free(&tp2855->ctrl_handler); in tp2855_remove()
1063 mutex_destroy(&tp2855->mutex); in tp2855_remove()
1065 pm_runtime_disable(&client->dev); in tp2855_remove()
1066 if (!pm_runtime_status_suspended(&client->dev)) in tp2855_remove()
1068 pm_runtime_set_suspended(&client->dev); in tp2855_remove()
1115 MODULE_AUTHOR("Vicent Chi <vicent.chi@rock-chips.com>");