Lines Matching defs:mt9p031
26 #include <media/i2c/mt9p031.h>
121 struct mt9p031 {
148 static struct mt9p031 *to_mt9p031(struct v4l2_subdev *sd)
150 return container_of(sd, struct mt9p031, subdev);
163 static int mt9p031_set_output_control(struct mt9p031 *mt9p031, u16 clear,
166 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
167 u16 value = (mt9p031->output_control & ~clear) | set;
174 mt9p031->output_control = value;
178 static int mt9p031_set_mode2(struct mt9p031 *mt9p031, u16 clear, u16 set)
180 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
181 u16 value = (mt9p031->mode2 & ~clear) | set;
188 mt9p031->mode2 = value;
192 static int mt9p031_reset(struct mt9p031 *mt9p031)
194 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
206 MT9P031_PIXEL_CLOCK_DIVIDE(mt9p031->clk_div));
210 return mt9p031_set_output_control(mt9p031, MT9P031_OUTPUT_CONTROL_CEN,
214 static int mt9p031_clk_setup(struct mt9p031 *mt9p031)
232 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
233 struct mt9p031_platform_data *pdata = mt9p031->pdata;
236 mt9p031->clk = devm_clk_get(&client->dev, NULL);
237 if (IS_ERR(mt9p031->clk))
238 return PTR_ERR(mt9p031->clk);
240 ret = clk_set_rate(mt9p031->clk, pdata->ext_freq);
253 mt9p031->clk_div = min_t(unsigned int, div, 64);
254 mt9p031->use_pll = false;
259 mt9p031->pll.ext_clock = pdata->ext_freq;
260 mt9p031->pll.pix_clock = pdata->target_freq;
261 mt9p031->use_pll = true;
263 return aptina_pll_calculate(&client->dev, &limits, &mt9p031->pll);
266 static int mt9p031_pll_enable(struct mt9p031 *mt9p031)
268 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
271 if (!mt9p031->use_pll)
280 (mt9p031->pll.m << 8) | (mt9p031->pll.n - 1));
284 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_2, mt9p031->pll.p1 - 1);
295 static inline int mt9p031_pll_disable(struct mt9p031 *mt9p031)
297 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
299 if (!mt9p031->use_pll)
306 static int mt9p031_power_on(struct mt9p031 *mt9p031)
311 if (mt9p031->reset) {
312 gpiod_set_value(mt9p031->reset, 1);
317 ret = regulator_bulk_enable(ARRAY_SIZE(mt9p031->regulators),
318 mt9p031->regulators);
323 if (mt9p031->clk) {
324 ret = clk_prepare_enable(mt9p031->clk);
326 regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators),
327 mt9p031->regulators);
333 if (mt9p031->reset) {
334 gpiod_set_value(mt9p031->reset, 0);
341 static void mt9p031_power_off(struct mt9p031 *mt9p031)
343 if (mt9p031->reset) {
344 gpiod_set_value(mt9p031->reset, 1);
348 regulator_bulk_disable(ARRAY_SIZE(mt9p031->regulators),
349 mt9p031->regulators);
351 if (mt9p031->clk)
352 clk_disable_unprepare(mt9p031->clk);
355 static int __mt9p031_set_power(struct mt9p031 *mt9p031, bool on)
357 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
361 mt9p031_power_off(mt9p031);
365 ret = mt9p031_power_on(mt9p031);
369 ret = mt9p031_reset(mt9p031);
375 return v4l2_ctrl_handler_setup(&mt9p031->ctrls);
382 static int mt9p031_set_params(struct mt9p031 *mt9p031)
384 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
385 struct v4l2_mbus_framefmt *format = &mt9p031->format;
386 const struct v4l2_rect *crop = &mt9p031->crop;
449 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
468 ret = mt9p031_set_output_control(mt9p031,
473 return mt9p031_pll_disable(mt9p031);
476 ret = mt9p031_set_params(mt9p031);
481 ret = mt9p031_set_output_control(mt9p031, 0,
496 return mt9p031_pll_enable(mt9p031);
503 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
508 code->code = mt9p031->format.code;
516 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
518 if (fse->index >= 8 || fse->code != mt9p031->format.code)
531 __mt9p031_get_pad_format(struct mt9p031 *mt9p031, struct v4l2_subdev_pad_config *cfg,
536 return v4l2_subdev_get_try_format(&mt9p031->subdev, cfg, pad);
538 return &mt9p031->format;
545 __mt9p031_get_pad_crop(struct mt9p031 *mt9p031, struct v4l2_subdev_pad_config *cfg,
550 return v4l2_subdev_get_try_crop(&mt9p031->subdev, cfg, pad);
552 return &mt9p031->crop;
562 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
564 fmt->format = *__mt9p031_get_pad_format(mt9p031, cfg, fmt->pad,
573 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
581 __crop = __mt9p031_get_pad_crop(mt9p031, cfg, format->pad,
597 __format = __mt9p031_get_pad_format(mt9p031, cfg, format->pad,
611 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
616 sel->r = *__mt9p031_get_pad_crop(mt9p031, cfg, sel->pad, sel->which);
624 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
651 __crop = __mt9p031_get_pad_crop(mt9p031, cfg, sel->pad, sel->which);
657 __format = __mt9p031_get_pad_format(mt9p031, cfg, sel->pad,
678 static int mt9p031_restore_blc(struct mt9p031 *mt9p031)
680 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
683 if (mt9p031->blc_auto->cur.val != 0) {
684 ret = mt9p031_set_mode2(mt9p031, 0,
690 if (mt9p031->blc_offset->cur.val != 0) {
692 mt9p031->blc_offset->cur.val);
702 struct mt9p031 *mt9p031 =
703 container_of(ctrl->handler, struct mt9p031, ctrls);
704 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
750 return mt9p031_set_mode2(mt9p031,
753 return mt9p031_set_mode2(mt9p031,
758 return mt9p031_set_mode2(mt9p031,
761 return mt9p031_set_mode2(mt9p031,
770 v4l2_ctrl_activate(mt9p031->blc_auto, ctrl->val == 0);
771 v4l2_ctrl_activate(mt9p031->blc_offset, ctrl->val == 0);
775 ret = mt9p031_restore_blc(mt9p031);
794 ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC,
808 ret = mt9p031_set_mode2(mt9p031,
910 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
913 mutex_lock(&mt9p031->power_lock);
918 if (mt9p031->power_count == !on) {
919 ret = __mt9p031_set_power(mt9p031, !!on);
925 mt9p031->power_count += on ? 1 : -1;
926 WARN_ON(mt9p031->power_count < 0);
929 mutex_unlock(&mt9p031->power_lock);
940 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
944 ret = mt9p031_power_on(mt9p031);
952 mt9p031_power_off(mt9p031);
968 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
980 if (mt9p031->model == MT9P031_MODEL_MONOCHROME)
1061 struct mt9p031 *mt9p031;
1076 mt9p031 = devm_kzalloc(&client->dev, sizeof(*mt9p031), GFP_KERNEL);
1077 if (mt9p031 == NULL)
1080 mt9p031->pdata = pdata;
1081 mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF;
1082 mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC;
1083 mt9p031->model = did->driver_data;
1085 mt9p031->regulators[0].supply = "vdd";
1086 mt9p031->regulators[1].supply = "vdd_io";
1087 mt9p031->regulators[2].supply = "vaa";
1089 ret = devm_regulator_bulk_get(&client->dev, 3, mt9p031->regulators);
1095 mutex_init(&mt9p031->power_lock);
1097 v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 6);
1099 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1103 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1106 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1108 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1110 v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1113 v4l2_ctrl_new_std_menu_items(&mt9p031->ctrls, &mt9p031_ctrl_ops,
1119 v4l2_ctrl_new_custom(&mt9p031->ctrls, &mt9p031_ctrls[i], NULL);
1121 mt9p031->subdev.ctrl_handler = &mt9p031->ctrls;
1123 if (mt9p031->ctrls.error) {
1125 __func__, mt9p031->ctrls.error);
1126 ret = mt9p031->ctrls.error;
1130 mt9p031->blc_auto = v4l2_ctrl_find(&mt9p031->ctrls, V4L2_CID_BLC_AUTO);
1131 mt9p031->blc_offset = v4l2_ctrl_find(&mt9p031->ctrls,
1134 v4l2_i2c_subdev_init(&mt9p031->subdev, client, &mt9p031_subdev_ops);
1135 mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops;
1137 mt9p031->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1138 mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE;
1139 ret = media_entity_pads_init(&mt9p031->subdev.entity, 1, &mt9p031->pad);
1143 mt9p031->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1145 mt9p031->crop.width = MT9P031_WINDOW_WIDTH_DEF;
1146 mt9p031->crop.height = MT9P031_WINDOW_HEIGHT_DEF;
1147 mt9p031->crop.left = MT9P031_COLUMN_START_DEF;
1148 mt9p031->crop.top = MT9P031_ROW_START_DEF;
1150 if (mt9p031->model == MT9P031_MODEL_MONOCHROME)
1151 mt9p031->format.code = MEDIA_BUS_FMT_Y12_1X12;
1153 mt9p031->format.code = MEDIA_BUS_FMT_SGRBG12_1X12;
1155 mt9p031->format.width = MT9P031_WINDOW_WIDTH_DEF;
1156 mt9p031->format.height = MT9P031_WINDOW_HEIGHT_DEF;
1157 mt9p031->format.field = V4L2_FIELD_NONE;
1158 mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB;
1160 mt9p031->reset = devm_gpiod_get_optional(&client->dev, "reset",
1163 ret = mt9p031_clk_setup(mt9p031);
1167 ret = v4l2_async_register_subdev(&mt9p031->subdev);
1171 v4l2_ctrl_handler_free(&mt9p031->ctrls);
1172 media_entity_cleanup(&mt9p031->subdev.entity);
1173 mutex_destroy(&mt9p031->power_lock);
1182 struct mt9p031 *mt9p031 = to_mt9p031(subdev);
1184 v4l2_ctrl_handler_free(&mt9p031->ctrls);
1187 mutex_destroy(&mt9p031->power_lock);
1193 { "mt9p031", MT9P031_MODEL_COLOR },
1201 { .compatible = "aptina,mt9p031", },
1211 .name = "mt9p031",