Lines Matching full:sensor

3  * mt9m114.c onsemi MT9M114 sensor driver
52 /* Sensor Core registers */
472 mt9m114_default_format_info(struct mt9m114 *sensor) in mt9m114_default_format_info() argument
474 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) in mt9m114_default_format_info()
481 mt9m114_format_info(struct mt9m114 *sensor, unsigned int pad, u32 code) in mt9m114_format_info() argument
492 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) in mt9m114_format_info()
505 return mt9m114_default_format_info(sensor); in mt9m114_format_info()
521 /* Sensor optimization */
656 static int mt9m114_poll_command(struct mt9m114 *sensor, u32 command) in mt9m114_poll_command() argument
663 ret = cci_read(sensor->regmap, MT9M114_COMMAND_REGISTER, &value, in mt9m114_poll_command()
675 dev_err(&sensor->client->dev, "Command %u completion timeout\n", in mt9m114_poll_command()
681 dev_err(&sensor->client->dev, "Command %u failed\n", command); in mt9m114_poll_command()
689 static int mt9m114_poll_state(struct mt9m114 *sensor, u32 state) in mt9m114_poll_state() argument
696 ret = cci_read(sensor->regmap, MT9M114_SYSMGR_CURRENT_STATE, in mt9m114_poll_state()
707 dev_err(&sensor->client->dev, "Timeout waiting for state 0x%02x\n", in mt9m114_poll_state()
712 static int mt9m114_set_state(struct mt9m114 *sensor, u8 next_state) in mt9m114_set_state() argument
717 cci_write(sensor->regmap, MT9M114_SYSMGR_NEXT_STATE, next_state, &ret); in mt9m114_set_state()
718 cci_write(sensor->regmap, MT9M114_COMMAND_REGISTER, in mt9m114_set_state()
725 ret = mt9m114_poll_command(sensor, MT9M114_COMMAND_REGISTER_SET_STATE); in mt9m114_set_state()
732 static int mt9m114_initialize(struct mt9m114 *sensor) in mt9m114_initialize() argument
737 ret = cci_multi_reg_write(sensor->regmap, mt9m114_init, in mt9m114_initialize()
740 dev_err(&sensor->client->dev, in mt9m114_initialize()
741 "Failed to initialize the sensor\n"); in mt9m114_initialize()
746 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE, in mt9m114_initialize()
748 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N, in mt9m114_initialize()
749 MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(sensor->pll.m, in mt9m114_initialize()
750 sensor->pll.n), in mt9m114_initialize()
752 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_P, in mt9m114_initialize()
753 MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(sensor->pll.p), &ret); in mt9m114_initialize()
754 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_PIXCLK, in mt9m114_initialize()
755 sensor->pixrate, &ret); in mt9m114_initialize()
758 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) { in mt9m114_initialize()
762 if (!(sensor->bus_cfg.bus.mipi_csi2.flags & in mt9m114_initialize()
769 cci_write(sensor->regmap, MT9M114_CAM_PORT_OUTPUT_CONTROL, value, &ret); in mt9m114_initialize()
773 ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE); in mt9m114_initialize()
777 ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_SUSPEND); in mt9m114_initialize()
784 static int mt9m114_configure(struct mt9m114 *sensor, in mt9m114_configure() argument
803 ifp_info = mt9m114_format_info(sensor, 1, ifp_format->code); in mt9m114_configure()
807 ret = cci_read(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE, in mt9m114_configure()
812 ret = cci_read(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT, in mt9m114_configure()
824 * example sensor modes. in mt9m114_configure()
826 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_START, in mt9m114_configure()
828 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_START, in mt9m114_configure()
830 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_END, in mt9m114_configure()
832 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_END, in mt9m114_configure()
834 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW, in mt9m114_configure()
845 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE, in mt9m114_configure()
854 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_XOFFSET, in mt9m114_configure()
856 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_YOFFSET, in mt9m114_configure()
858 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_WIDTH, in mt9m114_configure()
860 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_HEIGHT, in mt9m114_configure()
863 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_WIDTH, in mt9m114_configure()
865 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_HEIGHT, in mt9m114_configure()
869 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XSTART, in mt9m114_configure()
871 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YSTART, in mt9m114_configure()
873 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XEND, in mt9m114_configure()
875 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YEND, in mt9m114_configure()
878 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XSTART, in mt9m114_configure()
880 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YSTART, in mt9m114_configure()
882 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XEND, in mt9m114_configure()
884 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YEND, in mt9m114_configure()
887 cci_write(sensor->regmap, MT9M114_CAM_CROP_CROPMODE, in mt9m114_configure()
899 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT, in mt9m114_configure()
905 static int mt9m114_set_frame_rate(struct mt9m114 *sensor) in mt9m114_set_frame_rate() argument
907 u16 frame_rate = sensor->ifp.frame_rate << 8; in mt9m114_set_frame_rate()
910 cci_write(sensor->regmap, MT9M114_CAM_AET_MIN_FRAME_RATE, in mt9m114_set_frame_rate()
912 cci_write(sensor->regmap, MT9M114_CAM_AET_MAX_FRAME_RATE, in mt9m114_set_frame_rate()
918 static int mt9m114_start_streaming(struct mt9m114 *sensor, in mt9m114_start_streaming() argument
924 ret = pm_runtime_resume_and_get(&sensor->client->dev); in mt9m114_start_streaming()
928 ret = mt9m114_configure(sensor, pa_state, ifp_state); in mt9m114_start_streaming()
932 ret = mt9m114_set_frame_rate(sensor); in mt9m114_start_streaming()
936 ret = __v4l2_ctrl_handler_setup(&sensor->pa.hdl); in mt9m114_start_streaming()
940 ret = __v4l2_ctrl_handler_setup(&sensor->ifp.hdl); in mt9m114_start_streaming()
948 ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE); in mt9m114_start_streaming()
952 sensor->streaming = true; in mt9m114_start_streaming()
957 pm_runtime_mark_last_busy(&sensor->client->dev); in mt9m114_start_streaming()
958 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_start_streaming()
963 static int mt9m114_stop_streaming(struct mt9m114 *sensor) in mt9m114_stop_streaming() argument
967 sensor->streaming = false; in mt9m114_stop_streaming()
969 ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_SUSPEND); in mt9m114_stop_streaming()
971 pm_runtime_mark_last_busy(&sensor->client->dev); in mt9m114_stop_streaming()
972 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_stop_streaming()
996 struct mt9m114 *sensor = pa_ctrl_to_mt9m114(ctrl); in mt9m114_pa_g_ctrl() local
1000 if (!pm_runtime_get_if_in_use(&sensor->client->dev)) in mt9m114_pa_g_ctrl()
1005 ret = cci_read(sensor->regmap, in mt9m114_pa_g_ctrl()
1015 ret = cci_read(sensor->regmap, in mt9m114_pa_g_ctrl()
1029 pm_runtime_mark_last_busy(&sensor->client->dev); in mt9m114_pa_g_ctrl()
1030 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_pa_g_ctrl()
1037 struct mt9m114 *sensor = pa_ctrl_to_mt9m114(ctrl); in mt9m114_pa_s_ctrl() local
1044 if (!pm_runtime_get_if_in_use(&sensor->client->dev)) in mt9m114_pa_s_ctrl()
1047 state = v4l2_subdev_get_locked_active_state(&sensor->pa.sd); in mt9m114_pa_s_ctrl()
1052 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK, in mt9m114_pa_s_ctrl()
1057 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES, in mt9m114_pa_s_ctrl()
1062 cci_write(sensor->regmap, in mt9m114_pa_s_ctrl()
1071 * values by the sensor firmware. in mt9m114_pa_s_ctrl()
1073 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_ANALOG_GAIN, in mt9m114_pa_s_ctrl()
1079 ret = cci_update_bits(sensor->regmap, in mt9m114_pa_s_ctrl()
1086 ret = cci_update_bits(sensor->regmap, in mt9m114_pa_s_ctrl()
1096 pm_runtime_mark_last_busy(&sensor->client->dev); in mt9m114_pa_s_ctrl()
1097 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_pa_s_ctrl()
1107 static void mt9m114_pa_ctrl_update_exposure(struct mt9m114 *sensor, bool manual) in mt9m114_pa_ctrl_update_exposure() argument
1116 mt9m114_pa_g_ctrl(sensor->pa.exposure); in mt9m114_pa_ctrl_update_exposure()
1117 sensor->pa.exposure->cur.val = sensor->pa.exposure->val; in mt9m114_pa_ctrl_update_exposure()
1118 sensor->pa.exposure->flags &= ~V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_ctrl_update_exposure()
1120 mt9m114_pa_g_ctrl(sensor->pa.gain); in mt9m114_pa_ctrl_update_exposure()
1121 sensor->pa.gain->cur.val = sensor->pa.gain->val; in mt9m114_pa_ctrl_update_exposure()
1122 sensor->pa.gain->flags &= ~V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_ctrl_update_exposure()
1124 sensor->pa.exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_ctrl_update_exposure()
1125 sensor->pa.gain->flags |= V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_ctrl_update_exposure()
1129 static void mt9m114_pa_ctrl_update_blanking(struct mt9m114 *sensor, in mt9m114_pa_ctrl_update_blanking() argument
1137 __v4l2_ctrl_modify_range(sensor->pa.hblank, MT9M114_MIN_HBLANK, in mt9m114_pa_ctrl_update_blanking()
1142 __v4l2_ctrl_modify_range(sensor->pa.vblank, MT9M114_MIN_VBLANK, in mt9m114_pa_ctrl_update_blanking()
1217 struct mt9m114 *sensor = pa_to_mt9m114(sd); in mt9m114_pa_set_fmt() local
1226 /* The sensor can bin horizontally and vertically. */ in mt9m114_pa_set_fmt()
1235 mt9m114_pa_ctrl_update_blanking(sensor, format); in mt9m114_pa_set_fmt()
1267 struct mt9m114 *sensor = pa_to_mt9m114(sd); in mt9m114_pa_set_selection() local
1301 mt9m114_pa_ctrl_update_blanking(sensor, format); in mt9m114_pa_set_selection()
1323 static int mt9m114_pa_init(struct mt9m114 *sensor) in mt9m114_pa_init() argument
1325 struct v4l2_ctrl_handler *hdl = &sensor->pa.hdl; in mt9m114_pa_init()
1326 struct v4l2_subdev *sd = &sensor->pa.sd; in mt9m114_pa_init()
1327 struct media_pad *pads = &sensor->pa.pad; in mt9m114_pa_init()
1336 v4l2_i2c_subdev_set_name(sd, sensor->client, NULL, " pixel array"); in mt9m114_pa_init()
1340 sd->dev = &sensor->client->dev; in mt9m114_pa_init()
1341 v4l2_set_subdevdata(sd, sensor->client); in mt9m114_pa_init()
1355 sensor->pa.hblank = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, in mt9m114_pa_init()
1360 sensor->pa.vblank = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, in mt9m114_pa_init()
1372 sensor->pa.exposure = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, in mt9m114_pa_init()
1375 if (sensor->pa.exposure) in mt9m114_pa_init()
1376 sensor->pa.exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_init()
1378 sensor->pa.gain = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, in mt9m114_pa_init()
1381 if (sensor->pa.gain) in mt9m114_pa_init()
1382 sensor->pa.gain->flags |= V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_init()
1386 sensor->pixrate, sensor->pixrate, 1, in mt9m114_pa_init()
1387 sensor->pixrate); in mt9m114_pa_init()
1410 mt9m114_pa_ctrl_update_blanking(sensor, format); in mt9m114_pa_init()
1418 v4l2_ctrl_handler_free(&sensor->pa.hdl); in mt9m114_pa_init()
1419 media_entity_cleanup(&sensor->pa.sd.entity); in mt9m114_pa_init()
1423 static void mt9m114_pa_cleanup(struct mt9m114 *sensor) in mt9m114_pa_cleanup() argument
1425 v4l2_ctrl_handler_free(&sensor->pa.hdl); in mt9m114_pa_cleanup()
1426 media_entity_cleanup(&sensor->pa.sd.entity); in mt9m114_pa_cleanup()
1460 struct mt9m114 *sensor = ifp_ctrl_to_mt9m114(ctrl); in mt9m114_ifp_s_ctrl() local
1465 mt9m114_pa_ctrl_update_exposure(sensor, in mt9m114_ifp_s_ctrl()
1469 if (!pm_runtime_get_if_in_use(&sensor->client->dev)) in mt9m114_ifp_s_ctrl()
1481 cci_write(sensor->regmap, MT9M114_CAM_AWB_AWBMODE, value, &ret); in mt9m114_ifp_s_ctrl()
1488 cci_write(sensor->regmap, MT9M114_CCM_ALGO, value, &ret); in mt9m114_ifp_s_ctrl()
1498 cci_write(sensor->regmap, MT9M114_AE_TRACK_ALGO, value, &ret); in mt9m114_ifp_s_ctrl()
1508 unsigned int pattern = sensor->ifp.tpg[MT9M114_TPG_PATTERN]->val; in mt9m114_ifp_s_ctrl()
1511 cci_write(sensor->regmap, MT9M114_CAM_MODE_SELECT, in mt9m114_ifp_s_ctrl()
1513 cci_write(sensor->regmap, in mt9m114_ifp_s_ctrl()
1516 cci_write(sensor->regmap, in mt9m114_ifp_s_ctrl()
1518 sensor->ifp.tpg[MT9M114_TPG_RED]->val, &ret); in mt9m114_ifp_s_ctrl()
1519 cci_write(sensor->regmap, in mt9m114_ifp_s_ctrl()
1521 sensor->ifp.tpg[MT9M114_TPG_GREEN]->val, &ret); in mt9m114_ifp_s_ctrl()
1522 cci_write(sensor->regmap, in mt9m114_ifp_s_ctrl()
1524 sensor->ifp.tpg[MT9M114_TPG_BLUE]->val, &ret); in mt9m114_ifp_s_ctrl()
1526 cci_write(sensor->regmap, MT9M114_CAM_MODE_SELECT, in mt9m114_ifp_s_ctrl()
1535 if (ret || !sensor->streaming) in mt9m114_ifp_s_ctrl()
1538 ret = mt9m114_set_state(sensor, in mt9m114_ifp_s_ctrl()
1548 pm_runtime_mark_last_busy(&sensor->client->dev); in mt9m114_ifp_s_ctrl()
1549 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_ifp_s_ctrl()
1569 struct mt9m114 *sensor = ifp_to_mt9m114(sd); in mt9m114_ifp_s_stream() local
1575 return mt9m114_stop_streaming(sensor); in mt9m114_ifp_s_stream()
1577 ifp_state = v4l2_subdev_lock_and_get_active_state(&sensor->ifp.sd); in mt9m114_ifp_s_stream()
1578 pa_state = v4l2_subdev_lock_and_get_active_state(&sensor->pa.sd); in mt9m114_ifp_s_stream()
1580 ret = mt9m114_start_streaming(sensor, pa_state, ifp_state); in mt9m114_ifp_s_stream()
1593 struct mt9m114 *sensor = ifp_to_mt9m114(sd); in mt9m114_ifp_get_frame_interval() local
1602 mutex_lock(sensor->ifp.hdl.lock); in mt9m114_ifp_get_frame_interval()
1605 ival->denominator = sensor->ifp.frame_rate; in mt9m114_ifp_get_frame_interval()
1607 mutex_unlock(sensor->ifp.hdl.lock); in mt9m114_ifp_get_frame_interval()
1617 struct mt9m114 *sensor = ifp_to_mt9m114(sd); in mt9m114_ifp_set_frame_interval() local
1627 mutex_lock(sensor->ifp.hdl.lock); in mt9m114_ifp_set_frame_interval()
1630 sensor->ifp.frame_rate = min_t(unsigned int, in mt9m114_ifp_set_frame_interval()
1634 sensor->ifp.frame_rate = MT9M114_MAX_FRAME_RATE; in mt9m114_ifp_set_frame_interval()
1637 ival->denominator = sensor->ifp.frame_rate; in mt9m114_ifp_set_frame_interval()
1639 if (sensor->streaming) in mt9m114_ifp_set_frame_interval()
1640 ret = mt9m114_set_frame_rate(sensor); in mt9m114_ifp_set_frame_interval()
1642 mutex_unlock(sensor->ifp.hdl.lock); in mt9m114_ifp_set_frame_interval()
1650 struct mt9m114 *sensor = ifp_to_mt9m114(sd); in mt9m114_ifp_init_state() local
1684 format->code = mt9m114_default_format_info(sensor)->code; in mt9m114_ifp_init_state()
1699 struct mt9m114 *sensor = ifp_to_mt9m114(sd); in mt9m114_ifp_enum_mbus_code() local
1713 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) in mt9m114_ifp_enum_mbus_code()
1743 struct mt9m114 *sensor = ifp_to_mt9m114(sd); in mt9m114_ifp_enum_framesizes() local
1749 info = mt9m114_format_info(sensor, fse->pad, fse->code); in mt9m114_ifp_enum_framesizes()
1777 struct mt9m114 *sensor = ifp_to_mt9m114(sd); in mt9m114_ifp_enum_frameintervals() local
1783 info = mt9m114_format_info(sensor, fie->pad, fie->code); in mt9m114_ifp_enum_frameintervals()
1797 struct mt9m114 *sensor = ifp_to_mt9m114(sd); in mt9m114_ifp_set_fmt() local
1814 info = mt9m114_format_info(sensor, 1, fmt->format.code); in mt9m114_ifp_set_fmt()
1953 struct mt9m114 *sensor = ifp_to_mt9m114(sd); in mt9m114_ifp_unregistered() local
1955 v4l2_device_unregister_subdev(&sensor->pa.sd); in mt9m114_ifp_unregistered()
1960 struct mt9m114 *sensor = ifp_to_mt9m114(sd); in mt9m114_ifp_registered() local
1963 ret = v4l2_device_register_subdev(sd->v4l2_dev, &sensor->pa.sd); in mt9m114_ifp_registered()
1965 dev_err(&sensor->client->dev, in mt9m114_ifp_registered()
1970 ret = media_create_pad_link(&sensor->pa.sd.entity, 0, in mt9m114_ifp_registered()
1971 &sensor->ifp.sd.entity, 0, in mt9m114_ifp_registered()
1975 dev_err(&sensor->client->dev, in mt9m114_ifp_registered()
1977 v4l2_device_unregister_subdev(&sensor->pa.sd); in mt9m114_ifp_registered()
2011 static int mt9m114_ifp_init(struct mt9m114 *sensor) in mt9m114_ifp_init() argument
2013 struct v4l2_subdev *sd = &sensor->ifp.sd; in mt9m114_ifp_init()
2014 struct media_pad *pads = sensor->ifp.pads; in mt9m114_ifp_init()
2015 struct v4l2_ctrl_handler *hdl = &sensor->ifp.hdl; in mt9m114_ifp_init()
2020 v4l2_i2c_subdev_init(sd, sensor->client, &mt9m114_ifp_ops); in mt9m114_ifp_init()
2021 v4l2_i2c_subdev_set_name(sd, sensor->client, NULL, " ifp"); in mt9m114_ifp_init()
2035 sensor->ifp.frame_rate = MT9M114_DEF_FRAME_RATE; in mt9m114_ifp_init()
2049 sensor->bus_cfg.nr_of_link_frequencies - 1, in mt9m114_ifp_init()
2050 0, sensor->bus_cfg.link_frequencies); in mt9m114_ifp_init()
2056 sensor->pixrate, sensor->pixrate, 1, in mt9m114_ifp_init()
2057 sensor->pixrate); in mt9m114_ifp_init()
2059 sensor->ifp.tpg[MT9M114_TPG_PATTERN] = in mt9m114_ifp_init()
2064 sensor->ifp.tpg[MT9M114_TPG_RED] = in mt9m114_ifp_init()
2068 sensor->ifp.tpg[MT9M114_TPG_GREEN] = in mt9m114_ifp_init()
2072 sensor->ifp.tpg[MT9M114_TPG_BLUE] = in mt9m114_ifp_init()
2077 v4l2_ctrl_cluster(ARRAY_SIZE(sensor->ifp.tpg), sensor->ifp.tpg); in mt9m114_ifp_init()
2094 v4l2_ctrl_handler_free(&sensor->ifp.hdl); in mt9m114_ifp_init()
2095 media_entity_cleanup(&sensor->ifp.sd.entity); in mt9m114_ifp_init()
2099 static void mt9m114_ifp_cleanup(struct mt9m114 *sensor) in mt9m114_ifp_cleanup() argument
2101 v4l2_ctrl_handler_free(&sensor->ifp.hdl); in mt9m114_ifp_cleanup()
2102 media_entity_cleanup(&sensor->ifp.sd.entity); in mt9m114_ifp_cleanup()
2109 static int mt9m114_power_on(struct mt9m114 *sensor) in mt9m114_power_on() argument
2114 ret = regulator_bulk_enable(ARRAY_SIZE(sensor->supplies), in mt9m114_power_on()
2115 sensor->supplies); in mt9m114_power_on()
2119 ret = clk_prepare_enable(sensor->clk); in mt9m114_power_on()
2124 if (sensor->reset) { in mt9m114_power_on()
2125 long freq = clk_get_rate(sensor->clk); in mt9m114_power_on()
2134 gpiod_set_value(sensor->reset, 1); in mt9m114_power_on()
2136 gpiod_set_value(sensor->reset, 0); in mt9m114_power_on()
2140 * the sensor to be ready to accept I2C commands. in mt9m114_power_on()
2144 cci_write(sensor->regmap, MT9M114_RESET_AND_MISC_CONTROL, in mt9m114_power_on()
2146 cci_write(sensor->regmap, MT9M114_RESET_AND_MISC_CONTROL, 0, in mt9m114_power_on()
2150 dev_err(&sensor->client->dev, "Soft reset failed\n"); in mt9m114_power_on()
2156 * Wait for the sensor to be ready to accept I2C commands by polling the in mt9m114_power_on()
2161 ret = mt9m114_poll_command(sensor, MT9M114_COMMAND_REGISTER_SET_STATE); in mt9m114_power_on()
2165 if (sensor->bus_cfg.bus_type == V4L2_MBUS_PARALLEL) { in mt9m114_power_on()
2167 * In parallel mode (OE set to low), the sensor will enter the in mt9m114_power_on()
2171 ret = mt9m114_set_state(sensor, in mt9m114_power_on()
2178 * Before issuing any Set-State command, we must ensure that the sensor in mt9m114_power_on()
2182 ret = mt9m114_poll_state(sensor, MT9M114_SYS_STATE_STANDBY); in mt9m114_power_on()
2189 clk_disable_unprepare(sensor->clk); in mt9m114_power_on()
2191 regulator_bulk_disable(ARRAY_SIZE(sensor->supplies), sensor->supplies); in mt9m114_power_on()
2195 static void mt9m114_power_off(struct mt9m114 *sensor) in mt9m114_power_off() argument
2197 clk_disable_unprepare(sensor->clk); in mt9m114_power_off()
2198 regulator_bulk_disable(ARRAY_SIZE(sensor->supplies), sensor->supplies); in mt9m114_power_off()
2204 struct mt9m114 *sensor = ifp_to_mt9m114(sd); in mt9m114_runtime_resume() local
2207 ret = mt9m114_power_on(sensor); in mt9m114_runtime_resume()
2211 ret = mt9m114_initialize(sensor); in mt9m114_runtime_resume()
2213 mt9m114_power_off(sensor); in mt9m114_runtime_resume()
2223 struct mt9m114 *sensor = ifp_to_mt9m114(sd); in mt9m114_runtime_suspend() local
2225 mt9m114_power_off(sensor); in mt9m114_runtime_suspend()
2238 static int mt9m114_clk_init(struct mt9m114 *sensor) in mt9m114_clk_init() argument
2243 sensor->pll.m = 32; in mt9m114_clk_init()
2244 sensor->pll.n = 1; in mt9m114_clk_init()
2245 sensor->pll.p = 7; in mt9m114_clk_init()
2250 * parallel mode, the sensor ouputs one pixel in two PIXCLK cycles. in mt9m114_clk_init()
2252 sensor->pixrate = clk_get_rate(sensor->clk) * sensor->pll.m in mt9m114_clk_init()
2253 / ((sensor->pll.n + 1) * (sensor->pll.p + 1)); in mt9m114_clk_init()
2255 link_freq = sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY in mt9m114_clk_init()
2256 ? sensor->pixrate * 8 : sensor->pixrate * 2; in mt9m114_clk_init()
2258 if (sensor->bus_cfg.nr_of_link_frequencies != 1 || in mt9m114_clk_init()
2259 sensor->bus_cfg.link_frequencies[0] != link_freq) { in mt9m114_clk_init()
2260 dev_err(&sensor->client->dev, "Unsupported DT link-frequencies\n"); in mt9m114_clk_init()
2267 static int mt9m114_identify(struct mt9m114 *sensor) in mt9m114_identify() argument
2273 ret = cci_read(sensor->regmap, MT9M114_CHIP_ID, &value, NULL); in mt9m114_identify()
2275 dev_err(&sensor->client->dev, "Failed to read chip ID\n"); in mt9m114_identify()
2280 dev_err(&sensor->client->dev, "Invalid chip ID 0x%04llx\n", in mt9m114_identify()
2285 cci_read(sensor->regmap, MT9M114_MON_MAJOR_VERSION, &major, &ret); in mt9m114_identify()
2286 cci_read(sensor->regmap, MT9M114_MON_MINOR_VERSION, &minor, &ret); in mt9m114_identify()
2287 cci_read(sensor->regmap, MT9M114_MON_RELEASE_VERSION, &release, &ret); in mt9m114_identify()
2288 cci_read(sensor->regmap, MT9M114_CUSTOMER_REV, &customer, &ret); in mt9m114_identify()
2290 dev_err(&sensor->client->dev, "Failed to read version\n"); in mt9m114_identify()
2294 dev_dbg(&sensor->client->dev, in mt9m114_identify()
2301 static int mt9m114_parse_dt(struct mt9m114 *sensor) in mt9m114_parse_dt() argument
2303 struct fwnode_handle *fwnode = dev_fwnode(&sensor->client->dev); in mt9m114_parse_dt()
2309 dev_err(&sensor->client->dev, "No endpoint found\n"); in mt9m114_parse_dt()
2313 sensor->bus_cfg.bus_type = V4L2_MBUS_UNKNOWN; in mt9m114_parse_dt()
2314 ret = v4l2_fwnode_endpoint_alloc_parse(ep, &sensor->bus_cfg); in mt9m114_parse_dt()
2317 dev_err(&sensor->client->dev, "Failed to parse endpoint\n"); in mt9m114_parse_dt()
2321 switch (sensor->bus_cfg.bus_type) { in mt9m114_parse_dt()
2327 dev_err(&sensor->client->dev, "unsupported bus type %u\n", in mt9m114_parse_dt()
2328 sensor->bus_cfg.bus_type); in mt9m114_parse_dt()
2336 v4l2_fwnode_endpoint_free(&sensor->bus_cfg); in mt9m114_parse_dt()
2343 struct mt9m114 *sensor; in mt9m114_probe() local
2346 sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); in mt9m114_probe()
2347 if (!sensor) in mt9m114_probe()
2350 sensor->client = client; in mt9m114_probe()
2352 sensor->regmap = devm_cci_regmap_init_i2c(client, 16); in mt9m114_probe()
2353 if (IS_ERR(sensor->regmap)) { in mt9m114_probe()
2358 ret = mt9m114_parse_dt(sensor); in mt9m114_probe()
2363 sensor->clk = devm_clk_get(dev, NULL); in mt9m114_probe()
2364 if (IS_ERR(sensor->clk)) { in mt9m114_probe()
2365 ret = PTR_ERR(sensor->clk); in mt9m114_probe()
2370 sensor->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); in mt9m114_probe()
2371 if (IS_ERR(sensor->reset)) { in mt9m114_probe()
2372 ret = PTR_ERR(sensor->reset); in mt9m114_probe()
2377 sensor->supplies[0].supply = "vddio"; in mt9m114_probe()
2378 sensor->supplies[1].supply = "vdd"; in mt9m114_probe()
2379 sensor->supplies[2].supply = "vaa"; in mt9m114_probe()
2381 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sensor->supplies), in mt9m114_probe()
2382 sensor->supplies); in mt9m114_probe()
2388 ret = mt9m114_clk_init(sensor); in mt9m114_probe()
2393 * Identify the sensor. The driver supports runtime PM, but needs to in mt9m114_probe()
2395 * the sensor on manually here, and initialize it after identification in mt9m114_probe()
2398 ret = mt9m114_power_on(sensor); in mt9m114_probe()
2404 ret = mt9m114_identify(sensor); in mt9m114_probe()
2408 ret = mt9m114_initialize(sensor); in mt9m114_probe()
2424 ret = mt9m114_pa_init(sensor); in mt9m114_probe()
2428 ret = mt9m114_ifp_init(sensor); in mt9m114_probe()
2432 ret = v4l2_async_register_subdev(&sensor->ifp.sd); in mt9m114_probe()
2446 mt9m114_ifp_cleanup(sensor); in mt9m114_probe()
2448 mt9m114_pa_cleanup(sensor); in mt9m114_probe()
2453 mt9m114_power_off(sensor); in mt9m114_probe()
2455 v4l2_fwnode_endpoint_free(&sensor->bus_cfg); in mt9m114_probe()
2462 struct mt9m114 *sensor = ifp_to_mt9m114(sd); in mt9m114_remove() local
2465 v4l2_async_unregister_subdev(&sensor->ifp.sd); in mt9m114_remove()
2467 mt9m114_ifp_cleanup(sensor); in mt9m114_remove()
2468 mt9m114_pa_cleanup(sensor); in mt9m114_remove()
2469 v4l2_fwnode_endpoint_free(&sensor->bus_cfg); in mt9m114_remove()
2477 mt9m114_power_off(sensor); in mt9m114_remove()
2499 MODULE_DESCRIPTION("onsemi MT9M114 Sensor Driver");