Lines Matching full:mt9v111
3 * V4L2 sensor driver for Aptina MT9V111 image sensor
31 * MT9V111 is a 1/4-Inch CMOS digital image sensor with an integrated
276 struct mt9v111_dev *mt9v111 = sd_to_mt9v111(sd); in __mt9v111_addr_space_select() local
280 if (mt9v111->addr_space == addr_space) in __mt9v111_addr_space_select()
295 mt9v111->addr_space = addr_space; in __mt9v111_addr_space_select()
361 struct mt9v111_dev *mt9v111 = sd_to_mt9v111(sd); in __mt9v111_power_on() local
364 ret = clk_prepare_enable(mt9v111->clk); in __mt9v111_power_on()
368 clk_set_rate(mt9v111->clk, mt9v111->sysclk); in __mt9v111_power_on()
370 gpiod_set_value(mt9v111->standby, 0); in __mt9v111_power_on()
373 gpiod_set_value(mt9v111->oe, 1); in __mt9v111_power_on()
381 struct mt9v111_dev *mt9v111 = sd_to_mt9v111(sd); in __mt9v111_power_off() local
383 gpiod_set_value(mt9v111->oe, 0); in __mt9v111_power_off()
386 gpiod_set_value(mt9v111->standby, 1); in __mt9v111_power_off()
389 clk_disable_unprepare(mt9v111->clk); in __mt9v111_power_off()
394 static int __mt9v111_hw_reset(struct mt9v111_dev *mt9v111) in __mt9v111_hw_reset() argument
396 if (!mt9v111->reset) in __mt9v111_hw_reset()
399 gpiod_set_value(mt9v111->reset, 1); in __mt9v111_hw_reset()
402 gpiod_set_value(mt9v111->reset, 0); in __mt9v111_hw_reset()
408 static int __mt9v111_sw_reset(struct mt9v111_dev *mt9v111) in __mt9v111_sw_reset() argument
410 struct i2c_client *c = mt9v111->client; in __mt9v111_sw_reset()
446 static int mt9v111_calc_frame_rate(struct mt9v111_dev *mt9v111, in mt9v111_calc_frame_rate() argument
491 pclk = DIV_ROUND_CLOSEST(mt9v111->sysclk, 2); in mt9v111_calc_frame_rate()
518 ret = v4l2_ctrl_s_ctrl_int64(mt9v111->hblank, hb); in mt9v111_calc_frame_rate()
522 ret = v4l2_ctrl_s_ctrl_int64(mt9v111->vblank, vb); in mt9v111_calc_frame_rate()
532 static int mt9v111_hw_config(struct mt9v111_dev *mt9v111) in mt9v111_hw_config() argument
534 struct i2c_client *c = mt9v111->client; in mt9v111_hw_config()
539 ret = __mt9v111_hw_reset(mt9v111); in mt9v111_hw_config()
541 ret = __mt9v111_sw_reset(mt9v111); in mt9v111_hw_config()
546 ret = mt9v111->sysclk < DIV_ROUND_CLOSEST(MT9V111_MAX_CLKIN, 2) ? in mt9v111_hw_config()
562 switch (mt9v111->fmt.code) { in mt9v111_hw_config()
618 mt9v111->fmt.width); in mt9v111_hw_config()
623 mt9v111->fmt.height); in mt9v111_hw_config()
628 ret = v4l2_ctrl_handler_setup(&mt9v111->ctrls); in mt9v111_hw_config()
646 struct mt9v111_dev *mt9v111 = sd_to_mt9v111(sd); in mt9v111_s_power() local
650 mutex_lock(&mt9v111->pwr_mutex); in mt9v111_s_power()
656 pwr_count = mt9v111->pwr_count; in mt9v111_s_power()
663 mt9v111->pwr_count = pwr_count; in mt9v111_s_power()
665 mutex_unlock(&mt9v111->pwr_mutex); in mt9v111_s_power()
675 mt9v111->pwr_count = pwr_count; in mt9v111_s_power()
677 mutex_unlock(&mt9v111->pwr_mutex); in mt9v111_s_power()
684 struct mt9v111_dev *mt9v111 = sd_to_mt9v111(subdev); in mt9v111_s_stream() local
687 mutex_lock(&mt9v111->stream_mutex); in mt9v111_s_stream()
689 if (mt9v111->streaming == enable) { in mt9v111_s_stream()
690 mutex_unlock(&mt9v111->stream_mutex); in mt9v111_s_stream()
698 if (enable && mt9v111->pending) { in mt9v111_s_stream()
699 ret = mt9v111_hw_config(mt9v111); in mt9v111_s_stream()
708 mt9v111->pending = false; in mt9v111_s_stream()
711 mt9v111->streaming = enable ? true : false; in mt9v111_s_stream()
712 mutex_unlock(&mt9v111->stream_mutex); in mt9v111_s_stream()
717 mutex_unlock(&mt9v111->stream_mutex); in mt9v111_s_stream()
726 struct mt9v111_dev *mt9v111 = sd_to_mt9v111(sd); in mt9v111_set_frame_interval() local
743 mutex_lock(&mt9v111->stream_mutex); in mt9v111_set_frame_interval()
745 if (mt9v111->streaming) { in mt9v111_set_frame_interval()
746 mutex_unlock(&mt9v111->stream_mutex); in mt9v111_set_frame_interval()
750 if (mt9v111->fps == fps) { in mt9v111_set_frame_interval()
751 mutex_unlock(&mt9v111->stream_mutex); in mt9v111_set_frame_interval()
756 if (mt9v111->fmt.width < QVGA_WIDTH && in mt9v111_set_frame_interval()
757 mt9v111->fmt.height < QVGA_HEIGHT) in mt9v111_set_frame_interval()
759 else if (mt9v111->fmt.width < CIF_WIDTH && in mt9v111_set_frame_interval()
760 mt9v111->fmt.height < CIF_HEIGHT) in mt9v111_set_frame_interval()
763 max_fps = mt9v111->sysclk < in mt9v111_set_frame_interval()
768 mutex_unlock(&mt9v111->stream_mutex); in mt9v111_set_frame_interval()
772 mt9v111_calc_frame_rate(mt9v111, tpf); in mt9v111_set_frame_interval()
774 mt9v111->fps = fps; in mt9v111_set_frame_interval()
775 mt9v111->pending = true; in mt9v111_set_frame_interval()
777 mutex_unlock(&mt9v111->stream_mutex); in mt9v111_set_frame_interval()
786 struct mt9v111_dev *mt9v111 = sd_to_mt9v111(sd); in mt9v111_get_frame_interval() local
796 mutex_lock(&mt9v111->stream_mutex); in mt9v111_get_frame_interval()
799 tpf->denominator = mt9v111->fps; in mt9v111_get_frame_interval()
801 mutex_unlock(&mt9v111->stream_mutex); in mt9v111_get_frame_interval()
807 struct mt9v111_dev *mt9v111, in __mt9v111_get_pad_format() argument
816 return &mt9v111->fmt; in __mt9v111_get_pad_format()
876 struct mt9v111_dev *mt9v111 = sd_to_mt9v111(subdev); in mt9v111_get_format() local
881 mutex_lock(&mt9v111->stream_mutex); in mt9v111_get_format()
882 format->format = *__mt9v111_get_pad_format(mt9v111, sd_state, in mt9v111_get_format()
885 mutex_unlock(&mt9v111->stream_mutex); in mt9v111_get_format()
894 struct mt9v111_dev *mt9v111 = sd_to_mt9v111(subdev); in mt9v111_set_format() local
901 mutex_lock(&mt9v111->stream_mutex); in mt9v111_set_format()
902 if (mt9v111->streaming) { in mt9v111_set_format()
903 mutex_unlock(&mt9v111->stream_mutex); in mt9v111_set_format()
908 mutex_unlock(&mt9v111->stream_mutex); in mt9v111_set_format()
939 __fmt = __mt9v111_get_pad_format(mt9v111, sd_state, format->pad, in mt9v111_set_format()
954 mt9v111->pending = true; in mt9v111_set_format()
956 dev_dbg(mt9v111->dev, "%s: mbus_code: %x - (%ux%u)\n", in mt9v111_set_format()
962 mutex_unlock(&mt9v111->stream_mutex); in mt9v111_set_format()
1010 struct mt9v111_dev *mt9v111 = container_of(ctrl->handler, in mt9v111_s_ctrl() local
1015 mutex_lock(&mt9v111->pwr_mutex); in mt9v111_s_ctrl()
1020 if (!mt9v111->pwr_count) { in mt9v111_s_ctrl()
1021 mt9v111->pending = true; in mt9v111_s_ctrl()
1022 mutex_unlock(&mt9v111->pwr_mutex); in mt9v111_s_ctrl()
1025 mutex_unlock(&mt9v111->pwr_mutex); in mt9v111_s_ctrl()
1034 if (mt9v111->auto_exp->is_new || mt9v111->auto_awb->is_new) { in mt9v111_s_ctrl()
1035 if (mt9v111->auto_exp->val == V4L2_EXPOSURE_MANUAL && in mt9v111_s_ctrl()
1036 mt9v111->auto_awb->val == V4L2_WHITE_BALANCE_MANUAL) in mt9v111_s_ctrl()
1037 ret = mt9v111_update(mt9v111->client, MT9V111_R01_IFP, in mt9v111_s_ctrl()
1042 ret = mt9v111_update(mt9v111->client, MT9V111_R01_IFP, in mt9v111_s_ctrl()
1053 ret = mt9v111_update(mt9v111->client, MT9V111_R01_IFP, in mt9v111_s_ctrl()
1060 ret = mt9v111_update(mt9v111->client, MT9V111_R01_IFP, in mt9v111_s_ctrl()
1067 ret = mt9v111_update(mt9v111->client, MT9V111_R01_CORE, in mt9v111_s_ctrl()
1070 mt9v111->hblank->val); in mt9v111_s_ctrl()
1073 ret = mt9v111_update(mt9v111->client, MT9V111_R01_CORE, in mt9v111_s_ctrl()
1076 mt9v111->vblank->val); in mt9v111_s_ctrl()
1087 static int mt9v111_chip_probe(struct mt9v111_dev *mt9v111) in mt9v111_chip_probe() argument
1092 ret = __mt9v111_power_on(&mt9v111->sd); in mt9v111_chip_probe()
1096 ret = mt9v111_read(mt9v111->client, MT9V111_R01_CORE, in mt9v111_chip_probe()
1103 dev_err(mt9v111->dev, in mt9v111_chip_probe()
1104 "Unable to identify MT9V111 chip: 0x%2x%2x\n", in mt9v111_chip_probe()
1110 dev_dbg(mt9v111->dev, "Chip identified: 0x%2x%2x\n", in mt9v111_chip_probe()
1114 __mt9v111_power_off(&mt9v111->sd); in mt9v111_chip_probe()
1121 struct mt9v111_dev *mt9v111; in mt9v111_probe() local
1125 mt9v111 = devm_kzalloc(&client->dev, sizeof(*mt9v111), GFP_KERNEL); in mt9v111_probe()
1126 if (!mt9v111) in mt9v111_probe()
1129 mt9v111->dev = &client->dev; in mt9v111_probe()
1130 mt9v111->client = client; in mt9v111_probe()
1132 mt9v111->clk = devm_clk_get(&client->dev, NULL); in mt9v111_probe()
1133 if (IS_ERR(mt9v111->clk)) in mt9v111_probe()
1134 return PTR_ERR(mt9v111->clk); in mt9v111_probe()
1136 mt9v111->sysclk = clk_get_rate(mt9v111->clk); in mt9v111_probe()
1137 if (mt9v111->sysclk > MT9V111_MAX_CLKIN) in mt9v111_probe()
1140 mt9v111->oe = devm_gpiod_get_optional(&client->dev, "enable", in mt9v111_probe()
1142 if (IS_ERR(mt9v111->oe)) { in mt9v111_probe()
1144 PTR_ERR(mt9v111->oe)); in mt9v111_probe()
1145 return PTR_ERR(mt9v111->oe); in mt9v111_probe()
1148 mt9v111->standby = devm_gpiod_get_optional(&client->dev, "standby", in mt9v111_probe()
1150 if (IS_ERR(mt9v111->standby)) { in mt9v111_probe()
1152 PTR_ERR(mt9v111->standby)); in mt9v111_probe()
1153 return PTR_ERR(mt9v111->standby); in mt9v111_probe()
1156 mt9v111->reset = devm_gpiod_get_optional(&client->dev, "reset", in mt9v111_probe()
1158 if (IS_ERR(mt9v111->reset)) { in mt9v111_probe()
1160 PTR_ERR(mt9v111->reset)); in mt9v111_probe()
1161 return PTR_ERR(mt9v111->reset); in mt9v111_probe()
1164 mutex_init(&mt9v111->pwr_mutex); in mt9v111_probe()
1165 mutex_init(&mt9v111->stream_mutex); in mt9v111_probe()
1167 v4l2_ctrl_handler_init(&mt9v111->ctrls, 5); in mt9v111_probe()
1169 mt9v111->auto_awb = v4l2_ctrl_new_std(&mt9v111->ctrls, in mt9v111_probe()
1174 mt9v111->auto_exp = v4l2_ctrl_new_std_menu(&mt9v111->ctrls, in mt9v111_probe()
1179 mt9v111->hblank = v4l2_ctrl_new_std(&mt9v111->ctrls, &mt9v111_ctrl_ops, in mt9v111_probe()
1184 mt9v111->vblank = v4l2_ctrl_new_std(&mt9v111->ctrls, &mt9v111_ctrl_ops, in mt9v111_probe()
1191 v4l2_ctrl_new_std(&mt9v111->ctrls, &mt9v111_ctrl_ops, in mt9v111_probe()
1193 DIV_ROUND_CLOSEST(mt9v111->sysclk, 2), 1, in mt9v111_probe()
1194 DIV_ROUND_CLOSEST(mt9v111->sysclk, 2)); in mt9v111_probe()
1196 if (mt9v111->ctrls.error) { in mt9v111_probe()
1197 ret = mt9v111->ctrls.error; in mt9v111_probe()
1200 mt9v111->sd.ctrl_handler = &mt9v111->ctrls; in mt9v111_probe()
1203 mt9v111->fmt = mt9v111_def_fmt; in mt9v111_probe()
1206 mt9v111->fps = 15; in mt9v111_probe()
1208 tpf.denominator = mt9v111->fps; in mt9v111_probe()
1209 mt9v111_calc_frame_rate(mt9v111, &tpf); in mt9v111_probe()
1211 mt9v111->pwr_count = 0; in mt9v111_probe()
1212 mt9v111->addr_space = MT9V111_R01_IFP; in mt9v111_probe()
1213 mt9v111->pending = true; in mt9v111_probe()
1215 v4l2_i2c_subdev_init(&mt9v111->sd, client, &mt9v111_ops); in mt9v111_probe()
1216 mt9v111->sd.internal_ops = &mt9v111_internal_ops; in mt9v111_probe()
1218 mt9v111->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in mt9v111_probe()
1219 mt9v111->sd.entity.ops = &mt9v111_subdev_entity_ops; in mt9v111_probe()
1220 mt9v111->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in mt9v111_probe()
1222 mt9v111->pad.flags = MEDIA_PAD_FL_SOURCE; in mt9v111_probe()
1223 ret = media_entity_pads_init(&mt9v111->sd.entity, 1, &mt9v111->pad); in mt9v111_probe()
1227 ret = mt9v111_chip_probe(mt9v111); in mt9v111_probe()
1231 ret = v4l2_async_register_subdev(&mt9v111->sd); in mt9v111_probe()
1238 media_entity_cleanup(&mt9v111->sd.entity); in mt9v111_probe()
1241 v4l2_ctrl_handler_free(&mt9v111->ctrls); in mt9v111_probe()
1243 mutex_destroy(&mt9v111->pwr_mutex); in mt9v111_probe()
1244 mutex_destroy(&mt9v111->stream_mutex); in mt9v111_probe()
1252 struct mt9v111_dev *mt9v111 = sd_to_mt9v111(sd); in mt9v111_remove() local
1258 v4l2_ctrl_handler_free(&mt9v111->ctrls); in mt9v111_remove()
1260 mutex_destroy(&mt9v111->pwr_mutex); in mt9v111_remove()
1261 mutex_destroy(&mt9v111->stream_mutex); in mt9v111_remove()
1265 { .compatible = "aptina,mt9v111", },
1272 .name = "mt9v111",
1281 MODULE_DESCRIPTION("V4L2 sensor driver for Aptina MT9V111");