Lines Matching refs:mt9m111
228 struct mt9m111 { struct
282 static const struct mt9m111_datafmt *mt9m111_find_datafmt(struct mt9m111 *mt9m111, in mt9m111_find_datafmt() argument
290 return mt9m111->fmt; in mt9m111_find_datafmt()
293 static struct mt9m111 *to_mt9m111(const struct i2c_client *client) in to_mt9m111()
295 return container_of(i2c_get_clientdata(client), struct mt9m111, subdev); in to_mt9m111()
302 struct mt9m111 *mt9m111 = to_mt9m111(client); in reg_page_map_set() local
305 if (page == mt9m111->lastpage) in reg_page_map_set()
312 mt9m111->lastpage = page; in reg_page_map_set()
373 static int mt9m111_set_context(struct mt9m111 *mt9m111, in mt9m111_set_context() argument
376 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_set_context()
380 static int mt9m111_setup_rect_ctx(struct mt9m111 *mt9m111, in mt9m111_setup_rect_ctx() argument
384 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_setup_rect_ctx()
395 static int mt9m111_setup_geometry(struct mt9m111 *mt9m111, struct v4l2_rect *rect, in mt9m111_setup_geometry() argument
398 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_setup_geometry()
413 ret = mt9m111_setup_rect_ctx(mt9m111, &context_b, in mt9m111_setup_geometry()
416 ret = mt9m111_setup_rect_ctx(mt9m111, &context_a, in mt9m111_setup_geometry()
427 static int mt9m111_enable(struct mt9m111 *mt9m111) in mt9m111_enable() argument
429 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_enable()
433 static int mt9m111_reset(struct mt9m111 *mt9m111) in mt9m111_reset() argument
435 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_reset()
453 struct mt9m111 *mt9m111 = to_mt9m111(client); in mt9m111_set_selection() local
462 if (mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8 || in mt9m111_set_selection()
463 mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) { in mt9m111_set_selection()
479 width = min(mt9m111->width, rect.width); in mt9m111_set_selection()
480 height = min(mt9m111->height, rect.height); in mt9m111_set_selection()
482 ret = mt9m111_setup_geometry(mt9m111, &rect, width, height, mt9m111->fmt->code); in mt9m111_set_selection()
484 mt9m111->rect = rect; in mt9m111_set_selection()
485 mt9m111->width = width; in mt9m111_set_selection()
486 mt9m111->height = height; in mt9m111_set_selection()
497 struct mt9m111 *mt9m111 = to_mt9m111(client); in mt9m111_get_selection() local
510 sel->r = mt9m111->rect; in mt9m111_get_selection()
522 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); in mt9m111_get_fmt() local
533 mf->width = mt9m111->width; in mt9m111_get_fmt()
534 mf->height = mt9m111->height; in mt9m111_get_fmt()
535 mf->code = mt9m111->fmt->code; in mt9m111_get_fmt()
536 mf->colorspace = mt9m111->fmt->colorspace; in mt9m111_get_fmt()
545 static int mt9m111_set_pixfmt(struct mt9m111 *mt9m111, in mt9m111_set_pixfmt() argument
548 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_set_pixfmt()
607 if (mt9m111->pclk_sample == 0) in mt9m111_set_pixfmt()
625 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); in mt9m111_set_fmt() local
627 struct v4l2_rect *rect = &mt9m111->rect; in mt9m111_set_fmt()
631 if (mt9m111->is_streaming) in mt9m111_set_fmt()
637 fmt = mt9m111_find_datafmt(mt9m111, mf->code); in mt9m111_set_fmt()
678 ret = mt9m111_setup_geometry(mt9m111, rect, mf->width, mf->height, mf->code); in mt9m111_set_fmt()
680 ret = mt9m111_set_pixfmt(mt9m111, mf->code); in mt9m111_set_fmt()
682 mt9m111->width = mf->width; in mt9m111_set_fmt()
683 mt9m111->height = mf->height; in mt9m111_set_fmt()
684 mt9m111->fmt = fmt; in mt9m111_set_fmt()
691 mt9m111_find_mode(struct mt9m111 *mt9m111, unsigned int req_fps, in mt9m111_find_mode() argument
695 struct v4l2_rect *sensor_rect = &mt9m111->rect; in mt9m111_find_mode()
707 dev_info(mt9m111->subdev.dev, in mt9m111_find_mode()
715 dev_dbg(mt9m111->subdev.dev, in mt9m111_find_mode()
740 mt9m111->ctx = (best_gap_idx == MT9M111_MODE_QSXGA_30FPS) ? &context_a : in mt9m111_find_mode()
780 static int mt9m111_set_flip(struct mt9m111 *mt9m111, int flip, int mask) in mt9m111_set_flip() argument
782 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_set_flip()
786 ret = mt9m111_reg_set(client, mt9m111->ctx->read_mode, mask); in mt9m111_set_flip()
788 ret = mt9m111_reg_clear(client, mt9m111->ctx->read_mode, mask); in mt9m111_set_flip()
793 static int mt9m111_get_global_gain(struct mt9m111 *mt9m111) in mt9m111_get_global_gain() argument
795 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_get_global_gain()
805 static int mt9m111_set_global_gain(struct mt9m111 *mt9m111, int gain) in mt9m111_set_global_gain() argument
807 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_set_global_gain()
823 static int mt9m111_set_autoexposure(struct mt9m111 *mt9m111, int val) in mt9m111_set_autoexposure() argument
825 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_set_autoexposure()
832 static int mt9m111_set_autowhitebalance(struct mt9m111 *mt9m111, int on) in mt9m111_set_autowhitebalance() argument
834 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_set_autowhitebalance()
852 static int mt9m111_set_test_pattern(struct mt9m111 *mt9m111, int val) in mt9m111_set_test_pattern() argument
854 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_set_test_pattern()
860 static int mt9m111_set_colorfx(struct mt9m111 *mt9m111, int val) in mt9m111_set_colorfx() argument
862 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_set_colorfx()
885 struct mt9m111 *mt9m111 = container_of(ctrl->handler, in mt9m111_s_ctrl() local
886 struct mt9m111, hdl); in mt9m111_s_ctrl()
890 return mt9m111_set_flip(mt9m111, ctrl->val, in mt9m111_s_ctrl()
893 return mt9m111_set_flip(mt9m111, ctrl->val, in mt9m111_s_ctrl()
896 return mt9m111_set_global_gain(mt9m111, ctrl->val); in mt9m111_s_ctrl()
898 return mt9m111_set_autoexposure(mt9m111, ctrl->val); in mt9m111_s_ctrl()
900 return mt9m111_set_autowhitebalance(mt9m111, ctrl->val); in mt9m111_s_ctrl()
902 return mt9m111_set_test_pattern(mt9m111, ctrl->val); in mt9m111_s_ctrl()
904 return mt9m111_set_colorfx(mt9m111, ctrl->val); in mt9m111_s_ctrl()
910 static int mt9m111_suspend(struct mt9m111 *mt9m111) in mt9m111_suspend() argument
912 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_suspend()
915 v4l2_ctrl_s_ctrl(mt9m111->gain, mt9m111_get_global_gain(mt9m111)); in mt9m111_suspend()
928 static void mt9m111_restore_state(struct mt9m111 *mt9m111) in mt9m111_restore_state() argument
930 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_restore_state()
932 mt9m111_set_context(mt9m111, mt9m111->ctx); in mt9m111_restore_state()
933 mt9m111_set_pixfmt(mt9m111, mt9m111->fmt->code); in mt9m111_restore_state()
934 mt9m111_setup_geometry(mt9m111, &mt9m111->rect, in mt9m111_restore_state()
935 mt9m111->width, mt9m111->height, mt9m111->fmt->code); in mt9m111_restore_state()
936 v4l2_ctrl_handler_setup(&mt9m111->hdl); in mt9m111_restore_state()
937 mt9m111_reg_mask(client, mt9m111->ctx->read_mode, in mt9m111_restore_state()
938 mt9m111->current_mode->reg_val, in mt9m111_restore_state()
939 mt9m111->current_mode->reg_mask); in mt9m111_restore_state()
942 static int mt9m111_resume(struct mt9m111 *mt9m111) in mt9m111_resume() argument
944 int ret = mt9m111_enable(mt9m111); in mt9m111_resume()
946 ret = mt9m111_reset(mt9m111); in mt9m111_resume()
948 mt9m111_restore_state(mt9m111); in mt9m111_resume()
953 static int mt9m111_init(struct mt9m111 *mt9m111) in mt9m111_init() argument
955 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_init()
958 ret = mt9m111_enable(mt9m111); in mt9m111_init()
960 ret = mt9m111_reset(mt9m111); in mt9m111_init()
962 ret = mt9m111_set_context(mt9m111, mt9m111->ctx); in mt9m111_init()
968 static int mt9m111_power_on(struct mt9m111 *mt9m111) in mt9m111_power_on() argument
970 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); in mt9m111_power_on()
973 ret = clk_prepare_enable(mt9m111->clk); in mt9m111_power_on()
977 ret = regulator_enable(mt9m111->regulator); in mt9m111_power_on()
981 ret = mt9m111_resume(mt9m111); in mt9m111_power_on()
988 regulator_disable(mt9m111->regulator); in mt9m111_power_on()
991 clk_disable_unprepare(mt9m111->clk); in mt9m111_power_on()
998 static void mt9m111_power_off(struct mt9m111 *mt9m111) in mt9m111_power_off() argument
1000 mt9m111_suspend(mt9m111); in mt9m111_power_off()
1001 regulator_disable(mt9m111->regulator); in mt9m111_power_off()
1002 clk_disable_unprepare(mt9m111->clk); in mt9m111_power_off()
1007 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); in mt9m111_s_power() local
1010 mutex_lock(&mt9m111->power_lock); in mt9m111_s_power()
1016 if (mt9m111->power_count == !on) { in mt9m111_s_power()
1018 ret = mt9m111_power_on(mt9m111); in mt9m111_s_power()
1020 mt9m111_power_off(mt9m111); in mt9m111_s_power()
1025 mt9m111->power_count += on ? 1 : -1; in mt9m111_s_power()
1026 WARN_ON(mt9m111->power_count < 0); in mt9m111_s_power()
1029 mutex_unlock(&mt9m111->power_lock); in mt9m111_s_power()
1052 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); in mt9m111_get_frame_interval() local
1061 fi->interval = mt9m111->frame_interval; in mt9m111_get_frame_interval()
1070 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); in mt9m111_set_frame_interval() local
1075 if (mt9m111->is_streaming) in mt9m111_set_frame_interval()
1096 mode = mt9m111_find_mode(mt9m111, fps, mt9m111->width, mt9m111->height); in mt9m111_set_frame_interval()
1105 mt9m111->current_mode = mode; in mt9m111_set_frame_interval()
1106 mt9m111->frame_interval = fi->interval; in mt9m111_set_frame_interval()
1124 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); in mt9m111_s_stream() local
1126 mt9m111->is_streaming = !!enable; in mt9m111_s_stream()
1152 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); in mt9m111_get_mbus_config() local
1161 cfg->bus.parallel.flags |= mt9m111->pclk_sample ? in mt9m111_get_mbus_config()
1199 struct mt9m111 *mt9m111 = to_mt9m111(client); in mt9m111_video_probe() local
1203 ret = mt9m111_s_power(&mt9m111->subdev, 1); in mt9m111_video_probe()
1225 ret = mt9m111_init(mt9m111); in mt9m111_video_probe()
1229 ret = v4l2_ctrl_handler_setup(&mt9m111->hdl); in mt9m111_video_probe()
1232 mt9m111_s_power(&mt9m111->subdev, 0); in mt9m111_video_probe()
1236 static int mt9m111_probe_fw(struct i2c_client *client, struct mt9m111 *mt9m111) in mt9m111_probe_fw() argument
1252 mt9m111->pclk_sample = !!(bus_cfg.bus.parallel.flags & in mt9m111_probe_fw()
1262 struct mt9m111 *mt9m111; in mt9m111_probe() local
1272 mt9m111 = devm_kzalloc(&client->dev, sizeof(struct mt9m111), GFP_KERNEL); in mt9m111_probe()
1273 if (!mt9m111) in mt9m111_probe()
1277 ret = mt9m111_probe_fw(client, mt9m111); in mt9m111_probe()
1282 mt9m111->clk = devm_clk_get(&client->dev, "mclk"); in mt9m111_probe()
1283 if (IS_ERR(mt9m111->clk)) in mt9m111_probe()
1284 return PTR_ERR(mt9m111->clk); in mt9m111_probe()
1286 mt9m111->regulator = devm_regulator_get(&client->dev, "vdd"); in mt9m111_probe()
1287 if (IS_ERR(mt9m111->regulator)) { in mt9m111_probe()
1289 PTR_ERR(mt9m111->regulator)); in mt9m111_probe()
1290 return PTR_ERR(mt9m111->regulator); in mt9m111_probe()
1294 mt9m111->ctx = &context_b; in mt9m111_probe()
1296 v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops); in mt9m111_probe()
1297 mt9m111->subdev.internal_ops = &mt9m111_internal_ops; in mt9m111_probe()
1298 mt9m111->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | in mt9m111_probe()
1301 v4l2_ctrl_handler_init(&mt9m111->hdl, 7); in mt9m111_probe()
1302 v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops, in mt9m111_probe()
1304 v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops, in mt9m111_probe()
1306 v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops, in mt9m111_probe()
1308 mt9m111->gain = v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops, in mt9m111_probe()
1310 v4l2_ctrl_new_std_menu(&mt9m111->hdl, in mt9m111_probe()
1313 v4l2_ctrl_new_std_menu_items(&mt9m111->hdl, in mt9m111_probe()
1317 v4l2_ctrl_new_std_menu(&mt9m111->hdl, &mt9m111_ctrl_ops, in mt9m111_probe()
1325 mt9m111->subdev.ctrl_handler = &mt9m111->hdl; in mt9m111_probe()
1326 if (mt9m111->hdl.error) { in mt9m111_probe()
1327 ret = mt9m111->hdl.error; in mt9m111_probe()
1331 mt9m111->pad.flags = MEDIA_PAD_FL_SOURCE; in mt9m111_probe()
1332 mt9m111->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR; in mt9m111_probe()
1333 ret = media_entity_pads_init(&mt9m111->subdev.entity, 1, &mt9m111->pad); in mt9m111_probe()
1337 mt9m111->current_mode = &mt9m111_mode_data[MT9M111_MODE_SXGA_15FPS]; in mt9m111_probe()
1338 mt9m111->frame_interval.numerator = 1; in mt9m111_probe()
1339 mt9m111->frame_interval.denominator = mt9m111->current_mode->max_fps; in mt9m111_probe()
1342 mt9m111->rect.left = MT9M111_MIN_DARK_COLS; in mt9m111_probe()
1343 mt9m111->rect.top = MT9M111_MIN_DARK_ROWS; in mt9m111_probe()
1344 mt9m111->rect.width = MT9M111_MAX_WIDTH; in mt9m111_probe()
1345 mt9m111->rect.height = MT9M111_MAX_HEIGHT; in mt9m111_probe()
1346 mt9m111->width = mt9m111->rect.width; in mt9m111_probe()
1347 mt9m111->height = mt9m111->rect.height; in mt9m111_probe()
1348 mt9m111->fmt = &mt9m111_colour_fmts[0]; in mt9m111_probe()
1349 mt9m111->lastpage = -1; in mt9m111_probe()
1350 mutex_init(&mt9m111->power_lock); in mt9m111_probe()
1356 mt9m111->subdev.dev = &client->dev; in mt9m111_probe()
1357 ret = v4l2_async_register_subdev(&mt9m111->subdev); in mt9m111_probe()
1364 media_entity_cleanup(&mt9m111->subdev.entity); in mt9m111_probe()
1366 v4l2_ctrl_handler_free(&mt9m111->hdl); in mt9m111_probe()
1373 struct mt9m111 *mt9m111 = to_mt9m111(client); in mt9m111_remove() local
1375 v4l2_async_unregister_subdev(&mt9m111->subdev); in mt9m111_remove()
1376 media_entity_cleanup(&mt9m111->subdev.entity); in mt9m111_remove()
1377 v4l2_ctrl_handler_free(&mt9m111->hdl); in mt9m111_remove()