提交 a8bbf12a 编写于 作者: H Hans Verkuil 提交者: Mauro Carvalho Chehab

V4L/DVB (3249): Generalized cx25840 video/audio input handling


- Added VIDIOC_S_AUDIO to set the audio inputs separately.
- Removed AUDC_SET_INPUT.
- Made the video inputs much more general.
- Removed cardtype CID and replaced with a CID to enable
the PVR150 workaround. The cardtype is no longer necessary
with the general video input change.
- Update VIDIOC_LOG_STATUS output to show the video and
audio inputs separately.
Signed-off-by: NHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: NMauro Carvalho Chehab <mchehab@brturbo.com.br>
上级 3578d3dd
...@@ -37,8 +37,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) ...@@ -37,8 +37,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
cx25840_write(client, 0x127, 0x50); cx25840_write(client, 0x127, 0x50);
switch (state->audio_input) { if (state->aud_input != CX25840_AUDIO_SERIAL) {
case AUDIO_TUNER:
switch (freq) { switch (freq) {
case 32000: case 32000:
/* VID_PLL and AUX_PLL */ /* VID_PLL and AUX_PLL */
...@@ -79,12 +78,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) ...@@ -79,12 +78,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
cx25840_write4(client, 0x90c, 0xaa4f0108); cx25840_write4(client, 0x90c, 0xaa4f0108);
break; break;
} }
break; } else {
case AUDIO_EXTERN_1:
case AUDIO_EXTERN_2:
case AUDIO_INTERN:
case AUDIO_RADIO:
switch (freq) { switch (freq) {
case 32000: case 32000:
/* VID_PLL and AUX_PLL */ /* VID_PLL and AUX_PLL */
...@@ -137,7 +131,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) ...@@ -137,7 +131,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
cx25840_write4(client, 0x90c, 0x55550108); cx25840_write4(client, 0x90c, 0x55550108);
break; break;
} }
break;
} }
/* deassert soft reset */ /* deassert soft reset */
...@@ -148,48 +141,33 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) ...@@ -148,48 +141,33 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq)
return 0; return 0;
} }
static int set_input(struct i2c_client *client, int audio_input) void cx25840_audio_set_path(struct i2c_client *client)
{ {
struct cx25840_state *state = i2c_get_clientdata(client); struct cx25840_state *state = i2c_get_clientdata(client);
cx25840_dbg("set audio input (%d)\n", audio_input);
/* stop microcontroller */ /* stop microcontroller */
cx25840_and_or(client, 0x803, ~0x10, 0); cx25840_and_or(client, 0x803, ~0x10, 0);
/* Mute everything to prevent the PFFT! */ /* Mute everything to prevent the PFFT! */
cx25840_write(client, 0x8d3, 0x1f); cx25840_write(client, 0x8d3, 0x1f);
switch (audio_input) { if (state->aud_input == CX25840_AUDIO_SERIAL) {
case AUDIO_TUNER:
/* Set Path1 to Analog Demod Main Channel */
cx25840_write4(client, 0x8d0, 0x7038061f);
/* When the microcontroller detects the
* audio format, it will unmute the lines */
cx25840_and_or(client, 0x803, ~0x10, 0x10);
break;
case AUDIO_EXTERN_1:
case AUDIO_EXTERN_2:
case AUDIO_INTERN:
case AUDIO_RADIO:
/* Set Path1 to Serial Audio Input */ /* Set Path1 to Serial Audio Input */
cx25840_write4(client, 0x8d0, 0x12100101); cx25840_write4(client, 0x8d0, 0x12100101);
/* The microcontroller should not be started for the /* The microcontroller should not be started for the
* non-tuner inputs: autodetection is specific for * non-tuner inputs: autodetection is specific for
* TV audio. */ * TV audio. */
break; } else {
/* Set Path1 to Analog Demod Main Channel */
cx25840_write4(client, 0x8d0, 0x7038061f);
default: /* When the microcontroller detects the
cx25840_dbg("Invalid audio input selection %d\n", audio_input); * audio format, it will unmute the lines */
return -EINVAL; cx25840_and_or(client, 0x803, ~0x10, 0x10);
} }
state->audio_input = audio_input; set_audclk_freq(client, state->audclk_freq);
return set_audclk_freq(client, state->audclk_freq);
} }
inline static int get_volume(struct i2c_client *client) inline static int get_volume(struct i2c_client *client)
...@@ -292,7 +270,7 @@ inline static void set_mute(struct i2c_client *client, int mute) ...@@ -292,7 +270,7 @@ inline static void set_mute(struct i2c_client *client, int mute)
{ {
struct cx25840_state *state = i2c_get_clientdata(client); struct cx25840_state *state = i2c_get_clientdata(client);
if (state->audio_input == AUDIO_TUNER) { if (state->aud_input != CX25840_AUDIO_SERIAL) {
/* Must turn off microcontroller in order to mute sound. /* Must turn off microcontroller in order to mute sound.
* Not sure if this is the best method, but it does work. * Not sure if this is the best method, but it does work.
* If the microcontroller is running, then it will undo any * If the microcontroller is running, then it will undo any
...@@ -316,10 +294,9 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) ...@@ -316,10 +294,9 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
struct v4l2_control *ctrl = arg; struct v4l2_control *ctrl = arg;
switch (cmd) { switch (cmd) {
case AUDC_SET_INPUT:
return set_input(client, *(int *)arg);
case VIDIOC_INT_AUDIO_CLOCK_FREQ: case VIDIOC_INT_AUDIO_CLOCK_FREQ:
return set_audclk_freq(client, *(u32 *)arg); return set_audclk_freq(client, *(u32 *)arg);
case VIDIOC_G_CTRL: case VIDIOC_G_CTRL:
switch (ctrl->id) { switch (ctrl->id) {
case V4L2_CID_AUDIO_VOLUME: case V4L2_CID_AUDIO_VOLUME:
...@@ -341,6 +318,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) ...@@ -341,6 +318,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
return -EINVAL; return -EINVAL;
} }
break; break;
case VIDIOC_S_CTRL: case VIDIOC_S_CTRL:
switch (ctrl->id) { switch (ctrl->id) {
case V4L2_CID_AUDIO_VOLUME: case V4L2_CID_AUDIO_VOLUME:
...@@ -362,6 +340,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) ...@@ -362,6 +340,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
return -EINVAL; return -EINVAL;
} }
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
......
...@@ -115,8 +115,8 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask, ...@@ -115,8 +115,8 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask,
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
static int set_input(struct i2c_client *, enum cx25840_input); static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
static void input_change(struct i2c_client *); enum cx25840_audio_input aud_input);
static void log_status(struct i2c_client *client); static void log_status(struct i2c_client *client);
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
...@@ -195,10 +195,8 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw) ...@@ -195,10 +195,8 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw)
/* AC97 shift */ /* AC97 shift */
cx25840_write(client, 0x8cf, 0x0f); cx25840_write(client, 0x8cf, 0x0f);
/* (re)set video input */ /* (re)set input */
set_input(client, state->input); set_input(client, state->vid_input, state->aud_input);
/* (re)set audio input */
cx25840_audio(client, AUDC_SET_INPUT, &state->audio_input);
/* start microcontroller */ /* start microcontroller */
cx25840_and_or(client, 0x803, ~0x10, 0x10); cx25840_and_or(client, 0x803, ~0x10, 0x10);
...@@ -223,7 +221,7 @@ static void input_change(struct i2c_client *client) ...@@ -223,7 +221,7 @@ static void input_change(struct i2c_client *client)
cx25840_write(client, 0x80b, 0x10); cx25840_write(client, 0x80b, 0x10);
} else if (std & V4L2_STD_NTSC) { } else if (std & V4L2_STD_NTSC) {
/* NTSC */ /* NTSC */
if (state->cardtype == CARDTYPE_PVR150_WORKAROUND) { if (state->pvr150_workaround) {
/* Certain Hauppauge PVR150 models have a hardware bug /* Certain Hauppauge PVR150 models have a hardware bug
that causes audio to drop out. For these models the that causes audio to drop out. For these models the
audio standard must be set explicitly. audio standard must be set explicitly.
...@@ -259,72 +257,68 @@ static void input_change(struct i2c_client *client) ...@@ -259,72 +257,68 @@ static void input_change(struct i2c_client *client)
} }
} }
static int set_input(struct i2c_client *client, enum cx25840_input input) static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input,
enum cx25840_audio_input aud_input)
{ {
struct cx25840_state *state = i2c_get_clientdata(client); struct cx25840_state *state = i2c_get_clientdata(client);
u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&
vid_input <= CX25840_COMPOSITE8);
u8 reg;
cx25840_dbg("decoder set input (%d)\n", input); cx25840_dbg("decoder set video input %d, audio input %d\n",
vid_input, aud_input);
switch (input) { if (is_composite) {
case CX25840_TUNER: reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);
cx25840_dbg("now setting Tuner input\n"); } else {
int luma = vid_input & 0xf0;
if (state->cardtype == CARDTYPE_PVR150 || int chroma = vid_input & 0xf00;
state->cardtype == CARDTYPE_PVR150_WORKAROUND) {
/* CH_SEL_ADC2=1 */
cx25840_and_or(client, 0x102, ~0x2, 0x02);
}
/* Video Input Control */
if (state->cardtype == CARDTYPE_PG600) {
cx25840_write(client, 0x103, 0x11);
} else {
cx25840_write(client, 0x103, 0x46);
}
/* INPUT_MODE=0 */
cx25840_and_or(client, 0x401, ~0x6, 0x00);
break;
case CX25840_COMPOSITE0:
case CX25840_COMPOSITE1:
cx25840_dbg("now setting Composite input\n");
/* Video Input Control */ if ((vid_input & ~0xff0) ||
if (state->cardtype == CARDTYPE_PG600) { luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA4 ||
cx25840_write(client, 0x103, 0x00); chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
} else { cx25840_err("0x%04x is not a valid video input!\n", vid_input);
cx25840_write(client, 0x103, 0x02); return -EINVAL;
} }
reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4);
/* INPUT_MODE=0 */ if (chroma >= CX25840_SVIDEO_CHROMA7) {
cx25840_and_or(client, 0x401, ~0x6, 0x00); reg &= 0x3f;
break; reg |= (chroma - CX25840_SVIDEO_CHROMA7) >> 2;
case CX25840_SVIDEO0:
case CX25840_SVIDEO1:
cx25840_dbg("now setting S-Video input\n");
/* CH_SEL_ADC2=0 */
cx25840_and_or(client, 0x102, ~0x2, 0x00);
/* Video Input Control */
if (state->cardtype == CARDTYPE_PG600) {
cx25840_write(client, 0x103, 0x02);
} else { } else {
cx25840_write(client, 0x103, 0x10); reg &= 0xcf;
reg |= (chroma - CX25840_SVIDEO_CHROMA4) >> 4;
} }
}
/* INPUT_MODE=1 */ switch (aud_input) {
cx25840_and_or(client, 0x401, ~0x6, 0x02); case CX25840_AUDIO_SERIAL:
/* do nothing, use serial audio input */
break; break;
case CX25840_AUDIO4: reg &= ~0x30; break;
case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break;
case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break;
case CX25840_AUDIO7: reg &= ~0xc0; break;
case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
default: default:
cx25840_err("%d is not a valid input!\n", input); cx25840_err("0x%04x is not a valid audio input!\n", aud_input);
return -EINVAL; return -EINVAL;
} }
state->input = input; cx25840_write(client, 0x103, reg);
/* Set INPUT_MODE to Composite (0) or S-Video (1) */
cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);
/* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
/* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)
cx25840_and_or(client, 0x102, ~0x4, 4);
else
cx25840_and_or(client, 0x102, ~0x4, 0);
state->vid_input = vid_input;
state->aud_input = aud_input;
cx25840_audio_set_path(client);
input_change(client); input_change(client);
return 0; return 0;
} }
...@@ -395,18 +389,9 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) ...@@ -395,18 +389,9 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
struct cx25840_state *state = i2c_get_clientdata(client); struct cx25840_state *state = i2c_get_clientdata(client);
switch (ctrl->id) { switch (ctrl->id) {
case CX25840_CID_CARDTYPE: case CX25840_CID_ENABLE_PVR150_WORKAROUND:
switch (ctrl->value) { state->pvr150_workaround = ctrl->value;
case CARDTYPE_PVR150: set_input(client, state->vid_input, state->aud_input);
case CARDTYPE_PVR150_WORKAROUND:
case CARDTYPE_PG600:
state->cardtype = ctrl->value;
break;
default:
return -ERANGE;
}
set_input(client, state->input);
break; break;
case V4L2_CID_BRIGHTNESS: case V4L2_CID_BRIGHTNESS:
...@@ -465,8 +450,8 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) ...@@ -465,8 +450,8 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
struct cx25840_state *state = i2c_get_clientdata(client); struct cx25840_state *state = i2c_get_clientdata(client);
switch (ctrl->id) { switch (ctrl->id) {
case CX25840_CID_CARDTYPE: case CX25840_CID_ENABLE_PVR150_WORKAROUND:
ctrl->value = state->cardtype; ctrl->value = state->pvr150_workaround;
break; break;
case V4L2_CID_BRIGHTNESS: case V4L2_CID_BRIGHTNESS:
ctrl->value = cx25840_read(client, 0x414) + 128; ctrl->value = cx25840_read(client, 0x414) + 128;
...@@ -615,7 +600,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, ...@@ -615,7 +600,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
return cx25840_vbi(client, cmd, arg); return cx25840_vbi(client, cmd, arg);
case VIDIOC_INT_AUDIO_CLOCK_FREQ: case VIDIOC_INT_AUDIO_CLOCK_FREQ:
case AUDC_SET_INPUT:
result = cx25840_audio(client, cmd, arg); result = cx25840_audio(client, cmd, arg);
break; break;
...@@ -652,13 +636,30 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, ...@@ -652,13 +636,30 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
break; break;
case VIDIOC_G_INPUT: case VIDIOC_G_INPUT:
*(int *)arg = state->input; *(int *)arg = state->vid_input;
break; break;
case VIDIOC_S_INPUT: case VIDIOC_S_INPUT:
result = set_input(client, *(int *)arg); result = set_input(client, *(enum cx25840_video_input *)arg, state->aud_input);
break; break;
case VIDIOC_S_AUDIO:
{
struct v4l2_audio *input = arg;
result = set_input(client, state->vid_input, input->index);
break;
}
case VIDIOC_G_AUDIO:
{
struct v4l2_audio *input = arg;
memset(input, 0, sizeof(*input));
input->index = state->aud_input;
break;
}
case VIDIOC_S_FREQUENCY: case VIDIOC_S_FREQUENCY:
input_change(client); input_change(client);
break; break;
...@@ -801,10 +802,10 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, ...@@ -801,10 +802,10 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
i2c_set_clientdata(client, state); i2c_set_clientdata(client, state);
memset(state, 0, sizeof(struct cx25840_state)); memset(state, 0, sizeof(struct cx25840_state));
state->input = CX25840_TUNER; state->vid_input = CX25840_COMPOSITE7;
state->aud_input = CX25840_AUDIO8;
state->audclk_freq = 48000; state->audclk_freq = 48000;
state->audio_input = AUDIO_TUNER; state->pvr150_workaround = 0;
state->cardtype = CARDTYPE_PVR150;
cx25840_initialize(client, 1); cx25840_initialize(client, 1);
...@@ -888,6 +889,8 @@ static void log_status(struct i2c_client *client) ...@@ -888,6 +889,8 @@ static void log_status(struct i2c_client *client)
u8 pref_mode = cx25840_read(client, 0x809); u8 pref_mode = cx25840_read(client, 0x809);
u8 afc0 = cx25840_read(client, 0x80b); u8 afc0 = cx25840_read(client, 0x80b);
u8 mute_ctl = cx25840_read(client, 0x8d3); u8 mute_ctl = cx25840_read(client, 0x8d3);
int vid_input = state->vid_input;
int aud_input = state->aud_input;
char *p; char *p;
cx25840_info("Video signal: %spresent\n", cx25840_info("Video signal: %spresent\n",
...@@ -997,16 +1000,19 @@ static void log_status(struct i2c_client *client) ...@@ -997,16 +1000,19 @@ static void log_status(struct i2c_client *client)
cx25840_info("Specified standard: %s\n", cx25840_info("Specified standard: %s\n",
vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
switch (state->input) { if (vid_input >= CX25840_COMPOSITE1 &&
case CX25840_COMPOSITE0: p = "Composite 0"; break; vid_input <= CX25840_COMPOSITE8) {
case CX25840_COMPOSITE1: p = "Composite 1"; break; cx25840_info("Specified video input: Composite %d\n",
case CX25840_SVIDEO0: p = "S-Video 0"; break; vid_input - CX25840_COMPOSITE1 + 1);
case CX25840_SVIDEO1: p = "S-Video 1"; break; } else {
case CX25840_TUNER: p = "Tuner"; break; cx25840_info("Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
(vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
}
if (aud_input) {
cx25840_info("Specified audio input: Tuner (In%d)\n", aud_input);
} else {
cx25840_info("Specified audio input: External\n");
} }
cx25840_info("Specified input: %s\n", p);
cx25840_info("Specified audio input: %s\n",
state->audio_input == 0 ? "Tuner" : "External");
cx25840_info("Specified audioclock freq: %d Hz\n", state->audclk_freq); cx25840_info("Specified audioclock freq: %d Hz\n", state->audclk_freq);
......
...@@ -39,32 +39,58 @@ extern int cx25840_debug; ...@@ -39,32 +39,58 @@ extern int cx25840_debug;
printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
#define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0) /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is
present in Hauppauge PVR-150 (and possibly PVR-500) cards that have
/* The CARDTYPE_PVR150_WORKAROUND cardtype activates a workaround for a certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The
hardware bug that is present in PVR150 (and possible PVR500) cards that
have certain NTSC tuners (tveeprom model numbers 85, 99 and 112). The
audio autodetect fails on some channels for these models and the workaround audio autodetect fails on some channels for these models and the workaround
is to select the audio standard explicitly. Many thanks to Hauppauge for is to select the audio standard explicitly. Many thanks to Hauppauge for
providing this information. */ providing this information. */
enum cx25840_cardtype { #define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0)
CARDTYPE_PVR150,
CARDTYPE_PG600, enum cx25840_video_input {
CARDTYPE_PVR150_WORKAROUND, /* Composite video inputs In1-In8 */
CX25840_COMPOSITE1 = 1,
CX25840_COMPOSITE2,
CX25840_COMPOSITE3,
CX25840_COMPOSITE4,
CX25840_COMPOSITE5,
CX25840_COMPOSITE6,
CX25840_COMPOSITE7,
CX25840_COMPOSITE8,
/* S-Video inputs consist of one luma input (In1-In4) ORed with one
chroma input (In5-In8) */
CX25840_SVIDEO_LUMA1 = 0x10,
CX25840_SVIDEO_LUMA2 = 0x20,
CX25840_SVIDEO_LUMA3 = 0x30,
CX25840_SVIDEO_LUMA4 = 0x40,
CX25840_SVIDEO_CHROMA4 = 0x400,
CX25840_SVIDEO_CHROMA5 = 0x500,
CX25840_SVIDEO_CHROMA6 = 0x600,
CX25840_SVIDEO_CHROMA7 = 0x700,
CX25840_SVIDEO_CHROMA8 = 0x800,
/* S-Video aliases for common luma/chroma combinations */
CX25840_SVIDEO1 = 0x510,
CX25840_SVIDEO2 = 0x620,
CX25840_SVIDEO3 = 0x730,
CX25840_SVIDEO4 = 0x840,
}; };
enum cx25840_input { enum cx25840_audio_input {
CX25840_TUNER, /* Audio inputs: serial or In4-In8 */
CX25840_COMPOSITE0, CX25840_AUDIO_SERIAL,
CX25840_COMPOSITE1, CX25840_AUDIO4 = 4,
CX25840_SVIDEO0, CX25840_AUDIO5,
CX25840_SVIDEO1 CX25840_AUDIO6,
CX25840_AUDIO7,
CX25840_AUDIO8,
}; };
struct cx25840_state { struct cx25840_state {
enum cx25840_cardtype cardtype; int pvr150_workaround;
enum cx25840_input input; enum cx25840_video_input vid_input;
int audio_input; enum cx25840_audio_input aud_input;
u32 audclk_freq; u32 audclk_freq;
}; };
...@@ -84,6 +110,7 @@ int cx25840_loadfw(struct i2c_client *client); ...@@ -84,6 +110,7 @@ int cx25840_loadfw(struct i2c_client *client);
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* cx25850-audio.c */ /* cx25850-audio.c */
int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg); int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg);
void cx25840_audio_set_path(struct i2c_client *client);
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* cx25850-vbi.c */ /* cx25850-vbi.c */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册