#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/i2c.h>
+#include <media/audiochip.h>
#include <media/v4l2-common.h>
-#include <media/cx25840.h>
-#include "cx25840-core.h"
+#include "cx25840.h"
MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver");
MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford");
cx25840_write(client, 0x4a5, 0x00);
cx25840_write(client, 0x402, 0x00);
/* 8. */
- cx25840_and_or(client, 0x401, ~0x18, 0);
- cx25840_and_or(client, 0x4a2, ~0x10, 0x10);
- /* steps 8c and 8d are done in change_input() */
+ cx25840_write(client, 0x401, 0x18);
+ cx25840_write(client, 0x4a2, 0x10);
+ cx25840_write(client, 0x402, 0x04);
/* 10. */
cx25840_write(client, 0x8d3, 0x1f);
cx25840_write(client, 0x8e3, 0x03);
struct cx25840_state *state = i2c_get_clientdata(client);
v4l2_std_id std = cx25840_get_v4lstd(client);
- /* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */
- if (std & V4L2_STD_SECAM) {
- cx25840_write(client, 0x402, 0);
- }
- else {
- cx25840_write(client, 0x402, 0x04);
- cx25840_write(client, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
- }
- cx25840_and_or(client, 0x401, ~0x60, 0);
- cx25840_and_or(client, 0x401, ~0x60, 0x60);
-
/* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC
instead of V4L2_STD_PAL. Someone needs to test this. */
if (std & V4L2_STD_PAL) {
}
}
- /* Follow step 9 of section 3.16 in the cx25840 datasheet.
- Without this PAL may display a vertical ghosting effect.
- This happens for example with the Yuan MPC622. */
- if (fmt >= 4 && fmt < 8) {
- /* Set format to NTSC-M */
- cx25840_and_or(client, 0x400, ~0xf, 1);
- /* Turn off LCOMB */
- cx25840_and_or(client, 0x47b, ~6, 0);
- }
cx25840_and_or(client, 0x400, ~0xf, fmt);
cx25840_vbi_setup(client);
return 0;
}
switch (fmt) {
- case 0x1:
- {
- /* if the audio std is A2-M, then this is the South Korean
- NTSC standard */
- if (cx25840_read(client, 0x805) == 2)
- return V4L2_STD_NTSC_M_KR;
- return V4L2_STD_NTSC_M;
- }
+ case 0x1: return V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR;
case 0x2: return V4L2_STD_NTSC_M_JP;
case 0x3: return V4L2_STD_NTSC_443;
case 0x4: return V4L2_STD_PAL;
{
struct cx25840_state *state = i2c_get_clientdata(client);
struct v4l2_tuner *vt = arg;
- struct v4l2_routing *route = arg;
switch (cmd) {
#ifdef CONFIG_VIDEO_ADV_DEBUG
state->radio = 1;
break;
- case VIDIOC_INT_G_VIDEO_ROUTING:
- route->input = state->vid_input;
- route->output = 0;
+ case VIDIOC_G_INPUT:
+ *(int *)arg = state->vid_input;
break;
- case VIDIOC_INT_S_VIDEO_ROUTING:
- return set_input(client, route->input, state->aud_input);
+ case VIDIOC_S_INPUT:
+ return set_input(client, *(enum cx25840_video_input *)arg, state->aud_input);
- case VIDIOC_INT_G_AUDIO_ROUTING:
- route->input = state->aud_input;
- route->output = 0;
- break;
+ case VIDIOC_S_AUDIO:
+ {
+ struct v4l2_audio *input = arg;
+
+ return set_input(client, state->vid_input, input->index);
+ }
- case VIDIOC_INT_S_AUDIO_ROUTING:
- return set_input(client, state->vid_input, route->input);
+ case VIDIOC_G_AUDIO:
+ {
+ struct v4l2_audio *input = arg;
+
+ memset(input, 0, sizeof(*input));
+ input->index = state->aud_input;
+ break;
+ }
case VIDIOC_S_FREQUENCY:
input_change(client);
case VIDIOC_G_TUNER:
{
u8 mode = cx25840_read(client, 0x804);
+ u8 pref = cx25840_read(client, 0x809) & 0xf;
u8 vpres = cx25840_read(client, 0x80a) & 0x10;
int val = 0;
val |= V4L2_TUNER_SUB_MONO;
if (mode == 2 || mode == 4)
- val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+ val |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
if (mode & 0x10)
val |= V4L2_TUNER_SUB_SAP;
vt->rxsubchans = val;
- vt->audmode = state->audmode;
+
+ switch (pref) {
+ case 0:
+ vt->audmode = V4L2_TUNER_MODE_MONO;
+ break;
+ case 1:
+ case 2:
+ vt->audmode = V4L2_TUNER_MODE_LANG2;
+ break;
+ case 4:
+ default:
+ vt->audmode = V4L2_TUNER_MODE_STEREO;
+ }
break;
}
case VIDIOC_S_TUNER:
- if (state->radio)
- break;
-
switch (vt->audmode) {
case V4L2_TUNER_MODE_MONO:
- /* mono -> mono
- stereo -> mono
- bilingual -> lang1 */
+ case V4L2_TUNER_MODE_LANG1:
+ /* Force PREF_MODE to MONO */
cx25840_and_or(client, 0x809, ~0xf, 0x00);
break;
case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang1 */
+ /* Force PREF_MODE to STEREO */
cx25840_and_or(client, 0x809, ~0xf, 0x04);
break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang1/lang2 */
- cx25840_and_or(client, 0x809, ~0xf, 0x07);
- break;
case V4L2_TUNER_MODE_LANG2:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang2 */
+ /* Force PREF_MODE to LANG2 */
cx25840_and_or(client, 0x809, ~0xf, 0x01);
break;
- default:
- return -EINVAL;
}
- state->audmode = vt->audmode;
break;
case VIDIOC_G_FMT:
state->aud_input = CX25840_AUDIO8;
state->audclk_freq = 48000;
state->pvr150_workaround = 0;
- state->audmode = V4L2_TUNER_MODE_LANG1;
cx25840_initialize(client, 1);