diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2006-01-09 15:21:32 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 2006-01-09 15:21:32 -0500 |
commit | 7560d7a4f9add362d60d4513033cf522c37adeea (patch) | |
tree | ca408b9b374f641373f57650bd5f462a64b810fe /drivers/media/video/msp3400-driver.c | |
parent | 3d7d027a9bf41437aa93baf14a1aada521ad9b12 (diff) |
V4L/DVB (3317): msp3400: use v4l2_std_id and determine chip capabilities.
- Replace old norm by the v4l2_std_id values.
- Add code to correctly detect the various capabilities of the
various msp chips. It's not yet used, that's going to be the next step.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Diffstat (limited to 'drivers/media/video/msp3400-driver.c')
-rw-r--r-- | drivers/media/video/msp3400-driver.c | 120 |
1 files changed, 67 insertions, 53 deletions
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index fbd85120c331..0c2ab7e9d1cc 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
@@ -312,10 +312,16 @@ void msp_set_audio(struct i2c_client *client) | |||
312 | msp_write_dsp(client, 0x0003, treble); /* loudspeaker */ | 312 | msp_write_dsp(client, 0x0003, treble); /* loudspeaker */ |
313 | } | 313 | } |
314 | 314 | ||
315 | int msp_modus(struct i2c_client *client, int norm) | 315 | int msp_modus(struct i2c_client *client) |
316 | { | 316 | { |
317 | switch (norm) { | 317 | struct msp_state *state = i2c_get_clientdata(client); |
318 | case VIDEO_MODE_PAL: | 318 | |
319 | if (state->radio) { | ||
320 | v4l_dbg(1, client, "video mode selected to Radio\n"); | ||
321 | return 0x0003; | ||
322 | } | ||
323 | |||
324 | if (state->std & V4L2_STD_PAL) { | ||
319 | v4l_dbg(1, client, "video mode selected to PAL\n"); | 325 | v4l_dbg(1, client, "video mode selected to PAL\n"); |
320 | 326 | ||
321 | #if 1 | 327 | #if 1 |
@@ -325,37 +331,16 @@ int msp_modus(struct i2c_client *client, int norm) | |||
325 | /* previous value, try this if it breaks ... */ | 331 | /* previous value, try this if it breaks ... */ |
326 | return 0x1003; | 332 | return 0x1003; |
327 | #endif | 333 | #endif |
328 | case VIDEO_MODE_NTSC: /* BTSC */ | 334 | } |
335 | if (state->std & V4L2_STD_NTSC) { | ||
329 | v4l_dbg(1, client, "video mode selected to NTSC\n"); | 336 | v4l_dbg(1, client, "video mode selected to NTSC\n"); |
330 | return 0x2003; | 337 | return 0x2003; |
331 | case VIDEO_MODE_SECAM: | 338 | } |
339 | if (state->std & V4L2_STD_SECAM) { | ||
332 | v4l_dbg(1, client, "video mode selected to SECAM\n"); | 340 | v4l_dbg(1, client, "video mode selected to SECAM\n"); |
333 | return 0x0003; | 341 | return 0x0003; |
334 | case VIDEO_MODE_RADIO: | ||
335 | v4l_dbg(1, client, "video mode selected to Radio\n"); | ||
336 | return 0x0003; | ||
337 | case VIDEO_MODE_AUTO: | ||
338 | v4l_dbg(1, client, "video mode selected to Auto\n"); | ||
339 | return 0x2003; | ||
340 | default: | ||
341 | return 0x0003; | ||
342 | } | ||
343 | } | ||
344 | |||
345 | int msp_standard(int norm) | ||
346 | { | ||
347 | switch (norm) { | ||
348 | case VIDEO_MODE_PAL: | ||
349 | return 1; | ||
350 | case VIDEO_MODE_NTSC: /* BTSC */ | ||
351 | return 0x0020; | ||
352 | case VIDEO_MODE_SECAM: | ||
353 | return 1; | ||
354 | case VIDEO_MODE_RADIO: | ||
355 | return 0x0040; | ||
356 | default: | ||
357 | return 1; | ||
358 | } | 342 | } |
343 | return 0x0003; | ||
359 | } | 344 | } |
360 | 345 | ||
361 | /* ------------------------------------------------------------------------ */ | 346 | /* ------------------------------------------------------------------------ */ |
@@ -617,7 +602,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
617 | break; | 602 | break; |
618 | 603 | ||
619 | case AUDC_SET_RADIO: | 604 | case AUDC_SET_RADIO: |
620 | state->norm = VIDEO_MODE_RADIO; | 605 | state->radio = 1; |
621 | v4l_dbg(1, client, "switching to radio mode\n"); | 606 | v4l_dbg(1, client, "switching to radio mode\n"); |
622 | state->watch_stereo = 0; | 607 | state->watch_stereo = 0; |
623 | switch (state->opmode) { | 608 | switch (state->opmode) { |
@@ -673,7 +658,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
673 | state->treble = va->treble; | 658 | state->treble = va->treble; |
674 | msp_set_audio(client); | 659 | msp_set_audio(client); |
675 | 660 | ||
676 | if (va->mode != 0 && state->norm != VIDEO_MODE_RADIO) | 661 | if (va->mode != 0 && state->radio == 0) |
677 | msp_any_set_audmode(client, msp_mode_v4l1_to_v4l2(va->mode)); | 662 | msp_any_set_audmode(client, msp_mode_v4l1_to_v4l2(va->mode)); |
678 | break; | 663 | break; |
679 | } | 664 | } |
@@ -682,7 +667,13 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
682 | { | 667 | { |
683 | struct video_channel *vc = arg; | 668 | struct video_channel *vc = arg; |
684 | 669 | ||
685 | state->norm = vc->norm; | 670 | state->radio = 0; |
671 | if (vc->norm == VIDEO_MODE_PAL) | ||
672 | state->std = V4L2_STD_PAL; | ||
673 | else if (vc->norm == VIDEO_MODE_SECAM) | ||
674 | state->std = V4L2_STD_SECAM; | ||
675 | else | ||
676 | state->std = V4L2_STD_NTSC; | ||
686 | msp_wake_thread(client); | 677 | msp_wake_thread(client); |
687 | break; | 678 | break; |
688 | } | 679 | } |
@@ -709,15 +700,8 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
709 | { | 700 | { |
710 | v4l2_std_id *id = arg; | 701 | v4l2_std_id *id = arg; |
711 | 702 | ||
712 | /*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/ | 703 | state->std = *id; |
713 | if (*id & V4L2_STD_PAL) { | 704 | state->radio = 0; |
714 | state->norm = VIDEO_MODE_PAL; | ||
715 | } else if (*id & V4L2_STD_SECAM) { | ||
716 | state->norm = VIDEO_MODE_SECAM; | ||
717 | } else { | ||
718 | state->norm = VIDEO_MODE_NTSC; | ||
719 | } | ||
720 | |||
721 | msp_wake_thread(client); | 705 | msp_wake_thread(client); |
722 | return 0; | 706 | return 0; |
723 | } | 707 | } |
@@ -965,6 +949,11 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | |||
965 | struct i2c_client *client; | 949 | struct i2c_client *client; |
966 | struct msp_state *state; | 950 | struct msp_state *state; |
967 | int (*thread_func)(void *data) = NULL; | 951 | int (*thread_func)(void *data) = NULL; |
952 | int msp_hard; | ||
953 | int msp_family; | ||
954 | int msp_revision; | ||
955 | int msp_product, msp_prod_hi, msp_prod_lo; | ||
956 | int msp_rom; | ||
968 | 957 | ||
969 | client = kmalloc(sizeof(*client), GFP_KERNEL); | 958 | client = kmalloc(sizeof(*client), GFP_KERNEL); |
970 | if (client == NULL) | 959 | if (client == NULL) |
@@ -989,7 +978,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | |||
989 | i2c_set_clientdata(client, state); | 978 | i2c_set_clientdata(client, state); |
990 | 979 | ||
991 | memset(state, 0, sizeof(*state)); | 980 | memset(state, 0, sizeof(*state)); |
992 | state->norm = VIDEO_MODE_NTSC; | 981 | state->std = V4L2_STD_NTSC; |
993 | state->volume = 58880; /* 0db gain */ | 982 | state->volume = 58880; /* 0db gain */ |
994 | state->balance = 32768; /* 0db gain */ | 983 | state->balance = 32768; /* 0db gain */ |
995 | state->bass = 32768; | 984 | state->bass = 32768; |
@@ -1012,20 +1001,45 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | |||
1012 | 1001 | ||
1013 | msp_set_audio(client); | 1002 | msp_set_audio(client); |
1014 | 1003 | ||
1015 | snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d", | 1004 | msp_family = ((state->rev1 >> 4) & 0x0f) + 3; |
1016 | ((state->rev1 >> 4) & 0x0f) + '3', | 1005 | msp_product = (state->rev2 >> 8) & 0xff; |
1017 | (state->rev2 >> 8) & 0xff, | 1006 | msp_prod_hi = msp_product / 10; |
1018 | (state->rev1 & 0x0f) + '@', | 1007 | msp_prod_lo = msp_product % 10; |
1019 | ((state->rev1 >> 8) & 0xff) + '@', | 1008 | msp_revision = (state->rev1 & 0x0f) + '@'; |
1020 | state->rev2 & 0x1f); | 1009 | msp_hard = ((state->rev1 >> 8) & 0xff) + '@'; |
1010 | msp_rom = state->rev2 & 0x1f; | ||
1011 | snprintf(client->name, sizeof(client->name), "MSP%d4%02d%c-%c%d", | ||
1012 | msp_family, msp_product, | ||
1013 | msp_revision, msp_hard, msp_rom); | ||
1014 | |||
1015 | /* Has NICAM support: all mspx41x and mspx45x products have NICAM */ | ||
1016 | state->has_nicam = msp_prod_hi == 1 || msp_prod_hi == 5; | ||
1017 | /* Has radio support: was added with revision G */ | ||
1018 | state->has_radio = msp_revision >= 'G'; | ||
1019 | /* Has headphones output: not for stripped down products */ | ||
1020 | state->has_headphones = msp_prod_lo < 5; | ||
1021 | /* Has scart4 input: not in pre D revisions, not in stripped D revs */ | ||
1022 | state->has_scart4 = msp_family >= 4 || (msp_revision >= 'D' && msp_prod_lo < 5); | ||
1023 | /* Has scart2 and scart3 inputs and scart2 output: not in stripped | ||
1024 | down products of the '3' family */ | ||
1025 | state->has_scart23_in_scart2_out = msp_family >= 4 || msp_prod_lo < 5; | ||
1026 | /* Has subwoofer output: not in pre-D revs and not in stripped down products */ | ||
1027 | state->has_subwoofer = msp_revision >= 'D' && msp_prod_lo < 5; | ||
1028 | /* Has soundprocessing (bass/treble/balance/loudness/equalizer): not in | ||
1029 | stripped down products */ | ||
1030 | state->has_sound_processing = msp_prod_lo < 7; | ||
1031 | /* Has Virtual Dolby Surround: only in msp34x1 */ | ||
1032 | state->has_virtual_dolby_surround = msp_revision == 'G' && msp_prod_lo == 1; | ||
1033 | /* Has Virtual Dolby Surround & Dolby Pro Logic: only in msp34x2 */ | ||
1034 | state->has_dolby_pro_logic = msp_revision == 'G' && msp_prod_lo == 2; | ||
1021 | 1035 | ||
1022 | state->opmode = opmode; | 1036 | state->opmode = opmode; |
1023 | if (state->opmode == OPMODE_AUTO) { | 1037 | if (state->opmode == OPMODE_AUTO) { |
1024 | /* MSP revision G and up have both autodetect and autoselect */ | 1038 | /* MSP revision G and up have both autodetect and autoselect */ |
1025 | if ((state->rev1 & 0x0f) >= 'G'-'@') | 1039 | if (msp_revision >= 'G') |
1026 | state->opmode = OPMODE_AUTOSELECT; | 1040 | state->opmode = OPMODE_AUTOSELECT; |
1027 | /* MSP revision D and up have autodetect */ | 1041 | /* MSP revision D and up have autodetect */ |
1028 | else if ((state->rev1 & 0x0f) >= 'D'-'@') | 1042 | else if (msp_revision >= 'D') |
1029 | state->opmode = OPMODE_AUTODETECT; | 1043 | state->opmode = OPMODE_AUTODETECT; |
1030 | else | 1044 | else |
1031 | state->opmode = OPMODE_MANUAL; | 1045 | state->opmode = OPMODE_MANUAL; |
@@ -1034,11 +1048,11 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) | |||
1034 | /* hello world :-) */ | 1048 | /* hello world :-) */ |
1035 | v4l_info(client, "%s found @ 0x%x (%s)\n", client->name, address << 1, adapter->name); | 1049 | v4l_info(client, "%s found @ 0x%x (%s)\n", client->name, address << 1, adapter->name); |
1036 | v4l_info(client, "%s ", client->name); | 1050 | v4l_info(client, "%s ", client->name); |
1037 | if (HAVE_NICAM(state) && HAVE_RADIO(state)) | 1051 | if (state->has_nicam && state->has_radio) |
1038 | printk("supports nicam and radio, "); | 1052 | printk("supports nicam and radio, "); |
1039 | else if (HAVE_NICAM(state)) | 1053 | else if (state->has_nicam) |
1040 | printk("supports nicam, "); | 1054 | printk("supports nicam, "); |
1041 | else if (HAVE_RADIO(state)) | 1055 | else if (state->has_radio) |
1042 | printk("supports radio, "); | 1056 | printk("supports radio, "); |
1043 | printk("mode is "); | 1057 | printk("mode is "); |
1044 | 1058 | ||