Lines Matching +full:colour +full:- +full:sensor
1 // SPDX-License-Identifier: GPL-2.0
14 #include <media/v4l2-ctrls.h>
15 #include <media/v4l2-device.h>
16 #include <media/v4l2-fwnode.h>
66 /* Analog gain controls from sensor */
72 /* Digital gain controls from sensor */
147 #define HI846_REG_TEST_PATTERN 0x020a /* 1-9 */
1032 "Solid Colour",
1033 "100% Colour Bars",
1034 "Fade To Grey Colour Bars",
1197 return hi846->cur_mode->link_freq_index; in hi846_get_link_freq_index()
1210 u64 pixel_rate = link_freq * 2 * hi846->nr_lanes; in hi846_calc_pixel_rate()
1219 struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd); in hi846_read_reg()
1226 msgs[0].addr = client->addr; in hi846_read_reg()
1230 msgs[1].addr = client->addr; in hi846_read_reg()
1235 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); in hi846_read_reg()
1237 dev_err(&client->dev, "i2c read error: %d\n", ret); in hi846_read_reg()
1238 return -EIO; in hi846_read_reg()
1248 struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd); in hi846_write_reg()
1251 { .addr = client->addr, .flags = 0, in hi846_write_reg()
1256 ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); in hi846_write_reg()
1258 dev_err(&client->dev, "i2c write error\n"); in hi846_write_reg()
1259 return -EIO; in hi846_write_reg()
1267 struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd); in hi846_write_reg_16()
1278 dev_err(&client->dev, "i2c_master_send != %zu: %d\n", in hi846_write_reg_16()
1280 *err = -EIO; in hi846_write_reg_16()
1287 struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd); in hi846_write_reg_list()
1291 for (i = 0; i < r_list->num_of_regs; i++) { in hi846_write_reg_list()
1292 hi846_write_reg_16(hi846, r_list->regs[i].address, in hi846_write_reg_list()
1293 r_list->regs[i].val, &ret); in hi846_write_reg_list()
1295 dev_err_ratelimited(&client->dev, in hi846_write_reg_list()
1297 r_list->regs[i].address, ret); in hi846_write_reg_list()
1338 struct hi846 *hi846 = container_of(ctrl->handler, in hi846_set_ctrl()
1340 struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd); in hi846_set_ctrl()
1346 if (ctrl->id == V4L2_CID_VBLANK) { in hi846_set_ctrl()
1348 exposure_max = hi846->cur_mode->height + ctrl->val - in hi846_set_ctrl()
1350 __v4l2_ctrl_modify_range(hi846->exposure, in hi846_set_ctrl()
1351 hi846->exposure->minimum, in hi846_set_ctrl()
1352 exposure_max, hi846->exposure->step, in hi846_set_ctrl()
1356 ret = pm_runtime_get_if_in_use(&client->dev); in hi846_set_ctrl()
1357 if (!ret || ret == -EAGAIN) in hi846_set_ctrl()
1360 switch (ctrl->id) { in hi846_set_ctrl()
1362 ret = hi846_write_reg(hi846, HI846_REG_ANALOG_GAIN, ctrl->val); in hi846_set_ctrl()
1366 ret = hi846_update_digital_gain(hi846, ctrl->val); in hi846_set_ctrl()
1370 shutter = ctrl->val; in hi846_set_ctrl()
1371 frame_len = hi846->cur_mode->frame_len; in hi846_set_ctrl()
1373 if (shutter > frame_len - 6) { /* margin */ in hi846_set_ctrl()
1382 if (shutter > (0xffff - 6)) in hi846_set_ctrl()
1383 shutter = 0xffff - 6; in hi846_set_ctrl()
1392 hi846->cur_mode->height + ctrl->val, &ret); in hi846_set_ctrl()
1395 ret = hi846_test_pattern(hi846, ctrl->val); in hi846_set_ctrl()
1399 ret = -EINVAL; in hi846_set_ctrl()
1403 pm_runtime_put(&client->dev); in hi846_set_ctrl()
1417 struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd); in hi846_init_controls()
1420 ctrl_hdlr = &hi846->ctrl_handler; in hi846_init_controls()
1425 ctrl_hdlr->lock = &hi846->mutex; in hi846_init_controls()
1427 hi846->link_freq = in hi846_init_controls()
1430 ARRAY_SIZE(hi846_link_freqs) - 1, in hi846_init_controls()
1432 if (hi846->link_freq) in hi846_init_controls()
1433 hi846->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in hi846_init_controls()
1435 hi846->pixel_rate = in hi846_init_controls()
1440 hi846->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &hi846_ctrl_ops, in hi846_init_controls()
1442 hi846->cur_mode->frame_len - in hi846_init_controls()
1443 hi846->cur_mode->height, in hi846_init_controls()
1444 HI846_FLL_MAX - in hi846_init_controls()
1445 hi846->cur_mode->height, 1, in hi846_init_controls()
1446 hi846->cur_mode->frame_len - in hi846_init_controls()
1447 hi846->cur_mode->height); in hi846_init_controls()
1449 h_blank = hi846->cur_mode->llp - hi846->cur_mode->width; in hi846_init_controls()
1451 hi846->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &hi846_ctrl_ops, in hi846_init_controls()
1454 if (hi846->hblank) in hi846_init_controls()
1455 hi846->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; in hi846_init_controls()
1463 exposure_max = hi846->cur_mode->frame_len - HI846_EXPOSURE_MAX_MARGIN; in hi846_init_controls()
1464 hi846->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &hi846_ctrl_ops, in hi846_init_controls()
1471 ARRAY_SIZE(hi846_test_pattern_menu) - 1, in hi846_init_controls()
1473 if (ctrl_hdlr->error) { in hi846_init_controls()
1474 dev_err(&client->dev, "v4l ctrl handler error: %d\n", in hi846_init_controls()
1475 ctrl_hdlr->error); in hi846_init_controls()
1476 ret = ctrl_hdlr->error; in hi846_init_controls()
1480 ret = v4l2_fwnode_device_parse(&client->dev, &props); in hi846_init_controls()
1489 hi846->sd.ctrl_handler = ctrl_hdlr; in hi846_init_controls()
1500 struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd); in hi846_set_video_mode()
1506 dev_dbg(&client->dev, "%s: link freq: %llu\n", __func__, in hi846_set_video_mode()
1513 dummy_lines = (frame_length > hi846->cur_mode->frame_len) ? in hi846_set_video_mode()
1514 (frame_length - hi846->cur_mode->frame_len) : 0; in hi846_set_video_mode()
1516 frame_length = hi846->cur_mode->frame_len + dummy_lines; in hi846_set_video_mode()
1518 dev_dbg(&client->dev, "%s: frame length calculated: %llu\n", __func__, in hi846_set_video_mode()
1530 struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd); in hi846_start_streaming()
1534 if (hi846->nr_lanes == 2) in hi846_start_streaming()
1539 dev_err(&client->dev, "failed to set plls: %d\n", ret); in hi846_start_streaming()
1543 ret = hi846_write_reg_list(hi846, &hi846->cur_mode->reg_list_config); in hi846_start_streaming()
1545 dev_err(&client->dev, "failed to set mode: %d\n", ret); in hi846_start_streaming()
1549 if (hi846->nr_lanes == 2) in hi846_start_streaming()
1551 &hi846->cur_mode->reg_list_2lane); in hi846_start_streaming()
1554 &hi846->cur_mode->reg_list_4lane); in hi846_start_streaming()
1556 dev_err(&client->dev, "failed to set mipi mode: %d\n", ret); in hi846_start_streaming()
1560 hi846_set_video_mode(hi846, hi846->cur_mode->fps); in hi846_start_streaming()
1562 ret = __v4l2_ctrl_handler_setup(hi846->sd.ctrl_handler); in hi846_start_streaming()
1578 dev_info(&client->dev, "visible pixel width and height is 0\n"); in hi846_start_streaming()
1583 dev_err(&client->dev, "failed to start stream"); in hi846_start_streaming()
1587 hi846->streaming = 1; in hi846_start_streaming()
1589 dev_dbg(&client->dev, "%s: started streaming successfully\n", __func__); in hi846_start_streaming()
1596 struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd); in hi846_stop_streaming()
1599 dev_err(&client->dev, "failed to stop stream"); in hi846_stop_streaming()
1601 hi846->streaming = 0; in hi846_stop_streaming()
1610 mutex_lock(&hi846->mutex); in hi846_set_stream()
1613 ret = pm_runtime_resume_and_get(&client->dev); in hi846_set_stream()
1622 pm_runtime_put(&client->dev); in hi846_set_stream()
1626 mutex_unlock(&hi846->mutex); in hi846_set_stream()
1635 ret = regulator_bulk_enable(HI846_NUM_SUPPLIES, hi846->supplies); in hi846_power_on()
1639 ret = clk_prepare_enable(hi846->clock); in hi846_power_on()
1643 if (hi846->shutdown_gpio) in hi846_power_on()
1644 gpiod_set_value_cansleep(hi846->shutdown_gpio, 0); in hi846_power_on()
1648 if (hi846->rst_gpio) in hi846_power_on()
1649 gpiod_set_value_cansleep(hi846->rst_gpio, 0); in hi846_power_on()
1655 regulator_bulk_disable(HI846_NUM_SUPPLIES, hi846->supplies); in hi846_power_on()
1662 if (hi846->rst_gpio) in hi846_power_off()
1663 gpiod_set_value_cansleep(hi846->rst_gpio, 1); in hi846_power_off()
1665 if (hi846->shutdown_gpio) in hi846_power_off()
1666 gpiod_set_value_cansleep(hi846->shutdown_gpio, 1); in hi846_power_off()
1668 clk_disable_unprepare(hi846->clock); in hi846_power_off()
1669 return regulator_bulk_disable(HI846_NUM_SUPPLIES, hi846->supplies); in hi846_power_off()
1695 struct v4l2_mbus_framefmt *mf = &format->format; in hi846_set_format()
1697 const struct hi846_datafmt *fmt = hi846_find_datafmt(mf->code); in hi846_set_format()
1702 mf->code = hi846_colour_fmts[0].code; in hi846_set_format()
1703 mf->colorspace = hi846_colour_fmts[0].colorspace; in hi846_set_format()
1707 if (format->which == V4L2_SUBDEV_FORMAT_TRY) { in hi846_set_format()
1708 *v4l2_subdev_state_get_format(sd_state, format->pad) = *mf; in hi846_set_format()
1712 if (hi846->nr_lanes == 2) { in hi846_set_format()
1713 if (!hi846->cur_mode->reg_list_2lane.num_of_regs) { in hi846_set_format()
1714 dev_err(&client->dev, in hi846_set_format()
1716 return -EINVAL; in hi846_set_format()
1719 if (!hi846->cur_mode->reg_list_4lane.num_of_regs) { in hi846_set_format()
1720 dev_err(&client->dev, in hi846_set_format()
1722 return -EINVAL; in hi846_set_format()
1726 mutex_lock(&hi846->mutex); in hi846_set_format()
1728 if (hi846->streaming) { in hi846_set_format()
1729 mutex_unlock(&hi846->mutex); in hi846_set_format()
1730 return -EBUSY; in hi846_set_format()
1733 hi846->fmt = fmt; in hi846_set_format()
1735 hi846->cur_mode = in hi846_set_format()
1738 width, height, mf->width, mf->height); in hi846_set_format()
1739 dev_dbg(&client->dev, "%s: found mode: %dx%d\n", __func__, in hi846_set_format()
1740 hi846->cur_mode->width, hi846->cur_mode->height); in hi846_set_format()
1742 tgt_fps = hi846->cur_mode->fps; in hi846_set_format()
1743 dev_dbg(&client->dev, "%s: target fps: %d\n", __func__, tgt_fps); in hi846_set_format()
1745 mf->width = hi846->cur_mode->width; in hi846_set_format()
1746 mf->height = hi846->cur_mode->height; in hi846_set_format()
1747 mf->code = HI846_MEDIA_BUS_FORMAT; in hi846_set_format()
1748 mf->field = V4L2_FIELD_NONE; in hi846_set_format()
1750 __v4l2_ctrl_s_ctrl(hi846->link_freq, hi846_get_link_freq_index(hi846)); in hi846_set_format()
1751 __v4l2_ctrl_s_ctrl_int64(hi846->pixel_rate, in hi846_set_format()
1755 vblank_def = hi846->cur_mode->frame_len - hi846->cur_mode->height; in hi846_set_format()
1756 __v4l2_ctrl_modify_range(hi846->vblank, in hi846_set_format()
1757 hi846->cur_mode->frame_len - in hi846_set_format()
1758 hi846->cur_mode->height, in hi846_set_format()
1759 HI846_FLL_MAX - hi846->cur_mode->height, 1, in hi846_set_format()
1761 __v4l2_ctrl_s_ctrl(hi846->vblank, vblank_def); in hi846_set_format()
1763 h_blank = hi846->cur_mode->llp - hi846->cur_mode->width; in hi846_set_format()
1765 __v4l2_ctrl_modify_range(hi846->hblank, h_blank, h_blank, 1, in hi846_set_format()
1768 dev_dbg(&client->dev, "Set fmt w=%d h=%d code=0x%x colorspace=0x%x\n", in hi846_set_format()
1769 mf->width, mf->height, in hi846_set_format()
1770 fmt->code, fmt->colorspace); in hi846_set_format()
1772 mutex_unlock(&hi846->mutex); in hi846_set_format()
1782 struct v4l2_mbus_framefmt *mf = &format->format; in hi846_get_format()
1785 if (format->which == V4L2_SUBDEV_FORMAT_TRY) { in hi846_get_format()
1786 format->format = *v4l2_subdev_state_get_format(sd_state, in hi846_get_format()
1787 format->pad); in hi846_get_format()
1791 mutex_lock(&hi846->mutex); in hi846_get_format()
1792 mf->code = HI846_MEDIA_BUS_FORMAT; in hi846_get_format()
1793 mf->colorspace = V4L2_COLORSPACE_RAW; in hi846_get_format()
1794 mf->field = V4L2_FIELD_NONE; in hi846_get_format()
1795 mf->width = hi846->cur_mode->width; in hi846_get_format()
1796 mf->height = hi846->cur_mode->height; in hi846_get_format()
1797 mutex_unlock(&hi846->mutex); in hi846_get_format()
1798 dev_dbg(&client->dev, in hi846_get_format()
1800 mf->width, mf->height, mf->code, mf->colorspace); in hi846_get_format()
1809 if (code->pad || code->index > 0) in hi846_enum_mbus_code()
1810 return -EINVAL; in hi846_enum_mbus_code()
1812 code->code = HI846_MEDIA_BUS_FORMAT; in hi846_enum_mbus_code()
1823 if (fse->pad || fse->index >= ARRAY_SIZE(supported_modes)) in hi846_enum_frame_size()
1824 return -EINVAL; in hi846_enum_frame_size()
1826 if (fse->code != HI846_MEDIA_BUS_FORMAT) { in hi846_enum_frame_size()
1827 dev_err(&client->dev, "frame size enum not matching\n"); in hi846_enum_frame_size()
1828 return -EINVAL; in hi846_enum_frame_size()
1831 fse->min_width = supported_modes[fse->index].width; in hi846_enum_frame_size()
1832 fse->max_width = supported_modes[fse->index].width; in hi846_enum_frame_size()
1833 fse->min_height = supported_modes[fse->index].height; in hi846_enum_frame_size()
1834 fse->max_height = supported_modes[fse->index].height; in hi846_enum_frame_size()
1836 dev_dbg(&client->dev, "%s: max width: %d max height: %d\n", __func__, in hi846_enum_frame_size()
1837 fse->max_width, fse->max_height); in hi846_enum_frame_size()
1848 switch (sel->target) { in hi846_get_selection()
1851 mutex_lock(&hi846->mutex); in hi846_get_selection()
1852 switch (sel->which) { in hi846_get_selection()
1854 sel->r = *v4l2_subdev_state_get_crop(sd_state, sel->pad); in hi846_get_selection()
1857 sel->r = hi846->cur_mode->crop; in hi846_get_selection()
1860 mutex_unlock(&hi846->mutex); in hi846_get_selection()
1864 sel->r.top = 0; in hi846_get_selection()
1865 sel->r.left = 0; in hi846_get_selection()
1866 sel->r.width = 3264; in hi846_get_selection()
1867 sel->r.height = 2448; in hi846_get_selection()
1870 return -EINVAL; in hi846_get_selection()
1882 mutex_lock(&hi846->mutex); in hi846_init_state()
1883 mf->code = HI846_MEDIA_BUS_FORMAT; in hi846_init_state()
1884 mf->colorspace = V4L2_COLORSPACE_RAW; in hi846_init_state()
1885 mf->field = V4L2_FIELD_NONE; in hi846_init_state()
1886 mf->width = hi846->cur_mode->width; in hi846_init_state()
1887 mf->height = hi846->cur_mode->height; in hi846_init_state()
1888 mutex_unlock(&hi846->mutex); in hi846_init_state()
1920 struct i2c_client *client = v4l2_get_subdevdata(&hi846->sd); in hi846_identify_module()
1929 dev_err(&client->dev, "wrong chip id low byte: %x", lo); in hi846_identify_module()
1930 return -ENXIO; in hi846_identify_module()
1938 dev_err(&client->dev, "wrong chip id high byte: %x", hi); in hi846_identify_module()
1939 return -ENXIO; in hi846_identify_module()
1942 dev_info(&client->dev, "chip id %02X %02X using %d mipi lanes\n", in hi846_identify_module()
1943 hi, lo, hi846->nr_lanes); in hi846_identify_module()
1956 for (j = 0; j < ep->nr_of_link_frequencies; j++) in hi846_check_link_freqs()
1957 if (freqs[i] == ep->link_frequencies[j]) in hi846_check_link_freqs()
1959 if (j == ep->nr_of_link_frequencies) in hi846_check_link_freqs()
1979 return -ENXIO; in hi846_parse_dt()
1993 ret = -EINVAL; in hi846_parse_dt()
1997 hi846->nr_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes; in hi846_parse_dt()
2000 dev_err(dev, "link-frequency property not found in DT\n"); in hi846_parse_dt()
2001 ret = -EINVAL; in hi846_parse_dt()
2009 ret = -EINVAL; in hi846_parse_dt()
2015 hi846->rst_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); in hi846_parse_dt()
2016 if (IS_ERR(hi846->rst_gpio)) { in hi846_parse_dt()
2018 hi846->rst_gpio); in hi846_parse_dt()
2019 return PTR_ERR(hi846->rst_gpio); in hi846_parse_dt()
2022 hi846->shutdown_gpio = devm_gpiod_get_optional(dev, "shutdown", in hi846_parse_dt()
2024 if (IS_ERR(hi846->shutdown_gpio)) { in hi846_parse_dt()
2026 hi846->shutdown_gpio); in hi846_parse_dt()
2027 return PTR_ERR(hi846->shutdown_gpio); in hi846_parse_dt()
2044 hi846 = devm_kzalloc(&client->dev, sizeof(*hi846), GFP_KERNEL); in hi846_probe()
2046 return -ENOMEM; in hi846_probe()
2048 ret = hi846_parse_dt(hi846, &client->dev); in hi846_probe()
2050 dev_err(&client->dev, "failed to check HW configuration: %d", in hi846_probe()
2055 hi846->clock = devm_clk_get(&client->dev, NULL); in hi846_probe()
2056 if (IS_ERR(hi846->clock)) { in hi846_probe()
2057 dev_err(&client->dev, "failed to get clock: %pe\n", in hi846_probe()
2058 hi846->clock); in hi846_probe()
2059 return PTR_ERR(hi846->clock); in hi846_probe()
2062 mclk_freq = clk_get_rate(hi846->clock); in hi846_probe()
2064 dev_warn(&client->dev, in hi846_probe()
2069 hi846->supplies[i].supply = hi846_supply_names[i]; in hi846_probe()
2071 ret = devm_regulator_bulk_get(&client->dev, HI846_NUM_SUPPLIES, in hi846_probe()
2072 hi846->supplies); in hi846_probe()
2076 v4l2_i2c_subdev_init(&hi846->sd, client, &hi846_subdev_ops); in hi846_probe()
2077 hi846->sd.internal_ops = &hi846_internal_ops; in hi846_probe()
2079 mutex_init(&hi846->mutex); in hi846_probe()
2089 hi846->cur_mode = &supported_modes[0]; in hi846_probe()
2093 dev_err(&client->dev, "failed to init controls: %d", ret); in hi846_probe()
2097 hi846->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in hi846_probe()
2098 hi846->sd.entity.ops = &hi846_subdev_entity_ops; in hi846_probe()
2099 hi846->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in hi846_probe()
2100 hi846->pad.flags = MEDIA_PAD_FL_SOURCE; in hi846_probe()
2101 ret = media_entity_pads_init(&hi846->sd.entity, 1, &hi846->pad); in hi846_probe()
2103 dev_err(&client->dev, "failed to init entity pads: %d", ret); in hi846_probe()
2107 ret = v4l2_async_register_subdev_sensor(&hi846->sd); in hi846_probe()
2109 dev_err(&client->dev, "failed to register V4L2 subdev: %d", in hi846_probe()
2114 pm_runtime_set_active(&client->dev); in hi846_probe()
2115 pm_runtime_enable(&client->dev); in hi846_probe()
2116 pm_runtime_idle(&client->dev); in hi846_probe()
2121 media_entity_cleanup(&hi846->sd.entity); in hi846_probe()
2124 v4l2_ctrl_handler_free(hi846->sd.ctrl_handler); in hi846_probe()
2130 mutex_destroy(&hi846->mutex); in hi846_probe()
2141 media_entity_cleanup(&sd->entity); in hi846_remove()
2142 v4l2_ctrl_handler_free(sd->ctrl_handler); in hi846_remove()
2144 pm_runtime_disable(&client->dev); in hi846_remove()
2145 if (!pm_runtime_status_suspended(&client->dev)) in hi846_remove()
2146 hi846_suspend(&client->dev); in hi846_remove()
2147 pm_runtime_set_suspended(&client->dev); in hi846_remove()
2149 mutex_destroy(&hi846->mutex); in hi846_remove()
2176 MODULE_DESCRIPTION("Hynix HI846 sensor driver");