static void input_change(struct i2c_client *client)
{
struct cx25840_state *state = i2c_get_clientdata(client);
- v4l2_std_id std = cx25840_get_v4lstd(client);
+ v4l2_std_id std = state->std;
/* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */
if (std & V4L2_STD_SECAM) {
/* ----------------------------------------------------------------------- */
-static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
+static int set_v4lstd(struct i2c_client *client)
{
- u8 fmt=0; /* zero is autodetect */
+ struct cx25840_state *state = i2c_get_clientdata(client);
+ u8 fmt = 0; /* zero is autodetect */
+ u8 pal_m = 0;
/* First tests should be against specific std */
- if (std == V4L2_STD_NTSC_M_JP) {
- fmt=0x2;
- } else if (std == V4L2_STD_NTSC_443) {
- fmt=0x3;
- } else if (std == V4L2_STD_PAL_M) {
- fmt=0x5;
- } else if (std == V4L2_STD_PAL_N) {
- fmt=0x6;
- } else if (std == V4L2_STD_PAL_Nc) {
- fmt=0x7;
- } else if (std == V4L2_STD_PAL_60) {
- fmt=0x8;
+ if (state->std == V4L2_STD_NTSC_M_JP) {
+ fmt = 0x2;
+ } else if (state->std == V4L2_STD_NTSC_443) {
+ fmt = 0x3;
+ } else if (state->std == V4L2_STD_PAL_M) {
+ pal_m = 1;
+ fmt = 0x5;
+ } else if (state->std == V4L2_STD_PAL_N) {
+ fmt = 0x6;
+ } else if (state->std == V4L2_STD_PAL_Nc) {
+ fmt = 0x7;
+ } else if (state->std == V4L2_STD_PAL_60) {
+ fmt = 0x8;
} else {
/* Then, test against generic ones */
- if (std & V4L2_STD_NTSC) {
- fmt=0x1;
- } else if (std & V4L2_STD_PAL) {
- fmt=0x4;
- } else if (std & V4L2_STD_SECAM) {
- fmt=0xc;
- }
+ if (state->std & V4L2_STD_NTSC)
+ fmt = 0x1;
+ else if (state->std & V4L2_STD_PAL)
+ fmt = 0x4;
+ else if (state->std & V4L2_STD_SECAM)
+ fmt = 0xc;
}
v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt);
cx25840_and_or(client, 0x47b, ~6, 0);
}
cx25840_and_or(client, 0x400, ~0xf, fmt);
+ cx25840_and_or(client, 0x403, ~0x3, pal_m);
cx25840_vbi_setup(client);
+ if (!state->is_cx25836)
+ input_change(client);
return 0;
}
-v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
-{
- struct cx25840_state *state = i2c_get_clientdata(client);
- /* check VID_FMT_SEL first */
- u8 fmt = cx25840_read(client, 0x400) & 0xf;
-
- if (!fmt) {
- /* check AFD_FMT_STAT if set to autodetect */
- fmt = cx25840_read(client, 0x40d) & 0xf;
- }
-
- switch (fmt) {
- case 0x1:
- {
- /* if the audio std is A2-M, then this is the South Korean
- NTSC standard */
- if (!state->is_cx25836 && cx25840_read(client, 0x805) == 2)
- return V4L2_STD_NTSC_M_KR;
- return V4L2_STD_NTSC_M;
- }
- case 0x2: return V4L2_STD_NTSC_M_JP;
- case 0x3: return V4L2_STD_NTSC_443;
- case 0x4: return V4L2_STD_PAL;
- case 0x5: return V4L2_STD_PAL_M;
- case 0x6: return V4L2_STD_PAL_N;
- case 0x7: return V4L2_STD_PAL_Nc;
- case 0x8: return V4L2_STD_PAL_60;
- case 0xc: return V4L2_STD_SECAM;
- default: return V4L2_STD_UNKNOWN;
- }
-}
-
/* ----------------------------------------------------------------------- */
static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
{
+ struct cx25840_state *state = i2c_get_clientdata(client);
struct v4l2_pix_format *pix;
int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
- int is_50Hz = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60);
+ int is_50Hz = !(state->std & V4L2_STD_525_60);
switch (fmt->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
}
case VIDIOC_G_STD:
- *(v4l2_std_id *)arg = cx25840_get_v4lstd(client);
+ *(v4l2_std_id *)arg = state->std;
break;
case VIDIOC_S_STD:
+ if (state->radio == 0 && state->std == *(v4l2_std_id *)arg)
+ return 0;
state->radio = 0;
- return set_v4lstd(client, *(v4l2_std_id *)arg);
+ state->std = *(v4l2_std_id *)arg;
+ return set_v4lstd(client);
case AUDC_SET_RADIO:
state->radio = 1;
void cx25840_vbi_setup(struct i2c_client *client)
{
struct cx25840_state *state = i2c_get_clientdata(client);
- v4l2_std_id std = cx25840_get_v4lstd(client);
+ v4l2_std_id std = state->std;
int hblank,hactive,burst,vblank,vactive,sc,vblank656,src_decimation;
int luma_lpf,uv_lpf, comb;
u32 pll_int,pll_frac,pll_post;
0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
0, 0, 0, 0
};
- int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60);
+ int is_pal = !(state->std & V4L2_STD_525_60);
int i;
fmt = arg;
case VIDIOC_S_FMT:
{
- int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_525_60);
+ int is_pal = !(state->std & V4L2_STD_525_60);
int vbi_offset = is_pal ? 1 : 0;
int i, x;
u8 lcr[24];