Lines Matching +full:sensor +full:- +full:gain
1 // SPDX-License-Identifier: GPL-2.0-or-later
16 #include <media/v4l2-ctrls.h>
17 #include <media/v4l2-device.h>
18 #include <media/v4l2-fwnode.h>
19 #include <media/v4l2-image-sizes.h>
20 #include <media/v4l2-mediabus.h>
84 #define OV5648_PLL_DIV_ROOT_DIV(v) ((((v) - 1) << 4) & BIT(4))
97 #define OV5648_PLLS_DIV_PLLS_DIV_R(v) ((((v) - 1) << 2) & BIT(2))
117 /* Exposure/gain/banding */
335 /* MIPI CSI-2 */
499 (&container_of((c)->handler, struct ov5648_sensor, \
500 ctrls.handler)->subdev)
513 * +-< XVCLK
515 * +-+ pll_pre_div (0x3037 [3:0], special values: 5: 1.5, 7: 2.5)
517 * +-+ pll_mul (0x3036 [7:0])
519 * +-+ sys_div (0x3035 [7:4])
521 * +-+ mipi_div (0x3035 [3:0])
523 * | +-> MIPI_SCLK
525 * | +-+ mipi_phy_div (2)
527 * | +-> MIPI_CLK
529 * +-+ root_div (0x3037 [4])
531 * +-+ bit_div (0x3034 [3:0], 8 bits: 2, 10 bits: 2.5, other: 1)
533 * +-+ sclk_div (0x3106 [3:2])
535 * +-> SCLK
537 * +-+ mipi_div (0x3035, 1: PCLK = SCLK)
539 * +-> PCLK
554 * +-< XVCLK
556 * +-+ plls_pre_div (0x303d [5:4], special values: 0: 1, 1: 1.5)
558 * +-+ plls_div_r (0x303d [2])
560 * +-+ plls_mul (0x303b [4:0])
562 * +-+ sys_div (0x303c [3:0])
564 * +-+ sel_div (0x303d [1:0], special values: 0: 1, 3: 2.5)
566 * +-> ADCLK
578 * General formulas for (array-centered) mode calculation:
579 * - photo_array_width = 2624
580 * - crop_start_x = (photo_array_width - output_size_x) / 2
581 * - crop_end_x = crop_start_x + offset_x + output_size_x - 1
583 * - photo_array_height = 1956
584 * - crop_start_y = (photo_array_height - output_size_y) / 2
585 * - crop_end_y = crop_start_y + offset_y + output_size_y - 1
609 /* 8-bit frame interval followed by 10-bit frame interval. */
612 /* 8-bit config followed by 10-bit config. */
632 struct v4l2_ctrl *gain; member
966 static int ov5648_read(struct ov5648_sensor *sensor, u16 address, u8 *value) in ov5648_read() argument
969 struct i2c_client *client = sensor->i2c_client; in ov5648_read()
974 dev_dbg(&client->dev, "i2c send error at address %#04x\n", in ov5648_read()
981 dev_dbg(&client->dev, "i2c recv error at address %#04x\n", in ov5648_read()
989 static int ov5648_write(struct ov5648_sensor *sensor, u16 address, u8 value) in ov5648_write() argument
992 struct i2c_client *client = sensor->i2c_client; in ov5648_write()
997 dev_dbg(&client->dev, "i2c send error at address %#04x\n", in ov5648_write()
1005 static int ov5648_write_sequence(struct ov5648_sensor *sensor, in ov5648_write_sequence() argument
1013 ret = ov5648_write(sensor, sequence[i].address, in ov5648_write_sequence()
1025 static int ov5648_update_bits(struct ov5648_sensor *sensor, u16 address, in ov5648_update_bits() argument
1031 ret = ov5648_read(sensor, address, &value); in ov5648_update_bits()
1038 ret = ov5648_write(sensor, address, value); in ov5648_update_bits()
1045 /* Sensor */
1047 static int ov5648_sw_reset(struct ov5648_sensor *sensor) in ov5648_sw_reset() argument
1049 return ov5648_write(sensor, OV5648_SW_RESET_REG, OV5648_SW_RESET_RESET); in ov5648_sw_reset()
1052 static int ov5648_sw_standby(struct ov5648_sensor *sensor, int standby) in ov5648_sw_standby() argument
1059 return ov5648_write(sensor, OV5648_SW_STANDBY_REG, value); in ov5648_sw_standby()
1062 static int ov5648_chip_id_check(struct ov5648_sensor *sensor) in ov5648_chip_id_check() argument
1071 ret = ov5648_read(sensor, regs[i], &value); in ov5648_chip_id_check()
1076 dev_err(sensor->dev, in ov5648_chip_id_check()
1079 return -EINVAL; in ov5648_chip_id_check()
1086 static int ov5648_avdd_internal_power(struct ov5648_sensor *sensor, int on) in ov5648_avdd_internal_power() argument
1088 return ov5648_write(sensor, OV5648_A_PWC_PK_O0_REG, in ov5648_avdd_internal_power()
1092 static int ov5648_pad_configure(struct ov5648_sensor *sensor) in ov5648_pad_configure() argument
1098 ret = ov5648_write(sensor, OV5648_PAD_OEN1_REG, 0); in ov5648_pad_configure()
1102 ret = ov5648_write(sensor, OV5648_PAD_OEN2_REG, 0); in ov5648_pad_configure()
1108 return ov5648_write(sensor, OV5648_PAD_PK_REG, in ov5648_pad_configure()
1113 static int ov5648_mipi_configure(struct ov5648_sensor *sensor) in ov5648_mipi_configure() argument
1116 &sensor->endpoint.bus.mipi_csi2; in ov5648_mipi_configure()
1117 unsigned int lanes_count = bus_mipi_csi2->num_data_lanes; in ov5648_mipi_configure()
1120 ret = ov5648_write(sensor, OV5648_MIPI_CTRL0_REG, in ov5648_mipi_configure()
1127 return ov5648_write(sensor, OV5648_MIPI_SC_CTRL0_REG, in ov5648_mipi_configure()
1133 static int ov5648_black_level_configure(struct ov5648_sensor *sensor) in ov5648_black_level_configure() argument
1139 ret = ov5648_write(sensor, OV5648_BLC_CTRL1_REG, in ov5648_black_level_configure()
1144 ret = ov5648_write(sensor, OV5648_BLC_CTRL2_REG, in ov5648_black_level_configure()
1150 ret = ov5648_write(sensor, OV5648_BLC_LINE_NUM_REG, in ov5648_black_level_configure()
1155 return ov5648_update_bits(sensor, OV5648_BLC_CTRL5_REG, in ov5648_black_level_configure()
1160 static int ov5648_isp_configure(struct ov5648_sensor *sensor) in ov5648_isp_configure() argument
1169 ret = ov5648_update_bits(sensor, OV5648_ISP_CTRL0_REG, bits, bits); in ov5648_isp_configure()
1174 ret = ov5648_write(sensor, OV5648_ISP_CTRL1_REG, in ov5648_isp_configure()
1179 /* Enable AWB gain and windowing. */ in ov5648_isp_configure()
1180 ret = ov5648_write(sensor, OV5648_ISP_CTRL2_REG, in ov5648_isp_configure()
1186 /* Enable buffering and auto-binning. */ in ov5648_isp_configure()
1187 ret = ov5648_write(sensor, OV5648_ISP_CTRL3_REG, in ov5648_isp_configure()
1193 ret = ov5648_write(sensor, OV5648_ISP_CTRL4_REG, 0); in ov5648_isp_configure()
1197 ret = ov5648_write(sensor, OV5648_ISP_CTRL1F_REG, in ov5648_isp_configure()
1202 /* Enable post-binning filters. */ in ov5648_isp_configure()
1203 ret = ov5648_write(sensor, OV5648_ISP_CTRL4B_REG, in ov5648_isp_configure()
1210 ret = ov5648_write(sensor, OV5648_AEC_CTRL0_REG, in ov5648_isp_configure()
1216 return ov5648_write(sensor, OV5648_MANUAL_CTRL_REG, in ov5648_isp_configure()
1220 static unsigned long ov5648_mode_pll1_rate(struct ov5648_sensor *sensor, in ov5648_mode_pll1_rate() argument
1226 xvclk_rate = clk_get_rate(sensor->xvclk); in ov5648_mode_pll1_rate()
1227 pll1_rate = xvclk_rate * config->pll_mul; in ov5648_mode_pll1_rate()
1229 switch (config->pll_pre_div) { in ov5648_mode_pll1_rate()
1239 pll1_rate /= config->pll_pre_div; in ov5648_mode_pll1_rate()
1246 static int ov5648_mode_pll1_configure(struct ov5648_sensor *sensor, in ov5648_mode_pll1_configure() argument
1258 config = mode->pll1_config[0]; in ov5648_mode_pll1_configure()
1262 config = mode->pll1_config[1]; in ov5648_mode_pll1_configure()
1266 return -EINVAL; in ov5648_mode_pll1_configure()
1269 ret = ov5648_write(sensor, OV5648_PLL_CTRL0_REG, value); in ov5648_mode_pll1_configure()
1273 ret = ov5648_write(sensor, OV5648_PLL_DIV_REG, in ov5648_mode_pll1_configure()
1274 OV5648_PLL_DIV_ROOT_DIV(config->root_div) | in ov5648_mode_pll1_configure()
1275 OV5648_PLL_DIV_PLL_PRE_DIV(config->pll_pre_div)); in ov5648_mode_pll1_configure()
1279 ret = ov5648_write(sensor, OV5648_PLL_MUL_REG, in ov5648_mode_pll1_configure()
1280 OV5648_PLL_MUL(config->pll_mul)); in ov5648_mode_pll1_configure()
1284 ret = ov5648_write(sensor, OV5648_PLL_CTRL1_REG, in ov5648_mode_pll1_configure()
1285 OV5648_PLL_CTRL1_SYS_DIV(config->sys_div) | in ov5648_mode_pll1_configure()
1286 OV5648_PLL_CTRL1_MIPI_DIV(config->mipi_div)); in ov5648_mode_pll1_configure()
1290 return ov5648_write(sensor, OV5648_SRB_CTRL_REG, in ov5648_mode_pll1_configure()
1291 OV5648_SRB_CTRL_SCLK_DIV(config->sclk_div) | in ov5648_mode_pll1_configure()
1295 static int ov5648_mode_pll2_configure(struct ov5648_sensor *sensor, in ov5648_mode_pll2_configure() argument
1298 const struct ov5648_pll2_config *config = mode->pll2_config; in ov5648_mode_pll2_configure()
1301 ret = ov5648_write(sensor, OV5648_PLLS_DIV_REG, in ov5648_mode_pll2_configure()
1302 OV5648_PLLS_DIV_PLLS_PRE_DIV(config->plls_pre_div) | in ov5648_mode_pll2_configure()
1303 OV5648_PLLS_DIV_PLLS_DIV_R(config->plls_div_r) | in ov5648_mode_pll2_configure()
1304 OV5648_PLLS_DIV_PLLS_SEL_DIV(config->sel_div)); in ov5648_mode_pll2_configure()
1308 ret = ov5648_write(sensor, OV5648_PLLS_MUL_REG, in ov5648_mode_pll2_configure()
1309 OV5648_PLLS_MUL(config->plls_mul)); in ov5648_mode_pll2_configure()
1313 return ov5648_write(sensor, OV5648_PLLS_CTRL_REG, in ov5648_mode_pll2_configure()
1315 OV5648_PLLS_CTRL_SYS_DIV(config->sys_div)); in ov5648_mode_pll2_configure()
1318 static int ov5648_mode_configure(struct ov5648_sensor *sensor, in ov5648_mode_configure() argument
1325 ret = ov5648_write(sensor, OV5648_CROP_START_X_H_REG, in ov5648_mode_configure()
1326 OV5648_CROP_START_X_H(mode->crop_start_x)); in ov5648_mode_configure()
1330 ret = ov5648_write(sensor, OV5648_CROP_START_X_L_REG, in ov5648_mode_configure()
1331 OV5648_CROP_START_X_L(mode->crop_start_x)); in ov5648_mode_configure()
1337 ret = ov5648_write(sensor, OV5648_OFFSET_X_H_REG, in ov5648_mode_configure()
1338 OV5648_OFFSET_X_H(mode->offset_x)); in ov5648_mode_configure()
1342 ret = ov5648_write(sensor, OV5648_OFFSET_X_L_REG, in ov5648_mode_configure()
1343 OV5648_OFFSET_X_L(mode->offset_x)); in ov5648_mode_configure()
1349 ret = ov5648_write(sensor, OV5648_OUTPUT_SIZE_X_H_REG, in ov5648_mode_configure()
1350 OV5648_OUTPUT_SIZE_X_H(mode->output_size_x)); in ov5648_mode_configure()
1354 ret = ov5648_write(sensor, OV5648_OUTPUT_SIZE_X_L_REG, in ov5648_mode_configure()
1355 OV5648_OUTPUT_SIZE_X_L(mode->output_size_x)); in ov5648_mode_configure()
1361 ret = ov5648_write(sensor, OV5648_CROP_END_X_H_REG, in ov5648_mode_configure()
1362 OV5648_CROP_END_X_H(mode->crop_end_x)); in ov5648_mode_configure()
1366 ret = ov5648_write(sensor, OV5648_CROP_END_X_L_REG, in ov5648_mode_configure()
1367 OV5648_CROP_END_X_L(mode->crop_end_x)); in ov5648_mode_configure()
1373 ret = ov5648_write(sensor, OV5648_HTS_H_REG, OV5648_HTS_H(mode->hts)); in ov5648_mode_configure()
1377 ret = ov5648_write(sensor, OV5648_HTS_L_REG, OV5648_HTS_L(mode->hts)); in ov5648_mode_configure()
1383 ret = ov5648_write(sensor, OV5648_CROP_START_Y_H_REG, in ov5648_mode_configure()
1384 OV5648_CROP_START_Y_H(mode->crop_start_y)); in ov5648_mode_configure()
1388 ret = ov5648_write(sensor, OV5648_CROP_START_Y_L_REG, in ov5648_mode_configure()
1389 OV5648_CROP_START_Y_L(mode->crop_start_y)); in ov5648_mode_configure()
1395 ret = ov5648_write(sensor, OV5648_OFFSET_Y_H_REG, in ov5648_mode_configure()
1396 OV5648_OFFSET_Y_H(mode->offset_y)); in ov5648_mode_configure()
1400 ret = ov5648_write(sensor, OV5648_OFFSET_Y_L_REG, in ov5648_mode_configure()
1401 OV5648_OFFSET_Y_L(mode->offset_y)); in ov5648_mode_configure()
1407 ret = ov5648_write(sensor, OV5648_OUTPUT_SIZE_Y_H_REG, in ov5648_mode_configure()
1408 OV5648_OUTPUT_SIZE_Y_H(mode->output_size_y)); in ov5648_mode_configure()
1412 ret = ov5648_write(sensor, OV5648_OUTPUT_SIZE_Y_L_REG, in ov5648_mode_configure()
1413 OV5648_OUTPUT_SIZE_Y_L(mode->output_size_y)); in ov5648_mode_configure()
1419 ret = ov5648_write(sensor, OV5648_CROP_END_Y_H_REG, in ov5648_mode_configure()
1420 OV5648_CROP_END_Y_H(mode->crop_end_y)); in ov5648_mode_configure()
1424 ret = ov5648_write(sensor, OV5648_CROP_END_Y_L_REG, in ov5648_mode_configure()
1425 OV5648_CROP_END_Y_L(mode->crop_end_y)); in ov5648_mode_configure()
1431 ret = ov5648_write(sensor, OV5648_VTS_H_REG, OV5648_VTS_H(mode->vts)); in ov5648_mode_configure()
1435 ret = ov5648_write(sensor, OV5648_VTS_L_REG, OV5648_VTS_L(mode->vts)); in ov5648_mode_configure()
1445 ret = ov5648_update_bits(sensor, OV5648_TC20_REG, in ov5648_mode_configure()
1448 mode->binning_y ? OV5648_TC20_BINNING_VERT_EN : in ov5648_mode_configure()
1453 ret = ov5648_update_bits(sensor, OV5648_TC21_REG, in ov5648_mode_configure()
1455 mode->binning_x ? OV5648_TC21_BINNING_HORZ_EN : in ov5648_mode_configure()
1460 ret = ov5648_write(sensor, OV5648_SUB_INC_X_REG, in ov5648_mode_configure()
1461 OV5648_SUB_INC_X_ODD(mode->inc_x_odd) | in ov5648_mode_configure()
1462 OV5648_SUB_INC_X_EVEN(mode->inc_x_even)); in ov5648_mode_configure()
1466 ret = ov5648_write(sensor, OV5648_SUB_INC_Y_REG, in ov5648_mode_configure()
1467 OV5648_SUB_INC_Y_ODD(mode->inc_y_odd) | in ov5648_mode_configure()
1468 OV5648_SUB_INC_Y_EVEN(mode->inc_y_even)); in ov5648_mode_configure()
1474 ret = ov5648_mode_pll1_configure(sensor, mode, mbus_code); in ov5648_mode_configure()
1478 ret = ov5648_mode_pll2_configure(sensor, mode); in ov5648_mode_configure()
1484 if (mode->register_values) { in ov5648_mode_configure()
1485 ret = ov5648_write_sequence(sensor, mode->register_values, in ov5648_mode_configure()
1486 mode->register_values_count); in ov5648_mode_configure()
1494 static unsigned long ov5648_mode_mipi_clk_rate(struct ov5648_sensor *sensor, in ov5648_mode_mipi_clk_rate() argument
1503 config = mode->pll1_config[0]; in ov5648_mode_mipi_clk_rate()
1506 config = mode->pll1_config[1]; in ov5648_mode_mipi_clk_rate()
1512 pll1_rate = ov5648_mode_pll1_rate(sensor, config); in ov5648_mode_mipi_clk_rate()
1514 return pll1_rate / config->sys_div / config->mipi_div / 2; in ov5648_mode_mipi_clk_rate()
1519 static int ov5648_exposure_auto_configure(struct ov5648_sensor *sensor, in ov5648_exposure_auto_configure() argument
1522 return ov5648_update_bits(sensor, OV5648_MANUAL_CTRL_REG, in ov5648_exposure_auto_configure()
1527 static int ov5648_exposure_configure(struct ov5648_sensor *sensor, u32 exposure) in ov5648_exposure_configure() argument
1529 struct ov5648_ctrls *ctrls = &sensor->ctrls; in ov5648_exposure_configure()
1532 if (ctrls->exposure_auto->val != V4L2_EXPOSURE_MANUAL) in ov5648_exposure_configure()
1533 return -EINVAL; in ov5648_exposure_configure()
1535 ret = ov5648_write(sensor, OV5648_EXPOSURE_CTRL_HH_REG, in ov5648_exposure_configure()
1540 ret = ov5648_write(sensor, OV5648_EXPOSURE_CTRL_H_REG, in ov5648_exposure_configure()
1545 return ov5648_write(sensor, OV5648_EXPOSURE_CTRL_L_REG, in ov5648_exposure_configure()
1549 static int ov5648_exposure_value(struct ov5648_sensor *sensor, in ov5648_exposure_value() argument
1555 ret = ov5648_read(sensor, OV5648_EXPOSURE_CTRL_HH_REG, &exposure_hh); in ov5648_exposure_value()
1559 ret = ov5648_read(sensor, OV5648_EXPOSURE_CTRL_H_REG, &exposure_h); in ov5648_exposure_value()
1563 ret = ov5648_read(sensor, OV5648_EXPOSURE_CTRL_L_REG, &exposure_l); in ov5648_exposure_value()
1574 /* Gain */
1576 static int ov5648_gain_auto_configure(struct ov5648_sensor *sensor, bool enable) in ov5648_gain_auto_configure() argument
1578 return ov5648_update_bits(sensor, OV5648_MANUAL_CTRL_REG, in ov5648_gain_auto_configure()
1583 static int ov5648_gain_configure(struct ov5648_sensor *sensor, u32 gain) in ov5648_gain_configure() argument
1585 struct ov5648_ctrls *ctrls = &sensor->ctrls; in ov5648_gain_configure()
1588 if (ctrls->gain_auto->val) in ov5648_gain_configure()
1589 return -EINVAL; in ov5648_gain_configure()
1591 ret = ov5648_write(sensor, OV5648_GAIN_CTRL_H_REG, in ov5648_gain_configure()
1592 OV5648_GAIN_CTRL_H(gain)); in ov5648_gain_configure()
1596 return ov5648_write(sensor, OV5648_GAIN_CTRL_L_REG, in ov5648_gain_configure()
1597 OV5648_GAIN_CTRL_L(gain)); in ov5648_gain_configure()
1600 static int ov5648_gain_value(struct ov5648_sensor *sensor, u32 *gain) in ov5648_gain_value() argument
1605 ret = ov5648_read(sensor, OV5648_GAIN_CTRL_H_REG, &gain_h); in ov5648_gain_value()
1609 ret = ov5648_read(sensor, OV5648_GAIN_CTRL_L_REG, &gain_l); in ov5648_gain_value()
1613 *gain = OV5648_GAIN_CTRL_H_VALUE((u32)gain_h) | in ov5648_gain_value()
1621 static int ov5648_white_balance_auto_configure(struct ov5648_sensor *sensor, in ov5648_white_balance_auto_configure() argument
1624 return ov5648_write(sensor, OV5648_AWB_CTRL_REG, in ov5648_white_balance_auto_configure()
1628 static int ov5648_white_balance_configure(struct ov5648_sensor *sensor, in ov5648_white_balance_configure() argument
1631 struct ov5648_ctrls *ctrls = &sensor->ctrls; in ov5648_white_balance_configure()
1634 if (ctrls->white_balance_auto->val) in ov5648_white_balance_configure()
1635 return -EINVAL; in ov5648_white_balance_configure()
1637 ret = ov5648_write(sensor, OV5648_GAIN_RED_MAN_H_REG, in ov5648_white_balance_configure()
1642 ret = ov5648_write(sensor, OV5648_GAIN_RED_MAN_L_REG, in ov5648_white_balance_configure()
1647 ret = ov5648_write(sensor, OV5648_GAIN_BLUE_MAN_H_REG, in ov5648_white_balance_configure()
1652 return ov5648_write(sensor, OV5648_GAIN_BLUE_MAN_L_REG, in ov5648_white_balance_configure()
1658 static int ov5648_flip_vert_configure(struct ov5648_sensor *sensor, bool enable) in ov5648_flip_vert_configure() argument
1663 return ov5648_update_bits(sensor, OV5648_TC20_REG, bits, in ov5648_flip_vert_configure()
1667 static int ov5648_flip_horz_configure(struct ov5648_sensor *sensor, bool enable) in ov5648_flip_horz_configure() argument
1672 return ov5648_update_bits(sensor, OV5648_TC21_REG, bits, in ov5648_flip_horz_configure()
1678 static int ov5648_test_pattern_configure(struct ov5648_sensor *sensor, in ov5648_test_pattern_configure() argument
1682 return -EINVAL; in ov5648_test_pattern_configure()
1684 return ov5648_write(sensor, OV5648_ISP_CTRL3D_REG, in ov5648_test_pattern_configure()
1690 static int ov5648_state_mipi_configure(struct ov5648_sensor *sensor, in ov5648_state_mipi_configure() argument
1694 struct ov5648_ctrls *ctrls = &sensor->ctrls; in ov5648_state_mipi_configure()
1696 &sensor->endpoint.bus.mipi_csi2; in ov5648_state_mipi_configure()
1703 mipi_clk_rate = ov5648_mode_mipi_clk_rate(sensor, mode, mbus_code); in ov5648_state_mipi_configure()
1705 return -EINVAL; in ov5648_state_mipi_configure()
1714 for (j = 0; j < sensor->endpoint.nr_of_link_frequencies; j++) { in ov5648_state_mipi_configure()
1715 u64 freq = sensor->endpoint.link_frequencies[j]; in ov5648_state_mipi_configure()
1722 dev_err(sensor->dev, in ov5648_state_mipi_configure()
1725 } else if (j == sensor->endpoint.nr_of_link_frequencies) { in ov5648_state_mipi_configure()
1726 dev_err(sensor->dev, in ov5648_state_mipi_configure()
1727 "failed to find %lu clk rate in endpoint link-frequencies\n", in ov5648_state_mipi_configure()
1730 __v4l2_ctrl_s_ctrl(ctrls->link_freq, i); in ov5648_state_mipi_configure()
1741 return -EINVAL; in ov5648_state_mipi_configure()
1744 lanes_count = bus_mipi_csi2->num_data_lanes; in ov5648_state_mipi_configure()
1747 __v4l2_ctrl_s_ctrl_int64(ctrls->pixel_rate, mipi_pixel_rate); in ov5648_state_mipi_configure()
1752 static int ov5648_state_configure(struct ov5648_sensor *sensor, in ov5648_state_configure() argument
1758 if (sensor->state.streaming) in ov5648_state_configure()
1759 return -EBUSY; in ov5648_state_configure()
1762 if (pm_runtime_enabled(sensor->dev) && in ov5648_state_configure()
1763 !pm_runtime_suspended(sensor->dev)) { in ov5648_state_configure()
1764 ret = ov5648_mode_configure(sensor, mode, mbus_code); in ov5648_state_configure()
1769 ret = ov5648_state_mipi_configure(sensor, mode, mbus_code); in ov5648_state_configure()
1773 sensor->state.mode = mode; in ov5648_state_configure()
1774 sensor->state.mbus_code = mbus_code; in ov5648_state_configure()
1779 static int ov5648_state_init(struct ov5648_sensor *sensor) in ov5648_state_init() argument
1783 mutex_lock(&sensor->mutex); in ov5648_state_init()
1784 ret = ov5648_state_configure(sensor, &ov5648_modes[0], in ov5648_state_init()
1786 mutex_unlock(&sensor->mutex); in ov5648_state_init()
1791 /* Sensor Base */
1793 static int ov5648_sensor_init(struct ov5648_sensor *sensor) in ov5648_sensor_init() argument
1797 ret = ov5648_sw_reset(sensor); in ov5648_sensor_init()
1799 dev_err(sensor->dev, "failed to perform sw reset\n"); in ov5648_sensor_init()
1803 ret = ov5648_sw_standby(sensor, 1); in ov5648_sensor_init()
1805 dev_err(sensor->dev, "failed to set sensor standby\n"); in ov5648_sensor_init()
1809 ret = ov5648_chip_id_check(sensor); in ov5648_sensor_init()
1811 dev_err(sensor->dev, "failed to check sensor chip id\n"); in ov5648_sensor_init()
1815 ret = ov5648_avdd_internal_power(sensor, !sensor->avdd); in ov5648_sensor_init()
1817 dev_err(sensor->dev, "failed to set internal avdd power\n"); in ov5648_sensor_init()
1821 ret = ov5648_write_sequence(sensor, ov5648_init_sequence, in ov5648_sensor_init()
1824 dev_err(sensor->dev, "failed to write init sequence\n"); in ov5648_sensor_init()
1828 ret = ov5648_pad_configure(sensor); in ov5648_sensor_init()
1830 dev_err(sensor->dev, "failed to configure pad\n"); in ov5648_sensor_init()
1834 ret = ov5648_mipi_configure(sensor); in ov5648_sensor_init()
1836 dev_err(sensor->dev, "failed to configure MIPI\n"); in ov5648_sensor_init()
1840 ret = ov5648_isp_configure(sensor); in ov5648_sensor_init()
1842 dev_err(sensor->dev, "failed to configure ISP\n"); in ov5648_sensor_init()
1846 ret = ov5648_black_level_configure(sensor); in ov5648_sensor_init()
1848 dev_err(sensor->dev, "failed to configure black level\n"); in ov5648_sensor_init()
1853 ret = ov5648_state_configure(sensor, sensor->state.mode, in ov5648_sensor_init()
1854 sensor->state.mbus_code); in ov5648_sensor_init()
1856 dev_err(sensor->dev, "failed to configure state\n"); in ov5648_sensor_init()
1863 static int ov5648_sensor_power(struct ov5648_sensor *sensor, bool on) in ov5648_sensor_power() argument
1870 * - power-down GPIO must be active (low) during power-on; in ov5648_sensor_power()
1871 * - reset GPIO state does not matter during power-on; in ov5648_sensor_power()
1872 * - XVCLK must be provided 1 ms before register access; in ov5648_sensor_power()
1873 * - 10 ms are needed between power-down deassert and register access. in ov5648_sensor_power()
1876 /* Note that regulator-and-GPIO-based power is untested. */ in ov5648_sensor_power()
1878 gpiod_set_value_cansleep(sensor->reset, 1); in ov5648_sensor_power()
1879 gpiod_set_value_cansleep(sensor->powerdown, 1); in ov5648_sensor_power()
1881 ret = regulator_enable(sensor->dovdd); in ov5648_sensor_power()
1883 dev_err(sensor->dev, in ov5648_sensor_power()
1888 if (sensor->avdd) { in ov5648_sensor_power()
1889 ret = regulator_enable(sensor->avdd); in ov5648_sensor_power()
1891 dev_err(sensor->dev, in ov5648_sensor_power()
1897 ret = regulator_enable(sensor->dvdd); in ov5648_sensor_power()
1899 dev_err(sensor->dev, in ov5648_sensor_power()
1907 ret = clk_prepare_enable(sensor->xvclk); in ov5648_sensor_power()
1909 dev_err(sensor->dev, "failed to enable XVCLK clock\n"); in ov5648_sensor_power()
1913 gpiod_set_value_cansleep(sensor->reset, 0); in ov5648_sensor_power()
1914 gpiod_set_value_cansleep(sensor->powerdown, 0); in ov5648_sensor_power()
1919 gpiod_set_value_cansleep(sensor->powerdown, 1); in ov5648_sensor_power()
1920 gpiod_set_value_cansleep(sensor->reset, 1); in ov5648_sensor_power()
1922 clk_disable_unprepare(sensor->xvclk); in ov5648_sensor_power()
1924 regulator_disable(sensor->dvdd); in ov5648_sensor_power()
1926 if (sensor->avdd) in ov5648_sensor_power()
1927 regulator_disable(sensor->avdd); in ov5648_sensor_power()
1929 regulator_disable(sensor->dovdd); in ov5648_sensor_power()
1940 struct ov5648_sensor *sensor = ov5648_subdev_sensor(subdev); in ov5648_g_volatile_ctrl() local
1941 struct ov5648_ctrls *ctrls = &sensor->ctrls; in ov5648_g_volatile_ctrl()
1944 switch (ctrl->id) { in ov5648_g_volatile_ctrl()
1946 ret = ov5648_exposure_value(sensor, &ctrls->exposure->val); in ov5648_g_volatile_ctrl()
1951 ret = ov5648_gain_value(sensor, &ctrls->gain->val); in ov5648_g_volatile_ctrl()
1956 return -EINVAL; in ov5648_g_volatile_ctrl()
1965 struct ov5648_sensor *sensor = ov5648_subdev_sensor(subdev); in ov5648_s_ctrl() local
1966 struct ov5648_ctrls *ctrls = &sensor->ctrls; in ov5648_s_ctrl()
1971 /* Wait for the sensor to be on before setting controls. */ in ov5648_s_ctrl()
1972 if (pm_runtime_suspended(sensor->dev)) in ov5648_s_ctrl()
1975 switch (ctrl->id) { in ov5648_s_ctrl()
1977 enable = ctrl->val == V4L2_EXPOSURE_AUTO; in ov5648_s_ctrl()
1979 ret = ov5648_exposure_auto_configure(sensor, enable); in ov5648_s_ctrl()
1983 if (!enable && ctrls->exposure->is_new) { in ov5648_s_ctrl()
1984 ret = ov5648_exposure_configure(sensor, in ov5648_s_ctrl()
1985 ctrls->exposure->val); in ov5648_s_ctrl()
1991 enable = !!ctrl->val; in ov5648_s_ctrl()
1993 ret = ov5648_gain_auto_configure(sensor, enable); in ov5648_s_ctrl()
1998 ret = ov5648_gain_configure(sensor, ctrls->gain->val); in ov5648_s_ctrl()
2004 enable = !!ctrl->val; in ov5648_s_ctrl()
2006 ret = ov5648_white_balance_auto_configure(sensor, enable); in ov5648_s_ctrl()
2011 ret = ov5648_white_balance_configure(sensor, in ov5648_s_ctrl()
2012 ctrls->red_balance->val, in ov5648_s_ctrl()
2013 ctrls->blue_balance->val); in ov5648_s_ctrl()
2019 enable = !!ctrl->val; in ov5648_s_ctrl()
2020 return ov5648_flip_horz_configure(sensor, enable); in ov5648_s_ctrl()
2022 enable = !!ctrl->val; in ov5648_s_ctrl()
2023 return ov5648_flip_vert_configure(sensor, enable); in ov5648_s_ctrl()
2025 index = (unsigned int)ctrl->val; in ov5648_s_ctrl()
2026 return ov5648_test_pattern_configure(sensor, index); in ov5648_s_ctrl()
2028 return -EINVAL; in ov5648_s_ctrl()
2039 static int ov5648_ctrls_init(struct ov5648_sensor *sensor) in ov5648_ctrls_init() argument
2041 struct ov5648_ctrls *ctrls = &sensor->ctrls; in ov5648_ctrls_init()
2042 struct v4l2_ctrl_handler *handler = &ctrls->handler; in ov5648_ctrls_init()
2049 handler->lock = &sensor->mutex; in ov5648_ctrls_init()
2053 ctrls->exposure_auto = v4l2_ctrl_new_std_menu(handler, ops, in ov5648_ctrls_init()
2058 ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, in ov5648_ctrls_init()
2061 v4l2_ctrl_auto_cluster(2, &ctrls->exposure_auto, 1, true); in ov5648_ctrls_init()
2063 /* Gain */ in ov5648_ctrls_init()
2065 ctrls->gain_auto = in ov5648_ctrls_init()
2068 ctrls->gain = v4l2_ctrl_new_std(handler, ops, V4L2_CID_GAIN, 16, 1023, in ov5648_ctrls_init()
2071 v4l2_ctrl_auto_cluster(2, &ctrls->gain_auto, 0, true); in ov5648_ctrls_init()
2075 ctrls->white_balance_auto = in ov5648_ctrls_init()
2079 ctrls->red_balance = v4l2_ctrl_new_std(handler, ops, in ov5648_ctrls_init()
2083 ctrls->blue_balance = v4l2_ctrl_new_std(handler, ops, in ov5648_ctrls_init()
2087 v4l2_ctrl_auto_cluster(3, &ctrls->white_balance_auto, 0, false); in ov5648_ctrls_init()
2097 ARRAY_SIZE(ov5648_test_pattern_menu) - 1, in ov5648_ctrls_init()
2100 /* MIPI CSI-2 */ in ov5648_ctrls_init()
2102 ctrls->link_freq = in ov5648_ctrls_init()
2104 ARRAY_SIZE(ov5648_link_freq_menu) - 1, in ov5648_ctrls_init()
2107 ctrls->pixel_rate = in ov5648_ctrls_init()
2111 if (handler->error) { in ov5648_ctrls_init()
2112 ret = handler->error; in ov5648_ctrls_init()
2116 ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; in ov5648_ctrls_init()
2117 ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE; in ov5648_ctrls_init()
2119 ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in ov5648_ctrls_init()
2120 ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY; in ov5648_ctrls_init()
2122 sensor->subdev.ctrl_handler = handler; in ov5648_ctrls_init()
2136 struct ov5648_sensor *sensor = ov5648_subdev_sensor(subdev); in ov5648_s_stream() local
2137 struct ov5648_state *state = &sensor->state; in ov5648_s_stream()
2141 ret = pm_runtime_resume_and_get(sensor->dev); in ov5648_s_stream()
2146 mutex_lock(&sensor->mutex); in ov5648_s_stream()
2147 ret = ov5648_sw_standby(sensor, !enable); in ov5648_s_stream()
2148 mutex_unlock(&sensor->mutex); in ov5648_s_stream()
2153 state->streaming = !!enable; in ov5648_s_stream()
2156 pm_runtime_put(sensor->dev); in ov5648_s_stream()
2171 if (code_enum->index >= ARRAY_SIZE(ov5648_mbus_codes)) in ov5648_enum_mbus_code()
2172 return -EINVAL; in ov5648_enum_mbus_code()
2174 code_enum->code = ov5648_mbus_codes[code_enum->index]; in ov5648_enum_mbus_code()
2183 mbus_format->width = mode->output_size_x; in ov5648_mbus_format_fill()
2184 mbus_format->height = mode->output_size_y; in ov5648_mbus_format_fill()
2185 mbus_format->code = mbus_code; in ov5648_mbus_format_fill()
2187 mbus_format->field = V4L2_FIELD_NONE; in ov5648_mbus_format_fill()
2188 mbus_format->colorspace = V4L2_COLORSPACE_RAW; in ov5648_mbus_format_fill()
2189 mbus_format->ycbcr_enc = in ov5648_mbus_format_fill()
2190 V4L2_MAP_YCBCR_ENC_DEFAULT(mbus_format->colorspace); in ov5648_mbus_format_fill()
2191 mbus_format->quantization = V4L2_QUANTIZATION_FULL_RANGE; in ov5648_mbus_format_fill()
2192 mbus_format->xfer_func = in ov5648_mbus_format_fill()
2193 V4L2_MAP_XFER_FUNC_DEFAULT(mbus_format->colorspace); in ov5648_mbus_format_fill()
2200 struct ov5648_sensor *sensor = ov5648_subdev_sensor(subdev); in ov5648_get_fmt() local
2201 struct v4l2_mbus_framefmt *mbus_format = &format->format; in ov5648_get_fmt()
2203 mutex_lock(&sensor->mutex); in ov5648_get_fmt()
2205 if (format->which == V4L2_SUBDEV_FORMAT_TRY) in ov5648_get_fmt()
2207 format->pad); in ov5648_get_fmt()
2209 ov5648_mbus_format_fill(mbus_format, sensor->state.mbus_code, in ov5648_get_fmt()
2210 sensor->state.mode); in ov5648_get_fmt()
2212 mutex_unlock(&sensor->mutex); in ov5648_get_fmt()
2221 struct ov5648_sensor *sensor = ov5648_subdev_sensor(subdev); in ov5648_set_fmt() local
2222 struct v4l2_mbus_framefmt *mbus_format = &format->format; in ov5648_set_fmt()
2228 mutex_lock(&sensor->mutex); in ov5648_set_fmt()
2230 if (sensor->state.streaming) { in ov5648_set_fmt()
2231 ret = -EBUSY; in ov5648_set_fmt()
2237 if (ov5648_mbus_codes[index] == mbus_format->code) { in ov5648_set_fmt()
2238 mbus_code = mbus_format->code; in ov5648_set_fmt()
2250 mbus_format->width, mbus_format->height); in ov5648_set_fmt()
2252 ret = -EINVAL; in ov5648_set_fmt()
2258 if (format->which == V4L2_SUBDEV_FORMAT_TRY) in ov5648_set_fmt()
2259 *v4l2_subdev_state_get_format(sd_state, format->pad) = in ov5648_set_fmt()
2261 else if (sensor->state.mode != mode || in ov5648_set_fmt()
2262 sensor->state.mbus_code != mbus_code) in ov5648_set_fmt()
2263 ret = ov5648_state_configure(sensor, mode, mbus_code); in ov5648_set_fmt()
2266 mutex_unlock(&sensor->mutex); in ov5648_set_fmt()
2275 struct ov5648_sensor *sensor = ov5648_subdev_sensor(subdev); in ov5648_get_frame_interval() local
2283 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE) in ov5648_get_frame_interval()
2284 return -EINVAL; in ov5648_get_frame_interval()
2286 mutex_lock(&sensor->mutex); in ov5648_get_frame_interval()
2288 mode = sensor->state.mode; in ov5648_get_frame_interval()
2290 switch (sensor->state.mbus_code) { in ov5648_get_frame_interval()
2292 interval->interval = mode->frame_interval[0]; in ov5648_get_frame_interval()
2295 interval->interval = mode->frame_interval[1]; in ov5648_get_frame_interval()
2298 ret = -EINVAL; in ov5648_get_frame_interval()
2301 mutex_unlock(&sensor->mutex); in ov5648_get_frame_interval()
2312 if (size_enum->index >= ARRAY_SIZE(ov5648_modes)) in ov5648_enum_frame_size()
2313 return -EINVAL; in ov5648_enum_frame_size()
2315 mode = &ov5648_modes[size_enum->index]; in ov5648_enum_frame_size()
2317 size_enum->min_width = size_enum->max_width = mode->output_size_x; in ov5648_enum_frame_size()
2318 size_enum->min_height = size_enum->max_height = mode->output_size_y; in ov5648_enum_frame_size()
2331 if (interval_enum->index > 0) in ov5648_enum_frame_interval()
2332 return -EINVAL; in ov5648_enum_frame_interval()
2342 if (mode->output_size_x == interval_enum->width && in ov5648_enum_frame_interval()
2343 mode->output_size_y == interval_enum->height) { in ov5648_enum_frame_interval()
2344 if (interval_index == interval_enum->index) in ov5648_enum_frame_interval()
2352 return -EINVAL; in ov5648_enum_frame_interval()
2354 switch (interval_enum->code) { in ov5648_enum_frame_interval()
2356 interval_enum->interval = mode->frame_interval[0]; in ov5648_enum_frame_interval()
2359 interval_enum->interval = mode->frame_interval[1]; in ov5648_enum_frame_interval()
2362 return -EINVAL; in ov5648_enum_frame_interval()
2387 struct ov5648_sensor *sensor = ov5648_subdev_sensor(subdev); in ov5648_suspend() local
2388 struct ov5648_state *state = &sensor->state; in ov5648_suspend()
2391 mutex_lock(&sensor->mutex); in ov5648_suspend()
2393 if (state->streaming) { in ov5648_suspend()
2394 ret = ov5648_sw_standby(sensor, true); in ov5648_suspend()
2399 ret = ov5648_sensor_power(sensor, false); in ov5648_suspend()
2401 ov5648_sw_standby(sensor, false); in ov5648_suspend()
2404 mutex_unlock(&sensor->mutex); in ov5648_suspend()
2413 struct ov5648_sensor *sensor = ov5648_subdev_sensor(subdev); in ov5648_resume() local
2414 struct ov5648_state *state = &sensor->state; in ov5648_resume()
2417 mutex_lock(&sensor->mutex); in ov5648_resume()
2419 ret = ov5648_sensor_power(sensor, true); in ov5648_resume()
2423 ret = ov5648_sensor_init(sensor); in ov5648_resume()
2427 ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); in ov5648_resume()
2431 if (state->streaming) { in ov5648_resume()
2432 ret = ov5648_sw_standby(sensor, false); in ov5648_resume()
2440 ov5648_sensor_power(sensor, false); in ov5648_resume()
2443 mutex_unlock(&sensor->mutex); in ov5648_resume()
2450 struct device *dev = &client->dev; in ov5648_probe()
2452 struct ov5648_sensor *sensor; in ov5648_probe() local
2458 sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); in ov5648_probe()
2459 if (!sensor) in ov5648_probe()
2460 return -ENOMEM; in ov5648_probe()
2462 sensor->dev = dev; in ov5648_probe()
2463 sensor->i2c_client = client; in ov5648_probe()
2470 return -EINVAL; in ov5648_probe()
2473 sensor->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY; in ov5648_probe()
2475 ret = v4l2_fwnode_endpoint_alloc_parse(handle, &sensor->endpoint); in ov5648_probe()
2484 sensor->powerdown = devm_gpiod_get_optional(dev, "powerdown", in ov5648_probe()
2486 if (IS_ERR(sensor->powerdown)) { in ov5648_probe()
2487 ret = PTR_ERR(sensor->powerdown); in ov5648_probe()
2491 sensor->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); in ov5648_probe()
2492 if (IS_ERR(sensor->reset)) { in ov5648_probe()
2493 ret = PTR_ERR(sensor->reset); in ov5648_probe()
2500 sensor->dvdd = devm_regulator_get(dev, "dvdd"); in ov5648_probe()
2501 if (IS_ERR(sensor->dvdd)) { in ov5648_probe()
2503 ret = PTR_ERR(sensor->dvdd); in ov5648_probe()
2508 sensor->dovdd = devm_regulator_get(dev, "dovdd"); in ov5648_probe()
2509 if (IS_ERR(sensor->dovdd)) { in ov5648_probe()
2511 ret = PTR_ERR(sensor->dovdd); in ov5648_probe()
2516 sensor->avdd = devm_regulator_get_optional(dev, "avdd"); in ov5648_probe()
2517 if (IS_ERR(sensor->avdd)) { in ov5648_probe()
2519 sensor->avdd = NULL; in ov5648_probe()
2524 sensor->xvclk = devm_clk_get(dev, NULL); in ov5648_probe()
2525 if (IS_ERR(sensor->xvclk)) { in ov5648_probe()
2527 ret = PTR_ERR(sensor->xvclk); in ov5648_probe()
2531 rate = clk_get_rate(sensor->xvclk); in ov5648_probe()
2534 ret = -EINVAL; in ov5648_probe()
2540 subdev = &sensor->subdev; in ov5648_probe()
2543 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in ov5648_probe()
2544 subdev->entity.function = MEDIA_ENT_F_CAM_SENSOR; in ov5648_probe()
2546 pad = &sensor->pad; in ov5648_probe()
2547 pad->flags = MEDIA_PAD_FL_SOURCE; in ov5648_probe()
2549 ret = media_entity_pads_init(&subdev->entity, 1, pad); in ov5648_probe()
2555 mutex_init(&sensor->mutex); in ov5648_probe()
2557 /* Sensor */ in ov5648_probe()
2559 ret = ov5648_ctrls_init(sensor); in ov5648_probe()
2563 ret = ov5648_state_init(sensor); in ov5648_probe()
2569 pm_runtime_enable(sensor->dev); in ov5648_probe()
2570 pm_runtime_set_suspended(sensor->dev); in ov5648_probe()
2581 pm_runtime_disable(sensor->dev); in ov5648_probe()
2584 v4l2_ctrl_handler_free(&sensor->ctrls.handler); in ov5648_probe()
2587 mutex_destroy(&sensor->mutex); in ov5648_probe()
2590 media_entity_cleanup(&sensor->subdev.entity); in ov5648_probe()
2593 v4l2_fwnode_endpoint_free(&sensor->endpoint); in ov5648_probe()
2601 struct ov5648_sensor *sensor = ov5648_subdev_sensor(subdev); in ov5648_remove() local
2604 pm_runtime_disable(sensor->dev); in ov5648_remove()
2605 v4l2_ctrl_handler_free(&sensor->ctrls.handler); in ov5648_remove()
2606 mutex_destroy(&sensor->mutex); in ov5648_remove()
2607 media_entity_cleanup(&subdev->entity); in ov5648_remove()
2608 v4l2_fwnode_endpoint_free(&sensor->endpoint); in ov5648_remove()
2634 MODULE_DESCRIPTION("V4L2 driver for the OmniVision OV5648 image sensor");