Lines Matching +full:south +full:- +full:field
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* cx25840 - Conexant CX25840 audio/video decoder driver
10 * - cleanup/rewrite for V4L2 API (2005)
36 #include <media/v4l2-common.h>
37 #include <media/drv-intf/cx25840.h>
39 #include "cx25840-core.h"
73 /* ----------------------------------------------------------------------- */
107 msgs[0].addr = client->addr; in cx25840_read()
113 msgs[1].addr = client->addr; in cx25840_read()
118 if (i2c_transfer(client->adapter, msgs, 2) < 2) in cx25840_read()
132 msgs[0].addr = client->addr; in cx25840_read4()
138 msgs[1].addr = client->addr; in cx25840_read4()
143 if (i2c_transfer(client->adapter, msgs, 2) < 2) in cx25840_read4()
166 /* ----------------------------------------------------------------------- */
172 /* ----------------------------------------------------------------------- */
536 /* ----------------------------------------------------------------------- */
574 *reset configuration is described on page 3-77 in cx25836_initialize()
604 cx25840_loadfw(state->c); in cx25840_work_handler()
605 wake_up(&state->fw_wait); in cx25840_work_handler()
610 if ((state)->vid_config & (opt_msk)) { \
611 if (((state)->vid_config & (opt_msk)) == \
629 if (state->vid_config & CX25840_VCONFIG_FMT_MASK) in cx25840_vconfig_apply()
631 switch (state->vid_config & CX25840_VCONFIG_FMT_MASK) { in cx25840_vconfig_apply()
665 if (state->vid_config & CX25840_VCONFIG_CLKGATE_MASK) in cx25840_vconfig_apply()
667 switch (state->vid_config & CX25840_VCONFIG_CLKGATE_MASK) { in cx25840_vconfig_apply()
699 /* datasheet startup in numbered steps, refer to page 3-77 */ in cx25840_initialize()
718 * bit-banging i2c interface to finish uploading the in cx25840_initialize()
721 INIT_WORK(&state->fw_work, cx25840_work_handler); in cx25840_initialize()
722 init_waitqueue_head(&state->fw_wait); in cx25840_initialize()
725 prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); in cx25840_initialize()
726 queue_work(q, &state->fw_work); in cx25840_initialize()
728 finish_wait(&state->fw_wait, &wait); in cx25840_initialize()
761 set_input(client, state->vid_input, state->aud_input); in cx25840_initialize()
763 if (state->generic_mode) in cx25840_initialize()
778 if (v4l2_get_subdev_hostdata(&state->sd)) in cx23885_initialize()
779 clk_freq = *((u32 *)v4l2_get_subdev_hostdata(&state->sd)); in cx23885_initialize()
784 * 0x0-0x2 can't be read or written. in cx23885_initialize()
810 switch (state->id) { in cx23885_initialize()
863 switch (state->id) { in cx23885_initialize()
896 switch (state->id) { in cx23885_initialize()
955 * bit-banging i2c interface to finish uploading the in cx23885_initialize()
958 INIT_WORK(&state->fw_work, cx25840_work_handler); in cx23885_initialize()
959 init_waitqueue_head(&state->fw_wait); in cx23885_initialize()
962 prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); in cx23885_initialize()
963 queue_work(q, &state->fw_work); in cx23885_initialize()
965 finish_wait(&state->fw_wait, &wait); in cx23885_initialize()
979 set_input(client, state->vid_input, state->aud_input); in cx23885_initialize()
984 /* Disable and clear video interrupts - we don't use them */ in cx23885_initialize()
987 /* Disable and clear audio interrupts - we don't use them */ in cx23885_initialize()
994 * - VIP 1.1 control codes - 10bit, blue field enable. in cx23885_initialize()
995 * - enable raw data during vertical blanking. in cx23885_initialize()
996 * - enable ancillary Data insertion for 656 or VIP. in cx23885_initialize()
1000 /* CC on - VBI_LINE_CTRL3, FLD_VBI_MD_LINE12 */ in cx23885_initialize()
1001 cx25840_write(client, state->vbi_regs_offset + 0x42f, 0x66); in cx23885_initialize()
1003 /* HVR-1250 / HVR1850 DIF related */ in cx23885_initialize()
1013 /* AFE_CLK_OUT_CTRL - Select the clock output source as output */ in cx23885_initialize()
1016 /* I2C_OUT_CTL - I2S output configuration as in cx23885_initialize()
1024 /* AFE_DIAG_CTRL3 - Inverted Polarity for Audio and Video */ in cx23885_initialize()
1028 /* ----------------------------------------------------------------------- */
1080 * bit-banging i2c interface to finish uploading the in cx231xx_initialize()
1083 INIT_WORK(&state->fw_work, cx25840_work_handler); in cx231xx_initialize()
1084 init_waitqueue_head(&state->fw_wait); in cx231xx_initialize()
1087 prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE); in cx231xx_initialize()
1088 queue_work(q, &state->fw_work); in cx231xx_initialize()
1090 finish_wait(&state->fw_wait, &wait); in cx231xx_initialize()
1097 set_input(client, state->vid_input, state->aud_input); in cx231xx_initialize()
1110 /* ----------------------------------------------------------------------- */
1115 v4l2_std_id std = state->std; in cx25840_std_setup()
1132 if (state->generic_mode) { in cx25840_std_setup()
1149 if (state->generic_mode) { in cx25840_std_setup()
1167 if (state->generic_mode) { in cx25840_std_setup()
1174 if (!state->generic_mode) { in cx25840_std_setup()
1191 if (!state->generic_mode) { in cx25840_std_setup()
1229 "Chroma sub-carrier freq = %d.%06d MHz\n", in cx25840_std_setup()
1274 state->vbi_line_offset = 5; in cx25840_std_setup()
1277 state->vbi_line_offset = 8; in cx25840_std_setup()
1281 /* ----------------------------------------------------------------------- */
1286 v4l2_std_id std = state->std; in input_change()
1305 if (state->radio) { in input_change()
1316 int hw_fix = state->pvr150_workaround; in input_change()
1322 /* South Korea uses A2 audio standard */ in input_change()
1333 * Since system PAL-L is pretty much non-existent and in input_change()
1343 * If only one of SECAM-DK / SECAM-L is required, then force in input_change()
1395 reg = 0xf0 + (vid_input - CX25840_COMPOSITE1); in set_input()
1404 return -EINVAL; in set_input()
1406 reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4); in set_input()
1409 reg |= (chroma - CX25840_SVIDEO_CHROMA7) >> 2; in set_input()
1412 reg |= (chroma - CX25840_SVIDEO_CHROMA4) >> 4; in set_input()
1446 return -EINVAL; in set_input()
1452 /* Set INPUT_MODE to Composite, S-Video or Component */ in set_input()
1467 /* 18271 IF - Nobody else yet uses a different in set_input()
1538 /* S-Video */ in set_input()
1577 state->vid_input = vid_input; in set_input()
1578 state->aud_input = aud_input; in set_input()
1628 * AUD_IO_CTRL - I2S Input, Parallel1 in set_input()
1629 * - Channel 1 src - Parallel1 (Merlin out) in set_input()
1630 * - Channel 2 src - Parallel2 (Merlin out) in set_input()
1631 * - Channel 3 src - Parallel3 (Merlin AC97 out) in set_input()
1632 * - I2S source and dir - Merlin, output in set_input()
1648 /* ----------------------------------------------------------------------- */
1657 if (state->std == V4L2_STD_NTSC_M_JP) { in set_v4lstd()
1659 } else if (state->std == V4L2_STD_NTSC_443) { in set_v4lstd()
1661 } else if (state->std == V4L2_STD_PAL_M) { in set_v4lstd()
1664 } else if (state->std == V4L2_STD_PAL_N) { in set_v4lstd()
1666 } else if (state->std == V4L2_STD_PAL_Nc) { in set_v4lstd()
1668 } else if (state->std == V4L2_STD_PAL_60) { in set_v4lstd()
1672 if (state->std & V4L2_STD_NTSC) in set_v4lstd()
1674 else if (state->std & V4L2_STD_PAL) in set_v4lstd()
1676 else if (state->std & V4L2_STD_SECAM) in set_v4lstd()
1689 /* Set format to NTSC-M */ in set_v4lstd()
1705 /* ----------------------------------------------------------------------- */
1713 switch (ctrl->id) { in cx25840_s_ctrl()
1715 cx25840_write(client, 0x414, ctrl->val - 128); in cx25840_s_ctrl()
1719 cx25840_write(client, 0x415, ctrl->val << 1); in cx25840_s_ctrl()
1724 cx25840_write(client, 0x418, ctrl->val << 1); in cx25840_s_ctrl()
1725 cx25840_write(client, 0x419, ctrl->val << 1); in cx25840_s_ctrl()
1727 cx25840_write(client, 0x420, ctrl->val << 1); in cx25840_s_ctrl()
1728 cx25840_write(client, 0x421, ctrl->val << 1); in cx25840_s_ctrl()
1734 cx25840_write(client, 0x41a, ctrl->val); in cx25840_s_ctrl()
1736 cx25840_write(client, 0x422, ctrl->val); in cx25840_s_ctrl()
1740 return -EINVAL; in cx25840_s_ctrl()
1746 /* ----------------------------------------------------------------------- */
1752 struct v4l2_mbus_framefmt *fmt = &format->format; in cx25840_set_fmt()
1757 int is_50hz = !(state->std & V4L2_STD_525_60); in cx25840_set_fmt()
1759 if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED) in cx25840_set_fmt()
1760 return -EINVAL; in cx25840_set_fmt()
1762 fmt->field = V4L2_FIELD_INTERLACED; in cx25840_set_fmt()
1763 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; in cx25840_set_fmt()
1781 if (!state->generic_mode) { in cx25840_set_fmt()
1785 * cx23888 in 525-line mode is programmed for 486 active lines in cx25840_set_fmt()
1792 v_add--; in cx25840_set_fmt()
1806 return -EINVAL; in cx25840_set_fmt()
1809 fmt->width = clamp(fmt->width, (h_src + 15) / 16, h_src); in cx25840_set_fmt()
1812 fmt->height = clamp(fmt->height, (u32)1, v_src - v_add); in cx25840_set_fmt()
1814 fmt->height = clamp(fmt->height, (v_src - v_add * 8 + 7) / 8, in cx25840_set_fmt()
1815 v_src - v_add); in cx25840_set_fmt()
1817 if (format->which == V4L2_SUBDEV_FORMAT_TRY) in cx25840_set_fmt()
1820 hsc = (h_src * (1 << 20)) / fmt->width - (1 << 20); in cx25840_set_fmt()
1821 vsc = (1 << 16) - (v_src * (1 << 9) / (fmt->height + v_add) - (1 << 9)); in cx25840_set_fmt()
1824 if (fmt->width >= 385) in cx25840_set_fmt()
1826 else if (fmt->width > 192) in cx25840_set_fmt()
1828 else if (fmt->width > 96) in cx25840_set_fmt()
1835 (unsigned int)fmt->width, (unsigned int)fmt->height, in cx25840_set_fmt()
1856 /* ----------------------------------------------------------------------- */
1862 "NTSC-M", "NTSC-J", "NTSC-4.43", in log_video_status()
1863 "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60", in log_video_status()
1873 int vid_input = state->vid_input; in log_video_status()
1886 vid_input - CX25840_COMPOSITE1 + 1); in log_video_status()
1889 "Specified video input: S-Video (Luma In%d, Chroma In%d)\n", in log_video_status()
1894 state->audclk_freq); in log_video_status()
1897 /* ----------------------------------------------------------------------- */
1909 int aud_input = state->aud_input; in log_audio_status()
1953 p = "A2-M"; in log_audio_status()
1956 p = "A2-BG"; in log_audio_status()
1959 p = "A2-DK1"; in log_audio_status()
1962 p = "A2-DK2"; in log_audio_status()
1965 p = "A2-DK3"; in log_audio_status()
1971 p = "AM-L"; in log_audio_status()
1974 p = "NICAM-BG"; in log_audio_status()
1977 p = "NICAM-DK"; in log_audio_status()
1980 p = "NICAM-I"; in log_audio_status()
1983 p = "NICAM-L"; in log_audio_status()
1986 p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; in log_audio_status()
1995 p = "high-deviation FM"; in log_audio_status()
1998 p = "very high-deviation FM"; in log_audio_status()
2028 p = "A2-M"; in log_audio_status()
2031 p = "A2-BG"; in log_audio_status()
2034 p = "A2-DK1"; in log_audio_status()
2037 p = "A2-DK2"; in log_audio_status()
2040 p = "A2-DK3"; in log_audio_status()
2046 p = "AM-L"; in log_audio_status()
2049 p = "NICAM-BG"; in log_audio_status()
2052 p = "NICAM-DK"; in log_audio_status()
2055 p = "NICAM-I"; in log_audio_status()
2058 p = "NICAM-L"; in log_audio_status()
2083 p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; in log_audio_status()
2137 p = "A2-M"; in log_audio_status()
2215 p = "A2-M"; in log_audio_status()
2230 (state)->vid_config &= ~(opt_msk); \
2231 (state)->vid_config |= (cfg_in) & (opt_msk); \
2252 /* ----------------------------------------------------------------------- */
2259 * The generic mode disables some of the ivtv-related hacks in this driver.
2267 state->generic_mode = true; in cx25840_init()
2271 state->vid_config = CX25840_VCONFIG_FMT_BT656 | in cx25840_init()
2308 state->is_initialized = 1; in cx25840_reset()
2331 if (!state->is_initialized) { in cx25840_load_fw()
2344 reg->size = 1; in cx25840_g_register()
2345 reg->val = cx25840_read(client, reg->reg & 0x0fff); in cx25840_g_register()
2354 cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff); in cx25840_s_register()
2474 *std = state->std; in cx25840_g_std()
2484 if (state->radio == 0 && state->std == std) in cx25840_s_std()
2486 state->radio = 0; in cx25840_s_std()
2487 state->std = std; in cx25840_s_std()
2495 state->radio = 1; in cx25840_s_radio()
2508 if (is_cx2584x(state) && state->generic_mode && config) { in cx25840_s_video_routing()
2513 return set_input(client, input, state->aud_input); in cx25840_s_video_routing()
2524 return set_input(client, state->vid_input, input); in cx25840_s_audio_routing()
2544 if (state->radio) in cx25840_g_tuner()
2547 vt->signal = vpres ? 0xffff : 0x0; in cx25840_g_tuner()
2551 vt->capability |= V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | in cx25840_g_tuner()
2568 vt->rxsubchans = val; in cx25840_g_tuner()
2569 vt->audmode = state->audmode; in cx25840_g_tuner()
2578 if (state->radio || is_cx2583x(state)) in cx25840_s_tuner()
2581 switch (vt->audmode) { in cx25840_s_tuner()
2584 * mono -> mono in cx25840_s_tuner()
2585 * stereo -> mono in cx25840_s_tuner()
2586 * bilingual -> lang1 in cx25840_s_tuner()
2593 * mono -> mono in cx25840_s_tuner()
2594 * stereo -> stereo in cx25840_s_tuner()
2595 * bilingual -> lang1 in cx25840_s_tuner()
2601 * mono -> mono in cx25840_s_tuner()
2602 * stereo -> stereo in cx25840_s_tuner()
2603 * bilingual -> lang1/lang2 in cx25840_s_tuner()
2609 * mono -> mono in cx25840_s_tuner()
2610 * stereo -> stereo in cx25840_s_tuner()
2611 * bilingual -> lang2 in cx25840_s_tuner()
2616 return -EINVAL; in cx25840_s_tuner()
2618 state->audmode = vt->audmode; in cx25840_s_tuner()
2631 v4l2_ctrl_handler_log_status(&state->hdl, sd->name); in cx25840_log_status()
2715 return -ENODEV; in cx25840_irq_handler()
2718 /* ----------------------------------------------------------------------- */
3557 coeffs = ifhz_coeffs[(ifHz - 3000000) / 100000]; in cx23885_dif_setup()
3582 v4l2_std_id std = state->std; in cx23888_std_setup()
3615 v4l_dbg(1, cx25840_debug, client, "%s() Selecting PAL-BG", in cx23888_std_setup()
3644 set_input(client, state->vid_input, state->aud_input); in cx23888_std_setup()
3647 /* ----------------------------------------------------------------------- */
3710 /* ----------------------------------------------------------------------- */
3768 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) in cx25840_probe()
3769 return -EIO; in cx25840_probe()
3773 client->addr << 1); in cx25840_probe()
3784 id = CX25836 + ((device_id >> 4) & 0xf) - 6; in cx25840_probe()
3795 client->addr << 1, client->adapter->name); in cx25840_probe()
3798 return -ENODEV; in cx25840_probe()
3801 return -ENODEV; in cx25840_probe()
3804 state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL); in cx25840_probe()
3806 return -ENOMEM; in cx25840_probe()
3808 sd = &state->sd; in cx25840_probe()
3816 * TUNER --------> | | in cx25840_probe()
3825 state->pads[CX25840_PAD_INPUT].flags = MEDIA_PAD_FL_SINK; in cx25840_probe()
3826 state->pads[CX25840_PAD_INPUT].sig_type = PAD_SIGNAL_ANALOG; in cx25840_probe()
3827 state->pads[CX25840_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; in cx25840_probe()
3828 state->pads[CX25840_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV; in cx25840_probe()
3829 sd->entity.function = MEDIA_ENT_F_ATV_DECODER; in cx25840_probe()
3831 ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(state->pads), in cx25840_probe()
3832 state->pads); in cx25840_probe()
3842 client->addr << 1, client->adapter->name); in cx25840_probe()
3846 client->addr << 1, client->adapter->name); in cx25840_probe()
3850 client->addr << 1, client->adapter->name); in cx25840_probe()
3854 device_id, client->addr << 1, client->adapter->name); in cx25840_probe()
3864 v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n", in cx25840_probe()
3868 client->addr << 1, client->adapter->name); in cx25840_probe()
3873 v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n", in cx25840_probe()
3875 client->addr << 1, client->adapter->name); in cx25840_probe()
3879 state->c = client; in cx25840_probe()
3880 state->vid_input = CX25840_COMPOSITE7; in cx25840_probe()
3881 state->aud_input = CX25840_AUDIO8; in cx25840_probe()
3882 state->audclk_freq = 48000; in cx25840_probe()
3883 state->audmode = V4L2_TUNER_MODE_LANG1; in cx25840_probe()
3884 state->vbi_line_offset = 8; in cx25840_probe()
3885 state->id = id; in cx25840_probe()
3886 state->rev = device_id; in cx25840_probe()
3887 state->vbi_regs_offset = id == CX23888_AV ? 0x500 - 0x424 : 0; in cx25840_probe()
3888 state->std = V4L2_STD_NTSC_M; in cx25840_probe()
3889 v4l2_ctrl_handler_init(&state->hdl, 9); in cx25840_probe()
3890 v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops, in cx25840_probe()
3892 v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops, in cx25840_probe()
3894 v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops, in cx25840_probe()
3896 v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops, in cx25840_probe()
3897 V4L2_CID_HUE, -128, 127, 1, 0); in cx25840_probe()
3901 * Enforce the legacy PVR-350/MSP3400 to PVR-150/CX25843 volume in cx25840_probe()
3902 * scale mapping limits to avoid -ERANGE errors when in cx25840_probe()
3906 /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */ in cx25840_probe()
3910 /* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */ in cx25840_probe()
3914 default_volume = (((228 - default_volume) >> 1) + 23) << 9; in cx25840_probe()
3916 state->volume = v4l2_ctrl_new_std(&state->hdl, in cx25840_probe()
3921 state->mute = v4l2_ctrl_new_std(&state->hdl, in cx25840_probe()
3925 v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops, in cx25840_probe()
3928 v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops, in cx25840_probe()
3931 v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops, in cx25840_probe()
3935 sd->ctrl_handler = &state->hdl; in cx25840_probe()
3936 if (state->hdl.error) { in cx25840_probe()
3937 int err = state->hdl.error; in cx25840_probe()
3939 v4l2_ctrl_handler_free(&state->hdl); in cx25840_probe()
3943 v4l2_ctrl_cluster(2, &state->volume); in cx25840_probe()
3944 v4l2_ctrl_handler_setup(&state->hdl); in cx25840_probe()
3946 if (client->dev.platform_data) { in cx25840_probe()
3947 struct cx25840_platform_data *pdata = client->dev.platform_data; in cx25840_probe()
3949 state->pvr150_workaround = pdata->pvr150_workaround; in cx25840_probe()
3963 v4l2_ctrl_handler_free(&state->hdl); in cx25840_remove()