diff options
author | Jean-Francois Moine <moinejf@free.fr> | 2009-04-05 18:03:02 +0200 |
---|---|---|
committer | Jean-Francois Moine <moinejf@free.fr> | 2009-04-05 18:03:02 +0200 |
commit | bcaafb56e4c3741c1923db37683a4590dda2cbfb (patch) | |
tree | 4ade810f7cbd3425665c1ce57769745871565866 /linux/drivers/media/video/cx25840 | |
parent | ffa071fb6b99731b41db5e814dbb2b0403c7c98c (diff) | |
parent | 8dd3ceb79cec4a833fbc9fd654b7e71e9548d331 (diff) | |
download | mediapointer-dvb-s2-bcaafb56e4c3741c1923db37683a4590dda2cbfb.tar.gz mediapointer-dvb-s2-bcaafb56e4c3741c1923db37683a4590dda2cbfb.tar.bz2 |
merge: v4l-dvb
Diffstat (limited to 'linux/drivers/media/video/cx25840')
-rw-r--r-- | linux/drivers/media/video/cx25840/cx25840-audio.c | 121 | ||||
-rw-r--r-- | linux/drivers/media/video/cx25840/cx25840-core.c | 69 | ||||
-rw-r--r-- | linux/drivers/media/video/cx25840/cx25840-core.h | 8 | ||||
-rw-r--r-- | linux/drivers/media/video/cx25840/cx25840-vbi.c | 314 |
4 files changed, 235 insertions, 277 deletions
diff --git a/linux/drivers/media/video/cx25840/cx25840-audio.c b/linux/drivers/media/video/cx25840/cx25840-audio.c index 9dcdef03e..f0a91f981 100644 --- a/linux/drivers/media/video/cx25840/cx25840-audio.c +++ b/linux/drivers/media/video/cx25840/cx25840-audio.c @@ -378,75 +378,74 @@ static void set_mute(struct i2c_client *client, int mute) } } -int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) +int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq) { - struct cx25840_state *state = to_state(i2c_get_clientdata(client)); - struct v4l2_control *ctrl = arg; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct cx25840_state *state = to_state(sd); int retval; - switch (cmd) { - case VIDIOC_INT_AUDIO_CLOCK_FREQ: - if (!state->is_cx25836) - cx25840_and_or(client, 0x810, ~0x1, 1); - if (state->aud_input != CX25840_AUDIO_SERIAL) { - cx25840_and_or(client, 0x803, ~0x10, 0); - cx25840_write(client, 0x8d3, 0x1f); - } - retval = set_audclk_freq(client, *(u32 *)arg); - if (state->aud_input != CX25840_AUDIO_SERIAL) { - cx25840_and_or(client, 0x803, ~0x10, 0x10); - } - if (!state->is_cx25836) - cx25840_and_or(client, 0x810, ~0x1, 0); - return retval; - - case VIDIOC_G_CTRL: - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - ctrl->value = get_volume(client); - break; - case V4L2_CID_AUDIO_BASS: - ctrl->value = get_bass(client); - break; - case V4L2_CID_AUDIO_TREBLE: - ctrl->value = get_treble(client); - break; - case V4L2_CID_AUDIO_BALANCE: - ctrl->value = get_balance(client); - break; - case V4L2_CID_AUDIO_MUTE: - ctrl->value = get_mute(client); - break; - default: - return -EINVAL; - } - break; + if (!state->is_cx25836) + cx25840_and_or(client, 0x810, ~0x1, 1); + if (state->aud_input != CX25840_AUDIO_SERIAL) { + cx25840_and_or(client, 0x803, ~0x10, 0); + cx25840_write(client, 0x8d3, 0x1f); + } + retval = set_audclk_freq(client, freq); + if (state->aud_input != CX25840_AUDIO_SERIAL) + cx25840_and_or(client, 0x803, ~0x10, 0x10); + if (!state->is_cx25836) + cx25840_and_or(client, 0x810, ~0x1, 0); + return retval; +} - case VIDIOC_S_CTRL: - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - set_volume(client, ctrl->value); - break; - case V4L2_CID_AUDIO_BASS: - set_bass(client, ctrl->value); - break; - case V4L2_CID_AUDIO_TREBLE: - set_treble(client, ctrl->value); - break; - case V4L2_CID_AUDIO_BALANCE: - set_balance(client, ctrl->value); - break; - case V4L2_CID_AUDIO_MUTE: - set_mute(client, ctrl->value); - break; - default: - return -EINVAL; - } - break; +int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + switch (ctrl->id) { + case V4L2_CID_AUDIO_VOLUME: + ctrl->value = get_volume(client); + break; + case V4L2_CID_AUDIO_BASS: + ctrl->value = get_bass(client); + break; + case V4L2_CID_AUDIO_TREBLE: + ctrl->value = get_treble(client); + break; + case V4L2_CID_AUDIO_BALANCE: + ctrl->value = get_balance(client); + break; + case V4L2_CID_AUDIO_MUTE: + ctrl->value = get_mute(client); + break; default: return -EINVAL; } + return 0; +} +int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + switch (ctrl->id) { + case V4L2_CID_AUDIO_VOLUME: + set_volume(client, ctrl->value); + break; + case V4L2_CID_AUDIO_BASS: + set_bass(client, ctrl->value); + break; + case V4L2_CID_AUDIO_TREBLE: + set_treble(client, ctrl->value); + break; + case V4L2_CID_AUDIO_BALANCE: + set_balance(client, ctrl->value); + break; + case V4L2_CID_AUDIO_MUTE: + set_mute(client, ctrl->value); + break; + default: + return -EINVAL; + } return 0; } diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c index 5387a846f..2929bf3b7 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.c +++ b/linux/drivers/media/video/cx25840/cx25840-core.c @@ -39,7 +39,7 @@ #include <linux/delay.h> #include <media/v4l2-common.h> #include <media/v4l2-chip-ident.h> -#include <media/v4l2-i2c-drv-legacy.h> +#include <media/v4l2-i2c-drv.h> #include <media/cx25840.h> #include "compat.h" @@ -49,15 +49,17 @@ MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver"); MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford"); MODULE_LICENSE("GPL"); -static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; - static int cx25840_debug; module_param_named(debug,cx25840_debug, int, 0644); MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]"); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) +static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; + I2C_CLIENT_INSMOD; +#endif /* ----------------------------------------------------------------------- */ @@ -891,7 +893,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_MUTE: if (state->is_cx25836) return -EINVAL; - return cx25840_audio(client, VIDIOC_S_CTRL, ctrl); + return cx25840_audio_s_ctrl(sd, ctrl); default: return -EINVAL; @@ -928,7 +930,7 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_MUTE: if (state->is_cx25836) return -EINVAL; - return cx25840_audio(client, VIDIOC_G_CTRL, ctrl); + return cx25840_audio_g_ctrl(sd, ctrl); default: return -EINVAL; } @@ -940,11 +942,9 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) { - struct i2c_client *client = v4l2_get_subdevdata(sd); - switch (fmt->type) { case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - return cx25840_vbi(client, VIDIOC_G_FMT, fmt); + return cx25840_vbi_g_fmt(sd, fmt); default: return -EINVAL; } @@ -1006,10 +1006,10 @@ static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - return cx25840_vbi(client, VIDIOC_S_FMT, fmt); + return cx25840_vbi_s_fmt(sd, fmt); case V4L2_BUF_TYPE_VBI_CAPTURE: - return cx25840_vbi(client, VIDIOC_S_FMT, fmt); + return cx25840_vbi_s_fmt(sd, fmt); default: return -EINVAL; @@ -1214,7 +1214,7 @@ static void log_audio_status(struct i2c_client *client) /* ----------------------------------------------------------------------- */ -/* This init operation must be called to load the driver's firmware. +/* This load_fw operation must be called to load the driver's firmware. Without this the audio standard detection will fail and you will only get mono. @@ -1224,13 +1224,13 @@ static void log_audio_status(struct i2c_client *client) postponing it is that loading this firmware takes a long time (seconds) due to the slow i2c bus speed. So it will speed up the boot process if you can avoid loading the fw as long as the video device isn't used. */ -static int cx25840_init(struct v4l2_subdev *sd, u32 val) +static int cx25840_load_fw(struct v4l2_subdev *sd) { struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); if (!state->is_initialized) { - /* initialize on first use */ + /* initialize and load firmware */ state->is_initialized = 1; if (state->is_cx25836) cx25836_initialize(client); @@ -1271,20 +1271,6 @@ static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register * } #endif -static int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return cx25840_vbi(client, VIDIOC_INT_DECODE_VBI_LINE, vbi); -} - -static int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - return cx25840_audio(client, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freq); -} - static int cx25840_s_stream(struct v4l2_subdev *sd, int enable) { struct cx25840_state *state = to_state(sd); @@ -1368,22 +1354,24 @@ static int cx25840_s_radio(struct v4l2_subdev *sd) return 0; } -static int cx25840_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) +static int cx25840_s_video_routing(struct v4l2_subdev *sd, + u32 input, u32 output, u32 config) { struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - return set_input(client, route->input, state->aud_input); + return set_input(client, input, state->aud_input); } -static int cx25840_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route) +static int cx25840_s_audio_routing(struct v4l2_subdev *sd, + u32 input, u32 output, u32 config) { struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); if (state->is_cx25836) return -EINVAL; - return set_input(client, state->vid_input, route->input); + return set_input(client, state->vid_input, input); } static int cx25840_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq) @@ -1510,19 +1498,6 @@ static int cx25840_log_status(struct v4l2_subdev *sd) return 0; } -static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg) -{ - /* ignore this command */ - if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG) - return 0; - - /* Old-style drivers rely on initialization on first use, so - call the init whenever a command is issued to this driver. - New-style drivers using v4l2_subdev should call init explicitly. */ - cx25840_init(i2c_get_clientdata(client), 0); - return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); -} - /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops cx25840_core_ops = { @@ -1531,8 +1506,9 @@ static const struct v4l2_subdev_core_ops cx25840_core_ops = { .g_ctrl = cx25840_g_ctrl, .s_ctrl = cx25840_s_ctrl, .queryctrl = cx25840_queryctrl, + .s_std = cx25840_s_std, .reset = cx25840_reset, - .init = cx25840_init, + .load_fw = cx25840_load_fw, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = cx25840_g_register, .s_register = cx25840_s_register, @@ -1541,7 +1517,6 @@ static const struct v4l2_subdev_core_ops cx25840_core_ops = { static const struct v4l2_subdev_tuner_ops cx25840_tuner_ops = { .s_frequency = cx25840_s_frequency, - .s_std = cx25840_s_std, .s_radio = cx25840_s_radio, .g_tuner = cx25840_g_tuner, .s_tuner = cx25840_s_tuner, @@ -1663,8 +1638,6 @@ MODULE_DEVICE_TABLE(i2c, cx25840_id); #endif static struct v4l2_i2c_driver_data v4l2_i2c_data = { .name = "cx25840", - .driverid = I2C_DRIVERID_CX25840, - .command = cx25840_command, .probe = cx25840_probe, .remove = cx25840_remove, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) diff --git a/linux/drivers/media/video/cx25840/cx25840-core.h b/linux/drivers/media/video/cx25840/cx25840-core.h index 422c63752..580c320da 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.h +++ b/linux/drivers/media/video/cx25840/cx25840-core.h @@ -77,11 +77,15 @@ int cx25840_loadfw(struct i2c_client *client); /* ----------------------------------------------------------------------- */ /* cx25850-audio.c */ -int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg); void cx25840_audio_set_path(struct i2c_client *client); +int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq); +int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl); /* ----------------------------------------------------------------------- */ /* cx25850-vbi.c */ -int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg); +int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt); +int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt); +int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi); #endif diff --git a/linux/drivers/media/video/cx25840/cx25840-vbi.c b/linux/drivers/media/video/cx25840/cx25840-vbi.c index 7790afd5b..011987326 100644 --- a/linux/drivers/media/video/cx25840/cx25840-vbi.c +++ b/linux/drivers/media/video/cx25840/cx25840-vbi.c @@ -83,199 +83,181 @@ static int decode_vps(u8 * dst, u8 * p) return err & 0xf0; } -int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) +int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) { - struct cx25840_state *state = to_state(i2c_get_clientdata(client)); - struct v4l2_format *fmt; + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct cx25840_state *state = to_state(sd); struct v4l2_sliced_vbi_format *svbi; + static const u16 lcr2vbi[] = { + 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ + 0, V4L2_SLICED_WSS_625, 0, /* 4 */ + V4L2_SLICED_CAPTION_525, /* 6 */ + 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ + 0, 0, 0, 0 + }; + int is_pal = !(state->std & V4L2_STD_525_60); + int i; - switch (cmd) { - case VIDIOC_G_FMT: - { - static u16 lcr2vbi[] = { - 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ - 0, V4L2_SLICED_WSS_625, 0, /* 4 */ - V4L2_SLICED_CAPTION_525, /* 6 */ - 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ - 0, 0, 0, 0 - }; - int is_pal = !(state->std & V4L2_STD_525_60); - int i; - - fmt = arg; - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) - return -EINVAL; - svbi = &fmt->fmt.sliced; - memset(svbi, 0, sizeof(*svbi)); - /* we're done if raw VBI is active */ - if ((cx25840_read(client, 0x404) & 0x10) == 0) - break; + if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) + return -EINVAL; + svbi = &fmt->fmt.sliced; + memset(svbi, 0, sizeof(*svbi)); + /* we're done if raw VBI is active */ + if ((cx25840_read(client, 0x404) & 0x10) == 0) + return 0; - if (is_pal) { - for (i = 7; i <= 23; i++) { - u8 v = cx25840_read(client, 0x424 + i - 7); + if (is_pal) { + for (i = 7; i <= 23; i++) { + u8 v = cx25840_read(client, 0x424 + i - 7); - svbi->service_lines[0][i] = lcr2vbi[v >> 4]; - svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; - svbi->service_set |= - svbi->service_lines[0][i] | svbi->service_lines[1][i]; - } + svbi->service_lines[0][i] = lcr2vbi[v >> 4]; + svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; + svbi->service_set |= svbi->service_lines[0][i] | + svbi->service_lines[1][i]; } - else { - for (i = 10; i <= 21; i++) { - u8 v = cx25840_read(client, 0x424 + i - 10); - - svbi->service_lines[0][i] = lcr2vbi[v >> 4]; - svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; - svbi->service_set |= - svbi->service_lines[0][i] | svbi->service_lines[1][i]; - } + } else { + for (i = 10; i <= 21; i++) { + u8 v = cx25840_read(client, 0x424 + i - 10); + + svbi->service_lines[0][i] = lcr2vbi[v >> 4]; + svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; + svbi->service_set |= svbi->service_lines[0][i] | + svbi->service_lines[1][i]; } - break; } + return 0; +} - case VIDIOC_S_FMT: - { - int is_pal = !(state->std & V4L2_STD_525_60); - int vbi_offset = is_pal ? 1 : 0; - int i, x; - u8 lcr[24]; - - fmt = arg; - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && - fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE) - return -EINVAL; - svbi = &fmt->fmt.sliced; - if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - /* raw VBI */ - memset(svbi, 0, sizeof(*svbi)); - - /* Setup standard */ - cx25840_std_setup(client); - - /* VBI Offset */ - cx25840_write(client, 0x47f, vbi_offset); - cx25840_write(client, 0x404, 0x2e); - break; - } - - for (x = 0; x <= 23; x++) - lcr[x] = 0x00; +int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct cx25840_state *state = to_state(sd); + struct v4l2_sliced_vbi_format *svbi; + int is_pal = !(state->std & V4L2_STD_525_60); + int vbi_offset = is_pal ? 1 : 0; + int i, x; + u8 lcr[24]; + + if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && + fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE) + return -EINVAL; + svbi = &fmt->fmt.sliced; + if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { + /* raw VBI */ + memset(svbi, 0, sizeof(*svbi)); /* Setup standard */ cx25840_std_setup(client); - /* Sliced VBI */ - cx25840_write(client, 0x404, 0x32); /* Ancillary data */ - cx25840_write(client, 0x406, 0x13); + /* VBI Offset */ cx25840_write(client, 0x47f, vbi_offset); + cx25840_write(client, 0x404, 0x2e); + return 0; + } - if (is_pal) { - for (i = 0; i <= 6; i++) - svbi->service_lines[0][i] = - svbi->service_lines[1][i] = 0; - } else { - for (i = 0; i <= 9; i++) - svbi->service_lines[0][i] = - svbi->service_lines[1][i] = 0; - - for (i = 22; i <= 23; i++) - svbi->service_lines[0][i] = - svbi->service_lines[1][i] = 0; - } - - for (i = 7; i <= 23; i++) { - for (x = 0; x <= 1; x++) { - switch (svbi->service_lines[1-x][i]) { - case V4L2_SLICED_TELETEXT_B: - lcr[i] |= 1 << (4 * x); - break; - case V4L2_SLICED_WSS_625: - lcr[i] |= 4 << (4 * x); - break; - case V4L2_SLICED_CAPTION_525: - lcr[i] |= 6 << (4 * x); - break; - case V4L2_SLICED_VPS: - lcr[i] |= 9 << (4 * x); - break; - } - } - } + for (x = 0; x <= 23; x++) + lcr[x] = 0x00; + + /* Setup standard */ + cx25840_std_setup(client); + + /* Sliced VBI */ + cx25840_write(client, 0x404, 0x32); /* Ancillary data */ + cx25840_write(client, 0x406, 0x13); + cx25840_write(client, 0x47f, vbi_offset); + + if (is_pal) { + for (i = 0; i <= 6; i++) + svbi->service_lines[0][i] = + svbi->service_lines[1][i] = 0; + } else { + for (i = 0; i <= 9; i++) + svbi->service_lines[0][i] = + svbi->service_lines[1][i] = 0; + + for (i = 22; i <= 23; i++) + svbi->service_lines[0][i] = + svbi->service_lines[1][i] = 0; + } - if (is_pal) { - for (x = 1, i = 0x424; i <= 0x434; i++, x++) { - cx25840_write(client, i, lcr[6 + x]); - } - } - else { - for (x = 1, i = 0x424; i <= 0x430; i++, x++) { - cx25840_write(client, i, lcr[9 + x]); - } - for (i = 0x431; i <= 0x434; i++) { - cx25840_write(client, i, 0); + for (i = 7; i <= 23; i++) { + for (x = 0; x <= 1; x++) { + switch (svbi->service_lines[1-x][i]) { + case V4L2_SLICED_TELETEXT_B: + lcr[i] |= 1 << (4 * x); + break; + case V4L2_SLICED_WSS_625: + lcr[i] |= 4 << (4 * x); + break; + case V4L2_SLICED_CAPTION_525: + lcr[i] |= 6 << (4 * x); + break; + case V4L2_SLICED_VPS: + lcr[i] |= 9 << (4 * x); + break; } } + } - cx25840_write(client, 0x43c, 0x16); - - if (is_pal) { - cx25840_write(client, 0x474, 0x2a); - } else { - cx25840_write(client, 0x474, 0x22); - } - break; + if (is_pal) { + for (x = 1, i = 0x424; i <= 0x434; i++, x++) + cx25840_write(client, i, lcr[6 + x]); + } else { + for (x = 1, i = 0x424; i <= 0x430; i++, x++) + cx25840_write(client, i, lcr[9 + x]); + for (i = 0x431; i <= 0x434; i++) + cx25840_write(client, i, 0); } - case VIDIOC_INT_DECODE_VBI_LINE: - { - struct v4l2_decode_vbi_line *vbi = arg; - u8 *p = vbi->p; - int id1, id2, l, err = 0; + cx25840_write(client, 0x43c, 0x16); + cx25840_write(client, 0x474, is_pal ? 0x2a : 0x22); + return 0; +} - if (p[0] || p[1] != 0xff || p[2] != 0xff || - (p[3] != 0x55 && p[3] != 0x91)) { - vbi->line = vbi->type = 0; - break; - } +int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi) +{ + struct cx25840_state *state = to_state(sd); + u8 *p = vbi->p; + int id1, id2, l, err = 0; + + if (p[0] || p[1] != 0xff || p[2] != 0xff || + (p[3] != 0x55 && p[3] != 0x91)) { + vbi->line = vbi->type = 0; + return 0; + } - p += 4; - id1 = p[-1]; - id2 = p[0] & 0xf; - l = p[2] & 0x3f; - l += state->vbi_line_offset; - p += 4; + p += 4; + id1 = p[-1]; + id2 = p[0] & 0xf; + l = p[2] & 0x3f; + l += state->vbi_line_offset; + p += 4; - switch (id2) { - case 1: - id2 = V4L2_SLICED_TELETEXT_B; - break; - case 4: - id2 = V4L2_SLICED_WSS_625; - break; - case 6: - id2 = V4L2_SLICED_CAPTION_525; - err = !odd_parity(p[0]) || !odd_parity(p[1]); - break; - case 9: - id2 = V4L2_SLICED_VPS; - if (decode_vps(p, p) != 0) { - err = 1; - } - break; - default: - id2 = 0; + switch (id2) { + case 1: + id2 = V4L2_SLICED_TELETEXT_B; + break; + case 4: + id2 = V4L2_SLICED_WSS_625; + break; + case 6: + id2 = V4L2_SLICED_CAPTION_525; + err = !odd_parity(p[0]) || !odd_parity(p[1]); + break; + case 9: + id2 = V4L2_SLICED_VPS; + if (decode_vps(p, p) != 0) err = 1; - break; - } - - vbi->type = err ? 0 : id2; - vbi->line = err ? 0 : l; - vbi->is_second_field = err ? 0 : (id1 == 0x55); - vbi->p = p; break; - } + default: + id2 = 0; + err = 1; + break; } + vbi->type = err ? 0 : id2; + vbi->line = err ? 0 : l; + vbi->is_second_field = err ? 0 : (id1 == 0x55); + vbi->p = p; return 0; } |