Lines Matching +full:dsp +full:- +full:standby
1 // SPDX-License-Identifier: GPL-2.0-or-later
18 #include <media/v4l2-ctrls.h>
19 #include <media/v4l2-device.h>
20 #include <media/v4l2-fwnode.h>
21 #include <media/v4l2-image-sizes.h>
22 #include <media/v4l2-mediabus.h>
41 #define OV8865_PLL_CTRL3_M_DIV(v) (((v) - 1) & GENMASK(3, 0))
47 #define OV8865_PLL_CTRL6_SYS_DIV(v) (((v) - 1) & BIT(0))
52 #define OV8865_PLL_CTRLA_PRE_DIV_HALF(v) (((v) - 1) & BIT(0))
62 #define OV8865_PLL_CTRLF_SYS_PRE_DIV(v) (((v) - 1) & GENMASK(3, 0))
66 #define OV8865_PLL_CTRL12_PRE_DIV_HALF(v) ((((v) - 1) << 4) & BIT(4))
67 #define OV8865_PLL_CTRL12_DAC_DIV(v) (((v) - 1) & GENMASK(3, 0))
101 #define OV8865_MIPI_SC_CTRL0_LANES(v) ((((v) - 1) << 5) & \
115 #define OV8865_PCLK_SEL_PCLK_DIV(v) ((((v) - 1) << 3) & BIT(3))
440 #define OV8865_VAP_CTRL1_HSUB_COEF(v) ((((v) - 1) << 2) & \
442 #define OV8865_VAP_CTRL1_VSUB_COEF(v) (((v) - 1) & GENMASK(1, 0))
444 /* Pre-DSP */
471 (&container_of((c)->handler, struct ov8865_sensor, \
472 ctrls.handler)->subdev)
485 * +-< EXTCLK
487 * +-+ pll_pre_div_half (0x30a [0])
489 * +-+ pll_pre_div (0x300 [2:0], special values:
491 * +-+ pll_mul (0x301 [1:0], 0x302 [7:0])
493 * +-+ m_div (0x303 [3:0])
495 * | +-> PHY_SCLK
497 * | +-+ mipi_div (0x304 [1:0], special values: 0: 4, 1: 5, 2: 6, 3: 8)
499 * | +-+ pclk_div (0x3020 [3])
501 * | +-> PCLK
503 * +-+ sys_pre_div (0x305 [1:0], special values: 0: 3, 1: 4, 2: 5, 3: 6)
505 * +-+ sys_div (0x306 [0])
507 * +-+ sys_sel (0x3032 [7], 0: PLL1, 1: PLL2)
509 * +-+ sclk_sel (0x3033 [1], 0: sys_sel, 1: PLL2 DAC_CLK)
511 * +-+ sclk_pre_div (0x3106 [3:2], special values:
514 * +-+ sclk_div (0x3106 [7:4], special values: 0: 1)
516 * +-> SCLK
533 * +-< EXTCLK
535 * +-+ pll_pre_div_half (0x312 [4])
537 * +-+ pll_pre_div (0x30b [2:0], special values:
539 * +-+ pll_mul (0x30c [1:0], 0x30d [7:0])
541 * +-+ dac_div (0x312 [3:0])
543 * | +-> DAC_CLK
545 * +-+ sys_pre_div (0x30f [3:0])
547 * +-+ sys_div (0x30e [2:0], special values:
550 * +-+ sys_sel (0x3032 [7], 0: PLL1, 1: PLL2)
552 * +-+ sclk_sel (0x3033 [1], 0: sys_sel, 1: PLL2 DAC_CLK)
554 * +-+ sclk_pre_div (0x3106 [3:2], special values:
557 * +-+ sclk_div (0x3106 [7:4], special values: 0: 1)
559 * +-> SCLK
598 * General formulas for (array-centered) mode calculation:
599 * - photo_array_width = 3296
600 * - crop_start_x = (photo_array_width - output_size_x) / 2
601 * - crop_end_x = crop_start_x + offset_x + output_size_x - 1
603 * - photo_array_height = 2480
604 * - crop_start_y = (photo_array_height - output_size_y) / 2
605 * - crop_end_y = crop_start_y + offset_y + output_size_y - 1
1351 struct i2c_client *client = sensor->i2c_client; in ov8865_read()
1356 dev_dbg(&client->dev, "i2c send error at address %#04x\n", in ov8865_read()
1363 dev_dbg(&client->dev, "i2c recv error at address %#04x\n", in ov8865_read()
1374 struct i2c_client *client = sensor->i2c_client; in ov8865_write()
1379 dev_dbg(&client->dev, "i2c send error at address %#04x\n", in ov8865_write()
1430 static int ov8865_sw_standby(struct ov8865_sensor *sensor, int standby) in ov8865_sw_standby() argument
1434 if (!standby) in ov8865_sw_standby()
1456 dev_err(sensor->dev, in ov8865_chip_id_check()
1459 return -EINVAL; in ov8865_chip_id_check()
1475 &sensor->endpoint.bus.mipi_csi2; in ov8865_mipi_configure()
1476 unsigned int lanes_count = bus_mipi_csi2->num_data_lanes; in ov8865_mipi_configure()
1572 config = sensor->pll_configs->pll1_config; in ov8865_mode_pll1_rate()
1573 pll1_rate = sensor->extclk_rate * config->pll_mul / config->pll_pre_div_half; in ov8865_mode_pll1_rate()
1575 switch (config->pll_pre_div) { in ov8865_mode_pll1_rate()
1596 pll1_rate /= config->pll_pre_div; in ov8865_mode_pll1_rate()
1611 config = sensor->pll_configs->pll1_config; in ov8865_mode_pll1_configure()
1618 return -EINVAL; in ov8865_mode_pll1_configure()
1626 OV8865_PLL_CTRLA_PRE_DIV_HALF(config->pll_pre_div_half)); in ov8865_mode_pll1_configure()
1631 OV8865_PLL_CTRL0_PRE_DIV(config->pll_pre_div)); in ov8865_mode_pll1_configure()
1636 OV8865_PLL_CTRL1_MUL_H(config->pll_mul)); in ov8865_mode_pll1_configure()
1641 OV8865_PLL_CTRL2_MUL_L(config->pll_mul)); in ov8865_mode_pll1_configure()
1646 OV8865_PLL_CTRL3_M_DIV(config->m_div)); in ov8865_mode_pll1_configure()
1651 OV8865_PLL_CTRL4_MIPI_DIV(config->mipi_div)); in ov8865_mode_pll1_configure()
1657 OV8865_PCLK_SEL_PCLK_DIV(config->pclk_div)); in ov8865_mode_pll1_configure()
1662 OV8865_PLL_CTRL5_SYS_PRE_DIV(config->sys_pre_div)); in ov8865_mode_pll1_configure()
1667 OV8865_PLL_CTRL6_SYS_DIV(config->sys_div)); in ov8865_mode_pll1_configure()
1682 config = mode->pll2_binning ? sensor->pll_configs->pll2_config_binning : in ov8865_mode_pll2_configure()
1683 sensor->pll_configs->pll2_config_native; in ov8865_mode_pll2_configure()
1686 OV8865_PLL_CTRL12_PRE_DIV_HALF(config->pll_pre_div_half) | in ov8865_mode_pll2_configure()
1687 OV8865_PLL_CTRL12_DAC_DIV(config->dac_div)); in ov8865_mode_pll2_configure()
1692 OV8865_PLL_CTRLB_PRE_DIV(config->pll_pre_div)); in ov8865_mode_pll2_configure()
1697 OV8865_PLL_CTRLC_MUL_H(config->pll_mul)); in ov8865_mode_pll2_configure()
1702 OV8865_PLL_CTRLD_MUL_L(config->pll_mul)); in ov8865_mode_pll2_configure()
1707 OV8865_PLL_CTRLF_SYS_PRE_DIV(config->sys_pre_div)); in ov8865_mode_pll2_configure()
1712 OV8865_PLL_CTRLE_SYS_DIV(config->sys_div)); in ov8865_mode_pll2_configure()
1722 OV8865_CLK_SEL0_PLL1_SYS_SEL(config->sys_sel)); in ov8865_mode_sclk_configure()
1728 OV8865_CLK_SEL1_PLL_SCLK_SEL(config->sclk_sel)); in ov8865_mode_sclk_configure()
1734 OV8865_SCLK_CTRL_SCLK_DIV(config->sclk_div) | in ov8865_mode_sclk_configure()
1735 OV8865_SCLK_CTRL_SCLK_PRE_DIV(config->sclk_pre_div)); in ov8865_mode_sclk_configure()
1751 if (mode->binning_x) in ov8865_mode_binning_configure()
1754 if (mode->binning_y) in ov8865_mode_binning_configure()
1757 if (mode->sync_hbin) in ov8865_mode_binning_configure()
1760 if (mode->horz_var2) in ov8865_mode_binning_configure()
1769 mode->variopixel ? in ov8865_mode_binning_configure()
1774 if (mode->variopixel) { in ov8865_mode_binning_configure()
1776 variopixel_hsub_coef = mode->variopixel_hsub_coef; in ov8865_mode_binning_configure()
1777 variopixel_vsub_coef = mode->variopixel_vsub_coef; in ov8865_mode_binning_configure()
1790 OV8865_INC_X_ODD(mode->inc_x_odd)); in ov8865_mode_binning_configure()
1795 OV8865_INC_X_EVEN(mode->inc_x_even)); in ov8865_mode_binning_configure()
1800 OV8865_INC_Y_ODD(mode->inc_y_odd)); in ov8865_mode_binning_configure()
1805 OV8865_INC_Y_EVEN(mode->inc_y_even)); in ov8865_mode_binning_configure()
1815 mode->blc_col_shift_mask | in ov8865_mode_black_level_configure()
1823 OV8865_BLC_TOP_ZLINE_START(mode->blc_top_zero_line_start)); in ov8865_mode_black_level_configure()
1828 OV8865_BLC_TOP_ZLINE_NUM(mode->blc_top_zero_line_num)); in ov8865_mode_black_level_configure()
1835 OV8865_BLC_TOP_BLKLINE_START(mode->blc_top_black_line_start)); in ov8865_mode_black_level_configure()
1840 OV8865_BLC_TOP_BLKLINE_NUM(mode->blc_top_black_line_num)); in ov8865_mode_black_level_configure()
1847 OV8865_BLC_BOT_ZLINE_START(mode->blc_bottom_zero_line_start)); in ov8865_mode_black_level_configure()
1852 OV8865_BLC_BOT_ZLINE_NUM(mode->blc_bottom_zero_line_num)); in ov8865_mode_black_level_configure()
1859 OV8865_BLC_BOT_BLKLINE_START(mode->blc_bottom_black_line_start)); in ov8865_mode_black_level_configure()
1864 OV8865_BLC_BOT_BLKLINE_NUM(mode->blc_bottom_black_line_num)); in ov8865_mode_black_level_configure()
1871 OV8865_BLC_ANCHOR_LEFT_START_H(mode->blc_anchor_left_start)); in ov8865_mode_black_level_configure()
1876 OV8865_BLC_ANCHOR_LEFT_START_L(mode->blc_anchor_left_start)); in ov8865_mode_black_level_configure()
1881 OV8865_BLC_ANCHOR_LEFT_END_H(mode->blc_anchor_left_end)); in ov8865_mode_black_level_configure()
1886 OV8865_BLC_ANCHOR_LEFT_END_L(mode->blc_anchor_left_end)); in ov8865_mode_black_level_configure()
1891 OV8865_BLC_ANCHOR_RIGHT_START_H(mode->blc_anchor_right_start)); in ov8865_mode_black_level_configure()
1896 OV8865_BLC_ANCHOR_RIGHT_START_L(mode->blc_anchor_right_start)); in ov8865_mode_black_level_configure()
1901 OV8865_BLC_ANCHOR_RIGHT_END_H(mode->blc_anchor_right_end)); in ov8865_mode_black_level_configure()
1906 OV8865_BLC_ANCHOR_RIGHT_END_L(mode->blc_anchor_right_end)); in ov8865_mode_black_level_configure()
1917 OV8865_OUTPUT_SIZE_X_H(mode->output_size_x)); in ov8865_mode_configure()
1922 OV8865_OUTPUT_SIZE_X_L(mode->output_size_x)); in ov8865_mode_configure()
1928 ret = ov8865_write(sensor, OV8865_HTS_H_REG, OV8865_HTS_H(mode->hts)); in ov8865_mode_configure()
1932 ret = ov8865_write(sensor, OV8865_HTS_L_REG, OV8865_HTS_L(mode->hts)); in ov8865_mode_configure()
1939 OV8865_OUTPUT_SIZE_Y_H(mode->output_size_y)); in ov8865_mode_configure()
1944 OV8865_OUTPUT_SIZE_Y_L(mode->output_size_y)); in ov8865_mode_configure()
1950 ret = ov8865_write(sensor, OV8865_VTS_H_REG, OV8865_VTS_H(mode->vts)); in ov8865_mode_configure()
1954 ret = ov8865_write(sensor, OV8865_VTS_L_REG, OV8865_VTS_L(mode->vts)); in ov8865_mode_configure()
1958 if (mode->size_auto) { in ov8865_mode_configure()
1972 OV8865_AUTO_SIZE_BOUNDARIES_Y(mode->size_auto_boundary_y) | in ov8865_mode_configure()
1973 OV8865_AUTO_SIZE_BOUNDARIES_X(mode->size_auto_boundary_x)); in ov8865_mode_configure()
1980 OV8865_CROP_START_X_H(mode->crop_start_x)); in ov8865_mode_configure()
1985 OV8865_CROP_START_X_L(mode->crop_start_x)); in ov8865_mode_configure()
1992 OV8865_OFFSET_X_H(mode->offset_x)); in ov8865_mode_configure()
1997 OV8865_OFFSET_X_L(mode->offset_x)); in ov8865_mode_configure()
2004 OV8865_CROP_END_X_H(mode->crop_end_x)); in ov8865_mode_configure()
2009 OV8865_CROP_END_X_L(mode->crop_end_x)); in ov8865_mode_configure()
2016 OV8865_CROP_START_Y_H(mode->crop_start_y)); in ov8865_mode_configure()
2021 OV8865_CROP_START_Y_L(mode->crop_start_y)); in ov8865_mode_configure()
2028 OV8865_OFFSET_Y_H(mode->offset_y)); in ov8865_mode_configure()
2033 OV8865_OFFSET_Y_L(mode->offset_y)); in ov8865_mode_configure()
2040 OV8865_CROP_END_Y_H(mode->crop_end_y)); in ov8865_mode_configure()
2045 OV8865_CROP_END_Y_L(mode->crop_end_y)); in ov8865_mode_configure()
2053 OV8865_VFIFO_READ_START_H(mode->vfifo_read_start)); in ov8865_mode_configure()
2058 OV8865_VFIFO_READ_START_L(mode->vfifo_read_start)); in ov8865_mode_configure()
2063 OV8865_ABLC_NUM(mode->ablc_num)); in ov8865_mode_configure()
2068 OV8865_ZLINE_NUM(mode->zline_num)); in ov8865_mode_configure()
2100 if (mode->register_values) { in ov8865_mode_configure()
2101 ret = ov8865_write_sequence(sensor, mode->register_values, in ov8865_mode_configure()
2102 mode->register_values_count); in ov8865_mode_configure()
2116 config = sensor->pll_configs->pll1_config; in ov8865_mode_mipi_clk_rate()
2120 return pll1_rate / config->m_div / 2; in ov8865_mode_mipi_clk_rate()
2217 return -EINVAL; in ov8865_test_pattern_configure()
2227 u16 vts = sensor->state.mode->output_size_y + vblank; in ov8865_vts_configure()
2243 struct ov8865_ctrls *ctrls = &sensor->ctrls; in ov8865_state_mipi_configure()
2245 &sensor->endpoint.bus.mipi_csi2; in ov8865_state_mipi_configure()
2254 return -EINVAL; in ov8865_state_mipi_configure()
2263 for (j = 0; j < sensor->endpoint.nr_of_link_frequencies; j++) { in ov8865_state_mipi_configure()
2264 u64 freq = sensor->endpoint.link_frequencies[j]; in ov8865_state_mipi_configure()
2271 dev_err(sensor->dev, in ov8865_state_mipi_configure()
2274 } else if (j == sensor->endpoint.nr_of_link_frequencies) { in ov8865_state_mipi_configure()
2275 dev_err(sensor->dev, in ov8865_state_mipi_configure()
2276 "failed to find %lu clk rate in endpoint link-frequencies\n", in ov8865_state_mipi_configure()
2279 __v4l2_ctrl_s_ctrl(ctrls->link_freq, i); in ov8865_state_mipi_configure()
2287 return -EINVAL; in ov8865_state_mipi_configure()
2290 lanes_count = bus_mipi_csi2->num_data_lanes; in ov8865_state_mipi_configure()
2293 __v4l2_ctrl_s_ctrl_int64(ctrls->pixel_rate, mipi_pixel_rate); in ov8865_state_mipi_configure()
2304 if (sensor->state.streaming) in ov8865_state_configure()
2305 return -EBUSY; in ov8865_state_configure()
2308 if (pm_runtime_enabled(sensor->dev) && in ov8865_state_configure()
2309 !pm_runtime_suspended(sensor->dev)) { in ov8865_state_configure()
2319 sensor->state.mode = mode; in ov8865_state_configure()
2320 sensor->state.mbus_code = mbus_code; in ov8865_state_configure()
2339 dev_err(sensor->dev, "failed to perform sw reset\n"); in ov8865_sensor_init()
2345 dev_err(sensor->dev, "failed to set sensor standby\n"); in ov8865_sensor_init()
2351 dev_err(sensor->dev, "failed to check sensor chip id\n"); in ov8865_sensor_init()
2358 dev_err(sensor->dev, "failed to write init sequence\n"); in ov8865_sensor_init()
2364 dev_err(sensor->dev, "failed to configure pad\n"); in ov8865_sensor_init()
2370 dev_err(sensor->dev, "failed to configure MIPI\n"); in ov8865_sensor_init()
2376 dev_err(sensor->dev, "failed to configure ISP\n"); in ov8865_sensor_init()
2382 dev_err(sensor->dev, "failed to configure black level\n"); in ov8865_sensor_init()
2387 ret = ov8865_state_configure(sensor, sensor->state.mode, in ov8865_sensor_init()
2388 sensor->state.mbus_code); in ov8865_sensor_init()
2390 dev_err(sensor->dev, "failed to configure state\n"); in ov8865_sensor_init()
2403 gpiod_set_value_cansleep(sensor->reset, 1); in ov8865_sensor_power()
2404 gpiod_set_value_cansleep(sensor->powerdown, 1); in ov8865_sensor_power()
2406 ret = regulator_enable(sensor->dovdd); in ov8865_sensor_power()
2408 dev_err(sensor->dev, in ov8865_sensor_power()
2413 ret = regulator_enable(sensor->avdd); in ov8865_sensor_power()
2415 dev_err(sensor->dev, in ov8865_sensor_power()
2420 ret = regulator_enable(sensor->dvdd); in ov8865_sensor_power()
2422 dev_err(sensor->dev, in ov8865_sensor_power()
2427 ret = clk_prepare_enable(sensor->extclk); in ov8865_sensor_power()
2429 dev_err(sensor->dev, "failed to enable EXTCLK clock\n"); in ov8865_sensor_power()
2433 gpiod_set_value_cansleep(sensor->reset, 0); in ov8865_sensor_power()
2434 gpiod_set_value_cansleep(sensor->powerdown, 0); in ov8865_sensor_power()
2439 gpiod_set_value_cansleep(sensor->powerdown, 1); in ov8865_sensor_power()
2440 gpiod_set_value_cansleep(sensor->reset, 1); in ov8865_sensor_power()
2442 clk_disable_unprepare(sensor->extclk); in ov8865_sensor_power()
2445 regulator_disable(sensor->dvdd); in ov8865_sensor_power()
2447 regulator_disable(sensor->avdd); in ov8865_sensor_power()
2449 regulator_disable(sensor->dovdd); in ov8865_sensor_power()
2465 if (ctrl->id == V4L2_CID_VBLANK) { in ov8865_s_ctrl()
2468 exposure_max = sensor->state.mode->output_size_y + ctrl->val - in ov8865_s_ctrl()
2470 __v4l2_ctrl_modify_range(sensor->ctrls.exposure, in ov8865_s_ctrl()
2471 sensor->ctrls.exposure->minimum, in ov8865_s_ctrl()
2473 sensor->ctrls.exposure->step, in ov8865_s_ctrl()
2474 min(sensor->ctrls.exposure->val, in ov8865_s_ctrl()
2479 if (pm_runtime_suspended(sensor->dev)) in ov8865_s_ctrl()
2482 switch (ctrl->id) { in ov8865_s_ctrl()
2484 ret = ov8865_exposure_configure(sensor, ctrl->val); in ov8865_s_ctrl()
2489 ret = ov8865_analog_gain_configure(sensor, ctrl->val); in ov8865_s_ctrl()
2494 return ov8865_red_balance_configure(sensor, ctrl->val); in ov8865_s_ctrl()
2496 return ov8865_blue_balance_configure(sensor, ctrl->val); in ov8865_s_ctrl()
2498 return ov8865_flip_horz_configure(sensor, !!ctrl->val); in ov8865_s_ctrl()
2500 return ov8865_flip_vert_configure(sensor, !!ctrl->val); in ov8865_s_ctrl()
2502 index = (unsigned int)ctrl->val; in ov8865_s_ctrl()
2505 return ov8865_vts_configure(sensor, ctrl->val); in ov8865_s_ctrl()
2507 return -EINVAL; in ov8865_s_ctrl()
2519 struct ov8865_ctrls *ctrls = &sensor->ctrls; in ov8865_ctrls_init()
2520 struct v4l2_ctrl_handler *handler = &ctrls->handler; in ov8865_ctrls_init()
2531 handler->lock = &sensor->mutex; in ov8865_ctrls_init()
2535 ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 2, in ov8865_ctrls_init()
2559 ARRAY_SIZE(ov8865_test_pattern_menu) - 1, in ov8865_ctrls_init()
2563 hblank = mode->hts - mode->output_size_x; in ov8865_ctrls_init()
2564 ctrls->hblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_HBLANK, hblank, in ov8865_ctrls_init()
2567 if (ctrls->hblank) in ov8865_ctrls_init()
2568 ctrls->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; in ov8865_ctrls_init()
2570 vblank_max = OV8865_TIMING_MAX_VTS - mode->output_size_y; in ov8865_ctrls_init()
2571 vblank_def = mode->vts - mode->output_size_y; in ov8865_ctrls_init()
2572 ctrls->vblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_VBLANK, in ov8865_ctrls_init()
2576 /* MIPI CSI-2 */ in ov8865_ctrls_init()
2578 ctrls->link_freq = in ov8865_ctrls_init()
2580 ARRAY_SIZE(ov8865_link_freq_menu) - 1, in ov8865_ctrls_init()
2583 ctrls->pixel_rate = in ov8865_ctrls_init()
2588 ret = v4l2_fwnode_device_parse(sensor->dev, &props); in ov8865_ctrls_init()
2596 if (handler->error) { in ov8865_ctrls_init()
2597 ret = handler->error; in ov8865_ctrls_init()
2601 ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in ov8865_ctrls_init()
2602 ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY; in ov8865_ctrls_init()
2604 sensor->subdev.ctrl_handler = handler; in ov8865_ctrls_init()
2619 struct ov8865_state *state = &sensor->state; in ov8865_s_stream()
2623 ret = pm_runtime_resume_and_get(sensor->dev); in ov8865_s_stream()
2628 mutex_lock(&sensor->mutex); in ov8865_s_stream()
2630 mutex_unlock(&sensor->mutex); in ov8865_s_stream()
2635 state->streaming = !!enable; in ov8865_s_stream()
2638 pm_runtime_put(sensor->dev); in ov8865_s_stream()
2653 if (code_enum->index >= ARRAY_SIZE(ov8865_mbus_codes)) in ov8865_enum_mbus_code()
2654 return -EINVAL; in ov8865_enum_mbus_code()
2656 code_enum->code = ov8865_mbus_codes[code_enum->index]; in ov8865_enum_mbus_code()
2665 mbus_format->width = mode->output_size_x; in ov8865_mbus_format_fill()
2666 mbus_format->height = mode->output_size_y; in ov8865_mbus_format_fill()
2667 mbus_format->code = mbus_code; in ov8865_mbus_format_fill()
2669 mbus_format->field = V4L2_FIELD_NONE; in ov8865_mbus_format_fill()
2670 mbus_format->colorspace = V4L2_COLORSPACE_RAW; in ov8865_mbus_format_fill()
2671 mbus_format->ycbcr_enc = in ov8865_mbus_format_fill()
2672 V4L2_MAP_YCBCR_ENC_DEFAULT(mbus_format->colorspace); in ov8865_mbus_format_fill()
2673 mbus_format->quantization = V4L2_QUANTIZATION_FULL_RANGE; in ov8865_mbus_format_fill()
2674 mbus_format->xfer_func = in ov8865_mbus_format_fill()
2675 V4L2_MAP_XFER_FUNC_DEFAULT(mbus_format->colorspace); in ov8865_mbus_format_fill()
2683 struct v4l2_mbus_framefmt *mbus_format = &format->format; in ov8865_get_fmt()
2685 mutex_lock(&sensor->mutex); in ov8865_get_fmt()
2687 if (format->which == V4L2_SUBDEV_FORMAT_TRY) in ov8865_get_fmt()
2689 format->pad); in ov8865_get_fmt()
2691 ov8865_mbus_format_fill(mbus_format, sensor->state.mbus_code, in ov8865_get_fmt()
2692 sensor->state.mode); in ov8865_get_fmt()
2694 mutex_unlock(&sensor->mutex); in ov8865_get_fmt()
2704 struct v4l2_mbus_framefmt *mbus_format = &format->format; in ov8865_set_fmt()
2712 mutex_lock(&sensor->mutex); in ov8865_set_fmt()
2714 if (sensor->state.streaming) { in ov8865_set_fmt()
2715 ret = -EBUSY; in ov8865_set_fmt()
2721 if (ov8865_mbus_codes[index] == mbus_format->code) { in ov8865_set_fmt()
2722 mbus_code = mbus_format->code; in ov8865_set_fmt()
2734 mbus_format->width, mbus_format->height); in ov8865_set_fmt()
2736 ret = -EINVAL; in ov8865_set_fmt()
2742 if (format->which == V4L2_SUBDEV_FORMAT_TRY) in ov8865_set_fmt()
2743 *v4l2_subdev_state_get_format(sd_state, format->pad) = in ov8865_set_fmt()
2745 else if (sensor->state.mode != mode || in ov8865_set_fmt()
2746 sensor->state.mbus_code != mbus_code) in ov8865_set_fmt()
2749 __v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV8865_TIMING_MIN_VTS, in ov8865_set_fmt()
2750 OV8865_TIMING_MAX_VTS - mode->output_size_y, in ov8865_set_fmt()
2751 1, mode->vts - mode->output_size_y); in ov8865_set_fmt()
2753 hblank = mode->hts - mode->output_size_x; in ov8865_set_fmt()
2754 __v4l2_ctrl_modify_range(sensor->ctrls.hblank, hblank, hblank, 1, in ov8865_set_fmt()
2757 exposure_max = mode->vts - OV8865_INTEGRATION_TIME_MARGIN; in ov8865_set_fmt()
2758 __v4l2_ctrl_modify_range(sensor->ctrls.exposure, in ov8865_set_fmt()
2759 sensor->ctrls.exposure->minimum, exposure_max, in ov8865_set_fmt()
2760 sensor->ctrls.exposure->step, in ov8865_set_fmt()
2761 min(sensor->ctrls.exposure->val, in ov8865_set_fmt()
2765 mutex_unlock(&sensor->mutex); in ov8865_set_fmt()
2776 if (size_enum->index >= ARRAY_SIZE(ov8865_modes)) in ov8865_enum_frame_size()
2777 return -EINVAL; in ov8865_enum_frame_size()
2779 mode = &ov8865_modes[size_enum->index]; in ov8865_enum_frame_size()
2781 size_enum->min_width = size_enum->max_width = mode->output_size_x; in ov8865_enum_frame_size()
2782 size_enum->min_height = size_enum->max_height = mode->output_size_y; in ov8865_enum_frame_size()
2792 const struct ov8865_mode *mode = sensor->state.mode; in __ov8865_get_pad_crop()
2799 r->height = mode->output_size_y; in __ov8865_get_pad_crop()
2800 r->width = mode->output_size_x; in __ov8865_get_pad_crop()
2801 r->top = (OV8865_NATIVE_HEIGHT - mode->output_size_y) / 2; in __ov8865_get_pad_crop()
2802 r->left = (OV8865_NATIVE_WIDTH - mode->output_size_x) / 2; in __ov8865_get_pad_crop()
2813 switch (sel->target) { in ov8865_get_selection()
2815 mutex_lock(&sensor->mutex); in ov8865_get_selection()
2816 __ov8865_get_pad_crop(sensor, state, sel->pad, in ov8865_get_selection()
2817 sel->which, &sel->r); in ov8865_get_selection()
2818 mutex_unlock(&sensor->mutex); in ov8865_get_selection()
2821 sel->r.top = 0; in ov8865_get_selection()
2822 sel->r.left = 0; in ov8865_get_selection()
2823 sel->r.width = OV8865_NATIVE_WIDTH; in ov8865_get_selection()
2824 sel->r.height = OV8865_NATIVE_HEIGHT; in ov8865_get_selection()
2828 sel->r.top = OV8865_ACTIVE_START_TOP; in ov8865_get_selection()
2829 sel->r.left = OV8865_ACTIVE_START_LEFT; in ov8865_get_selection()
2830 sel->r.width = OV8865_ACTIVE_WIDTH; in ov8865_get_selection()
2831 sel->r.height = OV8865_ACTIVE_HEIGHT; in ov8865_get_selection()
2834 return -EINVAL; in ov8865_get_selection()
2853 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE) in ov8865_get_frame_interval()
2854 return -EINVAL; in ov8865_get_frame_interval()
2856 mutex_lock(&sensor->mutex); in ov8865_get_frame_interval()
2858 mode = sensor->state.mode; in ov8865_get_frame_interval()
2859 framesize = mode->hts * (mode->output_size_y + in ov8865_get_frame_interval()
2860 sensor->ctrls.vblank->val); in ov8865_get_frame_interval()
2861 fps = DIV_ROUND_CLOSEST(sensor->ctrls.pixel_rate->val, framesize); in ov8865_get_frame_interval()
2863 interval->interval.numerator = 1; in ov8865_get_frame_interval()
2864 interval->interval.denominator = fps; in ov8865_get_frame_interval()
2866 mutex_unlock(&sensor->mutex); in ov8865_get_frame_interval()
2892 struct ov8865_state *state = &sensor->state; in ov8865_suspend()
2895 mutex_lock(&sensor->mutex); in ov8865_suspend()
2897 if (state->streaming) { in ov8865_suspend()
2908 mutex_unlock(&sensor->mutex); in ov8865_suspend()
2918 struct ov8865_state *state = &sensor->state; in ov8865_resume()
2921 mutex_lock(&sensor->mutex); in ov8865_resume()
2931 ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); in ov8865_resume()
2935 if (state->streaming) { in ov8865_resume()
2947 mutex_unlock(&sensor->mutex); in ov8865_resume()
2954 struct device *dev = &client->dev; in ov8865_probe()
2965 return -ENOMEM; in ov8865_probe()
2967 sensor->dev = dev; in ov8865_probe()
2968 sensor->i2c_client = client; in ov8865_probe()
2973 sensor->dvdd = devm_regulator_get(dev, "dvdd"); in ov8865_probe()
2974 if (IS_ERR(sensor->dvdd)) in ov8865_probe()
2975 return dev_err_probe(dev, PTR_ERR(sensor->dvdd), in ov8865_probe()
2979 sensor->dovdd = devm_regulator_get(dev, "dovdd"); in ov8865_probe()
2980 if (IS_ERR(sensor->dovdd)) in ov8865_probe()
2981 return dev_err_probe(dev, PTR_ERR(sensor->dovdd), in ov8865_probe()
2985 sensor->avdd = devm_regulator_get(dev, "avdd"); in ov8865_probe()
2986 if (IS_ERR(sensor->avdd)) in ov8865_probe()
2987 return dev_err_probe(dev, PTR_ERR(sensor->avdd), in ov8865_probe()
2994 return -EPROBE_DEFER; in ov8865_probe()
2996 sensor->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY; in ov8865_probe()
2998 ret = v4l2_fwnode_endpoint_alloc_parse(handle, &sensor->endpoint); in ov8865_probe()
3007 sensor->powerdown = devm_gpiod_get_optional(dev, "powerdown", in ov8865_probe()
3009 if (IS_ERR(sensor->powerdown)) { in ov8865_probe()
3010 ret = PTR_ERR(sensor->powerdown); in ov8865_probe()
3014 sensor->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); in ov8865_probe()
3015 if (IS_ERR(sensor->reset)) { in ov8865_probe()
3016 ret = PTR_ERR(sensor->reset); in ov8865_probe()
3022 sensor->extclk = devm_clk_get(dev, NULL); in ov8865_probe()
3023 if (PTR_ERR(sensor->extclk) == -ENOENT) { in ov8865_probe()
3025 sensor->extclk = NULL; in ov8865_probe()
3026 } else if (IS_ERR(sensor->extclk)) { in ov8865_probe()
3028 ret = PTR_ERR(sensor->extclk); in ov8865_probe()
3035 * have an external clock AND a clock-frequency property. Check for the in ov8865_probe()
3036 * clock-frequency property and if found, set that rate if we managed in ov8865_probe()
3041 ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency", in ov8865_probe()
3043 if (!ret && sensor->extclk) { in ov8865_probe()
3044 ret = clk_set_rate(sensor->extclk, rate); in ov8865_probe()
3049 } else if (ret && !sensor->extclk) { in ov8865_probe()
3054 sensor->extclk_rate = rate ? rate : clk_get_rate(sensor->extclk); in ov8865_probe()
3057 if (sensor->extclk_rate == supported_extclk_rates[i]) in ov8865_probe()
3063 sensor->extclk_rate); in ov8865_probe()
3064 ret = -EINVAL; in ov8865_probe()
3068 sensor->pll_configs = ov8865_pll_configs[i]; in ov8865_probe()
3072 subdev = &sensor->subdev; in ov8865_probe()
3075 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in ov8865_probe()
3076 subdev->entity.function = MEDIA_ENT_F_CAM_SENSOR; in ov8865_probe()
3078 pad = &sensor->pad; in ov8865_probe()
3079 pad->flags = MEDIA_PAD_FL_SOURCE; in ov8865_probe()
3081 ret = media_entity_pads_init(&subdev->entity, 1, pad); in ov8865_probe()
3087 mutex_init(&sensor->mutex); in ov8865_probe()
3095 mutex_lock(&sensor->mutex); in ov8865_probe()
3097 mutex_unlock(&sensor->mutex); in ov8865_probe()
3103 pm_runtime_set_suspended(sensor->dev); in ov8865_probe()
3104 pm_runtime_enable(sensor->dev); in ov8865_probe()
3115 pm_runtime_disable(sensor->dev); in ov8865_probe()
3118 v4l2_ctrl_handler_free(&sensor->ctrls.handler); in ov8865_probe()
3121 mutex_destroy(&sensor->mutex); in ov8865_probe()
3124 media_entity_cleanup(&sensor->subdev.entity); in ov8865_probe()
3127 v4l2_fwnode_endpoint_free(&sensor->endpoint); in ov8865_probe()
3138 pm_runtime_disable(sensor->dev); in ov8865_remove()
3139 v4l2_ctrl_handler_free(&sensor->ctrls.handler); in ov8865_remove()
3140 mutex_destroy(&sensor->mutex); in ov8865_remove()
3141 media_entity_cleanup(&subdev->entity); in ov8865_remove()
3143 v4l2_fwnode_endpoint_free(&sensor->endpoint); in ov8865_remove()