Lines Matching +full:vsync +full:- +full:polarity +full:- +full:high
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>
45 #define CROP_HI 0x07 /* Cropping Register, High */
52 #define SCALE_HI 0x0E /* Scaling Register, High */
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 */
162 #define VSP_LO 0x00 /* 0 : VS pin output polarity is active low */
163 #define VSP_HI 0x80 /* 1 : VS pin output polarity is active high. */
165 #define VSSL_VSYNC 0x00 /* 0 : VSYNC */
170 #define HSP_LOW 0x00 /* 0 : HS pin output polarity is active low */
171 #define HSP_HI 0x08 /* 1 : HS pin output polarity is active high.*/
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 */
358 (scale->vscale & 0x0F00) >> 4 | in tw9910_set_scale()
359 (scale->hscale & 0x0F00) >> 8); in tw9910_set_scale()
364 scale->hscale & 0x00FF); in tw9910_set_scale()
369 scale->vscale & 0x00FF); in tw9910_set_scale()
379 /* bit 10 - 3 */ in tw9910_set_hsync()
385 /* bit 10 - 3 */ in tw9910_set_hsync()
392 /* bit 2 - 0 */ in tw9910_set_hsync()
393 if (priv->revision == 1) in tw9910_set_hsync()
447 tmp = abs(width - scale[i].width) + in tw9910_select_norm()
448 abs(height - scale[i].height); in tw9910_select_norm()
469 switch (priv->revision) { in tw9910_s_stream()
477 dev_err(&client->dev, "un-supported revision\n"); in tw9910_s_stream()
478 return -EINVAL; in tw9910_s_stream()
483 if (!priv->scale) { in tw9910_s_stream()
484 dev_err(&client->dev, "norm select error\n"); in tw9910_s_stream()
485 return -EPERM; in tw9910_s_stream()
488 dev_dbg(&client->dev, "%s %dx%d\n", in tw9910_s_stream()
489 priv->scale->name, in tw9910_s_stream()
490 priv->scale->width, in tw9910_s_stream()
491 priv->scale->height); in tw9910_s_stream()
506 *norm = priv->norm; in tw9910_g_std()
522 return -EINVAL; in tw9910_s_std()
524 priv->norm = norm; in tw9910_s_std()
557 if (reg->reg > 0xff) in tw9910_g_register()
558 return -EINVAL; in tw9910_g_register()
560 reg->size = 1; in tw9910_g_register()
561 ret = i2c_smbus_read_byte_data(client, reg->reg); in tw9910_g_register()
567 * reg->val = __u64 in tw9910_g_register()
569 reg->val = (__u64)ret; in tw9910_g_register()
579 if (reg->reg > 0xff || in tw9910_s_register()
580 reg->val > 0xff) in tw9910_s_register()
581 return -EINVAL; in tw9910_s_register()
583 return i2c_smbus_write_byte_data(client, reg->reg, reg->val); in tw9910_s_register()
597 struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); in tw9910_power_on()
600 if (priv->clk) { in tw9910_power_on()
601 ret = clk_prepare_enable(priv->clk); in tw9910_power_on()
606 tw9910_set_gpio_value(priv->pdn_gpio, 0); in tw9910_power_on()
610 * platforms (namely the SuperH Migo-R). Until a framework becomes in tw9910_power_on()
614 priv->rstb_gpio = gpiod_get_optional(&client->dev, "rstb", in tw9910_power_on()
616 if (IS_ERR(priv->rstb_gpio)) { in tw9910_power_on()
617 dev_info(&client->dev, "Unable to get GPIO \"rstb\""); in tw9910_power_on()
618 clk_disable_unprepare(priv->clk); in tw9910_power_on()
619 tw9910_set_gpio_value(priv->pdn_gpio, 1); in tw9910_power_on()
620 return PTR_ERR(priv->rstb_gpio); in tw9910_power_on()
623 if (priv->rstb_gpio) { in tw9910_power_on()
624 tw9910_set_gpio_value(priv->rstb_gpio, 1); in tw9910_power_on()
625 tw9910_set_gpio_value(priv->rstb_gpio, 0); in tw9910_power_on()
627 gpiod_put(priv->rstb_gpio); in tw9910_power_on()
635 clk_disable_unprepare(priv->clk); in tw9910_power_off()
636 tw9910_set_gpio_value(priv->pdn_gpio, 1); in tw9910_power_off()
653 int ret = -EINVAL; in tw9910_set_frame()
657 priv->scale = tw9910_select_norm(priv->norm, *width, *height); in tw9910_set_frame()
658 if (!priv->scale) in tw9910_set_frame()
666 if (priv->info->buswidth == 16) in tw9910_set_frame()
674 switch (priv->info->mpout) { in tw9910_set_frame()
700 ret = tw9910_set_scale(client, priv->scale); in tw9910_set_frame()
709 *width = priv->scale->width; in tw9910_set_frame()
710 *height = priv->scale->height; in tw9910_set_frame()
717 priv->scale = NULL; in tw9910_set_frame()
729 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) in tw9910_get_selection()
730 return -EINVAL; in tw9910_get_selection()
732 if (sel->target > V4L2_SEL_TGT_CROP_BOUNDS) in tw9910_get_selection()
733 return -EINVAL; in tw9910_get_selection()
735 sel->r.left = 0; in tw9910_get_selection()
736 sel->r.top = 0; in tw9910_get_selection()
737 if (priv->norm & V4L2_STD_NTSC) { in tw9910_get_selection()
738 sel->r.width = 640; in tw9910_get_selection()
739 sel->r.height = 480; in tw9910_get_selection()
741 sel->r.width = 768; in tw9910_get_selection()
742 sel->r.height = 576; in tw9910_get_selection()
752 struct v4l2_mbus_framefmt *mf = &format->format; in tw9910_get_fmt()
756 if (format->pad) in tw9910_get_fmt()
757 return -EINVAL; in tw9910_get_fmt()
759 if (!priv->scale) { in tw9910_get_fmt()
760 priv->scale = tw9910_select_norm(priv->norm, 640, 480); in tw9910_get_fmt()
761 if (!priv->scale) in tw9910_get_fmt()
762 return -EINVAL; in tw9910_get_fmt()
765 mf->width = priv->scale->width; in tw9910_get_fmt()
766 mf->height = priv->scale->height; in tw9910_get_fmt()
767 mf->code = MEDIA_BUS_FMT_UYVY8_2X8; in tw9910_get_fmt()
768 mf->colorspace = V4L2_COLORSPACE_SMPTE170M; in tw9910_get_fmt()
769 mf->field = V4L2_FIELD_INTERLACED_BT; in tw9910_get_fmt()
777 u32 width = mf->width, height = mf->height; in tw9910_s_fmt()
780 WARN_ON(mf->field != V4L2_FIELD_ANY && in tw9910_s_fmt()
781 mf->field != V4L2_FIELD_INTERLACED_BT); in tw9910_s_fmt()
784 if (mf->code != MEDIA_BUS_FMT_UYVY8_2X8) in tw9910_s_fmt()
785 return -EINVAL; in tw9910_s_fmt()
787 mf->colorspace = V4L2_COLORSPACE_SMPTE170M; in tw9910_s_fmt()
793 mf->width = width; in tw9910_s_fmt()
794 mf->height = height; in tw9910_s_fmt()
803 struct v4l2_mbus_framefmt *mf = &format->format; in tw9910_set_fmt()
808 if (format->pad) in tw9910_set_fmt()
809 return -EINVAL; in tw9910_set_fmt()
811 if (mf->field == V4L2_FIELD_ANY) { in tw9910_set_fmt()
812 mf->field = V4L2_FIELD_INTERLACED_BT; in tw9910_set_fmt()
813 } else if (mf->field != V4L2_FIELD_INTERLACED_BT) { in tw9910_set_fmt()
814 dev_err(&client->dev, "Field type %d invalid\n", mf->field); in tw9910_set_fmt()
815 return -EINVAL; in tw9910_set_fmt()
818 mf->code = MEDIA_BUS_FMT_UYVY8_2X8; in tw9910_set_fmt()
819 mf->colorspace = V4L2_COLORSPACE_SMPTE170M; in tw9910_set_fmt()
822 scale = tw9910_select_norm(priv->norm, mf->width, mf->height); in tw9910_set_fmt()
824 return -EINVAL; in tw9910_set_fmt()
826 mf->width = scale->width; in tw9910_set_fmt()
827 mf->height = scale->height; in tw9910_set_fmt()
829 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) in tw9910_set_fmt()
832 sd_state->pads->try_fmt = *mf; in tw9910_set_fmt()
844 if (priv->info->buswidth != 16 && priv->info->buswidth != 8) { in tw9910_video_probe()
845 dev_err(&client->dev, "bus width error\n"); in tw9910_video_probe()
846 return -ENODEV; in tw9910_video_probe()
849 ret = tw9910_s_power(&priv->subdev, 1); in tw9910_video_probe()
858 priv->revision = GET_REV(id); in tw9910_video_probe()
861 if (id != 0x0b || priv->revision > 0x01) { in tw9910_video_probe()
862 dev_err(&client->dev, "Product ID error %x:%x\n", in tw9910_video_probe()
863 id, priv->revision); in tw9910_video_probe()
864 ret = -ENODEV; in tw9910_video_probe()
868 dev_info(&client->dev, "tw9910 Product ID %0x:%0x\n", in tw9910_video_probe()
869 id, priv->revision); in tw9910_video_probe()
871 priv->norm = V4L2_STD_NTSC; in tw9910_video_probe()
872 priv->scale = &tw9910_ntsc_scales[0]; in tw9910_video_probe()
875 tw9910_s_power(&priv->subdev, 0); in tw9910_video_probe()
892 if (code->pad || code->index) in tw9910_enum_mbus_code()
893 return -EINVAL; in tw9910_enum_mbus_code()
895 code->code = MEDIA_BUS_FMT_UYVY8_2X8; in tw9910_enum_mbus_code()
937 struct i2c_adapter *adapter = client->adapter; in tw9910_probe()
940 if (!client->dev.platform_data) { in tw9910_probe()
941 dev_err(&client->dev, "TW9910: missing platform data!\n"); in tw9910_probe()
942 return -EINVAL; in tw9910_probe()
945 info = client->dev.platform_data; in tw9910_probe()
948 dev_err(&client->dev, in tw9910_probe()
949 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_BYTE_DATA\n"); in tw9910_probe()
950 return -EIO; in tw9910_probe()
953 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); in tw9910_probe()
955 return -ENOMEM; in tw9910_probe()
957 priv->info = info; in tw9910_probe()
959 v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops); in tw9910_probe()
961 priv->clk = clk_get(&client->dev, "xti"); in tw9910_probe()
962 if (PTR_ERR(priv->clk) == -ENOENT) { in tw9910_probe()
963 priv->clk = NULL; in tw9910_probe()
964 } else if (IS_ERR(priv->clk)) { in tw9910_probe()
965 dev_err(&client->dev, "Unable to get xti clock\n"); in tw9910_probe()
966 return PTR_ERR(priv->clk); in tw9910_probe()
969 priv->pdn_gpio = gpiod_get_optional(&client->dev, "pdn", in tw9910_probe()
971 if (IS_ERR(priv->pdn_gpio)) { in tw9910_probe()
972 dev_info(&client->dev, "Unable to get GPIO \"pdn\""); in tw9910_probe()
973 ret = PTR_ERR(priv->pdn_gpio); in tw9910_probe()
981 ret = v4l2_async_register_subdev(&priv->subdev); in tw9910_probe()
988 if (priv->pdn_gpio) in tw9910_probe()
989 gpiod_put(priv->pdn_gpio); in tw9910_probe()
991 clk_put(priv->clk); in tw9910_probe()
1000 if (priv->pdn_gpio) in tw9910_remove()
1001 gpiod_put(priv->pdn_gpio); in tw9910_remove()
1002 clk_put(priv->clk); in tw9910_remove()
1003 v4l2_async_unregister_subdev(&priv->subdev); in tw9910_remove()