diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2006-01-09 12:25:42 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 2006-01-09 12:25:42 -0500 |
commit | a8bbf12ad8a8ad532cea0b67f0127ad90d336b04 (patch) | |
tree | bd8d9fb0888a7fe28b4795d7567c01ccf72b3c38 /drivers/media/video/cx25840 | |
parent | 3578d3dd0b1e468a44a76a83efe90476a854625d (diff) |
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: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Diffstat (limited to 'drivers/media/video/cx25840')
-rw-r--r-- | drivers/media/video/cx25840/cx25840-audio.c | 51 | ||||
-rw-r--r-- | drivers/media/video/cx25840/cx25840-core.c | 180 | ||||
-rw-r--r-- | drivers/media/video/cx25840/cx25840.h | 63 |
3 files changed, 153 insertions, 141 deletions
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c index 6c44bd9c1704..fe6bc411d71f 100644 --- a/drivers/media/video/cx25840/cx25840-audio.c +++ b/drivers/media/video/cx25840/cx25840-audio.c | |||
@@ -37,8 +37,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
37 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ | 37 | /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ |
38 | cx25840_write(client, 0x127, 0x50); | 38 | cx25840_write(client, 0x127, 0x50); |
39 | 39 | ||
40 | switch (state->audio_input) { | 40 | if (state->aud_input != CX25840_AUDIO_SERIAL) { |
41 | case AUDIO_TUNER: | ||
42 | switch (freq) { | 41 | switch (freq) { |
43 | case 32000: | 42 | case 32000: |
44 | /* VID_PLL and AUX_PLL */ | 43 | /* VID_PLL and AUX_PLL */ |
@@ -79,12 +78,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
79 | cx25840_write4(client, 0x90c, 0xaa4f0108); | 78 | cx25840_write4(client, 0x90c, 0xaa4f0108); |
80 | break; | 79 | break; |
81 | } | 80 | } |
82 | break; | 81 | } else { |
83 | |||
84 | case AUDIO_EXTERN_1: | ||
85 | case AUDIO_EXTERN_2: | ||
86 | case AUDIO_INTERN: | ||
87 | case AUDIO_RADIO: | ||
88 | switch (freq) { | 82 | switch (freq) { |
89 | case 32000: | 83 | case 32000: |
90 | /* VID_PLL and AUX_PLL */ | 84 | /* VID_PLL and AUX_PLL */ |
@@ -137,7 +131,6 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
137 | cx25840_write4(client, 0x90c, 0x55550108); | 131 | cx25840_write4(client, 0x90c, 0x55550108); |
138 | break; | 132 | break; |
139 | } | 133 | } |
140 | break; | ||
141 | } | 134 | } |
142 | 135 | ||
143 | /* deassert soft reset */ | 136 | /* deassert soft reset */ |
@@ -148,48 +141,33 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) | |||
148 | return 0; | 141 | return 0; |
149 | } | 142 | } |
150 | 143 | ||
151 | static int set_input(struct i2c_client *client, int audio_input) | 144 | void cx25840_audio_set_path(struct i2c_client *client) |
152 | { | 145 | { |
153 | struct cx25840_state *state = i2c_get_clientdata(client); | 146 | struct cx25840_state *state = i2c_get_clientdata(client); |
154 | 147 | ||
155 | cx25840_dbg("set audio input (%d)\n", audio_input); | ||
156 | |||
157 | /* stop microcontroller */ | 148 | /* stop microcontroller */ |
158 | cx25840_and_or(client, 0x803, ~0x10, 0); | 149 | cx25840_and_or(client, 0x803, ~0x10, 0); |
159 | 150 | ||
160 | /* Mute everything to prevent the PFFT! */ | 151 | /* Mute everything to prevent the PFFT! */ |
161 | cx25840_write(client, 0x8d3, 0x1f); | 152 | cx25840_write(client, 0x8d3, 0x1f); |
162 | 153 | ||
163 | switch (audio_input) { | 154 | if (state->aud_input == CX25840_AUDIO_SERIAL) { |
164 | case AUDIO_TUNER: | ||
165 | /* Set Path1 to Analog Demod Main Channel */ | ||
166 | cx25840_write4(client, 0x8d0, 0x7038061f); | ||
167 | |||
168 | /* When the microcontroller detects the | ||
169 | * audio format, it will unmute the lines */ | ||
170 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | ||
171 | break; | ||
172 | |||
173 | case AUDIO_EXTERN_1: | ||
174 | case AUDIO_EXTERN_2: | ||
175 | case AUDIO_INTERN: | ||
176 | case AUDIO_RADIO: | ||
177 | /* Set Path1 to Serial Audio Input */ | 155 | /* Set Path1 to Serial Audio Input */ |
178 | cx25840_write4(client, 0x8d0, 0x12100101); | 156 | cx25840_write4(client, 0x8d0, 0x12100101); |
179 | 157 | ||
180 | /* The microcontroller should not be started for the | 158 | /* The microcontroller should not be started for the |
181 | * non-tuner inputs: autodetection is specific for | 159 | * non-tuner inputs: autodetection is specific for |
182 | * TV audio. */ | 160 | * TV audio. */ |
183 | break; | 161 | } else { |
162 | /* Set Path1 to Analog Demod Main Channel */ | ||
163 | cx25840_write4(client, 0x8d0, 0x7038061f); | ||
184 | 164 | ||
185 | default: | 165 | /* When the microcontroller detects the |
186 | cx25840_dbg("Invalid audio input selection %d\n", audio_input); | 166 | * audio format, it will unmute the lines */ |
187 | return -EINVAL; | 167 | cx25840_and_or(client, 0x803, ~0x10, 0x10); |
188 | } | 168 | } |
189 | 169 | ||
190 | state->audio_input = audio_input; | 170 | set_audclk_freq(client, state->audclk_freq); |
191 | |||
192 | return set_audclk_freq(client, state->audclk_freq); | ||
193 | } | 171 | } |
194 | 172 | ||
195 | inline static int get_volume(struct i2c_client *client) | 173 | 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 | { | 270 | { |
293 | struct cx25840_state *state = i2c_get_clientdata(client); | 271 | struct cx25840_state *state = i2c_get_clientdata(client); |
294 | 272 | ||
295 | if (state->audio_input == AUDIO_TUNER) { | 273 | if (state->aud_input != CX25840_AUDIO_SERIAL) { |
296 | /* Must turn off microcontroller in order to mute sound. | 274 | /* Must turn off microcontroller in order to mute sound. |
297 | * Not sure if this is the best method, but it does work. | 275 | * Not sure if this is the best method, but it does work. |
298 | * If the microcontroller is running, then it will undo any | 276 | * 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 | struct v4l2_control *ctrl = arg; | 294 | struct v4l2_control *ctrl = arg; |
317 | 295 | ||
318 | switch (cmd) { | 296 | switch (cmd) { |
319 | case AUDC_SET_INPUT: | ||
320 | return set_input(client, *(int *)arg); | ||
321 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | 297 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: |
322 | return set_audclk_freq(client, *(u32 *)arg); | 298 | return set_audclk_freq(client, *(u32 *)arg); |
299 | |||
323 | case VIDIOC_G_CTRL: | 300 | case VIDIOC_G_CTRL: |
324 | switch (ctrl->id) { | 301 | switch (ctrl->id) { |
325 | case V4L2_CID_AUDIO_VOLUME: | 302 | case V4L2_CID_AUDIO_VOLUME: |
@@ -341,6 +318,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) | |||
341 | return -EINVAL; | 318 | return -EINVAL; |
342 | } | 319 | } |
343 | break; | 320 | break; |
321 | |||
344 | case VIDIOC_S_CTRL: | 322 | case VIDIOC_S_CTRL: |
345 | switch (ctrl->id) { | 323 | switch (ctrl->id) { |
346 | case V4L2_CID_AUDIO_VOLUME: | 324 | case V4L2_CID_AUDIO_VOLUME: |
@@ -362,6 +340,7 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) | |||
362 | return -EINVAL; | 340 | return -EINVAL; |
363 | } | 341 | } |
364 | break; | 342 | break; |
343 | |||
365 | default: | 344 | default: |
366 | return -EINVAL; | 345 | return -EINVAL; |
367 | } | 346 | } |
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index c2c1e856aa60..a897d6b7d708 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -115,8 +115,8 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask, | |||
115 | 115 | ||
116 | /* ----------------------------------------------------------------------- */ | 116 | /* ----------------------------------------------------------------------- */ |
117 | 117 | ||
118 | static int set_input(struct i2c_client *, enum cx25840_input); | 118 | static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, |
119 | static void input_change(struct i2c_client *); | 119 | enum cx25840_audio_input aud_input); |
120 | static void log_status(struct i2c_client *client); | 120 | static void log_status(struct i2c_client *client); |
121 | 121 | ||
122 | /* ----------------------------------------------------------------------- */ | 122 | /* ----------------------------------------------------------------------- */ |
@@ -195,10 +195,8 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw) | |||
195 | /* AC97 shift */ | 195 | /* AC97 shift */ |
196 | cx25840_write(client, 0x8cf, 0x0f); | 196 | cx25840_write(client, 0x8cf, 0x0f); |
197 | 197 | ||
198 | /* (re)set video input */ | 198 | /* (re)set input */ |
199 | set_input(client, state->input); | 199 | set_input(client, state->vid_input, state->aud_input); |
200 | /* (re)set audio input */ | ||
201 | cx25840_audio(client, AUDC_SET_INPUT, &state->audio_input); | ||
202 | 200 | ||
203 | /* start microcontroller */ | 201 | /* start microcontroller */ |
204 | cx25840_and_or(client, 0x803, ~0x10, 0x10); | 202 | cx25840_and_or(client, 0x803, ~0x10, 0x10); |
@@ -223,7 +221,7 @@ static void input_change(struct i2c_client *client) | |||
223 | cx25840_write(client, 0x80b, 0x10); | 221 | cx25840_write(client, 0x80b, 0x10); |
224 | } else if (std & V4L2_STD_NTSC) { | 222 | } else if (std & V4L2_STD_NTSC) { |
225 | /* NTSC */ | 223 | /* NTSC */ |
226 | if (state->cardtype == CARDTYPE_PVR150_WORKAROUND) { | 224 | if (state->pvr150_workaround) { |
227 | /* Certain Hauppauge PVR150 models have a hardware bug | 225 | /* Certain Hauppauge PVR150 models have a hardware bug |
228 | that causes audio to drop out. For these models the | 226 | that causes audio to drop out. For these models the |
229 | audio standard must be set explicitly. | 227 | audio standard must be set explicitly. |
@@ -259,72 +257,68 @@ static void input_change(struct i2c_client *client) | |||
259 | } | 257 | } |
260 | } | 258 | } |
261 | 259 | ||
262 | static int set_input(struct i2c_client *client, enum cx25840_input input) | 260 | static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, |
261 | enum cx25840_audio_input aud_input) | ||
263 | { | 262 | { |
264 | struct cx25840_state *state = i2c_get_clientdata(client); | 263 | struct cx25840_state *state = i2c_get_clientdata(client); |
264 | u8 is_composite = (vid_input >= CX25840_COMPOSITE1 && | ||
265 | vid_input <= CX25840_COMPOSITE8); | ||
266 | u8 reg; | ||
265 | 267 | ||
266 | cx25840_dbg("decoder set input (%d)\n", input); | 268 | cx25840_dbg("decoder set video input %d, audio input %d\n", |
269 | vid_input, aud_input); | ||
267 | 270 | ||
268 | switch (input) { | 271 | if (is_composite) { |
269 | case CX25840_TUNER: | 272 | reg = 0xf0 + (vid_input - CX25840_COMPOSITE1); |
270 | cx25840_dbg("now setting Tuner input\n"); | 273 | } else { |
271 | 274 | int luma = vid_input & 0xf0; | |
272 | if (state->cardtype == CARDTYPE_PVR150 || | 275 | int chroma = vid_input & 0xf00; |
273 | state->cardtype == CARDTYPE_PVR150_WORKAROUND) { | ||
274 | /* CH_SEL_ADC2=1 */ | ||
275 | cx25840_and_or(client, 0x102, ~0x2, 0x02); | ||
276 | } | ||
277 | |||
278 | /* Video Input Control */ | ||
279 | if (state->cardtype == CARDTYPE_PG600) { | ||
280 | cx25840_write(client, 0x103, 0x11); | ||
281 | } else { | ||
282 | cx25840_write(client, 0x103, 0x46); | ||
283 | } | ||
284 | |||
285 | /* INPUT_MODE=0 */ | ||
286 | cx25840_and_or(client, 0x401, ~0x6, 0x00); | ||
287 | break; | ||
288 | |||
289 | case CX25840_COMPOSITE0: | ||
290 | case CX25840_COMPOSITE1: | ||
291 | cx25840_dbg("now setting Composite input\n"); | ||
292 | 276 | ||
293 | /* Video Input Control */ | 277 | if ((vid_input & ~0xff0) || |
294 | if (state->cardtype == CARDTYPE_PG600) { | 278 | luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA4 || |
295 | cx25840_write(client, 0x103, 0x00); | 279 | chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) { |
296 | } else { | 280 | cx25840_err("0x%04x is not a valid video input!\n", vid_input); |
297 | cx25840_write(client, 0x103, 0x02); | 281 | return -EINVAL; |
298 | } | 282 | } |
299 | 283 | reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4); | |
300 | /* INPUT_MODE=0 */ | 284 | if (chroma >= CX25840_SVIDEO_CHROMA7) { |
301 | cx25840_and_or(client, 0x401, ~0x6, 0x00); | 285 | reg &= 0x3f; |
302 | break; | 286 | reg |= (chroma - CX25840_SVIDEO_CHROMA7) >> 2; |
303 | |||
304 | case CX25840_SVIDEO0: | ||
305 | case CX25840_SVIDEO1: | ||
306 | cx25840_dbg("now setting S-Video input\n"); | ||
307 | |||
308 | /* CH_SEL_ADC2=0 */ | ||
309 | cx25840_and_or(client, 0x102, ~0x2, 0x00); | ||
310 | |||
311 | /* Video Input Control */ | ||
312 | if (state->cardtype == CARDTYPE_PG600) { | ||
313 | cx25840_write(client, 0x103, 0x02); | ||
314 | } else { | 287 | } else { |
315 | cx25840_write(client, 0x103, 0x10); | 288 | reg &= 0xcf; |
289 | reg |= (chroma - CX25840_SVIDEO_CHROMA4) >> 4; | ||
316 | } | 290 | } |
291 | } | ||
317 | 292 | ||
318 | /* INPUT_MODE=1 */ | 293 | switch (aud_input) { |
319 | cx25840_and_or(client, 0x401, ~0x6, 0x02); | 294 | case CX25840_AUDIO_SERIAL: |
295 | /* do nothing, use serial audio input */ | ||
320 | break; | 296 | break; |
297 | case CX25840_AUDIO4: reg &= ~0x30; break; | ||
298 | case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break; | ||
299 | case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break; | ||
300 | case CX25840_AUDIO7: reg &= ~0xc0; break; | ||
301 | case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break; | ||
321 | 302 | ||
322 | default: | 303 | default: |
323 | cx25840_err("%d is not a valid input!\n", input); | 304 | cx25840_err("0x%04x is not a valid audio input!\n", aud_input); |
324 | return -EINVAL; | 305 | return -EINVAL; |
325 | } | 306 | } |
326 | 307 | ||
327 | state->input = input; | 308 | cx25840_write(client, 0x103, reg); |
309 | /* Set INPUT_MODE to Composite (0) or S-Video (1) */ | ||
310 | cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02); | ||
311 | /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ | ||
312 | cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); | ||
313 | /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ | ||
314 | if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30) | ||
315 | cx25840_and_or(client, 0x102, ~0x4, 4); | ||
316 | else | ||
317 | cx25840_and_or(client, 0x102, ~0x4, 0); | ||
318 | |||
319 | state->vid_input = vid_input; | ||
320 | state->aud_input = aud_input; | ||
321 | cx25840_audio_set_path(client); | ||
328 | input_change(client); | 322 | input_change(client); |
329 | return 0; | 323 | return 0; |
330 | } | 324 | } |
@@ -395,18 +389,9 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
395 | struct cx25840_state *state = i2c_get_clientdata(client); | 389 | struct cx25840_state *state = i2c_get_clientdata(client); |
396 | 390 | ||
397 | switch (ctrl->id) { | 391 | switch (ctrl->id) { |
398 | case CX25840_CID_CARDTYPE: | 392 | case CX25840_CID_ENABLE_PVR150_WORKAROUND: |
399 | switch (ctrl->value) { | 393 | state->pvr150_workaround = ctrl->value; |
400 | case CARDTYPE_PVR150: | 394 | set_input(client, state->vid_input, state->aud_input); |
401 | case CARDTYPE_PVR150_WORKAROUND: | ||
402 | case CARDTYPE_PG600: | ||
403 | state->cardtype = ctrl->value; | ||
404 | break; | ||
405 | default: | ||
406 | return -ERANGE; | ||
407 | } | ||
408 | |||
409 | set_input(client, state->input); | ||
410 | break; | 395 | break; |
411 | 396 | ||
412 | case V4L2_CID_BRIGHTNESS: | 397 | case V4L2_CID_BRIGHTNESS: |
@@ -465,8 +450,8 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
465 | struct cx25840_state *state = i2c_get_clientdata(client); | 450 | struct cx25840_state *state = i2c_get_clientdata(client); |
466 | 451 | ||
467 | switch (ctrl->id) { | 452 | switch (ctrl->id) { |
468 | case CX25840_CID_CARDTYPE: | 453 | case CX25840_CID_ENABLE_PVR150_WORKAROUND: |
469 | ctrl->value = state->cardtype; | 454 | ctrl->value = state->pvr150_workaround; |
470 | break; | 455 | break; |
471 | case V4L2_CID_BRIGHTNESS: | 456 | case V4L2_CID_BRIGHTNESS: |
472 | ctrl->value = cx25840_read(client, 0x414) + 128; | 457 | ctrl->value = cx25840_read(client, 0x414) + 128; |
@@ -615,7 +600,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
615 | return cx25840_vbi(client, cmd, arg); | 600 | return cx25840_vbi(client, cmd, arg); |
616 | 601 | ||
617 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: | 602 | case VIDIOC_INT_AUDIO_CLOCK_FREQ: |
618 | case AUDC_SET_INPUT: | ||
619 | result = cx25840_audio(client, cmd, arg); | 603 | result = cx25840_audio(client, cmd, arg); |
620 | break; | 604 | break; |
621 | 605 | ||
@@ -652,13 +636,30 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
652 | break; | 636 | break; |
653 | 637 | ||
654 | case VIDIOC_G_INPUT: | 638 | case VIDIOC_G_INPUT: |
655 | *(int *)arg = state->input; | 639 | *(int *)arg = state->vid_input; |
656 | break; | 640 | break; |
657 | 641 | ||
658 | case VIDIOC_S_INPUT: | 642 | case VIDIOC_S_INPUT: |
659 | result = set_input(client, *(int *)arg); | 643 | result = set_input(client, *(enum cx25840_video_input *)arg, state->aud_input); |
660 | break; | 644 | break; |
661 | 645 | ||
646 | case VIDIOC_S_AUDIO: | ||
647 | { | ||
648 | struct v4l2_audio *input = arg; | ||
649 | |||
650 | result = set_input(client, state->vid_input, input->index); | ||
651 | break; | ||
652 | } | ||
653 | |||
654 | case VIDIOC_G_AUDIO: | ||
655 | { | ||
656 | struct v4l2_audio *input = arg; | ||
657 | |||
658 | memset(input, 0, sizeof(*input)); | ||
659 | input->index = state->aud_input; | ||
660 | break; | ||
661 | } | ||
662 | |||
662 | case VIDIOC_S_FREQUENCY: | 663 | case VIDIOC_S_FREQUENCY: |
663 | input_change(client); | 664 | input_change(client); |
664 | break; | 665 | break; |
@@ -801,10 +802,10 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, | |||
801 | 802 | ||
802 | i2c_set_clientdata(client, state); | 803 | i2c_set_clientdata(client, state); |
803 | memset(state, 0, sizeof(struct cx25840_state)); | 804 | memset(state, 0, sizeof(struct cx25840_state)); |
804 | state->input = CX25840_TUNER; | 805 | state->vid_input = CX25840_COMPOSITE7; |
806 | state->aud_input = CX25840_AUDIO8; | ||
805 | state->audclk_freq = 48000; | 807 | state->audclk_freq = 48000; |
806 | state->audio_input = AUDIO_TUNER; | 808 | state->pvr150_workaround = 0; |
807 | state->cardtype = CARDTYPE_PVR150; | ||
808 | 809 | ||
809 | cx25840_initialize(client, 1); | 810 | cx25840_initialize(client, 1); |
810 | 811 | ||
@@ -888,6 +889,8 @@ static void log_status(struct i2c_client *client) | |||
888 | u8 pref_mode = cx25840_read(client, 0x809); | 889 | u8 pref_mode = cx25840_read(client, 0x809); |
889 | u8 afc0 = cx25840_read(client, 0x80b); | 890 | u8 afc0 = cx25840_read(client, 0x80b); |
890 | u8 mute_ctl = cx25840_read(client, 0x8d3); | 891 | u8 mute_ctl = cx25840_read(client, 0x8d3); |
892 | int vid_input = state->vid_input; | ||
893 | int aud_input = state->aud_input; | ||
891 | char *p; | 894 | char *p; |
892 | 895 | ||
893 | cx25840_info("Video signal: %spresent\n", | 896 | cx25840_info("Video signal: %spresent\n", |
@@ -997,16 +1000,19 @@ static void log_status(struct i2c_client *client) | |||
997 | cx25840_info("Specified standard: %s\n", | 1000 | cx25840_info("Specified standard: %s\n", |
998 | vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); | 1001 | vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); |
999 | 1002 | ||
1000 | switch (state->input) { | 1003 | if (vid_input >= CX25840_COMPOSITE1 && |
1001 | case CX25840_COMPOSITE0: p = "Composite 0"; break; | 1004 | vid_input <= CX25840_COMPOSITE8) { |
1002 | case CX25840_COMPOSITE1: p = "Composite 1"; break; | 1005 | cx25840_info("Specified video input: Composite %d\n", |
1003 | case CX25840_SVIDEO0: p = "S-Video 0"; break; | 1006 | vid_input - CX25840_COMPOSITE1 + 1); |
1004 | case CX25840_SVIDEO1: p = "S-Video 1"; break; | 1007 | } else { |
1005 | case CX25840_TUNER: p = "Tuner"; break; | 1008 | cx25840_info("Specified video input: S-Video (Luma In%d, Chroma In%d)\n", |
1009 | (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); | ||
1010 | } | ||
1011 | if (aud_input) { | ||
1012 | cx25840_info("Specified audio input: Tuner (In%d)\n", aud_input); | ||
1013 | } else { | ||
1014 | cx25840_info("Specified audio input: External\n"); | ||
1006 | } | 1015 | } |
1007 | cx25840_info("Specified input: %s\n", p); | ||
1008 | cx25840_info("Specified audio input: %s\n", | ||
1009 | state->audio_input == 0 ? "Tuner" : "External"); | ||
1010 | 1016 | ||
1011 | cx25840_info("Specified audioclock freq: %d Hz\n", state->audclk_freq); | 1017 | cx25840_info("Specified audioclock freq: %d Hz\n", state->audclk_freq); |
1012 | 1018 | ||
diff --git a/drivers/media/video/cx25840/cx25840.h b/drivers/media/video/cx25840/cx25840.h index 4731a19092a6..3dc67e79c856 100644 --- a/drivers/media/video/cx25840/cx25840.h +++ b/drivers/media/video/cx25840/cx25840.h | |||
@@ -39,32 +39,58 @@ extern int cx25840_debug; | |||
39 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ | 39 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ |
40 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | 40 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) |
41 | 41 | ||
42 | #define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0) | 42 | /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is |
43 | 43 | present in Hauppauge PVR-150 (and possibly PVR-500) cards that have | |
44 | /* The CARDTYPE_PVR150_WORKAROUND cardtype activates a workaround for a | 44 | certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The |
45 | hardware bug that is present in PVR150 (and possible PVR500) cards that | ||
46 | have certain NTSC tuners (tveeprom model numbers 85, 99 and 112). The | ||
47 | audio autodetect fails on some channels for these models and the workaround | 45 | audio autodetect fails on some channels for these models and the workaround |
48 | is to select the audio standard explicitly. Many thanks to Hauppauge for | 46 | is to select the audio standard explicitly. Many thanks to Hauppauge for |
49 | providing this information. */ | 47 | providing this information. */ |
50 | enum cx25840_cardtype { | 48 | #define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0) |
51 | CARDTYPE_PVR150, | 49 | |
52 | CARDTYPE_PG600, | 50 | enum cx25840_video_input { |
53 | CARDTYPE_PVR150_WORKAROUND, | 51 | /* Composite video inputs In1-In8 */ |
52 | CX25840_COMPOSITE1 = 1, | ||
53 | CX25840_COMPOSITE2, | ||
54 | CX25840_COMPOSITE3, | ||
55 | CX25840_COMPOSITE4, | ||
56 | CX25840_COMPOSITE5, | ||
57 | CX25840_COMPOSITE6, | ||
58 | CX25840_COMPOSITE7, | ||
59 | CX25840_COMPOSITE8, | ||
60 | |||
61 | /* S-Video inputs consist of one luma input (In1-In4) ORed with one | ||
62 | chroma input (In5-In8) */ | ||
63 | CX25840_SVIDEO_LUMA1 = 0x10, | ||
64 | CX25840_SVIDEO_LUMA2 = 0x20, | ||
65 | CX25840_SVIDEO_LUMA3 = 0x30, | ||
66 | CX25840_SVIDEO_LUMA4 = 0x40, | ||
67 | CX25840_SVIDEO_CHROMA4 = 0x400, | ||
68 | CX25840_SVIDEO_CHROMA5 = 0x500, | ||
69 | CX25840_SVIDEO_CHROMA6 = 0x600, | ||
70 | CX25840_SVIDEO_CHROMA7 = 0x700, | ||
71 | CX25840_SVIDEO_CHROMA8 = 0x800, | ||
72 | |||
73 | /* S-Video aliases for common luma/chroma combinations */ | ||
74 | CX25840_SVIDEO1 = 0x510, | ||
75 | CX25840_SVIDEO2 = 0x620, | ||
76 | CX25840_SVIDEO3 = 0x730, | ||
77 | CX25840_SVIDEO4 = 0x840, | ||
54 | }; | 78 | }; |
55 | 79 | ||
56 | enum cx25840_input { | 80 | enum cx25840_audio_input { |
57 | CX25840_TUNER, | 81 | /* Audio inputs: serial or In4-In8 */ |
58 | CX25840_COMPOSITE0, | 82 | CX25840_AUDIO_SERIAL, |
59 | CX25840_COMPOSITE1, | 83 | CX25840_AUDIO4 = 4, |
60 | CX25840_SVIDEO0, | 84 | CX25840_AUDIO5, |
61 | CX25840_SVIDEO1 | 85 | CX25840_AUDIO6, |
86 | CX25840_AUDIO7, | ||
87 | CX25840_AUDIO8, | ||
62 | }; | 88 | }; |
63 | 89 | ||
64 | struct cx25840_state { | 90 | struct cx25840_state { |
65 | enum cx25840_cardtype cardtype; | 91 | int pvr150_workaround; |
66 | enum cx25840_input input; | 92 | enum cx25840_video_input vid_input; |
67 | int audio_input; | 93 | enum cx25840_audio_input aud_input; |
68 | u32 audclk_freq; | 94 | u32 audclk_freq; |
69 | }; | 95 | }; |
70 | 96 | ||
@@ -84,6 +110,7 @@ int cx25840_loadfw(struct i2c_client *client); | |||
84 | /* ----------------------------------------------------------------------- */ | 110 | /* ----------------------------------------------------------------------- */ |
85 | /* cx25850-audio.c */ | 111 | /* cx25850-audio.c */ |
86 | int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg); | 112 | int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg); |
113 | void cx25840_audio_set_path(struct i2c_client *client); | ||
87 | 114 | ||
88 | /* ----------------------------------------------------------------------- */ | 115 | /* ----------------------------------------------------------------------- */ |
89 | /* cx25850-vbi.c */ | 116 | /* cx25850-vbi.c */ |