X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fvideo%2Fcx25840%2Fcx25840-core.c;fp=drivers%2Fmedia%2Fvideo%2Fcx25840%2Fcx25840-core.c;h=5588b9a5c4304c795c5036acd232dca0747b7347;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=7bb7589a07c30719f7796e78081d01cc0e878ee7;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 7bb7589a0..5588b9a5c 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -10,9 +10,6 @@ * * VBI support by Hans Verkuil . * - * NTSC sliced VBI support by Christopher Neufeld - * with additional fixes by Hans Verkuil . - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 @@ -34,10 +31,10 @@ #include #include #include +#include #include -#include -#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"); @@ -46,7 +43,7 @@ MODULE_LICENSE("GPL"); static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; -int cx25840_debug; +static int cx25840_debug; module_param_named(debug,cx25840_debug, int, 0644); @@ -104,11 +101,11 @@ u32 cx25840_read4(struct i2c_client * client, u16 addr) if (i2c_master_recv(client, buffer, 4) < 4) return 0; - return (buffer[3] << 24) | (buffer[2] << 16) | - (buffer[1] << 8) | buffer[0]; + return (buffer[0] << 24) | (buffer[1] << 16) | + (buffer[2] << 8) | buffer[3]; } -int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned and_mask, +int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask, u8 or_value) { return cx25840_write(client, addr, @@ -120,8 +117,7 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned and_mask, static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, enum cx25840_audio_input aud_input); -static void log_audio_status(struct i2c_client *client); -static void log_video_status(struct i2c_client *client); +static void log_status(struct i2c_client *client); /* ----------------------------------------------------------------------- */ @@ -151,33 +147,6 @@ static void init_dll2(struct i2c_client *client) cx25840_write(client, 0x15d, 0xe1); } -static void cx25836_initialize(struct i2c_client *client) -{ - /* reset configuration is described on page 3-77 of the CX25836 datasheet */ - /* 2. */ - cx25840_and_or(client, 0x000, ~0x01, 0x01); - cx25840_and_or(client, 0x000, ~0x01, 0x00); - /* 3a. */ - cx25840_and_or(client, 0x15a, ~0x70, 0x00); - /* 3b. */ - cx25840_and_or(client, 0x15b, ~0x1e, 0x06); - /* 3c. */ - cx25840_and_or(client, 0x159, ~0x02, 0x02); - /* 3d. */ - /* There should be a 10-us delay here, but since the - i2c bus already has a 10-us delay we don't need to do - anything */ - /* 3e. */ - cx25840_and_or(client, 0x159, ~0x02, 0x00); - /* 3f. */ - cx25840_and_or(client, 0x159, ~0xc0, 0xc0); - /* 3g. */ - cx25840_and_or(client, 0x159, ~0x01, 0x00); - cx25840_and_or(client, 0x159, ~0x01, 0x01); - /* 3h. */ - cx25840_and_or(client, 0x15b, ~0x1e, 0x10); -} - static void cx25840_initialize(struct i2c_client *client, int loadfw) { struct cx25840_state *state = i2c_get_clientdata(client); @@ -207,9 +176,9 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw) 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); @@ -240,18 +209,17 @@ static void input_change(struct i2c_client *client) 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); - - if (std & V4L2_STD_525_60) { + /* 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 tuner change procedure for PAL */ + cx25840_write(client, 0x808, 0xff); + cx25840_write(client, 0x80b, 0x10); + } else if (std & V4L2_STD_SECAM) { + /* Select autodetect for SECAM */ + cx25840_write(client, 0x808, 0xff); + cx25840_write(client, 0x80b, 0x10); + } else if (std & V4L2_STD_NTSC) { /* Certain Hauppauge PVR150 models have a hardware bug that causes audio to drop out. For these models the audio standard must be set explicitly. @@ -270,14 +238,6 @@ static void input_change(struct i2c_client *client) cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6); } cx25840_write(client, 0x80b, 0x00); - } else if (std & V4L2_STD_PAL) { - /* Follow tuner change procedure for PAL */ - cx25840_write(client, 0x808, 0xff); - cx25840_write(client, 0x80b, 0x10); - } else if (std & V4L2_STD_SECAM) { - /* Select autodetect for SECAM */ - cx25840_write(client, 0x808, 0xff); - cx25840_write(client, 0x80b, 0x10); } if (cx25840_read(client, 0x803) & 0x10) { @@ -348,10 +308,8 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp state->vid_input = vid_input; state->aud_input = aud_input; - if (!state->is_cx25836) { - cx25840_audio_set_path(client); - input_change(client); - } + cx25840_audio_set_path(client); + input_change(client); return 0; } @@ -385,17 +343,6 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) } } - v4l_dbg(1, cx25840_debug, client, "changing video std to fmt %i\n",fmt); - - /* 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; @@ -403,7 +350,6 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) 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; @@ -413,14 +359,7 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) } 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 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; @@ -490,8 +429,6 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_TREBLE: case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_MUTE: - if (state->is_cx25836) - return -EINVAL; return cx25840_audio(client, VIDIOC_S_CTRL, ctrl); default: @@ -526,8 +463,6 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_TREBLE: case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_MUTE: - if (state->is_cx25836) - return -EINVAL; return cx25840_audio(client, VIDIOC_G_CTRL, ctrl); default: return -EINVAL; @@ -617,12 +552,96 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) /* ----------------------------------------------------------------------- */ +static struct v4l2_queryctrl cx25840_qctrl[] = { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 128, + .flags = 0, + }, { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 64, + .flags = 0, + }, { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 64, + .flags = 0, + }, { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = -128, + .maximum = 127, + .step = 1, + .default_value = 0, + .flags = 0, + }, { + .id = V4L2_CID_AUDIO_VOLUME, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Volume", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 58880, + .flags = 0, + }, { + .id = V4L2_CID_AUDIO_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Balance", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 32768, + .flags = 0, + }, { + .id = V4L2_CID_AUDIO_MUTE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + .flags = 0, + }, { + .id = V4L2_CID_AUDIO_BASS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Bass", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 32768, + }, { + .id = V4L2_CID_AUDIO_TREBLE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Treble", + .minimum = 0, + .maximum = 65535, + .step = 65535/100, + .default_value = 32768, + }, +}; + +/* ----------------------------------------------------------------------- */ + static int cx25840_command(struct i2c_client *client, unsigned int cmd, void *arg) { 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 @@ -659,8 +678,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, case VIDIOC_STREAMON: v4l_dbg(1, cx25840_debug, client, "enable output\n"); - cx25840_write(client, 0x115, state->is_cx25836 ? 0x0c : 0x8c); - cx25840_write(client, 0x116, state->is_cx25836 ? 0x04 : 0x07); + cx25840_write(client, 0x115, 0x8c); + cx25840_write(client, 0x116, 0x07); break; case VIDIOC_STREAMOFF: @@ -670,9 +689,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, break; case VIDIOC_LOG_STATUS: - log_video_status(client); - if (!state->is_cx25836) - log_audio_status(client); + log_status(client); break; case VIDIOC_G_CTRL: @@ -684,29 +701,13 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, case VIDIOC_QUERYCTRL: { struct v4l2_queryctrl *qc = arg; + int i; - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill_std(qc); - default: - break; - } - if (state->is_cx25836) - return -EINVAL; - - switch (qc->id) { - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill_std(qc); - default: - return -EINVAL; - } + for (i = 0; i < ARRAY_SIZE(cx25840_qctrl); i++) + if (qc->id && qc->id == cx25840_qctrl[i].id) { + memcpy(qc, &cx25840_qctrl[i], sizeof(*qc)); + return 0; + } return -EINVAL; } @@ -722,50 +723,48 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, 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: - if (state->is_cx25836) - return -EINVAL; - route->input = state->aud_input; - route->output = 0; - break; + case VIDIOC_S_AUDIO: + { + struct v4l2_audio *input = arg; - case VIDIOC_INT_S_AUDIO_ROUTING: - if (state->is_cx25836) - return -EINVAL; - return set_input(client, state->vid_input, route->input); + return set_input(client, state->vid_input, input->index); + } + + case VIDIOC_G_AUDIO: + { + struct v4l2_audio *input = arg; + + memset(input, 0, sizeof(*input)); + input->index = state->aud_input; + break; + } case VIDIOC_S_FREQUENCY: - if (!state->is_cx25836) { - input_change(client); - } + input_change(client); break; case VIDIOC_G_TUNER: { - u8 vpres = cx25840_read(client, 0x40e) & 0x20; - u8 mode; + u8 mode = cx25840_read(client, 0x804); + u8 pref = cx25840_read(client, 0x809) & 0xf; + u8 vpres = cx25840_read(client, 0x80a) & 0x10; int val = 0; if (state->radio) break; - vt->signal = vpres ? 0xffff : 0x0; - if (state->is_cx25836) - break; - vt->capability |= V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; - mode = cx25840_read(client, 0x804); + vt->signal = vpres ? 0xffff : 0x0; /* get rxsubchans and audmode */ if ((mode & 0xf) == 1) @@ -774,50 +773,44 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, 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 || state->is_cx25836) - 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: @@ -827,14 +820,12 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, return set_v4lfmt(client, (struct v4l2_format *)arg); case VIDIOC_INT_RESET: - if (state->is_cx25836) - cx25836_initialize(client); - else - cx25840_initialize(client, 0); + cx25840_initialize(client, 0); break; case VIDIOC_INT_G_CHIP_IDENT: - *(enum v4l2_chip_ident *)arg = state->id; + *(enum v4l2_chip_ident *)arg = + V4L2_IDENT_CX25840 + ((cx25840_read(client, 0x100) >> 4) & 0xf); break; default: @@ -853,7 +844,6 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, { struct i2c_client *client; struct cx25840_state *state; - enum v4l2_chip_ident id; u16 device_id; /* Check if the adapter supports the needed features @@ -862,11 +852,10 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) return 0; - state = kzalloc(sizeof(struct cx25840_state), GFP_KERNEL); - if (state == 0) + client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (client == 0) return -ENOMEM; - client = &state->c; client->addr = address; client->adapter = adapter; client->driver = &i2c_driver_cx25840; @@ -878,18 +867,10 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, device_id |= cx25840_read(client, 0x100); /* The high byte of the device ID should be - * 0x83 for the cx2583x and 0x84 for the cx2584x */ - if ((device_id & 0xff00) == 0x8300) { - id = V4L2_IDENT_CX25836 + ((device_id >> 4) & 0xf) - 6; - state->is_cx25836 = 1; - } - else if ((device_id & 0xff00) == 0x8400) { - id = V4L2_IDENT_CX25840 + ((device_id >> 4) & 0xf); - state->is_cx25836 = 0; - } - else { + * 0x84 if chip is present */ + if ((device_id & 0xff00) != 0x8400) { v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n"); - kfree(state); + kfree(client); return 0; } @@ -898,19 +879,20 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3, address << 1, adapter->name); + state = kmalloc(sizeof(struct cx25840_state), GFP_KERNEL); + if (state == NULL) { + kfree(client); + return -ENOMEM; + } + i2c_set_clientdata(client, state); + memset(state, 0, sizeof(struct cx25840_state)); state->vid_input = CX25840_COMPOSITE7; state->aud_input = CX25840_AUDIO8; state->audclk_freq = 48000; state->pvr150_workaround = 0; - state->audmode = V4L2_TUNER_MODE_LANG1; - state->vbi_line_offset = 8; - state->id = id; - if (state->is_cx25836) - cx25836_initialize(client); - else - cx25840_initialize(client, 1); + cx25840_initialize(client, 1); i2c_attach_client(client); @@ -935,6 +917,7 @@ static int cx25840_detach_client(struct i2c_client *client) } kfree(state); + kfree(client); return 0; } @@ -967,7 +950,7 @@ module_exit(m__exit); /* ----------------------------------------------------------------------- */ -static void log_video_status(struct i2c_client *client) +static void log_status(struct i2c_client *client) { static const char *const fmt_strs[] = { "0x0", @@ -979,36 +962,9 @@ static void log_video_status(struct i2c_client *client) }; struct cx25840_state *state = i2c_get_clientdata(client); + u8 microctrl_vidfmt = cx25840_read(client, 0x80a); u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf; u8 gen_stat1 = cx25840_read(client, 0x40d); - u8 gen_stat2 = cx25840_read(client, 0x40e); - int vid_input = state->vid_input; - - v4l_info(client, "Video signal: %spresent\n", - (gen_stat2 & 0x20) ? "" : "not "); - v4l_info(client, "Detected format: %s\n", - fmt_strs[gen_stat1 & 0xf]); - - v4l_info(client, "Specified standard: %s\n", - vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); - - if (vid_input >= CX25840_COMPOSITE1 && - vid_input <= CX25840_COMPOSITE8) { - v4l_info(client, "Specified video input: Composite %d\n", - vid_input - CX25840_COMPOSITE1 + 1); - } else { - v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n", - (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); - } - - v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq); -} - -/* ----------------------------------------------------------------------- */ - -static void log_audio_status(struct i2c_client *client) -{ - struct cx25840_state *state = i2c_get_clientdata(client); u8 download_ctl = cx25840_read(client, 0x803); u8 mod_det_stat0 = cx25840_read(client, 0x804); u8 mod_det_stat1 = cx25840_read(client, 0x805); @@ -1016,9 +972,15 @@ static void log_audio_status(struct i2c_client *client) u8 pref_mode = cx25840_read(client, 0x809); u8 afc0 = cx25840_read(client, 0x80b); u8 mute_ctl = cx25840_read(client, 0x8d3); + int vid_input = state->vid_input; int aud_input = state->aud_input; char *p; + v4l_info(client, "Video signal: %spresent\n", + (microctrl_vidfmt & 0x10) ? "" : "not "); + v4l_info(client, "Detected format: %s\n", + fmt_strs[gen_stat1 & 0xf]); + switch (mod_det_stat0) { case 0x00: p = "mono"; break; case 0x01: p = "stereo"; break; @@ -1118,12 +1080,25 @@ static void log_audio_status(struct i2c_client *client) v4l_info(client, "Configured audio system: %s\n", p); } + v4l_info(client, "Specified standard: %s\n", + vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); + + if (vid_input >= CX25840_COMPOSITE1 && + vid_input <= CX25840_COMPOSITE8) { + v4l_info(client, "Specified video input: Composite %d\n", + vid_input - CX25840_COMPOSITE1 + 1); + } else { + v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n", + (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); + } if (aud_input) { v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input); } else { v4l_info(client, "Specified audio input: External\n"); } + v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq); + switch (pref_mode & 0xf) { case 0: p = "mono/language A"; break; case 1: p = "language B"; break;