Lines Matching +full:gain +full:- +full:scaling +full:- +full:n
1 // SPDX-License-Identifier: GPL-2.0
13 * Copyright 2006-7 Jonathan Corbet <corbet@lwn.net>
26 #include <linux/v4l2-mediabus.h>
30 #include <media/v4l2-subdev.h>
51 #define VSCALE_LO 0x0D /* Vertical Scaling Register, Low */
52 #define SCALE_HI 0x0E /* Scaling Register, High */
53 #define HSCALE_LO 0x0F /* Horizontal Scaling Register, Low */
57 #define SAT_U 0x13 /* Chroma (U) Gain Register */
58 #define SAT_V 0x14 /* Chroma (V) Gain Register */
68 #define CLMPG 0x20 /* Clamping Gain */
69 #define IAGC 0x21 /* Individual AGC Gain */
70 #define AGCGAIN 0x22 /* AGC Gain */
136 #define IFSEL_S 0x10 /* 01 : S-video decoding */
146 /* 1 : ITU-R-656 compatible data sequence format */
147 #define LEN 0x40 /* 0 : 8-bit YCrCb 4:2:2 output format */
148 /* 1 : 16-bit YCrCb 4:2:2 output format.*/
150 /* 0 : free-run output mode */
151 #define AINC 0x10 /* Serial interface auto-indexing control */
152 /* 0 : auto-increment */
153 /* 1 : non-auto */
158 #define OEN_TRI_SEL_ALL_OFF_r0 0x06 /* All tri-stated for Rev0 */
159 #define OEN_TRI_SEL_ALL_OFF_r1 0x07 /* All tri-stated for Rev1 */
183 * This bit is self-resetting.
199 #define RTSEL_HLOCK 0x01 /* 0001 = H-lock */
200 #define RTSEL_SLOCK 0x02 /* 0010 = S-lock */
201 #define RTSEL_VLOCK 0x03 /* 0011 = V-lock */
353 (scale->vscale & 0x0F00) >> 4 | in tw9910_set_scale()
354 (scale->hscale & 0x0F00) >> 8); in tw9910_set_scale()
359 scale->hscale & 0x00FF); in tw9910_set_scale()
364 scale->vscale & 0x00FF); in tw9910_set_scale()
374 /* bit 10 - 3 */ in tw9910_set_hsync()
380 /* bit 10 - 3 */ in tw9910_set_hsync()
387 /* bit 2 - 0 */ in tw9910_set_hsync()
388 if (priv->revision == 1) in tw9910_set_hsync()
442 tmp = abs(width - scale[i].width) + in tw9910_select_norm()
443 abs(height - scale[i].height); in tw9910_select_norm()
464 switch (priv->revision) { in tw9910_s_stream()
472 dev_err(&client->dev, "un-supported revision\n"); in tw9910_s_stream()
473 return -EINVAL; in tw9910_s_stream()
478 if (!priv->scale) { in tw9910_s_stream()
479 dev_err(&client->dev, "norm select error\n"); in tw9910_s_stream()
480 return -EPERM; in tw9910_s_stream()
483 dev_dbg(&client->dev, "%s %dx%d\n", in tw9910_s_stream()
484 priv->scale->name, in tw9910_s_stream()
485 priv->scale->width, in tw9910_s_stream()
486 priv->scale->height); in tw9910_s_stream()
501 *norm = priv->norm; in tw9910_g_std()
517 return -EINVAL; in tw9910_s_std()
519 priv->norm = norm; in tw9910_s_std()
552 if (reg->reg > 0xff) in tw9910_g_register()
553 return -EINVAL; in tw9910_g_register()
555 reg->size = 1; in tw9910_g_register()
556 ret = i2c_smbus_read_byte_data(client, reg->reg); in tw9910_g_register()
562 * reg->val = __u64 in tw9910_g_register()
564 reg->val = (__u64)ret; in tw9910_g_register()
574 if (reg->reg > 0xff || in tw9910_s_register()
575 reg->val > 0xff) in tw9910_s_register()
576 return -EINVAL; in tw9910_s_register()
578 return i2c_smbus_write_byte_data(client, reg->reg, reg->val); in tw9910_s_register()
592 struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); in tw9910_power_on()
595 if (priv->clk) { in tw9910_power_on()
596 ret = clk_prepare_enable(priv->clk); in tw9910_power_on()
601 tw9910_set_gpio_value(priv->pdn_gpio, 0); in tw9910_power_on()
605 * platforms (namely the SuperH Migo-R). Until a framework becomes in tw9910_power_on()
609 priv->rstb_gpio = gpiod_get_optional(&client->dev, "rstb", in tw9910_power_on()
611 if (IS_ERR(priv->rstb_gpio)) { in tw9910_power_on()
612 dev_info(&client->dev, "Unable to get GPIO \"rstb\""); in tw9910_power_on()
613 clk_disable_unprepare(priv->clk); in tw9910_power_on()
614 tw9910_set_gpio_value(priv->pdn_gpio, 1); in tw9910_power_on()
615 return PTR_ERR(priv->rstb_gpio); in tw9910_power_on()
618 if (priv->rstb_gpio) { in tw9910_power_on()
619 tw9910_set_gpio_value(priv->rstb_gpio, 1); in tw9910_power_on()
620 tw9910_set_gpio_value(priv->rstb_gpio, 0); in tw9910_power_on()
622 gpiod_put(priv->rstb_gpio); in tw9910_power_on()
630 clk_disable_unprepare(priv->clk); in tw9910_power_off()
631 tw9910_set_gpio_value(priv->pdn_gpio, 1); in tw9910_power_off()
648 int ret = -EINVAL; in tw9910_set_frame()
652 priv->scale = tw9910_select_norm(priv->norm, *width, *height); in tw9910_set_frame()
653 if (!priv->scale) in tw9910_set_frame()
661 if (priv->info->buswidth == 16) in tw9910_set_frame()
669 switch (priv->info->mpout) { in tw9910_set_frame()
695 ret = tw9910_set_scale(client, priv->scale); in tw9910_set_frame()
704 *width = priv->scale->width; in tw9910_set_frame()
705 *height = priv->scale->height; in tw9910_set_frame()
712 priv->scale = NULL; in tw9910_set_frame()
724 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) in tw9910_get_selection()
725 return -EINVAL; in tw9910_get_selection()
727 if (sel->target > V4L2_SEL_TGT_CROP_BOUNDS) in tw9910_get_selection()
728 return -EINVAL; in tw9910_get_selection()
730 sel->r.left = 0; in tw9910_get_selection()
731 sel->r.top = 0; in tw9910_get_selection()
732 if (priv->norm & V4L2_STD_NTSC) { in tw9910_get_selection()
733 sel->r.width = 640; in tw9910_get_selection()
734 sel->r.height = 480; in tw9910_get_selection()
736 sel->r.width = 768; in tw9910_get_selection()
737 sel->r.height = 576; in tw9910_get_selection()
747 struct v4l2_mbus_framefmt *mf = &format->format; in tw9910_get_fmt()
751 if (format->pad) in tw9910_get_fmt()
752 return -EINVAL; in tw9910_get_fmt()
754 if (!priv->scale) { in tw9910_get_fmt()
755 priv->scale = tw9910_select_norm(priv->norm, 640, 480); in tw9910_get_fmt()
756 if (!priv->scale) in tw9910_get_fmt()
757 return -EINVAL; in tw9910_get_fmt()
760 mf->width = priv->scale->width; in tw9910_get_fmt()
761 mf->height = priv->scale->height; in tw9910_get_fmt()
762 mf->code = MEDIA_BUS_FMT_UYVY8_2X8; in tw9910_get_fmt()
763 mf->colorspace = V4L2_COLORSPACE_SMPTE170M; in tw9910_get_fmt()
764 mf->field = V4L2_FIELD_INTERLACED_BT; in tw9910_get_fmt()
772 u32 width = mf->width, height = mf->height; in tw9910_s_fmt()
775 WARN_ON(mf->field != V4L2_FIELD_ANY && in tw9910_s_fmt()
776 mf->field != V4L2_FIELD_INTERLACED_BT); in tw9910_s_fmt()
779 if (mf->code != MEDIA_BUS_FMT_UYVY8_2X8) in tw9910_s_fmt()
780 return -EINVAL; in tw9910_s_fmt()
782 mf->colorspace = V4L2_COLORSPACE_SMPTE170M; in tw9910_s_fmt()
788 mf->width = width; in tw9910_s_fmt()
789 mf->height = height; in tw9910_s_fmt()
798 struct v4l2_mbus_framefmt *mf = &format->format; in tw9910_set_fmt()
803 if (format->pad) in tw9910_set_fmt()
804 return -EINVAL; in tw9910_set_fmt()
806 if (mf->field == V4L2_FIELD_ANY) { in tw9910_set_fmt()
807 mf->field = V4L2_FIELD_INTERLACED_BT; in tw9910_set_fmt()
808 } else if (mf->field != V4L2_FIELD_INTERLACED_BT) { in tw9910_set_fmt()
809 dev_err(&client->dev, "Field type %d invalid\n", mf->field); in tw9910_set_fmt()
810 return -EINVAL; in tw9910_set_fmt()
813 mf->code = MEDIA_BUS_FMT_UYVY8_2X8; in tw9910_set_fmt()
814 mf->colorspace = V4L2_COLORSPACE_SMPTE170M; in tw9910_set_fmt()
817 scale = tw9910_select_norm(priv->norm, mf->width, mf->height); in tw9910_set_fmt()
819 return -EINVAL; in tw9910_set_fmt()
821 mf->width = scale->width; in tw9910_set_fmt()
822 mf->height = scale->height; in tw9910_set_fmt()
824 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) in tw9910_set_fmt()
837 if (priv->info->buswidth != 16 && priv->info->buswidth != 8) { in tw9910_video_probe()
838 dev_err(&client->dev, "bus width error\n"); in tw9910_video_probe()
839 return -ENODEV; in tw9910_video_probe()
842 ret = tw9910_s_power(&priv->subdev, 1); in tw9910_video_probe()
851 priv->revision = GET_REV(id); in tw9910_video_probe()
854 if (id != 0x0b || priv->revision > 0x01) { in tw9910_video_probe()
855 dev_err(&client->dev, "Product ID error %x:%x\n", in tw9910_video_probe()
856 id, priv->revision); in tw9910_video_probe()
857 ret = -ENODEV; in tw9910_video_probe()
861 dev_info(&client->dev, "tw9910 Product ID %0x:%0x\n", in tw9910_video_probe()
862 id, priv->revision); in tw9910_video_probe()
864 priv->norm = V4L2_STD_NTSC; in tw9910_video_probe()
865 priv->scale = &tw9910_ntsc_scales[0]; in tw9910_video_probe()
868 tw9910_s_power(&priv->subdev, 0); in tw9910_video_probe()
885 if (code->pad || code->index) in tw9910_enum_mbus_code()
886 return -EINVAL; in tw9910_enum_mbus_code()
888 code->code = MEDIA_BUS_FMT_UYVY8_2X8; in tw9910_enum_mbus_code()
929 struct i2c_adapter *adapter = client->adapter; in tw9910_probe()
932 if (!client->dev.platform_data) { in tw9910_probe()
933 dev_err(&client->dev, "TW9910: missing platform data!\n"); in tw9910_probe()
934 return -EINVAL; in tw9910_probe()
937 info = client->dev.platform_data; in tw9910_probe()
940 dev_err(&client->dev, in tw9910_probe()
941 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE_DATA\n"); in tw9910_probe()
942 return -EIO; in tw9910_probe()
945 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); in tw9910_probe()
947 return -ENOMEM; in tw9910_probe()
949 priv->info = info; in tw9910_probe()
951 v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops); in tw9910_probe()
953 priv->clk = clk_get(&client->dev, "xti"); in tw9910_probe()
954 if (PTR_ERR(priv->clk) == -ENOENT) { in tw9910_probe()
955 priv->clk = NULL; in tw9910_probe()
956 } else if (IS_ERR(priv->clk)) { in tw9910_probe()
957 dev_err(&client->dev, "Unable to get xti clock\n"); in tw9910_probe()
958 return PTR_ERR(priv->clk); in tw9910_probe()
961 priv->pdn_gpio = gpiod_get_optional(&client->dev, "pdn", in tw9910_probe()
963 if (IS_ERR(priv->pdn_gpio)) { in tw9910_probe()
964 dev_info(&client->dev, "Unable to get GPIO \"pdn\""); in tw9910_probe()
965 ret = PTR_ERR(priv->pdn_gpio); in tw9910_probe()
973 ret = v4l2_async_register_subdev(&priv->subdev); in tw9910_probe()
980 if (priv->pdn_gpio) in tw9910_probe()
981 gpiod_put(priv->pdn_gpio); in tw9910_probe()
983 clk_put(priv->clk); in tw9910_probe()
992 if (priv->pdn_gpio) in tw9910_remove()
993 gpiod_put(priv->pdn_gpio); in tw9910_remove()
994 clk_put(priv->clk); in tw9910_remove()
995 v4l2_async_unregister_subdev(&priv->subdev); in tw9910_remove()