Lines Matching +full:camera +full:- +full:command +full:- +full:set
1 // SPDX-License-Identifier: GPL-2.0
3 * mt9t112 Camera Driver
14 * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
20 * v4l-utils compliance tools will report errors.
30 #include <linux/v4l2-mediabus.h>
34 #include <media/v4l2-common.h>
35 #include <media/v4l2-image-sizes.h>
36 #include <media/v4l2-subdev.h>
150 static int __mt9t112_reg_read(const struct i2c_client *client, u16 command) in __mt9t112_reg_read() argument
156 command = swab16(command); in __mt9t112_reg_read()
158 msg[0].addr = client->addr; in __mt9t112_reg_read()
161 msg[0].buf = (u8 *)&command; in __mt9t112_reg_read()
163 msg[1].addr = client->addr; in __mt9t112_reg_read()
172 ret = i2c_transfer(client->adapter, msg, 2); in __mt9t112_reg_read()
182 u16 command, u16 data) in __mt9t112_reg_write() argument
188 command = swab16(command); in __mt9t112_reg_write()
191 memcpy(buf + 0, &command, 2); in __mt9t112_reg_write()
194 msg.addr = client->addr; in __mt9t112_reg_write()
203 ret = i2c_transfer(client->adapter, &msg, 1); in __mt9t112_reg_write()
209 u16 command, u16 mask, u16 set) in __mt9t112_reg_mask_set() argument
211 int val = __mt9t112_reg_read(client, command); in __mt9t112_reg_mask_set()
217 val |= set & mask; in __mt9t112_reg_mask_set()
219 return __mt9t112_reg_write(client, command, val); in __mt9t112_reg_mask_set()
223 static int __mt9t112_mcu_read(const struct i2c_client *client, u16 command) in __mt9t112_mcu_read() argument
227 ret = __mt9t112_reg_write(client, 0x098E, command); in __mt9t112_mcu_read()
235 u16 command, u16 data) in __mt9t112_mcu_write() argument
239 ret = __mt9t112_reg_write(client, 0x098E, command); in __mt9t112_mcu_write()
247 u16 command, u16 mask, u16 set) in __mt9t112_mcu_mask_set() argument
249 int val = __mt9t112_mcu_read(client, command); in __mt9t112_mcu_mask_set()
255 val |= set & mask; in __mt9t112_mcu_mask_set()
257 return __mt9t112_mcu_write(client, command, val); in __mt9t112_mcu_mask_set()
305 dev_dbg(&client->dev, "EXTCLK : %10u K %s\n", ext, enable); in mt9t112_clock_info()
309 dev_dbg(&client->dev, "VCO : %10u K %s\n", vco, enable); in mt9t112_clock_info()
313 dev_dbg(&client->dev, "PIXCLK : %10u K %s\n", clk, enable); in mt9t112_clock_info()
317 dev_dbg(&client->dev, "MIPICLK : %10u K %s\n", clk, enable); in mt9t112_clock_info()
321 dev_dbg(&client->dev, "MCU CLK : %10u K %s\n", clk, enable); in mt9t112_clock_info()
325 dev_dbg(&client->dev, "SOC CLK : %10u K %s\n", clk, enable); in mt9t112_clock_info()
329 dev_dbg(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable); in mt9t112_clock_info()
332 dev_dbg(&client->dev, "External sensor : %10u K\n", clk); in mt9t112_clock_info()
336 dev_dbg(&client->dev, "PFD : %10u K %s\n", clk, enable); in mt9t112_clock_info()
346 u16 wstart = (MAX_WIDTH - width) / 2; in mt9t112_set_a_frame_size()
347 u16 hstart = (MAX_HEIGHT - height) / 2; in mt9t112_set_a_frame_size()
409 priv->info->divider.m, priv->info->divider.n, in mt9t112_init_pll()
410 priv->info->divider.p1, priv->info->divider.p2, in mt9t112_init_pll()
411 priv->info->divider.p3, priv->info->divider.p4, in mt9t112_init_pll()
412 priv->info->divider.p5, priv->info->divider.p6, in mt9t112_init_pll()
413 priv->info->divider.p7); in mt9t112_init_pll()
710 /* Set max slew rates. */ in mt9t112_init_camera()
727 reg->size = 2; in mt9t112_g_register()
728 mt9t112_reg_read(ret, client, reg->reg); in mt9t112_g_register()
730 reg->val = (__u64)ret; in mt9t112_g_register()
741 mt9t112_reg_write(ret, client, reg->reg, reg->val); in mt9t112_s_register()
751 ret = clk_prepare_enable(priv->clk); in mt9t112_power_on()
755 if (priv->standby_gpio) { in mt9t112_power_on()
756 gpiod_set_value(priv->standby_gpio, 0); in mt9t112_power_on()
765 clk_disable_unprepare(priv->clk); in mt9t112_power_off()
766 if (priv->standby_gpio) { in mt9t112_power_off()
767 gpiod_set_value(priv->standby_gpio, 1); in mt9t112_power_off()
804 * mt9t112 camera will be very warm. in mt9t112_s_stream()
806 * But current driver can not stop mt9t112 camera. in mt9t112_s_stream()
807 * So, set small size here to solve this problem. in mt9t112_s_stream()
813 if (!priv->init_done) { in mt9t112_s_stream()
814 u16 param = MT9T112_FLAG_PCLK_RISING_EDGE & priv->info->flags ? in mt9t112_s_stream()
824 priv->init_done = true; in mt9t112_s_stream()
827 mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt); in mt9t112_s_stream()
828 mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order); in mt9t112_s_stream()
831 mt9t112_set_a_frame_size(client, priv->frame.width, priv->frame.height); in mt9t112_s_stream()
835 dev_dbg(&client->dev, "format : %d\n", priv->format->code); in mt9t112_s_stream()
836 dev_dbg(&client->dev, "size : %d x %d\n", in mt9t112_s_stream()
837 priv->frame.width, in mt9t112_s_stream()
838 priv->frame.height); in mt9t112_s_stream()
854 for (i = 0; i < priv->num_formats; i++) in mt9t112_set_params()
858 if (i == priv->num_formats) in mt9t112_set_params()
859 return -EINVAL; in mt9t112_set_params()
861 priv->frame = *rect; in mt9t112_set_params()
866 v4l_bound_align_image(&priv->frame.width, 0, MAX_WIDTH, 0, in mt9t112_set_params()
867 &priv->frame.height, 0, MAX_HEIGHT, 0, 0); in mt9t112_set_params()
869 priv->format = mt9t112_cfmts + i; in mt9t112_set_params()
881 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) in mt9t112_get_selection()
882 return -EINVAL; in mt9t112_get_selection()
884 switch (sel->target) { in mt9t112_get_selection()
886 sel->r.left = 0; in mt9t112_get_selection()
887 sel->r.top = 0; in mt9t112_get_selection()
888 sel->r.width = MAX_WIDTH; in mt9t112_get_selection()
889 sel->r.height = MAX_HEIGHT; in mt9t112_get_selection()
892 sel->r = priv->frame; in mt9t112_get_selection()
895 return -EINVAL; in mt9t112_get_selection()
905 const struct v4l2_rect *rect = &sel->r; in mt9t112_set_selection()
907 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || in mt9t112_set_selection()
908 sel->target != V4L2_SEL_TGT_CROP) in mt9t112_set_selection()
909 return -EINVAL; in mt9t112_set_selection()
911 return mt9t112_set_params(priv, rect, priv->format->code); in mt9t112_set_selection()
918 struct v4l2_mbus_framefmt *mf = &format->format; in mt9t112_get_fmt()
922 if (format->pad) in mt9t112_get_fmt()
923 return -EINVAL; in mt9t112_get_fmt()
925 mf->width = priv->frame.width; in mt9t112_get_fmt()
926 mf->height = priv->frame.height; in mt9t112_get_fmt()
927 mf->colorspace = priv->format->colorspace; in mt9t112_get_fmt()
928 mf->code = priv->format->code; in mt9t112_get_fmt()
929 mf->field = V4L2_FIELD_NONE; in mt9t112_get_fmt()
940 .width = mf->width, in mt9t112_s_fmt()
941 .height = mf->height, in mt9t112_s_fmt()
942 .left = priv->frame.left, in mt9t112_s_fmt()
943 .top = priv->frame.top, in mt9t112_s_fmt()
947 ret = mt9t112_set_params(priv, &rect, mf->code); in mt9t112_s_fmt()
950 mf->colorspace = priv->format->colorspace; in mt9t112_s_fmt()
960 struct v4l2_mbus_framefmt *mf = &format->format; in mt9t112_set_fmt()
964 if (format->pad) in mt9t112_set_fmt()
965 return -EINVAL; in mt9t112_set_fmt()
967 for (i = 0; i < priv->num_formats; i++) in mt9t112_set_fmt()
968 if (mt9t112_cfmts[i].code == mf->code) in mt9t112_set_fmt()
971 if (i == priv->num_formats) { in mt9t112_set_fmt()
972 mf->code = MEDIA_BUS_FMT_UYVY8_2X8; in mt9t112_set_fmt()
973 mf->colorspace = V4L2_COLORSPACE_JPEG; in mt9t112_set_fmt()
975 mf->colorspace = mt9t112_cfmts[i].colorspace; in mt9t112_set_fmt()
978 v4l_bound_align_image(&mf->width, 0, MAX_WIDTH, 0, in mt9t112_set_fmt()
979 &mf->height, 0, MAX_HEIGHT, 0, 0); in mt9t112_set_fmt()
981 mf->field = V4L2_FIELD_NONE; in mt9t112_set_fmt()
983 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) in mt9t112_set_fmt()
996 if (code->pad || code->index >= priv->num_formats) in mt9t112_enum_mbus_code()
997 return -EINVAL; in mt9t112_enum_mbus_code()
999 code->code = mt9t112_cfmts[code->index].code; in mt9t112_enum_mbus_code()
1032 ret = mt9t112_s_power(&priv->subdev, 1); in mt9t112_camera_probe()
1042 priv->num_formats = 1; in mt9t112_camera_probe()
1046 priv->num_formats = ARRAY_SIZE(mt9t112_cfmts); in mt9t112_camera_probe()
1049 dev_err(&client->dev, "Product ID error %04x\n", chipid); in mt9t112_camera_probe()
1050 ret = -ENODEV; in mt9t112_camera_probe()
1054 dev_info(&client->dev, "%s chip ID %04x\n", devname, chipid); in mt9t112_camera_probe()
1057 mt9t112_s_power(&priv->subdev, 0); in mt9t112_camera_probe()
1067 if (!client->dev.platform_data) { in mt9t112_probe()
1068 dev_err(&client->dev, "mt9t112: missing platform data!\n"); in mt9t112_probe()
1069 return -EINVAL; in mt9t112_probe()
1072 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); in mt9t112_probe()
1074 return -ENOMEM; in mt9t112_probe()
1076 priv->info = client->dev.platform_data; in mt9t112_probe()
1077 priv->init_done = false; in mt9t112_probe()
1079 v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); in mt9t112_probe()
1081 priv->clk = devm_clk_get(&client->dev, "extclk"); in mt9t112_probe()
1082 if (PTR_ERR(priv->clk) == -ENOENT) { in mt9t112_probe()
1083 priv->clk = NULL; in mt9t112_probe()
1084 } else if (IS_ERR(priv->clk)) { in mt9t112_probe()
1085 dev_err(&client->dev, "Unable to get clock \"extclk\"\n"); in mt9t112_probe()
1086 return PTR_ERR(priv->clk); in mt9t112_probe()
1089 priv->standby_gpio = devm_gpiod_get_optional(&client->dev, "standby", in mt9t112_probe()
1091 if (IS_ERR(priv->standby_gpio)) { in mt9t112_probe()
1092 dev_err(&client->dev, "Unable to get gpio \"standby\"\n"); in mt9t112_probe()
1093 return PTR_ERR(priv->standby_gpio); in mt9t112_probe()
1100 return v4l2_async_register_subdev(&priv->subdev); in mt9t112_probe()
1107 clk_disable_unprepare(priv->clk); in mt9t112_remove()
1108 v4l2_async_unregister_subdev(&priv->subdev); in mt9t112_remove()
1128 MODULE_DESCRIPTION("V4L2 driver for MT9T111/MT9T112 camera sensor");