diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/cx18/cx18-av-audio.c | 120 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-av-core.c | 29 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-av-core.h | 9 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-av-vbi.c | 325 |
4 files changed, 228 insertions, 255 deletions
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c index a2f0ad57043..9e30983f2ff 100644 --- a/drivers/media/video/cx18/cx18-av-audio.c +++ b/drivers/media/video/cx18/cx18-av-audio.c @@ -464,82 +464,76 @@ static void set_mute(struct cx18 *cx, int mute) } } -int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg) +int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq) { + struct cx18 *cx = v4l2_get_subdevdata(sd); struct cx18_av_state *state = &cx->av_state; - struct v4l2_control *ctrl = arg; int retval; + u8 v; - switch (cmd) { - case VIDIOC_INT_AUDIO_CLOCK_FREQ: - { - u8 v; - if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { - v = cx18_av_read(cx, 0x803) & ~0x10; - cx18_av_write_expect(cx, 0x803, v, v, 0x1f); - cx18_av_write(cx, 0x8d3, 0x1f); - } - v = cx18_av_read(cx, 0x810) | 0x1; - cx18_av_write_expect(cx, 0x810, v, v, 0x0f); + if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { + v = cx18_av_read(cx, 0x803) & ~0x10; + cx18_av_write_expect(cx, 0x803, v, v, 0x1f); + cx18_av_write(cx, 0x8d3, 0x1f); + } + v = cx18_av_read(cx, 0x810) | 0x1; + cx18_av_write_expect(cx, 0x810, v, v, 0x0f); - retval = set_audclk_freq(cx, *(u32 *)arg); + retval = set_audclk_freq(cx, freq); - v = cx18_av_read(cx, 0x810) & ~0x1; - cx18_av_write_expect(cx, 0x810, v, v, 0x0f); - if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { - v = cx18_av_read(cx, 0x803) | 0x10; - cx18_av_write_expect(cx, 0x803, v, v, 0x1f); - } - return retval; + v = cx18_av_read(cx, 0x810) & ~0x1; + cx18_av_write_expect(cx, 0x810, v, v, 0x0f); + if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { + v = cx18_av_read(cx, 0x803) | 0x10; + cx18_av_write_expect(cx, 0x803, v, v, 0x1f); } + return retval; +} - case VIDIOC_G_CTRL: - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - ctrl->value = get_volume(cx); - break; - case V4L2_CID_AUDIO_BASS: - ctrl->value = get_bass(cx); - break; - case V4L2_CID_AUDIO_TREBLE: - ctrl->value = get_treble(cx); - break; - case V4L2_CID_AUDIO_BALANCE: - ctrl->value = get_balance(cx); - break; - case V4L2_CID_AUDIO_MUTE: - ctrl->value = get_mute(cx); - break; - default: - return -EINVAL; - } +int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl) +{ + switch (ctrl->id) { + case V4L2_CID_AUDIO_VOLUME: + ctrl->value = get_volume(cx); break; - - case VIDIOC_S_CTRL: - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - set_volume(cx, ctrl->value); - break; - case V4L2_CID_AUDIO_BASS: - set_bass(cx, ctrl->value); - break; - case V4L2_CID_AUDIO_TREBLE: - set_treble(cx, ctrl->value); - break; - case V4L2_CID_AUDIO_BALANCE: - set_balance(cx, ctrl->value); - break; - case V4L2_CID_AUDIO_MUTE: - set_mute(cx, ctrl->value); - break; - default: - return -EINVAL; - } + case V4L2_CID_AUDIO_BASS: + ctrl->value = get_bass(cx); + break; + case V4L2_CID_AUDIO_TREBLE: + ctrl->value = get_treble(cx); + break; + case V4L2_CID_AUDIO_BALANCE: + ctrl->value = get_balance(cx); + break; + case V4L2_CID_AUDIO_MUTE: + ctrl->value = get_mute(cx); break; - default: return -EINVAL; } + return 0; +} +int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl) +{ + switch (ctrl->id) { + case V4L2_CID_AUDIO_VOLUME: + set_volume(cx, ctrl->value); + break; + case V4L2_CID_AUDIO_BASS: + set_bass(cx, ctrl->value); + break; + case V4L2_CID_AUDIO_TREBLE: + set_treble(cx, ctrl->value); + break; + case V4L2_CID_AUDIO_BALANCE: + set_balance(cx, ctrl->value); + break; + case V4L2_CID_AUDIO_MUTE: + set_mute(cx, ctrl->value); + break; + default: + return -EINVAL; + } return 0; } diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index 21f4be8393b..f4dd9d78eb3 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c @@ -413,19 +413,6 @@ void cx18_av_std_setup(struct cx18 *cx) cx18_av_write(cx, 0x47f, state->slicer_line_delay); } -static int cx18_av_decode_vbi_line(struct v4l2_subdev *sd, - struct v4l2_decode_vbi_line *vbi_line) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); - return cx18_av_vbi(cx, VIDIOC_INT_DECODE_VBI_LINE, vbi_line); -} - -static int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq) -{ - struct cx18 *cx = v4l2_get_subdevdata(sd); - return cx18_av_audio(cx, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freq); -} - static void input_change(struct cx18 *cx) { struct cx18_av_state *state = &cx->av_state; @@ -772,7 +759,7 @@ static int cx18_av_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_TREBLE: case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_MUTE: - return cx18_av_audio(cx, VIDIOC_S_CTRL, ctrl); + return cx18_av_audio_s_ctrl(cx, ctrl); default: return -EINVAL; @@ -802,7 +789,7 @@ static int cx18_av_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_TREBLE: case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_MUTE: - return cx18_av_audio(cx, VIDIOC_G_CTRL, ctrl); + return cx18_av_audio_g_ctrl(cx, ctrl); default: return -EINVAL; } @@ -845,13 +832,7 @@ static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) { struct cx18 *cx = v4l2_get_subdevdata(sd); - switch (fmt->type) { - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - return cx18_av_vbi(cx, VIDIOC_G_FMT, fmt); - default: - return -EINVAL; - } - return 0; + return cx18_av_vbi_g_fmt(cx, fmt); } static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) @@ -925,10 +906,10 @@ static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt) break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt); + return cx18_av_vbi_s_fmt(cx, fmt); case V4L2_BUF_TYPE_VBI_CAPTURE: - return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt); + return cx18_av_vbi_s_fmt(cx, fmt); default: return -EINVAL; diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h index 2687a2c91dd..c458120e8c9 100644 --- a/drivers/media/video/cx18/cx18-av-core.h +++ b/drivers/media/video/cx18/cx18-av-core.h @@ -355,11 +355,16 @@ int cx18_av_loadfw(struct cx18 *cx); /* ----------------------------------------------------------------------- */ /* cx18_av-audio.c */ -int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg); +int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl); +int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl); +int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq); void cx18_av_audio_set_path(struct cx18 *cx); /* ----------------------------------------------------------------------- */ /* cx18_av-vbi.c */ -int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg); +int cx18_av_decode_vbi_line(struct v4l2_subdev *sd, + struct v4l2_decode_vbi_line *vbi); +int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt); +int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt); #endif diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c index 27699839b80..23b31670bf1 100644 --- a/drivers/media/video/cx18/cx18-av-vbi.c +++ b/drivers/media/video/cx18/cx18-av-vbi.c @@ -129,196 +129,189 @@ static int decode_vps(u8 *dst, u8 *p) return err & 0xf0; } -int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) +int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt) { struct cx18_av_state *state = &cx->av_state; - struct v4l2_format *fmt; 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 ((cx18_av_read(cx, 0x404) & 0x10) == 0) - break; - - if (is_pal) { - for (i = 7; i <= 23; i++) { - u8 v = cx18_av_read(cx, 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]; - } - } else { - for (i = 10; i <= 21; i++) { - u8 v = cx18_av_read(cx, 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; - } + 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 ((cx18_av_read(cx, 0x404) & 0x10) == 0) + return 0; + + if (is_pal) { + for (i = 7; i <= 23; i++) { + u8 v = cx18_av_read(cx, 0x424 + i - 7); - case VIDIOC_S_FMT: - { - int is_pal = !(state->std & V4L2_STD_525_60); - 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 */ - cx18_av_std_setup(cx); - - /* VBI Offset */ - cx18_av_write(cx, 0x47f, state->slicer_line_delay); - cx18_av_write(cx, 0x404, 0x2e); - break; + 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 = cx18_av_read(cx, 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]; + } + } + return 0; +} - for (x = 0; x <= 23; x++) - lcr[x] = 0x00; +int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt) +{ + struct cx18_av_state *state = &cx->av_state; + struct v4l2_sliced_vbi_format *svbi; + int is_pal = !(state->std & V4L2_STD_525_60); + 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 */ cx18_av_std_setup(cx); - /* Sliced VBI */ - cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */ - cx18_av_write(cx, 0x406, 0x13); + /* VBI Offset */ cx18_av_write(cx, 0x47f, state->slicer_line_delay); + cx18_av_write(cx, 0x404, 0x2e); + return 0; + } - /* Force impossible lines to 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 (x = 0; x <= 23; x++) + lcr[x] = 0x00; + + /* Setup standard */ + cx18_av_std_setup(cx); + + /* Sliced VBI */ + cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */ + cx18_av_write(cx, 0x406, 0x13); + cx18_av_write(cx, 0x47f, state->slicer_line_delay); + + /* Force impossible lines to 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; + } - /* Build register values for requested service lines */ - 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; - } + /* Build register values for requested service lines */ + 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; } } + } - if (is_pal) { - for (x = 1, i = 0x424; i <= 0x434; i++, x++) - cx18_av_write(cx, i, lcr[6 + x]); - } else { - for (x = 1, i = 0x424; i <= 0x430; i++, x++) - cx18_av_write(cx, i, lcr[9 + x]); - for (i = 0x431; i <= 0x434; i++) - cx18_av_write(cx, i, 0); - } + if (is_pal) { + for (x = 1, i = 0x424; i <= 0x434; i++, x++) + cx18_av_write(cx, i, lcr[6 + x]); + } else { + for (x = 1, i = 0x424; i <= 0x430; i++, x++) + cx18_av_write(cx, i, lcr[9 + x]); + for (i = 0x431; i <= 0x434; i++) + cx18_av_write(cx, i, 0); + } - cx18_av_write(cx, 0x43c, 0x16); - /* FIXME - should match vblank set in cx18_av_std_setup() */ - cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26); - break; + cx18_av_write(cx, 0x43c, 0x16); + /* FIXME - should match vblank set in cx18_av_std_setup() */ + cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26); + return 0; +} + +int cx18_av_decode_vbi_line(struct v4l2_subdev *sd, + struct v4l2_decode_vbi_line *vbi) +{ + struct cx18 *cx = v4l2_get_subdevdata(sd); + struct cx18_av_state *state = &cx->av_state; + struct vbi_anc_data *anc = (struct vbi_anc_data *)vbi->p; + u8 *p; + int did, sdid, l, err = 0; + + /* + * Check for the ancillary data header for sliced VBI + */ + if (anc->preamble[0] || + anc->preamble[1] != 0xff || anc->preamble[2] != 0xff || + (anc->did != sliced_vbi_did[0] && + anc->did != sliced_vbi_did[1])) { + vbi->line = vbi->type = 0; + return 0; } - case VIDIOC_INT_DECODE_VBI_LINE: - { - struct v4l2_decode_vbi_line *vbi = arg; - u8 *p; - struct vbi_anc_data *anc = (struct vbi_anc_data *) vbi->p; - int did, sdid, l, err = 0; - - /* - * Check for the ancillary data header for sliced VBI - */ - if (anc->preamble[0] || - anc->preamble[1] != 0xff || anc->preamble[2] != 0xff || - (anc->did != sliced_vbi_did[0] && - anc->did != sliced_vbi_did[1])) { - vbi->line = vbi->type = 0; - break; - } + did = anc->did; + sdid = anc->sdid & 0xf; + l = anc->idid[0] & 0x3f; + l += state->slicer_line_offset; + p = anc->payload; - did = anc->did; - sdid = anc->sdid & 0xf; - l = anc->idid[0] & 0x3f; - l += state->slicer_line_offset; - p = anc->payload; - - /* Decode the SDID set by the slicer */ - switch (sdid) { - case 1: - sdid = V4L2_SLICED_TELETEXT_B; - break; - case 4: - sdid = V4L2_SLICED_WSS_625; - break; - case 6: - sdid = V4L2_SLICED_CAPTION_525; - err = !odd_parity(p[0]) || !odd_parity(p[1]); - break; - case 9: - sdid = V4L2_SLICED_VPS; - if (decode_vps(p, p) != 0) - err = 1; - break; - default: - sdid = 0; + /* Decode the SDID set by the slicer */ + switch (sdid) { + case 1: + sdid = V4L2_SLICED_TELETEXT_B; + break; + case 4: + sdid = V4L2_SLICED_WSS_625; + break; + case 6: + sdid = V4L2_SLICED_CAPTION_525; + err = !odd_parity(p[0]) || !odd_parity(p[1]); + break; + case 9: + sdid = V4L2_SLICED_VPS; + if (decode_vps(p, p) != 0) err = 1; - break; - } - - vbi->type = err ? 0 : sdid; - vbi->line = err ? 0 : l; - vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]); - vbi->p = p; break; - } + default: + sdid = 0; + err = 1; + break; } + vbi->type = err ? 0 : sdid; + vbi->line = err ? 0 : l; + vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]); + vbi->p = p; return 0; } |