diff options
Diffstat (limited to 'drivers/media')
115 files changed, 18589 insertions, 5840 deletions
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c index 31fccb4f05d6..4b71fd6f7aed 100644 --- a/drivers/media/common/ir-common.c +++ b/drivers/media/common/ir-common.c | |||
@@ -116,7 +116,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = { | |||
116 | [ 46 ] = KEY_BLUE, | 116 | [ 46 ] = KEY_BLUE, |
117 | [ 24 ] = KEY_KPPLUS, /* fine tune + */ | 117 | [ 24 ] = KEY_KPPLUS, /* fine tune + */ |
118 | [ 25 ] = KEY_KPMINUS, /* fine tune - */ | 118 | [ 25 ] = KEY_KPMINUS, /* fine tune - */ |
119 | [ 33 ] = KEY_KPDOT, | 119 | [ 33 ] = KEY_KPDOT, |
120 | [ 19 ] = KEY_KPENTER, | 120 | [ 19 ] = KEY_KPENTER, |
121 | [ 34 ] = KEY_BACK, | 121 | [ 34 ] = KEY_BACK, |
122 | [ 35 ] = KEY_PLAYPAUSE, | 122 | [ 35 ] = KEY_PLAYPAUSE, |
@@ -239,7 +239,7 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) | |||
239 | dprintk(1,"%s: key event code=%d down=%d\n", | 239 | dprintk(1,"%s: key event code=%d down=%d\n", |
240 | dev->name,ir->keycode,ir->keypressed); | 240 | dev->name,ir->keycode,ir->keypressed); |
241 | input_report_key(dev,ir->keycode,ir->keypressed); | 241 | input_report_key(dev,ir->keycode,ir->keypressed); |
242 | input_sync(dev); | 242 | input_sync(dev); |
243 | } | 243 | } |
244 | 244 | ||
245 | /* -------------------------------------------------------------------------- */ | 245 | /* -------------------------------------------------------------------------- */ |
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 47e28b0ee951..a35330315f65 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | |||
@@ -13,6 +13,8 @@ | |||
13 | #include "bcm3510.h" | 13 | #include "bcm3510.h" |
14 | #include "stv0297.h" | 14 | #include "stv0297.h" |
15 | #include "mt312.h" | 15 | #include "mt312.h" |
16 | #include "lgdt330x.h" | ||
17 | #include "dvb-pll.h" | ||
16 | 18 | ||
17 | /* lnb control */ | 19 | /* lnb control */ |
18 | 20 | ||
@@ -234,7 +236,6 @@ static struct stv0299_config samsung_tbmu24112_config = { | |||
234 | .inittab = samsung_tbmu24112_inittab, | 236 | .inittab = samsung_tbmu24112_inittab, |
235 | .mclk = 88000000UL, | 237 | .mclk = 88000000UL, |
236 | .invert = 0, | 238 | .invert = 0, |
237 | .enhanced_tuning = 0, | ||
238 | .skip_reinit = 0, | 239 | .skip_reinit = 0, |
239 | .lock_output = STV0229_LOCKOUTPUT_LK, | 240 | .lock_output = STV0229_LOCKOUTPUT_LK, |
240 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 241 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
@@ -296,6 +297,52 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir | |||
296 | return request_firmware(fw, name, fc->dev); | 297 | return request_firmware(fw, name, fc->dev); |
297 | } | 298 | } |
298 | 299 | ||
300 | static int lgdt3303_pll_set(struct dvb_frontend* fe, | ||
301 | struct dvb_frontend_parameters* params) | ||
302 | { | ||
303 | struct flexcop_device *fc = fe->dvb->priv; | ||
304 | u8 buf[4]; | ||
305 | struct i2c_msg msg = | ||
306 | { .addr = 0x61, .flags = 0, .buf = buf, .len = 4 }; | ||
307 | int err; | ||
308 | |||
309 | dvb_pll_configure(&dvb_pll_tdvs_tua6034,buf, params->frequency, 0); | ||
310 | dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
311 | __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); | ||
312 | if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) { | ||
313 | printk(KERN_WARNING "lgdt3303: %s error " | ||
314 | "(addr %02x <- %02x, err = %i)\n", | ||
315 | __FUNCTION__, buf[0], buf[1], err); | ||
316 | if (err < 0) | ||
317 | return err; | ||
318 | else | ||
319 | return -EREMOTEIO; | ||
320 | } | ||
321 | |||
322 | buf[0] = 0x86 | 0x18; | ||
323 | buf[1] = 0x50; | ||
324 | msg.len = 2; | ||
325 | if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) { | ||
326 | printk(KERN_WARNING "lgdt3303: %s error " | ||
327 | "(addr %02x <- %02x, err = %i)\n", | ||
328 | __FUNCTION__, buf[0], buf[1], err); | ||
329 | if (err < 0) | ||
330 | return err; | ||
331 | else | ||
332 | return -EREMOTEIO; | ||
333 | } | ||
334 | |||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | static struct lgdt330x_config air2pc_atsc_hd5000_config = { | ||
339 | .demod_address = 0x59, | ||
340 | .demod_chip = LGDT3303, | ||
341 | .serial_mpeg = 0x04, | ||
342 | .pll_set = lgdt3303_pll_set, | ||
343 | .clock_polarity_flip = 1, | ||
344 | }; | ||
345 | |||
299 | static struct nxt2002_config samsung_tbmv_config = { | 346 | static struct nxt2002_config samsung_tbmv_config = { |
300 | .demod_address = 0x0a, | 347 | .demod_address = 0x0a, |
301 | .request_firmware = flexcop_fe_request_firmware, | 348 | .request_firmware = flexcop_fe_request_firmware, |
@@ -458,6 +505,11 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
458 | fc->dev_type = FC_AIR_ATSC2; | 505 | fc->dev_type = FC_AIR_ATSC2; |
459 | info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); | 506 | info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); |
460 | } else | 507 | } else |
508 | /* try the air atsc 3nd generation (lgdt3303) */ | ||
509 | if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { | ||
510 | fc->dev_type = FC_AIR_ATSC3; | ||
511 | info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); | ||
512 | } else | ||
461 | /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ | 513 | /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ |
462 | if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) { | 514 | if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) { |
463 | fc->dev_type = FC_AIR_ATSC1; | 515 | fc->dev_type = FC_AIR_ATSC1; |
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c index 3a08d38b318a..62282d8dbfa8 100644 --- a/drivers/media/dvb/b2c2/flexcop-misc.c +++ b/drivers/media/dvb/b2c2/flexcop-misc.c | |||
@@ -51,6 +51,7 @@ const char *flexcop_device_names[] = { | |||
51 | "Sky2PC/SkyStar 2 DVB-S", | 51 | "Sky2PC/SkyStar 2 DVB-S", |
52 | "Sky2PC/SkyStar 2 DVB-S (old version)", | 52 | "Sky2PC/SkyStar 2 DVB-S (old version)", |
53 | "Cable2PC/CableStar 2 DVB-C", | 53 | "Cable2PC/CableStar 2 DVB-C", |
54 | "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", | ||
54 | }; | 55 | }; |
55 | 56 | ||
56 | const char *flexcop_bus_names[] = { | 57 | const char *flexcop_bus_names[] = { |
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h index 4ae1eb5bfe98..23cc6431e2b8 100644 --- a/drivers/media/dvb/b2c2/flexcop-reg.h +++ b/drivers/media/dvb/b2c2/flexcop-reg.h | |||
@@ -26,6 +26,7 @@ typedef enum { | |||
26 | FC_SKY, | 26 | FC_SKY, |
27 | FC_SKY_OLD, | 27 | FC_SKY_OLD, |
28 | FC_CABLE, | 28 | FC_CABLE, |
29 | FC_AIR_ATSC3, | ||
29 | } flexcop_device_type_t; | 30 | } flexcop_device_type_t; |
30 | 31 | ||
31 | typedef enum { | 32 | typedef enum { |
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c index 12873d435406..123ed96f6faa 100644 --- a/drivers/media/dvb/b2c2/flexcop.c +++ b/drivers/media/dvb/b2c2/flexcop.c | |||
@@ -193,6 +193,7 @@ static void flexcop_reset(struct flexcop_device *fc) | |||
193 | v204 = fc->read_ibi_reg(fc,misc_204); | 193 | v204 = fc->read_ibi_reg(fc,misc_204); |
194 | v204.misc_204.Per_reset_sig = 0; | 194 | v204.misc_204.Per_reset_sig = 0; |
195 | fc->write_ibi_reg(fc,misc_204,v204); | 195 | fc->write_ibi_reg(fc,misc_204,v204); |
196 | msleep(1); | ||
196 | v204.misc_204.Per_reset_sig = 1; | 197 | v204.misc_204.Per_reset_sig = 1; |
197 | fc->write_ibi_reg(fc,misc_204,v204); | 198 | fc->write_ibi_reg(fc,misc_204,v204); |
198 | } | 199 | } |
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig index 1e85d16491b0..2337b41714e0 100644 --- a/drivers/media/dvb/bt8xx/Kconfig +++ b/drivers/media/dvb/bt8xx/Kconfig | |||
@@ -6,10 +6,12 @@ config DVB_BT8XX | |||
6 | select DVB_NXT6000 | 6 | select DVB_NXT6000 |
7 | select DVB_CX24110 | 7 | select DVB_CX24110 |
8 | select DVB_OR51211 | 8 | select DVB_OR51211 |
9 | select DVB_LGDT330X | ||
9 | help | 10 | help |
10 | Support for PCI cards based on the Bt8xx PCI bridge. Examples are | 11 | Support for PCI cards based on the Bt8xx PCI bridge. Examples are |
11 | the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, | 12 | the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, |
12 | the pcHDTV HD2000 cards, and certain AVerMedia cards. | 13 | the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and |
14 | some AVerMedia cards. | ||
13 | 15 | ||
14 | Since these cards have no MPEG decoder onboard, they transmit | 16 | Since these cards have no MPEG decoder onboard, they transmit |
15 | only compressed MPEG data over the PCI bus, so you need | 17 | only compressed MPEG data over the PCI bus, so you need |
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index b3c9d7327ac1..8977c7a313df 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -690,8 +690,8 @@ struct dst_types dst_tlist[] = { | |||
690 | .device_id = "DTT-CI", | 690 | .device_id = "DTT-CI", |
691 | .offset = 1, | 691 | .offset = 1, |
692 | .dst_type = DST_TYPE_IS_TERR, | 692 | .dst_type = DST_TYPE_IS_TERR, |
693 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, | 693 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE, |
694 | .dst_feature = 0 | 694 | .dst_feature = DST_TYPE_HAS_CA |
695 | }, | 695 | }, |
696 | 696 | ||
697 | { | 697 | { |
@@ -796,6 +796,56 @@ static int dst_get_vendor(struct dst_state *state) | |||
796 | return 0; | 796 | return 0; |
797 | } | 797 | } |
798 | 798 | ||
799 | static int dst_get_tuner_info(struct dst_state *state) | ||
800 | { | ||
801 | u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
802 | u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
803 | |||
804 | get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); | ||
805 | get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); | ||
806 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { | ||
807 | if (dst_command(state, get_tuner_2, 8) < 0) { | ||
808 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | ||
809 | return -1; | ||
810 | } | ||
811 | } else { | ||
812 | if (dst_command(state, get_tuner_1, 8) < 0) { | ||
813 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | ||
814 | return -1; | ||
815 | } | ||
816 | } | ||
817 | memset(&state->board_info, '\0', 8); | ||
818 | memcpy(&state->board_info, &state->rxbuffer, 8); | ||
819 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { | ||
820 | if (state->board_info[1] == 0x0b) { | ||
821 | if (state->type_flags & DST_TYPE_HAS_TS204) | ||
822 | state->type_flags &= ~DST_TYPE_HAS_TS204; | ||
823 | state->type_flags |= DST_TYPE_HAS_NEWTUNE; | ||
824 | dprintk(verbose, DST_INFO, 1, "DST type has TS=188"); | ||
825 | } else { | ||
826 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | ||
827 | state->type_flags &= ~DST_TYPE_HAS_NEWTUNE; | ||
828 | state->type_flags |= DST_TYPE_HAS_TS204; | ||
829 | dprintk(verbose, DST_INFO, 1, "DST type has TS=204"); | ||
830 | } | ||
831 | } else { | ||
832 | if (state->board_info[0] == 0xbc) { | ||
833 | if (state->type_flags & DST_TYPE_HAS_TS204) | ||
834 | state->type_flags &= ~DST_TYPE_HAS_TS204; | ||
835 | state->type_flags |= DST_TYPE_HAS_NEWTUNE; | ||
836 | dprintk(verbose, DST_INFO, 1, "DST type has TS=188, Daughterboard=[%d]", state->board_info[1]); | ||
837 | |||
838 | } else if (state->board_info[0] == 0xcc) { | ||
839 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | ||
840 | state->type_flags &= ~DST_TYPE_HAS_NEWTUNE; | ||
841 | state->type_flags |= DST_TYPE_HAS_TS204; | ||
842 | dprintk(verbose, DST_INFO, 1, "DST type has TS=204 Daughterboard=[%d]", state->board_info[1]); | ||
843 | } | ||
844 | } | ||
845 | |||
846 | return 0; | ||
847 | } | ||
848 | |||
799 | static int dst_get_device_id(struct dst_state *state) | 849 | static int dst_get_device_id(struct dst_state *state) |
800 | { | 850 | { |
801 | u8 reply; | 851 | u8 reply; |
@@ -855,15 +905,12 @@ static int dst_get_device_id(struct dst_state *state) | |||
855 | state->dst_type = use_dst_type; | 905 | state->dst_type = use_dst_type; |
856 | dst_type_flags_print(state->type_flags); | 906 | dst_type_flags_print(state->type_flags); |
857 | 907 | ||
858 | if (state->type_flags & DST_TYPE_HAS_TS204) { | ||
859 | dst_packsize(state, 204); | ||
860 | } | ||
861 | |||
862 | return 0; | 908 | return 0; |
863 | } | 909 | } |
864 | 910 | ||
865 | static int dst_probe(struct dst_state *state) | 911 | static int dst_probe(struct dst_state *state) |
866 | { | 912 | { |
913 | sema_init(&state->dst_mutex, 1); | ||
867 | if ((rdc_8820_reset(state)) < 0) { | 914 | if ((rdc_8820_reset(state)) < 0) { |
868 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); | 915 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); |
869 | return -1; | 916 | return -1; |
@@ -886,6 +933,13 @@ static int dst_probe(struct dst_state *state) | |||
886 | dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); | 933 | dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); |
887 | return 0; | 934 | return 0; |
888 | } | 935 | } |
936 | if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { | ||
937 | if (dst_get_tuner_info(state) < 0) | ||
938 | dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command"); | ||
939 | } | ||
940 | if (state->type_flags & DST_TYPE_HAS_TS204) { | ||
941 | dst_packsize(state, 204); | ||
942 | } | ||
889 | if (state->type_flags & DST_TYPE_HAS_FW_BUILD) { | 943 | if (state->type_flags & DST_TYPE_HAS_FW_BUILD) { |
890 | if (dst_fw_ver(state) < 0) { | 944 | if (dst_fw_ver(state) < 0) { |
891 | dprintk(verbose, DST_INFO, 1, "FW: Unsupported command"); | 945 | dprintk(verbose, DST_INFO, 1, "FW: Unsupported command"); |
@@ -907,21 +961,23 @@ static int dst_probe(struct dst_state *state) | |||
907 | int dst_command(struct dst_state *state, u8 *data, u8 len) | 961 | int dst_command(struct dst_state *state, u8 *data, u8 len) |
908 | { | 962 | { |
909 | u8 reply; | 963 | u8 reply; |
964 | |||
965 | down(&state->dst_mutex); | ||
910 | if ((dst_comm_init(state)) < 0) { | 966 | if ((dst_comm_init(state)) < 0) { |
911 | dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); | 967 | dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); |
912 | return -1; | 968 | goto error; |
913 | } | 969 | } |
914 | if (write_dst(state, data, len)) { | 970 | if (write_dst(state, data, len)) { |
915 | dprintk(verbose, DST_INFO, 1, "Tring to recover.. "); | 971 | dprintk(verbose, DST_INFO, 1, "Tring to recover.. "); |
916 | if ((dst_error_recovery(state)) < 0) { | 972 | if ((dst_error_recovery(state)) < 0) { |
917 | dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); | 973 | dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); |
918 | return -1; | 974 | goto error; |
919 | } | 975 | } |
920 | return -1; | 976 | goto error; |
921 | } | 977 | } |
922 | if ((dst_pio_disable(state)) < 0) { | 978 | if ((dst_pio_disable(state)) < 0) { |
923 | dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); | 979 | dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); |
924 | return -1; | 980 | goto error; |
925 | } | 981 | } |
926 | if (state->type_flags & DST_TYPE_HAS_FW_1) | 982 | if (state->type_flags & DST_TYPE_HAS_FW_1) |
927 | udelay(3000); | 983 | udelay(3000); |
@@ -929,36 +985,41 @@ int dst_command(struct dst_state *state, u8 *data, u8 len) | |||
929 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); | 985 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); |
930 | if ((dst_error_recovery(state)) < 0) { | 986 | if ((dst_error_recovery(state)) < 0) { |
931 | dprintk(verbose, DST_INFO, 1, "Recovery Failed."); | 987 | dprintk(verbose, DST_INFO, 1, "Recovery Failed."); |
932 | return -1; | 988 | goto error; |
933 | } | 989 | } |
934 | return -1; | 990 | goto error; |
935 | } | 991 | } |
936 | if (reply != ACK) { | 992 | if (reply != ACK) { |
937 | dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); | 993 | dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); |
938 | return -1; | 994 | goto error; |
939 | } | 995 | } |
940 | if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) | 996 | if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) |
941 | return 0; | 997 | goto error; |
942 | if (state->type_flags & DST_TYPE_HAS_FW_1) | 998 | if (state->type_flags & DST_TYPE_HAS_FW_1) |
943 | udelay(3000); | 999 | udelay(3000); |
944 | else | 1000 | else |
945 | udelay(2000); | 1001 | udelay(2000); |
946 | if (!dst_wait_dst_ready(state, NO_DELAY)) | 1002 | if (!dst_wait_dst_ready(state, NO_DELAY)) |
947 | return -1; | 1003 | goto error; |
948 | if (read_dst(state, state->rxbuffer, FIXED_COMM)) { | 1004 | if (read_dst(state, state->rxbuffer, FIXED_COMM)) { |
949 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); | 1005 | dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); |
950 | if ((dst_error_recovery(state)) < 0) { | 1006 | if ((dst_error_recovery(state)) < 0) { |
951 | dprintk(verbose, DST_INFO, 1, "Recovery failed."); | 1007 | dprintk(verbose, DST_INFO, 1, "Recovery failed."); |
952 | return -1; | 1008 | goto error; |
953 | } | 1009 | } |
954 | return -1; | 1010 | goto error; |
955 | } | 1011 | } |
956 | if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { | 1012 | if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { |
957 | dprintk(verbose, DST_INFO, 1, "checksum failure"); | 1013 | dprintk(verbose, DST_INFO, 1, "checksum failure"); |
958 | return -1; | 1014 | goto error; |
959 | } | 1015 | } |
960 | 1016 | up(&state->dst_mutex); | |
961 | return 0; | 1017 | return 0; |
1018 | |||
1019 | error: | ||
1020 | up(&state->dst_mutex); | ||
1021 | return -EIO; | ||
1022 | |||
962 | } | 1023 | } |
963 | EXPORT_SYMBOL(dst_command); | 1024 | EXPORT_SYMBOL(dst_command); |
964 | 1025 | ||
@@ -1016,7 +1077,7 @@ static int dst_get_tuna(struct dst_state *state) | |||
1016 | return 0; | 1077 | return 0; |
1017 | state->diseq_flags &= ~(HAS_LOCK); | 1078 | state->diseq_flags &= ~(HAS_LOCK); |
1018 | if (!dst_wait_dst_ready(state, NO_DELAY)) | 1079 | if (!dst_wait_dst_ready(state, NO_DELAY)) |
1019 | return 0; | 1080 | return -EIO; |
1020 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | 1081 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) |
1021 | /* how to get variable length reply ???? */ | 1082 | /* how to get variable length reply ???? */ |
1022 | retval = read_dst(state, state->rx_tuna, 10); | 1083 | retval = read_dst(state, state->rx_tuna, 10); |
@@ -1024,22 +1085,27 @@ static int dst_get_tuna(struct dst_state *state) | |||
1024 | retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); | 1085 | retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); |
1025 | if (retval < 0) { | 1086 | if (retval < 0) { |
1026 | dprintk(verbose, DST_DEBUG, 1, "read not successful"); | 1087 | dprintk(verbose, DST_DEBUG, 1, "read not successful"); |
1027 | return 0; | 1088 | return retval; |
1028 | } | 1089 | } |
1029 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | 1090 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { |
1030 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { | 1091 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { |
1031 | dprintk(verbose, DST_INFO, 1, "checksum failure ? "); | 1092 | dprintk(verbose, DST_INFO, 1, "checksum failure ? "); |
1032 | return 0; | 1093 | return -EIO; |
1033 | } | 1094 | } |
1034 | } else { | 1095 | } else { |
1035 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) { | 1096 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) { |
1036 | dprintk(verbose, DST_INFO, 1, "checksum failure? "); | 1097 | dprintk(verbose, DST_INFO, 1, "checksum failure? "); |
1037 | return 0; | 1098 | return -EIO; |
1038 | } | 1099 | } |
1039 | } | 1100 | } |
1040 | if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0) | 1101 | if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0) |
1041 | return 0; | 1102 | return 0; |
1042 | state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; | 1103 | if (state->dst_type == DST_TYPE_IS_SAT) { |
1104 | state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; | ||
1105 | } else { | ||
1106 | state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4]; | ||
1107 | } | ||
1108 | state->decode_freq = state->decode_freq * 1000; | ||
1043 | state->decode_lock = 1; | 1109 | state->decode_lock = 1; |
1044 | state->diseq_flags |= HAS_LOCK; | 1110 | state->diseq_flags |= HAS_LOCK; |
1045 | 1111 | ||
@@ -1062,10 +1128,10 @@ static int dst_write_tuna(struct dvb_frontend *fe) | |||
1062 | dst_set_voltage(fe, SEC_VOLTAGE_13); | 1128 | dst_set_voltage(fe, SEC_VOLTAGE_13); |
1063 | } | 1129 | } |
1064 | state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); | 1130 | state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); |
1065 | 1131 | down(&state->dst_mutex); | |
1066 | if ((dst_comm_init(state)) < 0) { | 1132 | if ((dst_comm_init(state)) < 0) { |
1067 | dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); | 1133 | dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); |
1068 | return -1; | 1134 | goto error; |
1069 | } | 1135 | } |
1070 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | 1136 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { |
1071 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); | 1137 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); |
@@ -1077,23 +1143,29 @@ static int dst_write_tuna(struct dvb_frontend *fe) | |||
1077 | if (retval < 0) { | 1143 | if (retval < 0) { |
1078 | dst_pio_disable(state); | 1144 | dst_pio_disable(state); |
1079 | dprintk(verbose, DST_DEBUG, 1, "write not successful"); | 1145 | dprintk(verbose, DST_DEBUG, 1, "write not successful"); |
1080 | return retval; | 1146 | goto werr; |
1081 | } | 1147 | } |
1082 | if ((dst_pio_disable(state)) < 0) { | 1148 | if ((dst_pio_disable(state)) < 0) { |
1083 | dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !"); | 1149 | dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !"); |
1084 | return -1; | 1150 | goto error; |
1085 | } | 1151 | } |
1086 | if ((read_dst(state, &reply, GET_ACK) < 0)) { | 1152 | if ((read_dst(state, &reply, GET_ACK) < 0)) { |
1087 | dprintk(verbose, DST_DEBUG, 1, "read verify not successful."); | 1153 | dprintk(verbose, DST_DEBUG, 1, "read verify not successful."); |
1088 | return -1; | 1154 | goto error; |
1089 | } | 1155 | } |
1090 | if (reply != ACK) { | 1156 | if (reply != ACK) { |
1091 | dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply); | 1157 | dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply); |
1092 | return 0; | 1158 | goto error; |
1093 | } | 1159 | } |
1094 | state->diseq_flags |= ATTEMPT_TUNE; | 1160 | state->diseq_flags |= ATTEMPT_TUNE; |
1095 | 1161 | retval = dst_get_tuna(state); | |
1096 | return dst_get_tuna(state); | 1162 | werr: |
1163 | up(&state->dst_mutex); | ||
1164 | return retval; | ||
1165 | |||
1166 | error: | ||
1167 | up(&state->dst_mutex); | ||
1168 | return -EIO; | ||
1097 | } | 1169 | } |
1098 | 1170 | ||
1099 | /* | 1171 | /* |
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index 6776a592045f..e6541aff3996 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c | |||
@@ -69,62 +69,53 @@ static int ca_set_pid(void) | |||
69 | } | 69 | } |
70 | 70 | ||
71 | 71 | ||
72 | static int put_checksum(u8 *check_string, int length) | 72 | static void put_checksum(u8 *check_string, int length) |
73 | { | 73 | { |
74 | u8 i = 0, checksum = 0; | 74 | dprintk(verbose, DST_CA_DEBUG, 1, " Computing string checksum."); |
75 | 75 | dprintk(verbose, DST_CA_DEBUG, 1, " -> string length : 0x%02x", length); | |
76 | dprintk(verbose, DST_CA_DEBUG, 1, " ========================= Checksum calculation ==========================="); | 76 | check_string[length] = dst_check_sum (check_string, length); |
77 | dprintk(verbose, DST_CA_DEBUG, 1, " String Length=[0x%02x]", length); | 77 | dprintk(verbose, DST_CA_DEBUG, 1, " -> checksum : 0x%02x", check_string[length]); |
78 | dprintk(verbose, DST_CA_DEBUG, 1, " String=["); | ||
79 | |||
80 | while (i < length) { | ||
81 | dprintk(verbose, DST_CA_DEBUG, 0, " %02x", check_string[i]); | ||
82 | checksum += check_string[i]; | ||
83 | i++; | ||
84 | } | ||
85 | dprintk(verbose, DST_CA_DEBUG, 0, " ]\n"); | ||
86 | dprintk(verbose, DST_CA_DEBUG, 1, "Sum=[%02x]\n", checksum); | ||
87 | check_string[length] = ~checksum + 1; | ||
88 | dprintk(verbose, DST_CA_DEBUG, 1, " Checksum=[%02x]", check_string[length]); | ||
89 | dprintk(verbose, DST_CA_DEBUG, 1, " =========================================================================="); | ||
90 | |||
91 | return 0; | ||
92 | } | 78 | } |
93 | 79 | ||
94 | static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read) | 80 | static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read) |
95 | { | 81 | { |
96 | u8 reply; | 82 | u8 reply; |
97 | 83 | ||
84 | down(&state->dst_mutex); | ||
98 | dst_comm_init(state); | 85 | dst_comm_init(state); |
99 | msleep(65); | 86 | msleep(65); |
100 | 87 | ||
101 | if (write_dst(state, data, len)) { | 88 | if (write_dst(state, data, len)) { |
102 | dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); | 89 | dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); |
103 | dst_error_recovery(state); | 90 | dst_error_recovery(state); |
104 | return -1; | 91 | goto error; |
105 | } | 92 | } |
106 | if ((dst_pio_disable(state)) < 0) { | 93 | if ((dst_pio_disable(state)) < 0) { |
107 | dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); | 94 | dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); |
108 | return -1; | 95 | goto error; |
109 | } | 96 | } |
110 | if (read_dst(state, &reply, GET_ACK) < 0) { | 97 | if (read_dst(state, &reply, GET_ACK) < 0) { |
111 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); | 98 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); |
112 | dst_error_recovery(state); | 99 | dst_error_recovery(state); |
113 | return -1; | 100 | goto error; |
114 | } | 101 | } |
115 | if (read) { | 102 | if (read) { |
116 | if (! dst_wait_dst_ready(state, LONG_DELAY)) { | 103 | if (! dst_wait_dst_ready(state, LONG_DELAY)) { |
117 | dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); | 104 | dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); |
118 | return -1; | 105 | goto error; |
119 | } | 106 | } |
120 | if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ | 107 | if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ |
121 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); | 108 | dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); |
122 | dst_error_recovery(state); | 109 | dst_error_recovery(state); |
123 | return -1; | 110 | goto error; |
124 | } | 111 | } |
125 | } | 112 | } |
126 | 113 | up(&state->dst_mutex); | |
127 | return 0; | 114 | return 0; |
115 | |||
116 | error: | ||
117 | up(&state->dst_mutex); | ||
118 | return -EIO; | ||
128 | } | 119 | } |
129 | 120 | ||
130 | 121 | ||
@@ -166,7 +157,7 @@ static int ca_get_app_info(struct dst_state *state) | |||
166 | return 0; | 157 | return 0; |
167 | } | 158 | } |
168 | 159 | ||
169 | static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void *arg) | 160 | static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void __user *arg) |
170 | { | 161 | { |
171 | int i; | 162 | int i; |
172 | u8 slot_cap[256]; | 163 | u8 slot_cap[256]; |
@@ -192,25 +183,25 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, | |||
192 | p_ca_caps->descr_num = slot_cap[7]; | 183 | p_ca_caps->descr_num = slot_cap[7]; |
193 | p_ca_caps->descr_type = 1; | 184 | p_ca_caps->descr_type = 1; |
194 | 185 | ||
195 | if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) | 186 | if (copy_to_user(arg, p_ca_caps, sizeof (struct ca_caps))) |
196 | return -EFAULT; | 187 | return -EFAULT; |
197 | 188 | ||
198 | return 0; | 189 | return 0; |
199 | } | 190 | } |
200 | 191 | ||
201 | /* Need some more work */ | 192 | /* Need some more work */ |
202 | static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) | 193 | static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg) |
203 | { | 194 | { |
204 | return -EOPNOTSUPP; | 195 | return -EOPNOTSUPP; |
205 | } | 196 | } |
206 | 197 | ||
207 | 198 | ||
208 | static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void *arg) | 199 | static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void __user *arg) |
209 | { | 200 | { |
210 | int i; | 201 | int i; |
211 | static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; | 202 | static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; |
212 | 203 | ||
213 | u8 *slot_info = state->rxbuffer; | 204 | u8 *slot_info = state->messages; |
214 | 205 | ||
215 | put_checksum(&slot_command[0], 7); | 206 | put_checksum(&slot_command[0], 7); |
216 | if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { | 207 | if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { |
@@ -238,19 +229,19 @@ static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_s | |||
238 | } else | 229 | } else |
239 | p_ca_slot_info->flags = 0; | 230 | p_ca_slot_info->flags = 0; |
240 | 231 | ||
241 | if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) | 232 | if (copy_to_user(arg, p_ca_slot_info, sizeof (struct ca_slot_info))) |
242 | return -EFAULT; | 233 | return -EFAULT; |
243 | 234 | ||
244 | return 0; | 235 | return 0; |
245 | } | 236 | } |
246 | 237 | ||
247 | 238 | ||
248 | static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) | 239 | static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg) |
249 | { | 240 | { |
250 | u8 i = 0; | 241 | u8 i = 0; |
251 | u32 command = 0; | 242 | u32 command = 0; |
252 | 243 | ||
253 | if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) | 244 | if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) |
254 | return -EFAULT; | 245 | return -EFAULT; |
255 | 246 | ||
256 | if (p_ca_message->msg) { | 247 | if (p_ca_message->msg) { |
@@ -266,7 +257,7 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
266 | switch (command) { | 257 | switch (command) { |
267 | case CA_APP_INFO: | 258 | case CA_APP_INFO: |
268 | memcpy(p_ca_message->msg, state->messages, 128); | 259 | memcpy(p_ca_message->msg, state->messages, 128); |
269 | if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) ) | 260 | if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) |
270 | return -EFAULT; | 261 | return -EFAULT; |
271 | break; | 262 | break; |
272 | } | 263 | } |
@@ -315,7 +306,7 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 l | |||
315 | return 0; | 306 | return 0; |
316 | } | 307 | } |
317 | 308 | ||
318 | u32 asn_1_decode(u8 *asn_1_array) | 309 | static u32 asn_1_decode(u8 *asn_1_array) |
319 | { | 310 | { |
320 | u8 length_field = 0, word_count = 0, count = 0; | 311 | u8 length_field = 0, word_count = 0, count = 0; |
321 | u32 length = 0; | 312 | u32 length = 0; |
@@ -328,7 +319,8 @@ u32 asn_1_decode(u8 *asn_1_array) | |||
328 | } else { | 319 | } else { |
329 | word_count = length_field & 0x7f; | 320 | word_count = length_field & 0x7f; |
330 | for (count = 0; count < word_count; count++) { | 321 | for (count = 0; count < word_count; count++) { |
331 | length = (length | asn_1_array[count + 1]) << 8; | 322 | length = length << 8; |
323 | length += asn_1_array[count + 1]; | ||
332 | dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length); | 324 | dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length); |
333 | } | 325 | } |
334 | } | 326 | } |
@@ -399,13 +391,14 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message | |||
399 | return 0; | 391 | return 0; |
400 | } | 392 | } |
401 | 393 | ||
402 | static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) | 394 | static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg) |
403 | { | 395 | { |
404 | int i = 0; | 396 | int i = 0; |
405 | unsigned int ca_message_header_len; | 397 | unsigned int ca_message_header_len; |
406 | 398 | ||
407 | u32 command = 0; | 399 | u32 command = 0; |
408 | struct ca_msg *hw_buffer; | 400 | struct ca_msg *hw_buffer; |
401 | int result = 0; | ||
409 | 402 | ||
410 | if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { | 403 | if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { |
411 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); | 404 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); |
@@ -413,8 +406,11 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
413 | } | 406 | } |
414 | dprintk(verbose, DST_CA_DEBUG, 1, " "); | 407 | dprintk(verbose, DST_CA_DEBUG, 1, " "); |
415 | 408 | ||
416 | if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) | 409 | if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) { |
417 | return -EFAULT; | 410 | result = -EFAULT; |
411 | goto free_mem_and_exit; | ||
412 | } | ||
413 | |||
418 | 414 | ||
419 | if (p_ca_message->msg) { | 415 | if (p_ca_message->msg) { |
420 | ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */ | 416 | ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */ |
@@ -433,7 +429,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
433 | dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT"); | 429 | dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT"); |
434 | if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started | 430 | if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started |
435 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !"); | 431 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !"); |
436 | return -1; | 432 | result = -1; |
433 | goto free_mem_and_exit; | ||
437 | } | 434 | } |
438 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !"); | 435 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !"); |
439 | break; | 436 | break; |
@@ -442,7 +439,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
442 | /* Have to handle the 2 basic types of cards here */ | 439 | /* Have to handle the 2 basic types of cards here */ |
443 | if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { | 440 | if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { |
444 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !"); | 441 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !"); |
445 | return -1; | 442 | result = -1; |
443 | goto free_mem_and_exit; | ||
446 | } | 444 | } |
447 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !"); | 445 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !"); |
448 | break; | 446 | break; |
@@ -451,22 +449,28 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
451 | 449 | ||
452 | if ((ca_get_app_info(state)) < 0) { | 450 | if ((ca_get_app_info(state)) < 0) { |
453 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !"); | 451 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !"); |
454 | return -1; | 452 | result = -1; |
453 | goto free_mem_and_exit; | ||
455 | } | 454 | } |
456 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); | 455 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); |
457 | break; | 456 | break; |
458 | } | 457 | } |
459 | } | 458 | } |
460 | return 0; | 459 | free_mem_and_exit: |
460 | kfree (hw_buffer); | ||
461 | |||
462 | return result; | ||
461 | } | 463 | } |
462 | 464 | ||
463 | static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) | 465 | static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg) |
464 | { | 466 | { |
465 | struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; | 467 | struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; |
466 | struct dst_state* state = (struct dst_state*) dvbdev->priv; | 468 | struct dst_state* state = (struct dst_state*) dvbdev->priv; |
467 | struct ca_slot_info *p_ca_slot_info; | 469 | struct ca_slot_info *p_ca_slot_info; |
468 | struct ca_caps *p_ca_caps; | 470 | struct ca_caps *p_ca_caps; |
469 | struct ca_msg *p_ca_message; | 471 | struct ca_msg *p_ca_message; |
472 | void __user *arg = (void __user *)ioctl_arg; | ||
473 | int result = 0; | ||
470 | 474 | ||
471 | if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { | 475 | if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { |
472 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); | 476 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); |
@@ -486,14 +490,16 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
486 | dprintk(verbose, DST_CA_INFO, 1, " Sending message"); | 490 | dprintk(verbose, DST_CA_INFO, 1, " Sending message"); |
487 | if ((ca_send_message(state, p_ca_message, arg)) < 0) { | 491 | if ((ca_send_message(state, p_ca_message, arg)) < 0) { |
488 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !"); | 492 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !"); |
489 | return -1; | 493 | result = -1; |
494 | goto free_mem_and_exit; | ||
490 | } | 495 | } |
491 | break; | 496 | break; |
492 | case CA_GET_MSG: | 497 | case CA_GET_MSG: |
493 | dprintk(verbose, DST_CA_INFO, 1, " Getting message"); | 498 | dprintk(verbose, DST_CA_INFO, 1, " Getting message"); |
494 | if ((ca_get_message(state, p_ca_message, arg)) < 0) { | 499 | if ((ca_get_message(state, p_ca_message, arg)) < 0) { |
495 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !"); | 500 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !"); |
496 | return -1; | 501 | result = -1; |
502 | goto free_mem_and_exit; | ||
497 | } | 503 | } |
498 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !"); | 504 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !"); |
499 | break; | 505 | break; |
@@ -506,7 +512,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
506 | dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info"); | 512 | dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info"); |
507 | if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { | 513 | if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { |
508 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !"); | 514 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !"); |
509 | return -1; | 515 | result = -1; |
516 | goto free_mem_and_exit; | ||
510 | } | 517 | } |
511 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !"); | 518 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !"); |
512 | break; | 519 | break; |
@@ -514,7 +521,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
514 | dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities"); | 521 | dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities"); |
515 | if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { | 522 | if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { |
516 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !"); | 523 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !"); |
517 | return -1; | 524 | result = -1; |
525 | goto free_mem_and_exit; | ||
518 | } | 526 | } |
519 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !"); | 527 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !"); |
520 | break; | 528 | break; |
@@ -522,7 +530,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
522 | dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description"); | 530 | dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description"); |
523 | if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { | 531 | if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { |
524 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !"); | 532 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !"); |
525 | return -1; | 533 | result = -1; |
534 | goto free_mem_and_exit; | ||
526 | } | 535 | } |
527 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !"); | 536 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !"); |
528 | break; | 537 | break; |
@@ -530,7 +539,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
530 | dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler"); | 539 | dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler"); |
531 | if ((ca_set_slot_descr()) < 0) { | 540 | if ((ca_set_slot_descr()) < 0) { |
532 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !"); | 541 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !"); |
533 | return -1; | 542 | result = -1; |
543 | goto free_mem_and_exit; | ||
534 | } | 544 | } |
535 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !"); | 545 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !"); |
536 | break; | 546 | break; |
@@ -538,14 +548,19 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
538 | dprintk(verbose, DST_CA_INFO, 1, " Setting PID"); | 548 | dprintk(verbose, DST_CA_INFO, 1, " Setting PID"); |
539 | if ((ca_set_pid()) < 0) { | 549 | if ((ca_set_pid()) < 0) { |
540 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !"); | 550 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !"); |
541 | return -1; | 551 | result = -1; |
552 | goto free_mem_and_exit; | ||
542 | } | 553 | } |
543 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !"); | 554 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !"); |
544 | default: | 555 | default: |
545 | return -EOPNOTSUPP; | 556 | result = -EOPNOTSUPP; |
546 | }; | 557 | }; |
558 | free_mem_and_exit: | ||
559 | kfree (p_ca_message); | ||
560 | kfree (p_ca_slot_info); | ||
561 | kfree (p_ca_caps); | ||
547 | 562 | ||
548 | return 0; | 563 | return result; |
549 | } | 564 | } |
550 | 565 | ||
551 | static int dst_ca_open(struct inode *inode, struct file *file) | 566 | static int dst_ca_open(struct inode *inode, struct file *file) |
@@ -582,7 +597,7 @@ static int dst_ca_write(struct file *file, const char __user *buffer, size_t len | |||
582 | 597 | ||
583 | static struct file_operations dst_ca_fops = { | 598 | static struct file_operations dst_ca_fops = { |
584 | .owner = THIS_MODULE, | 599 | .owner = THIS_MODULE, |
585 | .ioctl = (void *)dst_ca_ioctl, | 600 | .ioctl = dst_ca_ioctl, |
586 | .open = dst_ca_open, | 601 | .open = dst_ca_open, |
587 | .release = dst_ca_release, | 602 | .release = dst_ca_release, |
588 | .read = dst_ca_read, | 603 | .read = dst_ca_read, |
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h index 3281a6ca3685..81557f38fe38 100644 --- a/drivers/media/dvb/bt8xx/dst_common.h +++ b/drivers/media/dvb/bt8xx/dst_common.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #ifndef DST_COMMON_H | 22 | #ifndef DST_COMMON_H |
23 | #define DST_COMMON_H | 23 | #define DST_COMMON_H |
24 | 24 | ||
25 | #include <linux/smp_lock.h> | ||
25 | #include <linux/dvb/frontend.h> | 26 | #include <linux/dvb/frontend.h> |
26 | #include <linux/device.h> | 27 | #include <linux/device.h> |
27 | #include "bt878.h" | 28 | #include "bt878.h" |
@@ -49,6 +50,7 @@ | |||
49 | #define DST_TYPE_HAS_FW_BUILD 64 | 50 | #define DST_TYPE_HAS_FW_BUILD 64 |
50 | #define DST_TYPE_HAS_OBS_REGS 128 | 51 | #define DST_TYPE_HAS_OBS_REGS 128 |
51 | #define DST_TYPE_HAS_INC_COUNT 256 | 52 | #define DST_TYPE_HAS_INC_COUNT 256 |
53 | #define DST_TYPE_HAS_MULTI_FE 512 | ||
52 | 54 | ||
53 | /* Card capability list */ | 55 | /* Card capability list */ |
54 | 56 | ||
@@ -117,6 +119,9 @@ struct dst_state { | |||
117 | u8 fw_version[8]; | 119 | u8 fw_version[8]; |
118 | u8 card_info[8]; | 120 | u8 card_info[8]; |
119 | u8 vendor[8]; | 121 | u8 vendor[8]; |
122 | u8 board_info[8]; | ||
123 | |||
124 | struct semaphore dst_mutex; | ||
120 | }; | 125 | }; |
121 | 126 | ||
122 | struct dst_types { | 127 | struct dst_types { |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index c5c7672cd538..2e398090cf63 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "dvb_frontend.h" | 34 | #include "dvb_frontend.h" |
35 | #include "dvb-bt8xx.h" | 35 | #include "dvb-bt8xx.h" |
36 | #include "bt878.h" | 36 | #include "bt878.h" |
37 | #include "dvb-pll.h" | ||
37 | 38 | ||
38 | static int debug; | 39 | static int debug; |
39 | 40 | ||
@@ -279,7 +280,7 @@ static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_front | |||
279 | data[0] = (div >> 8) & 0x7f; | 280 | data[0] = (div >> 8) & 0x7f; |
280 | data[1] = div & 0xff; | 281 | data[1] = div & 0xff; |
281 | data[2] = ((div >> 10) & 0x60) | cfg; | 282 | data[2] = ((div >> 10) & 0x60) | cfg; |
282 | data[3] = cpump | band_select; | 283 | data[3] = (cpump << 6) | band_select; |
283 | 284 | ||
284 | i2c_transfer(card->i2c_adapter, &msg, 1); | 285 | i2c_transfer(card->i2c_adapter, &msg, 1); |
285 | return (div * 166666 - 36000000); | 286 | return (div * 166666 - 36000000); |
@@ -522,9 +523,7 @@ static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) | |||
522 | /* | 523 | /* |
523 | * Reset the frontend, must be called before trying | 524 | * Reset the frontend, must be called before trying |
524 | * to initialise the MT352 or mt352_attach | 525 | * to initialise the MT352 or mt352_attach |
525 | * will fail. | 526 | * will fail. Same goes for the nxt6000 frontend. |
526 | * | ||
527 | * Presumably not required for the NXT6000 frontend. | ||
528 | * | 527 | * |
529 | */ | 528 | */ |
530 | 529 | ||
@@ -546,14 +545,63 @@ static struct mt352_config digitv_alps_tded4_config = { | |||
546 | .pll_set = digitv_alps_tded4_pll_set, | 545 | .pll_set = digitv_alps_tded4_pll_set, |
547 | }; | 546 | }; |
548 | 547 | ||
548 | static int tdvs_tua6034_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | ||
549 | { | ||
550 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; | ||
551 | u8 buf[4]; | ||
552 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
553 | int err; | ||
554 | |||
555 | dvb_pll_configure(&dvb_pll_tdvs_tua6034, buf, params->frequency, 0); | ||
556 | dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
557 | __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); | ||
558 | if ((err = i2c_transfer(card->i2c_adapter, &msg, 1)) != 1) { | ||
559 | printk(KERN_WARNING "dvb-bt8xx: %s error " | ||
560 | "(addr %02x <- %02x, err = %i)\n", | ||
561 | __FUNCTION__, buf[0], buf[1], err); | ||
562 | if (err < 0) | ||
563 | return err; | ||
564 | else | ||
565 | return -EREMOTEIO; | ||
566 | } | ||
567 | |||
568 | /* Set the Auxiliary Byte. */ | ||
569 | buf[2] &= ~0x20; | ||
570 | buf[2] |= 0x18; | ||
571 | buf[3] = 0x50; | ||
572 | i2c_transfer(card->i2c_adapter, &msg, 1); | ||
573 | |||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static struct lgdt330x_config tdvs_tua6034_config = { | ||
578 | .demod_address = 0x0e, | ||
579 | .demod_chip = LGDT3303, | ||
580 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ | ||
581 | .pll_set = tdvs_tua6034_pll_set, | ||
582 | }; | ||
583 | |||
584 | static void lgdt330x_reset(struct dvb_bt8xx_card *bt) | ||
585 | { | ||
586 | /* Set pin 27 of the lgdt3303 chip high to reset the frontend */ | ||
587 | |||
588 | /* Pulse the reset line */ | ||
589 | bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */ | ||
590 | bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low */ | ||
591 | msleep(100); | ||
592 | |||
593 | bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */ | ||
594 | msleep(100); | ||
595 | } | ||
596 | |||
549 | static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | 597 | static void frontend_init(struct dvb_bt8xx_card *card, u32 type) |
550 | { | 598 | { |
551 | int ret; | 599 | int ret; |
552 | struct dst_state* state = NULL; | 600 | struct dst_state* state = NULL; |
553 | 601 | ||
554 | switch(type) { | 602 | switch(type) { |
555 | #ifdef BTTV_DVICO_DVBT_LITE | 603 | #ifdef BTTV_BOARD_DVICO_DVBT_LITE |
556 | case BTTV_DVICO_DVBT_LITE: | 604 | case BTTV_BOARD_DVICO_DVBT_LITE: |
557 | card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); | 605 | card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); |
558 | if (card->fe != NULL) { | 606 | if (card->fe != NULL) { |
559 | card->fe->ops->info.frequency_min = 174000000; | 607 | card->fe->ops->info.frequency_min = 174000000; |
@@ -562,10 +610,19 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
562 | break; | 610 | break; |
563 | #endif | 611 | #endif |
564 | 612 | ||
565 | #ifdef BTTV_TWINHAN_VP3021 | 613 | #ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE |
566 | case BTTV_TWINHAN_VP3021: | 614 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: |
615 | lgdt330x_reset(card); | ||
616 | card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); | ||
617 | if (card->fe != NULL) | ||
618 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); | ||
619 | break; | ||
620 | #endif | ||
621 | |||
622 | #ifdef BTTV_BOARD_TWINHAN_VP3021 | ||
623 | case BTTV_BOARD_TWINHAN_VP3021: | ||
567 | #else | 624 | #else |
568 | case BTTV_NEBULA_DIGITV: | 625 | case BTTV_BOARD_NEBULA_DIGITV: |
569 | #endif | 626 | #endif |
570 | /* | 627 | /* |
571 | * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); | 628 | * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); |
@@ -573,6 +630,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
573 | */ | 630 | */ |
574 | 631 | ||
575 | /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */ | 632 | /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */ |
633 | digitv_alps_tded4_reset(card); | ||
576 | card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); | 634 | card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); |
577 | if (card->fe != NULL) { | 635 | if (card->fe != NULL) { |
578 | dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); | 636 | dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); |
@@ -587,11 +645,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
587 | dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); | 645 | dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); |
588 | break; | 646 | break; |
589 | 647 | ||
590 | case BTTV_AVDVBT_761: | 648 | case BTTV_BOARD_AVDVBT_761: |
591 | card->fe = sp887x_attach(µtune_mt7202dtf_config, card->i2c_adapter); | 649 | card->fe = sp887x_attach(µtune_mt7202dtf_config, card->i2c_adapter); |
592 | break; | 650 | break; |
593 | 651 | ||
594 | case BTTV_AVDVBT_771: | 652 | case BTTV_BOARD_AVDVBT_771: |
595 | card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); | 653 | card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); |
596 | if (card->fe != NULL) { | 654 | if (card->fe != NULL) { |
597 | card->fe->ops->info.frequency_min = 174000000; | 655 | card->fe->ops->info.frequency_min = 174000000; |
@@ -599,7 +657,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
599 | } | 657 | } |
600 | break; | 658 | break; |
601 | 659 | ||
602 | case BTTV_TWINHAN_DST: | 660 | case BTTV_BOARD_TWINHAN_DST: |
603 | /* DST is not a frontend driver !!! */ | 661 | /* DST is not a frontend driver !!! */ |
604 | state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); | 662 | state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); |
605 | /* Setup the Card */ | 663 | /* Setup the Card */ |
@@ -620,11 +678,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
620 | ret = dst_ca_attach(state, &card->dvb_adapter); | 678 | ret = dst_ca_attach(state, &card->dvb_adapter); |
621 | break; | 679 | break; |
622 | 680 | ||
623 | case BTTV_PINNACLESAT: | 681 | case BTTV_BOARD_PINNACLESAT: |
624 | card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); | 682 | card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); |
625 | break; | 683 | break; |
626 | 684 | ||
627 | case BTTV_PC_HDTV: | 685 | case BTTV_BOARD_PC_HDTV: |
628 | card->fe = or51211_attach(&or51211_config, card->i2c_adapter); | 686 | card->fe = or51211_attach(&or51211_config, card->i2c_adapter); |
629 | break; | 687 | break; |
630 | } | 688 | } |
@@ -746,7 +804,7 @@ static int dvb_bt8xx_probe(struct device *dev) | |||
746 | card->i2c_adapter = &sub->core->i2c_adap; | 804 | card->i2c_adapter = &sub->core->i2c_adap; |
747 | 805 | ||
748 | switch(sub->core->type) { | 806 | switch(sub->core->type) { |
749 | case BTTV_PINNACLESAT: | 807 | case BTTV_BOARD_PINNACLESAT: |
750 | card->gpio_mode = 0x0400c060; | 808 | card->gpio_mode = 0x0400c060; |
751 | /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, | 809 | /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, |
752 | BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ | 810 | BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ |
@@ -754,8 +812,8 @@ static int dvb_bt8xx_probe(struct device *dev) | |||
754 | card->irq_err_ignore = 0; | 812 | card->irq_err_ignore = 0; |
755 | break; | 813 | break; |
756 | 814 | ||
757 | #ifdef BTTV_DVICO_DVBT_LITE | 815 | #ifdef BTTV_BOARD_DVICO_DVBT_LITE |
758 | case BTTV_DVICO_DVBT_LITE: | 816 | case BTTV_BOARD_DVICO_DVBT_LITE: |
759 | #endif | 817 | #endif |
760 | card->gpio_mode = 0x0400C060; | 818 | card->gpio_mode = 0x0400C060; |
761 | card->op_sync_orin = 0; | 819 | card->op_sync_orin = 0; |
@@ -765,26 +823,34 @@ static int dvb_bt8xx_probe(struct device *dev) | |||
765 | * DA_APP(parallel) */ | 823 | * DA_APP(parallel) */ |
766 | break; | 824 | break; |
767 | 825 | ||
768 | #ifdef BTTV_TWINHAN_VP3021 | 826 | #ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE |
769 | case BTTV_TWINHAN_VP3021: | 827 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: |
828 | #endif | ||
829 | card->gpio_mode = 0x0400c060; | ||
830 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | ||
831 | card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; | ||
832 | break; | ||
833 | |||
834 | #ifdef BTTV_BOARD_TWINHAN_VP3021 | ||
835 | case BTTV_BOARD_TWINHAN_VP3021: | ||
770 | #else | 836 | #else |
771 | case BTTV_NEBULA_DIGITV: | 837 | case BTTV_BOARD_NEBULA_DIGITV: |
772 | #endif | 838 | #endif |
773 | case BTTV_AVDVBT_761: | 839 | case BTTV_BOARD_AVDVBT_761: |
774 | card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); | 840 | card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); |
775 | card->op_sync_orin = 0; | 841 | card->op_sync_orin = 0; |
776 | card->irq_err_ignore = 0; | 842 | card->irq_err_ignore = 0; |
777 | /* A_PWRDN DA_SBR DA_APP (high speed serial) */ | 843 | /* A_PWRDN DA_SBR DA_APP (high speed serial) */ |
778 | break; | 844 | break; |
779 | 845 | ||
780 | case BTTV_AVDVBT_771: //case 0x07711461: | 846 | case BTTV_BOARD_AVDVBT_771: //case 0x07711461: |
781 | card->gpio_mode = 0x0400402B; | 847 | card->gpio_mode = 0x0400402B; |
782 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | 848 | card->op_sync_orin = BT878_RISC_SYNC_MASK; |
783 | card->irq_err_ignore = 0; | 849 | card->irq_err_ignore = 0; |
784 | /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ | 850 | /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ |
785 | break; | 851 | break; |
786 | 852 | ||
787 | case BTTV_TWINHAN_DST: | 853 | case BTTV_BOARD_TWINHAN_DST: |
788 | card->gpio_mode = 0x2204f2c; | 854 | card->gpio_mode = 0x2204f2c; |
789 | card->op_sync_orin = BT878_RISC_SYNC_MASK; | 855 | card->op_sync_orin = BT878_RISC_SYNC_MASK; |
790 | card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR | | 856 | card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR | |
@@ -802,7 +868,7 @@ static int dvb_bt8xx_probe(struct device *dev) | |||
802 | * RISC+FIFO ENABLE */ | 868 | * RISC+FIFO ENABLE */ |
803 | break; | 869 | break; |
804 | 870 | ||
805 | case BTTV_PC_HDTV: | 871 | case BTTV_BOARD_PC_HDTV: |
806 | card->gpio_mode = 0x0100EC7B; | 872 | card->gpio_mode = 0x0100EC7B; |
807 | card->op_sync_orin = 0; | 873 | card->op_sync_orin = 0; |
808 | card->irq_err_ignore = 0; | 874 | card->irq_err_ignore = 0; |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h index 9ec8e5bd6c1f..cf035a80361c 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #include "nxt6000.h" | 35 | #include "nxt6000.h" |
36 | #include "cx24110.h" | 36 | #include "cx24110.h" |
37 | #include "or51211.h" | 37 | #include "or51211.h" |
38 | #include "lgdt330x.h" | ||
38 | 39 | ||
39 | struct dvb_bt8xx_card { | 40 | struct dvb_bt8xx_card { |
40 | struct semaphore lock; | 41 | struct semaphore lock; |
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h index 9719a3b30f78..7d7b0067f228 100644 --- a/drivers/media/dvb/dvb-core/demux.h +++ b/drivers/media/dvb/dvb-core/demux.h | |||
@@ -48,8 +48,11 @@ | |||
48 | * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter. | 48 | * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter. |
49 | */ | 49 | */ |
50 | 50 | ||
51 | #ifndef DMX_MAX_SECTION_SIZE | ||
52 | #define DMX_MAX_SECTION_SIZE 4096 | ||
53 | #endif | ||
51 | #ifndef DMX_MAX_SECFEED_SIZE | 54 | #ifndef DMX_MAX_SECFEED_SIZE |
52 | #define DMX_MAX_SECFEED_SIZE 4096 | 55 | #define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188) |
53 | #endif | 56 | #endif |
54 | 57 | ||
55 | 58 | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index dc476dda2b71..b4c899b15959 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c | |||
@@ -246,7 +246,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, | |||
246 | 246 | ||
247 | for (n = 0; sec->secbufp + 2 < limit; n++) { | 247 | for (n = 0; sec->secbufp + 2 < limit; n++) { |
248 | seclen = section_length(sec->secbuf); | 248 | seclen = section_length(sec->secbuf); |
249 | if (seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE | 249 | if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE |
250 | || seclen + sec->secbufp > limit) | 250 | || seclen + sec->secbufp > limit) |
251 | return 0; | 251 | return 0; |
252 | sec->seclen = seclen; | 252 | sec->seclen = seclen; |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index a8bc84240b50..6ffa6b216363 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -42,8 +42,6 @@ | |||
42 | #include "dvb_frontend.h" | 42 | #include "dvb_frontend.h" |
43 | #include "dvbdev.h" | 43 | #include "dvbdev.h" |
44 | 44 | ||
45 | // #define DEBUG_LOCKLOSS 1 | ||
46 | |||
47 | static int dvb_frontend_debug; | 45 | static int dvb_frontend_debug; |
48 | static int dvb_shutdown_timeout = 5; | 46 | static int dvb_shutdown_timeout = 5; |
49 | static int dvb_force_auto_inversion; | 47 | static int dvb_force_auto_inversion; |
@@ -438,25 +436,6 @@ static int dvb_frontend_thread(void *data) | |||
438 | if (s & FE_HAS_LOCK) | 436 | if (s & FE_HAS_LOCK) |
439 | continue; | 437 | continue; |
440 | else { /* if we _WERE_ tuned, but now don't have a lock */ | 438 | else { /* if we _WERE_ tuned, but now don't have a lock */ |
441 | #ifdef DEBUG_LOCKLOSS | ||
442 | /* first of all try setting the tone again if it was on - this | ||
443 | * sometimes works around problems with noisy power supplies */ | ||
444 | if (fe->ops->set_tone && (fepriv->tone == SEC_TONE_ON)) { | ||
445 | fe->ops->set_tone(fe, fepriv->tone); | ||
446 | mdelay(100); | ||
447 | s = 0; | ||
448 | fe->ops->read_status(fe, &s); | ||
449 | if (s & FE_HAS_LOCK) { | ||
450 | printk("DVB%i: Lock was lost, but regained by setting " | ||
451 | "the tone. This may indicate your power supply " | ||
452 | "is noisy/slightly incompatable with this DVB-S " | ||
453 | "adapter\n", fe->dvb->num); | ||
454 | fepriv->state = FESTATE_TUNED; | ||
455 | continue; | ||
456 | } | ||
457 | } | ||
458 | #endif | ||
459 | /* some other reason for losing the lock - start zigzagging */ | ||
460 | fepriv->state = FESTATE_ZIGZAG_FAST; | 439 | fepriv->state = FESTATE_ZIGZAG_FAST; |
461 | fepriv->started_auto_step = fepriv->auto_step; | 440 | fepriv->started_auto_step = fepriv->auto_step; |
462 | check_wrapped = 0; | 441 | check_wrapped = 0; |
@@ -577,6 +556,49 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) | |||
577 | fepriv->thread_pid); | 556 | fepriv->thread_pid); |
578 | } | 557 | } |
579 | 558 | ||
559 | s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime) | ||
560 | { | ||
561 | return ((curtime.tv_usec < lasttime.tv_usec) ? | ||
562 | 1000000 - lasttime.tv_usec + curtime.tv_usec : | ||
563 | curtime.tv_usec - lasttime.tv_usec); | ||
564 | } | ||
565 | EXPORT_SYMBOL(timeval_usec_diff); | ||
566 | |||
567 | static inline void timeval_usec_add(struct timeval *curtime, u32 add_usec) | ||
568 | { | ||
569 | curtime->tv_usec += add_usec; | ||
570 | if (curtime->tv_usec >= 1000000) { | ||
571 | curtime->tv_usec -= 1000000; | ||
572 | curtime->tv_sec++; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | /* | ||
577 | * Sleep until gettimeofday() > waketime + add_usec | ||
578 | * This needs to be as precise as possible, but as the delay is | ||
579 | * usually between 2ms and 32ms, it is done using a scheduled msleep | ||
580 | * followed by usleep (normally a busy-wait loop) for the remainder | ||
581 | */ | ||
582 | void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec) | ||
583 | { | ||
584 | struct timeval lasttime; | ||
585 | s32 delta, newdelta; | ||
586 | |||
587 | timeval_usec_add(waketime, add_usec); | ||
588 | |||
589 | do_gettimeofday(&lasttime); | ||
590 | delta = timeval_usec_diff(lasttime, *waketime); | ||
591 | if (delta > 2500) { | ||
592 | msleep((delta - 1500) / 1000); | ||
593 | do_gettimeofday(&lasttime); | ||
594 | newdelta = timeval_usec_diff(lasttime, *waketime); | ||
595 | delta = (newdelta > delta) ? 0 : newdelta; | ||
596 | } | ||
597 | if (delta > 0) | ||
598 | udelay(delta); | ||
599 | } | ||
600 | EXPORT_SYMBOL(dvb_frontend_sleep_until); | ||
601 | |||
580 | static int dvb_frontend_start(struct dvb_frontend *fe) | 602 | static int dvb_frontend_start(struct dvb_frontend *fe) |
581 | { | 603 | { |
582 | int ret; | 604 | int ret; |
@@ -728,6 +750,60 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
728 | err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg); | 750 | err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg); |
729 | fepriv->state = FESTATE_DISEQC; | 751 | fepriv->state = FESTATE_DISEQC; |
730 | fepriv->status = 0; | 752 | fepriv->status = 0; |
753 | } else if (fe->ops->set_voltage) { | ||
754 | /* | ||
755 | * NOTE: This is a fallback condition. Some frontends | ||
756 | * (stv0299 for instance) take longer than 8msec to | ||
757 | * respond to a set_voltage command. Those switches | ||
758 | * need custom routines to switch properly. For all | ||
759 | * other frontends, the following shoule work ok. | ||
760 | * Dish network legacy switches (as used by Dish500) | ||
761 | * are controlled by sending 9-bit command words | ||
762 | * spaced 8msec apart. | ||
763 | * the actual command word is switch/port dependant | ||
764 | * so it is up to the userspace application to send | ||
765 | * the right command. | ||
766 | * The command must always start with a '0' after | ||
767 | * initialization, so parg is 8 bits and does not | ||
768 | * include the initialization or start bit | ||
769 | */ | ||
770 | unsigned int cmd = ((unsigned int) parg) << 1; | ||
771 | struct timeval nexttime; | ||
772 | struct timeval tv[10]; | ||
773 | int i; | ||
774 | u8 last = 1; | ||
775 | if (dvb_frontend_debug) | ||
776 | printk("%s switch command: 0x%04x\n", __FUNCTION__, cmd); | ||
777 | do_gettimeofday(&nexttime); | ||
778 | if (dvb_frontend_debug) | ||
779 | memcpy(&tv[0], &nexttime, sizeof(struct timeval)); | ||
780 | /* before sending a command, initialize by sending | ||
781 | * a 32ms 18V to the switch | ||
782 | */ | ||
783 | fe->ops->set_voltage(fe, SEC_VOLTAGE_18); | ||
784 | dvb_frontend_sleep_until(&nexttime, 32000); | ||
785 | |||
786 | for (i = 0; i < 9; i++) { | ||
787 | if (dvb_frontend_debug) | ||
788 | do_gettimeofday(&tv[i + 1]); | ||
789 | if ((cmd & 0x01) != last) { | ||
790 | /* set voltage to (last ? 13V : 18V) */ | ||
791 | fe->ops->set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); | ||
792 | last = (last) ? 0 : 1; | ||
793 | } | ||
794 | cmd = cmd >> 1; | ||
795 | if (i != 8) | ||
796 | dvb_frontend_sleep_until(&nexttime, 8000); | ||
797 | } | ||
798 | if (dvb_frontend_debug) { | ||
799 | printk("%s(%d): switch delay (should be 32k followed by all 8k\n", | ||
800 | __FUNCTION__, fe->dvb->num); | ||
801 | for (i = 1; i < 10; i++) | ||
802 | printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i])); | ||
803 | } | ||
804 | err = 0; | ||
805 | fepriv->state = FESTATE_DISEQC; | ||
806 | fepriv->status = 0; | ||
731 | } | 807 | } |
732 | break; | 808 | break; |
733 | 809 | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 9c2c1d1136bd..348c9b0b988a 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h | |||
@@ -101,4 +101,7 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb, | |||
101 | 101 | ||
102 | extern int dvb_unregister_frontend(struct dvb_frontend* fe); | 102 | extern int dvb_unregister_frontend(struct dvb_frontend* fe); |
103 | 103 | ||
104 | extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec); | ||
105 | extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime); | ||
106 | |||
104 | #endif | 107 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c index e55322ef76b3..49f541d9a042 100644 --- a/drivers/media/dvb/dvb-usb/a800.c +++ b/drivers/media/dvb/dvb-usb/a800.c | |||
@@ -43,11 +43,9 @@ static struct dvb_usb_rc_key a800_rc_keys[] = { | |||
43 | { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */ | 43 | { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */ |
44 | { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */ | 44 | { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */ |
45 | { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */ | 45 | { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */ |
46 | { 0x02, 0x03, KEY_CHANNELUP }, /* CH UP */ | ||
47 | { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */ | 46 | { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */ |
48 | { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */ | 47 | { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */ |
49 | { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */ | 48 | { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */ |
50 | { 0x02, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */ | ||
51 | { 0x02, 0x14, KEY_MUTE }, /* MUTE */ | 49 | { 0x02, 0x14, KEY_MUTE }, /* MUTE */ |
52 | { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */ | 50 | { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */ |
53 | { 0x02, 0x19, KEY_RECORD }, /* RECORD */ | 51 | { 0x02, 0x19, KEY_RECORD }, /* RECORD */ |
@@ -57,8 +55,6 @@ static struct dvb_usb_rc_key a800_rc_keys[] = { | |||
57 | { 0x02, 0x1d, KEY_BACK }, /* << / RED */ | 55 | { 0x02, 0x1d, KEY_BACK }, /* << / RED */ |
58 | { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */ | 56 | { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */ |
59 | { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */ | 57 | { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */ |
60 | { 0x02, 0x01, KEY_FIRST }, /* |<< / GREEN */ | ||
61 | { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */ | ||
62 | { 0x02, 0x04, KEY_EPG }, /* EPG */ | 58 | { 0x02, 0x04, KEY_EPG }, /* EPG */ |
63 | { 0x02, 0x15, KEY_MENU }, /* MENU */ | 59 | { 0x02, 0x15, KEY_MENU }, /* MENU */ |
64 | 60 | ||
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index 0058505634a0..aa271a2496d5 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c | |||
@@ -82,13 +82,15 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d) | |||
82 | static struct dvb_usb_properties dibusb1_1_properties; | 82 | static struct dvb_usb_properties dibusb1_1_properties; |
83 | static struct dvb_usb_properties dibusb1_1_an2235_properties; | 83 | static struct dvb_usb_properties dibusb1_1_an2235_properties; |
84 | static struct dvb_usb_properties dibusb2_0b_properties; | 84 | static struct dvb_usb_properties dibusb2_0b_properties; |
85 | static struct dvb_usb_properties artec_t1_usb2_properties; | ||
85 | 86 | ||
86 | static int dibusb_probe(struct usb_interface *intf, | 87 | static int dibusb_probe(struct usb_interface *intf, |
87 | const struct usb_device_id *id) | 88 | const struct usb_device_id *id) |
88 | { | 89 | { |
89 | if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 || | 90 | if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 || |
90 | dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 || | 91 | dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 || |
91 | dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0) | 92 | dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0 || |
93 | dvb_usb_device_init(intf,&artec_t1_usb2_properties,THIS_MODULE,NULL) == 0) | ||
92 | return 0; | 94 | return 0; |
93 | 95 | ||
94 | return -EINVAL; | 96 | return -EINVAL; |
@@ -128,10 +130,13 @@ static struct usb_device_id dibusb_dib3000mb_table [] = { | |||
128 | 130 | ||
129 | /* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, | 131 | /* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, |
130 | 132 | ||
133 | /* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, | ||
134 | /* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, | ||
135 | |||
131 | // #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs | 136 | // #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs |
132 | 137 | ||
133 | #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs | 138 | #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs |
134 | /* 28 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, | 139 | /* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, |
135 | #endif | 140 | #endif |
136 | { } /* Terminating entry */ | 141 | { } /* Terminating entry */ |
137 | }; | 142 | }; |
@@ -264,7 +269,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { | |||
264 | }, | 269 | }, |
265 | #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs | 270 | #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs |
266 | { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", | 271 | { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", |
267 | { &dibusb_dib3000mb_table[28], NULL }, | 272 | { &dibusb_dib3000mb_table[30], NULL }, |
268 | { NULL }, | 273 | { NULL }, |
269 | }, | 274 | }, |
270 | #endif | 275 | #endif |
@@ -273,7 +278,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { | |||
273 | 278 | ||
274 | static struct dvb_usb_properties dibusb2_0b_properties = { | 279 | static struct dvb_usb_properties dibusb2_0b_properties = { |
275 | .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, | 280 | .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, |
276 | .pid_filter_count = 32, | 281 | .pid_filter_count = 16, |
277 | 282 | ||
278 | .usb_ctrl = CYPRESS_FX2, | 283 | .usb_ctrl = CYPRESS_FX2, |
279 | 284 | ||
@@ -321,6 +326,52 @@ static struct dvb_usb_properties dibusb2_0b_properties = { | |||
321 | } | 326 | } |
322 | }; | 327 | }; |
323 | 328 | ||
329 | static struct dvb_usb_properties artec_t1_usb2_properties = { | ||
330 | .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, | ||
331 | .pid_filter_count = 16, | ||
332 | |||
333 | .usb_ctrl = CYPRESS_FX2, | ||
334 | |||
335 | .firmware = "dvb-usb-dibusb-6.0.0.8.fw", | ||
336 | |||
337 | .size_of_priv = sizeof(struct dibusb_state), | ||
338 | |||
339 | .streaming_ctrl = dibusb2_0_streaming_ctrl, | ||
340 | .pid_filter = dibusb_pid_filter, | ||
341 | .pid_filter_ctrl = dibusb_pid_filter_ctrl, | ||
342 | .power_ctrl = dibusb2_0_power_ctrl, | ||
343 | .frontend_attach = dibusb_dib3000mb_frontend_attach, | ||
344 | .tuner_attach = dibusb_tuner_probe_and_attach, | ||
345 | |||
346 | .rc_interval = DEFAULT_RC_INTERVAL, | ||
347 | .rc_key_map = dibusb_rc_keys, | ||
348 | .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */ | ||
349 | .rc_query = dibusb_rc_query, | ||
350 | |||
351 | .i2c_algo = &dibusb_i2c_algo, | ||
352 | |||
353 | .generic_bulk_ctrl_endpoint = 0x01, | ||
354 | /* parameter for the MPEG2-data transfer */ | ||
355 | .urb = { | ||
356 | .type = DVB_USB_BULK, | ||
357 | .count = 7, | ||
358 | .endpoint = 0x06, | ||
359 | .u = { | ||
360 | .bulk = { | ||
361 | .buffersize = 4096, | ||
362 | } | ||
363 | } | ||
364 | }, | ||
365 | |||
366 | .num_device_descs = 1, | ||
367 | .devices = { | ||
368 | { "Artec T1 USB2.0", | ||
369 | { &dibusb_dib3000mb_table[28], NULL }, | ||
370 | { &dibusb_dib3000mb_table[29], NULL }, | ||
371 | }, | ||
372 | } | ||
373 | }; | ||
374 | |||
324 | static struct usb_driver dibusb_driver = { | 375 | static struct usb_driver dibusb_driver = { |
325 | .owner = THIS_MODULE, | 376 | .owner = THIS_MODULE, |
326 | .name = "dvb_usb_dibusb_mb", | 377 | .name = "dvb_usb_dibusb_mb", |
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h index 6611f62977c0..2d99d05c7eab 100644 --- a/drivers/media/dvb/dvb-usb/dibusb.h +++ b/drivers/media/dvb/dvb-usb/dibusb.h | |||
@@ -11,7 +11,9 @@ | |||
11 | #ifndef _DVB_USB_DIBUSB_H_ | 11 | #ifndef _DVB_USB_DIBUSB_H_ |
12 | #define _DVB_USB_DIBUSB_H_ | 12 | #define _DVB_USB_DIBUSB_H_ |
13 | 13 | ||
14 | #define DVB_USB_LOG_PREFIX "dibusb" | 14 | #ifndef DVB_USB_LOG_PREFIX |
15 | #define DVB_USB_LOG_PREFIX "dibusb" | ||
16 | #endif | ||
15 | #include "dvb-usb.h" | 17 | #include "dvb-usb.h" |
16 | 18 | ||
17 | #include "dib3000.h" | 19 | #include "dib3000.h" |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 0818996bf150..6be99e537e12 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | |||
@@ -43,10 +43,14 @@ | |||
43 | #define USB_PID_COMPRO_DVBU2000_WARM 0xd001 | 43 | #define USB_PID_COMPRO_DVBU2000_WARM 0xd001 |
44 | #define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c | 44 | #define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c |
45 | #define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d | 45 | #define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d |
46 | #define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064 | ||
47 | #define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065 | ||
46 | #define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 | 48 | #define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 |
47 | #define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9 | 49 | #define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9 |
48 | #define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6 | 50 | #define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6 |
49 | #define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7 | 51 | #define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7 |
52 | #define USB_PID_DIBCOM_STK7700 0x1e14 | ||
53 | #define USB_PID_DIBCOM_STK7700_REENUM 0x1e15 | ||
50 | #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 | 54 | #define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 |
51 | #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 | 55 | #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 |
52 | #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 | 56 | #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 |
@@ -68,6 +72,7 @@ | |||
68 | #define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108 | 72 | #define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108 |
69 | #define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235 | 73 | #define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235 |
70 | #define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109 | 74 | #define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109 |
75 | #define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a | ||
71 | #define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613 | 76 | #define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613 |
72 | #define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002 | 77 | #define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002 |
73 | #define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e | 78 | #define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c index f5799a4c228e..36b7048c02d2 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c | |||
@@ -196,7 +196,9 @@ static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, un | |||
196 | dvb_usb_free_stream_buffers(d); | 196 | dvb_usb_free_stream_buffers(d); |
197 | return -ENOMEM; | 197 | return -ENOMEM; |
198 | } | 198 | } |
199 | deb_mem("buffer %d: %p (dma: %d)\n",d->buf_num,d->buf_list[d->buf_num],d->dma_addr[d->buf_num]); | 199 | deb_mem("buffer %d: %p (dma: %llu)\n", |
200 | d->buf_num, d->buf_list[d->buf_num], | ||
201 | (unsigned long long)d->dma_addr[d->buf_num]); | ||
200 | memset(d->buf_list[d->buf_num],0,size); | 202 | memset(d->buf_list[d->buf_num],0,size); |
201 | } | 203 | } |
202 | deb_mem("allocation successful\n"); | 204 | deb_mem("allocation successful\n"); |
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index a50a41f6f79d..8e269e1c1f9d 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -164,6 +164,14 @@ config DVB_NXT2002 | |||
164 | help | 164 | help |
165 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. | 165 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. |
166 | 166 | ||
167 | config DVB_NXT200X | ||
168 | tristate "Nextwave NXT2002/NXT2004 based" | ||
169 | depends on DVB_CORE | ||
170 | select FW_LOADER | ||
171 | help | ||
172 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | ||
173 | to support this frontend. | ||
174 | |||
167 | config DVB_OR51211 | 175 | config DVB_OR51211 |
168 | tristate "or51211 based (pcHDTV HD2000 card)" | 176 | tristate "or51211 based (pcHDTV HD2000 card)" |
169 | depends on DVB_CORE | 177 | depends on DVB_CORE |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index ad8658ffd60a..a98760fe08a1 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -26,6 +26,7 @@ obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o | |||
26 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o | 26 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o |
27 | obj-$(CONFIG_DVB_STV0297) += stv0297.o | 27 | obj-$(CONFIG_DVB_STV0297) += stv0297.o |
28 | obj-$(CONFIG_DVB_NXT2002) += nxt2002.o | 28 | obj-$(CONFIG_DVB_NXT2002) += nxt2002.o |
29 | obj-$(CONFIG_DVB_NXT200X) += nxt200x.o | ||
29 | obj-$(CONFIG_DVB_OR51211) += or51211.o | 30 | obj-$(CONFIG_DVB_OR51211) += or51211.o |
30 | obj-$(CONFIG_DVB_OR51132) += or51132.o | 31 | obj-$(CONFIG_DVB_OR51132) += or51132.o |
31 | obj-$(CONFIG_DVB_BCM3510) += bcm3510.o | 32 | obj-$(CONFIG_DVB_BCM3510) += bcm3510.o |
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 536c35d969b7..f857b869616c 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
@@ -226,7 +226,7 @@ struct dvb_pll_desc dvb_pll_tua6034 = { | |||
226 | EXPORT_SYMBOL(dvb_pll_tua6034); | 226 | EXPORT_SYMBOL(dvb_pll_tua6034); |
227 | 227 | ||
228 | /* Infineon TUA6034 | 228 | /* Infineon TUA6034 |
229 | * used in LG Innotek TDVS-H062F | 229 | * used in LG TDVS H061F and LG TDVS H062F |
230 | */ | 230 | */ |
231 | struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { | 231 | struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { |
232 | .name = "LG/Infineon TUA6034", | 232 | .name = "LG/Infineon TUA6034", |
@@ -292,6 +292,58 @@ struct dvb_pll_desc dvb_pll_tded4 = { | |||
292 | }; | 292 | }; |
293 | EXPORT_SYMBOL(dvb_pll_tded4); | 293 | EXPORT_SYMBOL(dvb_pll_tded4); |
294 | 294 | ||
295 | /* ALPS TDHU2 | ||
296 | * used in AverTVHD MCE A180 | ||
297 | */ | ||
298 | struct dvb_pll_desc dvb_pll_tdhu2 = { | ||
299 | .name = "ALPS TDHU2", | ||
300 | .min = 54000000, | ||
301 | .max = 864000000, | ||
302 | .count = 4, | ||
303 | .entries = { | ||
304 | { 162000000, 44000000, 62500, 0x85, 0x01 }, | ||
305 | { 426000000, 44000000, 62500, 0x85, 0x02 }, | ||
306 | { 782000000, 44000000, 62500, 0x85, 0x08 }, | ||
307 | { 999999999, 44000000, 62500, 0x85, 0x88 }, | ||
308 | } | ||
309 | }; | ||
310 | EXPORT_SYMBOL(dvb_pll_tdhu2); | ||
311 | |||
312 | /* Philips TUV1236D | ||
313 | * used in ATI HDTV Wonder | ||
314 | */ | ||
315 | struct dvb_pll_desc dvb_pll_tuv1236d = { | ||
316 | .name = "Philips TUV1236D", | ||
317 | .min = 54000000, | ||
318 | .max = 864000000, | ||
319 | .count = 3, | ||
320 | .entries = { | ||
321 | { 157250000, 44000000, 62500, 0xc6, 0x41 }, | ||
322 | { 454000000, 44000000, 62500, 0xc6, 0x42 }, | ||
323 | { 999999999, 44000000, 62500, 0xc6, 0x44 }, | ||
324 | }, | ||
325 | }; | ||
326 | EXPORT_SYMBOL(dvb_pll_tuv1236d); | ||
327 | |||
328 | /* Samsung TBMV30111IN | ||
329 | * used in Air2PC ATSC - 2nd generation (nxt2002) | ||
330 | */ | ||
331 | struct dvb_pll_desc dvb_pll_tbmv30111in = { | ||
332 | .name = "Samsung TBMV30111IN", | ||
333 | .min = 54000000, | ||
334 | .max = 860000000, | ||
335 | .count = 4, | ||
336 | .entries = { | ||
337 | { 172000000, 44000000, 166666, 0xb4, 0x01 }, | ||
338 | { 214000000, 44000000, 166666, 0xb4, 0x02 }, | ||
339 | { 467000000, 44000000, 166666, 0xbc, 0x02 }, | ||
340 | { 721000000, 44000000, 166666, 0xbc, 0x08 }, | ||
341 | { 841000000, 44000000, 166666, 0xf4, 0x08 }, | ||
342 | { 999999999, 44000000, 166666, 0xfc, 0x02 }, | ||
343 | } | ||
344 | }; | ||
345 | EXPORT_SYMBOL(dvb_pll_tbmv30111in); | ||
346 | |||
295 | /* ----------------------------------------------------------- */ | 347 | /* ----------------------------------------------------------- */ |
296 | /* code */ | 348 | /* code */ |
297 | 349 | ||
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index 205b2d1a8852..497d31dcf41e 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
@@ -36,6 +36,10 @@ extern struct dvb_pll_desc dvb_pll_tda665x; | |||
36 | extern struct dvb_pll_desc dvb_pll_fmd1216me; | 36 | extern struct dvb_pll_desc dvb_pll_fmd1216me; |
37 | extern struct dvb_pll_desc dvb_pll_tded4; | 37 | extern struct dvb_pll_desc dvb_pll_tded4; |
38 | 38 | ||
39 | extern struct dvb_pll_desc dvb_pll_tuv1236d; | ||
40 | extern struct dvb_pll_desc dvb_pll_tdhu2; | ||
41 | extern struct dvb_pll_desc dvb_pll_tbmv30111in; | ||
42 | |||
39 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | 43 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, |
40 | u32 freq, int bandwidth); | 44 | u32 freq, int bandwidth); |
41 | 45 | ||
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index 7852b83b82d4..6a33f5a19a8d 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c | |||
@@ -26,6 +26,8 @@ | |||
26 | * DViCO FusionHDTV 3 Gold-Q | 26 | * DViCO FusionHDTV 3 Gold-Q |
27 | * DViCO FusionHDTV 3 Gold-T | 27 | * DViCO FusionHDTV 3 Gold-T |
28 | * DViCO FusionHDTV 5 Gold | 28 | * DViCO FusionHDTV 5 Gold |
29 | * DViCO FusionHDTV 5 Lite | ||
30 | * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) | ||
29 | * | 31 | * |
30 | * TODO: | 32 | * TODO: |
31 | * signal strength always returns 0. | 33 | * signal strength always returns 0. |
@@ -222,6 +224,11 @@ static int lgdt330x_init(struct dvb_frontend* fe) | |||
222 | 0x4c, 0x14 | 224 | 0x4c, 0x14 |
223 | }; | 225 | }; |
224 | 226 | ||
227 | static u8 flip_lgdt3303_init_data[] = { | ||
228 | 0x4c, 0x14, | ||
229 | 0x87, 0xf3 | ||
230 | }; | ||
231 | |||
225 | struct lgdt330x_state* state = fe->demodulator_priv; | 232 | struct lgdt330x_state* state = fe->demodulator_priv; |
226 | char *chip_name; | 233 | char *chip_name; |
227 | int err; | 234 | int err; |
@@ -234,8 +241,13 @@ static int lgdt330x_init(struct dvb_frontend* fe) | |||
234 | break; | 241 | break; |
235 | case LGDT3303: | 242 | case LGDT3303: |
236 | chip_name = "LGDT3303"; | 243 | chip_name = "LGDT3303"; |
237 | err = i2c_write_demod_bytes(state, lgdt3303_init_data, | 244 | if (state->config->clock_polarity_flip) { |
238 | sizeof(lgdt3303_init_data)); | 245 | err = i2c_write_demod_bytes(state, flip_lgdt3303_init_data, |
246 | sizeof(flip_lgdt3303_init_data)); | ||
247 | } else { | ||
248 | err = i2c_write_demod_bytes(state, lgdt3303_init_data, | ||
249 | sizeof(lgdt3303_init_data)); | ||
250 | } | ||
239 | break; | 251 | break; |
240 | default: | 252 | default: |
241 | chip_name = "undefined"; | 253 | chip_name = "undefined"; |
@@ -743,9 +755,8 @@ static struct dvb_frontend_ops lgdt3302_ops = { | |||
743 | .frequency_min= 54000000, | 755 | .frequency_min= 54000000, |
744 | .frequency_max= 858000000, | 756 | .frequency_max= 858000000, |
745 | .frequency_stepsize= 62500, | 757 | .frequency_stepsize= 62500, |
746 | /* Symbol rate is for all VSB modes need to check QAM */ | 758 | .symbol_rate_min = 5056941, /* QAM 64 */ |
747 | .symbol_rate_min = 10762000, | 759 | .symbol_rate_max = 10762000, /* VSB 8 */ |
748 | .symbol_rate_max = 10762000, | ||
749 | .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB | 760 | .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB |
750 | }, | 761 | }, |
751 | .init = lgdt330x_init, | 762 | .init = lgdt330x_init, |
@@ -767,9 +778,8 @@ static struct dvb_frontend_ops lgdt3303_ops = { | |||
767 | .frequency_min= 54000000, | 778 | .frequency_min= 54000000, |
768 | .frequency_max= 858000000, | 779 | .frequency_max= 858000000, |
769 | .frequency_stepsize= 62500, | 780 | .frequency_stepsize= 62500, |
770 | /* Symbol rate is for all VSB modes need to check QAM */ | 781 | .symbol_rate_min = 5056941, /* QAM 64 */ |
771 | .symbol_rate_min = 10762000, | 782 | .symbol_rate_max = 10762000, /* VSB 8 */ |
772 | .symbol_rate_max = 10762000, | ||
773 | .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB | 783 | .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB |
774 | }, | 784 | }, |
775 | .init = lgdt330x_init, | 785 | .init = lgdt330x_init, |
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h index e209ba1e47c5..2a6529cccf1a 100644 --- a/drivers/media/dvb/frontends/lgdt330x.h +++ b/drivers/media/dvb/frontends/lgdt330x.h | |||
@@ -47,6 +47,10 @@ struct lgdt330x_config | |||
47 | 47 | ||
48 | /* Need to set device param for start_dma */ | 48 | /* Need to set device param for start_dma */ |
49 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 49 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); |
50 | |||
51 | /* Flip the polarity of the mpeg data transfer clock using alternate init data | ||
52 | * This option applies ONLY to LGDT3303 - 0:disabled (default) 1:enabled */ | ||
53 | int clock_polarity_flip; | ||
50 | }; | 54 | }; |
51 | 55 | ||
52 | extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, | 56 | extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, |
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c new file mode 100644 index 000000000000..bad0933eb714 --- /dev/null +++ b/drivers/media/dvb/frontends/nxt200x.c | |||
@@ -0,0 +1,1205 @@ | |||
1 | /* | ||
2 | * Support for NXT2002 and NXT2004 - VSB/QAM | ||
3 | * | ||
4 | * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com) | ||
5 | * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> | ||
6 | * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | /* | ||
25 | * NOTES ABOUT THIS DRIVER | ||
26 | * | ||
27 | * This Linux driver supports: | ||
28 | * B2C2/BBTI Technisat Air2PC - ATSC (NXT2002) | ||
29 | * AverTVHD MCE A180 (NXT2004) | ||
30 | * ATI HDTV Wonder (NXT2004) | ||
31 | * | ||
32 | * This driver needs external firmware. Please use the command | ||
33 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" or | ||
34 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to | ||
35 | * download/extract the appropriate firmware, and then copy it to | ||
36 | * /usr/lib/hotplug/firmware/ or /lib/firmware/ | ||
37 | * (depending on configuration of firmware hotplug). | ||
38 | */ | ||
39 | #define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" | ||
40 | #define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw" | ||
41 | #define CRC_CCIT_MASK 0x1021 | ||
42 | |||
43 | #include <linux/kernel.h> | ||
44 | #include <linux/init.h> | ||
45 | #include <linux/module.h> | ||
46 | #include <linux/moduleparam.h> | ||
47 | |||
48 | #include "dvb_frontend.h" | ||
49 | #include "dvb-pll.h" | ||
50 | #include "nxt200x.h" | ||
51 | |||
52 | struct nxt200x_state { | ||
53 | |||
54 | struct i2c_adapter* i2c; | ||
55 | struct dvb_frontend_ops ops; | ||
56 | const struct nxt200x_config* config; | ||
57 | struct dvb_frontend frontend; | ||
58 | |||
59 | /* demodulator private data */ | ||
60 | nxt_chip_type demod_chip; | ||
61 | u8 initialised:1; | ||
62 | }; | ||
63 | |||
64 | static int debug; | ||
65 | #define dprintk(args...) \ | ||
66 | do { \ | ||
67 | if (debug) printk(KERN_DEBUG "nxt200x: " args); \ | ||
68 | } while (0) | ||
69 | |||
70 | static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len) | ||
71 | { | ||
72 | int err; | ||
73 | struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len }; | ||
74 | |||
75 | if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { | ||
76 | printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n", | ||
77 | __FUNCTION__, addr, err); | ||
78 | return -EREMOTEIO; | ||
79 | } | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len) | ||
84 | { | ||
85 | int err; | ||
86 | struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len }; | ||
87 | |||
88 | if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { | ||
89 | printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n", | ||
90 | __FUNCTION__, addr, err); | ||
91 | return -EREMOTEIO; | ||
92 | } | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, u8 *buf, u8 len) | ||
97 | { | ||
98 | u8 buf2 [len+1]; | ||
99 | int err; | ||
100 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 }; | ||
101 | |||
102 | buf2[0] = reg; | ||
103 | memcpy(&buf2[1], buf, len); | ||
104 | |||
105 | if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { | ||
106 | printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n", | ||
107 | __FUNCTION__, state->config->demod_address, err); | ||
108 | return -EREMOTEIO; | ||
109 | } | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static u8 nxt200x_readbytes (struct nxt200x_state* state, u8 reg, u8* buf, u8 len) | ||
114 | { | ||
115 | u8 reg2 [] = { reg }; | ||
116 | |||
117 | struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 }, | ||
118 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } }; | ||
119 | |||
120 | int err; | ||
121 | |||
122 | if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) { | ||
123 | printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n", | ||
124 | __FUNCTION__, state->config->demod_address, err); | ||
125 | return -EREMOTEIO; | ||
126 | } | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static u16 nxt200x_crc(u16 crc, u8 c) | ||
131 | { | ||
132 | u8 i; | ||
133 | u16 input = (u16) c & 0xFF; | ||
134 | |||
135 | input<<=8; | ||
136 | for(i=0; i<8; i++) { | ||
137 | if((crc^input) & 0x8000) | ||
138 | crc=(crc<<1)^CRC_CCIT_MASK; | ||
139 | else | ||
140 | crc<<=1; | ||
141 | input<<=1; | ||
142 | } | ||
143 | return crc; | ||
144 | } | ||
145 | |||
146 | static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len) | ||
147 | { | ||
148 | u8 attr, len2, buf; | ||
149 | dprintk("%s\n", __FUNCTION__); | ||
150 | |||
151 | /* set mutli register register */ | ||
152 | nxt200x_writebytes(state, 0x35, ®, 1); | ||
153 | |||
154 | /* send the actual data */ | ||
155 | nxt200x_writebytes(state, 0x36, data, len); | ||
156 | |||
157 | switch (state->demod_chip) { | ||
158 | case NXT2002: | ||
159 | len2 = len; | ||
160 | buf = 0x02; | ||
161 | break; | ||
162 | case NXT2004: | ||
163 | /* probably not right, but gives correct values */ | ||
164 | attr = 0x02; | ||
165 | if (reg & 0x80) { | ||
166 | attr = attr << 1; | ||
167 | if (reg & 0x04) | ||
168 | attr = attr >> 1; | ||
169 | } | ||
170 | /* set write bit */ | ||
171 | len2 = ((attr << 4) | 0x10) | len; | ||
172 | buf = 0x80; | ||
173 | break; | ||
174 | default: | ||
175 | return -EINVAL; | ||
176 | break; | ||
177 | } | ||
178 | |||
179 | /* set multi register length */ | ||
180 | nxt200x_writebytes(state, 0x34, &len2, 1); | ||
181 | |||
182 | /* toggle the multireg write bit */ | ||
183 | nxt200x_writebytes(state, 0x21, &buf, 1); | ||
184 | |||
185 | nxt200x_readbytes(state, 0x21, &buf, 1); | ||
186 | |||
187 | switch (state->demod_chip) { | ||
188 | case NXT2002: | ||
189 | if ((buf & 0x02) == 0) | ||
190 | return 0; | ||
191 | break; | ||
192 | case NXT2004: | ||
193 | if (buf == 0) | ||
194 | return 0; | ||
195 | break; | ||
196 | default: | ||
197 | return -EINVAL; | ||
198 | break; | ||
199 | } | ||
200 | |||
201 | printk(KERN_WARNING "nxt200x: Error writing multireg register 0x%02X\n",reg); | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len) | ||
207 | { | ||
208 | int i; | ||
209 | u8 buf, len2, attr; | ||
210 | dprintk("%s\n", __FUNCTION__); | ||
211 | |||
212 | /* set mutli register register */ | ||
213 | nxt200x_writebytes(state, 0x35, ®, 1); | ||
214 | |||
215 | switch (state->demod_chip) { | ||
216 | case NXT2002: | ||
217 | /* set multi register length */ | ||
218 | len2 = len & 0x80; | ||
219 | nxt200x_writebytes(state, 0x34, &len2, 1); | ||
220 | |||
221 | /* read the actual data */ | ||
222 | nxt200x_readbytes(state, reg, data, len); | ||
223 | return 0; | ||
224 | break; | ||
225 | case NXT2004: | ||
226 | /* probably not right, but gives correct values */ | ||
227 | attr = 0x02; | ||
228 | if (reg & 0x80) { | ||
229 | attr = attr << 1; | ||
230 | if (reg & 0x04) | ||
231 | attr = attr >> 1; | ||
232 | } | ||
233 | |||
234 | /* set multi register length */ | ||
235 | len2 = (attr << 4) | len; | ||
236 | nxt200x_writebytes(state, 0x34, &len2, 1); | ||
237 | |||
238 | /* toggle the multireg bit*/ | ||
239 | buf = 0x80; | ||
240 | nxt200x_writebytes(state, 0x21, &buf, 1); | ||
241 | |||
242 | /* read the actual data */ | ||
243 | for(i = 0; i < len; i++) { | ||
244 | nxt200x_readbytes(state, 0x36 + i, &data[i], 1); | ||
245 | } | ||
246 | return 0; | ||
247 | break; | ||
248 | default: | ||
249 | return -EINVAL; | ||
250 | break; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | static void nxt200x_microcontroller_stop (struct nxt200x_state* state) | ||
255 | { | ||
256 | u8 buf, stopval, counter = 0; | ||
257 | dprintk("%s\n", __FUNCTION__); | ||
258 | |||
259 | /* set correct stop value */ | ||
260 | switch (state->demod_chip) { | ||
261 | case NXT2002: | ||
262 | stopval = 0x40; | ||
263 | break; | ||
264 | case NXT2004: | ||
265 | stopval = 0x10; | ||
266 | break; | ||
267 | default: | ||
268 | stopval = 0; | ||
269 | break; | ||
270 | } | ||
271 | |||
272 | buf = 0x80; | ||
273 | nxt200x_writebytes(state, 0x22, &buf, 1); | ||
274 | |||
275 | while (counter < 20) { | ||
276 | nxt200x_readbytes(state, 0x31, &buf, 1); | ||
277 | if (buf & stopval) | ||
278 | return; | ||
279 | msleep(10); | ||
280 | counter++; | ||
281 | } | ||
282 | |||
283 | printk(KERN_WARNING "nxt200x: Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n"); | ||
284 | return; | ||
285 | } | ||
286 | |||
287 | static void nxt200x_microcontroller_start (struct nxt200x_state* state) | ||
288 | { | ||
289 | u8 buf; | ||
290 | dprintk("%s\n", __FUNCTION__); | ||
291 | |||
292 | buf = 0x00; | ||
293 | nxt200x_writebytes(state, 0x22, &buf, 1); | ||
294 | } | ||
295 | |||
296 | static void nxt2004_microcontroller_init (struct nxt200x_state* state) | ||
297 | { | ||
298 | u8 buf[9]; | ||
299 | u8 counter = 0; | ||
300 | dprintk("%s\n", __FUNCTION__); | ||
301 | |||
302 | buf[0] = 0x00; | ||
303 | nxt200x_writebytes(state, 0x2b, buf, 1); | ||
304 | buf[0] = 0x70; | ||
305 | nxt200x_writebytes(state, 0x34, buf, 1); | ||
306 | buf[0] = 0x04; | ||
307 | nxt200x_writebytes(state, 0x35, buf, 1); | ||
308 | buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89; | ||
309 | buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0; | ||
310 | nxt200x_writebytes(state, 0x36, buf, 9); | ||
311 | buf[0] = 0x80; | ||
312 | nxt200x_writebytes(state, 0x21, buf, 1); | ||
313 | |||
314 | while (counter < 20) { | ||
315 | nxt200x_readbytes(state, 0x21, buf, 1); | ||
316 | if (buf[0] == 0) | ||
317 | return; | ||
318 | msleep(10); | ||
319 | counter++; | ||
320 | } | ||
321 | |||
322 | printk(KERN_WARNING "nxt200x: Timeout waiting for nxt2004 to init.\n"); | ||
323 | |||
324 | return; | ||
325 | } | ||
326 | |||
327 | static int nxt200x_writetuner (struct nxt200x_state* state, u8* data) | ||
328 | { | ||
329 | u8 buf, count = 0; | ||
330 | |||
331 | dprintk("%s\n", __FUNCTION__); | ||
332 | |||
333 | dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[0], data[1], data[2], data[3]); | ||
334 | |||
335 | /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip. | ||
336 | * direct write is required for Philips TUV1236D and ALPS TDHU2 */ | ||
337 | switch (state->demod_chip) { | ||
338 | case NXT2004: | ||
339 | if (i2c_writebytes(state, state->config->pll_address, data, 4)) | ||
340 | printk(KERN_WARNING "nxt200x: error writing to tuner\n"); | ||
341 | /* wait until we have a lock */ | ||
342 | while (count < 20) { | ||
343 | i2c_readbytes(state, state->config->pll_address, &buf, 1); | ||
344 | if (buf & 0x40) | ||
345 | return 0; | ||
346 | msleep(100); | ||
347 | count++; | ||
348 | } | ||
349 | printk("nxt2004: timeout waiting for tuner lock\n"); | ||
350 | break; | ||
351 | case NXT2002: | ||
352 | /* set the i2c transfer speed to the tuner */ | ||
353 | buf = 0x03; | ||
354 | nxt200x_writebytes(state, 0x20, &buf, 1); | ||
355 | |||
356 | /* setup to transfer 4 bytes via i2c */ | ||
357 | buf = 0x04; | ||
358 | nxt200x_writebytes(state, 0x34, &buf, 1); | ||
359 | |||
360 | /* write actual tuner bytes */ | ||
361 | nxt200x_writebytes(state, 0x36, data, 4); | ||
362 | |||
363 | /* set tuner i2c address */ | ||
364 | buf = state->config->pll_address; | ||
365 | nxt200x_writebytes(state, 0x35, &buf, 1); | ||
366 | |||
367 | /* write UC Opmode to begin transfer */ | ||
368 | buf = 0x80; | ||
369 | nxt200x_writebytes(state, 0x21, &buf, 1); | ||
370 | |||
371 | while (count < 20) { | ||
372 | nxt200x_readbytes(state, 0x21, &buf, 1); | ||
373 | if ((buf & 0x80)== 0x00) | ||
374 | return 0; | ||
375 | msleep(100); | ||
376 | count++; | ||
377 | } | ||
378 | printk("nxt2002: timeout error writing tuner\n"); | ||
379 | break; | ||
380 | default: | ||
381 | return -EINVAL; | ||
382 | break; | ||
383 | } | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static void nxt200x_agc_reset(struct nxt200x_state* state) | ||
388 | { | ||
389 | u8 buf; | ||
390 | dprintk("%s\n", __FUNCTION__); | ||
391 | |||
392 | switch (state->demod_chip) { | ||
393 | case NXT2002: | ||
394 | buf = 0x08; | ||
395 | nxt200x_writebytes(state, 0x08, &buf, 1); | ||
396 | buf = 0x00; | ||
397 | nxt200x_writebytes(state, 0x08, &buf, 1); | ||
398 | break; | ||
399 | case NXT2004: | ||
400 | nxt200x_readreg_multibyte(state, 0x08, &buf, 1); | ||
401 | buf = 0x08; | ||
402 | nxt200x_writereg_multibyte(state, 0x08, &buf, 1); | ||
403 | buf = 0x00; | ||
404 | nxt200x_writereg_multibyte(state, 0x08, &buf, 1); | ||
405 | break; | ||
406 | default: | ||
407 | break; | ||
408 | } | ||
409 | return; | ||
410 | } | ||
411 | |||
412 | static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) | ||
413 | { | ||
414 | |||
415 | struct nxt200x_state* state = fe->demodulator_priv; | ||
416 | u8 buf[3], written = 0, chunkpos = 0; | ||
417 | u16 rambase, position, crc = 0; | ||
418 | |||
419 | dprintk("%s\n", __FUNCTION__); | ||
420 | dprintk("Firmware is %zu bytes\n", fw->size); | ||
421 | |||
422 | /* Get the RAM base for this nxt2002 */ | ||
423 | nxt200x_readbytes(state, 0x10, buf, 1); | ||
424 | |||
425 | if (buf[0] & 0x10) | ||
426 | rambase = 0x1000; | ||
427 | else | ||
428 | rambase = 0x0000; | ||
429 | |||
430 | dprintk("rambase on this nxt2002 is %04X\n", rambase); | ||
431 | |||
432 | /* Hold the micro in reset while loading firmware */ | ||
433 | buf[0] = 0x80; | ||
434 | nxt200x_writebytes(state, 0x2B, buf, 1); | ||
435 | |||
436 | for (position = 0; position < fw->size; position++) { | ||
437 | if (written == 0) { | ||
438 | crc = 0; | ||
439 | chunkpos = 0x28; | ||
440 | buf[0] = ((rambase + position) >> 8); | ||
441 | buf[1] = (rambase + position) & 0xFF; | ||
442 | buf[2] = 0x81; | ||
443 | /* write starting address */ | ||
444 | nxt200x_writebytes(state, 0x29, buf, 3); | ||
445 | } | ||
446 | written++; | ||
447 | chunkpos++; | ||
448 | |||
449 | if ((written % 4) == 0) | ||
450 | nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4); | ||
451 | |||
452 | crc = nxt200x_crc(crc, fw->data[position]); | ||
453 | |||
454 | if ((written == 255) || (position+1 == fw->size)) { | ||
455 | /* write remaining bytes of firmware */ | ||
456 | nxt200x_writebytes(state, chunkpos+4-(written %4), | ||
457 | &fw->data[position-(written %4) + 1], | ||
458 | written %4); | ||
459 | buf[0] = crc << 8; | ||
460 | buf[1] = crc & 0xFF; | ||
461 | |||
462 | /* write crc */ | ||
463 | nxt200x_writebytes(state, 0x2C, buf, 2); | ||
464 | |||
465 | /* do a read to stop things */ | ||
466 | nxt200x_readbytes(state, 0x2A, buf, 1); | ||
467 | |||
468 | /* set transfer mode to complete */ | ||
469 | buf[0] = 0x80; | ||
470 | nxt200x_writebytes(state, 0x2B, buf, 1); | ||
471 | |||
472 | written = 0; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | return 0; | ||
477 | }; | ||
478 | |||
479 | static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) | ||
480 | { | ||
481 | |||
482 | struct nxt200x_state* state = fe->demodulator_priv; | ||
483 | u8 buf[3]; | ||
484 | u16 rambase, position, crc=0; | ||
485 | |||
486 | dprintk("%s\n", __FUNCTION__); | ||
487 | dprintk("Firmware is %zu bytes\n", fw->size); | ||
488 | |||
489 | /* set rambase */ | ||
490 | rambase = 0x1000; | ||
491 | |||
492 | /* hold the micro in reset while loading firmware */ | ||
493 | buf[0] = 0x80; | ||
494 | nxt200x_writebytes(state, 0x2B, buf,1); | ||
495 | |||
496 | /* calculate firmware CRC */ | ||
497 | for (position = 0; position < fw->size; position++) { | ||
498 | crc = nxt200x_crc(crc, fw->data[position]); | ||
499 | } | ||
500 | |||
501 | buf[0] = rambase >> 8; | ||
502 | buf[1] = rambase & 0xFF; | ||
503 | buf[2] = 0x81; | ||
504 | /* write starting address */ | ||
505 | nxt200x_writebytes(state,0x29,buf,3); | ||
506 | |||
507 | for (position = 0; position < fw->size;) { | ||
508 | nxt200x_writebytes(state, 0x2C, &fw->data[position], | ||
509 | fw->size-position > 255 ? 255 : fw->size-position); | ||
510 | position += (fw->size-position > 255 ? 255 : fw->size-position); | ||
511 | } | ||
512 | buf[0] = crc >> 8; | ||
513 | buf[1] = crc & 0xFF; | ||
514 | |||
515 | dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]); | ||
516 | |||
517 | /* write crc */ | ||
518 | nxt200x_writebytes(state, 0x2C, buf,2); | ||
519 | |||
520 | /* do a read to stop things */ | ||
521 | nxt200x_readbytes(state, 0x2C, buf, 1); | ||
522 | |||
523 | /* set transfer mode to complete */ | ||
524 | buf[0] = 0x80; | ||
525 | nxt200x_writebytes(state, 0x2B, buf,1); | ||
526 | |||
527 | return 0; | ||
528 | }; | ||
529 | |||
530 | static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | ||
531 | struct dvb_frontend_parameters *p) | ||
532 | { | ||
533 | struct nxt200x_state* state = fe->demodulator_priv; | ||
534 | u8 buf[4]; | ||
535 | |||
536 | /* stop the micro first */ | ||
537 | nxt200x_microcontroller_stop(state); | ||
538 | |||
539 | if (state->demod_chip == NXT2004) { | ||
540 | /* make sure demod is set to digital */ | ||
541 | buf[0] = 0x04; | ||
542 | nxt200x_writebytes(state, 0x14, buf, 1); | ||
543 | buf[0] = 0x00; | ||
544 | nxt200x_writebytes(state, 0x17, buf, 1); | ||
545 | } | ||
546 | |||
547 | /* get tuning information */ | ||
548 | dvb_pll_configure(state->config->pll_desc, buf, p->frequency, 0); | ||
549 | |||
550 | /* set additional params */ | ||
551 | switch (p->u.vsb.modulation) { | ||
552 | case QAM_64: | ||
553 | case QAM_256: | ||
554 | /* Set punctured clock for QAM */ | ||
555 | /* This is just a guess since I am unable to test it */ | ||
556 | if (state->config->set_ts_params) | ||
557 | state->config->set_ts_params(fe, 1); | ||
558 | |||
559 | /* set input */ | ||
560 | if (state->config->set_pll_input) | ||
561 | state->config->set_pll_input(buf, 1); | ||
562 | break; | ||
563 | case VSB_8: | ||
564 | /* Set non-punctured clock for VSB */ | ||
565 | if (state->config->set_ts_params) | ||
566 | state->config->set_ts_params(fe, 0); | ||
567 | |||
568 | /* set input */ | ||
569 | if (state->config->set_pll_input) | ||
570 | state->config->set_pll_input(buf, 0); | ||
571 | break; | ||
572 | default: | ||
573 | return -EINVAL; | ||
574 | break; | ||
575 | } | ||
576 | |||
577 | /* write frequency information */ | ||
578 | nxt200x_writetuner(state, buf); | ||
579 | |||
580 | /* reset the agc now that tuning has been completed */ | ||
581 | nxt200x_agc_reset(state); | ||
582 | |||
583 | /* set target power level */ | ||
584 | switch (p->u.vsb.modulation) { | ||
585 | case QAM_64: | ||
586 | case QAM_256: | ||
587 | buf[0] = 0x74; | ||
588 | break; | ||
589 | case VSB_8: | ||
590 | buf[0] = 0x70; | ||
591 | break; | ||
592 | default: | ||
593 | return -EINVAL; | ||
594 | break; | ||
595 | } | ||
596 | nxt200x_writebytes(state, 0x42, buf, 1); | ||
597 | |||
598 | /* configure sdm */ | ||
599 | switch (state->demod_chip) { | ||
600 | case NXT2002: | ||
601 | buf[0] = 0x87; | ||
602 | break; | ||
603 | case NXT2004: | ||
604 | buf[0] = 0x07; | ||
605 | break; | ||
606 | default: | ||
607 | return -EINVAL; | ||
608 | break; | ||
609 | } | ||
610 | nxt200x_writebytes(state, 0x57, buf, 1); | ||
611 | |||
612 | /* write sdm1 input */ | ||
613 | buf[0] = 0x10; | ||
614 | buf[1] = 0x00; | ||
615 | nxt200x_writebytes(state, 0x58, buf, 2); | ||
616 | |||
617 | /* write sdmx input */ | ||
618 | switch (p->u.vsb.modulation) { | ||
619 | case QAM_64: | ||
620 | buf[0] = 0x68; | ||
621 | break; | ||
622 | case QAM_256: | ||
623 | buf[0] = 0x64; | ||
624 | break; | ||
625 | case VSB_8: | ||
626 | buf[0] = 0x60; | ||
627 | break; | ||
628 | default: | ||
629 | return -EINVAL; | ||
630 | break; | ||
631 | } | ||
632 | buf[1] = 0x00; | ||
633 | nxt200x_writebytes(state, 0x5C, buf, 2); | ||
634 | |||
635 | /* write adc power lpf fc */ | ||
636 | buf[0] = 0x05; | ||
637 | nxt200x_writebytes(state, 0x43, buf, 1); | ||
638 | |||
639 | if (state->demod_chip == NXT2004) { | ||
640 | /* write ??? */ | ||
641 | buf[0] = 0x00; | ||
642 | buf[1] = 0x00; | ||
643 | nxt200x_writebytes(state, 0x46, buf, 2); | ||
644 | } | ||
645 | |||
646 | /* write accumulator2 input */ | ||
647 | buf[0] = 0x80; | ||
648 | buf[1] = 0x00; | ||
649 | nxt200x_writebytes(state, 0x4B, buf, 2); | ||
650 | |||
651 | /* write kg1 */ | ||
652 | buf[0] = 0x00; | ||
653 | nxt200x_writebytes(state, 0x4D, buf, 1); | ||
654 | |||
655 | /* write sdm12 lpf fc */ | ||
656 | buf[0] = 0x44; | ||
657 | nxt200x_writebytes(state, 0x55, buf, 1); | ||
658 | |||
659 | /* write agc control reg */ | ||
660 | buf[0] = 0x04; | ||
661 | nxt200x_writebytes(state, 0x41, buf, 1); | ||
662 | |||
663 | if (state->demod_chip == NXT2004) { | ||
664 | nxt200x_readreg_multibyte(state, 0x80, buf, 1); | ||
665 | buf[0] = 0x24; | ||
666 | nxt200x_writereg_multibyte(state, 0x80, buf, 1); | ||
667 | |||
668 | /* soft reset? */ | ||
669 | nxt200x_readreg_multibyte(state, 0x08, buf, 1); | ||
670 | buf[0] = 0x10; | ||
671 | nxt200x_writereg_multibyte(state, 0x08, buf, 1); | ||
672 | nxt200x_readreg_multibyte(state, 0x08, buf, 1); | ||
673 | buf[0] = 0x00; | ||
674 | nxt200x_writereg_multibyte(state, 0x08, buf, 1); | ||
675 | |||
676 | nxt200x_readreg_multibyte(state, 0x80, buf, 1); | ||
677 | buf[0] = 0x04; | ||
678 | nxt200x_writereg_multibyte(state, 0x80, buf, 1); | ||
679 | buf[0] = 0x00; | ||
680 | nxt200x_writereg_multibyte(state, 0x81, buf, 1); | ||
681 | buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00; | ||
682 | nxt200x_writereg_multibyte(state, 0x82, buf, 3); | ||
683 | nxt200x_readreg_multibyte(state, 0x88, buf, 1); | ||
684 | buf[0] = 0x11; | ||
685 | nxt200x_writereg_multibyte(state, 0x88, buf, 1); | ||
686 | nxt200x_readreg_multibyte(state, 0x80, buf, 1); | ||
687 | buf[0] = 0x44; | ||
688 | nxt200x_writereg_multibyte(state, 0x80, buf, 1); | ||
689 | } | ||
690 | |||
691 | /* write agc ucgp0 */ | ||
692 | switch (p->u.vsb.modulation) { | ||
693 | case QAM_64: | ||
694 | buf[0] = 0x02; | ||
695 | break; | ||
696 | case QAM_256: | ||
697 | buf[0] = 0x03; | ||
698 | break; | ||
699 | case VSB_8: | ||
700 | buf[0] = 0x00; | ||
701 | break; | ||
702 | default: | ||
703 | return -EINVAL; | ||
704 | break; | ||
705 | } | ||
706 | nxt200x_writebytes(state, 0x30, buf, 1); | ||
707 | |||
708 | /* write agc control reg */ | ||
709 | buf[0] = 0x00; | ||
710 | nxt200x_writebytes(state, 0x41, buf, 1); | ||
711 | |||
712 | /* write accumulator2 input */ | ||
713 | buf[0] = 0x80; | ||
714 | buf[1] = 0x00; | ||
715 | nxt200x_writebytes(state, 0x49, buf,2); | ||
716 | nxt200x_writebytes(state, 0x4B, buf,2); | ||
717 | |||
718 | /* write agc control reg */ | ||
719 | buf[0] = 0x04; | ||
720 | nxt200x_writebytes(state, 0x41, buf, 1); | ||
721 | |||
722 | nxt200x_microcontroller_start(state); | ||
723 | |||
724 | if (state->demod_chip == NXT2004) { | ||
725 | nxt2004_microcontroller_init(state); | ||
726 | |||
727 | /* ???? */ | ||
728 | buf[0] = 0xF0; | ||
729 | buf[1] = 0x00; | ||
730 | nxt200x_writebytes(state, 0x5C, buf, 2); | ||
731 | } | ||
732 | |||
733 | /* adjacent channel detection should be done here, but I don't | ||
734 | have any stations with this need so I cannot test it */ | ||
735 | |||
736 | return 0; | ||
737 | } | ||
738 | |||
739 | static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
740 | { | ||
741 | struct nxt200x_state* state = fe->demodulator_priv; | ||
742 | u8 lock; | ||
743 | nxt200x_readbytes(state, 0x31, &lock, 1); | ||
744 | |||
745 | *status = 0; | ||
746 | if (lock & 0x20) { | ||
747 | *status |= FE_HAS_SIGNAL; | ||
748 | *status |= FE_HAS_CARRIER; | ||
749 | *status |= FE_HAS_VITERBI; | ||
750 | *status |= FE_HAS_SYNC; | ||
751 | *status |= FE_HAS_LOCK; | ||
752 | } | ||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber) | ||
757 | { | ||
758 | struct nxt200x_state* state = fe->demodulator_priv; | ||
759 | u8 b[3]; | ||
760 | |||
761 | nxt200x_readreg_multibyte(state, 0xE6, b, 3); | ||
762 | |||
763 | *ber = ((b[0] << 8) + b[1]) * 8; | ||
764 | |||
765 | return 0; | ||
766 | } | ||
767 | |||
768 | static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength) | ||
769 | { | ||
770 | struct nxt200x_state* state = fe->demodulator_priv; | ||
771 | u8 b[2]; | ||
772 | u16 temp = 0; | ||
773 | |||
774 | /* setup to read cluster variance */ | ||
775 | b[0] = 0x00; | ||
776 | nxt200x_writebytes(state, 0xA1, b, 1); | ||
777 | |||
778 | /* get multreg val */ | ||
779 | nxt200x_readreg_multibyte(state, 0xA6, b, 2); | ||
780 | |||
781 | temp = (b[0] << 8) | b[1]; | ||
782 | *strength = ((0x7FFF - temp) & 0x0FFF) * 16; | ||
783 | |||
784 | return 0; | ||
785 | } | ||
786 | |||
787 | static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr) | ||
788 | { | ||
789 | |||
790 | struct nxt200x_state* state = fe->demodulator_priv; | ||
791 | u8 b[2]; | ||
792 | u16 temp = 0, temp2; | ||
793 | u32 snrdb = 0; | ||
794 | |||
795 | /* setup to read cluster variance */ | ||
796 | b[0] = 0x00; | ||
797 | nxt200x_writebytes(state, 0xA1, b, 1); | ||
798 | |||
799 | /* get multreg val from 0xA6 */ | ||
800 | nxt200x_readreg_multibyte(state, 0xA6, b, 2); | ||
801 | |||
802 | temp = (b[0] << 8) | b[1]; | ||
803 | temp2 = 0x7FFF - temp; | ||
804 | |||
805 | /* snr will be in db */ | ||
806 | if (temp2 > 0x7F00) | ||
807 | snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) ); | ||
808 | else if (temp2 > 0x7EC0) | ||
809 | snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) ); | ||
810 | else if (temp2 > 0x7C00) | ||
811 | snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) ); | ||
812 | else | ||
813 | snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) ); | ||
814 | |||
815 | /* the value reported back from the frontend will be FFFF=32db 0000=0db */ | ||
816 | *snr = snrdb * (0xFFFF/32000); | ||
817 | |||
818 | return 0; | ||
819 | } | ||
820 | |||
821 | static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
822 | { | ||
823 | struct nxt200x_state* state = fe->demodulator_priv; | ||
824 | u8 b[3]; | ||
825 | |||
826 | nxt200x_readreg_multibyte(state, 0xE6, b, 3); | ||
827 | *ucblocks = b[2]; | ||
828 | |||
829 | return 0; | ||
830 | } | ||
831 | |||
832 | static int nxt200x_sleep(struct dvb_frontend* fe) | ||
833 | { | ||
834 | return 0; | ||
835 | } | ||
836 | |||
837 | static int nxt2002_init(struct dvb_frontend* fe) | ||
838 | { | ||
839 | struct nxt200x_state* state = fe->demodulator_priv; | ||
840 | const struct firmware *fw; | ||
841 | int ret; | ||
842 | u8 buf[2]; | ||
843 | |||
844 | /* request the firmware, this will block until someone uploads it */ | ||
845 | printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE); | ||
846 | ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, &state->i2c->dev); | ||
847 | printk("nxt2002: Waiting for firmware upload(2)...\n"); | ||
848 | if (ret) { | ||
849 | printk("nxt2002: No firmware uploaded (timeout or file not found?)\n"); | ||
850 | return ret; | ||
851 | } | ||
852 | |||
853 | ret = nxt2002_load_firmware(fe, fw); | ||
854 | if (ret) { | ||
855 | printk("nxt2002: Writing firmware to device failed\n"); | ||
856 | release_firmware(fw); | ||
857 | return ret; | ||
858 | } | ||
859 | printk("nxt2002: Firmware upload complete\n"); | ||
860 | |||
861 | /* Put the micro into reset */ | ||
862 | nxt200x_microcontroller_stop(state); | ||
863 | |||
864 | /* ensure transfer is complete */ | ||
865 | buf[0]=0x00; | ||
866 | nxt200x_writebytes(state, 0x2B, buf, 1); | ||
867 | |||
868 | /* Put the micro into reset for real this time */ | ||
869 | nxt200x_microcontroller_stop(state); | ||
870 | |||
871 | /* soft reset everything (agc,frontend,eq,fec)*/ | ||
872 | buf[0] = 0x0F; | ||
873 | nxt200x_writebytes(state, 0x08, buf, 1); | ||
874 | buf[0] = 0x00; | ||
875 | nxt200x_writebytes(state, 0x08, buf, 1); | ||
876 | |||
877 | /* write agc sdm configure */ | ||
878 | buf[0] = 0xF1; | ||
879 | nxt200x_writebytes(state, 0x57, buf, 1); | ||
880 | |||
881 | /* write mod output format */ | ||
882 | buf[0] = 0x20; | ||
883 | nxt200x_writebytes(state, 0x09, buf, 1); | ||
884 | |||
885 | /* write fec mpeg mode */ | ||
886 | buf[0] = 0x7E; | ||
887 | buf[1] = 0x00; | ||
888 | nxt200x_writebytes(state, 0xE9, buf, 2); | ||
889 | |||
890 | /* write mux selection */ | ||
891 | buf[0] = 0x00; | ||
892 | nxt200x_writebytes(state, 0xCC, buf, 1); | ||
893 | |||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | static int nxt2004_init(struct dvb_frontend* fe) | ||
898 | { | ||
899 | struct nxt200x_state* state = fe->demodulator_priv; | ||
900 | const struct firmware *fw; | ||
901 | int ret; | ||
902 | u8 buf[3]; | ||
903 | |||
904 | /* ??? */ | ||
905 | buf[0]=0x00; | ||
906 | nxt200x_writebytes(state, 0x1E, buf, 1); | ||
907 | |||
908 | /* request the firmware, this will block until someone uploads it */ | ||
909 | printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE); | ||
910 | ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, &state->i2c->dev); | ||
911 | printk("nxt2004: Waiting for firmware upload(2)...\n"); | ||
912 | if (ret) { | ||
913 | printk("nxt2004: No firmware uploaded (timeout or file not found?)\n"); | ||
914 | return ret; | ||
915 | } | ||
916 | |||
917 | ret = nxt2004_load_firmware(fe, fw); | ||
918 | if (ret) { | ||
919 | printk("nxt2004: Writing firmware to device failed\n"); | ||
920 | release_firmware(fw); | ||
921 | return ret; | ||
922 | } | ||
923 | printk("nxt2004: Firmware upload complete\n"); | ||
924 | |||
925 | /* ensure transfer is complete */ | ||
926 | buf[0] = 0x01; | ||
927 | nxt200x_writebytes(state, 0x19, buf, 1); | ||
928 | |||
929 | nxt2004_microcontroller_init(state); | ||
930 | nxt200x_microcontroller_stop(state); | ||
931 | nxt200x_microcontroller_stop(state); | ||
932 | nxt2004_microcontroller_init(state); | ||
933 | nxt200x_microcontroller_stop(state); | ||
934 | |||
935 | /* soft reset everything (agc,frontend,eq,fec)*/ | ||
936 | buf[0] = 0xFF; | ||
937 | nxt200x_writereg_multibyte(state, 0x08, buf, 1); | ||
938 | buf[0] = 0x00; | ||
939 | nxt200x_writereg_multibyte(state, 0x08, buf, 1); | ||
940 | |||
941 | /* write agc sdm configure */ | ||
942 | buf[0] = 0xD7; | ||
943 | nxt200x_writebytes(state, 0x57, buf, 1); | ||
944 | |||
945 | /* ???*/ | ||
946 | buf[0] = 0x07; | ||
947 | buf[1] = 0xfe; | ||
948 | nxt200x_writebytes(state, 0x35, buf, 2); | ||
949 | buf[0] = 0x12; | ||
950 | nxt200x_writebytes(state, 0x34, buf, 1); | ||
951 | buf[0] = 0x80; | ||
952 | nxt200x_writebytes(state, 0x21, buf, 1); | ||
953 | |||
954 | /* ???*/ | ||
955 | buf[0] = 0x21; | ||
956 | nxt200x_writebytes(state, 0x0A, buf, 1); | ||
957 | |||
958 | /* ???*/ | ||
959 | buf[0] = 0x01; | ||
960 | nxt200x_writereg_multibyte(state, 0x80, buf, 1); | ||
961 | |||
962 | /* write fec mpeg mode */ | ||
963 | buf[0] = 0x7E; | ||
964 | buf[1] = 0x00; | ||
965 | nxt200x_writebytes(state, 0xE9, buf, 2); | ||
966 | |||
967 | /* write mux selection */ | ||
968 | buf[0] = 0x00; | ||
969 | nxt200x_writebytes(state, 0xCC, buf, 1); | ||
970 | |||
971 | /* ???*/ | ||
972 | nxt200x_readreg_multibyte(state, 0x80, buf, 1); | ||
973 | buf[0] = 0x00; | ||
974 | nxt200x_writereg_multibyte(state, 0x80, buf, 1); | ||
975 | |||
976 | /* soft reset? */ | ||
977 | nxt200x_readreg_multibyte(state, 0x08, buf, 1); | ||
978 | buf[0] = 0x10; | ||
979 | nxt200x_writereg_multibyte(state, 0x08, buf, 1); | ||
980 | nxt200x_readreg_multibyte(state, 0x08, buf, 1); | ||
981 | buf[0] = 0x00; | ||
982 | nxt200x_writereg_multibyte(state, 0x08, buf, 1); | ||
983 | |||
984 | /* ???*/ | ||
985 | nxt200x_readreg_multibyte(state, 0x80, buf, 1); | ||
986 | buf[0] = 0x01; | ||
987 | nxt200x_writereg_multibyte(state, 0x80, buf, 1); | ||
988 | buf[0] = 0x70; | ||
989 | nxt200x_writereg_multibyte(state, 0x81, buf, 1); | ||
990 | buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66; | ||
991 | nxt200x_writereg_multibyte(state, 0x82, buf, 3); | ||
992 | |||
993 | nxt200x_readreg_multibyte(state, 0x88, buf, 1); | ||
994 | buf[0] = 0x11; | ||
995 | nxt200x_writereg_multibyte(state, 0x88, buf, 1); | ||
996 | nxt200x_readreg_multibyte(state, 0x80, buf, 1); | ||
997 | buf[0] = 0x40; | ||
998 | nxt200x_writereg_multibyte(state, 0x80, buf, 1); | ||
999 | |||
1000 | nxt200x_readbytes(state, 0x10, buf, 1); | ||
1001 | buf[0] = 0x10; | ||
1002 | nxt200x_writebytes(state, 0x10, buf, 1); | ||
1003 | nxt200x_readbytes(state, 0x0A, buf, 1); | ||
1004 | buf[0] = 0x21; | ||
1005 | nxt200x_writebytes(state, 0x0A, buf, 1); | ||
1006 | |||
1007 | nxt2004_microcontroller_init(state); | ||
1008 | |||
1009 | buf[0] = 0x21; | ||
1010 | nxt200x_writebytes(state, 0x0A, buf, 1); | ||
1011 | buf[0] = 0x7E; | ||
1012 | nxt200x_writebytes(state, 0xE9, buf, 1); | ||
1013 | buf[0] = 0x00; | ||
1014 | nxt200x_writebytes(state, 0xEA, buf, 1); | ||
1015 | |||
1016 | nxt200x_readreg_multibyte(state, 0x80, buf, 1); | ||
1017 | buf[0] = 0x00; | ||
1018 | nxt200x_writereg_multibyte(state, 0x80, buf, 1); | ||
1019 | nxt200x_readreg_multibyte(state, 0x80, buf, 1); | ||
1020 | buf[0] = 0x00; | ||
1021 | nxt200x_writereg_multibyte(state, 0x80, buf, 1); | ||
1022 | |||
1023 | /* soft reset? */ | ||
1024 | nxt200x_readreg_multibyte(state, 0x08, buf, 1); | ||
1025 | buf[0] = 0x10; | ||
1026 | nxt200x_writereg_multibyte(state, 0x08, buf, 1); | ||
1027 | nxt200x_readreg_multibyte(state, 0x08, buf, 1); | ||
1028 | buf[0] = 0x00; | ||
1029 | nxt200x_writereg_multibyte(state, 0x08, buf, 1); | ||
1030 | |||
1031 | nxt200x_readreg_multibyte(state, 0x80, buf, 1); | ||
1032 | buf[0] = 0x04; | ||
1033 | nxt200x_writereg_multibyte(state, 0x80, buf, 1); | ||
1034 | buf[0] = 0x00; | ||
1035 | nxt200x_writereg_multibyte(state, 0x81, buf, 1); | ||
1036 | buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00; | ||
1037 | nxt200x_writereg_multibyte(state, 0x82, buf, 3); | ||
1038 | |||
1039 | nxt200x_readreg_multibyte(state, 0x88, buf, 1); | ||
1040 | buf[0] = 0x11; | ||
1041 | nxt200x_writereg_multibyte(state, 0x88, buf, 1); | ||
1042 | |||
1043 | nxt200x_readreg_multibyte(state, 0x80, buf, 1); | ||
1044 | buf[0] = 0x44; | ||
1045 | nxt200x_writereg_multibyte(state, 0x80, buf, 1); | ||
1046 | |||
1047 | /* initialize tuner */ | ||
1048 | nxt200x_readbytes(state, 0x10, buf, 1); | ||
1049 | buf[0] = 0x12; | ||
1050 | nxt200x_writebytes(state, 0x10, buf, 1); | ||
1051 | buf[0] = 0x04; | ||
1052 | nxt200x_writebytes(state, 0x13, buf, 1); | ||
1053 | buf[0] = 0x00; | ||
1054 | nxt200x_writebytes(state, 0x16, buf, 1); | ||
1055 | buf[0] = 0x04; | ||
1056 | nxt200x_writebytes(state, 0x14, buf, 1); | ||
1057 | buf[0] = 0x00; | ||
1058 | nxt200x_writebytes(state, 0x14, buf, 1); | ||
1059 | nxt200x_writebytes(state, 0x17, buf, 1); | ||
1060 | nxt200x_writebytes(state, 0x14, buf, 1); | ||
1061 | nxt200x_writebytes(state, 0x17, buf, 1); | ||
1062 | |||
1063 | return 0; | ||
1064 | } | ||
1065 | |||
1066 | static int nxt200x_init(struct dvb_frontend* fe) | ||
1067 | { | ||
1068 | struct nxt200x_state* state = fe->demodulator_priv; | ||
1069 | int ret = 0; | ||
1070 | |||
1071 | if (!state->initialised) { | ||
1072 | switch (state->demod_chip) { | ||
1073 | case NXT2002: | ||
1074 | ret = nxt2002_init(fe); | ||
1075 | break; | ||
1076 | case NXT2004: | ||
1077 | ret = nxt2004_init(fe); | ||
1078 | break; | ||
1079 | default: | ||
1080 | return -EINVAL; | ||
1081 | break; | ||
1082 | } | ||
1083 | state->initialised = 1; | ||
1084 | } | ||
1085 | return ret; | ||
1086 | } | ||
1087 | |||
1088 | static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) | ||
1089 | { | ||
1090 | fesettings->min_delay_ms = 500; | ||
1091 | fesettings->step_size = 0; | ||
1092 | fesettings->max_drift = 0; | ||
1093 | return 0; | ||
1094 | } | ||
1095 | |||
1096 | static void nxt200x_release(struct dvb_frontend* fe) | ||
1097 | { | ||
1098 | struct nxt200x_state* state = fe->demodulator_priv; | ||
1099 | kfree(state); | ||
1100 | } | ||
1101 | |||
1102 | static struct dvb_frontend_ops nxt200x_ops; | ||
1103 | |||
1104 | struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, | ||
1105 | struct i2c_adapter* i2c) | ||
1106 | { | ||
1107 | struct nxt200x_state* state = NULL; | ||
1108 | u8 buf [] = {0,0,0,0,0}; | ||
1109 | |||
1110 | /* allocate memory for the internal state */ | ||
1111 | state = (struct nxt200x_state*) kmalloc(sizeof(struct nxt200x_state), GFP_KERNEL); | ||
1112 | if (state == NULL) | ||
1113 | goto error; | ||
1114 | memset(state,0,sizeof(*state)); | ||
1115 | |||
1116 | /* setup the state */ | ||
1117 | state->config = config; | ||
1118 | state->i2c = i2c; | ||
1119 | memcpy(&state->ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops)); | ||
1120 | state->initialised = 0; | ||
1121 | |||
1122 | /* read card id */ | ||
1123 | nxt200x_readbytes(state, 0x00, buf, 5); | ||
1124 | dprintk("NXT info: %02X %02X %02X %02X %02X\n", | ||
1125 | buf[0], buf[1], buf[2], buf[3], buf[4]); | ||
1126 | |||
1127 | /* set demod chip */ | ||
1128 | switch (buf[0]) { | ||
1129 | case 0x04: | ||
1130 | state->demod_chip = NXT2002; | ||
1131 | printk("nxt200x: NXT2002 Detected\n"); | ||
1132 | break; | ||
1133 | case 0x05: | ||
1134 | state->demod_chip = NXT2004; | ||
1135 | printk("nxt200x: NXT2004 Detected\n"); | ||
1136 | break; | ||
1137 | default: | ||
1138 | goto error; | ||
1139 | } | ||
1140 | |||
1141 | /* make sure demod chip is supported */ | ||
1142 | switch (state->demod_chip) { | ||
1143 | case NXT2002: | ||
1144 | if (buf[0] != 0x04) goto error; /* device id */ | ||
1145 | if (buf[1] != 0x02) goto error; /* fab id */ | ||
1146 | if (buf[2] != 0x11) goto error; /* month */ | ||
1147 | if (buf[3] != 0x20) goto error; /* year msb */ | ||
1148 | if (buf[4] != 0x00) goto error; /* year lsb */ | ||
1149 | break; | ||
1150 | case NXT2004: | ||
1151 | if (buf[0] != 0x05) goto error; /* device id */ | ||
1152 | break; | ||
1153 | default: | ||
1154 | goto error; | ||
1155 | } | ||
1156 | |||
1157 | /* create dvb_frontend */ | ||
1158 | state->frontend.ops = &state->ops; | ||
1159 | state->frontend.demodulator_priv = state; | ||
1160 | return &state->frontend; | ||
1161 | |||
1162 | error: | ||
1163 | kfree(state); | ||
1164 | printk("Unknown/Unsupported NXT chip: %02X %02X %02X %02X %02X\n", | ||
1165 | buf[0], buf[1], buf[2], buf[3], buf[4]); | ||
1166 | return NULL; | ||
1167 | } | ||
1168 | |||
1169 | static struct dvb_frontend_ops nxt200x_ops = { | ||
1170 | |||
1171 | .info = { | ||
1172 | .name = "Nextwave NXT200X VSB/QAM frontend", | ||
1173 | .type = FE_ATSC, | ||
1174 | .frequency_min = 54000000, | ||
1175 | .frequency_max = 860000000, | ||
1176 | .frequency_stepsize = 166666, /* stepsize is just a guess */ | ||
1177 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
1178 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
1179 | FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256 | ||
1180 | }, | ||
1181 | |||
1182 | .release = nxt200x_release, | ||
1183 | |||
1184 | .init = nxt200x_init, | ||
1185 | .sleep = nxt200x_sleep, | ||
1186 | |||
1187 | .set_frontend = nxt200x_setup_frontend_parameters, | ||
1188 | .get_tune_settings = nxt200x_get_tune_settings, | ||
1189 | |||
1190 | .read_status = nxt200x_read_status, | ||
1191 | .read_ber = nxt200x_read_ber, | ||
1192 | .read_signal_strength = nxt200x_read_signal_strength, | ||
1193 | .read_snr = nxt200x_read_snr, | ||
1194 | .read_ucblocks = nxt200x_read_ucblocks, | ||
1195 | }; | ||
1196 | |||
1197 | module_param(debug, int, 0644); | ||
1198 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
1199 | |||
1200 | MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver"); | ||
1201 | MODULE_AUTHOR("Kirk Lapray, Jean-Francois Thibert, and Taylor Jacob"); | ||
1202 | MODULE_LICENSE("GPL"); | ||
1203 | |||
1204 | EXPORT_SYMBOL(nxt200x_attach); | ||
1205 | |||
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h new file mode 100644 index 000000000000..1d9d70bc37ef --- /dev/null +++ b/drivers/media/dvb/frontends/nxt200x.h | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * Support for NXT2002 and NXT2004 - VSB/QAM | ||
3 | * | ||
4 | * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com) | ||
5 | * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> | ||
6 | * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifndef NXT200X_H | ||
25 | #define NXT200X_H | ||
26 | |||
27 | #include <linux/dvb/frontend.h> | ||
28 | #include <linux/firmware.h> | ||
29 | |||
30 | typedef enum nxt_chip_t { | ||
31 | NXTUNDEFINED, | ||
32 | NXT2002, | ||
33 | NXT2004 | ||
34 | }nxt_chip_type; | ||
35 | |||
36 | struct nxt200x_config | ||
37 | { | ||
38 | /* the demodulator's i2c address */ | ||
39 | u8 demod_address; | ||
40 | |||
41 | /* tuner information */ | ||
42 | u8 pll_address; | ||
43 | struct dvb_pll_desc *pll_desc; | ||
44 | |||
45 | /* used to set pll input */ | ||
46 | int (*set_pll_input)(u8* buf, int input); | ||
47 | |||
48 | /* need to set device param for start_dma */ | ||
49 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | ||
50 | }; | ||
51 | |||
52 | extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, | ||
53 | struct i2c_adapter* i2c); | ||
54 | |||
55 | #endif /* NXT200X_H */ | ||
56 | |||
57 | /* | ||
58 | * Local variables: | ||
59 | * c-basic-offset: 8 | ||
60 | * End: | ||
61 | */ | ||
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c index fc74c40d6477..78bded861d02 100644 --- a/drivers/media/dvb/frontends/or51132.c +++ b/drivers/media/dvb/frontends/or51132.c | |||
@@ -468,6 +468,7 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
468 | unsigned char snd_buf[2]; | 468 | unsigned char snd_buf[2]; |
469 | u8 rcvr_stat; | 469 | u8 rcvr_stat; |
470 | u16 snr_equ; | 470 | u16 snr_equ; |
471 | u32 signal_strength; | ||
471 | int usK; | 472 | int usK; |
472 | 473 | ||
473 | snd_buf[0]=0x04; | 474 | snd_buf[0]=0x04; |
@@ -503,7 +504,11 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
503 | usK = (rcvr_stat & 0x10) ? 3 : 0; | 504 | usK = (rcvr_stat & 0x10) ? 3 : 0; |
504 | 505 | ||
505 | /* The value reported back from the frontend will be FFFF=100% 0000=0% */ | 506 | /* The value reported back from the frontend will be FFFF=100% 0000=0% */ |
506 | *strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000; | 507 | signal_strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000; |
508 | if (signal_strength > 0xffff) | ||
509 | *strength = 0xffff; | ||
510 | else | ||
511 | *strength = signal_strength; | ||
507 | dprintk("read_signal_strength %i\n",*strength); | 512 | dprintk("read_signal_strength %i\n",*strength); |
508 | 513 | ||
509 | return 0; | 514 | return 0; |
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c index 8a9db23dd1b7..531f76246e5f 100644 --- a/drivers/media/dvb/frontends/or51211.c +++ b/drivers/media/dvb/frontends/or51211.c | |||
@@ -339,6 +339,7 @@ static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
339 | u8 rec_buf[2]; | 339 | u8 rec_buf[2]; |
340 | u8 snd_buf[4]; | 340 | u8 snd_buf[4]; |
341 | u8 snr_equ; | 341 | u8 snr_equ; |
342 | u32 signal_strength; | ||
342 | 343 | ||
343 | /* SNR after Equalizer */ | 344 | /* SNR after Equalizer */ |
344 | snd_buf[0] = 0x04; | 345 | snd_buf[0] = 0x04; |
@@ -358,8 +359,11 @@ static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
358 | snr_equ = rec_buf[0] & 0xff; | 359 | snr_equ = rec_buf[0] & 0xff; |
359 | 360 | ||
360 | /* The value reported back from the frontend will be FFFF=100% 0000=0% */ | 361 | /* The value reported back from the frontend will be FFFF=100% 0000=0% */ |
361 | *strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000; | 362 | signal_strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000; |
362 | 363 | if (signal_strength > 0xffff) | |
364 | *strength = 0xffff; | ||
365 | else | ||
366 | *strength = signal_strength; | ||
363 | dprintk("read_signal_strength %i\n",*strength); | 367 | dprintk("read_signal_strength %i\n",*strength); |
364 | 368 | ||
365 | return 0; | 369 | return 0; |
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c index 889d9257215d..29c48665e130 100644 --- a/drivers/media/dvb/frontends/stv0299.c +++ b/drivers/media/dvb/frontends/stv0299.c | |||
@@ -64,8 +64,12 @@ struct stv0299_state { | |||
64 | u32 tuner_frequency; | 64 | u32 tuner_frequency; |
65 | u32 symbol_rate; | 65 | u32 symbol_rate; |
66 | fe_code_rate_t fec_inner; | 66 | fe_code_rate_t fec_inner; |
67 | int errmode; | ||
67 | }; | 68 | }; |
68 | 69 | ||
70 | #define STATUS_BER 0 | ||
71 | #define STATUS_UCBLOCKS 1 | ||
72 | |||
69 | static int debug; | 73 | static int debug; |
70 | static int debug_legacy_dish_switch; | 74 | static int debug_legacy_dish_switch; |
71 | #define dprintk(args...) \ | 75 | #define dprintk(args...) \ |
@@ -383,36 +387,6 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag | |||
383 | }; | 387 | }; |
384 | } | 388 | } |
385 | 389 | ||
386 | static inline s32 stv0299_calc_usec_delay (struct timeval lasttime, struct timeval curtime) | ||
387 | { | ||
388 | return ((curtime.tv_usec < lasttime.tv_usec) ? | ||
389 | 1000000 - lasttime.tv_usec + curtime.tv_usec : | ||
390 | curtime.tv_usec - lasttime.tv_usec); | ||
391 | } | ||
392 | |||
393 | static void stv0299_sleep_until (struct timeval *waketime, u32 add_usec) | ||
394 | { | ||
395 | struct timeval lasttime; | ||
396 | s32 delta, newdelta; | ||
397 | |||
398 | waketime->tv_usec += add_usec; | ||
399 | if (waketime->tv_usec >= 1000000) { | ||
400 | waketime->tv_usec -= 1000000; | ||
401 | waketime->tv_sec++; | ||
402 | } | ||
403 | |||
404 | do_gettimeofday (&lasttime); | ||
405 | delta = stv0299_calc_usec_delay (lasttime, *waketime); | ||
406 | if (delta > 2500) { | ||
407 | msleep ((delta - 1500) / 1000); | ||
408 | do_gettimeofday (&lasttime); | ||
409 | newdelta = stv0299_calc_usec_delay (lasttime, *waketime); | ||
410 | delta = (newdelta > delta) ? 0 : newdelta; | ||
411 | } | ||
412 | if (delta > 0) | ||
413 | udelay (delta); | ||
414 | } | ||
415 | |||
416 | static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) | 390 | static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) |
417 | { | 391 | { |
418 | struct stv0299_state* state = fe->demodulator_priv; | 392 | struct stv0299_state* state = fe->demodulator_priv; |
@@ -440,7 +414,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) | |||
440 | memcpy (&tv[0], &nexttime, sizeof (struct timeval)); | 414 | memcpy (&tv[0], &nexttime, sizeof (struct timeval)); |
441 | stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */ | 415 | stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */ |
442 | 416 | ||
443 | stv0299_sleep_until (&nexttime, 32000); | 417 | dvb_frontend_sleep_until(&nexttime, 32000); |
444 | 418 | ||
445 | for (i=0; i<9; i++) { | 419 | for (i=0; i<9; i++) { |
446 | if (debug_legacy_dish_switch) | 420 | if (debug_legacy_dish_switch) |
@@ -454,13 +428,13 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) | |||
454 | cmd = cmd >> 1; | 428 | cmd = cmd >> 1; |
455 | 429 | ||
456 | if (i != 8) | 430 | if (i != 8) |
457 | stv0299_sleep_until (&nexttime, 8000); | 431 | dvb_frontend_sleep_until(&nexttime, 8000); |
458 | } | 432 | } |
459 | if (debug_legacy_dish_switch) { | 433 | if (debug_legacy_dish_switch) { |
460 | printk ("%s(%d): switch delay (should be 32k followed by all 8k\n", | 434 | printk ("%s(%d): switch delay (should be 32k followed by all 8k\n", |
461 | __FUNCTION__, fe->dvb->num); | 435 | __FUNCTION__, fe->dvb->num); |
462 | for (i=1; i < 10; i++) | 436 | for (i = 1; i < 10; i++) |
463 | printk ("%d: %d\n", i, stv0299_calc_usec_delay (tv[i-1] , tv[i])); | 437 | printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i])); |
464 | } | 438 | } |
465 | 439 | ||
466 | return 0; | 440 | return 0; |
@@ -517,8 +491,7 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber) | |||
517 | { | 491 | { |
518 | struct stv0299_state* state = fe->demodulator_priv; | 492 | struct stv0299_state* state = fe->demodulator_priv; |
519 | 493 | ||
520 | stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x10); | 494 | if (state->errmode != STATUS_BER) return 0; |
521 | msleep(100); | ||
522 | *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); | 495 | *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); |
523 | 496 | ||
524 | return 0; | 497 | return 0; |
@@ -557,9 +530,8 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
557 | { | 530 | { |
558 | struct stv0299_state* state = fe->demodulator_priv; | 531 | struct stv0299_state* state = fe->demodulator_priv; |
559 | 532 | ||
560 | stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x30); | 533 | if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0; |
561 | msleep(100); | 534 | else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); |
562 | *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); | ||
563 | 535 | ||
564 | return 0; | 536 | return 0; |
565 | } | 537 | } |
@@ -581,49 +553,14 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
581 | if (state->config->invert) invval = (~invval) & 1; | 553 | if (state->config->invert) invval = (~invval) & 1; |
582 | stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); | 554 | stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); |
583 | 555 | ||
584 | if (state->config->enhanced_tuning) { | 556 | stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ |
585 | /* check if we should do a finetune */ | 557 | state->config->pll_set(fe, state->i2c, p); |
586 | int frequency_delta = p->frequency - state->tuner_frequency; | 558 | stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */ |
587 | int minmax = p->u.qpsk.symbol_rate / 2000; | ||
588 | if (minmax < 5000) minmax = 5000; | ||
589 | |||
590 | if ((frequency_delta > -minmax) && (frequency_delta < minmax) && (frequency_delta != 0) && | ||
591 | (state->fec_inner == p->u.qpsk.fec_inner) && | ||
592 | (state->symbol_rate == p->u.qpsk.symbol_rate)) { | ||
593 | int Drot_freq = (frequency_delta << 16) / (state->config->mclk / 1000); | ||
594 | |||
595 | // zap the derotator registers first | ||
596 | stv0299_writeregI(state, 0x22, 0x00); | ||
597 | stv0299_writeregI(state, 0x23, 0x00); | ||
598 | |||
599 | // now set them as we want | ||
600 | stv0299_writeregI(state, 0x22, Drot_freq >> 8); | ||
601 | stv0299_writeregI(state, 0x23, Drot_freq); | ||
602 | } else { | ||
603 | /* A "normal" tune is requested */ | ||
604 | stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ | ||
605 | state->config->pll_set(fe, state->i2c, p); | ||
606 | stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */ | ||
607 | |||
608 | stv0299_writeregI(state, 0x32, 0x80); | ||
609 | stv0299_writeregI(state, 0x22, 0x00); | ||
610 | stv0299_writeregI(state, 0x23, 0x00); | ||
611 | stv0299_writeregI(state, 0x32, 0x19); | ||
612 | stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); | ||
613 | stv0299_set_FEC (state, p->u.qpsk.fec_inner); | ||
614 | } | ||
615 | } else { | ||
616 | stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ | ||
617 | state->config->pll_set(fe, state->i2c, p); | ||
618 | stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */ | ||
619 | 559 | ||
620 | stv0299_set_FEC (state, p->u.qpsk.fec_inner); | 560 | stv0299_set_FEC (state, p->u.qpsk.fec_inner); |
621 | stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); | 561 | stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); |
622 | stv0299_writeregI(state, 0x22, 0x00); | 562 | stv0299_writeregI(state, 0x22, 0x00); |
623 | stv0299_writeregI(state, 0x23, 0x00); | 563 | stv0299_writeregI(state, 0x23, 0x00); |
624 | stv0299_readreg (state, 0x23); | ||
625 | stv0299_writeregI(state, 0x12, 0xb9); | ||
626 | } | ||
627 | 564 | ||
628 | state->tuner_frequency = p->frequency; | 565 | state->tuner_frequency = p->frequency; |
629 | state->fec_inner = p->u.qpsk.fec_inner; | 566 | state->fec_inner = p->u.qpsk.fec_inner; |
@@ -708,6 +645,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, | |||
708 | state->tuner_frequency = 0; | 645 | state->tuner_frequency = 0; |
709 | state->symbol_rate = 0; | 646 | state->symbol_rate = 0; |
710 | state->fec_inner = 0; | 647 | state->fec_inner = 0; |
648 | state->errmode = STATUS_BER; | ||
711 | 649 | ||
712 | /* check if the demod is there */ | 650 | /* check if the demod is there */ |
713 | stv0299_writeregI(state, 0x02, 0x34); /* standby off */ | 651 | stv0299_writeregI(state, 0x02, 0x34); /* standby off */ |
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h index d0c4484861e1..9af3d71c89db 100644 --- a/drivers/media/dvb/frontends/stv0299.h +++ b/drivers/media/dvb/frontends/stv0299.h | |||
@@ -73,9 +73,6 @@ struct stv0299_config | |||
73 | /* does the inversion require inversion? */ | 73 | /* does the inversion require inversion? */ |
74 | u8 invert:1; | 74 | u8 invert:1; |
75 | 75 | ||
76 | /* Should the enhanced tuning code be used? */ | ||
77 | u8 enhanced_tuning:1; | ||
78 | |||
79 | /* Skip reinitialisation? */ | 76 | /* Skip reinitialisation? */ |
80 | u8 skip_reinit:1; | 77 | u8 skip_reinit:1; |
81 | 78 | ||
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index 3529c618f828..7968743826fc 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c | |||
@@ -420,7 +420,7 @@ static void tda10046_init_plls(struct dvb_frontend* fe) | |||
420 | struct tda1004x_state* state = fe->demodulator_priv; | 420 | struct tda1004x_state* state = fe->demodulator_priv; |
421 | 421 | ||
422 | tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); | 422 | tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); |
423 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10 | 423 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x0a); // PLL M = 10 |
424 | if (state->config->xtal_freq == TDA10046_XTAL_4M ) { | 424 | if (state->config->xtal_freq == TDA10046_XTAL_4M ) { |
425 | dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); | 425 | dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); |
426 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 | 426 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 |
@@ -597,7 +597,10 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
597 | // Init the tuner PLL | 597 | // Init the tuner PLL |
598 | if (state->config->pll_init) { | 598 | if (state->config->pll_init) { |
599 | tda1004x_enable_tuner_i2c(state); | 599 | tda1004x_enable_tuner_i2c(state); |
600 | state->config->pll_init(fe); | 600 | if (state->config->pll_init(fe)) { |
601 | printk(KERN_ERR "tda1004x: pll init failed\n"); | ||
602 | return -EIO; | ||
603 | } | ||
601 | tda1004x_disable_tuner_i2c(state); | 604 | tda1004x_disable_tuner_i2c(state); |
602 | } | 605 | } |
603 | 606 | ||
@@ -667,7 +670,10 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
667 | 670 | ||
668 | // set frequency | 671 | // set frequency |
669 | tda1004x_enable_tuner_i2c(state); | 672 | tda1004x_enable_tuner_i2c(state); |
670 | state->config->pll_set(fe, fe_params); | 673 | if (state->config->pll_set(fe, fe_params)) { |
674 | printk(KERN_ERR "tda1004x: pll set failed\n"); | ||
675 | return -EIO; | ||
676 | } | ||
671 | tda1004x_disable_tuner_i2c(state); | 677 | tda1004x_disable_tuner_i2c(state); |
672 | 678 | ||
673 | // Hardcoded to use auto as much as possible on the TDA10045 as it | 679 | // Hardcoded to use auto as much as possible on the TDA10045 as it |
@@ -832,6 +838,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
832 | 838 | ||
833 | case TDA1004X_DEMOD_TDA10046: | 839 | case TDA1004X_DEMOD_TDA10046: |
834 | tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); | 840 | tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); |
841 | msleep(1); | ||
842 | tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1); | ||
835 | break; | 843 | break; |
836 | } | 844 | } |
837 | 845 | ||
@@ -1129,7 +1137,12 @@ static int tda1004x_sleep(struct dvb_frontend* fe) | |||
1129 | if (state->config->pll_sleep != NULL) { | 1137 | if (state->config->pll_sleep != NULL) { |
1130 | tda1004x_enable_tuner_i2c(state); | 1138 | tda1004x_enable_tuner_i2c(state); |
1131 | state->config->pll_sleep(fe); | 1139 | state->config->pll_sleep(fe); |
1132 | tda1004x_disable_tuner_i2c(state); | 1140 | if (state->config->if_freq != TDA10046_FREQ_052) { |
1141 | /* special hack for Philips EUROPA Based boards: | ||
1142 | * keep the I2c bridge open for tuner access in analog mode | ||
1143 | */ | ||
1144 | tda1004x_disable_tuner_i2c(state); | ||
1145 | } | ||
1133 | } | 1146 | } |
1134 | tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); | 1147 | tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); |
1135 | break; | 1148 | break; |
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 85b437bbddcd..bbebd1c4caca 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c | |||
@@ -286,15 +286,10 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets) | |||
286 | * although one packet has been transfered. | 286 | * although one packet has been transfered. |
287 | */ | 287 | */ |
288 | if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) { | 288 | if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) { |
289 | unsigned int i = 0, valid; | 289 | unsigned int i = 0; |
290 | while (pluto->dma_buf[i] == 0x47) | 290 | while (pluto->dma_buf[i] == 0x47) |
291 | i += 188; | 291 | i += 188; |
292 | valid = i / 188; | 292 | nbpackets = i / 188; |
293 | if (nbpackets != valid) { | ||
294 | dev_err(&pluto->pdev->dev, "nbpackets=%u valid=%u\n", | ||
295 | nbpackets, valid); | ||
296 | nbpackets = valid; | ||
297 | } | ||
298 | } | 293 | } |
299 | 294 | ||
300 | dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets); | 295 | dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets); |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 22b203f8ff27..87ea52757a21 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -1566,7 +1566,7 @@ static u8 alps_bsru6_inittab[] = { | |||
1566 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | 1566 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ |
1567 | 0x10, 0x3f, // AGC2 0x3d | 1567 | 0x10, 0x3f, // AGC2 0x3d |
1568 | 0x11, 0x84, | 1568 | 0x11, 0x84, |
1569 | 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on | 1569 | 0x12, 0xb9, |
1570 | 0x15, 0xc9, // lock detector threshold | 1570 | 0x15, 0xc9, // lock detector threshold |
1571 | 0x16, 0x00, | 1571 | 0x16, 0x00, |
1572 | 0x17, 0x00, | 1572 | 0x17, 0x00, |
@@ -1644,7 +1644,6 @@ static struct stv0299_config alps_bsru6_config = { | |||
1644 | .inittab = alps_bsru6_inittab, | 1644 | .inittab = alps_bsru6_inittab, |
1645 | .mclk = 88000000UL, | 1645 | .mclk = 88000000UL, |
1646 | .invert = 1, | 1646 | .invert = 1, |
1647 | .enhanced_tuning = 0, | ||
1648 | .skip_reinit = 0, | 1647 | .skip_reinit = 0, |
1649 | .lock_output = STV0229_LOCKOUTPUT_1, | 1648 | .lock_output = STV0229_LOCKOUTPUT_1, |
1650 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 1649 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
@@ -1669,7 +1668,7 @@ static u8 alps_bsbe1_inittab[] = { | |||
1669 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | 1668 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ |
1670 | 0x10, 0x3f, // AGC2 0x3d | 1669 | 0x10, 0x3f, // AGC2 0x3d |
1671 | 0x11, 0x84, | 1670 | 0x11, 0x84, |
1672 | 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on | 1671 | 0x12, 0xb9, |
1673 | 0x15, 0xc9, // lock detector threshold | 1672 | 0x15, 0xc9, // lock detector threshold |
1674 | 0x16, 0x00, | 1673 | 0x16, 0x00, |
1675 | 0x17, 0x00, | 1674 | 0x17, 0x00, |
@@ -1721,7 +1720,6 @@ static struct stv0299_config alps_bsbe1_config = { | |||
1721 | .inittab = alps_bsbe1_inittab, | 1720 | .inittab = alps_bsbe1_inittab, |
1722 | .mclk = 88000000UL, | 1721 | .mclk = 88000000UL, |
1723 | .invert = 1, | 1722 | .invert = 1, |
1724 | .enhanced_tuning = 0, | ||
1725 | .skip_reinit = 0, | 1723 | .skip_reinit = 0, |
1726 | .min_delay_ms = 100, | 1724 | .min_delay_ms = 100, |
1727 | .set_symbol_rate = alps_bsru6_set_symbol_rate, | 1725 | .set_symbol_rate = alps_bsru6_set_symbol_rate, |
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 7692cd23f839..aa75dc03a0b3 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c | |||
@@ -499,7 +499,7 @@ static u8 typhoon_cinergy1200s_inittab[] = { | |||
499 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | 499 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ |
500 | 0x10, 0x3f, // AGC2 0x3d | 500 | 0x10, 0x3f, // AGC2 0x3d |
501 | 0x11, 0x84, | 501 | 0x11, 0x84, |
502 | 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on | 502 | 0x12, 0xb9, |
503 | 0x15, 0xc9, // lock detector threshold | 503 | 0x15, 0xc9, // lock detector threshold |
504 | 0x16, 0x00, | 504 | 0x16, 0x00, |
505 | 0x17, 0x00, | 505 | 0x17, 0x00, |
@@ -531,7 +531,6 @@ static struct stv0299_config typhoon_config = { | |||
531 | .inittab = typhoon_cinergy1200s_inittab, | 531 | .inittab = typhoon_cinergy1200s_inittab, |
532 | .mclk = 88000000UL, | 532 | .mclk = 88000000UL, |
533 | .invert = 0, | 533 | .invert = 0, |
534 | .enhanced_tuning = 0, | ||
535 | .skip_reinit = 0, | 534 | .skip_reinit = 0, |
536 | .lock_output = STV0229_LOCKOUTPUT_1, | 535 | .lock_output = STV0229_LOCKOUTPUT_1, |
537 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | 536 | .volt13_op0_op1 = STV0299_VOLT13_OP0, |
@@ -546,7 +545,6 @@ static struct stv0299_config cinergy_1200s_config = { | |||
546 | .inittab = typhoon_cinergy1200s_inittab, | 545 | .inittab = typhoon_cinergy1200s_inittab, |
547 | .mclk = 88000000UL, | 546 | .mclk = 88000000UL, |
548 | .invert = 0, | 547 | .invert = 0, |
549 | .enhanced_tuning = 0, | ||
550 | .skip_reinit = 0, | 548 | .skip_reinit = 0, |
551 | .lock_output = STV0229_LOCKOUTPUT_0, | 549 | .lock_output = STV0229_LOCKOUTPUT_0, |
552 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | 550 | .volt13_op0_op1 = STV0299_VOLT13_OP0, |
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 51c30ba68140..75fb92d60998 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
@@ -490,7 +490,7 @@ static u8 alps_bsru6_inittab[] = { | |||
490 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | 490 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ |
491 | 0x10, 0x3f, // AGC2 0x3d | 491 | 0x10, 0x3f, // AGC2 0x3d |
492 | 0x11, 0x84, | 492 | 0x11, 0x84, |
493 | 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on | 493 | 0x12, 0xb9, |
494 | 0x15, 0xc9, // lock detector threshold | 494 | 0x15, 0xc9, // lock detector threshold |
495 | 0x16, 0x00, | 495 | 0x16, 0x00, |
496 | 0x17, 0x00, | 496 | 0x17, 0x00, |
@@ -580,7 +580,6 @@ static struct stv0299_config alps_bsru6_config = { | |||
580 | .inittab = alps_bsru6_inittab, | 580 | .inittab = alps_bsru6_inittab, |
581 | .mclk = 88000000UL, | 581 | .mclk = 88000000UL, |
582 | .invert = 1, | 582 | .invert = 1, |
583 | .enhanced_tuning = 0, | ||
584 | .skip_reinit = 0, | 583 | .skip_reinit = 0, |
585 | .lock_output = STV0229_LOCKOUTPUT_1, | 584 | .lock_output = STV0229_LOCKOUTPUT_1, |
586 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 585 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
@@ -710,7 +709,6 @@ static struct stv0299_config philips_su1278_tt_config = { | |||
710 | .inittab = philips_su1278_tt_inittab, | 709 | .inittab = philips_su1278_tt_inittab, |
711 | .mclk = 64000000UL, | 710 | .mclk = 64000000UL, |
712 | .invert = 0, | 711 | .invert = 0, |
713 | .enhanced_tuning = 1, | ||
714 | .skip_reinit = 1, | 712 | .skip_reinit = 1, |
715 | .lock_output = STV0229_LOCKOUTPUT_1, | 713 | .lock_output = STV0229_LOCKOUTPUT_1, |
716 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 714 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c index b1f21ef0e3b3..755df81cbc49 100644 --- a/drivers/media/dvb/ttpci/budget-patch.c +++ b/drivers/media/dvb/ttpci/budget-patch.c | |||
@@ -305,7 +305,7 @@ static u8 alps_bsru6_inittab[] = { | |||
305 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | 305 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ |
306 | 0x10, 0x3f, // AGC2 0x3d | 306 | 0x10, 0x3f, // AGC2 0x3d |
307 | 0x11, 0x84, | 307 | 0x11, 0x84, |
308 | 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on | 308 | 0x12, 0xb9, |
309 | 0x15, 0xc9, // lock detector threshold | 309 | 0x15, 0xc9, // lock detector threshold |
310 | 0x16, 0x00, | 310 | 0x16, 0x00, |
311 | 0x17, 0x00, | 311 | 0x17, 0x00, |
@@ -379,7 +379,6 @@ static struct stv0299_config alps_bsru6_config = { | |||
379 | .inittab = alps_bsru6_inittab, | 379 | .inittab = alps_bsru6_inittab, |
380 | .mclk = 88000000UL, | 380 | .mclk = 88000000UL, |
381 | .invert = 1, | 381 | .invert = 1, |
382 | .enhanced_tuning = 0, | ||
383 | .skip_reinit = 0, | 382 | .skip_reinit = 0, |
384 | .lock_output = STV0229_LOCKOUTPUT_1, | 383 | .lock_output = STV0229_LOCKOUTPUT_1, |
385 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 384 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index 43d6c8268642..4fd8bbc47037 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c | |||
@@ -226,12 +226,14 @@ static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg) | |||
226 | return 0; | 226 | return 0; |
227 | } | 227 | } |
228 | 228 | ||
229 | static void lnbp21_init(struct budget* budget) | 229 | static int lnbp21_init(struct budget* budget) |
230 | { | 230 | { |
231 | u8 buf = 0x00; | 231 | u8 buf = 0x00; |
232 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) }; | 232 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) }; |
233 | 233 | ||
234 | i2c_transfer (&budget->i2c_adap, &msg, 1); | 234 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) |
235 | return -EIO; | ||
236 | return 0; | ||
235 | } | 237 | } |
236 | 238 | ||
237 | static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 239 | static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
@@ -273,7 +275,7 @@ static u8 alps_bsru6_inittab[] = { | |||
273 | 0x01, 0x15, | 275 | 0x01, 0x15, |
274 | 0x02, 0x00, | 276 | 0x02, 0x00, |
275 | 0x03, 0x00, | 277 | 0x03, 0x00, |
276 | 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ | 278 | 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ |
277 | 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ | 279 | 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ |
278 | 0x06, 0x40, /* DAC not used, set to high impendance mode */ | 280 | 0x06, 0x40, /* DAC not used, set to high impendance mode */ |
279 | 0x07, 0x00, /* DAC LSB */ | 281 | 0x07, 0x00, /* DAC LSB */ |
@@ -284,7 +286,7 @@ static u8 alps_bsru6_inittab[] = { | |||
284 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | 286 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ |
285 | 0x10, 0x3f, // AGC2 0x3d | 287 | 0x10, 0x3f, // AGC2 0x3d |
286 | 0x11, 0x84, | 288 | 0x11, 0x84, |
287 | 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on | 289 | 0x12, 0xb9, |
288 | 0x15, 0xc9, // lock detector threshold | 290 | 0x15, 0xc9, // lock detector threshold |
289 | 0x16, 0x00, | 291 | 0x16, 0x00, |
290 | 0x17, 0x00, | 292 | 0x17, 0x00, |
@@ -358,7 +360,6 @@ static struct stv0299_config alps_bsru6_config = { | |||
358 | .inittab = alps_bsru6_inittab, | 360 | .inittab = alps_bsru6_inittab, |
359 | .mclk = 88000000UL, | 361 | .mclk = 88000000UL, |
360 | .invert = 1, | 362 | .invert = 1, |
361 | .enhanced_tuning = 0, | ||
362 | .skip_reinit = 0, | 363 | .skip_reinit = 0, |
363 | .lock_output = STV0229_LOCKOUTPUT_1, | 364 | .lock_output = STV0229_LOCKOUTPUT_1, |
364 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 365 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
@@ -367,6 +368,79 @@ static struct stv0299_config alps_bsru6_config = { | |||
367 | .pll_set = alps_bsru6_pll_set, | 368 | .pll_set = alps_bsru6_pll_set, |
368 | }; | 369 | }; |
369 | 370 | ||
371 | static u8 alps_bsbe1_inittab[] = { | ||
372 | 0x01, 0x15, | ||
373 | 0x02, 0x30, | ||
374 | 0x03, 0x00, | ||
375 | 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ | ||
376 | 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ | ||
377 | 0x06, 0x40, /* DAC not used, set to high impendance mode */ | ||
378 | 0x07, 0x00, /* DAC LSB */ | ||
379 | 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ | ||
380 | 0x09, 0x00, /* FIFO */ | ||
381 | 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ | ||
382 | 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ | ||
383 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | ||
384 | 0x10, 0x3f, // AGC2 0x3d | ||
385 | 0x11, 0x84, | ||
386 | 0x12, 0xb9, | ||
387 | 0x15, 0xc9, // lock detector threshold | ||
388 | 0x16, 0x00, | ||
389 | 0x17, 0x00, | ||
390 | 0x18, 0x00, | ||
391 | 0x19, 0x00, | ||
392 | 0x1a, 0x00, | ||
393 | 0x1f, 0x50, | ||
394 | 0x20, 0x00, | ||
395 | 0x21, 0x00, | ||
396 | 0x22, 0x00, | ||
397 | 0x23, 0x00, | ||
398 | 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 | ||
399 | 0x29, 0x1e, // 1/2 threshold | ||
400 | 0x2a, 0x14, // 2/3 threshold | ||
401 | 0x2b, 0x0f, // 3/4 threshold | ||
402 | 0x2c, 0x09, // 5/6 threshold | ||
403 | 0x2d, 0x05, // 7/8 threshold | ||
404 | 0x2e, 0x01, | ||
405 | 0x31, 0x1f, // test all FECs | ||
406 | 0x32, 0x19, // viterbi and synchro search | ||
407 | 0x33, 0xfc, // rs control | ||
408 | 0x34, 0x93, // error control | ||
409 | 0x0f, 0x92, // 0x80 = inverse AGC | ||
410 | 0xff, 0xff | ||
411 | }; | ||
412 | |||
413 | static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) | ||
414 | { | ||
415 | int ret; | ||
416 | u8 data[4]; | ||
417 | u32 div; | ||
418 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
419 | |||
420 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | ||
421 | return -EINVAL; | ||
422 | |||
423 | div = (params->frequency + (125 - 1)) / 125; // round correctly | ||
424 | data[0] = (div >> 8) & 0x7f; | ||
425 | data[1] = div & 0xff; | ||
426 | data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | ||
427 | data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; | ||
428 | |||
429 | ret = i2c_transfer(i2c, &msg, 1); | ||
430 | return (ret != 1) ? -EIO : 0; | ||
431 | } | ||
432 | |||
433 | static struct stv0299_config alps_bsbe1_config = { | ||
434 | .demod_address = 0x68, | ||
435 | .inittab = alps_bsbe1_inittab, | ||
436 | .mclk = 88000000UL, | ||
437 | .invert = 1, | ||
438 | .skip_reinit = 0, | ||
439 | .min_delay_ms = 100, | ||
440 | .set_symbol_rate = alps_bsru6_set_symbol_rate, | ||
441 | .pll_set = alps_bsbe1_pll_set, | ||
442 | }; | ||
443 | |||
370 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 444 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
371 | { | 445 | { |
372 | struct budget* budget = (struct budget*) fe->dvb->priv; | 446 | struct budget* budget = (struct budget*) fe->dvb->priv; |
@@ -500,6 +574,19 @@ static u8 read_pwm(struct budget* budget) | |||
500 | static void frontend_init(struct budget *budget) | 574 | static void frontend_init(struct budget *budget) |
501 | { | 575 | { |
502 | switch(budget->dev->pci->subsystem_device) { | 576 | switch(budget->dev->pci->subsystem_device) { |
577 | case 0x1017: | ||
578 | // try the ALPS BSBE1 now | ||
579 | budget->dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget->i2c_adap); | ||
580 | if (budget->dvb_frontend) { | ||
581 | budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; | ||
582 | budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | ||
583 | if (lnbp21_init(budget)) { | ||
584 | printk("%s: No LNBP21 found!\n", __FUNCTION__); | ||
585 | goto error_out; | ||
586 | } | ||
587 | } | ||
588 | |||
589 | break; | ||
503 | case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) | 590 | case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) |
504 | case 0x1013: | 591 | case 0x1013: |
505 | // try the ALPS BSRV2 first of all | 592 | // try the ALPS BSRV2 first of all |
@@ -554,7 +641,10 @@ static void frontend_init(struct budget *budget) | |||
554 | if (budget->dvb_frontend) { | 641 | if (budget->dvb_frontend) { |
555 | budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; | 642 | budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; |
556 | budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | 643 | budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; |
557 | lnbp21_init(budget); | 644 | if (lnbp21_init(budget)) { |
645 | printk("%s: No LNBP21 found!\n", __FUNCTION__); | ||
646 | goto error_out; | ||
647 | } | ||
558 | break; | 648 | break; |
559 | } | 649 | } |
560 | } | 650 | } |
@@ -566,13 +656,17 @@ static void frontend_init(struct budget *budget) | |||
566 | budget->dev->pci->subsystem_vendor, | 656 | budget->dev->pci->subsystem_vendor, |
567 | budget->dev->pci->subsystem_device); | 657 | budget->dev->pci->subsystem_device); |
568 | } else { | 658 | } else { |
569 | if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { | 659 | if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) |
570 | printk("budget: Frontend registration failed!\n"); | 660 | goto error_out; |
571 | if (budget->dvb_frontend->ops->release) | ||
572 | budget->dvb_frontend->ops->release(budget->dvb_frontend); | ||
573 | budget->dvb_frontend = NULL; | ||
574 | } | ||
575 | } | 661 | } |
662 | return; | ||
663 | |||
664 | error_out: | ||
665 | printk("budget: Frontend registration failed!\n"); | ||
666 | if (budget->dvb_frontend->ops->release) | ||
667 | budget->dvb_frontend->ops->release(budget->dvb_frontend); | ||
668 | budget->dvb_frontend = NULL; | ||
669 | return; | ||
576 | } | 670 | } |
577 | 671 | ||
578 | static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) | 672 | static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) |
@@ -618,6 +712,7 @@ static int budget_detach (struct saa7146_dev* dev) | |||
618 | 712 | ||
619 | static struct saa7146_extension budget_extension; | 713 | static struct saa7146_extension budget_extension; |
620 | 714 | ||
715 | MAKE_BUDGET_INFO(ttbs2, "TT-Budget/WinTV-NOVA-S PCI (rev AL/alps bsbe1 lnbp21 frontend)", BUDGET_TT); | ||
621 | MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); | 716 | MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); |
622 | MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); | 717 | MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); |
623 | MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); | 718 | MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); |
@@ -630,6 +725,7 @@ static struct pci_device_id pci_tbl[] = { | |||
630 | MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), | 725 | MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), |
631 | MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), | 726 | MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), |
632 | MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), | 727 | MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), |
728 | MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), | ||
633 | MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), | 729 | MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), |
634 | MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), | 730 | MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), |
635 | MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), | 731 | MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), |
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index d200ab0ad9e7..fd53d6010502 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | |||
@@ -1198,7 +1198,7 @@ static u8 alps_bsbe1_inittab[] = { | |||
1198 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | 1198 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ |
1199 | 0x10, 0x3f, // AGC2 0x3d | 1199 | 0x10, 0x3f, // AGC2 0x3d |
1200 | 0x11, 0x84, | 1200 | 0x11, 0x84, |
1201 | 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on | 1201 | 0x12, 0xb9, |
1202 | 0x15, 0xc9, // lock detector threshold | 1202 | 0x15, 0xc9, // lock detector threshold |
1203 | 0x16, 0x00, | 1203 | 0x16, 0x00, |
1204 | 0x17, 0x00, | 1204 | 0x17, 0x00, |
@@ -1240,7 +1240,7 @@ static u8 alps_bsru6_inittab[] = { | |||
1240 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | 1240 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ |
1241 | 0x10, 0x3f, // AGC2 0x3d | 1241 | 0x10, 0x3f, // AGC2 0x3d |
1242 | 0x11, 0x84, | 1242 | 0x11, 0x84, |
1243 | 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on | 1243 | 0x12, 0xb9, |
1244 | 0x15, 0xc9, // lock detector threshold | 1244 | 0x15, 0xc9, // lock detector threshold |
1245 | 0x16, 0x00, | 1245 | 0x16, 0x00, |
1246 | 0x17, 0x00, | 1246 | 0x17, 0x00, |
@@ -1335,7 +1335,6 @@ static struct stv0299_config alps_stv0299_config = { | |||
1335 | .inittab = alps_bsru6_inittab, | 1335 | .inittab = alps_bsru6_inittab, |
1336 | .mclk = 88000000UL, | 1336 | .mclk = 88000000UL, |
1337 | .invert = 1, | 1337 | .invert = 1, |
1338 | .enhanced_tuning = 0, | ||
1339 | .skip_reinit = 0, | 1338 | .skip_reinit = 0, |
1340 | .lock_output = STV0229_LOCKOUTPUT_1, | 1339 | .lock_output = STV0229_LOCKOUTPUT_1, |
1341 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 1340 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index bbb989df4cf0..199b01188858 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -25,6 +25,16 @@ config VIDEO_BT848 | |||
25 | To compile this driver as a module, choose M here: the | 25 | To compile this driver as a module, choose M here: the |
26 | module will be called bttv. | 26 | module will be called bttv. |
27 | 27 | ||
28 | config VIDEO_BT848_DVB | ||
29 | tristate "DVB/ATSC Support for bt878 based TV cards" | ||
30 | depends on VIDEO_BT848 && DVB_CORE | ||
31 | select DVB_BT8XX | ||
32 | ---help--- | ||
33 | This adds support for DVB/ATSC cards based on the BT878 chip. | ||
34 | |||
35 | To compile this driver as a module, choose M here: the | ||
36 | module will be called dvb-bt8xx. | ||
37 | |||
28 | config VIDEO_SAA6588 | 38 | config VIDEO_SAA6588 |
29 | tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards" | 39 | tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards" |
30 | depends on VIDEO_DEV && I2C && VIDEO_BT848 | 40 | depends on VIDEO_DEV && I2C && VIDEO_BT848 |
@@ -243,29 +253,7 @@ config VIDEO_MEYE | |||
243 | To compile this driver as a module, choose M here: the | 253 | To compile this driver as a module, choose M here: the |
244 | module will be called meye. | 254 | module will be called meye. |
245 | 255 | ||
246 | config VIDEO_SAA7134 | 256 | source "drivers/media/video/saa7134/Kconfig" |
247 | tristate "Philips SAA7134 support" | ||
248 | depends on VIDEO_DEV && PCI && I2C && SOUND | ||
249 | select VIDEO_BUF | ||
250 | select VIDEO_IR | ||
251 | select VIDEO_TUNER | ||
252 | select CRC32 | ||
253 | ---help--- | ||
254 | This is a video4linux driver for Philips SAA7130/7134 based | ||
255 | TV cards. | ||
256 | |||
257 | To compile this driver as a module, choose M here: the | ||
258 | module will be called saa7134. | ||
259 | |||
260 | config VIDEO_SAA7134_DVB | ||
261 | tristate "DVB Support for saa7134 based TV cards" | ||
262 | depends on VIDEO_SAA7134 && DVB_CORE | ||
263 | select VIDEO_BUF_DVB | ||
264 | select DVB_MT352 | ||
265 | select DVB_TDA1004X | ||
266 | ---help--- | ||
267 | This adds support for DVB cards based on the | ||
268 | Philips saa7134 chip. | ||
269 | 257 | ||
270 | config VIDEO_MXB | 258 | config VIDEO_MXB |
271 | tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" | 259 | tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" |
@@ -316,34 +304,9 @@ config VIDEO_HEXIUM_GEMINI | |||
316 | To compile this driver as a module, choose M here: the | 304 | To compile this driver as a module, choose M here: the |
317 | module will be called hexium_gemini. | 305 | module will be called hexium_gemini. |
318 | 306 | ||
319 | config VIDEO_CX88 | 307 | source "drivers/media/video/cx88/Kconfig" |
320 | tristate "Conexant 2388x (bt878 successor) support" | ||
321 | depends on VIDEO_DEV && PCI && I2C && EXPERIMENTAL | ||
322 | select I2C_ALGOBIT | ||
323 | select FW_LOADER | ||
324 | select VIDEO_BTCX | ||
325 | select VIDEO_BUF | ||
326 | select VIDEO_TUNER | ||
327 | select VIDEO_TVEEPROM | ||
328 | select VIDEO_IR | ||
329 | ---help--- | ||
330 | This is a video4linux driver for Conexant 2388x based | ||
331 | TV cards. | ||
332 | 308 | ||
333 | To compile this driver as a module, choose M here: the | 309 | source "drivers/media/video/em28xx/Kconfig" |
334 | module will be called cx8800 | ||
335 | |||
336 | config VIDEO_CX88_DVB | ||
337 | tristate "DVB Support for cx2388x based TV cards" | ||
338 | depends on VIDEO_CX88 && DVB_CORE | ||
339 | select VIDEO_BUF_DVB | ||
340 | select DVB_MT352 | ||
341 | select DVB_OR51132 | ||
342 | select DVB_CX22702 | ||
343 | select DVB_LGDT330X | ||
344 | ---help--- | ||
345 | This adds support for DVB/ATSC cards based on the | ||
346 | Connexant 2388x chip. | ||
347 | 310 | ||
348 | config VIDEO_OVCAMCHIP | 311 | config VIDEO_OVCAMCHIP |
349 | tristate "OmniVision Camera Chip support" | 312 | tristate "OmniVision Camera Chip support" |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 046b82de9285..3ac465992400 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -5,7 +5,6 @@ | |||
5 | bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ | 5 | bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ |
6 | bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o | 6 | bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o |
7 | zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o | 7 | zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o |
8 | rds-objs := saa6588.o | ||
9 | zr36067-objs := zoran_procfs.o zoran_device.o \ | 8 | zr36067-objs := zoran_procfs.o zoran_device.o \ |
10 | zoran_driver.o zoran_card.o | 9 | zoran_driver.o zoran_card.o |
11 | tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o | 10 | tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o |
@@ -16,7 +15,7 @@ obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ | |||
16 | obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o | 15 | obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o |
17 | 16 | ||
18 | obj-$(CONFIG_VIDEO_ZR36120) += zoran.o | 17 | obj-$(CONFIG_VIDEO_ZR36120) += zoran.o |
19 | obj-$(CONFIG_VIDEO_SAA6588) += rds.o | 18 | obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o |
20 | obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o | 19 | obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o |
21 | obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o | 20 | obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o |
22 | obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o | 21 | obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o |
@@ -39,6 +38,8 @@ obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o | |||
39 | obj-$(CONFIG_VIDEO_MEYE) += meye.o | 38 | obj-$(CONFIG_VIDEO_MEYE) += meye.o |
40 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ | 39 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ |
41 | obj-$(CONFIG_VIDEO_CX88) += cx88/ | 40 | obj-$(CONFIG_VIDEO_CX88) += cx88/ |
41 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ | ||
42 | obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o | ||
42 | obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ | 43 | obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ |
43 | obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o | 44 | obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o |
44 | obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o | 45 | obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o |
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 0823ddaf7004..881cdcb1875d 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/devfs_fs_kernel.h> | 23 | #include <linux/devfs_fs_kernel.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/version.h> | ||
26 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
27 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
28 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c index 76c1b63ebdf2..e4063950ae57 100644 --- a/drivers/media/video/bt832.c +++ b/drivers/media/video/bt832.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | 33 | ||
34 | #include <media/audiochip.h> | 34 | #include <media/audiochip.h> |
35 | #include <media/id.h> | ||
36 | #include "bttv.h" | 35 | #include "bttv.h" |
37 | #include "bt832.h" | 36 | #include "bt832.h" |
38 | 37 | ||
@@ -54,36 +53,36 @@ static struct i2c_driver driver; | |||
54 | static struct i2c_client client_template; | 53 | static struct i2c_client client_template; |
55 | 54 | ||
56 | struct bt832 { | 55 | struct bt832 { |
57 | struct i2c_client client; | 56 | struct i2c_client client; |
58 | }; | 57 | }; |
59 | 58 | ||
60 | int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf) | 59 | int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf) |
61 | { | 60 | { |
62 | int i,rc; | 61 | int i,rc; |
63 | buf[0]=0x80; // start at register 0 with auto-increment | 62 | buf[0]=0x80; // start at register 0 with auto-increment |
64 | if (1 != (rc = i2c_master_send(i2c_client_s,buf,1))) | 63 | if (1 != (rc = i2c_master_send(i2c_client_s,buf,1))) |
65 | printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc); | 64 | printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc); |
66 | 65 | ||
67 | for(i=0;i<65;i++) | 66 | for(i=0;i<65;i++) |
68 | buf[i]=0; | 67 | buf[i]=0; |
69 | if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65))) | 68 | if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65))) |
70 | printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc); | 69 | printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc); |
71 | 70 | ||
72 | // Note: On READ the first byte is the current index | 71 | // Note: On READ the first byte is the current index |
73 | // (e.g. 0x80, what we just wrote) | 72 | // (e.g. 0x80, what we just wrote) |
74 | 73 | ||
75 | if(1) { | 74 | if(1) { |
76 | int i; | 75 | int i; |
77 | printk("BT832 hexdump:\n"); | 76 | printk("BT832 hexdump:\n"); |
78 | for(i=1;i<65;i++) { | 77 | for(i=1;i<65;i++) { |
79 | if(i!=1) { | 78 | if(i!=1) { |
80 | if(((i-1)%8)==0) printk(" "); | 79 | if(((i-1)%8)==0) printk(" "); |
81 | if(((i-1)%16)==0) printk("\n"); | 80 | if(((i-1)%16)==0) printk("\n"); |
82 | } | 81 | } |
83 | printk(" %02x",buf[i]); | 82 | printk(" %02x",buf[i]); |
84 | } | 83 | } |
85 | printk("\n"); | 84 | printk("\n"); |
86 | } | 85 | } |
87 | return 0; | 86 | return 0; |
88 | } | 87 | } |
89 | 88 | ||
@@ -102,13 +101,13 @@ int bt832_init(struct i2c_client *i2c_client_s) | |||
102 | return 0; | 101 | return 0; |
103 | } | 102 | } |
104 | 103 | ||
105 | printk("Write 0 tp VPSTATUS\n"); | 104 | printk("Write 0 tp VPSTATUS\n"); |
106 | buf[0]=BT832_VP_STATUS; // Reg.52 | 105 | buf[0]=BT832_VP_STATUS; // Reg.52 |
107 | buf[1]= 0x00; | 106 | buf[1]= 0x00; |
108 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) | 107 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) |
109 | printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); | 108 | printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); |
110 | 109 | ||
111 | bt832_hexdump(i2c_client_s,buf); | 110 | bt832_hexdump(i2c_client_s,buf); |
112 | 111 | ||
113 | 112 | ||
114 | // Leave low power mode: | 113 | // Leave low power mode: |
@@ -116,17 +115,17 @@ int bt832_init(struct i2c_client *i2c_client_s) | |||
116 | buf[0]=BT832_CAM_SETUP0; //0x39 57 | 115 | buf[0]=BT832_CAM_SETUP0; //0x39 57 |
117 | buf[1]=0x08; | 116 | buf[1]=0x08; |
118 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) | 117 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) |
119 | printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc); | 118 | printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc); |
120 | 119 | ||
121 | bt832_hexdump(i2c_client_s,buf); | 120 | bt832_hexdump(i2c_client_s,buf); |
122 | 121 | ||
123 | printk("Write 0 tp VPSTATUS\n"); | 122 | printk("Write 0 tp VPSTATUS\n"); |
124 | buf[0]=BT832_VP_STATUS; // Reg.52 | 123 | buf[0]=BT832_VP_STATUS; // Reg.52 |
125 | buf[1]= 0x00; | 124 | buf[1]= 0x00; |
126 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) | 125 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) |
127 | printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); | 126 | printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); |
128 | 127 | ||
129 | bt832_hexdump(i2c_client_s,buf); | 128 | bt832_hexdump(i2c_client_s,buf); |
130 | 129 | ||
131 | 130 | ||
132 | // Enable Output | 131 | // Enable Output |
@@ -134,22 +133,22 @@ int bt832_init(struct i2c_client *i2c_client_s) | |||
134 | buf[0]=BT832_VP_CONTROL1; // Reg.40 | 133 | buf[0]=BT832_VP_CONTROL1; // Reg.40 |
135 | buf[1]= 0x27 & (~0x01); // Default | !skip | 134 | buf[1]= 0x27 & (~0x01); // Default | !skip |
136 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) | 135 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) |
137 | printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc); | 136 | printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc); |
138 | 137 | ||
139 | bt832_hexdump(i2c_client_s,buf); | 138 | bt832_hexdump(i2c_client_s,buf); |
140 | 139 | ||
141 | 140 | ||
142 | // for testing (even works when no camera attached) | 141 | // for testing (even works when no camera attached) |
143 | printk("bt832: *** Generate NTSC M Bars *****\n"); | 142 | printk("bt832: *** Generate NTSC M Bars *****\n"); |
144 | buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42 | 143 | buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42 |
145 | buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally | 144 | buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally |
146 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) | 145 | if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) |
147 | printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc); | 146 | printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc); |
148 | 147 | ||
149 | printk("Bt832: Camera Present: %s\n", | 148 | printk("Bt832: Camera Present: %s\n", |
150 | (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no"); | 149 | (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no"); |
151 | 150 | ||
152 | bt832_hexdump(i2c_client_s,buf); | 151 | bt832_hexdump(i2c_client_s,buf); |
153 | kfree(buf); | 152 | kfree(buf); |
154 | return 1; | 153 | return 1; |
155 | } | 154 | } |
@@ -162,17 +161,17 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind) | |||
162 | 161 | ||
163 | printk("bt832_attach\n"); | 162 | printk("bt832_attach\n"); |
164 | 163 | ||
165 | client_template.adapter = adap; | 164 | client_template.adapter = adap; |
166 | client_template.addr = addr; | 165 | client_template.addr = addr; |
167 | 166 | ||
168 | printk("bt832: chip found @ 0x%x\n", addr<<1); | 167 | printk("bt832: chip found @ 0x%x\n", addr<<1); |
169 | 168 | ||
170 | if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) | 169 | if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) |
171 | return -ENOMEM; | 170 | return -ENOMEM; |
172 | memset(t,0,sizeof(*t)); | 171 | memset(t,0,sizeof(*t)); |
173 | t->client = client_template; | 172 | t->client = client_template; |
174 | i2c_set_clientdata(&t->client, t); | 173 | i2c_set_clientdata(&t->client, t); |
175 | i2c_attach_client(&t->client); | 174 | i2c_attach_client(&t->client); |
176 | 175 | ||
177 | if(! bt832_init(&t->client)) { | 176 | if(! bt832_init(&t->client)) { |
178 | bt832_detach(&t->client); | 177 | bt832_detach(&t->client); |
@@ -211,7 +210,7 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
211 | 210 | ||
212 | printk("bt832: command %x\n",cmd); | 211 | printk("bt832: command %x\n",cmd); |
213 | 212 | ||
214 | switch (cmd) { | 213 | switch (cmd) { |
215 | case BT832_HEXDUMP: { | 214 | case BT832_HEXDUMP: { |
216 | unsigned char *buf; | 215 | unsigned char *buf; |
217 | buf=kmalloc(65,GFP_KERNEL); | 216 | buf=kmalloc(65,GFP_KERNEL); |
diff --git a/drivers/media/video/bt832.h b/drivers/media/video/bt832.h index 9b6a8d2c96b5..1ce8fa71f7db 100644 --- a/drivers/media/video/bt832.h +++ b/drivers/media/video/bt832.h | |||
@@ -233,8 +233,8 @@ SetInterlaceMode( spec.interlace ); | |||
233 | /* from web: | 233 | /* from web: |
234 | Video Sampling | 234 | Video Sampling |
235 | Digital video is a sampled form of analog video. The most common sampling schemes in use today are: | 235 | Digital video is a sampled form of analog video. The most common sampling schemes in use today are: |
236 | Pixel Clock Horiz Horiz Vert | 236 | Pixel Clock Horiz Horiz Vert |
237 | Rate Total Active | 237 | Rate Total Active |
238 | NTSC square pixel 12.27 MHz 780 640 525 | 238 | NTSC square pixel 12.27 MHz 780 640 525 |
239 | NTSC CCIR-601 13.5 MHz 858 720 525 | 239 | NTSC CCIR-601 13.5 MHz 858 720 525 |
240 | NTSC 4FSc 14.32 MHz 910 768 525 | 240 | NTSC 4FSc 14.32 MHz 910 768 525 |
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c index 0881a17d5226..3413bace443a 100644 --- a/drivers/media/video/bttv-cards.c +++ b/drivers/media/video/bttv-cards.c | |||
@@ -6,7 +6,7 @@ | |||
6 | like the big tvcards array for the most part | 6 | like the big tvcards array for the most part |
7 | 7 | ||
8 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) | 8 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) |
9 | & Marcus Metzler (mocm@thp.uni-koeln.de) | 9 | & Marcus Metzler (mocm@thp.uni-koeln.de) |
10 | (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> | 10 | (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> |
11 | 11 | ||
12 | This program is free software; you can redistribute it and/or modify | 12 | This program is free software; you can redistribute it and/or modify |
@@ -145,162 +145,163 @@ static struct CARD { | |||
145 | int cardnr; | 145 | int cardnr; |
146 | char *name; | 146 | char *name; |
147 | } cards[] __devinitdata = { | 147 | } cards[] __devinitdata = { |
148 | { 0x13eb0070, BTTV_HAUPPAUGE878, "Hauppauge WinTV" }, | 148 | { 0x13eb0070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV" }, |
149 | { 0x39000070, BTTV_HAUPPAUGE878, "Hauppauge WinTV-D" }, | 149 | { 0x39000070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV-D" }, |
150 | { 0x45000070, BTTV_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" }, | 150 | { 0x45000070, BTTV_BOARD_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" }, |
151 | { 0xff000070, BTTV_OSPREY1x0, "Osprey-100" }, | 151 | { 0xff000070, BTTV_BOARD_OSPREY1x0, "Osprey-100" }, |
152 | { 0xff010070, BTTV_OSPREY2x0_SVID,"Osprey-200" }, | 152 | { 0xff010070, BTTV_BOARD_OSPREY2x0_SVID,"Osprey-200" }, |
153 | { 0xff020070, BTTV_OSPREY500, "Osprey-500" }, | 153 | { 0xff020070, BTTV_BOARD_OSPREY500, "Osprey-500" }, |
154 | { 0xff030070, BTTV_OSPREY2000, "Osprey-2000" }, | 154 | { 0xff030070, BTTV_BOARD_OSPREY2000, "Osprey-2000" }, |
155 | { 0xff040070, BTTV_OSPREY540, "Osprey-540" }, | 155 | { 0xff040070, BTTV_BOARD_OSPREY540, "Osprey-540" }, |
156 | 156 | { 0xff070070, BTTV_BOARD_OSPREY440, "Osprey-440" }, | |
157 | { 0x00011002, BTTV_ATI_TVWONDER, "ATI TV Wonder" }, | 157 | |
158 | { 0x00031002, BTTV_ATI_TVWONDERVE,"ATI TV Wonder/VE" }, | 158 | { 0x00011002, BTTV_BOARD_ATI_TVWONDER, "ATI TV Wonder" }, |
159 | 159 | { 0x00031002, BTTV_BOARD_ATI_TVWONDERVE,"ATI TV Wonder/VE" }, | |
160 | { 0x6606107d, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, | 160 | |
161 | { 0x6607107d, BTTV_WINFASTVC100, "Leadtek WinFast VC 100" }, | 161 | { 0x6606107d, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" }, |
162 | { 0x6609107d, BTTV_WINFAST2000, "Leadtek TV 2000 XP" }, | 162 | { 0x6607107d, BTTV_BOARD_WINFASTVC100, "Leadtek WinFast VC 100" }, |
163 | { 0x263610b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, | 163 | { 0x6609107d, BTTV_BOARD_WINFAST2000, "Leadtek TV 2000 XP" }, |
164 | { 0x264510b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, | 164 | { 0x263610b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, |
165 | { 0x402010fc, BTTV_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" }, | 165 | { 0x264510b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, |
166 | { 0x405010fc, BTTV_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" }, | 166 | { 0x402010fc, BTTV_BOARD_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" }, |
167 | { 0x407010fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, | 167 | { 0x405010fc, BTTV_BOARD_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" }, |
168 | { 0xd01810fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, | 168 | { 0x407010fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, |
169 | 169 | { 0xd01810fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, | |
170 | { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, | 170 | |
171 | { 0x001211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" }, | ||
171 | /* some cards ship with byteswapped IDs ... */ | 172 | /* some cards ship with byteswapped IDs ... */ |
172 | { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, | 173 | { 0x1200bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" }, |
173 | { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, | 174 | { 0xff00bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" }, |
174 | /* this seems to happen as well ... */ | 175 | /* this seems to happen as well ... */ |
175 | { 0xff1211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, | 176 | { 0xff1211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" }, |
176 | 177 | ||
177 | { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, | 178 | { 0x3000121a, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, |
178 | { 0x263710b4, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, | 179 | { 0x263710b4, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, |
179 | { 0x3060121a, BTTV_STB2, "3Dfx VoodooTV 100/ STB OEM" }, | 180 | { 0x3060121a, BTTV_BOARD_STB2, "3Dfx VoodooTV 100/ STB OEM" }, |
180 | 181 | ||
181 | { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" }, | 182 | { 0x3000144f, BTTV_BOARD_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" }, |
182 | { 0xa005144f, BTTV_MAGICTVIEW063, "CPH06X TView99-Card" }, | 183 | { 0xa005144f, BTTV_BOARD_MAGICTVIEW063, "CPH06X TView99-Card" }, |
183 | { 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" }, | 184 | { 0x3002144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" }, |
184 | { 0x3005144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" }, | 185 | { 0x3005144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" }, |
185 | { 0x5000144f, BTTV_MAGICTVIEW061, "Askey CPH050" }, | 186 | { 0x5000144f, BTTV_BOARD_MAGICTVIEW061, "Askey CPH050" }, |
186 | { 0x300014ff, BTTV_MAGICTVIEW061, "TView 99 (CPH061)" }, | 187 | { 0x300014ff, BTTV_BOARD_MAGICTVIEW061, "TView 99 (CPH061)" }, |
187 | { 0x300214ff, BTTV_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" }, | 188 | { 0x300214ff, BTTV_BOARD_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" }, |
188 | 189 | ||
189 | { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, | 190 | { 0x00011461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" }, |
190 | { 0x00021461, BTTV_AVERMEDIA98, "AVermedia TVCapture 98" }, | 191 | { 0x00021461, BTTV_BOARD_AVERMEDIA98, "AVermedia TVCapture 98" }, |
191 | { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, | 192 | { 0x00031461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" }, |
192 | { 0x00041461, BTTV_AVERMEDIA98, "AVerMedia TVCapture 98" }, | 193 | { 0x00041461, BTTV_BOARD_AVERMEDIA98, "AVerMedia TVCapture 98" }, |
193 | { 0x03001461, BTTV_AVERMEDIA98, "VDOMATE TV TUNER CARD" }, | 194 | { 0x03001461, BTTV_BOARD_AVERMEDIA98, "VDOMATE TV TUNER CARD" }, |
194 | 195 | ||
195 | { 0x1117153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" }, | 196 | { 0x1117153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" }, |
196 | { 0x1118153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" }, | 197 | { 0x1118153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" }, |
197 | { 0x1119153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL I)" }, | 198 | { 0x1119153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL I)" }, |
198 | { 0x111a153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL I)" }, | 199 | { 0x111a153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL I)" }, |
199 | 200 | ||
200 | { 0x1123153b, BTTV_TERRATVRADIO, "Terratec TV Radio+" }, | 201 | { 0x1123153b, BTTV_BOARD_TERRATVRADIO, "Terratec TV Radio+" }, |
201 | { 0x1127153b, BTTV_TERRATV, "Terratec TV+ (V1.05)" }, | 202 | { 0x1127153b, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.05)" }, |
202 | /* clashes with FlyVideo | 203 | /* clashes with FlyVideo |
203 | *{ 0x18521852, BTTV_TERRATV, "Terratec TV+ (V1.10)" }, */ | 204 | *{ 0x18521852, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.10)" }, */ |
204 | { 0x1134153b, BTTV_TERRATVALUE, "Terratec TValue (LR102)" }, | 205 | { 0x1134153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (LR102)" }, |
205 | { 0x1135153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */ | 206 | { 0x1135153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */ |
206 | { 0x5018153b, BTTV_TERRATVALUE, "Terratec TValue" }, /* ?? */ | 207 | { 0x5018153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue" }, /* ?? */ |
207 | { 0xff3b153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */ | 208 | { 0xff3b153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */ |
208 | 209 | ||
209 | { 0x400015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, | 210 | { 0x400015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, |
210 | { 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, | 211 | { 0x400a15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, |
211 | { 0x400d15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, | 212 | { 0x400d15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, |
212 | { 0x401015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, | 213 | { 0x401015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, |
213 | { 0x401615b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, | 214 | { 0x401615b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, |
214 | 215 | ||
215 | { 0x1430aa00, BTTV_PV143, "Provideo PV143A" }, | 216 | { 0x1430aa00, BTTV_BOARD_PV143, "Provideo PV143A" }, |
216 | { 0x1431aa00, BTTV_PV143, "Provideo PV143B" }, | 217 | { 0x1431aa00, BTTV_BOARD_PV143, "Provideo PV143B" }, |
217 | { 0x1432aa00, BTTV_PV143, "Provideo PV143C" }, | 218 | { 0x1432aa00, BTTV_BOARD_PV143, "Provideo PV143C" }, |
218 | { 0x1433aa00, BTTV_PV143, "Provideo PV143D" }, | 219 | { 0x1433aa00, BTTV_BOARD_PV143, "Provideo PV143D" }, |
219 | { 0x1433aa03, BTTV_PV143, "Security Eyes" }, | 220 | { 0x1433aa03, BTTV_BOARD_PV143, "Security Eyes" }, |
220 | 221 | ||
221 | { 0x1460aa00, BTTV_PV150, "Provideo PV150A-1" }, | 222 | { 0x1460aa00, BTTV_BOARD_PV150, "Provideo PV150A-1" }, |
222 | { 0x1461aa01, BTTV_PV150, "Provideo PV150A-2" }, | 223 | { 0x1461aa01, BTTV_BOARD_PV150, "Provideo PV150A-2" }, |
223 | { 0x1462aa02, BTTV_PV150, "Provideo PV150A-3" }, | 224 | { 0x1462aa02, BTTV_BOARD_PV150, "Provideo PV150A-3" }, |
224 | { 0x1463aa03, BTTV_PV150, "Provideo PV150A-4" }, | 225 | { 0x1463aa03, BTTV_BOARD_PV150, "Provideo PV150A-4" }, |
225 | 226 | ||
226 | { 0x1464aa04, BTTV_PV150, "Provideo PV150B-1" }, | 227 | { 0x1464aa04, BTTV_BOARD_PV150, "Provideo PV150B-1" }, |
227 | { 0x1465aa05, BTTV_PV150, "Provideo PV150B-2" }, | 228 | { 0x1465aa05, BTTV_BOARD_PV150, "Provideo PV150B-2" }, |
228 | { 0x1466aa06, BTTV_PV150, "Provideo PV150B-3" }, | 229 | { 0x1466aa06, BTTV_BOARD_PV150, "Provideo PV150B-3" }, |
229 | { 0x1467aa07, BTTV_PV150, "Provideo PV150B-4" }, | 230 | { 0x1467aa07, BTTV_BOARD_PV150, "Provideo PV150B-4" }, |
230 | 231 | ||
231 | { 0xa132ff00, BTTV_IVC100, "IVC-100" }, | 232 | { 0xa132ff00, BTTV_BOARD_IVC100, "IVC-100" }, |
232 | { 0xa1550000, BTTV_IVC200, "IVC-200" }, | 233 | { 0xa1550000, BTTV_BOARD_IVC200, "IVC-200" }, |
233 | { 0xa1550001, BTTV_IVC200, "IVC-200" }, | 234 | { 0xa1550001, BTTV_BOARD_IVC200, "IVC-200" }, |
234 | { 0xa1550002, BTTV_IVC200, "IVC-200" }, | 235 | { 0xa1550002, BTTV_BOARD_IVC200, "IVC-200" }, |
235 | { 0xa1550003, BTTV_IVC200, "IVC-200" }, | 236 | { 0xa1550003, BTTV_BOARD_IVC200, "IVC-200" }, |
236 | { 0xa1550100, BTTV_IVC200, "IVC-200G" }, | 237 | { 0xa1550100, BTTV_BOARD_IVC200, "IVC-200G" }, |
237 | { 0xa1550101, BTTV_IVC200, "IVC-200G" }, | 238 | { 0xa1550101, BTTV_BOARD_IVC200, "IVC-200G" }, |
238 | { 0xa1550102, BTTV_IVC200, "IVC-200G" }, | 239 | { 0xa1550102, BTTV_BOARD_IVC200, "IVC-200G" }, |
239 | { 0xa1550103, BTTV_IVC200, "IVC-200G" }, | 240 | { 0xa1550103, BTTV_BOARD_IVC200, "IVC-200G" }, |
240 | { 0xa182ff00, BTTV_IVC120, "IVC-120G" }, | 241 | { 0xa182ff00, BTTV_BOARD_IVC120, "IVC-120G" }, |
241 | { 0xa182ff01, BTTV_IVC120, "IVC-120G" }, | 242 | { 0xa182ff01, BTTV_BOARD_IVC120, "IVC-120G" }, |
242 | { 0xa182ff02, BTTV_IVC120, "IVC-120G" }, | 243 | { 0xa182ff02, BTTV_BOARD_IVC120, "IVC-120G" }, |
243 | { 0xa182ff03, BTTV_IVC120, "IVC-120G" }, | 244 | { 0xa182ff03, BTTV_BOARD_IVC120, "IVC-120G" }, |
244 | { 0xa182ff04, BTTV_IVC120, "IVC-120G" }, | 245 | { 0xa182ff04, BTTV_BOARD_IVC120, "IVC-120G" }, |
245 | { 0xa182ff05, BTTV_IVC120, "IVC-120G" }, | 246 | { 0xa182ff05, BTTV_BOARD_IVC120, "IVC-120G" }, |
246 | { 0xa182ff06, BTTV_IVC120, "IVC-120G" }, | 247 | { 0xa182ff06, BTTV_BOARD_IVC120, "IVC-120G" }, |
247 | { 0xa182ff07, BTTV_IVC120, "IVC-120G" }, | 248 | { 0xa182ff07, BTTV_BOARD_IVC120, "IVC-120G" }, |
248 | { 0xa182ff08, BTTV_IVC120, "IVC-120G" }, | 249 | { 0xa182ff08, BTTV_BOARD_IVC120, "IVC-120G" }, |
249 | { 0xa182ff09, BTTV_IVC120, "IVC-120G" }, | 250 | { 0xa182ff09, BTTV_BOARD_IVC120, "IVC-120G" }, |
250 | { 0xa182ff0a, BTTV_IVC120, "IVC-120G" }, | 251 | { 0xa182ff0a, BTTV_BOARD_IVC120, "IVC-120G" }, |
251 | { 0xa182ff0b, BTTV_IVC120, "IVC-120G" }, | 252 | { 0xa182ff0b, BTTV_BOARD_IVC120, "IVC-120G" }, |
252 | { 0xa182ff0c, BTTV_IVC120, "IVC-120G" }, | 253 | { 0xa182ff0c, BTTV_BOARD_IVC120, "IVC-120G" }, |
253 | { 0xa182ff0d, BTTV_IVC120, "IVC-120G" }, | 254 | { 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" }, |
254 | { 0xa182ff0e, BTTV_IVC120, "IVC-120G" }, | 255 | { 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" }, |
255 | { 0xa182ff0f, BTTV_IVC120, "IVC-120G" }, | 256 | { 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" }, |
256 | 257 | ||
257 | { 0x41424344, BTTV_GRANDTEC, "GrandTec Multi Capture" }, | 258 | { 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" }, |
258 | { 0x01020304, BTTV_XGUARD, "Grandtec Grand X-Guard" }, | 259 | { 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" }, |
259 | 260 | ||
260 | { 0x18501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, | 261 | { 0x18501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, |
261 | { 0xa0501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, | 262 | { 0xa0501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, |
262 | { 0x18511851, BTTV_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" }, | 263 | { 0x18511851, BTTV_BOARD_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" }, |
263 | { 0x18521852, BTTV_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" }, | 264 | { 0x18521852, BTTV_BOARD_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" }, |
264 | { 0x41a0a051, BTTV_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" }, | 265 | { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" }, |
265 | { 0x18501f7f, BTTV_FLYVIDEO_98, "Lifeview Flyvideo 98" }, | 266 | { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" }, |
266 | 267 | ||
267 | { 0x010115cb, BTTV_GMV1, "AG GMV1" }, | 268 | { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" }, |
268 | { 0x010114c7, BTTV_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, | 269 | { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, |
269 | 270 | ||
270 | { 0x10b42636, BTTV_HAUPPAUGE878, "STB ???" }, | 271 | { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" }, |
271 | { 0x217d6606, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, | 272 | { 0x217d6606, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" }, |
272 | { 0xfff6f6ff, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, | 273 | { 0xfff6f6ff, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" }, |
273 | { 0x03116000, BTTV_SENSORAY311, "Sensoray 311" }, | 274 | { 0x03116000, BTTV_BOARD_SENSORAY311, "Sensoray 311" }, |
274 | { 0x00790e11, BTTV_WINDVR, "Canopus WinDVR PCI" }, | 275 | { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" }, |
275 | { 0xa0fca1a0, BTTV_ZOLTRIX, "Face to Face Tvmax" }, | 276 | { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" }, |
276 | { 0x20007063, BTTV_PC_HDTV, "pcHDTV HD-2000 TV"}, | 277 | { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"}, |
277 | { 0x82b2aa6a, BTTV_SIMUS_GVC1100, "SIMUS GVC1100" }, | 278 | { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" }, |
278 | { 0x146caa0c, BTTV_PV951, "ituner spectra8" }, | 279 | { 0x146caa0c, BTTV_BOARD_PV951, "ituner spectra8" }, |
279 | { 0x200a1295, BTTV_PXC200, "ImageNation PXC200A" }, | 280 | { 0x200a1295, BTTV_BOARD_PXC200, "ImageNation PXC200A" }, |
280 | 281 | ||
281 | { 0x40111554, BTTV_PV_BT878P_9B, "Prolink Pixelview PV-BT" }, | 282 | { 0x40111554, BTTV_BOARD_PV_BT878P_9B, "Prolink Pixelview PV-BT" }, |
282 | { 0x17de0a01, BTTV_KWORLD, "Mecer TV/FM/Video Tuner" }, | 283 | { 0x17de0a01, BTTV_BOARD_KWORLD, "Mecer TV/FM/Video Tuner" }, |
283 | 284 | ||
284 | { 0x01051805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" }, | 285 | { 0x01051805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" }, |
285 | { 0x01061805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" }, | 286 | { 0x01061805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" }, |
286 | { 0x01071805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" }, | 287 | { 0x01071805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" }, |
287 | { 0x01081805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" }, | 288 | { 0x01081805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" }, |
288 | 289 | ||
289 | { 0x15409511, BTTV_ACORP_Y878F, "Acorp Y878F" }, | 290 | { 0x15409511, BTTV_BOARD_ACORP_Y878F, "Acorp Y878F" }, |
290 | 291 | ||
291 | /* likely broken, vendor id doesn't match the other magic views ... | 292 | /* likely broken, vendor id doesn't match the other magic views ... |
292 | * { 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */ | 293 | * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */ |
293 | 294 | ||
294 | /* DVB cards (using pci function .1 for mpeg data xfer) */ | 295 | /* DVB cards (using pci function .1 for mpeg data xfer) */ |
295 | { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, | 296 | { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, |
296 | { 0x07611461, BTTV_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, | 297 | { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, |
297 | { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" }, | 298 | { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" }, |
298 | { 0x002611bd, BTTV_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, | 299 | { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, |
299 | { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB" }, | 300 | { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" }, |
300 | { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, | 301 | { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, |
301 | { 0x07711461, BTTV_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, | 302 | { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, |
302 | { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, | 303 | { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, |
303 | { 0xd50018ac, BTTV_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, | 304 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, |
304 | 305 | ||
305 | { 0, -1, NULL } | 306 | { 0, -1, NULL } |
306 | }; | 307 | }; |
@@ -309,2116 +310,2494 @@ static struct CARD { | |||
309 | /* array with description for bt848 / bt878 tv/grabber cards */ | 310 | /* array with description for bt848 / bt878 tv/grabber cards */ |
310 | 311 | ||
311 | struct tvcard bttv_tvcards[] = { | 312 | struct tvcard bttv_tvcards[] = { |
312 | { | 313 | /* ---- card 0x00 ---------------------------------- */ |
313 | /* ---- card 0x00 ---------------------------------- */ | 314 | [BTTV_BOARD_UNKNOWN] = { |
314 | .name = " *** UNKNOWN/GENERIC *** ", | 315 | .name = " *** UNKNOWN/GENERIC *** ", |
315 | .video_inputs = 4, | 316 | .video_inputs = 4, |
316 | .audio_inputs = 1, | 317 | .audio_inputs = 1, |
317 | .tuner = 0, | 318 | .tuner = 0, |
318 | .svhs = 2, | 319 | .svhs = 2, |
319 | .muxsel = { 2, 3, 1, 0}, | 320 | .muxsel = { 2, 3, 1, 0}, |
320 | .tuner_type = -1, | 321 | .tuner_type = -1, |
321 | .tuner_addr = ADDR_UNSET, | 322 | .tuner_addr = ADDR_UNSET, |
322 | },{ | 323 | .radio_addr = ADDR_UNSET, |
323 | .name = "MIRO PCTV", | 324 | }, |
324 | .video_inputs = 4, | 325 | [BTTV_BOARD_MIRO] = { |
325 | .audio_inputs = 1, | 326 | .name = "MIRO PCTV", |
326 | .tuner = 0, | 327 | .video_inputs = 4, |
327 | .svhs = 2, | 328 | .audio_inputs = 1, |
328 | .gpiomask = 15, | 329 | .tuner = 0, |
329 | .muxsel = { 2, 3, 1, 1}, | 330 | .svhs = 2, |
330 | .audiomux = { 2, 0, 0, 0, 10}, | 331 | .gpiomask = 15, |
331 | .needs_tvaudio = 1, | 332 | .muxsel = { 2, 3, 1, 1}, |
332 | .tuner_type = -1, | 333 | .audiomux = { 2, 0, 0, 0, 10}, |
333 | .tuner_addr = ADDR_UNSET, | 334 | .needs_tvaudio = 1, |
334 | },{ | 335 | .tuner_type = -1, |
335 | .name = "Hauppauge (bt848)", | 336 | .tuner_addr = ADDR_UNSET, |
336 | .video_inputs = 4, | 337 | .radio_addr = ADDR_UNSET, |
337 | .audio_inputs = 1, | 338 | }, |
338 | .tuner = 0, | 339 | [BTTV_BOARD_HAUPPAUGE] = { |
339 | .svhs = 2, | 340 | .name = "Hauppauge (bt848)", |
340 | .gpiomask = 7, | 341 | .video_inputs = 4, |
341 | .muxsel = { 2, 3, 1, 1}, | 342 | .audio_inputs = 1, |
342 | .audiomux = { 0, 1, 2, 3, 4}, | 343 | .tuner = 0, |
343 | .needs_tvaudio = 1, | 344 | .svhs = 2, |
344 | .tuner_type = -1, | 345 | .gpiomask = 7, |
345 | .tuner_addr = ADDR_UNSET, | 346 | .muxsel = { 2, 3, 1, 1}, |
346 | },{ | 347 | .audiomux = { 0, 1, 2, 3, 4}, |
347 | .name = "STB, Gateway P/N 6000699 (bt848)", | 348 | .needs_tvaudio = 1, |
348 | .video_inputs = 3, | 349 | .tuner_type = -1, |
349 | .audio_inputs = 1, | 350 | .tuner_addr = ADDR_UNSET, |
350 | .tuner = 0, | 351 | .radio_addr = ADDR_UNSET, |
351 | .svhs = 2, | 352 | }, |
352 | .gpiomask = 7, | 353 | [BTTV_BOARD_STB] = { |
353 | .muxsel = { 2, 3, 1, 1}, | 354 | .name = "STB, Gateway P/N 6000699 (bt848)", |
354 | .audiomux = { 4, 0, 2, 3, 1}, | 355 | .video_inputs = 3, |
355 | .no_msp34xx = 1, | 356 | .audio_inputs = 1, |
356 | .needs_tvaudio = 1, | 357 | .tuner = 0, |
357 | .tuner_type = TUNER_PHILIPS_NTSC, | 358 | .svhs = 2, |
358 | .tuner_addr = ADDR_UNSET, | 359 | .gpiomask = 7, |
359 | .pll = PLL_28, | 360 | .muxsel = { 2, 3, 1, 1}, |
360 | .has_radio = 1, | 361 | .audiomux = { 4, 0, 2, 3, 1}, |
361 | },{ | 362 | .no_msp34xx = 1, |
362 | 363 | .needs_tvaudio = 1, | |
363 | /* ---- card 0x04 ---------------------------------- */ | 364 | .tuner_type = TUNER_PHILIPS_NTSC, |
364 | .name = "Intel Create and Share PCI/ Smart Video Recorder III", | 365 | .tuner_addr = ADDR_UNSET, |
365 | .video_inputs = 4, | 366 | .radio_addr = ADDR_UNSET, |
366 | .audio_inputs = 0, | 367 | .pll = PLL_28, |
367 | .tuner = -1, | 368 | .has_radio = 1, |
368 | .svhs = 2, | 369 | }, |
369 | .gpiomask = 0, | 370 | |
370 | .muxsel = { 2, 3, 1, 1}, | 371 | /* ---- card 0x04 ---------------------------------- */ |
371 | .audiomux = { 0 }, | 372 | [BTTV_BOARD_INTEL] = { |
372 | .needs_tvaudio = 0, | 373 | .name = "Intel Create and Share PCI/ Smart Video Recorder III", |
373 | .tuner_type = 4, | 374 | .video_inputs = 4, |
374 | .tuner_addr = ADDR_UNSET, | 375 | .audio_inputs = 0, |
375 | },{ | 376 | .tuner = -1, |
376 | .name = "Diamond DTV2000", | 377 | .svhs = 2, |
377 | .video_inputs = 4, | 378 | .gpiomask = 0, |
378 | .audio_inputs = 1, | 379 | .muxsel = { 2, 3, 1, 1}, |
379 | .tuner = 0, | 380 | .audiomux = { 0 }, |
380 | .svhs = 2, | 381 | .needs_tvaudio = 0, |
381 | .gpiomask = 3, | 382 | .tuner_type = 4, |
382 | .muxsel = { 2, 3, 1, 0}, | 383 | .tuner_addr = ADDR_UNSET, |
383 | .audiomux = { 0, 1, 0, 1, 3}, | 384 | .radio_addr = ADDR_UNSET, |
384 | .needs_tvaudio = 1, | 385 | }, |
385 | .tuner_type = -1, | 386 | [BTTV_BOARD_DIAMOND] = { |
386 | .tuner_addr = ADDR_UNSET, | 387 | .name = "Diamond DTV2000", |
387 | },{ | 388 | .video_inputs = 4, |
388 | .name = "AVerMedia TVPhone", | 389 | .audio_inputs = 1, |
389 | .video_inputs = 3, | 390 | .tuner = 0, |
390 | .audio_inputs = 1, | 391 | .svhs = 2, |
391 | .tuner = 0, | 392 | .gpiomask = 3, |
392 | .svhs = 3, | 393 | .muxsel = { 2, 3, 1, 0}, |
393 | .muxsel = { 2, 3, 1, 1}, | 394 | .audiomux = { 0, 1, 0, 1, 3}, |
394 | .gpiomask = 0x0f, | 395 | .needs_tvaudio = 1, |
395 | .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0}, | 396 | .tuner_type = -1, |
396 | /* 0x04 for some cards ?? */ | 397 | .tuner_addr = ADDR_UNSET, |
397 | .needs_tvaudio = 1, | 398 | .radio_addr = ADDR_UNSET, |
398 | .tuner_type = -1, | 399 | }, |
399 | .tuner_addr = ADDR_UNSET, | 400 | [BTTV_BOARD_AVERMEDIA] = { |
400 | .audio_hook = avermedia_tvphone_audio, | 401 | .name = "AVerMedia TVPhone", |
401 | .has_remote = 1, | 402 | .video_inputs = 3, |
402 | },{ | 403 | .audio_inputs = 1, |
403 | .name = "MATRIX-Vision MV-Delta", | 404 | .tuner = 0, |
404 | .video_inputs = 5, | 405 | .svhs = 3, |
405 | .audio_inputs = 1, | 406 | .muxsel = { 2, 3, 1, 1}, |
406 | .tuner = -1, | 407 | .gpiomask = 0x0f, |
407 | .svhs = 3, | 408 | .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0}, |
408 | .gpiomask = 0, | 409 | /* 0x04 for some cards ?? */ |
409 | .muxsel = { 2, 3, 1, 0, 0}, | 410 | .needs_tvaudio = 1, |
410 | .audiomux = {0 }, | 411 | .tuner_type = -1, |
411 | .needs_tvaudio = 1, | 412 | .tuner_addr = ADDR_UNSET, |
412 | .tuner_type = -1, | 413 | .radio_addr = ADDR_UNSET, |
413 | .tuner_addr = ADDR_UNSET, | 414 | .audio_hook = avermedia_tvphone_audio, |
414 | },{ | 415 | .has_remote = 1, |
415 | 416 | }, | |
416 | /* ---- card 0x08 ---------------------------------- */ | 417 | [BTTV_BOARD_MATRIX_VISION] = { |
417 | .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26", | 418 | .name = "MATRIX-Vision MV-Delta", |
418 | .video_inputs = 4, | 419 | .video_inputs = 5, |
419 | .audio_inputs = 1, | 420 | .audio_inputs = 1, |
420 | .tuner = 0, | 421 | .tuner = -1, |
421 | .svhs = 2, | 422 | .svhs = 3, |
422 | .gpiomask = 0xc00, | 423 | .gpiomask = 0, |
423 | .muxsel = { 2, 3, 1, 1}, | 424 | .muxsel = { 2, 3, 1, 0, 0}, |
424 | .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0}, | 425 | .audiomux = {0 }, |
425 | .needs_tvaudio = 1, | 426 | .needs_tvaudio = 1, |
426 | .pll = PLL_28, | 427 | .tuner_type = -1, |
427 | .tuner_type = -1, | 428 | .tuner_addr = ADDR_UNSET, |
428 | .tuner_addr = ADDR_UNSET, | 429 | .radio_addr = ADDR_UNSET, |
429 | },{ | 430 | }, |
430 | .name = "IMS/IXmicro TurboTV", | 431 | |
431 | .video_inputs = 3, | 432 | /* ---- card 0x08 ---------------------------------- */ |
432 | .audio_inputs = 1, | 433 | [BTTV_BOARD_FLYVIDEO] = { |
433 | .tuner = 0, | 434 | .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26", |
434 | .svhs = 2, | 435 | .video_inputs = 4, |
435 | .gpiomask = 3, | 436 | .audio_inputs = 1, |
436 | .muxsel = { 2, 3, 1, 1}, | 437 | .tuner = 0, |
437 | .audiomux = { 1, 1, 2, 3, 0}, | 438 | .svhs = 2, |
438 | .needs_tvaudio = 0, | 439 | .gpiomask = 0xc00, |
439 | .pll = PLL_28, | 440 | .muxsel = { 2, 3, 1, 1}, |
440 | .tuner_type = TUNER_TEMIC_PAL, | 441 | .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0}, |
441 | .tuner_addr = ADDR_UNSET, | 442 | .needs_tvaudio = 1, |
442 | },{ | 443 | .pll = PLL_28, |
443 | .name = "Hauppauge (bt878)", | 444 | .tuner_type = -1, |
444 | .video_inputs = 4, | 445 | .tuner_addr = ADDR_UNSET, |
445 | .audio_inputs = 1, | 446 | .radio_addr = ADDR_UNSET, |
446 | .tuner = 0, | 447 | }, |
447 | .svhs = 2, | 448 | [BTTV_BOARD_TURBOTV] = { |
448 | .gpiomask = 0x0f, /* old: 7 */ | 449 | .name = "IMS/IXmicro TurboTV", |
449 | .muxsel = { 2, 0, 1, 1}, | 450 | .video_inputs = 3, |
450 | .audiomux = { 0, 1, 2, 3, 4}, | 451 | .audio_inputs = 1, |
451 | .needs_tvaudio = 1, | 452 | .tuner = 0, |
452 | .pll = PLL_28, | 453 | .svhs = 2, |
453 | .tuner_type = -1, | 454 | .gpiomask = 3, |
454 | .tuner_addr = ADDR_UNSET, | 455 | .muxsel = { 2, 3, 1, 1}, |
455 | },{ | 456 | .audiomux = { 1, 1, 2, 3, 0}, |
456 | .name = "MIRO PCTV pro", | 457 | .needs_tvaudio = 0, |
457 | .video_inputs = 3, | 458 | .pll = PLL_28, |
458 | .audio_inputs = 1, | 459 | .tuner_type = TUNER_TEMIC_PAL, |
459 | .tuner = 0, | 460 | .tuner_addr = ADDR_UNSET, |
460 | .svhs = 2, | 461 | .radio_addr = ADDR_UNSET, |
461 | .gpiomask = 0x3014f, | 462 | }, |
462 | .muxsel = { 2, 3, 1, 1}, | 463 | [BTTV_BOARD_HAUPPAUGE878] = { |
463 | .audiomux = { 0x20001,0x10001, 0, 0,10}, | 464 | .name = "Hauppauge (bt878)", |
464 | .needs_tvaudio = 1, | 465 | .video_inputs = 4, |
465 | .tuner_type = -1, | 466 | .audio_inputs = 1, |
466 | .tuner_addr = ADDR_UNSET, | 467 | .tuner = 0, |
467 | },{ | 468 | .svhs = 2, |
468 | 469 | .gpiomask = 0x0f, /* old: 7 */ | |
469 | /* ---- card 0x0c ---------------------------------- */ | 470 | .muxsel = { 2, 0, 1, 1}, |
470 | .name = "ADS Technologies Channel Surfer TV (bt848)", | 471 | .audiomux = { 0, 1, 2, 3, 4}, |
471 | .video_inputs = 3, | 472 | .needs_tvaudio = 1, |
472 | .audio_inputs = 1, | 473 | .pll = PLL_28, |
473 | .tuner = 0, | 474 | .tuner_type = -1, |
474 | .svhs = 2, | 475 | .tuner_addr = ADDR_UNSET, |
475 | .gpiomask = 15, | 476 | .radio_addr = ADDR_UNSET, |
476 | .muxsel = { 2, 3, 1, 1}, | 477 | }, |
477 | .audiomux = { 13, 14, 11, 7, 0, 0}, | 478 | [BTTV_BOARD_MIROPRO] = { |
478 | .needs_tvaudio = 1, | 479 | .name = "MIRO PCTV pro", |
479 | .tuner_type = -1, | 480 | .video_inputs = 3, |
480 | .tuner_addr = ADDR_UNSET, | 481 | .audio_inputs = 1, |
481 | },{ | 482 | .tuner = 0, |
482 | .name = "AVerMedia TVCapture 98", | 483 | .svhs = 2, |
483 | .video_inputs = 3, | 484 | .gpiomask = 0x3014f, |
484 | .audio_inputs = 4, | 485 | .muxsel = { 2, 3, 1, 1}, |
485 | .tuner = 0, | 486 | .audiomux = { 0x20001,0x10001, 0, 0,10}, |
486 | .svhs = 2, | 487 | .needs_tvaudio = 1, |
487 | .gpiomask = 15, | 488 | .tuner_type = -1, |
488 | .muxsel = { 2, 3, 1, 1}, | 489 | .tuner_addr = ADDR_UNSET, |
489 | .audiomux = { 13, 14, 11, 7, 0, 0}, | 490 | .radio_addr = ADDR_UNSET, |
490 | .needs_tvaudio = 1, | 491 | }, |
491 | .msp34xx_alt = 1, | 492 | |
492 | .pll = PLL_28, | 493 | /* ---- card 0x0c ---------------------------------- */ |
493 | .tuner_type = TUNER_PHILIPS_PAL, | 494 | [BTTV_BOARD_ADSTECH_TV] = { |
494 | .tuner_addr = ADDR_UNSET, | 495 | .name = "ADS Technologies Channel Surfer TV (bt848)", |
495 | .audio_hook = avermedia_tv_stereo_audio, | 496 | .video_inputs = 3, |
496 | },{ | 497 | .audio_inputs = 1, |
497 | .name = "Aimslab Video Highway Xtreme (VHX)", | 498 | .tuner = 0, |
498 | .video_inputs = 3, | 499 | .svhs = 2, |
499 | .audio_inputs = 1, | 500 | .gpiomask = 15, |
500 | .tuner = 0, | 501 | .muxsel = { 2, 3, 1, 1}, |
501 | .svhs = 2, | 502 | .audiomux = { 13, 14, 11, 7, 0, 0}, |
502 | .gpiomask = 7, | 503 | .needs_tvaudio = 1, |
503 | .muxsel = { 2, 3, 1, 1}, | 504 | .tuner_type = -1, |
504 | .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */ | 505 | .tuner_addr = ADDR_UNSET, |
505 | .needs_tvaudio = 1, | 506 | .radio_addr = ADDR_UNSET, |
506 | .pll = PLL_28, | 507 | }, |
507 | .tuner_type = -1, | 508 | [BTTV_BOARD_AVERMEDIA98] = { |
508 | .tuner_addr = ADDR_UNSET, | 509 | .name = "AVerMedia TVCapture 98", |
509 | },{ | 510 | .video_inputs = 3, |
510 | .name = "Zoltrix TV-Max", | 511 | .audio_inputs = 4, |
511 | .video_inputs = 3, | 512 | .tuner = 0, |
512 | .audio_inputs = 1, | 513 | .svhs = 2, |
513 | .tuner = 0, | 514 | .gpiomask = 15, |
514 | .svhs = 2, | 515 | .muxsel = { 2, 3, 1, 1}, |
515 | .gpiomask = 15, | 516 | .audiomux = { 13, 14, 11, 7, 0, 0}, |
516 | .muxsel = { 2, 3, 1, 1}, | 517 | .needs_tvaudio = 1, |
517 | .audiomux = {0 , 0, 1 , 0, 10}, | 518 | .msp34xx_alt = 1, |
518 | .needs_tvaudio = 1, | 519 | .pll = PLL_28, |
519 | .tuner_type = -1, | 520 | .tuner_type = TUNER_PHILIPS_PAL, |
520 | .tuner_addr = ADDR_UNSET, | 521 | .tuner_addr = ADDR_UNSET, |
521 | },{ | 522 | .radio_addr = ADDR_UNSET, |
522 | 523 | .audio_hook = avermedia_tv_stereo_audio, | |
523 | /* ---- card 0x10 ---------------------------------- */ | 524 | .no_gpioirq = 1, |
524 | .name = "Prolink Pixelview PlayTV (bt878)", | 525 | }, |
525 | .video_inputs = 3, | 526 | [BTTV_BOARD_VHX] = { |
526 | .audio_inputs = 1, | 527 | .name = "Aimslab Video Highway Xtreme (VHX)", |
527 | .tuner = 0, | 528 | .video_inputs = 3, |
528 | .svhs = 2, | 529 | .audio_inputs = 1, |
529 | .gpiomask = 0x01fe00, | 530 | .tuner = 0, |
530 | .muxsel = { 2, 3, 1, 1}, | 531 | .svhs = 2, |
531 | /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */ | 532 | .gpiomask = 7, |
532 | .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, | 533 | .muxsel = { 2, 3, 1, 1}, |
533 | .needs_tvaudio = 1, | 534 | .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */ |
534 | .pll = PLL_28, | 535 | .needs_tvaudio = 1, |
535 | .tuner_type = -1, | 536 | .pll = PLL_28, |
536 | },{ | 537 | .tuner_type = -1, |
537 | .name = "Leadtek WinView 601", | 538 | .tuner_addr = ADDR_UNSET, |
538 | .video_inputs = 3, | 539 | .radio_addr = ADDR_UNSET, |
539 | .audio_inputs = 1, | 540 | }, |
540 | .tuner = 0, | 541 | [BTTV_BOARD_ZOLTRIX] = { |
541 | .svhs = 2, | 542 | .name = "Zoltrix TV-Max", |
542 | .gpiomask = 0x8300f8, | 543 | .video_inputs = 3, |
543 | .muxsel = { 2, 3, 1, 1,0}, | 544 | .audio_inputs = 1, |
544 | .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007}, | 545 | .tuner = 0, |
545 | .needs_tvaudio = 1, | 546 | .svhs = 2, |
546 | .tuner_type = -1, | 547 | .gpiomask = 15, |
547 | .tuner_addr = ADDR_UNSET, | 548 | .muxsel = { 2, 3, 1, 1}, |
548 | .audio_hook = winview_audio, | 549 | .audiomux = {0 , 0, 1 , 0, 10}, |
549 | .has_radio = 1, | 550 | .needs_tvaudio = 1, |
550 | },{ | 551 | .tuner_type = -1, |
551 | .name = "AVEC Intercapture", | 552 | .tuner_addr = ADDR_UNSET, |
552 | .video_inputs = 3, | 553 | .radio_addr = ADDR_UNSET, |
553 | .audio_inputs = 2, | 554 | }, |
554 | .tuner = 0, | 555 | |
555 | .svhs = 2, | 556 | /* ---- card 0x10 ---------------------------------- */ |
556 | .gpiomask = 0, | 557 | [BTTV_BOARD_PIXVIEWPLAYTV] = { |
557 | .muxsel = {2, 3, 1, 1}, | 558 | .name = "Prolink Pixelview PlayTV (bt878)", |
558 | .audiomux = {1, 0, 0, 0, 0}, | 559 | .video_inputs = 3, |
559 | .needs_tvaudio = 1, | 560 | .audio_inputs = 1, |
560 | .tuner_type = -1, | 561 | .tuner = 0, |
561 | .tuner_addr = ADDR_UNSET, | 562 | .svhs = 2, |
562 | },{ | 563 | .gpiomask = 0x01fe00, |
563 | .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", | 564 | .muxsel = { 2, 3, 1, 1}, |
564 | .video_inputs = 4, | 565 | #if 0 |
565 | .audio_inputs = 1, | 566 | /* old */ |
566 | .tuner = -1, | 567 | .audiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 }, |
567 | .svhs = -1, | 568 | #else |
568 | .gpiomask = 0x8dff00, | 569 | /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */ |
569 | .muxsel = { 2, 3, 1, 1}, | 570 | .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, |
570 | .audiomux = { 0 }, | 571 | #endif |
571 | .no_msp34xx = 1, | 572 | .needs_tvaudio = 1, |
572 | .tuner_type = -1, | 573 | .pll = PLL_28, |
573 | .tuner_addr = ADDR_UNSET, | 574 | .tuner_type = -1, |
574 | },{ | 575 | }, |
575 | 576 | [BTTV_BOARD_WINVIEW_601] = { | |
576 | /* ---- card 0x14 ---------------------------------- */ | 577 | .name = "Leadtek WinView 601", |
577 | .name = "CEI Raffles Card", | 578 | .video_inputs = 3, |
578 | .video_inputs = 3, | 579 | .audio_inputs = 1, |
579 | .audio_inputs = 3, | 580 | .tuner = 0, |
580 | .tuner = 0, | 581 | .svhs = 2, |
581 | .svhs = 2, | 582 | .gpiomask = 0x8300f8, |
582 | .muxsel = {2, 3, 1, 1}, | 583 | .muxsel = { 2, 3, 1, 1,0}, |
583 | .tuner_type = -1, | 584 | .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007}, |
584 | .tuner_addr = ADDR_UNSET, | 585 | .needs_tvaudio = 1, |
585 | },{ | 586 | .tuner_type = -1, |
586 | .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50", | 587 | .tuner_addr = ADDR_UNSET, |
587 | .video_inputs = 4, | 588 | .radio_addr = ADDR_UNSET, |
588 | .audio_inputs = 2, /* tuner, line in */ | 589 | .audio_hook = winview_audio, |
589 | .tuner = 0, | 590 | .has_radio = 1, |
590 | .svhs = 2, | 591 | }, |
591 | .gpiomask = 0x1800, | 592 | [BTTV_BOARD_AVEC_INTERCAP] = { |
592 | .muxsel = { 2, 3, 1, 1}, | 593 | .name = "AVEC Intercapture", |
593 | .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, | 594 | .video_inputs = 3, |
594 | .pll = PLL_28, | 595 | .audio_inputs = 2, |
595 | .tuner_type = TUNER_PHILIPS_PAL_I, | 596 | .tuner = 0, |
596 | .tuner_addr = ADDR_UNSET, | 597 | .svhs = 2, |
597 | },{ | 598 | .gpiomask = 0, |
598 | .name = "Askey CPH050/ Phoebe Tv Master + FM", | 599 | .muxsel = {2, 3, 1, 1}, |
599 | .video_inputs = 3, | 600 | .audiomux = {1, 0, 0, 0, 0}, |
600 | .audio_inputs = 1, | 601 | .needs_tvaudio = 1, |
601 | .tuner = 0, | 602 | .tuner_type = -1, |
602 | .svhs = 2, | 603 | .tuner_addr = ADDR_UNSET, |
603 | .gpiomask = 0xc00, | 604 | .radio_addr = ADDR_UNSET, |
604 | .muxsel = { 2, 3, 1, 1}, | 605 | }, |
605 | .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0}, | 606 | [BTTV_BOARD_LIFE_FLYKIT] = { |
606 | .needs_tvaudio = 1, | 607 | .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", |
607 | .pll = PLL_28, | 608 | .video_inputs = 4, |
608 | .tuner_type = -1, | 609 | .audio_inputs = 1, |
609 | .tuner_addr = ADDR_UNSET, | 610 | .tuner = -1, |
610 | },{ | 611 | .svhs = -1, |
611 | .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878", | 612 | .gpiomask = 0x8dff00, |
612 | .video_inputs = 3, | 613 | .muxsel = { 2, 3, 1, 1}, |
613 | .audio_inputs = 1, | 614 | .audiomux = { 0 }, |
614 | .tuner = 0, | 615 | .no_msp34xx = 1, |
615 | .svhs = -1, | 616 | .tuner_type = -1, |
616 | .gpiomask = 7, | 617 | .tuner_addr = ADDR_UNSET, |
617 | .muxsel = { 2, 3, -1 }, | 618 | .radio_addr = ADDR_UNSET, |
618 | .digital_mode = DIGITAL_MODE_CAMERA, | 619 | }, |
619 | .audiomux = { 0, 0, 0, 0, 0 }, | 620 | |
620 | .no_msp34xx = 1, | 621 | /* ---- card 0x14 ---------------------------------- */ |
621 | .pll = PLL_28, | 622 | [BTTV_BOARD_CEI_RAFFLES] = { |
622 | .tuner_type = TUNER_ALPS_TSBB5_PAL_I, | 623 | .name = "CEI Raffles Card", |
623 | .tuner_addr = ADDR_UNSET, | 624 | .video_inputs = 3, |
624 | },{ | 625 | .audio_inputs = 3, |
625 | 626 | .tuner = 0, | |
626 | /* ---- card 0x18 ---------------------------------- */ | 627 | .svhs = 2, |
627 | .name = "Askey CPH05X/06X (bt878) [many vendors]", | 628 | .muxsel = {2, 3, 1, 1}, |
628 | .video_inputs = 3, | 629 | .tuner_type = -1, |
629 | .audio_inputs = 1, | 630 | .tuner_addr = ADDR_UNSET, |
630 | .tuner = 0, | 631 | .radio_addr = ADDR_UNSET, |
631 | .svhs = 2, | 632 | }, |
632 | .gpiomask = 0xe00, | 633 | [BTTV_BOARD_CONFERENCETV] = { |
633 | .muxsel = { 2, 3, 1, 1}, | 634 | .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50", |
634 | .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00}, | 635 | .video_inputs = 4, |
635 | .needs_tvaudio = 1, | 636 | .audio_inputs = 2, /* tuner, line in */ |
636 | .pll = PLL_28, | 637 | .tuner = 0, |
637 | .tuner_type = -1, | 638 | .svhs = 2, |
638 | .tuner_addr = ADDR_UNSET, | 639 | .gpiomask = 0x1800, |
639 | .has_remote = 1, | 640 | .muxsel = { 2, 3, 1, 1}, |
640 | },{ | 641 | .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, |
641 | .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", | 642 | .pll = PLL_28, |
642 | .video_inputs = 3, | 643 | .tuner_type = TUNER_PHILIPS_PAL_I, |
643 | .audio_inputs = 1, | 644 | .tuner_addr = ADDR_UNSET, |
644 | .tuner = 0, | 645 | .radio_addr = ADDR_UNSET, |
645 | .svhs = 2, | 646 | }, |
646 | .gpiomask = 0x1f0fff, | 647 | [BTTV_BOARD_PHOEBE_TVMAS] = { |
647 | .muxsel = { 2, 3, 1, 1}, | 648 | .name = "Askey CPH050/ Phoebe Tv Master + FM", |
648 | .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000}, | 649 | .video_inputs = 3, |
649 | .needs_tvaudio = 0, | 650 | .audio_inputs = 1, |
650 | .tuner_type = TUNER_PHILIPS_PAL, | 651 | .tuner = 0, |
651 | .tuner_addr = ADDR_UNSET, | 652 | .svhs = 2, |
652 | .audio_hook = terratv_audio, | 653 | .gpiomask = 0xc00, |
653 | },{ | 654 | .muxsel = { 2, 3, 1, 1}, |
654 | .name = "Hauppauge WinCam newer (bt878)", | 655 | .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0}, |
655 | .video_inputs = 4, | 656 | .needs_tvaudio = 1, |
656 | .audio_inputs = 1, | 657 | .pll = PLL_28, |
657 | .tuner = 0, | 658 | .tuner_type = -1, |
658 | .svhs = 3, | 659 | .tuner_addr = ADDR_UNSET, |
659 | .gpiomask = 7, | 660 | .radio_addr = ADDR_UNSET, |
660 | .muxsel = { 2, 0, 1, 1}, | 661 | }, |
661 | .audiomux = { 0, 1, 2, 3, 4}, | 662 | [BTTV_BOARD_MODTEC_205] = { |
662 | .needs_tvaudio = 1, | 663 | .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878", |
663 | .tuner_type = -1, | 664 | .video_inputs = 3, |
664 | .tuner_addr = ADDR_UNSET, | 665 | .audio_inputs = 1, |
665 | },{ | 666 | .tuner = 0, |
666 | .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50", | 667 | .svhs = -1, |
667 | .video_inputs = 4, | 668 | .gpiomask = 7, |
668 | .audio_inputs = 2, | 669 | .muxsel = { 2, 3, -1 }, |
669 | .tuner = 0, | 670 | .digital_mode = DIGITAL_MODE_CAMERA, |
670 | .svhs = 2, | 671 | .audiomux = { 0, 0, 0, 0, 0 }, |
671 | .gpiomask = 0x1800, | 672 | .no_msp34xx = 1, |
672 | .muxsel = { 2, 3, 1, 1}, | 673 | .pll = PLL_28, |
673 | .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, | 674 | .tuner_type = TUNER_ALPS_TSBB5_PAL_I, |
674 | .pll = PLL_28, | 675 | .tuner_addr = ADDR_UNSET, |
675 | .tuner_type = TUNER_PHILIPS_SECAM, | 676 | .radio_addr = ADDR_UNSET, |
676 | .tuner_addr = ADDR_UNSET, | 677 | }, |
677 | },{ | 678 | |
678 | 679 | /* ---- card 0x18 ---------------------------------- */ | |
679 | /* ---- card 0x1c ---------------------------------- */ | 680 | [BTTV_BOARD_MAGICTVIEW061] = { |
680 | .name = "Terratec TerraTV+ Version 1.1 (bt878)", | 681 | .name = "Askey CPH05X/06X (bt878) [many vendors]", |
681 | .video_inputs = 3, | 682 | .video_inputs = 3, |
682 | .audio_inputs = 1, | 683 | .audio_inputs = 1, |
683 | .tuner = 0, | 684 | .tuner = 0, |
684 | .svhs = 2, | 685 | .svhs = 2, |
685 | .gpiomask = 0x1f0fff, | 686 | .gpiomask = 0xe00, |
686 | .muxsel = { 2, 3, 1, 1}, | 687 | .muxsel = { 2, 3, 1, 1}, |
687 | .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000}, | 688 | .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00}, |
688 | .needs_tvaudio = 0, | 689 | .needs_tvaudio = 1, |
689 | .tuner_type = TUNER_PHILIPS_PAL, | 690 | .pll = PLL_28, |
690 | .tuner_addr = ADDR_UNSET, | 691 | .tuner_type = -1, |
691 | .audio_hook = terratv_audio, | 692 | .tuner_addr = ADDR_UNSET, |
692 | /* GPIO wiring: | 693 | .radio_addr = ADDR_UNSET, |
693 | External 20 pin connector (for Active Radio Upgrade board) | 694 | .has_remote = 1, |
694 | gpio00: i2c-sda | 695 | }, |
695 | gpio01: i2c-scl | 696 | [BTTV_BOARD_VOBIS_BOOSTAR] = { |
696 | gpio02: om5610-data | 697 | .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", |
697 | gpio03: om5610-clk | 698 | .video_inputs = 3, |
698 | gpio04: om5610-wre | 699 | .audio_inputs = 1, |
699 | gpio05: om5610-stereo | 700 | .tuner = 0, |
700 | gpio06: rds6588-davn | 701 | .svhs = 2, |
701 | gpio07: Pin 7 n.c. | 702 | .gpiomask = 0x1f0fff, |
702 | gpio08: nIOW | 703 | .muxsel = { 2, 3, 1, 1}, |
703 | gpio09+10: nIOR, nSEL ?? (bt878) | 704 | .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000}, |
704 | gpio09: nIOR (bt848) | 705 | .needs_tvaudio = 0, |
705 | gpio10: nSEL (bt848) | 706 | .tuner_type = TUNER_PHILIPS_PAL, |
706 | Sound Routing: | 707 | .tuner_addr = ADDR_UNSET, |
707 | gpio16: u2-A0 (1st 4052bt) | 708 | .radio_addr = ADDR_UNSET, |
708 | gpio17: u2-A1 | 709 | .audio_hook = terratv_audio, |
709 | gpio18: u2-nEN | 710 | }, |
710 | gpio19: u4-A0 (2nd 4052) | 711 | [BTTV_BOARD_HAUPPAUG_WCAM] = { |
711 | gpio20: u4-A1 | 712 | .name = "Hauppauge WinCam newer (bt878)", |
712 | u4-nEN - GND | 713 | .video_inputs = 4, |
713 | Btspy: | 714 | .audio_inputs = 1, |
714 | 00000 : Cdrom (internal audio input) | 715 | .tuner = 0, |
715 | 10000 : ext. Video audio input | 716 | .svhs = 3, |
716 | 20000 : TV Mono | 717 | .gpiomask = 7, |
717 | a0000 : TV Mono/2 | 718 | .muxsel = { 2, 0, 1, 1}, |
718 | 1a0000 : TV Stereo | 719 | .audiomux = { 0, 1, 2, 3, 4}, |
719 | 30000 : Radio | 720 | .needs_tvaudio = 1, |
720 | 40000 : Mute | 721 | .tuner_type = -1, |
721 | */ | 722 | .tuner_addr = ADDR_UNSET, |
722 | 723 | .radio_addr = ADDR_UNSET, | |
723 | },{ | 724 | }, |
724 | /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */ | 725 | [BTTV_BOARD_MAXI] = { |
725 | .name = "Imagenation PXC200", | 726 | .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50", |
726 | .video_inputs = 5, | 727 | .video_inputs = 4, |
727 | .audio_inputs = 1, | 728 | .audio_inputs = 2, |
728 | .tuner = -1, | 729 | .tuner = 0, |
729 | .svhs = 1, /* was: 4 */ | 730 | .svhs = 2, |
730 | .gpiomask = 0, | 731 | .gpiomask = 0x1800, |
731 | .muxsel = { 2, 3, 1, 0, 0}, | 732 | .muxsel = { 2, 3, 1, 1}, |
732 | .audiomux = { 0 }, | 733 | .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, |
733 | .needs_tvaudio = 1, | 734 | .pll = PLL_28, |
734 | .tuner_type = -1, | 735 | .tuner_type = TUNER_PHILIPS_SECAM, |
735 | .tuner_addr = ADDR_UNSET, | 736 | .tuner_addr = ADDR_UNSET, |
736 | .muxsel_hook = PXC200_muxsel, | 737 | .radio_addr = ADDR_UNSET, |
737 | 738 | }, | |
738 | },{ | 739 | |
739 | .name = "Lifeview FlyVideo 98 LR50", | 740 | /* ---- card 0x1c ---------------------------------- */ |
740 | .video_inputs = 4, | 741 | [BTTV_BOARD_TERRATV] = { |
741 | .audio_inputs = 1, | 742 | .name = "Terratec TerraTV+ Version 1.1 (bt878)", |
742 | .tuner = 0, | 743 | .video_inputs = 3, |
743 | .svhs = 2, | 744 | .audio_inputs = 1, |
744 | .gpiomask = 0x1800, /* 0x8dfe00 */ | 745 | .tuner = 0, |
745 | .muxsel = { 2, 3, 1, 1}, | 746 | .svhs = 2, |
746 | .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 }, | 747 | .gpiomask = 0x1f0fff, |
747 | .pll = PLL_28, | 748 | .muxsel = { 2, 3, 1, 1}, |
748 | .tuner_type = -1, | 749 | .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000}, |
749 | .tuner_addr = ADDR_UNSET, | 750 | .needs_tvaudio = 0, |
750 | },{ | 751 | .tuner_type = TUNER_PHILIPS_PAL, |
751 | .name = "Formac iProTV, Formac ProTV I (bt848)", | 752 | .tuner_addr = ADDR_UNSET, |
752 | .video_inputs = 4, | 753 | .radio_addr = ADDR_UNSET, |
753 | .audio_inputs = 1, | 754 | .audio_hook = terratv_audio, |
754 | .tuner = 0, | 755 | /* GPIO wiring: |
755 | .svhs = 3, | 756 | External 20 pin connector (for Active Radio Upgrade board) |
756 | .gpiomask = 1, | 757 | gpio00: i2c-sda |
757 | .muxsel = { 2, 3, 1, 1}, | 758 | gpio01: i2c-scl |
758 | .audiomux = { 1, 0, 0, 0, 0 }, | 759 | gpio02: om5610-data |
759 | .pll = PLL_28, | 760 | gpio03: om5610-clk |
760 | .tuner_type = TUNER_PHILIPS_PAL, | 761 | gpio04: om5610-wre |
761 | .tuner_addr = ADDR_UNSET, | 762 | gpio05: om5610-stereo |
762 | },{ | 763 | gpio06: rds6588-davn |
763 | 764 | gpio07: Pin 7 n.c. | |
764 | /* ---- card 0x20 ---------------------------------- */ | 765 | gpio08: nIOW |
765 | .name = "Intel Create and Share PCI/ Smart Video Recorder III", | 766 | gpio09+10: nIOR, nSEL ?? (bt878) |
766 | .video_inputs = 4, | 767 | gpio09: nIOR (bt848) |
767 | .audio_inputs = 0, | 768 | gpio10: nSEL (bt848) |
768 | .tuner = -1, | 769 | Sound Routing: |
769 | .svhs = 2, | 770 | gpio16: u2-A0 (1st 4052bt) |
770 | .gpiomask = 0, | 771 | gpio17: u2-A1 |
771 | .muxsel = { 2, 3, 1, 1}, | 772 | gpio18: u2-nEN |
772 | .audiomux = { 0 }, | 773 | gpio19: u4-A0 (2nd 4052) |
773 | .needs_tvaudio = 0, | 774 | gpio20: u4-A1 |
774 | .tuner_type = 4, | 775 | u4-nEN - GND |
775 | .tuner_addr = ADDR_UNSET, | 776 | Btspy: |
776 | },{ | 777 | 00000 : Cdrom (internal audio input) |
777 | .name = "Terratec TerraTValue Version Bt878", | 778 | 10000 : ext. Video audio input |
778 | .video_inputs = 3, | 779 | 20000 : TV Mono |
779 | .audio_inputs = 1, | 780 | a0000 : TV Mono/2 |
780 | .tuner = 0, | 781 | 1a0000 : TV Stereo |
781 | .svhs = 2, | 782 | 30000 : Radio |
782 | .gpiomask = 0xffff00, | 783 | 40000 : Mute |
783 | .muxsel = { 2, 3, 1, 1}, | ||
784 | .audiomux = { 0x500, 0, 0x300, 0x900, 0x900}, | ||
785 | .needs_tvaudio = 1, | ||
786 | .pll = PLL_28, | ||
787 | .tuner_type = TUNER_PHILIPS_PAL, | ||
788 | .tuner_addr = ADDR_UNSET, | ||
789 | },{ | ||
790 | .name = "Leadtek WinFast 2000/ WinFast 2000 XP", | ||
791 | .video_inputs = 4, | ||
792 | .audio_inputs = 1, | ||
793 | .tuner = 0, | ||
794 | .svhs = 2, | ||
795 | .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */ | ||
796 | /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */ | ||
797 | .gpiomask = 0xb33000, | ||
798 | .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 }, | ||
799 | /* Audio Routing for "WinFast 2000 XP" (no tv stereo !) | ||
800 | gpio23 -- hef4052:nEnable (0x800000) | ||
801 | gpio12 -- hef4052:A1 | ||
802 | gpio13 -- hef4052:A0 | ||
803 | 0x0000: external audio | ||
804 | 0x1000: FM | ||
805 | 0x2000: TV | ||
806 | 0x3000: n.c. | ||
807 | Note: There exists another variant "Winfast 2000" with tv stereo !? | ||
808 | Note: eeprom only contains FF and pci subsystem id 107d:6606 | ||
809 | */ | ||
810 | .needs_tvaudio = 0, | ||
811 | .pll = PLL_28, | ||
812 | .has_radio = 1, | ||
813 | .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */ | ||
814 | .tuner_addr = ADDR_UNSET, | ||
815 | .audio_hook = winfast2000_audio, | ||
816 | .has_remote = 1, | ||
817 | },{ | ||
818 | .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II", | ||
819 | .video_inputs = 4, | ||
820 | .audio_inputs = 3, | ||
821 | .tuner = 0, | ||
822 | .svhs = 2, | ||
823 | .gpiomask = 0x1800, | ||
824 | .muxsel = { 2, 3, 1, 1}, | ||
825 | .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, | ||
826 | .pll = PLL_28, | ||
827 | .tuner_type = -1, | ||
828 | .tuner_addr = ADDR_UNSET, | ||
829 | },{ | ||
830 | |||
831 | /* ---- card 0x24 ---------------------------------- */ | ||
832 | .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner", | ||
833 | .video_inputs = 4, | ||
834 | .audio_inputs = 3, | ||
835 | .tuner = 0, | ||
836 | .svhs = 2, | ||
837 | .gpiomask = 0x1800, | ||
838 | .muxsel = { 2, 3, 1, 1}, | ||
839 | .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 }, | ||
840 | .pll = PLL_28, | ||
841 | .tuner_type = -1, | ||
842 | .tuner_addr = ADDR_UNSET, | ||
843 | .has_radio = 1, | ||
844 | },{ | ||
845 | .name = "Prolink PixelView PlayTV pro", | ||
846 | .video_inputs = 3, | ||
847 | .audio_inputs = 1, | ||
848 | .tuner = 0, | ||
849 | .svhs = 2, | ||
850 | .gpiomask = 0xff, | ||
851 | .muxsel = { 2, 3, 1, 1 }, | ||
852 | .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 }, | ||
853 | .no_msp34xx = 1, | ||
854 | .pll = PLL_28, | ||
855 | .tuner_type = -1, | ||
856 | .tuner_addr = ADDR_UNSET, | ||
857 | },{ | ||
858 | .name = "Askey CPH06X TView99", | ||
859 | .video_inputs = 4, | ||
860 | .audio_inputs = 1, | ||
861 | .tuner = 0, | ||
862 | .svhs = 2, | ||
863 | .gpiomask = 0x551e00, | ||
864 | .muxsel = { 2, 3, 1, 0}, | ||
865 | .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 }, | ||
866 | .needs_tvaudio = 1, | ||
867 | .pll = PLL_28, | ||
868 | .tuner_type = 1, | ||
869 | .tuner_addr = ADDR_UNSET, | ||
870 | .has_remote = 1, | ||
871 | },{ | ||
872 | .name = "Pinnacle PCTV Studio/Rave", | ||
873 | .video_inputs = 3, | ||
874 | .audio_inputs = 1, | ||
875 | .tuner = 0, | ||
876 | .svhs = 2, | ||
877 | .gpiomask = 0x03000F, | ||
878 | .muxsel = { 2, 3, 1, 1}, | ||
879 | .audiomux = { 2, 0xd0001, 0, 0, 1}, | ||
880 | .needs_tvaudio = 0, | ||
881 | .pll = PLL_28, | ||
882 | .tuner_type = -1, | ||
883 | .tuner_addr = ADDR_UNSET, | ||
884 | },{ | ||
885 | |||
886 | /* ---- card 0x28 ---------------------------------- */ | ||
887 | .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100", | ||
888 | .video_inputs = 3, | ||
889 | .audio_inputs = 1, | ||
890 | .tuner = 0, | ||
891 | .svhs = 2, | ||
892 | .gpiomask = 7, | ||
893 | .muxsel = { 2, 3, 1, 1}, | ||
894 | .audiomux = { 4, 0, 2, 3, 1}, | ||
895 | .no_msp34xx = 1, | ||
896 | .needs_tvaudio = 1, | ||
897 | .tuner_type = TUNER_PHILIPS_NTSC, | ||
898 | .tuner_addr = ADDR_UNSET, | ||
899 | .pll = PLL_28, | ||
900 | .has_radio = 1, | ||
901 | },{ | ||
902 | .name = "AVerMedia TVPhone 98", | ||
903 | .video_inputs = 3, | ||
904 | .audio_inputs = 4, | ||
905 | .tuner = 0, | ||
906 | .svhs = 2, | ||
907 | .gpiomask = 15, | ||
908 | .muxsel = { 2, 3, 1, 1}, | ||
909 | .audiomux = { 13, 4, 11, 7, 0, 0}, | ||
910 | .needs_tvaudio = 1, | ||
911 | .pll = PLL_28, | ||
912 | .tuner_type = -1, | ||
913 | .tuner_addr = ADDR_UNSET, | ||
914 | .has_radio = 1, | ||
915 | .audio_hook = avermedia_tvphone_audio, | ||
916 | },{ | ||
917 | .name = "ProVideo PV951", /* pic16c54 */ | ||
918 | .video_inputs = 3, | ||
919 | .audio_inputs = 1, | ||
920 | .tuner = 0, | ||
921 | .svhs = 2, | ||
922 | .gpiomask = 0, | ||
923 | .muxsel = { 2, 3, 1, 1}, | ||
924 | .audiomux = { 0, 0, 0, 0, 0}, | ||
925 | .needs_tvaudio = 1, | ||
926 | .no_msp34xx = 1, | ||
927 | .pll = PLL_28, | ||
928 | .tuner_type = 1, | ||
929 | .tuner_addr = ADDR_UNSET, | ||
930 | },{ | ||
931 | .name = "Little OnAir TV", | ||
932 | .video_inputs = 3, | ||
933 | .audio_inputs = 1, | ||
934 | .tuner = 0, | ||
935 | .svhs = 2, | ||
936 | .gpiomask = 0xe00b, | ||
937 | .muxsel = {2, 3, 1, 1}, | ||
938 | .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc}, | ||
939 | .no_msp34xx = 1, | ||
940 | .tuner_type = -1, | ||
941 | .tuner_addr = ADDR_UNSET, | ||
942 | },{ | ||
943 | |||
944 | /* ---- card 0x2c ---------------------------------- */ | ||
945 | .name = "Sigma TVII-FM", | ||
946 | .video_inputs = 2, | ||
947 | .audio_inputs = 1, | ||
948 | .tuner = 0, | ||
949 | .svhs = -1, | ||
950 | .gpiomask = 3, | ||
951 | .muxsel = {2, 3, 1, 1}, | ||
952 | .audiomux = {1, 1, 0, 2, 3}, | ||
953 | .no_msp34xx = 1, | ||
954 | .pll = PLL_NONE, | ||
955 | .tuner_type = -1, | ||
956 | .tuner_addr = ADDR_UNSET, | ||
957 | },{ | ||
958 | .name = "MATRIX-Vision MV-Delta 2", | ||
959 | .video_inputs = 5, | ||
960 | .audio_inputs = 1, | ||
961 | .tuner = -1, | ||
962 | .svhs = 3, | ||
963 | .gpiomask = 0, | ||
964 | .muxsel = { 2, 3, 1, 0, 0}, | ||
965 | .audiomux = {0 }, | ||
966 | .no_msp34xx = 1, | ||
967 | .pll = PLL_28, | ||
968 | .tuner_type = -1, | ||
969 | .tuner_addr = ADDR_UNSET, | ||
970 | },{ | ||
971 | .name = "Zoltrix Genie TV/FM", | ||
972 | .video_inputs = 3, | ||
973 | .audio_inputs = 1, | ||
974 | .tuner = 0, | ||
975 | .svhs = 2, | ||
976 | .gpiomask = 0xbcf03f, | ||
977 | .muxsel = { 2, 3, 1, 1}, | ||
978 | .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f}, | ||
979 | .no_msp34xx = 1, | ||
980 | .pll = PLL_28, | ||
981 | .tuner_type = 21, | ||
982 | .tuner_addr = ADDR_UNSET, | ||
983 | },{ | ||
984 | .name = "Terratec TV/Radio+", | ||
985 | .video_inputs = 3, | ||
986 | .audio_inputs = 1, | ||
987 | .tuner = 0, | ||
988 | .svhs = 2, | ||
989 | .gpiomask = 0x70000, | ||
990 | .muxsel = { 2, 3, 1, 1}, | ||
991 | .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 }, | ||
992 | .needs_tvaudio = 1, | ||
993 | .no_msp34xx = 1, | ||
994 | .pll = PLL_35, | ||
995 | .tuner_type = 1, | ||
996 | .tuner_addr = ADDR_UNSET, | ||
997 | .has_radio = 1, | ||
998 | },{ | ||
999 | |||
1000 | /* ---- card 0x30 ---------------------------------- */ | ||
1001 | .name = "Askey CPH03x/ Dynalink Magic TView", | ||
1002 | .video_inputs = 3, | ||
1003 | .audio_inputs = 1, | ||
1004 | .tuner = 0, | ||
1005 | .svhs = 2, | ||
1006 | .gpiomask = 15, | ||
1007 | .muxsel = { 2, 3, 1, 1}, | ||
1008 | .audiomux = {2,0,0,0,1}, | ||
1009 | .needs_tvaudio = 1, | ||
1010 | .pll = PLL_28, | ||
1011 | .tuner_type = -1, | ||
1012 | .tuner_addr = ADDR_UNSET, | ||
1013 | },{ | ||
1014 | .name = "IODATA GV-BCTV3/PCI", | ||
1015 | .video_inputs = 3, | ||
1016 | .audio_inputs = 1, | ||
1017 | .tuner = 0, | ||
1018 | .svhs = 2, | ||
1019 | .gpiomask = 0x010f00, | ||
1020 | .muxsel = {2, 3, 0, 0}, | ||
1021 | .audiomux = {0x10000, 0, 0x10000, 0, 0, 0}, | ||
1022 | .no_msp34xx = 1, | ||
1023 | .pll = PLL_28, | ||
1024 | .tuner_type = TUNER_ALPS_TSHC6_NTSC, | ||
1025 | .tuner_addr = ADDR_UNSET, | ||
1026 | .audio_hook = gvbctv3pci_audio, | ||
1027 | },{ | ||
1028 | .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP", | ||
1029 | .video_inputs = 5, | ||
1030 | .audio_inputs = 1, | ||
1031 | .tuner = 0, | ||
1032 | .svhs = 3, | ||
1033 | .gpiomask = 0xAA0000, | ||
1034 | .muxsel = { 2,3,1,1,-1 }, | ||
1035 | .digital_mode = DIGITAL_MODE_CAMERA, | ||
1036 | .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 }, | ||
1037 | .no_msp34xx = 1, | ||
1038 | .pll = PLL_28, | ||
1039 | .tuner_type = TUNER_PHILIPS_PAL_I, | ||
1040 | .tuner_addr = ADDR_UNSET, | ||
1041 | .has_remote = 1, | ||
1042 | /* GPIO wiring: (different from Rev.4C !) | ||
1043 | GPIO17: U4.A0 (first hef4052bt) | ||
1044 | GPIO19: U4.A1 | ||
1045 | GPIO20: U5.A1 (second hef4052bt) | ||
1046 | GPIO21: U4.nEN | ||
1047 | GPIO22: BT832 Reset Line | ||
1048 | GPIO23: A5,A0, U5,nEN | ||
1049 | Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22 | ||
1050 | */ | ||
1051 | },{ | ||
1052 | .name = "Eagle Wireless Capricorn2 (bt878A)", | ||
1053 | .video_inputs = 4, | ||
1054 | .audio_inputs = 1, | ||
1055 | .tuner = 0, | ||
1056 | .svhs = 2, | ||
1057 | .gpiomask = 7, | ||
1058 | .muxsel = { 2, 0, 1, 1}, | ||
1059 | .audiomux = { 0, 1, 2, 3, 4}, | ||
1060 | .pll = PLL_28, | ||
1061 | .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */, | ||
1062 | .tuner_addr = ADDR_UNSET, | ||
1063 | },{ | ||
1064 | |||
1065 | /* ---- card 0x34 ---------------------------------- */ | ||
1066 | /* David Härdeman <david@2gen.com> */ | ||
1067 | .name = "Pinnacle PCTV Studio Pro", | ||
1068 | .video_inputs = 4, | ||
1069 | .audio_inputs = 1, | ||
1070 | .tuner = 0, | ||
1071 | .svhs = 3, | ||
1072 | .gpiomask = 0x03000F, | ||
1073 | .muxsel = { 2, 3, 1, 1}, | ||
1074 | .audiomux = { 1, 0xd0001, 0, 0, 10}, | ||
1075 | /* sound path (5 sources): | ||
1076 | MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable) | ||
1077 | 0= ext. Audio IN | ||
1078 | 1= from MUX2 | ||
1079 | 2= Mono TV sound from Tuner | ||
1080 | 3= not connected | ||
1081 | MUX2 (mask 0x30000): | ||
1082 | 0,2,3= from MSP34xx | ||
1083 | 1= FM stereo Radio from Tuner */ | ||
1084 | .needs_tvaudio = 0, | ||
1085 | .pll = PLL_28, | ||
1086 | .tuner_type = -1, | ||
1087 | .tuner_addr = ADDR_UNSET, | ||
1088 | },{ | ||
1089 | /* Claas Langbehn <claas@bigfoot.com>, | ||
1090 | Sven Grothklags <sven@upb.de> */ | ||
1091 | .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS", | ||
1092 | .video_inputs = 4, | ||
1093 | .audio_inputs = 3, | ||
1094 | .tuner = 0, | ||
1095 | .svhs = 2, | ||
1096 | .gpiomask = 0x1c, | ||
1097 | .muxsel = { 2, 3, 1, 1}, | ||
1098 | .audiomux = { 0, 0, 0x10, 8, 4 }, | ||
1099 | .needs_tvaudio = 1, | ||
1100 | .pll = PLL_28, | ||
1101 | .tuner_type = TUNER_PHILIPS_PAL, | ||
1102 | .tuner_addr = ADDR_UNSET, | ||
1103 | .has_radio = 1, | ||
1104 | },{ | ||
1105 | /* Tim Röstermundt <rosterm@uni-muenster.de> | ||
1106 | in de.comp.os.unix.linux.hardware: | ||
1107 | options bttv card=0 pll=1 radio=1 gpiomask=0x18e0 | ||
1108 | audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff | ||
1109 | options tuner type=5 */ | ||
1110 | .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]", | ||
1111 | .video_inputs = 4, | ||
1112 | .audio_inputs = 1, | ||
1113 | .tuner = 0, | ||
1114 | .svhs = 2, | ||
1115 | .gpiomask = 0x18e0, | ||
1116 | .muxsel = { 2, 3, 1, 1}, | ||
1117 | .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 }, | ||
1118 | /* For cards with tda9820/tda9821: | ||
1119 | 0x0000: Tuner normal stereo | ||
1120 | 0x0080: Tuner A2 SAP (second audio program = Zweikanalton) | ||
1121 | 0x0880: Tuner A2 stereo */ | ||
1122 | .pll = PLL_28, | ||
1123 | .tuner_type = -1, | ||
1124 | .tuner_addr = ADDR_UNSET, | ||
1125 | },{ | ||
1126 | /* Miguel Angel Alvarez <maacruz@navegalia.com> | ||
1127 | old Easy TV BT848 version (model CPH031) */ | ||
1128 | .name = "Askey CPH031/ BESTBUY Easy TV", | ||
1129 | .video_inputs = 4, | ||
1130 | .audio_inputs = 1, | ||
1131 | .tuner = 0, | ||
1132 | .svhs = 2, | ||
1133 | .gpiomask = 0xF, | ||
1134 | .muxsel = { 2, 3, 1, 0}, | ||
1135 | .audiomux = { 2, 0, 0, 0, 10}, | ||
1136 | .needs_tvaudio = 0, | ||
1137 | .pll = PLL_28, | ||
1138 | .tuner_type = TUNER_TEMIC_PAL, | ||
1139 | .tuner_addr = ADDR_UNSET, | ||
1140 | },{ | ||
1141 | |||
1142 | /* ---- card 0x38 ---------------------------------- */ | ||
1143 | /* Gordon Heydon <gjheydon@bigfoot.com ('98) */ | ||
1144 | .name = "Lifeview FlyVideo 98FM LR50", | ||
1145 | .video_inputs = 4, | ||
1146 | .audio_inputs = 3, | ||
1147 | .tuner = 0, | ||
1148 | .svhs = 2, | ||
1149 | .gpiomask = 0x1800, | ||
1150 | .muxsel = { 2, 3, 1, 1}, | ||
1151 | .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 }, | ||
1152 | .pll = PLL_28, | ||
1153 | .tuner_type = 5, | ||
1154 | .tuner_addr = ADDR_UNSET, | ||
1155 | },{ | ||
1156 | /* This is the ultimate cheapo capture card | ||
1157 | * just a BT848A on a small PCB! | ||
1158 | * Steve Hosgood <steve@equiinet.com> */ | ||
1159 | .name = "GrandTec 'Grand Video Capture' (Bt848)", | ||
1160 | .video_inputs = 2, | ||
1161 | .audio_inputs = 0, | ||
1162 | .tuner = -1, | ||
1163 | .svhs = 1, | ||
1164 | .gpiomask = 0, | ||
1165 | .muxsel = { 3, 1 }, | ||
1166 | .audiomux = { 0 }, | ||
1167 | .needs_tvaudio = 0, | ||
1168 | .no_msp34xx = 1, | ||
1169 | .pll = PLL_35, | ||
1170 | .tuner_type = -1, | ||
1171 | .tuner_addr = ADDR_UNSET, | ||
1172 | },{ | ||
1173 | /* Daniel Herrington <daniel.herrington@home.com> */ | ||
1174 | .name = "Askey CPH060/ Phoebe TV Master Only (No FM)", | ||
1175 | .video_inputs = 3, | ||
1176 | .audio_inputs = 1, | ||
1177 | .tuner = 0, | ||
1178 | .svhs = 2, | ||
1179 | .gpiomask = 0xe00, | ||
1180 | .muxsel = { 2, 3, 1, 1}, | ||
1181 | .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 }, | ||
1182 | .needs_tvaudio = 1, | ||
1183 | .pll = PLL_28, | ||
1184 | .tuner_type = TUNER_TEMIC_4036FY5_NTSC, | ||
1185 | .tuner_addr = ADDR_UNSET, | ||
1186 | },{ | ||
1187 | /* Matti Mottus <mottus@physic.ut.ee> */ | ||
1188 | .name = "Askey CPH03x TV Capturer", | ||
1189 | .video_inputs = 4, | ||
1190 | .audio_inputs = 1, | ||
1191 | .tuner = 0, | ||
1192 | .svhs = 2, | ||
1193 | .gpiomask = 0x03000F, | ||
1194 | .muxsel = { 2, 3, 1, 0}, | ||
1195 | .audiomux = { 2,0,0,0,1 }, | ||
1196 | .pll = PLL_28, | ||
1197 | .tuner_type = 0, | ||
1198 | .tuner_addr = ADDR_UNSET, | ||
1199 | },{ | ||
1200 | |||
1201 | /* ---- card 0x3c ---------------------------------- */ | ||
1202 | /* Philip Blundell <philb@gnu.org> */ | ||
1203 | .name = "Modular Technology MM100PCTV", | ||
1204 | .video_inputs = 2, | ||
1205 | .audio_inputs = 2, | ||
1206 | .tuner = 0, | ||
1207 | .svhs = -1, | ||
1208 | .gpiomask = 11, | ||
1209 | .muxsel = { 2, 3, 1, 1}, | ||
1210 | .audiomux = { 2, 0, 0, 1, 8}, | ||
1211 | .pll = PLL_35, | ||
1212 | .tuner_type = TUNER_TEMIC_PAL, | ||
1213 | .tuner_addr = ADDR_UNSET, | ||
1214 | },{ | ||
1215 | /* Adrian Cox <adrian@humboldt.co.uk */ | ||
1216 | .name = "AG Electronics GMV1", | ||
1217 | .video_inputs = 2, | ||
1218 | .audio_inputs = 0, | ||
1219 | .tuner = -1, | ||
1220 | .svhs = 1, | ||
1221 | .gpiomask = 0xF, | ||
1222 | .muxsel = { 2, 2}, | ||
1223 | .audiomux = { }, | ||
1224 | .no_msp34xx = 1, | ||
1225 | .needs_tvaudio = 0, | ||
1226 | .pll = PLL_28, | ||
1227 | .tuner_type = -1, | ||
1228 | .tuner_addr = ADDR_UNSET, | ||
1229 | },{ | ||
1230 | /* Miguel Angel Alvarez <maacruz@navegalia.com> | ||
1231 | new Easy TV BT878 version (model CPH061) | ||
1232 | special thanks to Informatica Mieres for providing the card */ | ||
1233 | .name = "Askey CPH061/ BESTBUY Easy TV (bt878)", | ||
1234 | .video_inputs = 3, | ||
1235 | .audio_inputs = 2, | ||
1236 | .tuner = 0, | ||
1237 | .svhs = 2, | ||
1238 | .gpiomask = 0xFF, | ||
1239 | .muxsel = { 2, 3, 1, 0}, | ||
1240 | .audiomux = { 1, 0, 4, 4, 9}, | ||
1241 | .needs_tvaudio = 0, | ||
1242 | .pll = PLL_28, | ||
1243 | .tuner_type = TUNER_PHILIPS_PAL, | ||
1244 | .tuner_addr = ADDR_UNSET, | ||
1245 | },{ | ||
1246 | /* Lukas Gebauer <geby@volny.cz> */ | ||
1247 | .name = "ATI TV-Wonder", | ||
1248 | .video_inputs = 3, | ||
1249 | .audio_inputs = 1, | ||
1250 | .tuner = 0, | ||
1251 | .svhs = 2, | ||
1252 | .gpiomask = 0xf03f, | ||
1253 | .muxsel = { 2, 3, 1, 0 }, | ||
1254 | .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe}, | ||
1255 | .pll = PLL_28, | ||
1256 | .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, | ||
1257 | .tuner_addr = ADDR_UNSET, | ||
1258 | },{ | ||
1259 | |||
1260 | /* ---- card 0x40 ---------------------------------- */ | ||
1261 | /* Lukas Gebauer <geby@volny.cz> */ | ||
1262 | .name = "ATI TV-Wonder VE", | ||
1263 | .video_inputs = 2, | ||
1264 | .audio_inputs = 1, | ||
1265 | .tuner = 0, | ||
1266 | .svhs = -1, | ||
1267 | .gpiomask = 1, | ||
1268 | .muxsel = { 2, 3, 0, 1}, | ||
1269 | .audiomux = { 0, 0, 1, 0, 0}, | ||
1270 | .no_msp34xx = 1, | ||
1271 | .pll = PLL_28, | ||
1272 | .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, | ||
1273 | .tuner_addr = ADDR_UNSET, | ||
1274 | },{ | ||
1275 | /* DeeJay <deejay@westel900.net (2000S) */ | ||
1276 | .name = "Lifeview FlyVideo 2000S LR90", | ||
1277 | .video_inputs = 3, | ||
1278 | .audio_inputs = 3, | ||
1279 | .tuner = 0, | ||
1280 | .svhs = 2, | ||
1281 | .gpiomask = 0x18e0, | ||
1282 | .muxsel = { 2, 3, 0, 1}, | ||
1283 | /* Radio changed from 1e80 to 0x800 to make | ||
1284 | FlyVideo2000S in .hu happy (gm)*/ | ||
1285 | /* -dk-???: set mute=0x1800 for tda9874h daughterboard */ | ||
1286 | .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 }, | ||
1287 | .audio_hook = fv2000s_audio, | ||
1288 | .no_msp34xx = 1, | ||
1289 | .no_tda9875 = 1, | ||
1290 | .needs_tvaudio = 1, | ||
1291 | .pll = PLL_28, | ||
1292 | .tuner_type = 5, | ||
1293 | .tuner_addr = ADDR_UNSET, | ||
1294 | },{ | ||
1295 | .name = "Terratec TValueRadio", | ||
1296 | .video_inputs = 3, | ||
1297 | .audio_inputs = 1, | ||
1298 | .tuner = 0, | ||
1299 | .svhs = 2, | ||
1300 | .gpiomask = 0xffff00, | ||
1301 | .muxsel = { 2, 3, 1, 1}, | ||
1302 | .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900}, | ||
1303 | .needs_tvaudio = 1, | ||
1304 | .pll = PLL_28, | ||
1305 | .tuner_type = TUNER_PHILIPS_PAL, | ||
1306 | .tuner_addr = ADDR_UNSET, | ||
1307 | .has_radio = 1, | ||
1308 | },{ | ||
1309 | /* TANAKA Kei <peg00625@nifty.com> */ | ||
1310 | .name = "IODATA GV-BCTV4/PCI", | ||
1311 | .video_inputs = 3, | ||
1312 | .audio_inputs = 1, | ||
1313 | .tuner = 0, | ||
1314 | .svhs = 2, | ||
1315 | .gpiomask = 0x010f00, | ||
1316 | .muxsel = {2, 3, 0, 0}, | ||
1317 | .audiomux = {0x10000, 0, 0x10000, 0, 0, 0}, | ||
1318 | .no_msp34xx = 1, | ||
1319 | .pll = PLL_28, | ||
1320 | .tuner_type = TUNER_SHARP_2U5JF5540_NTSC, | ||
1321 | .tuner_addr = ADDR_UNSET, | ||
1322 | .audio_hook = gvbctv3pci_audio, | ||
1323 | },{ | ||
1324 | |||
1325 | /* ---- card 0x44 ---------------------------------- */ | ||
1326 | .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)", | ||
1327 | /* try "insmod msp3400 simple=0" if you have | ||
1328 | * sound problems with this card. */ | ||
1329 | .video_inputs = 4, | ||
1330 | .audio_inputs = 1, | ||
1331 | .tuner = 0, | ||
1332 | .svhs = -1, | ||
1333 | .gpiomask = 0x4f8a00, | ||
1334 | /* 0x100000: 1=MSP enabled (0=disable again) | ||
1335 | * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ | ||
1336 | .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff}, | ||
1337 | /* tvtuner, radio, external,internal, mute, stereo | ||
1338 | * tuner, Composit, SVid, Composit-on-Svid-adapter */ | ||
1339 | .muxsel = { 2, 3 ,0 ,1}, | ||
1340 | .tuner_type = TUNER_MT2032, | ||
1341 | .tuner_addr = ADDR_UNSET, | ||
1342 | .pll = PLL_28, | ||
1343 | .has_radio = 1, | ||
1344 | },{ | ||
1345 | /* Philip Blundell <pb@nexus.co.uk> */ | ||
1346 | .name = "Active Imaging AIMMS", | ||
1347 | .video_inputs = 1, | ||
1348 | .audio_inputs = 0, | ||
1349 | .tuner = -1, | ||
1350 | .tuner_type = -1, | ||
1351 | .tuner_addr = ADDR_UNSET, | ||
1352 | .pll = PLL_28, | ||
1353 | .muxsel = { 2 }, | ||
1354 | .gpiomask = 0 | ||
1355 | },{ | ||
1356 | /* Tomasz Pyra <hellfire@sedez.iq.pl> */ | ||
1357 | .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)", | ||
1358 | .video_inputs = 3, | ||
1359 | .audio_inputs = 4, | ||
1360 | .tuner = 0, | ||
1361 | .svhs = 2, | ||
1362 | .gpiomask = 15, | ||
1363 | .muxsel = { 2, 3, 1, 1}, | ||
1364 | .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */ | ||
1365 | .needs_tvaudio = 1, | ||
1366 | .pll = PLL_28, | ||
1367 | .tuner_type = 25, | ||
1368 | .tuner_addr = ADDR_UNSET, | ||
1369 | .has_remote = 1, | ||
1370 | /* GPIO wiring: | ||
1371 | GPIO0: U4.A0 (hef4052bt) | ||
1372 | GPIO1: U4.A1 | ||
1373 | GPIO2: U4.A1 (second hef4052bt) | ||
1374 | GPIO3: U4.nEN, U5.A0, A5.nEN | ||
1375 | GPIO8-15: vrd866b ? | ||
1376 | */ | 784 | */ |
1377 | },{ | 785 | |
1378 | .name = "Lifeview FlyVideo 98EZ (capture only) LR51", | 786 | }, |
1379 | .video_inputs = 4, | 787 | [BTTV_BOARD_PXC200] = { |
1380 | .audio_inputs = 0, | 788 | /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */ |
1381 | .tuner = -1, | 789 | .name = "Imagenation PXC200", |
1382 | .svhs = 2, | 790 | .video_inputs = 5, |
1383 | .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */ | 791 | .audio_inputs = 1, |
1384 | .pll = PLL_28, | 792 | .tuner = -1, |
1385 | .no_msp34xx = 1, | 793 | .svhs = 1, /* was: 4 */ |
1386 | .tuner_type = UNSET, | 794 | .gpiomask = 0, |
1387 | .tuner_addr = ADDR_UNSET, | 795 | .muxsel = { 2, 3, 1, 0, 0}, |
1388 | },{ | 796 | .audiomux = { 0 }, |
1389 | 797 | .needs_tvaudio = 1, | |
1390 | /* ---- card 0x48 ---------------------------------- */ | 798 | .tuner_type = -1, |
1391 | /* Dariusz Kowalewski <darekk@automex.pl> */ | 799 | .tuner_addr = ADDR_UNSET, |
1392 | .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)", | 800 | .radio_addr = ADDR_UNSET, |
1393 | .video_inputs = 4, | 801 | .muxsel_hook = PXC200_muxsel, |
1394 | .audio_inputs = 1, | 802 | |
1395 | .tuner = 0, | 803 | }, |
1396 | .svhs = 2, | 804 | [BTTV_BOARD_FLYVIDEO_98] = { |
1397 | .gpiomask = 0x3f, | 805 | .name = "Lifeview FlyVideo 98 LR50", |
1398 | .muxsel = { 2, 3, 1, 1 }, | 806 | .video_inputs = 4, |
1399 | .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 }, | 807 | .audio_inputs = 1, |
1400 | .needs_tvaudio = 1, | 808 | .tuner = 0, |
1401 | .no_msp34xx = 1, | 809 | .svhs = 2, |
1402 | .no_tda9875 = 1, | 810 | .gpiomask = 0x1800, /* 0x8dfe00 */ |
1403 | .pll = PLL_28, | 811 | .muxsel = { 2, 3, 1, 1}, |
1404 | .tuner_type = 5, | 812 | .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 }, |
1405 | .tuner_addr = ADDR_UNSET, | 813 | .pll = PLL_28, |
1406 | .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */ | 814 | .tuner_type = -1, |
1407 | .has_radio = 1, /* Note: not all cards have radio */ | 815 | .tuner_addr = ADDR_UNSET, |
1408 | .has_remote = 1, | 816 | .radio_addr = ADDR_UNSET, |
1409 | /* GPIO wiring: | 817 | }, |
1410 | GPIO0: A0 hef4052 | 818 | [BTTV_BOARD_IPROTV] = { |
1411 | GPIO1: A1 hef4052 | 819 | .name = "Formac iProTV, Formac ProTV I (bt848)", |
1412 | GPIO3: nEN hef4052 | 820 | .video_inputs = 4, |
1413 | GPIO8-15: vrd866b | 821 | .audio_inputs = 1, |
1414 | GPIO20,22,23: R30,R29,R28 | 822 | .tuner = 0, |
1415 | */ | 823 | .svhs = 3, |
1416 | },{ | 824 | .gpiomask = 1, |
1417 | /* Clay Kunz <ckunz@mail.arc.nasa.gov> */ | 825 | .muxsel = { 2, 3, 1, 1}, |
1418 | /* you must jumper JP5 for the card to work */ | 826 | .audiomux = { 1, 0, 0, 0, 0 }, |
1419 | .name = "Sensoray 311", | 827 | .pll = PLL_28, |
1420 | .video_inputs = 5, | 828 | .tuner_type = TUNER_PHILIPS_PAL, |
1421 | .audio_inputs = 0, | 829 | .tuner_addr = ADDR_UNSET, |
1422 | .tuner = -1, | 830 | .radio_addr = ADDR_UNSET, |
1423 | .svhs = 4, | 831 | }, |
1424 | .gpiomask = 0, | 832 | |
1425 | .muxsel = { 2, 3, 1, 0, 0}, | 833 | /* ---- card 0x20 ---------------------------------- */ |
1426 | .audiomux = { 0 }, | 834 | [BTTV_BOARD_INTEL_C_S_PCI] = { |
1427 | .needs_tvaudio = 0, | 835 | .name = "Intel Create and Share PCI/ Smart Video Recorder III", |
1428 | .tuner_type = -1, | 836 | .video_inputs = 4, |
1429 | .tuner_addr = ADDR_UNSET, | 837 | .audio_inputs = 0, |
1430 | },{ | 838 | .tuner = -1, |
1431 | /* Miguel Freitas <miguel@cetuc.puc-rio.br> */ | 839 | .svhs = 2, |
1432 | .name = "RemoteVision MX (RV605)", | 840 | .gpiomask = 0, |
1433 | .video_inputs = 16, | 841 | .muxsel = { 2, 3, 1, 1}, |
1434 | .audio_inputs = 0, | 842 | .audiomux = { 0 }, |
1435 | .tuner = -1, | 843 | .needs_tvaudio = 0, |
1436 | .svhs = -1, | 844 | .tuner_type = 4, |
1437 | .gpiomask = 0x00, | 845 | .tuner_addr = ADDR_UNSET, |
1438 | .gpiomask2 = 0x07ff, | 846 | .radio_addr = ADDR_UNSET, |
1439 | .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, | 847 | }, |
1440 | 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 }, | 848 | [BTTV_BOARD_TERRATVALUE] = { |
1441 | .no_msp34xx = 1, | 849 | .name = "Terratec TerraTValue Version Bt878", |
1442 | .no_tda9875 = 1, | 850 | .video_inputs = 3, |
1443 | .tuner_type = -1, | 851 | .audio_inputs = 1, |
1444 | .tuner_addr = ADDR_UNSET, | 852 | .tuner = 0, |
1445 | .muxsel_hook = rv605_muxsel, | 853 | .svhs = 2, |
1446 | },{ | 854 | .gpiomask = 0xffff00, |
1447 | .name = "Powercolor MTV878/ MTV878R/ MTV878F", | 855 | .muxsel = { 2, 3, 1, 1}, |
1448 | .video_inputs = 3, | 856 | .audiomux = { 0x500, 0, 0x300, 0x900, 0x900}, |
1449 | .audio_inputs = 2, | 857 | .needs_tvaudio = 1, |
1450 | .tuner = 0, | 858 | .pll = PLL_28, |
1451 | .svhs = 2, | 859 | .tuner_type = TUNER_PHILIPS_PAL, |
1452 | .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */ | 860 | .tuner_addr = ADDR_UNSET, |
1453 | .muxsel = { 2, 1, 1, }, | 861 | .radio_addr = ADDR_UNSET, |
1454 | .audiomux = { 0, 1, 2, 2, 4 }, | 862 | }, |
1455 | .needs_tvaudio = 0, | 863 | [BTTV_BOARD_WINFAST2000] = { |
1456 | .tuner_type = TUNER_PHILIPS_PAL, | 864 | .name = "Leadtek WinFast 2000/ WinFast 2000 XP", |
1457 | .tuner_addr = ADDR_UNSET, | 865 | .video_inputs = 4, |
1458 | .pll = PLL_28, | 866 | .audio_inputs = 1, |
1459 | .has_radio = 1, | 867 | .tuner = 0, |
1460 | },{ | 868 | .svhs = 2, |
1461 | 869 | .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */ | |
1462 | /* ---- card 0x4c ---------------------------------- */ | 870 | #if 0 |
1463 | /* Masaki Suzuki <masaki@btree.org> */ | 871 | .gpiomask = 0xc33000, |
1464 | .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)", | 872 | .audiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000 }, |
1465 | .video_inputs = 3, | 873 | #else |
1466 | .audio_inputs = 1, | 874 | /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */ |
1467 | .tuner = 0, | 875 | .gpiomask = 0xb33000, |
1468 | .svhs = 2, | 876 | .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 }, |
1469 | .gpiomask = 0x140007, | 877 | #endif |
1470 | .muxsel = { 2, 3, 1, 1 }, | 878 | /* Audio Routing for "WinFast 2000 XP" (no tv stereo !) |
1471 | .audiomux = { 0, 1, 2, 3, 4, 0 }, | 879 | gpio23 -- hef4052:nEnable (0x800000) |
1472 | .tuner_type = TUNER_PHILIPS_NTSC, | 880 | gpio12 -- hef4052:A1 |
1473 | .tuner_addr = ADDR_UNSET, | 881 | gpio13 -- hef4052:A0 |
1474 | .audio_hook = windvr_audio, | 882 | 0x0000: external audio |
1475 | },{ | 883 | 0x1000: FM |
1476 | .name = "GrandTec Multi Capture Card (Bt878)", | 884 | 0x2000: TV |
1477 | .video_inputs = 4, | 885 | 0x3000: n.c. |
1478 | .audio_inputs = 0, | 886 | Note: There exists another variant "Winfast 2000" with tv stereo !? |
1479 | .tuner = -1, | 887 | Note: eeprom only contains FF and pci subsystem id 107d:6606 |
1480 | .svhs = -1, | 888 | */ |
1481 | .gpiomask = 0, | 889 | .needs_tvaudio = 0, |
1482 | .muxsel = { 2, 3, 1, 0 }, | 890 | .pll = PLL_28, |
1483 | .audiomux = { 0 }, | 891 | .has_radio = 1, |
1484 | .needs_tvaudio = 0, | 892 | .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */ |
1485 | .no_msp34xx = 1, | 893 | .tuner_addr = ADDR_UNSET, |
1486 | .pll = PLL_28, | 894 | .radio_addr = ADDR_UNSET, |
1487 | .tuner_type = -1, | 895 | .audio_hook = winfast2000_audio, |
1488 | .tuner_addr = ADDR_UNSET, | 896 | .has_remote = 1, |
1489 | },{ | 897 | }, |
1490 | .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", | 898 | [BTTV_BOARD_CHRONOS_VS2] = { |
1491 | .video_inputs = 4, | 899 | .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II", |
1492 | .audio_inputs = 3, | 900 | .video_inputs = 4, |
1493 | .tuner = 0, | 901 | .audio_inputs = 3, |
1494 | .svhs = 2, | 902 | .tuner = 0, |
1495 | .gpiomask = 7, | 903 | .svhs = 2, |
1496 | .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */ | 904 | .gpiomask = 0x1800, |
1497 | .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio! | 905 | .muxsel = { 2, 3, 1, 1}, |
1498 | * This card lacks external Audio In, so we mute it on Ext. & Int. | 906 | .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, |
1499 | * The PCB can take a sbx1637/sbx1673, wiring unknown. | 907 | .pll = PLL_28, |
1500 | * This card lacks PCI subsystem ID, sigh. | 908 | .tuner_type = -1, |
1501 | * audiomux=1: lower volume, 2+3: mute | 909 | .tuner_addr = ADDR_UNSET, |
1502 | * btwincap uses 0x80000/0x80003 | 910 | .radio_addr = ADDR_UNSET, |
1503 | */ | 911 | }, |
1504 | .needs_tvaudio = 0, | 912 | |
1505 | .no_msp34xx = 1, | 913 | /* ---- card 0x24 ---------------------------------- */ |
1506 | .pll = PLL_28, | 914 | [BTTV_BOARD_TYPHOON_TVIEW] = { |
1507 | .tuner_type = 5, | 915 | .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner", |
1508 | .tuner_addr = ADDR_UNSET, | 916 | .video_inputs = 4, |
1509 | /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and | 917 | .audio_inputs = 3, |
1510 | radio signal strength indicators work fine. */ | 918 | .tuner = 0, |
1511 | .has_radio = 1, | 919 | .svhs = 2, |
1512 | /* GPIO Info: | 920 | .gpiomask = 0x1800, |
1513 | GPIO0,1: HEF4052 A0,A1 | 921 | .muxsel = { 2, 3, 1, 1}, |
1514 | GPIO2: HEF4052 nENABLE | 922 | .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 }, |
1515 | GPIO3-7: n.c. | 923 | .pll = PLL_28, |
1516 | GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card] | 924 | .tuner_type = -1, |
1517 | GPIO14,15: ?? | 925 | .tuner_addr = ADDR_UNSET, |
1518 | GPIO16-21: n.c. | 926 | .radio_addr = ADDR_UNSET, |
1519 | GPIO22,23: ?? | 927 | .has_radio = 1, |
1520 | ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/ | 928 | }, |
1521 | },{ | 929 | [BTTV_BOARD_PXELVWPLTVPRO] = { |
1522 | /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */ | 930 | .name = "Prolink PixelView PlayTV pro", |
1523 | .name = "DSP Design TCVIDEO", | 931 | .video_inputs = 3, |
1524 | .video_inputs = 4, | 932 | .audio_inputs = 1, |
1525 | .svhs = -1, | 933 | .tuner = 0, |
1526 | .muxsel = { 2, 3, 1, 0}, | 934 | .svhs = 2, |
1527 | .pll = PLL_28, | 935 | .gpiomask = 0xff, |
1528 | .tuner_type = -1, | 936 | .muxsel = { 2, 3, 1, 1 }, |
1529 | .tuner_addr = ADDR_UNSET, | 937 | .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 }, |
1530 | },{ | 938 | .no_msp34xx = 1, |
1531 | 939 | .pll = PLL_28, | |
1532 | /* ---- card 0x50 ---------------------------------- */ | 940 | .tuner_type = -1, |
1533 | .name = "Hauppauge WinTV PVR", | 941 | .tuner_addr = ADDR_UNSET, |
1534 | .video_inputs = 4, | 942 | .radio_addr = ADDR_UNSET, |
1535 | .audio_inputs = 1, | 943 | }, |
1536 | .tuner = 0, | 944 | [BTTV_BOARD_MAGICTVIEW063] = { |
1537 | .svhs = 2, | 945 | .name = "Askey CPH06X TView99", |
1538 | .muxsel = { 2, 0, 1, 1}, | 946 | .video_inputs = 4, |
1539 | .needs_tvaudio = 1, | 947 | .audio_inputs = 1, |
1540 | .pll = PLL_28, | 948 | .tuner = 0, |
1541 | .tuner_type = -1, | 949 | .svhs = 2, |
1542 | .tuner_addr = ADDR_UNSET, | 950 | .gpiomask = 0x551e00, |
1543 | 951 | .muxsel = { 2, 3, 1, 0}, | |
1544 | .gpiomask = 7, | 952 | .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 }, |
1545 | .audiomux = {7}, | 953 | .needs_tvaudio = 1, |
1546 | },{ | 954 | .pll = PLL_28, |
1547 | .name = "IODATA GV-BCTV5/PCI", | 955 | .tuner_type = 1, |
1548 | .video_inputs = 3, | 956 | .tuner_addr = ADDR_UNSET, |
1549 | .audio_inputs = 1, | 957 | .radio_addr = ADDR_UNSET, |
1550 | .tuner = 0, | 958 | .has_remote = 1, |
1551 | .svhs = 2, | 959 | }, |
1552 | .gpiomask = 0x0f0f80, | 960 | [BTTV_BOARD_PINNACLE] = { |
1553 | .muxsel = {2, 3, 1, 0}, | 961 | .name = "Pinnacle PCTV Studio/Rave", |
1554 | .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0}, | 962 | .video_inputs = 3, |
1555 | .no_msp34xx = 1, | 963 | .audio_inputs = 1, |
1556 | .pll = PLL_28, | 964 | .tuner = 0, |
1557 | .tuner_type = TUNER_PHILIPS_NTSC_M, | 965 | .svhs = 2, |
1558 | .tuner_addr = ADDR_UNSET, | 966 | .gpiomask = 0x03000F, |
1559 | .audio_hook = gvbctv5pci_audio, | 967 | .muxsel = { 2, 3, 1, 1}, |
1560 | .has_radio = 1, | 968 | .audiomux = { 2, 0xd0001, 0, 0, 1}, |
1561 | },{ | 969 | .needs_tvaudio = 0, |
1562 | .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ | 970 | .pll = PLL_28, |
1563 | .video_inputs = 4, /* id-inputs-clock */ | 971 | .tuner_type = -1, |
1564 | .audio_inputs = 0, | 972 | .tuner_addr = ADDR_UNSET, |
1565 | .tuner = -1, | 973 | .radio_addr = ADDR_UNSET, |
1566 | .svhs = 3, | 974 | }, |
1567 | .muxsel = { 3, 2, 0, 1 }, | 975 | |
1568 | .pll = PLL_28, | 976 | /* ---- card 0x28 ---------------------------------- */ |
1569 | .tuner_type = -1, | 977 | [BTTV_BOARD_STB2] = { |
1570 | .tuner_addr = ADDR_UNSET, | 978 | .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100", |
1571 | .no_msp34xx = 1, | 979 | .video_inputs = 3, |
1572 | .no_tda9875 = 1, | 980 | .audio_inputs = 1, |
1573 | .no_tda7432 = 1, | 981 | .tuner = 0, |
1574 | },{ | 982 | .svhs = 2, |
1575 | .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ | 983 | .gpiomask = 7, |
1576 | .video_inputs = 3, | 984 | .muxsel = { 2, 3, 1, 1}, |
1577 | .audio_inputs = 0, | 985 | .audiomux = { 4, 0, 2, 3, 1}, |
1578 | .tuner = -1, | 986 | .no_msp34xx = 1, |
1579 | .svhs = 2, | 987 | .needs_tvaudio = 1, |
1580 | .muxsel = { 2, 3, 1 }, | 988 | .tuner_type = TUNER_PHILIPS_NTSC, |
1581 | .pll = PLL_28, | 989 | .tuner_addr = ADDR_UNSET, |
1582 | .tuner_type = -1, | 990 | .radio_addr = ADDR_UNSET, |
1583 | .tuner_addr = ADDR_UNSET, | 991 | .pll = PLL_28, |
1584 | .no_msp34xx = 1, | 992 | .has_radio = 1, |
1585 | .no_tda9875 = 1, | 993 | }, |
1586 | .no_tda7432 = 1, | 994 | [BTTV_BOARD_AVPHONE98] = { |
1587 | },{ | 995 | .name = "AVerMedia TVPhone 98", |
1588 | 996 | .video_inputs = 3, | |
1589 | /* ---- card 0x54 ---------------------------------- */ | 997 | .audio_inputs = 4, |
1590 | .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */ | 998 | .tuner = 0, |
1591 | .video_inputs = 2, | 999 | .svhs = 2, |
1592 | .audio_inputs = 0, | 1000 | .gpiomask = 15, |
1593 | .tuner = -1, | 1001 | .muxsel = { 2, 3, 1, 1}, |
1594 | .svhs = 1, | 1002 | .audiomux = { 13, 4, 11, 7, 0, 0}, |
1595 | .muxsel = { 3, 1 }, | 1003 | .needs_tvaudio = 1, |
1596 | .pll = PLL_28, | 1004 | .pll = PLL_28, |
1597 | .tuner_type = -1, | 1005 | .tuner_type = -1, |
1598 | .tuner_addr = ADDR_UNSET, | 1006 | .tuner_addr = ADDR_UNSET, |
1599 | .no_msp34xx = 1, | 1007 | .radio_addr = ADDR_UNSET, |
1600 | .no_tda9875 = 1, | 1008 | .has_radio = 1, |
1601 | .no_tda7432 = 1, | 1009 | .audio_hook = avermedia_tvphone_audio, |
1602 | },{ | 1010 | }, |
1603 | .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ | 1011 | [BTTV_BOARD_PV951] = { |
1604 | .video_inputs = 1, | 1012 | .name = "ProVideo PV951", /* pic16c54 */ |
1605 | .audio_inputs = 0, | 1013 | .video_inputs = 3, |
1606 | .tuner = -1, | 1014 | .audio_inputs = 1, |
1607 | .svhs = -1, | 1015 | .tuner = 0, |
1608 | .muxsel = { 0 }, | 1016 | .svhs = 2, |
1609 | .pll = PLL_28, | 1017 | .gpiomask = 0, |
1610 | .tuner_type = -1, | 1018 | .muxsel = { 2, 3, 1, 1}, |
1611 | .tuner_addr = ADDR_UNSET, | 1019 | .audiomux = { 0, 0, 0, 0, 0}, |
1612 | .no_msp34xx = 1, | 1020 | .needs_tvaudio = 1, |
1613 | .no_tda9875 = 1, | 1021 | .no_msp34xx = 1, |
1614 | .no_tda7432 = 1, | 1022 | .pll = PLL_28, |
1615 | },{ | 1023 | .tuner_type = 1, |
1616 | .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ | 1024 | .tuner_addr = ADDR_UNSET, |
1617 | .video_inputs = 2, | 1025 | .radio_addr = ADDR_UNSET, |
1618 | .audio_inputs = 0, | 1026 | }, |
1619 | .tuner = -1, | 1027 | [BTTV_BOARD_ONAIR_TV] = { |
1620 | .svhs = 1, | 1028 | .name = "Little OnAir TV", |
1621 | .muxsel = { 0, 1 }, | 1029 | .video_inputs = 3, |
1622 | .pll = PLL_28, | 1030 | .audio_inputs = 1, |
1623 | .tuner_type = -1, | 1031 | .tuner = 0, |
1624 | .tuner_addr = ADDR_UNSET, | 1032 | .svhs = 2, |
1625 | .no_msp34xx = 1, | 1033 | .gpiomask = 0xe00b, |
1626 | .no_tda9875 = 1, | 1034 | .muxsel = {2, 3, 1, 1}, |
1627 | .no_tda7432 = 1, | 1035 | .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc}, |
1628 | },{ | 1036 | .no_msp34xx = 1, |
1629 | .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ | 1037 | .tuner_type = -1, |
1630 | .video_inputs = 1, | 1038 | .tuner_addr = ADDR_UNSET, |
1631 | .audio_inputs = 1, | 1039 | .radio_addr = ADDR_UNSET, |
1632 | .tuner = -1, | 1040 | }, |
1633 | .svhs = -1, | 1041 | |
1634 | .muxsel = { 0 }, | 1042 | /* ---- card 0x2c ---------------------------------- */ |
1635 | .pll = PLL_28, | 1043 | [BTTV_BOARD_SIGMA_TVII_FM] = { |
1636 | .tuner_type = UNSET, | 1044 | .name = "Sigma TVII-FM", |
1637 | .tuner_addr = ADDR_UNSET, | 1045 | .video_inputs = 2, |
1638 | .no_msp34xx = 1, | 1046 | .audio_inputs = 1, |
1639 | .no_tda9875 = 1, | 1047 | .tuner = 0, |
1640 | .no_tda7432 = 1, | 1048 | .svhs = -1, |
1641 | },{ | 1049 | .gpiomask = 3, |
1642 | 1050 | .muxsel = {2, 3, 1, 1}, | |
1643 | /* ---- card 0x58 ---------------------------------- */ | 1051 | .audiomux = {1, 1, 0, 2, 3}, |
1644 | .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ | 1052 | .no_msp34xx = 1, |
1645 | .video_inputs = 2, | 1053 | .pll = PLL_NONE, |
1646 | .audio_inputs = 1, | 1054 | .tuner_type = -1, |
1647 | .tuner = -1, | 1055 | .tuner_addr = ADDR_UNSET, |
1648 | .svhs = 1, | 1056 | .radio_addr = ADDR_UNSET, |
1649 | .muxsel = { 0, 1 }, | 1057 | }, |
1650 | .pll = PLL_28, | 1058 | [BTTV_BOARD_MATRIX_VISION2] = { |
1651 | .tuner_type = UNSET, | 1059 | .name = "MATRIX-Vision MV-Delta 2", |
1652 | .tuner_addr = ADDR_UNSET, | 1060 | .video_inputs = 5, |
1653 | .no_msp34xx = 1, | 1061 | .audio_inputs = 1, |
1654 | .no_tda9875 = 1, | 1062 | .tuner = -1, |
1655 | .no_tda7432 = 1, | 1063 | .svhs = 3, |
1656 | },{ | 1064 | .gpiomask = 0, |
1657 | .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */ | 1065 | .muxsel = { 2, 3, 1, 0, 0}, |
1658 | .video_inputs = 2, | 1066 | .audiomux = {0 }, |
1659 | .audio_inputs = 1, | 1067 | .no_msp34xx = 1, |
1660 | .tuner = -1, | 1068 | .pll = PLL_28, |
1661 | .svhs = 1, | 1069 | .tuner_type = -1, |
1662 | .muxsel = { 2, 3 }, | 1070 | .tuner_addr = ADDR_UNSET, |
1663 | .pll = PLL_28, | 1071 | .radio_addr = ADDR_UNSET, |
1664 | .tuner_type = UNSET, | 1072 | }, |
1665 | .tuner_addr = ADDR_UNSET, | 1073 | [BTTV_BOARD_ZOLTRIX_GENIE] = { |
1666 | .no_msp34xx = 1, | 1074 | .name = "Zoltrix Genie TV/FM", |
1667 | .no_tda9875 = 1, | 1075 | .video_inputs = 3, |
1668 | .no_tda7432 = 1, | 1076 | .audio_inputs = 1, |
1669 | },{ | 1077 | .tuner = 0, |
1670 | .name = "Osprey 500", /* 500 */ | 1078 | .svhs = 2, |
1671 | .video_inputs = 2, | 1079 | .gpiomask = 0xbcf03f, |
1672 | .audio_inputs = 1, | 1080 | .muxsel = { 2, 3, 1, 1}, |
1673 | .tuner = -1, | 1081 | .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f}, |
1674 | .svhs = 1, | 1082 | .no_msp34xx = 1, |
1675 | .muxsel = { 2, 3 }, | 1083 | .pll = PLL_28, |
1676 | .pll = PLL_28, | 1084 | .tuner_type = 21, |
1677 | .tuner_type = -1, | 1085 | .tuner_addr = ADDR_UNSET, |
1678 | .tuner_addr = ADDR_UNSET, | 1086 | .radio_addr = ADDR_UNSET, |
1679 | .no_msp34xx = 1, | 1087 | }, |
1680 | .no_tda9875 = 1, | 1088 | [BTTV_BOARD_TERRATVRADIO] = { |
1681 | .no_tda7432 = 1, | 1089 | .name = "Terratec TV/Radio+", |
1682 | },{ | 1090 | .video_inputs = 3, |
1683 | .name = "Osprey 540", /* 540 */ | 1091 | .audio_inputs = 1, |
1684 | .video_inputs = 4, | 1092 | .tuner = 0, |
1685 | .audio_inputs = 1, | 1093 | .svhs = 2, |
1686 | .tuner = -1, | 1094 | .gpiomask = 0x70000, |
1687 | .pll = PLL_28, | 1095 | .muxsel = { 2, 3, 1, 1}, |
1688 | .tuner_type = -1, | 1096 | .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 }, |
1689 | .tuner_addr = ADDR_UNSET, | 1097 | .needs_tvaudio = 1, |
1690 | .no_msp34xx = 1, | 1098 | .no_msp34xx = 1, |
1691 | .no_tda9875 = 1, | 1099 | .pll = PLL_35, |
1692 | .no_tda7432 = 1, | 1100 | .tuner_type = 1, |
1693 | },{ | 1101 | .tuner_addr = ADDR_UNSET, |
1694 | 1102 | .radio_addr = ADDR_UNSET, | |
1695 | /* ---- card 0x5C ---------------------------------- */ | 1103 | .has_radio = 1, |
1696 | .name = "Osprey 2000", /* 2000 */ | 1104 | }, |
1697 | .video_inputs = 2, | 1105 | |
1698 | .audio_inputs = 1, | 1106 | /* ---- card 0x30 ---------------------------------- */ |
1699 | .tuner = -1, | 1107 | [BTTV_BOARD_DYNALINK] = { |
1700 | .svhs = 1, | 1108 | .name = "Askey CPH03x/ Dynalink Magic TView", |
1701 | .muxsel = { 2, 3 }, | 1109 | .video_inputs = 3, |
1702 | .pll = PLL_28, | 1110 | .audio_inputs = 1, |
1703 | .tuner_type = UNSET, | 1111 | .tuner = 0, |
1704 | .tuner_addr = ADDR_UNSET, | 1112 | .svhs = 2, |
1705 | .no_msp34xx = 1, | 1113 | .gpiomask = 15, |
1706 | .no_tda9875 = 1, | 1114 | .muxsel = { 2, 3, 1, 1}, |
1707 | .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */ | 1115 | .audiomux = {2,0,0,0,1}, |
1708 | },{ | 1116 | .needs_tvaudio = 1, |
1709 | /* M G Berberich <berberic@forwiss.uni-passau.de> */ | 1117 | .pll = PLL_28, |
1710 | .name = "IDS Eagle", | 1118 | .tuner_type = -1, |
1711 | .video_inputs = 4, | 1119 | .tuner_addr = ADDR_UNSET, |
1712 | .audio_inputs = 0, | 1120 | .radio_addr = ADDR_UNSET, |
1713 | .tuner = -1, | 1121 | }, |
1714 | .tuner_type = -1, | 1122 | [BTTV_BOARD_GVBCTV3PCI] = { |
1715 | .tuner_addr = ADDR_UNSET, | 1123 | .name = "IODATA GV-BCTV3/PCI", |
1716 | .svhs = -1, | 1124 | .video_inputs = 3, |
1717 | .gpiomask = 0, | 1125 | .audio_inputs = 1, |
1718 | .muxsel = { 0, 1, 2, 3 }, | 1126 | .tuner = 0, |
1719 | .muxsel_hook = eagle_muxsel, | 1127 | .svhs = 2, |
1720 | .no_msp34xx = 1, | 1128 | .gpiomask = 0x010f00, |
1721 | .no_tda9875 = 1, | 1129 | .muxsel = {2, 3, 0, 0}, |
1722 | .pll = PLL_28, | 1130 | .audiomux = {0x10000, 0, 0x10000, 0, 0, 0}, |
1723 | },{ | 1131 | .no_msp34xx = 1, |
1724 | .name = "Pinnacle PCTV Sat", | 1132 | .pll = PLL_28, |
1725 | .video_inputs = 2, | 1133 | .tuner_type = TUNER_ALPS_TSHC6_NTSC, |
1726 | .audio_inputs = 0, | 1134 | .tuner_addr = ADDR_UNSET, |
1727 | .svhs = 1, | 1135 | .radio_addr = ADDR_UNSET, |
1728 | .tuner = -1, | 1136 | .audio_hook = gvbctv3pci_audio, |
1729 | .tuner_type = -1, | 1137 | }, |
1730 | .tuner_addr = ADDR_UNSET, | 1138 | [BTTV_BOARD_PXELVWPLTVPAK] = { |
1731 | .no_msp34xx = 1, | 1139 | .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP", |
1732 | .no_tda9875 = 1, | 1140 | .video_inputs = 5, |
1733 | .no_tda7432 = 1, | 1141 | .audio_inputs = 1, |
1734 | .gpiomask = 0x01, | 1142 | .tuner = 0, |
1735 | .audiomux = { 0, 0, 0, 0, 1 }, | 1143 | .svhs = 3, |
1736 | .muxsel = { 3, 0, 1, 2}, | 1144 | .gpiomask = 0xAA0000, |
1737 | .needs_tvaudio = 0, | 1145 | .muxsel = { 2,3,1,1,-1 }, |
1738 | .pll = PLL_28, | 1146 | .digital_mode = DIGITAL_MODE_CAMERA, |
1739 | .no_gpioirq = 1, | 1147 | .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 }, |
1740 | .has_dvb = 1, | 1148 | .no_msp34xx = 1, |
1741 | },{ | 1149 | .pll = PLL_28, |
1742 | .name = "Formac ProTV II (bt878)", | 1150 | .tuner_type = TUNER_PHILIPS_PAL_I, |
1743 | .video_inputs = 4, | 1151 | .tuner_addr = ADDR_UNSET, |
1744 | .audio_inputs = 1, | 1152 | .radio_addr = ADDR_UNSET, |
1745 | .tuner = 0, | 1153 | .has_remote = 1, |
1746 | .svhs = 3, | 1154 | /* GPIO wiring: (different from Rev.4C !) |
1747 | .gpiomask = 2, | 1155 | GPIO17: U4.A0 (first hef4052bt) |
1748 | /* TV, Comp1, Composite over SVID con, SVID */ | 1156 | GPIO19: U4.A1 |
1749 | .muxsel = { 2, 3, 1, 1}, | 1157 | GPIO20: U5.A1 (second hef4052bt) |
1750 | .audiomux = { 2, 2, 0, 0, 0 }, | 1158 | GPIO21: U4.nEN |
1751 | .pll = PLL_28, | 1159 | GPIO22: BT832 Reset Line |
1752 | .has_radio = 1, | 1160 | GPIO23: A5,A0, U5,nEN |
1753 | .tuner_type = TUNER_PHILIPS_PAL, | 1161 | Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22 |
1754 | .tuner_addr = ADDR_UNSET, | 1162 | */ |
1755 | /* sound routing: | 1163 | }, |
1756 | GPIO=0x00,0x01,0x03: mute (?) | 1164 | [BTTV_BOARD_EAGLE] = { |
1757 | 0x02: both TV and radio (tuner: FM1216/I) | 1165 | .name = "Eagle Wireless Capricorn2 (bt878A)", |
1758 | The card has onboard audio connectors labeled "cdrom" and "board", | 1166 | .video_inputs = 4, |
1759 | not soldered here, though unknown wiring. | 1167 | .audio_inputs = 1, |
1760 | Card lacks: external audio in, pci subsystem id. | 1168 | .tuner = 0, |
1761 | */ | 1169 | .svhs = 2, |
1762 | },{ | 1170 | .gpiomask = 7, |
1763 | 1171 | .muxsel = { 2, 0, 1, 1}, | |
1764 | /* ---- card 0x60 ---------------------------------- */ | 1172 | .audiomux = { 0, 1, 2, 3, 4}, |
1765 | .name = "MachTV", | 1173 | .pll = PLL_28, |
1766 | .video_inputs = 3, | 1174 | .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */, |
1767 | .audio_inputs = 1, | 1175 | .tuner_addr = ADDR_UNSET, |
1768 | .tuner = 0, | 1176 | .radio_addr = ADDR_UNSET, |
1769 | .svhs = -1, | 1177 | }, |
1770 | .gpiomask = 7, | 1178 | |
1771 | .muxsel = { 2, 3, 1, 1}, | 1179 | /* ---- card 0x34 ---------------------------------- */ |
1772 | .audiomux = { 0, 1, 2, 3, 4}, | 1180 | [BTTV_BOARD_PINNACLEPRO] = { |
1773 | .needs_tvaudio = 1, | 1181 | /* David Härdeman <david@2gen.com> */ |
1774 | .tuner_type = 5, | 1182 | .name = "Pinnacle PCTV Studio Pro", |
1775 | .tuner_addr = ADDR_UNSET, | 1183 | .video_inputs = 4, |
1776 | .pll = 1, | 1184 | .audio_inputs = 1, |
1777 | },{ | 1185 | .tuner = 0, |
1778 | .name = "Euresys Picolo", | 1186 | .svhs = 3, |
1779 | .video_inputs = 3, | 1187 | .gpiomask = 0x03000F, |
1780 | .audio_inputs = 0, | 1188 | .muxsel = { 2, 3, 1, 1}, |
1781 | .tuner = -1, | 1189 | .audiomux = { 1, 0xd0001, 0, 0, 10}, |
1782 | .svhs = 2, | 1190 | /* sound path (5 sources): |
1783 | .gpiomask = 0, | 1191 | MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable) |
1784 | .no_msp34xx = 1, | 1192 | 0= ext. Audio IN |
1785 | .no_tda9875 = 1, | 1193 | 1= from MUX2 |
1786 | .no_tda7432 = 1, | 1194 | 2= Mono TV sound from Tuner |
1787 | .muxsel = { 2, 0, 1}, | 1195 | 3= not connected |
1788 | .pll = PLL_28, | 1196 | MUX2 (mask 0x30000): |
1789 | .tuner_type = UNSET, | 1197 | 0,2,3= from MSP34xx |
1790 | .tuner_addr = ADDR_UNSET, | 1198 | 1= FM stereo Radio from Tuner */ |
1791 | },{ | 1199 | .needs_tvaudio = 0, |
1792 | /* Luc Van Hoeylandt <luc@e-magic.be> */ | 1200 | .pll = PLL_28, |
1793 | .name = "ProVideo PV150", /* 0x4f */ | 1201 | .tuner_type = -1, |
1794 | .video_inputs = 2, | 1202 | .tuner_addr = ADDR_UNSET, |
1795 | .audio_inputs = 0, | 1203 | .radio_addr = ADDR_UNSET, |
1796 | .tuner = -1, | 1204 | }, |
1797 | .svhs = -1, | 1205 | [BTTV_BOARD_TVIEW_RDS_FM] = { |
1798 | .gpiomask = 0, | 1206 | /* Claas Langbehn <claas@bigfoot.com>, |
1799 | .muxsel = { 2, 3 }, | 1207 | Sven Grothklags <sven@upb.de> */ |
1800 | .audiomux = { 0 }, | 1208 | .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS", |
1801 | .needs_tvaudio = 0, | 1209 | .video_inputs = 4, |
1802 | .no_msp34xx = 1, | 1210 | .audio_inputs = 3, |
1803 | .pll = PLL_28, | 1211 | .tuner = 0, |
1804 | .tuner_type = UNSET, | 1212 | .svhs = 2, |
1805 | .tuner_addr = ADDR_UNSET, | 1213 | .gpiomask = 0x1c, |
1806 | },{ | 1214 | .muxsel = { 2, 3, 1, 1}, |
1807 | /* Hiroshi Takekawa <sian@big.or.jp> */ | 1215 | .audiomux = { 0, 0, 0x10, 8, 4 }, |
1808 | /* This card lacks subsystem ID */ | 1216 | .needs_tvaudio = 1, |
1809 | .name = "AD-TVK503", /* 0x63 */ | 1217 | .pll = PLL_28, |
1810 | .video_inputs = 4, | 1218 | .tuner_type = TUNER_PHILIPS_PAL, |
1811 | .audio_inputs = 1, | 1219 | .tuner_addr = ADDR_UNSET, |
1812 | .tuner = 0, | 1220 | .radio_addr = ADDR_UNSET, |
1813 | .svhs = 2, | 1221 | .has_radio = 1, |
1814 | .gpiomask = 0x001e8007, | 1222 | }, |
1815 | .muxsel = { 2, 3, 1, 0 }, | 1223 | [BTTV_BOARD_LIFETEC_9415] = { |
1816 | /* Tuner, Radio, external, internal, off, on */ | 1224 | /* Tim Röstermundt <rosterm@uni-muenster.de> |
1817 | .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 }, | 1225 | in de.comp.os.unix.linux.hardware: |
1818 | .needs_tvaudio = 0, | 1226 | options bttv card=0 pll=1 radio=1 gpiomask=0x18e0 |
1819 | .no_msp34xx = 1, | 1227 | audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff |
1820 | .pll = PLL_28, | 1228 | options tuner type=5 */ |
1821 | .tuner_type = 2, | 1229 | .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]", |
1822 | .tuner_addr = ADDR_UNSET, | 1230 | .video_inputs = 4, |
1823 | .audio_hook = adtvk503_audio, | 1231 | .audio_inputs = 1, |
1824 | },{ | 1232 | .tuner = 0, |
1825 | 1233 | .svhs = 2, | |
1826 | /* ---- card 0x64 ---------------------------------- */ | 1234 | .gpiomask = 0x18e0, |
1827 | .name = "Hercules Smart TV Stereo", | 1235 | .muxsel = { 2, 3, 1, 1}, |
1828 | .video_inputs = 4, | 1236 | .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 }, |
1829 | .audio_inputs = 1, | 1237 | /* For cards with tda9820/tda9821: |
1830 | .tuner = 0, | 1238 | 0x0000: Tuner normal stereo |
1831 | .svhs = 2, | 1239 | 0x0080: Tuner A2 SAP (second audio program = Zweikanalton) |
1832 | .gpiomask = 0x00, | 1240 | 0x0880: Tuner A2 stereo */ |
1833 | .muxsel = { 2, 3, 1, 1 }, | 1241 | .pll = PLL_28, |
1834 | .needs_tvaudio = 1, | 1242 | .tuner_type = -1, |
1835 | .no_msp34xx = 1, | 1243 | .tuner_addr = ADDR_UNSET, |
1836 | .pll = PLL_28, | 1244 | .radio_addr = ADDR_UNSET, |
1837 | .tuner_type = 5, | 1245 | }, |
1838 | .tuner_addr = ADDR_UNSET, | 1246 | [BTTV_BOARD_BESTBUY_EASYTV] = { |
1839 | /* Notes: | 1247 | /* Miguel Angel Alvarez <maacruz@navegalia.com> |
1840 | - card lacks subsystem ID | 1248 | old Easy TV BT848 version (model CPH031) */ |
1841 | - stereo variant w/ daughter board with tda9874a @0xb0 | 1249 | .name = "Askey CPH031/ BESTBUY Easy TV", |
1842 | - Audio Routing: | 1250 | .video_inputs = 4, |
1843 | always from tda9874 independent of GPIO (?) | 1251 | .audio_inputs = 1, |
1844 | external line in: unknown | 1252 | .tuner = 0, |
1845 | - Other chips: em78p156elp @ 0x96 (probably IR remote control) | 1253 | .svhs = 2, |
1846 | hef4053 (instead 4052) for unknown function | 1254 | .gpiomask = 0xF, |
1847 | */ | 1255 | .muxsel = { 2, 3, 1, 0}, |
1848 | },{ | 1256 | .audiomux = { 2, 0, 0, 0, 10}, |
1849 | .name = "Pace TV & Radio Card", | 1257 | .needs_tvaudio = 0, |
1850 | .video_inputs = 4, | 1258 | .pll = PLL_28, |
1851 | .audio_inputs = 1, | 1259 | .tuner_type = TUNER_TEMIC_PAL, |
1852 | .tuner = 0, | 1260 | .tuner_addr = ADDR_UNSET, |
1853 | .svhs = 2, | 1261 | .radio_addr = ADDR_UNSET, |
1854 | .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */ | 1262 | }, |
1855 | .gpiomask = 0, | 1263 | |
1856 | .no_tda9875 = 1, | 1264 | /* ---- card 0x38 ---------------------------------- */ |
1857 | .no_tda7432 = 1, | 1265 | [BTTV_BOARD_FLYVIDEO_98FM] = { |
1858 | .tuner_type = 1, | 1266 | /* Gordon Heydon <gjheydon@bigfoot.com ('98) */ |
1859 | .tuner_addr = ADDR_UNSET, | 1267 | .name = "Lifeview FlyVideo 98FM LR50", |
1860 | .has_radio = 1, | 1268 | .video_inputs = 4, |
1861 | .pll = PLL_28, | 1269 | .audio_inputs = 3, |
1862 | /* Bt878, Bt832, FI1246 tuner; no pci subsystem id | 1270 | .tuner = 0, |
1863 | only internal line out: (4pin header) RGGL | 1271 | .svhs = 2, |
1864 | Radio must be decoded by msp3410d (not routed through)*/ | 1272 | .gpiomask = 0x1800, |
1865 | /* | 1273 | .muxsel = { 2, 3, 1, 1}, |
1866 | .digital_mode = DIGITAL_MODE_CAMERA, todo! | 1274 | .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 }, |
1867 | */ | 1275 | .pll = PLL_28, |
1868 | },{ | 1276 | .tuner_type = 5, |
1869 | /* Chris Willing <chris@vislab.usyd.edu.au> */ | 1277 | .tuner_addr = ADDR_UNSET, |
1870 | .name = "IVC-200", | 1278 | .radio_addr = ADDR_UNSET, |
1871 | .video_inputs = 1, | 1279 | }, |
1872 | .audio_inputs = 0, | 1280 | /* This is the ultimate cheapo capture card |
1873 | .tuner = -1, | 1281 | * just a BT848A on a small PCB! |
1874 | .tuner_type = -1, | 1282 | * Steve Hosgood <steve@equiinet.com> */ |
1875 | .tuner_addr = ADDR_UNSET, | 1283 | [BTTV_BOARD_GRANDTEC] = { |
1876 | .svhs = -1, | 1284 | .name = "GrandTec 'Grand Video Capture' (Bt848)", |
1877 | .gpiomask = 0xdf, | 1285 | .video_inputs = 2, |
1878 | .muxsel = { 2 }, | 1286 | .audio_inputs = 0, |
1879 | .pll = PLL_28, | 1287 | .tuner = -1, |
1880 | },{ | 1288 | .svhs = 1, |
1881 | .name = "Grand X-Guard / Trust 814PCI", | 1289 | .gpiomask = 0, |
1882 | .video_inputs = 16, | 1290 | .muxsel = { 3, 1 }, |
1883 | .audio_inputs = 0, | 1291 | .audiomux = { 0 }, |
1884 | .tuner = -1, | 1292 | .needs_tvaudio = 0, |
1885 | .svhs = -1, | 1293 | .no_msp34xx = 1, |
1886 | .tuner_type = 4, | 1294 | .pll = PLL_35, |
1887 | .tuner_addr = ADDR_UNSET, | 1295 | .tuner_type = -1, |
1888 | .gpiomask2 = 0xff, | 1296 | .tuner_addr = ADDR_UNSET, |
1889 | .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 }, | 1297 | .radio_addr = ADDR_UNSET, |
1890 | .muxsel_hook = xguard_muxsel, | 1298 | }, |
1891 | .no_msp34xx = 1, | 1299 | [BTTV_BOARD_ASKEY_CPH060] = { |
1892 | .no_tda9875 = 1, | 1300 | /* Daniel Herrington <daniel.herrington@home.com> */ |
1893 | .no_tda7432 = 1, | 1301 | .name = "Askey CPH060/ Phoebe TV Master Only (No FM)", |
1894 | .pll = PLL_28, | 1302 | .video_inputs = 3, |
1895 | },{ | 1303 | .audio_inputs = 1, |
1896 | 1304 | .tuner = 0, | |
1897 | /* ---- card 0x68 ---------------------------------- */ | 1305 | .svhs = 2, |
1898 | .name = "Nebula Electronics DigiTV", | 1306 | .gpiomask = 0xe00, |
1899 | .video_inputs = 1, | 1307 | .muxsel = { 2, 3, 1, 1}, |
1900 | .tuner = -1, | 1308 | .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 }, |
1901 | .svhs = -1, | 1309 | .needs_tvaudio = 1, |
1902 | .muxsel = { 2, 3, 1, 0}, | 1310 | .pll = PLL_28, |
1903 | .no_msp34xx = 1, | 1311 | .tuner_type = TUNER_TEMIC_4036FY5_NTSC, |
1904 | .no_tda9875 = 1, | 1312 | .tuner_addr = ADDR_UNSET, |
1905 | .no_tda7432 = 1, | 1313 | .radio_addr = ADDR_UNSET, |
1906 | .pll = PLL_28, | 1314 | }, |
1907 | .tuner_type = -1, | 1315 | [BTTV_BOARD_ASKEY_CPH03X] = { |
1908 | .tuner_addr = ADDR_UNSET, | 1316 | /* Matti Mottus <mottus@physic.ut.ee> */ |
1909 | .has_dvb = 1, | 1317 | .name = "Askey CPH03x TV Capturer", |
1910 | .no_gpioirq = 1, | 1318 | .video_inputs = 4, |
1911 | },{ | 1319 | .audio_inputs = 1, |
1912 | /* Jorge Boncompte - DTI2 <jorge@dti2.net> */ | 1320 | .tuner = 0, |
1913 | .name = "ProVideo PV143", | 1321 | .svhs = 2, |
1914 | .video_inputs = 4, | 1322 | .gpiomask = 0x03000F, |
1915 | .audio_inputs = 0, | 1323 | .muxsel = { 2, 3, 1, 0}, |
1916 | .tuner = -1, | 1324 | .audiomux = { 2,0,0,0,1 }, |
1917 | .svhs = -1, | 1325 | .pll = PLL_28, |
1918 | .gpiomask = 0, | 1326 | .tuner_type = 0, |
1919 | .muxsel = { 2, 3, 1, 0 }, | 1327 | .tuner_addr = ADDR_UNSET, |
1920 | .audiomux = { 0 }, | 1328 | .radio_addr = ADDR_UNSET, |
1921 | .needs_tvaudio = 0, | 1329 | }, |
1922 | .no_msp34xx = 1, | 1330 | |
1923 | .pll = PLL_28, | 1331 | /* ---- card 0x3c ---------------------------------- */ |
1924 | .tuner_type = -1, | 1332 | [BTTV_BOARD_MM100PCTV] = { |
1925 | .tuner_addr = ADDR_UNSET, | 1333 | /* Philip Blundell <philb@gnu.org> */ |
1926 | },{ | 1334 | .name = "Modular Technology MM100PCTV", |
1927 | /* M.Klahr@phytec.de */ | 1335 | .video_inputs = 2, |
1928 | .name = "PHYTEC VD-009-X1 MiniDIN (bt878)", | 1336 | .audio_inputs = 2, |
1929 | .video_inputs = 4, | 1337 | .tuner = 0, |
1930 | .audio_inputs = 0, | 1338 | .svhs = -1, |
1931 | .tuner = -1, /* card has no tuner */ | 1339 | .gpiomask = 11, |
1932 | .svhs = 3, | 1340 | .muxsel = { 2, 3, 1, 1}, |
1933 | .gpiomask = 0x00, | 1341 | .audiomux = { 2, 0, 0, 1, 8}, |
1934 | .muxsel = { 2, 3, 1, 0}, | 1342 | .pll = PLL_35, |
1935 | .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ | 1343 | .tuner_type = TUNER_TEMIC_PAL, |
1936 | .needs_tvaudio = 1, | 1344 | .tuner_addr = ADDR_UNSET, |
1937 | .pll = PLL_28, | 1345 | .radio_addr = ADDR_UNSET, |
1938 | .tuner_type = -1, | 1346 | }, |
1939 | .tuner_addr = ADDR_UNSET, | 1347 | [BTTV_BOARD_GMV1] = { |
1940 | },{ | 1348 | /* Adrian Cox <adrian@humboldt.co.uk */ |
1941 | .name = "PHYTEC VD-009-X1 Combi (bt878)", | 1349 | .name = "AG Electronics GMV1", |
1942 | .video_inputs = 4, | 1350 | .video_inputs = 2, |
1943 | .audio_inputs = 0, | 1351 | .audio_inputs = 0, |
1944 | .tuner = -1, /* card has no tuner */ | 1352 | .tuner = -1, |
1945 | .svhs = 3, | 1353 | .svhs = 1, |
1946 | .gpiomask = 0x00, | 1354 | .gpiomask = 0xF, |
1947 | .muxsel = { 2, 3, 1, 1}, | 1355 | .muxsel = { 2, 2}, |
1948 | .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ | 1356 | .audiomux = { }, |
1949 | .needs_tvaudio = 1, | 1357 | .no_msp34xx = 1, |
1950 | .pll = PLL_28, | 1358 | .needs_tvaudio = 0, |
1951 | .tuner_type = -1, | 1359 | .pll = PLL_28, |
1952 | .tuner_addr = ADDR_UNSET, | 1360 | .tuner_type = -1, |
1953 | },{ | 1361 | .tuner_addr = ADDR_UNSET, |
1954 | 1362 | .radio_addr = ADDR_UNSET, | |
1955 | /* ---- card 0x6c ---------------------------------- */ | 1363 | }, |
1956 | .name = "PHYTEC VD-009 MiniDIN (bt878)", | 1364 | [BTTV_BOARD_BESTBUY_EASYTV2] = { |
1957 | .video_inputs = 10, | 1365 | /* Miguel Angel Alvarez <maacruz@navegalia.com> |
1958 | .audio_inputs = 0, | 1366 | new Easy TV BT878 version (model CPH061) |
1959 | .tuner = -1, /* card has no tuner */ | 1367 | special thanks to Informatica Mieres for providing the card */ |
1960 | .svhs = 9, | 1368 | .name = "Askey CPH061/ BESTBUY Easy TV (bt878)", |
1961 | .gpiomask = 0x00, | 1369 | .video_inputs = 3, |
1962 | .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio | 1370 | .audio_inputs = 2, |
1963 | via the upper nibble of muxsel. here: used for | 1371 | .tuner = 0, |
1964 | xternal video-mux */ | 1372 | .svhs = 2, |
1965 | .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 }, | 1373 | .gpiomask = 0xFF, |
1966 | .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ | 1374 | .muxsel = { 2, 3, 1, 0}, |
1967 | .needs_tvaudio = 1, | 1375 | .audiomux = { 1, 0, 4, 4, 9}, |
1968 | .pll = PLL_28, | 1376 | .needs_tvaudio = 0, |
1969 | .tuner_type = -1, | 1377 | .pll = PLL_28, |
1970 | .tuner_addr = ADDR_UNSET, | 1378 | .tuner_type = TUNER_PHILIPS_PAL, |
1971 | },{ | 1379 | .tuner_addr = ADDR_UNSET, |
1972 | .name = "PHYTEC VD-009 Combi (bt878)", | 1380 | .radio_addr = ADDR_UNSET, |
1973 | .video_inputs = 10, | 1381 | }, |
1974 | .audio_inputs = 0, | 1382 | [BTTV_BOARD_ATI_TVWONDER] = { |
1975 | .tuner = -1, /* card has no tuner */ | 1383 | /* Lukas Gebauer <geby@volny.cz> */ |
1976 | .svhs = 9, | 1384 | .name = "ATI TV-Wonder", |
1977 | .gpiomask = 0x00, | 1385 | .video_inputs = 3, |
1978 | .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio | 1386 | .audio_inputs = 1, |
1979 | via the upper nibble of muxsel. here: used for | 1387 | .tuner = 0, |
1980 | xternal video-mux */ | 1388 | .svhs = 2, |
1981 | .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 }, | 1389 | .gpiomask = 0xf03f, |
1982 | .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ | 1390 | .muxsel = { 2, 3, 1, 0 }, |
1983 | .needs_tvaudio = 1, | 1391 | .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe}, |
1984 | .pll = PLL_28, | 1392 | .pll = PLL_28, |
1985 | .tuner_type = -1, | 1393 | .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, |
1986 | .tuner_addr = ADDR_UNSET, | 1394 | .tuner_addr = ADDR_UNSET, |
1987 | },{ | 1395 | .radio_addr = ADDR_UNSET, |
1988 | .name = "IVC-100", | 1396 | }, |
1989 | .video_inputs = 4, | 1397 | |
1990 | .audio_inputs = 0, | 1398 | /* ---- card 0x40 ---------------------------------- */ |
1991 | .tuner = -1, | 1399 | [BTTV_BOARD_ATI_TVWONDERVE] = { |
1992 | .tuner_type = -1, | 1400 | /* Lukas Gebauer <geby@volny.cz> */ |
1993 | .tuner_addr = ADDR_UNSET, | 1401 | .name = "ATI TV-Wonder VE", |
1994 | .svhs = -1, | 1402 | .video_inputs = 2, |
1995 | .gpiomask = 0xdf, | 1403 | .audio_inputs = 1, |
1996 | .muxsel = { 2, 3, 1, 0 }, | 1404 | .tuner = 0, |
1997 | .pll = PLL_28, | 1405 | .svhs = -1, |
1998 | },{ | 1406 | .gpiomask = 1, |
1999 | /* IVC-120G - Alan Garfield <alan@fromorbit.com> */ | 1407 | .muxsel = { 2, 3, 0, 1}, |
2000 | .name = "IVC-120G", | 1408 | .audiomux = { 0, 0, 1, 0, 0}, |
2001 | .video_inputs = 16, | 1409 | .no_msp34xx = 1, |
2002 | .audio_inputs = 0, /* card has no audio */ | 1410 | .pll = PLL_28, |
2003 | .tuner = -1, /* card has no tuner */ | 1411 | .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, |
2004 | .tuner_type = -1, | 1412 | .tuner_addr = ADDR_UNSET, |
2005 | .tuner_addr = ADDR_UNSET, | 1413 | .radio_addr = ADDR_UNSET, |
2006 | .svhs = -1, /* card has no svhs */ | 1414 | }, |
2007 | .needs_tvaudio = 0, | 1415 | [BTTV_BOARD_FLYVIDEO2000] = { |
2008 | .no_msp34xx = 1, | 1416 | /* DeeJay <deejay@westel900.net (2000S) */ |
2009 | .no_tda9875 = 1, | 1417 | .name = "Lifeview FlyVideo 2000S LR90", |
2010 | .no_tda7432 = 1, | 1418 | .video_inputs = 3, |
2011 | .gpiomask = 0x00, | 1419 | .audio_inputs = 3, |
2012 | .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, | 1420 | .tuner = 0, |
2013 | 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }, | 1421 | .svhs = 2, |
2014 | .muxsel_hook = ivc120_muxsel, | 1422 | .gpiomask = 0x18e0, |
2015 | .pll = PLL_28, | 1423 | .muxsel = { 2, 3, 0, 1}, |
2016 | },{ | 1424 | /* Radio changed from 1e80 to 0x800 to make |
2017 | 1425 | FlyVideo2000S in .hu happy (gm)*/ | |
2018 | /* ---- card 0x70 ---------------------------------- */ | 1426 | /* -dk-???: set mute=0x1800 for tda9874h daughterboard */ |
2019 | .name = "pcHDTV HD-2000 TV", | 1427 | .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 }, |
2020 | .video_inputs = 4, | 1428 | .audio_hook = fv2000s_audio, |
2021 | .audio_inputs = 1, | 1429 | .no_msp34xx = 1, |
2022 | .tuner = 0, | 1430 | .no_tda9875 = 1, |
2023 | .svhs = 2, | 1431 | .needs_tvaudio = 1, |
2024 | .muxsel = { 2, 3, 1, 0}, | 1432 | .pll = PLL_28, |
2025 | .tuner_type = TUNER_PHILIPS_ATSC, | 1433 | .tuner_type = 5, |
2026 | .tuner_addr = ADDR_UNSET, | 1434 | .tuner_addr = ADDR_UNSET, |
2027 | .has_dvb = 1, | 1435 | .radio_addr = ADDR_UNSET, |
2028 | },{ | 1436 | }, |
2029 | .name = "Twinhan DST + clones", | 1437 | [BTTV_BOARD_TERRATVALUER] = { |
2030 | .no_msp34xx = 1, | 1438 | .name = "Terratec TValueRadio", |
2031 | .no_tda9875 = 1, | 1439 | .video_inputs = 3, |
2032 | .no_tda7432 = 1, | 1440 | .audio_inputs = 1, |
2033 | .tuner_type = TUNER_ABSENT, | 1441 | .tuner = 0, |
2034 | .tuner_addr = ADDR_UNSET, | 1442 | .svhs = 2, |
2035 | .no_video = 1, | 1443 | .gpiomask = 0xffff00, |
2036 | .has_dvb = 1, | 1444 | .muxsel = { 2, 3, 1, 1}, |
2037 | },{ | 1445 | .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900}, |
2038 | .name = "Winfast VC100", | 1446 | .needs_tvaudio = 1, |
2039 | .video_inputs = 3, | 1447 | .pll = PLL_28, |
2040 | .audio_inputs = 0, | 1448 | .tuner_type = TUNER_PHILIPS_PAL, |
2041 | .svhs = 1, | 1449 | .tuner_addr = ADDR_UNSET, |
2042 | .tuner = -1, | 1450 | .radio_addr = ADDR_UNSET, |
2043 | .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */ | 1451 | .has_radio = 1, |
2044 | .no_msp34xx = 1, | 1452 | }, |
2045 | .no_tda9875 = 1, | 1453 | [BTTV_BOARD_GVBCTV4PCI] = { |
2046 | .no_tda7432 = 1, | 1454 | /* TANAKA Kei <peg00625@nifty.com> */ |
2047 | .tuner_type = TUNER_ABSENT, | 1455 | .name = "IODATA GV-BCTV4/PCI", |
2048 | .tuner_addr = ADDR_UNSET, | 1456 | .video_inputs = 3, |
2049 | .pll = PLL_28, | 1457 | .audio_inputs = 1, |
2050 | },{ | 1458 | .tuner = 0, |
2051 | .name = "Teppro TEV-560/InterVision IV-560", | 1459 | .svhs = 2, |
2052 | .video_inputs = 3, | 1460 | .gpiomask = 0x010f00, |
2053 | .audio_inputs = 1, | 1461 | .muxsel = {2, 3, 0, 0}, |
2054 | .tuner = 0, | 1462 | .audiomux = {0x10000, 0, 0x10000, 0, 0, 0}, |
2055 | .svhs = 2, | 1463 | .no_msp34xx = 1, |
2056 | .gpiomask = 3, | 1464 | .pll = PLL_28, |
2057 | .muxsel = { 2, 3, 1, 1}, | 1465 | .tuner_type = TUNER_SHARP_2U5JF5540_NTSC, |
2058 | .audiomux = { 1, 1, 1, 1, 0}, | 1466 | .tuner_addr = ADDR_UNSET, |
2059 | .needs_tvaudio = 1, | 1467 | .radio_addr = ADDR_UNSET, |
2060 | .tuner_type = TUNER_PHILIPS_PAL, | 1468 | .audio_hook = gvbctv3pci_audio, |
2061 | .tuner_addr = ADDR_UNSET, | 1469 | }, |
2062 | .pll = PLL_35, | 1470 | |
2063 | },{ | 1471 | /* ---- card 0x44 ---------------------------------- */ |
2064 | 1472 | [BTTV_BOARD_VOODOOTV_FM] = { | |
2065 | /* ---- card 0x74 ---------------------------------- */ | 1473 | .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)", |
2066 | .name = "SIMUS GVC1100", | 1474 | /* try "insmod msp3400 simple=0" if you have |
2067 | .video_inputs = 4, | 1475 | * sound problems with this card. */ |
2068 | .audio_inputs = 0, | 1476 | .video_inputs = 4, |
2069 | .tuner = -1, | 1477 | .audio_inputs = 1, |
2070 | .svhs = -1, | 1478 | .tuner = 0, |
2071 | .tuner_type = -1, | 1479 | .svhs = -1, |
2072 | .tuner_addr = ADDR_UNSET, | 1480 | .gpiomask = 0x4f8a00, |
2073 | .pll = PLL_28, | 1481 | /* 0x100000: 1=MSP enabled (0=disable again) |
2074 | .muxsel = { 2, 2, 2, 2}, | 1482 | * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ |
2075 | .gpiomask = 0x3F, | 1483 | .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff}, |
2076 | .muxsel_hook = gvc1100_muxsel, | 1484 | /* tvtuner, radio, external,internal, mute, stereo |
2077 | },{ | 1485 | * tuner, Composit, SVid, Composit-on-Svid-adapter */ |
2078 | /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */ | 1486 | .muxsel = { 2, 3 ,0 ,1}, |
2079 | .name = "NGS NGSTV+", | 1487 | .tuner_type = TUNER_MT2032, |
2080 | .video_inputs = 3, | 1488 | .tuner_addr = ADDR_UNSET, |
2081 | .tuner = 0, | 1489 | .radio_addr = ADDR_UNSET, |
2082 | .svhs = 2, | 1490 | .pll = PLL_28, |
2083 | .gpiomask = 0x008007, | 1491 | .has_radio = 1, |
2084 | .muxsel = {2, 3, 0, 0}, | 1492 | }, |
2085 | .audiomux = {0, 0, 0, 0, 0x000003, 0}, | 1493 | [BTTV_BOARD_AIMMS] = { |
2086 | .pll = PLL_28, | 1494 | /* Philip Blundell <pb@nexus.co.uk> */ |
2087 | .tuner_type = TUNER_PHILIPS_PAL, | 1495 | .name = "Active Imaging AIMMS", |
2088 | .tuner_addr = ADDR_UNSET, | 1496 | .video_inputs = 1, |
2089 | .has_remote = 1, | 1497 | .audio_inputs = 0, |
2090 | },{ | 1498 | .tuner = -1, |
2091 | /* http://linuxmedialabs.com */ | 1499 | .tuner_type = -1, |
2092 | .name = "LMLBT4", | 1500 | .tuner_addr = ADDR_UNSET, |
2093 | .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ | 1501 | .radio_addr = ADDR_UNSET, |
2094 | .audio_inputs = 0, | 1502 | .pll = PLL_28, |
2095 | .tuner = -1, | 1503 | .muxsel = { 2 }, |
2096 | .svhs = -1, | 1504 | .gpiomask = 0 |
2097 | .muxsel = { 2, 3, 1, 0 }, | 1505 | }, |
2098 | .no_msp34xx = 1, | 1506 | [BTTV_BOARD_PV_BT878P_PLUS] = { |
2099 | .no_tda9875 = 1, | 1507 | /* Tomasz Pyra <hellfire@sedez.iq.pl> */ |
2100 | .no_tda7432 = 1, | 1508 | .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)", |
2101 | .needs_tvaudio = 0, | 1509 | .video_inputs = 3, |
2102 | .tuner_type = -1, | 1510 | .audio_inputs = 4, |
2103 | .tuner_addr = ADDR_UNSET, | 1511 | .tuner = 0, |
2104 | },{ | 1512 | .svhs = 2, |
2105 | /* Helmroos Harri <harri.helmroos@pp.inet.fi> */ | 1513 | .gpiomask = 15, |
2106 | .name = "Tekram M205 PRO", | 1514 | .muxsel = { 2, 3, 1, 1}, |
2107 | .video_inputs = 3, | 1515 | .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */ |
2108 | .audio_inputs = 1, | 1516 | .needs_tvaudio = 1, |
2109 | .tuner = 0, | 1517 | .pll = PLL_28, |
2110 | .tuner_type = TUNER_PHILIPS_PAL, | 1518 | .tuner_type = 25, |
2111 | .tuner_addr = ADDR_UNSET, | 1519 | .tuner_addr = ADDR_UNSET, |
2112 | .svhs = 2, | 1520 | .radio_addr = ADDR_UNSET, |
2113 | .needs_tvaudio = 0, | 1521 | .has_remote = 1, |
2114 | .gpiomask = 0x68, | 1522 | /* GPIO wiring: |
2115 | .muxsel = { 2, 3, 1}, | 1523 | GPIO0: U4.A0 (hef4052bt) |
2116 | .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 }, | 1524 | GPIO1: U4.A1 |
2117 | .pll = PLL_28, | 1525 | GPIO2: U4.A1 (second hef4052bt) |
2118 | },{ | 1526 | GPIO3: U4.nEN, U5.A0, A5.nEN |
2119 | 1527 | GPIO8-15: vrd866b ? | |
2120 | /* ---- card 0x78 ---------------------------------- */ | 1528 | */ |
2121 | /* Javier Cendan Ares <jcendan@lycos.es> */ | 1529 | }, |
2122 | /* bt878 TV + FM without subsystem ID */ | 1530 | [BTTV_BOARD_FLYVIDEO98EZ] = { |
2123 | .name = "Conceptronic CONTVFMi", | 1531 | .name = "Lifeview FlyVideo 98EZ (capture only) LR51", |
2124 | .video_inputs = 3, | 1532 | .video_inputs = 4, |
2125 | .audio_inputs = 1, | 1533 | .audio_inputs = 0, |
2126 | .tuner = 0, | 1534 | .tuner = -1, |
2127 | .svhs = 2, | 1535 | .svhs = 2, |
2128 | .gpiomask = 0x008007, | 1536 | .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */ |
2129 | .muxsel = { 2, 3, 1, 1 }, | 1537 | .pll = PLL_28, |
2130 | .audiomux = { 0, 1, 2, 2, 3 }, | 1538 | .no_msp34xx = 1, |
2131 | .needs_tvaudio = 0, | 1539 | .tuner_type = UNSET, |
2132 | .pll = PLL_28, | 1540 | .tuner_addr = ADDR_UNSET, |
2133 | .tuner_type = TUNER_PHILIPS_PAL, | 1541 | .radio_addr = ADDR_UNSET, |
2134 | .tuner_addr = ADDR_UNSET, | 1542 | }, |
2135 | .has_remote = 1, | 1543 | |
2136 | .has_radio = 1, | 1544 | /* ---- card 0x48 ---------------------------------- */ |
2137 | },{ | 1545 | [BTTV_BOARD_PV_BT878P_9B] = { |
2138 | /*Eric DEBIEF <debief@telemsa.com>*/ | 1546 | /* Dariusz Kowalewski <darekk@automex.pl> */ |
2139 | /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/ | 1547 | .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)", |
2140 | /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_PICOLO_TETRA_CHIP*/ | 1548 | .video_inputs = 4, |
2141 | /*0x79 in bttv.h*/ | 1549 | .audio_inputs = 1, |
2142 | .name = "Euresys Picolo Tetra", | 1550 | .tuner = 0, |
2143 | .video_inputs = 4, | 1551 | .svhs = 2, |
2144 | .audio_inputs = 0, | 1552 | .gpiomask = 0x3f, |
2145 | .tuner = -1, | 1553 | .muxsel = { 2, 3, 1, 1 }, |
2146 | .svhs = -1, | 1554 | .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 }, |
2147 | .gpiomask = 0, | 1555 | .needs_tvaudio = 1, |
2148 | .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ | 1556 | .no_msp34xx = 1, |
2149 | .no_msp34xx = 1, | 1557 | .no_tda9875 = 1, |
2150 | .no_tda9875 = 1, | 1558 | .pll = PLL_28, |
2151 | .no_tda7432 = 1, | 1559 | .tuner_type = 5, |
2152 | .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/ | 1560 | .tuner_addr = ADDR_UNSET, |
2153 | .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ | 1561 | .radio_addr = ADDR_UNSET, |
2154 | .pll = PLL_28, | 1562 | .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */ |
2155 | .needs_tvaudio = 0, | 1563 | .has_radio = 1, /* Note: not all cards have radio */ |
2156 | .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ | 1564 | .has_remote = 1, |
2157 | .tuner_type = -1, | 1565 | /* GPIO wiring: |
2158 | .tuner_addr = ADDR_UNSET, | 1566 | GPIO0: A0 hef4052 |
2159 | },{ | 1567 | GPIO1: A1 hef4052 |
2160 | /* Spirit TV Tuner from http://spiritmodems.com.au */ | 1568 | GPIO3: nEN hef4052 |
2161 | /* Stafford Goodsell <surge@goliath.homeunix.org> */ | 1569 | GPIO8-15: vrd866b |
2162 | .name = "Spirit TV Tuner", | 1570 | GPIO20,22,23: R30,R29,R28 |
2163 | .video_inputs = 3, | 1571 | */ |
2164 | .audio_inputs = 1, | 1572 | }, |
2165 | .tuner = 0, | 1573 | [BTTV_BOARD_SENSORAY311] = { |
2166 | .svhs = 2, | 1574 | /* Clay Kunz <ckunz@mail.arc.nasa.gov> */ |
2167 | .gpiomask = 0x0000000f, | 1575 | /* you must jumper JP5 for the card to work */ |
2168 | .muxsel = { 2, 1, 1 }, | 1576 | .name = "Sensoray 311", |
2169 | .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00}, | 1577 | .video_inputs = 5, |
2170 | .tuner_type = TUNER_TEMIC_PAL, | 1578 | .audio_inputs = 0, |
2171 | .tuner_addr = ADDR_UNSET, | 1579 | .tuner = -1, |
2172 | .no_msp34xx = 1, | 1580 | .svhs = 4, |
2173 | .no_tda9875 = 1, | 1581 | .gpiomask = 0, |
2174 | },{ | 1582 | .muxsel = { 2, 3, 1, 0, 0}, |
2175 | /* Wolfram Joost <wojo@frokaschwei.de> */ | 1583 | .audiomux = { 0 }, |
2176 | .name = "AVerMedia AVerTV DVB-T 771", | 1584 | .needs_tvaudio = 0, |
2177 | .video_inputs = 2, | 1585 | .tuner_type = -1, |
2178 | .svhs = 1, | 1586 | .tuner_addr = ADDR_UNSET, |
2179 | .tuner = -1, | 1587 | .radio_addr = ADDR_UNSET, |
2180 | .tuner_type = TUNER_ABSENT, | 1588 | }, |
2181 | .tuner_addr = ADDR_UNSET, | 1589 | [BTTV_BOARD_RV605] = { |
2182 | .muxsel = { 3 , 3 }, | 1590 | /* Miguel Freitas <miguel@cetuc.puc-rio.br> */ |
2183 | .no_msp34xx = 1, | 1591 | .name = "RemoteVision MX (RV605)", |
2184 | .no_tda9875 = 1, | 1592 | .video_inputs = 16, |
2185 | .no_tda7432 = 1, | 1593 | .audio_inputs = 0, |
2186 | .pll = PLL_28, | 1594 | .tuner = -1, |
2187 | .has_dvb = 1, | 1595 | .svhs = -1, |
2188 | .no_gpioirq = 1, | 1596 | .gpiomask = 0x00, |
2189 | .has_remote = 1, | 1597 | .gpiomask2 = 0x07ff, |
2190 | },{ | 1598 | .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, |
2191 | /* ---- card 0x7c ---------------------------------- */ | 1599 | 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 }, |
2192 | /* Matt Jesson <dvb@jesson.eclipse.co.uk> */ | 1600 | .no_msp34xx = 1, |
2193 | /* Based on the Nebula card data - added remote and new card number - BTTV_AVDVBT_761, see also ir-kbd-gpio.c */ | 1601 | .no_tda9875 = 1, |
2194 | .name = "AverMedia AverTV DVB-T 761", | 1602 | .tuner_type = -1, |
2195 | .video_inputs = 2, | 1603 | .tuner_addr = ADDR_UNSET, |
2196 | .tuner = -1, | 1604 | .radio_addr = ADDR_UNSET, |
2197 | .svhs = 1, | 1605 | .muxsel_hook = rv605_muxsel, |
2198 | .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */ | 1606 | }, |
2199 | .no_msp34xx = 1, | 1607 | [BTTV_BOARD_POWERCLR_MTV878] = { |
2200 | .no_tda9875 = 1, | 1608 | .name = "Powercolor MTV878/ MTV878R/ MTV878F", |
2201 | .no_tda7432 = 1, | 1609 | .video_inputs = 3, |
2202 | .pll = PLL_28, | 1610 | .audio_inputs = 2, |
2203 | .tuner_type = -1, | 1611 | .tuner = 0, |
2204 | .tuner_addr = ADDR_UNSET, | 1612 | .svhs = 2, |
2205 | .has_dvb = 1, | 1613 | .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */ |
2206 | .no_gpioirq = 1, | 1614 | .muxsel = { 2, 1, 1, }, |
2207 | .has_remote = 1, | 1615 | .audiomux = { 0, 1, 2, 2, 4 }, |
2208 | },{ | 1616 | .needs_tvaudio = 0, |
2209 | /* andre.schwarz@matrix-vision.de */ | 1617 | .tuner_type = TUNER_PHILIPS_PAL, |
2210 | .name = "MATRIX Vision Sigma-SQ", | 1618 | .tuner_addr = ADDR_UNSET, |
2211 | .video_inputs = 16, | 1619 | .radio_addr = ADDR_UNSET, |
2212 | .audio_inputs = 0, | 1620 | .pll = PLL_28, |
2213 | .tuner = -1, | 1621 | .has_radio = 1, |
2214 | .svhs = -1, | 1622 | }, |
2215 | .gpiomask = 0x0, | 1623 | |
2216 | .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, | 1624 | /* ---- card 0x4c ---------------------------------- */ |
2217 | 3, 3, 3, 3, 3, 3, 3, 3 }, | 1625 | [BTTV_BOARD_WINDVR] = { |
2218 | .muxsel_hook = sigmaSQ_muxsel, | 1626 | /* Masaki Suzuki <masaki@btree.org> */ |
2219 | .audiomux = { 0 }, | 1627 | .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)", |
2220 | .no_msp34xx = 1, | 1628 | .video_inputs = 3, |
2221 | .pll = PLL_28, | 1629 | .audio_inputs = 1, |
2222 | .tuner_type = -1, | 1630 | .tuner = 0, |
2223 | .tuner_addr = ADDR_UNSET, | 1631 | .svhs = 2, |
2224 | },{ | 1632 | .gpiomask = 0x140007, |
2225 | /* andre.schwarz@matrix-vision.de */ | 1633 | .muxsel = { 2, 3, 1, 1 }, |
2226 | .name = "MATRIX Vision Sigma-SLC", | 1634 | .audiomux = { 0, 1, 2, 3, 4, 0 }, |
2227 | .video_inputs = 4, | 1635 | .tuner_type = TUNER_PHILIPS_NTSC, |
2228 | .audio_inputs = 0, | 1636 | .tuner_addr = ADDR_UNSET, |
2229 | .tuner = -1, | 1637 | .radio_addr = ADDR_UNSET, |
2230 | .svhs = -1, | 1638 | .audio_hook = windvr_audio, |
2231 | .gpiomask = 0x0, | 1639 | }, |
2232 | .muxsel = { 2, 2, 2, 2 }, | 1640 | [BTTV_BOARD_GRANDTEC_MULTI] = { |
2233 | .muxsel_hook = sigmaSLC_muxsel, | 1641 | .name = "GrandTec Multi Capture Card (Bt878)", |
2234 | .audiomux = { 0 }, | 1642 | .video_inputs = 4, |
2235 | .no_msp34xx = 1, | 1643 | .audio_inputs = 0, |
2236 | .pll = PLL_28, | 1644 | .tuner = -1, |
2237 | .tuner_type = -1, | 1645 | .svhs = -1, |
2238 | .tuner_addr = ADDR_UNSET, | 1646 | .gpiomask = 0, |
2239 | },{ | 1647 | .muxsel = { 2, 3, 1, 0 }, |
2240 | /* BTTV_APAC_VIEWCOMP */ | 1648 | .audiomux = { 0 }, |
2241 | /* Attila Kondoros <attila.kondoros@chello.hu> */ | 1649 | .needs_tvaudio = 0, |
2242 | /* bt878 TV + FM 0x00000000 subsystem ID */ | 1650 | .no_msp34xx = 1, |
2243 | .name = "APAC Viewcomp 878(AMAX)", | 1651 | .pll = PLL_28, |
2244 | .video_inputs = 2, | 1652 | .tuner_type = -1, |
2245 | .audio_inputs = 1, | 1653 | .tuner_addr = ADDR_UNSET, |
2246 | .tuner = 0, | 1654 | .radio_addr = ADDR_UNSET, |
2247 | .svhs = -1, | 1655 | }, |
2248 | .gpiomask = 0xFF, | 1656 | [BTTV_BOARD_KWORLD] = { |
2249 | .muxsel = { 2, 3, 1, 1}, | 1657 | .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", |
2250 | .audiomux = { 2, 0, 0, 0, 10}, | 1658 | .video_inputs = 4, |
2251 | .needs_tvaudio = 0, | 1659 | .audio_inputs = 3, |
2252 | .pll = PLL_28, | 1660 | .tuner = 0, |
2253 | .tuner_type = TUNER_PHILIPS_PAL, | 1661 | .svhs = 2, |
2254 | .tuner_addr = ADDR_UNSET, | 1662 | .gpiomask = 7, |
2255 | .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */ | 1663 | .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */ |
2256 | .has_radio = 1, /* not every card has radio */ | 1664 | .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio! |
2257 | },{ | 1665 | * This card lacks external Audio In, so we mute it on Ext. & Int. |
2258 | 1666 | * The PCB can take a sbx1637/sbx1673, wiring unknown. | |
2259 | /* ---- card 0x80 ---------------------------------- */ | 1667 | * This card lacks PCI subsystem ID, sigh. |
2260 | /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */ | 1668 | * audiomux=1: lower volume, 2+3: mute |
2261 | .name = "DViCO FusionHDTV DVB-T Lite", | 1669 | * btwincap uses 0x80000/0x80003 |
2262 | .tuner = -1, | 1670 | */ |
2263 | .no_msp34xx = 1, | 1671 | .needs_tvaudio = 0, |
2264 | .no_tda9875 = 1, | 1672 | .no_msp34xx = 1, |
2265 | .no_tda7432 = 1, | 1673 | .pll = PLL_28, |
2266 | .pll = PLL_28, | 1674 | .tuner_type = 5, |
2267 | .no_video = 1, | 1675 | .tuner_addr = ADDR_UNSET, |
2268 | .has_dvb = 1, | 1676 | .radio_addr = ADDR_UNSET, |
2269 | .tuner_type = -1, | 1677 | /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and |
2270 | .tuner_addr = ADDR_UNSET, | 1678 | radio signal strength indicators work fine. */ |
2271 | },{ | 1679 | .has_radio = 1, |
2272 | /* Steven <photon38@pchome.com.tw> */ | 1680 | /* GPIO Info: |
2273 | .name = "V-Gear MyVCD", | 1681 | GPIO0,1: HEF4052 A0,A1 |
2274 | .video_inputs = 3, | 1682 | GPIO2: HEF4052 nENABLE |
2275 | .audio_inputs = 1, | 1683 | GPIO3-7: n.c. |
2276 | .tuner = 0, | 1684 | GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card] |
2277 | .svhs = 2, | 1685 | GPIO14,15: ?? |
2278 | .gpiomask = 0x3f, | 1686 | GPIO16-21: n.c. |
2279 | .muxsel = {2, 3, 1, 0}, | 1687 | GPIO22,23: ?? |
2280 | .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31}, | 1688 | ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/ |
2281 | .no_msp34xx = 1, | 1689 | }, |
2282 | .pll = PLL_28, | 1690 | [BTTV_BOARD_DSP_TCVIDEO] = { |
2283 | .tuner_type = TUNER_PHILIPS_NTSC_M, | 1691 | /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */ |
2284 | .tuner_addr = ADDR_UNSET, | 1692 | .name = "DSP Design TCVIDEO", |
2285 | .has_radio = 0, | 1693 | .video_inputs = 4, |
2286 | },{ | 1694 | .svhs = -1, |
2287 | /* Rick C <cryptdragoon@gmail.com> */ | 1695 | .muxsel = { 2, 3, 1, 0}, |
2288 | .name = "Super TV Tuner", | 1696 | .pll = PLL_28, |
2289 | .video_inputs = 4, | 1697 | .tuner_type = -1, |
2290 | .audio_inputs = 1, | 1698 | .tuner_addr = ADDR_UNSET, |
2291 | .tuner = 0, | 1699 | .radio_addr = ADDR_UNSET, |
2292 | .svhs = 2, | 1700 | }, |
2293 | .muxsel = { 2, 3, 1, 0}, | 1701 | |
2294 | .tuner_type = TUNER_PHILIPS_NTSC, | 1702 | /* ---- card 0x50 ---------------------------------- */ |
2295 | .tuner_addr = ADDR_UNSET, | 1703 | [BTTV_BOARD_HAUPPAUGEPVR] = { |
2296 | .gpiomask = 0x008007, | 1704 | .name = "Hauppauge WinTV PVR", |
2297 | .audiomux = { 0, 0x000001,0,0, 0}, | 1705 | .video_inputs = 4, |
2298 | .needs_tvaudio = 1, | 1706 | .audio_inputs = 1, |
2299 | .has_radio = 1, | 1707 | .tuner = 0, |
2300 | },{ | 1708 | .svhs = 2, |
2301 | /* Chris Fanning <video4linux@haydon.net> */ | 1709 | .muxsel = { 2, 0, 1, 1}, |
2302 | .name = "Tibet Systems 'Progress DVR' CS16", | 1710 | .needs_tvaudio = 1, |
2303 | .video_inputs = 16, | 1711 | .pll = PLL_28, |
2304 | .audio_inputs = 0, | 1712 | .tuner_type = -1, |
2305 | .tuner = -1, | 1713 | .tuner_addr = ADDR_UNSET, |
2306 | .svhs = -1, | 1714 | .radio_addr = ADDR_UNSET, |
2307 | .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, | 1715 | |
2308 | .pll = PLL_28, | 1716 | .gpiomask = 7, |
2309 | .no_msp34xx = 1, | 1717 | .audiomux = {7}, |
2310 | .no_tda9875 = 1, | 1718 | }, |
2311 | .no_tda7432 = 1, | 1719 | [BTTV_BOARD_GVBCTV5PCI] = { |
2312 | .tuner_type = -1, | 1720 | .name = "IODATA GV-BCTV5/PCI", |
2313 | .tuner_addr = ADDR_UNSET, | 1721 | .video_inputs = 3, |
2314 | .muxsel_hook = tibetCS16_muxsel, | 1722 | .audio_inputs = 1, |
2315 | }, | 1723 | .tuner = 0, |
2316 | { | 1724 | .svhs = 2, |
2317 | /* Bill Brack <wbrack@mmm.com.hk> */ | 1725 | .gpiomask = 0x0f0f80, |
2318 | /* | 1726 | .muxsel = {2, 3, 1, 0}, |
2319 | * Note that, because of the card's wiring, the "master" | 1727 | .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0}, |
2320 | * BT878A chip (i.e. the one which controls the analog switch | 1728 | .no_msp34xx = 1, |
2321 | * and must use this card type) is the 2nd one detected. The | 1729 | .pll = PLL_28, |
2322 | * other 3 chips should use card type 0x85, whose description | 1730 | .tuner_type = TUNER_PHILIPS_NTSC_M, |
2323 | * follows this one. There is a EEPROM on the card (which is | 1731 | .tuner_addr = ADDR_UNSET, |
2324 | * connected to the I2C of one of those other chips), but is | 1732 | .radio_addr = ADDR_UNSET, |
2325 | * not currently handled. There is also a facility for a | 1733 | .audio_hook = gvbctv5pci_audio, |
2326 | * "monitor", which is also not currently implemented. | 1734 | .has_radio = 1, |
2327 | */ | 1735 | }, |
2328 | .name = "Kodicom 4400R (master)", | 1736 | [BTTV_BOARD_OSPREY1x0] = { |
2329 | .video_inputs = 16, | 1737 | .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ |
2330 | .audio_inputs = 0, | 1738 | .video_inputs = 4, /* id-inputs-clock */ |
2331 | .tuner = -1, | 1739 | .audio_inputs = 0, |
2332 | .tuner_type = -1, | 1740 | .tuner = -1, |
2333 | .tuner_addr = ADDR_UNSET, | 1741 | .svhs = 3, |
2334 | .svhs = -1, | 1742 | .muxsel = { 3, 2, 0, 1 }, |
2335 | /* GPIO bits 0-9 used for analog switch: | 1743 | .pll = PLL_28, |
2336 | * 00 - 03: camera selector | 1744 | .tuner_type = -1, |
2337 | * 04 - 06: channel (controller) selector | 1745 | .tuner_addr = ADDR_UNSET, |
2338 | * 07: data (1->on, 0->off) | 1746 | .radio_addr = ADDR_UNSET, |
2339 | * 08: strobe | 1747 | .no_msp34xx = 1, |
2340 | * 09: reset | 1748 | .no_tda9875 = 1, |
2341 | * bit 16 is input from sync separator for the channel | 1749 | .no_tda7432 = 1, |
2342 | */ | 1750 | }, |
2343 | .gpiomask = 0x0003ff, | 1751 | [BTTV_BOARD_OSPREY1x0_848] = { |
2344 | .no_gpioirq = 1, | 1752 | .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ |
2345 | .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, | 1753 | .video_inputs = 3, |
2346 | .pll = PLL_28, | 1754 | .audio_inputs = 0, |
2347 | .no_msp34xx = 1, | 1755 | .tuner = -1, |
2348 | .no_tda7432 = 1, | 1756 | .svhs = 2, |
2349 | .no_tda9875 = 1, | 1757 | .muxsel = { 2, 3, 1 }, |
2350 | .muxsel_hook = kodicom4400r_muxsel, | 1758 | .pll = PLL_28, |
2351 | }, | 1759 | .tuner_type = -1, |
2352 | { | 1760 | .tuner_addr = ADDR_UNSET, |
2353 | /* Bill Brack <wbrack@mmm.com.hk> */ | 1761 | .radio_addr = ADDR_UNSET, |
2354 | /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the | 1762 | .no_msp34xx = 1, |
2355 | * one which controls the analog switch, and must use the card type) | 1763 | .no_tda9875 = 1, |
2356 | * is the 2nd one detected. The other 3 chips should use this card | 1764 | .no_tda7432 = 1, |
2357 | * type | 1765 | }, |
1766 | |||
1767 | /* ---- card 0x54 ---------------------------------- */ | ||
1768 | [BTTV_BOARD_OSPREY101_848] = { | ||
1769 | .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */ | ||
1770 | .video_inputs = 2, | ||
1771 | .audio_inputs = 0, | ||
1772 | .tuner = -1, | ||
1773 | .svhs = 1, | ||
1774 | .muxsel = { 3, 1 }, | ||
1775 | .pll = PLL_28, | ||
1776 | .tuner_type = -1, | ||
1777 | .tuner_addr = ADDR_UNSET, | ||
1778 | .radio_addr = ADDR_UNSET, | ||
1779 | .no_msp34xx = 1, | ||
1780 | .no_tda9875 = 1, | ||
1781 | .no_tda7432 = 1, | ||
1782 | }, | ||
1783 | [BTTV_BOARD_OSPREY1x1] = { | ||
1784 | .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ | ||
1785 | .video_inputs = 1, | ||
1786 | .audio_inputs = 0, | ||
1787 | .tuner = -1, | ||
1788 | .svhs = -1, | ||
1789 | .muxsel = { 0 }, | ||
1790 | .pll = PLL_28, | ||
1791 | .tuner_type = -1, | ||
1792 | .tuner_addr = ADDR_UNSET, | ||
1793 | .radio_addr = ADDR_UNSET, | ||
1794 | .no_msp34xx = 1, | ||
1795 | .no_tda9875 = 1, | ||
1796 | .no_tda7432 = 1, | ||
1797 | }, | ||
1798 | [BTTV_BOARD_OSPREY1x1_SVID] = { | ||
1799 | .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ | ||
1800 | .video_inputs = 2, | ||
1801 | .audio_inputs = 0, | ||
1802 | .tuner = -1, | ||
1803 | .svhs = 1, | ||
1804 | .muxsel = { 0, 1 }, | ||
1805 | .pll = PLL_28, | ||
1806 | .tuner_type = -1, | ||
1807 | .tuner_addr = ADDR_UNSET, | ||
1808 | .radio_addr = ADDR_UNSET, | ||
1809 | .no_msp34xx = 1, | ||
1810 | .no_tda9875 = 1, | ||
1811 | .no_tda7432 = 1, | ||
1812 | }, | ||
1813 | [BTTV_BOARD_OSPREY2xx] = { | ||
1814 | .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ | ||
1815 | .video_inputs = 1, | ||
1816 | .audio_inputs = 1, | ||
1817 | .tuner = -1, | ||
1818 | .svhs = -1, | ||
1819 | .muxsel = { 0 }, | ||
1820 | .pll = PLL_28, | ||
1821 | .tuner_type = UNSET, | ||
1822 | .tuner_addr = ADDR_UNSET, | ||
1823 | .radio_addr = ADDR_UNSET, | ||
1824 | .no_msp34xx = 1, | ||
1825 | .no_tda9875 = 1, | ||
1826 | .no_tda7432 = 1, | ||
1827 | }, | ||
1828 | |||
1829 | /* ---- card 0x58 ---------------------------------- */ | ||
1830 | [BTTV_BOARD_OSPREY2x0_SVID] = { | ||
1831 | .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ | ||
1832 | .video_inputs = 2, | ||
1833 | .audio_inputs = 1, | ||
1834 | .tuner = -1, | ||
1835 | .svhs = 1, | ||
1836 | .muxsel = { 0, 1 }, | ||
1837 | .pll = PLL_28, | ||
1838 | .tuner_type = UNSET, | ||
1839 | .tuner_addr = ADDR_UNSET, | ||
1840 | .radio_addr = ADDR_UNSET, | ||
1841 | .no_msp34xx = 1, | ||
1842 | .no_tda9875 = 1, | ||
1843 | .no_tda7432 = 1, | ||
1844 | }, | ||
1845 | [BTTV_BOARD_OSPREY2x0] = { | ||
1846 | .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */ | ||
1847 | .video_inputs = 2, | ||
1848 | .audio_inputs = 1, | ||
1849 | .tuner = -1, | ||
1850 | .svhs = 1, | ||
1851 | .muxsel = { 2, 3 }, | ||
1852 | .pll = PLL_28, | ||
1853 | .tuner_type = UNSET, | ||
1854 | .tuner_addr = ADDR_UNSET, | ||
1855 | .radio_addr = ADDR_UNSET, | ||
1856 | .no_msp34xx = 1, | ||
1857 | .no_tda9875 = 1, | ||
1858 | .no_tda7432 = 1, | ||
1859 | }, | ||
1860 | [BTTV_BOARD_OSPREY500] = { | ||
1861 | .name = "Osprey 500", /* 500 */ | ||
1862 | .video_inputs = 2, | ||
1863 | .audio_inputs = 1, | ||
1864 | .tuner = -1, | ||
1865 | .svhs = 1, | ||
1866 | .muxsel = { 2, 3 }, | ||
1867 | .pll = PLL_28, | ||
1868 | .tuner_type = -1, | ||
1869 | .tuner_addr = ADDR_UNSET, | ||
1870 | .radio_addr = ADDR_UNSET, | ||
1871 | .no_msp34xx = 1, | ||
1872 | .no_tda9875 = 1, | ||
1873 | .no_tda7432 = 1, | ||
1874 | }, | ||
1875 | [BTTV_BOARD_OSPREY540] = { | ||
1876 | .name = "Osprey 540", /* 540 */ | ||
1877 | .video_inputs = 4, | ||
1878 | .audio_inputs = 1, | ||
1879 | .tuner = -1, | ||
1880 | #if 0 /* TODO ... */ | ||
1881 | .svhs = OSPREY540_SVID_ANALOG, | ||
1882 | .muxsel = { [OSPREY540_COMP_ANALOG] = 2, | ||
1883 | [OSPREY540_SVID_ANALOG] = 3, }, | ||
1884 | #endif | ||
1885 | .pll = PLL_28, | ||
1886 | .tuner_type = -1, | ||
1887 | .tuner_addr = ADDR_UNSET, | ||
1888 | .radio_addr = ADDR_UNSET, | ||
1889 | .no_msp34xx = 1, | ||
1890 | .no_tda9875 = 1, | ||
1891 | .no_tda7432 = 1, | ||
1892 | #if 0 /* TODO ... */ | ||
1893 | .muxsel_hook = osprey_540_muxsel, | ||
1894 | .picture_hook = osprey_540_set_picture, | ||
1895 | #endif | ||
1896 | }, | ||
1897 | |||
1898 | /* ---- card 0x5C ---------------------------------- */ | ||
1899 | [BTTV_BOARD_OSPREY2000] = { | ||
1900 | .name = "Osprey 2000", /* 2000 */ | ||
1901 | .video_inputs = 2, | ||
1902 | .audio_inputs = 1, | ||
1903 | .tuner = -1, | ||
1904 | .svhs = 1, | ||
1905 | .muxsel = { 2, 3 }, | ||
1906 | .pll = PLL_28, | ||
1907 | .tuner_type = UNSET, | ||
1908 | .tuner_addr = ADDR_UNSET, | ||
1909 | .radio_addr = ADDR_UNSET, | ||
1910 | .no_msp34xx = 1, | ||
1911 | .no_tda9875 = 1, | ||
1912 | .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */ | ||
1913 | }, | ||
1914 | [BTTV_BOARD_IDS_EAGLE] = { | ||
1915 | /* M G Berberich <berberic@forwiss.uni-passau.de> */ | ||
1916 | .name = "IDS Eagle", | ||
1917 | .video_inputs = 4, | ||
1918 | .audio_inputs = 0, | ||
1919 | .tuner = -1, | ||
1920 | .tuner_type = -1, | ||
1921 | .tuner_addr = ADDR_UNSET, | ||
1922 | .radio_addr = ADDR_UNSET, | ||
1923 | .svhs = -1, | ||
1924 | .gpiomask = 0, | ||
1925 | .muxsel = { 0, 1, 2, 3 }, | ||
1926 | .muxsel_hook = eagle_muxsel, | ||
1927 | .no_msp34xx = 1, | ||
1928 | .no_tda9875 = 1, | ||
1929 | .pll = PLL_28, | ||
1930 | }, | ||
1931 | [BTTV_BOARD_PINNACLESAT] = { | ||
1932 | .name = "Pinnacle PCTV Sat", | ||
1933 | .video_inputs = 2, | ||
1934 | .audio_inputs = 0, | ||
1935 | .svhs = 1, | ||
1936 | .tuner = -1, | ||
1937 | .tuner_type = -1, | ||
1938 | .tuner_addr = ADDR_UNSET, | ||
1939 | .radio_addr = ADDR_UNSET, | ||
1940 | .no_msp34xx = 1, | ||
1941 | .no_tda9875 = 1, | ||
1942 | .no_tda7432 = 1, | ||
1943 | .muxsel = { 3, 0, 1, 2}, | ||
1944 | .pll = PLL_28, | ||
1945 | .no_gpioirq = 1, | ||
1946 | .has_dvb = 1, | ||
1947 | }, | ||
1948 | [BTTV_BOARD_FORMAC_PROTV] = { | ||
1949 | .name = "Formac ProTV II (bt878)", | ||
1950 | .video_inputs = 4, | ||
1951 | .audio_inputs = 1, | ||
1952 | .tuner = 0, | ||
1953 | .svhs = 3, | ||
1954 | .gpiomask = 2, | ||
1955 | /* TV, Comp1, Composite over SVID con, SVID */ | ||
1956 | .muxsel = { 2, 3, 1, 1}, | ||
1957 | .audiomux = { 2, 2, 0, 0, 0 }, | ||
1958 | .pll = PLL_28, | ||
1959 | .has_radio = 1, | ||
1960 | .tuner_type = TUNER_PHILIPS_PAL, | ||
1961 | .tuner_addr = ADDR_UNSET, | ||
1962 | .radio_addr = ADDR_UNSET, | ||
1963 | /* sound routing: | ||
1964 | GPIO=0x00,0x01,0x03: mute (?) | ||
1965 | 0x02: both TV and radio (tuner: FM1216/I) | ||
1966 | The card has onboard audio connectors labeled "cdrom" and "board", | ||
1967 | not soldered here, though unknown wiring. | ||
1968 | Card lacks: external audio in, pci subsystem id. | ||
2358 | */ | 1969 | */ |
2359 | .name = "Kodicom 4400R (slave)", | 1970 | }, |
2360 | .video_inputs = 16, | 1971 | |
2361 | .audio_inputs = 0, | 1972 | /* ---- card 0x60 ---------------------------------- */ |
2362 | .tuner = -1, | 1973 | [BTTV_BOARD_MACHTV] = { |
2363 | .tuner_type = -1, | 1974 | .name = "MachTV", |
2364 | .tuner_addr = ADDR_UNSET, | 1975 | .video_inputs = 3, |
2365 | .svhs = -1, | 1976 | .audio_inputs = 1, |
2366 | .gpiomask = 0x010000, | 1977 | .tuner = 0, |
2367 | .no_gpioirq = 1, | 1978 | .svhs = -1, |
2368 | .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, | 1979 | .gpiomask = 7, |
2369 | .pll = PLL_28, | 1980 | .muxsel = { 2, 3, 1, 1}, |
2370 | .no_msp34xx = 1, | 1981 | .audiomux = { 0, 1, 2, 3, 4}, |
2371 | .no_tda7432 = 1, | 1982 | .needs_tvaudio = 1, |
2372 | .no_tda9875 = 1, | 1983 | .tuner_type = 5, |
2373 | .muxsel_hook = kodicom4400r_muxsel, | 1984 | .tuner_addr = ADDR_UNSET, |
2374 | }, | 1985 | .radio_addr = ADDR_UNSET, |
2375 | { | 1986 | .pll = PLL_28, |
2376 | /* ---- card 0x86---------------------------------- */ | 1987 | }, |
2377 | /* Michael Henson <mhenson@clarityvi.com> */ | 1988 | [BTTV_BOARD_EURESYS_PICOLO] = { |
2378 | /* Adlink RTV24 with special unlock codes */ | 1989 | .name = "Euresys Picolo", |
2379 | .name = "Adlink RTV24", | 1990 | .video_inputs = 3, |
2380 | .video_inputs = 4, | 1991 | .audio_inputs = 0, |
2381 | .audio_inputs = 1, | 1992 | .tuner = -1, |
2382 | .tuner = 0, | 1993 | .svhs = 2, |
2383 | .svhs = 2, | 1994 | .gpiomask = 0, |
2384 | .muxsel = { 2, 3, 1, 0}, | 1995 | .no_msp34xx = 1, |
2385 | .tuner_type = -1, | 1996 | .no_tda9875 = 1, |
2386 | .tuner_addr = ADDR_UNSET, | 1997 | .no_tda7432 = 1, |
2387 | .pll = PLL_28, | 1998 | .muxsel = { 2, 0, 1}, |
2388 | }, | 1999 | .pll = PLL_28, |
2389 | { | 2000 | .tuner_type = UNSET, |
2390 | /* ---- card 0x87---------------------------------- */ | 2001 | .tuner_addr = ADDR_UNSET, |
2391 | /* Michael Krufky <mkrufky@m1k.net> */ | 2002 | .radio_addr = ADDR_UNSET, |
2392 | .name = "DViCO FusionHDTV 5 Lite", | 2003 | }, |
2393 | .tuner = 0, | 2004 | [BTTV_BOARD_PV150] = { |
2394 | .tuner_type = TUNER_LG_TDVS_H062F, | 2005 | /* Luc Van Hoeylandt <luc@e-magic.be> */ |
2395 | .tuner_addr = ADDR_UNSET, | 2006 | .name = "ProVideo PV150", /* 0x4f */ |
2396 | .video_inputs = 3, | 2007 | .video_inputs = 2, |
2397 | .audio_inputs = 1, | 2008 | .audio_inputs = 0, |
2398 | .svhs = 2, | 2009 | .tuner = -1, |
2399 | .muxsel = { 2, 3, 1 }, | 2010 | .svhs = -1, |
2400 | .gpiomask = 0x00e00007, | 2011 | .gpiomask = 0, |
2401 | .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 }, | 2012 | .muxsel = { 2, 3 }, |
2402 | .no_msp34xx = 1, | 2013 | .audiomux = { 0 }, |
2403 | .no_tda9875 = 1, | 2014 | .needs_tvaudio = 0, |
2404 | .no_tda7432 = 1, | 2015 | .no_msp34xx = 1, |
2405 | },{ | 2016 | .pll = PLL_28, |
2406 | /* ---- card 0x88---------------------------------- */ | 2017 | .tuner_type = UNSET, |
2407 | /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */ | 2018 | .tuner_addr = ADDR_UNSET, |
2408 | .name = "Acorp Y878F", | 2019 | .radio_addr = ADDR_UNSET, |
2409 | .video_inputs = 3, | 2020 | }, |
2410 | .audio_inputs = 1, | 2021 | [BTTV_BOARD_AD_TVK503] = { |
2411 | .tuner = 0, | 2022 | /* Hiroshi Takekawa <sian@big.or.jp> */ |
2412 | .svhs = 2, | 2023 | /* This card lacks subsystem ID */ |
2413 | .gpiomask = 0x01fe00, | 2024 | .name = "AD-TVK503", /* 0x63 */ |
2414 | .muxsel = { 2, 3, 1, 1}, | 2025 | .video_inputs = 4, |
2415 | .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, | 2026 | .audio_inputs = 1, |
2416 | .needs_tvaudio = 1, | 2027 | .tuner = 0, |
2417 | .pll = PLL_28, | 2028 | .svhs = 2, |
2418 | .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, | 2029 | .gpiomask = 0x001e8007, |
2419 | .tuner_addr = 0xc1 >>1, | 2030 | .muxsel = { 2, 3, 1, 0 }, |
2420 | .has_radio = 1, | 2031 | /* Tuner, Radio, external, internal, off, on */ |
2421 | }}; | 2032 | .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 }, |
2033 | .needs_tvaudio = 0, | ||
2034 | .no_msp34xx = 1, | ||
2035 | .pll = PLL_28, | ||
2036 | .tuner_type = 2, | ||
2037 | .tuner_addr = ADDR_UNSET, | ||
2038 | .radio_addr = ADDR_UNSET, | ||
2039 | .audio_hook = adtvk503_audio, | ||
2040 | }, | ||
2041 | |||
2042 | /* ---- card 0x64 ---------------------------------- */ | ||
2043 | [BTTV_BOARD_HERCULES_SM_TV] = { | ||
2044 | .name = "Hercules Smart TV Stereo", | ||
2045 | .video_inputs = 4, | ||
2046 | .audio_inputs = 1, | ||
2047 | .tuner = 0, | ||
2048 | .svhs = 2, | ||
2049 | .gpiomask = 0x00, | ||
2050 | .muxsel = { 2, 3, 1, 1 }, | ||
2051 | .needs_tvaudio = 1, | ||
2052 | .no_msp34xx = 1, | ||
2053 | .pll = PLL_28, | ||
2054 | .tuner_type = 5, | ||
2055 | .tuner_addr = ADDR_UNSET, | ||
2056 | .radio_addr = ADDR_UNSET, | ||
2057 | /* Notes: | ||
2058 | - card lacks subsystem ID | ||
2059 | - stereo variant w/ daughter board with tda9874a @0xb0 | ||
2060 | - Audio Routing: | ||
2061 | always from tda9874 independent of GPIO (?) | ||
2062 | external line in: unknown | ||
2063 | - Other chips: em78p156elp @ 0x96 (probably IR remote control) | ||
2064 | hef4053 (instead 4052) for unknown function | ||
2065 | */ | ||
2066 | }, | ||
2067 | [BTTV_BOARD_PACETV] = { | ||
2068 | .name = "Pace TV & Radio Card", | ||
2069 | .video_inputs = 4, | ||
2070 | .audio_inputs = 1, | ||
2071 | .tuner = 0, | ||
2072 | .svhs = 2, | ||
2073 | .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */ | ||
2074 | .gpiomask = 0, | ||
2075 | .no_tda9875 = 1, | ||
2076 | .no_tda7432 = 1, | ||
2077 | .tuner_type = 1, | ||
2078 | .tuner_addr = ADDR_UNSET, | ||
2079 | .radio_addr = ADDR_UNSET, | ||
2080 | .has_radio = 1, | ||
2081 | .pll = PLL_28, | ||
2082 | /* Bt878, Bt832, FI1246 tuner; no pci subsystem id | ||
2083 | only internal line out: (4pin header) RGGL | ||
2084 | Radio must be decoded by msp3410d (not routed through)*/ | ||
2085 | /* | ||
2086 | .digital_mode = DIGITAL_MODE_CAMERA, todo! | ||
2087 | */ | ||
2088 | }, | ||
2089 | [BTTV_BOARD_IVC200] = { | ||
2090 | /* Chris Willing <chris@vislab.usyd.edu.au> */ | ||
2091 | .name = "IVC-200", | ||
2092 | .video_inputs = 1, | ||
2093 | .audio_inputs = 0, | ||
2094 | .tuner = -1, | ||
2095 | .tuner_type = -1, | ||
2096 | .tuner_addr = ADDR_UNSET, | ||
2097 | .radio_addr = ADDR_UNSET, | ||
2098 | .svhs = -1, | ||
2099 | .gpiomask = 0xdf, | ||
2100 | .muxsel = { 2 }, | ||
2101 | .pll = PLL_28, | ||
2102 | }, | ||
2103 | [BTTV_BOARD_XGUARD] = { | ||
2104 | .name = "Grand X-Guard / Trust 814PCI", | ||
2105 | .video_inputs = 16, | ||
2106 | .audio_inputs = 0, | ||
2107 | .tuner = -1, | ||
2108 | .svhs = -1, | ||
2109 | .tuner_type = 4, | ||
2110 | .tuner_addr = ADDR_UNSET, | ||
2111 | .radio_addr = ADDR_UNSET, | ||
2112 | .gpiomask2 = 0xff, | ||
2113 | .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 }, | ||
2114 | .muxsel_hook = xguard_muxsel, | ||
2115 | .no_msp34xx = 1, | ||
2116 | .no_tda9875 = 1, | ||
2117 | .no_tda7432 = 1, | ||
2118 | .pll = PLL_28, | ||
2119 | }, | ||
2120 | |||
2121 | /* ---- card 0x68 ---------------------------------- */ | ||
2122 | [BTTV_BOARD_NEBULA_DIGITV] = { | ||
2123 | .name = "Nebula Electronics DigiTV", | ||
2124 | .video_inputs = 1, | ||
2125 | .tuner = -1, | ||
2126 | .svhs = -1, | ||
2127 | .muxsel = { 2, 3, 1, 0}, | ||
2128 | .no_msp34xx = 1, | ||
2129 | .no_tda9875 = 1, | ||
2130 | .no_tda7432 = 1, | ||
2131 | .pll = PLL_28, | ||
2132 | .tuner_type = -1, | ||
2133 | .tuner_addr = ADDR_UNSET, | ||
2134 | .radio_addr = ADDR_UNSET, | ||
2135 | .has_dvb = 1, | ||
2136 | .no_gpioirq = 1, | ||
2137 | }, | ||
2138 | [BTTV_BOARD_PV143] = { | ||
2139 | /* Jorge Boncompte - DTI2 <jorge@dti2.net> */ | ||
2140 | .name = "ProVideo PV143", | ||
2141 | .video_inputs = 4, | ||
2142 | .audio_inputs = 0, | ||
2143 | .tuner = -1, | ||
2144 | .svhs = -1, | ||
2145 | .gpiomask = 0, | ||
2146 | .muxsel = { 2, 3, 1, 0 }, | ||
2147 | .audiomux = { 0 }, | ||
2148 | .needs_tvaudio = 0, | ||
2149 | .no_msp34xx = 1, | ||
2150 | .pll = PLL_28, | ||
2151 | .tuner_type = -1, | ||
2152 | .tuner_addr = ADDR_UNSET, | ||
2153 | .radio_addr = ADDR_UNSET, | ||
2154 | }, | ||
2155 | [BTTV_BOARD_VD009X1_MINIDIN] = { | ||
2156 | /* M.Klahr@phytec.de */ | ||
2157 | .name = "PHYTEC VD-009-X1 MiniDIN (bt878)", | ||
2158 | .video_inputs = 4, | ||
2159 | .audio_inputs = 0, | ||
2160 | .tuner = -1, /* card has no tuner */ | ||
2161 | .svhs = 3, | ||
2162 | .gpiomask = 0x00, | ||
2163 | .muxsel = { 2, 3, 1, 0}, | ||
2164 | .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ | ||
2165 | .needs_tvaudio = 1, | ||
2166 | .pll = PLL_28, | ||
2167 | .tuner_type = -1, | ||
2168 | .tuner_addr = ADDR_UNSET, | ||
2169 | .radio_addr = ADDR_UNSET, | ||
2170 | }, | ||
2171 | [BTTV_BOARD_VD009X1_COMBI] = { | ||
2172 | .name = "PHYTEC VD-009-X1 Combi (bt878)", | ||
2173 | .video_inputs = 4, | ||
2174 | .audio_inputs = 0, | ||
2175 | .tuner = -1, /* card has no tuner */ | ||
2176 | .svhs = 3, | ||
2177 | .gpiomask = 0x00, | ||
2178 | .muxsel = { 2, 3, 1, 1}, | ||
2179 | .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ | ||
2180 | .needs_tvaudio = 1, | ||
2181 | .pll = PLL_28, | ||
2182 | .tuner_type = -1, | ||
2183 | .tuner_addr = ADDR_UNSET, | ||
2184 | .radio_addr = ADDR_UNSET, | ||
2185 | }, | ||
2186 | |||
2187 | /* ---- card 0x6c ---------------------------------- */ | ||
2188 | [BTTV_BOARD_VD009_MINIDIN] = { | ||
2189 | .name = "PHYTEC VD-009 MiniDIN (bt878)", | ||
2190 | .video_inputs = 10, | ||
2191 | .audio_inputs = 0, | ||
2192 | .tuner = -1, /* card has no tuner */ | ||
2193 | .svhs = 9, | ||
2194 | .gpiomask = 0x00, | ||
2195 | .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio | ||
2196 | via the upper nibble of muxsel. here: used for | ||
2197 | xternal video-mux */ | ||
2198 | .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 }, | ||
2199 | .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ | ||
2200 | .needs_tvaudio = 1, | ||
2201 | .pll = PLL_28, | ||
2202 | .tuner_type = -1, | ||
2203 | .tuner_addr = ADDR_UNSET, | ||
2204 | .radio_addr = ADDR_UNSET, | ||
2205 | }, | ||
2206 | [BTTV_BOARD_VD009_COMBI] = { | ||
2207 | .name = "PHYTEC VD-009 Combi (bt878)", | ||
2208 | .video_inputs = 10, | ||
2209 | .audio_inputs = 0, | ||
2210 | .tuner = -1, /* card has no tuner */ | ||
2211 | .svhs = 9, | ||
2212 | .gpiomask = 0x00, | ||
2213 | .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio | ||
2214 | via the upper nibble of muxsel. here: used for | ||
2215 | xternal video-mux */ | ||
2216 | .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 }, | ||
2217 | .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ | ||
2218 | .needs_tvaudio = 1, | ||
2219 | .pll = PLL_28, | ||
2220 | .tuner_type = -1, | ||
2221 | .tuner_addr = ADDR_UNSET, | ||
2222 | .radio_addr = ADDR_UNSET, | ||
2223 | }, | ||
2224 | [BTTV_BOARD_IVC100] = { | ||
2225 | .name = "IVC-100", | ||
2226 | .video_inputs = 4, | ||
2227 | .audio_inputs = 0, | ||
2228 | .tuner = -1, | ||
2229 | .tuner_type = -1, | ||
2230 | .tuner_addr = ADDR_UNSET, | ||
2231 | .radio_addr = ADDR_UNSET, | ||
2232 | .svhs = -1, | ||
2233 | .gpiomask = 0xdf, | ||
2234 | .muxsel = { 2, 3, 1, 0 }, | ||
2235 | .pll = PLL_28, | ||
2236 | }, | ||
2237 | [BTTV_BOARD_IVC120] = { | ||
2238 | /* IVC-120G - Alan Garfield <alan@fromorbit.com> */ | ||
2239 | .name = "IVC-120G", | ||
2240 | .video_inputs = 16, | ||
2241 | .audio_inputs = 0, /* card has no audio */ | ||
2242 | .tuner = -1, /* card has no tuner */ | ||
2243 | .tuner_type = -1, | ||
2244 | .tuner_addr = ADDR_UNSET, | ||
2245 | .radio_addr = ADDR_UNSET, | ||
2246 | .svhs = -1, /* card has no svhs */ | ||
2247 | .needs_tvaudio = 0, | ||
2248 | .no_msp34xx = 1, | ||
2249 | .no_tda9875 = 1, | ||
2250 | .no_tda7432 = 1, | ||
2251 | .gpiomask = 0x00, | ||
2252 | .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, | ||
2253 | 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }, | ||
2254 | .muxsel_hook = ivc120_muxsel, | ||
2255 | .pll = PLL_28, | ||
2256 | }, | ||
2257 | |||
2258 | /* ---- card 0x70 ---------------------------------- */ | ||
2259 | [BTTV_BOARD_PC_HDTV] = { | ||
2260 | .name = "pcHDTV HD-2000 TV", | ||
2261 | .video_inputs = 4, | ||
2262 | .audio_inputs = 1, | ||
2263 | .tuner = 0, | ||
2264 | .svhs = 2, | ||
2265 | .muxsel = { 2, 3, 1, 0}, | ||
2266 | .tuner_type = TUNER_PHILIPS_ATSC, | ||
2267 | .tuner_addr = ADDR_UNSET, | ||
2268 | .radio_addr = ADDR_UNSET, | ||
2269 | .has_dvb = 1, | ||
2270 | }, | ||
2271 | [BTTV_BOARD_TWINHAN_DST] = { | ||
2272 | .name = "Twinhan DST + clones", | ||
2273 | .no_msp34xx = 1, | ||
2274 | .no_tda9875 = 1, | ||
2275 | .no_tda7432 = 1, | ||
2276 | .tuner_type = TUNER_ABSENT, | ||
2277 | .tuner_addr = ADDR_UNSET, | ||
2278 | .radio_addr = ADDR_UNSET, | ||
2279 | .no_video = 1, | ||
2280 | .has_dvb = 1, | ||
2281 | }, | ||
2282 | [BTTV_BOARD_WINFASTVC100] = { | ||
2283 | .name = "Winfast VC100", | ||
2284 | .video_inputs = 3, | ||
2285 | .audio_inputs = 0, | ||
2286 | .svhs = 1, | ||
2287 | .tuner = -1, | ||
2288 | .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */ | ||
2289 | .no_msp34xx = 1, | ||
2290 | .no_tda9875 = 1, | ||
2291 | .no_tda7432 = 1, | ||
2292 | .tuner_type = TUNER_ABSENT, | ||
2293 | .tuner_addr = ADDR_UNSET, | ||
2294 | .radio_addr = ADDR_UNSET, | ||
2295 | .pll = PLL_28, | ||
2296 | }, | ||
2297 | [BTTV_BOARD_TEV560] = { | ||
2298 | .name = "Teppro TEV-560/InterVision IV-560", | ||
2299 | .video_inputs = 3, | ||
2300 | .audio_inputs = 1, | ||
2301 | .tuner = 0, | ||
2302 | .svhs = 2, | ||
2303 | .gpiomask = 3, | ||
2304 | .muxsel = { 2, 3, 1, 1}, | ||
2305 | .audiomux = { 1, 1, 1, 1, 0}, | ||
2306 | .needs_tvaudio = 1, | ||
2307 | .tuner_type = TUNER_PHILIPS_PAL, | ||
2308 | .tuner_addr = ADDR_UNSET, | ||
2309 | .radio_addr = ADDR_UNSET, | ||
2310 | .pll = PLL_35, | ||
2311 | }, | ||
2312 | |||
2313 | /* ---- card 0x74 ---------------------------------- */ | ||
2314 | [BTTV_BOARD_SIMUS_GVC1100] = { | ||
2315 | .name = "SIMUS GVC1100", | ||
2316 | .video_inputs = 4, | ||
2317 | .audio_inputs = 0, | ||
2318 | .tuner = -1, | ||
2319 | .svhs = -1, | ||
2320 | .tuner_type = -1, | ||
2321 | .tuner_addr = ADDR_UNSET, | ||
2322 | .radio_addr = ADDR_UNSET, | ||
2323 | .pll = PLL_28, | ||
2324 | .muxsel = { 2, 2, 2, 2}, | ||
2325 | .gpiomask = 0x3F, | ||
2326 | .muxsel_hook = gvc1100_muxsel, | ||
2327 | }, | ||
2328 | [BTTV_BOARD_NGSTV_PLUS] = { | ||
2329 | /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */ | ||
2330 | .name = "NGS NGSTV+", | ||
2331 | .video_inputs = 3, | ||
2332 | .tuner = 0, | ||
2333 | .svhs = 2, | ||
2334 | .gpiomask = 0x008007, | ||
2335 | .muxsel = {2, 3, 0, 0}, | ||
2336 | .audiomux = {0, 0, 0, 0, 0x000003, 0}, | ||
2337 | .pll = PLL_28, | ||
2338 | .tuner_type = TUNER_PHILIPS_PAL, | ||
2339 | .tuner_addr = ADDR_UNSET, | ||
2340 | .radio_addr = ADDR_UNSET, | ||
2341 | .has_remote = 1, | ||
2342 | }, | ||
2343 | [BTTV_BOARD_LMLBT4] = { | ||
2344 | /* http://linuxmedialabs.com */ | ||
2345 | .name = "LMLBT4", | ||
2346 | .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ | ||
2347 | .audio_inputs = 0, | ||
2348 | .tuner = -1, | ||
2349 | .svhs = -1, | ||
2350 | .muxsel = { 2, 3, 1, 0 }, | ||
2351 | .no_msp34xx = 1, | ||
2352 | .no_tda9875 = 1, | ||
2353 | .no_tda7432 = 1, | ||
2354 | .needs_tvaudio = 0, | ||
2355 | .tuner_type = -1, | ||
2356 | .tuner_addr = ADDR_UNSET, | ||
2357 | .radio_addr = ADDR_UNSET, | ||
2358 | }, | ||
2359 | [BTTV_BOARD_TEKRAM_M205] = { | ||
2360 | /* Helmroos Harri <harri.helmroos@pp.inet.fi> */ | ||
2361 | .name = "Tekram M205 PRO", | ||
2362 | .video_inputs = 3, | ||
2363 | .audio_inputs = 1, | ||
2364 | .tuner = 0, | ||
2365 | .tuner_type = TUNER_PHILIPS_PAL, | ||
2366 | .tuner_addr = ADDR_UNSET, | ||
2367 | .radio_addr = ADDR_UNSET, | ||
2368 | .svhs = 2, | ||
2369 | .needs_tvaudio = 0, | ||
2370 | .gpiomask = 0x68, | ||
2371 | .muxsel = { 2, 3, 1}, | ||
2372 | .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 }, | ||
2373 | .pll = PLL_28, | ||
2374 | }, | ||
2375 | |||
2376 | /* ---- card 0x78 ---------------------------------- */ | ||
2377 | [BTTV_BOARD_CONTVFMI] = { | ||
2378 | /* Javier Cendan Ares <jcendan@lycos.es> */ | ||
2379 | /* bt878 TV + FM without subsystem ID */ | ||
2380 | .name = "Conceptronic CONTVFMi", | ||
2381 | .video_inputs = 3, | ||
2382 | .audio_inputs = 1, | ||
2383 | .tuner = 0, | ||
2384 | .svhs = 2, | ||
2385 | .gpiomask = 0x008007, | ||
2386 | .muxsel = { 2, 3, 1, 1 }, | ||
2387 | .audiomux = { 0, 1, 2, 2, 3 }, | ||
2388 | .needs_tvaudio = 0, | ||
2389 | .pll = PLL_28, | ||
2390 | .tuner_type = TUNER_PHILIPS_PAL, | ||
2391 | .tuner_addr = ADDR_UNSET, | ||
2392 | .radio_addr = ADDR_UNSET, | ||
2393 | .has_remote = 1, | ||
2394 | .has_radio = 1, | ||
2395 | }, | ||
2396 | [BTTV_BOARD_PICOLO_TETRA_CHIP] = { | ||
2397 | /*Eric DEBIEF <debief@telemsa.com>*/ | ||
2398 | /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/ | ||
2399 | /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_BOARD_PICOLO_TETRA_CHIP*/ | ||
2400 | /*0x79 in bttv.h*/ | ||
2401 | .name = "Euresys Picolo Tetra", | ||
2402 | .video_inputs = 4, | ||
2403 | .audio_inputs = 0, | ||
2404 | .tuner = -1, | ||
2405 | .svhs = -1, | ||
2406 | .gpiomask = 0, | ||
2407 | .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ | ||
2408 | .no_msp34xx = 1, | ||
2409 | .no_tda9875 = 1, | ||
2410 | .no_tda7432 = 1, | ||
2411 | .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/ | ||
2412 | .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ | ||
2413 | .pll = PLL_28, | ||
2414 | .needs_tvaudio = 0, | ||
2415 | .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ | ||
2416 | .tuner_type = -1, | ||
2417 | .tuner_addr = ADDR_UNSET, | ||
2418 | .radio_addr = ADDR_UNSET, | ||
2419 | }, | ||
2420 | [BTTV_BOARD_SPIRIT_TV] = { | ||
2421 | /* Spirit TV Tuner from http://spiritmodems.com.au */ | ||
2422 | /* Stafford Goodsell <surge@goliath.homeunix.org> */ | ||
2423 | .name = "Spirit TV Tuner", | ||
2424 | .video_inputs = 3, | ||
2425 | .audio_inputs = 1, | ||
2426 | .tuner = 0, | ||
2427 | .svhs = 2, | ||
2428 | .gpiomask = 0x0000000f, | ||
2429 | .muxsel = { 2, 1, 1 }, | ||
2430 | .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00}, | ||
2431 | .tuner_type = TUNER_TEMIC_PAL, | ||
2432 | .tuner_addr = ADDR_UNSET, | ||
2433 | .radio_addr = ADDR_UNSET, | ||
2434 | .no_msp34xx = 1, | ||
2435 | .no_tda9875 = 1, | ||
2436 | }, | ||
2437 | [BTTV_BOARD_AVDVBT_771] = { | ||
2438 | /* Wolfram Joost <wojo@frokaschwei.de> */ | ||
2439 | .name = "AVerMedia AVerTV DVB-T 771", | ||
2440 | .video_inputs = 2, | ||
2441 | .svhs = 1, | ||
2442 | .tuner = -1, | ||
2443 | .tuner_type = TUNER_ABSENT, | ||
2444 | .tuner_addr = ADDR_UNSET, | ||
2445 | .radio_addr = ADDR_UNSET, | ||
2446 | .muxsel = { 3 , 3 }, | ||
2447 | .no_msp34xx = 1, | ||
2448 | .no_tda9875 = 1, | ||
2449 | .no_tda7432 = 1, | ||
2450 | .pll = PLL_28, | ||
2451 | .has_dvb = 1, | ||
2452 | .no_gpioirq = 1, | ||
2453 | .has_remote = 1, | ||
2454 | }, | ||
2455 | /* ---- card 0x7c ---------------------------------- */ | ||
2456 | [BTTV_BOARD_AVDVBT_761] = { | ||
2457 | /* Matt Jesson <dvb@jesson.eclipse.co.uk> */ | ||
2458 | /* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */ | ||
2459 | .name = "AverMedia AverTV DVB-T 761", | ||
2460 | .video_inputs = 2, | ||
2461 | .tuner = -1, | ||
2462 | .svhs = 1, | ||
2463 | .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */ | ||
2464 | .no_msp34xx = 1, | ||
2465 | .no_tda9875 = 1, | ||
2466 | .no_tda7432 = 1, | ||
2467 | .pll = PLL_28, | ||
2468 | .tuner_type = -1, | ||
2469 | .tuner_addr = ADDR_UNSET, | ||
2470 | .radio_addr = ADDR_UNSET, | ||
2471 | .has_dvb = 1, | ||
2472 | .no_gpioirq = 1, | ||
2473 | .has_remote = 1, | ||
2474 | }, | ||
2475 | [BTTV_BOARD_MATRIX_VISIONSQ] = { | ||
2476 | /* andre.schwarz@matrix-vision.de */ | ||
2477 | .name = "MATRIX Vision Sigma-SQ", | ||
2478 | .video_inputs = 16, | ||
2479 | .audio_inputs = 0, | ||
2480 | .tuner = -1, | ||
2481 | .svhs = -1, | ||
2482 | .gpiomask = 0x0, | ||
2483 | .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, | ||
2484 | 3, 3, 3, 3, 3, 3, 3, 3 }, | ||
2485 | .muxsel_hook = sigmaSQ_muxsel, | ||
2486 | .audiomux = { 0 }, | ||
2487 | .no_msp34xx = 1, | ||
2488 | .pll = PLL_28, | ||
2489 | .tuner_type = -1, | ||
2490 | .tuner_addr = ADDR_UNSET, | ||
2491 | .radio_addr = ADDR_UNSET, | ||
2492 | }, | ||
2493 | [BTTV_BOARD_MATRIX_VISIONSLC] = { | ||
2494 | /* andre.schwarz@matrix-vision.de */ | ||
2495 | .name = "MATRIX Vision Sigma-SLC", | ||
2496 | .video_inputs = 4, | ||
2497 | .audio_inputs = 0, | ||
2498 | .tuner = -1, | ||
2499 | .svhs = -1, | ||
2500 | .gpiomask = 0x0, | ||
2501 | .muxsel = { 2, 2, 2, 2 }, | ||
2502 | .muxsel_hook = sigmaSLC_muxsel, | ||
2503 | .audiomux = { 0 }, | ||
2504 | .no_msp34xx = 1, | ||
2505 | .pll = PLL_28, | ||
2506 | .tuner_type = -1, | ||
2507 | .tuner_addr = ADDR_UNSET, | ||
2508 | .radio_addr = ADDR_UNSET, | ||
2509 | }, | ||
2510 | /* BTTV_BOARD_APAC_VIEWCOMP */ | ||
2511 | [BTTV_BOARD_APAC_VIEWCOMP] = { | ||
2512 | /* Attila Kondoros <attila.kondoros@chello.hu> */ | ||
2513 | /* bt878 TV + FM 0x00000000 subsystem ID */ | ||
2514 | .name = "APAC Viewcomp 878(AMAX)", | ||
2515 | .video_inputs = 2, | ||
2516 | .audio_inputs = 1, | ||
2517 | .tuner = 0, | ||
2518 | .svhs = -1, | ||
2519 | .gpiomask = 0xFF, | ||
2520 | .muxsel = { 2, 3, 1, 1}, | ||
2521 | .audiomux = { 2, 0, 0, 0, 10}, | ||
2522 | .needs_tvaudio = 0, | ||
2523 | .pll = PLL_28, | ||
2524 | .tuner_type = TUNER_PHILIPS_PAL, | ||
2525 | .tuner_addr = ADDR_UNSET, | ||
2526 | .radio_addr = ADDR_UNSET, | ||
2527 | .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */ | ||
2528 | .has_radio = 1, /* not every card has radio */ | ||
2529 | }, | ||
2530 | |||
2531 | /* ---- card 0x80 ---------------------------------- */ | ||
2532 | [BTTV_BOARD_DVICO_DVBT_LITE] = { | ||
2533 | /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */ | ||
2534 | .name = "DViCO FusionHDTV DVB-T Lite", | ||
2535 | .tuner = -1, | ||
2536 | .no_msp34xx = 1, | ||
2537 | .no_tda9875 = 1, | ||
2538 | .no_tda7432 = 1, | ||
2539 | .pll = PLL_28, | ||
2540 | .no_video = 1, | ||
2541 | .has_dvb = 1, | ||
2542 | .tuner_type = -1, | ||
2543 | .tuner_addr = ADDR_UNSET, | ||
2544 | .radio_addr = ADDR_UNSET, | ||
2545 | }, | ||
2546 | [BTTV_BOARD_VGEAR_MYVCD] = { | ||
2547 | /* Steven <photon38@pchome.com.tw> */ | ||
2548 | .name = "V-Gear MyVCD", | ||
2549 | .video_inputs = 3, | ||
2550 | .audio_inputs = 1, | ||
2551 | .tuner = 0, | ||
2552 | .svhs = 2, | ||
2553 | .gpiomask = 0x3f, | ||
2554 | .muxsel = {2, 3, 1, 0}, | ||
2555 | .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31}, | ||
2556 | .no_msp34xx = 1, | ||
2557 | .pll = PLL_28, | ||
2558 | .tuner_type = TUNER_PHILIPS_NTSC_M, | ||
2559 | .tuner_addr = ADDR_UNSET, | ||
2560 | .radio_addr = ADDR_UNSET, | ||
2561 | .has_radio = 0, | ||
2562 | #if 0 | ||
2563 | .has_remote = 1, | ||
2564 | #endif | ||
2565 | }, | ||
2566 | [BTTV_BOARD_SUPER_TV] = { | ||
2567 | /* Rick C <cryptdragoon@gmail.com> */ | ||
2568 | .name = "Super TV Tuner", | ||
2569 | .video_inputs = 4, | ||
2570 | .audio_inputs = 1, | ||
2571 | .tuner = 0, | ||
2572 | .svhs = 2, | ||
2573 | .muxsel = { 2, 3, 1, 0}, | ||
2574 | .tuner_type = TUNER_PHILIPS_NTSC, | ||
2575 | .tuner_addr = ADDR_UNSET, | ||
2576 | .radio_addr = ADDR_UNSET, | ||
2577 | .gpiomask = 0x008007, | ||
2578 | .audiomux = { 0, 0x000001,0,0, 0}, | ||
2579 | .needs_tvaudio = 1, | ||
2580 | .has_radio = 1, | ||
2581 | }, | ||
2582 | [BTTV_BOARD_TIBET_CS16] = { | ||
2583 | /* Chris Fanning <video4linux@haydon.net> */ | ||
2584 | .name = "Tibet Systems 'Progress DVR' CS16", | ||
2585 | .video_inputs = 16, | ||
2586 | .audio_inputs = 0, | ||
2587 | .tuner = -1, | ||
2588 | .svhs = -1, | ||
2589 | .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, | ||
2590 | .pll = PLL_28, | ||
2591 | .no_msp34xx = 1, | ||
2592 | .no_tda9875 = 1, | ||
2593 | .no_tda7432 = 1, | ||
2594 | .tuner_type = -1, | ||
2595 | .tuner_addr = ADDR_UNSET, | ||
2596 | .radio_addr = ADDR_UNSET, | ||
2597 | .muxsel_hook = tibetCS16_muxsel, | ||
2598 | }, | ||
2599 | [BTTV_BOARD_KODICOM_4400R] = { | ||
2600 | /* Bill Brack <wbrack@mmm.com.hk> */ | ||
2601 | /* | ||
2602 | * Note that, because of the card's wiring, the "master" | ||
2603 | * BT878A chip (i.e. the one which controls the analog switch | ||
2604 | * and must use this card type) is the 2nd one detected. The | ||
2605 | * other 3 chips should use card type 0x85, whose description | ||
2606 | * follows this one. There is a EEPROM on the card (which is | ||
2607 | * connected to the I2C of one of those other chips), but is | ||
2608 | * not currently handled. There is also a facility for a | ||
2609 | * "monitor", which is also not currently implemented. | ||
2610 | */ | ||
2611 | .name = "Kodicom 4400R (master)", | ||
2612 | .video_inputs = 16, | ||
2613 | .audio_inputs = 0, | ||
2614 | .tuner = -1, | ||
2615 | .tuner_type = -1, | ||
2616 | .tuner_addr = ADDR_UNSET, | ||
2617 | .radio_addr = ADDR_UNSET, | ||
2618 | .svhs = -1, | ||
2619 | /* GPIO bits 0-9 used for analog switch: | ||
2620 | * 00 - 03: camera selector | ||
2621 | * 04 - 06: channel (controller) selector | ||
2622 | * 07: data (1->on, 0->off) | ||
2623 | * 08: strobe | ||
2624 | * 09: reset | ||
2625 | * bit 16 is input from sync separator for the channel | ||
2626 | */ | ||
2627 | .gpiomask = 0x0003ff, | ||
2628 | .no_gpioirq = 1, | ||
2629 | .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, | ||
2630 | .pll = PLL_28, | ||
2631 | .no_msp34xx = 1, | ||
2632 | .no_tda7432 = 1, | ||
2633 | .no_tda9875 = 1, | ||
2634 | .muxsel_hook = kodicom4400r_muxsel, | ||
2635 | }, | ||
2636 | [BTTV_BOARD_KODICOM_4400R_SL] = { | ||
2637 | /* Bill Brack <wbrack@mmm.com.hk> */ | ||
2638 | /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the | ||
2639 | * one which controls the analog switch, and must use the card type) | ||
2640 | * is the 2nd one detected. The other 3 chips should use this card | ||
2641 | * type | ||
2642 | */ | ||
2643 | .name = "Kodicom 4400R (slave)", | ||
2644 | .video_inputs = 16, | ||
2645 | .audio_inputs = 0, | ||
2646 | .tuner = -1, | ||
2647 | .tuner_type = -1, | ||
2648 | .tuner_addr = ADDR_UNSET, | ||
2649 | .radio_addr = ADDR_UNSET, | ||
2650 | .svhs = -1, | ||
2651 | .gpiomask = 0x010000, | ||
2652 | .no_gpioirq = 1, | ||
2653 | .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, | ||
2654 | .pll = PLL_28, | ||
2655 | .no_msp34xx = 1, | ||
2656 | .no_tda7432 = 1, | ||
2657 | .no_tda9875 = 1, | ||
2658 | .muxsel_hook = kodicom4400r_muxsel, | ||
2659 | }, | ||
2660 | /* ---- card 0x86---------------------------------- */ | ||
2661 | [BTTV_BOARD_ADLINK_RTV24] = { | ||
2662 | /* Michael Henson <mhenson@clarityvi.com> */ | ||
2663 | /* Adlink RTV24 with special unlock codes */ | ||
2664 | .name = "Adlink RTV24", | ||
2665 | .video_inputs = 4, | ||
2666 | .audio_inputs = 1, | ||
2667 | .tuner = 0, | ||
2668 | .svhs = 2, | ||
2669 | .muxsel = { 2, 3, 1, 0}, | ||
2670 | .tuner_type = -1, | ||
2671 | .tuner_addr = ADDR_UNSET, | ||
2672 | .radio_addr = ADDR_UNSET, | ||
2673 | .pll = PLL_28, | ||
2674 | }, | ||
2675 | /* ---- card 0x87---------------------------------- */ | ||
2676 | [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = { | ||
2677 | /* Michael Krufky <mkrufky@m1k.net> */ | ||
2678 | .name = "DViCO FusionHDTV 5 Lite", | ||
2679 | .tuner = 0, | ||
2680 | .tuner_type = TUNER_LG_TDVS_H062F, | ||
2681 | .tuner_addr = ADDR_UNSET, | ||
2682 | .radio_addr = ADDR_UNSET, | ||
2683 | .video_inputs = 3, | ||
2684 | .audio_inputs = 1, | ||
2685 | .svhs = 2, | ||
2686 | .muxsel = { 2, 3, 1 }, | ||
2687 | .gpiomask = 0x00e00007, | ||
2688 | .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 }, | ||
2689 | .no_msp34xx = 1, | ||
2690 | .no_tda9875 = 1, | ||
2691 | .no_tda7432 = 1, | ||
2692 | .has_dvb = 1, | ||
2693 | }, | ||
2694 | /* ---- card 0x88---------------------------------- */ | ||
2695 | [BTTV_BOARD_ACORP_Y878F] = { | ||
2696 | /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */ | ||
2697 | .name = "Acorp Y878F", | ||
2698 | .video_inputs = 3, | ||
2699 | .audio_inputs = 1, | ||
2700 | .tuner = 0, | ||
2701 | .svhs = 2, | ||
2702 | .gpiomask = 0x01fe00, | ||
2703 | .muxsel = { 2, 3, 1, 1}, | ||
2704 | .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, | ||
2705 | .needs_tvaudio = 1, | ||
2706 | .pll = PLL_28, | ||
2707 | .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, | ||
2708 | .tuner_addr = 0xc1 >>1, | ||
2709 | .radio_addr = 0xc1 >>1, | ||
2710 | .has_radio = 1, | ||
2711 | }, | ||
2712 | /* ---- card 0x89 ---------------------------------- */ | ||
2713 | [BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = { | ||
2714 | .name = "Conceptronic CTVFMi v2", | ||
2715 | .video_inputs = 3, | ||
2716 | .audio_inputs = 1, | ||
2717 | .tuner = 0, | ||
2718 | .svhs = 2, | ||
2719 | .gpiomask = 0x001c0007, | ||
2720 | .muxsel = { 2, 3, 1, 1 }, | ||
2721 | .audiomux = { 0, 1, 2, 2, 3 }, | ||
2722 | .needs_tvaudio = 0, | ||
2723 | .pll = PLL_28, | ||
2724 | .tuner_type = TUNER_TENA_9533_DI, | ||
2725 | .tuner_addr = ADDR_UNSET, | ||
2726 | .radio_addr = ADDR_UNSET, | ||
2727 | .has_remote = 1, | ||
2728 | .has_radio = 1, | ||
2729 | }, | ||
2730 | /* ---- card 0x8a ---------------------------------- */ | ||
2731 | [BTTV_BOARD_PV_BT878P_2E] = { | ||
2732 | .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)", | ||
2733 | .video_inputs = 5, | ||
2734 | .audio_inputs = 1, | ||
2735 | .tuner = 0, | ||
2736 | .svhs = 3, | ||
2737 | .gpiomask = 0x01fe00, | ||
2738 | .muxsel = { 2,3,1,1,-1 }, | ||
2739 | .digital_mode = DIGITAL_MODE_CAMERA, | ||
2740 | .audiomux = { 0x00400, 0x10400, 0x04400, 0x80000, 0x12400, 0x46000 }, | ||
2741 | .no_msp34xx = 1, | ||
2742 | .pll = PLL_28, | ||
2743 | .tuner_type = TUNER_LG_PAL_FM, | ||
2744 | .tuner_addr = ADDR_UNSET, | ||
2745 | .radio_addr = ADDR_UNSET, | ||
2746 | .has_remote = 1, | ||
2747 | }, | ||
2748 | /* ---- card 0x8b ---------------------------------- */ | ||
2749 | [BTTV_BOARD_PV_M4900] = { | ||
2750 | /* Sérgio Fortier <sergiofortier@yahoo.com.br> */ | ||
2751 | .name = "Prolink PixelView PlayTV MPEG2 PV-M4900", | ||
2752 | .video_inputs = 3, | ||
2753 | .audio_inputs = 1, | ||
2754 | .tuner = 0, | ||
2755 | .svhs = 2, | ||
2756 | .gpiomask = 0x3f, | ||
2757 | .muxsel = { 2, 3, 1, 1 }, | ||
2758 | .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 }, | ||
2759 | .no_msp34xx = 1, | ||
2760 | .pll = PLL_28, | ||
2761 | .tuner_type = TUNER_YMEC_TVF_5533MF, | ||
2762 | .tuner_addr = ADDR_UNSET, | ||
2763 | .radio_addr = ADDR_UNSET, | ||
2764 | .has_radio = 1, | ||
2765 | .has_remote = 1, | ||
2766 | }, | ||
2767 | /* ---- card 0x8c ---------------------------------- */ | ||
2768 | [BTTV_BOARD_OSPREY440] = { | ||
2769 | .name = "Osprey 440", | ||
2770 | .video_inputs = 1, | ||
2771 | .audio_inputs = 1, | ||
2772 | .tuner = -1, | ||
2773 | .svhs = 1, | ||
2774 | .muxsel = { 2 }, | ||
2775 | .pll = PLL_28, | ||
2776 | .tuner_type = UNSET, | ||
2777 | .tuner_addr = ADDR_UNSET, | ||
2778 | .radio_addr = ADDR_UNSET, | ||
2779 | .no_msp34xx = 1, | ||
2780 | .no_tda9875 = 1, | ||
2781 | .no_tda7432 = 1, | ||
2782 | }, | ||
2783 | /* ---- card 0x8d ---------------------------------- */ | ||
2784 | [BTTV_BOARD_ASOUND_SKYEYE] = { | ||
2785 | .name = "Asound Skyeye PCTV", | ||
2786 | .video_inputs = 3, | ||
2787 | .audio_inputs = 1, | ||
2788 | .tuner = 0, | ||
2789 | .svhs = 2, | ||
2790 | .gpiomask = 15, | ||
2791 | .muxsel = { 2, 3, 1, 1}, | ||
2792 | .audiomux = {2,0,0,0,1}, | ||
2793 | .needs_tvaudio = 1, | ||
2794 | .pll = PLL_28, | ||
2795 | .tuner_type = 2, | ||
2796 | .tuner_addr = ADDR_UNSET, | ||
2797 | .radio_addr = ADDR_UNSET, | ||
2798 | }, | ||
2799 | |||
2800 | }; | ||
2422 | 2801 | ||
2423 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); | 2802 | static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); |
2424 | 2803 | ||
@@ -2461,7 +2840,7 @@ void __devinit bttv_idcard(struct bttv *btv) | |||
2461 | btv->c.nr, btv->cardid & 0xffff, | 2840 | btv->c.nr, btv->cardid & 0xffff, |
2462 | (btv->cardid >> 16) & 0xffff); | 2841 | (btv->cardid >> 16) & 0xffff); |
2463 | printk(KERN_DEBUG "please mail id, board name and " | 2842 | printk(KERN_DEBUG "please mail id, board name and " |
2464 | "the correct card= insmod option to kraxel@bytesex.org\n"); | 2843 | "the correct card= insmod option to video4linux-list@redhat.com\n"); |
2465 | } | 2844 | } |
2466 | } | 2845 | } |
2467 | 2846 | ||
@@ -2510,11 +2889,11 @@ void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256]) | |||
2510 | int type = -1; | 2889 | int type = -1; |
2511 | 2890 | ||
2512 | if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13)) | 2891 | if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13)) |
2513 | type = BTTV_MODTEC_205; | 2892 | type = BTTV_BOARD_MODTEC_205; |
2514 | else if (0 == strncmp(eeprom_data+20,"Picolo",7)) | 2893 | else if (0 == strncmp(eeprom_data+20,"Picolo",7)) |
2515 | type = BTTV_EURESYS_PICOLO; | 2894 | type = BTTV_BOARD_EURESYS_PICOLO; |
2516 | else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0) | 2895 | else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0) |
2517 | type = BTTV_HAUPPAUGE; /* old bt848 */ | 2896 | type = BTTV_BOARD_HAUPPAUGE; /* old bt848 */ |
2518 | 2897 | ||
2519 | if (-1 != type) { | 2898 | if (-1 != type) { |
2520 | btv->c.type = type; | 2899 | btv->c.type = type; |
@@ -2548,7 +2927,7 @@ static void flyvideo_gpio(struct bttv *btv) | |||
2548 | switch(ttype) { | 2927 | switch(ttype) { |
2549 | case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */ | 2928 | case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */ |
2550 | break; | 2929 | break; |
2551 | case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */ | 2930 | case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */ |
2552 | break; | 2931 | break; |
2553 | case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */ | 2932 | case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */ |
2554 | break; | 2933 | break; |
@@ -2564,7 +2943,7 @@ static void flyvideo_gpio(struct bttv *btv) | |||
2564 | has_radio = gpio & 0x400000; | 2943 | has_radio = gpio & 0x400000; |
2565 | /* unknown 0x200000; | 2944 | /* unknown 0x200000; |
2566 | * unknown2 0x100000; */ | 2945 | * unknown2 0x100000; */ |
2567 | is_capture_only = !(gpio & 0x008000); /* GPIO15 */ | 2946 | is_capture_only = !(gpio & 0x008000); /* GPIO15 */ |
2568 | has_tda9820_tda9821 = !(gpio & 0x004000); | 2947 | has_tda9820_tda9821 = !(gpio & 0x004000); |
2569 | is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */ | 2948 | is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */ |
2570 | /* | 2949 | /* |
@@ -2601,7 +2980,7 @@ static void miro_pinnacle_gpio(struct bttv *btv) | |||
2601 | char *info; | 2980 | char *info; |
2602 | 2981 | ||
2603 | gpio_inout(0xffffff, 0); | 2982 | gpio_inout(0xffffff, 0); |
2604 | gpio = gpio_read(); | 2983 | gpio = gpio_read(); |
2605 | id = ((gpio>>10) & 63) -1; | 2984 | id = ((gpio>>10) & 63) -1; |
2606 | msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx"); | 2985 | msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx"); |
2607 | if (id < 32) { | 2986 | if (id < 32) { |
@@ -2620,10 +2999,10 @@ static void miro_pinnacle_gpio(struct bttv *btv) | |||
2620 | btv->has_radio = 0; | 2999 | btv->has_radio = 0; |
2621 | } | 3000 | } |
2622 | if (-1 != msp) { | 3001 | if (-1 != msp) { |
2623 | if (btv->c.type == BTTV_MIRO) | 3002 | if (btv->c.type == BTTV_BOARD_MIRO) |
2624 | btv->c.type = BTTV_MIROPRO; | 3003 | btv->c.type = BTTV_BOARD_MIROPRO; |
2625 | if (btv->c.type == BTTV_PINNACLE) | 3004 | if (btv->c.type == BTTV_BOARD_PINNACLE) |
2626 | btv->c.type = BTTV_PINNACLEPRO; | 3005 | btv->c.type = BTTV_BOARD_PINNACLEPRO; |
2627 | } | 3006 | } |
2628 | printk(KERN_INFO | 3007 | printk(KERN_INFO |
2629 | "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n", | 3008 | "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n", |
@@ -2664,7 +3043,7 @@ static void miro_pinnacle_gpio(struct bttv *btv) | |||
2664 | break; | 3043 | break; |
2665 | } | 3044 | } |
2666 | if (-1 != msp) | 3045 | if (-1 != msp) |
2667 | btv->c.type = BTTV_PINNACLEPRO; | 3046 | btv->c.type = BTTV_BOARD_PINNACLEPRO; |
2668 | printk(KERN_INFO | 3047 | printk(KERN_INFO |
2669 | "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n", | 3048 | "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n", |
2670 | btv->c.nr, id, info, btv->has_radio ? "yes" : "no"); | 3049 | btv->c.nr, id, info, btv->has_radio ? "yes" : "no"); |
@@ -2712,7 +3091,7 @@ static void eagle_muxsel(struct bttv *btv, unsigned int input) | |||
2712 | 3091 | ||
2713 | static void gvc1100_muxsel(struct bttv *btv, unsigned int input) | 3092 | static void gvc1100_muxsel(struct bttv *btv, unsigned int input) |
2714 | { | 3093 | { |
2715 | static const int masks[] = {0x30, 0x01, 0x12, 0x23}; | 3094 | static const int masks[] = {0x30, 0x01, 0x12, 0x23}; |
2716 | gpio_write(masks[input%4]); | 3095 | gpio_write(masks[input%4]); |
2717 | } | 3096 | } |
2718 | 3097 | ||
@@ -2778,26 +3157,27 @@ static void bttv_reset_audio(struct bttv *btv) | |||
2778 | void __devinit bttv_init_card1(struct bttv *btv) | 3157 | void __devinit bttv_init_card1(struct bttv *btv) |
2779 | { | 3158 | { |
2780 | switch (btv->c.type) { | 3159 | switch (btv->c.type) { |
2781 | case BTTV_HAUPPAUGE: | 3160 | case BTTV_BOARD_HAUPPAUGE: |
2782 | case BTTV_HAUPPAUGE878: | 3161 | case BTTV_BOARD_HAUPPAUGE878: |
2783 | boot_msp34xx(btv,5); | 3162 | boot_msp34xx(btv,5); |
2784 | break; | 3163 | break; |
2785 | case BTTV_VOODOOTV_FM: | 3164 | case BTTV_BOARD_VOODOOTV_FM: |
2786 | boot_msp34xx(btv,20); | 3165 | boot_msp34xx(btv,20); |
2787 | break; | 3166 | break; |
2788 | case BTTV_AVERMEDIA98: | 3167 | case BTTV_BOARD_AVERMEDIA98: |
2789 | boot_msp34xx(btv,11); | 3168 | boot_msp34xx(btv,11); |
2790 | break; | 3169 | break; |
2791 | case BTTV_HAUPPAUGEPVR: | 3170 | case BTTV_BOARD_HAUPPAUGEPVR: |
2792 | pvr_boot(btv); | 3171 | pvr_boot(btv); |
2793 | break; | 3172 | break; |
2794 | case BTTV_TWINHAN_DST: | 3173 | case BTTV_BOARD_TWINHAN_DST: |
2795 | case BTTV_AVDVBT_771: | 3174 | case BTTV_BOARD_AVDVBT_771: |
3175 | case BTTV_BOARD_PINNACLESAT: | ||
2796 | btv->use_i2c_hw = 1; | 3176 | btv->use_i2c_hw = 1; |
2797 | break; | 3177 | break; |
2798 | case BTTV_ADLINK_RTV24: | 3178 | case BTTV_BOARD_ADLINK_RTV24: |
2799 | init_RTV24( btv ); | 3179 | init_RTV24( btv ); |
2800 | break; | 3180 | break; |
2801 | 3181 | ||
2802 | } | 3182 | } |
2803 | if (!bttv_tvcards[btv->c.type].has_dvb) | 3183 | if (!bttv_tvcards[btv->c.type].has_dvb) |
@@ -2810,53 +3190,53 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
2810 | int tda9887; | 3190 | int tda9887; |
2811 | int addr=ADDR_UNSET; | 3191 | int addr=ADDR_UNSET; |
2812 | 3192 | ||
2813 | btv->tuner_type = -1; | 3193 | btv->tuner_type = -1; |
2814 | 3194 | ||
2815 | if (BTTV_UNKNOWN == btv->c.type) { | 3195 | if (BTTV_BOARD_UNKNOWN == btv->c.type) { |
2816 | bttv_readee(btv,eeprom_data,0xa0); | 3196 | bttv_readee(btv,eeprom_data,0xa0); |
2817 | identify_by_eeprom(btv,eeprom_data); | 3197 | identify_by_eeprom(btv,eeprom_data); |
2818 | } | 3198 | } |
2819 | 3199 | ||
2820 | switch (btv->c.type) { | 3200 | switch (btv->c.type) { |
2821 | case BTTV_MIRO: | 3201 | case BTTV_BOARD_MIRO: |
2822 | case BTTV_MIROPRO: | 3202 | case BTTV_BOARD_MIROPRO: |
2823 | case BTTV_PINNACLE: | 3203 | case BTTV_BOARD_PINNACLE: |
2824 | case BTTV_PINNACLEPRO: | 3204 | case BTTV_BOARD_PINNACLEPRO: |
2825 | /* miro/pinnacle */ | 3205 | /* miro/pinnacle */ |
2826 | miro_pinnacle_gpio(btv); | 3206 | miro_pinnacle_gpio(btv); |
2827 | break; | 3207 | break; |
2828 | case BTTV_FLYVIDEO_98: | 3208 | case BTTV_BOARD_FLYVIDEO_98: |
2829 | case BTTV_MAXI: | 3209 | case BTTV_BOARD_MAXI: |
2830 | case BTTV_LIFE_FLYKIT: | 3210 | case BTTV_BOARD_LIFE_FLYKIT: |
2831 | case BTTV_FLYVIDEO: | 3211 | case BTTV_BOARD_FLYVIDEO: |
2832 | case BTTV_TYPHOON_TVIEW: | 3212 | case BTTV_BOARD_TYPHOON_TVIEW: |
2833 | case BTTV_CHRONOS_VS2: | 3213 | case BTTV_BOARD_CHRONOS_VS2: |
2834 | case BTTV_FLYVIDEO_98FM: | 3214 | case BTTV_BOARD_FLYVIDEO_98FM: |
2835 | case BTTV_FLYVIDEO2000: | 3215 | case BTTV_BOARD_FLYVIDEO2000: |
2836 | case BTTV_FLYVIDEO98EZ: | 3216 | case BTTV_BOARD_FLYVIDEO98EZ: |
2837 | case BTTV_CONFERENCETV: | 3217 | case BTTV_BOARD_CONFERENCETV: |
2838 | case BTTV_LIFETEC_9415: | 3218 | case BTTV_BOARD_LIFETEC_9415: |
2839 | flyvideo_gpio(btv); | 3219 | flyvideo_gpio(btv); |
2840 | break; | 3220 | break; |
2841 | case BTTV_HAUPPAUGE: | 3221 | case BTTV_BOARD_HAUPPAUGE: |
2842 | case BTTV_HAUPPAUGE878: | 3222 | case BTTV_BOARD_HAUPPAUGE878: |
2843 | case BTTV_HAUPPAUGEPVR: | 3223 | case BTTV_BOARD_HAUPPAUGEPVR: |
2844 | /* pick up some config infos from the eeprom */ | 3224 | /* pick up some config infos from the eeprom */ |
2845 | bttv_readee(btv,eeprom_data,0xa0); | 3225 | bttv_readee(btv,eeprom_data,0xa0); |
2846 | hauppauge_eeprom(btv); | 3226 | hauppauge_eeprom(btv); |
2847 | break; | 3227 | break; |
2848 | case BTTV_AVERMEDIA98: | 3228 | case BTTV_BOARD_AVERMEDIA98: |
2849 | case BTTV_AVPHONE98: | 3229 | case BTTV_BOARD_AVPHONE98: |
2850 | bttv_readee(btv,eeprom_data,0xa0); | 3230 | bttv_readee(btv,eeprom_data,0xa0); |
2851 | avermedia_eeprom(btv); | 3231 | avermedia_eeprom(btv); |
2852 | break; | 3232 | break; |
2853 | case BTTV_PXC200: | 3233 | case BTTV_BOARD_PXC200: |
2854 | init_PXC200(btv); | 3234 | init_PXC200(btv); |
2855 | break; | 3235 | break; |
2856 | case BTTV_PICOLO_TETRA_CHIP: | 3236 | case BTTV_BOARD_PICOLO_TETRA_CHIP: |
2857 | picolo_tetra_init(btv); | 3237 | picolo_tetra_init(btv); |
2858 | break; | 3238 | break; |
2859 | case BTTV_VHX: | 3239 | case BTTV_BOARD_VHX: |
2860 | btv->has_radio = 1; | 3240 | btv->has_radio = 1; |
2861 | btv->has_matchbox = 1; | 3241 | btv->has_matchbox = 1; |
2862 | btv->mbox_we = 0x20; | 3242 | btv->mbox_we = 0x20; |
@@ -2865,58 +3245,58 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
2865 | btv->mbox_data = 0x10; | 3245 | btv->mbox_data = 0x10; |
2866 | btv->mbox_mask = 0x38; | 3246 | btv->mbox_mask = 0x38; |
2867 | break; | 3247 | break; |
2868 | case BTTV_VOBIS_BOOSTAR: | 3248 | case BTTV_BOARD_VOBIS_BOOSTAR: |
2869 | case BTTV_TERRATV: | 3249 | case BTTV_BOARD_TERRATV: |
2870 | terratec_active_radio_upgrade(btv); | 3250 | terratec_active_radio_upgrade(btv); |
2871 | break; | 3251 | break; |
2872 | case BTTV_MAGICTVIEW061: | 3252 | case BTTV_BOARD_MAGICTVIEW061: |
2873 | if (btv->cardid == 0x3002144f) { | 3253 | if (btv->cardid == 0x3002144f) { |
2874 | btv->has_radio=1; | 3254 | btv->has_radio=1; |
2875 | printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr); | 3255 | printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr); |
2876 | } | 3256 | } |
2877 | break; | 3257 | break; |
2878 | case BTTV_STB2: | 3258 | case BTTV_BOARD_STB2: |
2879 | if (btv->cardid == 0x3060121a) { | 3259 | if (btv->cardid == 0x3060121a) { |
2880 | /* Fix up entry for 3DFX VoodooTV 100, | 3260 | /* Fix up entry for 3DFX VoodooTV 100, |
2881 | which is an OEM STB card variant. */ | 3261 | which is an OEM STB card variant. */ |
2882 | btv->has_radio=0; | 3262 | btv->has_radio=0; |
2883 | btv->tuner_type=TUNER_TEMIC_NTSC; | 3263 | btv->tuner_type=TUNER_TEMIC_NTSC; |
2884 | } | 3264 | } |
2885 | break; | 3265 | break; |
2886 | case BTTV_OSPREY1x0: | 3266 | case BTTV_BOARD_OSPREY1x0: |
2887 | case BTTV_OSPREY1x0_848: | 3267 | case BTTV_BOARD_OSPREY1x0_848: |
2888 | case BTTV_OSPREY101_848: | 3268 | case BTTV_BOARD_OSPREY101_848: |
2889 | case BTTV_OSPREY1x1: | 3269 | case BTTV_BOARD_OSPREY1x1: |
2890 | case BTTV_OSPREY1x1_SVID: | 3270 | case BTTV_BOARD_OSPREY1x1_SVID: |
2891 | case BTTV_OSPREY2xx: | 3271 | case BTTV_BOARD_OSPREY2xx: |
2892 | case BTTV_OSPREY2x0_SVID: | 3272 | case BTTV_BOARD_OSPREY2x0_SVID: |
2893 | case BTTV_OSPREY2x0: | 3273 | case BTTV_BOARD_OSPREY2x0: |
2894 | case BTTV_OSPREY500: | 3274 | case BTTV_BOARD_OSPREY500: |
2895 | case BTTV_OSPREY540: | 3275 | case BTTV_BOARD_OSPREY540: |
2896 | case BTTV_OSPREY2000: | 3276 | case BTTV_BOARD_OSPREY2000: |
2897 | bttv_readee(btv,eeprom_data,0xa0); | 3277 | bttv_readee(btv,eeprom_data,0xa0); |
2898 | osprey_eeprom(btv); | 3278 | osprey_eeprom(btv); |
2899 | break; | 3279 | break; |
2900 | case BTTV_IDS_EAGLE: | 3280 | case BTTV_BOARD_IDS_EAGLE: |
2901 | init_ids_eagle(btv); | 3281 | init_ids_eagle(btv); |
2902 | break; | 3282 | break; |
2903 | case BTTV_MODTEC_205: | 3283 | case BTTV_BOARD_MODTEC_205: |
2904 | bttv_readee(btv,eeprom_data,0xa0); | 3284 | bttv_readee(btv,eeprom_data,0xa0); |
2905 | modtec_eeprom(btv); | 3285 | modtec_eeprom(btv); |
2906 | break; | 3286 | break; |
2907 | case BTTV_LMLBT4: | 3287 | case BTTV_BOARD_LMLBT4: |
2908 | init_lmlbt4x(btv); | 3288 | init_lmlbt4x(btv); |
2909 | break; | 3289 | break; |
2910 | case BTTV_TIBET_CS16: | 3290 | case BTTV_BOARD_TIBET_CS16: |
2911 | tibetCS16_init(btv); | 3291 | tibetCS16_init(btv); |
2912 | break; | 3292 | break; |
2913 | case BTTV_KODICOM_4400R: | 3293 | case BTTV_BOARD_KODICOM_4400R: |
2914 | kodicom4400r_init(btv); | 3294 | kodicom4400r_init(btv); |
2915 | break; | 3295 | break; |
2916 | } | 3296 | } |
2917 | 3297 | ||
2918 | /* pll configuration */ | 3298 | /* pll configuration */ |
2919 | if (!(btv->id==848 && btv->revision==0x11)) { | 3299 | if (!(btv->id==848 && btv->revision==0x11)) { |
2920 | /* defaults from card list */ | 3300 | /* defaults from card list */ |
2921 | if (PLL_28 == bttv_tvcards[btv->c.type].pll) { | 3301 | if (PLL_28 == bttv_tvcards[btv->c.type].pll) { |
2922 | btv->pll.pll_ifreq=28636363; | 3302 | btv->pll.pll_ifreq=28636363; |
@@ -2927,26 +3307,26 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
2927 | btv->pll.pll_crystal=BT848_IFORM_XT1; | 3307 | btv->pll.pll_crystal=BT848_IFORM_XT1; |
2928 | } | 3308 | } |
2929 | /* insmod options can override */ | 3309 | /* insmod options can override */ |
2930 | switch (pll[btv->c.nr]) { | 3310 | switch (pll[btv->c.nr]) { |
2931 | case 0: /* none */ | 3311 | case 0: /* none */ |
2932 | btv->pll.pll_crystal = 0; | 3312 | btv->pll.pll_crystal = 0; |
2933 | btv->pll.pll_ifreq = 0; | 3313 | btv->pll.pll_ifreq = 0; |
2934 | btv->pll.pll_ofreq = 0; | 3314 | btv->pll.pll_ofreq = 0; |
2935 | break; | 3315 | break; |
2936 | case 1: /* 28 MHz */ | 3316 | case 1: /* 28 MHz */ |
2937 | case 28: | 3317 | case 28: |
2938 | btv->pll.pll_ifreq = 28636363; | 3318 | btv->pll.pll_ifreq = 28636363; |
2939 | btv->pll.pll_ofreq = 0; | 3319 | btv->pll.pll_ofreq = 0; |
2940 | btv->pll.pll_crystal = BT848_IFORM_XT0; | 3320 | btv->pll.pll_crystal = BT848_IFORM_XT0; |
2941 | break; | 3321 | break; |
2942 | case 2: /* 35 MHz */ | 3322 | case 2: /* 35 MHz */ |
2943 | case 35: | 3323 | case 35: |
2944 | btv->pll.pll_ifreq = 35468950; | 3324 | btv->pll.pll_ifreq = 35468950; |
2945 | btv->pll.pll_ofreq = 0; | 3325 | btv->pll.pll_ofreq = 0; |
2946 | btv->pll.pll_crystal = BT848_IFORM_XT1; | 3326 | btv->pll.pll_crystal = BT848_IFORM_XT1; |
2947 | break; | 3327 | break; |
2948 | } | 3328 | } |
2949 | } | 3329 | } |
2950 | btv->pll.pll_current = -1; | 3330 | btv->pll.pll_current = -1; |
2951 | 3331 | ||
2952 | /* tuner configuration (from card list / autodetect / insmod option) */ | 3332 | /* tuner configuration (from card list / autodetect / insmod option) */ |
@@ -2955,23 +3335,26 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
2955 | 3335 | ||
2956 | if (UNSET != bttv_tvcards[btv->c.type].tuner_type) | 3336 | if (UNSET != bttv_tvcards[btv->c.type].tuner_type) |
2957 | if(UNSET == btv->tuner_type) | 3337 | if(UNSET == btv->tuner_type) |
2958 | btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; | 3338 | btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; |
2959 | if (UNSET != tuner[btv->c.nr]) | 3339 | if (UNSET != tuner[btv->c.nr]) |
2960 | btv->tuner_type = tuner[btv->c.nr]; | 3340 | btv->tuner_type = tuner[btv->c.nr]; |
2961 | printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type); | 3341 | printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type); |
2962 | if (btv->pinnacle_id != UNSET) | 3342 | |
2963 | bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE, | ||
2964 | &btv->pinnacle_id); | ||
2965 | if (btv->tuner_type != UNSET) { | 3343 | if (btv->tuner_type != UNSET) { |
2966 | struct tuner_setup tun_setup; | 3344 | struct tuner_setup tun_setup; |
2967 | 3345 | ||
2968 | tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; | 3346 | tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; |
2969 | tun_setup.type = btv->tuner_type; | 3347 | tun_setup.type = btv->tuner_type; |
2970 | tun_setup.addr = addr; | 3348 | tun_setup.addr = addr; |
2971 | 3349 | ||
2972 | bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); | 3350 | bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); |
2973 | } | 3351 | } |
2974 | 3352 | ||
3353 | if (btv->pinnacle_id != UNSET) { | ||
3354 | bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE, | ||
3355 | &btv->pinnacle_id); | ||
3356 | } | ||
3357 | |||
2975 | btv->svhs = bttv_tvcards[btv->c.type].svhs; | 3358 | btv->svhs = bttv_tvcards[btv->c.type].svhs; |
2976 | if (svhs[btv->c.nr] != UNSET) | 3359 | if (svhs[btv->c.nr] != UNSET) |
2977 | btv->svhs = svhs[btv->c.nr]; | 3360 | btv->svhs = svhs[btv->c.nr]; |
@@ -2982,8 +3365,8 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
2982 | btv->has_radio=1; | 3365 | btv->has_radio=1; |
2983 | if (bttv_tvcards[btv->c.type].has_remote) | 3366 | if (bttv_tvcards[btv->c.type].has_remote) |
2984 | btv->has_remote=1; | 3367 | btv->has_remote=1; |
2985 | if (bttv_tvcards[btv->c.type].no_gpioirq) | 3368 | if (!bttv_tvcards[btv->c.type].no_gpioirq) |
2986 | btv->gpioirq=0; | 3369 | btv->gpioirq=1; |
2987 | if (bttv_tvcards[btv->c.type].audio_hook) | 3370 | if (bttv_tvcards[btv->c.type].audio_hook) |
2988 | btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; | 3371 | btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; |
2989 | 3372 | ||
@@ -3024,6 +3407,9 @@ void __devinit bttv_init_card2(struct bttv *btv) | |||
3024 | if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && | 3407 | if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && |
3025 | bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0) | 3408 | bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0) |
3026 | tda9887 = 1; | 3409 | tda9887 = 1; |
3410 | /* Hybrid DVB card, DOES have a tda9887 */ | ||
3411 | if (btv->c.type == BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE) | ||
3412 | tda9887 = 1; | ||
3027 | if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) || | 3413 | if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) || |
3028 | (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) || | 3414 | (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) || |
3029 | (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) || | 3415 | (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) || |
@@ -3045,11 +3431,11 @@ static void modtec_eeprom(struct bttv *btv) | |||
3045 | } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) { | 3431 | } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) { |
3046 | btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I; | 3432 | btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I; |
3047 | printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", | 3433 | printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", |
3048 | btv->c.nr,&eeprom_data[0x1e]); | 3434 | btv->c.nr,&eeprom_data[0x1e]); |
3049 | } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) { | 3435 | } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) { |
3050 | btv->tuner_type=TUNER_PHILIPS_NTSC; | 3436 | btv->tuner_type=TUNER_PHILIPS_NTSC; |
3051 | printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", | 3437 | printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", |
3052 | btv->c.nr,&eeprom_data[0x1e]); | 3438 | btv->c.nr,&eeprom_data[0x1e]); |
3053 | } else { | 3439 | } else { |
3054 | printk("bttv%d: Modtec: Unknown TunerString: %s\n", | 3440 | printk("bttv%d: Modtec: Unknown TunerString: %s\n", |
3055 | btv->c.nr,&eeprom_data[0x1e]); | 3441 | btv->c.nr,&eeprom_data[0x1e]); |
@@ -3114,7 +3500,7 @@ static int terratec_active_radio_upgrade(struct bttv *btv) | |||
3114 | static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen) | 3500 | static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen) |
3115 | { | 3501 | { |
3116 | u32 n; | 3502 | u32 n; |
3117 | u8 bits; | 3503 | u8 bits; |
3118 | int i; | 3504 | int i; |
3119 | 3505 | ||
3120 | gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG); | 3506 | gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG); |
@@ -3150,19 +3536,19 @@ static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen) | |||
3150 | 3536 | ||
3151 | static int __devinit pvr_boot(struct bttv *btv) | 3537 | static int __devinit pvr_boot(struct bttv *btv) |
3152 | { | 3538 | { |
3153 | const struct firmware *fw_entry; | 3539 | const struct firmware *fw_entry; |
3154 | int rc; | 3540 | int rc; |
3155 | 3541 | ||
3156 | rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev); | 3542 | rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev); |
3157 | if (rc != 0) { | 3543 | if (rc != 0) { |
3158 | printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n", | 3544 | printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n", |
3159 | btv->c.nr); | 3545 | btv->c.nr); |
3160 | return rc; | 3546 | return rc; |
3161 | } | 3547 | } |
3162 | rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size); | 3548 | rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size); |
3163 | printk(KERN_INFO "bttv%d: altera firmware upload %s\n", | 3549 | printk(KERN_INFO "bttv%d: altera firmware upload %s\n", |
3164 | btv->c.nr, (rc < 0) ? "failed" : "ok"); | 3550 | btv->c.nr, (rc < 0) ? "failed" : "ok"); |
3165 | release_firmware(fw_entry); | 3551 | release_firmware(fw_entry); |
3166 | return rc; | 3552 | return rc; |
3167 | } | 3553 | } |
3168 | 3554 | ||
@@ -3176,33 +3562,33 @@ static void __devinit osprey_eeprom(struct bttv *btv) | |||
3176 | unsigned long serial = 0; | 3562 | unsigned long serial = 0; |
3177 | 3563 | ||
3178 | if (btv->c.type == 0) { | 3564 | if (btv->c.type == 0) { |
3179 | /* this might be an antique... check for MMAC label in eeprom */ | 3565 | /* this might be an antique... check for MMAC label in eeprom */ |
3180 | if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) { | 3566 | if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) { |
3181 | unsigned char checksum = 0; | 3567 | unsigned char checksum = 0; |
3182 | for (i =0; i<21; i++) | 3568 | for (i =0; i<21; i++) |
3183 | checksum += ee[i]; | 3569 | checksum += ee[i]; |
3184 | if (checksum != ee[21]) | 3570 | if (checksum != ee[21]) |
3185 | return; | 3571 | return; |
3186 | btv->c.type = BTTV_OSPREY1x0_848; | 3572 | btv->c.type = BTTV_BOARD_OSPREY1x0_848; |
3187 | for (i = 12; i < 21; i++) | 3573 | for (i = 12; i < 21; i++) |
3188 | serial *= 10, serial += ee[i] - '0'; | 3574 | serial *= 10, serial += ee[i] - '0'; |
3189 | } | 3575 | } |
3190 | } else { | 3576 | } else { |
3191 | unsigned short type; | 3577 | unsigned short type; |
3192 | int offset = 4*16; | 3578 | int offset = 4*16; |
3193 | 3579 | ||
3194 | for(; offset < 8*16; offset += 16) { | 3580 | for(; offset < 8*16; offset += 16) { |
3195 | unsigned short checksum = 0; | 3581 | unsigned short checksum = 0; |
3196 | /* verify the checksum */ | 3582 | /* verify the checksum */ |
3197 | for(i = 0; i<14; i++) checksum += ee[i+offset]; | 3583 | for(i = 0; i<14; i++) checksum += ee[i+offset]; |
3198 | checksum = ~checksum; /* no idea why */ | 3584 | checksum = ~checksum; /* no idea why */ |
3199 | if ((((checksum>>8)&0x0FF) == ee[offset+14]) && | 3585 | if ((((checksum>>8)&0x0FF) == ee[offset+14]) && |
3200 | ((checksum & 0x0FF) == ee[offset+15])) { | 3586 | ((checksum & 0x0FF) == ee[offset+15])) { |
3201 | break; | 3587 | break; |
3202 | } | 3588 | } |
3203 | } | 3589 | } |
3204 | 3590 | ||
3205 | if (offset >= 8*16) | 3591 | if (offset >= 8*16) |
3206 | return; | 3592 | return; |
3207 | 3593 | ||
3208 | /* found a valid descriptor */ | 3594 | /* found a valid descriptor */ |
@@ -3212,47 +3598,47 @@ static void __devinit osprey_eeprom(struct bttv *btv) | |||
3212 | 3598 | ||
3213 | /* 848 based */ | 3599 | /* 848 based */ |
3214 | case 0x0004: | 3600 | case 0x0004: |
3215 | btv->c.type = BTTV_OSPREY1x0_848; | 3601 | btv->c.type = BTTV_BOARD_OSPREY1x0_848; |
3216 | break; | 3602 | break; |
3217 | case 0x0005: | 3603 | case 0x0005: |
3218 | btv->c.type = BTTV_OSPREY101_848; | 3604 | btv->c.type = BTTV_BOARD_OSPREY101_848; |
3219 | break; | 3605 | break; |
3220 | 3606 | ||
3221 | /* 878 based */ | 3607 | /* 878 based */ |
3222 | case 0x0012: | 3608 | case 0x0012: |
3223 | case 0x0013: | 3609 | case 0x0013: |
3224 | btv->c.type = BTTV_OSPREY1x0; | 3610 | btv->c.type = BTTV_BOARD_OSPREY1x0; |
3225 | break; | 3611 | break; |
3226 | case 0x0014: | 3612 | case 0x0014: |
3227 | case 0x0015: | 3613 | case 0x0015: |
3228 | btv->c.type = BTTV_OSPREY1x1; | 3614 | btv->c.type = BTTV_BOARD_OSPREY1x1; |
3229 | break; | 3615 | break; |
3230 | case 0x0016: | 3616 | case 0x0016: |
3231 | case 0x0017: | 3617 | case 0x0017: |
3232 | case 0x0020: | 3618 | case 0x0020: |
3233 | btv->c.type = BTTV_OSPREY1x1_SVID; | 3619 | btv->c.type = BTTV_BOARD_OSPREY1x1_SVID; |
3234 | break; | 3620 | break; |
3235 | case 0x0018: | 3621 | case 0x0018: |
3236 | case 0x0019: | 3622 | case 0x0019: |
3237 | case 0x001E: | 3623 | case 0x001E: |
3238 | case 0x001F: | 3624 | case 0x001F: |
3239 | btv->c.type = BTTV_OSPREY2xx; | 3625 | btv->c.type = BTTV_BOARD_OSPREY2xx; |
3240 | break; | 3626 | break; |
3241 | case 0x001A: | 3627 | case 0x001A: |
3242 | case 0x001B: | 3628 | case 0x001B: |
3243 | btv->c.type = BTTV_OSPREY2x0_SVID; | 3629 | btv->c.type = BTTV_BOARD_OSPREY2x0_SVID; |
3244 | break; | 3630 | break; |
3245 | case 0x0040: | 3631 | case 0x0040: |
3246 | btv->c.type = BTTV_OSPREY500; | 3632 | btv->c.type = BTTV_BOARD_OSPREY500; |
3247 | break; | 3633 | break; |
3248 | case 0x0050: | 3634 | case 0x0050: |
3249 | case 0x0056: | 3635 | case 0x0056: |
3250 | btv->c.type = BTTV_OSPREY540; | 3636 | btv->c.type = BTTV_BOARD_OSPREY540; |
3251 | /* bttv_osprey_540_init(btv); */ | 3637 | /* bttv_osprey_540_init(btv); */ |
3252 | break; | 3638 | break; |
3253 | case 0x0060: | 3639 | case 0x0060: |
3254 | case 0x0070: | 3640 | case 0x0070: |
3255 | btv->c.type = BTTV_OSPREY2x0; | 3641 | btv->c.type = BTTV_BOARD_OSPREY2x0; |
3256 | /* enable output on select control lines */ | 3642 | /* enable output on select control lines */ |
3257 | gpio_inout(0xffffff,0x000303); | 3643 | gpio_inout(0xffffff,0x000303); |
3258 | break; | 3644 | break; |
@@ -3274,27 +3660,27 @@ static void __devinit osprey_eeprom(struct bttv *btv) | |||
3274 | /* AVermedia specific stuff, from bktr_card.c */ | 3660 | /* AVermedia specific stuff, from bktr_card.c */ |
3275 | 3661 | ||
3276 | static int tuner_0_table[] = { | 3662 | static int tuner_0_table[] = { |
3277 | TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/, | 3663 | TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/, |
3278 | TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/, | 3664 | TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/, |
3279 | TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL, | 3665 | TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL, |
3280 | TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM, | 3666 | TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM, |
3281 | TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL, | 3667 | TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL, |
3282 | TUNER_PHILIPS_FM1216ME_MK3 }; | 3668 | TUNER_PHILIPS_FM1216ME_MK3 }; |
3283 | 3669 | ||
3284 | static int tuner_1_table[] = { | 3670 | static int tuner_1_table[] = { |
3285 | TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL, | 3671 | TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL, |
3286 | TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, | 3672 | TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, |
3287 | TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, | 3673 | TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, |
3288 | TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */ | 3674 | TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */ |
3289 | TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL}; | 3675 | TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL}; |
3290 | 3676 | ||
3291 | static void __devinit avermedia_eeprom(struct bttv *btv) | 3677 | static void __devinit avermedia_eeprom(struct bttv *btv) |
3292 | { | 3678 | { |
3293 | int tuner_make,tuner_tv_fm,tuner_format,tuner=0; | 3679 | int tuner_make,tuner_tv_fm,tuner_format,tuner=0; |
3294 | 3680 | ||
3295 | tuner_make = (eeprom_data[0x41] & 0x7); | 3681 | tuner_make = (eeprom_data[0x41] & 0x7); |
3296 | tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3; | 3682 | tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3; |
3297 | tuner_format = (eeprom_data[0x42] & 0xf0) >> 4; | 3683 | tuner_format = (eeprom_data[0x42] & 0xf0) >> 4; |
3298 | btv->has_remote = (eeprom_data[0x42] & 0x01); | 3684 | btv->has_remote = (eeprom_data[0x42] & 0x01); |
3299 | 3685 | ||
3300 | if (tuner_make == 0 || tuner_make == 2) | 3686 | if (tuner_make == 0 || tuner_make == 2) |
@@ -3325,13 +3711,13 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm) | |||
3325 | { | 3711 | { |
3326 | /* fix up our card entry */ | 3712 | /* fix up our card entry */ |
3327 | if(norm==VIDEO_MODE_NTSC) { | 3713 | if(norm==VIDEO_MODE_NTSC) { |
3328 | bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x957fff; | 3714 | bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x957fff; |
3329 | bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x957fff; | 3715 | bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x957fff; |
3330 | dprintk("bttv_tda9880_setnorm to NTSC\n"); | 3716 | dprintk("bttv_tda9880_setnorm to NTSC\n"); |
3331 | } | 3717 | } |
3332 | else { | 3718 | else { |
3333 | bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x947fff; | 3719 | bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x947fff; |
3334 | bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x947fff; | 3720 | bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x947fff; |
3335 | dprintk("bttv_tda9880_setnorm to PAL\n"); | 3721 | dprintk("bttv_tda9880_setnorm to PAL\n"); |
3336 | } | 3722 | } |
3337 | /* set GPIO according */ | 3723 | /* set GPIO according */ |
@@ -3342,7 +3728,7 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm) | |||
3342 | 3728 | ||
3343 | /* | 3729 | /* |
3344 | * reset/enable the MSP on some Hauppauge cards | 3730 | * reset/enable the MSP on some Hauppauge cards |
3345 | * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)! | 3731 | * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)! |
3346 | * | 3732 | * |
3347 | * Hauppauge: pin 5 | 3733 | * Hauppauge: pin 5 |
3348 | * Voodoo: pin 20 | 3734 | * Voodoo: pin 20 |
@@ -3353,7 +3739,7 @@ static void __devinit boot_msp34xx(struct bttv *btv, int pin) | |||
3353 | 3739 | ||
3354 | gpio_inout(mask,mask); | 3740 | gpio_inout(mask,mask); |
3355 | gpio_bits(mask,0); | 3741 | gpio_bits(mask,0); |
3356 | udelay(2500); | 3742 | udelay(2500); |
3357 | gpio_bits(mask,mask); | 3743 | gpio_bits(mask,mask); |
3358 | 3744 | ||
3359 | if (bttv_gpio) | 3745 | if (bttv_gpio) |
@@ -3429,7 +3815,7 @@ static void __devinit init_PXC200(struct bttv *btv) | |||
3429 | udelay(10); | 3815 | udelay(10); |
3430 | gpio_write(1<<2); | 3816 | gpio_write(1<<2); |
3431 | 3817 | ||
3432 | for (i = 0; i < ARRAY_SIZE(vals); i++) { | 3818 | for (i = 0; i < ARRAY_SIZE(vals); i++) { |
3433 | tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1); | 3819 | tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1); |
3434 | if (tmp != -1) { | 3820 | if (tmp != -1) { |
3435 | printk(KERN_INFO | 3821 | printk(KERN_INFO |
@@ -3872,30 +4258,30 @@ avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v, int set) | |||
3872 | static void | 4258 | static void |
3873 | lt9415_audio(struct bttv *btv, struct video_audio *v, int set) | 4259 | lt9415_audio(struct bttv *btv, struct video_audio *v, int set) |
3874 | { | 4260 | { |
3875 | int val = 0; | 4261 | int val = 0; |
3876 | 4262 | ||
3877 | if (gpio_read() & 0x4000) { | 4263 | if (gpio_read() & 0x4000) { |
3878 | v->mode = VIDEO_SOUND_MONO; | 4264 | v->mode = VIDEO_SOUND_MONO; |
3879 | return; | 4265 | return; |
3880 | } | 4266 | } |
3881 | 4267 | ||
3882 | if (set) { | 4268 | if (set) { |
3883 | if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */ | 4269 | if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */ |
3884 | val = 0x0080; | 4270 | val = 0x0080; |
3885 | if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */ | 4271 | if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */ |
3886 | val = 0x0880; | 4272 | val = 0x0880; |
3887 | if ((v->mode & VIDEO_SOUND_LANG1) || | 4273 | if ((v->mode & VIDEO_SOUND_LANG1) || |
3888 | (v->mode & VIDEO_SOUND_MONO)) | 4274 | (v->mode & VIDEO_SOUND_MONO)) |
3889 | val = 0; | 4275 | val = 0; |
3890 | gpio_bits(0x0880, val); | 4276 | gpio_bits(0x0880, val); |
3891 | if (bttv_gpio) | 4277 | if (bttv_gpio) |
3892 | bttv_gpio_tracking(btv,"lt9415"); | 4278 | bttv_gpio_tracking(btv,"lt9415"); |
3893 | } else { | 4279 | } else { |
3894 | /* autodetect doesn't work with this card :-( */ | 4280 | /* autodetect doesn't work with this card :-( */ |
3895 | v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | | 4281 | v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | |
3896 | VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; | 4282 | VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; |
3897 | return; | 4283 | return; |
3898 | } | 4284 | } |
3899 | } | 4285 | } |
3900 | 4286 | ||
3901 | /* TDA9821 on TerraTV+ Bt848, Bt878 */ | 4287 | /* TDA9821 on TerraTV+ Bt848, Bt878 */ |
@@ -4018,26 +4404,26 @@ fv2000s_audio(struct bttv *btv, struct video_audio *v, int set) | |||
4018 | static void | 4404 | static void |
4019 | windvr_audio(struct bttv *btv, struct video_audio *v, int set) | 4405 | windvr_audio(struct bttv *btv, struct video_audio *v, int set) |
4020 | { | 4406 | { |
4021 | unsigned long val = 0; | 4407 | unsigned long val = 0; |
4022 | 4408 | ||
4023 | if (set) { | 4409 | if (set) { |
4024 | if (v->mode & VIDEO_SOUND_MONO) | 4410 | if (v->mode & VIDEO_SOUND_MONO) |
4025 | val = 0x040000; | 4411 | val = 0x040000; |
4026 | if (v->mode & VIDEO_SOUND_LANG1) | 4412 | if (v->mode & VIDEO_SOUND_LANG1) |
4027 | val = 0; | 4413 | val = 0; |
4028 | if (v->mode & VIDEO_SOUND_LANG2) | 4414 | if (v->mode & VIDEO_SOUND_LANG2) |
4029 | val = 0x100000; | 4415 | val = 0x100000; |
4030 | if (v->mode & VIDEO_SOUND_STEREO) | 4416 | if (v->mode & VIDEO_SOUND_STEREO) |
4031 | val = 0; | 4417 | val = 0; |
4032 | if (val) { | 4418 | if (val) { |
4033 | gpio_bits(0x140000, val); | 4419 | gpio_bits(0x140000, val); |
4034 | if (bttv_gpio) | 4420 | if (bttv_gpio) |
4035 | bttv_gpio_tracking(btv,"windvr"); | 4421 | bttv_gpio_tracking(btv,"windvr"); |
4036 | } | 4422 | } |
4037 | } else { | 4423 | } else { |
4038 | v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | | 4424 | v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | |
4039 | VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; | 4425 | VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; |
4040 | } | 4426 | } |
4041 | } | 4427 | } |
4042 | 4428 | ||
4043 | /* | 4429 | /* |
@@ -4280,10 +4666,10 @@ static void kodicom4400r_init(struct bttv *btv) | |||
4280 | static void xguard_muxsel(struct bttv *btv, unsigned int input) | 4666 | static void xguard_muxsel(struct bttv *btv, unsigned int input) |
4281 | { | 4667 | { |
4282 | static const int masks[] = { | 4668 | static const int masks[] = { |
4283 | ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10, | 4669 | ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10, |
4284 | ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10, | 4670 | ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10, |
4285 | ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11, | 4671 | ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11, |
4286 | ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11, | 4672 | ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11, |
4287 | }; | 4673 | }; |
4288 | gpio_write(masks[input%16]); | 4674 | gpio_write(masks[input%16]); |
4289 | } | 4675 | } |
@@ -4388,10 +4774,10 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input) | |||
4388 | 4774 | ||
4389 | static void PXC200_muxsel(struct bttv *btv, unsigned int input) | 4775 | static void PXC200_muxsel(struct bttv *btv, unsigned int input) |
4390 | { | 4776 | { |
4391 | int rc; | 4777 | int rc; |
4392 | long mux; | 4778 | long mux; |
4393 | int bitmask; | 4779 | int bitmask; |
4394 | unsigned char buf[2]; | 4780 | unsigned char buf[2]; |
4395 | 4781 | ||
4396 | /* Read PIC config to determine if this is a PXC200F */ | 4782 | /* Read PIC config to determine if this is a PXC200F */ |
4397 | /* PX_I2C_CMD_CFG*/ | 4783 | /* PX_I2C_CMD_CFG*/ |
@@ -4421,14 +4807,14 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input) | |||
4421 | /* bitmask=0x30f; */ | 4807 | /* bitmask=0x30f; */ |
4422 | bitmask=0x302; | 4808 | bitmask=0x302; |
4423 | /* check whether we have a PXC200A */ | 4809 | /* check whether we have a PXC200A */ |
4424 | if (btv->cardid == PX_PXC200A_CARDID) { | 4810 | if (btv->cardid == PX_PXC200A_CARDID) { |
4425 | bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */ | 4811 | bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */ |
4426 | bitmask |= 7<<4; /* the DAC */ | 4812 | bitmask |= 7<<4; /* the DAC */ |
4427 | } | 4813 | } |
4428 | btwrite(bitmask, BT848_GPIO_OUT_EN); | 4814 | btwrite(bitmask, BT848_GPIO_OUT_EN); |
4429 | 4815 | ||
4430 | bitmask = btread(BT848_GPIO_DATA); | 4816 | bitmask = btread(BT848_GPIO_DATA); |
4431 | if (btv->cardid == PX_PXC200A_CARDID) | 4817 | if (btv->cardid == PX_PXC200A_CARDID) |
4432 | bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7); | 4818 | bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7); |
4433 | else /* older device */ | 4819 | else /* older device */ |
4434 | bitmask = (bitmask & ~0x300) | ((mux & 3) << 8); | 4820 | bitmask = (bitmask & ~0x300) | ((mux & 3) << 8); |
@@ -4441,7 +4827,7 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input) | |||
4441 | * | 4827 | * |
4442 | * needed because bttv-driver sets mux before calling this function | 4828 | * needed because bttv-driver sets mux before calling this function |
4443 | */ | 4829 | */ |
4444 | if (btv->cardid == PX_PXC200A_CARDID) | 4830 | if (btv->cardid == PX_PXC200A_CARDID) |
4445 | btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM); | 4831 | btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM); |
4446 | else /* older device */ | 4832 | else /* older device */ |
4447 | btand(~BT848_IFORM_MUXSEL,BT848_IFORM); | 4833 | btand(~BT848_IFORM_MUXSEL,BT848_IFORM); |
@@ -4485,10 +4871,9 @@ void __devinit bttv_check_chipset(void) | |||
4485 | } | 4871 | } |
4486 | if (UNSET != latency) | 4872 | if (UNSET != latency) |
4487 | printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency); | 4873 | printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency); |
4488 | 4874 | while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, | |
4489 | while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL, | ||
4490 | PCI_DEVICE_ID_INTEL_82441, dev))) { | 4875 | PCI_DEVICE_ID_INTEL_82441, dev))) { |
4491 | unsigned char b; | 4876 | unsigned char b; |
4492 | pci_read_config_byte(dev, 0x53, &b); | 4877 | pci_read_config_byte(dev, 0x53, &b); |
4493 | if (bttv_debug) | 4878 | if (bttv_debug) |
4494 | printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, " | 4879 | printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, " |
@@ -4498,7 +4883,7 @@ void __devinit bttv_check_chipset(void) | |||
4498 | 4883 | ||
4499 | int __devinit bttv_handle_chipset(struct bttv *btv) | 4884 | int __devinit bttv_handle_chipset(struct bttv *btv) |
4500 | { | 4885 | { |
4501 | unsigned char command; | 4886 | unsigned char command; |
4502 | 4887 | ||
4503 | if (!triton1 && !vsfx && UNSET == latency) | 4888 | if (!triton1 && !vsfx && UNSET == latency) |
4504 | return 0; | 4889 | return 0; |
@@ -4519,13 +4904,13 @@ int __devinit bttv_handle_chipset(struct bttv *btv) | |||
4519 | btv->triton1 = BT848_INT_ETBF; | 4904 | btv->triton1 = BT848_INT_ETBF; |
4520 | } else { | 4905 | } else { |
4521 | /* bt878 has a bit in the pci config space for it */ | 4906 | /* bt878 has a bit in the pci config space for it */ |
4522 | pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command); | 4907 | pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command); |
4523 | if (triton1) | 4908 | if (triton1) |
4524 | command |= BT878_EN_TBFX; | 4909 | command |= BT878_EN_TBFX; |
4525 | if (vsfx) | 4910 | if (vsfx) |
4526 | command |= BT878_EN_VSFX; | 4911 | command |= BT878_EN_VSFX; |
4527 | pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command); | 4912 | pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command); |
4528 | } | 4913 | } |
4529 | if (UNSET != latency) | 4914 | if (UNSET != latency) |
4530 | pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency); | 4915 | pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency); |
4531 | return 0; | 4916 | return 0; |
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index d538a994ff04..0005741d5514 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c | |||
@@ -3,7 +3,7 @@ | |||
3 | bttv - Bt848 frame grabber driver | 3 | bttv - Bt848 frame grabber driver |
4 | 4 | ||
5 | Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de> | 5 | Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de> |
6 | & Marcus Metzler <mocm@thp.uni-koeln.de> | 6 | & Marcus Metzler <mocm@thp.uni-koeln.de> |
7 | (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org> | 7 | (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org> |
8 | 8 | ||
9 | some v4l2 code lines are taken from Justin's bttv2 driver which is | 9 | some v4l2 code lines are taken from Justin's bttv2 driver which is |
@@ -192,8 +192,8 @@ static u8 SRAM_Table[][60] = | |||
192 | 192 | ||
193 | const struct bttv_tvnorm bttv_tvnorms[] = { | 193 | const struct bttv_tvnorm bttv_tvnorms[] = { |
194 | /* PAL-BDGHI */ | 194 | /* PAL-BDGHI */ |
195 | /* max. active video is actually 922, but 924 is divisible by 4 and 3! */ | 195 | /* max. active video is actually 922, but 924 is divisible by 4 and 3! */ |
196 | /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */ | 196 | /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */ |
197 | { | 197 | { |
198 | .v4l2_id = V4L2_STD_PAL, | 198 | .v4l2_id = V4L2_STD_PAL, |
199 | .name = "PAL", | 199 | .name = "PAL", |
@@ -806,9 +806,9 @@ static void bt848A_set_timing(struct bttv *btv) | |||
806 | btv->c.nr,table_idx); | 806 | btv->c.nr,table_idx); |
807 | 807 | ||
808 | /* timing change...reset timing generator address */ | 808 | /* timing change...reset timing generator address */ |
809 | btwrite(0x00, BT848_TGCTRL); | 809 | btwrite(0x00, BT848_TGCTRL); |
810 | btwrite(0x02, BT848_TGCTRL); | 810 | btwrite(0x02, BT848_TGCTRL); |
811 | btwrite(0x00, BT848_TGCTRL); | 811 | btwrite(0x00, BT848_TGCTRL); |
812 | 812 | ||
813 | len=SRAM_Table[table_idx][0]; | 813 | len=SRAM_Table[table_idx][0]; |
814 | for(i = 1; i <= len; i++) | 814 | for(i = 1; i <= len; i++) |
@@ -847,7 +847,7 @@ static void bt848_hue(struct bttv *btv, int hue) | |||
847 | 847 | ||
848 | /* -128 to 127 */ | 848 | /* -128 to 127 */ |
849 | value = (hue >> 8) - 128; | 849 | value = (hue >> 8) - 128; |
850 | btwrite(value & 0xff, BT848_HUE); | 850 | btwrite(value & 0xff, BT848_HUE); |
851 | } | 851 | } |
852 | 852 | ||
853 | static void bt848_contrast(struct bttv *btv, int cont) | 853 | static void bt848_contrast(struct bttv *btv, int cont) |
@@ -859,9 +859,9 @@ static void bt848_contrast(struct bttv *btv, int cont) | |||
859 | /* 0-511 */ | 859 | /* 0-511 */ |
860 | value = (cont >> 7); | 860 | value = (cont >> 7); |
861 | hibit = (value >> 6) & 4; | 861 | hibit = (value >> 6) & 4; |
862 | btwrite(value & 0xff, BT848_CONTRAST_LO); | 862 | btwrite(value & 0xff, BT848_CONTRAST_LO); |
863 | btaor(hibit, ~4, BT848_E_CONTROL); | 863 | btaor(hibit, ~4, BT848_E_CONTROL); |
864 | btaor(hibit, ~4, BT848_O_CONTROL); | 864 | btaor(hibit, ~4, BT848_O_CONTROL); |
865 | } | 865 | } |
866 | 866 | ||
867 | static void bt848_sat(struct bttv *btv, int color) | 867 | static void bt848_sat(struct bttv *btv, int color) |
@@ -873,12 +873,12 @@ static void bt848_sat(struct bttv *btv, int color) | |||
873 | /* 0-511 for the color */ | 873 | /* 0-511 for the color */ |
874 | val_u = ((color * btv->opt_uv_ratio) / 50) >> 7; | 874 | val_u = ((color * btv->opt_uv_ratio) / 50) >> 7; |
875 | val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254; | 875 | val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254; |
876 | hibits = (val_u >> 7) & 2; | 876 | hibits = (val_u >> 7) & 2; |
877 | hibits |= (val_v >> 8) & 1; | 877 | hibits |= (val_v >> 8) & 1; |
878 | btwrite(val_u & 0xff, BT848_SAT_U_LO); | 878 | btwrite(val_u & 0xff, BT848_SAT_U_LO); |
879 | btwrite(val_v & 0xff, BT848_SAT_V_LO); | 879 | btwrite(val_v & 0xff, BT848_SAT_V_LO); |
880 | btaor(hibits, ~3, BT848_E_CONTROL); | 880 | btaor(hibits, ~3, BT848_E_CONTROL); |
881 | btaor(hibits, ~3, BT848_O_CONTROL); | 881 | btaor(hibits, ~3, BT848_O_CONTROL); |
882 | } | 882 | } |
883 | 883 | ||
884 | /* ----------------------------------------------------------------------- */ | 884 | /* ----------------------------------------------------------------------- */ |
@@ -891,7 +891,7 @@ video_mux(struct bttv *btv, unsigned int input) | |||
891 | if (input >= bttv_tvcards[btv->c.type].video_inputs) | 891 | if (input >= bttv_tvcards[btv->c.type].video_inputs) |
892 | return -EINVAL; | 892 | return -EINVAL; |
893 | 893 | ||
894 | /* needed by RemoteVideo MX */ | 894 | /* needed by RemoteVideo MX */ |
895 | mask2 = bttv_tvcards[btv->c.type].gpiomask2; | 895 | mask2 = bttv_tvcards[btv->c.type].gpiomask2; |
896 | if (mask2) | 896 | if (mask2) |
897 | gpio_inout(mask2,mask2); | 897 | gpio_inout(mask2,mask2); |
@@ -964,7 +964,7 @@ i2c_vidiocschan(struct bttv *btv) | |||
964 | c.norm = btv->tvnorm; | 964 | c.norm = btv->tvnorm; |
965 | c.channel = btv->input; | 965 | c.channel = btv->input; |
966 | bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c); | 966 | bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c); |
967 | if (btv->c.type == BTTV_VOODOOTV_FM) | 967 | if (btv->c.type == BTTV_BOARD_VOODOOTV_FM) |
968 | bttv_tda9880_setnorm(btv,c.norm); | 968 | bttv_tda9880_setnorm(btv,c.norm); |
969 | } | 969 | } |
970 | 970 | ||
@@ -988,7 +988,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm) | |||
988 | bt848A_set_timing(btv); | 988 | bt848A_set_timing(btv); |
989 | 989 | ||
990 | switch (btv->c.type) { | 990 | switch (btv->c.type) { |
991 | case BTTV_VOODOOTV_FM: | 991 | case BTTV_BOARD_VOODOOTV_FM: |
992 | bttv_tda9880_setnorm(btv,norm); | 992 | bttv_tda9880_setnorm(btv,norm); |
993 | break; | 993 | break; |
994 | } | 994 | } |
@@ -1055,22 +1055,22 @@ static void init_bt848(struct bttv *btv) | |||
1055 | btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); | 1055 | btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); |
1056 | btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM); | 1056 | btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM); |
1057 | 1057 | ||
1058 | /* set planar and packed mode trigger points and */ | 1058 | /* set planar and packed mode trigger points and */ |
1059 | /* set rising edge of inverted GPINTR pin as irq trigger */ | 1059 | /* set rising edge of inverted GPINTR pin as irq trigger */ |
1060 | btwrite(BT848_GPIO_DMA_CTL_PKTP_32| | 1060 | btwrite(BT848_GPIO_DMA_CTL_PKTP_32| |
1061 | BT848_GPIO_DMA_CTL_PLTP1_16| | 1061 | BT848_GPIO_DMA_CTL_PLTP1_16| |
1062 | BT848_GPIO_DMA_CTL_PLTP23_16| | 1062 | BT848_GPIO_DMA_CTL_PLTP23_16| |
1063 | BT848_GPIO_DMA_CTL_GPINTC| | 1063 | BT848_GPIO_DMA_CTL_GPINTC| |
1064 | BT848_GPIO_DMA_CTL_GPINTI, | 1064 | BT848_GPIO_DMA_CTL_GPINTI, |
1065 | BT848_GPIO_DMA_CTL); | 1065 | BT848_GPIO_DMA_CTL); |
1066 | 1066 | ||
1067 | val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0; | 1067 | val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0; |
1068 | btwrite(val, BT848_E_SCLOOP); | 1068 | btwrite(val, BT848_E_SCLOOP); |
1069 | btwrite(val, BT848_O_SCLOOP); | 1069 | btwrite(val, BT848_O_SCLOOP); |
1070 | 1070 | ||
1071 | btwrite(0x20, BT848_E_VSCALE_HI); | 1071 | btwrite(0x20, BT848_E_VSCALE_HI); |
1072 | btwrite(0x20, BT848_O_VSCALE_HI); | 1072 | btwrite(0x20, BT848_O_VSCALE_HI); |
1073 | btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), | 1073 | btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), |
1074 | BT848_ADC); | 1074 | BT848_ADC); |
1075 | 1075 | ||
1076 | btwrite(whitecrush_upper, BT848_WC_UP); | 1076 | btwrite(whitecrush_upper, BT848_WC_UP); |
@@ -1089,7 +1089,7 @@ static void init_bt848(struct bttv *btv) | |||
1089 | bt848_contrast(btv, btv->contrast); | 1089 | bt848_contrast(btv, btv->contrast); |
1090 | bt848_sat(btv, btv->saturation); | 1090 | bt848_sat(btv, btv->saturation); |
1091 | 1091 | ||
1092 | /* interrupt */ | 1092 | /* interrupt */ |
1093 | init_irqreg(btv); | 1093 | init_irqreg(btv); |
1094 | } | 1094 | } |
1095 | 1095 | ||
@@ -1105,7 +1105,7 @@ static void bttv_reinit_bt848(struct bttv *btv) | |||
1105 | spin_unlock_irqrestore(&btv->s_lock,flags); | 1105 | spin_unlock_irqrestore(&btv->s_lock,flags); |
1106 | 1106 | ||
1107 | init_bt848(btv); | 1107 | init_bt848(btv); |
1108 | btv->pll.pll_current = -1; | 1108 | btv->pll.pll_current = -1; |
1109 | set_input(btv,btv->input); | 1109 | set_input(btv,btv->input); |
1110 | } | 1110 | } |
1111 | 1111 | ||
@@ -1398,7 +1398,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh, | |||
1398 | /* video4linux (1) interface */ | 1398 | /* video4linux (1) interface */ |
1399 | 1399 | ||
1400 | static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf, | 1400 | static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf, |
1401 | const struct bttv_format *fmt, | 1401 | const struct bttv_format *fmt, |
1402 | unsigned int width, unsigned int height, | 1402 | unsigned int width, unsigned int height, |
1403 | enum v4l2_field field) | 1403 | enum v4l2_field field) |
1404 | { | 1404 | { |
@@ -1521,8 +1521,8 @@ static const char *v4l1_ioctls[] = { | |||
1521 | static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | 1521 | static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) |
1522 | { | 1522 | { |
1523 | switch (cmd) { | 1523 | switch (cmd) { |
1524 | case BTTV_VERSION: | 1524 | case BTTV_VERSION: |
1525 | return BTTV_VERSION_CODE; | 1525 | return BTTV_VERSION_CODE; |
1526 | 1526 | ||
1527 | /* *** v4l1 *** ************************************************ */ | 1527 | /* *** v4l1 *** ************************************************ */ |
1528 | case VIDIOCGFREQ: | 1528 | case VIDIOCGFREQ: |
@@ -1576,32 +1576,32 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | |||
1576 | return 0; | 1576 | return 0; |
1577 | } | 1577 | } |
1578 | 1578 | ||
1579 | case VIDIOCGCHAN: | 1579 | case VIDIOCGCHAN: |
1580 | { | 1580 | { |
1581 | struct video_channel *v = arg; | 1581 | struct video_channel *v = arg; |
1582 | unsigned int channel = v->channel; | 1582 | unsigned int channel = v->channel; |
1583 | 1583 | ||
1584 | if (channel >= bttv_tvcards[btv->c.type].video_inputs) | 1584 | if (channel >= bttv_tvcards[btv->c.type].video_inputs) |
1585 | return -EINVAL; | 1585 | return -EINVAL; |
1586 | v->tuners=0; | 1586 | v->tuners=0; |
1587 | v->flags = VIDEO_VC_AUDIO; | 1587 | v->flags = VIDEO_VC_AUDIO; |
1588 | v->type = VIDEO_TYPE_CAMERA; | 1588 | v->type = VIDEO_TYPE_CAMERA; |
1589 | v->norm = btv->tvnorm; | 1589 | v->norm = btv->tvnorm; |
1590 | if (channel == bttv_tvcards[btv->c.type].tuner) { | 1590 | if (channel == bttv_tvcards[btv->c.type].tuner) { |
1591 | strcpy(v->name,"Television"); | 1591 | strcpy(v->name,"Television"); |
1592 | v->flags|=VIDEO_VC_TUNER; | 1592 | v->flags|=VIDEO_VC_TUNER; |
1593 | v->type=VIDEO_TYPE_TV; | 1593 | v->type=VIDEO_TYPE_TV; |
1594 | v->tuners=1; | 1594 | v->tuners=1; |
1595 | } else if (channel == btv->svhs) { | 1595 | } else if (channel == btv->svhs) { |
1596 | strcpy(v->name,"S-Video"); | 1596 | strcpy(v->name,"S-Video"); |
1597 | } else { | 1597 | } else { |
1598 | sprintf(v->name,"Composite%d",channel); | 1598 | sprintf(v->name,"Composite%d",channel); |
1599 | } | 1599 | } |
1600 | return 0; | 1600 | return 0; |
1601 | } | 1601 | } |
1602 | case VIDIOCSCHAN: | 1602 | case VIDIOCSCHAN: |
1603 | { | 1603 | { |
1604 | struct video_channel *v = arg; | 1604 | struct video_channel *v = arg; |
1605 | unsigned int channel = v->channel; | 1605 | unsigned int channel = v->channel; |
1606 | 1606 | ||
1607 | if (channel >= bttv_tvcards[btv->c.type].video_inputs) | 1607 | if (channel >= bttv_tvcards[btv->c.type].video_inputs) |
@@ -1623,7 +1623,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | |||
1623 | return 0; | 1623 | return 0; |
1624 | } | 1624 | } |
1625 | 1625 | ||
1626 | case VIDIOCGAUDIO: | 1626 | case VIDIOCGAUDIO: |
1627 | { | 1627 | { |
1628 | struct video_audio *v = arg; | 1628 | struct video_audio *v = arg; |
1629 | 1629 | ||
@@ -1728,7 +1728,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | |||
1728 | } else if (i->index == btv->svhs) { | 1728 | } else if (i->index == btv->svhs) { |
1729 | sprintf(i->name, "S-Video"); | 1729 | sprintf(i->name, "S-Video"); |
1730 | } else { | 1730 | } else { |
1731 | sprintf(i->name,"Composite%d",i->index); | 1731 | sprintf(i->name,"Composite%d",i->index); |
1732 | } | 1732 | } |
1733 | if (i->index == btv->input) { | 1733 | if (i->index == btv->input) { |
1734 | __u32 dstatus = btread(BT848_DSTATUS); | 1734 | __u32 dstatus = btread(BT848_DSTATUS); |
@@ -1851,6 +1851,11 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) | |||
1851 | up(&btv->lock); | 1851 | up(&btv->lock); |
1852 | return 0; | 1852 | return 0; |
1853 | } | 1853 | } |
1854 | case VIDIOC_LOG_STATUS: | ||
1855 | { | ||
1856 | bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, 0); | ||
1857 | return 0; | ||
1858 | } | ||
1854 | 1859 | ||
1855 | default: | 1860 | default: |
1856 | return -ENOIOCTLCMD; | 1861 | return -ENOIOCTLCMD; |
@@ -2163,7 +2168,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv, | |||
2163 | if (0 != retval) | 2168 | if (0 != retval) |
2164 | return retval; | 2169 | return retval; |
2165 | if (locked_btres(fh->btv, RESOURCE_VBI)) | 2170 | if (locked_btres(fh->btv, RESOURCE_VBI)) |
2166 | return -EBUSY; | 2171 | return -EBUSY; |
2167 | bttv_vbi_try_fmt(fh,f); | 2172 | bttv_vbi_try_fmt(fh,f); |
2168 | bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]); | 2173 | bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]); |
2169 | bttv_vbi_get_fmt(fh,f); | 2174 | bttv_vbi_get_fmt(fh,f); |
@@ -2201,9 +2206,9 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2201 | bttv_reinit_bt848(btv); | 2206 | bttv_reinit_bt848(btv); |
2202 | 2207 | ||
2203 | switch (cmd) { | 2208 | switch (cmd) { |
2204 | case VIDIOCSFREQ: | 2209 | case VIDIOCSFREQ: |
2205 | case VIDIOCSTUNER: | 2210 | case VIDIOCSTUNER: |
2206 | case VIDIOCSCHAN: | 2211 | case VIDIOCSCHAN: |
2207 | case VIDIOC_S_CTRL: | 2212 | case VIDIOC_S_CTRL: |
2208 | case VIDIOC_S_STD: | 2213 | case VIDIOC_S_STD: |
2209 | case VIDIOC_S_INPUT: | 2214 | case VIDIOC_S_INPUT: |
@@ -2219,10 +2224,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2219 | /* *** v4l1 *** ************************************************ */ | 2224 | /* *** v4l1 *** ************************************************ */ |
2220 | case VIDIOCGCAP: | 2225 | case VIDIOCGCAP: |
2221 | { | 2226 | { |
2222 | struct video_capability *cap = arg; | 2227 | struct video_capability *cap = arg; |
2223 | 2228 | ||
2224 | memset(cap,0,sizeof(*cap)); | 2229 | memset(cap,0,sizeof(*cap)); |
2225 | strcpy(cap->name,btv->video_dev->name); | 2230 | strcpy(cap->name,btv->video_dev->name); |
2226 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { | 2231 | if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { |
2227 | /* vbi */ | 2232 | /* vbi */ |
2228 | cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT; | 2233 | cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT; |
@@ -2242,7 +2247,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2242 | } | 2247 | } |
2243 | cap->channels = bttv_tvcards[btv->c.type].video_inputs; | 2248 | cap->channels = bttv_tvcards[btv->c.type].video_inputs; |
2244 | cap->audios = bttv_tvcards[btv->c.type].audio_inputs; | 2249 | cap->audios = bttv_tvcards[btv->c.type].audio_inputs; |
2245 | return 0; | 2250 | return 0; |
2246 | } | 2251 | } |
2247 | 2252 | ||
2248 | case VIDIOCGPICT: | 2253 | case VIDIOCGPICT: |
@@ -2291,7 +2296,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2291 | bt848_hue(btv,pic->hue); | 2296 | bt848_hue(btv,pic->hue); |
2292 | bt848_sat(btv,pic->colour); | 2297 | bt848_sat(btv,pic->colour); |
2293 | up(&fh->cap.lock); | 2298 | up(&fh->cap.lock); |
2294 | return 0; | 2299 | return 0; |
2295 | } | 2300 | } |
2296 | 2301 | ||
2297 | case VIDIOCGWIN: | 2302 | case VIDIOCGWIN: |
@@ -2352,8 +2357,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2352 | unsigned long end; | 2357 | unsigned long end; |
2353 | 2358 | ||
2354 | if(!capable(CAP_SYS_ADMIN) && | 2359 | if(!capable(CAP_SYS_ADMIN) && |
2355 | !capable(CAP_SYS_RAWIO)) | 2360 | !capable(CAP_SYS_RAWIO)) |
2356 | return -EPERM; | 2361 | return -EPERM; |
2357 | end = (unsigned long)fbuf->base + | 2362 | end = (unsigned long)fbuf->base + |
2358 | fbuf->height * fbuf->bytesperline; | 2363 | fbuf->height * fbuf->bytesperline; |
2359 | down(&fh->cap.lock); | 2364 | down(&fh->cap.lock); |
@@ -2427,7 +2432,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2427 | } | 2432 | } |
2428 | 2433 | ||
2429 | /* switch over */ | 2434 | /* switch over */ |
2430 | retval = bttv_switch_overlay(btv,fh,new); | 2435 | retval = bttv_switch_overlay(btv,fh,new); |
2431 | up(&fh->cap.lock); | 2436 | up(&fh->cap.lock); |
2432 | return retval; | 2437 | return retval; |
2433 | } | 2438 | } |
@@ -2566,13 +2571,13 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2566 | return 0; | 2571 | return 0; |
2567 | } | 2572 | } |
2568 | 2573 | ||
2569 | case BTTV_VERSION: | 2574 | case BTTV_VERSION: |
2570 | case VIDIOCGFREQ: | 2575 | case VIDIOCGFREQ: |
2571 | case VIDIOCSFREQ: | 2576 | case VIDIOCSFREQ: |
2572 | case VIDIOCGTUNER: | 2577 | case VIDIOCGTUNER: |
2573 | case VIDIOCSTUNER: | 2578 | case VIDIOCSTUNER: |
2574 | case VIDIOCGCHAN: | 2579 | case VIDIOCGCHAN: |
2575 | case VIDIOCSCHAN: | 2580 | case VIDIOCSCHAN: |
2576 | case VIDIOCGAUDIO: | 2581 | case VIDIOCGAUDIO: |
2577 | case VIDIOCSAUDIO: | 2582 | case VIDIOCSAUDIO: |
2578 | return bttv_common_ioctls(btv,cmd,arg); | 2583 | return bttv_common_ioctls(btv,cmd,arg); |
@@ -2584,8 +2589,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2584 | 2589 | ||
2585 | if (0 == v4l2) | 2590 | if (0 == v4l2) |
2586 | return -EINVAL; | 2591 | return -EINVAL; |
2587 | strcpy(cap->driver,"bttv"); | 2592 | strcpy(cap->driver,"bttv"); |
2588 | strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card)); | 2593 | strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card)); |
2589 | sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci)); | 2594 | sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci)); |
2590 | cap->version = BTTV_VERSION_CODE; | 2595 | cap->version = BTTV_VERSION_CODE; |
2591 | cap->capabilities = | 2596 | cap->capabilities = |
@@ -2856,6 +2861,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2856 | case VIDIOC_S_TUNER: | 2861 | case VIDIOC_S_TUNER: |
2857 | case VIDIOC_G_FREQUENCY: | 2862 | case VIDIOC_G_FREQUENCY: |
2858 | case VIDIOC_S_FREQUENCY: | 2863 | case VIDIOC_S_FREQUENCY: |
2864 | case VIDIOC_LOG_STATUS: | ||
2859 | return bttv_common_ioctls(btv,cmd,arg); | 2865 | return bttv_common_ioctls(btv,cmd,arg); |
2860 | 2866 | ||
2861 | default: | 2867 | default: |
@@ -3091,7 +3097,7 @@ static struct video_device bttv_video_template = | |||
3091 | { | 3097 | { |
3092 | .name = "UNSET", | 3098 | .name = "UNSET", |
3093 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| | 3099 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| |
3094 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, | 3100 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, |
3095 | .hardware = VID_HARDWARE_BT848, | 3101 | .hardware = VID_HARDWARE_BT848, |
3096 | .fops = &bttv_fops, | 3102 | .fops = &bttv_fops, |
3097 | .minor = -1, | 3103 | .minor = -1, |
@@ -3137,7 +3143,7 @@ static int radio_open(struct inode *inode, struct file *file) | |||
3137 | audio_mux(btv,AUDIO_RADIO); | 3143 | audio_mux(btv,AUDIO_RADIO); |
3138 | 3144 | ||
3139 | up(&btv->lock); | 3145 | up(&btv->lock); |
3140 | return 0; | 3146 | return 0; |
3141 | } | 3147 | } |
3142 | 3148 | ||
3143 | static int radio_release(struct inode *inode, struct file *file) | 3149 | static int radio_release(struct inode *inode, struct file *file) |
@@ -3160,34 +3166,34 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
3160 | switch (cmd) { | 3166 | switch (cmd) { |
3161 | case VIDIOCGCAP: | 3167 | case VIDIOCGCAP: |
3162 | { | 3168 | { |
3163 | struct video_capability *cap = arg; | 3169 | struct video_capability *cap = arg; |
3164 | 3170 | ||
3165 | memset(cap,0,sizeof(*cap)); | 3171 | memset(cap,0,sizeof(*cap)); |
3166 | strcpy(cap->name,btv->radio_dev->name); | 3172 | strcpy(cap->name,btv->radio_dev->name); |
3167 | cap->type = VID_TYPE_TUNER; | 3173 | cap->type = VID_TYPE_TUNER; |
3168 | cap->channels = 1; | 3174 | cap->channels = 1; |
3169 | cap->audios = 1; | 3175 | cap->audios = 1; |
3170 | return 0; | 3176 | return 0; |
3171 | } | 3177 | } |
3172 | 3178 | ||
3173 | case VIDIOCGTUNER: | 3179 | case VIDIOCGTUNER: |
3174 | { | 3180 | { |
3175 | struct video_tuner *v = arg; | 3181 | struct video_tuner *v = arg; |
3176 | 3182 | ||
3177 | if(v->tuner) | 3183 | if(v->tuner) |
3178 | return -EINVAL; | 3184 | return -EINVAL; |
3179 | memset(v,0,sizeof(*v)); | 3185 | memset(v,0,sizeof(*v)); |
3180 | strcpy(v->name, "Radio"); | 3186 | strcpy(v->name, "Radio"); |
3181 | bttv_call_i2c_clients(btv,cmd,v); | 3187 | bttv_call_i2c_clients(btv,cmd,v); |
3182 | return 0; | 3188 | return 0; |
3183 | } | 3189 | } |
3184 | case VIDIOCSTUNER: | 3190 | case VIDIOCSTUNER: |
3185 | /* nothing to do */ | 3191 | /* nothing to do */ |
3186 | return 0; | 3192 | return 0; |
3187 | 3193 | ||
3188 | case BTTV_VERSION: | 3194 | case BTTV_VERSION: |
3189 | case VIDIOCGFREQ: | 3195 | case VIDIOCGFREQ: |
3190 | case VIDIOCSFREQ: | 3196 | case VIDIOCSFREQ: |
3191 | case VIDIOCGAUDIO: | 3197 | case VIDIOCGAUDIO: |
3192 | case VIDIOCSAUDIO: | 3198 | case VIDIOCSAUDIO: |
3193 | return bttv_common_ioctls(btv,cmd,arg); | 3199 | return bttv_common_ioctls(btv,cmd,arg); |
@@ -3693,7 +3699,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs) | |||
3693 | } | 3699 | } |
3694 | 3700 | ||
3695 | if (astat&BT848_INT_VSYNC) | 3701 | if (astat&BT848_INT_VSYNC) |
3696 | btv->field_count++; | 3702 | btv->field_count++; |
3697 | 3703 | ||
3698 | if (astat & BT848_INT_GPINT) { | 3704 | if (astat & BT848_INT_GPINT) { |
3699 | wake_up(&btv->gpioq); | 3705 | wake_up(&btv->gpioq); |
@@ -3705,13 +3711,13 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs) | |||
3705 | wake_up(&btv->i2c_queue); | 3711 | wake_up(&btv->i2c_queue); |
3706 | } | 3712 | } |
3707 | 3713 | ||
3708 | if ((astat & BT848_INT_RISCI) && (stat & (4<<28))) | 3714 | if ((astat & BT848_INT_RISCI) && (stat & (4<<28))) |
3709 | bttv_irq_switch_vbi(btv); | 3715 | bttv_irq_switch_vbi(btv); |
3710 | 3716 | ||
3711 | if ((astat & BT848_INT_RISCI) && (stat & (2<<28))) | 3717 | if ((astat & BT848_INT_RISCI) && (stat & (2<<28))) |
3712 | bttv_irq_wakeup_top(btv); | 3718 | bttv_irq_wakeup_top(btv); |
3713 | 3719 | ||
3714 | if ((astat & BT848_INT_RISCI) && (stat & (1<<28))) | 3720 | if ((astat & BT848_INT_RISCI) && (stat & (1<<28))) |
3715 | bttv_irq_switch_video(btv); | 3721 | bttv_irq_switch_video(btv); |
3716 | 3722 | ||
3717 | if ((astat & BT848_INT_HLOCK) && btv->opt_automute) | 3723 | if ((astat & BT848_INT_HLOCK) && btv->opt_automute) |
@@ -3736,10 +3742,22 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs) | |||
3736 | 3742 | ||
3737 | count++; | 3743 | count++; |
3738 | if (count > 4) { | 3744 | if (count > 4) { |
3739 | btwrite(0, BT848_INT_MASK); | 3745 | |
3740 | printk(KERN_ERR | 3746 | if (count > 8 || !(astat & BT848_INT_GPINT)) { |
3741 | "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr); | 3747 | btwrite(0, BT848_INT_MASK); |
3748 | |||
3749 | printk(KERN_ERR | ||
3750 | "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr); | ||
3751 | } else { | ||
3752 | printk(KERN_ERR | ||
3753 | "bttv%d: IRQ lockup, clearing GPINT from int mask [", btv->c.nr); | ||
3754 | |||
3755 | btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT), | ||
3756 | BT848_INT_MASK); | ||
3757 | }; | ||
3758 | |||
3742 | bttv_print_irqbits(stat,astat); | 3759 | bttv_print_irqbits(stat,astat); |
3760 | |||
3743 | printk("]\n"); | 3761 | printk("]\n"); |
3744 | } | 3762 | } |
3745 | } | 3763 | } |
@@ -3808,7 +3826,7 @@ static int __devinit bttv_register_video(struct bttv *btv) | |||
3808 | 3826 | ||
3809 | /* video */ | 3827 | /* video */ |
3810 | btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); | 3828 | btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); |
3811 | if (NULL == btv->video_dev) | 3829 | if (NULL == btv->video_dev) |
3812 | goto err; | 3830 | goto err; |
3813 | if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0) | 3831 | if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0) |
3814 | goto err; | 3832 | goto err; |
@@ -3818,18 +3836,18 @@ static int __devinit bttv_register_video(struct bttv *btv) | |||
3818 | 3836 | ||
3819 | /* vbi */ | 3837 | /* vbi */ |
3820 | btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi"); | 3838 | btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi"); |
3821 | if (NULL == btv->vbi_dev) | 3839 | if (NULL == btv->vbi_dev) |
3822 | goto err; | 3840 | goto err; |
3823 | if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) | 3841 | if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) |
3824 | goto err; | 3842 | goto err; |
3825 | printk(KERN_INFO "bttv%d: registered device vbi%d\n", | 3843 | printk(KERN_INFO "bttv%d: registered device vbi%d\n", |
3826 | btv->c.nr,btv->vbi_dev->minor & 0x1f); | 3844 | btv->c.nr,btv->vbi_dev->minor & 0x1f); |
3827 | 3845 | ||
3828 | if (!btv->has_radio) | 3846 | if (!btv->has_radio) |
3829 | return 0; | 3847 | return 0; |
3830 | /* radio */ | 3848 | /* radio */ |
3831 | btv->radio_dev = vdev_init(btv, &radio_template, "radio"); | 3849 | btv->radio_dev = vdev_init(btv, &radio_template, "radio"); |
3832 | if (NULL == btv->radio_dev) | 3850 | if (NULL == btv->radio_dev) |
3833 | goto err; | 3851 | goto err; |
3834 | if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) | 3852 | if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) |
3835 | goto err; | 3853 | goto err; |
@@ -3850,11 +3868,11 @@ static int __devinit bttv_register_video(struct bttv *btv) | |||
3850 | static void pci_set_command(struct pci_dev *dev) | 3868 | static void pci_set_command(struct pci_dev *dev) |
3851 | { | 3869 | { |
3852 | #if defined(__powerpc__) | 3870 | #if defined(__powerpc__) |
3853 | unsigned int cmd; | 3871 | unsigned int cmd; |
3854 | 3872 | ||
3855 | pci_read_config_dword(dev, PCI_COMMAND, &cmd); | 3873 | pci_read_config_dword(dev, PCI_COMMAND, &cmd); |
3856 | cmd = (cmd | PCI_COMMAND_MEMORY ); | 3874 | cmd = (cmd | PCI_COMMAND_MEMORY ); |
3857 | pci_write_config_dword(dev, PCI_COMMAND, cmd); | 3875 | pci_write_config_dword(dev, PCI_COMMAND, cmd); |
3858 | #endif | 3876 | #endif |
3859 | } | 3877 | } |
3860 | 3878 | ||
@@ -3868,63 +3886,62 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
3868 | if (bttv_num == BTTV_MAX) | 3886 | if (bttv_num == BTTV_MAX) |
3869 | return -ENOMEM; | 3887 | return -ENOMEM; |
3870 | printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num); | 3888 | printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num); |
3871 | btv=&bttvs[bttv_num]; | 3889 | btv=&bttvs[bttv_num]; |
3872 | memset(btv,0,sizeof(*btv)); | 3890 | memset(btv,0,sizeof(*btv)); |
3873 | btv->c.nr = bttv_num; | 3891 | btv->c.nr = bttv_num; |
3874 | sprintf(btv->c.name,"bttv%d",btv->c.nr); | 3892 | sprintf(btv->c.name,"bttv%d",btv->c.nr); |
3875 | 3893 | ||
3876 | /* initialize structs / fill in defaults */ | 3894 | /* initialize structs / fill in defaults */ |
3877 | init_MUTEX(&btv->lock); | 3895 | init_MUTEX(&btv->lock); |
3878 | init_MUTEX(&btv->reslock); | 3896 | init_MUTEX(&btv->reslock); |
3879 | spin_lock_init(&btv->s_lock); | 3897 | spin_lock_init(&btv->s_lock); |
3880 | spin_lock_init(&btv->gpio_lock); | 3898 | spin_lock_init(&btv->gpio_lock); |
3881 | init_waitqueue_head(&btv->gpioq); | 3899 | init_waitqueue_head(&btv->gpioq); |
3882 | init_waitqueue_head(&btv->i2c_queue); | 3900 | init_waitqueue_head(&btv->i2c_queue); |
3883 | INIT_LIST_HEAD(&btv->c.subs); | 3901 | INIT_LIST_HEAD(&btv->c.subs); |
3884 | INIT_LIST_HEAD(&btv->capture); | 3902 | INIT_LIST_HEAD(&btv->capture); |
3885 | INIT_LIST_HEAD(&btv->vcapture); | 3903 | INIT_LIST_HEAD(&btv->vcapture); |
3886 | v4l2_prio_init(&btv->prio); | 3904 | v4l2_prio_init(&btv->prio); |
3887 | 3905 | ||
3888 | init_timer(&btv->timeout); | 3906 | init_timer(&btv->timeout); |
3889 | btv->timeout.function = bttv_irq_timeout; | 3907 | btv->timeout.function = bttv_irq_timeout; |
3890 | btv->timeout.data = (unsigned long)btv; | 3908 | btv->timeout.data = (unsigned long)btv; |
3891 | 3909 | ||
3892 | btv->i2c_rc = -1; | 3910 | btv->i2c_rc = -1; |
3893 | btv->tuner_type = UNSET; | 3911 | btv->tuner_type = UNSET; |
3894 | btv->pinnacle_id = UNSET; | 3912 | btv->pinnacle_id = UNSET; |
3895 | btv->new_input = UNSET; | 3913 | btv->new_input = UNSET; |
3896 | btv->gpioirq = 1; | ||
3897 | btv->has_radio=radio[btv->c.nr]; | 3914 | btv->has_radio=radio[btv->c.nr]; |
3898 | 3915 | ||
3899 | /* pci stuff (init, get irq/mmio, ... */ | 3916 | /* pci stuff (init, get irq/mmio, ... */ |
3900 | btv->c.pci = dev; | 3917 | btv->c.pci = dev; |
3901 | btv->id = dev->device; | 3918 | btv->id = dev->device; |
3902 | if (pci_enable_device(dev)) { | 3919 | if (pci_enable_device(dev)) { |
3903 | printk(KERN_WARNING "bttv%d: Can't enable device.\n", | 3920 | printk(KERN_WARNING "bttv%d: Can't enable device.\n", |
3904 | btv->c.nr); | 3921 | btv->c.nr); |
3905 | return -EIO; | 3922 | return -EIO; |
3906 | } | 3923 | } |
3907 | if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { | 3924 | if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { |
3908 | printk(KERN_WARNING "bttv%d: No suitable DMA available.\n", | 3925 | printk(KERN_WARNING "bttv%d: No suitable DMA available.\n", |
3909 | btv->c.nr); | 3926 | btv->c.nr); |
3910 | return -EIO; | 3927 | return -EIO; |
3911 | } | 3928 | } |
3912 | if (!request_mem_region(pci_resource_start(dev,0), | 3929 | if (!request_mem_region(pci_resource_start(dev,0), |
3913 | pci_resource_len(dev,0), | 3930 | pci_resource_len(dev,0), |
3914 | btv->c.name)) { | 3931 | btv->c.name)) { |
3915 | printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n", | 3932 | printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n", |
3916 | btv->c.nr, pci_resource_start(dev,0)); | 3933 | btv->c.nr, pci_resource_start(dev,0)); |
3917 | return -EBUSY; | 3934 | return -EBUSY; |
3918 | } | 3935 | } |
3919 | pci_set_master(dev); | 3936 | pci_set_master(dev); |
3920 | pci_set_command(dev); | 3937 | pci_set_command(dev); |
3921 | pci_set_drvdata(dev,btv); | 3938 | pci_set_drvdata(dev,btv); |
3922 | 3939 | ||
3923 | pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision); | 3940 | pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision); |
3924 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); | 3941 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); |
3925 | printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", | 3942 | printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", |
3926 | bttv_num,btv->id, btv->revision, pci_name(dev)); | 3943 | bttv_num,btv->id, btv->revision, pci_name(dev)); |
3927 | printk("irq: %d, latency: %d, mmio: 0x%lx\n", | 3944 | printk("irq: %d, latency: %d, mmio: 0x%lx\n", |
3928 | btv->c.pci->irq, lat, pci_resource_start(dev,0)); | 3945 | btv->c.pci->irq, lat, pci_resource_start(dev,0)); |
3929 | schedule(); | 3946 | schedule(); |
3930 | 3947 | ||
@@ -3935,23 +3952,23 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
3935 | goto fail1; | 3952 | goto fail1; |
3936 | } | 3953 | } |
3937 | 3954 | ||
3938 | /* identify card */ | 3955 | /* identify card */ |
3939 | bttv_idcard(btv); | 3956 | bttv_idcard(btv); |
3940 | 3957 | ||
3941 | /* disable irqs, register irq handler */ | 3958 | /* disable irqs, register irq handler */ |
3942 | btwrite(0, BT848_INT_MASK); | 3959 | btwrite(0, BT848_INT_MASK); |
3943 | result = request_irq(btv->c.pci->irq, bttv_irq, | 3960 | result = request_irq(btv->c.pci->irq, bttv_irq, |
3944 | SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv); | 3961 | SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv); |
3945 | if (result < 0) { | 3962 | if (result < 0) { |
3946 | printk(KERN_ERR "bttv%d: can't get IRQ %d\n", | 3963 | printk(KERN_ERR "bttv%d: can't get IRQ %d\n", |
3947 | bttv_num,btv->c.pci->irq); | 3964 | bttv_num,btv->c.pci->irq); |
3948 | goto fail1; | 3965 | goto fail1; |
3949 | } | 3966 | } |
3950 | 3967 | ||
3951 | if (0 != bttv_handle_chipset(btv)) { | 3968 | if (0 != bttv_handle_chipset(btv)) { |
3952 | result = -EIO; | 3969 | result = -EIO; |
3953 | goto fail2; | 3970 | goto fail2; |
3954 | } | 3971 | } |
3955 | 3972 | ||
3956 | /* init options from insmod args */ | 3973 | /* init options from insmod args */ |
3957 | btv->opt_combfilter = combfilter; | 3974 | btv->opt_combfilter = combfilter; |
@@ -3977,29 +3994,29 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
3977 | btv->input = 0; | 3994 | btv->input = 0; |
3978 | 3995 | ||
3979 | /* initialize hardware */ | 3996 | /* initialize hardware */ |
3980 | if (bttv_gpio) | 3997 | if (bttv_gpio) |
3981 | bttv_gpio_tracking(btv,"pre-init"); | 3998 | bttv_gpio_tracking(btv,"pre-init"); |
3982 | 3999 | ||
3983 | bttv_risc_init_main(btv); | 4000 | bttv_risc_init_main(btv); |
3984 | init_bt848(btv); | 4001 | init_bt848(btv); |
3985 | 4002 | ||
3986 | /* gpio */ | 4003 | /* gpio */ |
3987 | btwrite(0x00, BT848_GPIO_REG_INP); | 4004 | btwrite(0x00, BT848_GPIO_REG_INP); |
3988 | btwrite(0x00, BT848_GPIO_OUT_EN); | 4005 | btwrite(0x00, BT848_GPIO_OUT_EN); |
3989 | if (bttv_verbose) | 4006 | if (bttv_verbose) |
3990 | bttv_gpio_tracking(btv,"init"); | 4007 | bttv_gpio_tracking(btv,"init"); |
3991 | 4008 | ||
3992 | /* needs to be done before i2c is registered */ | 4009 | /* needs to be done before i2c is registered */ |
3993 | bttv_init_card1(btv); | 4010 | bttv_init_card1(btv); |
3994 | 4011 | ||
3995 | /* register i2c + gpio */ | 4012 | /* register i2c + gpio */ |
3996 | init_bttv_i2c(btv); | 4013 | init_bttv_i2c(btv); |
3997 | 4014 | ||
3998 | /* some card-specific stuff (needs working i2c) */ | 4015 | /* some card-specific stuff (needs working i2c) */ |
3999 | bttv_init_card2(btv); | 4016 | bttv_init_card2(btv); |
4000 | init_irqreg(btv); | 4017 | init_irqreg(btv); |
4001 | 4018 | ||
4002 | /* register video4linux + input */ | 4019 | /* register video4linux + input */ |
4003 | if (!bttv_tvcards[btv->c.type].no_video) { | 4020 | if (!bttv_tvcards[btv->c.type].no_video) { |
4004 | bttv_register_video(btv); | 4021 | bttv_register_video(btv); |
4005 | bt848_bright(btv,32768); | 4022 | bt848_bright(btv,32768); |
@@ -4018,10 +4035,10 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
4018 | 4035 | ||
4019 | /* everything is fine */ | 4036 | /* everything is fine */ |
4020 | bttv_num++; | 4037 | bttv_num++; |
4021 | return 0; | 4038 | return 0; |
4022 | 4039 | ||
4023 | fail2: | 4040 | fail2: |
4024 | free_irq(btv->c.pci->irq,btv); | 4041 | free_irq(btv->c.pci->irq,btv); |
4025 | 4042 | ||
4026 | fail1: | 4043 | fail1: |
4027 | if (btv->bt848_mmio) | 4044 | if (btv->bt848_mmio) |
@@ -4034,12 +4051,12 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
4034 | 4051 | ||
4035 | static void __devexit bttv_remove(struct pci_dev *pci_dev) | 4052 | static void __devexit bttv_remove(struct pci_dev *pci_dev) |
4036 | { | 4053 | { |
4037 | struct bttv *btv = pci_get_drvdata(pci_dev); | 4054 | struct bttv *btv = pci_get_drvdata(pci_dev); |
4038 | 4055 | ||
4039 | if (bttv_verbose) | 4056 | if (bttv_verbose) |
4040 | printk("bttv%d: unloading\n",btv->c.nr); | 4057 | printk("bttv%d: unloading\n",btv->c.nr); |
4041 | 4058 | ||
4042 | /* shutdown everything (DMA+IRQs) */ | 4059 | /* shutdown everything (DMA+IRQs) */ |
4043 | btand(~15, BT848_GPIO_DMA_CTL); | 4060 | btand(~15, BT848_GPIO_DMA_CTL); |
4044 | btwrite(0, BT848_INT_MASK); | 4061 | btwrite(0, BT848_INT_MASK); |
4045 | btwrite(~0x0, BT848_INT_STAT); | 4062 | btwrite(~0x0, BT848_INT_STAT); |
@@ -4052,7 +4069,7 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev) | |||
4052 | wake_up(&btv->gpioq); | 4069 | wake_up(&btv->gpioq); |
4053 | bttv_sub_del_devices(&btv->c); | 4070 | bttv_sub_del_devices(&btv->c); |
4054 | 4071 | ||
4055 | /* unregister i2c_bus + input */ | 4072 | /* unregister i2c_bus + input */ |
4056 | fini_bttv_i2c(btv); | 4073 | fini_bttv_i2c(btv); |
4057 | 4074 | ||
4058 | /* unregister video4linux */ | 4075 | /* unregister video4linux */ |
@@ -4062,18 +4079,18 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev) | |||
4062 | btcx_riscmem_free(btv->c.pci,&btv->main); | 4079 | btcx_riscmem_free(btv->c.pci,&btv->main); |
4063 | 4080 | ||
4064 | /* free ressources */ | 4081 | /* free ressources */ |
4065 | free_irq(btv->c.pci->irq,btv); | 4082 | free_irq(btv->c.pci->irq,btv); |
4066 | iounmap(btv->bt848_mmio); | 4083 | iounmap(btv->bt848_mmio); |
4067 | release_mem_region(pci_resource_start(btv->c.pci,0), | 4084 | release_mem_region(pci_resource_start(btv->c.pci,0), |
4068 | pci_resource_len(btv->c.pci,0)); | 4085 | pci_resource_len(btv->c.pci,0)); |
4069 | 4086 | ||
4070 | pci_set_drvdata(pci_dev, NULL); | 4087 | pci_set_drvdata(pci_dev, NULL); |
4071 | return; | 4088 | return; |
4072 | } | 4089 | } |
4073 | 4090 | ||
4074 | static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state) | 4091 | static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state) |
4075 | { | 4092 | { |
4076 | struct bttv *btv = pci_get_drvdata(pci_dev); | 4093 | struct bttv *btv = pci_get_drvdata(pci_dev); |
4077 | struct bttv_buffer_set idle; | 4094 | struct bttv_buffer_set idle; |
4078 | unsigned long flags; | 4095 | unsigned long flags; |
4079 | 4096 | ||
@@ -4108,7 +4125,7 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state) | |||
4108 | 4125 | ||
4109 | static int bttv_resume(struct pci_dev *pci_dev) | 4126 | static int bttv_resume(struct pci_dev *pci_dev) |
4110 | { | 4127 | { |
4111 | struct bttv *btv = pci_get_drvdata(pci_dev); | 4128 | struct bttv *btv = pci_get_drvdata(pci_dev); |
4112 | unsigned long flags; | 4129 | unsigned long flags; |
4113 | int err; | 4130 | int err; |
4114 | 4131 | ||
@@ -4153,24 +4170,24 @@ static int bttv_resume(struct pci_dev *pci_dev) | |||
4153 | } | 4170 | } |
4154 | 4171 | ||
4155 | static struct pci_device_id bttv_pci_tbl[] = { | 4172 | static struct pci_device_id bttv_pci_tbl[] = { |
4156 | {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848, | 4173 | {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848, |
4157 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 4174 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
4158 | {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849, | 4175 | {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849, |
4159 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 4176 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
4160 | {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878, | 4177 | {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878, |
4161 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 4178 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
4162 | {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879, | 4179 | {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879, |
4163 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 4180 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
4164 | {0,} | 4181 | {0,} |
4165 | }; | 4182 | }; |
4166 | 4183 | ||
4167 | MODULE_DEVICE_TABLE(pci, bttv_pci_tbl); | 4184 | MODULE_DEVICE_TABLE(pci, bttv_pci_tbl); |
4168 | 4185 | ||
4169 | static struct pci_driver bttv_pci_driver = { | 4186 | static struct pci_driver bttv_pci_driver = { |
4170 | .name = "bttv", | 4187 | .name = "bttv", |
4171 | .id_table = bttv_pci_tbl, | 4188 | .id_table = bttv_pci_tbl, |
4172 | .probe = bttv_probe, | 4189 | .probe = bttv_probe, |
4173 | .remove = __devexit_p(bttv_remove), | 4190 | .remove = __devexit_p(bttv_remove), |
4174 | .suspend = bttv_suspend, | 4191 | .suspend = bttv_suspend, |
4175 | .resume = bttv_resume, | 4192 | .resume = bttv_resume, |
4176 | }; | 4193 | }; |
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c index 6b280c03e398..575ce8b8e714 100644 --- a/drivers/media/video/bttv-gpio.c +++ b/drivers/media/video/bttv-gpio.c | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | 8 | ||
9 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) | 9 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) |
10 | & Marcus Metzler (mocm@thp.uni-koeln.de) | 10 | & Marcus Metzler (mocm@thp.uni-koeln.de) |
11 | (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> | 11 | (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> |
12 | 12 | ||
13 | This program is free software; you can redistribute it and/or modify | 13 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c index e684df37eb0e..77619eb131f6 100644 --- a/drivers/media/video/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c | |||
@@ -5,7 +5,7 @@ | |||
5 | bttv - Bt848 frame grabber driver | 5 | bttv - Bt848 frame grabber driver |
6 | 6 | ||
7 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) | 7 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) |
8 | & Marcus Metzler (mocm@thp.uni-koeln.de) | 8 | & Marcus Metzler (mocm@thp.uni-koeln.de) |
9 | (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> | 9 | (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> |
10 | 10 | ||
11 | This program is free software; you can redistribute it and/or modify | 11 | This program is free software; you can redistribute it and/or modify |
@@ -237,7 +237,7 @@ bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last) | |||
237 | err: | 237 | err: |
238 | if (i2c_debug) | 238 | if (i2c_debug) |
239 | printk(" ERR: %d\n",retval); | 239 | printk(" ERR: %d\n",retval); |
240 | return retval; | 240 | return retval; |
241 | } | 241 | } |
242 | 242 | ||
243 | static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) | 243 | static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) |
@@ -290,7 +290,13 @@ static struct i2c_adapter bttv_i2c_adap_hw_template = { | |||
290 | 290 | ||
291 | static int attach_inform(struct i2c_client *client) | 291 | static int attach_inform(struct i2c_client *client) |
292 | { | 292 | { |
293 | struct bttv *btv = i2c_get_adapdata(client->adapter); | 293 | struct bttv *btv = i2c_get_adapdata(client->adapter); |
294 | int addr=ADDR_UNSET; | ||
295 | |||
296 | |||
297 | if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr) | ||
298 | addr = bttv_tvcards[btv->c.type].tuner_addr; | ||
299 | |||
294 | 300 | ||
295 | if (bttv_debug) | 301 | if (bttv_debug) |
296 | printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n", | 302 | printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n", |
@@ -300,19 +306,20 @@ static int attach_inform(struct i2c_client *client) | |||
300 | return 0; | 306 | return 0; |
301 | 307 | ||
302 | if (btv->tuner_type != UNSET) { | 308 | if (btv->tuner_type != UNSET) { |
303 | struct tuner_setup tun_setup; | 309 | struct tuner_setup tun_setup; |
310 | |||
311 | if ((addr==ADDR_UNSET) || | ||
312 | (addr==client->addr)) { | ||
304 | 313 | ||
305 | tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; | 314 | tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO; |
306 | tun_setup.type = btv->tuner_type; | 315 | tun_setup.type = btv->tuner_type; |
307 | tun_setup.addr = ADDR_UNSET; | 316 | tun_setup.addr = addr; |
317 | bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); | ||
318 | } | ||
308 | 319 | ||
309 | client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup); | ||
310 | } | 320 | } |
311 | 321 | ||
312 | if (btv->pinnacle_id != UNSET) | 322 | return 0; |
313 | client->driver->command(client,AUDC_CONFIG_PINNACLE, | ||
314 | &btv->pinnacle_id); | ||
315 | return 0; | ||
316 | } | 323 | } |
317 | 324 | ||
318 | void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) | 325 | void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) |
@@ -330,43 +337,43 @@ static struct i2c_client bttv_i2c_client_template = { | |||
330 | /* read I2C */ | 337 | /* read I2C */ |
331 | int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) | 338 | int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) |
332 | { | 339 | { |
333 | unsigned char buffer = 0; | 340 | unsigned char buffer = 0; |
334 | 341 | ||
335 | if (0 != btv->i2c_rc) | 342 | if (0 != btv->i2c_rc) |
336 | return -1; | 343 | return -1; |
337 | if (bttv_verbose && NULL != probe_for) | 344 | if (bttv_verbose && NULL != probe_for) |
338 | printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ", | 345 | printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ", |
339 | btv->c.nr,probe_for,addr); | 346 | btv->c.nr,probe_for,addr); |
340 | btv->i2c_client.addr = addr >> 1; | 347 | btv->i2c_client.addr = addr >> 1; |
341 | if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) { | 348 | if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) { |
342 | if (NULL != probe_for) { | 349 | if (NULL != probe_for) { |
343 | if (bttv_verbose) | 350 | if (bttv_verbose) |
344 | printk("not found\n"); | 351 | printk("not found\n"); |
345 | } else | 352 | } else |
346 | printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n", | 353 | printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n", |
347 | btv->c.nr,addr); | 354 | btv->c.nr,addr); |
348 | return -1; | 355 | return -1; |
349 | } | 356 | } |
350 | if (bttv_verbose && NULL != probe_for) | 357 | if (bttv_verbose && NULL != probe_for) |
351 | printk("found\n"); | 358 | printk("found\n"); |
352 | return buffer; | 359 | return buffer; |
353 | } | 360 | } |
354 | 361 | ||
355 | /* write I2C */ | 362 | /* write I2C */ |
356 | int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, | 363 | int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, |
357 | unsigned char b2, int both) | 364 | unsigned char b2, int both) |
358 | { | 365 | { |
359 | unsigned char buffer[2]; | 366 | unsigned char buffer[2]; |
360 | int bytes = both ? 2 : 1; | 367 | int bytes = both ? 2 : 1; |
361 | 368 | ||
362 | if (0 != btv->i2c_rc) | 369 | if (0 != btv->i2c_rc) |
363 | return -1; | 370 | return -1; |
364 | btv->i2c_client.addr = addr >> 1; | 371 | btv->i2c_client.addr = addr >> 1; |
365 | buffer[0] = b1; | 372 | buffer[0] = b1; |
366 | buffer[1] = b2; | 373 | buffer[1] = b2; |
367 | if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes)) | 374 | if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes)) |
368 | return -1; | 375 | return -1; |
369 | return 0; | 376 | return 0; |
370 | } | 377 | } |
371 | 378 | ||
372 | /* read EEPROM content */ | 379 | /* read EEPROM content */ |
@@ -431,8 +438,8 @@ int __devinit init_bttv_i2c(struct bttv *btv) | |||
431 | "bt%d #%d [%s]", btv->id, btv->c.nr, | 438 | "bt%d #%d [%s]", btv->id, btv->c.nr, |
432 | btv->use_i2c_hw ? "hw" : "sw"); | 439 | btv->use_i2c_hw ? "hw" : "sw"); |
433 | 440 | ||
434 | i2c_set_adapdata(&btv->c.i2c_adap, btv); | 441 | i2c_set_adapdata(&btv->c.i2c_adap, btv); |
435 | btv->i2c_client.adapter = &btv->c.i2c_adap; | 442 | btv->i2c_client.adapter = &btv->c.i2c_adap; |
436 | 443 | ||
437 | #ifdef I2C_CLASS_TV_ANALOG | 444 | #ifdef I2C_CLASS_TV_ANALOG |
438 | if (bttv_tvcards[btv->c.type].no_video) | 445 | if (bttv_tvcards[btv->c.type].no_video) |
diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c index e8aada772b89..19b564ab0e92 100644 --- a/drivers/media/video/bttv-if.c +++ b/drivers/media/video/bttv-if.c | |||
@@ -1,13 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | 2 | ||
3 | bttv-if.c -- old gpio interface to other kernel modules | 3 | bttv-if.c -- old gpio interface to other kernel modules |
4 | don't use in new code, will go away in 2.7 | 4 | don't use in new code, will go away in 2.7 |
5 | have a look at bttv-gpio.c instead. | 5 | have a look at bttv-gpio.c instead. |
6 | 6 | ||
7 | bttv - Bt848 frame grabber driver | 7 | bttv - Bt848 frame grabber driver |
8 | 8 | ||
9 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) | 9 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) |
10 | & Marcus Metzler (mocm@thp.uni-koeln.de) | 10 | & Marcus Metzler (mocm@thp.uni-koeln.de) |
11 | (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> | 11 | (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> |
12 | 12 | ||
13 | This program is free software; you can redistribute it and/or modify | 13 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c index a5ed99b89445..b40e9734bf08 100644 --- a/drivers/media/video/bttv-risc.c +++ b/drivers/media/video/bttv-risc.c | |||
@@ -74,27 +74,27 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, | |||
74 | } | 74 | } |
75 | if (bpl <= sg_dma_len(sg)-offset) { | 75 | if (bpl <= sg_dma_len(sg)-offset) { |
76 | /* fits into current chunk */ | 76 | /* fits into current chunk */ |
77 | *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| | 77 | *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| |
78 | BT848_RISC_EOL|bpl); | 78 | BT848_RISC_EOL|bpl); |
79 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); | 79 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); |
80 | offset+=bpl; | 80 | offset+=bpl; |
81 | } else { | 81 | } else { |
82 | /* scanline needs to be splitted */ | 82 | /* scanline needs to be splitted */ |
83 | todo = bpl; | 83 | todo = bpl; |
84 | *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| | 84 | *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| |
85 | (sg_dma_len(sg)-offset)); | 85 | (sg_dma_len(sg)-offset)); |
86 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); | 86 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); |
87 | todo -= (sg_dma_len(sg)-offset); | 87 | todo -= (sg_dma_len(sg)-offset); |
88 | offset = 0; | 88 | offset = 0; |
89 | sg++; | 89 | sg++; |
90 | while (todo > sg_dma_len(sg)) { | 90 | while (todo > sg_dma_len(sg)) { |
91 | *(rp++)=cpu_to_le32(BT848_RISC_WRITE| | 91 | *(rp++)=cpu_to_le32(BT848_RISC_WRITE| |
92 | sg_dma_len(sg)); | 92 | sg_dma_len(sg)); |
93 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); | 93 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); |
94 | todo -= sg_dma_len(sg); | 94 | todo -= sg_dma_len(sg); |
95 | sg++; | 95 | sg++; |
96 | } | 96 | } |
97 | *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL| | 97 | *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL| |
98 | todo); | 98 | todo); |
99 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); | 99 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); |
100 | offset += todo; | 100 | offset += todo; |
@@ -201,8 +201,8 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, | |||
201 | ri |= BT848_RISC_EOL; | 201 | ri |= BT848_RISC_EOL; |
202 | 202 | ||
203 | /* write risc instruction */ | 203 | /* write risc instruction */ |
204 | *(rp++)=cpu_to_le32(ri | ylen); | 204 | *(rp++)=cpu_to_le32(ri | ylen); |
205 | *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) | | 205 | *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) | |
206 | (ylen >> hshift)); | 206 | (ylen >> hshift)); |
207 | *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset); | 207 | *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset); |
208 | yoffset += ylen; | 208 | yoffset += ylen; |
@@ -319,7 +319,7 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo, | |||
319 | int width, int height, int interleaved, int norm) | 319 | int width, int height, int interleaved, int norm) |
320 | { | 320 | { |
321 | const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm]; | 321 | const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm]; |
322 | u32 xsf, sr; | 322 | u32 xsf, sr; |
323 | int vdelay; | 323 | int vdelay; |
324 | 324 | ||
325 | int swidth = tvnorm->swidth; | 325 | int swidth = tvnorm->swidth; |
@@ -334,52 +334,52 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo, | |||
334 | 334 | ||
335 | vdelay = tvnorm->vdelay; | 335 | vdelay = tvnorm->vdelay; |
336 | 336 | ||
337 | xsf = (width*scaledtwidth)/swidth; | 337 | xsf = (width*scaledtwidth)/swidth; |
338 | geo->hscale = ((totalwidth*4096UL)/xsf-4096); | 338 | geo->hscale = ((totalwidth*4096UL)/xsf-4096); |
339 | geo->hdelay = tvnorm->hdelayx1; | 339 | geo->hdelay = tvnorm->hdelayx1; |
340 | geo->hdelay = (geo->hdelay*width)/swidth; | 340 | geo->hdelay = (geo->hdelay*width)/swidth; |
341 | geo->hdelay &= 0x3fe; | 341 | geo->hdelay &= 0x3fe; |
342 | sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512; | 342 | sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512; |
343 | geo->vscale = (0x10000UL-sr) & 0x1fff; | 343 | geo->vscale = (0x10000UL-sr) & 0x1fff; |
344 | geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) | | 344 | geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) | |
345 | ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0); | 345 | ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0); |
346 | geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0; | 346 | geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0; |
347 | geo->vdelay = vdelay; | 347 | geo->vdelay = vdelay; |
348 | geo->width = width; | 348 | geo->width = width; |
349 | geo->sheight = tvnorm->sheight; | 349 | geo->sheight = tvnorm->sheight; |
350 | geo->vtotal = tvnorm->vtotal; | 350 | geo->vtotal = tvnorm->vtotal; |
351 | 351 | ||
352 | if (btv->opt_combfilter) { | 352 | if (btv->opt_combfilter) { |
353 | geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0); | 353 | geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0); |
354 | geo->comb = (width < 769) ? 1 : 0; | 354 | geo->comb = (width < 769) ? 1 : 0; |
355 | } else { | 355 | } else { |
356 | geo->vtc = 0; | 356 | geo->vtc = 0; |
357 | geo->comb = 0; | 357 | geo->comb = 0; |
358 | } | 358 | } |
359 | } | 359 | } |
360 | 360 | ||
361 | static void | 361 | static void |
362 | bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) | 362 | bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) |
363 | { | 363 | { |
364 | int off = odd ? 0x80 : 0x00; | 364 | int off = odd ? 0x80 : 0x00; |
365 | 365 | ||
366 | if (geo->comb) | 366 | if (geo->comb) |
367 | btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); | 367 | btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); |
368 | else | 368 | else |
369 | btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); | 369 | btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); |
370 | 370 | ||
371 | btwrite(geo->vtc, BT848_E_VTC+off); | 371 | btwrite(geo->vtc, BT848_E_VTC+off); |
372 | btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off); | 372 | btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off); |
373 | btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off); | 373 | btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off); |
374 | btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off); | 374 | btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off); |
375 | btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off); | 375 | btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off); |
376 | btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off); | 376 | btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off); |
377 | btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off); | 377 | btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off); |
378 | btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off); | 378 | btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off); |
379 | btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off); | 379 | btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off); |
380 | btwrite(geo->crop, BT848_E_CROP+off); | 380 | btwrite(geo->crop, BT848_E_CROP+off); |
381 | btwrite(geo->vtotal>>8, BT848_VTOTAL_HI); | 381 | btwrite(geo->vtotal>>8, BT848_VTOTAL_HI); |
382 | btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO); | 382 | btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO); |
383 | } | 383 | } |
384 | 384 | ||
385 | /* ---------------------------------------------------------- */ | 385 | /* ---------------------------------------------------------- */ |
@@ -420,7 +420,7 @@ bttv_set_dma(struct bttv *btv, int override) | |||
420 | } else { | 420 | } else { |
421 | del_timer(&btv->timeout); | 421 | del_timer(&btv->timeout); |
422 | } | 422 | } |
423 | btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd); | 423 | btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd); |
424 | 424 | ||
425 | btaor(capctl, ~0x0f, BT848_CAP_CTL); | 425 | btaor(capctl, ~0x0f, BT848_CAP_CTL); |
426 | if (capctl) { | 426 | if (capctl) { |
@@ -432,7 +432,7 @@ bttv_set_dma(struct bttv *btv, int override) | |||
432 | } else { | 432 | } else { |
433 | if (!btv->dma_on) | 433 | if (!btv->dma_on) |
434 | return; | 434 | return; |
435 | btand(~3, BT848_GPIO_DMA_CTL); | 435 | btand(~3, BT848_GPIO_DMA_CTL); |
436 | btv->dma_on = 0; | 436 | btv->dma_on = 0; |
437 | } | 437 | } |
438 | return; | 438 | return; |
@@ -460,19 +460,19 @@ bttv_risc_init_main(struct bttv *btv) | |||
460 | btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP); | 460 | btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP); |
461 | btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2)); | 461 | btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2)); |
462 | 462 | ||
463 | btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | | 463 | btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | |
464 | BT848_FIFO_STATUS_VRO); | 464 | BT848_FIFO_STATUS_VRO); |
465 | btv->main.cpu[9] = cpu_to_le32(0); | 465 | btv->main.cpu[9] = cpu_to_le32(0); |
466 | 466 | ||
467 | /* bottom field */ | 467 | /* bottom field */ |
468 | btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP); | 468 | btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP); |
469 | btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2)); | 469 | btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2)); |
470 | btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP); | 470 | btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP); |
471 | btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2)); | 471 | btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2)); |
472 | 472 | ||
473 | /* jump back to top field */ | 473 | /* jump back to top field */ |
474 | btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP); | 474 | btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP); |
475 | btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2)); | 475 | btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2)); |
476 | 476 | ||
477 | return 0; | 477 | return 0; |
478 | } | 478 | } |
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h index d254e90e3bb9..124ea41dada4 100644 --- a/drivers/media/video/bttv.h +++ b/drivers/media/video/bttv.h | |||
@@ -20,123 +20,148 @@ | |||
20 | /* ---------------------------------------------------------- */ | 20 | /* ---------------------------------------------------------- */ |
21 | /* exported by bttv-cards.c */ | 21 | /* exported by bttv-cards.c */ |
22 | 22 | ||
23 | #define BTTV_UNKNOWN 0x00 | 23 | #define BTTV_BOARD_UNKNOWN 0x00 |
24 | #define BTTV_MIRO 0x01 | 24 | #define BTTV_BOARD_MIRO 0x01 |
25 | #define BTTV_HAUPPAUGE 0x02 | 25 | #define BTTV_BOARD_HAUPPAUGE 0x02 |
26 | #define BTTV_STB 0x03 | 26 | #define BTTV_BOARD_STB 0x03 |
27 | #define BTTV_INTEL 0x04 | 27 | #define BTTV_BOARD_INTEL 0x04 |
28 | #define BTTV_DIAMOND 0x05 | 28 | #define BTTV_BOARD_DIAMOND 0x05 |
29 | #define BTTV_AVERMEDIA 0x06 | 29 | #define BTTV_BOARD_AVERMEDIA 0x06 |
30 | #define BTTV_MATRIX_VISION 0x07 | 30 | #define BTTV_BOARD_MATRIX_VISION 0x07 |
31 | #define BTTV_FLYVIDEO 0x08 | 31 | #define BTTV_BOARD_FLYVIDEO 0x08 |
32 | #define BTTV_TURBOTV 0x09 | 32 | #define BTTV_BOARD_TURBOTV 0x09 |
33 | #define BTTV_HAUPPAUGE878 0x0a | 33 | #define BTTV_BOARD_HAUPPAUGE878 0x0a |
34 | #define BTTV_MIROPRO 0x0b | 34 | #define BTTV_BOARD_MIROPRO 0x0b |
35 | #define BTTV_ADSTECH_TV 0x0c | 35 | #define BTTV_BOARD_ADSTECH_TV 0x0c |
36 | #define BTTV_AVERMEDIA98 0x0d | 36 | #define BTTV_BOARD_AVERMEDIA98 0x0d |
37 | #define BTTV_VHX 0x0e | 37 | #define BTTV_BOARD_VHX 0x0e |
38 | #define BTTV_ZOLTRIX 0x0f | 38 | #define BTTV_BOARD_ZOLTRIX 0x0f |
39 | #define BTTV_PIXVIEWPLAYTV 0x10 | 39 | #define BTTV_BOARD_PIXVIEWPLAYTV 0x10 |
40 | #define BTTV_WINVIEW_601 0x11 | 40 | #define BTTV_BOARD_WINVIEW_601 0x11 |
41 | #define BTTV_AVEC_INTERCAP 0x12 | 41 | #define BTTV_BOARD_AVEC_INTERCAP 0x12 |
42 | #define BTTV_LIFE_FLYKIT 0x13 | 42 | #define BTTV_BOARD_LIFE_FLYKIT 0x13 |
43 | #define BTTV_CEI_RAFFLES 0x14 | 43 | #define BTTV_BOARD_CEI_RAFFLES 0x14 |
44 | #define BTTV_CONFERENCETV 0x15 | 44 | #define BTTV_BOARD_CONFERENCETV 0x15 |
45 | #define BTTV_PHOEBE_TVMAS 0x16 | 45 | #define BTTV_BOARD_PHOEBE_TVMAS 0x16 |
46 | #define BTTV_MODTEC_205 0x17 | 46 | #define BTTV_BOARD_MODTEC_205 0x17 |
47 | #define BTTV_MAGICTVIEW061 0x18 | 47 | #define BTTV_BOARD_MAGICTVIEW061 0x18 |
48 | #define BTTV_VOBIS_BOOSTAR 0x19 | 48 | #define BTTV_BOARD_VOBIS_BOOSTAR 0x19 |
49 | #define BTTV_HAUPPAUG_WCAM 0x1a | 49 | #define BTTV_BOARD_HAUPPAUG_WCAM 0x1a |
50 | #define BTTV_MAXI 0x1b | 50 | #define BTTV_BOARD_MAXI 0x1b |
51 | #define BTTV_TERRATV 0x1c | 51 | #define BTTV_BOARD_TERRATV 0x1c |
52 | #define BTTV_PXC200 0x1d | 52 | #define BTTV_BOARD_PXC200 0x1d |
53 | #define BTTV_FLYVIDEO_98 0x1e | 53 | #define BTTV_BOARD_FLYVIDEO_98 0x1e |
54 | #define BTTV_IPROTV 0x1f | 54 | #define BTTV_BOARD_IPROTV 0x1f |
55 | #define BTTV_INTEL_C_S_PCI 0x20 | 55 | #define BTTV_BOARD_INTEL_C_S_PCI 0x20 |
56 | #define BTTV_TERRATVALUE 0x21 | 56 | #define BTTV_BOARD_TERRATVALUE 0x21 |
57 | #define BTTV_WINFAST2000 0x22 | 57 | #define BTTV_BOARD_WINFAST2000 0x22 |
58 | #define BTTV_CHRONOS_VS2 0x23 | 58 | #define BTTV_BOARD_CHRONOS_VS2 0x23 |
59 | #define BTTV_TYPHOON_TVIEW 0x24 | 59 | #define BTTV_BOARD_TYPHOON_TVIEW 0x24 |
60 | #define BTTV_PXELVWPLTVPRO 0x25 | 60 | #define BTTV_BOARD_PXELVWPLTVPRO 0x25 |
61 | #define BTTV_MAGICTVIEW063 0x26 | 61 | #define BTTV_BOARD_MAGICTVIEW063 0x26 |
62 | #define BTTV_PINNACLE 0x27 | 62 | #define BTTV_BOARD_PINNACLE 0x27 |
63 | #define BTTV_STB2 0x28 | 63 | #define BTTV_BOARD_STB2 0x28 |
64 | #define BTTV_AVPHONE98 0x29 | 64 | #define BTTV_BOARD_AVPHONE98 0x29 |
65 | #define BTTV_PV951 0x2a | 65 | #define BTTV_BOARD_PV951 0x2a |
66 | #define BTTV_ONAIR_TV 0x2b | 66 | #define BTTV_BOARD_ONAIR_TV 0x2b |
67 | #define BTTV_SIGMA_TVII_FM 0x2c | 67 | #define BTTV_BOARD_SIGMA_TVII_FM 0x2c |
68 | #define BTTV_MATRIX_VISION2 0x2d | 68 | #define BTTV_BOARD_MATRIX_VISION2 0x2d |
69 | #define BTTV_ZOLTRIX_GENIE 0x2e | 69 | #define BTTV_BOARD_ZOLTRIX_GENIE 0x2e |
70 | #define BTTV_TERRATVRADIO 0x2f | 70 | #define BTTV_BOARD_TERRATVRADIO 0x2f |
71 | #define BTTV_DYNALINK 0x30 | 71 | #define BTTV_BOARD_DYNALINK 0x30 |
72 | #define BTTV_GVBCTV3PCI 0x31 | 72 | #define BTTV_BOARD_GVBCTV3PCI 0x31 |
73 | #define BTTV_PXELVWPLTVPAK 0x32 | 73 | #define BTTV_BOARD_PXELVWPLTVPAK 0x32 |
74 | #define BTTV_EAGLE 0x33 | 74 | #define BTTV_BOARD_EAGLE 0x33 |
75 | #define BTTV_PINNACLEPRO 0x34 | 75 | #define BTTV_BOARD_PINNACLEPRO 0x34 |
76 | #define BTTV_TVIEW_RDS_FM 0x35 | 76 | #define BTTV_BOARD_TVIEW_RDS_FM 0x35 |
77 | #define BTTV_LIFETEC_9415 0x36 | 77 | #define BTTV_BOARD_LIFETEC_9415 0x36 |
78 | #define BTTV_BESTBUY_EASYTV 0x37 | 78 | #define BTTV_BOARD_BESTBUY_EASYTV 0x37 |
79 | #define BTTV_FLYVIDEO_98FM 0x38 | 79 | #define BTTV_BOARD_FLYVIDEO_98FM 0x38 |
80 | #define BTTV_GMV1 0x3d | 80 | #define BTTV_BOARD_GRANDTEC 0x39 |
81 | #define BTTV_BESTBUY_EASYTV2 0x3e | 81 | #define BTTV_BOARD_ASKEY_CPH060 0x3a |
82 | #define BTTV_ATI_TVWONDER 0x3f | 82 | #define BTTV_BOARD_ASKEY_CPH03X 0x3b |
83 | #define BTTV_ATI_TVWONDERVE 0x40 | 83 | #define BTTV_BOARD_MM100PCTV 0x3c |
84 | #define BTTV_FLYVIDEO2000 0x41 | 84 | #define BTTV_BOARD_GMV1 0x3d |
85 | #define BTTV_TERRATVALUER 0x42 | 85 | #define BTTV_BOARD_BESTBUY_EASYTV2 0x3e |
86 | #define BTTV_GVBCTV4PCI 0x43 | 86 | #define BTTV_BOARD_ATI_TVWONDER 0x3f |
87 | #define BTTV_VOODOOTV_FM 0x44 | 87 | #define BTTV_BOARD_ATI_TVWONDERVE 0x40 |
88 | #define BTTV_AIMMS 0x45 | 88 | #define BTTV_BOARD_FLYVIDEO2000 0x41 |
89 | #define BTTV_PV_BT878P_PLUS 0x46 | 89 | #define BTTV_BOARD_TERRATVALUER 0x42 |
90 | #define BTTV_FLYVIDEO98EZ 0x47 | 90 | #define BTTV_BOARD_GVBCTV4PCI 0x43 |
91 | #define BTTV_PV_BT878P_9B 0x48 | 91 | #define BTTV_BOARD_VOODOOTV_FM 0x44 |
92 | #define BTTV_SENSORAY311 0x49 | 92 | #define BTTV_BOARD_AIMMS 0x45 |
93 | #define BTTV_RV605 0x4a | 93 | #define BTTV_BOARD_PV_BT878P_PLUS 0x46 |
94 | #define BTTV_WINDVR 0x4c | 94 | #define BTTV_BOARD_FLYVIDEO98EZ 0x47 |
95 | #define BTTV_GRANDTEC 0x4d | 95 | #define BTTV_BOARD_PV_BT878P_9B 0x48 |
96 | #define BTTV_KWORLD 0x4e | 96 | #define BTTV_BOARD_SENSORAY311 0x49 |
97 | #define BTTV_HAUPPAUGEPVR 0x50 | 97 | #define BTTV_BOARD_RV605 0x4a |
98 | #define BTTV_GVBCTV5PCI 0x51 | 98 | #define BTTV_BOARD_POWERCLR_MTV878 0x4b |
99 | #define BTTV_OSPREY1x0 0x52 | 99 | #define BTTV_BOARD_WINDVR 0x4c |
100 | #define BTTV_OSPREY1x0_848 0x53 | 100 | #define BTTV_BOARD_GRANDTEC_MULTI 0x4d |
101 | #define BTTV_OSPREY101_848 0x54 | 101 | #define BTTV_BOARD_KWORLD 0x4e |
102 | #define BTTV_OSPREY1x1 0x55 | 102 | #define BTTV_BOARD_DSP_TCVIDEO 0x4f |
103 | #define BTTV_OSPREY1x1_SVID 0x56 | 103 | #define BTTV_BOARD_HAUPPAUGEPVR 0x50 |
104 | #define BTTV_OSPREY2xx 0x57 | 104 | #define BTTV_BOARD_GVBCTV5PCI 0x51 |
105 | #define BTTV_OSPREY2x0_SVID 0x58 | 105 | #define BTTV_BOARD_OSPREY1x0 0x52 |
106 | #define BTTV_OSPREY2x0 0x59 | 106 | #define BTTV_BOARD_OSPREY1x0_848 0x53 |
107 | #define BTTV_OSPREY500 0x5a | 107 | #define BTTV_BOARD_OSPREY101_848 0x54 |
108 | #define BTTV_OSPREY540 0x5b | 108 | #define BTTV_BOARD_OSPREY1x1 0x55 |
109 | #define BTTV_OSPREY2000 0x5c | 109 | #define BTTV_BOARD_OSPREY1x1_SVID 0x56 |
110 | #define BTTV_IDS_EAGLE 0x5d | 110 | #define BTTV_BOARD_OSPREY2xx 0x57 |
111 | #define BTTV_PINNACLESAT 0x5e | 111 | #define BTTV_BOARD_OSPREY2x0_SVID 0x58 |
112 | #define BTTV_FORMAC_PROTV 0x5f | 112 | #define BTTV_BOARD_OSPREY2x0 0x59 |
113 | #define BTTV_EURESYS_PICOLO 0x61 | 113 | #define BTTV_BOARD_OSPREY500 0x5a |
114 | #define BTTV_PV150 0x62 | 114 | #define BTTV_BOARD_OSPREY540 0x5b |
115 | #define BTTV_AD_TVK503 0x63 | 115 | #define BTTV_BOARD_OSPREY2000 0x5c |
116 | #define BTTV_IVC200 0x66 | 116 | #define BTTV_BOARD_IDS_EAGLE 0x5d |
117 | #define BTTV_XGUARD 0x67 | 117 | #define BTTV_BOARD_PINNACLESAT 0x5e |
118 | #define BTTV_NEBULA_DIGITV 0x68 | 118 | #define BTTV_BOARD_FORMAC_PROTV 0x5f |
119 | #define BTTV_PV143 0x69 | 119 | #define BTTV_BOARD_MACHTV 0x60 |
120 | #define BTTV_IVC100 0x6e | 120 | #define BTTV_BOARD_EURESYS_PICOLO 0x61 |
121 | #define BTTV_IVC120 0x6f | 121 | #define BTTV_BOARD_PV150 0x62 |
122 | #define BTTV_PC_HDTV 0x70 | 122 | #define BTTV_BOARD_AD_TVK503 0x63 |
123 | #define BTTV_TWINHAN_DST 0x71 | 123 | #define BTTV_BOARD_HERCULES_SM_TV 0x64 |
124 | #define BTTV_WINFASTVC100 0x72 | 124 | #define BTTV_BOARD_PACETV 0x65 |
125 | #define BTTV_SIMUS_GVC1100 0x74 | 125 | #define BTTV_BOARD_IVC200 0x66 |
126 | #define BTTV_NGSTV_PLUS 0x75 | 126 | #define BTTV_BOARD_XGUARD 0x67 |
127 | #define BTTV_LMLBT4 0x76 | 127 | #define BTTV_BOARD_NEBULA_DIGITV 0x68 |
128 | #define BTTV_PICOLO_TETRA_CHIP 0x79 | 128 | #define BTTV_BOARD_PV143 0x69 |
129 | #define BTTV_AVDVBT_771 0x7b | 129 | #define BTTV_BOARD_VD009X1_MINIDIN 0x6a |
130 | #define BTTV_AVDVBT_761 0x7c | 130 | #define BTTV_BOARD_VD009X1_COMBI 0x6b |
131 | #define BTTV_MATRIX_VISIONSQ 0x7d | 131 | #define BTTV_BOARD_VD009_MINIDIN 0x6c |
132 | #define BTTV_MATRIX_VISIONSLC 0x7e | 132 | #define BTTV_BOARD_VD009_COMBI 0x6d |
133 | #define BTTV_APAC_VIEWCOMP 0x7f | 133 | #define BTTV_BOARD_IVC100 0x6e |
134 | #define BTTV_DVICO_DVBT_LITE 0x80 | 134 | #define BTTV_BOARD_IVC120 0x6f |
135 | #define BTTV_TIBET_CS16 0x83 | 135 | #define BTTV_BOARD_PC_HDTV 0x70 |
136 | #define BTTV_KODICOM_4400R 0x84 | 136 | #define BTTV_BOARD_TWINHAN_DST 0x71 |
137 | #define BTTV_ADLINK_RTV24 0x86 | 137 | #define BTTV_BOARD_WINFASTVC100 0x72 |
138 | #define BTTV_DVICO_FUSIONHDTV_5_LITE 0x87 | 138 | #define BTTV_BOARD_TEV560 0x73 |
139 | #define BTTV_ACORP_Y878F 0x88 | 139 | #define BTTV_BOARD_SIMUS_GVC1100 0x74 |
140 | #define BTTV_BOARD_NGSTV_PLUS 0x75 | ||
141 | #define BTTV_BOARD_LMLBT4 0x76 | ||
142 | #define BTTV_BOARD_TEKRAM_M205 0x77 | ||
143 | #define BTTV_BOARD_CONTVFMI 0x78 | ||
144 | #define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79 | ||
145 | #define BTTV_BOARD_SPIRIT_TV 0x7a | ||
146 | #define BTTV_BOARD_AVDVBT_771 0x7b | ||
147 | #define BTTV_BOARD_AVDVBT_761 0x7c | ||
148 | #define BTTV_BOARD_MATRIX_VISIONSQ 0x7d | ||
149 | #define BTTV_BOARD_MATRIX_VISIONSLC 0x7e | ||
150 | #define BTTV_BOARD_APAC_VIEWCOMP 0x7f | ||
151 | #define BTTV_BOARD_DVICO_DVBT_LITE 0x80 | ||
152 | #define BTTV_BOARD_VGEAR_MYVCD 0x81 | ||
153 | #define BTTV_BOARD_SUPER_TV 0x82 | ||
154 | #define BTTV_BOARD_TIBET_CS16 0x83 | ||
155 | #define BTTV_BOARD_KODICOM_4400R 0x84 | ||
156 | #define BTTV_BOARD_KODICOM_4400R_SL 0x85 | ||
157 | #define BTTV_BOARD_ADLINK_RTV24 0x86 | ||
158 | #define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87 | ||
159 | #define BTTV_BOARD_ACORP_Y878F 0x88 | ||
160 | #define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89 | ||
161 | #define BTTV_BOARD_PV_BT878P_2E 0x8a | ||
162 | #define BTTV_BOARD_PV_M4900 0x8b | ||
163 | #define BTTV_BOARD_OSPREY440 0x8c | ||
164 | #define BTTV_BOARD_ASOUND_SKYEYE 0x8d | ||
140 | 165 | ||
141 | /* i2c address list */ | 166 | /* i2c address list */ |
142 | #define I2C_TSA5522 0xc2 | 167 | #define I2C_TSA5522 0xc2 |
@@ -177,7 +202,7 @@ struct bttv_core { | |||
177 | struct list_head subs; /* struct bttv_sub_device */ | 202 | struct list_head subs; /* struct bttv_sub_device */ |
178 | 203 | ||
179 | /* device config */ | 204 | /* device config */ |
180 | unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ | 205 | unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ |
181 | unsigned int type; /* card type (pointer into tvcards[]) */ | 206 | unsigned int type; /* card type (pointer into tvcards[]) */ |
182 | char name[8]; /* dev name */ | 207 | char name[8]; /* dev name */ |
183 | }; | 208 | }; |
@@ -186,16 +211,16 @@ struct bttv; | |||
186 | 211 | ||
187 | struct tvcard | 212 | struct tvcard |
188 | { | 213 | { |
189 | char *name; | 214 | char *name; |
190 | unsigned int video_inputs; | 215 | unsigned int video_inputs; |
191 | unsigned int audio_inputs; | 216 | unsigned int audio_inputs; |
192 | unsigned int tuner; | 217 | unsigned int tuner; |
193 | unsigned int svhs; | 218 | unsigned int svhs; |
194 | unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO | 219 | unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO |
195 | u32 gpiomask; | 220 | u32 gpiomask; |
196 | u32 muxsel[16]; | 221 | u32 muxsel[16]; |
197 | u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */ | 222 | u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */ |
198 | u32 gpiomask2; /* GPIO MUX mask */ | 223 | u32 gpiomask2; /* GPIO MUX mask */ |
199 | 224 | ||
200 | /* i2c audio flags */ | 225 | /* i2c audio flags */ |
201 | unsigned int no_msp34xx:1; | 226 | unsigned int no_msp34xx:1; |
@@ -218,6 +243,7 @@ struct tvcard | |||
218 | 243 | ||
219 | unsigned int tuner_type; | 244 | unsigned int tuner_type; |
220 | unsigned int tuner_addr; | 245 | unsigned int tuner_addr; |
246 | unsigned int radio_addr; | ||
221 | 247 | ||
222 | unsigned int has_radio; | 248 | unsigned int has_radio; |
223 | void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); | 249 | void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); |
@@ -246,7 +272,7 @@ extern int bttv_handle_chipset(struct bttv *btv); | |||
246 | interface below for new code */ | 272 | interface below for new code */ |
247 | 273 | ||
248 | /* returns card type + card ID (for bt878-based ones) | 274 | /* returns card type + card ID (for bt878-based ones) |
249 | for possible values see lines below beginning with #define BTTV_UNKNOWN | 275 | for possible values see lines below beginning with #define BTTV_BOARD_UNKNOWN |
250 | returns negative value if error occurred | 276 | returns negative value if error occurred |
251 | */ | 277 | */ |
252 | extern int bttv_get_cardinfo(unsigned int card, int *type, | 278 | extern int bttv_get_cardinfo(unsigned int card, int *type, |
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h index e0e7c7a84bc5..386f546f7d11 100644 --- a/drivers/media/video/bttvp.h +++ b/drivers/media/video/bttvp.h | |||
@@ -77,14 +77,14 @@ | |||
77 | struct bttv_tvnorm { | 77 | struct bttv_tvnorm { |
78 | int v4l2_id; | 78 | int v4l2_id; |
79 | char *name; | 79 | char *name; |
80 | u32 Fsc; | 80 | u32 Fsc; |
81 | u16 swidth, sheight; /* scaled standard width, height */ | 81 | u16 swidth, sheight; /* scaled standard width, height */ |
82 | u16 totalwidth; | 82 | u16 totalwidth; |
83 | u8 adelay, bdelay, iform; | 83 | u8 adelay, bdelay, iform; |
84 | u32 scaledtwidth; | 84 | u32 scaledtwidth; |
85 | u16 hdelayx1, hactivex1; | 85 | u16 hdelayx1, hactivex1; |
86 | u16 vdelay; | 86 | u16 vdelay; |
87 | u8 vbipack; | 87 | u8 vbipack; |
88 | u16 vtotal; | 88 | u16 vtotal; |
89 | int sram; | 89 | int sram; |
90 | }; | 90 | }; |
@@ -267,8 +267,8 @@ struct bttv { | |||
267 | 267 | ||
268 | /* card configuration info */ | 268 | /* card configuration info */ |
269 | unsigned int cardid; /* pci subsystem id (bt878 based ones) */ | 269 | unsigned int cardid; /* pci subsystem id (bt878 based ones) */ |
270 | unsigned int tuner_type; /* tuner chip type */ | 270 | unsigned int tuner_type; /* tuner chip type */ |
271 | unsigned int pinnacle_id; | 271 | unsigned int pinnacle_id; |
272 | unsigned int svhs; | 272 | unsigned int svhs; |
273 | struct bttv_pll_info pll; | 273 | struct bttv_pll_info pll; |
274 | int triton1; | 274 | int triton1; |
@@ -301,9 +301,9 @@ struct bttv { | |||
301 | 301 | ||
302 | /* locking */ | 302 | /* locking */ |
303 | spinlock_t s_lock; | 303 | spinlock_t s_lock; |
304 | struct semaphore lock; | 304 | struct semaphore lock; |
305 | int resources; | 305 | int resources; |
306 | struct semaphore reslock; | 306 | struct semaphore reslock; |
307 | #ifdef VIDIOC_G_PRIORITY | 307 | #ifdef VIDIOC_G_PRIORITY |
308 | struct v4l2_prio_state prio; | 308 | struct v4l2_prio_state prio; |
309 | #endif | 309 | #endif |
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c new file mode 100644 index 000000000000..780b352ec119 --- /dev/null +++ b/drivers/media/video/cs53l32a.c | |||
@@ -0,0 +1,240 @@ | |||
1 | /* | ||
2 | * cs53l32a (Adaptec AVC-2010 and AVC-2410) i2c ivtv driver. | ||
3 | * Copyright (C) 2005 Martin Vaughan | ||
4 | * | ||
5 | * Audio source switching for Adaptec AVC-2410 added by Trev Jackson | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/types.h> | ||
25 | #include <linux/ioctl.h> | ||
26 | #include <asm/uaccess.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/i2c-id.h> | ||
29 | #include <linux/videodev.h> | ||
30 | #include <media/audiochip.h> | ||
31 | |||
32 | MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC"); | ||
33 | MODULE_AUTHOR("Martin Vaughan"); | ||
34 | MODULE_LICENSE("GPL"); | ||
35 | |||
36 | static int debug = 0; | ||
37 | |||
38 | module_param(debug, bool, 0644); | ||
39 | |||
40 | MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On"); | ||
41 | |||
42 | #define cs53l32a_dbg(fmt, arg...) \ | ||
43 | do { \ | ||
44 | if (debug) \ | ||
45 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | ||
46 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
47 | } while (0) | ||
48 | |||
49 | #define cs53l32a_err(fmt, arg...) do { \ | ||
50 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \ | ||
51 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
52 | #define cs53l32a_info(fmt, arg...) do { \ | ||
53 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \ | ||
54 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
55 | |||
56 | static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; | ||
57 | |||
58 | |||
59 | I2C_CLIENT_INSMOD; | ||
60 | |||
61 | /* ----------------------------------------------------------------------- */ | ||
62 | |||
63 | static int cs53l32a_write(struct i2c_client *client, u8 reg, u8 value) | ||
64 | { | ||
65 | return i2c_smbus_write_byte_data(client, reg, value); | ||
66 | } | ||
67 | |||
68 | static int cs53l32a_read(struct i2c_client *client, u8 reg) | ||
69 | { | ||
70 | return i2c_smbus_read_byte_data(client, reg); | ||
71 | } | ||
72 | |||
73 | static int cs53l32a_command(struct i2c_client *client, unsigned int cmd, | ||
74 | void *arg) | ||
75 | { | ||
76 | int *input = arg; | ||
77 | |||
78 | switch (cmd) { | ||
79 | case AUDC_SET_INPUT: | ||
80 | switch (*input) { | ||
81 | case AUDIO_TUNER: | ||
82 | cs53l32a_write(client, 0x01, 0x01); | ||
83 | break; | ||
84 | case AUDIO_EXTERN: | ||
85 | cs53l32a_write(client, 0x01, 0x21); | ||
86 | break; | ||
87 | case AUDIO_MUTE: | ||
88 | cs53l32a_write(client, 0x03, 0xF0); | ||
89 | break; | ||
90 | case AUDIO_UNMUTE: | ||
91 | cs53l32a_write(client, 0x03, 0x30); | ||
92 | break; | ||
93 | default: | ||
94 | cs53l32a_err("Invalid input %d.\n", *input); | ||
95 | return -EINVAL; | ||
96 | } | ||
97 | break; | ||
98 | |||
99 | case VIDIOC_S_CTRL: | ||
100 | { | ||
101 | struct v4l2_control *ctrl = arg; | ||
102 | |||
103 | if (ctrl->id != V4L2_CID_AUDIO_VOLUME) | ||
104 | return -EINVAL; | ||
105 | if (ctrl->value > 12 || ctrl->value < -90) | ||
106 | return -EINVAL; | ||
107 | cs53l32a_write(client, 0x04, (u8) ctrl->value); | ||
108 | cs53l32a_write(client, 0x05, (u8) ctrl->value); | ||
109 | break; | ||
110 | } | ||
111 | |||
112 | case VIDIOC_LOG_STATUS: | ||
113 | { | ||
114 | u8 v = cs53l32a_read(client, 0x01); | ||
115 | u8 m = cs53l32a_read(client, 0x03); | ||
116 | |||
117 | cs53l32a_info("Input: %s%s\n", | ||
118 | v == 0x21 ? "external line in" : "tuner", | ||
119 | (m & 0xC0) ? " (muted)" : ""); | ||
120 | break; | ||
121 | } | ||
122 | |||
123 | default: | ||
124 | return -EINVAL; | ||
125 | } | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | /* ----------------------------------------------------------------------- */ | ||
130 | |||
131 | /* i2c implementation */ | ||
132 | |||
133 | /* | ||
134 | * Generic i2c probe | ||
135 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | ||
136 | */ | ||
137 | |||
138 | static struct i2c_driver i2c_driver; | ||
139 | |||
140 | static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind) | ||
141 | { | ||
142 | struct i2c_client *client; | ||
143 | int i; | ||
144 | |||
145 | /* Check if the adapter supports the needed features */ | ||
146 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
147 | return 0; | ||
148 | |||
149 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
150 | if (client == 0) | ||
151 | return -ENOMEM; | ||
152 | |||
153 | memset(client, 0, sizeof(struct i2c_client)); | ||
154 | client->addr = address; | ||
155 | client->adapter = adapter; | ||
156 | client->driver = &i2c_driver; | ||
157 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
158 | snprintf(client->name, sizeof(client->name) - 1, "cs53l32a"); | ||
159 | |||
160 | cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name); | ||
161 | |||
162 | for (i = 1; i <= 7; i++) { | ||
163 | u8 v = cs53l32a_read(client, i); | ||
164 | |||
165 | cs53l32a_dbg("Read Reg %d %02x\n", i, v); | ||
166 | } | ||
167 | |||
168 | /* Set cs53l32a internal register for Adaptec 2010/2410 setup */ | ||
169 | |||
170 | cs53l32a_write(client, 0x01, (u8) 0x21); | ||
171 | cs53l32a_write(client, 0x02, (u8) 0x29); | ||
172 | cs53l32a_write(client, 0x03, (u8) 0x30); | ||
173 | cs53l32a_write(client, 0x04, (u8) 0x00); | ||
174 | cs53l32a_write(client, 0x05, (u8) 0x00); | ||
175 | cs53l32a_write(client, 0x06, (u8) 0x00); | ||
176 | cs53l32a_write(client, 0x07, (u8) 0x00); | ||
177 | |||
178 | /* Display results, should be 0x21,0x29,0x30,0x00,0x00,0x00,0x00 */ | ||
179 | |||
180 | for (i = 1; i <= 7; i++) { | ||
181 | u8 v = cs53l32a_read(client, i); | ||
182 | |||
183 | cs53l32a_dbg("Read Reg %d %02x\n", i, v); | ||
184 | } | ||
185 | |||
186 | i2c_attach_client(client); | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | static int cs53l32a_probe(struct i2c_adapter *adapter) | ||
192 | { | ||
193 | #ifdef I2C_CLASS_TV_ANALOG | ||
194 | if (adapter->class & I2C_CLASS_TV_ANALOG) | ||
195 | #else | ||
196 | if (adapter->id == I2C_HW_B_BT848) | ||
197 | #endif | ||
198 | return i2c_probe(adapter, &addr_data, cs53l32a_attach); | ||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static int cs53l32a_detach(struct i2c_client *client) | ||
203 | { | ||
204 | int err; | ||
205 | |||
206 | err = i2c_detach_client(client); | ||
207 | if (err) { | ||
208 | return err; | ||
209 | } | ||
210 | kfree(client); | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | /* ----------------------------------------------------------------------- */ | ||
216 | |||
217 | /* i2c implementation */ | ||
218 | static struct i2c_driver i2c_driver = { | ||
219 | .name = "cs53l32a", | ||
220 | .id = I2C_DRIVERID_CS53L32A, | ||
221 | .flags = I2C_DF_NOTIFY, | ||
222 | .attach_adapter = cs53l32a_probe, | ||
223 | .detach_client = cs53l32a_detach, | ||
224 | .command = cs53l32a_command, | ||
225 | .owner = THIS_MODULE, | ||
226 | }; | ||
227 | |||
228 | |||
229 | static int __init cs53l32a_init_module(void) | ||
230 | { | ||
231 | return i2c_add_driver(&i2c_driver); | ||
232 | } | ||
233 | |||
234 | static void __exit cs53l32a_cleanup_module(void) | ||
235 | { | ||
236 | i2c_del_driver(&i2c_driver); | ||
237 | } | ||
238 | |||
239 | module_init(cs53l32a_init_module); | ||
240 | module_exit(cs53l32a_cleanup_module); | ||
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig new file mode 100644 index 000000000000..41818b6205b3 --- /dev/null +++ b/drivers/media/video/cx88/Kconfig | |||
@@ -0,0 +1,91 @@ | |||
1 | config VIDEO_CX88 | ||
2 | tristate "Conexant 2388x (bt878 successor) support" | ||
3 | depends on VIDEO_DEV && PCI && I2C | ||
4 | select I2C_ALGOBIT | ||
5 | select FW_LOADER | ||
6 | select VIDEO_BTCX | ||
7 | select VIDEO_BUF | ||
8 | select VIDEO_TUNER | ||
9 | select VIDEO_TVEEPROM | ||
10 | select VIDEO_IR | ||
11 | ---help--- | ||
12 | This is a video4linux driver for Conexant 2388x based | ||
13 | TV cards. | ||
14 | |||
15 | To compile this driver as a module, choose M here: the | ||
16 | module will be called cx8800 | ||
17 | |||
18 | config VIDEO_CX88_DVB | ||
19 | tristate "DVB/ATSC Support for cx2388x based TV cards" | ||
20 | depends on VIDEO_CX88 && DVB_CORE | ||
21 | select VIDEO_BUF_DVB | ||
22 | ---help--- | ||
23 | This adds support for DVB/ATSC cards based on the | ||
24 | Connexant 2388x chip. | ||
25 | |||
26 | To compile this driver as a module, choose M here: the | ||
27 | module will be called cx88-dvb. | ||
28 | |||
29 | You must also select one or more DVB/ATSC demodulators. | ||
30 | If you are unsure which you need, choose all of them. | ||
31 | |||
32 | config VIDEO_CX88_DVB_ALL_FRONTENDS | ||
33 | bool "Build all supported frontends for cx2388x based TV cards" | ||
34 | default y | ||
35 | depends on VIDEO_CX88_DVB | ||
36 | select DVB_MT352 | ||
37 | select DVB_OR51132 | ||
38 | select DVB_CX22702 | ||
39 | select DVB_LGDT330X | ||
40 | select DVB_NXT200X | ||
41 | ---help--- | ||
42 | This builds cx88-dvb with all currently supported frontend | ||
43 | demodulators. If you wish to tweak your configuration, and | ||
44 | only include support for the hardware that you need, choose N here. | ||
45 | |||
46 | If you are unsure, choose Y. | ||
47 | |||
48 | config VIDEO_CX88_DVB_MT352 | ||
49 | tristate "Zarlink MT352 DVB-T Support" | ||
50 | default m | ||
51 | depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS | ||
52 | select DVB_MT352 | ||
53 | ---help--- | ||
54 | This adds DVB-T support for cards based on the | ||
55 | Connexant 2388x chip and the MT352 demodulator. | ||
56 | |||
57 | config VIDEO_CX88_DVB_OR51132 | ||
58 | tristate "OR51132 ATSC Support" | ||
59 | default m | ||
60 | depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS | ||
61 | select DVB_OR51132 | ||
62 | ---help--- | ||
63 | This adds ATSC 8VSB and QAM64/256 support for cards based on the | ||
64 | Connexant 2388x chip and the OR51132 demodulator. | ||
65 | |||
66 | config VIDEO_CX88_DVB_CX22702 | ||
67 | tristate "Conexant CX22702 DVB-T Support" | ||
68 | default m | ||
69 | depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS | ||
70 | select DVB_CX22702 | ||
71 | ---help--- | ||
72 | This adds DVB-T support for cards based on the | ||
73 | Connexant 2388x chip and the CX22702 demodulator. | ||
74 | |||
75 | config VIDEO_CX88_DVB_LGDT330X | ||
76 | tristate "LG Electronics DT3302/DT3303 ATSC Support" | ||
77 | default m | ||
78 | depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS | ||
79 | select DVB_LGDT330X | ||
80 | ---help--- | ||
81 | This adds ATSC 8VSB and QAM64/256 support for cards based on the | ||
82 | Connexant 2388x chip and the LGDT3302/LGDT3303 demodulator. | ||
83 | |||
84 | config VIDEO_CX88_DVB_NXT200X | ||
85 | tristate "NXT2002/NXT2004 ATSC Support" | ||
86 | default m | ||
87 | depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS | ||
88 | select DVB_NXT200X | ||
89 | ---help--- | ||
90 | This adds ATSC 8VSB and QAM64/256 support for cards based on the | ||
91 | Connexant 2388x chip and the NXT2002/NXT2004 demodulator. | ||
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile index 107e48645e3a..0df40b773454 100644 --- a/drivers/media/video/cx88/Makefile +++ b/drivers/media/video/cx88/Makefile | |||
@@ -9,6 +9,9 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o | |||
9 | EXTRA_CFLAGS += -I$(src)/.. | 9 | EXTRA_CFLAGS += -I$(src)/.. |
10 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 10 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core |
11 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends | 11 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends |
12 | ifneq ($(CONFIG_VIDEO_BUF_DVB),n) | ||
13 | EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1 | ||
14 | endif | ||
12 | ifneq ($(CONFIG_DVB_CX22702),n) | 15 | ifneq ($(CONFIG_DVB_CX22702),n) |
13 | EXTRA_CFLAGS += -DHAVE_CX22702=1 | 16 | EXTRA_CFLAGS += -DHAVE_CX22702=1 |
14 | endif | 17 | endif |
@@ -21,3 +24,6 @@ endif | |||
21 | ifneq ($(CONFIG_DVB_MT352),n) | 24 | ifneq ($(CONFIG_DVB_MT352),n) |
22 | EXTRA_CFLAGS += -DHAVE_MT352=1 | 25 | EXTRA_CFLAGS += -DHAVE_MT352=1 |
23 | endif | 26 | endif |
27 | ifneq ($(CONFIG_DVB_NXT200X),n) | ||
28 | EXTRA_CFLAGS += -DHAVE_NXT200X=1 | ||
29 | endif | ||
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 0c0c59e94774..4ae3f78cccf2 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -38,7 +38,7 @@ MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>"); | |||
38 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 38 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
39 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
40 | 40 | ||
41 | static unsigned int mpegbufs = 8; | 41 | static unsigned int mpegbufs = 32; |
42 | module_param(mpegbufs,int,0644); | 42 | module_param(mpegbufs,int,0644); |
43 | MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32"); | 43 | MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32"); |
44 | 44 | ||
@@ -436,7 +436,7 @@ static int memory_write(struct cx88_core *core, u32 address, u32 value) | |||
436 | 436 | ||
437 | static int memory_read(struct cx88_core *core, u32 address, u32 *value) | 437 | static int memory_read(struct cx88_core *core, u32 address, u32 *value) |
438 | { | 438 | { |
439 | int retval; | 439 | int retval; |
440 | u32 val; | 440 | u32 val; |
441 | 441 | ||
442 | /* Warning: address is dword address (4 bytes) */ | 442 | /* Warning: address is dword address (4 bytes) */ |
@@ -605,11 +605,11 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) | |||
605 | u32 *dataptr; | 605 | u32 *dataptr; |
606 | 606 | ||
607 | retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED); | 607 | retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED); |
608 | retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); | 608 | retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); |
609 | retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640); | 609 | retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640); |
610 | retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A); | 610 | retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A); |
611 | msleep(1); | 611 | msleep(1); |
612 | retval |= register_write(dev->core, IVTV_REG_APU, 0); | 612 | retval |= register_write(dev->core, IVTV_REG_APU, 0); |
613 | 613 | ||
614 | if (retval < 0) | 614 | if (retval < 0) |
615 | dprintk(0, "Error with register_write\n"); | 615 | dprintk(0, "Error with register_write\n"); |
@@ -657,13 +657,13 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) | |||
657 | release_firmware(firmware); | 657 | release_firmware(firmware); |
658 | dprintk(0, "Firmware upload successful.\n"); | 658 | dprintk(0, "Firmware upload successful.\n"); |
659 | 659 | ||
660 | retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); | 660 | retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); |
661 | retval |= register_read(dev->core, IVTV_REG_SPU, &value); | 661 | retval |= register_read(dev->core, IVTV_REG_SPU, &value); |
662 | retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE); | 662 | retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE); |
663 | msleep(1); | 663 | msleep(1); |
664 | 664 | ||
665 | retval |= register_read(dev->core, IVTV_REG_VPU, &value); | 665 | retval |= register_read(dev->core, IVTV_REG_VPU, &value); |
666 | retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8); | 666 | retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8); |
667 | 667 | ||
668 | if (retval < 0) | 668 | if (retval < 0) |
669 | dprintk(0, "Error with register_write\n"); | 669 | dprintk(0, "Error with register_write\n"); |
@@ -683,84 +683,560 @@ DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | M | |||
683 | ================================================================================================================= | 683 | ================================================================================================================= |
684 | *DB: "DirectBurn" | 684 | *DB: "DirectBurn" |
685 | */ | 685 | */ |
686 | static void blackbird_codec_settings(struct cx8802_dev *dev) | 686 | |
687 | static struct blackbird_dnr default_dnr_params = { | ||
688 | .mode = BLACKBIRD_DNR_BITS_MANUAL, | ||
689 | .type = BLACKBIRD_MEDIAN_FILTER_DISABLED, | ||
690 | .spatial = 0, | ||
691 | .temporal = 0 | ||
692 | }; | ||
693 | static struct v4l2_mpeg_compression default_mpeg_params = { | ||
694 | .st_type = V4L2_MPEG_PS_2, | ||
695 | .st_bitrate = { | ||
696 | .mode = V4L2_BITRATE_CBR, | ||
697 | .min = 0, | ||
698 | .target = 0, | ||
699 | .max = 0 | ||
700 | }, | ||
701 | .ts_pid_pmt = 16, | ||
702 | .ts_pid_audio = 260, | ||
703 | .ts_pid_video = 256, | ||
704 | .ts_pid_pcr = 259, | ||
705 | .ps_size = 0, | ||
706 | .au_type = V4L2_MPEG_AU_2_II, | ||
707 | .au_bitrate = { | ||
708 | .mode = V4L2_BITRATE_CBR, | ||
709 | .min = 224, | ||
710 | .target = 224, | ||
711 | .max = 224 | ||
712 | }, | ||
713 | .au_sample_rate = 44100, | ||
714 | .au_pesid = 0, | ||
715 | .vi_type = V4L2_MPEG_VI_2, | ||
716 | .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3, | ||
717 | .vi_bitrate = { | ||
718 | .mode = V4L2_BITRATE_CBR, | ||
719 | .min = 4000, | ||
720 | .target = 4500, | ||
721 | .max = 6000 | ||
722 | }, | ||
723 | .vi_frame_rate = 25, | ||
724 | .vi_frames_per_gop = 15, | ||
725 | .vi_bframes_count = 2, | ||
726 | .vi_pesid = 0, | ||
727 | .closed_gops = 0, | ||
728 | .pulldown = 0 | ||
729 | }; | ||
730 | |||
731 | static enum blackbird_stream_type mpeg_stream_types[] = { | ||
732 | [V4L2_MPEG_SS_1] = BLACKBIRD_STREAM_MPEG1, | ||
733 | [V4L2_MPEG_PS_2] = BLACKBIRD_STREAM_PROGRAM, | ||
734 | [V4L2_MPEG_TS_2] = BLACKBIRD_STREAM_TRANSPORT, | ||
735 | [V4L2_MPEG_PS_DVD] = BLACKBIRD_STREAM_DVD, | ||
736 | }; | ||
737 | static enum blackbird_aspect_ratio mpeg_stream_ratios[] = { | ||
738 | [V4L2_MPEG_ASPECT_SQUARE] = BLACKBIRD_ASPECT_RATIO_1_1_SQUARE, | ||
739 | [V4L2_MPEG_ASPECT_4_3] = BLACKBIRD_ASPECT_RATIO_4_3, | ||
740 | [V4L2_MPEG_ASPECT_16_9] = BLACKBIRD_ASPECT_RATIO_16_9, | ||
741 | [V4L2_MPEG_ASPECT_1_221] = BLACKBIRD_ASPECT_RATIO_221_100, | ||
742 | }; | ||
743 | static enum blackbird_video_bitrate_type mpeg_video_bitrates[] = { | ||
744 | [V4L2_BITRATE_NONE] = BLACKBIRD_VIDEO_CBR, | ||
745 | [V4L2_BITRATE_CBR] = BLACKBIRD_VIDEO_CBR, | ||
746 | [V4L2_BITRATE_VBR] = BLACKBIRD_VIDEO_VBR, | ||
747 | }; | ||
748 | /* find the best layer I/II bitrate to fit a given numeric value */ | ||
749 | struct bitrate_bits { | ||
750 | u32 bits; /* layer bits for the best fit */ | ||
751 | u32 rate; /* actual numeric value for the layer best fit */ | ||
752 | }; | ||
753 | struct bitrate_approximation { | ||
754 | u32 target; /* numeric value of the rate we want */ | ||
755 | struct bitrate_bits layer[2]; | ||
756 | }; | ||
757 | static struct bitrate_approximation mpeg_audio_bitrates[] = { | ||
758 | /* target layer[0].bits layer[0].rate layer[1].bits layer[1].rate */ | ||
759 | { 0, { { 0, 0, }, { 0, 0, }, }, }, | ||
760 | { 32, { { BLACKBIRD_AUDIO_BITS_LAYER_1_32 , 32, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_32 , 32, }, }, }, | ||
761 | { 48, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_48 , 48, }, }, }, | ||
762 | { 56, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_56 , 56, }, }, }, | ||
763 | { 64, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_64 , 64, }, }, }, | ||
764 | { 80, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_80 , 80, }, }, }, | ||
765 | { 96, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_96 , 96, }, }, }, | ||
766 | { 112, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_112, 112, }, }, }, | ||
767 | { 128, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_128, 128, }, }, }, | ||
768 | { 160, { { BLACKBIRD_AUDIO_BITS_LAYER_1_160, 160, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_160, 160, }, }, }, | ||
769 | { 192, { { BLACKBIRD_AUDIO_BITS_LAYER_1_192, 192, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_192, 192, }, }, }, | ||
770 | { 224, { { BLACKBIRD_AUDIO_BITS_LAYER_1_224, 224, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_224, 224, }, }, }, | ||
771 | { 256, { { BLACKBIRD_AUDIO_BITS_LAYER_1_256, 256, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_256, 256, }, }, }, | ||
772 | { 288, { { BLACKBIRD_AUDIO_BITS_LAYER_1_288, 288, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, }, | ||
773 | { 320, { { BLACKBIRD_AUDIO_BITS_LAYER_1_320, 320, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, }, | ||
774 | { 352, { { BLACKBIRD_AUDIO_BITS_LAYER_1_352, 352, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, }, | ||
775 | { 384, { { BLACKBIRD_AUDIO_BITS_LAYER_1_384, 384, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, }, | ||
776 | { 416, { { BLACKBIRD_AUDIO_BITS_LAYER_1_416, 416, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, }, | ||
777 | { 448, { { BLACKBIRD_AUDIO_BITS_LAYER_1_448, 448, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, }, | ||
778 | }; | ||
779 | static const int BITRATES_SIZE = ARRAY_SIZE(mpeg_audio_bitrates); | ||
780 | |||
781 | static void blackbird_set_default_params(struct cx8802_dev *dev) | ||
687 | { | 782 | { |
688 | int bitrate_mode = 1; | 783 | struct v4l2_mpeg_compression *params = &dev->params; |
689 | int bitrate = 7500000; | 784 | u32 au_params; |
690 | int bitrate_peak = 7500000; | ||
691 | bitrate_mode = BLACKBIRD_VIDEO_CBR; | ||
692 | bitrate = 4000*1024; | ||
693 | bitrate_peak = 4000*1024; | ||
694 | 785 | ||
695 | /* assign stream type */ | 786 | /* assign stream type */ |
696 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM); | 787 | if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) ) |
697 | 788 | params->st_type = V4L2_MPEG_PS_2; | |
698 | /* assign output port */ | 789 | if( params->st_type == V4L2_MPEG_SS_1 ) |
699 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */ | 790 | params->vi_type = V4L2_MPEG_VI_1; |
791 | else | ||
792 | params->vi_type = V4L2_MPEG_VI_2; | ||
793 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]); | ||
700 | 794 | ||
701 | /* assign framerate */ | 795 | /* assign framerate */ |
702 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25); | 796 | if( params->vi_frame_rate <= 25 ) |
703 | 797 | { | |
704 | /* assign frame size */ | 798 | params->vi_frame_rate = 25; |
705 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0, | 799 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25); |
706 | dev->height, dev->width); | 800 | } |
801 | else | ||
802 | { | ||
803 | params->vi_frame_rate = 30; | ||
804 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30); | ||
805 | } | ||
707 | 806 | ||
708 | /* assign aspect ratio */ | 807 | /* assign aspect ratio */ |
709 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, BLACKBIRD_ASPECT_RATIO_4_3); | 808 | if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) ) |
710 | 809 | params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3; | |
711 | /* assign bitrates */ | 810 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]); |
712 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 5, 0, | ||
713 | bitrate_mode, /* mode */ | ||
714 | bitrate, /* bps */ | ||
715 | bitrate_peak / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */ | ||
716 | BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */ | ||
717 | 811 | ||
718 | /* assign gop properties */ | 812 | /* assign gop properties */ |
719 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, 15, 3); | 813 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1); |
814 | |||
815 | /* assign gop closure */ | ||
816 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops); | ||
720 | 817 | ||
721 | /* assign 3 2 pulldown */ | 818 | /* assign 3 2 pulldown */ |
722 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, BLACKBIRD_3_2_PULLDOWN_DISABLED); | 819 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown); |
820 | |||
821 | /* make sure the params are within bounds */ | ||
822 | if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) | ||
823 | params->vi_bitrate.mode = V4L2_BITRATE_NONE; | ||
824 | if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) | ||
825 | params->vi_bitrate.mode = V4L2_BITRATE_NONE; | ||
826 | if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) | ||
827 | params->au_bitrate.mode = V4L2_BITRATE_NONE; | ||
723 | 828 | ||
724 | /* assign audio properties */ | 829 | /* assign audio properties */ |
725 | /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ | 830 | /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ |
726 | /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4)); | 831 | au_params = BLACKBIRD_AUDIO_BITS_STEREO | |
727 | blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4)); */ | ||
728 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, | ||
729 | BLACKBIRD_AUDIO_BITS_44100HZ | | ||
730 | BLACKBIRD_AUDIO_BITS_LAYER_2 | | ||
731 | BLACKBIRD_AUDIO_BITS_LAYER_2_224 | | ||
732 | BLACKBIRD_AUDIO_BITS_STEREO | | ||
733 | /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */ | 832 | /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */ |
734 | BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE | | 833 | BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE | |
735 | BLACKBIRD_AUDIO_BITS_CRC_OFF | | 834 | BLACKBIRD_AUDIO_BITS_CRC_OFF | |
736 | BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF | | 835 | BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF | |
737 | BLACKBIRD_AUDIO_BITS_COPY | 836 | BLACKBIRD_AUDIO_BITS_COPY | |
738 | ); | 837 | 0; |
838 | if( params->au_sample_rate <= 32000 ) | ||
839 | { | ||
840 | params->au_sample_rate = 32000; | ||
841 | au_params |= BLACKBIRD_AUDIO_BITS_32000HZ; | ||
842 | } | ||
843 | else if( params->au_sample_rate <= 44100 ) | ||
844 | { | ||
845 | params->au_sample_rate = 44100; | ||
846 | au_params |= BLACKBIRD_AUDIO_BITS_44100HZ; | ||
847 | } | ||
848 | else | ||
849 | { | ||
850 | params->au_sample_rate = 48000; | ||
851 | au_params |= BLACKBIRD_AUDIO_BITS_48000HZ; | ||
852 | } | ||
853 | if( params->au_type == V4L2_MPEG_AU_2_I ) | ||
854 | { | ||
855 | au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1; | ||
856 | } | ||
857 | else | ||
858 | { | ||
859 | /* TODO: try to handle the other formats more gracefully */ | ||
860 | params->au_type = V4L2_MPEG_AU_2_II; | ||
861 | au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2; | ||
862 | } | ||
863 | if( params->au_bitrate.mode ) | ||
864 | { | ||
865 | int layer; | ||
866 | |||
867 | if( params->au_bitrate.mode == V4L2_BITRATE_CBR ) | ||
868 | params->au_bitrate.max = params->vi_bitrate.target; | ||
869 | else | ||
870 | params->au_bitrate.target = params->vi_bitrate.max; | ||
871 | |||
872 | layer = params->au_type; | ||
873 | if( params->au_bitrate.target == 0 ) | ||
874 | { | ||
875 | /* TODO: use the minimum possible bitrate instead of 0 ? */ | ||
876 | au_params |= 0; | ||
877 | } | ||
878 | else if( params->au_bitrate.target >= | ||
879 | mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate ) | ||
880 | { | ||
881 | /* clamp the bitrate to the max supported by the standard */ | ||
882 | params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate; | ||
883 | params->au_bitrate.max = params->au_bitrate.target; | ||
884 | au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits; | ||
885 | } | ||
886 | else | ||
887 | { | ||
888 | /* round up to the nearest supported bitrate */ | ||
889 | int i; | ||
890 | for(i = 1; i < BITRATES_SIZE; i++) | ||
891 | { | ||
892 | if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate && | ||
893 | params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate ) | ||
894 | { | ||
895 | params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate; | ||
896 | params->au_bitrate.max = params->au_bitrate.target; | ||
897 | au_params |= mpeg_audio_bitrates[i].layer[layer].bits; | ||
898 | break; | ||
899 | } | ||
900 | } | ||
901 | } | ||
902 | } | ||
903 | else | ||
904 | { | ||
905 | /* TODO: ??? */ | ||
906 | params->au_bitrate.target = params->au_bitrate.max = 0; | ||
907 | au_params |= 0; | ||
908 | } | ||
909 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params ); | ||
910 | |||
911 | /* assign bitrates */ | ||
912 | if( params->vi_bitrate.mode ) | ||
913 | { | ||
914 | /* bitrate is set, let's figure out the cbr/vbr mess */ | ||
915 | if( params->vi_bitrate.max < params->vi_bitrate.target ) | ||
916 | { | ||
917 | if( params->vi_bitrate.mode == V4L2_BITRATE_CBR ) | ||
918 | params->vi_bitrate.max = params->vi_bitrate.target; | ||
919 | else | ||
920 | params->vi_bitrate.target = params->vi_bitrate.max; | ||
921 | } | ||
922 | } | ||
923 | else | ||
924 | { | ||
925 | if( params->st_bitrate.max < params->st_bitrate.target ) | ||
926 | { | ||
927 | if( params->st_bitrate.mode == V4L2_BITRATE_VBR ) | ||
928 | params->st_bitrate.target = params->st_bitrate.max; | ||
929 | else | ||
930 | params->st_bitrate.max = params->st_bitrate.target; | ||
931 | } | ||
932 | /* calculate vi_bitrate = st_bitrate - au_bitrate */ | ||
933 | params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max; | ||
934 | params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target; | ||
935 | } | ||
936 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0, | ||
937 | mpeg_video_bitrates[params->vi_bitrate.mode], | ||
938 | params->vi_bitrate.target * 1000, /* kbps -> bps */ | ||
939 | params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */ | ||
940 | BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */ | ||
941 | |||
942 | /* TODO: implement the stream ID stuff: | ||
943 | ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr, | ||
944 | ps_size, au_pesid, vi_pesid | ||
945 | */ | ||
946 | } | ||
947 | #define CHECK_PARAM( name ) ( dev->params.name != params->name ) | ||
948 | #define IF_PARAM( name ) if( CHECK_PARAM( name ) ) | ||
949 | #define UPDATE_PARAM( name ) dev->params.name = params->name | ||
950 | void blackbird_set_params(struct cx8802_dev *dev, struct v4l2_mpeg_compression *params) | ||
951 | { | ||
952 | u32 au_params; | ||
953 | |||
954 | /* assign stream type */ | ||
955 | if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) ) | ||
956 | params->st_type = V4L2_MPEG_PS_2; | ||
957 | if( params->st_type == V4L2_MPEG_SS_1 ) | ||
958 | params->vi_type = V4L2_MPEG_VI_1; | ||
959 | else | ||
960 | params->vi_type = V4L2_MPEG_VI_2; | ||
961 | if( CHECK_PARAM( st_type ) || CHECK_PARAM( vi_type ) ) | ||
962 | { | ||
963 | UPDATE_PARAM( st_type ); | ||
964 | UPDATE_PARAM( vi_type ); | ||
965 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]); | ||
966 | } | ||
967 | |||
968 | /* assign framerate */ | ||
969 | if( params->vi_frame_rate <= 25 ) | ||
970 | params->vi_frame_rate = 25; | ||
971 | else | ||
972 | params->vi_frame_rate = 30; | ||
973 | IF_PARAM( vi_frame_rate ) | ||
974 | { | ||
975 | UPDATE_PARAM( vi_frame_rate ); | ||
976 | if( params->vi_frame_rate == 25 ) | ||
977 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25); | ||
978 | else | ||
979 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30); | ||
980 | } | ||
981 | |||
982 | /* assign aspect ratio */ | ||
983 | if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) ) | ||
984 | params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3; | ||
985 | IF_PARAM( vi_aspect_ratio ) | ||
986 | { | ||
987 | UPDATE_PARAM( vi_aspect_ratio ); | ||
988 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]); | ||
989 | } | ||
990 | |||
991 | /* assign gop properties */ | ||
992 | if( CHECK_PARAM( vi_frames_per_gop ) || CHECK_PARAM( vi_bframes_count ) ) | ||
993 | { | ||
994 | UPDATE_PARAM( vi_frames_per_gop ); | ||
995 | UPDATE_PARAM( vi_bframes_count ); | ||
996 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1); | ||
997 | } | ||
739 | 998 | ||
740 | /* assign gop closure */ | 999 | /* assign gop closure */ |
741 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, BLACKBIRD_GOP_CLOSURE_OFF); | 1000 | IF_PARAM( closed_gops ) |
1001 | { | ||
1002 | UPDATE_PARAM( closed_gops ); | ||
1003 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops); | ||
1004 | } | ||
1005 | |||
1006 | /* assign 3 2 pulldown */ | ||
1007 | IF_PARAM( pulldown ) | ||
1008 | { | ||
1009 | UPDATE_PARAM( pulldown ); | ||
1010 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown); | ||
1011 | } | ||
1012 | |||
1013 | /* make sure the params are within bounds */ | ||
1014 | if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) | ||
1015 | params->vi_bitrate.mode = V4L2_BITRATE_NONE; | ||
1016 | if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) | ||
1017 | params->vi_bitrate.mode = V4L2_BITRATE_NONE; | ||
1018 | if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) ) | ||
1019 | params->au_bitrate.mode = V4L2_BITRATE_NONE; | ||
1020 | |||
1021 | /* assign audio properties */ | ||
1022 | /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ | ||
1023 | au_params = BLACKBIRD_AUDIO_BITS_STEREO | | ||
1024 | /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */ | ||
1025 | BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE | | ||
1026 | BLACKBIRD_AUDIO_BITS_CRC_OFF | | ||
1027 | BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF | | ||
1028 | BLACKBIRD_AUDIO_BITS_COPY | | ||
1029 | 0; | ||
1030 | if( params->au_sample_rate < 32000 ) | ||
1031 | { | ||
1032 | params->au_sample_rate = 32000; | ||
1033 | au_params |= BLACKBIRD_AUDIO_BITS_32000HZ; | ||
1034 | } | ||
1035 | else if( params->au_sample_rate < 44100 ) | ||
1036 | { | ||
1037 | params->au_sample_rate = 44100; | ||
1038 | au_params |= BLACKBIRD_AUDIO_BITS_44100HZ; | ||
1039 | } | ||
1040 | else | ||
1041 | { | ||
1042 | params->au_sample_rate = 48000; | ||
1043 | au_params |= BLACKBIRD_AUDIO_BITS_48000HZ; | ||
1044 | } | ||
1045 | if( params->au_type == V4L2_MPEG_AU_2_I ) | ||
1046 | { | ||
1047 | au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1; | ||
1048 | } | ||
1049 | else | ||
1050 | { | ||
1051 | /* TODO: try to handle the other formats more gracefully */ | ||
1052 | params->au_type = V4L2_MPEG_AU_2_II; | ||
1053 | au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2; | ||
1054 | } | ||
1055 | if( params->au_bitrate.mode ) | ||
1056 | { | ||
1057 | int layer; | ||
1058 | |||
1059 | if( params->au_bitrate.mode == V4L2_BITRATE_CBR ) | ||
1060 | params->au_bitrate.max = params->vi_bitrate.target; | ||
1061 | else | ||
1062 | params->au_bitrate.target = params->vi_bitrate.max; | ||
1063 | |||
1064 | layer = params->au_type; | ||
1065 | if( params->au_bitrate.target == 0 ) | ||
1066 | { | ||
1067 | /* TODO: use the minimum possible bitrate instead of 0 ? */ | ||
1068 | au_params |= 0; | ||
1069 | } | ||
1070 | else if( params->au_bitrate.target >= | ||
1071 | mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate ) | ||
1072 | { | ||
1073 | /* clamp the bitrate to the max supported by the standard */ | ||
1074 | params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate; | ||
1075 | params->au_bitrate.max = params->au_bitrate.target; | ||
1076 | au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits; | ||
1077 | } | ||
1078 | else | ||
1079 | { | ||
1080 | /* round up to the nearest supported bitrate */ | ||
1081 | int i; | ||
1082 | for(i = 1; i < BITRATES_SIZE; i++) | ||
1083 | { | ||
1084 | if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate && | ||
1085 | params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate ) | ||
1086 | { | ||
1087 | params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate; | ||
1088 | params->au_bitrate.max = params->au_bitrate.target; | ||
1089 | au_params |= mpeg_audio_bitrates[i].layer[layer].bits; | ||
1090 | break; | ||
1091 | } | ||
1092 | } | ||
1093 | } | ||
1094 | } | ||
1095 | else | ||
1096 | { | ||
1097 | /* TODO: ??? */ | ||
1098 | params->au_bitrate.target = params->au_bitrate.max = 0; | ||
1099 | au_params |= 0; | ||
1100 | } | ||
1101 | if( CHECK_PARAM( au_type ) || CHECK_PARAM( au_sample_rate ) | ||
1102 | || CHECK_PARAM( au_bitrate.mode ) || CHECK_PARAM( au_bitrate.max ) | ||
1103 | || CHECK_PARAM( au_bitrate.target ) | ||
1104 | ) | ||
1105 | { | ||
1106 | UPDATE_PARAM( au_type ); | ||
1107 | UPDATE_PARAM( au_sample_rate ); | ||
1108 | UPDATE_PARAM( au_bitrate ); | ||
1109 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params ); | ||
1110 | } | ||
1111 | |||
1112 | /* assign bitrates */ | ||
1113 | if( params->vi_bitrate.mode ) | ||
1114 | { | ||
1115 | /* bitrate is set, let's figure out the cbr/vbr mess */ | ||
1116 | if( params->vi_bitrate.max < params->vi_bitrate.target ) | ||
1117 | { | ||
1118 | if( params->vi_bitrate.mode == V4L2_BITRATE_CBR ) | ||
1119 | params->vi_bitrate.max = params->vi_bitrate.target; | ||
1120 | else | ||
1121 | params->vi_bitrate.target = params->vi_bitrate.max; | ||
1122 | } | ||
1123 | } | ||
1124 | else | ||
1125 | { | ||
1126 | if( params->st_bitrate.max < params->st_bitrate.target ) | ||
1127 | { | ||
1128 | if( params->st_bitrate.mode == V4L2_BITRATE_VBR ) | ||
1129 | params->st_bitrate.target = params->st_bitrate.max; | ||
1130 | else | ||
1131 | params->st_bitrate.max = params->st_bitrate.target; | ||
1132 | } | ||
1133 | /* calculate vi_bitrate = st_bitrate - au_bitrate */ | ||
1134 | params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max; | ||
1135 | params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target; | ||
1136 | } | ||
1137 | UPDATE_PARAM( st_bitrate ); | ||
1138 | if( CHECK_PARAM( vi_bitrate.mode ) || CHECK_PARAM( vi_bitrate.max ) | ||
1139 | || CHECK_PARAM( vi_bitrate.target ) | ||
1140 | ) | ||
1141 | { | ||
1142 | UPDATE_PARAM( vi_bitrate ); | ||
1143 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0, | ||
1144 | mpeg_video_bitrates[params->vi_bitrate.mode], | ||
1145 | params->vi_bitrate.target * 1000, /* kbps -> bps */ | ||
1146 | params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */ | ||
1147 | BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */ | ||
1148 | } | ||
742 | 1149 | ||
1150 | /* TODO: implement the stream ID stuff: | ||
1151 | ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr, | ||
1152 | ps_size, au_pesid, vi_pesid | ||
1153 | */ | ||
1154 | UPDATE_PARAM( ts_pid_pmt ); | ||
1155 | UPDATE_PARAM( ts_pid_audio ); | ||
1156 | UPDATE_PARAM( ts_pid_video ); | ||
1157 | UPDATE_PARAM( ts_pid_pcr ); | ||
1158 | UPDATE_PARAM( ps_size ); | ||
1159 | UPDATE_PARAM( au_pesid ); | ||
1160 | UPDATE_PARAM( vi_pesid ); | ||
1161 | } | ||
743 | 1162 | ||
1163 | static void blackbird_set_default_dnr_params(struct cx8802_dev *dev) | ||
1164 | { | ||
744 | /* assign dnr filter mode */ | 1165 | /* assign dnr filter mode */ |
1166 | if( dev->dnr_params.mode > BLACKBIRD_DNR_BITS_AUTO ) | ||
1167 | dev->dnr_params.mode = BLACKBIRD_DNR_BITS_MANUAL; | ||
1168 | if( dev->dnr_params.type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL ) | ||
1169 | dev->dnr_params.type = BLACKBIRD_MEDIAN_FILTER_DISABLED; | ||
745 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, | 1170 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, |
746 | BLACKBIRD_DNR_BITS_MANUAL, | 1171 | dev->dnr_params.mode, |
747 | BLACKBIRD_MEDIAN_FILTER_DISABLED | 1172 | dev->dnr_params.type |
748 | ); | 1173 | ); |
749 | 1174 | ||
750 | /* assign dnr filter props*/ | 1175 | /* assign dnr filter props*/ |
751 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, 0, 0); | 1176 | if( dev->dnr_params.spatial > 15 ) |
1177 | dev->dnr_params.spatial = 15; | ||
1178 | if( dev->dnr_params.temporal > 31 ) | ||
1179 | dev->dnr_params.temporal = 31; | ||
1180 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, | ||
1181 | dev->dnr_params.spatial, | ||
1182 | dev->dnr_params.temporal | ||
1183 | ); | ||
1184 | } | ||
1185 | #define CHECK_DNR_PARAM( name ) ( dev->dnr_params.name != dnr_params->name ) | ||
1186 | #define UPDATE_DNR_PARAM( name ) dev->dnr_params.name = dnr_params->name | ||
1187 | void blackbird_set_dnr_params(struct cx8802_dev *dev, struct blackbird_dnr* dnr_params) | ||
1188 | { | ||
1189 | /* assign dnr filter mode */ | ||
1190 | /* clamp values */ | ||
1191 | if( dnr_params->mode > BLACKBIRD_DNR_BITS_AUTO ) | ||
1192 | dnr_params->mode = BLACKBIRD_DNR_BITS_MANUAL; | ||
1193 | if( dnr_params->type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL ) | ||
1194 | dnr_params->type = BLACKBIRD_MEDIAN_FILTER_DISABLED; | ||
1195 | /* check if the params actually changed */ | ||
1196 | if( CHECK_DNR_PARAM( mode ) || CHECK_DNR_PARAM( type ) ) | ||
1197 | { | ||
1198 | UPDATE_DNR_PARAM( mode ); | ||
1199 | UPDATE_DNR_PARAM( type ); | ||
1200 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, dnr_params->mode, dnr_params->type); | ||
1201 | } | ||
1202 | |||
1203 | /* assign dnr filter props*/ | ||
1204 | if( dnr_params->spatial > 15 ) | ||
1205 | dnr_params->spatial = 15; | ||
1206 | if( dnr_params->temporal > 31 ) | ||
1207 | dnr_params->temporal = 31; | ||
1208 | if( CHECK_DNR_PARAM( spatial ) || CHECK_DNR_PARAM( temporal ) ) | ||
1209 | { | ||
1210 | UPDATE_DNR_PARAM( spatial ); | ||
1211 | UPDATE_DNR_PARAM( temporal ); | ||
1212 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, dnr_params->spatial, dnr_params->temporal); | ||
1213 | } | ||
1214 | } | ||
1215 | |||
1216 | static void blackbird_codec_settings(struct cx8802_dev *dev) | ||
1217 | { | ||
1218 | |||
1219 | /* assign output port */ | ||
1220 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */ | ||
1221 | |||
1222 | /* assign frame size */ | ||
1223 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0, | ||
1224 | dev->height, dev->width); | ||
752 | 1225 | ||
753 | /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */ | 1226 | /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */ |
754 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255); | 1227 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255); |
755 | 1228 | ||
756 | /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */ | 1229 | /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */ |
757 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0, | 1230 | blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0, |
758 | BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ, | 1231 | BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ, |
759 | BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ | 1232 | BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ |
760 | ); | 1233 | ); |
761 | 1234 | ||
762 | /* assign frame drop rate */ | 1235 | /* assign frame drop rate */ |
763 | /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */ | 1236 | /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */ |
1237 | |||
1238 | blackbird_set_default_params(dev); | ||
1239 | blackbird_set_default_dnr_params(dev); | ||
764 | } | 1240 | } |
765 | 1241 | ||
766 | static int blackbird_initialize_codec(struct cx8802_dev *dev) | 1242 | static int blackbird_initialize_codec(struct cx8802_dev *dev) |
@@ -851,15 +1327,10 @@ static int bb_buf_setup(struct videobuf_queue *q, | |||
851 | struct cx8802_fh *fh = q->priv_data; | 1327 | struct cx8802_fh *fh = q->priv_data; |
852 | 1328 | ||
853 | fh->dev->ts_packet_size = 188 * 4; /* was: 512 */ | 1329 | fh->dev->ts_packet_size = 188 * 4; /* was: 512 */ |
854 | fh->dev->ts_packet_count = 32; /* was: 100 */ | 1330 | fh->dev->ts_packet_count = mpegbufs; /* was: 100 */ |
855 | 1331 | ||
856 | *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count; | 1332 | *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count; |
857 | if (0 == *count) | 1333 | *count = fh->dev->ts_packet_count; |
858 | *count = mpegbufs; | ||
859 | if (*count < 2) | ||
860 | *count = 2; | ||
861 | if (*count > 32) | ||
862 | *count = 32; | ||
863 | return 0; | 1334 | return 0; |
864 | } | 1335 | } |
865 | 1336 | ||
@@ -868,7 +1339,7 @@ bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
868 | enum v4l2_field field) | 1339 | enum v4l2_field field) |
869 | { | 1340 | { |
870 | struct cx8802_fh *fh = q->priv_data; | 1341 | struct cx8802_fh *fh = q->priv_data; |
871 | return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb); | 1342 | return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb, field); |
872 | } | 1343 | } |
873 | 1344 | ||
874 | static void | 1345 | static void |
@@ -920,8 +1391,6 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, | |||
920 | V4L2_CAP_VIDEO_CAPTURE | | 1391 | V4L2_CAP_VIDEO_CAPTURE | |
921 | V4L2_CAP_READWRITE | | 1392 | V4L2_CAP_READWRITE | |
922 | V4L2_CAP_STREAMING | | 1393 | V4L2_CAP_STREAMING | |
923 | V4L2_CAP_VBI_CAPTURE | | ||
924 | V4L2_CAP_VIDEO_OVERLAY | | ||
925 | 0; | 1394 | 0; |
926 | if (UNSET != core->tuner_type) | 1395 | if (UNSET != core->tuner_type) |
927 | cap->capabilities |= V4L2_CAP_TUNER; | 1396 | cap->capabilities |= V4L2_CAP_TUNER; |
@@ -941,27 +1410,52 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, | |||
941 | 1410 | ||
942 | memset(f,0,sizeof(*f)); | 1411 | memset(f,0,sizeof(*f)); |
943 | f->index = index; | 1412 | f->index = index; |
944 | strlcpy(f->description, "MPEG TS", sizeof(f->description)); | 1413 | strlcpy(f->description, "MPEG", sizeof(f->description)); |
945 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1414 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
946 | f->pixelformat = V4L2_PIX_FMT_MPEG; | 1415 | f->pixelformat = V4L2_PIX_FMT_MPEG; |
947 | return 0; | 1416 | return 0; |
948 | } | 1417 | } |
949 | case VIDIOC_G_FMT: | 1418 | case VIDIOC_G_FMT: |
950 | case VIDIOC_S_FMT: | ||
951 | case VIDIOC_TRY_FMT: | ||
952 | { | 1419 | { |
953 | /* FIXME -- quick'n'dirty for exactly one size ... */ | ||
954 | struct v4l2_format *f = arg; | 1420 | struct v4l2_format *f = arg; |
955 | 1421 | ||
956 | memset(f,0,sizeof(*f)); | 1422 | memset(f,0,sizeof(*f)); |
957 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1423 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1424 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
1425 | f->fmt.pix.bytesperline = 0; | ||
1426 | f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */ | ||
1427 | f->fmt.pix.colorspace = 0; | ||
958 | f->fmt.pix.width = dev->width; | 1428 | f->fmt.pix.width = dev->width; |
959 | f->fmt.pix.height = dev->height; | 1429 | f->fmt.pix.height = dev->height; |
1430 | f->fmt.pix.field = fh->mpegq.field; | ||
1431 | dprintk(0,"VIDIOC_G_FMT: w: %d, h: %d, f: %d\n", | ||
1432 | dev->width, dev->height, fh->mpegq.field ); | ||
1433 | return 0; | ||
1434 | } | ||
1435 | case VIDIOC_TRY_FMT: | ||
1436 | { | ||
1437 | struct v4l2_format *f = arg; | ||
1438 | |||
1439 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1440 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | ||
1441 | f->fmt.pix.bytesperline = 0; | ||
1442 | f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */; | ||
1443 | f->fmt.pix.colorspace = 0; | ||
1444 | dprintk(0,"VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", | ||
1445 | dev->width, dev->height, fh->mpegq.field ); | ||
1446 | return 0; | ||
1447 | } | ||
1448 | case VIDIOC_S_FMT: | ||
1449 | { | ||
1450 | struct v4l2_format *f = arg; | ||
1451 | |||
1452 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
960 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | 1453 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; |
961 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
962 | f->fmt.pix.bytesperline = 0; | 1454 | f->fmt.pix.bytesperline = 0; |
963 | f->fmt.pix.sizeimage = 188 * 4 * 1024; /* 1024 * 512 */ /* FIXME: BUFFER_SIZE */; | 1455 | f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */; |
964 | f->fmt.pix.colorspace = 0; | 1456 | f->fmt.pix.colorspace = 0; |
1457 | dprintk(0,"VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", | ||
1458 | f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field ); | ||
965 | return 0; | 1459 | return 0; |
966 | } | 1460 | } |
967 | 1461 | ||
@@ -985,6 +1479,22 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, | |||
985 | case VIDIOC_STREAMOFF: | 1479 | case VIDIOC_STREAMOFF: |
986 | return videobuf_streamoff(&fh->mpegq); | 1480 | return videobuf_streamoff(&fh->mpegq); |
987 | 1481 | ||
1482 | /* --- mpeg compression -------------------------------------- */ | ||
1483 | case VIDIOC_G_MPEGCOMP: | ||
1484 | { | ||
1485 | struct v4l2_mpeg_compression *f = arg; | ||
1486 | |||
1487 | memcpy(f,&dev->params,sizeof(*f)); | ||
1488 | return 0; | ||
1489 | } | ||
1490 | case VIDIOC_S_MPEGCOMP: | ||
1491 | { | ||
1492 | struct v4l2_mpeg_compression *f = arg; | ||
1493 | |||
1494 | blackbird_set_params(dev, f); | ||
1495 | return 0; | ||
1496 | } | ||
1497 | |||
988 | default: | 1498 | default: |
989 | return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook ); | 1499 | return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook ); |
990 | } | 1500 | } |
@@ -1034,16 +1544,17 @@ static int mpeg_open(struct inode *inode, struct file *file) | |||
1034 | file->private_data = fh; | 1544 | file->private_data = fh; |
1035 | fh->dev = dev; | 1545 | fh->dev = dev; |
1036 | 1546 | ||
1037 | /* FIXME: locking against other video device */ | ||
1038 | cx88_set_scale(dev->core, dev->width, dev->height, | ||
1039 | V4L2_FIELD_INTERLACED); | ||
1040 | |||
1041 | videobuf_queue_init(&fh->mpegq, &blackbird_qops, | 1547 | videobuf_queue_init(&fh->mpegq, &blackbird_qops, |
1042 | dev->pci, &dev->slock, | 1548 | dev->pci, &dev->slock, |
1043 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1549 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
1044 | V4L2_FIELD_TOP, | 1550 | V4L2_FIELD_INTERLACED, |
1045 | sizeof(struct cx88_buffer), | 1551 | sizeof(struct cx88_buffer), |
1046 | fh); | 1552 | fh); |
1553 | |||
1554 | /* FIXME: locking against other video device */ | ||
1555 | cx88_set_scale(dev->core, dev->width, dev->height, | ||
1556 | fh->mpegq.field); | ||
1557 | |||
1047 | return 0; | 1558 | return 0; |
1048 | } | 1559 | } |
1049 | 1560 | ||
@@ -1173,6 +1684,8 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev, | |||
1173 | dev->core = core; | 1684 | dev->core = core; |
1174 | dev->width = 720; | 1685 | dev->width = 720; |
1175 | dev->height = 576; | 1686 | dev->height = 576; |
1687 | memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params)); | ||
1688 | memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params)); | ||
1176 | 1689 | ||
1177 | err = cx8802_init_common(dev); | 1690 | err = cx8802_init_common(dev); |
1178 | if (0 != err) | 1691 | if (0 != err) |
@@ -1199,7 +1712,7 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev, | |||
1199 | 1712 | ||
1200 | static void __devexit blackbird_remove(struct pci_dev *pci_dev) | 1713 | static void __devexit blackbird_remove(struct pci_dev *pci_dev) |
1201 | { | 1714 | { |
1202 | struct cx8802_dev *dev = pci_get_drvdata(pci_dev); | 1715 | struct cx8802_dev *dev = pci_get_drvdata(pci_dev); |
1203 | 1716 | ||
1204 | /* blackbird */ | 1717 | /* blackbird */ |
1205 | blackbird_unregister_video(dev); | 1718 | blackbird_unregister_video(dev); |
@@ -1215,8 +1728,8 @@ static struct pci_device_id cx8802_pci_tbl[] = { | |||
1215 | { | 1728 | { |
1216 | .vendor = 0x14f1, | 1729 | .vendor = 0x14f1, |
1217 | .device = 0x8802, | 1730 | .device = 0x8802, |
1218 | .subvendor = PCI_ANY_ID, | 1731 | .subvendor = PCI_ANY_ID, |
1219 | .subdevice = PCI_ANY_ID, | 1732 | .subdevice = PCI_ANY_ID, |
1220 | },{ | 1733 | },{ |
1221 | /* --- end of list --- */ | 1734 | /* --- end of list --- */ |
1222 | } | 1735 | } |
@@ -1224,10 +1737,10 @@ static struct pci_device_id cx8802_pci_tbl[] = { | |||
1224 | MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); | 1737 | MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); |
1225 | 1738 | ||
1226 | static struct pci_driver blackbird_pci_driver = { | 1739 | static struct pci_driver blackbird_pci_driver = { |
1227 | .name = "cx88-blackbird", | 1740 | .name = "cx88-blackbird", |
1228 | .id_table = cx8802_pci_tbl, | 1741 | .id_table = cx8802_pci_tbl, |
1229 | .probe = blackbird_probe, | 1742 | .probe = blackbird_probe, |
1230 | .remove = __devexit_p(blackbird_remove), | 1743 | .remove = __devexit_p(blackbird_remove), |
1231 | .suspend = cx8802_suspend_common, | 1744 | .suspend = cx8802_suspend_common, |
1232 | .resume = cx8802_resume_common, | 1745 | .resume = cx8802_resume_common, |
1233 | }; | 1746 | }; |
@@ -1257,6 +1770,8 @@ module_exit(blackbird_fini); | |||
1257 | 1770 | ||
1258 | EXPORT_SYMBOL(cx88_ioctl_hook); | 1771 | EXPORT_SYMBOL(cx88_ioctl_hook); |
1259 | EXPORT_SYMBOL(cx88_ioctl_translator); | 1772 | EXPORT_SYMBOL(cx88_ioctl_translator); |
1773 | EXPORT_SYMBOL(blackbird_set_params); | ||
1774 | EXPORT_SYMBOL(blackbird_set_dnr_params); | ||
1260 | 1775 | ||
1261 | /* ----------------------------------------------------------- */ | 1776 | /* ----------------------------------------------------------- */ |
1262 | /* | 1777 | /* |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 4da91d535a5b..f2268631b7c0 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -126,27 +126,27 @@ struct cx88_board cx88_boards[] = { | |||
126 | .input = {{ | 126 | .input = {{ |
127 | .type = CX88_VMUX_TELEVISION, | 127 | .type = CX88_VMUX_TELEVISION, |
128 | .vmux = 0, | 128 | .vmux = 0, |
129 | .gpio0 = 0x03ff, | 129 | .gpio0 = 0x03ff, |
130 | },{ | 130 | },{ |
131 | .type = CX88_VMUX_COMPOSITE1, | 131 | .type = CX88_VMUX_COMPOSITE1, |
132 | .vmux = 1, | 132 | .vmux = 1, |
133 | .gpio0 = 0x03fe, | 133 | .gpio0 = 0x03fe, |
134 | },{ | 134 | },{ |
135 | .type = CX88_VMUX_SVIDEO, | 135 | .type = CX88_VMUX_SVIDEO, |
136 | .vmux = 2, | 136 | .vmux = 2, |
137 | .gpio0 = 0x03fe, | 137 | .gpio0 = 0x03fe, |
138 | }}, | 138 | }}, |
139 | }, | 139 | }, |
140 | [CX88_BOARD_WINFAST2000XP_EXPERT] = { | 140 | [CX88_BOARD_WINFAST2000XP_EXPERT] = { |
141 | .name = "Leadtek Winfast 2000XP Expert", | 141 | .name = "Leadtek Winfast 2000XP Expert", |
142 | .tuner_type = TUNER_PHILIPS_4IN1, | 142 | .tuner_type = TUNER_PHILIPS_4IN1, |
143 | .radio_type = UNSET, | 143 | .radio_type = UNSET, |
144 | .tuner_addr = ADDR_UNSET, | 144 | .tuner_addr = ADDR_UNSET, |
145 | .radio_addr = ADDR_UNSET, | 145 | .radio_addr = ADDR_UNSET, |
146 | .tda9887_conf = TDA9887_PRESENT, | 146 | .tda9887_conf = TDA9887_PRESENT, |
147 | .input = {{ | 147 | .input = {{ |
148 | .type = CX88_VMUX_TELEVISION, | 148 | .type = CX88_VMUX_TELEVISION, |
149 | .vmux = 0, | 149 | .vmux = 0, |
150 | .gpio0 = 0x00F5e700, | 150 | .gpio0 = 0x00F5e700, |
151 | .gpio1 = 0x00003004, | 151 | .gpio1 = 0x00003004, |
152 | .gpio2 = 0x00F5e700, | 152 | .gpio2 = 0x00F5e700, |
@@ -165,16 +165,16 @@ struct cx88_board cx88_boards[] = { | |||
165 | .gpio1 = 0x00003004, | 165 | .gpio1 = 0x00003004, |
166 | .gpio2 = 0x00F5c700, | 166 | .gpio2 = 0x00F5c700, |
167 | .gpio3 = 0x02000000, | 167 | .gpio3 = 0x02000000, |
168 | }}, | 168 | }}, |
169 | .radio = { | 169 | .radio = { |
170 | .type = CX88_RADIO, | 170 | .type = CX88_RADIO, |
171 | .gpio0 = 0x00F5d700, | 171 | .gpio0 = 0x00F5d700, |
172 | .gpio1 = 0x00003004, | 172 | .gpio1 = 0x00003004, |
173 | .gpio2 = 0x00F5d700, | 173 | .gpio2 = 0x00F5d700, |
174 | .gpio3 = 0x02000000, | 174 | .gpio3 = 0x02000000, |
175 | }, | 175 | }, |
176 | }, | 176 | }, |
177 | [CX88_BOARD_AVERTV_303] = { | 177 | [CX88_BOARD_AVERTV_STUDIO_303] = { |
178 | .name = "AverTV Studio 303 (M126)", | 178 | .name = "AverTV Studio 303 (M126)", |
179 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 179 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
180 | .radio_type = UNSET, | 180 | .radio_type = UNSET, |
@@ -206,7 +206,7 @@ struct cx88_board cx88_boards[] = { | |||
206 | .radio_type = UNSET, | 206 | .radio_type = UNSET, |
207 | .tuner_addr = ADDR_UNSET, | 207 | .tuner_addr = ADDR_UNSET, |
208 | .radio_addr = ADDR_UNSET, | 208 | .radio_addr = ADDR_UNSET, |
209 | .tda9887_conf = TDA9887_PRESENT, | 209 | .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER_NTSC, |
210 | .input = {{ | 210 | .input = {{ |
211 | .type = CX88_VMUX_TELEVISION, | 211 | .type = CX88_VMUX_TELEVISION, |
212 | .vmux = 0, | 212 | .vmux = 0, |
@@ -214,32 +214,32 @@ struct cx88_board cx88_boards[] = { | |||
214 | .gpio1 = 0x000080c0, | 214 | .gpio1 = 0x000080c0, |
215 | .gpio2 = 0x0000ff40, | 215 | .gpio2 = 0x0000ff40, |
216 | },{ | 216 | },{ |
217 | .type = CX88_VMUX_COMPOSITE1, | 217 | .type = CX88_VMUX_COMPOSITE1, |
218 | .vmux = 1, | 218 | .vmux = 1, |
219 | .gpio0 = 0x000040bf, | 219 | .gpio0 = 0x000040bf, |
220 | .gpio1 = 0x000080c0, | 220 | .gpio1 = 0x000080c0, |
221 | .gpio2 = 0x0000ff40, | 221 | .gpio2 = 0x0000ff40, |
222 | },{ | 222 | },{ |
223 | .type = CX88_VMUX_SVIDEO, | 223 | .type = CX88_VMUX_SVIDEO, |
224 | .vmux = 2, | 224 | .vmux = 2, |
225 | .gpio0 = 0x000040bf, | 225 | .gpio0 = 0x000040bf, |
226 | .gpio1 = 0x000080c0, | 226 | .gpio1 = 0x000080c0, |
227 | .gpio2 = 0x0000ff40, | 227 | .gpio2 = 0x0000ff40, |
228 | }}, | 228 | }}, |
229 | .radio = { | 229 | .radio = { |
230 | .type = CX88_RADIO, | 230 | .type = CX88_RADIO, |
231 | }, | 231 | }, |
232 | }, | 232 | }, |
233 | [CX88_BOARD_WINFAST_DV2000] = { | 233 | [CX88_BOARD_WINFAST_DV2000] = { |
234 | .name = "Leadtek Winfast DV2000", | 234 | .name = "Leadtek Winfast DV2000", |
235 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 235 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
236 | .radio_type = UNSET, | 236 | .radio_type = UNSET, |
237 | .tuner_addr = ADDR_UNSET, | 237 | .tuner_addr = ADDR_UNSET, |
238 | .radio_addr = ADDR_UNSET, | 238 | .radio_addr = ADDR_UNSET, |
239 | .tda9887_conf = TDA9887_PRESENT, | 239 | .tda9887_conf = TDA9887_PRESENT, |
240 | .input = {{ | 240 | .input = {{ |
241 | .type = CX88_VMUX_TELEVISION, | 241 | .type = CX88_VMUX_TELEVISION, |
242 | .vmux = 0, | 242 | .vmux = 0, |
243 | .gpio0 = 0x0035e700, | 243 | .gpio0 = 0x0035e700, |
244 | .gpio1 = 0x00003004, | 244 | .gpio1 = 0x00003004, |
245 | .gpio2 = 0x0035e700, | 245 | .gpio2 = 0x0035e700, |
@@ -260,14 +260,14 @@ struct cx88_board cx88_boards[] = { | |||
260 | .gpio2 = 0x02000000, | 260 | .gpio2 = 0x02000000, |
261 | .gpio3 = 0x02000000, | 261 | .gpio3 = 0x02000000, |
262 | }}, | 262 | }}, |
263 | .radio = { | 263 | .radio = { |
264 | .type = CX88_RADIO, | 264 | .type = CX88_RADIO, |
265 | .gpio0 = 0x0035d700, | 265 | .gpio0 = 0x0035d700, |
266 | .gpio1 = 0x00007004, | 266 | .gpio1 = 0x00007004, |
267 | .gpio2 = 0x0035d700, | 267 | .gpio2 = 0x0035d700, |
268 | .gpio3 = 0x02000000, | 268 | .gpio3 = 0x02000000, |
269 | }, | 269 | }, |
270 | }, | 270 | }, |
271 | [CX88_BOARD_LEADTEK_PVR2000] = { | 271 | [CX88_BOARD_LEADTEK_PVR2000] = { |
272 | // gpio values for PAL version from regspy by DScaler | 272 | // gpio values for PAL version from regspy by DScaler |
273 | .name = "Leadtek PVR 2000", | 273 | .name = "Leadtek PVR 2000", |
@@ -296,25 +296,25 @@ struct cx88_board cx88_boards[] = { | |||
296 | .blackbird = 1, | 296 | .blackbird = 1, |
297 | }, | 297 | }, |
298 | [CX88_BOARD_IODATA_GVVCP3PCI] = { | 298 | [CX88_BOARD_IODATA_GVVCP3PCI] = { |
299 | .name = "IODATA GV-VCP3/PCI", | 299 | .name = "IODATA GV-VCP3/PCI", |
300 | .tuner_type = TUNER_ABSENT, | 300 | .tuner_type = TUNER_ABSENT, |
301 | .radio_type = UNSET, | 301 | .radio_type = UNSET, |
302 | .tuner_addr = ADDR_UNSET, | 302 | .tuner_addr = ADDR_UNSET, |
303 | .radio_addr = ADDR_UNSET, | 303 | .radio_addr = ADDR_UNSET, |
304 | .input = {{ | 304 | .input = {{ |
305 | .type = CX88_VMUX_COMPOSITE1, | 305 | .type = CX88_VMUX_COMPOSITE1, |
306 | .vmux = 0, | 306 | .vmux = 0, |
307 | },{ | 307 | },{ |
308 | .type = CX88_VMUX_COMPOSITE2, | 308 | .type = CX88_VMUX_COMPOSITE2, |
309 | .vmux = 1, | 309 | .vmux = 1, |
310 | },{ | 310 | },{ |
311 | .type = CX88_VMUX_SVIDEO, | 311 | .type = CX88_VMUX_SVIDEO, |
312 | .vmux = 2, | 312 | .vmux = 2, |
313 | }}, | 313 | }}, |
314 | }, | 314 | }, |
315 | [CX88_BOARD_PROLINK_PLAYTVPVR] = { | 315 | [CX88_BOARD_PROLINK_PLAYTVPVR] = { |
316 | .name = "Prolink PlayTV PVR", | 316 | .name = "Prolink PlayTV PVR", |
317 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, | 317 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, |
318 | .radio_type = UNSET, | 318 | .radio_type = UNSET, |
319 | .tuner_addr = ADDR_UNSET, | 319 | .tuner_addr = ADDR_UNSET, |
320 | .radio_addr = ADDR_UNSET, | 320 | .radio_addr = ADDR_UNSET, |
@@ -348,15 +348,15 @@ struct cx88_board cx88_boards[] = { | |||
348 | .type = CX88_VMUX_TELEVISION, | 348 | .type = CX88_VMUX_TELEVISION, |
349 | .vmux = 0, | 349 | .vmux = 0, |
350 | .gpio0 = 0x0000fde6, | 350 | .gpio0 = 0x0000fde6, |
351 | },{ | 351 | },{ |
352 | .type = CX88_VMUX_SVIDEO, | 352 | .type = CX88_VMUX_SVIDEO, |
353 | .vmux = 2, | 353 | .vmux = 2, |
354 | .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in? | 354 | .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in? |
355 | }}, | 355 | }}, |
356 | .radio = { | 356 | .radio = { |
357 | .type = CX88_RADIO, | 357 | .type = CX88_RADIO, |
358 | .gpio0 = 0x0000fde2, | 358 | .gpio0 = 0x0000fde2, |
359 | }, | 359 | }, |
360 | .blackbird = 1, | 360 | .blackbird = 1, |
361 | }, | 361 | }, |
362 | [CX88_BOARD_MSI_TVANYWHERE] = { | 362 | [CX88_BOARD_MSI_TVANYWHERE] = { |
@@ -372,34 +372,34 @@ struct cx88_board cx88_boards[] = { | |||
372 | .gpio0 = 0x00000fbf, | 372 | .gpio0 = 0x00000fbf, |
373 | .gpio2 = 0x0000fc08, | 373 | .gpio2 = 0x0000fc08, |
374 | },{ | 374 | },{ |
375 | .type = CX88_VMUX_COMPOSITE1, | 375 | .type = CX88_VMUX_COMPOSITE1, |
376 | .vmux = 1, | 376 | .vmux = 1, |
377 | .gpio0 = 0x00000fbf, | 377 | .gpio0 = 0x00000fbf, |
378 | .gpio2 = 0x0000fc68, | 378 | .gpio2 = 0x0000fc68, |
379 | },{ | 379 | },{ |
380 | .type = CX88_VMUX_SVIDEO, | 380 | .type = CX88_VMUX_SVIDEO, |
381 | .vmux = 2, | 381 | .vmux = 2, |
382 | .gpio0 = 0x00000fbf, | 382 | .gpio0 = 0x00000fbf, |
383 | .gpio2 = 0x0000fc68, | 383 | .gpio2 = 0x0000fc68, |
384 | }}, | 384 | }}, |
385 | }, | 385 | }, |
386 | [CX88_BOARD_KWORLD_DVB_T] = { | 386 | [CX88_BOARD_KWORLD_DVB_T] = { |
387 | .name = "KWorld/VStream XPert DVB-T", | 387 | .name = "KWorld/VStream XPert DVB-T", |
388 | .tuner_type = TUNER_ABSENT, | 388 | .tuner_type = TUNER_ABSENT, |
389 | .radio_type = UNSET, | 389 | .radio_type = UNSET, |
390 | .tuner_addr = ADDR_UNSET, | 390 | .tuner_addr = ADDR_UNSET, |
391 | .radio_addr = ADDR_UNSET, | 391 | .radio_addr = ADDR_UNSET, |
392 | .input = {{ | 392 | .input = {{ |
393 | .type = CX88_VMUX_COMPOSITE1, | 393 | .type = CX88_VMUX_COMPOSITE1, |
394 | .vmux = 1, | 394 | .vmux = 1, |
395 | .gpio0 = 0x0700, | 395 | .gpio0 = 0x0700, |
396 | .gpio2 = 0x0101, | 396 | .gpio2 = 0x0101, |
397 | },{ | 397 | },{ |
398 | .type = CX88_VMUX_SVIDEO, | 398 | .type = CX88_VMUX_SVIDEO, |
399 | .vmux = 2, | 399 | .vmux = 2, |
400 | .gpio0 = 0x0700, | 400 | .gpio0 = 0x0700, |
401 | .gpio2 = 0x0101, | 401 | .gpio2 = 0x0101, |
402 | }}, | 402 | }}, |
403 | .dvb = 1, | 403 | .dvb = 1, |
404 | }, | 404 | }, |
405 | [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = { | 405 | [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = { |
@@ -425,27 +425,27 @@ struct cx88_board cx88_boards[] = { | |||
425 | .radio_type = UNSET, | 425 | .radio_type = UNSET, |
426 | .tuner_addr = ADDR_UNSET, | 426 | .tuner_addr = ADDR_UNSET, |
427 | .radio_addr = ADDR_UNSET, | 427 | .radio_addr = ADDR_UNSET, |
428 | .input = {{ | 428 | .input = {{ |
429 | .type = CX88_VMUX_TELEVISION, | 429 | .type = CX88_VMUX_TELEVISION, |
430 | .vmux = 0, | 430 | .vmux = 0, |
431 | .gpio0 = 0x07f8, | 431 | .gpio0 = 0x07f8, |
432 | },{ | 432 | },{ |
433 | .type = CX88_VMUX_DEBUG, | 433 | .type = CX88_VMUX_DEBUG, |
434 | .vmux = 0, | 434 | .vmux = 0, |
435 | .gpio0 = 0x07f9, // mono from tuner chip | 435 | .gpio0 = 0x07f9, // mono from tuner chip |
436 | },{ | 436 | },{ |
437 | .type = CX88_VMUX_COMPOSITE1, | 437 | .type = CX88_VMUX_COMPOSITE1, |
438 | .vmux = 1, | 438 | .vmux = 1, |
439 | .gpio0 = 0x000007fa, | 439 | .gpio0 = 0x000007fa, |
440 | },{ | 440 | },{ |
441 | .type = CX88_VMUX_SVIDEO, | 441 | .type = CX88_VMUX_SVIDEO, |
442 | .vmux = 2, | 442 | .vmux = 2, |
443 | .gpio0 = 0x000007fa, | 443 | .gpio0 = 0x000007fa, |
444 | }}, | 444 | }}, |
445 | .radio = { | 445 | .radio = { |
446 | .type = CX88_RADIO, | 446 | .type = CX88_RADIO, |
447 | .gpio0 = 0x000007f8, | 447 | .gpio0 = 0x000007f8, |
448 | }, | 448 | }, |
449 | }, | 449 | }, |
450 | [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = { | 450 | [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = { |
451 | .name = "DViCO FusionHDTV 3 Gold-Q", | 451 | .name = "DViCO FusionHDTV 3 Gold-Q", |
@@ -489,28 +489,28 @@ struct cx88_board cx88_boards[] = { | |||
489 | }}, | 489 | }}, |
490 | .dvb = 1, | 490 | .dvb = 1, |
491 | }, | 491 | }, |
492 | [CX88_BOARD_HAUPPAUGE_DVB_T1] = { | 492 | [CX88_BOARD_HAUPPAUGE_DVB_T1] = { |
493 | .name = "Hauppauge Nova-T DVB-T", | 493 | .name = "Hauppauge Nova-T DVB-T", |
494 | .tuner_type = TUNER_ABSENT, | 494 | .tuner_type = TUNER_ABSENT, |
495 | .radio_type = UNSET, | 495 | .radio_type = UNSET, |
496 | .tuner_addr = ADDR_UNSET, | 496 | .tuner_addr = ADDR_UNSET, |
497 | .radio_addr = ADDR_UNSET, | 497 | .radio_addr = ADDR_UNSET, |
498 | .input = {{ | 498 | .input = {{ |
499 | .type = CX88_VMUX_DVB, | 499 | .type = CX88_VMUX_DVB, |
500 | .vmux = 0, | 500 | .vmux = 0, |
501 | }}, | 501 | }}, |
502 | .dvb = 1, | 502 | .dvb = 1, |
503 | }, | 503 | }, |
504 | [CX88_BOARD_CONEXANT_DVB_T1] = { | 504 | [CX88_BOARD_CONEXANT_DVB_T1] = { |
505 | .name = "Conexant DVB-T reference design", | 505 | .name = "Conexant DVB-T reference design", |
506 | .tuner_type = TUNER_ABSENT, | 506 | .tuner_type = TUNER_ABSENT, |
507 | .radio_type = UNSET, | 507 | .radio_type = UNSET, |
508 | .tuner_addr = ADDR_UNSET, | 508 | .tuner_addr = ADDR_UNSET, |
509 | .radio_addr = ADDR_UNSET, | 509 | .radio_addr = ADDR_UNSET, |
510 | .input = {{ | 510 | .input = {{ |
511 | .type = CX88_VMUX_DVB, | 511 | .type = CX88_VMUX_DVB, |
512 | .vmux = 0, | 512 | .vmux = 0, |
513 | }}, | 513 | }}, |
514 | .dvb = 1, | 514 | .dvb = 1, |
515 | }, | 515 | }, |
516 | [CX88_BOARD_PROVIDEO_PV259] = { | 516 | [CX88_BOARD_PROVIDEO_PV259] = { |
@@ -543,12 +543,12 @@ struct cx88_board cx88_boards[] = { | |||
543 | .dvb = 1, | 543 | .dvb = 1, |
544 | }, | 544 | }, |
545 | [CX88_BOARD_DNTV_LIVE_DVB_T] = { | 545 | [CX88_BOARD_DNTV_LIVE_DVB_T] = { |
546 | .name = "digitalnow DNTV Live! DVB-T", | 546 | .name = "digitalnow DNTV Live! DVB-T", |
547 | .tuner_type = TUNER_ABSENT, | 547 | .tuner_type = TUNER_ABSENT, |
548 | .radio_type = UNSET, | 548 | .radio_type = UNSET, |
549 | .tuner_addr = ADDR_UNSET, | 549 | .tuner_addr = ADDR_UNSET, |
550 | .radio_addr = ADDR_UNSET, | 550 | .radio_addr = ADDR_UNSET, |
551 | .input = {{ | 551 | .input = {{ |
552 | .type = CX88_VMUX_COMPOSITE1, | 552 | .type = CX88_VMUX_COMPOSITE1, |
553 | .vmux = 1, | 553 | .vmux = 1, |
554 | .gpio0 = 0x00000700, | 554 | .gpio0 = 0x00000700, |
@@ -705,44 +705,44 @@ struct cx88_board cx88_boards[] = { | |||
705 | .gpio0 = 0xbf60, | 705 | .gpio0 = 0xbf60, |
706 | }, | 706 | }, |
707 | }, | 707 | }, |
708 | [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { | 708 | [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { |
709 | .name = "DViCO FusionHDTV 3 Gold-T", | 709 | .name = "DViCO FusionHDTV 3 Gold-T", |
710 | .tuner_type = TUNER_THOMSON_DTT7611, | 710 | .tuner_type = TUNER_THOMSON_DTT7611, |
711 | .radio_type = UNSET, | 711 | .radio_type = UNSET, |
712 | .tuner_addr = ADDR_UNSET, | 712 | .tuner_addr = ADDR_UNSET, |
713 | .radio_addr = ADDR_UNSET, | 713 | .radio_addr = ADDR_UNSET, |
714 | .input = {{ | 714 | .input = {{ |
715 | .type = CX88_VMUX_TELEVISION, | 715 | .type = CX88_VMUX_TELEVISION, |
716 | .vmux = 0, | 716 | .vmux = 0, |
717 | .gpio0 = 0x97ed, | 717 | .gpio0 = 0x97ed, |
718 | },{ | 718 | },{ |
719 | .type = CX88_VMUX_COMPOSITE1, | 719 | .type = CX88_VMUX_COMPOSITE1, |
720 | .vmux = 1, | 720 | .vmux = 1, |
721 | .gpio0 = 0x97e9, | 721 | .gpio0 = 0x97e9, |
722 | },{ | 722 | },{ |
723 | .type = CX88_VMUX_SVIDEO, | 723 | .type = CX88_VMUX_SVIDEO, |
724 | .vmux = 2, | 724 | .vmux = 2, |
725 | .gpio0 = 0x97e9, | 725 | .gpio0 = 0x97e9, |
726 | }}, | 726 | }}, |
727 | .dvb = 1, | 727 | .dvb = 1, |
728 | }, | 728 | }, |
729 | [CX88_BOARD_ADSTECH_DVB_T_PCI] = { | 729 | [CX88_BOARD_ADSTECH_DVB_T_PCI] = { |
730 | .name = "ADS Tech Instant TV DVB-T PCI", | 730 | .name = "ADS Tech Instant TV DVB-T PCI", |
731 | .tuner_type = TUNER_ABSENT, | 731 | .tuner_type = TUNER_ABSENT, |
732 | .radio_type = UNSET, | 732 | .radio_type = UNSET, |
733 | .tuner_addr = ADDR_UNSET, | 733 | .tuner_addr = ADDR_UNSET, |
734 | .radio_addr = ADDR_UNSET, | 734 | .radio_addr = ADDR_UNSET, |
735 | .input = {{ | 735 | .input = {{ |
736 | .type = CX88_VMUX_COMPOSITE1, | 736 | .type = CX88_VMUX_COMPOSITE1, |
737 | .vmux = 1, | 737 | .vmux = 1, |
738 | .gpio0 = 0x0700, | 738 | .gpio0 = 0x0700, |
739 | .gpio2 = 0x0101, | 739 | .gpio2 = 0x0101, |
740 | },{ | 740 | },{ |
741 | .type = CX88_VMUX_SVIDEO, | 741 | .type = CX88_VMUX_SVIDEO, |
742 | .vmux = 2, | 742 | .vmux = 2, |
743 | .gpio0 = 0x0700, | 743 | .gpio0 = 0x0700, |
744 | .gpio2 = 0x0101, | 744 | .gpio2 = 0x0101, |
745 | }}, | 745 | }}, |
746 | .dvb = 1, | 746 | .dvb = 1, |
747 | }, | 747 | }, |
748 | [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = { | 748 | [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = { |
@@ -762,20 +762,139 @@ struct cx88_board cx88_boards[] = { | |||
762 | .radio_addr = ADDR_UNSET, | 762 | .radio_addr = ADDR_UNSET, |
763 | .tda9887_conf = TDA9887_PRESENT, | 763 | .tda9887_conf = TDA9887_PRESENT, |
764 | .input = {{ | 764 | .input = {{ |
765 | .type = CX88_VMUX_TELEVISION, | 765 | .type = CX88_VMUX_TELEVISION, |
766 | .vmux = 0, | 766 | .vmux = 0, |
767 | .gpio0 = 0x87fd, | 767 | .gpio0 = 0x87fd, |
768 | },{ | 768 | },{ |
769 | .type = CX88_VMUX_COMPOSITE1, | 769 | .type = CX88_VMUX_COMPOSITE1, |
770 | .vmux = 1, | 770 | .vmux = 1, |
771 | .gpio0 = 0x87f9, | 771 | .gpio0 = 0x87f9, |
772 | },{ | 772 | },{ |
773 | .type = CX88_VMUX_SVIDEO, | 773 | .type = CX88_VMUX_SVIDEO, |
774 | .vmux = 2, | 774 | .vmux = 2, |
775 | .gpio0 = 0x87f9, | 775 | .gpio0 = 0x87f9, |
776 | }}, | 776 | }}, |
777 | .dvb = 1, | ||
778 | }, | ||
779 | [CX88_BOARD_AVERMEDIA_ULTRATV_MC_550] = { | ||
780 | .name = "AverMedia UltraTV Media Center PCI 550", | ||
781 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, | ||
782 | .radio_type = UNSET, | ||
783 | .tuner_addr = ADDR_UNSET, | ||
784 | .radio_addr = ADDR_UNSET, | ||
785 | .tda9887_conf = TDA9887_PRESENT, | ||
786 | .blackbird = 1, | ||
787 | .input = {{ | ||
788 | .type = CX88_VMUX_COMPOSITE1, | ||
789 | .vmux = 0, | ||
790 | .gpio0 = 0x0000cd73, | ||
791 | },{ | ||
792 | .type = CX88_VMUX_SVIDEO, | ||
793 | .vmux = 1, | ||
794 | .gpio0 = 0x0000cd73, | ||
795 | },{ | ||
796 | .type = CX88_VMUX_TELEVISION, | ||
797 | .vmux = 3, | ||
798 | .gpio0 = 0x0000cdb3, | ||
799 | }}, | ||
800 | .radio = { | ||
801 | .type = CX88_RADIO, | ||
802 | .vmux = 2, | ||
803 | .gpio0 = 0x0000cdf3, | ||
804 | }, | ||
805 | }, | ||
806 | [CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD] = { | ||
807 | /* Alexander Wold <awold@bigfoot.com> */ | ||
808 | .name = "Kworld V-Stream Xpert DVD", | ||
809 | .tuner_type = UNSET, | ||
810 | .input = {{ | ||
811 | .type = CX88_VMUX_COMPOSITE1, | ||
812 | .vmux = 1, | ||
813 | .gpio0 = 0x03000000, | ||
814 | .gpio1 = 0x01000000, | ||
815 | .gpio2 = 0x02000000, | ||
816 | .gpio3 = 0x00100000, | ||
817 | },{ | ||
818 | .type = CX88_VMUX_SVIDEO, | ||
819 | .vmux = 2, | ||
820 | .gpio0 = 0x03000000, | ||
821 | .gpio1 = 0x01000000, | ||
822 | .gpio2 = 0x02000000, | ||
823 | .gpio3 = 0x00100000, | ||
824 | }}, | ||
825 | }, | ||
826 | [CX88_BOARD_ATI_HDTVWONDER] = { | ||
827 | .name = "ATI HDTV Wonder", | ||
828 | .tuner_type = TUNER_PHILIPS_TUV1236D, | ||
829 | .radio_type = UNSET, | ||
830 | .tuner_addr = ADDR_UNSET, | ||
831 | .radio_addr = ADDR_UNSET, | ||
832 | .input = {{ | ||
833 | .type = CX88_VMUX_TELEVISION, | ||
834 | .vmux = 0, | ||
835 | .gpio0 = 0x00000ff7, | ||
836 | .gpio1 = 0x000000ff, | ||
837 | .gpio2 = 0x00000001, | ||
838 | .gpio3 = 0x00000000, | ||
839 | },{ | ||
840 | .type = CX88_VMUX_COMPOSITE1, | ||
841 | .vmux = 1, | ||
842 | .gpio0 = 0x00000ffe, | ||
843 | .gpio1 = 0x000000ff, | ||
844 | .gpio2 = 0x00000001, | ||
845 | .gpio3 = 0x00000000, | ||
846 | },{ | ||
847 | .type = CX88_VMUX_SVIDEO, | ||
848 | .vmux = 2, | ||
849 | .gpio0 = 0x00000ffe, | ||
850 | .gpio1 = 0x000000ff, | ||
851 | .gpio2 = 0x00000001, | ||
852 | .gpio3 = 0x00000000, | ||
853 | }}, | ||
777 | .dvb = 1, | 854 | .dvb = 1, |
778 | }, | 855 | }, |
856 | [CX88_BOARD_WINFAST_DTV1000] = { | ||
857 | .name = "WinFast DTV1000-T", | ||
858 | .tuner_type = TUNER_ABSENT, | ||
859 | .radio_type = UNSET, | ||
860 | .tuner_addr = ADDR_UNSET, | ||
861 | .radio_addr = ADDR_UNSET, | ||
862 | .input = {{ | ||
863 | .type = CX88_VMUX_DVB, | ||
864 | .vmux = 0, | ||
865 | }}, | ||
866 | .dvb = 1, | ||
867 | }, | ||
868 | [CX88_BOARD_AVERTV_303] = { | ||
869 | .name = "AVerTV 303 (M126)", | ||
870 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
871 | .radio_type = UNSET, | ||
872 | .tuner_addr = ADDR_UNSET, | ||
873 | .radio_addr = ADDR_UNSET, | ||
874 | .tda9887_conf = TDA9887_PRESENT, | ||
875 | .input = {{ | ||
876 | .type = CX88_VMUX_TELEVISION, | ||
877 | .vmux = 0, | ||
878 | .gpio0 = 0x00ff, | ||
879 | .gpio1 = 0xe09f, | ||
880 | .gpio2 = 0x0010, | ||
881 | .gpio3 = 0x0000, | ||
882 | },{ | ||
883 | .type = CX88_VMUX_COMPOSITE1, | ||
884 | .vmux = 1, | ||
885 | .gpio0 = 0x00ff, | ||
886 | .gpio1 = 0xe05f, | ||
887 | .gpio2 = 0x0010, | ||
888 | .gpio3 = 0x0000, | ||
889 | },{ | ||
890 | .type = CX88_VMUX_SVIDEO, | ||
891 | .vmux = 2, | ||
892 | .gpio0 = 0x00ff, | ||
893 | .gpio1 = 0xe05f, | ||
894 | .gpio2 = 0x0010, | ||
895 | .gpio3 = 0x0000, | ||
896 | }}, | ||
897 | }, | ||
779 | }; | 898 | }; |
780 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); | 899 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); |
781 | 900 | ||
@@ -804,41 +923,41 @@ struct cx88_subid cx88_subids[] = { | |||
804 | .subdevice = 0x00f8, | 923 | .subdevice = 0x00f8, |
805 | .card = CX88_BOARD_ATI_WONDER_PRO, | 924 | .card = CX88_BOARD_ATI_WONDER_PRO, |
806 | },{ | 925 | },{ |
807 | .subvendor = 0x107d, | 926 | .subvendor = 0x107d, |
808 | .subdevice = 0x6611, | 927 | .subdevice = 0x6611, |
809 | .card = CX88_BOARD_WINFAST2000XP_EXPERT, | 928 | .card = CX88_BOARD_WINFAST2000XP_EXPERT, |
929 | },{ | ||
930 | .subvendor = 0x107d, | ||
931 | .subdevice = 0x6613, /* NTSC */ | ||
932 | .card = CX88_BOARD_WINFAST2000XP_EXPERT, | ||
810 | },{ | 933 | },{ |
811 | .subvendor = 0x107d, | 934 | .subvendor = 0x107d, |
812 | .subdevice = 0x6613, /* NTSC */ | 935 | .subdevice = 0x6620, |
813 | .card = CX88_BOARD_WINFAST2000XP_EXPERT, | 936 | .card = CX88_BOARD_WINFAST_DV2000, |
937 | },{ | ||
938 | .subvendor = 0x107d, | ||
939 | .subdevice = 0x663b, | ||
940 | .card = CX88_BOARD_LEADTEK_PVR2000, | ||
814 | },{ | 941 | },{ |
815 | .subvendor = 0x107d, | 942 | .subvendor = 0x107d, |
816 | .subdevice = 0x6620, | 943 | .subdevice = 0x663C, |
817 | .card = CX88_BOARD_WINFAST_DV2000, | 944 | .card = CX88_BOARD_LEADTEK_PVR2000, |
818 | },{ | 945 | },{ |
819 | .subvendor = 0x107d, | ||
820 | .subdevice = 0x663b, | ||
821 | .card = CX88_BOARD_LEADTEK_PVR2000, | ||
822 | },{ | ||
823 | .subvendor = 0x107d, | ||
824 | .subdevice = 0x663C, | ||
825 | .card = CX88_BOARD_LEADTEK_PVR2000, | ||
826 | },{ | ||
827 | .subvendor = 0x1461, | 946 | .subvendor = 0x1461, |
828 | .subdevice = 0x000b, | 947 | .subdevice = 0x000b, |
829 | .card = CX88_BOARD_AVERTV_303, | 948 | .card = CX88_BOARD_AVERTV_STUDIO_303, |
830 | },{ | 949 | },{ |
831 | .subvendor = 0x1462, | 950 | .subvendor = 0x1462, |
832 | .subdevice = 0x8606, | 951 | .subdevice = 0x8606, |
833 | .card = CX88_BOARD_MSI_TVANYWHERE_MASTER, | 952 | .card = CX88_BOARD_MSI_TVANYWHERE_MASTER, |
834 | },{ | 953 | },{ |
835 | .subvendor = 0x10fc, | 954 | .subvendor = 0x10fc, |
836 | .subdevice = 0xd003, | 955 | .subdevice = 0xd003, |
837 | .card = CX88_BOARD_IODATA_GVVCP3PCI, | 956 | .card = CX88_BOARD_IODATA_GVVCP3PCI, |
838 | },{ | 957 | },{ |
839 | .subvendor = 0x1043, | 958 | .subvendor = 0x1043, |
840 | .subdevice = 0x4823, /* with mpeg encoder */ | 959 | .subdevice = 0x4823, /* with mpeg encoder */ |
841 | .card = CX88_BOARD_ASUS_PVR_416, | 960 | .card = CX88_BOARD_ASUS_PVR_416, |
842 | },{ | 961 | },{ |
843 | .subvendor = 0x17de, | 962 | .subvendor = 0x17de, |
844 | .subdevice = 0x08a6, | 963 | .subdevice = 0x08a6, |
@@ -852,43 +971,43 @@ struct cx88_subid cx88_subids[] = { | |||
852 | .subdevice = 0xd820, | 971 | .subdevice = 0xd820, |
853 | .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T, | 972 | .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T, |
854 | },{ | 973 | },{ |
855 | .subvendor = 0x18AC, | 974 | .subvendor = 0x18ac, |
856 | .subdevice = 0xDB00, | 975 | .subdevice = 0xdb00, |
857 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1, | 976 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1, |
858 | },{ | 977 | },{ |
859 | .subvendor = 0x0070, | 978 | .subvendor = 0x0070, |
860 | .subdevice = 0x9002, | 979 | .subdevice = 0x9002, |
861 | .card = CX88_BOARD_HAUPPAUGE_DVB_T1, | 980 | .card = CX88_BOARD_HAUPPAUGE_DVB_T1, |
862 | },{ | 981 | },{ |
863 | .subvendor = 0x14f1, | 982 | .subvendor = 0x14f1, |
864 | .subdevice = 0x0187, | 983 | .subdevice = 0x0187, |
865 | .card = CX88_BOARD_CONEXANT_DVB_T1, | 984 | .card = CX88_BOARD_CONEXANT_DVB_T1, |
866 | },{ | 985 | },{ |
867 | .subvendor = 0x1540, | 986 | .subvendor = 0x1540, |
868 | .subdevice = 0x2580, | 987 | .subdevice = 0x2580, |
869 | .card = CX88_BOARD_PROVIDEO_PV259, | 988 | .card = CX88_BOARD_PROVIDEO_PV259, |
870 | },{ | 989 | },{ |
871 | .subvendor = 0x18AC, | 990 | .subvendor = 0x18ac, |
872 | .subdevice = 0xDB10, | 991 | .subdevice = 0xdb10, |
873 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, | 992 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, |
874 | },{ | 993 | },{ |
875 | .subvendor = 0x1554, | 994 | .subvendor = 0x1554, |
876 | .subdevice = 0x4811, | 995 | .subdevice = 0x4811, |
877 | .card = CX88_BOARD_PIXELVIEW, | 996 | .card = CX88_BOARD_PIXELVIEW, |
878 | },{ | 997 | },{ |
879 | .subvendor = 0x7063, | 998 | .subvendor = 0x7063, |
880 | .subdevice = 0x3000, /* HD-3000 card */ | 999 | .subdevice = 0x3000, /* HD-3000 card */ |
881 | .card = CX88_BOARD_PCHDTV_HD3000, | 1000 | .card = CX88_BOARD_PCHDTV_HD3000, |
882 | },{ | 1001 | },{ |
883 | .subvendor = 0x17DE, | 1002 | .subvendor = 0x17de, |
884 | .subdevice = 0xA8A6, | 1003 | .subdevice = 0xa8a6, |
885 | .card = CX88_BOARD_DNTV_LIVE_DVB_T, | 1004 | .card = CX88_BOARD_DNTV_LIVE_DVB_T, |
886 | },{ | 1005 | },{ |
887 | .subvendor = 0x0070, | 1006 | .subvendor = 0x0070, |
888 | .subdevice = 0x2801, | 1007 | .subdevice = 0x2801, |
889 | .card = CX88_BOARD_HAUPPAUGE_ROSLYN, | 1008 | .card = CX88_BOARD_HAUPPAUGE_ROSLYN, |
890 | },{ | 1009 | },{ |
891 | .subvendor = 0x14F1, | 1010 | .subvendor = 0x14f1, |
892 | .subdevice = 0x0342, | 1011 | .subdevice = 0x0342, |
893 | .card = CX88_BOARD_DIGITALLOGIC_MEC, | 1012 | .card = CX88_BOARD_DIGITALLOGIC_MEC, |
894 | },{ | 1013 | },{ |
@@ -899,14 +1018,30 @@ struct cx88_subid cx88_subids[] = { | |||
899 | .subvendor = 0x1421, | 1018 | .subvendor = 0x1421, |
900 | .subdevice = 0x0334, | 1019 | .subdevice = 0x0334, |
901 | .card = CX88_BOARD_ADSTECH_DVB_T_PCI, | 1020 | .card = CX88_BOARD_ADSTECH_DVB_T_PCI, |
902 | },{ | 1021 | },{ |
903 | .subvendor = 0x153b, | 1022 | .subvendor = 0x153b, |
904 | .subdevice = 0x1166, | 1023 | .subdevice = 0x1166, |
905 | .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1, | 1024 | .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1, |
906 | },{ | 1025 | },{ |
907 | .subvendor = 0x18ac, | 1026 | .subvendor = 0x18ac, |
908 | .subdevice = 0xd500, | 1027 | .subdevice = 0xd500, |
909 | .card = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD, | 1028 | .card = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD, |
1029 | },{ | ||
1030 | .subvendor = 0x1461, | ||
1031 | .subdevice = 0x8011, | ||
1032 | .card = CX88_BOARD_AVERMEDIA_ULTRATV_MC_550, | ||
1033 | },{ | ||
1034 | .subvendor = PCI_VENDOR_ID_ATI, | ||
1035 | .subdevice = 0xa101, | ||
1036 | .card = CX88_BOARD_ATI_HDTVWONDER, | ||
1037 | },{ | ||
1038 | .subvendor = 0x107d, | ||
1039 | .subdevice = 0x665f, | ||
1040 | .card = CX88_BOARD_WINFAST_DTV1000, | ||
1041 | },{ | ||
1042 | .subvendor = 0x1461, | ||
1043 | .subdevice = 0x000a, | ||
1044 | .card = CX88_BOARD_AVERTV_303, | ||
910 | }, | 1045 | }, |
911 | }; | 1046 | }; |
912 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); | 1047 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); |
@@ -1108,6 +1243,19 @@ void cx88_card_setup(struct cx88_core *core) | |||
1108 | cx_clear(MO_GP0_IO, 0x00000007); | 1243 | cx_clear(MO_GP0_IO, 0x00000007); |
1109 | cx_set(MO_GP2_IO, 0x00000101); | 1244 | cx_set(MO_GP2_IO, 0x00000101); |
1110 | break; | 1245 | break; |
1246 | case CX88_BOARD_ATI_HDTVWONDER: | ||
1247 | if (0 == core->i2c_rc) { | ||
1248 | /* enable tuner */ | ||
1249 | int i; | ||
1250 | u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 }; | ||
1251 | core->i2c_client.addr = 0x0a; | ||
1252 | |||
1253 | for (i = 0; i < 5; i++) | ||
1254 | if (2 != i2c_master_send(&core->i2c_client,&buffer[i*2],2)) | ||
1255 | printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n", | ||
1256 | core->name, i); | ||
1257 | } | ||
1258 | break; | ||
1111 | } | 1259 | } |
1112 | if (cx88_boards[core->board].radio.type == CX88_RADIO) | 1260 | if (cx88_boards[core->board].radio.type == CX88_RADIO) |
1113 | core->has_radio = 1; | 1261 | core->has_radio = 1; |
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index dc5c5c1f3461..eb806af17182 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
34 | #include <linux/videodev.h> | 34 | #include <linux/videodev2.h> |
35 | 35 | ||
36 | #include "cx88.h" | 36 | #include "cx88.h" |
37 | 37 | ||
@@ -153,26 +153,26 @@ static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist, | |||
153 | } | 153 | } |
154 | if (bpl <= sg_dma_len(sg)-offset) { | 154 | if (bpl <= sg_dma_len(sg)-offset) { |
155 | /* fits into current chunk */ | 155 | /* fits into current chunk */ |
156 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); | 156 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); |
157 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); | 157 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); |
158 | offset+=bpl; | 158 | offset+=bpl; |
159 | } else { | 159 | } else { |
160 | /* scanline needs to be splitted */ | 160 | /* scanline needs to be splitted */ |
161 | todo = bpl; | 161 | todo = bpl; |
162 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL| | 162 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL| |
163 | (sg_dma_len(sg)-offset)); | 163 | (sg_dma_len(sg)-offset)); |
164 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); | 164 | *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); |
165 | todo -= (sg_dma_len(sg)-offset); | 165 | todo -= (sg_dma_len(sg)-offset); |
166 | offset = 0; | 166 | offset = 0; |
167 | sg++; | 167 | sg++; |
168 | while (todo > sg_dma_len(sg)) { | 168 | while (todo > sg_dma_len(sg)) { |
169 | *(rp++)=cpu_to_le32(RISC_WRITE| | 169 | *(rp++)=cpu_to_le32(RISC_WRITE| |
170 | sg_dma_len(sg)); | 170 | sg_dma_len(sg)); |
171 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); | 171 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); |
172 | todo -= sg_dma_len(sg); | 172 | todo -= sg_dma_len(sg); |
173 | sg++; | 173 | sg++; |
174 | } | 174 | } |
175 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo); | 175 | *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo); |
176 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); | 176 | *(rp++)=cpu_to_le32(sg_dma_address(sg)); |
177 | offset += todo; | 177 | offset += todo; |
178 | } | 178 | } |
@@ -309,7 +309,7 @@ struct sram_channel cx88_sram_channels[] = { | |||
309 | .name = "video y / packed", | 309 | .name = "video y / packed", |
310 | .cmds_start = 0x180040, | 310 | .cmds_start = 0x180040, |
311 | .ctrl_start = 0x180400, | 311 | .ctrl_start = 0x180400, |
312 | .cdt = 0x180400 + 64, | 312 | .cdt = 0x180400 + 64, |
313 | .fifo_start = 0x180c00, | 313 | .fifo_start = 0x180c00, |
314 | .fifo_size = 0x002800, | 314 | .fifo_size = 0x002800, |
315 | .ptr1_reg = MO_DMA21_PTR1, | 315 | .ptr1_reg = MO_DMA21_PTR1, |
@@ -321,7 +321,7 @@ struct sram_channel cx88_sram_channels[] = { | |||
321 | .name = "video u", | 321 | .name = "video u", |
322 | .cmds_start = 0x180080, | 322 | .cmds_start = 0x180080, |
323 | .ctrl_start = 0x1804a0, | 323 | .ctrl_start = 0x1804a0, |
324 | .cdt = 0x1804a0 + 64, | 324 | .cdt = 0x1804a0 + 64, |
325 | .fifo_start = 0x183400, | 325 | .fifo_start = 0x183400, |
326 | .fifo_size = 0x000800, | 326 | .fifo_size = 0x000800, |
327 | .ptr1_reg = MO_DMA22_PTR1, | 327 | .ptr1_reg = MO_DMA22_PTR1, |
@@ -333,7 +333,7 @@ struct sram_channel cx88_sram_channels[] = { | |||
333 | .name = "video v", | 333 | .name = "video v", |
334 | .cmds_start = 0x1800c0, | 334 | .cmds_start = 0x1800c0, |
335 | .ctrl_start = 0x180540, | 335 | .ctrl_start = 0x180540, |
336 | .cdt = 0x180540 + 64, | 336 | .cdt = 0x180540 + 64, |
337 | .fifo_start = 0x183c00, | 337 | .fifo_start = 0x183c00, |
338 | .fifo_size = 0x000800, | 338 | .fifo_size = 0x000800, |
339 | .ptr1_reg = MO_DMA23_PTR1, | 339 | .ptr1_reg = MO_DMA23_PTR1, |
@@ -345,7 +345,7 @@ struct sram_channel cx88_sram_channels[] = { | |||
345 | .name = "vbi", | 345 | .name = "vbi", |
346 | .cmds_start = 0x180100, | 346 | .cmds_start = 0x180100, |
347 | .ctrl_start = 0x1805e0, | 347 | .ctrl_start = 0x1805e0, |
348 | .cdt = 0x1805e0 + 64, | 348 | .cdt = 0x1805e0 + 64, |
349 | .fifo_start = 0x184400, | 349 | .fifo_start = 0x184400, |
350 | .fifo_size = 0x001000, | 350 | .fifo_size = 0x001000, |
351 | .ptr1_reg = MO_DMA24_PTR1, | 351 | .ptr1_reg = MO_DMA24_PTR1, |
@@ -357,7 +357,7 @@ struct sram_channel cx88_sram_channels[] = { | |||
357 | .name = "audio from", | 357 | .name = "audio from", |
358 | .cmds_start = 0x180140, | 358 | .cmds_start = 0x180140, |
359 | .ctrl_start = 0x180680, | 359 | .ctrl_start = 0x180680, |
360 | .cdt = 0x180680 + 64, | 360 | .cdt = 0x180680 + 64, |
361 | .fifo_start = 0x185400, | 361 | .fifo_start = 0x185400, |
362 | .fifo_size = 0x000200, | 362 | .fifo_size = 0x000200, |
363 | .ptr1_reg = MO_DMA25_PTR1, | 363 | .ptr1_reg = MO_DMA25_PTR1, |
@@ -369,7 +369,7 @@ struct sram_channel cx88_sram_channels[] = { | |||
369 | .name = "audio to", | 369 | .name = "audio to", |
370 | .cmds_start = 0x180180, | 370 | .cmds_start = 0x180180, |
371 | .ctrl_start = 0x180720, | 371 | .ctrl_start = 0x180720, |
372 | .cdt = 0x180680 + 64, /* same as audio IN */ | 372 | .cdt = 0x180680 + 64, /* same as audio IN */ |
373 | .fifo_start = 0x185400, /* same as audio IN */ | 373 | .fifo_start = 0x185400, /* same as audio IN */ |
374 | .fifo_size = 0x000200, /* same as audio IN */ | 374 | .fifo_size = 0x000200, /* same as audio IN */ |
375 | .ptr1_reg = MO_DMA26_PTR1, | 375 | .ptr1_reg = MO_DMA26_PTR1, |
@@ -431,7 +431,7 @@ int cx88_sram_channel_setup(struct cx88_core *core, | |||
431 | /* ------------------------------------------------------------------ */ | 431 | /* ------------------------------------------------------------------ */ |
432 | /* debug helper code */ | 432 | /* debug helper code */ |
433 | 433 | ||
434 | int cx88_risc_decode(u32 risc) | 434 | static int cx88_risc_decode(u32 risc) |
435 | { | 435 | { |
436 | static char *instr[16] = { | 436 | static char *instr[16] = { |
437 | [ RISC_SYNC >> 28 ] = "sync", | 437 | [ RISC_SYNC >> 28 ] = "sync", |
@@ -845,19 +845,19 @@ static int set_tvaudio(struct cx88_core *core) | |||
845 | return 0; | 845 | return 0; |
846 | 846 | ||
847 | if (V4L2_STD_PAL_BG & norm->id) { | 847 | if (V4L2_STD_PAL_BG & norm->id) { |
848 | core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_BG; | 848 | core->tvaudio = WW_BG; |
849 | 849 | ||
850 | } else if (V4L2_STD_PAL_DK & norm->id) { | 850 | } else if (V4L2_STD_PAL_DK & norm->id) { |
851 | core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_DK; | 851 | core->tvaudio = WW_DK; |
852 | 852 | ||
853 | } else if (V4L2_STD_PAL_I & norm->id) { | 853 | } else if (V4L2_STD_PAL_I & norm->id) { |
854 | core->tvaudio = WW_NICAM_I; | 854 | core->tvaudio = WW_I; |
855 | 855 | ||
856 | } else if (V4L2_STD_SECAM_L & norm->id) { | 856 | } else if (V4L2_STD_SECAM_L & norm->id) { |
857 | core->tvaudio = WW_SYSTEM_L_AM; | 857 | core->tvaudio = WW_L; |
858 | 858 | ||
859 | } else if (V4L2_STD_SECAM_DK & norm->id) { | 859 | } else if (V4L2_STD_SECAM_DK & norm->id) { |
860 | core->tvaudio = WW_A2_DK; | 860 | core->tvaudio = WW_DK; |
861 | 861 | ||
862 | } else if ((V4L2_STD_NTSC_M & norm->id) || | 862 | } else if ((V4L2_STD_NTSC_M & norm->id) || |
863 | (V4L2_STD_PAL_M & norm->id)) { | 863 | (V4L2_STD_PAL_M & norm->id)) { |
@@ -1137,7 +1137,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci) | |||
1137 | if (!core->radio_addr) | 1137 | if (!core->radio_addr) |
1138 | core->radio_addr = cx88_boards[core->board].radio_addr; | 1138 | core->radio_addr = cx88_boards[core->board].radio_addr; |
1139 | 1139 | ||
1140 | printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n", | 1140 | printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n", |
1141 | core->tuner_type, core->tuner_addr<<1, | 1141 | core->tuner_type, core->tuner_addr<<1, |
1142 | core->radio_type, core->radio_addr<<1); | 1142 | core->radio_type, core->radio_addr<<1); |
1143 | 1143 | ||
@@ -1146,6 +1146,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci) | |||
1146 | /* init hardware */ | 1146 | /* init hardware */ |
1147 | cx88_reset(core); | 1147 | cx88_reset(core); |
1148 | cx88_i2c_init(core,pci); | 1148 | cx88_i2c_init(core,pci); |
1149 | cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL); | ||
1149 | cx88_card_setup(core); | 1150 | cx88_card_setup(core); |
1150 | cx88_ir_init(core,pci); | 1151 | cx88_ir_init(core,pci); |
1151 | 1152 | ||
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 4334744652de..9cce91ec334b 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/file.h> | 29 | #include <linux/file.h> |
30 | #include <linux/suspend.h> | 30 | #include <linux/suspend.h> |
31 | 31 | ||
32 | |||
33 | #include "cx88.h" | 32 | #include "cx88.h" |
34 | #include "dvb-pll.h" | 33 | #include "dvb-pll.h" |
35 | 34 | ||
@@ -46,6 +45,9 @@ | |||
46 | #ifdef HAVE_LGDT330X | 45 | #ifdef HAVE_LGDT330X |
47 | # include "lgdt330x.h" | 46 | # include "lgdt330x.h" |
48 | #endif | 47 | #endif |
48 | #ifdef HAVE_NXT200X | ||
49 | # include "nxt200x.h" | ||
50 | #endif | ||
49 | 51 | ||
50 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); | 52 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); |
51 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); | 53 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); |
@@ -78,7 +80,7 @@ static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
78 | enum v4l2_field field) | 80 | enum v4l2_field field) |
79 | { | 81 | { |
80 | struct cx8802_dev *dev = q->priv_data; | 82 | struct cx8802_dev *dev = q->priv_data; |
81 | return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb); | 83 | return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb,field); |
82 | } | 84 | } |
83 | 85 | ||
84 | static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | 86 | static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) |
@@ -129,7 +131,7 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) | |||
129 | static u8 reset [] = { 0x50, 0x80 }; | 131 | static u8 reset [] = { 0x50, 0x80 }; |
130 | static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | 132 | static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; |
131 | static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, | 133 | static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, |
132 | 0x00, 0xFF, 0x00, 0x40, 0x40 }; | 134 | 0x00, 0xFF, 0x00, 0x40, 0x40 }; |
133 | static u8 dntv_extra[] = { 0xB5, 0x7A }; | 135 | static u8 dntv_extra[] = { 0xB5, 0x7A }; |
134 | static u8 capt_range_cfg[] = { 0x75, 0x32 }; | 136 | static u8 capt_range_cfg[] = { 0x75, 0x32 }; |
135 | 137 | ||
@@ -285,6 +287,33 @@ static struct lgdt330x_config fusionhdtv_5_gold = { | |||
285 | }; | 287 | }; |
286 | #endif | 288 | #endif |
287 | 289 | ||
290 | #ifdef HAVE_NXT200X | ||
291 | static int nxt200x_set_ts_param(struct dvb_frontend* fe, | ||
292 | int is_punctured) | ||
293 | { | ||
294 | struct cx8802_dev *dev= fe->dvb->priv; | ||
295 | dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static int nxt200x_set_pll_input(u8* buf, int input) | ||
300 | { | ||
301 | if (input) | ||
302 | buf[3] |= 0x08; | ||
303 | else | ||
304 | buf[3] &= ~0x08; | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | static struct nxt200x_config ati_hdtvwonder = { | ||
309 | .demod_address = 0x0a, | ||
310 | .pll_address = 0x61, | ||
311 | .pll_desc = &dvb_pll_tuv1236d, | ||
312 | .set_pll_input = nxt200x_set_pll_input, | ||
313 | .set_ts_params = nxt200x_set_ts_param, | ||
314 | }; | ||
315 | #endif | ||
316 | |||
288 | static int dvb_register(struct cx8802_dev *dev) | 317 | static int dvb_register(struct cx8802_dev *dev) |
289 | { | 318 | { |
290 | /* init struct videobuf_dvb */ | 319 | /* init struct videobuf_dvb */ |
@@ -300,6 +329,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
300 | break; | 329 | break; |
301 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: | 330 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: |
302 | case CX88_BOARD_CONEXANT_DVB_T1: | 331 | case CX88_BOARD_CONEXANT_DVB_T1: |
332 | case CX88_BOARD_WINFAST_DTV1000: | ||
303 | dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, | 333 | dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, |
304 | &dev->core->i2c_adap); | 334 | &dev->core->i2c_adap); |
305 | break; | 335 | break; |
@@ -385,6 +415,12 @@ static int dvb_register(struct cx8802_dev *dev) | |||
385 | } | 415 | } |
386 | break; | 416 | break; |
387 | #endif | 417 | #endif |
418 | #ifdef HAVE_NXT200X | ||
419 | case CX88_BOARD_ATI_HDTVWONDER: | ||
420 | dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder, | ||
421 | &dev->core->i2c_adap); | ||
422 | break; | ||
423 | #endif | ||
388 | default: | 424 | default: |
389 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", | 425 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", |
390 | dev->core->name); | 426 | dev->core->name); |
@@ -403,6 +439,9 @@ static int dvb_register(struct cx8802_dev *dev) | |||
403 | /* Put the analog decoder in standby to keep it quiet */ | 439 | /* Put the analog decoder in standby to keep it quiet */ |
404 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); | 440 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); |
405 | 441 | ||
442 | /* Put the analog decoder in standby to keep it quiet */ | ||
443 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); | ||
444 | |||
406 | /* register everything */ | 445 | /* register everything */ |
407 | return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); | 446 | return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); |
408 | } | 447 | } |
@@ -461,7 +500,7 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev, | |||
461 | 500 | ||
462 | static void __devexit dvb_remove(struct pci_dev *pci_dev) | 501 | static void __devexit dvb_remove(struct pci_dev *pci_dev) |
463 | { | 502 | { |
464 | struct cx8802_dev *dev = pci_get_drvdata(pci_dev); | 503 | struct cx8802_dev *dev = pci_get_drvdata(pci_dev); |
465 | 504 | ||
466 | /* dvb */ | 505 | /* dvb */ |
467 | videobuf_dvb_unregister(&dev->dvb); | 506 | videobuf_dvb_unregister(&dev->dvb); |
@@ -476,8 +515,8 @@ static struct pci_device_id cx8802_pci_tbl[] = { | |||
476 | { | 515 | { |
477 | .vendor = 0x14f1, | 516 | .vendor = 0x14f1, |
478 | .device = 0x8802, | 517 | .device = 0x8802, |
479 | .subvendor = PCI_ANY_ID, | 518 | .subvendor = PCI_ANY_ID, |
480 | .subdevice = PCI_ANY_ID, | 519 | .subdevice = PCI_ANY_ID, |
481 | },{ | 520 | },{ |
482 | /* --- end of list --- */ | 521 | /* --- end of list --- */ |
483 | } | 522 | } |
@@ -485,10 +524,10 @@ static struct pci_device_id cx8802_pci_tbl[] = { | |||
485 | MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); | 524 | MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); |
486 | 525 | ||
487 | static struct pci_driver dvb_pci_driver = { | 526 | static struct pci_driver dvb_pci_driver = { |
488 | .name = "cx88-dvb", | 527 | .name = "cx88-dvb", |
489 | .id_table = cx8802_pci_tbl, | 528 | .id_table = cx8802_pci_tbl, |
490 | .probe = dvb_probe, | 529 | .probe = dvb_probe, |
491 | .remove = __devexit_p(dvb_remove), | 530 | .remove = __devexit_p(dvb_remove), |
492 | .suspend = cx8802_suspend_common, | 531 | .suspend = cx8802_suspend_common, |
493 | .resume = cx8802_resume_common, | 532 | .resume = cx8802_resume_common, |
494 | }; | 533 | }; |
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index 761cebd40dbd..9790d412f192 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c | |||
@@ -3,7 +3,7 @@ | |||
3 | cx88-i2c.c -- all the i2c code is here | 3 | cx88-i2c.c -- all the i2c code is here |
4 | 4 | ||
5 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) | 5 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) |
6 | & Marcus Metzler (mocm@thp.uni-koeln.de) | 6 | & Marcus Metzler (mocm@thp.uni-koeln.de) |
7 | (c) 2002 Yurij Sysoev <yurij@naturesoft.net> | 7 | (c) 2002 Yurij Sysoev <yurij@naturesoft.net> |
8 | (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> | 8 | (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> |
9 | 9 | ||
@@ -90,7 +90,7 @@ static int cx8800_bit_getsda(void *data) | |||
90 | 90 | ||
91 | static int attach_inform(struct i2c_client *client) | 91 | static int attach_inform(struct i2c_client *client) |
92 | { | 92 | { |
93 | struct tuner_setup tun_setup; | 93 | struct tuner_setup tun_setup; |
94 | struct cx88_core *core = i2c_get_adapdata(client->adapter); | 94 | struct cx88_core *core = i2c_get_adapdata(client->adapter); |
95 | 95 | ||
96 | dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", | 96 | dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", |
@@ -98,7 +98,7 @@ static int attach_inform(struct i2c_client *client) | |||
98 | if (!client->driver->command) | 98 | if (!client->driver->command) |
99 | return 0; | 99 | return 0; |
100 | 100 | ||
101 | if (core->radio_type != UNSET) { | 101 | if (core->radio_type != UNSET) { |
102 | if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) { | 102 | if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) { |
103 | tun_setup.mode_mask = T_RADIO; | 103 | tun_setup.mode_mask = T_RADIO; |
104 | tun_setup.type = core->radio_type; | 104 | tun_setup.type = core->radio_type; |
@@ -106,8 +106,8 @@ static int attach_inform(struct i2c_client *client) | |||
106 | 106 | ||
107 | client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup); | 107 | client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup); |
108 | } | 108 | } |
109 | } | 109 | } |
110 | if (core->tuner_type != UNSET) { | 110 | if (core->tuner_type != UNSET) { |
111 | if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) { | 111 | if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) { |
112 | 112 | ||
113 | tun_setup.mode_mask = T_ANALOG_TV; | 113 | tun_setup.mode_mask = T_ANALOG_TV; |
@@ -116,7 +116,7 @@ static int attach_inform(struct i2c_client *client) | |||
116 | 116 | ||
117 | client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup); | 117 | client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup); |
118 | } | 118 | } |
119 | } | 119 | } |
120 | 120 | ||
121 | if (core->tda9887_conf) | 121 | if (core->tda9887_conf) |
122 | client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf); | 122 | client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf); |
@@ -159,7 +159,7 @@ static struct i2c_adapter cx8800_i2c_adap_template = { | |||
159 | }; | 159 | }; |
160 | 160 | ||
161 | static struct i2c_client cx8800_i2c_client_template = { | 161 | static struct i2c_client cx8800_i2c_client_template = { |
162 | .name = "cx88xx internal", | 162 | .name = "cx88xx internal", |
163 | }; | 163 | }; |
164 | 164 | ||
165 | static char *i2c_devs[128] = { | 165 | static char *i2c_devs[128] = { |
@@ -202,10 +202,10 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) | |||
202 | 202 | ||
203 | core->i2c_adap.dev.parent = &pci->dev; | 203 | core->i2c_adap.dev.parent = &pci->dev; |
204 | strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); | 204 | strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); |
205 | core->i2c_algo.data = core; | 205 | core->i2c_algo.data = core; |
206 | i2c_set_adapdata(&core->i2c_adap,core); | 206 | i2c_set_adapdata(&core->i2c_adap,core); |
207 | core->i2c_adap.algo_data = &core->i2c_algo; | 207 | core->i2c_adap.algo_data = &core->i2c_algo; |
208 | core->i2c_client.adapter = &core->i2c_adap; | 208 | core->i2c_client.adapter = &core->i2c_adap; |
209 | 209 | ||
210 | cx8800_bit_setscl(core,1); | 210 | cx8800_bit_setscl(core,1); |
211 | cx8800_bit_setsda(core,1); | 211 | cx8800_bit_setsda(core,1); |
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index c27fe4c36f69..38b12ebaa49e 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -553,7 +553,7 @@ void cx88_ir_irq(struct cx88_core *core) | |||
553 | 553 | ||
554 | if ((ircode & 0xffff) != 0xeb04) { /* wrong address */ | 554 | if ((ircode & 0xffff) != 0xeb04) { /* wrong address */ |
555 | ir_dprintk("pulse distance decoded wrong address\n"); | 555 | ir_dprintk("pulse distance decoded wrong address\n"); |
556 | break; | 556 | break; |
557 | } | 557 | } |
558 | 558 | ||
559 | if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */ | 559 | if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */ |
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index ee2300e1ae0b..35e6d0c2b872 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -54,7 +54,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev, | |||
54 | { | 54 | { |
55 | struct cx88_core *core = dev->core; | 55 | struct cx88_core *core = dev->core; |
56 | 56 | ||
57 | dprintk(0, "cx8802_start_dma %d\n", buf->vb.width); | 57 | dprintk(0, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field); |
58 | 58 | ||
59 | /* setup fifo + format */ | 59 | /* setup fifo + format */ |
60 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], | 60 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], |
@@ -158,7 +158,8 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, | |||
158 | 158 | ||
159 | /* ------------------------------------------------------------------ */ | 159 | /* ------------------------------------------------------------------ */ |
160 | 160 | ||
161 | int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf) | 161 | int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf, |
162 | enum v4l2_field field) | ||
162 | { | 163 | { |
163 | int size = dev->ts_packet_size * dev->ts_packet_count; | 164 | int size = dev->ts_packet_size * dev->ts_packet_count; |
164 | int rc; | 165 | int rc; |
@@ -171,7 +172,7 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf) | |||
171 | buf->vb.width = dev->ts_packet_size; | 172 | buf->vb.width = dev->ts_packet_size; |
172 | buf->vb.height = dev->ts_packet_count; | 173 | buf->vb.height = dev->ts_packet_count; |
173 | buf->vb.size = size; | 174 | buf->vb.size = size; |
174 | buf->vb.field = V4L2_FIELD_TOP; | 175 | buf->vb.field = field /*V4L2_FIELD_TOP*/; |
175 | 176 | ||
176 | if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL))) | 177 | if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL))) |
177 | goto fail; | 178 | goto fail; |
@@ -315,14 +316,14 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) | |||
315 | spin_unlock(&dev->slock); | 316 | spin_unlock(&dev->slock); |
316 | } | 317 | } |
317 | 318 | ||
318 | /* other general errors */ | 319 | /* other general errors */ |
319 | if (status & 0x1f0100) { | 320 | if (status & 0x1f0100) { |
320 | dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 ); | 321 | dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 ); |
321 | spin_lock(&dev->slock); | 322 | spin_lock(&dev->slock); |
322 | cx8802_stop_dma(dev); | 323 | cx8802_stop_dma(dev); |
323 | cx8802_restart_queue(dev,&dev->mpegq); | 324 | cx8802_restart_queue(dev,&dev->mpegq); |
324 | spin_unlock(&dev->slock); | 325 | spin_unlock(&dev->slock); |
325 | } | 326 | } |
326 | } | 327 | } |
327 | 328 | ||
328 | #define MAX_IRQ_LOOP 10 | 329 | #define MAX_IRQ_LOOP 10 |
@@ -378,8 +379,8 @@ int cx8802_init_common(struct cx8802_dev *dev) | |||
378 | } | 379 | } |
379 | 380 | ||
380 | pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); | 381 | pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); |
381 | pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); | 382 | pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); |
382 | printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " | 383 | printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " |
383 | "latency: %d, mmio: 0x%lx\n", dev->core->name, | 384 | "latency: %d, mmio: 0x%lx\n", dev->core->name, |
384 | pci_name(dev->pci), dev->pci_rev, dev->pci->irq, | 385 | pci_name(dev->pci), dev->pci_rev, dev->pci->irq, |
385 | dev->pci_lat,pci_resource_start(dev->pci,0)); | 386 | dev->pci_lat,pci_resource_start(dev->pci,0)); |
@@ -429,7 +430,7 @@ void cx8802_fini_common(struct cx8802_dev *dev) | |||
429 | 430 | ||
430 | int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) | 431 | int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) |
431 | { | 432 | { |
432 | struct cx8802_dev *dev = pci_get_drvdata(pci_dev); | 433 | struct cx8802_dev *dev = pci_get_drvdata(pci_dev); |
433 | struct cx88_core *core = dev->core; | 434 | struct cx88_core *core = dev->core; |
434 | 435 | ||
435 | /* stop mpeg dma */ | 436 | /* stop mpeg dma */ |
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h index 0a3a62fc9bbb..d3bf5b17b1d4 100644 --- a/drivers/media/video/cx88/cx88-reg.h +++ b/drivers/media/video/cx88/cx88-reg.h | |||
@@ -3,9 +3,9 @@ | |||
3 | cx88x-hw.h - CX2388x register offsets | 3 | cx88x-hw.h - CX2388x register offsets |
4 | 4 | ||
5 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) | 5 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) |
6 | 2001 Michael Eskin | 6 | 2001 Michael Eskin |
7 | 2002 Yurij Sysoev <yurij@naturesoft.net> | 7 | 2002 Yurij Sysoev <yurij@naturesoft.net> |
8 | 2003 Gerd Knorr <kraxel@bytesex.org> | 8 | 2003 Gerd Knorr <kraxel@bytesex.org> |
9 | 9 | ||
10 | This program is free software; you can redistribute it and/or modify | 10 | This program is free software; you can redistribute it and/or modify |
11 | it under the terms of the GNU General Public License as published by | 11 | it under the terms of the GNU General Public License as published by |
@@ -728,13 +728,13 @@ | |||
728 | #define ColorFormatGamma 0x1000 | 728 | #define ColorFormatGamma 0x1000 |
729 | 729 | ||
730 | #define Interlaced 0x1 | 730 | #define Interlaced 0x1 |
731 | #define NonInterlaced 0x0 | 731 | #define NonInterlaced 0x0 |
732 | 732 | ||
733 | #define FieldEven 0x1 | 733 | #define FieldEven 0x1 |
734 | #define FieldOdd 0x0 | 734 | #define FieldOdd 0x0 |
735 | 735 | ||
736 | #define TGReadWriteMode 0x0 | 736 | #define TGReadWriteMode 0x0 |
737 | #define TGEnableMode 0x1 | 737 | #define TGEnableMode 0x1 |
738 | 738 | ||
739 | #define DV_CbAlign 0x0 | 739 | #define DV_CbAlign 0x0 |
740 | #define DV_Y0Align 0x1 | 740 | #define DV_Y0Align 0x1 |
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 2765acee0285..6d9bec1c583b 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c | |||
@@ -57,39 +57,38 @@ | |||
57 | #include "cx88.h" | 57 | #include "cx88.h" |
58 | 58 | ||
59 | static unsigned int audio_debug = 0; | 59 | static unsigned int audio_debug = 0; |
60 | module_param(audio_debug,int,0644); | 60 | module_param(audio_debug, int, 0644); |
61 | MODULE_PARM_DESC(audio_debug,"enable debug messages [audio]"); | 61 | MODULE_PARM_DESC(audio_debug, "enable debug messages [audio]"); |
62 | 62 | ||
63 | #define dprintk(fmt, arg...) if (audio_debug) \ | 63 | #define dprintk(fmt, arg...) if (audio_debug) \ |
64 | printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) | 64 | printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) |
65 | 65 | ||
66 | /* ----------------------------------------------------------- */ | 66 | /* ----------------------------------------------------------- */ |
67 | 67 | ||
68 | static char *aud_ctl_names[64] = | 68 | static char *aud_ctl_names[64] = { |
69 | { | 69 | [EN_BTSC_FORCE_MONO] = "BTSC_FORCE_MONO", |
70 | [ EN_BTSC_FORCE_MONO ] = "BTSC_FORCE_MONO", | 70 | [EN_BTSC_FORCE_STEREO] = "BTSC_FORCE_STEREO", |
71 | [ EN_BTSC_FORCE_STEREO ] = "BTSC_FORCE_STEREO", | 71 | [EN_BTSC_FORCE_SAP] = "BTSC_FORCE_SAP", |
72 | [ EN_BTSC_FORCE_SAP ] = "BTSC_FORCE_SAP", | 72 | [EN_BTSC_AUTO_STEREO] = "BTSC_AUTO_STEREO", |
73 | [ EN_BTSC_AUTO_STEREO ] = "BTSC_AUTO_STEREO", | 73 | [EN_BTSC_AUTO_SAP] = "BTSC_AUTO_SAP", |
74 | [ EN_BTSC_AUTO_SAP ] = "BTSC_AUTO_SAP", | 74 | [EN_A2_FORCE_MONO1] = "A2_FORCE_MONO1", |
75 | [ EN_A2_FORCE_MONO1 ] = "A2_FORCE_MONO1", | 75 | [EN_A2_FORCE_MONO2] = "A2_FORCE_MONO2", |
76 | [ EN_A2_FORCE_MONO2 ] = "A2_FORCE_MONO2", | 76 | [EN_A2_FORCE_STEREO] = "A2_FORCE_STEREO", |
77 | [ EN_A2_FORCE_STEREO ] = "A2_FORCE_STEREO", | 77 | [EN_A2_AUTO_MONO2] = "A2_AUTO_MONO2", |
78 | [ EN_A2_AUTO_MONO2 ] = "A2_AUTO_MONO2", | 78 | [EN_A2_AUTO_STEREO] = "A2_AUTO_STEREO", |
79 | [ EN_A2_AUTO_STEREO ] = "A2_AUTO_STEREO", | 79 | [EN_EIAJ_FORCE_MONO1] = "EIAJ_FORCE_MONO1", |
80 | [ EN_EIAJ_FORCE_MONO1 ] = "EIAJ_FORCE_MONO1", | 80 | [EN_EIAJ_FORCE_MONO2] = "EIAJ_FORCE_MONO2", |
81 | [ EN_EIAJ_FORCE_MONO2 ] = "EIAJ_FORCE_MONO2", | 81 | [EN_EIAJ_FORCE_STEREO] = "EIAJ_FORCE_STEREO", |
82 | [ EN_EIAJ_FORCE_STEREO ] = "EIAJ_FORCE_STEREO", | 82 | [EN_EIAJ_AUTO_MONO2] = "EIAJ_AUTO_MONO2", |
83 | [ EN_EIAJ_AUTO_MONO2 ] = "EIAJ_AUTO_MONO2", | 83 | [EN_EIAJ_AUTO_STEREO] = "EIAJ_AUTO_STEREO", |
84 | [ EN_EIAJ_AUTO_STEREO ] = "EIAJ_AUTO_STEREO", | 84 | [EN_NICAM_FORCE_MONO1] = "NICAM_FORCE_MONO1", |
85 | [ EN_NICAM_FORCE_MONO1 ] = "NICAM_FORCE_MONO1", | 85 | [EN_NICAM_FORCE_MONO2] = "NICAM_FORCE_MONO2", |
86 | [ EN_NICAM_FORCE_MONO2 ] = "NICAM_FORCE_MONO2", | 86 | [EN_NICAM_FORCE_STEREO] = "NICAM_FORCE_STEREO", |
87 | [ EN_NICAM_FORCE_STEREO ] = "NICAM_FORCE_STEREO", | 87 | [EN_NICAM_AUTO_MONO2] = "NICAM_AUTO_MONO2", |
88 | [ EN_NICAM_AUTO_MONO2 ] = "NICAM_AUTO_MONO2", | 88 | [EN_NICAM_AUTO_STEREO] = "NICAM_AUTO_STEREO", |
89 | [ EN_NICAM_AUTO_STEREO ] = "NICAM_AUTO_STEREO", | 89 | [EN_FMRADIO_FORCE_MONO] = "FMRADIO_FORCE_MONO", |
90 | [ EN_FMRADIO_FORCE_MONO ] = "FMRADIO_FORCE_MONO", | 90 | [EN_FMRADIO_FORCE_STEREO] = "FMRADIO_FORCE_STEREO", |
91 | [ EN_FMRADIO_FORCE_STEREO ] = "FMRADIO_FORCE_STEREO", | 91 | [EN_FMRADIO_AUTO_STEREO] = "FMRADIO_AUTO_STEREO", |
92 | [ EN_FMRADIO_AUTO_STEREO ] = "FMRADIO_AUTO_STEREO", | ||
93 | }; | 92 | }; |
94 | 93 | ||
95 | struct rlist { | 94 | struct rlist { |
@@ -97,8 +96,7 @@ struct rlist { | |||
97 | u32 val; | 96 | u32 val; |
98 | }; | 97 | }; |
99 | 98 | ||
100 | static void set_audio_registers(struct cx88_core *core, | 99 | static void set_audio_registers(struct cx88_core *core, const struct rlist *l) |
101 | const struct rlist *l) | ||
102 | { | 100 | { |
103 | int i; | 101 | int i; |
104 | 102 | ||
@@ -119,17 +117,18 @@ static void set_audio_registers(struct cx88_core *core, | |||
119 | } | 117 | } |
120 | } | 118 | } |
121 | 119 | ||
122 | static void set_audio_start(struct cx88_core *core, | 120 | static void set_audio_start(struct cx88_core *core, u32 mode) |
123 | u32 mode) | ||
124 | { | 121 | { |
125 | // mute | 122 | // mute |
126 | cx_write(AUD_VOL_CTL, (1 << 6)); | 123 | cx_write(AUD_VOL_CTL, (1 << 6)); |
127 | 124 | ||
128 | // start programming | 125 | // start programming |
129 | cx_write(AUD_CTL, 0x0000); | 126 | cx_write(MO_AUD_DMACNTRL, 0x0000); |
130 | cx_write(AUD_INIT, mode); | 127 | msleep(100); |
131 | cx_write(AUD_INIT_LD, 0x0001); | 128 | //cx_write(AUD_CTL, 0x0000); |
132 | cx_write(AUD_SOFT_RESET, 0x0001); | 129 | cx_write(AUD_INIT, mode); |
130 | cx_write(AUD_INIT_LD, 0x0001); | ||
131 | cx_write(AUD_SOFT_RESET, 0x0001); | ||
133 | } | 132 | } |
134 | 133 | ||
135 | static void set_audio_finish(struct cx88_core *core, u32 ctl) | 134 | static void set_audio_finish(struct cx88_core *core, u32 ctl) |
@@ -148,12 +147,13 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl) | |||
148 | cx_write(AUD_I2SCNTL, 0); | 147 | cx_write(AUD_I2SCNTL, 0); |
149 | //cx_write(AUD_APB_IN_RATE_ADJ, 0); | 148 | //cx_write(AUD_APB_IN_RATE_ADJ, 0); |
150 | } else { | 149 | } else { |
151 | ctl |= EN_DAC_ENABLE; | 150 | ctl |= EN_DAC_ENABLE; |
152 | cx_write(AUD_CTL, ctl); | 151 | cx_write(AUD_CTL, ctl); |
153 | } | 152 | } |
154 | 153 | ||
155 | /* finish programming */ | 154 | /* finish programming */ |
156 | cx_write(AUD_SOFT_RESET, 0x0000); | 155 | cx_write(AUD_SOFT_RESET, 0x0000); |
156 | cx_write(MO_AUD_DMACNTRL, 0x0003); | ||
157 | 157 | ||
158 | /* unmute */ | 158 | /* unmute */ |
159 | volume = cx_sread(SHADOW_AUD_VOL_CTL); | 159 | volume = cx_sread(SHADOW_AUD_VOL_CTL); |
@@ -162,486 +162,463 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl) | |||
162 | 162 | ||
163 | /* ----------------------------------------------------------- */ | 163 | /* ----------------------------------------------------------- */ |
164 | 164 | ||
165 | static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap, u32 mode) | 165 | static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap, |
166 | u32 mode) | ||
166 | { | 167 | { |
167 | static const struct rlist btsc[] = { | 168 | static const struct rlist btsc[] = { |
168 | { AUD_AFE_12DB_EN, 0x00000001 }, | 169 | {AUD_AFE_12DB_EN, 0x00000001}, |
169 | { AUD_OUT1_SEL, 0x00000013 }, | 170 | {AUD_OUT1_SEL, 0x00000013}, |
170 | { AUD_OUT1_SHIFT, 0x00000000 }, | 171 | {AUD_OUT1_SHIFT, 0x00000000}, |
171 | { AUD_POLY0_DDS_CONSTANT, 0x0012010c }, | 172 | {AUD_POLY0_DDS_CONSTANT, 0x0012010c}, |
172 | { AUD_DMD_RA_DDS, 0x00c3e7aa }, | 173 | {AUD_DMD_RA_DDS, 0x00c3e7aa}, |
173 | { AUD_DBX_IN_GAIN, 0x00004734 }, | 174 | {AUD_DBX_IN_GAIN, 0x00004734}, |
174 | { AUD_DBX_WBE_GAIN, 0x00004640 }, | 175 | {AUD_DBX_WBE_GAIN, 0x00004640}, |
175 | { AUD_DBX_SE_GAIN, 0x00008d31 }, | 176 | {AUD_DBX_SE_GAIN, 0x00008d31}, |
176 | { AUD_DCOC_0_SRC, 0x0000001a }, | 177 | {AUD_DCOC_0_SRC, 0x0000001a}, |
177 | { AUD_IIR1_4_SEL, 0x00000021 }, | 178 | {AUD_IIR1_4_SEL, 0x00000021}, |
178 | { AUD_DCOC_PASS_IN, 0x00000003 }, | 179 | {AUD_DCOC_PASS_IN, 0x00000003}, |
179 | { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, | 180 | {AUD_DCOC_0_SHIFT_IN0, 0x0000000a}, |
180 | { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, | 181 | {AUD_DCOC_0_SHIFT_IN1, 0x00000008}, |
181 | { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, | 182 | {AUD_DCOC_1_SHIFT_IN0, 0x0000000a}, |
182 | { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, | 183 | {AUD_DCOC_1_SHIFT_IN1, 0x00000008}, |
183 | { AUD_DN0_FREQ, 0x0000283b }, | 184 | {AUD_DN0_FREQ, 0x0000283b}, |
184 | { AUD_DN2_SRC_SEL, 0x00000008 }, | 185 | {AUD_DN2_SRC_SEL, 0x00000008}, |
185 | { AUD_DN2_FREQ, 0x00003000 }, | 186 | {AUD_DN2_FREQ, 0x00003000}, |
186 | { AUD_DN2_AFC, 0x00000002 }, | 187 | {AUD_DN2_AFC, 0x00000002}, |
187 | { AUD_DN2_SHFT, 0x00000000 }, | 188 | {AUD_DN2_SHFT, 0x00000000}, |
188 | { AUD_IIR2_2_SEL, 0x00000020 }, | 189 | {AUD_IIR2_2_SEL, 0x00000020}, |
189 | { AUD_IIR2_2_SHIFT, 0x00000000 }, | 190 | {AUD_IIR2_2_SHIFT, 0x00000000}, |
190 | { AUD_IIR2_3_SEL, 0x0000001f }, | 191 | {AUD_IIR2_3_SEL, 0x0000001f}, |
191 | { AUD_IIR2_3_SHIFT, 0x00000000 }, | 192 | {AUD_IIR2_3_SHIFT, 0x00000000}, |
192 | { AUD_CRDC1_SRC_SEL, 0x000003ce }, | 193 | {AUD_CRDC1_SRC_SEL, 0x000003ce}, |
193 | { AUD_CRDC1_SHIFT, 0x00000000 }, | 194 | {AUD_CRDC1_SHIFT, 0x00000000}, |
194 | { AUD_CORDIC_SHIFT_1, 0x00000007 }, | 195 | {AUD_CORDIC_SHIFT_1, 0x00000007}, |
195 | { AUD_DCOC_1_SRC, 0x0000001b }, | 196 | {AUD_DCOC_1_SRC, 0x0000001b}, |
196 | { AUD_DCOC1_SHIFT, 0x00000000 }, | 197 | {AUD_DCOC1_SHIFT, 0x00000000}, |
197 | { AUD_RDSI_SEL, 0x00000008 }, | 198 | {AUD_RDSI_SEL, 0x00000008}, |
198 | { AUD_RDSQ_SEL, 0x00000008 }, | 199 | {AUD_RDSQ_SEL, 0x00000008}, |
199 | { AUD_RDSI_SHIFT, 0x00000000 }, | 200 | {AUD_RDSI_SHIFT, 0x00000000}, |
200 | { AUD_RDSQ_SHIFT, 0x00000000 }, | 201 | {AUD_RDSQ_SHIFT, 0x00000000}, |
201 | { AUD_POLYPH80SCALEFAC, 0x00000003 }, | 202 | {AUD_POLYPH80SCALEFAC, 0x00000003}, |
202 | { /* end of list */ }, | 203 | { /* end of list */ }, |
203 | }; | 204 | }; |
204 | static const struct rlist btsc_sap[] = { | 205 | static const struct rlist btsc_sap[] = { |
205 | { AUD_AFE_12DB_EN, 0x00000001 }, | 206 | {AUD_AFE_12DB_EN, 0x00000001}, |
206 | { AUD_DBX_IN_GAIN, 0x00007200 }, | 207 | {AUD_DBX_IN_GAIN, 0x00007200}, |
207 | { AUD_DBX_WBE_GAIN, 0x00006200 }, | 208 | {AUD_DBX_WBE_GAIN, 0x00006200}, |
208 | { AUD_DBX_SE_GAIN, 0x00006200 }, | 209 | {AUD_DBX_SE_GAIN, 0x00006200}, |
209 | { AUD_IIR1_1_SEL, 0x00000000 }, | 210 | {AUD_IIR1_1_SEL, 0x00000000}, |
210 | { AUD_IIR1_3_SEL, 0x00000001 }, | 211 | {AUD_IIR1_3_SEL, 0x00000001}, |
211 | { AUD_DN1_SRC_SEL, 0x00000007 }, | 212 | {AUD_DN1_SRC_SEL, 0x00000007}, |
212 | { AUD_IIR1_4_SHIFT, 0x00000006 }, | 213 | {AUD_IIR1_4_SHIFT, 0x00000006}, |
213 | { AUD_IIR2_1_SHIFT, 0x00000000 }, | 214 | {AUD_IIR2_1_SHIFT, 0x00000000}, |
214 | { AUD_IIR2_2_SHIFT, 0x00000000 }, | 215 | {AUD_IIR2_2_SHIFT, 0x00000000}, |
215 | { AUD_IIR3_0_SHIFT, 0x00000000 }, | 216 | {AUD_IIR3_0_SHIFT, 0x00000000}, |
216 | { AUD_IIR3_1_SHIFT, 0x00000000 }, | 217 | {AUD_IIR3_1_SHIFT, 0x00000000}, |
217 | { AUD_IIR3_0_SEL, 0x0000000d }, | 218 | {AUD_IIR3_0_SEL, 0x0000000d}, |
218 | { AUD_IIR3_1_SEL, 0x0000000e }, | 219 | {AUD_IIR3_1_SEL, 0x0000000e}, |
219 | { AUD_DEEMPH1_SRC_SEL, 0x00000014 }, | 220 | {AUD_DEEMPH1_SRC_SEL, 0x00000014}, |
220 | { AUD_DEEMPH1_SHIFT, 0x00000000 }, | 221 | {AUD_DEEMPH1_SHIFT, 0x00000000}, |
221 | { AUD_DEEMPH1_G0, 0x00004000 }, | 222 | {AUD_DEEMPH1_G0, 0x00004000}, |
222 | { AUD_DEEMPH1_A0, 0x00000000 }, | 223 | {AUD_DEEMPH1_A0, 0x00000000}, |
223 | { AUD_DEEMPH1_B0, 0x00000000 }, | 224 | {AUD_DEEMPH1_B0, 0x00000000}, |
224 | { AUD_DEEMPH1_A1, 0x00000000 }, | 225 | {AUD_DEEMPH1_A1, 0x00000000}, |
225 | { AUD_DEEMPH1_B1, 0x00000000 }, | 226 | {AUD_DEEMPH1_B1, 0x00000000}, |
226 | { AUD_OUT0_SEL, 0x0000003f }, | 227 | {AUD_OUT0_SEL, 0x0000003f}, |
227 | { AUD_OUT1_SEL, 0x0000003f }, | 228 | {AUD_OUT1_SEL, 0x0000003f}, |
228 | { AUD_DN1_AFC, 0x00000002 }, | 229 | {AUD_DN1_AFC, 0x00000002}, |
229 | { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, | 230 | {AUD_DCOC_0_SHIFT_IN0, 0x0000000a}, |
230 | { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, | 231 | {AUD_DCOC_0_SHIFT_IN1, 0x00000008}, |
231 | { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, | 232 | {AUD_DCOC_1_SHIFT_IN0, 0x0000000a}, |
232 | { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, | 233 | {AUD_DCOC_1_SHIFT_IN1, 0x00000008}, |
233 | { AUD_IIR1_0_SEL, 0x0000001d }, | 234 | {AUD_IIR1_0_SEL, 0x0000001d}, |
234 | { AUD_IIR1_2_SEL, 0x0000001e }, | 235 | {AUD_IIR1_2_SEL, 0x0000001e}, |
235 | { AUD_IIR2_1_SEL, 0x00000002 }, | 236 | {AUD_IIR2_1_SEL, 0x00000002}, |
236 | { AUD_IIR2_2_SEL, 0x00000004 }, | 237 | {AUD_IIR2_2_SEL, 0x00000004}, |
237 | { AUD_IIR3_2_SEL, 0x0000000f }, | 238 | {AUD_IIR3_2_SEL, 0x0000000f}, |
238 | { AUD_DCOC2_SHIFT, 0x00000001 }, | 239 | {AUD_DCOC2_SHIFT, 0x00000001}, |
239 | { AUD_IIR3_2_SHIFT, 0x00000001 }, | 240 | {AUD_IIR3_2_SHIFT, 0x00000001}, |
240 | { AUD_DEEMPH0_SRC_SEL, 0x00000014 }, | 241 | {AUD_DEEMPH0_SRC_SEL, 0x00000014}, |
241 | { AUD_CORDIC_SHIFT_1, 0x00000006 }, | 242 | {AUD_CORDIC_SHIFT_1, 0x00000006}, |
242 | { AUD_POLY0_DDS_CONSTANT, 0x000e4db2 }, | 243 | {AUD_POLY0_DDS_CONSTANT, 0x000e4db2}, |
243 | { AUD_DMD_RA_DDS, 0x00f696e6 }, | 244 | {AUD_DMD_RA_DDS, 0x00f696e6}, |
244 | { AUD_IIR2_3_SEL, 0x00000025 }, | 245 | {AUD_IIR2_3_SEL, 0x00000025}, |
245 | { AUD_IIR1_4_SEL, 0x00000021 }, | 246 | {AUD_IIR1_4_SEL, 0x00000021}, |
246 | { AUD_DN1_FREQ, 0x0000c965 }, | 247 | {AUD_DN1_FREQ, 0x0000c965}, |
247 | { AUD_DCOC_PASS_IN, 0x00000003 }, | 248 | {AUD_DCOC_PASS_IN, 0x00000003}, |
248 | { AUD_DCOC_0_SRC, 0x0000001a }, | 249 | {AUD_DCOC_0_SRC, 0x0000001a}, |
249 | { AUD_DCOC_1_SRC, 0x0000001b }, | 250 | {AUD_DCOC_1_SRC, 0x0000001b}, |
250 | { AUD_DCOC1_SHIFT, 0x00000000 }, | 251 | {AUD_DCOC1_SHIFT, 0x00000000}, |
251 | { AUD_RDSI_SEL, 0x00000009 }, | 252 | {AUD_RDSI_SEL, 0x00000009}, |
252 | { AUD_RDSQ_SEL, 0x00000009 }, | 253 | {AUD_RDSQ_SEL, 0x00000009}, |
253 | { AUD_RDSI_SHIFT, 0x00000000 }, | 254 | {AUD_RDSI_SHIFT, 0x00000000}, |
254 | { AUD_RDSQ_SHIFT, 0x00000000 }, | 255 | {AUD_RDSQ_SHIFT, 0x00000000}, |
255 | { AUD_POLYPH80SCALEFAC, 0x00000003 }, | 256 | {AUD_POLYPH80SCALEFAC, 0x00000003}, |
256 | { /* end of list */ }, | 257 | { /* end of list */ }, |
257 | }; | 258 | }; |
258 | 259 | ||
259 | mode |= EN_FMRADIO_EN_RDS; | 260 | mode |= EN_FMRADIO_EN_RDS; |
260 | 261 | ||
261 | if (sap) { | 262 | if (sap) { |
262 | dprintk("%s SAP (status: unknown)\n",__FUNCTION__); | 263 | dprintk("%s SAP (status: unknown)\n", __FUNCTION__); |
263 | set_audio_start(core, SEL_SAP); | 264 | set_audio_start(core, SEL_SAP); |
264 | set_audio_registers(core, btsc_sap); | 265 | set_audio_registers(core, btsc_sap); |
265 | set_audio_finish(core, mode); | 266 | set_audio_finish(core, mode); |
266 | } else { | 267 | } else { |
267 | dprintk("%s (status: known-good)\n",__FUNCTION__); | 268 | dprintk("%s (status: known-good)\n", __FUNCTION__); |
268 | set_audio_start(core, SEL_BTSC); | 269 | set_audio_start(core, SEL_BTSC); |
269 | set_audio_registers(core, btsc); | 270 | set_audio_registers(core, btsc); |
270 | set_audio_finish(core, mode); | 271 | set_audio_finish(core, mode); |
271 | } | 272 | } |
272 | } | 273 | } |
273 | 274 | ||
274 | 275 | static void set_audio_standard_NICAM(struct cx88_core *core, u32 mode) | |
275 | static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo) | ||
276 | { | 276 | { |
277 | /* This is probably weird.. | 277 | static const struct rlist nicam_l[] = { |
278 | * Let's operate and find out. */ | 278 | {AUD_AFE_12DB_EN, 0x00000001}, |
279 | 279 | {AUD_RATE_ADJ1, 0x00000060}, | |
280 | static const struct rlist nicam_l_mono[] = { | 280 | {AUD_RATE_ADJ2, 0x000000F9}, |
281 | { AUD_ERRLOGPERIOD_R, 0x00000064 }, | 281 | {AUD_RATE_ADJ3, 0x000001CC}, |
282 | { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF }, | 282 | {AUD_RATE_ADJ4, 0x000002B3}, |
283 | { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F }, | 283 | {AUD_RATE_ADJ5, 0x00000726}, |
284 | { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F }, | 284 | {AUD_DEEMPHDENOM1_R, 0x0000F3D0}, |
285 | 285 | {AUD_DEEMPHDENOM2_R, 0x00000000}, | |
286 | { AUD_PDF_DDS_CNST_BYTE2, 0x48 }, | 286 | {AUD_ERRLOGPERIOD_R, 0x00000064}, |
287 | { AUD_PDF_DDS_CNST_BYTE1, 0x3D }, | 287 | {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF}, |
288 | { AUD_QAM_MODE, 0x00 }, | 288 | {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F}, |
289 | { AUD_PDF_DDS_CNST_BYTE0, 0xf5 }, | 289 | {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F}, |
290 | { AUD_PHACC_FREQ_8MSB, 0x3a }, | 290 | {AUD_POLYPH80SCALEFAC, 0x00000003}, |
291 | { AUD_PHACC_FREQ_8LSB, 0x4a }, | 291 | {AUD_DMD_RA_DDS, 0x00C00000}, |
292 | 292 | {AUD_PLL_INT, 0x0000001E}, | |
293 | { AUD_DEEMPHGAIN_R, 0x6680 }, | 293 | {AUD_PLL_DDS, 0x00000000}, |
294 | { AUD_DEEMPHNUMER1_R, 0x353DE }, | 294 | {AUD_PLL_FRAC, 0x0000E542}, |
295 | { AUD_DEEMPHNUMER2_R, 0x1B1 }, | 295 | {AUD_START_TIMER, 0x00000000}, |
296 | { AUD_DEEMPHDENOM1_R, 0x0F3D0 }, | 296 | {AUD_DEEMPHNUMER1_R, 0x000353DE}, |
297 | { AUD_DEEMPHDENOM2_R, 0x0 }, | 297 | {AUD_DEEMPHNUMER2_R, 0x000001B1}, |
298 | { AUD_FM_MODE_ENABLE, 0x7 }, | 298 | {AUD_PDF_DDS_CNST_BYTE2, 0x06}, |
299 | { AUD_POLYPH80SCALEFAC, 0x3 }, | 299 | {AUD_PDF_DDS_CNST_BYTE1, 0x82}, |
300 | { AUD_AFE_12DB_EN, 0x1 }, | 300 | {AUD_PDF_DDS_CNST_BYTE0, 0x12}, |
301 | { AAGC_GAIN, 0x0 }, | 301 | {AUD_QAM_MODE, 0x05}, |
302 | { AAGC_HYST, 0x18 }, | 302 | {AUD_PHACC_FREQ_8MSB, 0x34}, |
303 | { AAGC_DEF, 0x20 }, | 303 | {AUD_PHACC_FREQ_8LSB, 0x4C}, |
304 | { AUD_DN0_FREQ, 0x0 }, | 304 | {AUD_DEEMPHGAIN_R, 0x00006680}, |
305 | { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 }, | 305 | {AUD_RATE_THRES_DMD, 0x000000C0}, |
306 | { AUD_DCOC_0_SRC, 0x21 }, | ||
307 | { AUD_IIR1_0_SEL, 0x0 }, | ||
308 | { AUD_IIR1_0_SHIFT, 0x7 }, | ||
309 | { AUD_IIR1_1_SEL, 0x2 }, | ||
310 | { AUD_IIR1_1_SHIFT, 0x0 }, | ||
311 | { AUD_DCOC_1_SRC, 0x3 }, | ||
312 | { AUD_DCOC1_SHIFT, 0x0 }, | ||
313 | { AUD_DCOC_PASS_IN, 0x0 }, | ||
314 | { AUD_IIR1_2_SEL, 0x23 }, | ||
315 | { AUD_IIR1_2_SHIFT, 0x0 }, | ||
316 | { AUD_IIR1_3_SEL, 0x4 }, | ||
317 | { AUD_IIR1_3_SHIFT, 0x7 }, | ||
318 | { AUD_IIR1_4_SEL, 0x5 }, | ||
319 | { AUD_IIR1_4_SHIFT, 0x7 }, | ||
320 | { AUD_IIR3_0_SEL, 0x7 }, | ||
321 | { AUD_IIR3_0_SHIFT, 0x0 }, | ||
322 | { AUD_DEEMPH0_SRC_SEL, 0x11 }, | ||
323 | { AUD_DEEMPH0_SHIFT, 0x0 }, | ||
324 | { AUD_DEEMPH0_G0, 0x7000 }, | ||
325 | { AUD_DEEMPH0_A0, 0x0 }, | ||
326 | { AUD_DEEMPH0_B0, 0x0 }, | ||
327 | { AUD_DEEMPH0_A1, 0x0 }, | ||
328 | { AUD_DEEMPH0_B1, 0x0 }, | ||
329 | { AUD_DEEMPH1_SRC_SEL, 0x11 }, | ||
330 | { AUD_DEEMPH1_SHIFT, 0x0 }, | ||
331 | { AUD_DEEMPH1_G0, 0x7000 }, | ||
332 | { AUD_DEEMPH1_A0, 0x0 }, | ||
333 | { AUD_DEEMPH1_B0, 0x0 }, | ||
334 | { AUD_DEEMPH1_A1, 0x0 }, | ||
335 | { AUD_DEEMPH1_B1, 0x0 }, | ||
336 | { AUD_OUT0_SEL, 0x3F }, | ||
337 | { AUD_OUT1_SEL, 0x3F }, | ||
338 | { AUD_DMD_RA_DDS, 0x0F5C285 }, | ||
339 | { AUD_PLL_INT, 0x1E }, | ||
340 | { AUD_PLL_DDS, 0x0 }, | ||
341 | { AUD_PLL_FRAC, 0x0E542 }, | ||
342 | |||
343 | // setup QAM registers | ||
344 | { AUD_RATE_ADJ1, 0x00000100 }, | ||
345 | { AUD_RATE_ADJ2, 0x00000200 }, | ||
346 | { AUD_RATE_ADJ3, 0x00000300 }, | ||
347 | { AUD_RATE_ADJ4, 0x00000400 }, | ||
348 | { AUD_RATE_ADJ5, 0x00000500 }, | ||
349 | { AUD_RATE_THRES_DMD, 0x000000C0 }, | ||
350 | { /* end of list */ }, | 306 | { /* end of list */ }, |
351 | }; | 307 | }; |
352 | 308 | ||
353 | static const struct rlist nicam_l[] = { | 309 | static const struct rlist nicam_bgdki_common[] = { |
354 | // setup QAM registers | 310 | {AUD_AFE_12DB_EN, 0x00000001}, |
355 | { AUD_RATE_ADJ1, 0x00000060 }, | 311 | {AUD_RATE_ADJ1, 0x00000010}, |
356 | { AUD_RATE_ADJ2, 0x000000F9 }, | 312 | {AUD_RATE_ADJ2, 0x00000040}, |
357 | { AUD_RATE_ADJ3, 0x000001CC }, | 313 | {AUD_RATE_ADJ3, 0x00000100}, |
358 | { AUD_RATE_ADJ4, 0x000002B3 }, | 314 | {AUD_RATE_ADJ4, 0x00000400}, |
359 | { AUD_RATE_ADJ5, 0x00000726 }, | 315 | {AUD_RATE_ADJ5, 0x00001000}, |
360 | { AUD_DEEMPHDENOM1_R, 0x0000F3D0 }, | 316 | //{ AUD_DMD_RA_DDS, 0x00c0d5ce }, |
361 | { AUD_DEEMPHDENOM2_R, 0x00000000 }, | 317 | {AUD_ERRLOGPERIOD_R, 0x00000fff}, |
362 | { AUD_ERRLOGPERIOD_R, 0x00000064 }, | 318 | {AUD_ERRINTRPTTHSHLD1_R, 0x000003ff}, |
363 | { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF }, | 319 | {AUD_ERRINTRPTTHSHLD2_R, 0x000000ff}, |
364 | { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F }, | 320 | {AUD_ERRINTRPTTHSHLD3_R, 0x0000003f}, |
365 | { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F }, | 321 | {AUD_POLYPH80SCALEFAC, 0x00000003}, |
366 | { AUD_POLYPH80SCALEFAC, 0x00000003 }, | 322 | {AUD_DEEMPHGAIN_R, 0x000023c2}, |
367 | { AUD_DMD_RA_DDS, 0x00C00000 }, | 323 | {AUD_DEEMPHNUMER1_R, 0x0002a7bc}, |
368 | { AUD_PLL_INT, 0x0000001E }, | 324 | {AUD_DEEMPHNUMER2_R, 0x0003023e}, |
369 | { AUD_PLL_DDS, 0x00000000 }, | 325 | {AUD_DEEMPHDENOM1_R, 0x0000f3d0}, |
370 | { AUD_PLL_FRAC, 0x0000E542 }, | 326 | {AUD_DEEMPHDENOM2_R, 0x00000000}, |
371 | { AUD_START_TIMER, 0x00000000 }, | 327 | {AUD_PDF_DDS_CNST_BYTE2, 0x06}, |
372 | { AUD_DEEMPHNUMER1_R, 0x000353DE }, | 328 | {AUD_PDF_DDS_CNST_BYTE1, 0x82}, |
373 | { AUD_DEEMPHNUMER2_R, 0x000001B1 }, | 329 | {AUD_QAM_MODE, 0x05}, |
374 | { AUD_PDF_DDS_CNST_BYTE2, 0x06 }, | ||
375 | { AUD_PDF_DDS_CNST_BYTE1, 0x82 }, | ||
376 | { AUD_QAM_MODE, 0x05 }, | ||
377 | { AUD_PDF_DDS_CNST_BYTE0, 0x12 }, | ||
378 | { AUD_PHACC_FREQ_8MSB, 0x34 }, | ||
379 | { AUD_PHACC_FREQ_8LSB, 0x4C }, | ||
380 | { AUD_DEEMPHGAIN_R, 0x00006680 }, | ||
381 | { AUD_RATE_THRES_DMD, 0x000000C0 }, | ||
382 | { /* end of list */ }, | 330 | { /* end of list */ }, |
383 | } ; | 331 | }; |
384 | dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo); | ||
385 | |||
386 | if (!stereo) { | ||
387 | /* AM Mono */ | ||
388 | set_audio_start(core, SEL_A2); | ||
389 | set_audio_registers(core, nicam_l_mono); | ||
390 | set_audio_finish(core, EN_A2_FORCE_MONO1); | ||
391 | } else { | ||
392 | /* Nicam Stereo */ | ||
393 | set_audio_start(core, SEL_NICAM); | ||
394 | set_audio_registers(core, nicam_l); | ||
395 | set_audio_finish(core, 0x1924); /* FIXME */ | ||
396 | } | ||
397 | } | ||
398 | 332 | ||
399 | static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo) | 333 | static const struct rlist nicam_i[] = { |
400 | { | 334 | {AUD_PDF_DDS_CNST_BYTE0, 0x12}, |
401 | static const struct rlist pal_i_fm_mono[] = { | 335 | {AUD_PHACC_FREQ_8MSB, 0x3a}, |
402 | {AUD_ERRLOGPERIOD_R, 0x00000064}, | 336 | {AUD_PHACC_FREQ_8LSB, 0x93}, |
403 | {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, | 337 | { /* end of list */ }, |
404 | {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f}, | ||
405 | {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f}, | ||
406 | {AUD_PDF_DDS_CNST_BYTE2, 0x06}, | ||
407 | {AUD_PDF_DDS_CNST_BYTE1, 0x82}, | ||
408 | {AUD_PDF_DDS_CNST_BYTE0, 0x12}, | ||
409 | {AUD_QAM_MODE, 0x05}, | ||
410 | {AUD_PHACC_FREQ_8MSB, 0x3a}, | ||
411 | {AUD_PHACC_FREQ_8LSB, 0x93}, | ||
412 | {AUD_DMD_RA_DDS, 0x002a4f2f}, | ||
413 | {AUD_PLL_INT, 0x0000001e}, | ||
414 | {AUD_PLL_DDS, 0x00000004}, | ||
415 | {AUD_PLL_FRAC, 0x0000e542}, | ||
416 | {AUD_RATE_ADJ1, 0x00000100}, | ||
417 | {AUD_RATE_ADJ2, 0x00000200}, | ||
418 | {AUD_RATE_ADJ3, 0x00000300}, | ||
419 | {AUD_RATE_ADJ4, 0x00000400}, | ||
420 | {AUD_RATE_ADJ5, 0x00000500}, | ||
421 | {AUD_THR_FR, 0x00000000}, | ||
422 | {AUD_PILOT_BQD_1_K0, 0x0000755b}, | ||
423 | {AUD_PILOT_BQD_1_K1, 0x00551340}, | ||
424 | {AUD_PILOT_BQD_1_K2, 0x006d30be}, | ||
425 | {AUD_PILOT_BQD_1_K3, 0xffd394af}, | ||
426 | {AUD_PILOT_BQD_1_K4, 0x00400000}, | ||
427 | {AUD_PILOT_BQD_2_K0, 0x00040000}, | ||
428 | {AUD_PILOT_BQD_2_K1, 0x002a4841}, | ||
429 | {AUD_PILOT_BQD_2_K2, 0x00400000}, | ||
430 | {AUD_PILOT_BQD_2_K3, 0x00000000}, | ||
431 | {AUD_PILOT_BQD_2_K4, 0x00000000}, | ||
432 | {AUD_MODE_CHG_TIMER, 0x00000060}, | ||
433 | {AUD_AFE_12DB_EN, 0x00000001}, | ||
434 | {AAGC_HYST, 0x0000000a}, | ||
435 | {AUD_CORDIC_SHIFT_0, 0x00000007}, | ||
436 | {AUD_CORDIC_SHIFT_1, 0x00000007}, | ||
437 | {AUD_C1_UP_THR, 0x00007000}, | ||
438 | {AUD_C1_LO_THR, 0x00005400}, | ||
439 | {AUD_C2_UP_THR, 0x00005400}, | ||
440 | {AUD_C2_LO_THR, 0x00003000}, | ||
441 | {AUD_DCOC_0_SRC, 0x0000001a}, | ||
442 | {AUD_DCOC0_SHIFT, 0x00000000}, | ||
443 | {AUD_DCOC_0_SHIFT_IN0, 0x0000000a}, | ||
444 | {AUD_DCOC_0_SHIFT_IN1, 0x00000008}, | ||
445 | {AUD_DCOC_PASS_IN, 0x00000003}, | ||
446 | {AUD_IIR3_0_SEL, 0x00000021}, | ||
447 | {AUD_DN2_AFC, 0x00000002}, | ||
448 | {AUD_DCOC_1_SRC, 0x0000001b}, | ||
449 | {AUD_DCOC1_SHIFT, 0x00000000}, | ||
450 | {AUD_DCOC_1_SHIFT_IN0, 0x0000000a}, | ||
451 | {AUD_DCOC_1_SHIFT_IN1, 0x00000008}, | ||
452 | {AUD_IIR3_1_SEL, 0x00000023}, | ||
453 | {AUD_DN0_FREQ, 0x000035a3}, | ||
454 | {AUD_DN2_FREQ, 0x000029c7}, | ||
455 | {AUD_CRDC0_SRC_SEL, 0x00000511}, | ||
456 | {AUD_IIR1_0_SEL, 0x00000001}, | ||
457 | {AUD_IIR1_1_SEL, 0x00000000}, | ||
458 | {AUD_IIR3_2_SEL, 0x00000003}, | ||
459 | {AUD_IIR3_2_SHIFT, 0x00000000}, | ||
460 | {AUD_IIR3_0_SEL, 0x00000002}, | ||
461 | {AUD_IIR2_0_SEL, 0x00000021}, | ||
462 | {AUD_IIR2_0_SHIFT, 0x00000002}, | ||
463 | {AUD_DEEMPH0_SRC_SEL, 0x0000000b}, | ||
464 | {AUD_DEEMPH1_SRC_SEL, 0x0000000b}, | ||
465 | {AUD_POLYPH80SCALEFAC, 0x00000001}, | ||
466 | {AUD_START_TIMER, 0x00000000}, | ||
467 | { /* end of list */ }, | ||
468 | }; | ||
469 | |||
470 | static const struct rlist pal_i_nicam[] = { | ||
471 | { AUD_RATE_ADJ1, 0x00000010 }, | ||
472 | { AUD_RATE_ADJ2, 0x00000040 }, | ||
473 | { AUD_RATE_ADJ3, 0x00000100 }, | ||
474 | { AUD_RATE_ADJ4, 0x00000400 }, | ||
475 | { AUD_RATE_ADJ5, 0x00001000 }, | ||
476 | // { AUD_DMD_RA_DDS, 0x00c0d5ce }, | ||
477 | { AUD_DEEMPHGAIN_R, 0x000023c2 }, | ||
478 | { AUD_DEEMPHNUMER1_R, 0x0002a7bc }, | ||
479 | { AUD_DEEMPHNUMER2_R, 0x0003023e }, | ||
480 | { AUD_DEEMPHDENOM1_R, 0x0000f3d0 }, | ||
481 | { AUD_DEEMPHDENOM2_R, 0x00000000 }, | ||
482 | { AUD_DEEMPHDENOM2_R, 0x00000000 }, | ||
483 | { AUD_ERRLOGPERIOD_R, 0x00000fff }, | ||
484 | { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff }, | ||
485 | { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff }, | ||
486 | { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f }, | ||
487 | { AUD_POLYPH80SCALEFAC, 0x00000003 }, | ||
488 | { AUD_PDF_DDS_CNST_BYTE2, 0x06 }, | ||
489 | { AUD_PDF_DDS_CNST_BYTE1, 0x82 }, | ||
490 | { AUD_PDF_DDS_CNST_BYTE0, 0x16 }, | ||
491 | { AUD_QAM_MODE, 0x05 }, | ||
492 | { AUD_PDF_DDS_CNST_BYTE0, 0x12 }, | ||
493 | { AUD_PHACC_FREQ_8MSB, 0x3a }, | ||
494 | { AUD_PHACC_FREQ_8LSB, 0x93 }, | ||
495 | { /* end of list */ }, | ||
496 | }; | 338 | }; |
497 | 339 | ||
498 | dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo); | 340 | static const struct rlist nicam_default[] = { |
341 | {AUD_PDF_DDS_CNST_BYTE0, 0x16}, | ||
342 | {AUD_PHACC_FREQ_8MSB, 0x34}, | ||
343 | {AUD_PHACC_FREQ_8LSB, 0x4c}, | ||
344 | { /* end of list */ }, | ||
345 | }; | ||
499 | 346 | ||
500 | if (!stereo) { | 347 | set_audio_start(core,SEL_NICAM); |
501 | /* FM Mono */ | 348 | switch (core->tvaudio) { |
502 | set_audio_start(core, SEL_A2); | 349 | case WW_L: |
503 | set_audio_registers(core, pal_i_fm_mono); | 350 | dprintk("%s SECAM-L NICAM (status: devel)\n", __FUNCTION__); |
504 | set_audio_finish(core, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1); | 351 | set_audio_registers(core, nicam_l); |
505 | } else { | 352 | break; |
506 | /* Nicam Stereo */ | 353 | case WW_I: |
507 | set_audio_start(core, SEL_NICAM); | 354 | dprintk("%s PAL-I NICAM (status: devel)\n", __FUNCTION__); |
508 | set_audio_registers(core, pal_i_nicam); | 355 | set_audio_registers(core, nicam_bgdki_common); |
509 | set_audio_finish(core, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO); | 356 | set_audio_registers(core, nicam_i); |
510 | } | 357 | break; |
358 | default: | ||
359 | dprintk("%s PAL-BGDK NICAM (status: unknown)\n", __FUNCTION__); | ||
360 | set_audio_registers(core, nicam_bgdki_common); | ||
361 | set_audio_registers(core, nicam_default); | ||
362 | break; | ||
363 | }; | ||
364 | |||
365 | mode |= EN_DMTRX_LR | EN_DMTRX_BYPASS; | ||
366 | set_audio_finish(core, mode); | ||
511 | } | 367 | } |
512 | 368 | ||
513 | static void set_audio_standard_A2(struct cx88_core *core, u32 mode) | 369 | static void set_audio_standard_A2(struct cx88_core *core, u32 mode) |
514 | { | 370 | { |
515 | static const struct rlist a2_common[] = { | 371 | static const struct rlist a2_bgdk_common[] = { |
516 | {AUD_ERRLOGPERIOD_R, 0x00000064}, | 372 | {AUD_ERRLOGPERIOD_R, 0x00000064}, |
517 | {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, | 373 | {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, |
518 | {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f}, | 374 | {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f}, |
519 | {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f}, | 375 | {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f}, |
520 | {AUD_PDF_DDS_CNST_BYTE2, 0x06}, | 376 | {AUD_PDF_DDS_CNST_BYTE2, 0x06}, |
521 | {AUD_PDF_DDS_CNST_BYTE1, 0x82}, | 377 | {AUD_PDF_DDS_CNST_BYTE1, 0x82}, |
522 | {AUD_PDF_DDS_CNST_BYTE0, 0x12}, | 378 | {AUD_PDF_DDS_CNST_BYTE0, 0x12}, |
523 | {AUD_QAM_MODE, 0x05}, | 379 | {AUD_QAM_MODE, 0x05}, |
524 | {AUD_PHACC_FREQ_8MSB, 0x34}, | 380 | {AUD_PHACC_FREQ_8MSB, 0x34}, |
525 | {AUD_PHACC_FREQ_8LSB, 0x4c}, | 381 | {AUD_PHACC_FREQ_8LSB, 0x4c}, |
526 | {AUD_RATE_ADJ1, 0x00000100}, | 382 | {AUD_RATE_ADJ1, 0x00000100}, |
527 | {AUD_RATE_ADJ2, 0x00000200}, | 383 | {AUD_RATE_ADJ2, 0x00000200}, |
528 | {AUD_RATE_ADJ3, 0x00000300}, | 384 | {AUD_RATE_ADJ3, 0x00000300}, |
529 | {AUD_RATE_ADJ4, 0x00000400}, | 385 | {AUD_RATE_ADJ4, 0x00000400}, |
530 | {AUD_RATE_ADJ5, 0x00000500}, | 386 | {AUD_RATE_ADJ5, 0x00000500}, |
531 | {AUD_THR_FR, 0x00000000}, | 387 | {AUD_THR_FR, 0x00000000}, |
532 | {AAGC_HYST, 0x0000001a}, | 388 | {AAGC_HYST, 0x0000001a}, |
533 | {AUD_PILOT_BQD_1_K0, 0x0000755b}, | 389 | {AUD_PILOT_BQD_1_K0, 0x0000755b}, |
534 | {AUD_PILOT_BQD_1_K1, 0x00551340}, | 390 | {AUD_PILOT_BQD_1_K1, 0x00551340}, |
535 | {AUD_PILOT_BQD_1_K2, 0x006d30be}, | 391 | {AUD_PILOT_BQD_1_K2, 0x006d30be}, |
536 | {AUD_PILOT_BQD_1_K3, 0xffd394af}, | 392 | {AUD_PILOT_BQD_1_K3, 0xffd394af}, |
537 | {AUD_PILOT_BQD_1_K4, 0x00400000}, | 393 | {AUD_PILOT_BQD_1_K4, 0x00400000}, |
538 | {AUD_PILOT_BQD_2_K0, 0x00040000}, | 394 | {AUD_PILOT_BQD_2_K0, 0x00040000}, |
539 | {AUD_PILOT_BQD_2_K1, 0x002a4841}, | 395 | {AUD_PILOT_BQD_2_K1, 0x002a4841}, |
540 | {AUD_PILOT_BQD_2_K2, 0x00400000}, | 396 | {AUD_PILOT_BQD_2_K2, 0x00400000}, |
541 | {AUD_PILOT_BQD_2_K3, 0x00000000}, | 397 | {AUD_PILOT_BQD_2_K3, 0x00000000}, |
542 | {AUD_PILOT_BQD_2_K4, 0x00000000}, | 398 | {AUD_PILOT_BQD_2_K4, 0x00000000}, |
543 | {AUD_MODE_CHG_TIMER, 0x00000040}, | 399 | {AUD_MODE_CHG_TIMER, 0x00000040}, |
544 | {AUD_AFE_12DB_EN, 0x00000001}, | 400 | {AUD_AFE_12DB_EN, 0x00000001}, |
545 | {AUD_CORDIC_SHIFT_0, 0x00000007}, | 401 | {AUD_CORDIC_SHIFT_0, 0x00000007}, |
546 | {AUD_CORDIC_SHIFT_1, 0x00000007}, | 402 | {AUD_CORDIC_SHIFT_1, 0x00000007}, |
547 | {AUD_DEEMPH0_G0, 0x00000380}, | 403 | {AUD_DEEMPH0_G0, 0x00000380}, |
548 | {AUD_DEEMPH1_G0, 0x00000380}, | 404 | {AUD_DEEMPH1_G0, 0x00000380}, |
549 | {AUD_DCOC_0_SRC, 0x0000001a}, | 405 | {AUD_DCOC_0_SRC, 0x0000001a}, |
550 | {AUD_DCOC0_SHIFT, 0x00000000}, | 406 | {AUD_DCOC0_SHIFT, 0x00000000}, |
551 | {AUD_DCOC_0_SHIFT_IN0, 0x0000000a}, | 407 | {AUD_DCOC_0_SHIFT_IN0, 0x0000000a}, |
552 | {AUD_DCOC_0_SHIFT_IN1, 0x00000008}, | 408 | {AUD_DCOC_0_SHIFT_IN1, 0x00000008}, |
553 | {AUD_DCOC_PASS_IN, 0x00000003}, | 409 | {AUD_DCOC_PASS_IN, 0x00000003}, |
554 | {AUD_IIR3_0_SEL, 0x00000021}, | 410 | {AUD_IIR3_0_SEL, 0x00000021}, |
555 | {AUD_DN2_AFC, 0x00000002}, | 411 | {AUD_DN2_AFC, 0x00000002}, |
556 | {AUD_DCOC_1_SRC, 0x0000001b}, | 412 | {AUD_DCOC_1_SRC, 0x0000001b}, |
557 | {AUD_DCOC1_SHIFT, 0x00000000}, | 413 | {AUD_DCOC1_SHIFT, 0x00000000}, |
558 | {AUD_DCOC_1_SHIFT_IN0, 0x0000000a}, | 414 | {AUD_DCOC_1_SHIFT_IN0, 0x0000000a}, |
559 | {AUD_DCOC_1_SHIFT_IN1, 0x00000008}, | 415 | {AUD_DCOC_1_SHIFT_IN1, 0x00000008}, |
560 | {AUD_IIR3_1_SEL, 0x00000023}, | 416 | {AUD_IIR3_1_SEL, 0x00000023}, |
561 | {AUD_RDSI_SEL, 0x00000017}, | 417 | {AUD_RDSI_SEL, 0x00000017}, |
562 | {AUD_RDSI_SHIFT, 0x00000000}, | 418 | {AUD_RDSI_SHIFT, 0x00000000}, |
563 | {AUD_RDSQ_SEL, 0x00000017}, | 419 | {AUD_RDSQ_SEL, 0x00000017}, |
564 | {AUD_RDSQ_SHIFT, 0x00000000}, | 420 | {AUD_RDSQ_SHIFT, 0x00000000}, |
565 | {AUD_PLL_INT, 0x0000001e}, | 421 | {AUD_PLL_INT, 0x0000001e}, |
566 | {AUD_PLL_DDS, 0x00000000}, | 422 | {AUD_PLL_DDS, 0x00000000}, |
567 | {AUD_PLL_FRAC, 0x0000e542}, | 423 | {AUD_PLL_FRAC, 0x0000e542}, |
568 | {AUD_POLYPH80SCALEFAC, 0x00000001}, | 424 | {AUD_POLYPH80SCALEFAC, 0x00000001}, |
569 | {AUD_START_TIMER, 0x00000000}, | 425 | {AUD_START_TIMER, 0x00000000}, |
570 | { /* end of list */ }, | 426 | { /* end of list */ }, |
571 | }; | 427 | }; |
572 | 428 | ||
573 | static const struct rlist a2_bg[] = { | 429 | static const struct rlist a2_bg[] = { |
574 | {AUD_DMD_RA_DDS, 0x002a4f2f}, | 430 | {AUD_DMD_RA_DDS, 0x002a4f2f}, |
575 | {AUD_C1_UP_THR, 0x00007000}, | 431 | {AUD_C1_UP_THR, 0x00007000}, |
576 | {AUD_C1_LO_THR, 0x00005400}, | 432 | {AUD_C1_LO_THR, 0x00005400}, |
577 | {AUD_C2_UP_THR, 0x00005400}, | 433 | {AUD_C2_UP_THR, 0x00005400}, |
578 | {AUD_C2_LO_THR, 0x00003000}, | 434 | {AUD_C2_LO_THR, 0x00003000}, |
579 | { /* end of list */ }, | 435 | { /* end of list */ }, |
580 | }; | 436 | }; |
581 | 437 | ||
582 | static const struct rlist a2_dk[] = { | 438 | static const struct rlist a2_dk[] = { |
583 | {AUD_DMD_RA_DDS, 0x002a4f2f}, | 439 | {AUD_DMD_RA_DDS, 0x002a4f2f}, |
584 | {AUD_C1_UP_THR, 0x00007000}, | 440 | {AUD_C1_UP_THR, 0x00007000}, |
585 | {AUD_C1_LO_THR, 0x00005400}, | 441 | {AUD_C1_LO_THR, 0x00005400}, |
586 | {AUD_C2_UP_THR, 0x00005400}, | 442 | {AUD_C2_UP_THR, 0x00005400}, |
587 | {AUD_C2_LO_THR, 0x00003000}, | 443 | {AUD_C2_LO_THR, 0x00003000}, |
588 | {AUD_DN0_FREQ, 0x00003a1c}, | 444 | {AUD_DN0_FREQ, 0x00003a1c}, |
589 | {AUD_DN2_FREQ, 0x0000d2e0}, | 445 | {AUD_DN2_FREQ, 0x0000d2e0}, |
590 | { /* end of list */ }, | 446 | { /* end of list */ }, |
591 | }; | 447 | }; |
592 | /* unknown, probably NTSC-M */ | 448 | |
593 | static const struct rlist a2_m[] = { | 449 | static const struct rlist a1_i[] = { |
594 | {AUD_DMD_RA_DDS, 0x002a0425}, | 450 | {AUD_ERRLOGPERIOD_R, 0x00000064}, |
595 | {AUD_C1_UP_THR, 0x00003c00}, | 451 | {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, |
596 | {AUD_C1_LO_THR, 0x00003000}, | 452 | {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f}, |
597 | {AUD_C2_UP_THR, 0x00006000}, | 453 | {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f}, |
598 | {AUD_C2_LO_THR, 0x00003c00}, | 454 | {AUD_PDF_DDS_CNST_BYTE2, 0x06}, |
599 | {AUD_DEEMPH0_A0, 0x00007a80}, | 455 | {AUD_PDF_DDS_CNST_BYTE1, 0x82}, |
600 | {AUD_DEEMPH1_A0, 0x00007a80}, | 456 | {AUD_PDF_DDS_CNST_BYTE0, 0x12}, |
601 | {AUD_DEEMPH0_G0, 0x00001200}, | 457 | {AUD_QAM_MODE, 0x05}, |
602 | {AUD_DEEMPH1_G0, 0x00001200}, | 458 | {AUD_PHACC_FREQ_8MSB, 0x3a}, |
603 | {AUD_DN0_FREQ, 0x0000283b}, | 459 | {AUD_PHACC_FREQ_8LSB, 0x93}, |
604 | {AUD_DN1_FREQ, 0x00003418}, | 460 | {AUD_DMD_RA_DDS, 0x002a4f2f}, |
605 | {AUD_DN2_FREQ, 0x000029c7}, | 461 | {AUD_PLL_INT, 0x0000001e}, |
606 | {AUD_POLY0_DDS_CONSTANT, 0x000a7540}, | 462 | {AUD_PLL_DDS, 0x00000004}, |
463 | {AUD_PLL_FRAC, 0x0000e542}, | ||
464 | {AUD_RATE_ADJ1, 0x00000100}, | ||
465 | {AUD_RATE_ADJ2, 0x00000200}, | ||
466 | {AUD_RATE_ADJ3, 0x00000300}, | ||
467 | {AUD_RATE_ADJ4, 0x00000400}, | ||
468 | {AUD_RATE_ADJ5, 0x00000500}, | ||
469 | {AUD_THR_FR, 0x00000000}, | ||
470 | {AUD_PILOT_BQD_1_K0, 0x0000755b}, | ||
471 | {AUD_PILOT_BQD_1_K1, 0x00551340}, | ||
472 | {AUD_PILOT_BQD_1_K2, 0x006d30be}, | ||
473 | {AUD_PILOT_BQD_1_K3, 0xffd394af}, | ||
474 | {AUD_PILOT_BQD_1_K4, 0x00400000}, | ||
475 | {AUD_PILOT_BQD_2_K0, 0x00040000}, | ||
476 | {AUD_PILOT_BQD_2_K1, 0x002a4841}, | ||
477 | {AUD_PILOT_BQD_2_K2, 0x00400000}, | ||
478 | {AUD_PILOT_BQD_2_K3, 0x00000000}, | ||
479 | {AUD_PILOT_BQD_2_K4, 0x00000000}, | ||
480 | {AUD_MODE_CHG_TIMER, 0x00000060}, | ||
481 | {AUD_AFE_12DB_EN, 0x00000001}, | ||
482 | {AAGC_HYST, 0x0000000a}, | ||
483 | {AUD_CORDIC_SHIFT_0, 0x00000007}, | ||
484 | {AUD_CORDIC_SHIFT_1, 0x00000007}, | ||
485 | {AUD_C1_UP_THR, 0x00007000}, | ||
486 | {AUD_C1_LO_THR, 0x00005400}, | ||
487 | {AUD_C2_UP_THR, 0x00005400}, | ||
488 | {AUD_C2_LO_THR, 0x00003000}, | ||
489 | {AUD_DCOC_0_SRC, 0x0000001a}, | ||
490 | {AUD_DCOC0_SHIFT, 0x00000000}, | ||
491 | {AUD_DCOC_0_SHIFT_IN0, 0x0000000a}, | ||
492 | {AUD_DCOC_0_SHIFT_IN1, 0x00000008}, | ||
493 | {AUD_DCOC_PASS_IN, 0x00000003}, | ||
494 | {AUD_IIR3_0_SEL, 0x00000021}, | ||
495 | {AUD_DN2_AFC, 0x00000002}, | ||
496 | {AUD_DCOC_1_SRC, 0x0000001b}, | ||
497 | {AUD_DCOC1_SHIFT, 0x00000000}, | ||
498 | {AUD_DCOC_1_SHIFT_IN0, 0x0000000a}, | ||
499 | {AUD_DCOC_1_SHIFT_IN1, 0x00000008}, | ||
500 | {AUD_IIR3_1_SEL, 0x00000023}, | ||
501 | {AUD_DN0_FREQ, 0x000035a3}, | ||
502 | {AUD_DN2_FREQ, 0x000029c7}, | ||
503 | {AUD_CRDC0_SRC_SEL, 0x00000511}, | ||
504 | {AUD_IIR1_0_SEL, 0x00000001}, | ||
505 | {AUD_IIR1_1_SEL, 0x00000000}, | ||
506 | {AUD_IIR3_2_SEL, 0x00000003}, | ||
507 | {AUD_IIR3_2_SHIFT, 0x00000000}, | ||
508 | {AUD_IIR3_0_SEL, 0x00000002}, | ||
509 | {AUD_IIR2_0_SEL, 0x00000021}, | ||
510 | {AUD_IIR2_0_SHIFT, 0x00000002}, | ||
511 | {AUD_DEEMPH0_SRC_SEL, 0x0000000b}, | ||
512 | {AUD_DEEMPH1_SRC_SEL, 0x0000000b}, | ||
513 | {AUD_POLYPH80SCALEFAC, 0x00000001}, | ||
514 | {AUD_START_TIMER, 0x00000000}, | ||
607 | { /* end of list */ }, | 515 | { /* end of list */ }, |
608 | }; | 516 | }; |
609 | 517 | ||
610 | static const struct rlist a2_deemph50[] = { | 518 | static const struct rlist am_l[] = { |
611 | {AUD_DEEMPH0_G0, 0x00000380}, | 519 | {AUD_ERRLOGPERIOD_R, 0x00000064}, |
612 | {AUD_DEEMPH1_G0, 0x00000380}, | 520 | {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF}, |
613 | {AUD_DEEMPHGAIN_R, 0x000011e1}, | 521 | {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F}, |
614 | {AUD_DEEMPHNUMER1_R, 0x0002a7bc}, | 522 | {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F}, |
615 | {AUD_DEEMPHNUMER2_R, 0x0003023c}, | 523 | {AUD_PDF_DDS_CNST_BYTE2, 0x48}, |
616 | { /* end of list */ }, | 524 | {AUD_PDF_DDS_CNST_BYTE1, 0x3D}, |
525 | {AUD_QAM_MODE, 0x00}, | ||
526 | {AUD_PDF_DDS_CNST_BYTE0, 0xf5}, | ||
527 | {AUD_PHACC_FREQ_8MSB, 0x3a}, | ||
528 | {AUD_PHACC_FREQ_8LSB, 0x4a}, | ||
529 | {AUD_DEEMPHGAIN_R, 0x00006680}, | ||
530 | {AUD_DEEMPHNUMER1_R, 0x000353DE}, | ||
531 | {AUD_DEEMPHNUMER2_R, 0x000001B1}, | ||
532 | {AUD_DEEMPHDENOM1_R, 0x0000F3D0}, | ||
533 | {AUD_DEEMPHDENOM2_R, 0x00000000}, | ||
534 | {AUD_FM_MODE_ENABLE, 0x00000007}, | ||
535 | {AUD_POLYPH80SCALEFAC, 0x00000003}, | ||
536 | {AUD_AFE_12DB_EN, 0x00000001}, | ||
537 | {AAGC_GAIN, 0x00000000}, | ||
538 | {AAGC_HYST, 0x00000018}, | ||
539 | {AAGC_DEF, 0x00000020}, | ||
540 | {AUD_DN0_FREQ, 0x00000000}, | ||
541 | {AUD_POLY0_DDS_CONSTANT, 0x000E4DB2}, | ||
542 | {AUD_DCOC_0_SRC, 0x00000021}, | ||
543 | {AUD_IIR1_0_SEL, 0x00000000}, | ||
544 | {AUD_IIR1_0_SHIFT, 0x00000007}, | ||
545 | {AUD_IIR1_1_SEL, 0x00000002}, | ||
546 | {AUD_IIR1_1_SHIFT, 0x00000000}, | ||
547 | {AUD_DCOC_1_SRC, 0x00000003}, | ||
548 | {AUD_DCOC1_SHIFT, 0x00000000}, | ||
549 | {AUD_DCOC_PASS_IN, 0x00000000}, | ||
550 | {AUD_IIR1_2_SEL, 0x00000023}, | ||
551 | {AUD_IIR1_2_SHIFT, 0x00000000}, | ||
552 | {AUD_IIR1_3_SEL, 0x00000004}, | ||
553 | {AUD_IIR1_3_SHIFT, 0x00000007}, | ||
554 | {AUD_IIR1_4_SEL, 0x00000005}, | ||
555 | {AUD_IIR1_4_SHIFT, 0x00000007}, | ||
556 | {AUD_IIR3_0_SEL, 0x00000007}, | ||
557 | {AUD_IIR3_0_SHIFT, 0x00000000}, | ||
558 | {AUD_DEEMPH0_SRC_SEL, 0x00000011}, | ||
559 | {AUD_DEEMPH0_SHIFT, 0x00000000}, | ||
560 | {AUD_DEEMPH0_G0, 0x00007000}, | ||
561 | {AUD_DEEMPH0_A0, 0x00000000}, | ||
562 | {AUD_DEEMPH0_B0, 0x00000000}, | ||
563 | {AUD_DEEMPH0_A1, 0x00000000}, | ||
564 | {AUD_DEEMPH0_B1, 0x00000000}, | ||
565 | {AUD_DEEMPH1_SRC_SEL, 0x00000011}, | ||
566 | {AUD_DEEMPH1_SHIFT, 0x00000000}, | ||
567 | {AUD_DEEMPH1_G0, 0x00007000}, | ||
568 | {AUD_DEEMPH1_A0, 0x00000000}, | ||
569 | {AUD_DEEMPH1_B0, 0x00000000}, | ||
570 | {AUD_DEEMPH1_A1, 0x00000000}, | ||
571 | {AUD_DEEMPH1_B1, 0x00000000}, | ||
572 | {AUD_OUT0_SEL, 0x0000003F}, | ||
573 | {AUD_OUT1_SEL, 0x0000003F}, | ||
574 | {AUD_DMD_RA_DDS, 0x00F5C285}, | ||
575 | {AUD_PLL_INT, 0x0000001E}, | ||
576 | {AUD_PLL_DDS, 0x00000000}, | ||
577 | {AUD_PLL_FRAC, 0x0000E542}, | ||
578 | {AUD_RATE_ADJ1, 0x00000100}, | ||
579 | {AUD_RATE_ADJ2, 0x00000200}, | ||
580 | {AUD_RATE_ADJ3, 0x00000300}, | ||
581 | {AUD_RATE_ADJ4, 0x00000400}, | ||
582 | {AUD_RATE_ADJ5, 0x00000500}, | ||
583 | {AUD_RATE_THRES_DMD, 0x000000C0}, | ||
584 | { /* end of list */ }, | ||
617 | }; | 585 | }; |
618 | 586 | ||
619 | static const struct rlist a2_deemph75[] = { | 587 | static const struct rlist a2_deemph50[] = { |
620 | {AUD_DEEMPH0_G0, 0x00000480}, | 588 | {AUD_DEEMPH0_G0, 0x00000380}, |
621 | {AUD_DEEMPH1_G0, 0x00000480}, | 589 | {AUD_DEEMPH1_G0, 0x00000380}, |
622 | {AUD_DEEMPHGAIN_R, 0x00009000}, | 590 | {AUD_DEEMPHGAIN_R, 0x000011e1}, |
623 | {AUD_DEEMPHNUMER1_R, 0x000353de}, | 591 | {AUD_DEEMPHNUMER1_R, 0x0002a7bc}, |
624 | {AUD_DEEMPHNUMER2_R, 0x000001b1}, | 592 | {AUD_DEEMPHNUMER2_R, 0x0003023c}, |
625 | { /* end of list */ }, | 593 | { /* end of list */ }, |
626 | }; | 594 | }; |
627 | 595 | ||
628 | set_audio_start(core, SEL_A2); | 596 | set_audio_start(core, SEL_A2); |
629 | set_audio_registers(core, a2_common); | ||
630 | switch (core->tvaudio) { | 597 | switch (core->tvaudio) { |
631 | case WW_A2_BG: | 598 | case WW_BG: |
632 | dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__); | 599 | dprintk("%s PAL-BG A1/2 (status: known-good)\n", __FUNCTION__); |
633 | set_audio_registers(core, a2_bg); | 600 | set_audio_registers(core, a2_bgdk_common); |
634 | set_audio_registers(core, a2_deemph50); | 601 | set_audio_registers(core, a2_bg); |
602 | set_audio_registers(core, a2_deemph50); | ||
635 | break; | 603 | break; |
636 | case WW_A2_DK: | 604 | case WW_DK: |
637 | dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__); | 605 | dprintk("%s PAL-DK A1/2 (status: known-good)\n", __FUNCTION__); |
638 | set_audio_registers(core, a2_dk); | 606 | set_audio_registers(core, a2_bgdk_common); |
639 | set_audio_registers(core, a2_deemph50); | 607 | set_audio_registers(core, a2_dk); |
608 | set_audio_registers(core, a2_deemph50); | ||
640 | break; | 609 | break; |
641 | case WW_A2_M: | 610 | case WW_I: |
642 | dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__); | 611 | dprintk("%s PAL-I A1 (status: known-good)\n", __FUNCTION__); |
643 | set_audio_registers(core, a2_m); | 612 | set_audio_registers(core, a1_i); |
644 | set_audio_registers(core, a2_deemph75); | 613 | set_audio_registers(core, a2_deemph50); |
614 | break; | ||
615 | case WW_L: | ||
616 | dprintk("%s AM-L (status: devel)\n", __FUNCTION__); | ||
617 | set_audio_registers(core, am_l); | ||
618 | break; | ||
619 | default: | ||
620 | dprintk("%s Warning: wrong value\n", __FUNCTION__); | ||
621 | return; | ||
645 | break; | 622 | break; |
646 | }; | 623 | }; |
647 | 624 | ||
@@ -656,71 +633,71 @@ static void set_audio_standard_EIAJ(struct cx88_core *core) | |||
656 | 633 | ||
657 | { /* end of list */ }, | 634 | { /* end of list */ }, |
658 | }; | 635 | }; |
659 | dprintk("%s (status: unknown)\n",__FUNCTION__); | 636 | dprintk("%s (status: unknown)\n", __FUNCTION__); |
660 | 637 | ||
661 | set_audio_start(core, SEL_EIAJ); | 638 | set_audio_start(core, SEL_EIAJ); |
662 | set_audio_registers(core, eiaj); | 639 | set_audio_registers(core, eiaj); |
663 | set_audio_finish(core, EN_EIAJ_AUTO_STEREO); | 640 | set_audio_finish(core, EN_EIAJ_AUTO_STEREO); |
664 | } | 641 | } |
665 | 642 | ||
666 | static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph) | 643 | static void set_audio_standard_FM(struct cx88_core *core, |
644 | enum cx88_deemph_type deemph) | ||
667 | { | 645 | { |
668 | static const struct rlist fm_deemph_50[] = { | 646 | static const struct rlist fm_deemph_50[] = { |
669 | { AUD_DEEMPH0_G0, 0x0C45 }, | 647 | {AUD_DEEMPH0_G0, 0x0C45}, |
670 | { AUD_DEEMPH0_A0, 0x6262 }, | 648 | {AUD_DEEMPH0_A0, 0x6262}, |
671 | { AUD_DEEMPH0_B0, 0x1C29 }, | 649 | {AUD_DEEMPH0_B0, 0x1C29}, |
672 | { AUD_DEEMPH0_A1, 0x3FC66}, | 650 | {AUD_DEEMPH0_A1, 0x3FC66}, |
673 | { AUD_DEEMPH0_B1, 0x399A }, | 651 | {AUD_DEEMPH0_B1, 0x399A}, |
674 | 652 | ||
675 | { AUD_DEEMPH1_G0, 0x0D80 }, | 653 | {AUD_DEEMPH1_G0, 0x0D80}, |
676 | { AUD_DEEMPH1_A0, 0x6262 }, | 654 | {AUD_DEEMPH1_A0, 0x6262}, |
677 | { AUD_DEEMPH1_B0, 0x1C29 }, | 655 | {AUD_DEEMPH1_B0, 0x1C29}, |
678 | { AUD_DEEMPH1_A1, 0x3FC66}, | 656 | {AUD_DEEMPH1_A1, 0x3FC66}, |
679 | { AUD_DEEMPH1_B1, 0x399A}, | 657 | {AUD_DEEMPH1_B1, 0x399A}, |
680 | 658 | ||
681 | { AUD_POLYPH80SCALEFAC, 0x0003}, | 659 | {AUD_POLYPH80SCALEFAC, 0x0003}, |
682 | { /* end of list */ }, | 660 | { /* end of list */ }, |
683 | }; | 661 | }; |
684 | static const struct rlist fm_deemph_75[] = { | 662 | static const struct rlist fm_deemph_75[] = { |
685 | { AUD_DEEMPH0_G0, 0x091B }, | 663 | {AUD_DEEMPH0_G0, 0x091B}, |
686 | { AUD_DEEMPH0_A0, 0x6B68 }, | 664 | {AUD_DEEMPH0_A0, 0x6B68}, |
687 | { AUD_DEEMPH0_B0, 0x11EC }, | 665 | {AUD_DEEMPH0_B0, 0x11EC}, |
688 | { AUD_DEEMPH0_A1, 0x3FC66}, | 666 | {AUD_DEEMPH0_A1, 0x3FC66}, |
689 | { AUD_DEEMPH0_B1, 0x399A }, | 667 | {AUD_DEEMPH0_B1, 0x399A}, |
690 | 668 | ||
691 | { AUD_DEEMPH1_G0, 0x0AA0 }, | 669 | {AUD_DEEMPH1_G0, 0x0AA0}, |
692 | { AUD_DEEMPH1_A0, 0x6B68 }, | 670 | {AUD_DEEMPH1_A0, 0x6B68}, |
693 | { AUD_DEEMPH1_B0, 0x11EC }, | 671 | {AUD_DEEMPH1_B0, 0x11EC}, |
694 | { AUD_DEEMPH1_A1, 0x3FC66}, | 672 | {AUD_DEEMPH1_A1, 0x3FC66}, |
695 | { AUD_DEEMPH1_B1, 0x399A}, | 673 | {AUD_DEEMPH1_B1, 0x399A}, |
696 | 674 | ||
697 | { AUD_POLYPH80SCALEFAC, 0x0003}, | 675 | {AUD_POLYPH80SCALEFAC, 0x0003}, |
698 | { /* end of list */ }, | 676 | { /* end of list */ }, |
699 | }; | 677 | }; |
700 | 678 | ||
701 | /* It is enough to leave default values? */ | 679 | /* It is enough to leave default values? */ |
702 | static const struct rlist fm_no_deemph[] = { | 680 | static const struct rlist fm_no_deemph[] = { |
703 | 681 | ||
704 | { AUD_POLYPH80SCALEFAC, 0x0003}, | 682 | {AUD_POLYPH80SCALEFAC, 0x0003}, |
705 | { /* end of list */ }, | 683 | { /* end of list */ }, |
706 | }; | 684 | }; |
707 | 685 | ||
708 | dprintk("%s (status: unknown)\n",__FUNCTION__); | 686 | dprintk("%s (status: unknown)\n", __FUNCTION__); |
709 | set_audio_start(core, SEL_FMRADIO); | 687 | set_audio_start(core, SEL_FMRADIO); |
710 | 688 | ||
711 | switch (deemph) | 689 | switch (deemph) { |
712 | { | 690 | case FM_NO_DEEMPH: |
713 | case FM_NO_DEEMPH: | 691 | set_audio_registers(core, fm_no_deemph); |
714 | set_audio_registers(core, fm_no_deemph); | 692 | break; |
715 | break; | ||
716 | 693 | ||
717 | case FM_DEEMPH_50: | 694 | case FM_DEEMPH_50: |
718 | set_audio_registers(core, fm_deemph_50); | 695 | set_audio_registers(core, fm_deemph_50); |
719 | break; | 696 | break; |
720 | 697 | ||
721 | case FM_DEEMPH_75: | 698 | case FM_DEEMPH_75: |
722 | set_audio_registers(core, fm_deemph_75); | 699 | set_audio_registers(core, fm_deemph_75); |
723 | break; | 700 | break; |
724 | } | 701 | } |
725 | 702 | ||
726 | set_audio_finish(core, EN_FMRADIO_AUTO_STEREO); | 703 | set_audio_finish(core, EN_FMRADIO_AUTO_STEREO); |
@@ -728,36 +705,64 @@ static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type | |||
728 | 705 | ||
729 | /* ----------------------------------------------------------- */ | 706 | /* ----------------------------------------------------------- */ |
730 | 707 | ||
708 | int cx88_detect_nicam(struct cx88_core *core) | ||
709 | { | ||
710 | int i, j = 0; | ||
711 | |||
712 | dprintk("start nicam autodetect.\n"); | ||
713 | |||
714 | for (i = 0; i < 6; i++) { | ||
715 | /* if bit1=1 then nicam is detected */ | ||
716 | j += ((cx_read(AUD_NICAM_STATUS2) & 0x02) >> 1); | ||
717 | |||
718 | /* 3x detected: absolutly sure now */ | ||
719 | if (j == 3) { | ||
720 | dprintk("nicam is detected.\n"); | ||
721 | return 1; | ||
722 | } | ||
723 | |||
724 | /* wait a little bit for next reading status */ | ||
725 | msleep(10); | ||
726 | } | ||
727 | |||
728 | dprintk("nicam is not detected.\n"); | ||
729 | return 0; | ||
730 | } | ||
731 | |||
731 | void cx88_set_tvaudio(struct cx88_core *core) | 732 | void cx88_set_tvaudio(struct cx88_core *core) |
732 | { | 733 | { |
733 | switch (core->tvaudio) { | 734 | switch (core->tvaudio) { |
734 | case WW_BTSC: | 735 | case WW_BTSC: |
735 | set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO); | 736 | set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO); |
736 | break; | 737 | break; |
737 | case WW_NICAM_BGDKL: | 738 | case WW_BG: |
738 | set_audio_standard_NICAM_L(core,0); | 739 | case WW_DK: |
739 | break; | 740 | case WW_I: |
740 | case WW_NICAM_I: | 741 | case WW_L: |
741 | set_audio_standard_PAL_I(core,0); | 742 | /* prepare all dsp registers */ |
742 | break; | 743 | set_audio_standard_A2(core, EN_A2_FORCE_MONO1); |
743 | case WW_A2_BG: | 744 | |
744 | case WW_A2_DK: | 745 | /* set nicam mode - otherwise |
745 | case WW_A2_M: | 746 | AUD_NICAM_STATUS2 contains wrong values */ |
746 | set_audio_standard_A2(core, EN_A2_FORCE_MONO1); | 747 | set_audio_standard_NICAM(core, EN_NICAM_AUTO_STEREO); |
748 | if (0 == cx88_detect_nicam(core)) { | ||
749 | /* fall back to fm / am mono */ | ||
750 | set_audio_standard_A2(core, EN_A2_FORCE_MONO1); | ||
751 | core->use_nicam = 0; | ||
752 | } else { | ||
753 | core->use_nicam = 1; | ||
754 | } | ||
747 | break; | 755 | break; |
748 | case WW_EIAJ: | 756 | case WW_EIAJ: |
749 | set_audio_standard_EIAJ(core); | 757 | set_audio_standard_EIAJ(core); |
750 | break; | 758 | break; |
751 | case WW_FM: | 759 | case WW_FM: |
752 | set_audio_standard_FM(core,FM_NO_DEEMPH); | 760 | set_audio_standard_FM(core, FM_NO_DEEMPH); |
753 | break; | ||
754 | case WW_SYSTEM_L_AM: | ||
755 | set_audio_standard_NICAM_L(core, 1); | ||
756 | break; | 761 | break; |
757 | case WW_NONE: | 762 | case WW_NONE: |
758 | default: | 763 | default: |
759 | printk("%s/0: unknown tv audio mode [%d]\n", | 764 | printk("%s/0: unknown tv audio mode [%d]\n", |
760 | core->name, core->tvaudio); | 765 | core->name, core->tvaudio); |
761 | break; | 766 | break; |
762 | } | 767 | } |
763 | return; | 768 | return; |
@@ -766,24 +771,16 @@ void cx88_set_tvaudio(struct cx88_core *core) | |||
766 | void cx88_newstation(struct cx88_core *core) | 771 | void cx88_newstation(struct cx88_core *core) |
767 | { | 772 | { |
768 | core->audiomode_manual = UNSET; | 773 | core->audiomode_manual = UNSET; |
769 | |||
770 | switch (core->tvaudio) { | ||
771 | case WW_SYSTEM_L_AM: | ||
772 | /* try nicam ... */ | ||
773 | core->audiomode_current = V4L2_TUNER_MODE_STEREO; | ||
774 | set_audio_standard_NICAM_L(core, 1); | ||
775 | break; | ||
776 | } | ||
777 | } | 774 | } |
778 | 775 | ||
779 | void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) | 776 | void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) |
780 | { | 777 | { |
781 | static char *m[] = {"stereo", "dual mono", "mono", "sap"}; | 778 | static char *m[] = { "stereo", "dual mono", "mono", "sap" }; |
782 | static char *p[] = {"no pilot", "pilot c1", "pilot c2", "?"}; | 779 | static char *p[] = { "no pilot", "pilot c1", "pilot c2", "?" }; |
783 | u32 reg,mode,pilot; | 780 | u32 reg, mode, pilot; |
784 | 781 | ||
785 | reg = cx_read(AUD_STATUS); | 782 | reg = cx_read(AUD_STATUS); |
786 | mode = reg & 0x03; | 783 | mode = reg & 0x03; |
787 | pilot = (reg >> 2) & 0x03; | 784 | pilot = (reg >> 2) & 0x03; |
788 | 785 | ||
789 | if (core->astat != reg) | 786 | if (core->astat != reg) |
@@ -800,14 +797,13 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) | |||
800 | 797 | ||
801 | # if 0 | 798 | # if 0 |
802 | t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP | | 799 | t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP | |
803 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; | 800 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; |
804 | t->rxsubchans = V4L2_TUNER_SUB_MONO; | 801 | t->rxsubchans = V4L2_TUNER_SUB_MONO; |
805 | t->audmode = V4L2_TUNER_MODE_MONO; | 802 | t->audmode = V4L2_TUNER_MODE_MONO; |
806 | 803 | ||
807 | switch (core->tvaudio) { | 804 | switch (core->tvaudio) { |
808 | case WW_BTSC: | 805 | case WW_BTSC: |
809 | t->capability = V4L2_TUNER_CAP_STEREO | | 806 | t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP; |
810 | V4L2_TUNER_CAP_SAP; | ||
811 | t->rxsubchans = V4L2_TUNER_SUB_STEREO; | 807 | t->rxsubchans = V4L2_TUNER_SUB_STEREO; |
812 | if (1 == pilot) { | 808 | if (1 == pilot) { |
813 | /* SAP */ | 809 | /* SAP */ |
@@ -819,13 +815,15 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) | |||
819 | case WW_A2_M: | 815 | case WW_A2_M: |
820 | if (1 == pilot) { | 816 | if (1 == pilot) { |
821 | /* stereo */ | 817 | /* stereo */ |
822 | t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; | 818 | t->rxsubchans = |
819 | V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; | ||
823 | if (0 == mode) | 820 | if (0 == mode) |
824 | t->audmode = V4L2_TUNER_MODE_STEREO; | 821 | t->audmode = V4L2_TUNER_MODE_STEREO; |
825 | } | 822 | } |
826 | if (2 == pilot) { | 823 | if (2 == pilot) { |
827 | /* dual language -- FIXME */ | 824 | /* dual language -- FIXME */ |
828 | t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | 825 | t->rxsubchans = |
826 | V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; | ||
829 | t->audmode = V4L2_TUNER_MODE_LANG1; | 827 | t->audmode = V4L2_TUNER_MODE_LANG1; |
830 | } | 828 | } |
831 | break; | 829 | break; |
@@ -840,7 +838,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) | |||
840 | t->audmode = V4L2_TUNER_MODE_STEREO; | 838 | t->audmode = V4L2_TUNER_MODE_STEREO; |
841 | t->rxsubchans |= V4L2_TUNER_SUB_STEREO; | 839 | t->rxsubchans |= V4L2_TUNER_SUB_STEREO; |
842 | } | 840 | } |
843 | break ; | 841 | break; |
844 | default: | 842 | default: |
845 | /* nothing */ | 843 | /* nothing */ |
846 | break; | 844 | break; |
@@ -851,7 +849,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) | |||
851 | 849 | ||
852 | void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) | 850 | void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) |
853 | { | 851 | { |
854 | u32 ctl = UNSET; | 852 | u32 ctl = UNSET; |
855 | u32 mask = UNSET; | 853 | u32 mask = UNSET; |
856 | 854 | ||
857 | if (manual) { | 855 | if (manual) { |
@@ -879,68 +877,58 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) | |||
879 | break; | 877 | break; |
880 | } | 878 | } |
881 | break; | 879 | break; |
882 | case WW_A2_BG: | 880 | case WW_BG: |
883 | case WW_A2_DK: | 881 | case WW_DK: |
884 | case WW_A2_M: | 882 | case WW_I: |
885 | switch (mode) { | 883 | case WW_L: |
886 | case V4L2_TUNER_MODE_MONO: | 884 | if (1 == core->use_nicam) { |
887 | case V4L2_TUNER_MODE_LANG1: | 885 | switch (mode) { |
888 | set_audio_standard_A2(core, EN_A2_FORCE_MONO1); | 886 | case V4L2_TUNER_MODE_MONO: |
889 | break; | 887 | case V4L2_TUNER_MODE_LANG1: |
890 | case V4L2_TUNER_MODE_LANG2: | 888 | set_audio_standard_NICAM(core, |
891 | set_audio_standard_A2(core, EN_A2_FORCE_MONO2); | 889 | EN_NICAM_FORCE_MONO1); |
892 | break; | 890 | break; |
893 | case V4L2_TUNER_MODE_STEREO: | 891 | case V4L2_TUNER_MODE_LANG2: |
894 | set_audio_standard_A2(core, EN_A2_FORCE_STEREO); | 892 | set_audio_standard_NICAM(core, |
895 | break; | 893 | EN_NICAM_FORCE_MONO2); |
896 | } | 894 | break; |
897 | break; | 895 | case V4L2_TUNER_MODE_STEREO: |
898 | case WW_NICAM_BGDKL: | 896 | set_audio_standard_NICAM(core, |
899 | switch (mode) { | 897 | EN_NICAM_FORCE_STEREO); |
900 | case V4L2_TUNER_MODE_MONO: | 898 | break; |
901 | ctl = EN_NICAM_FORCE_MONO1; | 899 | } |
902 | mask = 0x3f; | 900 | } else { |
903 | break; | 901 | if ((core->tvaudio == WW_I) || (core->tvaudio == WW_L)) { |
904 | case V4L2_TUNER_MODE_LANG1: | 902 | /* fall back to fm / am mono */ |
905 | ctl = EN_NICAM_AUTO_MONO2; | 903 | set_audio_standard_A2(core, EN_A2_FORCE_MONO1); |
906 | mask = 0x3f; | 904 | } else { |
907 | break; | 905 | /* TODO: Add A2 autodection */ |
908 | case V4L2_TUNER_MODE_STEREO: | 906 | switch (mode) { |
909 | ctl = EN_NICAM_FORCE_STEREO | EN_DMTRX_LR; | 907 | case V4L2_TUNER_MODE_MONO: |
910 | mask = 0x93f; | 908 | case V4L2_TUNER_MODE_LANG1: |
911 | break; | 909 | set_audio_standard_A2(core, |
912 | } | 910 | EN_A2_FORCE_MONO1); |
913 | break; | 911 | break; |
914 | case WW_SYSTEM_L_AM: | 912 | case V4L2_TUNER_MODE_LANG2: |
915 | switch (mode) { | 913 | set_audio_standard_A2(core, |
916 | case V4L2_TUNER_MODE_MONO: | 914 | EN_A2_FORCE_MONO2); |
917 | case V4L2_TUNER_MODE_LANG1: /* FIXME */ | 915 | break; |
918 | set_audio_standard_NICAM_L(core, 0); | 916 | case V4L2_TUNER_MODE_STEREO: |
919 | break; | 917 | set_audio_standard_A2(core, |
920 | case V4L2_TUNER_MODE_STEREO: | 918 | EN_A2_FORCE_STEREO); |
921 | set_audio_standard_NICAM_L(core, 1); | 919 | break; |
922 | break; | 920 | } |
923 | } | 921 | } |
924 | break; | ||
925 | case WW_NICAM_I: | ||
926 | switch (mode) { | ||
927 | case V4L2_TUNER_MODE_MONO: | ||
928 | case V4L2_TUNER_MODE_LANG1: | ||
929 | set_audio_standard_PAL_I(core, 0); | ||
930 | break; | ||
931 | case V4L2_TUNER_MODE_STEREO: | ||
932 | set_audio_standard_PAL_I(core, 1); | ||
933 | break; | ||
934 | } | 922 | } |
935 | break; | 923 | break; |
936 | case WW_FM: | 924 | case WW_FM: |
937 | switch (mode) { | 925 | switch (mode) { |
938 | case V4L2_TUNER_MODE_MONO: | 926 | case V4L2_TUNER_MODE_MONO: |
939 | ctl = EN_FMRADIO_FORCE_MONO; | 927 | ctl = EN_FMRADIO_FORCE_MONO; |
940 | mask = 0x3f; | 928 | mask = 0x3f; |
941 | break; | 929 | break; |
942 | case V4L2_TUNER_MODE_STEREO: | 930 | case V4L2_TUNER_MODE_STEREO: |
943 | ctl = EN_FMRADIO_AUTO_STEREO; | 931 | ctl = EN_FMRADIO_AUTO_STEREO; |
944 | mask = 0x3f; | 932 | mask = 0x3f; |
945 | break; | 933 | break; |
946 | } | 934 | } |
@@ -970,8 +958,8 @@ int cx88_audio_thread(void *data) | |||
970 | break; | 958 | break; |
971 | 959 | ||
972 | /* just monitor the audio status for now ... */ | 960 | /* just monitor the audio status for now ... */ |
973 | memset(&t,0,sizeof(t)); | 961 | memset(&t, 0, sizeof(t)); |
974 | cx88_get_stereo(core,&t); | 962 | cx88_get_stereo(core, &t); |
975 | 963 | ||
976 | if (UNSET != core->audiomode_manual) | 964 | if (UNSET != core->audiomode_manual) |
977 | /* manually set, don't do anything. */ | 965 | /* manually set, don't do anything. */ |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 3dbc074fb515..24a48f8a48c1 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -34,6 +34,9 @@ | |||
34 | 34 | ||
35 | #include "cx88.h" | 35 | #include "cx88.h" |
36 | 36 | ||
37 | /* Include V4L1 specific functions. Should be removed soon */ | ||
38 | #include <linux/videodev.h> | ||
39 | |||
37 | MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); | 40 | MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); |
38 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 41 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
39 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
@@ -100,7 +103,7 @@ static struct cx88_tvnorm tvnorms[] = { | |||
100 | .id = V4L2_STD_PAL_I, | 103 | .id = V4L2_STD_PAL_I, |
101 | .cxiformat = VideoFormatPAL, | 104 | .cxiformat = VideoFormatPAL, |
102 | .cxoformat = 0x181f0008, | 105 | .cxoformat = 0x181f0008, |
103 | },{ | 106 | },{ |
104 | .name = "PAL-M", | 107 | .name = "PAL-M", |
105 | .id = V4L2_STD_PAL_M, | 108 | .id = V4L2_STD_PAL_M, |
106 | .cxiformat = VideoFormatPALM, | 109 | .cxiformat = VideoFormatPALM, |
@@ -470,7 +473,7 @@ static int restart_video_queue(struct cx8800_dev *dev, | |||
470 | struct list_head *item; | 473 | struct list_head *item; |
471 | 474 | ||
472 | if (!list_empty(&q->active)) { | 475 | if (!list_empty(&q->active)) { |
473 | buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); | 476 | buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); |
474 | dprintk(2,"restart_queue [%p/%d]: restart dma\n", | 477 | dprintk(2,"restart_queue [%p/%d]: restart dma\n", |
475 | buf, buf->vb.i); | 478 | buf, buf->vb.i); |
476 | start_video_dma(dev, q, buf); | 479 | start_video_dma(dev, q, buf); |
@@ -486,7 +489,7 @@ static int restart_video_queue(struct cx8800_dev *dev, | |||
486 | for (;;) { | 489 | for (;;) { |
487 | if (list_empty(&q->queued)) | 490 | if (list_empty(&q->queued)) |
488 | return 0; | 491 | return 0; |
489 | buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); | 492 | buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); |
490 | if (NULL == prev) { | 493 | if (NULL == prev) { |
491 | list_del(&buf->vb.queue); | 494 | list_del(&buf->vb.queue); |
492 | list_add_tail(&buf->vb.queue,&q->active); | 495 | list_add_tail(&buf->vb.queue,&q->active); |
@@ -783,11 +786,11 @@ static int video_open(struct inode *inode, struct file *file) | |||
783 | cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); | 786 | cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); |
784 | } | 787 | } |
785 | 788 | ||
786 | return 0; | 789 | return 0; |
787 | } | 790 | } |
788 | 791 | ||
789 | static ssize_t | 792 | static ssize_t |
790 | video_read(struct file *file, char *data, size_t count, loff_t *ppos) | 793 | video_read(struct file *file, char __user *data, size_t count, loff_t *ppos) |
791 | { | 794 | { |
792 | struct cx8800_fh *fh = file->private_data; | 795 | struct cx8800_fh *fh = file->private_data; |
793 | 796 | ||
@@ -922,7 +925,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl) | |||
922 | { | 925 | { |
923 | /* struct cx88_core *core = dev->core; */ | 926 | /* struct cx88_core *core = dev->core; */ |
924 | struct cx88_ctrl *c = NULL; | 927 | struct cx88_ctrl *c = NULL; |
925 | u32 v_sat_value; | 928 | u32 v_sat_value; |
926 | u32 value; | 929 | u32 value; |
927 | int i; | 930 | int i; |
928 | 931 | ||
@@ -1187,7 +1190,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1187 | struct v4l2_format *f = arg; | 1190 | struct v4l2_format *f = arg; |
1188 | return cx8800_try_fmt(dev,fh,f); | 1191 | return cx8800_try_fmt(dev,fh,f); |
1189 | } | 1192 | } |
1190 | 1193 | #ifdef HAVE_V4L1 | |
1191 | /* --- streaming capture ------------------------------------- */ | 1194 | /* --- streaming capture ------------------------------------- */ |
1192 | case VIDIOCGMBUF: | 1195 | case VIDIOCGMBUF: |
1193 | { | 1196 | { |
@@ -1213,6 +1216,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1213 | } | 1216 | } |
1214 | return 0; | 1217 | return 0; |
1215 | } | 1218 | } |
1219 | #endif | ||
1216 | case VIDIOC_REQBUFS: | 1220 | case VIDIOC_REQBUFS: |
1217 | return videobuf_reqbufs(get_queue(fh), arg); | 1221 | return videobuf_reqbufs(get_queue(fh), arg); |
1218 | 1222 | ||
@@ -1244,7 +1248,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1244 | res_free(dev,fh,res); | 1248 | res_free(dev,fh,res); |
1245 | return 0; | 1249 | return 0; |
1246 | } | 1250 | } |
1247 | |||
1248 | default: | 1251 | default: |
1249 | return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl ); | 1252 | return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl ); |
1250 | } | 1253 | } |
@@ -1252,15 +1255,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1252 | } | 1255 | } |
1253 | 1256 | ||
1254 | int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | 1257 | int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, |
1255 | struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl) | 1258 | struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl) |
1256 | { | 1259 | { |
1257 | int err; | 1260 | int err; |
1258 | 1261 | ||
1262 | dprintk( 1, "CORE IOCTL: 0x%x\n", cmd ); | ||
1259 | if (video_debug > 1) | 1263 | if (video_debug > 1) |
1260 | cx88_print_ioctl(core->name,cmd); | 1264 | cx88_print_ioctl(core->name,cmd); |
1261 | printk( KERN_INFO "CORE IOCTL: 0x%x\n", cmd ); | ||
1262 | cx88_print_ioctl(core->name,cmd); | ||
1263 | dprintk( 1, "CORE IOCTL: 0x%x\n", cmd ); | ||
1264 | 1265 | ||
1265 | switch (cmd) { | 1266 | switch (cmd) { |
1266 | /* ---------- tv norms ---------- */ | 1267 | /* ---------- tv norms ---------- */ |
@@ -1401,7 +1402,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | |||
1401 | 1402 | ||
1402 | cx88_get_stereo(core ,t); | 1403 | cx88_get_stereo(core ,t); |
1403 | reg = cx_read(MO_DEVICE_STATUS); | 1404 | reg = cx_read(MO_DEVICE_STATUS); |
1404 | t->signal = (reg & (1<<5)) ? 0xffff : 0x0000; | 1405 | t->signal = (reg & (1<<5)) ? 0xffff : 0x0000; |
1405 | return 0; | 1406 | return 0; |
1406 | } | 1407 | } |
1407 | case VIDIOC_S_TUNER: | 1408 | case VIDIOC_S_TUNER: |
@@ -1488,7 +1489,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
1488 | struct v4l2_capability *cap = arg; | 1489 | struct v4l2_capability *cap = arg; |
1489 | 1490 | ||
1490 | memset(cap,0,sizeof(*cap)); | 1491 | memset(cap,0,sizeof(*cap)); |
1491 | strcpy(cap->driver, "cx8800"); | 1492 | strcpy(cap->driver, "cx8800"); |
1492 | strlcpy(cap->card, cx88_boards[core->board].name, | 1493 | strlcpy(cap->card, cx88_boards[core->board].name, |
1493 | sizeof(cap->card)); | 1494 | sizeof(cap->card)); |
1494 | sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); | 1495 | sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); |
@@ -1505,6 +1506,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
1505 | 1506 | ||
1506 | memset(t,0,sizeof(*t)); | 1507 | memset(t,0,sizeof(*t)); |
1507 | strcpy(t->name, "Radio"); | 1508 | strcpy(t->name, "Radio"); |
1509 | t->type = V4L2_TUNER_RADIO; | ||
1508 | 1510 | ||
1509 | cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t); | 1511 | cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t); |
1510 | return 0; | 1512 | return 0; |
@@ -1539,6 +1541,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
1539 | *id = 0; | 1541 | *id = 0; |
1540 | return 0; | 1542 | return 0; |
1541 | } | 1543 | } |
1544 | #ifdef HAVE_V4L1 | ||
1542 | case VIDIOCSTUNER: | 1545 | case VIDIOCSTUNER: |
1543 | { | 1546 | { |
1544 | struct video_tuner *v = arg; | 1547 | struct video_tuner *v = arg; |
@@ -1549,6 +1552,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
1549 | cx88_call_i2c_clients(core,VIDIOCSTUNER,v); | 1552 | cx88_call_i2c_clients(core,VIDIOCSTUNER,v); |
1550 | return 0; | 1553 | return 0; |
1551 | } | 1554 | } |
1555 | #endif | ||
1552 | case VIDIOC_S_TUNER: | 1556 | case VIDIOC_S_TUNER: |
1553 | { | 1557 | { |
1554 | struct v4l2_tuner *t = arg; | 1558 | struct v4l2_tuner *t = arg; |
@@ -1829,8 +1833,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1829 | 1833 | ||
1830 | /* print pci info */ | 1834 | /* print pci info */ |
1831 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); | 1835 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); |
1832 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); | 1836 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); |
1833 | printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " | 1837 | printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " |
1834 | "latency: %d, mmio: 0x%lx\n", core->name, | 1838 | "latency: %d, mmio: 0x%lx\n", core->name, |
1835 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, | 1839 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, |
1836 | dev->pci_lat,pci_resource_start(pci_dev,0)); | 1840 | dev->pci_lat,pci_resource_start(pci_dev,0)); |
@@ -1946,7 +1950,7 @@ fail_free: | |||
1946 | 1950 | ||
1947 | static void __devexit cx8800_finidev(struct pci_dev *pci_dev) | 1951 | static void __devexit cx8800_finidev(struct pci_dev *pci_dev) |
1948 | { | 1952 | { |
1949 | struct cx8800_dev *dev = pci_get_drvdata(pci_dev); | 1953 | struct cx8800_dev *dev = pci_get_drvdata(pci_dev); |
1950 | struct cx88_core *core = dev->core; | 1954 | struct cx88_core *core = dev->core; |
1951 | 1955 | ||
1952 | /* stop thread */ | 1956 | /* stop thread */ |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index f48dd4353568..b19d3a9e2298 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include <linux/i2c-algo-bit.h> | 24 | #include <linux/i2c-algo-bit.h> |
25 | #include <linux/videodev.h> | 25 | #include <linux/videodev2.h> |
26 | #include <linux/kdev_t.h> | 26 | #include <linux/kdev_t.h> |
27 | 27 | ||
28 | #include <media/tuner.h> | 28 | #include <media/tuner.h> |
@@ -148,7 +148,7 @@ extern struct sram_channel cx88_sram_channels[]; | |||
148 | #define CX88_BOARD_PIXELVIEW 3 | 148 | #define CX88_BOARD_PIXELVIEW 3 |
149 | #define CX88_BOARD_ATI_WONDER_PRO 4 | 149 | #define CX88_BOARD_ATI_WONDER_PRO 4 |
150 | #define CX88_BOARD_WINFAST2000XP_EXPERT 5 | 150 | #define CX88_BOARD_WINFAST2000XP_EXPERT 5 |
151 | #define CX88_BOARD_AVERTV_303 6 | 151 | #define CX88_BOARD_AVERTV_STUDIO_303 6 |
152 | #define CX88_BOARD_MSI_TVANYWHERE_MASTER 7 | 152 | #define CX88_BOARD_MSI_TVANYWHERE_MASTER 7 |
153 | #define CX88_BOARD_WINFAST_DV2000 8 | 153 | #define CX88_BOARD_WINFAST_DV2000 8 |
154 | #define CX88_BOARD_LEADTEK_PVR2000 9 | 154 | #define CX88_BOARD_LEADTEK_PVR2000 9 |
@@ -174,6 +174,11 @@ extern struct sram_channel cx88_sram_channels[]; | |||
174 | #define CX88_BOARD_ADSTECH_DVB_T_PCI 29 | 174 | #define CX88_BOARD_ADSTECH_DVB_T_PCI 29 |
175 | #define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30 | 175 | #define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30 |
176 | #define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31 | 176 | #define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31 |
177 | #define CX88_BOARD_AVERMEDIA_ULTRATV_MC_550 32 | ||
178 | #define CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD 33 | ||
179 | #define CX88_BOARD_ATI_HDTVWONDER 34 | ||
180 | #define CX88_BOARD_WINFAST_DTV1000 35 | ||
181 | #define CX88_BOARD_AVERTV_303 36 | ||
177 | 182 | ||
178 | enum cx88_itype { | 183 | enum cx88_itype { |
179 | CX88_VMUX_COMPOSITE1 = 1, | 184 | CX88_VMUX_COMPOSITE1 = 1, |
@@ -203,8 +208,8 @@ struct cx88_board { | |||
203 | int tda9887_conf; | 208 | int tda9887_conf; |
204 | struct cx88_input input[MAX_CX88_INPUT]; | 209 | struct cx88_input input[MAX_CX88_INPUT]; |
205 | struct cx88_input radio; | 210 | struct cx88_input radio; |
206 | int blackbird:1; | 211 | unsigned int blackbird:1; |
207 | int dvb:1; | 212 | unsigned int dvb:1; |
208 | }; | 213 | }; |
209 | 214 | ||
210 | struct cx88_subid { | 215 | struct cx88_subid { |
@@ -255,8 +260,8 @@ struct cx88_core { | |||
255 | /* pci stuff */ | 260 | /* pci stuff */ |
256 | int pci_bus; | 261 | int pci_bus; |
257 | int pci_slot; | 262 | int pci_slot; |
258 | u32 __iomem *lmmio; | 263 | u32 __iomem *lmmio; |
259 | u8 __iomem *bmmio; | 264 | u8 __iomem *bmmio; |
260 | u32 shadow[SHADOW_MAX]; | 265 | u32 shadow[SHADOW_MAX]; |
261 | int pci_irqmask; | 266 | int pci_irqmask; |
262 | 267 | ||
@@ -287,6 +292,7 @@ struct cx88_core { | |||
287 | u32 audiomode_current; | 292 | u32 audiomode_current; |
288 | u32 input; | 293 | u32 input; |
289 | u32 astat; | 294 | u32 astat; |
295 | u32 use_nicam; | ||
290 | 296 | ||
291 | /* IR remote control state */ | 297 | /* IR remote control state */ |
292 | struct cx88_IR *ir; | 298 | struct cx88_IR *ir; |
@@ -370,6 +376,14 @@ struct cx8802_suspend_state { | |||
370 | int disabled; | 376 | int disabled; |
371 | }; | 377 | }; |
372 | 378 | ||
379 | /* TODO: move this to struct v4l2_mpeg_compression ? */ | ||
380 | struct blackbird_dnr { | ||
381 | u32 mode; | ||
382 | u32 type; | ||
383 | u32 spatial; | ||
384 | u32 temporal; | ||
385 | }; | ||
386 | |||
373 | struct cx8802_dev { | 387 | struct cx8802_dev { |
374 | struct cx88_core *core; | 388 | struct cx88_core *core; |
375 | spinlock_t slock; | 389 | spinlock_t slock; |
@@ -400,6 +414,10 @@ struct cx8802_dev { | |||
400 | 414 | ||
401 | /* for switching modulation types */ | 415 | /* for switching modulation types */ |
402 | unsigned char ts_gen_cntrl; | 416 | unsigned char ts_gen_cntrl; |
417 | |||
418 | /* mpeg params */ | ||
419 | struct v4l2_mpeg_compression params; | ||
420 | struct blackbird_dnr dnr_params; | ||
403 | }; | 421 | }; |
404 | 422 | ||
405 | /* ----------------------------------------------------------- */ | 423 | /* ----------------------------------------------------------- */ |
@@ -514,22 +532,20 @@ extern void cx88_card_setup(struct cx88_core *core); | |||
514 | 532 | ||
515 | #define WW_NONE 1 | 533 | #define WW_NONE 1 |
516 | #define WW_BTSC 2 | 534 | #define WW_BTSC 2 |
517 | #define WW_NICAM_I 3 | 535 | #define WW_BG 3 |
518 | #define WW_NICAM_BGDKL 4 | 536 | #define WW_DK 4 |
519 | #define WW_A1 5 | 537 | #define WW_I 5 |
520 | #define WW_A2_BG 6 | 538 | #define WW_L 6 |
521 | #define WW_A2_DK 7 | 539 | #define WW_EIAJ 7 |
522 | #define WW_A2_M 8 | 540 | #define WW_I2SPT 8 |
523 | #define WW_EIAJ 9 | 541 | #define WW_FM 9 |
524 | #define WW_SYSTEM_L_AM 10 | ||
525 | #define WW_I2SPT 11 | ||
526 | #define WW_FM 12 | ||
527 | 542 | ||
528 | void cx88_set_tvaudio(struct cx88_core *core); | 543 | void cx88_set_tvaudio(struct cx88_core *core); |
529 | void cx88_newstation(struct cx88_core *core); | 544 | void cx88_newstation(struct cx88_core *core); |
530 | void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t); | 545 | void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t); |
531 | void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual); | 546 | void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual); |
532 | int cx88_audio_thread(void *data); | 547 | int cx88_audio_thread(void *data); |
548 | int cx88_detect_nicam(struct cx88_core *core); | ||
533 | 549 | ||
534 | /* ----------------------------------------------------------- */ | 550 | /* ----------------------------------------------------------- */ |
535 | /* cx88-input.c */ | 551 | /* cx88-input.c */ |
@@ -541,7 +557,8 @@ void cx88_ir_irq(struct cx88_core *core); | |||
541 | /* ----------------------------------------------------------- */ | 557 | /* ----------------------------------------------------------- */ |
542 | /* cx88-mpeg.c */ | 558 | /* cx88-mpeg.c */ |
543 | 559 | ||
544 | int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf); | 560 | int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf, |
561 | enum v4l2_field field); | ||
545 | void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf); | 562 | void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf); |
546 | void cx8802_cancel_buffers(struct cx8802_dev *dev); | 563 | void cx8802_cancel_buffers(struct cx8802_dev *dev); |
547 | 564 | ||
@@ -562,6 +579,10 @@ extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | |||
562 | extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, | 579 | extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, |
563 | unsigned int cmd, void *arg); | 580 | unsigned int cmd, void *arg); |
564 | extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd); | 581 | extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd); |
582 | void blackbird_set_params(struct cx8802_dev *dev, | ||
583 | struct v4l2_mpeg_compression *params); | ||
584 | void blackbird_set_dnr_params(struct cx8802_dev *dev, | ||
585 | struct blackbird_dnr* dnr_params); | ||
565 | 586 | ||
566 | /* | 587 | /* |
567 | * Local variables: | 588 | * Local variables: |
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig new file mode 100644 index 000000000000..885fd0170086 --- /dev/null +++ b/drivers/media/video/em28xx/Kconfig | |||
@@ -0,0 +1,12 @@ | |||
1 | config VIDEO_EM28XX | ||
2 | tristate "Empia EM2800/2820/2840 USB video capture support" | ||
3 | depends on VIDEO_DEV && USB && I2C | ||
4 | select VIDEO_BUF | ||
5 | select VIDEO_TUNER | ||
6 | select VIDEO_TVEEPROM | ||
7 | select VIDEO_IR | ||
8 | ---help--- | ||
9 | This is a video4linux driver for Empia 28xx based TV cards. | ||
10 | |||
11 | To compile this driver as a module, choose M here: the | ||
12 | module will be called em28xx | ||
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile new file mode 100644 index 000000000000..da457a05b0dd --- /dev/null +++ b/drivers/media/video/em28xx/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \ | ||
2 | em28xx-input.o | ||
3 | |||
4 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o | ||
5 | |||
6 | EXTRA_CFLAGS += -I$(src)/.. | ||
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c new file mode 100644 index 000000000000..57779e63f35d --- /dev/null +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -0,0 +1,292 @@ | |||
1 | /* | ||
2 | em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | ||
3 | |||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | ||
5 | Markus Rechberger <mrechberger@gmail.com> | ||
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | ||
7 | Sascha Sommer <saschasommer@freenet.de> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/init.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/pci.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/i2c.h> | ||
29 | #include <linux/usb.h> | ||
30 | #include <media/tuner.h> | ||
31 | #include <media/audiochip.h> | ||
32 | #include <media/tveeprom.h> | ||
33 | #include "msp3400.h" | ||
34 | |||
35 | #include "em28xx.h" | ||
36 | |||
37 | struct em28xx_board em28xx_boards[] = { | ||
38 | [EM2800_BOARD_UNKNOWN] = { | ||
39 | .name = "Unknown EM2800 video grabber", | ||
40 | .is_em2800 = 1, | ||
41 | .vchannels = 2, | ||
42 | .norm = VIDEO_MODE_PAL, | ||
43 | .tda9887_conf = TDA9887_PRESENT, | ||
44 | .has_tuner = 1, | ||
45 | .decoder = EM28XX_SAA7113, | ||
46 | .input = {{ | ||
47 | .type = EM28XX_VMUX_COMPOSITE1, | ||
48 | .vmux = 0, | ||
49 | .amux = 1, | ||
50 | },{ | ||
51 | .type = EM28XX_VMUX_SVIDEO, | ||
52 | .vmux = 9, | ||
53 | .amux = 1, | ||
54 | }}, | ||
55 | }, | ||
56 | [EM2820_BOARD_UNKNOWN] = { | ||
57 | .name = "Unknown EM2820/2840 video grabber", | ||
58 | .is_em2800 = 0, | ||
59 | .vchannels = 2, | ||
60 | .norm = VIDEO_MODE_PAL, | ||
61 | .tda9887_conf = TDA9887_PRESENT, | ||
62 | .has_tuner = 1, | ||
63 | .decoder = EM28XX_SAA7113, | ||
64 | .input = {{ | ||
65 | .type = EM28XX_VMUX_COMPOSITE1, | ||
66 | .vmux = 0, | ||
67 | .amux = 1, | ||
68 | },{ | ||
69 | .type = EM28XX_VMUX_SVIDEO, | ||
70 | .vmux = 9, | ||
71 | .amux = 1, | ||
72 | }}, | ||
73 | }, | ||
74 | [EM2820_BOARD_TERRATEC_CINERGY_250] = { | ||
75 | .name = "Terratec Cinergy 250 USB", | ||
76 | .vchannels = 3, | ||
77 | .norm = VIDEO_MODE_PAL, | ||
78 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
79 | .tda9887_conf = TDA9887_PRESENT, | ||
80 | .has_tuner = 1, | ||
81 | .decoder = EM28XX_SAA7113, | ||
82 | .input = {{ | ||
83 | .type = EM28XX_VMUX_TELEVISION, | ||
84 | .vmux = 2, | ||
85 | .amux = 0, | ||
86 | },{ | ||
87 | .type = EM28XX_VMUX_COMPOSITE1, | ||
88 | .vmux = 0, | ||
89 | .amux = 1, | ||
90 | },{ | ||
91 | .type = EM28XX_VMUX_SVIDEO, | ||
92 | .vmux = 9, | ||
93 | .amux = 1, | ||
94 | }}, | ||
95 | }, | ||
96 | [EM2820_BOARD_PINNACLE_USB_2] = { | ||
97 | .name = "Pinnacle PCTV USB 2", | ||
98 | .vchannels = 3, | ||
99 | .norm = VIDEO_MODE_PAL, | ||
100 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
101 | .tda9887_conf = TDA9887_PRESENT, | ||
102 | .has_tuner = 1, | ||
103 | .decoder = EM28XX_SAA7113, | ||
104 | .input = {{ | ||
105 | .type = EM28XX_VMUX_TELEVISION, | ||
106 | .vmux = 2, | ||
107 | .amux = 0, | ||
108 | },{ | ||
109 | .type = EM28XX_VMUX_COMPOSITE1, | ||
110 | .vmux = 0, | ||
111 | .amux = 1, | ||
112 | },{ | ||
113 | .type = EM28XX_VMUX_SVIDEO, | ||
114 | .vmux = 9, | ||
115 | .amux = 1, | ||
116 | }}, | ||
117 | }, | ||
118 | [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = { | ||
119 | .name = "Hauppauge WinTV USB 2", | ||
120 | .vchannels = 3, | ||
121 | .norm = VIDEO_MODE_NTSC, | ||
122 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, | ||
123 | .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE, | ||
124 | .has_tuner = 1, | ||
125 | .decoder = EM28XX_TVP5150, | ||
126 | .has_msp34xx = 1, | ||
127 | /*FIXME: S-Video not tested */ | ||
128 | .input = {{ | ||
129 | .type = EM28XX_VMUX_TELEVISION, | ||
130 | .vmux = 0, | ||
131 | .amux = 6, | ||
132 | },{ | ||
133 | .type = EM28XX_VMUX_SVIDEO, | ||
134 | .vmux = 2, | ||
135 | .amux = 1, | ||
136 | }}, | ||
137 | }, | ||
138 | [EM2820_BOARD_MSI_VOX_USB_2] = { | ||
139 | .name = "MSI VOX USB 2.0", | ||
140 | .vchannels = 3, | ||
141 | .norm = VIDEO_MODE_PAL, | ||
142 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
143 | .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE, | ||
144 | .has_tuner = 1, | ||
145 | .decoder = EM28XX_SAA7114, | ||
146 | .input = {{ | ||
147 | .type = EM28XX_VMUX_TELEVISION, | ||
148 | .vmux = 4, | ||
149 | .amux = 0, | ||
150 | },{ | ||
151 | .type = EM28XX_VMUX_COMPOSITE1, | ||
152 | .vmux = 0, | ||
153 | .amux = 1, | ||
154 | },{ | ||
155 | .type = EM28XX_VMUX_SVIDEO, | ||
156 | .vmux = 9, | ||
157 | .amux = 1, | ||
158 | }}, | ||
159 | }, | ||
160 | [EM2800_BOARD_TERRATEC_CINERGY_200] = { | ||
161 | .name = "Terratec Cinergy 200 USB", | ||
162 | .is_em2800 = 1, | ||
163 | .vchannels = 3, | ||
164 | .norm = VIDEO_MODE_PAL, | ||
165 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
166 | .tda9887_conf = TDA9887_PRESENT, | ||
167 | .has_tuner = 1, | ||
168 | .decoder = EM28XX_SAA7113, | ||
169 | .input = {{ | ||
170 | .type = EM28XX_VMUX_TELEVISION, | ||
171 | .vmux = 2, | ||
172 | .amux = 0, | ||
173 | },{ | ||
174 | .type = EM28XX_VMUX_COMPOSITE1, | ||
175 | .vmux = 0, | ||
176 | .amux = 1, | ||
177 | },{ | ||
178 | .type = EM28XX_VMUX_SVIDEO, | ||
179 | .vmux = 9, | ||
180 | .amux = 1, | ||
181 | }}, | ||
182 | }, | ||
183 | [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { | ||
184 | .name = "Leadtek Winfast USB II", | ||
185 | .is_em2800 = 1, | ||
186 | .vchannels = 3, | ||
187 | .norm = VIDEO_MODE_PAL, | ||
188 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
189 | .tda9887_conf = TDA9887_PRESENT, | ||
190 | .has_tuner = 1, | ||
191 | .decoder = EM28XX_SAA7113, | ||
192 | .input = {{ | ||
193 | .type = EM28XX_VMUX_TELEVISION, | ||
194 | .vmux = 2, | ||
195 | .amux = 0, | ||
196 | },{ | ||
197 | .type = EM28XX_VMUX_COMPOSITE1, | ||
198 | .vmux = 0, | ||
199 | .amux = 1, | ||
200 | },{ | ||
201 | .type = EM28XX_VMUX_SVIDEO, | ||
202 | .vmux = 9, | ||
203 | .amux = 1, | ||
204 | }}, | ||
205 | }, | ||
206 | [EM2800_BOARD_KWORLD_USB2800] = { | ||
207 | .name = "Kworld USB2800", | ||
208 | .is_em2800 = 1, | ||
209 | .vchannels = 3, | ||
210 | .norm = VIDEO_MODE_PAL, | ||
211 | .tuner_type = TUNER_PHILIPS_ATSC, | ||
212 | .tda9887_conf = TDA9887_PRESENT, | ||
213 | .has_tuner = 1, | ||
214 | .decoder = EM28XX_SAA7113, | ||
215 | .input = {{ | ||
216 | .type = EM28XX_VMUX_TELEVISION, | ||
217 | .vmux = 2, | ||
218 | .amux = 0, | ||
219 | },{ | ||
220 | .type = EM28XX_VMUX_COMPOSITE1, | ||
221 | .vmux = 0, | ||
222 | .amux = 1, | ||
223 | },{ | ||
224 | .type = EM28XX_VMUX_SVIDEO, | ||
225 | .vmux = 9, | ||
226 | .amux = 1, | ||
227 | }}, | ||
228 | }, | ||
229 | [EM2820_BOARD_PINNACLE_DVC_90] = { | ||
230 | .name = "Pinnacle Dazzle DVC 90", | ||
231 | .vchannels = 3, | ||
232 | .norm = VIDEO_MODE_PAL, | ||
233 | .has_tuner = 0, | ||
234 | .decoder = EM28XX_SAA7113, | ||
235 | .input = {{ | ||
236 | .type = EM28XX_VMUX_COMPOSITE1, | ||
237 | .vmux = 0, | ||
238 | .amux = 1, | ||
239 | },{ | ||
240 | .type = EM28XX_VMUX_SVIDEO, | ||
241 | .vmux = 9, | ||
242 | .amux = 1, | ||
243 | }}, | ||
244 | }, | ||
245 | }; | ||
246 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); | ||
247 | |||
248 | /* table of devices that work with this driver */ | ||
249 | struct usb_device_id em28xx_id_table [] = { | ||
250 | { USB_DEVICE(0xeb1a, 0x2800), .driver_info = EM2800_BOARD_UNKNOWN }, | ||
251 | { USB_DEVICE(0xeb1a, 0x2820), .driver_info = EM2820_BOARD_MSI_VOX_USB_2 }, | ||
252 | { USB_DEVICE(0x0ccd, 0x0036), .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 }, | ||
253 | { USB_DEVICE(0x2304, 0x0208), .driver_info = EM2820_BOARD_PINNACLE_USB_2 }, | ||
254 | { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, | ||
255 | { USB_DEVICE(0x2304, 0x0207), .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, | ||
256 | { }, | ||
257 | }; | ||
258 | |||
259 | void em28xx_card_setup(struct em28xx *dev) | ||
260 | { | ||
261 | /* request some modules */ | ||
262 | if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) { | ||
263 | struct tveeprom tv; | ||
264 | struct v4l2_audioout ao; | ||
265 | #ifdef CONFIG_MODULES | ||
266 | request_module("tveeprom"); | ||
267 | request_module("ir-kbd-i2c"); | ||
268 | request_module("msp3400"); | ||
269 | #endif | ||
270 | /* Call first TVeeprom */ | ||
271 | |||
272 | dev->i2c_client.addr = 0xa0 >> 1; | ||
273 | tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata); | ||
274 | |||
275 | dev->tuner_type= tv.tuner_type; | ||
276 | if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { | ||
277 | dev->has_msp34xx=1; | ||
278 | memset (&ao,0,sizeof(ao)); | ||
279 | |||
280 | ao.index=2; | ||
281 | ao.mode=V4L2_AUDMODE_32BITS; | ||
282 | em28xx_i2c_call_clients(dev, VIDIOC_S_AUDOUT, &ao); | ||
283 | } else | ||
284 | dev->has_msp34xx=0; | ||
285 | } | ||
286 | } | ||
287 | |||
288 | EXPORT_SYMBOL(em28xx_boards); | ||
289 | EXPORT_SYMBOL(em28xx_bcount); | ||
290 | EXPORT_SYMBOL(em28xx_id_table); | ||
291 | |||
292 | MODULE_DEVICE_TABLE (usb, em28xx_id_table); | ||
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c new file mode 100644 index 000000000000..d54bc0127484 --- /dev/null +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -0,0 +1,817 @@ | |||
1 | /* | ||
2 | em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | ||
3 | |||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | ||
5 | Markus Rechberger <mrechberger@gmail.com> | ||
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | ||
7 | Sascha Sommer <saschasommer@freenet.de> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/init.h> | ||
25 | #include <linux/list.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/moduleparam.h> | ||
28 | #include <linux/usb.h> | ||
29 | #include <linux/vmalloc.h> | ||
30 | |||
31 | #include "em28xx.h" | ||
32 | |||
33 | /* #define ENABLE_DEBUG_ISOC_FRAMES */ | ||
34 | |||
35 | unsigned int core_debug; | ||
36 | module_param(core_debug,int,0644); | ||
37 | MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); | ||
38 | |||
39 | #define em28xx_coredbg(fmt, arg...) do {\ | ||
40 | if (core_debug) \ | ||
41 | printk(KERN_INFO "%s %s :"fmt, \ | ||
42 | dev->name, __FUNCTION__ , ##arg); } while (0) | ||
43 | |||
44 | unsigned int reg_debug; | ||
45 | module_param(reg_debug,int,0644); | ||
46 | MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); | ||
47 | |||
48 | #define em28xx_regdbg(fmt, arg...) do {\ | ||
49 | if (reg_debug) \ | ||
50 | printk(KERN_INFO "%s %s :"fmt, \ | ||
51 | dev->name, __FUNCTION__ , ##arg); } while (0) | ||
52 | |||
53 | unsigned int isoc_debug; | ||
54 | module_param(isoc_debug,int,0644); | ||
55 | MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]"); | ||
56 | |||
57 | #define em28xx_isocdbg(fmt, arg...) do {\ | ||
58 | if (isoc_debug) \ | ||
59 | printk(KERN_INFO "%s %s :"fmt, \ | ||
60 | dev->name, __FUNCTION__ , ##arg); } while (0) | ||
61 | |||
62 | static int alt = EM28XX_PINOUT; | ||
63 | module_param(alt, int, 0644); | ||
64 | MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); | ||
65 | |||
66 | /* ------------------------------------------------------------------ */ | ||
67 | /* debug help functions */ | ||
68 | |||
69 | static const char *v4l1_ioctls[] = { | ||
70 | "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT", | ||
71 | "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ", | ||
72 | "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT", | ||
73 | "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", | ||
74 | "SMICROCODE", "GVBIFMT", "SVBIFMT" }; | ||
75 | #define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) | ||
76 | |||
77 | static const char *v4l2_ioctls[] = { | ||
78 | "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT", | ||
79 | "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF", | ||
80 | "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON", | ||
81 | "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD", | ||
82 | "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER", | ||
83 | "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL", | ||
84 | "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43", | ||
85 | "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT", | ||
86 | "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR", | ||
87 | "S_MODULATOR" | ||
88 | }; | ||
89 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | ||
90 | |||
91 | void em28xx_print_ioctl(char *name, unsigned int cmd) | ||
92 | { | ||
93 | char *dir; | ||
94 | |||
95 | switch (_IOC_DIR(cmd)) { | ||
96 | case _IOC_NONE: dir = "--"; break; | ||
97 | case _IOC_READ: dir = "r-"; break; | ||
98 | case _IOC_WRITE: dir = "-w"; break; | ||
99 | case _IOC_READ | _IOC_WRITE: dir = "rw"; break; | ||
100 | default: dir = "??"; break; | ||
101 | } | ||
102 | switch (_IOC_TYPE(cmd)) { | ||
103 | case 'v': | ||
104 | printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n", | ||
105 | name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ? | ||
106 | v4l1_ioctls[_IOC_NR(cmd)] : "???"); | ||
107 | break; | ||
108 | case 'V': | ||
109 | printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n", | ||
110 | name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ? | ||
111 | v4l2_ioctls[_IOC_NR(cmd)] : "???"); | ||
112 | break; | ||
113 | default: | ||
114 | printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n", | ||
115 | name, cmd, dir, _IOC_NR(cmd)); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | static void *rvmalloc(size_t size) | ||
120 | { | ||
121 | void *mem; | ||
122 | unsigned long adr; | ||
123 | |||
124 | size = PAGE_ALIGN(size); | ||
125 | |||
126 | mem = vmalloc_32((unsigned long)size); | ||
127 | if (!mem) | ||
128 | return NULL; | ||
129 | |||
130 | memset(mem, 0, size); | ||
131 | |||
132 | adr = (unsigned long)mem; | ||
133 | while (size > 0) { | ||
134 | SetPageReserved(vmalloc_to_page((void *)adr)); | ||
135 | adr += PAGE_SIZE; | ||
136 | size -= PAGE_SIZE; | ||
137 | } | ||
138 | |||
139 | return mem; | ||
140 | } | ||
141 | |||
142 | static void rvfree(void *mem, size_t size) | ||
143 | { | ||
144 | unsigned long adr; | ||
145 | |||
146 | if (!mem) | ||
147 | return; | ||
148 | |||
149 | size = PAGE_ALIGN(size); | ||
150 | |||
151 | adr = (unsigned long)mem; | ||
152 | while (size > 0) { | ||
153 | ClearPageReserved(vmalloc_to_page((void *)adr)); | ||
154 | adr += PAGE_SIZE; | ||
155 | size -= PAGE_SIZE; | ||
156 | } | ||
157 | |||
158 | vfree(mem); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * em28xx_request_buffers() | ||
163 | * allocate a number of buffers | ||
164 | */ | ||
165 | u32 em28xx_request_buffers(struct em28xx *dev, u32 count) | ||
166 | { | ||
167 | const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */ | ||
168 | void *buff = NULL; | ||
169 | u32 i; | ||
170 | em28xx_coredbg("requested %i buffers with size %i", count, imagesize); | ||
171 | if (count > EM28XX_NUM_FRAMES) | ||
172 | count = EM28XX_NUM_FRAMES; | ||
173 | |||
174 | dev->num_frames = count; | ||
175 | while (dev->num_frames > 0) { | ||
176 | if ((buff = rvmalloc(dev->num_frames * imagesize))) | ||
177 | break; | ||
178 | dev->num_frames--; | ||
179 | } | ||
180 | |||
181 | for (i = 0; i < dev->num_frames; i++) { | ||
182 | dev->frame[i].bufmem = buff + i * imagesize; | ||
183 | dev->frame[i].buf.index = i; | ||
184 | dev->frame[i].buf.m.offset = i * imagesize; | ||
185 | dev->frame[i].buf.length = dev->frame_size; | ||
186 | dev->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
187 | dev->frame[i].buf.sequence = 0; | ||
188 | dev->frame[i].buf.field = V4L2_FIELD_NONE; | ||
189 | dev->frame[i].buf.memory = V4L2_MEMORY_MMAP; | ||
190 | dev->frame[i].buf.flags = 0; | ||
191 | } | ||
192 | return dev->num_frames; | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * em28xx_queue_unusedframes() | ||
197 | * add all frames that are not currently in use to the inbuffer queue | ||
198 | */ | ||
199 | void em28xx_queue_unusedframes(struct em28xx *dev) | ||
200 | { | ||
201 | unsigned long lock_flags; | ||
202 | u32 i; | ||
203 | |||
204 | for (i = 0; i < dev->num_frames; i++) | ||
205 | if (dev->frame[i].state == F_UNUSED) { | ||
206 | dev->frame[i].state = F_QUEUED; | ||
207 | spin_lock_irqsave(&dev->queue_lock, lock_flags); | ||
208 | list_add_tail(&dev->frame[i].frame, &dev->inqueue); | ||
209 | spin_unlock_irqrestore(&dev->queue_lock, lock_flags); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * em28xx_release_buffers() | ||
215 | * free frame buffers | ||
216 | */ | ||
217 | void em28xx_release_buffers(struct em28xx *dev) | ||
218 | { | ||
219 | if (dev->num_frames) { | ||
220 | rvfree(dev->frame[0].bufmem, | ||
221 | dev->num_frames * PAGE_ALIGN(dev->frame[0].buf.length)); | ||
222 | dev->num_frames = 0; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | * em28xx_read_reg_req() | ||
228 | * reads data from the usb device specifying bRequest | ||
229 | */ | ||
230 | int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | ||
231 | char *buf, int len) | ||
232 | { | ||
233 | int ret, byte; | ||
234 | |||
235 | em28xx_regdbg("req=%02x, reg=%02x ", req, reg); | ||
236 | |||
237 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | ||
238 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
239 | 0x0000, reg, buf, len, HZ); | ||
240 | |||
241 | if (reg_debug){ | ||
242 | printk(ret < 0 ? " failed!\n" : "%02x values: ", ret); | ||
243 | for (byte = 0; byte < len; byte++) { | ||
244 | printk(" %02x", buf[byte]); | ||
245 | } | ||
246 | printk("\n"); | ||
247 | } | ||
248 | |||
249 | return ret; | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * em28xx_read_reg_req() | ||
254 | * reads data from the usb device specifying bRequest | ||
255 | */ | ||
256 | int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg) | ||
257 | { | ||
258 | u8 val; | ||
259 | int ret; | ||
260 | |||
261 | em28xx_regdbg("req=%02x, reg=%02x:", req, reg); | ||
262 | |||
263 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | ||
264 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
265 | 0x0000, reg, &val, 1, HZ); | ||
266 | |||
267 | if (reg_debug) | ||
268 | printk(ret < 0 ? " failed!\n" : "%02x\n", val); | ||
269 | |||
270 | if (ret < 0) | ||
271 | return ret; | ||
272 | |||
273 | return val; | ||
274 | } | ||
275 | |||
276 | int em28xx_read_reg(struct em28xx *dev, u16 reg) | ||
277 | { | ||
278 | return em28xx_read_reg_req(dev, USB_REQ_GET_STATUS, reg); | ||
279 | } | ||
280 | |||
281 | /* | ||
282 | * em28xx_write_regs_req() | ||
283 | * sends data to the usb device, specifying bRequest | ||
284 | */ | ||
285 | int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | ||
286 | int len) | ||
287 | { | ||
288 | int ret; | ||
289 | |||
290 | /*usb_control_msg seems to expect a kmalloced buffer */ | ||
291 | unsigned char *bufs = kmalloc(len, GFP_KERNEL); | ||
292 | |||
293 | em28xx_regdbg("req=%02x reg=%02x:", req, reg); | ||
294 | |||
295 | if (reg_debug) { | ||
296 | int i; | ||
297 | for (i = 0; i < len; ++i) | ||
298 | printk (" %02x", (unsigned char)buf[i]); | ||
299 | printk ("\n"); | ||
300 | } | ||
301 | |||
302 | if (!bufs) | ||
303 | return -ENOMEM; | ||
304 | memcpy(bufs, buf, len); | ||
305 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, | ||
306 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
307 | 0x0000, reg, bufs, len, HZ); | ||
308 | mdelay(5); /* FIXME: magic number */ | ||
309 | kfree(bufs); | ||
310 | return ret; | ||
311 | } | ||
312 | |||
313 | int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len) | ||
314 | { | ||
315 | return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len); | ||
316 | } | ||
317 | |||
318 | /* | ||
319 | * em28xx_write_reg_bits() | ||
320 | * sets only some bits (specified by bitmask) of a register, by first reading | ||
321 | * the actual value | ||
322 | */ | ||
323 | int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, | ||
324 | u8 bitmask) | ||
325 | { | ||
326 | int oldval; | ||
327 | u8 newval; | ||
328 | if ((oldval = em28xx_read_reg(dev, reg)) < 0) | ||
329 | return oldval; | ||
330 | newval = (((u8) oldval) & ~bitmask) | (val & bitmask); | ||
331 | return em28xx_write_regs(dev, reg, &newval, 1); | ||
332 | } | ||
333 | |||
334 | /* | ||
335 | * em28xx_write_ac97() | ||
336 | * write a 16 bit value to the specified AC97 address (LSB first!) | ||
337 | */ | ||
338 | int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val) | ||
339 | { | ||
340 | int ret; | ||
341 | u8 addr = reg & 0x7f; | ||
342 | if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0) | ||
343 | return ret; | ||
344 | if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0) | ||
345 | return ret; | ||
346 | if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0) | ||
347 | return ret; | ||
348 | else if (((u8) ret) & 0x01) { | ||
349 | em28xx_warn ("AC97 command still being exectuted: not handled properly!\n"); | ||
350 | } | ||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | int em28xx_audio_analog_set(struct em28xx *dev) | ||
355 | { | ||
356 | char s[2] = { 0x00, 0x00 }; | ||
357 | s[0] |= 0x1f - dev->volume; | ||
358 | s[1] |= 0x1f - dev->volume; | ||
359 | if (dev->mute) | ||
360 | s[1] |= 0x80; | ||
361 | return em28xx_write_ac97(dev, MASTER_AC97, s); | ||
362 | } | ||
363 | |||
364 | |||
365 | int em28xx_colorlevels_set_default(struct em28xx *dev) | ||
366 | { | ||
367 | em28xx_write_regs(dev, YGAIN_REG, "\x10", 1); /* contrast */ | ||
368 | em28xx_write_regs(dev, YOFFSET_REG, "\x00", 1); /* brightness */ | ||
369 | em28xx_write_regs(dev, UVGAIN_REG, "\x10", 1); /* saturation */ | ||
370 | em28xx_write_regs(dev, UOFFSET_REG, "\x00", 1); | ||
371 | em28xx_write_regs(dev, VOFFSET_REG, "\x00", 1); | ||
372 | em28xx_write_regs(dev, SHARPNESS_REG, "\x00", 1); | ||
373 | |||
374 | em28xx_write_regs(dev, GAMMA_REG, "\x20", 1); | ||
375 | em28xx_write_regs(dev, RGAIN_REG, "\x20", 1); | ||
376 | em28xx_write_regs(dev, GGAIN_REG, "\x20", 1); | ||
377 | em28xx_write_regs(dev, BGAIN_REG, "\x20", 1); | ||
378 | em28xx_write_regs(dev, ROFFSET_REG, "\x00", 1); | ||
379 | em28xx_write_regs(dev, GOFFSET_REG, "\x00", 1); | ||
380 | return em28xx_write_regs(dev, BOFFSET_REG, "\x00", 1); | ||
381 | } | ||
382 | |||
383 | int em28xx_capture_start(struct em28xx *dev, int start) | ||
384 | { | ||
385 | int ret; | ||
386 | /* FIXME: which is the best order? */ | ||
387 | /* video registers are sampled by VREF */ | ||
388 | if ((ret = em28xx_write_reg_bits(dev, USBSUSP_REG, start ? 0x10 : 0x00, | ||
389 | 0x10)) < 0) | ||
390 | return ret; | ||
391 | /* enable video capture */ | ||
392 | return em28xx_write_regs(dev, VINENABLE_REG, start ? "\x67" : "\x27", 1); | ||
393 | } | ||
394 | |||
395 | int em28xx_outfmt_set_yuv422(struct em28xx *dev) | ||
396 | { | ||
397 | em28xx_write_regs(dev, OUTFMT_REG, "\x34", 1); | ||
398 | em28xx_write_regs(dev, VINMODE_REG, "\x10", 1); | ||
399 | return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1); | ||
400 | } | ||
401 | |||
402 | int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin, | ||
403 | u8 ymax) | ||
404 | { | ||
405 | em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax); | ||
406 | |||
407 | em28xx_write_regs(dev, XMIN_REG, &xmin, 1); | ||
408 | em28xx_write_regs(dev, XMAX_REG, &xmax, 1); | ||
409 | em28xx_write_regs(dev, YMIN_REG, &ymin, 1); | ||
410 | return em28xx_write_regs(dev, YMAX_REG, &ymax, 1); | ||
411 | } | ||
412 | |||
413 | int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, | ||
414 | u16 width, u16 height) | ||
415 | { | ||
416 | u8 cwidth = width; | ||
417 | u8 cheight = height; | ||
418 | u8 overflow = (height >> 7 & 0x02) | (width >> 8 & 0x01); | ||
419 | |||
420 | em28xx_coredbg("em28xx Area Set: (%d,%d)\n", (width | (overflow & 2) << 7), | ||
421 | (height | (overflow & 1) << 8)); | ||
422 | |||
423 | em28xx_write_regs(dev, HSTART_REG, &hstart, 1); | ||
424 | em28xx_write_regs(dev, VSTART_REG, &vstart, 1); | ||
425 | em28xx_write_regs(dev, CWIDTH_REG, &cwidth, 1); | ||
426 | em28xx_write_regs(dev, CHEIGHT_REG, &cheight, 1); | ||
427 | return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1); | ||
428 | } | ||
429 | |||
430 | int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) | ||
431 | { | ||
432 | u8 mode; | ||
433 | /* the em2800 scaler only supports scaling down to 50% */ | ||
434 | if(dev->is_em2800) | ||
435 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); | ||
436 | else { | ||
437 | u8 buf[2]; | ||
438 | buf[0] = h; | ||
439 | buf[1] = h >> 8; | ||
440 | em28xx_write_regs(dev, HSCALELOW_REG, (char *)buf, 2); | ||
441 | buf[0] = v; | ||
442 | buf[1] = v >> 8; | ||
443 | em28xx_write_regs(dev, VSCALELOW_REG, (char *)buf, 2); | ||
444 | /* it seems that both H and V scalers must be active to work correctly */ | ||
445 | mode = (h || v)? 0x30: 0x00; | ||
446 | } | ||
447 | return em28xx_write_reg_bits(dev, COMPR_REG, mode, 0x30); | ||
448 | } | ||
449 | |||
450 | /* FIXME: this only function read values from dev */ | ||
451 | int em28xx_resolution_set(struct em28xx *dev) | ||
452 | { | ||
453 | int width, height; | ||
454 | width = norm_maxw(dev); | ||
455 | height = norm_maxh(dev) >> 1; | ||
456 | |||
457 | em28xx_outfmt_set_yuv422(dev); | ||
458 | em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); | ||
459 | em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2); | ||
460 | return em28xx_scaler_set(dev, dev->hscale, dev->vscale); | ||
461 | } | ||
462 | |||
463 | |||
464 | /******************* isoc transfer handling ****************************/ | ||
465 | |||
466 | #ifdef ENABLE_DEBUG_ISOC_FRAMES | ||
467 | static void em28xx_isoc_dump(struct urb *urb, struct pt_regs *regs) | ||
468 | { | ||
469 | int len = 0; | ||
470 | int ntrans = 0; | ||
471 | int i; | ||
472 | |||
473 | printk(KERN_DEBUG "isocIrq: sf=%d np=%d ec=%x\n", | ||
474 | urb->start_frame, urb->number_of_packets, | ||
475 | urb->error_count); | ||
476 | for (i = 0; i < urb->number_of_packets; i++) { | ||
477 | unsigned char *buf = | ||
478 | urb->transfer_buffer + | ||
479 | urb->iso_frame_desc[i].offset; | ||
480 | int alen = urb->iso_frame_desc[i].actual_length; | ||
481 | if (alen > 0) { | ||
482 | if (buf[0] == 0x88) { | ||
483 | ntrans++; | ||
484 | len += alen; | ||
485 | } else if (buf[0] == 0x22) { | ||
486 | printk(KERN_DEBUG | ||
487 | "= l=%d nt=%d bpp=%d\n", | ||
488 | len - 4 * ntrans, ntrans, | ||
489 | ntrans == 0 ? 0 : len / ntrans); | ||
490 | ntrans = 1; | ||
491 | len = alen; | ||
492 | } else | ||
493 | printk(KERN_DEBUG "!\n"); | ||
494 | } | ||
495 | printk(KERN_DEBUG " n=%d s=%d al=%d %x\n", i, | ||
496 | urb->iso_frame_desc[i].status, | ||
497 | urb->iso_frame_desc[i].actual_length, | ||
498 | (unsigned int) | ||
499 | *((unsigned char *)(urb->transfer_buffer + | ||
500 | urb->iso_frame_desc[i]. | ||
501 | offset))); | ||
502 | } | ||
503 | } | ||
504 | #endif | ||
505 | |||
506 | static inline int em28xx_isoc_video(struct em28xx *dev,struct em28xx_frame_t **f, | ||
507 | unsigned long *lock_flags, unsigned char buf) | ||
508 | { | ||
509 | if (!(buf & 0x01)) { | ||
510 | if ((*f)->state == F_GRABBING) { | ||
511 | /*previous frame is incomplete */ | ||
512 | if ((*f)->fieldbytesused < dev->field_size) { | ||
513 | (*f)->state = F_ERROR; | ||
514 | em28xx_isocdbg ("dropping incomplete bottom field (%i missing bytes)", | ||
515 | dev->field_size-(*f)->fieldbytesused); | ||
516 | } else { | ||
517 | (*f)->state = F_DONE; | ||
518 | (*f)->buf.bytesused = dev->frame_size; | ||
519 | } | ||
520 | } | ||
521 | if ((*f)->state == F_DONE || (*f)->state == F_ERROR) { | ||
522 | /* move current frame to outqueue and get next free buffer from inqueue */ | ||
523 | spin_lock_irqsave(&dev-> queue_lock, *lock_flags); | ||
524 | list_move_tail(&(*f)->frame, &dev->outqueue); | ||
525 | if (!list_empty(&dev->inqueue)) | ||
526 | (*f) = list_entry(dev-> inqueue.next, | ||
527 | struct em28xx_frame_t,frame); | ||
528 | else | ||
529 | (*f) = NULL; | ||
530 | spin_unlock_irqrestore(&dev->queue_lock,*lock_flags); | ||
531 | } | ||
532 | if (!(*f)) { | ||
533 | em28xx_isocdbg ("new frame but no buffer is free"); | ||
534 | return -1; | ||
535 | } | ||
536 | do_gettimeofday(&(*f)->buf.timestamp); | ||
537 | (*f)->buf.sequence = ++dev->frame_count; | ||
538 | (*f)->buf.field = V4L2_FIELD_INTERLACED; | ||
539 | (*f)->state = F_GRABBING; | ||
540 | (*f)->buf.bytesused = 0; | ||
541 | (*f)->top_field = 1; | ||
542 | (*f)->fieldbytesused = 0; | ||
543 | } else { | ||
544 | /* acquiring bottom field */ | ||
545 | if ((*f)->state == F_GRABBING) { | ||
546 | if (!(*f)->top_field) { | ||
547 | (*f)->state = F_ERROR; | ||
548 | em28xx_isocdbg ("unexpected begin of bottom field; discarding it"); | ||
549 | } else if ((*f)-> fieldbytesused < dev->field_size - 172) { | ||
550 | (*f)->state = F_ERROR; | ||
551 | em28xx_isocdbg ("dropping incomplete top field (%i missing bytes)", | ||
552 | dev->field_size-(*f)->fieldbytesused); | ||
553 | } else { | ||
554 | (*f)->top_field = 0; | ||
555 | (*f)->fieldbytesused = 0; | ||
556 | } | ||
557 | } | ||
558 | } | ||
559 | return (0); | ||
560 | } | ||
561 | |||
562 | static inline void em28xx_isoc_video_copy(struct em28xx *dev, | ||
563 | struct em28xx_frame_t **f, unsigned char *buf, int len) | ||
564 | { | ||
565 | void *fieldstart, *startwrite, *startread; | ||
566 | int linesdone, currlinedone, offset, lencopy,remain; | ||
567 | |||
568 | if(dev->frame_size != (*f)->buf.length){ | ||
569 | em28xx_err("frame_size %i and buf.length %i are different!!!\n",dev->frame_size,(*f)->buf.length); | ||
570 | return; | ||
571 | } | ||
572 | |||
573 | if ((*f)->fieldbytesused + len > dev->field_size) | ||
574 | len =dev->field_size - (*f)->fieldbytesused; | ||
575 | |||
576 | if (buf[0] != 0x88 && buf[0] != 0x22) { | ||
577 | em28xx_isocdbg("frame is not complete\n"); | ||
578 | startread = buf; | ||
579 | len+=4; | ||
580 | } else | ||
581 | startread = buf + 4; | ||
582 | |||
583 | remain = len; | ||
584 | |||
585 | if ((*f)->top_field) | ||
586 | fieldstart = (*f)->bufmem; | ||
587 | else | ||
588 | fieldstart = (*f)->bufmem + dev->bytesperline; | ||
589 | |||
590 | linesdone = (*f)->fieldbytesused / dev->bytesperline; | ||
591 | currlinedone = (*f)->fieldbytesused % dev->bytesperline; | ||
592 | offset = linesdone * dev->bytesperline * 2 + currlinedone; | ||
593 | startwrite = fieldstart + offset; | ||
594 | lencopy = dev->bytesperline - currlinedone; | ||
595 | lencopy = lencopy > remain ? remain : lencopy; | ||
596 | |||
597 | memcpy(startwrite, startread, lencopy); | ||
598 | remain -= lencopy; | ||
599 | |||
600 | while (remain > 0) { | ||
601 | startwrite += lencopy + dev->bytesperline; | ||
602 | startread += lencopy; | ||
603 | if (dev->bytesperline > remain) | ||
604 | lencopy = remain; | ||
605 | else | ||
606 | lencopy = dev->bytesperline; | ||
607 | |||
608 | memcpy(startwrite, startread, lencopy); | ||
609 | remain -= lencopy; | ||
610 | } | ||
611 | |||
612 | (*f)->fieldbytesused += len; | ||
613 | } | ||
614 | |||
615 | /* | ||
616 | * em28xx_isoIrq() | ||
617 | * handles the incoming isoc urbs and fills the frames from our inqueue | ||
618 | */ | ||
619 | void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs) | ||
620 | { | ||
621 | struct em28xx *dev = urb->context; | ||
622 | int i, status; | ||
623 | struct em28xx_frame_t **f; | ||
624 | unsigned long lock_flags; | ||
625 | |||
626 | if (!dev) | ||
627 | return; | ||
628 | #ifdef ENABLE_DEBUG_ISOC_FRAMES | ||
629 | if (isoc_debug>1) | ||
630 | em28xx_isoc_dump(urb, regs); | ||
631 | #endif | ||
632 | |||
633 | if (urb->status == -ENOENT) | ||
634 | return; | ||
635 | |||
636 | f = &dev->frame_current; | ||
637 | |||
638 | if (dev->stream == STREAM_INTERRUPT) { | ||
639 | dev->stream = STREAM_OFF; | ||
640 | if ((*f)) | ||
641 | (*f)->state = F_QUEUED; | ||
642 | em28xx_isocdbg("stream interrupted"); | ||
643 | wake_up_interruptible(&dev->wait_stream); | ||
644 | } | ||
645 | |||
646 | if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) | ||
647 | return; | ||
648 | |||
649 | if (dev->stream == STREAM_ON && !list_empty(&dev->inqueue)) { | ||
650 | if (!(*f)) | ||
651 | (*f) = list_entry(dev->inqueue.next, | ||
652 | struct em28xx_frame_t, frame); | ||
653 | |||
654 | for (i = 0; i < urb->number_of_packets; i++) { | ||
655 | unsigned char *buf = urb->transfer_buffer + | ||
656 | urb->iso_frame_desc[i].offset; | ||
657 | int len = urb->iso_frame_desc[i].actual_length - 4; | ||
658 | |||
659 | if (urb->iso_frame_desc[i].status) { | ||
660 | em28xx_isocdbg("data error: [%d] len=%d, status=%d", i, | ||
661 | urb->iso_frame_desc[i].actual_length, | ||
662 | urb->iso_frame_desc[i].status); | ||
663 | if (urb->iso_frame_desc[i].status != -EPROTO) | ||
664 | continue; | ||
665 | } | ||
666 | if (urb->iso_frame_desc[i].actual_length <= 0) { | ||
667 | em28xx_isocdbg("packet %d is empty",i); | ||
668 | continue; | ||
669 | } | ||
670 | if (urb->iso_frame_desc[i].actual_length > | ||
671 | dev->max_pkt_size) { | ||
672 | em28xx_isocdbg("packet bigger than packet size"); | ||
673 | continue; | ||
674 | } | ||
675 | /*new frame */ | ||
676 | if (buf[0] == 0x22 && buf[1] == 0x5a) { | ||
677 | em28xx_isocdbg("Video frame, length=%i!",len); | ||
678 | |||
679 | if (em28xx_isoc_video(dev,f,&lock_flags,buf[2])) | ||
680 | break; | ||
681 | } else if (buf[0]==0x33 && buf[1]==0x95 && buf[2]==0x00) { | ||
682 | em28xx_isocdbg("VBI HEADER!!!"); | ||
683 | } | ||
684 | |||
685 | /* actual copying */ | ||
686 | if ((*f)->state == F_GRABBING) { | ||
687 | em28xx_isoc_video_copy(dev,f,buf, len); | ||
688 | } | ||
689 | } | ||
690 | } | ||
691 | |||
692 | for (i = 0; i < urb->number_of_packets; i++) { | ||
693 | urb->iso_frame_desc[i].status = 0; | ||
694 | urb->iso_frame_desc[i].actual_length = 0; | ||
695 | } | ||
696 | |||
697 | urb->status = 0; | ||
698 | if ((status = usb_submit_urb(urb, GFP_ATOMIC))) { | ||
699 | em28xx_errdev("resubmit of urb failed (error=%i)\n", status); | ||
700 | dev->state |= DEV_MISCONFIGURED; | ||
701 | } | ||
702 | wake_up_interruptible(&dev->wait_frame); | ||
703 | return; | ||
704 | } | ||
705 | |||
706 | /* | ||
707 | * em28xx_uninit_isoc() | ||
708 | * deallocates the buffers and urbs allocated during em28xx_init_iosc() | ||
709 | */ | ||
710 | void em28xx_uninit_isoc(struct em28xx *dev) | ||
711 | { | ||
712 | int i; | ||
713 | |||
714 | for (i = 0; i < EM28XX_NUM_BUFS; i++) { | ||
715 | if (dev->urb[i]) { | ||
716 | usb_kill_urb(dev->urb[i]); | ||
717 | if (dev->transfer_buffer[i]){ | ||
718 | usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma); | ||
719 | } | ||
720 | usb_free_urb(dev->urb[i]); | ||
721 | } | ||
722 | dev->urb[i] = NULL; | ||
723 | dev->transfer_buffer[i] = NULL; | ||
724 | } | ||
725 | em28xx_capture_start(dev, 0); | ||
726 | } | ||
727 | |||
728 | /* | ||
729 | * em28xx_init_isoc() | ||
730 | * allocates transfer buffers and submits the urbs for isoc transfer | ||
731 | */ | ||
732 | int em28xx_init_isoc(struct em28xx *dev) | ||
733 | { | ||
734 | /* change interface to 3 which allowes the biggest packet sizes */ | ||
735 | int i, errCode; | ||
736 | const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size; | ||
737 | |||
738 | /* reset streaming vars */ | ||
739 | dev->frame_current = NULL; | ||
740 | dev->frame_count = 0; | ||
741 | |||
742 | /* allocate urbs */ | ||
743 | for (i = 0; i < EM28XX_NUM_BUFS; i++) { | ||
744 | struct urb *urb; | ||
745 | int j, k; | ||
746 | /* allocate transfer buffer */ | ||
747 | urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL); | ||
748 | if (!urb){ | ||
749 | em28xx_errdev("cannot alloc urb %i\n", i); | ||
750 | em28xx_uninit_isoc(dev); | ||
751 | return -ENOMEM; | ||
752 | } | ||
753 | dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma); | ||
754 | if (!dev->transfer_buffer[i]) { | ||
755 | em28xx_errdev | ||
756 | ("unable to allocate %i bytes for transfer buffer %i\n", | ||
757 | sb_size, i); | ||
758 | em28xx_uninit_isoc(dev); | ||
759 | return -ENOMEM; | ||
760 | } | ||
761 | memset(dev->transfer_buffer[i], 0, sb_size); | ||
762 | urb->dev = dev->udev; | ||
763 | urb->context = dev; | ||
764 | urb->pipe = usb_rcvisocpipe(dev->udev, 0x82); | ||
765 | urb->transfer_flags = URB_ISO_ASAP; | ||
766 | urb->interval = 1; | ||
767 | urb->transfer_buffer = dev->transfer_buffer[i]; | ||
768 | urb->complete = em28xx_isocIrq; | ||
769 | urb->number_of_packets = EM28XX_NUM_PACKETS; | ||
770 | urb->transfer_buffer_length = sb_size; | ||
771 | for (j = k = 0; j < EM28XX_NUM_PACKETS; | ||
772 | j++, k += dev->max_pkt_size) { | ||
773 | urb->iso_frame_desc[j].offset = k; | ||
774 | urb->iso_frame_desc[j].length = | ||
775 | dev->max_pkt_size; | ||
776 | } | ||
777 | dev->urb[i] = urb; | ||
778 | } | ||
779 | |||
780 | /* submit urbs */ | ||
781 | for (i = 0; i < EM28XX_NUM_BUFS; i++) { | ||
782 | errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL); | ||
783 | if (errCode) { | ||
784 | em28xx_errdev("submit of urb %i failed (error=%i)\n", i, | ||
785 | errCode); | ||
786 | em28xx_uninit_isoc(dev); | ||
787 | return errCode; | ||
788 | } | ||
789 | } | ||
790 | |||
791 | return 0; | ||
792 | } | ||
793 | |||
794 | int em28xx_set_alternate(struct em28xx *dev) | ||
795 | { | ||
796 | int errCode, prev_alt = dev->alt; | ||
797 | dev->alt = alt; | ||
798 | if (dev->alt == 0) { | ||
799 | int i; | ||
800 | for(i=0;i< dev->num_alt; i++) | ||
801 | if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt]) | ||
802 | dev->alt=i; | ||
803 | } | ||
804 | |||
805 | if (dev->alt != prev_alt) { | ||
806 | dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt]; | ||
807 | em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt, | ||
808 | dev->max_pkt_size); | ||
809 | errCode = usb_set_interface(dev->udev, 0, dev->alt); | ||
810 | if (errCode < 0) { | ||
811 | em28xx_errdev ("cannot change alternate number to %d (error=%i)\n", | ||
812 | dev->alt, errCode); | ||
813 | return errCode; | ||
814 | } | ||
815 | } | ||
816 | return 0; | ||
817 | } | ||
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c new file mode 100644 index 000000000000..b32d9852f34c --- /dev/null +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
@@ -0,0 +1,586 @@ | |||
1 | /* | ||
2 | em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | ||
3 | |||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | ||
5 | Markus Rechberger <mrechberger@gmail.com> | ||
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | ||
7 | Sascha Sommer <saschasommer@freenet.de> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/usb.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/video_decoder.h> | ||
29 | |||
30 | #include "em28xx.h" | ||
31 | #include <media/tuner.h> | ||
32 | |||
33 | /* ----------------------------------------------------------- */ | ||
34 | |||
35 | static unsigned int i2c_scan = 0; | ||
36 | module_param(i2c_scan, int, 0444); | ||
37 | MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); | ||
38 | |||
39 | static unsigned int i2c_debug = 0; | ||
40 | module_param(i2c_debug, int, 0644); | ||
41 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | ||
42 | |||
43 | #define dprintk1(lvl,fmt, args...) if (i2c_debug>=lvl) do {\ | ||
44 | printk(fmt , ##args); } while (0) | ||
45 | #define dprintk2(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \ | ||
46 | printk(KERN_DEBUG "%s at %s: " fmt, \ | ||
47 | dev->name, __FUNCTION__ , ##args); } while (0) | ||
48 | |||
49 | /* | ||
50 | * em2800_i2c_send_max4() | ||
51 | * send up to 4 bytes to the i2c device | ||
52 | */ | ||
53 | static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr, | ||
54 | char *buf, int len) | ||
55 | { | ||
56 | int ret; | ||
57 | int write_timeout; | ||
58 | unsigned char b2[6]; | ||
59 | BUG_ON(len < 1 || len > 4); | ||
60 | b2[5] = 0x80 + len - 1; | ||
61 | b2[4] = addr; | ||
62 | b2[3] = buf[0]; | ||
63 | if (len > 1) | ||
64 | b2[2] = buf[1]; | ||
65 | if (len > 2) | ||
66 | b2[1] = buf[2]; | ||
67 | if (len > 3) | ||
68 | b2[0] = buf[3]; | ||
69 | |||
70 | ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len); | ||
71 | if (ret != 2 + len) { | ||
72 | em28xx_warn("writting to i2c device failed (error=%i)\n", ret); | ||
73 | return -EIO; | ||
74 | } | ||
75 | for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0; | ||
76 | write_timeout -= 5) { | ||
77 | ret = dev->em28xx_read_reg(dev, 0x05); | ||
78 | if (ret == 0x80 + len - 1) | ||
79 | return len; | ||
80 | mdelay(5); | ||
81 | } | ||
82 | em28xx_warn("i2c write timed out\n"); | ||
83 | return -EIO; | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * em2800_i2c_send_bytes() | ||
88 | */ | ||
89 | static int em2800_i2c_send_bytes(void *data, unsigned char addr, char *buf, | ||
90 | short len) | ||
91 | { | ||
92 | char *bufPtr = buf; | ||
93 | int ret; | ||
94 | int wrcount = 0; | ||
95 | int count; | ||
96 | int maxLen = 4; | ||
97 | struct em28xx *dev = (struct em28xx *)data; | ||
98 | while (len > 0) { | ||
99 | count = (len > maxLen) ? maxLen : len; | ||
100 | ret = em2800_i2c_send_max4(dev, addr, bufPtr, count); | ||
101 | if (ret > 0) { | ||
102 | len -= count; | ||
103 | bufPtr += count; | ||
104 | wrcount += count; | ||
105 | } else | ||
106 | return (ret < 0) ? ret : -EFAULT; | ||
107 | } | ||
108 | return wrcount; | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * em2800_i2c_check_for_device() | ||
113 | * check if there is a i2c_device at the supplied address | ||
114 | */ | ||
115 | static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr) | ||
116 | { | ||
117 | char msg; | ||
118 | int ret; | ||
119 | int write_timeout; | ||
120 | msg = addr; | ||
121 | ret = dev->em28xx_write_regs(dev, 0x04, &msg, 1); | ||
122 | if (ret < 0) { | ||
123 | em28xx_warn("setting i2c device address failed (error=%i)\n", | ||
124 | ret); | ||
125 | return ret; | ||
126 | } | ||
127 | msg = 0x84; | ||
128 | ret = dev->em28xx_write_regs(dev, 0x05, &msg, 1); | ||
129 | if (ret < 0) { | ||
130 | em28xx_warn("preparing i2c read failed (error=%i)\n", ret); | ||
131 | return ret; | ||
132 | } | ||
133 | for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0; | ||
134 | write_timeout -= 5) { | ||
135 | unsigned msg = dev->em28xx_read_reg(dev, 0x5); | ||
136 | if (msg == 0x94) | ||
137 | return -ENODEV; | ||
138 | else if (msg == 0x84) | ||
139 | return 0; | ||
140 | mdelay(5); | ||
141 | } | ||
142 | return -ENODEV; | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * em2800_i2c_recv_bytes() | ||
147 | * read from the i2c device | ||
148 | */ | ||
149 | static int em2800_i2c_recv_bytes(struct em28xx *dev, unsigned char addr, | ||
150 | char *buf, int len) | ||
151 | { | ||
152 | int ret; | ||
153 | /* check for the device and set i2c read address */ | ||
154 | ret = em2800_i2c_check_for_device(dev, addr); | ||
155 | if (ret) { | ||
156 | em28xx_warn | ||
157 | ("preparing read at i2c address 0x%x failed (error=%i)\n", | ||
158 | addr, ret); | ||
159 | return ret; | ||
160 | } | ||
161 | ret = dev->em28xx_read_reg_req_len(dev, 0x0, 0x3, buf, len); | ||
162 | if (ret < 0) { | ||
163 | em28xx_warn("reading from i2c device at 0x%x failed (error=%i)", | ||
164 | addr, ret); | ||
165 | return ret; | ||
166 | } | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | /* | ||
171 | * em28xx_i2c_send_bytes() | ||
172 | * untested for more than 4 bytes | ||
173 | */ | ||
174 | static int em28xx_i2c_send_bytes(void *data, unsigned char addr, char *buf, | ||
175 | short len, int stop) | ||
176 | { | ||
177 | int wrcount = 0; | ||
178 | struct em28xx *dev = (struct em28xx *)data; | ||
179 | |||
180 | wrcount = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len); | ||
181 | |||
182 | return wrcount; | ||
183 | } | ||
184 | |||
185 | /* | ||
186 | * em28xx_i2c_recv_bytes() | ||
187 | * read a byte from the i2c device | ||
188 | */ | ||
189 | static int em28xx_i2c_recv_bytes(struct em28xx *dev, unsigned char addr, | ||
190 | char *buf, int len) | ||
191 | { | ||
192 | int ret; | ||
193 | ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len); | ||
194 | if (ret < 0) { | ||
195 | em28xx_warn("reading i2c device failed (error=%i)\n", ret); | ||
196 | return ret; | ||
197 | } | ||
198 | if (dev->em28xx_read_reg(dev, 0x5) != 0) | ||
199 | return -ENODEV; | ||
200 | return ret; | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * em28xx_i2c_check_for_device() | ||
205 | * check if there is a i2c_device at the supplied address | ||
206 | */ | ||
207 | static int em28xx_i2c_check_for_device(struct em28xx *dev, unsigned char addr) | ||
208 | { | ||
209 | char msg; | ||
210 | int ret; | ||
211 | msg = addr; | ||
212 | |||
213 | ret = dev->em28xx_read_reg_req(dev, 2, addr); | ||
214 | if (ret < 0) { | ||
215 | em28xx_warn("reading from i2c device failed (error=%i)\n", ret); | ||
216 | return ret; | ||
217 | } | ||
218 | if (dev->em28xx_read_reg(dev, 0x5) != 0) | ||
219 | return -ENODEV; | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * em28xx_i2c_xfer() | ||
225 | * the main i2c transfer function | ||
226 | */ | ||
227 | static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, | ||
228 | struct i2c_msg msgs[], int num) | ||
229 | { | ||
230 | struct em28xx *dev = i2c_adap->algo_data; | ||
231 | int addr, rc, i, byte; | ||
232 | |||
233 | if (num <= 0) | ||
234 | return 0; | ||
235 | for (i = 0; i < num; i++) { | ||
236 | addr = msgs[i].addr << 1; | ||
237 | dprintk2(2,"%s %s addr=%x len=%d:", | ||
238 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", | ||
239 | i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); | ||
240 | if (!msgs[i].len) { /* no len: check only for device presence */ | ||
241 | if (dev->is_em2800) | ||
242 | rc = em2800_i2c_check_for_device(dev, addr); | ||
243 | else | ||
244 | rc = em28xx_i2c_check_for_device(dev, addr); | ||
245 | if (rc < 0) { | ||
246 | dprintk2(2," no device\n"); | ||
247 | return rc; | ||
248 | } | ||
249 | |||
250 | } else if (msgs[i].flags & I2C_M_RD) { | ||
251 | /* read bytes */ | ||
252 | if (dev->is_em2800) | ||
253 | rc = em2800_i2c_recv_bytes(dev, addr, | ||
254 | msgs[i].buf, | ||
255 | msgs[i].len); | ||
256 | else | ||
257 | rc = em28xx_i2c_recv_bytes(dev, addr, | ||
258 | msgs[i].buf, | ||
259 | msgs[i].len); | ||
260 | if (i2c_debug>=2) { | ||
261 | for (byte = 0; byte < msgs[i].len; byte++) { | ||
262 | printk(" %02x", msgs[i].buf[byte]); | ||
263 | } | ||
264 | } | ||
265 | } else { | ||
266 | /* write bytes */ | ||
267 | if (i2c_debug>=2) { | ||
268 | for (byte = 0; byte < msgs[i].len; byte++) | ||
269 | printk(" %02x", msgs[i].buf[byte]); | ||
270 | } | ||
271 | if (dev->is_em2800) | ||
272 | rc = em2800_i2c_send_bytes(dev, addr, | ||
273 | msgs[i].buf, | ||
274 | msgs[i].len); | ||
275 | else | ||
276 | rc = em28xx_i2c_send_bytes(dev, addr, | ||
277 | msgs[i].buf, | ||
278 | msgs[i].len, | ||
279 | i == num - 1); | ||
280 | if (rc < 0) | ||
281 | goto err; | ||
282 | } | ||
283 | if (i2c_debug>=2) | ||
284 | printk("\n"); | ||
285 | } | ||
286 | |||
287 | return num; | ||
288 | err: | ||
289 | dprintk2(2," ERROR: %i\n", rc); | ||
290 | return rc; | ||
291 | } | ||
292 | |||
293 | static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) | ||
294 | { | ||
295 | unsigned char buf, *p = eedata; | ||
296 | struct em28xx_eeprom *em_eeprom = (void *)eedata; | ||
297 | int i, err, size = len, block; | ||
298 | |||
299 | dev->i2c_client.addr = 0xa0 >> 1; | ||
300 | |||
301 | /* Check if board has eeprom */ | ||
302 | err = i2c_master_recv(&dev->i2c_client, &buf, 0); | ||
303 | if (err < 0) | ||
304 | return -1; | ||
305 | |||
306 | buf = 0; | ||
307 | if (1 != (err = i2c_master_send(&dev->i2c_client, &buf, 1))) { | ||
308 | printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", | ||
309 | dev->name, err); | ||
310 | return -1; | ||
311 | } | ||
312 | while (size > 0) { | ||
313 | if (size > 16) | ||
314 | block = 16; | ||
315 | else | ||
316 | block = size; | ||
317 | |||
318 | if (block != | ||
319 | (err = i2c_master_recv(&dev->i2c_client, p, block))) { | ||
320 | printk(KERN_WARNING | ||
321 | "%s: i2c eeprom read error (err=%d)\n", | ||
322 | dev->name, err); | ||
323 | return -1; | ||
324 | } | ||
325 | size -= block; | ||
326 | p += block; | ||
327 | } | ||
328 | for (i = 0; i < len; i++) { | ||
329 | if (0 == (i % 16)) | ||
330 | printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i); | ||
331 | printk(" %02x", eedata[i]); | ||
332 | if (15 == (i % 16)) | ||
333 | printk("\n"); | ||
334 | } | ||
335 | |||
336 | printk(KERN_INFO "EEPROM ID= 0x%08x\n", em_eeprom->id); | ||
337 | printk(KERN_INFO "Vendor/Product ID= %04x:%04x\n", em_eeprom->vendor_ID, | ||
338 | em_eeprom->product_ID); | ||
339 | |||
340 | switch (em_eeprom->chip_conf >> 4 & 0x3) { | ||
341 | case 0: | ||
342 | printk(KERN_INFO "No audio on board.\n"); | ||
343 | break; | ||
344 | case 1: | ||
345 | printk(KERN_INFO "AC97 audio (5 sample rates)\n"); | ||
346 | break; | ||
347 | case 2: | ||
348 | printk(KERN_INFO "I2S audio, sample rate=32k\n"); | ||
349 | break; | ||
350 | case 3: | ||
351 | printk(KERN_INFO "I2S audio, 3 sample rates\n"); | ||
352 | break; | ||
353 | } | ||
354 | |||
355 | if (em_eeprom->chip_conf & 1 << 3) | ||
356 | printk(KERN_INFO "USB Remote wakeup capable\n"); | ||
357 | |||
358 | if (em_eeprom->chip_conf & 1 << 2) | ||
359 | printk(KERN_INFO "USB Self power capable\n"); | ||
360 | |||
361 | switch (em_eeprom->chip_conf & 0x3) { | ||
362 | case 0: | ||
363 | printk(KERN_INFO "500mA max power\n"); | ||
364 | break; | ||
365 | case 1: | ||
366 | printk(KERN_INFO "400mA max power\n"); | ||
367 | break; | ||
368 | case 2: | ||
369 | printk(KERN_INFO "300mA max power\n"); | ||
370 | break; | ||
371 | case 3: | ||
372 | printk(KERN_INFO "200mA max power\n"); | ||
373 | break; | ||
374 | } | ||
375 | printk(KERN_INFO "Table at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", | ||
376 | em_eeprom->string_idx_table,em_eeprom->string1, | ||
377 | em_eeprom->string2,em_eeprom->string3); | ||
378 | |||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | /* ----------------------------------------------------------- */ | ||
383 | |||
384 | /* | ||
385 | * algo_control() | ||
386 | */ | ||
387 | static int algo_control(struct i2c_adapter *adapter, | ||
388 | unsigned int cmd, unsigned long arg) | ||
389 | { | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | /* | ||
394 | * functionality() | ||
395 | */ | ||
396 | static u32 functionality(struct i2c_adapter *adap) | ||
397 | { | ||
398 | return I2C_FUNC_SMBUS_EMUL; | ||
399 | } | ||
400 | |||
401 | #ifndef I2C_PEC | ||
402 | static void inc_use(struct i2c_adapter *adap) | ||
403 | { | ||
404 | MOD_INC_USE_COUNT; | ||
405 | } | ||
406 | |||
407 | static void dec_use(struct i2c_adapter *adap) | ||
408 | { | ||
409 | MOD_DEC_USE_COUNT; | ||
410 | } | ||
411 | #endif | ||
412 | |||
413 | static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client) | ||
414 | { | ||
415 | struct em28xx *dev = client->adapter->algo_data; | ||
416 | struct tuner_setup tun_setup; | ||
417 | |||
418 | if (dev->has_tuner) { | ||
419 | tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; | ||
420 | tun_setup.type = dev->tuner_type; | ||
421 | tun_setup.addr = dev->tuner_addr; | ||
422 | |||
423 | em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); | ||
424 | } | ||
425 | |||
426 | return (0); | ||
427 | } | ||
428 | |||
429 | /* | ||
430 | * attach_inform() | ||
431 | * gets called when a device attaches to the i2c bus | ||
432 | * does some basic configuration | ||
433 | */ | ||
434 | static int attach_inform(struct i2c_client *client) | ||
435 | { | ||
436 | struct em28xx *dev = client->adapter->algo_data; | ||
437 | |||
438 | switch (client->addr << 1) { | ||
439 | case 0x86: | ||
440 | em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf); | ||
441 | break; | ||
442 | case 0x42: | ||
443 | dprintk1(1,"attach_inform: saa7114 detected.\n"); | ||
444 | break; | ||
445 | case 0x4a: | ||
446 | dprintk1(1,"attach_inform: saa7113 detected.\n"); | ||
447 | break; | ||
448 | case 0xa0: | ||
449 | dprintk1(1,"attach_inform: eeprom detected.\n"); | ||
450 | break; | ||
451 | case 0x60: | ||
452 | case 0x8e: | ||
453 | { | ||
454 | struct IR_i2c *ir = i2c_get_clientdata(client); | ||
455 | dprintk1(1,"attach_inform: IR detected (%s).\n",ir->phys); | ||
456 | em28xx_set_ir(dev,ir); | ||
457 | break; | ||
458 | } | ||
459 | case 0x80: | ||
460 | case 0x88: | ||
461 | dprintk1(1,"attach_inform: msp34xx detected.\n"); | ||
462 | break; | ||
463 | case 0xb8: | ||
464 | case 0xba: | ||
465 | dprintk1(1,"attach_inform: tvp5150 detected.\n"); | ||
466 | break; | ||
467 | default: | ||
468 | dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1); | ||
469 | dev->tuner_addr = client->addr; | ||
470 | em28xx_set_tuner(-1, client); | ||
471 | } | ||
472 | |||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static struct i2c_algorithm em28xx_algo = { | ||
477 | .master_xfer = em28xx_i2c_xfer, | ||
478 | .algo_control = algo_control, | ||
479 | .functionality = functionality, | ||
480 | }; | ||
481 | |||
482 | static struct i2c_adapter em28xx_adap_template = { | ||
483 | #ifdef I2C_PEC | ||
484 | .owner = THIS_MODULE, | ||
485 | #else | ||
486 | .inc_use = inc_use, | ||
487 | .dec_use = dec_use, | ||
488 | #endif | ||
489 | #ifdef I2C_CLASS_TV_ANALOG | ||
490 | .class = I2C_CLASS_TV_ANALOG, | ||
491 | #endif | ||
492 | .name = "em28xx", | ||
493 | .id = I2C_HW_B_EM28XX, | ||
494 | .algo = &em28xx_algo, | ||
495 | .client_register = attach_inform, | ||
496 | }; | ||
497 | |||
498 | static struct i2c_client em28xx_client_template = { | ||
499 | .name = "em28xx internal", | ||
500 | .flags = I2C_CLIENT_ALLOW_USE, | ||
501 | }; | ||
502 | |||
503 | /* ----------------------------------------------------------- */ | ||
504 | |||
505 | /* | ||
506 | * i2c_devs | ||
507 | * incomplete list of known devices | ||
508 | */ | ||
509 | static char *i2c_devs[128] = { | ||
510 | [0x4a >> 1] = "saa7113h", | ||
511 | [0x60 >> 1] = "remote IR sensor", | ||
512 | [0x8e >> 1] = "remote IR sensor", | ||
513 | [0x86 >> 1] = "tda9887", | ||
514 | [0x80 >> 1] = "msp34xx", | ||
515 | [0x88 >> 1] = "msp34xx", | ||
516 | [0xa0 >> 1] = "eeprom", | ||
517 | [0xb8 >> 1] = "tvp5150a", | ||
518 | [0xba >> 1] = "tvp5150a", | ||
519 | [0xc0 >> 1] = "tuner (analog)", | ||
520 | [0xc2 >> 1] = "tuner (analog)", | ||
521 | [0xc4 >> 1] = "tuner (analog)", | ||
522 | [0xc6 >> 1] = "tuner (analog)", | ||
523 | }; | ||
524 | |||
525 | /* | ||
526 | * do_i2c_scan() | ||
527 | * check i2c address range for devices | ||
528 | */ | ||
529 | static void do_i2c_scan(char *name, struct i2c_client *c) | ||
530 | { | ||
531 | unsigned char buf; | ||
532 | int i, rc; | ||
533 | |||
534 | for (i = 0; i < 128; i++) { | ||
535 | c->addr = i; | ||
536 | rc = i2c_master_recv(c, &buf, 0); | ||
537 | if (rc < 0) | ||
538 | continue; | ||
539 | printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n", name, | ||
540 | i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); | ||
541 | } | ||
542 | } | ||
543 | |||
544 | /* | ||
545 | * em28xx_i2c_call_clients() | ||
546 | * send commands to all attached i2c devices | ||
547 | */ | ||
548 | void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg) | ||
549 | { | ||
550 | BUG_ON(NULL == dev->i2c_adap.algo_data); | ||
551 | i2c_clients_command(&dev->i2c_adap, cmd, arg); | ||
552 | } | ||
553 | |||
554 | /* | ||
555 | * em28xx_i2c_register() | ||
556 | * register i2c bus | ||
557 | */ | ||
558 | int em28xx_i2c_register(struct em28xx *dev) | ||
559 | { | ||
560 | BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg); | ||
561 | BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req); | ||
562 | dev->i2c_adap = em28xx_adap_template; | ||
563 | dev->i2c_adap.dev.parent = &dev->udev->dev; | ||
564 | strcpy(dev->i2c_adap.name, dev->name); | ||
565 | dev->i2c_adap.algo_data = dev; | ||
566 | i2c_add_adapter(&dev->i2c_adap); | ||
567 | |||
568 | dev->i2c_client = em28xx_client_template; | ||
569 | dev->i2c_client.adapter = &dev->i2c_adap; | ||
570 | |||
571 | em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata)); | ||
572 | |||
573 | if (i2c_scan) | ||
574 | do_i2c_scan(dev->name, &dev->i2c_client); | ||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | /* | ||
579 | * em28xx_i2c_unregister() | ||
580 | * unregister i2c_bus | ||
581 | */ | ||
582 | int em28xx_i2c_unregister(struct em28xx *dev) | ||
583 | { | ||
584 | i2c_del_adapter(&dev->i2c_adap); | ||
585 | return 0; | ||
586 | } | ||
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c new file mode 100644 index 000000000000..32c49df58adc --- /dev/null +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -0,0 +1,184 @@ | |||
1 | /* | ||
2 | handle em28xx IR remotes via linux kernel input layer. | ||
3 | |||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | ||
5 | Markus Rechberger <mrechberger@gmail.com> | ||
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | ||
7 | Sascha Sommer <saschasommer@freenet.de> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/moduleparam.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/sched.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/input.h> | ||
31 | #include <linux/usb.h> | ||
32 | |||
33 | #include "em28xx.h" | ||
34 | |||
35 | static unsigned int disable_ir = 0; | ||
36 | module_param(disable_ir, int, 0444); | ||
37 | MODULE_PARM_DESC(disable_ir,"disable infrared remote support"); | ||
38 | |||
39 | static unsigned int ir_debug = 0; | ||
40 | module_param(ir_debug, int, 0644); | ||
41 | MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); | ||
42 | |||
43 | #define dprintk(fmt, arg...) if (ir_debug) \ | ||
44 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) | ||
45 | |||
46 | /* ---------------------------------------------------------------------- */ | ||
47 | |||
48 | static IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = { | ||
49 | [ 0x01 ] = KEY_CHANNEL, | ||
50 | [ 0x02 ] = KEY_SELECT, | ||
51 | [ 0x03 ] = KEY_MUTE, | ||
52 | [ 0x04 ] = KEY_POWER, | ||
53 | [ 0x05 ] = KEY_KP1, | ||
54 | [ 0x06 ] = KEY_KP2, | ||
55 | [ 0x07 ] = KEY_KP3, | ||
56 | [ 0x08 ] = KEY_CHANNELUP, | ||
57 | [ 0x09 ] = KEY_KP4, | ||
58 | [ 0x0a ] = KEY_KP5, | ||
59 | [ 0x0b ] = KEY_KP6, | ||
60 | [ 0x0c ] = KEY_CHANNELDOWN, | ||
61 | [ 0x0d ] = KEY_KP7, | ||
62 | [ 0x0e ] = KEY_KP8, | ||
63 | [ 0x0f ] = KEY_KP9, | ||
64 | [ 0x10 ] = KEY_VOLUMEUP, | ||
65 | [ 0x11 ] = KEY_KP0, | ||
66 | [ 0x12 ] = KEY_MENU, | ||
67 | [ 0x13 ] = KEY_PRINT, | ||
68 | [ 0x14 ] = KEY_VOLUMEDOWN, | ||
69 | [ 0x16 ] = KEY_PAUSE, | ||
70 | [ 0x18 ] = KEY_RECORD, | ||
71 | [ 0x19 ] = KEY_REWIND, | ||
72 | [ 0x1a ] = KEY_PLAY, | ||
73 | [ 0x1b ] = KEY_FORWARD, | ||
74 | [ 0x1c ] = KEY_BACKSPACE, | ||
75 | [ 0x1e ] = KEY_STOP, | ||
76 | [ 0x40 ] = KEY_ZOOM, | ||
77 | }; | ||
78 | |||
79 | /* ----------------------------------------------------------------------- */ | ||
80 | |||
81 | static int get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
82 | { | ||
83 | unsigned char b; | ||
84 | |||
85 | /* poll IR chip */ | ||
86 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | ||
87 | dprintk("read error\n"); | ||
88 | return -EIO; | ||
89 | } | ||
90 | |||
91 | /* it seems that 0xFE indicates that a button is still hold | ||
92 | down, while 0xff indicates that no button is hold | ||
93 | down. 0xfe sequences are sometimes interrupted by 0xFF */ | ||
94 | |||
95 | dprintk("key %02x\n", b); | ||
96 | |||
97 | if (b == 0xff) | ||
98 | return 0; | ||
99 | |||
100 | if (b == 0xfe) | ||
101 | /* keep old data */ | ||
102 | return 1; | ||
103 | |||
104 | *ir_key = b; | ||
105 | *ir_raw = b; | ||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | |||
110 | static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
111 | { | ||
112 | unsigned char buf[2]; | ||
113 | unsigned char code; | ||
114 | |||
115 | /* poll IR chip */ | ||
116 | if (2 != i2c_master_recv(&ir->c,buf,2)) | ||
117 | return -EIO; | ||
118 | |||
119 | /* Does eliminate repeated parity code */ | ||
120 | if (buf[1]==0xff) | ||
121 | return 0; | ||
122 | |||
123 | /* avoid fast reapeating */ | ||
124 | if (buf[1]==ir->old) | ||
125 | return 0; | ||
126 | ir->old=buf[1]; | ||
127 | |||
128 | /* Rearranges bits to the right order */ | ||
129 | code= ((buf[0]&0x01)<<5) | /* 0010 0000 */ | ||
130 | ((buf[0]&0x02)<<3) | /* 0001 0000 */ | ||
131 | ((buf[0]&0x04)<<1) | /* 0000 1000 */ | ||
132 | ((buf[0]&0x08)>>1) | /* 0000 0100 */ | ||
133 | ((buf[0]&0x10)>>3) | /* 0000 0010 */ | ||
134 | ((buf[0]&0x20)>>5); /* 0000 0001 */ | ||
135 | |||
136 | dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",code,buf[0]); | ||
137 | |||
138 | /* return key */ | ||
139 | *ir_key = code; | ||
140 | *ir_raw = code; | ||
141 | return 1; | ||
142 | } | ||
143 | |||
144 | /* ----------------------------------------------------------------------- */ | ||
145 | void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir) | ||
146 | { | ||
147 | if (disable_ir) { | ||
148 | ir->get_key=NULL; | ||
149 | return ; | ||
150 | } | ||
151 | |||
152 | /* detect & configure */ | ||
153 | switch (dev->model) { | ||
154 | case (EM2800_BOARD_UNKNOWN): | ||
155 | break; | ||
156 | case (EM2820_BOARD_UNKNOWN): | ||
157 | break; | ||
158 | case (EM2800_BOARD_TERRATEC_CINERGY_200): | ||
159 | case (EM2820_BOARD_TERRATEC_CINERGY_250): | ||
160 | ir->ir_codes = ir_codes_em_terratec; | ||
161 | ir->get_key = get_key_terratec; | ||
162 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)"); | ||
163 | break; | ||
164 | case (EM2820_BOARD_PINNACLE_USB_2): | ||
165 | break; | ||
166 | case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2): | ||
167 | ir->ir_codes = ir_codes_hauppauge_new; | ||
168 | ir->get_key = get_key_em_haup; | ||
169 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM2840 Hauppauge)"); | ||
170 | break; | ||
171 | case (EM2820_BOARD_MSI_VOX_USB_2): | ||
172 | break; | ||
173 | case (EM2800_BOARD_LEADTEK_WINFAST_USBII): | ||
174 | break; | ||
175 | case (EM2800_BOARD_KWORLD_USB2800): | ||
176 | break; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | /* ---------------------------------------------------------------------- | ||
181 | * Local variables: | ||
182 | * c-basic-offset: 8 | ||
183 | * End: | ||
184 | */ | ||
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c new file mode 100644 index 000000000000..57c1826b928e --- /dev/null +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -0,0 +1,1933 @@ | |||
1 | /* | ||
2 | em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | ||
3 | |||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | ||
5 | Markus Rechberger <mrechberger@gmail.com> | ||
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | ||
7 | Sascha Sommer <saschasommer@freenet.de> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/init.h> | ||
25 | #include <linux/list.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/usb.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/version.h> | ||
31 | #include <linux/video_decoder.h> | ||
32 | |||
33 | #include "em28xx.h" | ||
34 | #include <media/tuner.h> | ||
35 | |||
36 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ | ||
37 | "Markus Rechberger <mrechberger@gmail.com>, " \ | ||
38 | "Mauro Carvalho Chehab <mchehab@brturbo.com.br>, " \ | ||
39 | "Sascha Sommer <saschasommer@freenet.de>" | ||
40 | |||
41 | #define DRIVER_NAME "em28xx" | ||
42 | #define DRIVER_DESC "Empia em28xx based USB video device driver" | ||
43 | #define EM28XX_VERSION_CODE KERNEL_VERSION(0, 0, 1) | ||
44 | |||
45 | #define em28xx_videodbg(fmt, arg...) do {\ | ||
46 | if (video_debug) \ | ||
47 | printk(KERN_INFO "%s %s :"fmt, \ | ||
48 | dev->name, __FUNCTION__ , ##arg); } while (0) | ||
49 | |||
50 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
51 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
52 | MODULE_LICENSE("GPL"); | ||
53 | |||
54 | static LIST_HEAD(em28xx_devlist); | ||
55 | |||
56 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | ||
57 | module_param_array(card, int, NULL, 0444); | ||
58 | MODULE_PARM_DESC(card,"card type"); | ||
59 | |||
60 | static int tuner = -1; | ||
61 | module_param(tuner, int, 0444); | ||
62 | MODULE_PARM_DESC(tuner, "tuner type"); | ||
63 | |||
64 | static unsigned int video_debug = 0; | ||
65 | module_param(video_debug,int,0644); | ||
66 | MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); | ||
67 | |||
68 | /* supported tv norms */ | ||
69 | static struct em28xx_tvnorm tvnorms[] = { | ||
70 | { | ||
71 | .name = "PAL", | ||
72 | .id = V4L2_STD_PAL, | ||
73 | .mode = VIDEO_MODE_PAL, | ||
74 | }, { | ||
75 | .name = "NTSC", | ||
76 | .id = V4L2_STD_NTSC, | ||
77 | .mode = VIDEO_MODE_NTSC, | ||
78 | }, { | ||
79 | .name = "SECAM", | ||
80 | .id = V4L2_STD_SECAM, | ||
81 | .mode = VIDEO_MODE_SECAM, | ||
82 | }, { | ||
83 | .name = "PAL-M", | ||
84 | .id = V4L2_STD_PAL_M, | ||
85 | .mode = VIDEO_MODE_PAL, | ||
86 | } | ||
87 | }; | ||
88 | |||
89 | static const unsigned char saa7114_i2c_init[] = { | ||
90 | 0x00,0x00,0x01,0x08,0x02,0xc4,0x03,0x30,0x04,0x90,0x05,0x90,0x06,0xeb,0x07,0xe0, | ||
91 | 0x08,0x88,0x09,0x40,0x0a,0x80,0x0b,0x44,0x0c,0x40,0x0d,0x00,0x0e,0x81,0x0f,0x2a, | ||
92 | 0x10,0x06,0x11,0x00,0x12,0xc8,0x13,0x80,0x14,0x00,0x15,0x11,0x16,0x01,0x17,0x42, | ||
93 | 0x18,0x40,0x19,0x80,0x40,0x00,0x41,0xff,0x42,0xff,0x43,0xff,0x44,0xff,0x45,0xff, | ||
94 | 0x46,0xff,0x47,0xff,0x48,0xff,0x49,0xff,0x4a,0xff,0x4b,0xff,0x4c,0xff,0x4d,0xff, | ||
95 | 0x4e,0xff,0x4f,0xff,0x50,0xff,0x51,0xff,0x52,0xff,0x53,0xff,0x54,0x5f,0x55,0xff, | ||
96 | 0x56,0xff,0x57,0xff,0x58,0x00,0x59,0x47,0x5a,0x03,0x5b,0x03,0x5d,0x3e,0x5e,0x00, | ||
97 | 0x80,0x1c,0x83,0x01,0x84,0xa5,0x85,0x10,0x86,0x45,0x87,0x41,0x88,0xf0,0x88,0x00, | ||
98 | 0x88,0xf0,0x90,0x00,0x91,0x08,0x92,0x00,0x93,0x80,0x94,0x08,0x95,0x00,0x96,0xc0, | ||
99 | 0x97,0x02,0x98,0x13,0x99,0x00,0x9a,0x38,0x9b,0x01,0x9c,0x80,0x9d,0x02,0x9e,0x06, | ||
100 | 0x9f,0x01,0xa0,0x01,0xa1,0x00,0xa2,0x00,0xa4,0x80,0xa5,0x36,0xa6,0x36,0xa8,0x67, | ||
101 | 0xa9,0x04,0xaa,0x00,0xac,0x33,0xad,0x02,0xae,0x00,0xb0,0xcd,0xb1,0x04,0xb2,0xcd, | ||
102 | 0xb3,0x04,0xb4,0x01,0xb8,0x00,0xb9,0x00,0xba,0x00,0xbb,0x00,0xbc,0x00,0xbd,0x00, | ||
103 | 0xbe,0x00,0xbf,0x00 | ||
104 | }; | ||
105 | |||
106 | #define TVNORMS ARRAY_SIZE(tvnorms) | ||
107 | |||
108 | /* supported controls */ | ||
109 | static struct v4l2_queryctrl em28xx_qctrl[] = { | ||
110 | { | ||
111 | .id = V4L2_CID_BRIGHTNESS, | ||
112 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
113 | .name = "Brightness", | ||
114 | .minimum = -128, | ||
115 | .maximum = 127, | ||
116 | .step = 1, | ||
117 | .default_value = 0, | ||
118 | .flags = 0, | ||
119 | },{ | ||
120 | .id = V4L2_CID_CONTRAST, | ||
121 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
122 | .name = "Contrast", | ||
123 | .minimum = 0x0, | ||
124 | .maximum = 0x1f, | ||
125 | .step = 0x1, | ||
126 | .default_value = 0x10, | ||
127 | .flags = 0, | ||
128 | },{ | ||
129 | .id = V4L2_CID_SATURATION, | ||
130 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
131 | .name = "Saturation", | ||
132 | .minimum = 0x0, | ||
133 | .maximum = 0x1f, | ||
134 | .step = 0x1, | ||
135 | .default_value = 0x10, | ||
136 | .flags = 0, | ||
137 | },{ | ||
138 | .id = V4L2_CID_AUDIO_VOLUME, | ||
139 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
140 | .name = "Volume", | ||
141 | .minimum = 0x0, | ||
142 | .maximum = 0x1f, | ||
143 | .step = 0x1, | ||
144 | .default_value = 0x1f, | ||
145 | .flags = 0, | ||
146 | },{ | ||
147 | .id = V4L2_CID_AUDIO_MUTE, | ||
148 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
149 | .name = "Mute", | ||
150 | .minimum = 0, | ||
151 | .maximum = 1, | ||
152 | .step = 1, | ||
153 | .default_value = 1, | ||
154 | .flags = 0, | ||
155 | },{ | ||
156 | .id = V4L2_CID_RED_BALANCE, | ||
157 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
158 | .name = "Red chroma balance", | ||
159 | .minimum = -128, | ||
160 | .maximum = 127, | ||
161 | .step = 1, | ||
162 | .default_value = 0, | ||
163 | .flags = 0, | ||
164 | },{ | ||
165 | .id = V4L2_CID_BLUE_BALANCE, | ||
166 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
167 | .name = "Blue chroma balance", | ||
168 | .minimum = -128, | ||
169 | .maximum = 127, | ||
170 | .step = 1, | ||
171 | .default_value = 0, | ||
172 | .flags = 0, | ||
173 | },{ | ||
174 | .id = V4L2_CID_GAMMA, | ||
175 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
176 | .name = "Gamma", | ||
177 | .minimum = 0x0, | ||
178 | .maximum = 0x3f, | ||
179 | .step = 0x1, | ||
180 | .default_value = 0x20, | ||
181 | .flags = 0, | ||
182 | } | ||
183 | }; | ||
184 | |||
185 | static struct usb_driver em28xx_usb_driver; | ||
186 | |||
187 | static DECLARE_MUTEX(em28xx_sysfs_lock); | ||
188 | static DECLARE_RWSEM(em28xx_disconnect); | ||
189 | |||
190 | /********************* v4l2 interface ******************************************/ | ||
191 | |||
192 | static inline unsigned long kvirt_to_pa(unsigned long adr) | ||
193 | { | ||
194 | unsigned long kva, ret; | ||
195 | |||
196 | kva = (unsigned long)page_address(vmalloc_to_page((void *)adr)); | ||
197 | kva |= adr & (PAGE_SIZE - 1); | ||
198 | ret = __pa(kva); | ||
199 | return ret; | ||
200 | } | ||
201 | |||
202 | /* | ||
203 | * em28xx_config() | ||
204 | * inits registers with sane defaults | ||
205 | */ | ||
206 | static int em28xx_config(struct em28xx *dev) | ||
207 | { | ||
208 | |||
209 | /* Sets I2C speed to 100 KHz */ | ||
210 | em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1); | ||
211 | |||
212 | /* enable vbi capturing */ | ||
213 | em28xx_audio_usb_mute(dev, 1); | ||
214 | dev->mute = 1; /* maybe not the right place... */ | ||
215 | dev->volume = 0x1f; | ||
216 | em28xx_audio_analog_set(dev); | ||
217 | em28xx_audio_analog_setup(dev); | ||
218 | em28xx_outfmt_set_yuv422(dev); | ||
219 | em28xx_colorlevels_set_default(dev); | ||
220 | em28xx_compression_disable(dev); | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | /* | ||
226 | * em28xx_config_i2c() | ||
227 | * configure i2c attached devices | ||
228 | */ | ||
229 | void em28xx_config_i2c(struct em28xx *dev) | ||
230 | { | ||
231 | struct v4l2_frequency f; | ||
232 | struct video_decoder_init em28xx_vdi = {.data = NULL }; | ||
233 | |||
234 | |||
235 | /* configure decoder */ | ||
236 | if(dev->model == EM2820_BOARD_MSI_VOX_USB_2){ | ||
237 | em28xx_vdi.data=saa7114_i2c_init; | ||
238 | em28xx_vdi.len=sizeof(saa7114_i2c_init); | ||
239 | } | ||
240 | |||
241 | |||
242 | em28xx_i2c_call_clients(dev, DECODER_INIT, &em28xx_vdi); | ||
243 | em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &dev->ctl_input); | ||
244 | /* em28xx_i2c_call_clients(dev,DECODER_SET_PICTURE, &dev->vpic); */ | ||
245 | /* em28xx_i2c_call_clients(dev,DECODER_SET_NORM,&dev->tvnorm->id); */ | ||
246 | /* em28xx_i2c_call_clients(dev,DECODER_ENABLE_OUTPUT,&output); */ | ||
247 | /* em28xx_i2c_call_clients(dev,DECODER_DUMP, NULL); */ | ||
248 | |||
249 | /* configure tuner */ | ||
250 | f.tuner = 0; | ||
251 | f.type = V4L2_TUNER_ANALOG_TV; | ||
252 | f.frequency = 9076; /* FIXME:remove magic number */ | ||
253 | dev->ctl_freq = f.frequency; | ||
254 | em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f); | ||
255 | |||
256 | /* configure tda9887 */ | ||
257 | |||
258 | |||
259 | /* em28xx_i2c_call_clients(dev,VIDIOC_S_STD,&dev->tvnorm->id); */ | ||
260 | } | ||
261 | |||
262 | /* | ||
263 | * em28xx_empty_framequeues() | ||
264 | * prepare queues for incoming and outgoing frames | ||
265 | */ | ||
266 | static void em28xx_empty_framequeues(struct em28xx *dev) | ||
267 | { | ||
268 | u32 i; | ||
269 | |||
270 | INIT_LIST_HEAD(&dev->inqueue); | ||
271 | INIT_LIST_HEAD(&dev->outqueue); | ||
272 | |||
273 | for (i = 0; i < EM28XX_NUM_FRAMES; i++) { | ||
274 | dev->frame[i].state = F_UNUSED; | ||
275 | dev->frame[i].buf.bytesused = 0; | ||
276 | } | ||
277 | } | ||
278 | |||
279 | static void video_mux(struct em28xx *dev, int index) | ||
280 | { | ||
281 | int input, ainput; | ||
282 | |||
283 | input = INPUT(index)->vmux; | ||
284 | dev->ctl_input = index; | ||
285 | dev->ctl_ainput = INPUT(index)->amux; | ||
286 | |||
287 | em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &input); | ||
288 | |||
289 | |||
290 | em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); | ||
291 | |||
292 | if (dev->has_msp34xx) { | ||
293 | em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput); | ||
294 | ainput = EM28XX_AUDIO_SRC_TUNER; | ||
295 | em28xx_audio_source(dev, ainput); | ||
296 | } else { | ||
297 | switch (dev->ctl_ainput) { | ||
298 | case 0: | ||
299 | ainput = EM28XX_AUDIO_SRC_TUNER; | ||
300 | break; | ||
301 | default: | ||
302 | ainput = EM28XX_AUDIO_SRC_LINE; | ||
303 | } | ||
304 | em28xx_audio_source(dev, ainput); | ||
305 | } | ||
306 | } | ||
307 | |||
308 | /* | ||
309 | * em28xx_v4l2_open() | ||
310 | * inits the device and starts isoc transfer | ||
311 | */ | ||
312 | static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | ||
313 | { | ||
314 | int minor = iminor(inode); | ||
315 | int errCode = 0; | ||
316 | struct em28xx *h,*dev = NULL; | ||
317 | struct list_head *list; | ||
318 | |||
319 | list_for_each(list,&em28xx_devlist) { | ||
320 | h = list_entry(list, struct em28xx, devlist); | ||
321 | if (h->vdev->minor == minor) { | ||
322 | dev = h; | ||
323 | } | ||
324 | } | ||
325 | |||
326 | filp->private_data=dev; | ||
327 | |||
328 | |||
329 | em28xx_videodbg("users=%d\n", dev->users); | ||
330 | |||
331 | if (!down_read_trylock(&em28xx_disconnect)) | ||
332 | return -ERESTARTSYS; | ||
333 | |||
334 | if (dev->users) { | ||
335 | em28xx_warn("this driver can be opened only once\n"); | ||
336 | up_read(&em28xx_disconnect); | ||
337 | return -EBUSY; | ||
338 | } | ||
339 | |||
340 | /* if(dev->vbi_dev->minor == minor){ | ||
341 | dev->type=V4L2_BUF_TYPE_VBI_CAPTURE; | ||
342 | }*/ | ||
343 | if (dev->vdev->minor == minor) { | ||
344 | dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
345 | } | ||
346 | |||
347 | init_MUTEX(&dev->fileop_lock); /* to 1 == available */ | ||
348 | spin_lock_init(&dev->queue_lock); | ||
349 | init_waitqueue_head(&dev->wait_frame); | ||
350 | init_waitqueue_head(&dev->wait_stream); | ||
351 | |||
352 | down(&dev->lock); | ||
353 | |||
354 | em28xx_set_alternate(dev); | ||
355 | |||
356 | dev->width = norm_maxw(dev); | ||
357 | dev->height = norm_maxh(dev); | ||
358 | dev->frame_size = dev->width * dev->height * 2; | ||
359 | dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ | ||
360 | dev->bytesperline = dev->width * 2; | ||
361 | dev->hscale = 0; | ||
362 | dev->vscale = 0; | ||
363 | |||
364 | em28xx_capture_start(dev, 1); | ||
365 | em28xx_resolution_set(dev); | ||
366 | |||
367 | /* start the transfer */ | ||
368 | errCode = em28xx_init_isoc(dev); | ||
369 | if (errCode) | ||
370 | goto err; | ||
371 | |||
372 | dev->users++; | ||
373 | filp->private_data = dev; | ||
374 | dev->io = IO_NONE; | ||
375 | dev->stream = STREAM_OFF; | ||
376 | dev->num_frames = 0; | ||
377 | |||
378 | /* prepare queues */ | ||
379 | em28xx_empty_framequeues(dev); | ||
380 | |||
381 | dev->state |= DEV_INITIALIZED; | ||
382 | |||
383 | video_mux(dev, 0); | ||
384 | |||
385 | err: | ||
386 | up(&dev->lock); | ||
387 | up_read(&em28xx_disconnect); | ||
388 | return errCode; | ||
389 | } | ||
390 | |||
391 | /* | ||
392 | * em28xx_realease_resources() | ||
393 | * unregisters the v4l2,i2c and usb devices | ||
394 | * called when the device gets disconected or at module unload | ||
395 | */ | ||
396 | static void em28xx_release_resources(struct em28xx *dev) | ||
397 | { | ||
398 | down(&em28xx_sysfs_lock); | ||
399 | |||
400 | em28xx_info("V4L2 device /dev/video%d deregistered\n", | ||
401 | dev->vdev->minor); | ||
402 | list_del(&dev->devlist); | ||
403 | video_unregister_device(dev->vdev); | ||
404 | /* video_unregister_device(dev->vbi_dev); */ | ||
405 | em28xx_i2c_unregister(dev); | ||
406 | usb_put_dev(dev->udev); | ||
407 | up(&em28xx_sysfs_lock); | ||
408 | } | ||
409 | |||
410 | /* | ||
411 | * em28xx_v4l2_close() | ||
412 | * stops streaming and deallocates all resources allocated by the v4l2 calls and ioctls | ||
413 | */ | ||
414 | static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | ||
415 | { | ||
416 | int errCode; | ||
417 | struct em28xx *dev=filp->private_data; | ||
418 | |||
419 | em28xx_videodbg("users=%d\n", dev->users); | ||
420 | |||
421 | down(&dev->lock); | ||
422 | |||
423 | em28xx_uninit_isoc(dev); | ||
424 | |||
425 | em28xx_release_buffers(dev); | ||
426 | |||
427 | /* the device is already disconnect, free the remaining resources */ | ||
428 | if (dev->state & DEV_DISCONNECTED) { | ||
429 | em28xx_release_resources(dev); | ||
430 | up(&dev->lock); | ||
431 | kfree(dev); | ||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | /* set alternate 0 */ | ||
436 | dev->alt = 0; | ||
437 | em28xx_videodbg("setting alternate 0\n"); | ||
438 | errCode = usb_set_interface(dev->udev, 0, 0); | ||
439 | if (errCode < 0) { | ||
440 | em28xx_errdev ("cannot change alternate number to 0 (error=%i)\n", | ||
441 | errCode); | ||
442 | } | ||
443 | |||
444 | dev->users--; | ||
445 | wake_up_interruptible_nr(&dev->open, 1); | ||
446 | up(&dev->lock); | ||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | /* | ||
451 | * em28xx_v4l2_read() | ||
452 | * will allocate buffers when called for the first time | ||
453 | */ | ||
454 | static ssize_t | ||
455 | em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count, | ||
456 | loff_t * f_pos) | ||
457 | { | ||
458 | struct em28xx_frame_t *f, *i; | ||
459 | unsigned long lock_flags; | ||
460 | int ret = 0; | ||
461 | struct em28xx *dev = filp->private_data; | ||
462 | |||
463 | if (down_interruptible(&dev->fileop_lock)) | ||
464 | return -ERESTARTSYS; | ||
465 | |||
466 | if (dev->state & DEV_DISCONNECTED) { | ||
467 | em28xx_videodbg("device not present\n"); | ||
468 | up(&dev->fileop_lock); | ||
469 | return -ENODEV; | ||
470 | } | ||
471 | |||
472 | if (dev->state & DEV_MISCONFIGURED) { | ||
473 | em28xx_videodbg("device misconfigured; close and open it again\n"); | ||
474 | up(&dev->fileop_lock); | ||
475 | return -EIO; | ||
476 | } | ||
477 | |||
478 | if (dev->io == IO_MMAP) { | ||
479 | em28xx_videodbg ("IO method is set to mmap; close and open" | ||
480 | " the device again to choose the read method\n"); | ||
481 | up(&dev->fileop_lock); | ||
482 | return -EINVAL; | ||
483 | } | ||
484 | |||
485 | if (dev->io == IO_NONE) { | ||
486 | if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) { | ||
487 | em28xx_errdev("read failed, not enough memory\n"); | ||
488 | up(&dev->fileop_lock); | ||
489 | return -ENOMEM; | ||
490 | } | ||
491 | dev->io = IO_READ; | ||
492 | dev->stream = STREAM_ON; | ||
493 | em28xx_queue_unusedframes(dev); | ||
494 | } | ||
495 | |||
496 | if (!count) { | ||
497 | up(&dev->fileop_lock); | ||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | if (list_empty(&dev->outqueue)) { | ||
502 | if (filp->f_flags & O_NONBLOCK) { | ||
503 | up(&dev->fileop_lock); | ||
504 | return -EAGAIN; | ||
505 | } | ||
506 | ret = wait_event_interruptible | ||
507 | (dev->wait_frame, | ||
508 | (!list_empty(&dev->outqueue)) || | ||
509 | (dev->state & DEV_DISCONNECTED)); | ||
510 | if (ret) { | ||
511 | up(&dev->fileop_lock); | ||
512 | return ret; | ||
513 | } | ||
514 | if (dev->state & DEV_DISCONNECTED) { | ||
515 | up(&dev->fileop_lock); | ||
516 | return -ENODEV; | ||
517 | } | ||
518 | } | ||
519 | |||
520 | f = list_entry(dev->outqueue.prev, struct em28xx_frame_t, frame); | ||
521 | |||
522 | spin_lock_irqsave(&dev->queue_lock, lock_flags); | ||
523 | list_for_each_entry(i, &dev->outqueue, frame) | ||
524 | i->state = F_UNUSED; | ||
525 | INIT_LIST_HEAD(&dev->outqueue); | ||
526 | spin_unlock_irqrestore(&dev->queue_lock, lock_flags); | ||
527 | |||
528 | em28xx_queue_unusedframes(dev); | ||
529 | |||
530 | if (count > f->buf.length) | ||
531 | count = f->buf.length; | ||
532 | |||
533 | if (copy_to_user(buf, f->bufmem, count)) { | ||
534 | up(&dev->fileop_lock); | ||
535 | return -EFAULT; | ||
536 | } | ||
537 | *f_pos += count; | ||
538 | |||
539 | up(&dev->fileop_lock); | ||
540 | |||
541 | return count; | ||
542 | } | ||
543 | |||
544 | /* | ||
545 | * em28xx_v4l2_poll() | ||
546 | * will allocate buffers when called for the first time | ||
547 | */ | ||
548 | static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait) | ||
549 | { | ||
550 | unsigned int mask = 0; | ||
551 | struct em28xx *dev = filp->private_data; | ||
552 | |||
553 | if (down_interruptible(&dev->fileop_lock)) | ||
554 | return POLLERR; | ||
555 | |||
556 | if (dev->state & DEV_DISCONNECTED) { | ||
557 | em28xx_videodbg("device not present\n"); | ||
558 | } else if (dev->state & DEV_MISCONFIGURED) { | ||
559 | em28xx_videodbg("device is misconfigured; close and open it again\n"); | ||
560 | } else { | ||
561 | if (dev->io == IO_NONE) { | ||
562 | if (!em28xx_request_buffers | ||
563 | (dev, EM28XX_NUM_READ_FRAMES)) { | ||
564 | em28xx_warn | ||
565 | ("poll() failed, not enough memory\n"); | ||
566 | } else { | ||
567 | dev->io = IO_READ; | ||
568 | dev->stream = STREAM_ON; | ||
569 | } | ||
570 | } | ||
571 | |||
572 | if (dev->io == IO_READ) { | ||
573 | em28xx_queue_unusedframes(dev); | ||
574 | poll_wait(filp, &dev->wait_frame, wait); | ||
575 | |||
576 | if (!list_empty(&dev->outqueue)) | ||
577 | mask |= POLLIN | POLLRDNORM; | ||
578 | |||
579 | up(&dev->fileop_lock); | ||
580 | |||
581 | return mask; | ||
582 | } | ||
583 | } | ||
584 | |||
585 | up(&dev->fileop_lock); | ||
586 | return POLLERR; | ||
587 | } | ||
588 | |||
589 | /* | ||
590 | * em28xx_vm_open() | ||
591 | */ | ||
592 | static void em28xx_vm_open(struct vm_area_struct *vma) | ||
593 | { | ||
594 | struct em28xx_frame_t *f = vma->vm_private_data; | ||
595 | f->vma_use_count++; | ||
596 | } | ||
597 | |||
598 | /* | ||
599 | * em28xx_vm_close() | ||
600 | */ | ||
601 | static void em28xx_vm_close(struct vm_area_struct *vma) | ||
602 | { | ||
603 | /* NOTE: buffers are not freed here */ | ||
604 | struct em28xx_frame_t *f = vma->vm_private_data; | ||
605 | f->vma_use_count--; | ||
606 | } | ||
607 | |||
608 | static struct vm_operations_struct em28xx_vm_ops = { | ||
609 | .open = em28xx_vm_open, | ||
610 | .close = em28xx_vm_close, | ||
611 | }; | ||
612 | |||
613 | /* | ||
614 | * em28xx_v4l2_mmap() | ||
615 | */ | ||
616 | static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | ||
617 | { | ||
618 | unsigned long size = vma->vm_end - vma->vm_start, | ||
619 | start = vma->vm_start, pos, page; | ||
620 | u32 i; | ||
621 | |||
622 | struct em28xx *dev = filp->private_data; | ||
623 | |||
624 | if (down_interruptible(&dev->fileop_lock)) | ||
625 | return -ERESTARTSYS; | ||
626 | |||
627 | if (dev->state & DEV_DISCONNECTED) { | ||
628 | em28xx_videodbg("mmap: device not present\n"); | ||
629 | up(&dev->fileop_lock); | ||
630 | return -ENODEV; | ||
631 | } | ||
632 | |||
633 | if (dev->state & DEV_MISCONFIGURED) { | ||
634 | em28xx_videodbg ("mmap: Device is misconfigured; close and " | ||
635 | "open it again\n"); | ||
636 | up(&dev->fileop_lock); | ||
637 | return -EIO; | ||
638 | } | ||
639 | |||
640 | if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || | ||
641 | size != PAGE_ALIGN(dev->frame[0].buf.length)) { | ||
642 | up(&dev->fileop_lock); | ||
643 | return -EINVAL; | ||
644 | } | ||
645 | |||
646 | for (i = 0; i < dev->num_frames; i++) { | ||
647 | if ((dev->frame[i].buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | ||
648 | break; | ||
649 | } | ||
650 | if (i == dev->num_frames) { | ||
651 | em28xx_videodbg("mmap: user supplied mapping address is out of range\n"); | ||
652 | up(&dev->fileop_lock); | ||
653 | return -EINVAL; | ||
654 | } | ||
655 | |||
656 | /* VM_IO is eventually going to replace PageReserved altogether */ | ||
657 | vma->vm_flags |= VM_IO; | ||
658 | vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ | ||
659 | |||
660 | pos = (unsigned long)dev->frame[i].bufmem; | ||
661 | while (size > 0) { /* size is page-aligned */ | ||
662 | page = vmalloc_to_pfn((void *)pos); | ||
663 | if (remap_pfn_range(vma, start, page, PAGE_SIZE, | ||
664 | vma->vm_page_prot)) { | ||
665 | em28xx_videodbg("mmap: rename page map failed\n"); | ||
666 | up(&dev->fileop_lock); | ||
667 | return -EAGAIN; | ||
668 | } | ||
669 | start += PAGE_SIZE; | ||
670 | pos += PAGE_SIZE; | ||
671 | size -= PAGE_SIZE; | ||
672 | } | ||
673 | |||
674 | vma->vm_ops = &em28xx_vm_ops; | ||
675 | vma->vm_private_data = &dev->frame[i]; | ||
676 | |||
677 | em28xx_vm_open(vma); | ||
678 | up(&dev->fileop_lock); | ||
679 | return 0; | ||
680 | } | ||
681 | |||
682 | /* | ||
683 | * em28xx_get_ctrl() | ||
684 | * return the current saturation, brightness or contrast, mute state | ||
685 | */ | ||
686 | static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) | ||
687 | { | ||
688 | s32 tmp; | ||
689 | switch (ctrl->id) { | ||
690 | case V4L2_CID_AUDIO_MUTE: | ||
691 | ctrl->value = dev->mute; | ||
692 | return 0; | ||
693 | case V4L2_CID_AUDIO_VOLUME: | ||
694 | ctrl->value = dev->volume; | ||
695 | return 0; | ||
696 | case V4L2_CID_BRIGHTNESS: | ||
697 | if ((tmp = em28xx_brightness_get(dev)) < 0) | ||
698 | return -EIO; | ||
699 | ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */ | ||
700 | return 0; | ||
701 | case V4L2_CID_CONTRAST: | ||
702 | if ((ctrl->value = em28xx_contrast_get(dev)) < 0) | ||
703 | return -EIO; | ||
704 | return 0; | ||
705 | case V4L2_CID_SATURATION: | ||
706 | if ((ctrl->value = em28xx_saturation_get(dev)) < 0) | ||
707 | return -EIO; | ||
708 | return 0; | ||
709 | case V4L2_CID_RED_BALANCE: | ||
710 | if ((tmp = em28xx_v_balance_get(dev)) < 0) | ||
711 | return -EIO; | ||
712 | ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */ | ||
713 | return 0; | ||
714 | case V4L2_CID_BLUE_BALANCE: | ||
715 | if ((tmp = em28xx_u_balance_get(dev)) < 0) | ||
716 | return -EIO; | ||
717 | ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */ | ||
718 | return 0; | ||
719 | case V4L2_CID_GAMMA: | ||
720 | if ((ctrl->value = em28xx_gamma_get(dev)) < 0) | ||
721 | return -EIO; | ||
722 | return 0; | ||
723 | default: | ||
724 | return -EINVAL; | ||
725 | } | ||
726 | } | ||
727 | |||
728 | /* | ||
729 | * em28xx_set_ctrl() | ||
730 | * mute or set new saturation, brightness or contrast | ||
731 | */ | ||
732 | static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) | ||
733 | { | ||
734 | switch (ctrl->id) { | ||
735 | case V4L2_CID_AUDIO_MUTE: | ||
736 | if (ctrl->value != dev->mute) { | ||
737 | dev->mute = ctrl->value; | ||
738 | em28xx_audio_usb_mute(dev, ctrl->value); | ||
739 | return em28xx_audio_analog_set(dev); | ||
740 | } | ||
741 | return 0; | ||
742 | case V4L2_CID_AUDIO_VOLUME: | ||
743 | dev->volume = ctrl->value; | ||
744 | return em28xx_audio_analog_set(dev); | ||
745 | case V4L2_CID_BRIGHTNESS: | ||
746 | return em28xx_brightness_set(dev, ctrl->value); | ||
747 | case V4L2_CID_CONTRAST: | ||
748 | return em28xx_contrast_set(dev, ctrl->value); | ||
749 | case V4L2_CID_SATURATION: | ||
750 | return em28xx_saturation_set(dev, ctrl->value); | ||
751 | case V4L2_CID_RED_BALANCE: | ||
752 | return em28xx_v_balance_set(dev, ctrl->value); | ||
753 | case V4L2_CID_BLUE_BALANCE: | ||
754 | return em28xx_u_balance_set(dev, ctrl->value); | ||
755 | case V4L2_CID_GAMMA: | ||
756 | return em28xx_gamma_set(dev, ctrl->value); | ||
757 | default: | ||
758 | return -EINVAL; | ||
759 | } | ||
760 | } | ||
761 | |||
762 | /* | ||
763 | * em28xx_stream_interrupt() | ||
764 | * stops streaming | ||
765 | */ | ||
766 | static int em28xx_stream_interrupt(struct em28xx *dev) | ||
767 | { | ||
768 | int ret = 0; | ||
769 | |||
770 | /* stop reading from the device */ | ||
771 | |||
772 | dev->stream = STREAM_INTERRUPT; | ||
773 | ret = wait_event_timeout(dev->wait_stream, | ||
774 | (dev->stream == STREAM_OFF) || | ||
775 | (dev->state & DEV_DISCONNECTED), | ||
776 | EM28XX_URB_TIMEOUT); | ||
777 | if (dev->state & DEV_DISCONNECTED) | ||
778 | return -ENODEV; | ||
779 | else if (ret) { | ||
780 | dev->state |= DEV_MISCONFIGURED; | ||
781 | em28xx_videodbg("device is misconfigured; close and " | ||
782 | "open /dev/video%d again\n", dev->vdev->minor); | ||
783 | return ret; | ||
784 | } | ||
785 | |||
786 | return 0; | ||
787 | } | ||
788 | |||
789 | static int em28xx_set_norm(struct em28xx *dev, int width, int height) | ||
790 | { | ||
791 | unsigned int hscale, vscale; | ||
792 | unsigned int maxh, maxw; | ||
793 | |||
794 | maxw = norm_maxw(dev); | ||
795 | maxh = norm_maxh(dev); | ||
796 | |||
797 | /* width must even because of the YUYV format */ | ||
798 | /* height must be even because of interlacing */ | ||
799 | height &= 0xfffe; | ||
800 | width &= 0xfffe; | ||
801 | |||
802 | if (height < 32) | ||
803 | height = 32; | ||
804 | if (height > maxh) | ||
805 | height = maxh; | ||
806 | if (width < 48) | ||
807 | width = 48; | ||
808 | if (width > maxw) | ||
809 | width = maxw; | ||
810 | |||
811 | if ((hscale = (((unsigned long)maxw) << 12) / width - 4096L) >= 0x4000) | ||
812 | hscale = 0x3fff; | ||
813 | width = (((unsigned long)maxw) << 12) / (hscale + 4096L); | ||
814 | |||
815 | if ((vscale = (((unsigned long)maxh) << 12) / height - 4096L) >= 0x4000) | ||
816 | vscale = 0x3fff; | ||
817 | height = (((unsigned long)maxh) << 12) / (vscale + 4096L); | ||
818 | |||
819 | /* set new image size */ | ||
820 | dev->width = width; | ||
821 | dev->height = height; | ||
822 | dev->frame_size = dev->width * dev->height * 2; | ||
823 | dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ | ||
824 | dev->bytesperline = dev->width * 2; | ||
825 | dev->hscale = hscale; | ||
826 | dev->vscale = vscale; | ||
827 | |||
828 | em28xx_resolution_set(dev); | ||
829 | |||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | /* | ||
834 | * em28xx_v4l2_do_ioctl() | ||
835 | * This function is _not_ called directly, but from | ||
836 | * em28xx_v4l2_ioctl. Userspace | ||
837 | * copying is done already, arg is a kernel pointer. | ||
838 | */ | ||
839 | static int em28xx_do_ioctl(struct inode *inode, struct file *filp, | ||
840 | struct em28xx *dev, unsigned int cmd, void *arg, | ||
841 | v4l2_kioctl driver_ioctl) | ||
842 | { | ||
843 | int ret; | ||
844 | |||
845 | switch (cmd) { | ||
846 | /* ---------- tv norms ---------- */ | ||
847 | case VIDIOC_ENUMSTD: | ||
848 | { | ||
849 | struct v4l2_standard *e = arg; | ||
850 | unsigned int i; | ||
851 | |||
852 | i = e->index; | ||
853 | if (i >= TVNORMS) | ||
854 | return -EINVAL; | ||
855 | ret = v4l2_video_std_construct(e, tvnorms[e->index].id, | ||
856 | tvnorms[e->index].name); | ||
857 | e->index = i; | ||
858 | if (ret < 0) | ||
859 | return ret; | ||
860 | return 0; | ||
861 | } | ||
862 | case VIDIOC_G_STD: | ||
863 | { | ||
864 | v4l2_std_id *id = arg; | ||
865 | |||
866 | *id = dev->tvnorm->id; | ||
867 | return 0; | ||
868 | } | ||
869 | case VIDIOC_S_STD: | ||
870 | { | ||
871 | v4l2_std_id *id = arg; | ||
872 | unsigned int i; | ||
873 | |||
874 | for (i = 0; i < TVNORMS; i++) | ||
875 | if (*id == tvnorms[i].id) | ||
876 | break; | ||
877 | if (i == TVNORMS) | ||
878 | for (i = 0; i < TVNORMS; i++) | ||
879 | if (*id & tvnorms[i].id) | ||
880 | break; | ||
881 | if (i == TVNORMS) | ||
882 | return -EINVAL; | ||
883 | |||
884 | down(&dev->lock); | ||
885 | dev->tvnorm = &tvnorms[i]; | ||
886 | |||
887 | em28xx_set_norm(dev, dev->width, dev->height); | ||
888 | |||
889 | /* | ||
890 | dev->width=norm_maxw(dev); | ||
891 | dev->height=norm_maxh(dev); | ||
892 | dev->frame_size=dev->width*dev->height*2; | ||
893 | dev->field_size=dev->frame_size>>1; | ||
894 | dev->bytesperline=dev->width*2; | ||
895 | dev->hscale=0; | ||
896 | dev->vscale=0; | ||
897 | |||
898 | em28xx_resolution_set(dev); | ||
899 | */ | ||
900 | /* | ||
901 | em28xx_uninit_isoc(dev); | ||
902 | em28xx_set_alternate(dev); | ||
903 | em28xx_capture_start(dev, 1); | ||
904 | em28xx_resolution_set(dev); | ||
905 | em28xx_init_isoc(dev); | ||
906 | */ | ||
907 | em28xx_i2c_call_clients(dev, DECODER_SET_NORM, | ||
908 | &tvnorms[i].mode); | ||
909 | em28xx_i2c_call_clients(dev, VIDIOC_S_STD, | ||
910 | &dev->tvnorm->id); | ||
911 | |||
912 | up(&dev->lock); | ||
913 | |||
914 | return 0; | ||
915 | } | ||
916 | |||
917 | /* ------ input switching ---------- */ | ||
918 | case VIDIOC_ENUMINPUT: | ||
919 | { | ||
920 | struct v4l2_input *i = arg; | ||
921 | unsigned int n; | ||
922 | static const char *iname[] = { | ||
923 | [EM28XX_VMUX_COMPOSITE1] = "Composite1", | ||
924 | [EM28XX_VMUX_COMPOSITE2] = "Composite2", | ||
925 | [EM28XX_VMUX_COMPOSITE3] = "Composite3", | ||
926 | [EM28XX_VMUX_COMPOSITE4] = "Composite4", | ||
927 | [EM28XX_VMUX_SVIDEO] = "S-Video", | ||
928 | [EM28XX_VMUX_TELEVISION] = "Television", | ||
929 | [EM28XX_VMUX_CABLE] = "Cable TV", | ||
930 | [EM28XX_VMUX_DVB] = "DVB", | ||
931 | [EM28XX_VMUX_DEBUG] = "for debug only", | ||
932 | }; | ||
933 | |||
934 | n = i->index; | ||
935 | if (n >= MAX_EM28XX_INPUT) | ||
936 | return -EINVAL; | ||
937 | if (0 == INPUT(n)->type) | ||
938 | return -EINVAL; | ||
939 | memset(i, 0, sizeof(*i)); | ||
940 | i->index = n; | ||
941 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
942 | strcpy(i->name, iname[INPUT(n)->type]); | ||
943 | if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) || | ||
944 | (EM28XX_VMUX_CABLE == INPUT(n)->type)) | ||
945 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
946 | for (n = 0; n < ARRAY_SIZE(tvnorms); n++) | ||
947 | i->std |= tvnorms[n].id; | ||
948 | return 0; | ||
949 | } | ||
950 | |||
951 | case VIDIOC_G_INPUT: | ||
952 | { | ||
953 | int *i = arg; | ||
954 | *i = dev->ctl_input; | ||
955 | |||
956 | return 0; | ||
957 | } | ||
958 | |||
959 | case VIDIOC_S_INPUT: | ||
960 | { | ||
961 | int *index = arg; | ||
962 | |||
963 | if (*index >= MAX_EM28XX_INPUT) | ||
964 | return -EINVAL; | ||
965 | if (0 == INPUT(*index)->type) | ||
966 | return -EINVAL; | ||
967 | |||
968 | down(&dev->lock); | ||
969 | video_mux(dev, *index); | ||
970 | up(&dev->lock); | ||
971 | |||
972 | return 0; | ||
973 | } | ||
974 | |||
975 | case VIDIOC_G_AUDIO: | ||
976 | { | ||
977 | struct v4l2_audio *a = arg; | ||
978 | unsigned int index = a->index; | ||
979 | |||
980 | if (a->index > 1) | ||
981 | return -EINVAL; | ||
982 | memset(a, 0, sizeof(*a)); | ||
983 | index = dev->ctl_ainput; | ||
984 | |||
985 | if (index == 0) { | ||
986 | strcpy(a->name, "Television"); | ||
987 | } else { | ||
988 | strcpy(a->name, "Line In"); | ||
989 | } | ||
990 | a->capability = V4L2_AUDCAP_STEREO; | ||
991 | a->index = index; | ||
992 | return 0; | ||
993 | } | ||
994 | |||
995 | case VIDIOC_S_AUDIO: | ||
996 | { | ||
997 | struct v4l2_audio *a = arg; | ||
998 | if (a->index != dev->ctl_ainput) | ||
999 | return -EINVAL; | ||
1000 | |||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | /* --- controls ---------------------------------------------- */ | ||
1005 | case VIDIOC_QUERYCTRL: | ||
1006 | { | ||
1007 | struct v4l2_queryctrl *qc = arg; | ||
1008 | u8 i, n; | ||
1009 | n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]); | ||
1010 | for (i = 0; i < n; i++) | ||
1011 | if (qc->id && qc->id == em28xx_qctrl[i].id) { | ||
1012 | memcpy(qc, &(em28xx_qctrl[i]), | ||
1013 | sizeof(*qc)); | ||
1014 | return 0; | ||
1015 | } | ||
1016 | |||
1017 | return -EINVAL; | ||
1018 | } | ||
1019 | |||
1020 | case VIDIOC_G_CTRL: | ||
1021 | { | ||
1022 | struct v4l2_control *ctrl = arg; | ||
1023 | |||
1024 | |||
1025 | return em28xx_get_ctrl(dev, ctrl); | ||
1026 | } | ||
1027 | |||
1028 | case VIDIOC_S_CTRL_OLD: /* ??? */ | ||
1029 | case VIDIOC_S_CTRL: | ||
1030 | { | ||
1031 | struct v4l2_control *ctrl = arg; | ||
1032 | u8 i, n; | ||
1033 | |||
1034 | |||
1035 | n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]); | ||
1036 | for (i = 0; i < n; i++) | ||
1037 | if (ctrl->id == em28xx_qctrl[i].id) { | ||
1038 | if (ctrl->value < | ||
1039 | em28xx_qctrl[i].minimum | ||
1040 | || ctrl->value > | ||
1041 | em28xx_qctrl[i].maximum) | ||
1042 | return -ERANGE; | ||
1043 | |||
1044 | return em28xx_set_ctrl(dev, ctrl); | ||
1045 | } | ||
1046 | return -EINVAL; | ||
1047 | } | ||
1048 | |||
1049 | /* --- tuner ioctls ------------------------------------------ */ | ||
1050 | case VIDIOC_G_TUNER: | ||
1051 | { | ||
1052 | struct v4l2_tuner *t = arg; | ||
1053 | int status = 0; | ||
1054 | |||
1055 | if (0 != t->index) | ||
1056 | return -EINVAL; | ||
1057 | |||
1058 | memset(t, 0, sizeof(*t)); | ||
1059 | strcpy(t->name, "Tuner"); | ||
1060 | t->type = V4L2_TUNER_ANALOG_TV; | ||
1061 | t->capability = V4L2_TUNER_CAP_NORM; | ||
1062 | t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */ | ||
1063 | /* t->signal = 0xffff;*/ | ||
1064 | /* em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/ | ||
1065 | /* No way to get signal strength? */ | ||
1066 | down(&dev->lock); | ||
1067 | em28xx_i2c_call_clients(dev, DECODER_GET_STATUS, | ||
1068 | &status); | ||
1069 | up(&dev->lock); | ||
1070 | t->signal = | ||
1071 | (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0; | ||
1072 | |||
1073 | em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal, | ||
1074 | t->afc); | ||
1075 | return 0; | ||
1076 | } | ||
1077 | case VIDIOC_S_TUNER: | ||
1078 | { | ||
1079 | struct v4l2_tuner *t = arg; | ||
1080 | int status = 0; | ||
1081 | |||
1082 | if (0 != t->index) | ||
1083 | return -EINVAL; | ||
1084 | memset(t, 0, sizeof(*t)); | ||
1085 | strcpy(t->name, "Tuner"); | ||
1086 | t->type = V4L2_TUNER_ANALOG_TV; | ||
1087 | t->capability = V4L2_TUNER_CAP_NORM; | ||
1088 | t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */ | ||
1089 | /* t->signal = 0xffff; */ | ||
1090 | /* No way to get signal strength? */ | ||
1091 | down(&dev->lock); | ||
1092 | em28xx_i2c_call_clients(dev, DECODER_GET_STATUS, | ||
1093 | &status); | ||
1094 | up(&dev->lock); | ||
1095 | t->signal = | ||
1096 | (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0; | ||
1097 | |||
1098 | em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n", | ||
1099 | t->signal, t->afc); | ||
1100 | return 0; | ||
1101 | } | ||
1102 | case VIDIOC_G_FREQUENCY: | ||
1103 | { | ||
1104 | struct v4l2_frequency *f = arg; | ||
1105 | |||
1106 | memset(f, 0, sizeof(*f)); | ||
1107 | f->type = V4L2_TUNER_ANALOG_TV; | ||
1108 | f->frequency = dev->ctl_freq; | ||
1109 | |||
1110 | return 0; | ||
1111 | } | ||
1112 | case VIDIOC_S_FREQUENCY: | ||
1113 | { | ||
1114 | struct v4l2_frequency *f = arg; | ||
1115 | |||
1116 | if (0 != f->tuner) | ||
1117 | return -EINVAL; | ||
1118 | |||
1119 | if (V4L2_TUNER_ANALOG_TV != f->type) | ||
1120 | return -EINVAL; | ||
1121 | |||
1122 | down(&dev->lock); | ||
1123 | dev->ctl_freq = f->frequency; | ||
1124 | em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); | ||
1125 | up(&dev->lock); | ||
1126 | return 0; | ||
1127 | } | ||
1128 | |||
1129 | case VIDIOC_CROPCAP: | ||
1130 | { | ||
1131 | struct v4l2_cropcap *cc = arg; | ||
1132 | |||
1133 | if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1134 | return -EINVAL; | ||
1135 | cc->bounds.left = 0; | ||
1136 | cc->bounds.top = 0; | ||
1137 | cc->bounds.width = dev->width; | ||
1138 | cc->bounds.height = dev->height; | ||
1139 | cc->defrect = cc->bounds; | ||
1140 | cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */ | ||
1141 | cc->pixelaspect.denominator = 59; | ||
1142 | return 0; | ||
1143 | } | ||
1144 | case VIDIOC_STREAMON: | ||
1145 | { | ||
1146 | int *type = arg; | ||
1147 | |||
1148 | if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE | ||
1149 | || dev->io != IO_MMAP) | ||
1150 | return -EINVAL; | ||
1151 | |||
1152 | if (list_empty(&dev->inqueue)) | ||
1153 | return -EINVAL; | ||
1154 | |||
1155 | dev->stream = STREAM_ON; /* FIXME: Start video capture here? */ | ||
1156 | |||
1157 | em28xx_videodbg("VIDIOC_STREAMON: starting stream\n"); | ||
1158 | |||
1159 | return 0; | ||
1160 | } | ||
1161 | case VIDIOC_STREAMOFF: | ||
1162 | { | ||
1163 | int *type = arg; | ||
1164 | int ret; | ||
1165 | |||
1166 | if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE | ||
1167 | || dev->io != IO_MMAP) | ||
1168 | return -EINVAL; | ||
1169 | |||
1170 | if (dev->stream == STREAM_ON) { | ||
1171 | em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n"); | ||
1172 | if ((ret = em28xx_stream_interrupt(dev))) | ||
1173 | return ret; | ||
1174 | } | ||
1175 | em28xx_empty_framequeues(dev); | ||
1176 | |||
1177 | return 0; | ||
1178 | } | ||
1179 | default: | ||
1180 | return v4l_compat_translate_ioctl(inode, filp, cmd, arg, | ||
1181 | driver_ioctl); | ||
1182 | } | ||
1183 | return 0; | ||
1184 | } | ||
1185 | |||
1186 | /* | ||
1187 | * em28xx_v4l2_do_ioctl() | ||
1188 | * This function is _not_ called directly, but from | ||
1189 | * em28xx_v4l2_ioctl. Userspace | ||
1190 | * copying is done already, arg is a kernel pointer. | ||
1191 | */ | ||
1192 | static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp, | ||
1193 | unsigned int cmd, void *arg) | ||
1194 | { | ||
1195 | struct em28xx *dev = filp->private_data; | ||
1196 | |||
1197 | if (!dev) | ||
1198 | return -ENODEV; | ||
1199 | |||
1200 | if (video_debug > 1) | ||
1201 | em28xx_print_ioctl(dev->name,cmd); | ||
1202 | |||
1203 | switch (cmd) { | ||
1204 | |||
1205 | /* --- capabilities ------------------------------------------ */ | ||
1206 | case VIDIOC_QUERYCAP: | ||
1207 | { | ||
1208 | struct v4l2_capability *cap = arg; | ||
1209 | |||
1210 | memset(cap, 0, sizeof(*cap)); | ||
1211 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); | ||
1212 | strlcpy(cap->card, em28xx_boards[dev->model].name, | ||
1213 | sizeof(cap->card)); | ||
1214 | strlcpy(cap->bus_info, dev->udev->dev.bus_id, | ||
1215 | sizeof(cap->bus_info)); | ||
1216 | cap->version = EM28XX_VERSION_CODE; | ||
1217 | cap->capabilities = | ||
1218 | V4L2_CAP_VIDEO_CAPTURE | | ||
1219 | V4L2_CAP_AUDIO | | ||
1220 | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; | ||
1221 | if (dev->has_tuner) | ||
1222 | cap->capabilities |= V4L2_CAP_TUNER; | ||
1223 | return 0; | ||
1224 | } | ||
1225 | |||
1226 | /* --- capture ioctls ---------------------------------------- */ | ||
1227 | case VIDIOC_ENUM_FMT: | ||
1228 | { | ||
1229 | struct v4l2_fmtdesc *fmtd = arg; | ||
1230 | |||
1231 | if (fmtd->index != 0) | ||
1232 | return -EINVAL; | ||
1233 | memset(fmtd, 0, sizeof(*fmtd)); | ||
1234 | fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1235 | strcpy(fmtd->description, "Packed YUY2"); | ||
1236 | fmtd->pixelformat = V4L2_PIX_FMT_YUYV; | ||
1237 | memset(fmtd->reserved, 0, sizeof(fmtd->reserved)); | ||
1238 | return 0; | ||
1239 | } | ||
1240 | |||
1241 | case VIDIOC_G_FMT: | ||
1242 | { | ||
1243 | struct v4l2_format *format = arg; | ||
1244 | |||
1245 | em28xx_videodbg("VIDIOC_G_FMT: type=%s\n", | ||
1246 | format->type == | ||
1247 | V4L2_BUF_TYPE_VIDEO_CAPTURE ? | ||
1248 | "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type == | ||
1249 | V4L2_BUF_TYPE_VBI_CAPTURE ? | ||
1250 | "V4L2_BUF_TYPE_VBI_CAPTURE " : | ||
1251 | "not supported"); | ||
1252 | |||
1253 | if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1254 | return -EINVAL; | ||
1255 | |||
1256 | format->fmt.pix.width = dev->width; | ||
1257 | format->fmt.pix.height = dev->height; | ||
1258 | format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; | ||
1259 | format->fmt.pix.bytesperline = dev->bytesperline; | ||
1260 | format->fmt.pix.sizeimage = dev->frame_size; | ||
1261 | format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
1262 | format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ | ||
1263 | |||
1264 | em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width, | ||
1265 | dev->height); | ||
1266 | return 0; | ||
1267 | } | ||
1268 | |||
1269 | case VIDIOC_TRY_FMT: | ||
1270 | case VIDIOC_S_FMT: | ||
1271 | { | ||
1272 | struct v4l2_format *format = arg; | ||
1273 | u32 i; | ||
1274 | int ret = 0; | ||
1275 | int width = format->fmt.pix.width; | ||
1276 | int height = format->fmt.pix.height; | ||
1277 | unsigned int hscale, vscale; | ||
1278 | unsigned int maxh, maxw; | ||
1279 | |||
1280 | maxw = norm_maxw(dev); | ||
1281 | maxh = norm_maxh(dev); | ||
1282 | |||
1283 | /* int both_fields; */ | ||
1284 | |||
1285 | em28xx_videodbg("%s: type=%s\n", | ||
1286 | cmd == | ||
1287 | VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : | ||
1288 | "VIDIOC_S_FMT", | ||
1289 | format->type == | ||
1290 | V4L2_BUF_TYPE_VIDEO_CAPTURE ? | ||
1291 | "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type == | ||
1292 | V4L2_BUF_TYPE_VBI_CAPTURE ? | ||
1293 | "V4L2_BUF_TYPE_VBI_CAPTURE " : | ||
1294 | "not supported"); | ||
1295 | |||
1296 | if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1297 | return -EINVAL; | ||
1298 | |||
1299 | em28xx_videodbg("%s: requested %dx%d\n", | ||
1300 | cmd == | ||
1301 | VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : | ||
1302 | "VIDIOC_S_FMT", format->fmt.pix.width, | ||
1303 | format->fmt.pix.height); | ||
1304 | |||
1305 | /* FIXME: Move some code away from here */ | ||
1306 | /* width must even because of the YUYV format */ | ||
1307 | /* height must be even because of interlacing */ | ||
1308 | height &= 0xfffe; | ||
1309 | width &= 0xfffe; | ||
1310 | |||
1311 | if (height < 32) | ||
1312 | height = 32; | ||
1313 | if (height > maxh) | ||
1314 | height = maxh; | ||
1315 | if (width < 48) | ||
1316 | width = 48; | ||
1317 | if (width > maxw) | ||
1318 | width = maxw; | ||
1319 | |||
1320 | if(dev->is_em2800){ | ||
1321 | /* the em2800 can only scale down to 50% */ | ||
1322 | if(height % (maxh / 2)) | ||
1323 | height=maxh; | ||
1324 | if(width % (maxw / 2)) | ||
1325 | width=maxw; | ||
1326 | /* according to empiatech support */ | ||
1327 | /* the MaxPacketSize is to small to support */ | ||
1328 | /* framesizes larger than 640x480 @ 30 fps */ | ||
1329 | /* or 640x576 @ 25 fps. As this would cut */ | ||
1330 | /* of a part of the image we prefer */ | ||
1331 | /* 360x576 or 360x480 for now */ | ||
1332 | if(width == maxw && height == maxh) | ||
1333 | width /= 2; | ||
1334 | } | ||
1335 | |||
1336 | if ((hscale = | ||
1337 | (((unsigned long)maxw) << 12) / width - 4096L) >= | ||
1338 | 0x4000) | ||
1339 | hscale = 0x3fff; | ||
1340 | width = | ||
1341 | (((unsigned long)maxw) << 12) / (hscale + 4096L); | ||
1342 | |||
1343 | if ((vscale = | ||
1344 | (((unsigned long)maxh) << 12) / height - 4096L) >= | ||
1345 | 0x4000) | ||
1346 | vscale = 0x3fff; | ||
1347 | height = | ||
1348 | (((unsigned long)maxh) << 12) / (vscale + 4096L); | ||
1349 | |||
1350 | format->fmt.pix.width = width; | ||
1351 | format->fmt.pix.height = height; | ||
1352 | format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; | ||
1353 | format->fmt.pix.bytesperline = width * 2; | ||
1354 | format->fmt.pix.sizeimage = width * 2 * height; | ||
1355 | format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
1356 | format->fmt.pix.field = V4L2_FIELD_INTERLACED; | ||
1357 | |||
1358 | em28xx_videodbg("%s: returned %dx%d (%d, %d)\n", | ||
1359 | cmd == | ||
1360 | VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" : | ||
1361 | "VIDIOC_S_FMT", format->fmt.pix.width, | ||
1362 | format->fmt.pix.height, hscale, vscale); | ||
1363 | |||
1364 | if (cmd == VIDIOC_TRY_FMT) | ||
1365 | return 0; | ||
1366 | |||
1367 | for (i = 0; i < dev->num_frames; i++) | ||
1368 | if (dev->frame[i].vma_use_count) { | ||
1369 | em28xx_videodbg("VIDIOC_S_FMT failed. " | ||
1370 | "Unmap the buffers first.\n"); | ||
1371 | return -EINVAL; | ||
1372 | } | ||
1373 | |||
1374 | /* stop io in case it is already in progress */ | ||
1375 | if (dev->stream == STREAM_ON) { | ||
1376 | em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n"); | ||
1377 | if ((ret = em28xx_stream_interrupt(dev))) | ||
1378 | return ret; | ||
1379 | } | ||
1380 | |||
1381 | em28xx_release_buffers(dev); | ||
1382 | dev->io = IO_NONE; | ||
1383 | |||
1384 | /* set new image size */ | ||
1385 | dev->width = width; | ||
1386 | dev->height = height; | ||
1387 | dev->frame_size = dev->width * dev->height * 2; | ||
1388 | dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ | ||
1389 | dev->bytesperline = dev->width * 2; | ||
1390 | dev->hscale = hscale; | ||
1391 | dev->vscale = vscale; | ||
1392 | /* dev->both_fileds = both_fileds; */ | ||
1393 | em28xx_uninit_isoc(dev); | ||
1394 | em28xx_set_alternate(dev); | ||
1395 | em28xx_capture_start(dev, 1); | ||
1396 | em28xx_resolution_set(dev); | ||
1397 | em28xx_init_isoc(dev); | ||
1398 | |||
1399 | return 0; | ||
1400 | } | ||
1401 | |||
1402 | /* --- streaming capture ------------------------------------- */ | ||
1403 | case VIDIOC_REQBUFS: | ||
1404 | { | ||
1405 | struct v4l2_requestbuffers *rb = arg; | ||
1406 | u32 i; | ||
1407 | int ret; | ||
1408 | |||
1409 | if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
1410 | rb->memory != V4L2_MEMORY_MMAP) | ||
1411 | return -EINVAL; | ||
1412 | |||
1413 | if (dev->io == IO_READ) { | ||
1414 | em28xx_videodbg ("method is set to read;" | ||
1415 | " close and open the device again to" | ||
1416 | " choose the mmap I/O method\n"); | ||
1417 | return -EINVAL; | ||
1418 | } | ||
1419 | |||
1420 | for (i = 0; i < dev->num_frames; i++) | ||
1421 | if (dev->frame[i].vma_use_count) { | ||
1422 | em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n"); | ||
1423 | return -EINVAL; | ||
1424 | } | ||
1425 | |||
1426 | if (dev->stream == STREAM_ON) { | ||
1427 | em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n"); | ||
1428 | if ((ret = em28xx_stream_interrupt(dev))) | ||
1429 | return ret; | ||
1430 | } | ||
1431 | |||
1432 | em28xx_empty_framequeues(dev); | ||
1433 | |||
1434 | em28xx_release_buffers(dev); | ||
1435 | if (rb->count) | ||
1436 | rb->count = | ||
1437 | em28xx_request_buffers(dev, rb->count); | ||
1438 | |||
1439 | dev->frame_current = NULL; | ||
1440 | |||
1441 | em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n", | ||
1442 | rb->count); | ||
1443 | dev->io = rb->count ? IO_MMAP : IO_NONE; | ||
1444 | return 0; | ||
1445 | } | ||
1446 | |||
1447 | case VIDIOC_QUERYBUF: | ||
1448 | { | ||
1449 | struct v4l2_buffer *b = arg; | ||
1450 | |||
1451 | if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
1452 | b->index >= dev->num_frames || dev->io != IO_MMAP) | ||
1453 | return -EINVAL; | ||
1454 | |||
1455 | memcpy(b, &dev->frame[b->index].buf, sizeof(*b)); | ||
1456 | |||
1457 | if (dev->frame[b->index].vma_use_count) { | ||
1458 | b->flags |= V4L2_BUF_FLAG_MAPPED; | ||
1459 | } | ||
1460 | if (dev->frame[b->index].state == F_DONE) | ||
1461 | b->flags |= V4L2_BUF_FLAG_DONE; | ||
1462 | else if (dev->frame[b->index].state != F_UNUSED) | ||
1463 | b->flags |= V4L2_BUF_FLAG_QUEUED; | ||
1464 | return 0; | ||
1465 | } | ||
1466 | case VIDIOC_QBUF: | ||
1467 | { | ||
1468 | struct v4l2_buffer *b = arg; | ||
1469 | unsigned long lock_flags; | ||
1470 | |||
1471 | if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
1472 | b->index >= dev->num_frames || dev->io != IO_MMAP) { | ||
1473 | return -EINVAL; | ||
1474 | } | ||
1475 | |||
1476 | if (dev->frame[b->index].state != F_UNUSED) { | ||
1477 | return -EAGAIN; | ||
1478 | } | ||
1479 | dev->frame[b->index].state = F_QUEUED; | ||
1480 | |||
1481 | /* add frame to fifo */ | ||
1482 | spin_lock_irqsave(&dev->queue_lock, lock_flags); | ||
1483 | list_add_tail(&dev->frame[b->index].frame, | ||
1484 | &dev->inqueue); | ||
1485 | spin_unlock_irqrestore(&dev->queue_lock, lock_flags); | ||
1486 | |||
1487 | return 0; | ||
1488 | } | ||
1489 | case VIDIOC_DQBUF: | ||
1490 | { | ||
1491 | struct v4l2_buffer *b = arg; | ||
1492 | struct em28xx_frame_t *f; | ||
1493 | unsigned long lock_flags; | ||
1494 | int ret = 0; | ||
1495 | |||
1496 | if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE | ||
1497 | || dev->io != IO_MMAP) | ||
1498 | return -EINVAL; | ||
1499 | |||
1500 | if (list_empty(&dev->outqueue)) { | ||
1501 | if (dev->stream == STREAM_OFF) | ||
1502 | return -EINVAL; | ||
1503 | if (filp->f_flags & O_NONBLOCK) | ||
1504 | return -EAGAIN; | ||
1505 | ret = wait_event_interruptible | ||
1506 | (dev->wait_frame, | ||
1507 | (!list_empty(&dev->outqueue)) || | ||
1508 | (dev->state & DEV_DISCONNECTED)); | ||
1509 | if (ret) | ||
1510 | return ret; | ||
1511 | if (dev->state & DEV_DISCONNECTED) | ||
1512 | return -ENODEV; | ||
1513 | } | ||
1514 | |||
1515 | spin_lock_irqsave(&dev->queue_lock, lock_flags); | ||
1516 | f = list_entry(dev->outqueue.next, | ||
1517 | struct em28xx_frame_t, frame); | ||
1518 | list_del(dev->outqueue.next); | ||
1519 | spin_unlock_irqrestore(&dev->queue_lock, lock_flags); | ||
1520 | |||
1521 | f->state = F_UNUSED; | ||
1522 | memcpy(b, &f->buf, sizeof(*b)); | ||
1523 | |||
1524 | if (f->vma_use_count) | ||
1525 | b->flags |= V4L2_BUF_FLAG_MAPPED; | ||
1526 | |||
1527 | return 0; | ||
1528 | } | ||
1529 | default: | ||
1530 | return em28xx_do_ioctl(inode, filp, dev, cmd, arg, | ||
1531 | em28xx_video_do_ioctl); | ||
1532 | } | ||
1533 | return 0; | ||
1534 | } | ||
1535 | |||
1536 | /* | ||
1537 | * em28xx_v4l2_ioctl() | ||
1538 | * handle v4l2 ioctl the main action happens in em28xx_v4l2_do_ioctl() | ||
1539 | */ | ||
1540 | static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp, | ||
1541 | unsigned int cmd, unsigned long arg) | ||
1542 | { | ||
1543 | int ret = 0; | ||
1544 | struct em28xx *dev = filp->private_data; | ||
1545 | |||
1546 | if (down_interruptible(&dev->fileop_lock)) | ||
1547 | return -ERESTARTSYS; | ||
1548 | |||
1549 | if (dev->state & DEV_DISCONNECTED) { | ||
1550 | em28xx_errdev("v4l2 ioctl: device not present\n"); | ||
1551 | up(&dev->fileop_lock); | ||
1552 | return -ENODEV; | ||
1553 | } | ||
1554 | |||
1555 | if (dev->state & DEV_MISCONFIGURED) { | ||
1556 | em28xx_errdev | ||
1557 | ("v4l2 ioctl: device is misconfigured; close and open it again\n"); | ||
1558 | up(&dev->fileop_lock); | ||
1559 | return -EIO; | ||
1560 | } | ||
1561 | |||
1562 | ret = video_usercopy(inode, filp, cmd, arg, em28xx_video_do_ioctl); | ||
1563 | |||
1564 | up(&dev->fileop_lock); | ||
1565 | |||
1566 | return ret; | ||
1567 | } | ||
1568 | |||
1569 | static struct file_operations em28xx_v4l_fops = { | ||
1570 | .owner = THIS_MODULE, | ||
1571 | .open = em28xx_v4l2_open, | ||
1572 | .release = em28xx_v4l2_close, | ||
1573 | .ioctl = em28xx_v4l2_ioctl, | ||
1574 | .read = em28xx_v4l2_read, | ||
1575 | .poll = em28xx_v4l2_poll, | ||
1576 | .mmap = em28xx_v4l2_mmap, | ||
1577 | .llseek = no_llseek, | ||
1578 | }; | ||
1579 | |||
1580 | /******************************** usb interface *****************************************/ | ||
1581 | |||
1582 | /* | ||
1583 | * em28xx_init_dev() | ||
1584 | * allocates and inits the device structs, registers i2c bus and v4l device | ||
1585 | */ | ||
1586 | static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | ||
1587 | int minor, int model) | ||
1588 | { | ||
1589 | struct em28xx *dev = *devhandle; | ||
1590 | int retval = -ENOMEM; | ||
1591 | int errCode, i; | ||
1592 | unsigned int maxh, maxw; | ||
1593 | |||
1594 | dev->udev = udev; | ||
1595 | dev->model = model; | ||
1596 | init_MUTEX(&dev->lock); | ||
1597 | init_waitqueue_head(&dev->open); | ||
1598 | |||
1599 | dev->em28xx_write_regs = em28xx_write_regs; | ||
1600 | dev->em28xx_read_reg = em28xx_read_reg; | ||
1601 | dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len; | ||
1602 | dev->em28xx_write_regs_req = em28xx_write_regs_req; | ||
1603 | dev->em28xx_read_reg_req = em28xx_read_reg_req; | ||
1604 | dev->is_em2800 = em28xx_boards[model].is_em2800; | ||
1605 | dev->has_tuner = em28xx_boards[model].has_tuner; | ||
1606 | dev->has_msp34xx = em28xx_boards[model].has_msp34xx; | ||
1607 | dev->tda9887_conf = em28xx_boards[model].tda9887_conf; | ||
1608 | dev->decoder = em28xx_boards[model].decoder; | ||
1609 | |||
1610 | if (tuner >= 0) | ||
1611 | dev->tuner_type = tuner; | ||
1612 | else | ||
1613 | dev->tuner_type = em28xx_boards[model].tuner_type; | ||
1614 | |||
1615 | dev->video_inputs = em28xx_boards[model].vchannels; | ||
1616 | |||
1617 | for (i = 0; i < TVNORMS; i++) | ||
1618 | if (em28xx_boards[model].norm == tvnorms[i].mode) | ||
1619 | break; | ||
1620 | if (i == TVNORMS) | ||
1621 | i = 0; | ||
1622 | |||
1623 | dev->tvnorm = &tvnorms[i]; /* set default norm */ | ||
1624 | |||
1625 | em28xx_videodbg("tvnorm=%s\n", dev->tvnorm->name); | ||
1626 | |||
1627 | maxw = norm_maxw(dev); | ||
1628 | maxh = norm_maxh(dev); | ||
1629 | |||
1630 | /* set default image size */ | ||
1631 | dev->width = maxw; | ||
1632 | dev->height = maxh; | ||
1633 | dev->interlaced = EM28XX_INTERLACED_DEFAULT; | ||
1634 | dev->field_size = dev->width * dev->height; | ||
1635 | dev->frame_size = | ||
1636 | dev->interlaced ? dev->field_size << 1 : dev->field_size; | ||
1637 | dev->bytesperline = dev->width * 2; | ||
1638 | dev->hscale = 0; | ||
1639 | dev->vscale = 0; | ||
1640 | dev->ctl_input = 2; | ||
1641 | |||
1642 | /* setup video picture settings for saa7113h */ | ||
1643 | memset(&dev->vpic, 0, sizeof(dev->vpic)); | ||
1644 | dev->vpic.colour = 128 << 8; | ||
1645 | dev->vpic.hue = 128 << 8; | ||
1646 | dev->vpic.brightness = 128 << 8; | ||
1647 | dev->vpic.contrast = 192 << 8; | ||
1648 | dev->vpic.whiteness = 128 << 8; /* This one isn't used */ | ||
1649 | dev->vpic.depth = 16; | ||
1650 | dev->vpic.palette = VIDEO_PALETTE_YUV422; | ||
1651 | |||
1652 | #ifdef CONFIG_MODULES | ||
1653 | /* request some modules */ | ||
1654 | if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114) | ||
1655 | request_module("saa711x"); | ||
1656 | if (dev->decoder == EM28XX_TVP5150) | ||
1657 | request_module("tvp5150"); | ||
1658 | if (dev->has_tuner) | ||
1659 | request_module("tuner"); | ||
1660 | if (dev->tda9887_conf) | ||
1661 | request_module("tda9887"); | ||
1662 | #endif | ||
1663 | errCode = em28xx_config(dev); | ||
1664 | if (errCode) { | ||
1665 | em28xx_errdev("error configuring device\n"); | ||
1666 | kfree(dev); | ||
1667 | return -ENOMEM; | ||
1668 | } | ||
1669 | |||
1670 | down(&dev->lock); | ||
1671 | /* register i2c bus */ | ||
1672 | em28xx_i2c_register(dev); | ||
1673 | |||
1674 | /* Do board specific init and eeprom reading */ | ||
1675 | em28xx_card_setup(dev); | ||
1676 | |||
1677 | /* configure the device */ | ||
1678 | em28xx_config_i2c(dev); | ||
1679 | |||
1680 | up(&dev->lock); | ||
1681 | |||
1682 | errCode = em28xx_config(dev); | ||
1683 | |||
1684 | #ifdef CONFIG_MODULES | ||
1685 | if (dev->has_msp34xx) | ||
1686 | request_module("msp3400"); | ||
1687 | #endif | ||
1688 | /* allocate and fill v4l2 device struct */ | ||
1689 | dev->vdev = video_device_alloc(); | ||
1690 | if (NULL == dev->vdev) { | ||
1691 | em28xx_errdev("cannot allocate video_device.\n"); | ||
1692 | kfree(dev); | ||
1693 | return -ENOMEM; | ||
1694 | } | ||
1695 | |||
1696 | dev->vdev->type = VID_TYPE_CAPTURE; | ||
1697 | if (dev->has_tuner) | ||
1698 | dev->vdev->type |= VID_TYPE_TUNER; | ||
1699 | dev->vdev->hardware = 0; | ||
1700 | dev->vdev->fops = &em28xx_v4l_fops; | ||
1701 | dev->vdev->minor = -1; | ||
1702 | dev->vdev->dev = &dev->udev->dev; | ||
1703 | dev->vdev->release = video_device_release; | ||
1704 | snprintf(dev->vdev->name, sizeof(dev->vdev->name), "%s", | ||
1705 | "em28xx video"); | ||
1706 | list_add_tail(&dev->devlist,&em28xx_devlist); | ||
1707 | |||
1708 | /* register v4l2 device */ | ||
1709 | down(&dev->lock); | ||
1710 | if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1))) { | ||
1711 | em28xx_errdev("unable to register video device (error=%i).\n", | ||
1712 | retval); | ||
1713 | up(&dev->lock); | ||
1714 | list_del(&dev->devlist); | ||
1715 | video_device_release(dev->vdev); | ||
1716 | kfree(dev); | ||
1717 | return -ENODEV; | ||
1718 | } | ||
1719 | if (dev->has_msp34xx) { | ||
1720 | /* Send a reset to other chips via gpio */ | ||
1721 | em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1); | ||
1722 | udelay(2500); | ||
1723 | em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1); | ||
1724 | udelay(2500); | ||
1725 | |||
1726 | } | ||
1727 | video_mux(dev, 0); | ||
1728 | |||
1729 | up(&dev->lock); | ||
1730 | |||
1731 | em28xx_info("V4L2 device registered as /dev/video%d\n", | ||
1732 | dev->vdev->minor); | ||
1733 | |||
1734 | return 0; | ||
1735 | } | ||
1736 | |||
1737 | /* | ||
1738 | * em28xx_usb_probe() | ||
1739 | * checks for supported devices | ||
1740 | */ | ||
1741 | static int em28xx_usb_probe(struct usb_interface *interface, | ||
1742 | const struct usb_device_id *id) | ||
1743 | { | ||
1744 | const struct usb_endpoint_descriptor *endpoint; | ||
1745 | struct usb_device *udev; | ||
1746 | struct usb_interface *uif; | ||
1747 | struct em28xx *dev = NULL; | ||
1748 | int retval = -ENODEV; | ||
1749 | int model,i,nr,ifnum; | ||
1750 | |||
1751 | udev = usb_get_dev(interface_to_usbdev(interface)); | ||
1752 | ifnum = interface->altsetting[0].desc.bInterfaceNumber; | ||
1753 | |||
1754 | |||
1755 | /* Don't register audio interfaces */ | ||
1756 | if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | ||
1757 | em28xx_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n", | ||
1758 | udev->descriptor.idVendor,udev->descriptor.idProduct, | ||
1759 | ifnum, | ||
1760 | interface->altsetting[0].desc.bInterfaceClass); | ||
1761 | return -ENODEV; | ||
1762 | } | ||
1763 | |||
1764 | em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n", | ||
1765 | udev->descriptor.idVendor,udev->descriptor.idProduct, | ||
1766 | ifnum, | ||
1767 | interface->altsetting[0].desc.bInterfaceClass); | ||
1768 | |||
1769 | endpoint = &interface->cur_altsetting->endpoint[1].desc; | ||
1770 | |||
1771 | /* check if the the device has the iso in endpoint at the correct place */ | ||
1772 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != | ||
1773 | USB_ENDPOINT_XFER_ISOC) { | ||
1774 | em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); | ||
1775 | return -ENODEV; | ||
1776 | } | ||
1777 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { | ||
1778 | em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); | ||
1779 | return -ENODEV; | ||
1780 | } | ||
1781 | |||
1782 | model=id->driver_info; | ||
1783 | nr=interface->minor; | ||
1784 | |||
1785 | if (nr>EM28XX_MAXBOARDS) { | ||
1786 | printk (DRIVER_NAME ": Supports only %i em28xx boards.\n",EM28XX_MAXBOARDS); | ||
1787 | return -ENOMEM; | ||
1788 | } | ||
1789 | |||
1790 | /* allocate memory for our device state and initialize it */ | ||
1791 | dev = kmalloc(sizeof(*dev), GFP_KERNEL); | ||
1792 | if (dev == NULL) { | ||
1793 | em28xx_err(DRIVER_NAME ": out of memory!\n"); | ||
1794 | return -ENOMEM; | ||
1795 | } | ||
1796 | memset(dev, 0, sizeof(*dev)); | ||
1797 | |||
1798 | /* compute alternate max packet sizes */ | ||
1799 | uif = udev->actconfig->interface[0]; | ||
1800 | |||
1801 | dev->num_alt=uif->num_altsetting; | ||
1802 | printk(DRIVER_NAME ": Alternate settings: %i\n",dev->num_alt); | ||
1803 | // dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)* | ||
1804 | dev->alt_max_pkt_size = kmalloc(32* | ||
1805 | dev->num_alt,GFP_KERNEL); | ||
1806 | if (dev->alt_max_pkt_size == NULL) { | ||
1807 | em28xx_err(DRIVER_NAME ": out of memory!\n"); | ||
1808 | return -ENOMEM; | ||
1809 | } | ||
1810 | |||
1811 | for (i = 0; i < dev->num_alt ; i++) { | ||
1812 | u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc. | ||
1813 | wMaxPacketSize); | ||
1814 | dev->alt_max_pkt_size[i] = | ||
1815 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | ||
1816 | printk(DRIVER_NAME ": Alternate setting %i, max size= %i\n",i, | ||
1817 | dev->alt_max_pkt_size[i]); | ||
1818 | } | ||
1819 | |||
1820 | snprintf(dev->name, 29, "em28xx #%d", nr); | ||
1821 | |||
1822 | if ((card[nr]>=0)&&(card[nr]<em28xx_bcount)) | ||
1823 | model=card[nr]; | ||
1824 | |||
1825 | if ((model==EM2800_BOARD_UNKNOWN)||(model==EM2820_BOARD_UNKNOWN)) { | ||
1826 | printk( "%s: Your board has no eeprom inside it and thus can't\n" | ||
1827 | "%s: be autodetected. Please pass card=<n> insmod option to\n" | ||
1828 | "%s: workaround that. Redirect complaints to the vendor of\n" | ||
1829 | "%s: the TV card. Best regards,\n" | ||
1830 | "%s: -- tux\n", | ||
1831 | dev->name,dev->name,dev->name,dev->name,dev->name); | ||
1832 | printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n", | ||
1833 | dev->name); | ||
1834 | for (i = 0; i < em28xx_bcount; i++) { | ||
1835 | printk("%s: card=%d -> %s\n", | ||
1836 | dev->name, i, em28xx_boards[i].name); | ||
1837 | } | ||
1838 | } | ||
1839 | |||
1840 | /* allocate device struct */ | ||
1841 | retval = em28xx_init_dev(&dev, udev, nr, model); | ||
1842 | if (retval) | ||
1843 | return retval; | ||
1844 | |||
1845 | em28xx_info("Found %s\n", em28xx_boards[model].name); | ||
1846 | |||
1847 | /* save our data pointer in this interface device */ | ||
1848 | usb_set_intfdata(interface, dev); | ||
1849 | return 0; | ||
1850 | } | ||
1851 | |||
1852 | /* | ||
1853 | * em28xx_usb_disconnect() | ||
1854 | * called when the device gets diconencted | ||
1855 | * video device will be unregistered on v4l2_close in case it is still open | ||
1856 | */ | ||
1857 | static void em28xx_usb_disconnect(struct usb_interface *interface) | ||
1858 | { | ||
1859 | struct em28xx *dev = usb_get_intfdata(interface); | ||
1860 | usb_set_intfdata(interface, NULL); | ||
1861 | |||
1862 | if (!dev) | ||
1863 | return; | ||
1864 | |||
1865 | down_write(&em28xx_disconnect); | ||
1866 | |||
1867 | down(&dev->lock); | ||
1868 | |||
1869 | em28xx_info("disconnecting %s\n", dev->vdev->name); | ||
1870 | |||
1871 | wake_up_interruptible_all(&dev->open); | ||
1872 | |||
1873 | if (dev->users) { | ||
1874 | em28xx_warn | ||
1875 | ("device /dev/video%d is open! Deregistration and memory " | ||
1876 | "deallocation are deferred on close.\n", dev->vdev->minor); | ||
1877 | dev->state |= DEV_MISCONFIGURED; | ||
1878 | em28xx_uninit_isoc(dev); | ||
1879 | dev->state |= DEV_DISCONNECTED; | ||
1880 | wake_up_interruptible(&dev->wait_frame); | ||
1881 | wake_up_interruptible(&dev->wait_stream); | ||
1882 | } else { | ||
1883 | dev->state |= DEV_DISCONNECTED; | ||
1884 | em28xx_release_resources(dev); | ||
1885 | } | ||
1886 | |||
1887 | up(&dev->lock); | ||
1888 | |||
1889 | if (!dev->users) { | ||
1890 | kfree(dev->alt_max_pkt_size); | ||
1891 | kfree(dev); | ||
1892 | } | ||
1893 | |||
1894 | up_write(&em28xx_disconnect); | ||
1895 | } | ||
1896 | |||
1897 | static struct usb_driver em28xx_usb_driver = { | ||
1898 | .owner = THIS_MODULE, | ||
1899 | .name = "em28xx", | ||
1900 | .probe = em28xx_usb_probe, | ||
1901 | .disconnect = em28xx_usb_disconnect, | ||
1902 | .id_table = em28xx_id_table, | ||
1903 | }; | ||
1904 | |||
1905 | static int __init em28xx_module_init(void) | ||
1906 | { | ||
1907 | int result; | ||
1908 | |||
1909 | printk(KERN_INFO DRIVER_NAME " v4l2 driver version %d.%d.%d loaded\n", | ||
1910 | (EM28XX_VERSION_CODE >> 16) & 0xff, | ||
1911 | (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff); | ||
1912 | #ifdef SNAPSHOT | ||
1913 | printk(KERN_INFO DRIVER_NAME " snapshot date %04d-%02d-%02d\n", | ||
1914 | SNAPSHOT / 10000, (SNAPSHOT / 100) % 100, SNAPSHOT % 100); | ||
1915 | #endif | ||
1916 | |||
1917 | /* register this driver with the USB subsystem */ | ||
1918 | result = usb_register(&em28xx_usb_driver); | ||
1919 | if (result) | ||
1920 | em28xx_err(DRIVER_NAME | ||
1921 | " usb_register failed. Error number %d.\n", result); | ||
1922 | |||
1923 | return result; | ||
1924 | } | ||
1925 | |||
1926 | static void __exit em28xx_module_exit(void) | ||
1927 | { | ||
1928 | /* deregister this driver with the USB subsystem */ | ||
1929 | usb_deregister(&em28xx_usb_driver); | ||
1930 | } | ||
1931 | |||
1932 | module_init(em28xx_module_init); | ||
1933 | module_exit(em28xx_module_exit); | ||
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h new file mode 100644 index 000000000000..5c7a41ce69f3 --- /dev/null +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -0,0 +1,513 @@ | |||
1 | /* | ||
2 | em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | ||
3 | |||
4 | Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> | ||
5 | Ludovico Cavedon <cavedon@sssup.it> | ||
6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | ||
7 | |||
8 | Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> | ||
9 | |||
10 | This program is free software; you can redistribute it and/or modify | ||
11 | it under the terms of the GNU General Public License as published by | ||
12 | the Free Software Foundation; either version 2 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU General Public License | ||
21 | along with this program; if not, write to the Free Software | ||
22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | #ifndef _EM28XX_H | ||
26 | #define _EM28XX_H | ||
27 | |||
28 | #include <linux/videodev.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <media/ir-kbd-i2c.h> | ||
31 | |||
32 | /* Boards supported by driver */ | ||
33 | |||
34 | #define EM2800_BOARD_UNKNOWN 0 | ||
35 | #define EM2820_BOARD_UNKNOWN 1 | ||
36 | #define EM2820_BOARD_TERRATEC_CINERGY_250 2 | ||
37 | #define EM2820_BOARD_PINNACLE_USB_2 3 | ||
38 | #define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4 | ||
39 | #define EM2820_BOARD_MSI_VOX_USB_2 5 | ||
40 | #define EM2800_BOARD_TERRATEC_CINERGY_200 6 | ||
41 | #define EM2800_BOARD_LEADTEK_WINFAST_USBII 7 | ||
42 | #define EM2800_BOARD_KWORLD_USB2800 8 | ||
43 | #define EM2820_BOARD_PINNACLE_DVC_90 9 | ||
44 | |||
45 | #define UNSET -1 | ||
46 | |||
47 | /* maximum number of em28xx boards */ | ||
48 | #define EM28XX_MAXBOARDS 1 /*FIXME: should be bigger */ | ||
49 | |||
50 | /* maximum number of frames that can be queued */ | ||
51 | #define EM28XX_NUM_FRAMES 5 | ||
52 | /* number of frames that get used for v4l2_read() */ | ||
53 | #define EM28XX_NUM_READ_FRAMES 2 | ||
54 | |||
55 | /* number of buffers for isoc transfers */ | ||
56 | #define EM28XX_NUM_BUFS 5 | ||
57 | |||
58 | /* number of packets for each buffer | ||
59 | windows requests only 40 packets .. so we better do the same | ||
60 | this is what I found out for all alternate numbers there! | ||
61 | */ | ||
62 | #define EM28XX_NUM_PACKETS 40 | ||
63 | |||
64 | /* default alternate; 0 means choose the best */ | ||
65 | #define EM28XX_PINOUT 0 | ||
66 | |||
67 | #define EM28XX_INTERLACED_DEFAULT 1 | ||
68 | |||
69 | /* | ||
70 | #define (use usbview if you want to get the other alternate number infos) | ||
71 | #define | ||
72 | #define alternate number 2 | ||
73 | #define Endpoint Address: 82 | ||
74 | Direction: in | ||
75 | Attribute: 1 | ||
76 | Type: Isoc | ||
77 | Max Packet Size: 1448 | ||
78 | Interval: 125us | ||
79 | |||
80 | alternate number 7 | ||
81 | |||
82 | Endpoint Address: 82 | ||
83 | Direction: in | ||
84 | Attribute: 1 | ||
85 | Type: Isoc | ||
86 | Max Packet Size: 3072 | ||
87 | Interval: 125us | ||
88 | */ | ||
89 | |||
90 | /* time to wait when stopping the isoc transfer */ | ||
91 | #define EM28XX_URB_TIMEOUT msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS) | ||
92 | |||
93 | /* time in msecs to wait for i2c writes to finish */ | ||
94 | #define EM2800_I2C_WRITE_TIMEOUT 20 | ||
95 | |||
96 | /* the various frame states */ | ||
97 | enum em28xx_frame_state { | ||
98 | F_UNUSED = 0, | ||
99 | F_QUEUED, | ||
100 | F_GRABBING, | ||
101 | F_DONE, | ||
102 | F_ERROR, | ||
103 | }; | ||
104 | |||
105 | /* stream states */ | ||
106 | enum em28xx_stream_state { | ||
107 | STREAM_OFF, | ||
108 | STREAM_INTERRUPT, | ||
109 | STREAM_ON, | ||
110 | }; | ||
111 | |||
112 | /* frames */ | ||
113 | struct em28xx_frame_t { | ||
114 | void *bufmem; | ||
115 | struct v4l2_buffer buf; | ||
116 | enum em28xx_frame_state state; | ||
117 | struct list_head frame; | ||
118 | unsigned long vma_use_count; | ||
119 | int top_field; | ||
120 | int fieldbytesused; | ||
121 | }; | ||
122 | |||
123 | /* io methods */ | ||
124 | enum em28xx_io_method { | ||
125 | IO_NONE, | ||
126 | IO_READ, | ||
127 | IO_MMAP, | ||
128 | }; | ||
129 | |||
130 | /* inputs */ | ||
131 | |||
132 | #define MAX_EM28XX_INPUT 4 | ||
133 | enum enum28xx_itype { | ||
134 | EM28XX_VMUX_COMPOSITE1 = 1, | ||
135 | EM28XX_VMUX_COMPOSITE2, | ||
136 | EM28XX_VMUX_COMPOSITE3, | ||
137 | EM28XX_VMUX_COMPOSITE4, | ||
138 | EM28XX_VMUX_SVIDEO, | ||
139 | EM28XX_VMUX_TELEVISION, | ||
140 | EM28XX_VMUX_CABLE, | ||
141 | EM28XX_VMUX_DVB, | ||
142 | EM28XX_VMUX_DEBUG, | ||
143 | EM28XX_RADIO, | ||
144 | }; | ||
145 | |||
146 | struct em28xx_input { | ||
147 | enum enum28xx_itype type; | ||
148 | unsigned int vmux; | ||
149 | unsigned int amux; | ||
150 | }; | ||
151 | |||
152 | #define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) | ||
153 | |||
154 | enum em28xx_decoder { | ||
155 | EM28XX_TVP5150, | ||
156 | EM28XX_SAA7113, | ||
157 | EM28XX_SAA7114 | ||
158 | }; | ||
159 | |||
160 | struct em28xx_board { | ||
161 | char *name; | ||
162 | int vchannels; | ||
163 | int norm; | ||
164 | int tuner_type; | ||
165 | |||
166 | /* i2c flags */ | ||
167 | unsigned int is_em2800; | ||
168 | unsigned int tda9887_conf; | ||
169 | |||
170 | unsigned int has_tuner:1; | ||
171 | unsigned int has_msp34xx:1; | ||
172 | |||
173 | enum em28xx_decoder decoder; | ||
174 | |||
175 | struct em28xx_input input[MAX_EM28XX_INPUT]; | ||
176 | }; | ||
177 | |||
178 | struct em28xx_eeprom { | ||
179 | u32 id; /* 0x9567eb1a */ | ||
180 | u16 vendor_ID; | ||
181 | u16 product_ID; | ||
182 | |||
183 | u16 chip_conf; | ||
184 | |||
185 | u16 board_conf; | ||
186 | |||
187 | u16 string1, string2, string3; | ||
188 | |||
189 | u8 string_idx_table; | ||
190 | }; | ||
191 | |||
192 | /* device states */ | ||
193 | enum em28xx_dev_state { | ||
194 | DEV_INITIALIZED = 0x01, | ||
195 | DEV_DISCONNECTED = 0x02, | ||
196 | DEV_MISCONFIGURED = 0x04, | ||
197 | }; | ||
198 | |||
199 | /* tvnorms */ | ||
200 | struct em28xx_tvnorm { | ||
201 | char *name; | ||
202 | v4l2_std_id id; | ||
203 | /* mode for saa7113h */ | ||
204 | int mode; | ||
205 | }; | ||
206 | |||
207 | /* main device struct */ | ||
208 | struct em28xx { | ||
209 | /* generic device properties */ | ||
210 | char name[30]; /* name (including minor) of the device */ | ||
211 | int model; /* index in the device_data struct */ | ||
212 | unsigned int is_em2800; | ||
213 | int video_inputs; /* number of video inputs */ | ||
214 | struct list_head devlist; | ||
215 | unsigned int has_tuner:1; | ||
216 | unsigned int has_msp34xx:1; | ||
217 | unsigned int has_tda9887:1; | ||
218 | |||
219 | enum em28xx_decoder decoder; | ||
220 | |||
221 | int tuner_type; /* type of the tuner */ | ||
222 | int tuner_addr; /* tuner address */ | ||
223 | int tda9887_conf; | ||
224 | /* i2c i/o */ | ||
225 | struct i2c_adapter i2c_adap; | ||
226 | struct i2c_client i2c_client; | ||
227 | /* video for linux */ | ||
228 | int users; /* user count for exclusive use */ | ||
229 | struct video_device *vdev; /* video for linux device struct */ | ||
230 | struct video_picture vpic; /* picture settings only used to init saa7113h */ | ||
231 | struct em28xx_tvnorm *tvnorm; /* selected tv norm */ | ||
232 | int ctl_freq; /* selected frequency */ | ||
233 | unsigned int ctl_input; /* selected input */ | ||
234 | unsigned int ctl_ainput; /* slected audio input */ | ||
235 | int mute; | ||
236 | int volume; | ||
237 | /* frame properties */ | ||
238 | struct em28xx_frame_t frame[EM28XX_NUM_FRAMES]; /* list of frames */ | ||
239 | int num_frames; /* number of frames currently in use */ | ||
240 | unsigned int frame_count; /* total number of transfered frames */ | ||
241 | struct em28xx_frame_t *frame_current; /* the frame that is being filled */ | ||
242 | int width; /* current frame width */ | ||
243 | int height; /* current frame height */ | ||
244 | int frame_size; /* current frame size */ | ||
245 | int field_size; /* current field size */ | ||
246 | int bytesperline; | ||
247 | int hscale; /* horizontal scale factor (see datasheet) */ | ||
248 | int vscale; /* vertical scale factor (see datasheet) */ | ||
249 | int interlaced; /* 1=interlace fileds, 0=just top fileds */ | ||
250 | int type; | ||
251 | |||
252 | /* states */ | ||
253 | enum em28xx_dev_state state; | ||
254 | enum em28xx_stream_state stream; | ||
255 | enum em28xx_io_method io; | ||
256 | /* locks */ | ||
257 | struct semaphore lock, fileop_lock; | ||
258 | spinlock_t queue_lock; | ||
259 | struct list_head inqueue, outqueue; | ||
260 | wait_queue_head_t open, wait_frame, wait_stream; | ||
261 | struct video_device *vbi_dev; | ||
262 | |||
263 | unsigned char eedata[256]; | ||
264 | |||
265 | /* usb transfer */ | ||
266 | struct usb_device *udev; /* the usb device */ | ||
267 | int alt; /* alternate */ | ||
268 | int max_pkt_size; /* max packet size of isoc transaction */ | ||
269 | int num_alt; /* Number of alternative settings */ | ||
270 | unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ | ||
271 | struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */ | ||
272 | char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */ | ||
273 | /* helper funcs that call usb_control_msg */ | ||
274 | int (*em28xx_write_regs) (struct em28xx * dev, u16 reg, char *buf, | ||
275 | int len); | ||
276 | int (*em28xx_read_reg) (struct em28xx * dev, u16 reg); | ||
277 | int (*em28xx_read_reg_req_len) (struct em28xx * dev, u8 req, u16 reg, | ||
278 | char *buf, int len); | ||
279 | int (*em28xx_write_regs_req) (struct em28xx * dev, u8 req, u16 reg, | ||
280 | char *buf, int len); | ||
281 | int (*em28xx_read_reg_req) (struct em28xx * dev, u8 req, u16 reg); | ||
282 | }; | ||
283 | |||
284 | /* Provided by em28xx-i2c.c */ | ||
285 | |||
286 | void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg); | ||
287 | int em28xx_i2c_register(struct em28xx *dev); | ||
288 | int em28xx_i2c_unregister(struct em28xx *dev); | ||
289 | |||
290 | /* Provided by em28xx-input.c */ | ||
291 | |||
292 | void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir); | ||
293 | |||
294 | /* Provided by em28xx-core.c */ | ||
295 | |||
296 | void em28xx_print_ioctl(char *name, unsigned int cmd); | ||
297 | |||
298 | u32 em28xx_request_buffers(struct em28xx *dev, u32 count); | ||
299 | void em28xx_queue_unusedframes(struct em28xx *dev); | ||
300 | void em28xx_release_buffers(struct em28xx *dev); | ||
301 | |||
302 | int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | ||
303 | char *buf, int len); | ||
304 | int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg); | ||
305 | int em28xx_read_reg(struct em28xx *dev, u16 reg); | ||
306 | int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | ||
307 | int len); | ||
308 | int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); | ||
309 | int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, | ||
310 | u8 bitmask); | ||
311 | int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val); | ||
312 | int em28xx_audio_analog_set(struct em28xx *dev); | ||
313 | int em28xx_colorlevels_set_default(struct em28xx *dev); | ||
314 | int em28xx_capture_start(struct em28xx *dev, int start); | ||
315 | int em28xx_outfmt_set_yuv422(struct em28xx *dev); | ||
316 | int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin, | ||
317 | u8 ymax); | ||
318 | int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, | ||
319 | u16 width, u16 height); | ||
320 | int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v); | ||
321 | int em28xx_resolution_set(struct em28xx *dev); | ||
322 | void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs); | ||
323 | int em28xx_init_isoc(struct em28xx *dev); | ||
324 | void em28xx_uninit_isoc(struct em28xx *dev); | ||
325 | int em28xx_set_alternate(struct em28xx *dev); | ||
326 | |||
327 | /* Provided by em28xx-cards.c */ | ||
328 | extern int em2800_variant_detect(struct usb_device* udev,int model); | ||
329 | extern void em28xx_card_setup(struct em28xx *dev); | ||
330 | extern struct em28xx_board em28xx_boards[]; | ||
331 | extern struct usb_device_id em28xx_id_table[]; | ||
332 | extern const unsigned int em28xx_bcount; | ||
333 | |||
334 | /* em28xx registers */ | ||
335 | #define CHIPID_REG 0x0a | ||
336 | #define USBSUSP_REG 0x0c /* */ | ||
337 | |||
338 | #define AUDIOSRC_REG 0x0e | ||
339 | #define XCLK_REG 0x0f | ||
340 | |||
341 | #define VINMODE_REG 0x10 | ||
342 | #define VINCTRL_REG 0x11 | ||
343 | #define VINENABLE_REG 0x12 /* */ | ||
344 | |||
345 | #define GAMMA_REG 0x14 | ||
346 | #define RGAIN_REG 0x15 | ||
347 | #define GGAIN_REG 0x16 | ||
348 | #define BGAIN_REG 0x17 | ||
349 | #define ROFFSET_REG 0x18 | ||
350 | #define GOFFSET_REG 0x19 | ||
351 | #define BOFFSET_REG 0x1a | ||
352 | |||
353 | #define OFLOW_REG 0x1b | ||
354 | #define HSTART_REG 0x1c | ||
355 | #define VSTART_REG 0x1d | ||
356 | #define CWIDTH_REG 0x1e | ||
357 | #define CHEIGHT_REG 0x1f | ||
358 | |||
359 | #define YGAIN_REG 0x20 | ||
360 | #define YOFFSET_REG 0x21 | ||
361 | #define UVGAIN_REG 0x22 | ||
362 | #define UOFFSET_REG 0x23 | ||
363 | #define VOFFSET_REG 0x24 | ||
364 | #define SHARPNESS_REG 0x25 | ||
365 | |||
366 | #define COMPR_REG 0x26 | ||
367 | #define OUTFMT_REG 0x27 | ||
368 | |||
369 | #define XMIN_REG 0x28 | ||
370 | #define XMAX_REG 0x29 | ||
371 | #define YMIN_REG 0x2a | ||
372 | #define YMAX_REG 0x2b | ||
373 | |||
374 | #define HSCALELOW_REG 0x30 | ||
375 | #define HSCALEHIGH_REG 0x31 | ||
376 | #define VSCALELOW_REG 0x32 | ||
377 | #define VSCALEHIGH_REG 0x33 | ||
378 | |||
379 | #define AC97LSB_REG 0x40 | ||
380 | #define AC97MSB_REG 0x41 | ||
381 | #define AC97ADDR_REG 0x42 | ||
382 | #define AC97BUSY_REG 0x43 | ||
383 | |||
384 | /* em202 registers */ | ||
385 | #define MASTER_AC97 0x02 | ||
386 | #define VIDEO_AC97 0x14 | ||
387 | |||
388 | /* register settings */ | ||
389 | #define EM28XX_AUDIO_SRC_TUNER 0xc0 | ||
390 | #define EM28XX_AUDIO_SRC_LINE 0x80 | ||
391 | |||
392 | /* printk macros */ | ||
393 | |||
394 | #define em28xx_err(fmt, arg...) do {\ | ||
395 | printk(KERN_ERR fmt , ##arg); } while (0) | ||
396 | |||
397 | #define em28xx_errdev(fmt, arg...) do {\ | ||
398 | printk(KERN_ERR "%s: "fmt,\ | ||
399 | dev->name , ##arg); } while (0) | ||
400 | |||
401 | #define em28xx_info(fmt, arg...) do {\ | ||
402 | printk(KERN_INFO "%s: "fmt,\ | ||
403 | dev->name , ##arg); } while (0) | ||
404 | #define em28xx_warn(fmt, arg...) do {\ | ||
405 | printk(KERN_WARNING "%s: "fmt,\ | ||
406 | dev->name , ##arg); } while (0) | ||
407 | |||
408 | inline static int em28xx_audio_source(struct em28xx *dev, int input) | ||
409 | { | ||
410 | return em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0); | ||
411 | } | ||
412 | |||
413 | inline static int em28xx_audio_usb_mute(struct em28xx *dev, int mute) | ||
414 | { | ||
415 | return em28xx_write_reg_bits(dev, XCLK_REG, mute ? 0x00 : 0x80, 0x80); | ||
416 | } | ||
417 | |||
418 | inline static int em28xx_audio_analog_setup(struct em28xx *dev) | ||
419 | { | ||
420 | /* unmute video mixer with default volume level */ | ||
421 | return em28xx_write_ac97(dev, VIDEO_AC97, "\x08\x08"); | ||
422 | } | ||
423 | |||
424 | inline static int em28xx_compression_disable(struct em28xx *dev) | ||
425 | { | ||
426 | /* side effect of disabling scaler and mixer */ | ||
427 | return em28xx_write_regs(dev, COMPR_REG, "\x00", 1); | ||
428 | } | ||
429 | |||
430 | inline static int em28xx_contrast_get(struct em28xx *dev) | ||
431 | { | ||
432 | return em28xx_read_reg(dev, YGAIN_REG) & 0x1f; | ||
433 | } | ||
434 | |||
435 | inline static int em28xx_brightness_get(struct em28xx *dev) | ||
436 | { | ||
437 | return em28xx_read_reg(dev, YOFFSET_REG); | ||
438 | } | ||
439 | |||
440 | inline static int em28xx_saturation_get(struct em28xx *dev) | ||
441 | { | ||
442 | return em28xx_read_reg(dev, UVGAIN_REG) & 0x1f; | ||
443 | } | ||
444 | |||
445 | inline static int em28xx_u_balance_get(struct em28xx *dev) | ||
446 | { | ||
447 | return em28xx_read_reg(dev, UOFFSET_REG); | ||
448 | } | ||
449 | |||
450 | inline static int em28xx_v_balance_get(struct em28xx *dev) | ||
451 | { | ||
452 | return em28xx_read_reg(dev, VOFFSET_REG); | ||
453 | } | ||
454 | |||
455 | inline static int em28xx_gamma_get(struct em28xx *dev) | ||
456 | { | ||
457 | return em28xx_read_reg(dev, GAMMA_REG) & 0x3f; | ||
458 | } | ||
459 | |||
460 | inline static int em28xx_contrast_set(struct em28xx *dev, s32 val) | ||
461 | { | ||
462 | u8 tmp = (u8) val; | ||
463 | return em28xx_write_regs(dev, YGAIN_REG, &tmp, 1); | ||
464 | } | ||
465 | |||
466 | inline static int em28xx_brightness_set(struct em28xx *dev, s32 val) | ||
467 | { | ||
468 | u8 tmp = (u8) val; | ||
469 | return em28xx_write_regs(dev, YOFFSET_REG, &tmp, 1); | ||
470 | } | ||
471 | |||
472 | inline static int em28xx_saturation_set(struct em28xx *dev, s32 val) | ||
473 | { | ||
474 | u8 tmp = (u8) val; | ||
475 | return em28xx_write_regs(dev, UVGAIN_REG, &tmp, 1); | ||
476 | } | ||
477 | |||
478 | inline static int em28xx_u_balance_set(struct em28xx *dev, s32 val) | ||
479 | { | ||
480 | u8 tmp = (u8) val; | ||
481 | return em28xx_write_regs(dev, UOFFSET_REG, &tmp, 1); | ||
482 | } | ||
483 | |||
484 | inline static int em28xx_v_balance_set(struct em28xx *dev, s32 val) | ||
485 | { | ||
486 | u8 tmp = (u8) val; | ||
487 | return em28xx_write_regs(dev, VOFFSET_REG, &tmp, 1); | ||
488 | } | ||
489 | |||
490 | inline static int em28xx_gamma_set(struct em28xx *dev, s32 val) | ||
491 | { | ||
492 | u8 tmp = (u8) val; | ||
493 | return em28xx_write_regs(dev, GAMMA_REG, &tmp, 1); | ||
494 | } | ||
495 | |||
496 | /*FIXME: maxw should be dependent of alt mode */ | ||
497 | inline static unsigned int norm_maxw(struct em28xx *dev) | ||
498 | { | ||
499 | switch(dev->model){ | ||
500 | case (EM2820_BOARD_MSI_VOX_USB_2): return(640); | ||
501 | default: return(720); | ||
502 | } | ||
503 | } | ||
504 | |||
505 | inline static unsigned int norm_maxh(struct em28xx *dev) | ||
506 | { | ||
507 | switch(dev->model){ | ||
508 | case (EM2820_BOARD_MSI_VOX_USB_2): return(480); | ||
509 | default: return (dev->tvnorm->id & V4L2_STD_625_50) ? 576 : 480; | ||
510 | } | ||
511 | } | ||
512 | |||
513 | #endif | ||
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c index 234151e48edc..ed81934ef3cd 100644 --- a/drivers/media/video/ir-kbd-gpio.c +++ b/drivers/media/video/ir-kbd-gpio.c | |||
@@ -156,6 +156,71 @@ static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { | |||
156 | 156 | ||
157 | /* ---------------------------------------------------------------------- */ | 157 | /* ---------------------------------------------------------------------- */ |
158 | 158 | ||
159 | /* Ricardo Cerqueira <v4l@cerqueira.org> */ | ||
160 | /* Weird matching, since the remote has "uncommon" keys */ | ||
161 | |||
162 | static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = { | ||
163 | |||
164 | [ 30 ] = KEY_POWER, // power | ||
165 | [ 7 ] = KEY_MEDIA, // source | ||
166 | [ 28 ] = KEY_SEARCH, // scan | ||
167 | |||
168 | /* FIXME: duplicate keycodes? | ||
169 | * | ||
170 | * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>> | ||
171 | * The GPIO values are | ||
172 | * 6397fb for both "Scan <" and "CH -", | ||
173 | * 639ffb for "Scan >" and "CH+", | ||
174 | * 6384fb for "Tune <" and "<<<", | ||
175 | * 638cfb for "Tune >" and ">>>", regardless of the mask. | ||
176 | * | ||
177 | * [ 23 ] = KEY_BACK, // fm scan << | ||
178 | * [ 31 ] = KEY_FORWARD, // fm scan >> | ||
179 | * | ||
180 | * [ 4 ] = KEY_LEFT, // fm tuning < | ||
181 | * [ 12 ] = KEY_RIGHT, // fm tuning > | ||
182 | * | ||
183 | * For now, these four keys are disabled. Pressing them will generate | ||
184 | * the CH+/CH-/<<</>>> events | ||
185 | */ | ||
186 | |||
187 | [ 3 ] = KEY_TUNER, // TV/FM | ||
188 | |||
189 | [ 0 ] = KEY_RECORD, | ||
190 | [ 8 ] = KEY_STOP, | ||
191 | [ 17 ] = KEY_PLAY, | ||
192 | |||
193 | [ 26 ] = KEY_PLAYPAUSE, // freeze | ||
194 | [ 25 ] = KEY_ZOOM, // zoom | ||
195 | [ 15 ] = KEY_TEXT, // min | ||
196 | |||
197 | [ 1 ] = KEY_KP1, | ||
198 | [ 11 ] = KEY_KP2, | ||
199 | [ 27 ] = KEY_KP3, | ||
200 | [ 5 ] = KEY_KP4, | ||
201 | [ 9 ] = KEY_KP5, | ||
202 | [ 21 ] = KEY_KP6, | ||
203 | [ 6 ] = KEY_KP7, | ||
204 | [ 10 ] = KEY_KP8, | ||
205 | [ 18 ] = KEY_KP9, | ||
206 | [ 2 ] = KEY_KP0, | ||
207 | [ 16 ] = KEY_LAST, // +100 | ||
208 | [ 19 ] = KEY_LIST, // recall | ||
209 | |||
210 | [ 31 ] = KEY_CHANNELUP, // chn down | ||
211 | [ 23 ] = KEY_CHANNELDOWN, // chn up | ||
212 | [ 22 ] = KEY_VOLUMEUP, // vol down | ||
213 | [ 20 ] = KEY_VOLUMEDOWN, // vol up | ||
214 | |||
215 | [ 4 ] = KEY_KPMINUS, // <<< | ||
216 | [ 14 ] = KEY_SETUP, // function | ||
217 | [ 12 ] = KEY_KPPLUS, // >>> | ||
218 | |||
219 | [ 13 ] = KEY_GOTO, // mts | ||
220 | [ 29 ] = KEY_REFRESH, // reset | ||
221 | [ 24 ] = KEY_MUTE // mute/unmute | ||
222 | }; | ||
223 | |||
159 | struct IR { | 224 | struct IR { |
160 | struct bttv_sub_device *sub; | 225 | struct bttv_sub_device *sub; |
161 | struct input_dev *input; | 226 | struct input_dev *input; |
@@ -282,53 +347,59 @@ static int ir_probe(struct device *dev) | |||
282 | 347 | ||
283 | /* detect & configure */ | 348 | /* detect & configure */ |
284 | switch (sub->core->type) { | 349 | switch (sub->core->type) { |
285 | case BTTV_AVERMEDIA: | 350 | case BTTV_BOARD_AVERMEDIA: |
286 | case BTTV_AVPHONE98: | 351 | case BTTV_BOARD_AVPHONE98: |
287 | case BTTV_AVERMEDIA98: | 352 | case BTTV_BOARD_AVERMEDIA98: |
288 | ir_codes = ir_codes_avermedia; | 353 | ir_codes = ir_codes_avermedia; |
289 | ir->mask_keycode = 0xf88000; | 354 | ir->mask_keycode = 0xf88000; |
290 | ir->mask_keydown = 0x010000; | 355 | ir->mask_keydown = 0x010000; |
291 | ir->polling = 50; // ms | 356 | ir->polling = 50; // ms |
292 | break; | 357 | break; |
293 | 358 | ||
294 | case BTTV_AVDVBT_761: | 359 | case BTTV_BOARD_AVDVBT_761: |
295 | case BTTV_AVDVBT_771: | 360 | case BTTV_BOARD_AVDVBT_771: |
296 | ir_codes = ir_codes_avermedia_dvbt; | 361 | ir_codes = ir_codes_avermedia_dvbt; |
297 | ir->mask_keycode = 0x0f00c0; | 362 | ir->mask_keycode = 0x0f00c0; |
298 | ir->mask_keydown = 0x000020; | 363 | ir->mask_keydown = 0x000020; |
299 | ir->polling = 50; // ms | 364 | ir->polling = 50; // ms |
300 | break; | 365 | break; |
301 | 366 | ||
302 | case BTTV_PXELVWPLTVPAK: | 367 | case BTTV_BOARD_PXELVWPLTVPAK: |
303 | ir_codes = ir_codes_pixelview; | 368 | ir_codes = ir_codes_pixelview; |
304 | ir->mask_keycode = 0x003e00; | 369 | ir->mask_keycode = 0x003e00; |
305 | ir->mask_keyup = 0x010000; | 370 | ir->mask_keyup = 0x010000; |
306 | ir->polling = 50; // ms | 371 | ir->polling = 50; // ms |
307 | break; | 372 | break; |
308 | case BTTV_PV_BT878P_9B: | 373 | case BTTV_BOARD_PV_BT878P_9B: |
309 | case BTTV_PV_BT878P_PLUS: | 374 | case BTTV_BOARD_PV_BT878P_PLUS: |
310 | ir_codes = ir_codes_pixelview; | 375 | ir_codes = ir_codes_pixelview; |
311 | ir->mask_keycode = 0x001f00; | 376 | ir->mask_keycode = 0x001f00; |
312 | ir->mask_keyup = 0x008000; | 377 | ir->mask_keyup = 0x008000; |
313 | ir->polling = 50; // ms | 378 | ir->polling = 50; // ms |
314 | break; | 379 | break; |
315 | 380 | ||
316 | case BTTV_WINFAST2000: | 381 | case BTTV_BOARD_WINFAST2000: |
317 | ir_codes = ir_codes_winfast; | 382 | ir_codes = ir_codes_winfast; |
318 | ir->mask_keycode = 0x1f8; | 383 | ir->mask_keycode = 0x1f8; |
319 | break; | 384 | break; |
320 | case BTTV_MAGICTVIEW061: | 385 | case BTTV_BOARD_MAGICTVIEW061: |
321 | case BTTV_MAGICTVIEW063: | 386 | case BTTV_BOARD_MAGICTVIEW063: |
322 | ir_codes = ir_codes_winfast; | 387 | ir_codes = ir_codes_winfast; |
323 | ir->mask_keycode = 0x0008e000; | 388 | ir->mask_keycode = 0x0008e000; |
324 | ir->mask_keydown = 0x00200000; | 389 | ir->mask_keydown = 0x00200000; |
325 | break; | 390 | break; |
326 | case BTTV_APAC_VIEWCOMP: | 391 | case BTTV_BOARD_APAC_VIEWCOMP: |
327 | ir_codes = ir_codes_apac_viewcomp; | 392 | ir_codes = ir_codes_apac_viewcomp; |
328 | ir->mask_keycode = 0x001f00; | 393 | ir->mask_keycode = 0x001f00; |
329 | ir->mask_keyup = 0x008000; | 394 | ir->mask_keyup = 0x008000; |
330 | ir->polling = 50; // ms | 395 | ir->polling = 50; // ms |
331 | break; | 396 | break; |
397 | case BTTV_BOARD_CONCEPTRONIC_CTVFMI2: | ||
398 | ir_codes = ir_codes_conceptronic; | ||
399 | ir->mask_keycode = 0x001F00; | ||
400 | ir->mask_keyup = 0x006000; | ||
401 | ir->polling = 50; // ms | ||
402 | break; | ||
332 | } | 403 | } |
333 | if (NULL == ir_codes) { | 404 | if (NULL == ir_codes) { |
334 | kfree(ir); | 405 | kfree(ir); |
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 9703d3d351f9..0085567a1421 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -8,6 +8,8 @@ | |||
8 | * Christoph Bartelmus <lirc@bartelmus.de> | 8 | * Christoph Bartelmus <lirc@bartelmus.de> |
9 | * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by | 9 | * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by |
10 | * Ulrich Mueller <ulrich.mueller42@web.de> | 10 | * Ulrich Mueller <ulrich.mueller42@web.de> |
11 | * modified for em2820 based USB TV tuners by | ||
12 | * Markus Rechberger <mrechberger@gmail.com> | ||
11 | * | 13 | * |
12 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
@@ -37,10 +39,9 @@ | |||
37 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
38 | #include <linux/i2c.h> | 40 | #include <linux/i2c.h> |
39 | #include <linux/workqueue.h> | 41 | #include <linux/workqueue.h> |
40 | |||
41 | #include <asm/semaphore.h> | 42 | #include <asm/semaphore.h> |
42 | |||
43 | #include <media/ir-common.h> | 43 | #include <media/ir-common.h> |
44 | #include <media/ir-kbd-i2c.h> | ||
44 | 45 | ||
45 | /* Mark Phalan <phalanm@o2.ie> */ | 46 | /* Mark Phalan <phalanm@o2.ie> */ |
46 | static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { | 47 | static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { |
@@ -81,57 +82,6 @@ static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { | |||
81 | [ 28 ] = KEY_MEDIA, /* PC/TV */ | 82 | [ 28 ] = KEY_MEDIA, /* PC/TV */ |
82 | }; | 83 | }; |
83 | 84 | ||
84 | static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { | ||
85 | [ 0x3 ] = KEY_POWER, | ||
86 | [ 0x6f ] = KEY_MUTE, | ||
87 | [ 0x10 ] = KEY_BACKSPACE, /* Recall */ | ||
88 | |||
89 | [ 0x11 ] = KEY_KP0, | ||
90 | [ 0x4 ] = KEY_KP1, | ||
91 | [ 0x5 ] = KEY_KP2, | ||
92 | [ 0x6 ] = KEY_KP3, | ||
93 | [ 0x8 ] = KEY_KP4, | ||
94 | [ 0x9 ] = KEY_KP5, | ||
95 | [ 0xa ] = KEY_KP6, | ||
96 | [ 0xc ] = KEY_KP7, | ||
97 | [ 0xd ] = KEY_KP8, | ||
98 | [ 0xe ] = KEY_KP9, | ||
99 | [ 0x12 ] = KEY_KPDOT, /* 100+ */ | ||
100 | |||
101 | [ 0x7 ] = KEY_VOLUMEUP, | ||
102 | [ 0xb ] = KEY_VOLUMEDOWN, | ||
103 | [ 0x1a ] = KEY_KPPLUS, | ||
104 | [ 0x18 ] = KEY_KPMINUS, | ||
105 | [ 0x15 ] = KEY_UP, | ||
106 | [ 0x1d ] = KEY_DOWN, | ||
107 | [ 0xf ] = KEY_CHANNELUP, | ||
108 | [ 0x13 ] = KEY_CHANNELDOWN, | ||
109 | [ 0x48 ] = KEY_ZOOM, | ||
110 | |||
111 | [ 0x1b ] = KEY_VIDEO, /* Video source */ | ||
112 | [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */ | ||
113 | [ 0x19 ] = KEY_SEARCH, /* Auto Scan */ | ||
114 | |||
115 | [ 0x4b ] = KEY_RECORD, | ||
116 | [ 0x46 ] = KEY_PLAY, | ||
117 | [ 0x45 ] = KEY_PAUSE, /* Pause */ | ||
118 | [ 0x44 ] = KEY_STOP, | ||
119 | [ 0x40 ] = KEY_FORWARD, /* Forward ? */ | ||
120 | [ 0x42 ] = KEY_REWIND, /* Backward ? */ | ||
121 | |||
122 | }; | ||
123 | |||
124 | struct IR { | ||
125 | struct i2c_client c; | ||
126 | struct input_dev *input; | ||
127 | struct ir_input_state ir; | ||
128 | |||
129 | struct work_struct work; | ||
130 | struct timer_list timer; | ||
131 | char phys[32]; | ||
132 | int (*get_key)(struct IR*, u32*, u32*); | ||
133 | }; | ||
134 | |||
135 | /* ----------------------------------------------------------------------- */ | 85 | /* ----------------------------------------------------------------------- */ |
136 | /* insmod parameters */ | 86 | /* insmod parameters */ |
137 | 87 | ||
@@ -144,7 +94,7 @@ module_param(debug, int, 0644); /* debug level (0,1,2) */ | |||
144 | 94 | ||
145 | /* ----------------------------------------------------------------------- */ | 95 | /* ----------------------------------------------------------------------- */ |
146 | 96 | ||
147 | static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw) | 97 | static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
148 | { | 98 | { |
149 | unsigned char buf[3]; | 99 | unsigned char buf[3]; |
150 | int start, toggle, dev, code; | 100 | int start, toggle, dev, code; |
@@ -171,9 +121,9 @@ static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw) | |||
171 | return 1; | 121 | return 1; |
172 | } | 122 | } |
173 | 123 | ||
174 | static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw) | 124 | static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
175 | { | 125 | { |
176 | unsigned char b; | 126 | unsigned char b; |
177 | 127 | ||
178 | /* poll IR chip */ | 128 | /* poll IR chip */ |
179 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 129 | if (1 != i2c_master_recv(&ir->c,&b,1)) { |
@@ -185,9 +135,9 @@ static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw) | |||
185 | return 1; | 135 | return 1; |
186 | } | 136 | } |
187 | 137 | ||
188 | static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw) | 138 | static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
189 | { | 139 | { |
190 | unsigned char b; | 140 | unsigned char b; |
191 | 141 | ||
192 | /* poll IR chip */ | 142 | /* poll IR chip */ |
193 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 143 | if (1 != i2c_master_recv(&ir->c,&b,1)) { |
@@ -205,7 +155,7 @@ static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw) | |||
205 | return 1; | 155 | return 1; |
206 | } | 156 | } |
207 | 157 | ||
208 | static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw) | 158 | static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
209 | { | 159 | { |
210 | unsigned char b; | 160 | unsigned char b; |
211 | 161 | ||
@@ -216,15 +166,15 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw) | |||
216 | } | 166 | } |
217 | 167 | ||
218 | /* it seems that 0xFE indicates that a button is still hold | 168 | /* it seems that 0xFE indicates that a button is still hold |
219 | down, while 0xFF indicates that no button is hold | 169 | down, while 0xff indicates that no button is hold |
220 | down. 0xFE sequences are sometimes interrupted by 0xFF */ | 170 | down. 0xfe sequences are sometimes interrupted by 0xFF */ |
221 | 171 | ||
222 | dprintk(2,"key %02x\n", b); | 172 | dprintk(2,"key %02x\n", b); |
223 | 173 | ||
224 | if (b == 0xFF) | 174 | if (b == 0xff) |
225 | return 0; | 175 | return 0; |
226 | 176 | ||
227 | if (b == 0xFE) | 177 | if (b == 0xfe) |
228 | /* keep old data */ | 178 | /* keep old data */ |
229 | return 1; | 179 | return 1; |
230 | 180 | ||
@@ -233,31 +183,9 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw) | |||
233 | return 1; | 183 | return 1; |
234 | } | 184 | } |
235 | 185 | ||
236 | static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw) | ||
237 | { | ||
238 | unsigned char b; | ||
239 | |||
240 | /* poll IR chip */ | ||
241 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | ||
242 | dprintk(1,"read error\n"); | ||
243 | return -EIO; | ||
244 | } | ||
245 | |||
246 | /* no button press */ | ||
247 | if (b==0) | ||
248 | return 0; | ||
249 | |||
250 | /* repeating */ | ||
251 | if (b & 0x80) | ||
252 | return 1; | ||
253 | |||
254 | *ir_key = b; | ||
255 | *ir_raw = b; | ||
256 | return 1; | ||
257 | } | ||
258 | /* ----------------------------------------------------------------------- */ | 186 | /* ----------------------------------------------------------------------- */ |
259 | 187 | ||
260 | static void ir_key_poll(struct IR *ir) | 188 | static void ir_key_poll(struct IR_i2c *ir) |
261 | { | 189 | { |
262 | static u32 ir_key, ir_raw; | 190 | static u32 ir_key, ir_raw; |
263 | int rc; | 191 | int rc; |
@@ -278,13 +206,13 @@ static void ir_key_poll(struct IR *ir) | |||
278 | 206 | ||
279 | static void ir_timer(unsigned long data) | 207 | static void ir_timer(unsigned long data) |
280 | { | 208 | { |
281 | struct IR *ir = (struct IR*)data; | 209 | struct IR_i2c *ir = (struct IR_i2c*)data; |
282 | schedule_work(&ir->work); | 210 | schedule_work(&ir->work); |
283 | } | 211 | } |
284 | 212 | ||
285 | static void ir_work(void *data) | 213 | static void ir_work(void *data) |
286 | { | 214 | { |
287 | struct IR *ir = data; | 215 | struct IR_i2c *ir = data; |
288 | ir_key_poll(ir); | 216 | ir_key_poll(ir); |
289 | mod_timer(&ir->timer, jiffies+HZ/10); | 217 | mod_timer(&ir->timer, jiffies+HZ/10); |
290 | } | 218 | } |
@@ -297,17 +225,17 @@ static int ir_detach(struct i2c_client *client); | |||
297 | static int ir_probe(struct i2c_adapter *adap); | 225 | static int ir_probe(struct i2c_adapter *adap); |
298 | 226 | ||
299 | static struct i2c_driver driver = { | 227 | static struct i2c_driver driver = { |
300 | .name = "ir remote kbd driver", | 228 | .name = "ir remote kbd driver", |
301 | .id = I2C_DRIVERID_EXP3, /* FIXME */ | 229 | .id = I2C_DRIVERID_EXP3, /* FIXME */ |
302 | .flags = I2C_DF_NOTIFY, | 230 | .flags = I2C_DF_NOTIFY, |
303 | .attach_adapter = ir_probe, | 231 | .attach_adapter = ir_probe, |
304 | .detach_client = ir_detach, | 232 | .detach_client = ir_detach, |
305 | }; | 233 | }; |
306 | 234 | ||
307 | static struct i2c_client client_template = | 235 | static struct i2c_client client_template = |
308 | { | 236 | { |
309 | .name = "unset", | 237 | .name = "unset", |
310 | .driver = &driver | 238 | .driver = &driver |
311 | }; | 239 | }; |
312 | 240 | ||
313 | static int ir_attach(struct i2c_adapter *adap, int addr, | 241 | static int ir_attach(struct i2c_adapter *adap, int addr, |
@@ -316,10 +244,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
316 | IR_KEYTAB_TYPE *ir_codes = NULL; | 244 | IR_KEYTAB_TYPE *ir_codes = NULL; |
317 | char *name; | 245 | char *name; |
318 | int ir_type; | 246 | int ir_type; |
319 | struct IR *ir; | 247 | struct IR_i2c *ir; |
320 | struct input_dev *input_dev; | 248 | struct input_dev *input_dev; |
321 | 249 | ||
322 | ir = kzalloc(sizeof(struct IR), GFP_KERNEL); | 250 | ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL); |
323 | input_dev = input_allocate_device(); | 251 | input_dev = input_allocate_device(); |
324 | if (!ir || !input_dev) { | 252 | if (!ir || !input_dev) { |
325 | kfree(ir); | 253 | kfree(ir); |
@@ -361,10 +289,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
361 | ir_codes = ir_codes_empty; | 289 | ir_codes = ir_codes_empty; |
362 | break; | 290 | break; |
363 | case 0x7a: | 291 | case 0x7a: |
364 | name = "Purple TV"; | 292 | case 0x47: |
365 | ir->get_key = get_key_purpletv; | 293 | /* Handled by saa7134-input */ |
294 | name = "SAA713x remote"; | ||
366 | ir_type = IR_TYPE_OTHER; | 295 | ir_type = IR_TYPE_OTHER; |
367 | ir_codes = ir_codes_purpletv; | ||
368 | break; | 296 | break; |
369 | default: | 297 | default: |
370 | /* shouldn't happen */ | 298 | /* shouldn't happen */ |
@@ -373,9 +301,24 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
373 | return -1; | 301 | return -1; |
374 | } | 302 | } |
375 | 303 | ||
376 | /* register i2c device */ | 304 | /* Sets name */ |
377 | i2c_attach_client(&ir->c); | ||
378 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); | 305 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); |
306 | ir->ir_codes=ir_codes; | ||
307 | |||
308 | /* register i2c device | ||
309 | * At device register, IR codes may be changed to be | ||
310 | * board dependent. | ||
311 | */ | ||
312 | i2c_attach_client(&ir->c); | ||
313 | |||
314 | /* If IR not supported or disabled, unregisters driver */ | ||
315 | if (ir->get_key == NULL) { | ||
316 | i2c_detach_client(&ir->c); | ||
317 | kfree(ir); | ||
318 | return -1; | ||
319 | } | ||
320 | |||
321 | /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */ | ||
379 | snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", | 322 | snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", |
380 | ir->c.adapter->dev.bus_id, | 323 | ir->c.adapter->dev.bus_id, |
381 | ir->c.dev.bus_id); | 324 | ir->c.dev.bus_id); |
@@ -386,6 +329,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
386 | input_dev->name = ir->c.name; | 329 | input_dev->name = ir->c.name; |
387 | input_dev->phys = ir->phys; | 330 | input_dev->phys = ir->phys; |
388 | 331 | ||
332 | /* register event device */ | ||
389 | input_register_device(ir->input); | 333 | input_register_device(ir->input); |
390 | 334 | ||
391 | /* start polling via eventd */ | 335 | /* start polling via eventd */ |
@@ -400,7 +344,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
400 | 344 | ||
401 | static int ir_detach(struct i2c_client *client) | 345 | static int ir_detach(struct i2c_client *client) |
402 | { | 346 | { |
403 | struct IR *ir = i2c_get_clientdata(client); | 347 | struct IR_i2c *ir = i2c_get_clientdata(client); |
404 | 348 | ||
405 | /* kill outstanding polls */ | 349 | /* kill outstanding polls */ |
406 | del_timer(&ir->timer); | 350 | del_timer(&ir->timer); |
@@ -428,9 +372,12 @@ static int ir_probe(struct i2c_adapter *adap) | |||
428 | */ | 372 | */ |
429 | 373 | ||
430 | static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; | 374 | static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; |
431 | static const int probe_saa7134[] = { 0x7a, -1 }; | 375 | static const int probe_saa7134[] = { 0x7a, 0x47, -1 }; |
376 | static const int probe_em28XX[] = { 0x30, 0x47, -1 }; | ||
432 | const int *probe = NULL; | 377 | const int *probe = NULL; |
433 | struct i2c_client c; char buf; int i,rc; | 378 | struct i2c_client c; |
379 | unsigned char buf; | ||
380 | int i,rc; | ||
434 | 381 | ||
435 | switch (adap->id) { | 382 | switch (adap->id) { |
436 | case I2C_HW_B_BT848: | 383 | case I2C_HW_B_BT848: |
@@ -439,6 +386,9 @@ static int ir_probe(struct i2c_adapter *adap) | |||
439 | case I2C_HW_SAA7134: | 386 | case I2C_HW_SAA7134: |
440 | probe = probe_saa7134; | 387 | probe = probe_saa7134; |
441 | break; | 388 | break; |
389 | case I2C_HW_B_EM28XX: | ||
390 | probe = probe_em28XX; | ||
391 | break; | ||
442 | } | 392 | } |
443 | if (NULL == probe) | 393 | if (NULL == probe) |
444 | return 0; | 394 | return 0; |
@@ -447,11 +397,11 @@ static int ir_probe(struct i2c_adapter *adap) | |||
447 | c.adapter = adap; | 397 | c.adapter = adap; |
448 | for (i = 0; -1 != probe[i]; i++) { | 398 | for (i = 0; -1 != probe[i]; i++) { |
449 | c.addr = probe[i]; | 399 | c.addr = probe[i]; |
450 | rc = i2c_master_recv(&c,&buf,1); | 400 | rc = i2c_master_recv(&c,&buf,0); |
451 | dprintk(1,"probe 0x%02x @ %s: %s\n", | 401 | dprintk(1,"probe 0x%02x @ %s: %s\n", |
452 | probe[i], adap->name, | 402 | probe[i], adap->name, |
453 | (1 == rc) ? "yes" : "no"); | 403 | (0 == rc) ? "yes" : "no"); |
454 | if (1 == rc) { | 404 | if (0 == rc) { |
455 | ir_attach(adap,probe[i],0,0); | 405 | ir_attach(adap,probe[i],0,0); |
456 | break; | 406 | break; |
457 | } | 407 | } |
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index e75e7948fd9d..a23fb0338986 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c | |||
@@ -54,9 +54,41 @@ | |||
54 | #include <asm/pgtable.h> | 54 | #include <asm/pgtable.h> |
55 | 55 | ||
56 | #include <media/audiochip.h> | 56 | #include <media/audiochip.h> |
57 | #include <media/id.h> | ||
58 | #include "msp3400.h" | 57 | #include "msp3400.h" |
59 | 58 | ||
59 | #define msp3400_dbg(fmt, arg...) \ | ||
60 | do { \ | ||
61 | if (debug) \ | ||
62 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | ||
63 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
64 | } while (0) | ||
65 | |||
66 | /* Medium volume debug. */ | ||
67 | #define msp3400_dbg_mediumvol(fmt, arg...) \ | ||
68 | do { \ | ||
69 | if (debug >= 2) \ | ||
70 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | ||
71 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
72 | } while (0) | ||
73 | |||
74 | /* High volume debug. Use with care. */ | ||
75 | #define msp3400_dbg_highvol(fmt, arg...) \ | ||
76 | do { \ | ||
77 | if (debug >= 16) \ | ||
78 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | ||
79 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
80 | } while (0) | ||
81 | |||
82 | #define msp3400_err(fmt, arg...) do { \ | ||
83 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \ | ||
84 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
85 | #define msp3400_warn(fmt, arg...) do { \ | ||
86 | printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->name, \ | ||
87 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
88 | #define msp3400_info(fmt, arg...) do { \ | ||
89 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \ | ||
90 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
91 | |||
60 | #define OPMODE_AUTO -1 | 92 | #define OPMODE_AUTO -1 |
61 | #define OPMODE_MANUAL 0 | 93 | #define OPMODE_MANUAL 0 |
62 | #define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */ | 94 | #define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */ |
@@ -73,15 +105,26 @@ static int dolby = 0; | |||
73 | 105 | ||
74 | static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual | 106 | static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual |
75 | (msp34xxg only) 0x00a0-0x03c0 */ | 107 | (msp34xxg only) 0x00a0-0x03c0 */ |
108 | #define DFP_COUNT 0x41 | ||
109 | static const int bl_dfp[] = { | ||
110 | 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a, | ||
111 | 0x0b, 0x0d, 0x0e, 0x10 | ||
112 | }; | ||
113 | |||
114 | #define IS_MSP34XX_G(msp) ((msp)->opmode==2) | ||
76 | 115 | ||
77 | struct msp3400c { | 116 | struct msp3400c { |
78 | int rev1,rev2; | 117 | int rev1,rev2; |
79 | 118 | ||
80 | int opmode; | 119 | int opmode; |
120 | int nicam; | ||
81 | int mode; | 121 | int mode; |
82 | int norm; | 122 | int norm; |
123 | int stereo; | ||
83 | int nicam_on; | 124 | int nicam_on; |
84 | int acb; | 125 | int acb; |
126 | int in_scart; | ||
127 | int i2s_mode; | ||
85 | int main, second; /* sound carrier */ | 128 | int main, second; /* sound carrier */ |
86 | int input; | 129 | int input; |
87 | int source; /* see msp34xxg_set_source */ | 130 | int source; /* see msp34xxg_set_source */ |
@@ -91,9 +134,12 @@ struct msp3400c { | |||
91 | int rxsubchans; | 134 | int rxsubchans; |
92 | 135 | ||
93 | int muted; | 136 | int muted; |
94 | int volume, balance; | 137 | int left, right; /* volume */ |
95 | int bass, treble; | 138 | int bass, treble; |
96 | 139 | ||
140 | /* shadow register set */ | ||
141 | int dfp_regs[DFP_COUNT]; | ||
142 | |||
97 | /* thread */ | 143 | /* thread */ |
98 | struct task_struct *kthread; | 144 | struct task_struct *kthread; |
99 | wait_queue_head_t wq; | 145 | wait_queue_head_t wq; |
@@ -101,6 +147,8 @@ struct msp3400c { | |||
101 | int watch_stereo:1; | 147 | int watch_stereo:1; |
102 | }; | 148 | }; |
103 | 149 | ||
150 | #define MIN(a,b) (((a)>(b))?(b):(a)) | ||
151 | #define MAX(a,b) (((a)>(b))?(a):(b)) | ||
104 | #define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00) | 152 | #define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00) |
105 | #define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@') | 153 | #define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@') |
106 | #define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@') | 154 | #define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@') |
@@ -110,9 +158,6 @@ struct msp3400c { | |||
110 | 158 | ||
111 | /* ---------------------------------------------------------------------- */ | 159 | /* ---------------------------------------------------------------------- */ |
112 | 160 | ||
113 | #define dprintk if (debug >= 1) printk | ||
114 | #define d2printk if (debug >= 2) printk | ||
115 | |||
116 | /* read-only */ | 161 | /* read-only */ |
117 | module_param(opmode, int, 0444); | 162 | module_param(opmode, int, 0444); |
118 | 163 | ||
@@ -132,11 +177,6 @@ MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Defau | |||
132 | MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); | 177 | MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); |
133 | MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); | 178 | MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); |
134 | 179 | ||
135 | |||
136 | MODULE_DESCRIPTION("device driver for msp34xx TV sound processor"); | ||
137 | MODULE_AUTHOR("Gerd Knorr"); | ||
138 | MODULE_LICENSE("Dual BSD/GPL"); /* FreeBSD uses this too */ | ||
139 | |||
140 | /* ---------------------------------------------------------------------- */ | 180 | /* ---------------------------------------------------------------------- */ |
141 | 181 | ||
142 | #define I2C_MSP3400C 0x80 | 182 | #define I2C_MSP3400C 0x80 |
@@ -153,6 +193,10 @@ static unsigned short normal_i2c[] = { | |||
153 | }; | 193 | }; |
154 | I2C_CLIENT_INSMOD; | 194 | I2C_CLIENT_INSMOD; |
155 | 195 | ||
196 | MODULE_DESCRIPTION("device driver for msp34xx TV sound processor"); | ||
197 | MODULE_AUTHOR("Gerd Knorr"); | ||
198 | MODULE_LICENSE("GPL"); | ||
199 | |||
156 | /* ----------------------------------------------------------------------- */ | 200 | /* ----------------------------------------------------------------------- */ |
157 | /* functions for talking to the MSP3400C Sound processor */ | 201 | /* functions for talking to the MSP3400C Sound processor */ |
158 | 202 | ||
@@ -172,68 +216,73 @@ static int msp3400c_reset(struct i2c_client *client) | |||
172 | { client->addr, I2C_M_RD, 2, read }, | 216 | { client->addr, I2C_M_RD, 2, read }, |
173 | }; | 217 | }; |
174 | 218 | ||
219 | msp3400_dbg_highvol("msp3400c_reset\n"); | ||
175 | if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) || | 220 | if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) || |
176 | (1 != i2c_transfer(client->adapter,&reset[1],1)) || | 221 | (1 != i2c_transfer(client->adapter,&reset[1],1)) || |
177 | (2 != i2c_transfer(client->adapter,test,2)) ) { | 222 | (2 != i2c_transfer(client->adapter,test,2)) ) { |
178 | printk(KERN_ERR "msp3400: chip reset failed\n"); | 223 | msp3400_err("chip reset failed\n"); |
179 | return -1; | 224 | return -1; |
180 | } | 225 | } |
181 | return 0; | 226 | return 0; |
182 | } | 227 | } |
183 | 228 | ||
184 | static int | 229 | static int msp3400c_read(struct i2c_client *client, int dev, int addr) |
185 | msp3400c_read(struct i2c_client *client, int dev, int addr) | ||
186 | { | 230 | { |
187 | int err; | 231 | int err,retval; |
232 | |||
233 | unsigned char write[3]; | ||
234 | unsigned char read[2]; | ||
235 | struct i2c_msg msgs[2] = { | ||
236 | { client->addr, 0, 3, write }, | ||
237 | { client->addr, I2C_M_RD, 2, read } | ||
238 | }; | ||
188 | 239 | ||
189 | unsigned char write[3]; | 240 | write[0] = dev+1; |
190 | unsigned char read[2]; | 241 | write[1] = addr >> 8; |
191 | struct i2c_msg msgs[2] = { | 242 | write[2] = addr & 0xff; |
192 | { client->addr, 0, 3, write }, | ||
193 | { client->addr, I2C_M_RD, 2, read } | ||
194 | }; | ||
195 | write[0] = dev+1; | ||
196 | write[1] = addr >> 8; | ||
197 | write[2] = addr & 0xff; | ||
198 | 243 | ||
199 | for (err = 0; err < 3;) { | 244 | for (err = 0; err < 3;) { |
200 | if (2 == i2c_transfer(client->adapter,msgs,2)) | 245 | if (2 == i2c_transfer(client->adapter,msgs,2)) |
201 | break; | 246 | break; |
202 | err++; | 247 | err++; |
203 | printk(KERN_WARNING "msp34xx: I/O error #%d (read 0x%02x/0x%02x)\n", | 248 | msp3400_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err, |
204 | err, dev, addr); | 249 | dev, addr); |
205 | msleep(10); | 250 | current->state = TASK_INTERRUPTIBLE; |
251 | schedule_timeout(msecs_to_jiffies(10)); | ||
206 | } | 252 | } |
207 | if (3 == err) { | 253 | if (3 == err) { |
208 | printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n"); | 254 | msp3400_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n"); |
209 | msp3400c_reset(client); | 255 | msp3400c_reset(client); |
210 | return -1; | 256 | return -1; |
211 | } | 257 | } |
212 | return read[0] << 8 | read[1]; | 258 | retval = read[0] << 8 | read[1]; |
259 | msp3400_dbg_highvol("msp3400c_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval); | ||
260 | return retval; | ||
213 | } | 261 | } |
214 | 262 | ||
215 | static int | 263 | static int msp3400c_write(struct i2c_client *client, int dev, int addr, int val) |
216 | msp3400c_write(struct i2c_client *client, int dev, int addr, int val) | ||
217 | { | 264 | { |
218 | int err; | 265 | int err; |
219 | unsigned char buffer[5]; | 266 | unsigned char buffer[5]; |
220 | 267 | ||
221 | buffer[0] = dev; | 268 | buffer[0] = dev; |
222 | buffer[1] = addr >> 8; | 269 | buffer[1] = addr >> 8; |
223 | buffer[2] = addr & 0xff; | 270 | buffer[2] = addr & 0xff; |
224 | buffer[3] = val >> 8; | 271 | buffer[3] = val >> 8; |
225 | buffer[4] = val & 0xff; | 272 | buffer[4] = val & 0xff; |
226 | 273 | ||
274 | msp3400_dbg_highvol("msp3400c_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val); | ||
227 | for (err = 0; err < 3;) { | 275 | for (err = 0; err < 3;) { |
228 | if (5 == i2c_master_send(client, buffer, 5)) | 276 | if (5 == i2c_master_send(client, buffer, 5)) |
229 | break; | 277 | break; |
230 | err++; | 278 | err++; |
231 | printk(KERN_WARNING "msp34xx: I/O error #%d (write 0x%02x/0x%02x)\n", | 279 | msp3400_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err, |
232 | err, dev, addr); | 280 | dev, addr); |
233 | msleep(10); | 281 | current->state = TASK_INTERRUPTIBLE; |
282 | schedule_timeout(msecs_to_jiffies(10)); | ||
234 | } | 283 | } |
235 | if (3 == err) { | 284 | if (3 == err) { |
236 | printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n"); | 285 | msp3400_warn("giving up, reseting chip. Sound will go off, sorry folks :-|\n"); |
237 | msp3400c_reset(client); | 286 | msp3400c_reset(client); |
238 | return -1; | 287 | return -1; |
239 | } | 288 | } |
@@ -266,45 +315,47 @@ static struct MSP_INIT_DATA_DEM { | |||
266 | int dfp_src; | 315 | int dfp_src; |
267 | int dfp_matrix; | 316 | int dfp_matrix; |
268 | } msp_init_data[] = { | 317 | } msp_init_data[] = { |
269 | /* AM (for carrier detect / msp3400) */ | 318 | { /* AM (for carrier detect / msp3400) */ |
270 | { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 }, | 319 | {75, 19, 36, 35, 39, 40}, |
271 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | 320 | {75, 19, 36, 35, 39, 40}, |
272 | 0x00d0, 0x0500, 0x0020, 0x3000}, | 321 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), |
273 | 322 | 0x00d0, 0x0500, 0x0020, 0x3000 | |
274 | /* AM (for carrier detect / msp3410) */ | 323 | },{ /* AM (for carrier detect / msp3410) */ |
275 | { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 }, | 324 | {-1, -1, -8, 2, 59, 126}, |
276 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | 325 | {-1, -1, -8, 2, 59, 126}, |
277 | 0x00d0, 0x0100, 0x0020, 0x3000}, | 326 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), |
278 | 327 | 0x00d0, 0x0100, 0x0020, 0x3000 | |
279 | /* FM Radio */ | 328 | },{ /* FM Radio */ |
280 | { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 }, | 329 | {-8, -8, 4, 6, 78, 107}, |
281 | MSP_CARRIER(10.7), MSP_CARRIER(10.7), | 330 | {-8, -8, 4, 6, 78, 107}, |
282 | 0x00d0, 0x0480, 0x0020, 0x3000 }, | 331 | MSP_CARRIER(10.7), MSP_CARRIER(10.7), |
283 | 332 | 0x00d0, 0x0480, 0x0020, 0x3000 | |
284 | /* Terrestial FM-mono + FM-stereo */ | 333 | },{ /* Terrestial FM-mono + FM-stereo */ |
285 | { { 3, 18, 27, 48, 66, 72 }, { 3, 18, 27, 48, 66, 72 }, | 334 | {3, 18, 27, 48, 66, 72}, |
286 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | 335 | {3, 18, 27, 48, 66, 72}, |
287 | 0x00d0, 0x0480, 0x0030, 0x3000}, | 336 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), |
288 | 337 | 0x00d0, 0x0480, 0x0030, 0x3000 | |
289 | /* Sat FM-mono */ | 338 | },{ /* Sat FM-mono */ |
290 | { { 1, 9, 14, 24, 33, 37 }, { 3, 18, 27, 48, 66, 72 }, | 339 | { 1, 9, 14, 24, 33, 37}, |
291 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), | 340 | { 3, 18, 27, 48, 66, 72}, |
292 | 0x00c6, 0x0480, 0x0000, 0x3000}, | 341 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), |
293 | 342 | 0x00c6, 0x0480, 0x0000, 0x3000 | |
294 | /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */ | 343 | },{ /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */ |
295 | { { -2, -8, -10, 10, 50, 86 }, { 3, 18, 27, 48, 66, 72 }, | 344 | {-2, -8, -10, 10, 50, 86}, |
296 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | 345 | {3, 18, 27, 48, 66, 72}, |
297 | 0x00d0, 0x0040, 0x0120, 0x3000}, | 346 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), |
298 | 347 | 0x00d0, 0x0040, 0x0120, 0x3000 | |
299 | /* NICAM/FM -- I (6.0/6.552) */ | 348 | },{ /* NICAM/FM -- I (6.0/6.552) */ |
300 | { { 2, 4, -6, -4, 40, 94 }, { 3, 18, 27, 48, 66, 72 }, | 349 | {2, 4, -6, -4, 40, 94}, |
301 | MSP_CARRIER(6.0), MSP_CARRIER(6.0), | 350 | {3, 18, 27, 48, 66, 72}, |
302 | 0x00d0, 0x0040, 0x0120, 0x3000}, | 351 | MSP_CARRIER(6.0), MSP_CARRIER(6.0), |
303 | 352 | 0x00d0, 0x0040, 0x0120, 0x3000 | |
304 | /* NICAM/AM -- L (6.5/5.85) */ | 353 | },{ /* NICAM/AM -- L (6.5/5.85) */ |
305 | { { -2, -8, -10, 10, 50, 86 }, { -4, -12, -9, 23, 79, 126 }, | 354 | {-2, -8, -10, 10, 50, 86}, |
306 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), | 355 | {-4, -12, -9, 23, 79, 126}, |
307 | 0x00c6, 0x0140, 0x0120, 0x7c03}, | 356 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), |
357 | 0x00c6, 0x0140, 0x0120, 0x7c03 | ||
358 | }, | ||
308 | }; | 359 | }; |
309 | 360 | ||
310 | struct CARRIER_DETECT { | 361 | struct CARRIER_DETECT { |
@@ -338,32 +389,68 @@ static struct CARRIER_DETECT carrier_detect_65[] = { | |||
338 | 389 | ||
339 | #define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT)) | 390 | #define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT)) |
340 | 391 | ||
341 | /* ----------------------------------------------------------------------- */ | 392 | /* ----------------------------------------------------------------------- * |
393 | * bits 9 8 5 - SCART DSP input Select: | ||
394 | * 0 0 0 - SCART 1 to DSP input (reset position) | ||
395 | * 0 1 0 - MONO to DSP input | ||
396 | * 1 0 0 - SCART 2 to DSP input | ||
397 | * 1 1 1 - Mute DSP input | ||
398 | * | ||
399 | * bits 11 10 6 - SCART 1 Output Select: | ||
400 | * 0 0 0 - undefined (reset position) | ||
401 | * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS) | ||
402 | * 1 0 0 - MONO input to SCART 1 Output | ||
403 | * 1 1 0 - SCART 1 DA to SCART 1 Output | ||
404 | * 0 0 1 - SCART 2 DA to SCART 1 Output | ||
405 | * 0 1 1 - SCART 1 Input to SCART 1 Output | ||
406 | * 1 1 1 - Mute SCART 1 Output | ||
407 | * | ||
408 | * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART): | ||
409 | * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position) | ||
410 | * 0 1 0 - SCART 1 Input to SCART 2 Output | ||
411 | * 1 0 0 - MONO input to SCART 2 Output | ||
412 | * 0 0 1 - SCART 2 DA to SCART 2 Output | ||
413 | * 0 1 1 - SCART 2 Input to SCART 2 Output | ||
414 | * 1 1 0 - Mute SCART 2 Output | ||
415 | * | ||
416 | * Bits 4 to 0 should be zero. | ||
417 | * ----------------------------------------------------------------------- */ | ||
342 | 418 | ||
343 | static int scarts[3][9] = { | 419 | static int scarts[3][9] = { |
344 | /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ | 420 | /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ |
345 | { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, | 421 | /* SCART DSP Input select */ |
346 | { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, | 422 | { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, |
347 | { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, | 423 | /* SCART1 Output select */ |
424 | { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, | ||
425 | /* SCART2 Output select */ | ||
426 | { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, | ||
348 | }; | 427 | }; |
349 | 428 | ||
350 | static char *scart_names[] = { | 429 | static char *scart_names[] = { |
351 | "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" | 430 | "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" |
352 | }; | 431 | }; |
353 | 432 | ||
354 | static void | 433 | static void msp3400c_set_scart(struct i2c_client *client, int in, int out) |
355 | msp3400c_set_scart(struct i2c_client *client, int in, int out) | ||
356 | { | 434 | { |
357 | struct msp3400c *msp = i2c_get_clientdata(client); | 435 | struct msp3400c *msp = i2c_get_clientdata(client); |
358 | 436 | ||
359 | if (-1 == scarts[out][in]) | 437 | msp->in_scart=in; |
360 | return; | 438 | |
439 | if (in >= 1 && in <= 8 && out >= 0 && out <= 2) { | ||
440 | if (-1 == scarts[out][in]) | ||
441 | return; | ||
361 | 442 | ||
362 | dprintk(KERN_DEBUG | 443 | msp->acb &= ~scarts[out][SCART_MASK]; |
363 | "msp34xx: scart switch: %s => %d\n",scart_names[in],out); | 444 | msp->acb |= scarts[out][in]; |
364 | msp->acb &= ~scarts[out][SCART_MASK]; | 445 | } else |
365 | msp->acb |= scarts[out][in]; | 446 | msp->acb = 0xf60; /* Mute Input and SCART 1 Output */ |
366 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb); | 447 | |
448 | msp3400_dbg("scart switch: %s => %d (ACB=0x%04x)\n", | ||
449 | scart_names[in], out, msp->acb); | ||
450 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb); | ||
451 | |||
452 | /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */ | ||
453 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); | ||
367 | } | 454 | } |
368 | 455 | ||
369 | /* ------------------------------------------------------------------------ */ | 456 | /* ------------------------------------------------------------------------ */ |
@@ -378,33 +465,34 @@ static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2) | |||
378 | } | 465 | } |
379 | 466 | ||
380 | static void msp3400c_setvolume(struct i2c_client *client, | 467 | static void msp3400c_setvolume(struct i2c_client *client, |
381 | int muted, int volume, int balance) | 468 | int muted, int left, int right) |
382 | { | 469 | { |
383 | int val = 0, bal = 0; | 470 | int vol = 0, val = 0, balance = 0; |
384 | 471 | ||
385 | if (!muted) { | 472 | if (!muted) { |
386 | /* 0x7f instead if 0x73 here has sound quality issues, | 473 | /* 0x7f instead if 0x73 here has sound quality issues, |
387 | * probably due to overmodulation + clipping ... */ | 474 | * probably due to overmodulation + clipping ... */ |
388 | val = (volume * 0x73 / 65535) << 8; | 475 | vol = (left > right) ? left : right; |
476 | val = (vol * 0x73 / 65535) << 8; | ||
389 | } | 477 | } |
390 | if (val) { | 478 | if (vol > 0) { |
391 | bal = (balance / 256) - 128; | 479 | balance = ((right - left) * 127) / vol; |
392 | } | 480 | } |
393 | dprintk(KERN_DEBUG | 481 | |
394 | "msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", | 482 | msp3400_dbg("setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", |
395 | muted ? "on" : "off", volume, balance, val>>8, bal); | 483 | muted ? "on" : "off", left, right, val >> 8, balance); |
396 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ | 484 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ |
397 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ | 485 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ |
398 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, | 486 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, |
399 | muted ? 0x01 : (val | 0x01)); | 487 | muted ? 0x1 : (val | 0x1)); |
400 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, bal << 8); | 488 | msp3400c_write(client, I2C_MSP3400C_DFP, 0x0001, balance << 8); |
401 | } | 489 | } |
402 | 490 | ||
403 | static void msp3400c_setbass(struct i2c_client *client, int bass) | 491 | static void msp3400c_setbass(struct i2c_client *client, int bass) |
404 | { | 492 | { |
405 | int val = ((bass-32768) * 0x60 / 65535) << 8; | 493 | int val = ((bass-32768) * 0x60 / 65535) << 8; |
406 | 494 | ||
407 | dprintk(KERN_DEBUG "msp34xx: setbass: %d 0x%02x\n",bass, val>>8); | 495 | msp3400_dbg("setbass: %d 0x%02x\n", bass, val >> 8); |
408 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ | 496 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ |
409 | } | 497 | } |
410 | 498 | ||
@@ -412,7 +500,7 @@ static void msp3400c_settreble(struct i2c_client *client, int treble) | |||
412 | { | 500 | { |
413 | int val = ((treble-32768) * 0x60 / 65535) << 8; | 501 | int val = ((treble-32768) * 0x60 / 65535) << 8; |
414 | 502 | ||
415 | dprintk(KERN_DEBUG "msp34xx: settreble: %d 0x%02x\n",treble, val>>8); | 503 | msp3400_dbg("settreble: %d 0x%02x\n",treble, val>>8); |
416 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ | 504 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ |
417 | } | 505 | } |
418 | 506 | ||
@@ -421,7 +509,7 @@ static void msp3400c_setmode(struct i2c_client *client, int type) | |||
421 | struct msp3400c *msp = i2c_get_clientdata(client); | 509 | struct msp3400c *msp = i2c_get_clientdata(client); |
422 | int i; | 510 | int i; |
423 | 511 | ||
424 | dprintk(KERN_DEBUG "msp3400: setmode: %d\n",type); | 512 | msp3400_dbg("setmode: %d\n",type); |
425 | msp->mode = type; | 513 | msp->mode = type; |
426 | msp->audmode = V4L2_TUNER_MODE_MONO; | 514 | msp->audmode = V4L2_TUNER_MODE_MONO; |
427 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; | 515 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; |
@@ -474,7 +562,8 @@ static void msp3400c_setmode(struct i2c_client *client, int type) | |||
474 | } | 562 | } |
475 | } | 563 | } |
476 | 564 | ||
477 | static int best_audio_mode(int rxsubchans) | 565 | /* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */ |
566 | static int best_video_sound(int rxsubchans) | ||
478 | { | 567 | { |
479 | if (rxsubchans & V4L2_TUNER_SUB_STEREO) | 568 | if (rxsubchans & V4L2_TUNER_SUB_STEREO) |
480 | return V4L2_TUNER_MODE_STEREO; | 569 | return V4L2_TUNER_MODE_STEREO; |
@@ -486,31 +575,31 @@ static int best_audio_mode(int rxsubchans) | |||
486 | } | 575 | } |
487 | 576 | ||
488 | /* turn on/off nicam + stereo */ | 577 | /* turn on/off nicam + stereo */ |
489 | static void msp3400c_set_audmode(struct i2c_client *client, int audmode) | 578 | static void msp3400c_setstereo(struct i2c_client *client, int mode) |
490 | { | 579 | { |
491 | static char *strmode[16] = { | 580 | static char *strmode[] = { "0", "mono", "stereo", "3", |
492 | #if __GNUC__ >= 3 | 581 | "lang1", "5", "6", "7", "lang2" |
493 | [ 0 ... 15 ] = "invalid", | ||
494 | #endif | ||
495 | [ V4L2_TUNER_MODE_MONO ] = "mono", | ||
496 | [ V4L2_TUNER_MODE_STEREO ] = "stereo", | ||
497 | [ V4L2_TUNER_MODE_LANG1 ] = "lang1", | ||
498 | [ V4L2_TUNER_MODE_LANG2 ] = "lang2", | ||
499 | }; | 582 | }; |
500 | struct msp3400c *msp = i2c_get_clientdata(client); | 583 | struct msp3400c *msp = i2c_get_clientdata(client); |
501 | int nicam=0; /* channel source: FM/AM or nicam */ | 584 | int nicam = 0; /* channel source: FM/AM or nicam */ |
502 | int src=0; | 585 | int src = 0; |
503 | 586 | ||
504 | BUG_ON(msp->opmode == OPMODE_SIMPLER); | 587 | if (IS_MSP34XX_G(msp)) { |
505 | msp->audmode = audmode; | 588 | /* this method would break everything, let's make sure |
589 | * it's never called | ||
590 | */ | ||
591 | msp3400_dbg | ||
592 | ("DEBUG WARNING setstereo called with mode=%d instead of set_source (ignored)\n", | ||
593 | mode); | ||
594 | return; | ||
595 | } | ||
506 | 596 | ||
507 | /* switch demodulator */ | 597 | /* switch demodulator */ |
508 | switch (msp->mode) { | 598 | switch (msp->mode) { |
509 | case MSP_MODE_FM_TERRA: | 599 | case MSP_MODE_FM_TERRA: |
510 | dprintk(KERN_DEBUG "msp3400: FM setstereo: %s\n", | 600 | msp3400_dbg("FM setstereo: %s\n", strmode[mode]); |
511 | strmode[audmode]); | ||
512 | msp3400c_setcarrier(client,msp->second,msp->main); | 601 | msp3400c_setcarrier(client,msp->second,msp->main); |
513 | switch (audmode) { | 602 | switch (mode) { |
514 | case V4L2_TUNER_MODE_STEREO: | 603 | case V4L2_TUNER_MODE_STEREO: |
515 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001); | 604 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001); |
516 | break; | 605 | break; |
@@ -522,9 +611,8 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode) | |||
522 | } | 611 | } |
523 | break; | 612 | break; |
524 | case MSP_MODE_FM_SAT: | 613 | case MSP_MODE_FM_SAT: |
525 | dprintk(KERN_DEBUG "msp3400: SAT setstereo: %s\n", | 614 | msp3400_dbg("SAT setstereo: %s\n", strmode[mode]); |
526 | strmode[audmode]); | 615 | switch (mode) { |
527 | switch (audmode) { | ||
528 | case V4L2_TUNER_MODE_MONO: | 616 | case V4L2_TUNER_MODE_MONO: |
529 | msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); | 617 | msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); |
530 | break; | 618 | break; |
@@ -542,39 +630,35 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode) | |||
542 | case MSP_MODE_FM_NICAM1: | 630 | case MSP_MODE_FM_NICAM1: |
543 | case MSP_MODE_FM_NICAM2: | 631 | case MSP_MODE_FM_NICAM2: |
544 | case MSP_MODE_AM_NICAM: | 632 | case MSP_MODE_AM_NICAM: |
545 | dprintk(KERN_DEBUG "msp3400: NICAM setstereo: %s\n", | 633 | msp3400_dbg("NICAM setstereo: %s\n",strmode[mode]); |
546 | strmode[audmode]); | ||
547 | msp3400c_setcarrier(client,msp->second,msp->main); | 634 | msp3400c_setcarrier(client,msp->second,msp->main); |
548 | if (msp->nicam_on) | 635 | if (msp->nicam_on) |
549 | nicam=0x0100; | 636 | nicam=0x0100; |
550 | break; | 637 | break; |
551 | case MSP_MODE_BTSC: | 638 | case MSP_MODE_BTSC: |
552 | dprintk(KERN_DEBUG "msp3400: BTSC setstereo: %s\n", | 639 | msp3400_dbg("BTSC setstereo: %s\n",strmode[mode]); |
553 | strmode[audmode]); | ||
554 | nicam=0x0300; | 640 | nicam=0x0300; |
555 | break; | 641 | break; |
556 | case MSP_MODE_EXTERN: | 642 | case MSP_MODE_EXTERN: |
557 | dprintk(KERN_DEBUG "msp3400: extern setstereo: %s\n", | 643 | msp3400_dbg("extern setstereo: %s\n",strmode[mode]); |
558 | strmode[audmode]); | ||
559 | nicam = 0x0200; | 644 | nicam = 0x0200; |
560 | break; | 645 | break; |
561 | case MSP_MODE_FM_RADIO: | 646 | case MSP_MODE_FM_RADIO: |
562 | dprintk(KERN_DEBUG "msp3400: FM-Radio setstereo: %s\n", | 647 | msp3400_dbg("FM-Radio setstereo: %s\n",strmode[mode]); |
563 | strmode[audmode]); | ||
564 | break; | 648 | break; |
565 | default: | 649 | default: |
566 | dprintk(KERN_DEBUG "msp3400: mono setstereo\n"); | 650 | msp3400_dbg("mono setstereo\n"); |
567 | return; | 651 | return; |
568 | } | 652 | } |
569 | 653 | ||
570 | /* switch audio */ | 654 | /* switch audio */ |
571 | switch (audmode) { | 655 | switch (best_video_sound(mode)) { |
572 | case V4L2_TUNER_MODE_STEREO: | 656 | case V4L2_TUNER_MODE_STEREO: |
573 | src = 0x0020 | nicam; | 657 | src = 0x0020 | nicam; |
574 | break; | 658 | break; |
575 | case V4L2_TUNER_MODE_MONO: | 659 | case V4L2_TUNER_MODE_MONO: |
576 | if (msp->mode == MSP_MODE_AM_NICAM) { | 660 | if (msp->mode == MSP_MODE_AM_NICAM) { |
577 | dprintk("msp3400: switching to AM mono\n"); | 661 | msp3400_dbg("switching to AM mono\n"); |
578 | /* AM mono decoding is handled by tuner, not MSP chip */ | 662 | /* AM mono decoding is handled by tuner, not MSP chip */ |
579 | /* SCART switching control register */ | 663 | /* SCART switching control register */ |
580 | msp3400c_set_scart(client,SCART_MONO,0); | 664 | msp3400c_set_scart(client,SCART_MONO,0); |
@@ -588,8 +672,7 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode) | |||
588 | src = 0x0010 | nicam; | 672 | src = 0x0010 | nicam; |
589 | break; | 673 | break; |
590 | } | 674 | } |
591 | dprintk(KERN_DEBUG | 675 | msp3400_dbg("setstereo final source/matrix = 0x%x\n", src); |
592 | "msp3400: setstereo final source/matrix = 0x%x\n", src); | ||
593 | 676 | ||
594 | if (dolby) { | 677 | if (dolby) { |
595 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); | 678 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); |
@@ -605,29 +688,55 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode) | |||
605 | } | 688 | } |
606 | 689 | ||
607 | static void | 690 | static void |
608 | msp3400c_print_mode(struct msp3400c *msp) | 691 | msp3400c_print_mode(struct i2c_client *client) |
609 | { | 692 | { |
693 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
694 | |||
610 | if (msp->main == msp->second) { | 695 | if (msp->main == msp->second) { |
611 | printk(KERN_DEBUG "msp3400: mono sound carrier: %d.%03d MHz\n", | 696 | msp3400_dbg("mono sound carrier: %d.%03d MHz\n", |
612 | msp->main/910000,(msp->main/910)%1000); | 697 | msp->main/910000,(msp->main/910)%1000); |
613 | } else { | 698 | } else { |
614 | printk(KERN_DEBUG "msp3400: main sound carrier: %d.%03d MHz\n", | 699 | msp3400_dbg("main sound carrier: %d.%03d MHz\n", |
615 | msp->main/910000,(msp->main/910)%1000); | 700 | msp->main/910000,(msp->main/910)%1000); |
616 | } | 701 | } |
617 | if (msp->mode == MSP_MODE_FM_NICAM1 || | 702 | if (msp->mode == MSP_MODE_FM_NICAM1 || msp->mode == MSP_MODE_FM_NICAM2) |
618 | msp->mode == MSP_MODE_FM_NICAM2) | 703 | msp3400_dbg("NICAM/FM carrier : %d.%03d MHz\n", |
619 | printk(KERN_DEBUG "msp3400: NICAM/FM carrier : %d.%03d MHz\n", | ||
620 | msp->second/910000,(msp->second/910)%1000); | 704 | msp->second/910000,(msp->second/910)%1000); |
621 | if (msp->mode == MSP_MODE_AM_NICAM) | 705 | if (msp->mode == MSP_MODE_AM_NICAM) |
622 | printk(KERN_DEBUG "msp3400: NICAM/AM carrier : %d.%03d MHz\n", | 706 | msp3400_dbg("NICAM/AM carrier : %d.%03d MHz\n", |
623 | msp->second/910000,(msp->second/910)%1000); | 707 | msp->second/910000,(msp->second/910)%1000); |
624 | if (msp->mode == MSP_MODE_FM_TERRA && | 708 | if (msp->mode == MSP_MODE_FM_TERRA && |
625 | msp->main != msp->second) { | 709 | msp->main != msp->second) { |
626 | printk(KERN_DEBUG "msp3400: FM-stereo carrier : %d.%03d MHz\n", | 710 | msp3400_dbg("FM-stereo carrier : %d.%03d MHz\n", |
627 | msp->second/910000,(msp->second/910)%1000); | 711 | msp->second/910000,(msp->second/910)%1000); |
628 | } | 712 | } |
629 | } | 713 | } |
630 | 714 | ||
715 | #define MSP3400_MAX 4 | ||
716 | static struct i2c_client *msps[MSP3400_MAX]; | ||
717 | static void msp3400c_restore_dfp(struct i2c_client *client) | ||
718 | { | ||
719 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
720 | int i; | ||
721 | |||
722 | for (i = 0; i < DFP_COUNT; i++) { | ||
723 | if (-1 == msp->dfp_regs[i]) | ||
724 | continue; | ||
725 | msp3400c_write(client, I2C_MSP3400C_DFP, i, msp->dfp_regs[i]); | ||
726 | } | ||
727 | } | ||
728 | |||
729 | /* if the dfp_regs is set, set what's in there. Otherwise, set the default value */ | ||
730 | static int msp3400c_write_dfp_with_default(struct i2c_client *client, | ||
731 | int addr, int default_value) | ||
732 | { | ||
733 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
734 | int value = default_value; | ||
735 | if (addr < DFP_COUNT && -1 != msp->dfp_regs[addr]) | ||
736 | value = msp->dfp_regs[addr]; | ||
737 | return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value); | ||
738 | } | ||
739 | |||
631 | /* ----------------------------------------------------------------------- */ | 740 | /* ----------------------------------------------------------------------- */ |
632 | 741 | ||
633 | struct REGISTER_DUMP { | 742 | struct REGISTER_DUMP { |
@@ -635,8 +744,15 @@ struct REGISTER_DUMP { | |||
635 | char *name; | 744 | char *name; |
636 | }; | 745 | }; |
637 | 746 | ||
638 | static int | 747 | struct REGISTER_DUMP d1[] = { |
639 | autodetect_stereo(struct i2c_client *client) | 748 | {0x007e, "autodetect"}, |
749 | {0x0023, "C_AD_BITS "}, | ||
750 | {0x0038, "ADD_BITS "}, | ||
751 | {0x003e, "CIB_BITS "}, | ||
752 | {0x0057, "ERROR_RATE"}, | ||
753 | }; | ||
754 | |||
755 | static int autodetect_stereo(struct i2c_client *client) | ||
640 | { | 756 | { |
641 | struct msp3400c *msp = i2c_get_clientdata(client); | 757 | struct msp3400c *msp = i2c_get_clientdata(client); |
642 | int val; | 758 | int val; |
@@ -649,8 +765,7 @@ autodetect_stereo(struct i2c_client *client) | |||
649 | val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18); | 765 | val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18); |
650 | if (val > 32767) | 766 | if (val > 32767) |
651 | val -= 65536; | 767 | val -= 65536; |
652 | dprintk(KERN_DEBUG | 768 | msp3400_dbg("stereo detect register: %d\n",val); |
653 | "msp34xx: stereo detect register: %d\n",val); | ||
654 | if (val > 4096) { | 769 | if (val > 4096) { |
655 | rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; | 770 | rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; |
656 | } else if (val < -4096) { | 771 | } else if (val < -4096) { |
@@ -664,8 +779,7 @@ autodetect_stereo(struct i2c_client *client) | |||
664 | case MSP_MODE_FM_NICAM2: | 779 | case MSP_MODE_FM_NICAM2: |
665 | case MSP_MODE_AM_NICAM: | 780 | case MSP_MODE_AM_NICAM: |
666 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23); | 781 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23); |
667 | dprintk(KERN_DEBUG | 782 | msp3400_dbg("nicam sync=%d, mode=%d\n", |
668 | "msp34xx: nicam sync=%d, mode=%d\n", | ||
669 | val & 1, (val & 0x1e) >> 1); | 783 | val & 1, (val & 0x1e) >> 1); |
670 | 784 | ||
671 | if (val & 1) { | 785 | if (val & 1) { |
@@ -698,8 +812,7 @@ autodetect_stereo(struct i2c_client *client) | |||
698 | break; | 812 | break; |
699 | case MSP_MODE_BTSC: | 813 | case MSP_MODE_BTSC: |
700 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200); | 814 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200); |
701 | dprintk(KERN_DEBUG | 815 | msp3400_dbg("status=0x%x (pri=%s, sec=%s, %s%s%s)\n", |
702 | "msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n", | ||
703 | val, | 816 | val, |
704 | (val & 0x0002) ? "no" : "yes", | 817 | (val & 0x0002) ? "no" : "yes", |
705 | (val & 0x0004) ? "no" : "yes", | 818 | (val & 0x0004) ? "no" : "yes", |
@@ -713,13 +826,13 @@ autodetect_stereo(struct i2c_client *client) | |||
713 | } | 826 | } |
714 | if (rxsubchans != msp->rxsubchans) { | 827 | if (rxsubchans != msp->rxsubchans) { |
715 | update = 1; | 828 | update = 1; |
716 | dprintk(KERN_DEBUG "msp34xx: watch: rxsubchans %d => %d\n", | 829 | msp3400_dbg("watch: rxsubchans %d => %d\n", |
717 | msp->rxsubchans,rxsubchans); | 830 | msp->rxsubchans,rxsubchans); |
718 | msp->rxsubchans = rxsubchans; | 831 | msp->rxsubchans = rxsubchans; |
719 | } | 832 | } |
720 | if (newnicam != msp->nicam_on) { | 833 | if (newnicam != msp->nicam_on) { |
721 | update = 1; | 834 | update = 1; |
722 | dprintk(KERN_DEBUG "msp34xx: watch: nicam %d => %d\n", | 835 | msp3400_dbg("watch: nicam %d => %d\n", |
723 | msp->nicam_on,newnicam); | 836 | msp->nicam_on,newnicam); |
724 | msp->nicam_on = newnicam; | 837 | msp->nicam_on = newnicam; |
725 | } | 838 | } |
@@ -756,8 +869,15 @@ static void watch_stereo(struct i2c_client *client) | |||
756 | { | 869 | { |
757 | struct msp3400c *msp = i2c_get_clientdata(client); | 870 | struct msp3400c *msp = i2c_get_clientdata(client); |
758 | 871 | ||
759 | if (autodetect_stereo(client)) | 872 | if (autodetect_stereo(client)) { |
760 | msp3400c_set_audmode(client,best_audio_mode(msp->rxsubchans)); | 873 | if (msp->stereo & V4L2_TUNER_MODE_STEREO) |
874 | msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO); | ||
875 | else if (msp->stereo & VIDEO_SOUND_LANG1) | ||
876 | msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1); | ||
877 | else | ||
878 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
879 | } | ||
880 | |||
761 | if (once) | 881 | if (once) |
762 | msp->watch_stereo = 0; | 882 | msp->watch_stereo = 0; |
763 | } | 883 | } |
@@ -769,14 +889,14 @@ static int msp3400c_thread(void *data) | |||
769 | struct CARRIER_DETECT *cd; | 889 | struct CARRIER_DETECT *cd; |
770 | int count, max1,max2,val1,val2, val,this; | 890 | int count, max1,max2,val1,val2, val,this; |
771 | 891 | ||
772 | printk("msp3400: kthread started\n"); | 892 | msp3400_info("msp3400 daemon started\n"); |
773 | for (;;) { | 893 | for (;;) { |
774 | d2printk("msp3400: thread: sleep\n"); | 894 | msp3400_dbg_mediumvol("msp3400 thread: sleep\n"); |
775 | msp34xx_sleep(msp,-1); | 895 | msp34xx_sleep(msp,-1); |
776 | d2printk("msp3400: thread: wakeup\n"); | 896 | msp3400_dbg_mediumvol("msp3400 thread: wakeup\n"); |
777 | 897 | ||
778 | restart: | 898 | restart: |
779 | dprintk("msp3410: thread: restart scan\n"); | 899 | msp3400_dbg("thread: restart scan\n"); |
780 | msp->restart = 0; | 900 | msp->restart = 0; |
781 | if (kthread_should_stop()) | 901 | if (kthread_should_stop()) |
782 | break; | 902 | break; |
@@ -784,9 +904,8 @@ static int msp3400c_thread(void *data) | |||
784 | if (VIDEO_MODE_RADIO == msp->norm || | 904 | if (VIDEO_MODE_RADIO == msp->norm || |
785 | MSP_MODE_EXTERN == msp->mode) { | 905 | MSP_MODE_EXTERN == msp->mode) { |
786 | /* no carrier scan, just unmute */ | 906 | /* no carrier scan, just unmute */ |
787 | printk("msp3400: thread: no carrier scan\n"); | 907 | msp3400_info("thread: no carrier scan\n"); |
788 | msp3400c_setvolume(client, msp->muted, | 908 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
789 | msp->volume, msp->balance); | ||
790 | continue; | 909 | continue; |
791 | } | 910 | } |
792 | 911 | ||
@@ -802,13 +921,14 @@ static int msp3400c_thread(void *data) | |||
802 | goto restart; | 921 | goto restart; |
803 | 922 | ||
804 | /* carrier detect pass #1 -- main carrier */ | 923 | /* carrier detect pass #1 -- main carrier */ |
805 | cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main); | 924 | cd = carrier_detect_main; |
925 | count = CARRIER_COUNT(carrier_detect_main); | ||
806 | 926 | ||
807 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { | 927 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { |
808 | /* autodetect doesn't work well with AM ... */ | 928 | /* autodetect doesn't work well with AM ... */ |
809 | max1 = 3; | 929 | max1 = 3; |
810 | count = 0; | 930 | count = 0; |
811 | dprintk("msp3400: AM sound override\n"); | 931 | msp3400_dbg("AM sound override\n"); |
812 | } | 932 | } |
813 | 933 | ||
814 | for (this = 0; this < count; this++) { | 934 | for (this = 0; this < count; this++) { |
@@ -820,7 +940,7 @@ static int msp3400c_thread(void *data) | |||
820 | val -= 65536; | 940 | val -= 65536; |
821 | if (val1 < val) | 941 | if (val1 < val) |
822 | val1 = val, max1 = this; | 942 | val1 = val, max1 = this; |
823 | dprintk("msp3400: carrier1 val: %5d / %s\n", val,cd[this].name); | 943 | msp3400_dbg("carrier1 val: %5d / %s\n", val,cd[this].name); |
824 | } | 944 | } |
825 | 945 | ||
826 | /* carrier detect pass #2 -- second (stereo) carrier */ | 946 | /* carrier detect pass #2 -- second (stereo) carrier */ |
@@ -836,13 +956,16 @@ static int msp3400c_thread(void *data) | |||
836 | case 0: /* 4.5 */ | 956 | case 0: /* 4.5 */ |
837 | case 2: /* 6.0 */ | 957 | case 2: /* 6.0 */ |
838 | default: | 958 | default: |
839 | cd = NULL; count = 0; | 959 | cd = NULL; |
960 | count = 0; | ||
840 | break; | 961 | break; |
841 | } | 962 | } |
842 | 963 | ||
843 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { | 964 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { |
844 | /* autodetect doesn't work well with AM ... */ | 965 | /* autodetect doesn't work well with AM ... */ |
845 | cd = NULL; count = 0; max2 = 0; | 966 | cd = NULL; |
967 | count = 0; | ||
968 | max2 = 0; | ||
846 | } | 969 | } |
847 | for (this = 0; this < count; this++) { | 970 | for (this = 0; this < count; this++) { |
848 | msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); | 971 | msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); |
@@ -853,7 +976,7 @@ static int msp3400c_thread(void *data) | |||
853 | val -= 65536; | 976 | val -= 65536; |
854 | if (val2 < val) | 977 | if (val2 < val) |
855 | val2 = val, max2 = this; | 978 | val2 = val, max2 = this; |
856 | dprintk("msp3400: carrier2 val: %5d / %s\n", val,cd[this].name); | 979 | msp3400_dbg("carrier2 val: %5d / %s\n", val,cd[this].name); |
857 | } | 980 | } |
858 | 981 | ||
859 | /* programm the msp3400 according to the results */ | 982 | /* programm the msp3400 according to the results */ |
@@ -865,7 +988,7 @@ static int msp3400c_thread(void *data) | |||
865 | msp->second = carrier_detect_55[max2].cdo; | 988 | msp->second = carrier_detect_55[max2].cdo; |
866 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | 989 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); |
867 | msp->nicam_on = 0; | 990 | msp->nicam_on = 0; |
868 | msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); | 991 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); |
869 | msp->watch_stereo = 1; | 992 | msp->watch_stereo = 1; |
870 | } else if (max2 == 1 && HAVE_NICAM(msp)) { | 993 | } else if (max2 == 1 && HAVE_NICAM(msp)) { |
871 | /* B/G NICAM */ | 994 | /* B/G NICAM */ |
@@ -892,7 +1015,7 @@ static int msp3400c_thread(void *data) | |||
892 | msp->second = carrier_detect_65[max2].cdo; | 1015 | msp->second = carrier_detect_65[max2].cdo; |
893 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | 1016 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); |
894 | msp->nicam_on = 0; | 1017 | msp->nicam_on = 0; |
895 | msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); | 1018 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); |
896 | msp->watch_stereo = 1; | 1019 | msp->watch_stereo = 1; |
897 | } else if (max2 == 0 && | 1020 | } else if (max2 == 0 && |
898 | msp->norm == VIDEO_MODE_SECAM) { | 1021 | msp->norm == VIDEO_MODE_SECAM) { |
@@ -900,7 +1023,7 @@ static int msp3400c_thread(void *data) | |||
900 | msp->second = carrier_detect_65[max2].cdo; | 1023 | msp->second = carrier_detect_65[max2].cdo; |
901 | msp3400c_setmode(client, MSP_MODE_AM_NICAM); | 1024 | msp3400c_setmode(client, MSP_MODE_AM_NICAM); |
902 | msp->nicam_on = 0; | 1025 | msp->nicam_on = 0; |
903 | msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); | 1026 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); |
904 | msp3400c_setcarrier(client, msp->second, msp->main); | 1027 | msp3400c_setcarrier(client, msp->second, msp->main); |
905 | /* volume prescale for SCART (AM mono input) */ | 1028 | /* volume prescale for SCART (AM mono input) */ |
906 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900); | 1029 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900); |
@@ -924,15 +1047,16 @@ static int msp3400c_thread(void *data) | |||
924 | msp->nicam_on = 0; | 1047 | msp->nicam_on = 0; |
925 | msp3400c_setcarrier(client, msp->second, msp->main); | 1048 | msp3400c_setcarrier(client, msp->second, msp->main); |
926 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; | 1049 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; |
927 | msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); | 1050 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); |
928 | break; | 1051 | break; |
929 | } | 1052 | } |
930 | 1053 | ||
931 | /* unmute */ | 1054 | /* unmute */ |
932 | msp3400c_setvolume(client, msp->muted, | 1055 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
933 | msp->volume, msp->balance); | 1056 | msp3400c_restore_dfp(client); |
1057 | |||
934 | if (debug) | 1058 | if (debug) |
935 | msp3400c_print_mode(msp); | 1059 | msp3400c_print_mode(client); |
936 | 1060 | ||
937 | /* monitor tv audio mode */ | 1061 | /* monitor tv audio mode */ |
938 | while (msp->watch_stereo) { | 1062 | while (msp->watch_stereo) { |
@@ -941,7 +1065,7 @@ static int msp3400c_thread(void *data) | |||
941 | watch_stereo(client); | 1065 | watch_stereo(client); |
942 | } | 1066 | } |
943 | } | 1067 | } |
944 | dprintk(KERN_DEBUG "msp3400: thread: exit\n"); | 1068 | msp3400_dbg("thread: exit\n"); |
945 | return 0; | 1069 | return 0; |
946 | } | 1070 | } |
947 | 1071 | ||
@@ -985,10 +1109,12 @@ static inline const char *msp34xx_standard_mode_name(int mode) | |||
985 | return "unknown"; | 1109 | return "unknown"; |
986 | } | 1110 | } |
987 | 1111 | ||
988 | static int msp34xx_modus(int norm) | 1112 | static int msp34xx_modus(struct i2c_client *client, int norm) |
989 | { | 1113 | { |
990 | switch (norm) { | 1114 | switch (norm) { |
991 | case VIDEO_MODE_PAL: | 1115 | case VIDEO_MODE_PAL: |
1116 | msp3400_dbg("video mode selected to PAL\n"); | ||
1117 | |||
992 | #if 1 | 1118 | #if 1 |
993 | /* experimental: not sure this works with all chip versions */ | 1119 | /* experimental: not sure this works with all chip versions */ |
994 | return 0x7003; | 1120 | return 0x7003; |
@@ -997,12 +1123,16 @@ static int msp34xx_modus(int norm) | |||
997 | return 0x1003; | 1123 | return 0x1003; |
998 | #endif | 1124 | #endif |
999 | case VIDEO_MODE_NTSC: /* BTSC */ | 1125 | case VIDEO_MODE_NTSC: /* BTSC */ |
1126 | msp3400_dbg("video mode selected to NTSC\n"); | ||
1000 | return 0x2003; | 1127 | return 0x2003; |
1001 | case VIDEO_MODE_SECAM: | 1128 | case VIDEO_MODE_SECAM: |
1129 | msp3400_dbg("video mode selected to SECAM\n"); | ||
1002 | return 0x0003; | 1130 | return 0x0003; |
1003 | case VIDEO_MODE_RADIO: | 1131 | case VIDEO_MODE_RADIO: |
1132 | msp3400_dbg("video mode selected to Radio\n"); | ||
1004 | return 0x0003; | 1133 | return 0x0003; |
1005 | case VIDEO_MODE_AUTO: | 1134 | case VIDEO_MODE_AUTO: |
1135 | msp3400_dbg("video mode selected to Auto\n"); | ||
1006 | return 0x2003; | 1136 | return 0x2003; |
1007 | default: | 1137 | default: |
1008 | return 0x0003; | 1138 | return 0x0003; |
@@ -1031,23 +1161,22 @@ static int msp3410d_thread(void *data) | |||
1031 | struct msp3400c *msp = i2c_get_clientdata(client); | 1161 | struct msp3400c *msp = i2c_get_clientdata(client); |
1032 | int mode,val,i,std; | 1162 | int mode,val,i,std; |
1033 | 1163 | ||
1034 | printk("msp3410: daemon started\n"); | 1164 | msp3400_info("msp3410 daemon started\n"); |
1035 | for (;;) { | 1165 | for (;;) { |
1036 | d2printk(KERN_DEBUG "msp3410: thread: sleep\n"); | 1166 | msp3400_dbg_mediumvol("msp3410 thread: sleep\n"); |
1037 | msp34xx_sleep(msp,-1); | 1167 | msp34xx_sleep(msp,-1); |
1038 | d2printk(KERN_DEBUG "msp3410: thread: wakeup\n"); | 1168 | msp3400_dbg_mediumvol("msp3410 thread: wakeup\n"); |
1039 | 1169 | ||
1040 | restart: | 1170 | restart: |
1041 | dprintk("msp3410: thread: restart scan\n"); | 1171 | msp3400_dbg("thread: restart scan\n"); |
1042 | msp->restart = 0; | 1172 | msp->restart = 0; |
1043 | if (kthread_should_stop()) | 1173 | if (kthread_should_stop()) |
1044 | break; | 1174 | break; |
1045 | 1175 | ||
1046 | if (msp->mode == MSP_MODE_EXTERN) { | 1176 | if (msp->mode == MSP_MODE_EXTERN) { |
1047 | /* no carrier scan needed, just unmute */ | 1177 | /* no carrier scan needed, just unmute */ |
1048 | dprintk(KERN_DEBUG "msp3410: thread: no carrier scan\n"); | 1178 | msp3400_dbg("thread: no carrier scan\n"); |
1049 | msp3400c_setvolume(client, msp->muted, | 1179 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
1050 | msp->volume, msp->balance); | ||
1051 | continue; | 1180 | continue; |
1052 | } | 1181 | } |
1053 | 1182 | ||
@@ -1059,14 +1188,14 @@ static int msp3410d_thread(void *data) | |||
1059 | goto restart; | 1188 | goto restart; |
1060 | 1189 | ||
1061 | /* start autodetect */ | 1190 | /* start autodetect */ |
1062 | mode = msp34xx_modus(msp->norm); | 1191 | mode = msp34xx_modus(client, msp->norm); |
1063 | std = msp34xx_standard(msp->norm); | 1192 | std = msp34xx_standard(msp->norm); |
1064 | msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode); | 1193 | msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode); |
1065 | msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std); | 1194 | msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std); |
1066 | msp->watch_stereo = 0; | 1195 | msp->watch_stereo = 0; |
1067 | 1196 | ||
1068 | if (debug) | 1197 | if (debug) |
1069 | printk(KERN_DEBUG "msp3410: setting mode: %s (0x%04x)\n", | 1198 | msp3400_dbg("setting mode: %s (0x%04x)\n", |
1070 | msp34xx_standard_mode_name(std) ,std); | 1199 | msp34xx_standard_mode_name(std) ,std); |
1071 | 1200 | ||
1072 | if (std != 1) { | 1201 | if (std != 1) { |
@@ -1082,13 +1211,13 @@ static int msp3410d_thread(void *data) | |||
1082 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); | 1211 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); |
1083 | if (val < 0x07ff) | 1212 | if (val < 0x07ff) |
1084 | break; | 1213 | break; |
1085 | dprintk(KERN_DEBUG "msp3410: detection still in progress\n"); | 1214 | msp3400_dbg("detection still in progress\n"); |
1086 | } | 1215 | } |
1087 | } | 1216 | } |
1088 | for (i = 0; modelist[i].name != NULL; i++) | 1217 | for (i = 0; modelist[i].name != NULL; i++) |
1089 | if (modelist[i].retval == val) | 1218 | if (modelist[i].retval == val) |
1090 | break; | 1219 | break; |
1091 | dprintk(KERN_DEBUG "msp3410: current mode: %s (0x%04x)\n", | 1220 | msp3400_dbg("current mode: %s (0x%04x)\n", |
1092 | modelist[i].name ? modelist[i].name : "unknown", | 1221 | modelist[i].name ? modelist[i].name : "unknown", |
1093 | val); | 1222 | val); |
1094 | msp->main = modelist[i].main; | 1223 | msp->main = modelist[i].main; |
@@ -1096,7 +1225,7 @@ static int msp3410d_thread(void *data) | |||
1096 | 1225 | ||
1097 | if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) { | 1226 | if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) { |
1098 | /* autodetection has failed, let backup */ | 1227 | /* autodetection has failed, let backup */ |
1099 | dprintk(KERN_DEBUG "msp3410: autodetection failed," | 1228 | msp3400_dbg("autodetection failed," |
1100 | " switching to backup mode: %s (0x%04x)\n", | 1229 | " switching to backup mode: %s (0x%04x)\n", |
1101 | modelist[8].name ? modelist[8].name : "unknown",val); | 1230 | modelist[8].name ? modelist[8].name : "unknown",val); |
1102 | val = 0x0009; | 1231 | val = 0x0009; |
@@ -1120,13 +1249,13 @@ static int msp3410d_thread(void *data) | |||
1120 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; | 1249 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; |
1121 | msp->nicam_on = 1; | 1250 | msp->nicam_on = 1; |
1122 | msp->watch_stereo = 1; | 1251 | msp->watch_stereo = 1; |
1123 | msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO); | 1252 | msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); |
1124 | break; | 1253 | break; |
1125 | case 0x0009: | 1254 | case 0x0009: |
1126 | msp->mode = MSP_MODE_AM_NICAM; | 1255 | msp->mode = MSP_MODE_AM_NICAM; |
1127 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; | 1256 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; |
1128 | msp->nicam_on = 1; | 1257 | msp->nicam_on = 1; |
1129 | msp3400c_set_audmode(client,V4L2_TUNER_MODE_MONO); | 1258 | msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO); |
1130 | msp->watch_stereo = 1; | 1259 | msp->watch_stereo = 1; |
1131 | break; | 1260 | break; |
1132 | case 0x0020: /* BTSC */ | 1261 | case 0x0020: /* BTSC */ |
@@ -1135,7 +1264,7 @@ static int msp3410d_thread(void *data) | |||
1135 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; | 1264 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; |
1136 | msp->nicam_on = 0; | 1265 | msp->nicam_on = 0; |
1137 | msp->watch_stereo = 1; | 1266 | msp->watch_stereo = 1; |
1138 | msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO); | 1267 | msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); |
1139 | break; | 1268 | break; |
1140 | case 0x0040: /* FM radio */ | 1269 | case 0x0040: /* FM radio */ |
1141 | msp->mode = MSP_MODE_FM_RADIO; | 1270 | msp->mode = MSP_MODE_FM_RADIO; |
@@ -1169,9 +1298,10 @@ static int msp3410d_thread(void *data) | |||
1169 | /* unmute, restore misc registers */ | 1298 | /* unmute, restore misc registers */ |
1170 | msp3400c_setbass(client, msp->bass); | 1299 | msp3400c_setbass(client, msp->bass); |
1171 | msp3400c_settreble(client, msp->treble); | 1300 | msp3400c_settreble(client, msp->treble); |
1172 | msp3400c_setvolume(client, msp->muted, | 1301 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
1173 | msp->volume, msp->balance); | 1302 | msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb); |
1174 | msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb); | 1303 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); |
1304 | msp3400c_restore_dfp(client); | ||
1175 | 1305 | ||
1176 | /* monitor tv audio mode */ | 1306 | /* monitor tv audio mode */ |
1177 | while (msp->watch_stereo) { | 1307 | while (msp->watch_stereo) { |
@@ -1180,7 +1310,7 @@ static int msp3410d_thread(void *data) | |||
1180 | watch_stereo(client); | 1310 | watch_stereo(client); |
1181 | } | 1311 | } |
1182 | } | 1312 | } |
1183 | dprintk(KERN_DEBUG "msp3410: thread: exit\n"); | 1313 | msp3400_dbg("thread: exit\n"); |
1184 | return 0; | 1314 | return 0; |
1185 | } | 1315 | } |
1186 | 1316 | ||
@@ -1195,7 +1325,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source); | |||
1195 | /* (re-)initialize the msp34xxg, according to the current norm in msp->norm | 1325 | /* (re-)initialize the msp34xxg, according to the current norm in msp->norm |
1196 | * return 0 if it worked, -1 if it failed | 1326 | * return 0 if it worked, -1 if it failed |
1197 | */ | 1327 | */ |
1198 | static int msp34xxg_init(struct i2c_client *client) | 1328 | static int msp34xxg_reset(struct i2c_client *client) |
1199 | { | 1329 | { |
1200 | struct msp3400c *msp = i2c_get_clientdata(client); | 1330 | struct msp3400c *msp = i2c_get_clientdata(client); |
1201 | int modus,std; | 1331 | int modus,std; |
@@ -1210,8 +1340,10 @@ static int msp34xxg_init(struct i2c_client *client) | |||
1210 | 0x0f20 /* mute DSP input, mute SCART 1 */)) | 1340 | 0x0f20 /* mute DSP input, mute SCART 1 */)) |
1211 | return -1; | 1341 | return -1; |
1212 | 1342 | ||
1343 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); | ||
1344 | |||
1213 | /* step-by-step initialisation, as described in the manual */ | 1345 | /* step-by-step initialisation, as described in the manual */ |
1214 | modus = msp34xx_modus(msp->norm); | 1346 | modus = msp34xx_modus(client, msp->norm); |
1215 | std = msp34xx_standard(msp->norm); | 1347 | std = msp34xx_standard(msp->norm); |
1216 | modus &= ~0x03; /* STATUS_CHANGE=0 */ | 1348 | modus &= ~0x03; /* STATUS_CHANGE=0 */ |
1217 | modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */ | 1349 | modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */ |
@@ -1222,7 +1354,7 @@ static int msp34xxg_init(struct i2c_client *client) | |||
1222 | return -1; | 1354 | return -1; |
1223 | if (msp3400c_write(client, | 1355 | if (msp3400c_write(client, |
1224 | I2C_MSP3400C_DEM, | 1356 | I2C_MSP3400C_DEM, |
1225 | 0x20/*stanard*/, | 1357 | 0x20/*standard*/, |
1226 | std)) | 1358 | std)) |
1227 | return -1; | 1359 | return -1; |
1228 | 1360 | ||
@@ -1230,21 +1362,18 @@ static int msp34xxg_init(struct i2c_client *client) | |||
1230 | standard/audio autodetection right now */ | 1362 | standard/audio autodetection right now */ |
1231 | msp34xxg_set_source(client, msp->source); | 1363 | msp34xxg_set_source(client, msp->source); |
1232 | 1364 | ||
1233 | if (msp3400c_write(client, I2C_MSP3400C_DFP, | 1365 | if (msp3400c_write_dfp_with_default(client, 0x0e, /* AM/FM Prescale */ |
1234 | 0x0e, /* AM/FM Prescale */ | 1366 | 0x3000 |
1235 | 0x3000 /* default: [15:8] 75khz deviation */)) | 1367 | /* default: [15:8] 75khz deviation */ |
1368 | )) | ||
1236 | return -1; | 1369 | return -1; |
1237 | 1370 | ||
1238 | if (msp3400c_write(client, I2C_MSP3400C_DFP, | 1371 | if (msp3400c_write_dfp_with_default(client, 0x10, /* NICAM Prescale */ |
1239 | 0x10, /* NICAM Prescale */ | 1372 | 0x5a00 |
1240 | 0x5a00 /* default: 9db gain (as recommended) */)) | 1373 | /* default: 9db gain (as recommended) */ |
1374 | )) | ||
1241 | return -1; | 1375 | return -1; |
1242 | 1376 | ||
1243 | if (msp3400c_write(client, | ||
1244 | I2C_MSP3400C_DEM, | ||
1245 | 0x20, /* STANDARD SELECT */ | ||
1246 | standard /* default: 0x01 for automatic standard select*/)) | ||
1247 | return -1; | ||
1248 | return 0; | 1377 | return 0; |
1249 | } | 1378 | } |
1250 | 1379 | ||
@@ -1254,27 +1383,27 @@ static int msp34xxg_thread(void *data) | |||
1254 | struct msp3400c *msp = i2c_get_clientdata(client); | 1383 | struct msp3400c *msp = i2c_get_clientdata(client); |
1255 | int val, std, i; | 1384 | int val, std, i; |
1256 | 1385 | ||
1257 | printk("msp34xxg: daemon started\n"); | 1386 | msp3400_info("msp34xxg daemon started\n"); |
1258 | msp->source = 1; /* default */ | 1387 | msp->source = 1; /* default */ |
1259 | for (;;) { | 1388 | for (;;) { |
1260 | d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n"); | 1389 | msp3400_dbg_mediumvol("msp34xxg thread: sleep\n"); |
1261 | msp34xx_sleep(msp,-1); | 1390 | msp34xx_sleep(msp,-1); |
1262 | d2printk(KERN_DEBUG "msp34xxg: thread: wakeup\n"); | 1391 | msp3400_dbg_mediumvol("msp34xxg thread: wakeup\n"); |
1263 | 1392 | ||
1264 | restart: | 1393 | restart: |
1265 | dprintk("msp34xxg: thread: restart scan\n"); | 1394 | msp3400_dbg("thread: restart scan\n"); |
1266 | msp->restart = 0; | 1395 | msp->restart = 0; |
1267 | if (kthread_should_stop()) | 1396 | if (kthread_should_stop()) |
1268 | break; | 1397 | break; |
1269 | 1398 | ||
1270 | /* setup the chip*/ | 1399 | /* setup the chip*/ |
1271 | msp34xxg_init(client); | 1400 | msp34xxg_reset(client); |
1272 | std = standard; | 1401 | std = standard; |
1273 | if (std != 0x01) | 1402 | if (std != 0x01) |
1274 | goto unmute; | 1403 | goto unmute; |
1275 | 1404 | ||
1276 | /* watch autodetect */ | 1405 | /* watch autodetect */ |
1277 | dprintk("msp34xxg: triggered autodetect, waiting for result\n"); | 1406 | msp3400_dbg("triggered autodetect, waiting for result\n"); |
1278 | for (i = 0; i < 10; i++) { | 1407 | for (i = 0; i < 10; i++) { |
1279 | if (msp34xx_sleep(msp,100)) | 1408 | if (msp34xx_sleep(msp,100)) |
1280 | goto restart; | 1409 | goto restart; |
@@ -1285,23 +1414,23 @@ static int msp34xxg_thread(void *data) | |||
1285 | std = val; | 1414 | std = val; |
1286 | break; | 1415 | break; |
1287 | } | 1416 | } |
1288 | dprintk("msp34xxg: detection still in progress\n"); | 1417 | msp3400_dbg("detection still in progress\n"); |
1289 | } | 1418 | } |
1290 | if (0x01 == std) { | 1419 | if (0x01 == std) { |
1291 | dprintk("msp34xxg: detection still in progress after 10 tries. giving up.\n"); | 1420 | msp3400_dbg("detection still in progress after 10 tries. giving up.\n"); |
1292 | continue; | 1421 | continue; |
1293 | } | 1422 | } |
1294 | 1423 | ||
1295 | unmute: | 1424 | unmute: |
1296 | dprintk("msp34xxg: current mode: %s (0x%04x)\n", | 1425 | msp3400_dbg("current mode: %s (0x%04x)\n", |
1297 | msp34xx_standard_mode_name(std), std); | 1426 | msp34xx_standard_mode_name(std), std); |
1298 | 1427 | ||
1299 | /* unmute: dispatch sound to scart output, set scart volume */ | 1428 | /* unmute: dispatch sound to scart output, set scart volume */ |
1300 | dprintk("msp34xxg: unmute\n"); | 1429 | msp3400_dbg("unmute\n"); |
1301 | 1430 | ||
1302 | msp3400c_setbass(client, msp->bass); | 1431 | msp3400c_setbass(client, msp->bass); |
1303 | msp3400c_settreble(client, msp->treble); | 1432 | msp3400c_settreble(client, msp->treble); |
1304 | msp3400c_setvolume(client, msp->muted, msp->volume, msp->balance); | 1433 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
1305 | 1434 | ||
1306 | /* restore ACB */ | 1435 | /* restore ACB */ |
1307 | if (msp3400c_write(client, | 1436 | if (msp3400c_write(client, |
@@ -1309,8 +1438,10 @@ static int msp34xxg_thread(void *data) | |||
1309 | 0x13, /* ACB */ | 1438 | 0x13, /* ACB */ |
1310 | msp->acb)) | 1439 | msp->acb)) |
1311 | return -1; | 1440 | return -1; |
1441 | |||
1442 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); | ||
1312 | } | 1443 | } |
1313 | dprintk(KERN_DEBUG "msp34xxg: thread: exit\n"); | 1444 | msp3400_dbg("thread: exit\n"); |
1314 | return 0; | 1445 | return 0; |
1315 | } | 1446 | } |
1316 | 1447 | ||
@@ -1329,7 +1460,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source) | |||
1329 | * for MONO (source==0) downmixing set bit[7:0] to 0x30 | 1460 | * for MONO (source==0) downmixing set bit[7:0] to 0x30 |
1330 | */ | 1461 | */ |
1331 | int value = (source&0x07)<<8|(source==0 ? 0x30:0x20); | 1462 | int value = (source&0x07)<<8|(source==0 ? 0x30:0x20); |
1332 | dprintk("msp34xxg: set source to %d (0x%x)\n", source, value); | 1463 | msp3400_dbg("set source to %d (0x%x)\n", source, value); |
1333 | msp3400c_write(client, | 1464 | msp3400c_write(client, |
1334 | I2C_MSP3400C_DFP, | 1465 | I2C_MSP3400C_DFP, |
1335 | 0x08, /* Loudspeaker Output */ | 1466 | 0x08, /* Loudspeaker Output */ |
@@ -1380,7 +1511,7 @@ static void msp34xxg_detect_stereo(struct i2c_client *client) | |||
1380 | * this is a problem, I'll handle SAP just like lang1/lang2. | 1511 | * this is a problem, I'll handle SAP just like lang1/lang2. |
1381 | */ | 1512 | */ |
1382 | } | 1513 | } |
1383 | dprintk("msp34xxg: status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", | 1514 | msp3400_dbg("status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", |
1384 | status, is_stereo, is_bilingual, msp->rxsubchans); | 1515 | status, is_stereo, is_bilingual, msp->rxsubchans); |
1385 | } | 1516 | } |
1386 | 1517 | ||
@@ -1427,7 +1558,7 @@ static void msp_wake_thread(struct i2c_client *client); | |||
1427 | 1558 | ||
1428 | static struct i2c_driver driver = { | 1559 | static struct i2c_driver driver = { |
1429 | .owner = THIS_MODULE, | 1560 | .owner = THIS_MODULE, |
1430 | .name = "i2c msp3400 driver", | 1561 | .name = "msp3400", |
1431 | .id = I2C_DRIVERID_MSP3400, | 1562 | .id = I2C_DRIVERID_MSP3400, |
1432 | .flags = I2C_DF_NOTIFY, | 1563 | .flags = I2C_DF_NOTIFY, |
1433 | .attach_adapter = msp_probe, | 1564 | .attach_adapter = msp_probe, |
@@ -1449,57 +1580,64 @@ static struct i2c_client client_template = | |||
1449 | static int msp_attach(struct i2c_adapter *adap, int addr, int kind) | 1580 | static int msp_attach(struct i2c_adapter *adap, int addr, int kind) |
1450 | { | 1581 | { |
1451 | struct msp3400c *msp; | 1582 | struct msp3400c *msp; |
1452 | struct i2c_client *c; | 1583 | struct i2c_client *client = &client_template; |
1453 | int (*thread_func)(void *data) = NULL; | 1584 | int (*thread_func)(void *data) = NULL; |
1585 | int i; | ||
1454 | 1586 | ||
1455 | client_template.adapter = adap; | 1587 | client_template.adapter = adap; |
1456 | client_template.addr = addr; | 1588 | client_template.addr = addr; |
1457 | 1589 | ||
1458 | if (-1 == msp3400c_reset(&client_template)) { | 1590 | if (-1 == msp3400c_reset(&client_template)) { |
1459 | dprintk("msp34xx: no chip found\n"); | 1591 | msp3400_dbg("no chip found\n"); |
1460 | return -1; | 1592 | return -1; |
1461 | } | 1593 | } |
1462 | 1594 | ||
1463 | if (NULL == (c = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) | 1595 | if (NULL == (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) |
1464 | return -ENOMEM; | 1596 | return -ENOMEM; |
1465 | memcpy(c,&client_template,sizeof(struct i2c_client)); | 1597 | memcpy(client,&client_template,sizeof(struct i2c_client)); |
1466 | if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) { | 1598 | if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) { |
1467 | kfree(c); | 1599 | kfree(client); |
1468 | return -ENOMEM; | 1600 | return -ENOMEM; |
1469 | } | 1601 | } |
1470 | 1602 | ||
1471 | memset(msp,0,sizeof(struct msp3400c)); | 1603 | memset(msp,0,sizeof(struct msp3400c)); |
1472 | msp->volume = 58880; /* 0db gain */ | 1604 | msp->norm = VIDEO_MODE_NTSC; |
1473 | msp->balance = 32768; | 1605 | msp->left = 58880; /* 0db gain */ |
1474 | msp->bass = 32768; | 1606 | msp->right = 58880; /* 0db gain */ |
1475 | msp->treble = 32768; | 1607 | msp->bass = 32768; |
1476 | msp->input = -1; | 1608 | msp->treble = 32768; |
1477 | msp->muted = 1; | 1609 | msp->input = -1; |
1478 | 1610 | msp->muted = 0; | |
1479 | i2c_set_clientdata(c, msp); | 1611 | msp->i2s_mode = 0; |
1612 | for (i = 0; i < DFP_COUNT; i++) | ||
1613 | msp->dfp_regs[i] = -1; | ||
1614 | |||
1615 | i2c_set_clientdata(client, msp); | ||
1480 | init_waitqueue_head(&msp->wq); | 1616 | init_waitqueue_head(&msp->wq); |
1481 | 1617 | ||
1482 | if (-1 == msp3400c_reset(c)) { | 1618 | if (-1 == msp3400c_reset(client)) { |
1483 | kfree(msp); | 1619 | kfree(msp); |
1484 | kfree(c); | 1620 | kfree(client); |
1485 | dprintk("msp34xx: no chip found\n"); | 1621 | msp3400_dbg("no chip found\n"); |
1486 | return -1; | 1622 | return -1; |
1487 | } | 1623 | } |
1488 | 1624 | ||
1489 | msp->rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e); | 1625 | msp->rev1 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1e); |
1490 | if (-1 != msp->rev1) | 1626 | if (-1 != msp->rev1) |
1491 | msp->rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f); | 1627 | msp->rev2 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1f); |
1492 | if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) { | 1628 | if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) { |
1493 | kfree(msp); | 1629 | kfree(msp); |
1494 | kfree(c); | 1630 | kfree(client); |
1495 | dprintk("msp34xx: error while reading chip version\n"); | 1631 | msp3400_dbg("error while reading chip version\n"); |
1496 | return -1; | 1632 | return -1; |
1497 | } | 1633 | } |
1634 | msp3400_dbg("rev1=0x%04x, rev2=0x%04x\n", msp->rev1, msp->rev2); | ||
1498 | 1635 | ||
1499 | msp3400c_setvolume(c, msp->muted, msp->volume, msp->balance); | 1636 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
1500 | 1637 | ||
1501 | snprintf(c->name, sizeof(c->name), "MSP34%02d%c-%c%d", | 1638 | snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d", |
1502 | (msp->rev2>>8)&0xff, (msp->rev1&0xff)+'@', | 1639 | ((msp->rev1>>4)&0x0f) + '3', |
1640 | (msp->rev2>>8)&0xff, (msp->rev1&0x0f)+'@', | ||
1503 | ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f); | 1641 | ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f); |
1504 | 1642 | ||
1505 | msp->opmode = opmode; | 1643 | msp->opmode = opmode; |
@@ -1513,7 +1651,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1513 | } | 1651 | } |
1514 | 1652 | ||
1515 | /* hello world :-) */ | 1653 | /* hello world :-) */ |
1516 | printk(KERN_INFO "msp34xx: init: chip=%s", c->name); | 1654 | msp3400_info("chip=%s", client->name); |
1517 | if (HAVE_NICAM(msp)) | 1655 | if (HAVE_NICAM(msp)) |
1518 | printk(" +nicam"); | 1656 | printk(" +nicam"); |
1519 | if (HAVE_SIMPLE(msp)) | 1657 | if (HAVE_SIMPLE(msp)) |
@@ -1542,29 +1680,49 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1542 | 1680 | ||
1543 | /* startup control thread if needed */ | 1681 | /* startup control thread if needed */ |
1544 | if (thread_func) { | 1682 | if (thread_func) { |
1545 | msp->kthread = kthread_run(thread_func, c, "msp34xx"); | 1683 | msp->kthread = kthread_run(thread_func, client, "msp34xx"); |
1684 | |||
1546 | if (NULL == msp->kthread) | 1685 | if (NULL == msp->kthread) |
1547 | printk(KERN_WARNING "msp34xx: kernel_thread() failed\n"); | 1686 | msp3400_warn("kernel_thread() failed\n"); |
1548 | msp_wake_thread(c); | 1687 | msp_wake_thread(client); |
1549 | } | 1688 | } |
1550 | 1689 | ||
1551 | /* done */ | 1690 | /* done */ |
1552 | i2c_attach_client(c); | 1691 | i2c_attach_client(client); |
1692 | |||
1693 | /* update our own array */ | ||
1694 | for (i = 0; i < MSP3400_MAX; i++) { | ||
1695 | if (NULL == msps[i]) { | ||
1696 | msps[i] = client; | ||
1697 | break; | ||
1698 | } | ||
1699 | } | ||
1700 | |||
1553 | return 0; | 1701 | return 0; |
1554 | } | 1702 | } |
1555 | 1703 | ||
1556 | static int msp_detach(struct i2c_client *client) | 1704 | static int msp_detach(struct i2c_client *client) |
1557 | { | 1705 | { |
1558 | struct msp3400c *msp = i2c_get_clientdata(client); | 1706 | struct msp3400c *msp = i2c_get_clientdata(client); |
1707 | int i; | ||
1559 | 1708 | ||
1560 | /* shutdown control thread */ | 1709 | /* shutdown control thread */ |
1561 | if (msp->kthread >= 0) { | 1710 | if (msp->kthread) { |
1562 | msp->restart = 1; | 1711 | msp->restart = 1; |
1563 | kthread_stop(msp->kthread); | 1712 | kthread_stop(msp->kthread); |
1564 | } | 1713 | } |
1565 | msp3400c_reset(client); | 1714 | msp3400c_reset(client); |
1715 | |||
1716 | /* update our own array */ | ||
1717 | for (i = 0; i < MSP3400_MAX; i++) { | ||
1718 | if (client == msps[i]) { | ||
1719 | msps[i] = NULL; | ||
1720 | break; | ||
1721 | } | ||
1722 | } | ||
1566 | 1723 | ||
1567 | i2c_detach_client(client); | 1724 | i2c_detach_client(client); |
1725 | |||
1568 | kfree(msp); | 1726 | kfree(msp); |
1569 | kfree(client); | 1727 | kfree(client); |
1570 | return 0; | 1728 | return 0; |
@@ -1640,7 +1798,7 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode) | |||
1640 | case OPMODE_MANUAL: | 1798 | case OPMODE_MANUAL: |
1641 | case OPMODE_SIMPLE: | 1799 | case OPMODE_SIMPLE: |
1642 | msp->watch_stereo = 0; | 1800 | msp->watch_stereo = 0; |
1643 | msp3400c_set_audmode(client, audmode); | 1801 | msp3400c_setstereo(client, audmode); |
1644 | break; | 1802 | break; |
1645 | case OPMODE_SIMPLER: | 1803 | case OPMODE_SIMPLER: |
1646 | msp34xxg_set_audmode(client, audmode); | 1804 | msp34xxg_set_audmode(client, audmode); |
@@ -1648,16 +1806,18 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode) | |||
1648 | } | 1806 | } |
1649 | } | 1807 | } |
1650 | 1808 | ||
1809 | |||
1651 | static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | 1810 | static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) |
1652 | { | 1811 | { |
1653 | struct msp3400c *msp = i2c_get_clientdata(client); | 1812 | struct msp3400c *msp = i2c_get_clientdata(client); |
1654 | __u16 *sarg = arg; | 1813 | __u16 *sarg = arg; |
1655 | int scart = 0; | 1814 | int scart = 0; |
1656 | 1815 | ||
1657 | switch (cmd) { | 1816 | switch (cmd) { |
1658 | 1817 | ||
1659 | case AUDC_SET_INPUT: | 1818 | case AUDC_SET_INPUT: |
1660 | dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)\n",*sarg); | 1819 | msp3400_dbg("AUDC_SET_INPUT(%d)\n",*sarg); |
1820 | |||
1661 | if (*sarg == msp->input) | 1821 | if (*sarg == msp->input) |
1662 | break; | 1822 | break; |
1663 | msp->input = *sarg; | 1823 | msp->input = *sarg; |
@@ -1691,15 +1851,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1691 | msp3400c_set_scart(client,scart,0); | 1851 | msp3400c_set_scart(client,scart,0); |
1692 | msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); | 1852 | msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); |
1693 | if (msp->opmode != OPMODE_SIMPLER) | 1853 | if (msp->opmode != OPMODE_SIMPLER) |
1694 | msp3400c_set_audmode(client, msp->audmode); | 1854 | msp3400c_setstereo(client, msp->audmode); |
1695 | } | 1855 | } |
1696 | msp_wake_thread(client); | 1856 | msp_wake_thread(client); |
1697 | break; | 1857 | break; |
1698 | 1858 | ||
1699 | case AUDC_SET_RADIO: | 1859 | case AUDC_SET_RADIO: |
1700 | dprintk(KERN_DEBUG "msp34xx: AUDC_SET_RADIO\n"); | 1860 | msp3400_dbg("AUDC_SET_RADIO\n"); |
1701 | msp->norm = VIDEO_MODE_RADIO; | 1861 | msp->norm = VIDEO_MODE_RADIO; |
1702 | dprintk(KERN_DEBUG "msp34xx: switching to radio mode\n"); | 1862 | msp3400_dbg("switching to radio mode\n"); |
1703 | msp->watch_stereo = 0; | 1863 | msp->watch_stereo = 0; |
1704 | switch (msp->opmode) { | 1864 | switch (msp->opmode) { |
1705 | case OPMODE_MANUAL: | 1865 | case OPMODE_MANUAL: |
@@ -1707,8 +1867,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1707 | msp3400c_setmode(client,MSP_MODE_FM_RADIO); | 1867 | msp3400c_setmode(client,MSP_MODE_FM_RADIO); |
1708 | msp3400c_setcarrier(client, MSP_CARRIER(10.7), | 1868 | msp3400c_setcarrier(client, MSP_CARRIER(10.7), |
1709 | MSP_CARRIER(10.7)); | 1869 | MSP_CARRIER(10.7)); |
1710 | msp3400c_setvolume(client, msp->muted, | 1870 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
1711 | msp->volume, msp->balance); | ||
1712 | break; | 1871 | break; |
1713 | case OPMODE_SIMPLE: | 1872 | case OPMODE_SIMPLE: |
1714 | case OPMODE_SIMPLER: | 1873 | case OPMODE_SIMPLER: |
@@ -1717,6 +1876,30 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1717 | break; | 1876 | break; |
1718 | } | 1877 | } |
1719 | break; | 1878 | break; |
1879 | /* work-in-progress: hook to control the DFP registers */ | ||
1880 | case MSP_SET_DFPREG: | ||
1881 | { | ||
1882 | struct msp_dfpreg *r = arg; | ||
1883 | int i; | ||
1884 | |||
1885 | if (r->reg < 0 || r->reg >= DFP_COUNT) | ||
1886 | return -EINVAL; | ||
1887 | for (i = 0; i < sizeof(bl_dfp) / sizeof(int); i++) | ||
1888 | if (r->reg == bl_dfp[i]) | ||
1889 | return -EINVAL; | ||
1890 | msp->dfp_regs[r->reg] = r->value; | ||
1891 | msp3400c_write(client, I2C_MSP3400C_DFP, r->reg, r->value); | ||
1892 | return 0; | ||
1893 | } | ||
1894 | case MSP_GET_DFPREG: | ||
1895 | { | ||
1896 | struct msp_dfpreg *r = arg; | ||
1897 | |||
1898 | if (r->reg < 0 || r->reg >= DFP_COUNT) | ||
1899 | return -EINVAL; | ||
1900 | r->value = msp3400c_read(client, I2C_MSP3400C_DFP, r->reg); | ||
1901 | return 0; | ||
1902 | } | ||
1720 | 1903 | ||
1721 | /* --- v4l ioctls --- */ | 1904 | /* --- v4l ioctls --- */ |
1722 | /* take care: bttv does userspace copying, we'll get a | 1905 | /* take care: bttv does userspace copying, we'll get a |
@@ -1725,7 +1908,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1725 | { | 1908 | { |
1726 | struct video_audio *va = arg; | 1909 | struct video_audio *va = arg; |
1727 | 1910 | ||
1728 | dprintk(KERN_DEBUG "msp34xx: VIDIOCGAUDIO\n"); | 1911 | msp3400_dbg("VIDIOCGAUDIO\n"); |
1729 | va->flags |= VIDEO_AUDIO_VOLUME | | 1912 | va->flags |= VIDEO_AUDIO_VOLUME | |
1730 | VIDEO_AUDIO_BASS | | 1913 | VIDEO_AUDIO_BASS | |
1731 | VIDEO_AUDIO_TREBLE | | 1914 | VIDEO_AUDIO_TREBLE | |
@@ -1733,8 +1916,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1733 | if (msp->muted) | 1916 | if (msp->muted) |
1734 | va->flags |= VIDEO_AUDIO_MUTE; | 1917 | va->flags |= VIDEO_AUDIO_MUTE; |
1735 | 1918 | ||
1736 | va->volume = msp->volume; | 1919 | if (msp->muted) |
1737 | va->balance = (va->volume) ? msp->balance : 32768; | 1920 | va->flags |= VIDEO_AUDIO_MUTE; |
1921 | va->volume = MAX(msp->left, msp->right); | ||
1922 | va->balance = (32768 * MIN(msp->left, msp->right)) / | ||
1923 | (va->volume ? va->volume : 1); | ||
1924 | va->balance = (msp->left < msp->right) ? | ||
1925 | (65535 - va->balance) : va->balance; | ||
1926 | if (0 == va->volume) | ||
1927 | va->balance = 32768; | ||
1738 | va->bass = msp->bass; | 1928 | va->bass = msp->bass; |
1739 | va->treble = msp->treble; | 1929 | va->treble = msp->treble; |
1740 | 1930 | ||
@@ -1746,27 +1936,43 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1746 | { | 1936 | { |
1747 | struct video_audio *va = arg; | 1937 | struct video_audio *va = arg; |
1748 | 1938 | ||
1749 | dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n"); | 1939 | msp3400_dbg("VIDIOCSAUDIO\n"); |
1750 | msp->muted = (va->flags & VIDEO_AUDIO_MUTE); | 1940 | msp->muted = (va->flags & VIDEO_AUDIO_MUTE); |
1751 | msp->volume = va->volume; | 1941 | msp->left = (MIN(65536 - va->balance, 32768) * |
1752 | msp->balance = va->balance; | 1942 | va->volume) / 32768; |
1943 | msp->right = (MIN(va->balance, 32768) * va->volume) / 32768; | ||
1753 | msp->bass = va->bass; | 1944 | msp->bass = va->bass; |
1754 | msp->treble = va->treble; | 1945 | msp->treble = va->treble; |
1755 | 1946 | msp3400_dbg("VIDIOCSAUDIO setting va->volume to %d\n", | |
1756 | msp3400c_setvolume(client, msp->muted, | 1947 | va->volume); |
1757 | msp->volume, msp->balance); | 1948 | msp3400_dbg("VIDIOCSAUDIO setting va->balance to %d\n", |
1758 | msp3400c_setbass(client,msp->bass); | 1949 | va->balance); |
1759 | msp3400c_settreble(client,msp->treble); | 1950 | msp3400_dbg("VIDIOCSAUDIO setting va->flags to %d\n", |
1951 | va->flags); | ||
1952 | msp3400_dbg("VIDIOCSAUDIO setting msp->left to %d\n", | ||
1953 | msp->left); | ||
1954 | msp3400_dbg("VIDIOCSAUDIO setting msp->right to %d\n", | ||
1955 | msp->right); | ||
1956 | msp3400_dbg("VIDIOCSAUDIO setting msp->bass to %d\n", | ||
1957 | msp->bass); | ||
1958 | msp3400_dbg("VIDIOCSAUDIO setting msp->treble to %d\n", | ||
1959 | msp->treble); | ||
1960 | msp3400_dbg("VIDIOCSAUDIO setting msp->mode to %d\n", | ||
1961 | msp->mode); | ||
1962 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | ||
1963 | msp3400c_setbass(client, msp->bass); | ||
1964 | msp3400c_settreble(client, msp->treble); | ||
1760 | 1965 | ||
1761 | if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO) | 1966 | if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO) |
1762 | msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode)); | 1967 | msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode)); |
1763 | break; | 1968 | break; |
1764 | } | 1969 | } |
1970 | |||
1765 | case VIDIOCSCHAN: | 1971 | case VIDIOCSCHAN: |
1766 | { | 1972 | { |
1767 | struct video_channel *vc = arg; | 1973 | struct video_channel *vc = arg; |
1768 | 1974 | ||
1769 | dprintk(KERN_DEBUG "msp34xx: VIDIOCSCHAN (norm=%d)\n",vc->norm); | 1975 | msp3400_dbg("VIDIOCSCHAN (norm=%d)\n",vc->norm); |
1770 | msp->norm = vc->norm; | 1976 | msp->norm = vc->norm; |
1771 | msp_wake_thread(client); | 1977 | msp_wake_thread(client); |
1772 | break; | 1978 | break; |
@@ -1776,12 +1982,135 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1776 | case VIDIOC_S_FREQUENCY: | 1982 | case VIDIOC_S_FREQUENCY: |
1777 | { | 1983 | { |
1778 | /* new channel -- kick audio carrier scan */ | 1984 | /* new channel -- kick audio carrier scan */ |
1779 | dprintk(KERN_DEBUG "msp34xx: VIDIOCSFREQ\n"); | 1985 | msp3400_dbg("VIDIOCSFREQ\n"); |
1780 | msp_wake_thread(client); | 1986 | msp_wake_thread(client); |
1781 | break; | 1987 | break; |
1782 | } | 1988 | } |
1783 | 1989 | ||
1990 | /* msp34xx specific */ | ||
1991 | case MSP_SET_MATRIX: | ||
1992 | { | ||
1993 | struct msp_matrix *mspm = arg; | ||
1994 | |||
1995 | msp3400_dbg("MSP_SET_MATRIX\n"); | ||
1996 | msp3400c_set_scart(client, mspm->input, mspm->output); | ||
1997 | break; | ||
1998 | } | ||
1999 | |||
1784 | /* --- v4l2 ioctls --- */ | 2000 | /* --- v4l2 ioctls --- */ |
2001 | case VIDIOC_S_STD: | ||
2002 | { | ||
2003 | v4l2_std_id *id = arg; | ||
2004 | |||
2005 | /*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/ | ||
2006 | if (*id & V4L2_STD_PAL) { | ||
2007 | msp->norm=VIDEO_MODE_PAL; | ||
2008 | } else if (*id & V4L2_STD_SECAM) { | ||
2009 | msp->norm=VIDEO_MODE_SECAM; | ||
2010 | } else { | ||
2011 | msp->norm=VIDEO_MODE_NTSC; | ||
2012 | } | ||
2013 | |||
2014 | msp_wake_thread(client); | ||
2015 | return 0; | ||
2016 | } | ||
2017 | |||
2018 | case VIDIOC_ENUMINPUT: | ||
2019 | { | ||
2020 | struct v4l2_input *i = arg; | ||
2021 | |||
2022 | if (i->index != 0) | ||
2023 | return -EINVAL; | ||
2024 | |||
2025 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
2026 | switch (i->index) { | ||
2027 | case AUDIO_RADIO: | ||
2028 | strcpy(i->name,"Radio"); | ||
2029 | break; | ||
2030 | case AUDIO_EXTERN_1: | ||
2031 | strcpy(i->name,"Extern 1"); | ||
2032 | break; | ||
2033 | case AUDIO_EXTERN_2: | ||
2034 | strcpy(i->name,"Extern 2"); | ||
2035 | break; | ||
2036 | case AUDIO_TUNER: | ||
2037 | strcpy(i->name,"Television"); | ||
2038 | break; | ||
2039 | default: | ||
2040 | return -EINVAL; | ||
2041 | } | ||
2042 | return 0; | ||
2043 | } | ||
2044 | |||
2045 | case VIDIOC_G_AUDIO: | ||
2046 | { | ||
2047 | struct v4l2_audio *a = arg; | ||
2048 | |||
2049 | memset(a,0,sizeof(*a)); | ||
2050 | |||
2051 | switch (a->index) { | ||
2052 | case AUDIO_RADIO: | ||
2053 | strcpy(a->name,"Radio"); | ||
2054 | break; | ||
2055 | case AUDIO_EXTERN_1: | ||
2056 | strcpy(a->name,"Extern 1"); | ||
2057 | break; | ||
2058 | case AUDIO_EXTERN_2: | ||
2059 | strcpy(a->name,"Extern 2"); | ||
2060 | break; | ||
2061 | case AUDIO_TUNER: | ||
2062 | strcpy(a->name,"Television"); | ||
2063 | break; | ||
2064 | default: | ||
2065 | return -EINVAL; | ||
2066 | } | ||
2067 | |||
2068 | msp_any_detect_stereo(client); | ||
2069 | if (msp->audmode == V4L2_TUNER_MODE_STEREO) { | ||
2070 | a->capability=V4L2_AUDCAP_STEREO; | ||
2071 | } | ||
2072 | |||
2073 | break; | ||
2074 | } | ||
2075 | case VIDIOC_S_AUDIO: | ||
2076 | { | ||
2077 | struct v4l2_audio *sarg = arg; | ||
2078 | |||
2079 | switch (sarg->index) { | ||
2080 | case AUDIO_RADIO: | ||
2081 | /* Hauppauge uses IN2 for the radio */ | ||
2082 | msp->mode = MSP_MODE_FM_RADIO; | ||
2083 | scart = SCART_IN2; | ||
2084 | break; | ||
2085 | case AUDIO_EXTERN_1: | ||
2086 | /* IN1 is often used for external input ... */ | ||
2087 | msp->mode = MSP_MODE_EXTERN; | ||
2088 | scart = SCART_IN1; | ||
2089 | break; | ||
2090 | case AUDIO_EXTERN_2: | ||
2091 | /* ... sometimes it is IN2 through ;) */ | ||
2092 | msp->mode = MSP_MODE_EXTERN; | ||
2093 | scart = SCART_IN2; | ||
2094 | break; | ||
2095 | case AUDIO_TUNER: | ||
2096 | msp->mode = -1; | ||
2097 | break; | ||
2098 | } | ||
2099 | if (scart) { | ||
2100 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
2101 | msp->audmode = V4L2_TUNER_MODE_STEREO; | ||
2102 | msp3400c_set_scart(client,scart,0); | ||
2103 | msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); | ||
2104 | } | ||
2105 | if (sarg->capability==V4L2_AUDCAP_STEREO) { | ||
2106 | msp->audmode = V4L2_TUNER_MODE_STEREO; | ||
2107 | } else { | ||
2108 | msp->audmode &= ~V4L2_TUNER_MODE_STEREO; | ||
2109 | } | ||
2110 | msp_any_set_audmode(client, msp->audmode); | ||
2111 | msp_wake_thread(client); | ||
2112 | break; | ||
2113 | } | ||
1785 | case VIDIOC_G_TUNER: | 2114 | case VIDIOC_G_TUNER: |
1786 | { | 2115 | { |
1787 | struct v4l2_tuner *vt = arg; | 2116 | struct v4l2_tuner *vt = arg; |
@@ -1804,13 +2133,46 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1804 | break; | 2133 | break; |
1805 | } | 2134 | } |
1806 | 2135 | ||
1807 | /* msp34xx specific */ | 2136 | case VIDIOC_G_AUDOUT: |
1808 | case MSP_SET_MATRIX: | ||
1809 | { | 2137 | { |
1810 | struct msp_matrix *mspm = arg; | 2138 | struct v4l2_audioout *a=(struct v4l2_audioout *)arg; |
2139 | int idx=a->index; | ||
2140 | |||
2141 | memset(a,0,sizeof(*a)); | ||
2142 | |||
2143 | switch (idx) { | ||
2144 | case 0: | ||
2145 | strcpy(a->name,"Scart1 Out"); | ||
2146 | break; | ||
2147 | case 1: | ||
2148 | strcpy(a->name,"Scart2 Out"); | ||
2149 | break; | ||
2150 | case 2: | ||
2151 | strcpy(a->name,"I2S Out"); | ||
2152 | break; | ||
2153 | default: | ||
2154 | return -EINVAL; | ||
2155 | } | ||
2156 | break; | ||
2157 | |||
2158 | } | ||
2159 | case VIDIOC_S_AUDOUT: | ||
2160 | { | ||
2161 | struct v4l2_audioout *a=(struct v4l2_audioout *)arg; | ||
2162 | |||
2163 | if (a->index<0||a->index>2) | ||
2164 | return -EINVAL; | ||
2165 | |||
2166 | if (a->index==2) { | ||
2167 | if (a->mode == V4L2_AUDMODE_32BITS) | ||
2168 | msp->i2s_mode=1; | ||
2169 | else | ||
2170 | msp->i2s_mode=0; | ||
2171 | } | ||
2172 | msp3400_dbg("Setting audio out on msp34xx to input %i, mode %i\n", | ||
2173 | a->index,msp->i2s_mode); | ||
2174 | msp3400c_set_scart(client,msp->in_scart,a->index+1); | ||
1811 | 2175 | ||
1812 | dprintk(KERN_DEBUG "msp34xx: MSP_SET_MATRIX\n"); | ||
1813 | msp3400c_set_scart(client, mspm->input, mspm->output); | ||
1814 | break; | 2176 | break; |
1815 | } | 2177 | } |
1816 | 2178 | ||
@@ -1823,19 +2185,19 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1823 | 2185 | ||
1824 | static int msp_suspend(struct device * dev, pm_message_t state) | 2186 | static int msp_suspend(struct device * dev, pm_message_t state) |
1825 | { | 2187 | { |
1826 | struct i2c_client *c = container_of(dev, struct i2c_client, dev); | 2188 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); |
1827 | 2189 | ||
1828 | dprintk("msp34xx: suspend\n"); | 2190 | msp3400_dbg("msp34xx: suspend\n"); |
1829 | msp3400c_reset(c); | 2191 | msp3400c_reset(client); |
1830 | return 0; | 2192 | return 0; |
1831 | } | 2193 | } |
1832 | 2194 | ||
1833 | static int msp_resume(struct device * dev) | 2195 | static int msp_resume(struct device * dev) |
1834 | { | 2196 | { |
1835 | struct i2c_client *c = container_of(dev, struct i2c_client, dev); | 2197 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); |
1836 | 2198 | ||
1837 | dprintk("msp34xx: resume\n"); | 2199 | msp3400_dbg("msp34xx: resume\n"); |
1838 | msp_wake_thread(c); | 2200 | msp_wake_thread(client); |
1839 | return 0; | 2201 | return 0; |
1840 | } | 2202 | } |
1841 | 2203 | ||
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c index 972aa5e0aeef..2180018f06de 100644 --- a/drivers/media/video/mt20xx.c +++ b/drivers/media/video/mt20xx.c | |||
@@ -76,17 +76,17 @@ static int mt2032_compute_freq(struct i2c_client *c, | |||
76 | unsigned int xogc) //all in Hz | 76 | unsigned int xogc) //all in Hz |
77 | { | 77 | { |
78 | struct tuner *t = i2c_get_clientdata(c); | 78 | struct tuner *t = i2c_get_clientdata(c); |
79 | unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1, | 79 | unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1, |
80 | desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq; | 80 | desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq; |
81 | 81 | ||
82 | fref= 5250 *1000; //5.25MHz | 82 | fref= 5250 *1000; //5.25MHz |
83 | desired_lo1=rfin+if1; | 83 | desired_lo1=rfin+if1; |
84 | 84 | ||
85 | lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000); | 85 | lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000); |
86 | lo1n=lo1/8; | 86 | lo1n=lo1/8; |
87 | lo1a=lo1-(lo1n*8); | 87 | lo1a=lo1-(lo1n*8); |
88 | 88 | ||
89 | s=rfin/1000/1000+1090; | 89 | s=rfin/1000/1000+1090; |
90 | 90 | ||
91 | if(optimize_vco) { | 91 | if(optimize_vco) { |
92 | if(s>1890) sel=0; | 92 | if(s>1890) sel=0; |
@@ -96,34 +96,34 @@ static int mt2032_compute_freq(struct i2c_client *c, | |||
96 | else sel=4; // >1090 | 96 | else sel=4; // >1090 |
97 | } | 97 | } |
98 | else { | 98 | else { |
99 | if(s>1790) sel=0; // <1958 | 99 | if(s>1790) sel=0; // <1958 |
100 | else if(s>1617) sel=1; | 100 | else if(s>1617) sel=1; |
101 | else if(s>1449) sel=2; | 101 | else if(s>1449) sel=2; |
102 | else if(s>1291) sel=3; | 102 | else if(s>1291) sel=3; |
103 | else sel=4; // >1090 | 103 | else sel=4; // >1090 |
104 | } | 104 | } |
105 | *ret_sel=sel; | 105 | *ret_sel=sel; |
106 | 106 | ||
107 | lo1freq=(lo1a+8*lo1n)*fref; | 107 | lo1freq=(lo1a+8*lo1n)*fref; |
108 | 108 | ||
109 | tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n", | 109 | tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n", |
110 | rfin,lo1,lo1n,lo1a,sel,lo1freq); | 110 | rfin,lo1,lo1n,lo1a,sel,lo1freq); |
111 | 111 | ||
112 | desired_lo2=lo1freq-rfin-if2; | 112 | desired_lo2=lo1freq-rfin-if2; |
113 | lo2=(desired_lo2)/fref; | 113 | lo2=(desired_lo2)/fref; |
114 | lo2n=lo2/8; | 114 | lo2n=lo2/8; |
115 | lo2a=lo2-(lo2n*8); | 115 | lo2a=lo2-(lo2n*8); |
116 | lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith | 116 | lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith |
117 | lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000; | 117 | lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000; |
118 | 118 | ||
119 | tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n", | 119 | tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n", |
120 | rfin,lo2,lo2n,lo2a,lo2num,lo2freq); | 120 | rfin,lo2,lo2n,lo2a,lo2num,lo2freq); |
121 | 121 | ||
122 | if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) { | 122 | if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) { |
123 | tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n", | 123 | tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n", |
124 | lo1a, lo1n, lo2a,lo2n); | 124 | lo1a, lo1n, lo2a,lo2n); |
125 | return(-1); | 125 | return(-1); |
126 | } | 126 | } |
127 | 127 | ||
128 | mt2032_spurcheck(c, lo1freq, desired_lo2, spectrum_from, spectrum_to); | 128 | mt2032_spurcheck(c, lo1freq, desired_lo2, spectrum_from, spectrum_to); |
129 | // should recalculate lo1 (one step up/down) | 129 | // should recalculate lo1 (one step up/down) |
@@ -135,10 +135,10 @@ static int mt2032_compute_freq(struct i2c_client *c, | |||
135 | buf[3]=0x0f; //reserved | 135 | buf[3]=0x0f; //reserved |
136 | buf[4]=0x1f; | 136 | buf[4]=0x1f; |
137 | buf[5]=(lo2n-1) | (lo2a<<5); | 137 | buf[5]=(lo2n-1) | (lo2a<<5); |
138 | if(rfin >400*1000*1000) | 138 | if(rfin >400*1000*1000) |
139 | buf[6]=0xe4; | 139 | buf[6]=0xe4; |
140 | else | 140 | else |
141 | buf[6]=0xf4; // set PKEN per rev 1.2 | 141 | buf[6]=0xf4; // set PKEN per rev 1.2 |
142 | buf[7]=8+xogc; | 142 | buf[7]=8+xogc; |
143 | buf[8]=0xc3; //reserved | 143 | buf[8]=0xc3; //reserved |
144 | buf[9]=0x4e; //reserved | 144 | buf[9]=0x4e; //reserved |
@@ -168,7 +168,7 @@ static int mt2032_check_lo_lock(struct i2c_client *c) | |||
168 | tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]); | 168 | tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]); |
169 | udelay(1000); | 169 | udelay(1000); |
170 | } | 170 | } |
171 | return lock; | 171 | return lock; |
172 | } | 172 | } |
173 | 173 | ||
174 | static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock) | 174 | static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock) |
@@ -202,7 +202,7 @@ static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock) | |||
202 | 202 | ||
203 | buf[0]=0x0f; | 203 | buf[0]=0x0f; |
204 | buf[1]=sel; | 204 | buf[1]=sel; |
205 | i2c_master_send(c,buf,2); | 205 | i2c_master_send(c,buf,2); |
206 | lock=mt2032_check_lo_lock(c); | 206 | lock=mt2032_check_lo_lock(c); |
207 | return lock; | 207 | return lock; |
208 | } | 208 | } |
@@ -219,23 +219,23 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin, | |||
219 | tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n", | 219 | tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n", |
220 | rfin,if1,if2,from,to); | 220 | rfin,if1,if2,from,to); |
221 | 221 | ||
222 | buf[0]=0; | 222 | buf[0]=0; |
223 | ret=i2c_master_send(c,buf,1); | 223 | ret=i2c_master_send(c,buf,1); |
224 | i2c_master_recv(c,buf,21); | 224 | i2c_master_recv(c,buf,21); |
225 | 225 | ||
226 | buf[0]=0; | 226 | buf[0]=0; |
227 | ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc); | 227 | ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc); |
228 | if (ret<0) | 228 | if (ret<0) |
229 | return; | 229 | return; |
230 | 230 | ||
231 | // send only the relevant registers per Rev. 1.2 | 231 | // send only the relevant registers per Rev. 1.2 |
232 | buf[0]=0; | 232 | buf[0]=0; |
233 | ret=i2c_master_send(c,buf,4); | 233 | ret=i2c_master_send(c,buf,4); |
234 | buf[5]=5; | 234 | buf[5]=5; |
235 | ret=i2c_master_send(c,buf+5,4); | 235 | ret=i2c_master_send(c,buf+5,4); |
236 | buf[11]=11; | 236 | buf[11]=11; |
237 | ret=i2c_master_send(c,buf+11,3); | 237 | ret=i2c_master_send(c,buf+11,3); |
238 | if(ret!=3) | 238 | if(ret!=3) |
239 | tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret); | 239 | tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret); |
240 | 240 | ||
241 | // wait for PLLs to lock (per manual), retry LINT if not. | 241 | // wait for PLLs to lock (per manual), retry LINT if not. |
@@ -253,7 +253,7 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin, | |||
253 | mdelay(10); | 253 | mdelay(10); |
254 | buf[1]=8+t->xogc; | 254 | buf[1]=8+t->xogc; |
255 | i2c_master_send(c,buf,2); | 255 | i2c_master_send(c,buf,2); |
256 | } | 256 | } |
257 | 257 | ||
258 | if (lock!=6) | 258 | if (lock!=6) |
259 | tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n"); | 259 | tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n"); |
@@ -284,7 +284,7 @@ static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
284 | if2 = 38900*1000; | 284 | if2 = 38900*1000; |
285 | } | 285 | } |
286 | 286 | ||
287 | mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */, | 287 | mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */, |
288 | 1090*1000*1000, if2, from, to); | 288 | 1090*1000*1000, if2, from, to); |
289 | } | 289 | } |
290 | 290 | ||
@@ -294,7 +294,7 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
294 | int if2 = t->radio_if2; | 294 | int if2 = t->radio_if2; |
295 | 295 | ||
296 | // per Manual for FM tuning: first if center freq. 1085 MHz | 296 | // per Manual for FM tuning: first if center freq. 1085 MHz |
297 | mt2032_set_if_freq(c, freq * 1000 / 16, | 297 | mt2032_set_if_freq(c, freq * 1000 / 16, |
298 | 1085*1000*1000,if2,if2,if2); | 298 | 1085*1000*1000,if2,if2,if2); |
299 | } | 299 | } |
300 | 300 | ||
@@ -302,57 +302,57 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
302 | static int mt2032_init(struct i2c_client *c) | 302 | static int mt2032_init(struct i2c_client *c) |
303 | { | 303 | { |
304 | struct tuner *t = i2c_get_clientdata(c); | 304 | struct tuner *t = i2c_get_clientdata(c); |
305 | unsigned char buf[21]; | 305 | unsigned char buf[21]; |
306 | int ret,xogc,xok=0; | 306 | int ret,xogc,xok=0; |
307 | 307 | ||
308 | // Initialize Registers per spec. | 308 | // Initialize Registers per spec. |
309 | buf[1]=2; // Index to register 2 | 309 | buf[1]=2; // Index to register 2 |
310 | buf[2]=0xff; | 310 | buf[2]=0xff; |
311 | buf[3]=0x0f; | 311 | buf[3]=0x0f; |
312 | buf[4]=0x1f; | 312 | buf[4]=0x1f; |
313 | ret=i2c_master_send(c,buf+1,4); | 313 | ret=i2c_master_send(c,buf+1,4); |
314 | 314 | ||
315 | buf[5]=6; // Index register 6 | 315 | buf[5]=6; // Index register 6 |
316 | buf[6]=0xe4; | 316 | buf[6]=0xe4; |
317 | buf[7]=0x8f; | 317 | buf[7]=0x8f; |
318 | buf[8]=0xc3; | 318 | buf[8]=0xc3; |
319 | buf[9]=0x4e; | 319 | buf[9]=0x4e; |
320 | buf[10]=0xec; | 320 | buf[10]=0xec; |
321 | ret=i2c_master_send(c,buf+5,6); | 321 | ret=i2c_master_send(c,buf+5,6); |
322 | 322 | ||
323 | buf[12]=13; // Index register 13 | 323 | buf[12]=13; // Index register 13 |
324 | buf[13]=0x32; | 324 | buf[13]=0x32; |
325 | ret=i2c_master_send(c,buf+12,2); | 325 | ret=i2c_master_send(c,buf+12,2); |
326 | 326 | ||
327 | // Adjust XOGC (register 7), wait for XOK | 327 | // Adjust XOGC (register 7), wait for XOK |
328 | xogc=7; | 328 | xogc=7; |
329 | do { | 329 | do { |
330 | tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); | 330 | tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); |
331 | mdelay(10); | 331 | mdelay(10); |
332 | buf[0]=0x0e; | 332 | buf[0]=0x0e; |
333 | i2c_master_send(c,buf,1); | 333 | i2c_master_send(c,buf,1); |
334 | i2c_master_recv(c,buf,1); | 334 | i2c_master_recv(c,buf,1); |
335 | xok=buf[0]&0x01; | 335 | xok=buf[0]&0x01; |
336 | tuner_dbg("mt2032: xok = 0x%02x\n",xok); | 336 | tuner_dbg("mt2032: xok = 0x%02x\n",xok); |
337 | if (xok == 1) break; | 337 | if (xok == 1) break; |
338 | 338 | ||
339 | xogc--; | 339 | xogc--; |
340 | tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); | 340 | tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); |
341 | if (xogc == 3) { | 341 | if (xogc == 3) { |
342 | xogc=4; // min. 4 per spec | 342 | xogc=4; // min. 4 per spec |
343 | break; | 343 | break; |
344 | } | 344 | } |
345 | buf[0]=0x07; | 345 | buf[0]=0x07; |
346 | buf[1]=0x88 + xogc; | 346 | buf[1]=0x88 + xogc; |
347 | ret=i2c_master_send(c,buf,2); | 347 | ret=i2c_master_send(c,buf,2); |
348 | if (ret!=2) | 348 | if (ret!=2) |
349 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret); | 349 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret); |
350 | } while (xok != 1 ); | 350 | } while (xok != 1 ); |
351 | t->xogc=xogc; | 351 | t->xogc=xogc; |
352 | 352 | ||
353 | t->tv_freq = mt2032_set_tv_freq; | 353 | t->tv_freq = mt2032_set_tv_freq; |
354 | t->radio_freq = mt2032_set_radio_freq; | 354 | t->radio_freq = mt2032_set_radio_freq; |
355 | return(1); | 355 | return(1); |
356 | } | 356 | } |
357 | 357 | ||
358 | static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna) | 358 | static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna) |
@@ -426,7 +426,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned | |||
426 | } | 426 | } |
427 | 427 | ||
428 | ret=i2c_master_send(c,buf,6); | 428 | ret=i2c_master_send(c,buf,6); |
429 | if (ret!=6) | 429 | if (ret!=6) |
430 | tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret); | 430 | tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret); |
431 | } | 431 | } |
432 | 432 | ||
@@ -437,11 +437,11 @@ static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
437 | 437 | ||
438 | if (t->std & V4L2_STD_525_60) { | 438 | if (t->std & V4L2_STD_525_60) { |
439 | // NTSC | 439 | // NTSC |
440 | if2 = 45750*1000; | 440 | if2 = 45750*1000; |
441 | } else { | 441 | } else { |
442 | // PAL | 442 | // PAL |
443 | if2 = 38900*1000; | 443 | if2 = 38900*1000; |
444 | } | 444 | } |
445 | if (V4L2_TUNER_DIGITAL_TV == t->mode) { | 445 | if (V4L2_TUNER_DIGITAL_TV == t->mode) { |
446 | // DVB (pinnacle 300i) | 446 | // DVB (pinnacle 300i) |
447 | if2 = 36150*1000; | 447 | if2 = 36150*1000; |
@@ -455,7 +455,7 @@ static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
455 | struct tuner *t = i2c_get_clientdata(c); | 455 | struct tuner *t = i2c_get_clientdata(c); |
456 | int if2 = t->radio_if2; | 456 | int if2 = t->radio_if2; |
457 | 457 | ||
458 | mt2050_set_if_freq(c, freq*62500, if2); | 458 | mt2050_set_if_freq(c, freq * 1000 / 16, if2); |
459 | mt2050_set_antenna(c, radio_antenna); | 459 | mt2050_set_antenna(c, radio_antenna); |
460 | } | 460 | } |
461 | 461 | ||
@@ -487,7 +487,7 @@ int microtune_init(struct i2c_client *c) | |||
487 | { | 487 | { |
488 | struct tuner *t = i2c_get_clientdata(c); | 488 | struct tuner *t = i2c_get_clientdata(c); |
489 | char *name; | 489 | char *name; |
490 | unsigned char buf[21]; | 490 | unsigned char buf[21]; |
491 | int company_code; | 491 | int company_code; |
492 | 492 | ||
493 | memset(buf,0,sizeof(buf)); | 493 | memset(buf,0,sizeof(buf)); |
@@ -496,17 +496,17 @@ int microtune_init(struct i2c_client *c) | |||
496 | t->standby = NULL; | 496 | t->standby = NULL; |
497 | name = "unknown"; | 497 | name = "unknown"; |
498 | 498 | ||
499 | i2c_master_send(c,buf,1); | 499 | i2c_master_send(c,buf,1); |
500 | i2c_master_recv(c,buf,21); | 500 | i2c_master_recv(c,buf,21); |
501 | if (tuner_debug) { | 501 | if (tuner_debug) { |
502 | int i; | 502 | int i; |
503 | tuner_dbg("MT20xx hexdump:"); | 503 | tuner_dbg("MT20xx hexdump:"); |
504 | for(i=0;i<21;i++) { | 504 | for(i=0;i<21;i++) { |
505 | printk(" %02x",buf[i]); | 505 | printk(" %02x",buf[i]); |
506 | if(((i+1)%8)==0) printk(" "); | 506 | if(((i+1)%8)==0) printk(" "); |
507 | } | 507 | } |
508 | printk("\n"); | 508 | printk("\n"); |
509 | } | 509 | } |
510 | company_code = buf[0x11] << 8 | buf[0x12]; | 510 | company_code = buf[0x11] << 8 | buf[0x12]; |
511 | tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n", | 511 | tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n", |
512 | company_code,buf[0x13],buf[0x14]); | 512 | company_code,buf[0x13],buf[0x14]); |
@@ -525,8 +525,8 @@ int microtune_init(struct i2c_client *c) | |||
525 | default: | 525 | default: |
526 | tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n", | 526 | tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n", |
527 | name); | 527 | name); |
528 | return 0; | 528 | return 0; |
529 | } | 529 | } |
530 | 530 | ||
531 | strlcpy(c->name, name, sizeof(c->name)); | 531 | strlcpy(c->name, name, sizeof(c->name)); |
532 | tuner_info("microtune %s found, OK\n",name); | 532 | tuner_info("microtune %s found, OK\n",name); |
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c index 72b70eb5da1d..dca3ddfd510f 100644 --- a/drivers/media/video/saa6588.c +++ b/drivers/media/video/saa6588.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/wait.h> | 31 | #include <linux/wait.h> |
32 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
33 | 33 | ||
34 | #include <media/id.h> | ||
35 | 34 | ||
36 | #include "rds.h" | 35 | #include "rds.h" |
37 | 36 | ||
@@ -246,7 +245,7 @@ static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf) | |||
246 | s->wr_index = 0; | 245 | s->wr_index = 0; |
247 | 246 | ||
248 | if (s->wr_index == s->rd_index) { | 247 | if (s->wr_index == s->rd_index) { |
249 | s->rd_index++; | 248 | s->rd_index += 3; |
250 | if (s->rd_index >= s->buf_size) | 249 | if (s->rd_index >= s->buf_size) |
251 | s->rd_index = 0; | 250 | s->rd_index = 0; |
252 | } else | 251 | } else |
@@ -328,7 +327,7 @@ static void saa6588_work(void *data) | |||
328 | struct saa6588 *s = (struct saa6588 *)data; | 327 | struct saa6588 *s = (struct saa6588 *)data; |
329 | 328 | ||
330 | saa6588_i2c_poll(s); | 329 | saa6588_i2c_poll(s); |
331 | mod_timer(&s->timer, jiffies + HZ / 50); /* 20 msec */ | 330 | mod_timer(&s->timer, jiffies + msecs_to_jiffies(20)); |
332 | } | 331 | } |
333 | 332 | ||
334 | static int saa6588_configure(struct saa6588 *s) | 333 | static int saa6588_configure(struct saa6588 *s) |
@@ -434,9 +433,9 @@ static int saa6588_probe(struct i2c_adapter *adap) | |||
434 | return i2c_probe(adap, &addr_data, saa6588_attach); | 433 | return i2c_probe(adap, &addr_data, saa6588_attach); |
435 | #else | 434 | #else |
436 | switch (adap->id) { | 435 | switch (adap->id) { |
437 | case I2C_ALGO_BIT | I2C_HW_B_BT848: | 436 | case I2C_HW_B_BT848: |
438 | case I2C_ALGO_BIT | I2C_HW_B_RIVA: | 437 | case I2C_HW_B_RIVA: |
439 | case I2C_ALGO_SAA7134: | 438 | case I2C_HW_SAA7134: |
440 | return i2c_probe(adap, &addr_data, saa6588_attach); | 439 | return i2c_probe(adap, &addr_data, saa6588_attach); |
441 | break; | 440 | break; |
442 | } | 441 | } |
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c new file mode 100644 index 000000000000..9aa8827de2c3 --- /dev/null +++ b/drivers/media/video/saa711x.c | |||
@@ -0,0 +1,593 @@ | |||
1 | /* | ||
2 | * saa711x - Philips SAA711x video decoder driver version 0.0.1 | ||
3 | * | ||
4 | * To do: Now, it handles only saa7113/7114. Should be improved to | ||
5 | * handle all Philips saa711x devices. | ||
6 | * | ||
7 | * Based on saa7113 driver from Dave Perks <dperks@ibm.net> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/fs.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/major.h> | ||
31 | #include <linux/slab.h> | ||
32 | #include <linux/mm.h> | ||
33 | #include <linux/pci.h> | ||
34 | #include <linux/signal.h> | ||
35 | #include <asm/io.h> | ||
36 | #include <asm/pgtable.h> | ||
37 | #include <asm/page.h> | ||
38 | #include <linux/sched.h> | ||
39 | #include <asm/segment.h> | ||
40 | #include <linux/types.h> | ||
41 | #include <asm/uaccess.h> | ||
42 | #include <linux/videodev.h> | ||
43 | |||
44 | MODULE_DESCRIPTION("Philips SAA711x video decoder driver"); | ||
45 | MODULE_AUTHOR("Dave Perks, Jose Ignacio Gijon, Joerg Heckenbach, Mark McClelland, Dwaine Garden"); | ||
46 | MODULE_LICENSE("GPL"); | ||
47 | |||
48 | #include <linux/i2c.h> | ||
49 | #include <linux/i2c-dev.h> | ||
50 | |||
51 | #define I2C_NAME(s) (s)->name | ||
52 | |||
53 | #include <linux/video_decoder.h> | ||
54 | |||
55 | static int debug = 0; | ||
56 | MODULE_PARM(debug, "i"); | ||
57 | MODULE_PARM_DESC(debug, " Set the default Debug level. Default: 0 (Off) - (0-1)"); | ||
58 | |||
59 | |||
60 | #define dprintk(num, format, args...) \ | ||
61 | do { \ | ||
62 | if (debug >= num) \ | ||
63 | printk(format , ##args); \ | ||
64 | } while (0) | ||
65 | |||
66 | /* ----------------------------------------------------------------------- */ | ||
67 | |||
68 | struct saa711x { | ||
69 | unsigned char reg[32]; | ||
70 | |||
71 | int norm; | ||
72 | int input; | ||
73 | int enable; | ||
74 | int bright; | ||
75 | int contrast; | ||
76 | int hue; | ||
77 | int sat; | ||
78 | }; | ||
79 | |||
80 | #define I2C_SAA7113 0x4A | ||
81 | #define I2C_SAA7114 0x42 | ||
82 | |||
83 | /* ----------------------------------------------------------------------- */ | ||
84 | |||
85 | static inline int | ||
86 | saa711x_write (struct i2c_client *client, | ||
87 | u8 reg, | ||
88 | u8 value) | ||
89 | { | ||
90 | struct saa711x *decoder = i2c_get_clientdata(client); | ||
91 | |||
92 | decoder->reg[reg] = value; | ||
93 | return i2c_smbus_write_byte_data(client, reg, value); | ||
94 | } | ||
95 | |||
96 | static int | ||
97 | saa711x_write_block (struct i2c_client *client, | ||
98 | const u8 *data, | ||
99 | unsigned int len) | ||
100 | { | ||
101 | int ret = -1; | ||
102 | u8 reg; | ||
103 | |||
104 | /* the saa711x has an autoincrement function, use it if | ||
105 | * the adapter understands raw I2C */ | ||
106 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
107 | /* do raw I2C, not smbus compatible */ | ||
108 | struct saa711x *decoder = i2c_get_clientdata(client); | ||
109 | struct i2c_msg msg; | ||
110 | u8 block_data[32]; | ||
111 | |||
112 | msg.addr = client->addr; | ||
113 | msg.flags = 0; | ||
114 | while (len >= 2) { | ||
115 | msg.buf = (char *) block_data; | ||
116 | msg.len = 0; | ||
117 | block_data[msg.len++] = reg = data[0]; | ||
118 | do { | ||
119 | block_data[msg.len++] = | ||
120 | decoder->reg[reg++] = data[1]; | ||
121 | len -= 2; | ||
122 | data += 2; | ||
123 | } while (len >= 2 && data[0] == reg && | ||
124 | msg.len < 32); | ||
125 | if ((ret = i2c_transfer(client->adapter, | ||
126 | &msg, 1)) < 0) | ||
127 | break; | ||
128 | } | ||
129 | } else { | ||
130 | /* do some slow I2C emulation kind of thing */ | ||
131 | while (len >= 2) { | ||
132 | reg = *data++; | ||
133 | if ((ret = saa711x_write(client, reg, | ||
134 | *data++)) < 0) | ||
135 | break; | ||
136 | len -= 2; | ||
137 | } | ||
138 | } | ||
139 | |||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | static int | ||
144 | saa711x_init_decoder (struct i2c_client *client, | ||
145 | struct video_decoder_init *init) | ||
146 | { | ||
147 | return saa711x_write_block(client, init->data, init->len); | ||
148 | } | ||
149 | |||
150 | static inline int | ||
151 | saa711x_read (struct i2c_client *client, | ||
152 | u8 reg) | ||
153 | { | ||
154 | return i2c_smbus_read_byte_data(client, reg); | ||
155 | } | ||
156 | |||
157 | /* ----------------------------------------------------------------------- */ | ||
158 | |||
159 | static const unsigned char saa711x_i2c_init[] = { | ||
160 | 0x00, 0x00, /* PH711x_CHIP_VERSION 00 - ID byte */ | ||
161 | 0x01, 0x08, /* PH711x_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */ | ||
162 | 0x02, 0xc0, /* PH711x_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */ | ||
163 | 0x03, 0x23, /* PH711x_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */ | ||
164 | 0x04, 0x00, /* PH711x_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */ | ||
165 | 0x05, 0x00, /* PH711x_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */ | ||
166 | 0x06, 0xeb, /* PH711x_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */ | ||
167 | 0x07, 0xe0, /* PH711x_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */ | ||
168 | 0x08, 0x88, /* PH711x_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */ | ||
169 | 0x09, 0x00, /* PH711x_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */ | ||
170 | 0x0a, 0x80, /* PH711x_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */ | ||
171 | 0x0b, 0x47, /* PH711x_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */ | ||
172 | 0x0c, 0x40, /* PH711x_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */ | ||
173 | 0x0d, 0x00, /* PH711x_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */ | ||
174 | 0x0e, 0x01, /* PH711x_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */ | ||
175 | 0x0f, 0xaa, /* PH711x_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */ | ||
176 | 0x10, 0x00, /* PH711x_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */ | ||
177 | 0x11, 0x1C, /* PH711x_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */ | ||
178 | 0x12, 0x01, /* PH711x_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */ | ||
179 | 0x13, 0x00, /* PH711x_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */ | ||
180 | 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */ | ||
181 | 0x15, 0x00, /* PH711x_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */ | ||
182 | 0x16, 0x00, /* PH711x_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */ | ||
183 | 0x17, 0x00, /* PH711x_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */ | ||
184 | }; | ||
185 | |||
186 | static int | ||
187 | saa711x_command (struct i2c_client *client, | ||
188 | unsigned int cmd, | ||
189 | void *arg) | ||
190 | { | ||
191 | struct saa711x *decoder = i2c_get_clientdata(client); | ||
192 | |||
193 | switch (cmd) { | ||
194 | |||
195 | case 0: | ||
196 | case DECODER_INIT: | ||
197 | { | ||
198 | struct video_decoder_init *init = arg; | ||
199 | if (NULL != init) | ||
200 | return saa711x_init_decoder(client, init); | ||
201 | else { | ||
202 | struct video_decoder_init vdi; | ||
203 | vdi.data = saa711x_i2c_init; | ||
204 | vdi.len = sizeof(saa711x_i2c_init); | ||
205 | return saa711x_init_decoder(client, &vdi); | ||
206 | } | ||
207 | } | ||
208 | |||
209 | case DECODER_DUMP: | ||
210 | { | ||
211 | int i; | ||
212 | |||
213 | for (i = 0; i < 32; i += 16) { | ||
214 | int j; | ||
215 | |||
216 | printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i); | ||
217 | for (j = 0; j < 16; ++j) { | ||
218 | printk(" %02x", | ||
219 | saa711x_read(client, i + j)); | ||
220 | } | ||
221 | printk("\n"); | ||
222 | } | ||
223 | } | ||
224 | break; | ||
225 | |||
226 | case DECODER_GET_CAPABILITIES: | ||
227 | { | ||
228 | struct video_decoder_capability *cap = arg; | ||
229 | |||
230 | cap->flags = VIDEO_DECODER_PAL | | ||
231 | VIDEO_DECODER_NTSC | | ||
232 | VIDEO_DECODER_SECAM | | ||
233 | VIDEO_DECODER_AUTO | | ||
234 | VIDEO_DECODER_CCIR; | ||
235 | cap->inputs = 8; | ||
236 | cap->outputs = 1; | ||
237 | } | ||
238 | break; | ||
239 | |||
240 | case DECODER_GET_STATUS: | ||
241 | { | ||
242 | int *iarg = arg; | ||
243 | int status; | ||
244 | int res; | ||
245 | |||
246 | status = saa711x_read(client, 0x1f); | ||
247 | dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client), | ||
248 | status); | ||
249 | res = 0; | ||
250 | if ((status & (1 << 6)) == 0) { | ||
251 | res |= DECODER_STATUS_GOOD; | ||
252 | } | ||
253 | switch (decoder->norm) { | ||
254 | case VIDEO_MODE_NTSC: | ||
255 | res |= DECODER_STATUS_NTSC; | ||
256 | break; | ||
257 | case VIDEO_MODE_PAL: | ||
258 | res |= DECODER_STATUS_PAL; | ||
259 | break; | ||
260 | case VIDEO_MODE_SECAM: | ||
261 | res |= DECODER_STATUS_SECAM; | ||
262 | break; | ||
263 | default: | ||
264 | case VIDEO_MODE_AUTO: | ||
265 | if ((status & (1 << 5)) != 0) { | ||
266 | res |= DECODER_STATUS_NTSC; | ||
267 | } else { | ||
268 | res |= DECODER_STATUS_PAL; | ||
269 | } | ||
270 | break; | ||
271 | } | ||
272 | if ((status & (1 << 0)) != 0) { | ||
273 | res |= DECODER_STATUS_COLOR; | ||
274 | } | ||
275 | *iarg = res; | ||
276 | } | ||
277 | break; | ||
278 | |||
279 | case DECODER_SET_GPIO: | ||
280 | { | ||
281 | int *iarg = arg; | ||
282 | if (0 != *iarg) { | ||
283 | saa711x_write(client, 0x11, | ||
284 | (decoder->reg[0x11] | 0x80)); | ||
285 | } else { | ||
286 | saa711x_write(client, 0x11, | ||
287 | (decoder->reg[0x11] & 0x7f)); | ||
288 | } | ||
289 | break; | ||
290 | } | ||
291 | |||
292 | case DECODER_SET_VBI_BYPASS: | ||
293 | { | ||
294 | int *iarg = arg; | ||
295 | if (0 != *iarg) { | ||
296 | saa711x_write(client, 0x13, | ||
297 | (decoder->reg[0x13] & 0xf0) | 0x0a); | ||
298 | } else { | ||
299 | saa711x_write(client, 0x13, | ||
300 | (decoder->reg[0x13] & 0xf0)); | ||
301 | } | ||
302 | break; | ||
303 | } | ||
304 | |||
305 | case DECODER_SET_NORM: | ||
306 | { | ||
307 | int *iarg = arg; | ||
308 | |||
309 | switch (*iarg) { | ||
310 | |||
311 | case VIDEO_MODE_NTSC: | ||
312 | saa711x_write(client, 0x08, | ||
313 | (decoder->reg[0x08] & 0x3f) | 0x40); | ||
314 | saa711x_write(client, 0x0e, | ||
315 | (decoder->reg[0x0e] & 0x8f)); | ||
316 | break; | ||
317 | |||
318 | case VIDEO_MODE_PAL: | ||
319 | saa711x_write(client, 0x08, | ||
320 | (decoder->reg[0x08] & 0x3f) | 0x00); | ||
321 | saa711x_write(client, 0x0e, | ||
322 | (decoder->reg[0x0e] & 0x8f)); | ||
323 | break; | ||
324 | |||
325 | case VIDEO_MODE_SECAM: | ||
326 | saa711x_write(client, 0x08, | ||
327 | (decoder->reg[0x0e] & 0x3f) | 0x00); | ||
328 | saa711x_write(client, 0x0e, | ||
329 | (decoder->reg[0x0e] & 0x8f) | 0x50); | ||
330 | break; | ||
331 | |||
332 | case VIDEO_MODE_AUTO: | ||
333 | saa711x_write(client, 0x08, | ||
334 | (decoder->reg[0x08] & 0x3f) | 0x80); | ||
335 | saa711x_write(client, 0x0e, | ||
336 | (decoder->reg[0x0e] & 0x8f)); | ||
337 | break; | ||
338 | |||
339 | default: | ||
340 | return -EINVAL; | ||
341 | |||
342 | } | ||
343 | decoder->norm = *iarg; | ||
344 | } | ||
345 | break; | ||
346 | |||
347 | case DECODER_SET_INPUT: | ||
348 | { | ||
349 | int *iarg = arg; | ||
350 | if (*iarg < 0 || *iarg > 9) { | ||
351 | return -EINVAL; | ||
352 | } | ||
353 | if (decoder->input != *iarg) { | ||
354 | decoder->input = *iarg; | ||
355 | /* select mode */ | ||
356 | saa711x_write(client, 0x02, | ||
357 | (decoder->reg[0x02] & 0xf0) | decoder->input); | ||
358 | /* bypass chrominance trap for modes 4..7 */ | ||
359 | saa711x_write(client, 0x09, | ||
360 | (decoder->reg[0x09] & 0x7f) | ((decoder->input > 3) ? 0x80 : 0)); | ||
361 | } | ||
362 | } | ||
363 | break; | ||
364 | |||
365 | case DECODER_SET_OUTPUT: | ||
366 | { | ||
367 | int *iarg = arg; | ||
368 | |||
369 | /* not much choice of outputs */ | ||
370 | if (*iarg != 0) { | ||
371 | return -EINVAL; | ||
372 | } | ||
373 | } | ||
374 | break; | ||
375 | |||
376 | case DECODER_ENABLE_OUTPUT: | ||
377 | { | ||
378 | int *iarg = arg; | ||
379 | int enable = (*iarg != 0); | ||
380 | |||
381 | if (decoder->enable != enable) { | ||
382 | decoder->enable = enable; | ||
383 | |||
384 | /* RJ: If output should be disabled (for | ||
385 | * playing videos), we also need a open PLL. | ||
386 | * The input is set to 0 (where no input | ||
387 | * source is connected), although this | ||
388 | * is not necessary. | ||
389 | * | ||
390 | * If output should be enabled, we have to | ||
391 | * reverse the above. | ||
392 | */ | ||
393 | |||
394 | if (decoder->enable) { | ||
395 | saa711x_write(client, 0x02, | ||
396 | (decoder-> | ||
397 | reg[0x02] & 0xf8) | | ||
398 | decoder->input); | ||
399 | saa711x_write(client, 0x08, | ||
400 | (decoder->reg[0x08] & 0xfb)); | ||
401 | saa711x_write(client, 0x11, | ||
402 | (decoder-> | ||
403 | reg[0x11] & 0xf3) | 0x0c); | ||
404 | } else { | ||
405 | saa711x_write(client, 0x02, | ||
406 | (decoder->reg[0x02] & 0xf8)); | ||
407 | saa711x_write(client, 0x08, | ||
408 | (decoder-> | ||
409 | reg[0x08] & 0xfb) | 0x04); | ||
410 | saa711x_write(client, 0x11, | ||
411 | (decoder->reg[0x11] & 0xf3)); | ||
412 | } | ||
413 | } | ||
414 | } | ||
415 | break; | ||
416 | |||
417 | case DECODER_SET_PICTURE: | ||
418 | { | ||
419 | struct video_picture *pic = arg; | ||
420 | |||
421 | if (decoder->bright != pic->brightness) { | ||
422 | /* We want 0 to 255 we get 0-65535 */ | ||
423 | decoder->bright = pic->brightness; | ||
424 | saa711x_write(client, 0x0a, decoder->bright >> 8); | ||
425 | } | ||
426 | if (decoder->contrast != pic->contrast) { | ||
427 | /* We want 0 to 127 we get 0-65535 */ | ||
428 | decoder->contrast = pic->contrast; | ||
429 | saa711x_write(client, 0x0b, | ||
430 | decoder->contrast >> 9); | ||
431 | } | ||
432 | if (decoder->sat != pic->colour) { | ||
433 | /* We want 0 to 127 we get 0-65535 */ | ||
434 | decoder->sat = pic->colour; | ||
435 | saa711x_write(client, 0x0c, decoder->sat >> 9); | ||
436 | } | ||
437 | if (decoder->hue != pic->hue) { | ||
438 | /* We want -128 to 127 we get 0-65535 */ | ||
439 | decoder->hue = pic->hue; | ||
440 | saa711x_write(client, 0x0d, | ||
441 | (decoder->hue - 32768) >> 8); | ||
442 | } | ||
443 | } | ||
444 | break; | ||
445 | |||
446 | default: | ||
447 | return -EINVAL; | ||
448 | } | ||
449 | |||
450 | return 0; | ||
451 | } | ||
452 | |||
453 | /* ----------------------------------------------------------------------- */ | ||
454 | |||
455 | /* | ||
456 | * Generic i2c probe | ||
457 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | ||
458 | */ | ||
459 | |||
460 | /* standard i2c insmod options */ | ||
461 | static unsigned short normal_i2c[] = { | ||
462 | I2C_SAA7113>>1, /* saa7113 */ | ||
463 | I2C_SAA7114>>1, /* saa7114 */ | ||
464 | I2C_CLIENT_END | ||
465 | }; | ||
466 | |||
467 | I2C_CLIENT_INSMOD; | ||
468 | |||
469 | |||
470 | static struct i2c_driver i2c_driver_saa711x; | ||
471 | |||
472 | static int | ||
473 | saa711x_detect_client (struct i2c_adapter *adapter, | ||
474 | int address, | ||
475 | int kind) | ||
476 | { | ||
477 | int i; | ||
478 | struct i2c_client *client; | ||
479 | struct saa711x *decoder; | ||
480 | struct video_decoder_init vdi; | ||
481 | |||
482 | dprintk(1, | ||
483 | KERN_INFO | ||
484 | "saa711x.c: detecting saa711x client on address 0x%x\n", | ||
485 | address << 1); | ||
486 | |||
487 | /* Check if the adapter supports the needed features */ | ||
488 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
489 | return 0; | ||
490 | |||
491 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
492 | if (client == 0) | ||
493 | return -ENOMEM; | ||
494 | memset(client, 0, sizeof(struct i2c_client)); | ||
495 | client->addr = address; | ||
496 | client->adapter = adapter; | ||
497 | client->driver = &i2c_driver_saa711x; | ||
498 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
499 | strlcpy(I2C_NAME(client), "saa711x", sizeof(I2C_NAME(client))); | ||
500 | decoder = kmalloc(sizeof(struct saa711x), GFP_KERNEL); | ||
501 | if (decoder == NULL) { | ||
502 | kfree(client); | ||
503 | return -ENOMEM; | ||
504 | } | ||
505 | memset(decoder, 0, sizeof(struct saa711x)); | ||
506 | decoder->norm = VIDEO_MODE_NTSC; | ||
507 | decoder->input = 0; | ||
508 | decoder->enable = 1; | ||
509 | decoder->bright = 32768; | ||
510 | decoder->contrast = 32768; | ||
511 | decoder->hue = 32768; | ||
512 | decoder->sat = 32768; | ||
513 | i2c_set_clientdata(client, decoder); | ||
514 | |||
515 | i = i2c_attach_client(client); | ||
516 | if (i) { | ||
517 | kfree(client); | ||
518 | kfree(decoder); | ||
519 | return i; | ||
520 | } | ||
521 | |||
522 | vdi.data = saa711x_i2c_init; | ||
523 | vdi.len = sizeof(saa711x_i2c_init); | ||
524 | i = saa711x_init_decoder(client, &vdi); | ||
525 | if (i < 0) { | ||
526 | dprintk(1, KERN_ERR "%s_attach error: init status %d\n", | ||
527 | I2C_NAME(client), i); | ||
528 | } else { | ||
529 | dprintk(1, | ||
530 | KERN_INFO | ||
531 | "%s_attach: chip version %x at address 0x%x\n", | ||
532 | I2C_NAME(client), saa711x_read(client, 0x00) >> 4, | ||
533 | client->addr << 1); | ||
534 | } | ||
535 | |||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | static int | ||
540 | saa711x_attach_adapter (struct i2c_adapter *adapter) | ||
541 | { | ||
542 | dprintk(1, | ||
543 | KERN_INFO | ||
544 | "saa711x.c: starting probe for adapter %s (0x%x)\n", | ||
545 | I2C_NAME(adapter), adapter->id); | ||
546 | return i2c_probe(adapter, &addr_data, &saa711x_detect_client); | ||
547 | } | ||
548 | |||
549 | static int | ||
550 | saa711x_detach_client (struct i2c_client *client) | ||
551 | { | ||
552 | struct saa711x *decoder = i2c_get_clientdata(client); | ||
553 | int err; | ||
554 | |||
555 | err = i2c_detach_client(client); | ||
556 | if (err) { | ||
557 | return err; | ||
558 | } | ||
559 | |||
560 | kfree(decoder); | ||
561 | kfree(client); | ||
562 | |||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | /* ----------------------------------------------------------------------- */ | ||
567 | |||
568 | static struct i2c_driver i2c_driver_saa711x = { | ||
569 | .owner = THIS_MODULE, | ||
570 | .name = "saa711x", | ||
571 | |||
572 | .id = I2C_DRIVERID_SAA711X, | ||
573 | .flags = I2C_DF_NOTIFY, | ||
574 | |||
575 | .attach_adapter = saa711x_attach_adapter, | ||
576 | .detach_client = saa711x_detach_client, | ||
577 | .command = saa711x_command, | ||
578 | }; | ||
579 | |||
580 | static int __init | ||
581 | saa711x_init (void) | ||
582 | { | ||
583 | return i2c_add_driver(&i2c_driver_saa711x); | ||
584 | } | ||
585 | |||
586 | static void __exit | ||
587 | saa711x_exit (void) | ||
588 | { | ||
589 | i2c_del_driver(&i2c_driver_saa711x); | ||
590 | } | ||
591 | |||
592 | module_init(saa711x_init); | ||
593 | module_exit(saa711x_exit); | ||
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig new file mode 100644 index 000000000000..624e8808a517 --- /dev/null +++ b/drivers/media/video/saa7134/Kconfig | |||
@@ -0,0 +1,68 @@ | |||
1 | config VIDEO_SAA7134 | ||
2 | tristate "Philips SAA7134 support" | ||
3 | depends on VIDEO_DEV && PCI && I2C && SOUND | ||
4 | select VIDEO_BUF | ||
5 | select VIDEO_IR | ||
6 | select VIDEO_TUNER | ||
7 | select CRC32 | ||
8 | ---help--- | ||
9 | This is a video4linux driver for Philips SAA713x based | ||
10 | TV cards. | ||
11 | |||
12 | To compile this driver as a module, choose M here: the | ||
13 | module will be called saa7134. | ||
14 | |||
15 | config VIDEO_SAA7134_DVB | ||
16 | tristate "DVB/ATSC Support for saa7134 based TV cards" | ||
17 | depends on VIDEO_SAA7134 && DVB_CORE | ||
18 | select VIDEO_BUF_DVB | ||
19 | ---help--- | ||
20 | This adds support for DVB cards based on the | ||
21 | Philips saa7134 chip. | ||
22 | |||
23 | To compile this driver as a module, choose M here: the | ||
24 | module will be called saa7134-dvb. | ||
25 | |||
26 | You must also select one or more DVB demodulators. | ||
27 | If you are unsure which you need, choose all of them. | ||
28 | |||
29 | config VIDEO_SAA7134_DVB_ALL_FRONTENDS | ||
30 | bool "Build all supported frontends for saa7134 based TV cards" | ||
31 | default y | ||
32 | depends on VIDEO_SAA7134_DVB | ||
33 | select DVB_MT352 | ||
34 | select DVB_TDA1004X | ||
35 | select DVB_NXT200X | ||
36 | ---help--- | ||
37 | This builds saa7134-dvb with all currently supported frontend | ||
38 | demodulators. If you wish to tweak your configuration, and | ||
39 | only include support for the hardware that you need, choose N here. | ||
40 | |||
41 | If you are unsure, choose Y. | ||
42 | |||
43 | config VIDEO_SAA7134_DVB_MT352 | ||
44 | tristate "Zarlink MT352 DVB-T Support" | ||
45 | default m | ||
46 | depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS | ||
47 | select DVB_MT352 | ||
48 | ---help--- | ||
49 | This adds DVB-T support for cards based on the | ||
50 | Philips saa7134 chip and the MT352 demodulator. | ||
51 | |||
52 | config VIDEO_SAA7134_DVB_TDA1004X | ||
53 | tristate "Phillips TDA10045H/TDA10046H DVB-T Support" | ||
54 | default m | ||
55 | depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS | ||
56 | select DVB_TDA1004X | ||
57 | ---help--- | ||
58 | This adds DVB-T support for cards based on the | ||
59 | Philips saa7134 chip and the TDA10045H/TDA10046H demodulator. | ||
60 | |||
61 | config VIDEO_SAA7134_DVB_NXT200X | ||
62 | tristate "NXT2002/NXT2004 ATSC Support" | ||
63 | default m | ||
64 | depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS | ||
65 | select DVB_NXT200X | ||
66 | ---help--- | ||
67 | This adds ATSC 8VSB and QAM64/256 support for cards based on the | ||
68 | Philips saa7134 chip and the NXT2002/NXT2004 demodulator. | ||
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile index b778ffd94e65..e0b28f0533af 100644 --- a/drivers/media/video/saa7134/Makefile +++ b/drivers/media/video/saa7134/Makefile | |||
@@ -3,15 +3,22 @@ saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \ | |||
3 | saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \ | 3 | saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \ |
4 | saa7134-vbi.o saa7134-video.o saa7134-input.o | 4 | saa7134-vbi.o saa7134-video.o saa7134-input.o |
5 | 5 | ||
6 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o saa6752hs.o | 6 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \ |
7 | saa6752hs.o saa7134-alsa.o | ||
7 | obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o | 8 | obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o |
8 | 9 | ||
9 | EXTRA_CFLAGS += -I$(src)/.. | 10 | EXTRA_CFLAGS += -I$(src)/.. |
10 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 11 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core |
11 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends | 12 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends |
13 | ifneq ($(CONFIG_VIDEO_BUF_DVB),n) | ||
14 | EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1 | ||
15 | endif | ||
12 | ifneq ($(CONFIG_DVB_MT352),n) | 16 | ifneq ($(CONFIG_DVB_MT352),n) |
13 | EXTRA_CFLAGS += -DHAVE_MT352=1 | 17 | EXTRA_CFLAGS += -DHAVE_MT352=1 |
14 | endif | 18 | endif |
15 | ifneq ($(CONFIG_DVB_TDA1004X),n) | 19 | ifneq ($(CONFIG_DVB_TDA1004X),n) |
16 | EXTRA_CFLAGS += -DHAVE_TDA1004X=1 | 20 | EXTRA_CFLAGS += -DHAVE_TDA1004X=1 |
17 | endif | 21 | endif |
22 | ifneq ($(CONFIG_DVB_NXT200X),n) | ||
23 | EXTRA_CFLAGS += -DHAVE_NXT200X=1 | ||
24 | endif | ||
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 382911c6ef22..cdd1ed9c8065 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/crc32.h> | 14 | #include <linux/crc32.h> |
15 | 15 | ||
16 | #include <media/id.h> | ||
17 | 16 | ||
18 | #define MPEG_VIDEO_TARGET_BITRATE_MAX 27000 | 17 | #define MPEG_VIDEO_TARGET_BITRATE_MAX 27000 |
19 | #define MPEG_VIDEO_MAX_BITRATE_MAX 27000 | 18 | #define MPEG_VIDEO_MAX_BITRATE_MAX 27000 |
@@ -57,6 +56,7 @@ struct saa6752hs_state { | |||
57 | struct i2c_client client; | 56 | struct i2c_client client; |
58 | struct v4l2_mpeg_compression params; | 57 | struct v4l2_mpeg_compression params; |
59 | enum saa6752hs_videoformat video_format; | 58 | enum saa6752hs_videoformat video_format; |
59 | v4l2_std_id standard; | ||
60 | }; | 60 | }; |
61 | 61 | ||
62 | enum saa6752hs_command { | 62 | enum saa6752hs_command { |
@@ -74,58 +74,58 @@ enum saa6752hs_command { | |||
74 | /* ---------------------------------------------------------------------- */ | 74 | /* ---------------------------------------------------------------------- */ |
75 | 75 | ||
76 | static u8 PAT[] = { | 76 | static u8 PAT[] = { |
77 | 0xc2, // i2c register | 77 | 0xc2, /* i2c register */ |
78 | 0x00, // table number for encoder | 78 | 0x00, /* table number for encoder */ |
79 | 79 | ||
80 | 0x47, // sync | 80 | 0x47, /* sync */ |
81 | 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) | 81 | 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) */ |
82 | 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) | 82 | 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */ |
83 | 83 | ||
84 | 0x00, // PSI pointer to start of table | 84 | 0x00, /* PSI pointer to start of table */ |
85 | 85 | ||
86 | 0x00, // tid(0) | 86 | 0x00, /* tid(0) */ |
87 | 0xb0, 0x0d, // section_syntax_indicator(1), section_length(13) | 87 | 0xb0, 0x0d, /* section_syntax_indicator(1), section_length(13) */ |
88 | 88 | ||
89 | 0x00, 0x01, // transport_stream_id(1) | 89 | 0x00, 0x01, /* transport_stream_id(1) */ |
90 | 90 | ||
91 | 0xc1, // version_number(0), current_next_indicator(1) | 91 | 0xc1, /* version_number(0), current_next_indicator(1) */ |
92 | 92 | ||
93 | 0x00, 0x00, // section_number(0), last_section_number(0) | 93 | 0x00, 0x00, /* section_number(0), last_section_number(0) */ |
94 | 94 | ||
95 | 0x00, 0x01, // program_number(1) | 95 | 0x00, 0x01, /* program_number(1) */ |
96 | 96 | ||
97 | 0xe0, 0x00, // PMT PID | 97 | 0xe0, 0x00, /* PMT PID */ |
98 | 98 | ||
99 | 0x00, 0x00, 0x00, 0x00 // CRC32 | 99 | 0x00, 0x00, 0x00, 0x00 /* CRC32 */ |
100 | }; | 100 | }; |
101 | 101 | ||
102 | static u8 PMT[] = { | 102 | static u8 PMT[] = { |
103 | 0xc2, // i2c register | 103 | 0xc2, /* i2c register */ |
104 | 0x01, // table number for encoder | 104 | 0x01, /* table number for encoder */ |
105 | 105 | ||
106 | 0x47, // sync | 106 | 0x47, /* sync */ |
107 | 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid | 107 | 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid */ |
108 | 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) | 108 | 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */ |
109 | 109 | ||
110 | 0x00, // PSI pointer to start of table | 110 | 0x00, /* PSI pointer to start of table */ |
111 | 111 | ||
112 | 0x02, // tid(2) | 112 | 0x02, /* tid(2) */ |
113 | 0xb0, 0x17, // section_syntax_indicator(1), section_length(23) | 113 | 0xb0, 0x17, /* section_syntax_indicator(1), section_length(23) */ |
114 | 114 | ||
115 | 0x00, 0x01, // program_number(1) | 115 | 0x00, 0x01, /* program_number(1) */ |
116 | 116 | ||
117 | 0xc1, // version_number(0), current_next_indicator(1) | 117 | 0xc1, /* version_number(0), current_next_indicator(1) */ |
118 | 118 | ||
119 | 0x00, 0x00, // section_number(0), last_section_number(0) | 119 | 0x00, 0x00, /* section_number(0), last_section_number(0) */ |
120 | 120 | ||
121 | 0xe0, 0x00, // PCR_PID | 121 | 0xe0, 0x00, /* PCR_PID */ |
122 | 122 | ||
123 | 0xf0, 0x00, // program_info_length(0) | 123 | 0xf0, 0x00, /* program_info_length(0) */ |
124 | 124 | ||
125 | 0x02, 0xe0, 0x00, 0xf0, 0x00, // video stream type(2), pid | 125 | 0x02, 0xe0, 0x00, 0xf0, 0x00, /* video stream type(2), pid */ |
126 | 0x04, 0xe0, 0x00, 0xf0, 0x00, // audio stream type(4), pid | 126 | 0x04, 0xe0, 0x00, 0xf0, 0x00, /* audio stream type(4), pid */ |
127 | 127 | ||
128 | 0x00, 0x00, 0x00, 0x00 // CRC32 | 128 | 0x00, 0x00, 0x00, 0x00 /* CRC32 */ |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static struct v4l2_mpeg_compression param_defaults = | 131 | static struct v4l2_mpeg_compression param_defaults = |
@@ -166,33 +166,33 @@ static int saa6752hs_chip_command(struct i2c_client* client, | |||
166 | unsigned long timeout; | 166 | unsigned long timeout; |
167 | int status = 0; | 167 | int status = 0; |
168 | 168 | ||
169 | // execute the command | 169 | /* execute the command */ |
170 | switch(command) { | 170 | switch(command) { |
171 | case SAA6752HS_COMMAND_RESET: | 171 | case SAA6752HS_COMMAND_RESET: |
172 | buf[0] = 0x00; | 172 | buf[0] = 0x00; |
173 | break; | 173 | break; |
174 | 174 | ||
175 | case SAA6752HS_COMMAND_STOP: | 175 | case SAA6752HS_COMMAND_STOP: |
176 | buf[0] = 0x03; | 176 | buf[0] = 0x03; |
177 | break; | 177 | break; |
178 | 178 | ||
179 | case SAA6752HS_COMMAND_START: | 179 | case SAA6752HS_COMMAND_START: |
180 | buf[0] = 0x02; | 180 | buf[0] = 0x02; |
181 | break; | 181 | break; |
182 | 182 | ||
183 | case SAA6752HS_COMMAND_PAUSE: | 183 | case SAA6752HS_COMMAND_PAUSE: |
184 | buf[0] = 0x04; | 184 | buf[0] = 0x04; |
185 | break; | 185 | break; |
186 | 186 | ||
187 | case SAA6752HS_COMMAND_RECONFIGURE: | 187 | case SAA6752HS_COMMAND_RECONFIGURE: |
188 | buf[0] = 0x05; | 188 | buf[0] = 0x05; |
189 | break; | 189 | break; |
190 | 190 | ||
191 | case SAA6752HS_COMMAND_SLEEP: | 191 | case SAA6752HS_COMMAND_SLEEP: |
192 | buf[0] = 0x06; | 192 | buf[0] = 0x06; |
193 | break; | 193 | break; |
194 | 194 | ||
195 | case SAA6752HS_COMMAND_RECONFIGURE_FORCE: | 195 | case SAA6752HS_COMMAND_RECONFIGURE_FORCE: |
196 | buf[0] = 0x07; | 196 | buf[0] = 0x07; |
197 | break; | 197 | break; |
198 | 198 | ||
@@ -200,13 +200,13 @@ static int saa6752hs_chip_command(struct i2c_client* client, | |||
200 | return -EINVAL; | 200 | return -EINVAL; |
201 | } | 201 | } |
202 | 202 | ||
203 | // set it and wait for it to be so | 203 | /* set it and wait for it to be so */ |
204 | i2c_master_send(client, buf, 1); | 204 | i2c_master_send(client, buf, 1); |
205 | timeout = jiffies + HZ * 3; | 205 | timeout = jiffies + HZ * 3; |
206 | for (;;) { | 206 | for (;;) { |
207 | // get the current status | 207 | /* get the current status */ |
208 | buf[0] = 0x10; | 208 | buf[0] = 0x10; |
209 | i2c_master_send(client, buf, 1); | 209 | i2c_master_send(client, buf, 1); |
210 | i2c_master_recv(client, buf, 1); | 210 | i2c_master_recv(client, buf, 1); |
211 | 211 | ||
212 | if (!(buf[0] & 0x20)) | 212 | if (!(buf[0] & 0x20)) |
@@ -216,61 +216,58 @@ static int saa6752hs_chip_command(struct i2c_client* client, | |||
216 | break; | 216 | break; |
217 | } | 217 | } |
218 | 218 | ||
219 | // wait a bit | ||
220 | msleep(10); | 219 | msleep(10); |
221 | } | 220 | } |
222 | 221 | ||
223 | // delay a bit to let encoder settle | 222 | /* delay a bit to let encoder settle */ |
224 | msleep(50); | 223 | msleep(50); |
225 | 224 | ||
226 | // done | 225 | return status; |
227 | return status; | ||
228 | } | 226 | } |
229 | 227 | ||
230 | 228 | ||
231 | static int saa6752hs_set_bitrate(struct i2c_client* client, | 229 | static int saa6752hs_set_bitrate(struct i2c_client* client, |
232 | struct v4l2_mpeg_compression* params) | 230 | struct v4l2_mpeg_compression* params) |
233 | { | 231 | { |
234 | u8 buf[3]; | 232 | u8 buf[3]; |
235 | 233 | ||
236 | // set the bitrate mode | 234 | /* set the bitrate mode */ |
237 | buf[0] = 0x71; | 235 | buf[0] = 0x71; |
238 | buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1; | 236 | buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1; |
239 | i2c_master_send(client, buf, 2); | 237 | i2c_master_send(client, buf, 2); |
240 | 238 | ||
241 | // set the video bitrate | 239 | /* set the video bitrate */ |
242 | if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) { | 240 | if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) { |
243 | // set the target bitrate | 241 | /* set the target bitrate */ |
244 | buf[0] = 0x80; | 242 | buf[0] = 0x80; |
245 | buf[1] = params->vi_bitrate.target >> 8; | 243 | buf[1] = params->vi_bitrate.target >> 8; |
246 | buf[2] = params->vi_bitrate.target & 0xff; | 244 | buf[2] = params->vi_bitrate.target & 0xff; |
247 | i2c_master_send(client, buf, 3); | 245 | i2c_master_send(client, buf, 3); |
248 | 246 | ||
249 | // set the max bitrate | 247 | /* set the max bitrate */ |
250 | buf[0] = 0x81; | 248 | buf[0] = 0x81; |
251 | buf[1] = params->vi_bitrate.max >> 8; | 249 | buf[1] = params->vi_bitrate.max >> 8; |
252 | buf[2] = params->vi_bitrate.max & 0xff; | 250 | buf[2] = params->vi_bitrate.max & 0xff; |
253 | i2c_master_send(client, buf, 3); | 251 | i2c_master_send(client, buf, 3); |
254 | } else { | 252 | } else { |
255 | // set the target bitrate (no max bitrate for CBR) | 253 | /* set the target bitrate (no max bitrate for CBR) */ |
256 | buf[0] = 0x81; | 254 | buf[0] = 0x81; |
257 | buf[1] = params->vi_bitrate.target >> 8; | 255 | buf[1] = params->vi_bitrate.target >> 8; |
258 | buf[2] = params->vi_bitrate.target & 0xff; | 256 | buf[2] = params->vi_bitrate.target & 0xff; |
259 | i2c_master_send(client, buf, 3); | 257 | i2c_master_send(client, buf, 3); |
260 | } | 258 | } |
261 | 259 | ||
262 | // set the audio bitrate | 260 | /* set the audio bitrate */ |
263 | buf[0] = 0x94; | 261 | buf[0] = 0x94; |
264 | buf[1] = (256 == params->au_bitrate.target) ? 0 : 1; | 262 | buf[1] = (256 == params->au_bitrate.target) ? 0 : 1; |
265 | i2c_master_send(client, buf, 2); | 263 | i2c_master_send(client, buf, 2); |
266 | 264 | ||
267 | // set the total bitrate | 265 | /* set the total bitrate */ |
268 | buf[0] = 0xb1; | 266 | buf[0] = 0xb1; |
269 | buf[1] = params->st_bitrate.target >> 8; | 267 | buf[1] = params->st_bitrate.target >> 8; |
270 | buf[2] = params->st_bitrate.target & 0xff; | 268 | buf[2] = params->st_bitrate.target & 0xff; |
271 | i2c_master_send(client, buf, 3); | 269 | i2c_master_send(client, buf, 3); |
272 | 270 | ||
273 | // return success | ||
274 | return 0; | 271 | return 0; |
275 | } | 272 | } |
276 | 273 | ||
@@ -376,36 +373,43 @@ static int saa6752hs_init(struct i2c_client* client) | |||
376 | 373 | ||
377 | h = i2c_get_clientdata(client); | 374 | h = i2c_get_clientdata(client); |
378 | 375 | ||
379 | // Set video format - must be done first as it resets other settings | 376 | /* Set video format - must be done first as it resets other settings */ |
380 | buf[0] = 0x41; | 377 | buf[0] = 0x41; |
381 | buf[1] = h->video_format; | 378 | buf[1] = h->video_format; |
382 | i2c_master_send(client, buf, 2); | 379 | i2c_master_send(client, buf, 2); |
383 | 380 | ||
384 | // set bitrate | 381 | /* Set number of lines in input signal */ |
385 | saa6752hs_set_bitrate(client, &h->params); | 382 | buf[0] = 0x40; |
383 | buf[1] = 0x00; | ||
384 | if (h->standard & V4L2_STD_525_60) | ||
385 | buf[1] = 0x01; | ||
386 | i2c_master_send(client, buf, 2); | ||
387 | |||
388 | /* set bitrate */ | ||
389 | saa6752hs_set_bitrate(client, &h->params); | ||
386 | 390 | ||
387 | // Set GOP structure {3, 13} | 391 | /* Set GOP structure {3, 13} */ |
388 | buf[0] = 0x72; | 392 | buf[0] = 0x72; |
389 | buf[1] = 0x03; | 393 | buf[1] = 0x03; |
390 | buf[2] = 0x0D; | 394 | buf[2] = 0x0D; |
391 | i2c_master_send(client,buf,3); | 395 | i2c_master_send(client,buf,3); |
392 | 396 | ||
393 | // Set minimum Q-scale {4} | 397 | /* Set minimum Q-scale {4} */ |
394 | buf[0] = 0x82; | 398 | buf[0] = 0x82; |
395 | buf[1] = 0x04; | 399 | buf[1] = 0x04; |
396 | i2c_master_send(client,buf,2); | 400 | i2c_master_send(client,buf,2); |
397 | 401 | ||
398 | // Set maximum Q-scale {12} | 402 | /* Set maximum Q-scale {12} */ |
399 | buf[0] = 0x83; | 403 | buf[0] = 0x83; |
400 | buf[1] = 0x0C; | 404 | buf[1] = 0x0C; |
401 | i2c_master_send(client,buf,2); | 405 | i2c_master_send(client,buf,2); |
402 | 406 | ||
403 | // Set Output Protocol | 407 | /* Set Output Protocol */ |
404 | buf[0] = 0xD0; | 408 | buf[0] = 0xD0; |
405 | buf[1] = 0x81; | 409 | buf[1] = 0x81; |
406 | i2c_master_send(client,buf,2); | 410 | i2c_master_send(client,buf,2); |
407 | 411 | ||
408 | // Set video output stream format {TS} | 412 | /* Set video output stream format {TS} */ |
409 | buf[0] = 0xB0; | 413 | buf[0] = 0xB0; |
410 | buf[1] = 0x05; | 414 | buf[1] = 0x05; |
411 | i2c_master_send(client,buf,2); | 415 | i2c_master_send(client,buf,2); |
@@ -421,9 +425,9 @@ static int saa6752hs_init(struct i2c_client* client) | |||
421 | localPAT[sizeof(PAT) - 1] = crc & 0xFF; | 425 | localPAT[sizeof(PAT) - 1] = crc & 0xFF; |
422 | 426 | ||
423 | /* compute PMT */ | 427 | /* compute PMT */ |
424 | memcpy(localPMT, PMT, sizeof(PMT)); | 428 | memcpy(localPMT, PMT, sizeof(PMT)); |
425 | localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f); | 429 | localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f); |
426 | localPMT[4] = h->params.ts_pid_pmt & 0xff; | 430 | localPMT[4] = h->params.ts_pid_pmt & 0xff; |
427 | localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F); | 431 | localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F); |
428 | localPMT[16] = h->params.ts_pid_pcr & 0xFF; | 432 | localPMT[16] = h->params.ts_pid_pcr & 0xFF; |
429 | localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F); | 433 | localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F); |
@@ -436,39 +440,39 @@ static int saa6752hs_init(struct i2c_client* client) | |||
436 | localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; | 440 | localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; |
437 | localPMT[sizeof(PMT) - 1] = crc & 0xFF; | 441 | localPMT[sizeof(PMT) - 1] = crc & 0xFF; |
438 | 442 | ||
439 | // Set Audio PID | 443 | /* Set Audio PID */ |
440 | buf[0] = 0xC1; | 444 | buf[0] = 0xC1; |
441 | buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; | 445 | buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; |
442 | buf[2] = h->params.ts_pid_audio & 0xFF; | 446 | buf[2] = h->params.ts_pid_audio & 0xFF; |
443 | i2c_master_send(client,buf,3); | 447 | i2c_master_send(client,buf,3); |
444 | 448 | ||
445 | // Set Video PID | 449 | /* Set Video PID */ |
446 | buf[0] = 0xC0; | 450 | buf[0] = 0xC0; |
447 | buf[1] = (h->params.ts_pid_video >> 8) & 0xFF; | 451 | buf[1] = (h->params.ts_pid_video >> 8) & 0xFF; |
448 | buf[2] = h->params.ts_pid_video & 0xFF; | 452 | buf[2] = h->params.ts_pid_video & 0xFF; |
449 | i2c_master_send(client,buf,3); | 453 | i2c_master_send(client,buf,3); |
450 | 454 | ||
451 | // Set PCR PID | 455 | /* Set PCR PID */ |
452 | buf[0] = 0xC4; | 456 | buf[0] = 0xC4; |
453 | buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF; | 457 | buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF; |
454 | buf[2] = h->params.ts_pid_pcr & 0xFF; | 458 | buf[2] = h->params.ts_pid_pcr & 0xFF; |
455 | i2c_master_send(client,buf,3); | 459 | i2c_master_send(client,buf,3); |
456 | 460 | ||
457 | // Send SI tables | 461 | /* Send SI tables */ |
458 | i2c_master_send(client,localPAT,sizeof(PAT)); | 462 | i2c_master_send(client,localPAT,sizeof(PAT)); |
459 | i2c_master_send(client,localPMT,sizeof(PMT)); | 463 | i2c_master_send(client,localPMT,sizeof(PMT)); |
460 | 464 | ||
461 | // mute then unmute audio. This removes buzzing artefacts | 465 | /* mute then unmute audio. This removes buzzing artefacts */ |
462 | buf[0] = 0xa4; | 466 | buf[0] = 0xa4; |
463 | buf[1] = 1; | 467 | buf[1] = 1; |
464 | i2c_master_send(client, buf, 2); | 468 | i2c_master_send(client, buf, 2); |
465 | buf[1] = 0; | 469 | buf[1] = 0; |
466 | i2c_master_send(client, buf, 2); | 470 | i2c_master_send(client, buf, 2); |
467 | 471 | ||
468 | // start it going | 472 | /* start it going */ |
469 | saa6752hs_chip_command(client, SAA6752HS_COMMAND_START); | 473 | saa6752hs_chip_command(client, SAA6752HS_COMMAND_START); |
470 | 474 | ||
471 | // readout current state | 475 | /* readout current state */ |
472 | buf[0] = 0xE1; | 476 | buf[0] = 0xE1; |
473 | buf[1] = 0xA7; | 477 | buf[1] = 0xA7; |
474 | buf[2] = 0xFE; | 478 | buf[2] = 0xFE; |
@@ -477,7 +481,7 @@ static int saa6752hs_init(struct i2c_client* client) | |||
477 | i2c_master_send(client, buf, 5); | 481 | i2c_master_send(client, buf, 5); |
478 | i2c_master_recv(client, buf2, 4); | 482 | i2c_master_recv(client, buf2, 4); |
479 | 483 | ||
480 | // change aspect ratio | 484 | /* change aspect ratio */ |
481 | buf[0] = 0xE0; | 485 | buf[0] = 0xE0; |
482 | buf[1] = 0xA7; | 486 | buf[1] = 0xA7; |
483 | buf[2] = 0xFE; | 487 | buf[2] = 0xFE; |
@@ -498,7 +502,6 @@ static int saa6752hs_init(struct i2c_client* client) | |||
498 | buf[8] = buf2[3]; | 502 | buf[8] = buf2[3]; |
499 | i2c_master_send(client, buf, 9); | 503 | i2c_master_send(client, buf, 9); |
500 | 504 | ||
501 | // return success | ||
502 | return 0; | 505 | return 0; |
503 | } | 506 | } |
504 | 507 | ||
@@ -506,16 +509,19 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) | |||
506 | { | 509 | { |
507 | struct saa6752hs_state *h; | 510 | struct saa6752hs_state *h; |
508 | 511 | ||
509 | printk("saa6752hs: chip found @ 0x%x\n", addr<<1); | 512 | printk("saa6752hs: chip found @ 0x%x\n", addr<<1); |
510 | 513 | ||
511 | if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL))) | 514 | if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL))) |
512 | return -ENOMEM; | 515 | return -ENOMEM; |
513 | memset(h,0,sizeof(*h)); | 516 | memset(h,0,sizeof(*h)); |
514 | h->client = client_template; | 517 | h->client = client_template; |
515 | h->params = param_defaults; | 518 | h->params = param_defaults; |
516 | h->client.adapter = adap; | 519 | h->client.adapter = adap; |
517 | h->client.addr = addr; | 520 | h->client.addr = addr; |
518 | 521 | ||
522 | /* Assume 625 input lines */ | ||
523 | h->standard = 0; | ||
524 | |||
519 | i2c_set_clientdata(&h->client, h); | 525 | i2c_set_clientdata(&h->client, h); |
520 | i2c_attach_client(&h->client); | 526 | i2c_attach_client(&h->client); |
521 | return 0; | 527 | return 0; |
@@ -545,7 +551,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
545 | struct v4l2_mpeg_compression *params = arg; | 551 | struct v4l2_mpeg_compression *params = arg; |
546 | int err = 0; | 552 | int err = 0; |
547 | 553 | ||
548 | switch (cmd) { | 554 | switch (cmd) { |
549 | case VIDIOC_S_MPEGCOMP: | 555 | case VIDIOC_S_MPEGCOMP: |
550 | if (NULL == params) { | 556 | if (NULL == params) { |
551 | /* apply settings and start encoder */ | 557 | /* apply settings and start encoder */ |
@@ -559,7 +565,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
559 | break; | 565 | break; |
560 | case VIDIOC_G_FMT: | 566 | case VIDIOC_G_FMT: |
561 | { | 567 | { |
562 | struct v4l2_format *f = arg; | 568 | struct v4l2_format *f = arg; |
563 | 569 | ||
564 | if (h->video_format == SAA6752HS_VF_UNKNOWN) | 570 | if (h->video_format == SAA6752HS_VF_UNKNOWN) |
565 | h->video_format = SAA6752HS_VF_D1; | 571 | h->video_format = SAA6752HS_VF_D1; |
@@ -576,6 +582,9 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
576 | saa6752hs_set_subsampling(client, f); | 582 | saa6752hs_set_subsampling(client, f); |
577 | break; | 583 | break; |
578 | } | 584 | } |
585 | case VIDIOC_S_STD: | ||
586 | h->standard = *((v4l2_std_id *) arg); | ||
587 | break; | ||
579 | default: | 588 | default: |
580 | /* nothing */ | 589 | /* nothing */ |
581 | break; | 590 | break; |
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c new file mode 100644 index 000000000000..4f3c42354329 --- /dev/null +++ b/drivers/media/video/saa7134/saa7134-alsa.c | |||
@@ -0,0 +1,1047 @@ | |||
1 | /* | ||
2 | * SAA713x ALSA support for V4L | ||
3 | * | ||
4 | * | ||
5 | * Caveats: | ||
6 | * - Volume doesn't work (it's always at max) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation, version 2 | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <sound/driver.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/time.h> | ||
27 | #include <linux/wait.h> | ||
28 | #include <linux/moduleparam.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <sound/core.h> | ||
31 | #include <sound/control.h> | ||
32 | #include <sound/pcm.h> | ||
33 | #include <sound/initval.h> | ||
34 | |||
35 | #include "saa7134.h" | ||
36 | #include "saa7134-reg.h" | ||
37 | |||
38 | static unsigned int debug = 0; | ||
39 | module_param(debug, int, 0644); | ||
40 | MODULE_PARM_DESC(debug,"enable debug messages [alsa]"); | ||
41 | |||
42 | /* | ||
43 | * Configuration macros | ||
44 | */ | ||
45 | |||
46 | /* defaults */ | ||
47 | #define MIXER_ADDR_TVTUNER 0 | ||
48 | #define MIXER_ADDR_LINE1 1 | ||
49 | #define MIXER_ADDR_LINE2 2 | ||
50 | #define MIXER_ADDR_LAST 2 | ||
51 | |||
52 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | ||
53 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | ||
54 | static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; | ||
55 | |||
56 | module_param_array(index, int, NULL, 0444); | ||
57 | MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s)."); | ||
58 | |||
59 | #define dprintk(fmt, arg...) if (debug) \ | ||
60 | printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg) | ||
61 | |||
62 | /* | ||
63 | * Main chip structure | ||
64 | */ | ||
65 | typedef struct snd_card_saa7134 { | ||
66 | snd_card_t *card; | ||
67 | spinlock_t mixer_lock; | ||
68 | int mixer_volume[MIXER_ADDR_LAST+1][2]; | ||
69 | int capture_source[MIXER_ADDR_LAST+1][2]; | ||
70 | struct pci_dev *pci; | ||
71 | struct saa7134_dev *saadev; | ||
72 | |||
73 | unsigned long iobase; | ||
74 | int irq; | ||
75 | |||
76 | spinlock_t lock; | ||
77 | } snd_card_saa7134_t; | ||
78 | |||
79 | |||
80 | |||
81 | /* | ||
82 | * PCM structure | ||
83 | */ | ||
84 | |||
85 | typedef struct snd_card_saa7134_pcm { | ||
86 | struct saa7134_dev *saadev; | ||
87 | |||
88 | spinlock_t lock; | ||
89 | unsigned int pcm_size; /* buffer size */ | ||
90 | unsigned int pcm_count; /* bytes per period */ | ||
91 | unsigned int pcm_bps; /* bytes per second */ | ||
92 | snd_pcm_substream_t *substream; | ||
93 | } snd_card_saa7134_pcm_t; | ||
94 | |||
95 | static snd_card_t *snd_saa7134_cards[SNDRV_CARDS]; | ||
96 | |||
97 | |||
98 | /* | ||
99 | * saa7134 DMA audio stop | ||
100 | * | ||
101 | * Called when the capture device is released or the buffer overflows | ||
102 | * | ||
103 | * - Copied verbatim from saa7134-oss's dsp_dma_stop. Can be dropped | ||
104 | * if we just share dsp_dma_stop and use it here | ||
105 | * | ||
106 | */ | ||
107 | |||
108 | static void saa7134_dma_stop(struct saa7134_dev *dev) | ||
109 | |||
110 | { | ||
111 | dev->dmasound.dma_blk = -1; | ||
112 | dev->dmasound.dma_running = 0; | ||
113 | saa7134_set_dmabits(dev); | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * saa7134 DMA audio start | ||
118 | * | ||
119 | * Called when preparing the capture device for use | ||
120 | * | ||
121 | * - Copied verbatim from saa7134-oss's dsp_dma_start. Can be dropped | ||
122 | * if we just share dsp_dma_start and use it here | ||
123 | * | ||
124 | */ | ||
125 | |||
126 | static void saa7134_dma_start(struct saa7134_dev *dev) | ||
127 | { | ||
128 | dev->dmasound.dma_blk = 0; | ||
129 | dev->dmasound.dma_running = 1; | ||
130 | saa7134_set_dmabits(dev); | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * saa7134 audio DMA IRQ handler | ||
135 | * | ||
136 | * Called whenever we get an SAA7134_IRQ_REPORT_DONE_RA3 interrupt | ||
137 | * Handles shifting between the 2 buffers, manages the read counters, | ||
138 | * and notifies ALSA when periods elapse | ||
139 | * | ||
140 | * - Mostly copied from saa7134-oss's saa7134_irq_oss_done. | ||
141 | * | ||
142 | */ | ||
143 | |||
144 | void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status) | ||
145 | { | ||
146 | int next_blk, reg = 0; | ||
147 | |||
148 | spin_lock(&dev->slock); | ||
149 | if (UNSET == dev->dmasound.dma_blk) { | ||
150 | dprintk("irq: recording stopped\n"); | ||
151 | goto done; | ||
152 | } | ||
153 | if (0 != (status & 0x0f000000)) | ||
154 | dprintk("irq: lost %ld\n", (status >> 24) & 0x0f); | ||
155 | if (0 == (status & 0x10000000)) { | ||
156 | /* odd */ | ||
157 | if (0 == (dev->dmasound.dma_blk & 0x01)) | ||
158 | reg = SAA7134_RS_BA1(6); | ||
159 | } else { | ||
160 | /* even */ | ||
161 | if (1 == (dev->dmasound.dma_blk & 0x01)) | ||
162 | reg = SAA7134_RS_BA2(6); | ||
163 | } | ||
164 | if (0 == reg) { | ||
165 | dprintk("irq: field oops [%s]\n", | ||
166 | (status & 0x10000000) ? "even" : "odd"); | ||
167 | goto done; | ||
168 | } | ||
169 | |||
170 | if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) { | ||
171 | dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count, | ||
172 | dev->dmasound.bufsize, dev->dmasound.blocks); | ||
173 | snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN); | ||
174 | saa7134_dma_stop(dev); | ||
175 | goto done; | ||
176 | } | ||
177 | |||
178 | /* next block addr */ | ||
179 | next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks; | ||
180 | saa_writel(reg,next_blk * dev->dmasound.blksize); | ||
181 | if (debug > 2) | ||
182 | dprintk("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n", | ||
183 | (status & 0x10000000) ? "even" : "odd ", next_blk, | ||
184 | next_blk * dev->dmasound.blksize, dev->dmasound.blocks, dev->dmasound.blksize, dev->dmasound.read_count); | ||
185 | |||
186 | /* update status & wake waiting readers */ | ||
187 | dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks; | ||
188 | dev->dmasound.read_count += dev->dmasound.blksize; | ||
189 | |||
190 | dev->dmasound.recording_on = reg; | ||
191 | |||
192 | if (dev->dmasound.read_count >= snd_pcm_lib_period_bytes(dev->dmasound.substream)) { | ||
193 | spin_unlock(&dev->slock); | ||
194 | snd_pcm_period_elapsed(dev->dmasound.substream); | ||
195 | spin_lock(&dev->slock); | ||
196 | } | ||
197 | done: | ||
198 | spin_unlock(&dev->slock); | ||
199 | |||
200 | } | ||
201 | |||
202 | /* | ||
203 | * IRQ request handler | ||
204 | * | ||
205 | * Runs along with saa7134's IRQ handler, discards anything that isn't | ||
206 | * DMA sound | ||
207 | * | ||
208 | */ | ||
209 | |||
210 | static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs) | ||
211 | { | ||
212 | struct saa7134_dev *dev = (struct saa7134_dev*) dev_id; | ||
213 | unsigned long report, status; | ||
214 | int loop, handled = 0; | ||
215 | |||
216 | for (loop = 0; loop < 10; loop++) { | ||
217 | report = saa_readl(SAA7134_IRQ_REPORT); | ||
218 | status = saa_readl(SAA7134_IRQ_STATUS); | ||
219 | |||
220 | if (report & SAA7134_IRQ_REPORT_DONE_RA3) { | ||
221 | handled = 1; | ||
222 | saa_writel(SAA7134_IRQ_REPORT,report); | ||
223 | saa7134_irq_alsa_done(dev, status); | ||
224 | } else { | ||
225 | goto out; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | if (loop == 10) { | ||
230 | dprintk("error! looping IRQ!"); | ||
231 | } | ||
232 | |||
233 | out: | ||
234 | return IRQ_RETVAL(handled); | ||
235 | } | ||
236 | |||
237 | /* | ||
238 | * ALSA capture trigger | ||
239 | * | ||
240 | * - One of the ALSA capture callbacks. | ||
241 | * | ||
242 | * Called whenever a capture is started or stopped. Must be defined, | ||
243 | * but there's nothing we want to do here | ||
244 | * | ||
245 | */ | ||
246 | |||
247 | static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream, | ||
248 | int cmd) | ||
249 | { | ||
250 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
251 | snd_card_saa7134_pcm_t *saapcm = runtime->private_data; | ||
252 | struct saa7134_dev *dev=saapcm->saadev; | ||
253 | int err = 0; | ||
254 | |||
255 | spin_lock_irq(&dev->slock); | ||
256 | if (cmd == SNDRV_PCM_TRIGGER_START) { | ||
257 | /* start dma */ | ||
258 | saa7134_dma_start(dev); | ||
259 | } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { | ||
260 | /* stop dma */ | ||
261 | saa7134_dma_stop(dev); | ||
262 | } else { | ||
263 | err = -EINVAL; | ||
264 | } | ||
265 | spin_unlock_irq(&dev->slock); | ||
266 | |||
267 | return err; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * DMA buffer config | ||
272 | * | ||
273 | * Sets the values that will later be used as the size of the buffer, | ||
274 | * size of the fragments, and total number of fragments. | ||
275 | * Must be called during the preparation stage, before memory is | ||
276 | * allocated | ||
277 | * | ||
278 | * - Copied verbatim from saa7134-oss. Can be dropped | ||
279 | * if we just share dsp_buffer_conf from OSS. | ||
280 | */ | ||
281 | |||
282 | static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) | ||
283 | { | ||
284 | if (blksize < 0x100) | ||
285 | blksize = 0x100; | ||
286 | if (blksize > 0x10000) | ||
287 | blksize = 0x10000; | ||
288 | |||
289 | if (blocks < 2) | ||
290 | blocks = 2; | ||
291 | if ((blksize * blocks) > 1024*1024) | ||
292 | blocks = 1024*1024 / blksize; | ||
293 | |||
294 | dev->dmasound.blocks = blocks; | ||
295 | dev->dmasound.blksize = blksize; | ||
296 | dev->dmasound.bufsize = blksize * blocks; | ||
297 | |||
298 | dprintk("buffer config: %d blocks / %d bytes, %d kB total\n", | ||
299 | blocks,blksize,blksize * blocks / 1024); | ||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | /* | ||
304 | * DMA buffer initialization | ||
305 | * | ||
306 | * Uses V4L functions to initialize the DMA. Shouldn't be necessary in | ||
307 | * ALSA, but I was unable to use ALSA's own DMA, and had to force the | ||
308 | * usage of V4L's | ||
309 | * | ||
310 | * - Copied verbatim from saa7134-oss. Can be dropped | ||
311 | * if we just share dsp_buffer_init from OSS. | ||
312 | */ | ||
313 | |||
314 | static int dsp_buffer_init(struct saa7134_dev *dev) | ||
315 | { | ||
316 | int err; | ||
317 | |||
318 | if (!dev->dmasound.bufsize) | ||
319 | BUG(); | ||
320 | videobuf_dma_init(&dev->dmasound.dma); | ||
321 | err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE, | ||
322 | (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); | ||
323 | if (0 != err) | ||
324 | return err; | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * ALSA PCM preparation | ||
330 | * | ||
331 | * - One of the ALSA capture callbacks. | ||
332 | * | ||
333 | * Called right after the capture device is opened, this function configures | ||
334 | * the buffer using the previously defined functions, allocates the memory, | ||
335 | * sets up the hardware registers, and then starts the DMA. When this function | ||
336 | * returns, the audio should be flowing. | ||
337 | * | ||
338 | */ | ||
339 | |||
340 | static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream) | ||
341 | { | ||
342 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
343 | int err, bswap, sign; | ||
344 | u32 fmt, control; | ||
345 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); | ||
346 | struct saa7134_dev *dev; | ||
347 | snd_card_saa7134_pcm_t *saapcm = runtime->private_data; | ||
348 | unsigned int bps; | ||
349 | unsigned long size; | ||
350 | unsigned count; | ||
351 | |||
352 | size = snd_pcm_lib_buffer_bytes(substream); | ||
353 | count = snd_pcm_lib_period_bytes(substream); | ||
354 | |||
355 | saapcm->saadev->dmasound.substream = substream; | ||
356 | bps = runtime->rate * runtime->channels; | ||
357 | bps *= snd_pcm_format_width(runtime->format); | ||
358 | bps /= 8; | ||
359 | if (bps <= 0) | ||
360 | return -EINVAL; | ||
361 | saapcm->pcm_bps = bps; | ||
362 | saapcm->pcm_size = snd_pcm_lib_buffer_bytes(substream); | ||
363 | saapcm->pcm_count = snd_pcm_lib_period_bytes(substream); | ||
364 | |||
365 | |||
366 | dev=saa7134->saadev; | ||
367 | |||
368 | dsp_buffer_conf(dev,saapcm->pcm_count,(saapcm->pcm_size/saapcm->pcm_count)); | ||
369 | |||
370 | err = dsp_buffer_init(dev); | ||
371 | if (0 != err) | ||
372 | goto fail2; | ||
373 | |||
374 | /* prepare buffer */ | ||
375 | if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma))) | ||
376 | return err; | ||
377 | if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) | ||
378 | goto fail1; | ||
379 | if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt, | ||
380 | dev->dmasound.dma.sglist, | ||
381 | dev->dmasound.dma.sglen, | ||
382 | 0))) | ||
383 | goto fail2; | ||
384 | |||
385 | |||
386 | |||
387 | switch (runtime->format) { | ||
388 | case SNDRV_PCM_FORMAT_U8: | ||
389 | case SNDRV_PCM_FORMAT_S8: | ||
390 | fmt = 0x00; | ||
391 | break; | ||
392 | case SNDRV_PCM_FORMAT_U16_LE: | ||
393 | case SNDRV_PCM_FORMAT_U16_BE: | ||
394 | case SNDRV_PCM_FORMAT_S16_LE: | ||
395 | case SNDRV_PCM_FORMAT_S16_BE: | ||
396 | fmt = 0x01; | ||
397 | break; | ||
398 | default: | ||
399 | err = -EINVAL; | ||
400 | return 1; | ||
401 | } | ||
402 | |||
403 | switch (runtime->format) { | ||
404 | case SNDRV_PCM_FORMAT_S8: | ||
405 | case SNDRV_PCM_FORMAT_S16_LE: | ||
406 | case SNDRV_PCM_FORMAT_S16_BE: | ||
407 | sign = 1; | ||
408 | break; | ||
409 | default: | ||
410 | sign = 0; | ||
411 | break; | ||
412 | } | ||
413 | |||
414 | switch (runtime->format) { | ||
415 | case SNDRV_PCM_FORMAT_U16_BE: | ||
416 | case SNDRV_PCM_FORMAT_S16_BE: | ||
417 | bswap = 1; break; | ||
418 | default: | ||
419 | bswap = 0; break; | ||
420 | } | ||
421 | |||
422 | switch (dev->pci->device) { | ||
423 | case PCI_DEVICE_ID_PHILIPS_SAA7134: | ||
424 | if (1 == runtime->channels) | ||
425 | fmt |= (1 << 3); | ||
426 | if (2 == runtime->channels) | ||
427 | fmt |= (3 << 3); | ||
428 | if (sign) | ||
429 | fmt |= 0x04; | ||
430 | |||
431 | fmt |= (MIXER_ADDR_TVTUNER == dev->dmasound.input) ? 0xc0 : 0x80; | ||
432 | saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff)); | ||
433 | saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8); | ||
434 | saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16); | ||
435 | saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt); | ||
436 | |||
437 | break; | ||
438 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | ||
439 | case PCI_DEVICE_ID_PHILIPS_SAA7135: | ||
440 | if (1 == runtime->channels) | ||
441 | fmt |= (1 << 4); | ||
442 | if (2 == runtime->channels) | ||
443 | fmt |= (2 << 4); | ||
444 | if (!sign) | ||
445 | fmt |= 0x04; | ||
446 | saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1); | ||
447 | saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24)); | ||
448 | //saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210); | ||
449 | break; | ||
450 | } | ||
451 | |||
452 | dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n", | ||
453 | runtime->format, runtime->channels, fmt, | ||
454 | bswap ? 'b' : '-'); | ||
455 | /* dma: setup channel 6 (= AUDIO) */ | ||
456 | control = SAA7134_RS_CONTROL_BURST_16 | | ||
457 | SAA7134_RS_CONTROL_ME | | ||
458 | (dev->dmasound.pt.dma >> 12); | ||
459 | if (bswap) | ||
460 | control |= SAA7134_RS_CONTROL_BSWAP; | ||
461 | |||
462 | /* I should be able to use runtime->dma_addr in the control | ||
463 | byte, but it doesn't work. So I allocate the DMA using the | ||
464 | V4L functions, and force ALSA to use that as the DMA area */ | ||
465 | |||
466 | runtime->dma_area = dev->dmasound.dma.vmalloc; | ||
467 | |||
468 | saa_writel(SAA7134_RS_BA1(6),0); | ||
469 | saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize); | ||
470 | saa_writel(SAA7134_RS_PITCH(6),0); | ||
471 | saa_writel(SAA7134_RS_CONTROL(6),control); | ||
472 | |||
473 | dev->dmasound.rate = runtime->rate; | ||
474 | |||
475 | return 0; | ||
476 | fail2: | ||
477 | saa7134_pgtable_free(dev->pci,&dev->dmasound.pt); | ||
478 | fail1: | ||
479 | videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma); | ||
480 | return err; | ||
481 | |||
482 | |||
483 | } | ||
484 | |||
485 | /* | ||
486 | * ALSA pointer fetching | ||
487 | * | ||
488 | * - One of the ALSA capture callbacks. | ||
489 | * | ||
490 | * Called whenever a period elapses, it must return the current hardware | ||
491 | * position of the buffer. | ||
492 | * Also resets the read counter used to prevent overruns | ||
493 | * | ||
494 | */ | ||
495 | |||
496 | static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream) | ||
497 | { | ||
498 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
499 | snd_card_saa7134_pcm_t *saapcm = runtime->private_data; | ||
500 | struct saa7134_dev *dev=saapcm->saadev; | ||
501 | |||
502 | |||
503 | |||
504 | if (dev->dmasound.read_count) { | ||
505 | dev->dmasound.read_count -= snd_pcm_lib_period_bytes(substream); | ||
506 | dev->dmasound.read_offset += snd_pcm_lib_period_bytes(substream); | ||
507 | if (dev->dmasound.read_offset == dev->dmasound.bufsize) | ||
508 | dev->dmasound.read_offset = 0; | ||
509 | } | ||
510 | |||
511 | return bytes_to_frames(runtime, dev->dmasound.read_offset); | ||
512 | } | ||
513 | |||
514 | /* | ||
515 | * ALSA hardware capabilities definition | ||
516 | */ | ||
517 | |||
518 | static snd_pcm_hardware_t snd_card_saa7134_capture = | ||
519 | { | ||
520 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | ||
521 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
522 | SNDRV_PCM_INFO_MMAP_VALID), | ||
523 | .formats = SNDRV_PCM_FMTBIT_S16_LE | \ | ||
524 | SNDRV_PCM_FMTBIT_S16_BE | \ | ||
525 | SNDRV_PCM_FMTBIT_S8 | \ | ||
526 | SNDRV_PCM_FMTBIT_U8 | \ | ||
527 | SNDRV_PCM_FMTBIT_U16_LE | \ | ||
528 | SNDRV_PCM_FMTBIT_U16_BE, | ||
529 | .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000, | ||
530 | .rate_min = 32000, | ||
531 | .rate_max = 48000, | ||
532 | .channels_min = 1, | ||
533 | .channels_max = 2, | ||
534 | .buffer_bytes_max = (256*1024), | ||
535 | .period_bytes_min = 64, | ||
536 | .period_bytes_max = (256*1024), | ||
537 | .periods_min = 2, | ||
538 | .periods_max = 1024, | ||
539 | }; | ||
540 | |||
541 | static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime) | ||
542 | { | ||
543 | snd_card_saa7134_pcm_t *saapcm = runtime->private_data; | ||
544 | |||
545 | kfree(saapcm); | ||
546 | } | ||
547 | |||
548 | |||
549 | /* | ||
550 | * ALSA hardware params | ||
551 | * | ||
552 | * - One of the ALSA capture callbacks. | ||
553 | * | ||
554 | * Called on initialization, right before the PCM preparation | ||
555 | * Usually used in ALSA to allocate the DMA, but since we don't use the | ||
556 | * ALSA DMA it does nothing | ||
557 | * | ||
558 | */ | ||
559 | |||
560 | static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream, | ||
561 | snd_pcm_hw_params_t * hw_params) | ||
562 | { | ||
563 | |||
564 | return 0; | ||
565 | |||
566 | |||
567 | } | ||
568 | |||
569 | /* | ||
570 | * ALSA hardware release | ||
571 | * | ||
572 | * - One of the ALSA capture callbacks. | ||
573 | * | ||
574 | * Called after closing the device, but before snd_card_saa7134_capture_close | ||
575 | * Usually used in ALSA to free the DMA, but since we don't use the | ||
576 | * ALSA DMA I'm almost sure this isn't necessary. | ||
577 | * | ||
578 | */ | ||
579 | |||
580 | static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream) | ||
581 | { | ||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | /* | ||
586 | * DMA buffer release | ||
587 | * | ||
588 | * Called after closing the device, during snd_card_saa7134_capture_close | ||
589 | * | ||
590 | */ | ||
591 | |||
592 | static int dsp_buffer_free(struct saa7134_dev *dev) | ||
593 | { | ||
594 | if (!dev->dmasound.blksize) | ||
595 | BUG(); | ||
596 | |||
597 | videobuf_dma_free(&dev->dmasound.dma); | ||
598 | |||
599 | dev->dmasound.blocks = 0; | ||
600 | dev->dmasound.blksize = 0; | ||
601 | dev->dmasound.bufsize = 0; | ||
602 | |||
603 | return 0; | ||
604 | } | ||
605 | |||
606 | /* | ||
607 | * ALSA capture finish | ||
608 | * | ||
609 | * - One of the ALSA capture callbacks. | ||
610 | * | ||
611 | * Called after closing the device. It stops the DMA audio and releases | ||
612 | * the buffers | ||
613 | * | ||
614 | */ | ||
615 | |||
616 | static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream) | ||
617 | { | ||
618 | snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream); | ||
619 | struct saa7134_dev *dev = chip->saadev; | ||
620 | |||
621 | /* unlock buffer */ | ||
622 | saa7134_pgtable_free(dev->pci,&dev->dmasound.pt); | ||
623 | videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma); | ||
624 | |||
625 | dsp_buffer_free(dev); | ||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | /* | ||
630 | * ALSA capture start | ||
631 | * | ||
632 | * - One of the ALSA capture callbacks. | ||
633 | * | ||
634 | * Called when opening the device. It creates and populates the PCM | ||
635 | * structure | ||
636 | * | ||
637 | */ | ||
638 | |||
639 | static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream) | ||
640 | { | ||
641 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
642 | snd_card_saa7134_pcm_t *saapcm; | ||
643 | snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); | ||
644 | struct saa7134_dev *dev = saa7134->saadev; | ||
645 | int err; | ||
646 | |||
647 | down(&dev->dmasound.lock); | ||
648 | |||
649 | dev->dmasound.afmt = SNDRV_PCM_FORMAT_U8; | ||
650 | dev->dmasound.channels = 2; | ||
651 | dev->dmasound.read_count = 0; | ||
652 | dev->dmasound.read_offset = 0; | ||
653 | |||
654 | up(&dev->dmasound.lock); | ||
655 | |||
656 | saapcm = kzalloc(sizeof(*saapcm), GFP_KERNEL); | ||
657 | if (saapcm == NULL) | ||
658 | return -ENOMEM; | ||
659 | saapcm->saadev=saa7134->saadev; | ||
660 | |||
661 | spin_lock_init(&saapcm->lock); | ||
662 | |||
663 | saapcm->substream = substream; | ||
664 | runtime->private_data = saapcm; | ||
665 | runtime->private_free = snd_card_saa7134_runtime_free; | ||
666 | runtime->hw = snd_card_saa7134_capture; | ||
667 | |||
668 | if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) | ||
669 | return err; | ||
670 | |||
671 | return 0; | ||
672 | } | ||
673 | |||
674 | /* | ||
675 | * ALSA capture callbacks definition | ||
676 | */ | ||
677 | |||
678 | static snd_pcm_ops_t snd_card_saa7134_capture_ops = { | ||
679 | .open = snd_card_saa7134_capture_open, | ||
680 | .close = snd_card_saa7134_capture_close, | ||
681 | .ioctl = snd_pcm_lib_ioctl, | ||
682 | .hw_params = snd_card_saa7134_hw_params, | ||
683 | .hw_free = snd_card_saa7134_hw_free, | ||
684 | .prepare = snd_card_saa7134_capture_prepare, | ||
685 | .trigger = snd_card_saa7134_capture_trigger, | ||
686 | .pointer = snd_card_saa7134_capture_pointer, | ||
687 | }; | ||
688 | |||
689 | /* | ||
690 | * ALSA PCM setup | ||
691 | * | ||
692 | * Called when initializing the board. Sets up the name and hooks up | ||
693 | * the callbacks | ||
694 | * | ||
695 | */ | ||
696 | |||
697 | static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device) | ||
698 | { | ||
699 | snd_pcm_t *pcm; | ||
700 | int err; | ||
701 | |||
702 | if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0) | ||
703 | return err; | ||
704 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_saa7134_capture_ops); | ||
705 | pcm->private_data = saa7134; | ||
706 | pcm->info_flags = 0; | ||
707 | strcpy(pcm->name, "SAA7134 PCM"); | ||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | #define SAA713x_VOLUME(xname, xindex, addr) \ | ||
712 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | ||
713 | .info = snd_saa7134_volume_info, \ | ||
714 | .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \ | ||
715 | .private_value = addr } | ||
716 | |||
717 | static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) | ||
718 | { | ||
719 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
720 | uinfo->count = 2; | ||
721 | uinfo->value.integer.min = 0; | ||
722 | uinfo->value.integer.max = 20; | ||
723 | return 0; | ||
724 | } | ||
725 | |||
726 | static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | ||
727 | { | ||
728 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | ||
729 | int addr = kcontrol->private_value; | ||
730 | |||
731 | ucontrol->value.integer.value[0] = chip->mixer_volume[addr][0]; | ||
732 | ucontrol->value.integer.value[1] = chip->mixer_volume[addr][1]; | ||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | ||
737 | { | ||
738 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | ||
739 | unsigned long flags; | ||
740 | int change, addr = kcontrol->private_value; | ||
741 | int left, right; | ||
742 | |||
743 | left = ucontrol->value.integer.value[0]; | ||
744 | if (left < 0) | ||
745 | left = 0; | ||
746 | if (left > 20) | ||
747 | left = 20; | ||
748 | right = ucontrol->value.integer.value[1]; | ||
749 | if (right < 0) | ||
750 | right = 0; | ||
751 | if (right > 20) | ||
752 | right = 20; | ||
753 | spin_lock_irqsave(&chip->mixer_lock, flags); | ||
754 | change = chip->mixer_volume[addr][0] != left || | ||
755 | chip->mixer_volume[addr][1] != right; | ||
756 | chip->mixer_volume[addr][0] = left; | ||
757 | chip->mixer_volume[addr][1] = right; | ||
758 | spin_unlock_irqrestore(&chip->mixer_lock, flags); | ||
759 | return change; | ||
760 | } | ||
761 | |||
762 | #define SAA713x_CAPSRC(xname, xindex, addr) \ | ||
763 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | ||
764 | .info = snd_saa7134_capsrc_info, \ | ||
765 | .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \ | ||
766 | .private_value = addr } | ||
767 | |||
768 | static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo) | ||
769 | { | ||
770 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
771 | uinfo->count = 2; | ||
772 | uinfo->value.integer.min = 0; | ||
773 | uinfo->value.integer.max = 1; | ||
774 | return 0; | ||
775 | } | ||
776 | |||
777 | static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | ||
778 | { | ||
779 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | ||
780 | unsigned long flags; | ||
781 | int addr = kcontrol->private_value; | ||
782 | |||
783 | spin_lock_irqsave(&chip->mixer_lock, flags); | ||
784 | ucontrol->value.integer.value[0] = chip->capture_source[addr][0]; | ||
785 | ucontrol->value.integer.value[1] = chip->capture_source[addr][1]; | ||
786 | spin_unlock_irqrestore(&chip->mixer_lock, flags); | ||
787 | return 0; | ||
788 | } | ||
789 | |||
790 | static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | ||
791 | { | ||
792 | snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); | ||
793 | unsigned long flags; | ||
794 | int change, addr = kcontrol->private_value; | ||
795 | int left, right; | ||
796 | u32 anabar, xbarin; | ||
797 | int analog_io, rate; | ||
798 | struct saa7134_dev *dev; | ||
799 | |||
800 | dev = chip->saadev; | ||
801 | |||
802 | left = ucontrol->value.integer.value[0] & 1; | ||
803 | right = ucontrol->value.integer.value[1] & 1; | ||
804 | spin_lock_irqsave(&chip->mixer_lock, flags); | ||
805 | |||
806 | change = chip->capture_source[addr][0] != left || | ||
807 | chip->capture_source[addr][1] != right; | ||
808 | chip->capture_source[addr][0] = left; | ||
809 | chip->capture_source[addr][1] = right; | ||
810 | dev->dmasound.input=addr; | ||
811 | spin_unlock_irqrestore(&chip->mixer_lock, flags); | ||
812 | |||
813 | |||
814 | if (change) { | ||
815 | switch (dev->pci->device) { | ||
816 | |||
817 | case PCI_DEVICE_ID_PHILIPS_SAA7134: | ||
818 | switch (addr) { | ||
819 | case MIXER_ADDR_TVTUNER: | ||
820 | saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0); | ||
821 | saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00); | ||
822 | break; | ||
823 | case MIXER_ADDR_LINE1: | ||
824 | case MIXER_ADDR_LINE2: | ||
825 | analog_io = (MIXER_ADDR_LINE1 == addr) ? 0x00 : 0x08; | ||
826 | rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03; | ||
827 | saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io); | ||
828 | saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80); | ||
829 | saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate); | ||
830 | break; | ||
831 | } | ||
832 | |||
833 | break; | ||
834 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | ||
835 | case PCI_DEVICE_ID_PHILIPS_SAA7135: | ||
836 | xbarin = 0x03; // adc | ||
837 | anabar = 0; | ||
838 | switch (addr) { | ||
839 | case MIXER_ADDR_TVTUNER: | ||
840 | xbarin = 0; // Demodulator | ||
841 | anabar = 2; // DACs | ||
842 | break; | ||
843 | case MIXER_ADDR_LINE1: | ||
844 | anabar = 0; // aux1, aux1 | ||
845 | break; | ||
846 | case MIXER_ADDR_LINE2: | ||
847 | anabar = 9; // aux2, aux2 | ||
848 | break; | ||
849 | } | ||
850 | |||
851 | /* output xbar always main channel */ | ||
852 | saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10); | ||
853 | |||
854 | if (left || right) { // We've got data, turn the input on | ||
855 | saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin); | ||
856 | saa_writel(SAA7133_ANALOG_IO_SELECT, anabar); | ||
857 | } else { | ||
858 | saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0); | ||
859 | saa_writel(SAA7133_ANALOG_IO_SELECT, 0); | ||
860 | } | ||
861 | break; | ||
862 | } | ||
863 | } | ||
864 | |||
865 | return change; | ||
866 | } | ||
867 | |||
868 | static snd_kcontrol_new_t snd_saa7134_controls[] = { | ||
869 | SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER), | ||
870 | SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER), | ||
871 | SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1), | ||
872 | SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1), | ||
873 | SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2), | ||
874 | SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2), | ||
875 | }; | ||
876 | |||
877 | /* | ||
878 | * ALSA mixer setup | ||
879 | * | ||
880 | * Called when initializing the board. Sets up the name and hooks up | ||
881 | * the callbacks | ||
882 | * | ||
883 | */ | ||
884 | |||
885 | static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip) | ||
886 | { | ||
887 | snd_card_t *card = chip->card; | ||
888 | unsigned int idx; | ||
889 | int err; | ||
890 | |||
891 | snd_assert(chip != NULL, return -EINVAL); | ||
892 | strcpy(card->mixername, "SAA7134 Mixer"); | ||
893 | |||
894 | for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_controls); idx++) { | ||
895 | if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_saa7134_controls[idx], chip))) < 0) | ||
896 | return err; | ||
897 | } | ||
898 | return 0; | ||
899 | } | ||
900 | |||
901 | static int snd_saa7134_free(snd_card_saa7134_t *chip) | ||
902 | { | ||
903 | return 0; | ||
904 | } | ||
905 | |||
906 | static int snd_saa7134_dev_free(snd_device_t *device) | ||
907 | { | ||
908 | snd_card_saa7134_t *chip = device->device_data; | ||
909 | return snd_saa7134_free(chip); | ||
910 | } | ||
911 | |||
912 | /* | ||
913 | * ALSA initialization | ||
914 | * | ||
915 | * Called by saa7134-core, it creates the basic structures and registers | ||
916 | * the ALSA devices | ||
917 | * | ||
918 | */ | ||
919 | |||
920 | int alsa_card_saa7134_create (struct saa7134_dev *saadev) | ||
921 | { | ||
922 | static int dev; | ||
923 | |||
924 | snd_card_t *card; | ||
925 | snd_card_saa7134_t *chip; | ||
926 | int err; | ||
927 | static snd_device_ops_t ops = { | ||
928 | .dev_free = snd_saa7134_dev_free, | ||
929 | }; | ||
930 | |||
931 | |||
932 | if (dev >= SNDRV_CARDS) | ||
933 | return -ENODEV; | ||
934 | if (!enable[dev]) | ||
935 | return -ENODEV; | ||
936 | |||
937 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | ||
938 | |||
939 | if (card == NULL) | ||
940 | return -ENOMEM; | ||
941 | |||
942 | strcpy(card->driver, "SAA7134"); | ||
943 | |||
944 | /* Card "creation" */ | ||
945 | |||
946 | chip = kcalloc(1, sizeof(*chip), GFP_KERNEL); | ||
947 | if (chip == NULL) { | ||
948 | return -ENOMEM; | ||
949 | } | ||
950 | |||
951 | spin_lock_init(&chip->lock); | ||
952 | spin_lock_init(&chip->mixer_lock); | ||
953 | |||
954 | chip->saadev = saadev; | ||
955 | |||
956 | chip->card = card; | ||
957 | |||
958 | chip->pci = saadev->pci; | ||
959 | chip->irq = saadev->pci->irq; | ||
960 | chip->iobase = pci_resource_start(saadev->pci, 0); | ||
961 | |||
962 | err = request_irq(saadev->pci->irq, saa7134_alsa_irq, | ||
963 | SA_SHIRQ | SA_INTERRUPT, saadev->name, saadev); | ||
964 | |||
965 | if (err < 0) { | ||
966 | printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n", | ||
967 | saadev->name, saadev->pci->irq); | ||
968 | goto __nodev; | ||
969 | } | ||
970 | |||
971 | if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { | ||
972 | goto __nodev; | ||
973 | } | ||
974 | |||
975 | if ((err = snd_card_saa7134_new_mixer(chip)) < 0) | ||
976 | goto __nodev; | ||
977 | |||
978 | if ((err = snd_card_saa7134_pcm(chip, 0)) < 0) | ||
979 | goto __nodev; | ||
980 | |||
981 | snd_card_set_dev(card, &chip->pci->dev); | ||
982 | |||
983 | /* End of "creation" */ | ||
984 | |||
985 | strcpy(card->shortname, "SAA7134"); | ||
986 | sprintf(card->longname, "%s at 0x%lx irq %d", | ||
987 | chip->saadev->name, chip->iobase, chip->irq); | ||
988 | |||
989 | if ((err = snd_card_register(card)) == 0) { | ||
990 | snd_saa7134_cards[dev] = card; | ||
991 | return 0; | ||
992 | } | ||
993 | |||
994 | __nodev: | ||
995 | snd_card_free(card); | ||
996 | kfree(chip); | ||
997 | return err; | ||
998 | } | ||
999 | |||
1000 | /* | ||
1001 | * Module initializer | ||
1002 | * | ||
1003 | * Loops through present saa7134 cards, and assigns an ALSA device | ||
1004 | * to each one | ||
1005 | * | ||
1006 | */ | ||
1007 | |||
1008 | static int saa7134_alsa_init(void) | ||
1009 | { | ||
1010 | struct saa7134_dev *saadev = NULL; | ||
1011 | struct list_head *list; | ||
1012 | |||
1013 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n"); | ||
1014 | |||
1015 | list_for_each(list,&saa7134_devlist) { | ||
1016 | saadev = list_entry(list, struct saa7134_dev, devlist); | ||
1017 | alsa_card_saa7134_create(saadev); | ||
1018 | } | ||
1019 | |||
1020 | if (saadev == NULL) | ||
1021 | printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n"); | ||
1022 | |||
1023 | return 0; | ||
1024 | |||
1025 | } | ||
1026 | |||
1027 | /* | ||
1028 | * Module destructor | ||
1029 | */ | ||
1030 | |||
1031 | void saa7134_alsa_exit(void) | ||
1032 | { | ||
1033 | int idx; | ||
1034 | |||
1035 | for (idx = 0; idx < SNDRV_CARDS; idx++) { | ||
1036 | snd_card_free(snd_saa7134_cards[idx]); | ||
1037 | } | ||
1038 | |||
1039 | printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n"); | ||
1040 | |||
1041 | return; | ||
1042 | } | ||
1043 | |||
1044 | module_init(saa7134_alsa_init); | ||
1045 | module_exit(saa7134_alsa_exit); | ||
1046 | MODULE_LICENSE("GPL"); | ||
1047 | MODULE_AUTHOR("Ricardo Cerqueira"); | ||
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index acc7a4335e23..663d03e5bc67 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
@@ -191,10 +191,14 @@ struct saa7134_board saa7134_boards[] = { | |||
191 | .amux = TV, | 191 | .amux = TV, |
192 | .tv = 1, | 192 | .tv = 1, |
193 | },{ | 193 | },{ |
194 | .name = name_comp1, | 194 | .name = name_comp1, /* Composite signal on S-Video input */ |
195 | .vmux = 0, | 195 | .vmux = 0, |
196 | .amux = LINE2, | 196 | .amux = LINE2, |
197 | },{ | 197 | },{ |
198 | .name = name_comp2, /* Composite input */ | ||
199 | .vmux = 3, | ||
200 | .amux = LINE2, | ||
201 | },{ | ||
198 | .name = name_svideo, | 202 | .name = name_svideo, |
199 | .vmux = 8, | 203 | .vmux = 8, |
200 | .amux = LINE2, | 204 | .amux = LINE2, |
@@ -2109,8 +2113,423 @@ struct saa7134_board saa7134_boards[] = { | |||
2109 | .gpio = 0x01, | 2113 | .gpio = 0x01, |
2110 | }, | 2114 | }, |
2111 | }, | 2115 | }, |
2112 | }; | 2116 | [SAA7134_BOARD_BEHOLD_409FM] = { |
2117 | /* <http://tuner.beholder.ru>, Sergey <skiv@orel.ru> */ | ||
2118 | .name = "Beholder BeholdTV 409 FM", | ||
2119 | .audio_clock = 0x00187de7, | ||
2120 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
2121 | .radio_type = UNSET, | ||
2122 | .tuner_addr = ADDR_UNSET, | ||
2123 | .radio_addr = ADDR_UNSET, | ||
2124 | .tda9887_conf = TDA9887_PRESENT, | ||
2125 | .inputs = {{ | ||
2126 | .name = name_tv, | ||
2127 | .vmux = 3, | ||
2128 | .amux = TV, | ||
2129 | .tv = 1, | ||
2130 | },{ | ||
2131 | .name = name_comp1, | ||
2132 | .vmux = 1, | ||
2133 | .amux = LINE1, | ||
2134 | },{ | ||
2135 | .name = name_svideo, | ||
2136 | .vmux = 8, | ||
2137 | .amux = LINE1, | ||
2138 | }}, | ||
2139 | .radio = { | ||
2140 | .name = name_radio, | ||
2141 | .amux = LINE2, | ||
2142 | }, | ||
2143 | }, | ||
2144 | [SAA7134_BOARD_GOTVIEW_7135] = { | ||
2145 | /* Mike Baikov <mike@baikov.com> */ | ||
2146 | /* Andrey Cvetcov <ays14@yandex.ru> */ | ||
2147 | .name = "GoTView 7135 PCI", | ||
2148 | .audio_clock = 0x00187de7, | ||
2149 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
2150 | .radio_type = UNSET, | ||
2151 | .tuner_addr = ADDR_UNSET, | ||
2152 | .radio_addr = ADDR_UNSET, | ||
2153 | .tda9887_conf = TDA9887_PRESENT, | ||
2154 | .gpiomask = 0x00200003, | ||
2155 | .inputs = {{ | ||
2156 | .name = name_tv, | ||
2157 | .vmux = 1, | ||
2158 | .amux = TV, | ||
2159 | .tv = 1, | ||
2160 | .gpio = 0x00200003, | ||
2161 | },{ | ||
2162 | .name = name_tv_mono, | ||
2163 | .vmux = 1, | ||
2164 | .amux = LINE2, | ||
2165 | .gpio = 0x00200003, | ||
2166 | },{ | ||
2167 | .name = name_comp1, | ||
2168 | .vmux = 3, | ||
2169 | .amux = LINE1, | ||
2170 | .gpio = 0x00200003, | ||
2171 | },{ | ||
2172 | .name = name_svideo, | ||
2173 | .vmux = 8, | ||
2174 | .amux = LINE1, | ||
2175 | .gpio = 0x00200003, | ||
2176 | }}, | ||
2177 | .radio = { | ||
2178 | .name = name_radio, | ||
2179 | .amux = LINE2, | ||
2180 | .gpio = 0x00200003, | ||
2181 | }, | ||
2182 | .mute = { | ||
2183 | .name = name_mute, | ||
2184 | .amux = TV, | ||
2185 | .gpio = 0x00200003, | ||
2186 | }, | ||
2187 | }, | ||
2188 | [SAA7134_BOARD_PHILIPS_EUROPA] = { | ||
2189 | .name = "Philips EUROPA V3 reference design", | ||
2190 | .audio_clock = 0x00187de7, | ||
2191 | .tuner_type = TUNER_PHILIPS_TD1316, | ||
2192 | .radio_type = UNSET, | ||
2193 | .tuner_addr = 0x61, | ||
2194 | .radio_addr = ADDR_UNSET, | ||
2195 | .tda9887_conf = TDA9887_PRESENT, | ||
2196 | .mpeg = SAA7134_MPEG_DVB, | ||
2197 | .inputs = {{ | ||
2198 | .name = name_tv, | ||
2199 | .vmux = 3, | ||
2200 | .amux = TV, | ||
2201 | .tv = 1, | ||
2202 | },{ | ||
2203 | .name = name_comp1, | ||
2204 | .vmux = 0, | ||
2205 | .amux = LINE2, | ||
2206 | },{ | ||
2207 | .name = name_svideo, | ||
2208 | .vmux = 8, | ||
2209 | .amux = LINE2, | ||
2210 | }}, | ||
2211 | }, | ||
2212 | [SAA7134_BOARD_VIDEOMATE_DVBT_300] = { | ||
2213 | .name = "Compro Videomate DVB-T300", | ||
2214 | .audio_clock = 0x00187de7, | ||
2215 | .tuner_type = TUNER_PHILIPS_TD1316, | ||
2216 | .radio_type = UNSET, | ||
2217 | .tuner_addr = 0x61, | ||
2218 | .radio_addr = ADDR_UNSET, | ||
2219 | .tda9887_conf = TDA9887_PRESENT, | ||
2220 | .mpeg = SAA7134_MPEG_DVB, | ||
2221 | .inputs = {{ | ||
2222 | .name = name_tv, | ||
2223 | .vmux = 3, | ||
2224 | .amux = TV, | ||
2225 | .tv = 1, | ||
2226 | },{ | ||
2227 | .name = name_comp1, | ||
2228 | .vmux = 1, | ||
2229 | .amux = LINE2, | ||
2230 | },{ | ||
2231 | .name = name_svideo, | ||
2232 | .vmux = 8, | ||
2233 | .amux = LINE2, | ||
2234 | }}, | ||
2235 | }, | ||
2236 | [SAA7134_BOARD_VIDEOMATE_DVBT_200] = { | ||
2237 | .name = "Compro Videomate DVB-T200", | ||
2238 | .tuner_type = TUNER_ABSENT, | ||
2239 | .audio_clock = 0x00187de7, | ||
2240 | .radio_type = UNSET, | ||
2241 | .tuner_addr = ADDR_UNSET, | ||
2242 | .radio_addr = ADDR_UNSET, | ||
2243 | .mpeg = SAA7134_MPEG_DVB, | ||
2244 | .inputs = {{ | ||
2245 | .name = name_comp1, | ||
2246 | .vmux = 0, | ||
2247 | .amux = LINE1, | ||
2248 | },{ | ||
2249 | .name = name_svideo, | ||
2250 | .vmux = 8, | ||
2251 | .amux = LINE1, | ||
2252 | }}, | ||
2253 | }, | ||
2254 | [SAA7134_BOARD_RTD_VFG7350] = { | ||
2255 | .name = "RTD Embedded Technologies VFG7350", | ||
2256 | .audio_clock = 0x00200000, | ||
2257 | .tuner_type = TUNER_ABSENT, | ||
2258 | .radio_type = UNSET, | ||
2259 | .tuner_addr = ADDR_UNSET, | ||
2260 | .radio_addr = ADDR_UNSET, | ||
2261 | .inputs = {{ | ||
2262 | .name = "Composite 0", | ||
2263 | .vmux = 0, | ||
2264 | .amux = LINE1, | ||
2265 | },{ | ||
2266 | .name = "Composite 1", | ||
2267 | .vmux = 1, | ||
2268 | .amux = LINE2, | ||
2269 | },{ | ||
2270 | .name = "Composite 2", | ||
2271 | .vmux = 2, | ||
2272 | .amux = LINE1, | ||
2273 | },{ | ||
2274 | .name = "Composite 3", | ||
2275 | .vmux = 3, | ||
2276 | .amux = LINE2, | ||
2277 | },{ | ||
2278 | .name = "S-Video 0", | ||
2279 | .vmux = 8, | ||
2280 | .amux = LINE1, | ||
2281 | },{ | ||
2282 | .name = "S-Video 1", | ||
2283 | .vmux = 9, | ||
2284 | .amux = LINE2, | ||
2285 | }}, | ||
2286 | .mpeg = SAA7134_MPEG_EMPRESS, | ||
2287 | .video_out = CCIR656, | ||
2288 | .vid_port_opts = ( SET_T_CODE_POLARITY_NON_INVERTED | | ||
2289 | SET_CLOCK_NOT_DELAYED | | ||
2290 | SET_CLOCK_INVERTED | | ||
2291 | SET_VSYNC_OFF ), | ||
2292 | }, | ||
2293 | [SAA7134_BOARD_RTD_VFG7330] = { | ||
2294 | .name = "RTD Embedded Technologies VFG7330", | ||
2295 | .audio_clock = 0x00200000, | ||
2296 | .tuner_type = TUNER_ABSENT, | ||
2297 | .radio_type = UNSET, | ||
2298 | .tuner_addr = ADDR_UNSET, | ||
2299 | .radio_addr = ADDR_UNSET, | ||
2300 | .inputs = {{ | ||
2301 | .name = "Composite 0", | ||
2302 | .vmux = 0, | ||
2303 | .amux = LINE1, | ||
2304 | },{ | ||
2305 | .name = "Composite 1", | ||
2306 | .vmux = 1, | ||
2307 | .amux = LINE2, | ||
2308 | },{ | ||
2309 | .name = "Composite 2", | ||
2310 | .vmux = 2, | ||
2311 | .amux = LINE1, | ||
2312 | },{ | ||
2313 | .name = "Composite 3", | ||
2314 | .vmux = 3, | ||
2315 | .amux = LINE2, | ||
2316 | },{ | ||
2317 | .name = "S-Video 0", | ||
2318 | .vmux = 8, | ||
2319 | .amux = LINE1, | ||
2320 | },{ | ||
2321 | .name = "S-Video 1", | ||
2322 | .vmux = 9, | ||
2323 | .amux = LINE2, | ||
2324 | }}, | ||
2325 | }, | ||
2326 | [SAA7134_BOARD_FLYTVPLATINUM_MINI2] = { | ||
2327 | .name = "LifeView FlyTV Platinum Mini2", | ||
2328 | .audio_clock = 0x00200000, | ||
2329 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
2330 | .radio_type = UNSET, | ||
2331 | .tuner_addr = ADDR_UNSET, | ||
2332 | .radio_addr = ADDR_UNSET, | ||
2113 | 2333 | ||
2334 | .inputs = {{ | ||
2335 | .name = name_tv, | ||
2336 | .vmux = 1, | ||
2337 | .amux = TV, | ||
2338 | .tv = 1, | ||
2339 | },{ | ||
2340 | .name = name_comp1, /* Composite signal on S-Video input */ | ||
2341 | .vmux = 0, | ||
2342 | .amux = LINE2, | ||
2343 | },{ | ||
2344 | .name = name_comp2, /* Composite input */ | ||
2345 | .vmux = 3, | ||
2346 | .amux = LINE2, | ||
2347 | },{ | ||
2348 | .name = name_svideo, | ||
2349 | .vmux = 8, | ||
2350 | .amux = LINE2, | ||
2351 | }}, | ||
2352 | }, | ||
2353 | [SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180] = { | ||
2354 | /* Michael Krufky <mkrufky@m1k.net> | ||
2355 | * Uses Alps Electric TDHU2, containing NXT2004 ATSC Decoder | ||
2356 | * AFAIK, there is no analog demod, thus, | ||
2357 | * no support for analog television. | ||
2358 | */ | ||
2359 | .name = "AVerMedia AVerTVHD MCE A180", | ||
2360 | .audio_clock = 0x00187de7, | ||
2361 | .tuner_type = TUNER_ABSENT, | ||
2362 | .radio_type = UNSET, | ||
2363 | .tuner_addr = ADDR_UNSET, | ||
2364 | .radio_addr = ADDR_UNSET, | ||
2365 | .mpeg = SAA7134_MPEG_DVB, | ||
2366 | .inputs = {{ | ||
2367 | .name = name_comp1, | ||
2368 | .vmux = 3, | ||
2369 | .amux = LINE2, | ||
2370 | },{ | ||
2371 | .name = name_svideo, | ||
2372 | .vmux = 8, | ||
2373 | .amux = LINE2, | ||
2374 | }}, | ||
2375 | }, | ||
2376 | [SAA7134_BOARD_MONSTERTV_MOBILE] = { | ||
2377 | .name = "SKNet MonsterTV Mobile", | ||
2378 | .audio_clock = 0x00187de7, | ||
2379 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
2380 | .radio_type = UNSET, | ||
2381 | .tuner_addr = ADDR_UNSET, | ||
2382 | .radio_addr = ADDR_UNSET, | ||
2383 | |||
2384 | .inputs = {{ | ||
2385 | .name = name_tv, | ||
2386 | .vmux = 1, | ||
2387 | .amux = TV, | ||
2388 | .tv = 1, | ||
2389 | },{ | ||
2390 | .name = name_comp1, | ||
2391 | .vmux = 3, | ||
2392 | .amux = LINE1, | ||
2393 | },{ | ||
2394 | .name = name_svideo, | ||
2395 | .vmux = 6, | ||
2396 | .amux = LINE1, | ||
2397 | }}, | ||
2398 | }, | ||
2399 | [SAA7134_BOARD_PINNACLE_PCTV_110i] = { | ||
2400 | .name = "Pinnacle PCTV 110i (saa7133)", | ||
2401 | .audio_clock = 0x00187de7, | ||
2402 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
2403 | .radio_type = UNSET, | ||
2404 | .tuner_addr = ADDR_UNSET, | ||
2405 | .radio_addr = ADDR_UNSET, | ||
2406 | .gpiomask = 0x080200000, | ||
2407 | .inputs = {{ | ||
2408 | .name = name_tv, | ||
2409 | .vmux = 4, | ||
2410 | .amux = TV, | ||
2411 | .tv = 1, | ||
2412 | },{ | ||
2413 | .name = name_comp1, | ||
2414 | .vmux = 1, | ||
2415 | .amux = LINE2, | ||
2416 | },{ | ||
2417 | .name = name_svideo, | ||
2418 | .vmux = 8, | ||
2419 | .amux = LINE2, | ||
2420 | }}, | ||
2421 | .radio = { | ||
2422 | .name = name_radio, | ||
2423 | .amux = LINE1, | ||
2424 | }, | ||
2425 | }, | ||
2426 | [SAA7134_BOARD_ASUSTeK_P7131_DUAL] = { | ||
2427 | .name = "ASUSTeK P7131 Dual", | ||
2428 | .audio_clock = 0x00187de7, | ||
2429 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
2430 | .radio_type = UNSET, | ||
2431 | .tuner_addr = ADDR_UNSET, | ||
2432 | .radio_addr = ADDR_UNSET, | ||
2433 | .gpiomask = 1 << 21, | ||
2434 | .mpeg = SAA7134_MPEG_DVB, | ||
2435 | .inputs = {{ | ||
2436 | .name = name_tv, | ||
2437 | .vmux = 1, | ||
2438 | .amux = TV, | ||
2439 | .tv = 1, | ||
2440 | },{ | ||
2441 | .name = name_comp1, | ||
2442 | .vmux = 3, | ||
2443 | .amux = LINE2, | ||
2444 | },{ | ||
2445 | .name = name_svideo, | ||
2446 | .vmux = 8, | ||
2447 | .amux = LINE2, | ||
2448 | }}, | ||
2449 | .radio = { | ||
2450 | .name = name_radio, | ||
2451 | .amux = TV, | ||
2452 | .gpio = 0x0200000, | ||
2453 | }, | ||
2454 | }, | ||
2455 | [SAA7134_BOARD_SEDNA_PC_TV_CARDBUS] = { | ||
2456 | /* Paul Tom Zalac <pzalac@gmail.com> */ | ||
2457 | /* Pavel Mihaylov <bin@bash.info> */ | ||
2458 | .name = "Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)", | ||
2459 | /* Sedna/MuchTV (OEM) Cardbus TV Tuner */ | ||
2460 | .audio_clock = 0x00187de7, | ||
2461 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
2462 | .radio_type = UNSET, | ||
2463 | .tuner_addr = ADDR_UNSET, | ||
2464 | .radio_addr = ADDR_UNSET, | ||
2465 | .gpiomask = 0xe880c0, | ||
2466 | .inputs = {{ | ||
2467 | .name = name_tv, | ||
2468 | .vmux = 3, | ||
2469 | .amux = TV, | ||
2470 | .tv = 1, | ||
2471 | },{ | ||
2472 | .name = name_comp1, | ||
2473 | .vmux = 1, | ||
2474 | .amux = LINE1, | ||
2475 | },{ | ||
2476 | .name = name_svideo, | ||
2477 | .vmux = 6, | ||
2478 | .amux = LINE1, | ||
2479 | }}, | ||
2480 | .radio = { | ||
2481 | .name = name_radio, | ||
2482 | .amux = LINE2, | ||
2483 | }, | ||
2484 | }, | ||
2485 | [SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV] = { | ||
2486 | /* "Cyril Lacoux (Yack)" <clacoux@ifeelgood.org> */ | ||
2487 | .name = "ASUS Digimatrix TV", | ||
2488 | .audio_clock = 0x00200000, | ||
2489 | .tuner_type = TUNER_PHILIPS_FQ1216ME, | ||
2490 | .tda9887_conf = TDA9887_PRESENT, | ||
2491 | .radio_type = UNSET, | ||
2492 | .tuner_addr = ADDR_UNSET, | ||
2493 | .radio_addr = ADDR_UNSET, | ||
2494 | .inputs = {{ | ||
2495 | .name = name_tv, | ||
2496 | .vmux = 1, | ||
2497 | .amux = TV, | ||
2498 | .tv = 1, | ||
2499 | },{ | ||
2500 | .name = name_comp1, | ||
2501 | .vmux = 3, | ||
2502 | .amux = LINE1, | ||
2503 | },{ | ||
2504 | .name = name_svideo, | ||
2505 | .vmux = 8, | ||
2506 | .amux = LINE1, | ||
2507 | }}, | ||
2508 | }, | ||
2509 | [SAA7134_BOARD_PHILIPS_TIGER] = { | ||
2510 | .name = "Philips Tiger reference design", | ||
2511 | .audio_clock = 0x00187de7, | ||
2512 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
2513 | .radio_type = UNSET, | ||
2514 | .tuner_addr = ADDR_UNSET, | ||
2515 | .radio_addr = ADDR_UNSET, | ||
2516 | .mpeg = SAA7134_MPEG_DVB, | ||
2517 | .inputs = {{ | ||
2518 | .name = name_tv, | ||
2519 | .vmux = 1, | ||
2520 | .amux = TV, | ||
2521 | .tv = 1, | ||
2522 | },{ | ||
2523 | .name = name_comp1, | ||
2524 | .vmux = 3, | ||
2525 | .amux = LINE1, | ||
2526 | },{ | ||
2527 | .name = name_svideo, | ||
2528 | .vmux = 8, | ||
2529 | .amux = LINE1, | ||
2530 | }}, | ||
2531 | }, | ||
2532 | }; | ||
2114 | 2533 | ||
2115 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); | 2534 | const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); |
2116 | 2535 | ||
@@ -2145,19 +2564,19 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
2145 | },{ | 2564 | },{ |
2146 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2565 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2147 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 2566 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
2148 | .subvendor = 0x153B, | 2567 | .subvendor = 0x153b, |
2149 | .subdevice = 0x1142, | 2568 | .subdevice = 0x1142, |
2150 | .driver_data = SAA7134_BOARD_CINERGY400, | 2569 | .driver_data = SAA7134_BOARD_CINERGY400, |
2151 | },{ | 2570 | },{ |
2152 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2571 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2153 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 2572 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
2154 | .subvendor = 0x153B, | 2573 | .subvendor = 0x153b, |
2155 | .subdevice = 0x1143, | 2574 | .subdevice = 0x1143, |
2156 | .driver_data = SAA7134_BOARD_CINERGY600, | 2575 | .driver_data = SAA7134_BOARD_CINERGY600, |
2157 | },{ | 2576 | },{ |
2158 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2577 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2159 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 2578 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
2160 | .subvendor = 0x153B, | 2579 | .subvendor = 0x153b, |
2161 | .subdevice = 0x1158, | 2580 | .subdevice = 0x1158, |
2162 | .driver_data = SAA7134_BOARD_CINERGY600_MK3, | 2581 | .driver_data = SAA7134_BOARD_CINERGY600_MK3, |
2163 | },{ | 2582 | },{ |
@@ -2193,6 +2612,18 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
2193 | },{ | 2612 | },{ |
2194 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2613 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2195 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 2614 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
2615 | .subvendor = 0x14c0, | ||
2616 | .subdevice = 0x1212, /* minipci, LR1212 */ | ||
2617 | .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI2, | ||
2618 | },{ | ||
2619 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2620 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
2621 | .subvendor = 0x4e42, | ||
2622 | .subdevice = 0x0212, /* OEM minipci, LR212 */ | ||
2623 | .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI, | ||
2624 | },{ | ||
2625 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2626 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
2196 | .subvendor = 0x5168, /* Animation Technologies (LifeView) */ | 2627 | .subvendor = 0x5168, /* Animation Technologies (LifeView) */ |
2197 | .subdevice = 0x0214, /* Standard PCI, LR214WF */ | 2628 | .subdevice = 0x0214, /* Standard PCI, LR214WF */ |
2198 | .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, | 2629 | .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, |
@@ -2369,7 +2800,7 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
2369 | },{ | 2800 | },{ |
2370 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2801 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2371 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | 2802 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, |
2372 | .subvendor = 0x153B, | 2803 | .subvendor = 0x153b, |
2373 | .subdevice = 0x1152, | 2804 | .subdevice = 0x1152, |
2374 | .driver_data = SAA7134_BOARD_CINERGY200, | 2805 | .driver_data = SAA7134_BOARD_CINERGY200, |
2375 | },{ | 2806 | },{ |
@@ -2434,13 +2865,18 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
2434 | .subvendor = 0x1421, | 2865 | .subvendor = 0x1421, |
2435 | .subdevice = 0x0350, /* PCI version */ | 2866 | .subdevice = 0x0350, /* PCI version */ |
2436 | .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, | 2867 | .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, |
2437 | |||
2438 | },{ | 2868 | },{ |
2439 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2869 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2440 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 2870 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
2441 | .subvendor = 0x1421, | 2871 | .subvendor = 0x1421, |
2442 | .subdevice = 0x0370, /* cardbus version */ | 2872 | .subdevice = 0x0370, /* cardbus version */ |
2443 | .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, | 2873 | .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, |
2874 | },{ | ||
2875 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2876 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
2877 | .subvendor = 0x1421, | ||
2878 | .subdevice = 0x1370, /* cardbus version */ | ||
2879 | .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, | ||
2444 | 2880 | ||
2445 | },{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */ | 2881 | },{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */ |
2446 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2882 | .vendor = PCI_VENDOR_ID_PHILIPS, |
@@ -2459,9 +2895,81 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
2459 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 2895 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
2460 | .subvendor = 0x1043, | 2896 | .subvendor = 0x1043, |
2461 | .subdevice = 0x0210, /* mini pci PAL/SECAM version */ | 2897 | .subdevice = 0x0210, /* mini pci PAL/SECAM version */ |
2462 | .driver_data = SAA7134_BOARD_FLYTV_DIGIMATRIX, | 2898 | .driver_data = SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV, |
2463 | 2899 | ||
2464 | },{ | 2900 | },{ |
2901 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2902 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
2903 | .subvendor = 0x0000, /* It shouldn't break anything, since subdevice id seems unique */ | ||
2904 | .subdevice = 0x4091, | ||
2905 | .driver_data = SAA7134_BOARD_BEHOLD_409FM, | ||
2906 | },{ | ||
2907 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2908 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
2909 | .subvendor = 0x5456, /* GoTView */ | ||
2910 | .subdevice = 0x7135, | ||
2911 | .driver_data = SAA7134_BOARD_GOTVIEW_7135, | ||
2912 | },{ | ||
2913 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2914 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | ||
2915 | .subvendor = PCI_VENDOR_ID_PHILIPS, | ||
2916 | .subdevice = 0x2004, | ||
2917 | .driver_data = SAA7134_BOARD_PHILIPS_EUROPA, | ||
2918 | },{ | ||
2919 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2920 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | ||
2921 | .subvendor = 0x185b, | ||
2922 | .subdevice = 0xc900, | ||
2923 | .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_300, | ||
2924 | },{ | ||
2925 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2926 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | ||
2927 | .subvendor = 0x185b, | ||
2928 | .subdevice = 0xc901, | ||
2929 | .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_200, | ||
2930 | },{ | ||
2931 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2932 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
2933 | .subvendor = 0x1435, | ||
2934 | .subdevice = 0x7350, | ||
2935 | .driver_data = SAA7134_BOARD_RTD_VFG7350, | ||
2936 | },{ | ||
2937 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2938 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
2939 | .subvendor = 0x1435, | ||
2940 | .subdevice = 0x7330, | ||
2941 | .driver_data = SAA7134_BOARD_RTD_VFG7330, | ||
2942 | },{ | ||
2943 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2944 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
2945 | .subvendor = 0x1461, | ||
2946 | .subdevice = 0x1044, | ||
2947 | .driver_data = SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180, | ||
2948 | },{ | ||
2949 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2950 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
2951 | .subvendor = 0x1131, | ||
2952 | .subdevice = 0x4ee9, | ||
2953 | .driver_data = SAA7134_BOARD_MONSTERTV_MOBILE, | ||
2954 | },{ | ||
2955 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2956 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
2957 | .subvendor = 0x11bd, | ||
2958 | .subdevice = 0x002e, | ||
2959 | .driver_data = SAA7134_BOARD_PINNACLE_PCTV_110i, | ||
2960 | },{ | ||
2961 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2962 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
2963 | .subvendor = 0x1043, | ||
2964 | .subdevice = 0x4862, | ||
2965 | .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL, | ||
2966 | },{ | ||
2967 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
2968 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | ||
2969 | .subvendor = PCI_VENDOR_ID_PHILIPS, | ||
2970 | .subdevice = 0x2018, | ||
2971 | .driver_data = SAA7134_BOARD_PHILIPS_TIGER, | ||
2972 | },{ | ||
2465 | /* --- boards without eeprom + subsystem ID --- */ | 2973 | /* --- boards without eeprom + subsystem ID --- */ |
2466 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2974 | .vendor = PCI_VENDOR_ID_PHILIPS, |
2467 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, | 2975 | .device = PCI_DEVICE_ID_PHILIPS_SAA7134, |
@@ -2530,9 +3038,10 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
2530 | switch (dev->board) { | 3038 | switch (dev->board) { |
2531 | case SAA7134_BOARD_FLYVIDEO2000: | 3039 | case SAA7134_BOARD_FLYVIDEO2000: |
2532 | case SAA7134_BOARD_FLYVIDEO3000: | 3040 | case SAA7134_BOARD_FLYVIDEO3000: |
2533 | dev->has_remote = 1; | 3041 | dev->has_remote = SAA7134_REMOTE_GPIO; |
2534 | board_flyvideo(dev); | 3042 | board_flyvideo(dev); |
2535 | break; | 3043 | break; |
3044 | case SAA7134_BOARD_FLYTVPLATINUM_MINI2: | ||
2536 | case SAA7134_BOARD_FLYTVPLATINUM_FM: | 3045 | case SAA7134_BOARD_FLYTVPLATINUM_FM: |
2537 | case SAA7134_BOARD_CINERGY400: | 3046 | case SAA7134_BOARD_CINERGY400: |
2538 | case SAA7134_BOARD_CINERGY600: | 3047 | case SAA7134_BOARD_CINERGY600: |
@@ -2550,10 +3059,16 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
2550 | /* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ | 3059 | /* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ |
2551 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: | 3060 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: |
2552 | case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: | 3061 | case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: |
3062 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | ||
3063 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: | ||
2553 | case SAA7134_BOARD_MANLI_MTV001: | 3064 | case SAA7134_BOARD_MANLI_MTV001: |
2554 | case SAA7134_BOARD_MANLI_MTV002: | 3065 | case SAA7134_BOARD_MANLI_MTV002: |
3066 | case SAA7134_BOARD_BEHOLD_409FM: | ||
2555 | case SAA7134_BOARD_AVACSSMARTTV: | 3067 | case SAA7134_BOARD_AVACSSMARTTV: |
2556 | dev->has_remote = 1; | 3068 | case SAA7134_BOARD_GOTVIEW_7135: |
3069 | case SAA7134_BOARD_KWORLD_TERMINATOR: | ||
3070 | case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: | ||
3071 | dev->has_remote = SAA7134_REMOTE_GPIO; | ||
2557 | break; | 3072 | break; |
2558 | case SAA7134_BOARD_MD5044: | 3073 | case SAA7134_BOARD_MD5044: |
2559 | printk("%s: seems there are two different versions of the MD5044\n" | 3074 | printk("%s: seems there are two different versions of the MD5044\n" |
@@ -2565,11 +3080,14 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
2565 | /* power-up tuner chip */ | 3080 | /* power-up tuner chip */ |
2566 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); | 3081 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); |
2567 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000); | 3082 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000); |
2568 | msleep(1); | 3083 | case SAA7134_BOARD_MONSTERTV_MOBILE: |
3084 | /* power-up tuner chip */ | ||
3085 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); | ||
3086 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004); | ||
2569 | break; | 3087 | break; |
2570 | case SAA7134_BOARD_FLYDVBTDUO: | 3088 | case SAA7134_BOARD_FLYDVBTDUO: |
2571 | case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS: | 3089 | case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS: |
2572 | /* turn the fan on Hac: static for the time being */ | 3090 | /* turn the fan on */ |
2573 | saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); | 3091 | saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); |
2574 | saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06); | 3092 | saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06); |
2575 | break; | 3093 | break; |
@@ -2579,6 +3097,22 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
2579 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); | 3097 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); |
2580 | msleep(1); | 3098 | msleep(1); |
2581 | break; | 3099 | break; |
3100 | case SAA7134_BOARD_RTD_VFG7350: | ||
3101 | |||
3102 | /* | ||
3103 | * Make sure Production Test Register at offset 0x1D1 is cleared | ||
3104 | * to take chip out of test mode. Clearing bit 4 (TST_EN_AOUT) | ||
3105 | * prevents pin 105 from remaining low; keeping pin 105 low | ||
3106 | * continually resets the SAA6752 chip. | ||
3107 | */ | ||
3108 | |||
3109 | saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00); | ||
3110 | break; | ||
3111 | /* i2c remotes */ | ||
3112 | case SAA7134_BOARD_PINNACLE_PCTV_110i: | ||
3113 | case SAA7134_BOARD_UPMOST_PURPLE_TV: | ||
3114 | dev->has_remote = SAA7134_REMOTE_I2C; | ||
3115 | break; | ||
2582 | } | 3116 | } |
2583 | return 0; | 3117 | return 0; |
2584 | } | 3118 | } |
@@ -2613,7 +3147,7 @@ int saa7134_board_init2(struct saa7134_dev *dev) | |||
2613 | saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup); | 3147 | saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup); |
2614 | } | 3148 | } |
2615 | break; | 3149 | break; |
2616 | case SAA7134_BOARD_MD7134: | 3150 | case SAA7134_BOARD_MD7134: |
2617 | { | 3151 | { |
2618 | struct tuner_setup tun_setup; | 3152 | struct tuner_setup tun_setup; |
2619 | u8 subaddr; | 3153 | u8 subaddr; |
@@ -2680,6 +3214,33 @@ case SAA7134_BOARD_MD7134: | |||
2680 | saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup); | 3214 | saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup); |
2681 | } | 3215 | } |
2682 | break; | 3216 | break; |
3217 | case SAA7134_BOARD_PHILIPS_EUROPA: | ||
3218 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | ||
3219 | /* The Philips EUROPA based hybrid boards have the tuner connected through | ||
3220 | * the channel decoder. We have to make it transparent to find it | ||
3221 | */ | ||
3222 | { | ||
3223 | struct tuner_setup tun_setup; | ||
3224 | u8 data[] = { 0x07, 0x02}; | ||
3225 | struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; | ||
3226 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
3227 | |||
3228 | tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; | ||
3229 | tun_setup.type = dev->tuner_type; | ||
3230 | tun_setup.addr = dev->tuner_addr; | ||
3231 | |||
3232 | saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup); | ||
3233 | } | ||
3234 | break; | ||
3235 | case SAA7134_BOARD_PHILIPS_TIGER: | ||
3236 | case SAA7134_BOARD_ASUSTeK_P7131_DUAL: | ||
3237 | /* this is a hybrid board, initialize to analog mode */ | ||
3238 | { | ||
3239 | u8 data[] = { 0x3c, 0x33, 0x68}; | ||
3240 | struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; | ||
3241 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
3242 | } | ||
3243 | break; | ||
2683 | } | 3244 | } |
2684 | return 0; | 3245 | return 0; |
2685 | } | 3246 | } |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index e5e36f3c6250..19b88744fb31 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -57,6 +57,10 @@ static unsigned int oss = 0; | |||
57 | module_param(oss, int, 0444); | 57 | module_param(oss, int, 0444); |
58 | MODULE_PARM_DESC(oss,"register oss devices (default: no)"); | 58 | MODULE_PARM_DESC(oss,"register oss devices (default: no)"); |
59 | 59 | ||
60 | static unsigned int alsa = 0; | ||
61 | module_param(alsa, int, 0444); | ||
62 | MODULE_PARM_DESC(alsa,"register alsa devices (default: no)"); | ||
63 | |||
60 | static unsigned int latency = UNSET; | 64 | static unsigned int latency = UNSET; |
61 | module_param(latency, int, 0444); | 65 | module_param(latency, int, 0444); |
62 | MODULE_PARM_DESC(latency,"pci latency timer"); | 66 | MODULE_PARM_DESC(latency,"pci latency timer"); |
@@ -190,6 +194,7 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg) | |||
190 | 194 | ||
191 | static int need_empress; | 195 | static int need_empress; |
192 | static int need_dvb; | 196 | static int need_dvb; |
197 | static int need_alsa; | ||
193 | 198 | ||
194 | static int pending_call(struct notifier_block *self, unsigned long state, | 199 | static int pending_call(struct notifier_block *self, unsigned long state, |
195 | void *module) | 200 | void *module) |
@@ -197,10 +202,12 @@ static int pending_call(struct notifier_block *self, unsigned long state, | |||
197 | if (module != THIS_MODULE || state != MODULE_STATE_LIVE) | 202 | if (module != THIS_MODULE || state != MODULE_STATE_LIVE) |
198 | return NOTIFY_DONE; | 203 | return NOTIFY_DONE; |
199 | 204 | ||
200 | if (need_empress) | 205 | if (need_empress) |
201 | request_module("saa7134-empress"); | 206 | request_module("saa7134-empress"); |
202 | if (need_dvb) | 207 | if (need_dvb) |
203 | request_module("saa7134-dvb"); | 208 | request_module("saa7134-dvb"); |
209 | if (need_alsa) | ||
210 | request_module("saa7134-alsa"); | ||
204 | return NOTIFY_DONE; | 211 | return NOTIFY_DONE; |
205 | } | 212 | } |
206 | 213 | ||
@@ -275,8 +282,8 @@ unsigned long saa7134_buffer_base(struct saa7134_buf *buf) | |||
275 | 282 | ||
276 | int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt) | 283 | int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt) |
277 | { | 284 | { |
278 | __le32 *cpu; | 285 | __le32 *cpu; |
279 | dma_addr_t dma_addr; | 286 | dma_addr_t dma_addr; |
280 | 287 | ||
281 | cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr); | 288 | cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr); |
282 | if (NULL == cpu) | 289 | if (NULL == cpu) |
@@ -436,7 +443,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev) | |||
436 | ctrl |= SAA7134_MAIN_CTRL_TE0; | 443 | ctrl |= SAA7134_MAIN_CTRL_TE0; |
437 | irq |= SAA7134_IRQ1_INTE_RA0_1 | | 444 | irq |= SAA7134_IRQ1_INTE_RA0_1 | |
438 | SAA7134_IRQ1_INTE_RA0_0; | 445 | SAA7134_IRQ1_INTE_RA0_0; |
439 | cap = dev->video_q.curr->vb.field; | 446 | cap = dev->video_q.curr->vb.field; |
440 | } | 447 | } |
441 | 448 | ||
442 | /* video capture -- dma 1+2 (planar modes) */ | 449 | /* video capture -- dma 1+2 (planar modes) */ |
@@ -465,7 +472,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev) | |||
465 | } | 472 | } |
466 | 473 | ||
467 | /* audio capture -- dma 3 */ | 474 | /* audio capture -- dma 3 */ |
468 | if (dev->oss.dma_running) { | 475 | if (dev->dmasound.dma_running) { |
469 | ctrl |= SAA7134_MAIN_CTRL_TE6; | 476 | ctrl |= SAA7134_MAIN_CTRL_TE6; |
470 | irq |= SAA7134_IRQ1_INTE_RA3_1 | | 477 | irq |= SAA7134_IRQ1_INTE_RA3_1 | |
471 | SAA7134_IRQ1_INTE_RA3_0; | 478 | SAA7134_IRQ1_INTE_RA3_0; |
@@ -570,6 +577,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
570 | dev->name); | 577 | dev->name); |
571 | goto out; | 578 | goto out; |
572 | } | 579 | } |
580 | |||
581 | /* If alsa support is active and we get a sound report, exit | ||
582 | and let the saa7134-alsa module deal with it */ | ||
583 | |||
584 | if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && alsa) { | ||
585 | if (irq_debug > 1) | ||
586 | printk(KERN_DEBUG "%s/irq: ignoring interrupt for ALSA\n", | ||
587 | dev->name); | ||
588 | goto out; | ||
589 | } | ||
590 | |||
573 | handled = 1; | 591 | handled = 1; |
574 | saa_writel(SAA7134_IRQ_REPORT,report); | 592 | saa_writel(SAA7134_IRQ_REPORT,report); |
575 | if (irq_debug) | 593 | if (irq_debug) |
@@ -591,13 +609,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
591 | card_has_mpeg(dev)) | 609 | card_has_mpeg(dev)) |
592 | saa7134_irq_ts_done(dev,status); | 610 | saa7134_irq_ts_done(dev,status); |
593 | 611 | ||
594 | if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) | 612 | if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) { |
595 | saa7134_irq_oss_done(dev,status); | 613 | if (oss) { |
614 | saa7134_irq_oss_done(dev,status); | ||
615 | } | ||
616 | } | ||
596 | 617 | ||
597 | if ((report & (SAA7134_IRQ_REPORT_GPIO16 | | 618 | if ((report & (SAA7134_IRQ_REPORT_GPIO16 | |
598 | SAA7134_IRQ_REPORT_GPIO18)) && | 619 | SAA7134_IRQ_REPORT_GPIO18)) && |
599 | dev->remote) | 620 | dev->remote) |
600 | saa7134_input_irq(dev); | 621 | saa7134_input_irq(dev); |
622 | |||
601 | } | 623 | } |
602 | 624 | ||
603 | if (10 == loop) { | 625 | if (10 == loop) { |
@@ -636,7 +658,7 @@ static int saa7134_hwinit1(struct saa7134_dev *dev) | |||
636 | 658 | ||
637 | saa_writel(SAA7134_IRQ1, 0); | 659 | saa_writel(SAA7134_IRQ1, 0); |
638 | saa_writel(SAA7134_IRQ2, 0); | 660 | saa_writel(SAA7134_IRQ2, 0); |
639 | init_MUTEX(&dev->lock); | 661 | init_MUTEX(&dev->lock); |
640 | spin_lock_init(&dev->slock); | 662 | spin_lock_init(&dev->slock); |
641 | 663 | ||
642 | saa7134_track_gpio(dev,"pre-init"); | 664 | saa7134_track_gpio(dev,"pre-init"); |
@@ -646,14 +668,6 @@ static int saa7134_hwinit1(struct saa7134_dev *dev) | |||
646 | saa7134_ts_init1(dev); | 668 | saa7134_ts_init1(dev); |
647 | saa7134_input_init1(dev); | 669 | saa7134_input_init1(dev); |
648 | 670 | ||
649 | switch (dev->pci->device) { | ||
650 | case PCI_DEVICE_ID_PHILIPS_SAA7134: | ||
651 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | ||
652 | case PCI_DEVICE_ID_PHILIPS_SAA7135: | ||
653 | saa7134_oss_init1(dev); | ||
654 | break; | ||
655 | } | ||
656 | |||
657 | /* RAM FIFO config */ | 671 | /* RAM FIFO config */ |
658 | saa_writel(SAA7134_FIFO_SIZE, 0x08070503); | 672 | saa_writel(SAA7134_FIFO_SIZE, 0x08070503); |
659 | saa_writel(SAA7134_THRESHOULD,0x02020202); | 673 | saa_writel(SAA7134_THRESHOULD,0x02020202); |
@@ -668,6 +682,21 @@ static int saa7134_hwinit1(struct saa7134_dev *dev) | |||
668 | SAA7134_MAIN_CTRL_ESFE | | 682 | SAA7134_MAIN_CTRL_ESFE | |
669 | SAA7134_MAIN_CTRL_EBDAC); | 683 | SAA7134_MAIN_CTRL_EBDAC); |
670 | 684 | ||
685 | /* | ||
686 | * Initialize OSS _after_ enabling audio clock PLL and audio processing. | ||
687 | * OSS initialization writes to registers via the audio DSP; these | ||
688 | * writes will fail unless the audio clock has been started. At worst, | ||
689 | * audio will not work. | ||
690 | */ | ||
691 | |||
692 | switch (dev->pci->device) { | ||
693 | case PCI_DEVICE_ID_PHILIPS_SAA7134: | ||
694 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | ||
695 | case PCI_DEVICE_ID_PHILIPS_SAA7135: | ||
696 | saa7134_oss_init1(dev); | ||
697 | break; | ||
698 | } | ||
699 | |||
671 | /* enable peripheral devices */ | 700 | /* enable peripheral devices */ |
672 | saa_writeb(SAA7134_SPECIAL_MODE, 0x01); | 701 | saa_writeb(SAA7134_SPECIAL_MODE, 0x01); |
673 | 702 | ||
@@ -687,7 +716,7 @@ static int saa7134_hwinit2(struct saa7134_dev *dev) | |||
687 | saa7134_tvaudio_init2(dev); | 716 | saa7134_tvaudio_init2(dev); |
688 | 717 | ||
689 | /* enable IRQ's */ | 718 | /* enable IRQ's */ |
690 | irq2_mask = | 719 | irq2_mask = |
691 | SAA7134_IRQ2_INTE_DEC3 | | 720 | SAA7134_IRQ2_INTE_DEC3 | |
692 | SAA7134_IRQ2_INTE_DEC2 | | 721 | SAA7134_IRQ2_INTE_DEC2 | |
693 | SAA7134_IRQ2_INTE_DEC1 | | 722 | SAA7134_IRQ2_INTE_DEC1 | |
@@ -695,10 +724,12 @@ static int saa7134_hwinit2(struct saa7134_dev *dev) | |||
695 | SAA7134_IRQ2_INTE_PE | | 724 | SAA7134_IRQ2_INTE_PE | |
696 | SAA7134_IRQ2_INTE_AR; | 725 | SAA7134_IRQ2_INTE_AR; |
697 | 726 | ||
698 | if (dev->has_remote) | 727 | if (dev->has_remote == SAA7134_REMOTE_GPIO) |
699 | irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 | | 728 | irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 | |
700 | SAA7134_IRQ2_INTE_GPIO18A | | 729 | SAA7134_IRQ2_INTE_GPIO18A | |
701 | SAA7134_IRQ2_INTE_GPIO16 ); | 730 | SAA7134_IRQ2_INTE_GPIO16 ); |
731 | else if (dev->has_remote == SAA7134_REMOTE_I2C) | ||
732 | request_module("ir-kbd-i2c"); | ||
702 | 733 | ||
703 | saa_writel(SAA7134_IRQ1, 0); | 734 | saa_writel(SAA7134_IRQ1, 0); |
704 | saa_writel(SAA7134_IRQ2, irq2_mask); | 735 | saa_writel(SAA7134_IRQ2, irq2_mask); |
@@ -872,8 +903,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
872 | 903 | ||
873 | /* print pci info */ | 904 | /* print pci info */ |
874 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); | 905 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); |
875 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); | 906 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); |
876 | printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " | 907 | printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " |
877 | "latency: %d, mmio: 0x%lx\n", dev->name, | 908 | "latency: %d, mmio: 0x%lx\n", dev->name, |
878 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, | 909 | pci_name(pci_dev), dev->pci_rev, pci_dev->irq, |
879 | dev->pci_lat,pci_resource_start(pci_dev,0)); | 910 | dev->pci_lat,pci_resource_start(pci_dev,0)); |
@@ -897,7 +928,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
897 | dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf; | 928 | dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf; |
898 | if (UNSET != tuner[dev->nr]) | 929 | if (UNSET != tuner[dev->nr]) |
899 | dev->tuner_type = tuner[dev->nr]; | 930 | dev->tuner_type = tuner[dev->nr]; |
900 | printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", | 931 | printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", |
901 | dev->name,pci_dev->subsystem_vendor, | 932 | dev->name,pci_dev->subsystem_vendor, |
902 | pci_dev->subsystem_device,saa7134_boards[dev->board].name, | 933 | pci_dev->subsystem_device,saa7134_boards[dev->board].name, |
903 | dev->board, card[dev->nr] == dev->board ? | 934 | dev->board, card[dev->nr] == dev->board ? |
@@ -947,14 +978,20 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
947 | request_module("tuner"); | 978 | request_module("tuner"); |
948 | if (dev->tda9887_conf) | 979 | if (dev->tda9887_conf) |
949 | request_module("tda9887"); | 980 | request_module("tda9887"); |
950 | if (card_is_empress(dev)) { | 981 | if (card_is_empress(dev)) { |
951 | request_module("saa6752hs"); | 982 | request_module("saa6752hs"); |
952 | request_module_depend("saa7134-empress",&need_empress); | 983 | request_module_depend("saa7134-empress",&need_empress); |
953 | } | 984 | } |
954 | 985 | ||
955 | if (card_is_dvb(dev)) | 986 | if (card_is_dvb(dev)) |
956 | request_module_depend("saa7134-dvb",&need_dvb); | 987 | request_module_depend("saa7134-dvb",&need_dvb); |
957 | 988 | ||
989 | if (!oss && alsa) { | ||
990 | dprintk("Requesting ALSA module\n"); | ||
991 | request_module_depend("saa7134-alsa",&need_alsa); | ||
992 | } | ||
993 | |||
994 | |||
958 | v4l2_prio_init(&dev->prio); | 995 | v4l2_prio_init(&dev->prio); |
959 | 996 | ||
960 | /* register v4l devices */ | 997 | /* register v4l devices */ |
@@ -993,22 +1030,22 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
993 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | 1030 | case PCI_DEVICE_ID_PHILIPS_SAA7133: |
994 | case PCI_DEVICE_ID_PHILIPS_SAA7135: | 1031 | case PCI_DEVICE_ID_PHILIPS_SAA7135: |
995 | if (oss) { | 1032 | if (oss) { |
996 | err = dev->oss.minor_dsp = | 1033 | err = dev->dmasound.minor_dsp = |
997 | register_sound_dsp(&saa7134_dsp_fops, | 1034 | register_sound_dsp(&saa7134_dsp_fops, |
998 | dsp_nr[dev->nr]); | 1035 | dsp_nr[dev->nr]); |
999 | if (err < 0) { | 1036 | if (err < 0) { |
1000 | goto fail4; | 1037 | goto fail4; |
1001 | } | 1038 | } |
1002 | printk(KERN_INFO "%s: registered device dsp%d\n", | 1039 | printk(KERN_INFO "%s: registered device dsp%d\n", |
1003 | dev->name,dev->oss.minor_dsp >> 4); | 1040 | dev->name,dev->dmasound.minor_dsp >> 4); |
1004 | 1041 | ||
1005 | err = dev->oss.minor_mixer = | 1042 | err = dev->dmasound.minor_mixer = |
1006 | register_sound_mixer(&saa7134_mixer_fops, | 1043 | register_sound_mixer(&saa7134_mixer_fops, |
1007 | mixer_nr[dev->nr]); | 1044 | mixer_nr[dev->nr]); |
1008 | if (err < 0) | 1045 | if (err < 0) |
1009 | goto fail5; | 1046 | goto fail5; |
1010 | printk(KERN_INFO "%s: registered device mixer%d\n", | 1047 | printk(KERN_INFO "%s: registered device mixer%d\n", |
1011 | dev->name,dev->oss.minor_mixer >> 4); | 1048 | dev->name,dev->dmasound.minor_mixer >> 4); |
1012 | } | 1049 | } |
1013 | break; | 1050 | break; |
1014 | } | 1051 | } |
@@ -1035,7 +1072,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
1035 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | 1072 | case PCI_DEVICE_ID_PHILIPS_SAA7133: |
1036 | case PCI_DEVICE_ID_PHILIPS_SAA7135: | 1073 | case PCI_DEVICE_ID_PHILIPS_SAA7135: |
1037 | if (oss) | 1074 | if (oss) |
1038 | unregister_sound_dsp(dev->oss.minor_dsp); | 1075 | unregister_sound_dsp(dev->dmasound.minor_dsp); |
1039 | break; | 1076 | break; |
1040 | } | 1077 | } |
1041 | fail4: | 1078 | fail4: |
@@ -1055,7 +1092,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
1055 | 1092 | ||
1056 | static void __devexit saa7134_finidev(struct pci_dev *pci_dev) | 1093 | static void __devexit saa7134_finidev(struct pci_dev *pci_dev) |
1057 | { | 1094 | { |
1058 | struct saa7134_dev *dev = pci_get_drvdata(pci_dev); | 1095 | struct saa7134_dev *dev = pci_get_drvdata(pci_dev); |
1059 | struct list_head *item; | 1096 | struct list_head *item; |
1060 | struct saa7134_mpeg_ops *mops; | 1097 | struct saa7134_mpeg_ops *mops; |
1061 | 1098 | ||
@@ -1093,8 +1130,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) | |||
1093 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | 1130 | case PCI_DEVICE_ID_PHILIPS_SAA7133: |
1094 | case PCI_DEVICE_ID_PHILIPS_SAA7135: | 1131 | case PCI_DEVICE_ID_PHILIPS_SAA7135: |
1095 | if (oss) { | 1132 | if (oss) { |
1096 | unregister_sound_mixer(dev->oss.minor_mixer); | 1133 | unregister_sound_mixer(dev->dmasound.minor_mixer); |
1097 | unregister_sound_dsp(dev->oss.minor_dsp); | 1134 | unregister_sound_dsp(dev->dmasound.minor_dsp); |
1098 | } | 1135 | } |
1099 | break; | 1136 | break; |
1100 | } | 1137 | } |
@@ -1149,10 +1186,10 @@ EXPORT_SYMBOL(saa7134_ts_unregister); | |||
1149 | /* ----------------------------------------------------------- */ | 1186 | /* ----------------------------------------------------------- */ |
1150 | 1187 | ||
1151 | static struct pci_driver saa7134_pci_driver = { | 1188 | static struct pci_driver saa7134_pci_driver = { |
1152 | .name = "saa7134", | 1189 | .name = "saa7134", |
1153 | .id_table = saa7134_pci_tbl, | 1190 | .id_table = saa7134_pci_tbl, |
1154 | .probe = saa7134_initdev, | 1191 | .probe = saa7134_initdev, |
1155 | .remove = __devexit_p(saa7134_finidev), | 1192 | .remove = __devexit_p(saa7134_finidev), |
1156 | }; | 1193 | }; |
1157 | 1194 | ||
1158 | static int saa7134_init(void) | 1195 | static int saa7134_init(void) |
@@ -1188,6 +1225,13 @@ EXPORT_SYMBOL(saa7134_i2c_call_clients); | |||
1188 | EXPORT_SYMBOL(saa7134_devlist); | 1225 | EXPORT_SYMBOL(saa7134_devlist); |
1189 | EXPORT_SYMBOL(saa7134_boards); | 1226 | EXPORT_SYMBOL(saa7134_boards); |
1190 | 1227 | ||
1228 | /* ----------------- For ALSA -------------------------------- */ | ||
1229 | |||
1230 | EXPORT_SYMBOL(saa7134_pgtable_free); | ||
1231 | EXPORT_SYMBOL(saa7134_pgtable_build); | ||
1232 | EXPORT_SYMBOL(saa7134_pgtable_alloc); | ||
1233 | EXPORT_SYMBOL(saa7134_set_dmabits); | ||
1234 | |||
1191 | /* ----------------------------------------------------------- */ | 1235 | /* ----------------------------------------------------------- */ |
1192 | /* | 1236 | /* |
1193 | * Local variables: | 1237 | * Local variables: |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 639ae51a052d..e016480c3468 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/kthread.h> | 29 | #include <linux/kthread.h> |
30 | #include <linux/suspend.h> | 30 | #include <linux/suspend.h> |
31 | 31 | ||
32 | |||
33 | #include "saa7134-reg.h" | 32 | #include "saa7134-reg.h" |
34 | #include "saa7134.h" | 33 | #include "saa7134.h" |
35 | 34 | ||
@@ -40,6 +39,10 @@ | |||
40 | #ifdef HAVE_TDA1004X | 39 | #ifdef HAVE_TDA1004X |
41 | # include "tda1004x.h" | 40 | # include "tda1004x.h" |
42 | #endif | 41 | #endif |
42 | #ifdef HAVE_NXT200X | ||
43 | # include "nxt200x.h" | ||
44 | # include "dvb-pll.h" | ||
45 | #endif | ||
43 | 46 | ||
44 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 47 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
45 | MODULE_LICENSE("GPL"); | 48 | MODULE_LICENSE("GPL"); |
@@ -151,25 +154,12 @@ static struct mt352_config pinnacle_300i = { | |||
151 | /* ------------------------------------------------------------------ */ | 154 | /* ------------------------------------------------------------------ */ |
152 | 155 | ||
153 | #ifdef HAVE_TDA1004X | 156 | #ifdef HAVE_TDA1004X |
154 | static int philips_tu1216_pll_init(struct dvb_frontend *fe) | ||
155 | { | ||
156 | struct saa7134_dev *dev = fe->dvb->priv; | ||
157 | static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; | ||
158 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; | ||
159 | |||
160 | /* setup PLL configuration */ | ||
161 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) | ||
162 | return -EIO; | ||
163 | msleep(1); | ||
164 | 157 | ||
165 | return 0; | 158 | static int philips_tda6651_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
166 | } | ||
167 | |||
168 | static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
169 | { | 159 | { |
170 | struct saa7134_dev *dev = fe->dvb->priv; | 160 | struct saa7134_dev *dev = fe->dvb->priv; |
171 | u8 tuner_buf[4]; | 161 | u8 tuner_buf[4]; |
172 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len = | 162 | struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf,.len = |
173 | sizeof(tuner_buf) }; | 163 | sizeof(tuner_buf) }; |
174 | int tuner_frequency = 0; | 164 | int tuner_frequency = 0; |
175 | u8 band, cp, filter; | 165 | u8 band, cp, filter; |
@@ -242,11 +232,36 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p | |||
242 | 232 | ||
243 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) | 233 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) |
244 | return -EIO; | 234 | return -EIO; |
235 | msleep(1); | ||
236 | return 0; | ||
237 | } | ||
245 | 238 | ||
239 | static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe) | ||
240 | { | ||
241 | struct saa7134_dev *dev = fe->dvb->priv; | ||
242 | static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; | ||
243 | struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; | ||
244 | |||
245 | /* setup PLL configuration */ | ||
246 | if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) | ||
247 | return -EIO; | ||
246 | msleep(1); | 248 | msleep(1); |
249 | |||
247 | return 0; | 250 | return 0; |
248 | } | 251 | } |
249 | 252 | ||
253 | /* ------------------------------------------------------------------ */ | ||
254 | |||
255 | static int philips_tu1216_pll_60_init(struct dvb_frontend *fe) | ||
256 | { | ||
257 | return philips_tda6651_pll_init(0x60, fe); | ||
258 | } | ||
259 | |||
260 | static int philips_tu1216_pll_60_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
261 | { | ||
262 | return philips_tda6651_pll_set(0x60, fe, params); | ||
263 | } | ||
264 | |||
250 | static int philips_tu1216_request_firmware(struct dvb_frontend *fe, | 265 | static int philips_tu1216_request_firmware(struct dvb_frontend *fe, |
251 | const struct firmware **fw, char *name) | 266 | const struct firmware **fw, char *name) |
252 | { | 267 | { |
@@ -254,22 +269,108 @@ static int philips_tu1216_request_firmware(struct dvb_frontend *fe, | |||
254 | return request_firmware(fw, name, &dev->pci->dev); | 269 | return request_firmware(fw, name, &dev->pci->dev); |
255 | } | 270 | } |
256 | 271 | ||
257 | static struct tda1004x_config philips_tu1216_config = { | 272 | static struct tda1004x_config philips_tu1216_60_config = { |
273 | |||
274 | .demod_address = 0x8, | ||
275 | .invert = 1, | ||
276 | .invert_oclk = 0, | ||
277 | .xtal_freq = TDA10046_XTAL_4M, | ||
278 | .agc_config = TDA10046_AGC_DEFAULT, | ||
279 | .if_freq = TDA10046_FREQ_3617, | ||
280 | .pll_init = philips_tu1216_pll_60_init, | ||
281 | .pll_set = philips_tu1216_pll_60_set, | ||
282 | .pll_sleep = NULL, | ||
283 | .request_firmware = philips_tu1216_request_firmware, | ||
284 | }; | ||
285 | |||
286 | /* ------------------------------------------------------------------ */ | ||
287 | |||
288 | static int philips_tu1216_pll_61_init(struct dvb_frontend *fe) | ||
289 | { | ||
290 | return philips_tda6651_pll_init(0x61, fe); | ||
291 | } | ||
292 | |||
293 | static int philips_tu1216_pll_61_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
294 | { | ||
295 | return philips_tda6651_pll_set(0x61, fe, params); | ||
296 | } | ||
297 | |||
298 | static struct tda1004x_config philips_tu1216_61_config = { | ||
258 | 299 | ||
259 | .demod_address = 0x8, | 300 | .demod_address = 0x8, |
260 | .invert = 1, | 301 | .invert = 1, |
261 | .invert_oclk = 1, | 302 | .invert_oclk = 0, |
262 | .xtal_freq = TDA10046_XTAL_4M, | 303 | .xtal_freq = TDA10046_XTAL_4M, |
263 | .agc_config = TDA10046_AGC_DEFAULT, | 304 | .agc_config = TDA10046_AGC_DEFAULT, |
264 | .if_freq = TDA10046_FREQ_3617, | 305 | .if_freq = TDA10046_FREQ_3617, |
265 | .pll_init = philips_tu1216_pll_init, | 306 | .pll_init = philips_tu1216_pll_61_init, |
266 | .pll_set = philips_tu1216_pll_set, | 307 | .pll_set = philips_tu1216_pll_61_set, |
267 | .pll_sleep = NULL, | 308 | .pll_sleep = NULL, |
268 | .request_firmware = philips_tu1216_request_firmware, | 309 | .request_firmware = philips_tu1216_request_firmware, |
269 | }; | 310 | }; |
270 | 311 | ||
271 | /* ------------------------------------------------------------------ */ | 312 | /* ------------------------------------------------------------------ */ |
272 | 313 | ||
314 | static int philips_europa_pll_init(struct dvb_frontend *fe) | ||
315 | { | ||
316 | struct saa7134_dev *dev = fe->dvb->priv; | ||
317 | static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab }; | ||
318 | struct i2c_msg init_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) }; | ||
319 | |||
320 | /* setup PLL configuration */ | ||
321 | if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) | ||
322 | return -EIO; | ||
323 | msleep(1); | ||
324 | |||
325 | /* switch the board to dvb mode */ | ||
326 | init_msg.addr = 0x43; | ||
327 | init_msg.len = 0x02; | ||
328 | msg[0] = 0x00; | ||
329 | msg[1] = 0x40; | ||
330 | if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) | ||
331 | return -EIO; | ||
332 | |||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static int philips_td1316_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
337 | { | ||
338 | return philips_tda6651_pll_set(0x61, fe, params); | ||
339 | } | ||
340 | |||
341 | static void philips_europa_analog(struct dvb_frontend *fe) | ||
342 | { | ||
343 | struct saa7134_dev *dev = fe->dvb->priv; | ||
344 | /* this message actually turns the tuner back to analog mode */ | ||
345 | static u8 msg[] = { 0x0b, 0xdc, 0x86, 0xa4 }; | ||
346 | struct i2c_msg analog_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) }; | ||
347 | |||
348 | i2c_transfer(&dev->i2c_adap, &analog_msg, 1); | ||
349 | msleep(1); | ||
350 | |||
351 | /* switch the board to analog mode */ | ||
352 | analog_msg.addr = 0x43; | ||
353 | analog_msg.len = 0x02; | ||
354 | msg[0] = 0x00; | ||
355 | msg[1] = 0x14; | ||
356 | i2c_transfer(&dev->i2c_adap, &analog_msg, 1); | ||
357 | } | ||
358 | |||
359 | static struct tda1004x_config philips_europa_config = { | ||
360 | |||
361 | .demod_address = 0x8, | ||
362 | .invert = 0, | ||
363 | .invert_oclk = 0, | ||
364 | .xtal_freq = TDA10046_XTAL_4M, | ||
365 | .agc_config = TDA10046_AGC_IFO_AUTO_POS, | ||
366 | .if_freq = TDA10046_FREQ_052, | ||
367 | .pll_init = philips_europa_pll_init, | ||
368 | .pll_set = philips_td1316_pll_set, | ||
369 | .pll_sleep = philips_europa_analog, | ||
370 | .request_firmware = NULL, | ||
371 | }; | ||
372 | |||
373 | /* ------------------------------------------------------------------ */ | ||
273 | 374 | ||
274 | static int philips_fmd1216_pll_init(struct dvb_frontend *fe) | 375 | static int philips_fmd1216_pll_init(struct dvb_frontend *fe) |
275 | { | 376 | { |
@@ -382,7 +483,6 @@ static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_ | |||
382 | return 0; | 483 | return 0; |
383 | } | 484 | } |
384 | 485 | ||
385 | #ifdef HAVE_TDA1004X | ||
386 | static struct tda1004x_config medion_cardbus = { | 486 | static struct tda1004x_config medion_cardbus = { |
387 | .demod_address = 0x08, | 487 | .demod_address = 0x08, |
388 | .invert = 1, | 488 | .invert = 1, |
@@ -395,7 +495,6 @@ static struct tda1004x_config medion_cardbus = { | |||
395 | .pll_sleep = philips_fmd1216_analog, | 495 | .pll_sleep = philips_fmd1216_analog, |
396 | .request_firmware = NULL, | 496 | .request_firmware = NULL, |
397 | }; | 497 | }; |
398 | #endif | ||
399 | 498 | ||
400 | /* ------------------------------------------------------------------ */ | 499 | /* ------------------------------------------------------------------ */ |
401 | 500 | ||
@@ -452,7 +551,7 @@ static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_ | |||
452 | u8 tuner_buf[14]; | 551 | u8 tuner_buf[14]; |
453 | 552 | ||
454 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf, | 553 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf, |
455 | .len = sizeof(tuner_buf) }; | 554 | .len = sizeof(tuner_buf) }; |
456 | int i, tuner_freq, if_freq; | 555 | int i, tuner_freq, if_freq; |
457 | u32 N; | 556 | u32 N; |
458 | switch (params->u.ofdm.bandwidth) { | 557 | switch (params->u.ofdm.bandwidth) { |
@@ -511,7 +610,7 @@ static void philips_tda827x_pll_sleep(struct dvb_frontend *fe) | |||
511 | struct saa7134_dev *dev = fe->dvb->priv; | 610 | struct saa7134_dev *dev = fe->dvb->priv; |
512 | static u8 tda827x_sleep[] = { 0x30, 0xd0}; | 611 | static u8 tda827x_sleep[] = { 0x30, 0xd0}; |
513 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep, | 612 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep, |
514 | .len = sizeof(tda827x_sleep) }; | 613 | .len = sizeof(tda827x_sleep) }; |
515 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); | 614 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); |
516 | } | 615 | } |
517 | 616 | ||
@@ -527,6 +626,202 @@ static struct tda1004x_config tda827x_lifeview_config = { | |||
527 | .pll_sleep = philips_tda827x_pll_sleep, | 626 | .pll_sleep = philips_tda827x_pll_sleep, |
528 | .request_firmware = NULL, | 627 | .request_firmware = NULL, |
529 | }; | 628 | }; |
629 | |||
630 | /* ------------------------------------------------------------------ */ | ||
631 | |||
632 | struct tda827xa_data { | ||
633 | u32 lomax; | ||
634 | u8 svco; | ||
635 | u8 spd; | ||
636 | u8 scr; | ||
637 | u8 sbs; | ||
638 | u8 gc3; | ||
639 | }; | ||
640 | |||
641 | static struct tda827xa_data tda827xa_dvbt[] = { | ||
642 | { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
643 | { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
644 | { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
645 | { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
646 | { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
647 | { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
648 | { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
649 | { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
650 | { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
651 | { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
652 | { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
653 | { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
654 | { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
655 | { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
656 | { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
657 | { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
658 | { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
659 | { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, | ||
660 | { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
661 | { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
662 | { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
663 | { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
664 | { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
665 | { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
666 | { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
667 | { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, | ||
668 | { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}}; | ||
669 | |||
670 | |||
671 | static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
672 | { | ||
673 | struct saa7134_dev *dev = fe->dvb->priv; | ||
674 | u8 tuner_buf[14]; | ||
675 | unsigned char reg2[2]; | ||
676 | |||
677 | struct i2c_msg msg = {.addr = addr,.flags = 0,.buf = tuner_buf}; | ||
678 | int i, tuner_freq, if_freq; | ||
679 | u32 N; | ||
680 | |||
681 | switch (params->u.ofdm.bandwidth) { | ||
682 | case BANDWIDTH_6_MHZ: | ||
683 | if_freq = 4000000; | ||
684 | break; | ||
685 | case BANDWIDTH_7_MHZ: | ||
686 | if_freq = 4500000; | ||
687 | break; | ||
688 | default: /* 8 MHz or Auto */ | ||
689 | if_freq = 5000000; | ||
690 | break; | ||
691 | } | ||
692 | tuner_freq = params->frequency + if_freq; | ||
693 | |||
694 | i = 0; | ||
695 | while (tda827xa_dvbt[i].lomax < tuner_freq) { | ||
696 | if(tda827xa_dvbt[i + 1].lomax == 0) | ||
697 | break; | ||
698 | i++; | ||
699 | } | ||
700 | |||
701 | N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd; | ||
702 | tuner_buf[0] = 0; // subaddress | ||
703 | tuner_buf[1] = N >> 8; | ||
704 | tuner_buf[2] = N & 0xff; | ||
705 | tuner_buf[3] = 0; | ||
706 | tuner_buf[4] = 0x16; | ||
707 | tuner_buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) + | ||
708 | tda827xa_dvbt[i].sbs; | ||
709 | tuner_buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4); | ||
710 | tuner_buf[7] = 0x0c; | ||
711 | tuner_buf[8] = 0x06; | ||
712 | tuner_buf[9] = 0x24; | ||
713 | tuner_buf[10] = 0xff; | ||
714 | tuner_buf[11] = 0x60; | ||
715 | tuner_buf[12] = 0x00; | ||
716 | tuner_buf[13] = 0x39; // lpsel | ||
717 | msg.len = 14; | ||
718 | if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) | ||
719 | return -EIO; | ||
720 | |||
721 | msg.buf= reg2; | ||
722 | msg.len = 2; | ||
723 | reg2[0] = 0x60; | ||
724 | reg2[1] = 0x3c; | ||
725 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
726 | |||
727 | reg2[0] = 0xa0; | ||
728 | reg2[1] = 0x40; | ||
729 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
730 | |||
731 | msleep(2); | ||
732 | /* correct CP value */ | ||
733 | reg2[0] = 0x30; | ||
734 | reg2[1] = 0x10 + tda827xa_dvbt[i].scr; | ||
735 | msg.len = 2; | ||
736 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
737 | |||
738 | msleep(550); | ||
739 | reg2[0] = 0x50; | ||
740 | reg2[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4); | ||
741 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
742 | |||
743 | return 0; | ||
744 | |||
745 | } | ||
746 | |||
747 | static void philips_tda827xa_pll_sleep(u8 addr, struct dvb_frontend *fe) | ||
748 | { | ||
749 | struct saa7134_dev *dev = fe->dvb->priv; | ||
750 | static u8 tda827xa_sleep[] = { 0x30, 0x90}; | ||
751 | struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827xa_sleep, | ||
752 | .len = sizeof(tda827xa_sleep) }; | ||
753 | i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); | ||
754 | |||
755 | } | ||
756 | |||
757 | /* ------------------------------------------------------------------ */ | ||
758 | |||
759 | static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
760 | { | ||
761 | int ret; | ||
762 | struct saa7134_dev *dev = fe->dvb->priv; | ||
763 | static u8 tda8290_close[] = { 0x21, 0xc0}; | ||
764 | static u8 tda8290_open[] = { 0x21, 0x80}; | ||
765 | struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2}; | ||
766 | /* close tda8290 i2c bridge */ | ||
767 | tda8290_msg.buf = tda8290_close; | ||
768 | ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1); | ||
769 | if (ret != 1) | ||
770 | return -EIO; | ||
771 | msleep(20); | ||
772 | ret = philips_tda827xa_pll_set(0x61, fe, params); | ||
773 | if (ret != 0) | ||
774 | return ret; | ||
775 | /* open tda8290 i2c bridge */ | ||
776 | tda8290_msg.buf = tda8290_open; | ||
777 | i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1); | ||
778 | return ret; | ||
779 | }; | ||
780 | |||
781 | static int philips_tiger_dvb_mode(struct dvb_frontend *fe) | ||
782 | { | ||
783 | struct saa7134_dev *dev = fe->dvb->priv; | ||
784 | static u8 data[] = { 0x3c, 0x33, 0x6a}; | ||
785 | struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; | ||
786 | |||
787 | if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) | ||
788 | return -EIO; | ||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | static void philips_tiger_analog_mode(struct dvb_frontend *fe) | ||
793 | { | ||
794 | struct saa7134_dev *dev = fe->dvb->priv; | ||
795 | static u8 data[] = { 0x3c, 0x33, 0x68}; | ||
796 | struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; | ||
797 | |||
798 | i2c_transfer(&dev->i2c_adap, &msg, 1); | ||
799 | philips_tda827xa_pll_sleep( 0x61, fe); | ||
800 | } | ||
801 | |||
802 | static struct tda1004x_config philips_tiger_config = { | ||
803 | .demod_address = 0x08, | ||
804 | .invert = 1, | ||
805 | .invert_oclk = 0, | ||
806 | .xtal_freq = TDA10046_XTAL_16M, | ||
807 | .agc_config = TDA10046_AGC_TDA827X, | ||
808 | .if_freq = TDA10046_FREQ_045, | ||
809 | .pll_init = philips_tiger_dvb_mode, | ||
810 | .pll_set = philips_tiger_pll_set, | ||
811 | .pll_sleep = philips_tiger_analog_mode, | ||
812 | .request_firmware = NULL, | ||
813 | }; | ||
814 | |||
815 | #endif | ||
816 | |||
817 | /* ------------------------------------------------------------------ */ | ||
818 | |||
819 | #ifdef HAVE_NXT200X | ||
820 | static struct nxt200x_config avertvhda180 = { | ||
821 | .demod_address = 0x0a, | ||
822 | .pll_address = 0x61, | ||
823 | .pll_desc = &dvb_pll_tdhu2, | ||
824 | }; | ||
530 | #endif | 825 | #endif |
531 | 826 | ||
532 | /* ------------------------------------------------------------------ */ | 827 | /* ------------------------------------------------------------------ */ |
@@ -558,7 +853,7 @@ static int dvb_init(struct saa7134_dev *dev) | |||
558 | &dev->i2c_adap); | 853 | &dev->i2c_adap); |
559 | break; | 854 | break; |
560 | case SAA7134_BOARD_PHILIPS_TOUGH: | 855 | case SAA7134_BOARD_PHILIPS_TOUGH: |
561 | dev->dvb.frontend = tda10046_attach(&philips_tu1216_config, | 856 | dev->dvb.frontend = tda10046_attach(&philips_tu1216_60_config, |
562 | &dev->i2c_adap); | 857 | &dev->i2c_adap); |
563 | break; | 858 | break; |
564 | case SAA7134_BOARD_FLYDVBTDUO: | 859 | case SAA7134_BOARD_FLYDVBTDUO: |
@@ -569,6 +864,31 @@ static int dvb_init(struct saa7134_dev *dev) | |||
569 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, | 864 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, |
570 | &dev->i2c_adap); | 865 | &dev->i2c_adap); |
571 | break; | 866 | break; |
867 | case SAA7134_BOARD_PHILIPS_EUROPA: | ||
868 | dev->dvb.frontend = tda10046_attach(&philips_europa_config, | ||
869 | &dev->i2c_adap); | ||
870 | break; | ||
871 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | ||
872 | dev->dvb.frontend = tda10046_attach(&philips_europa_config, | ||
873 | &dev->i2c_adap); | ||
874 | break; | ||
875 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: | ||
876 | dev->dvb.frontend = tda10046_attach(&philips_tu1216_61_config, | ||
877 | &dev->i2c_adap); | ||
878 | break; | ||
879 | case SAA7134_BOARD_PHILIPS_TIGER: | ||
880 | dev->dvb.frontend = tda10046_attach(&philips_tiger_config, | ||
881 | &dev->i2c_adap); | ||
882 | break; | ||
883 | case SAA7134_BOARD_ASUSTeK_P7131_DUAL: | ||
884 | dev->dvb.frontend = tda10046_attach(&philips_tiger_config, | ||
885 | &dev->i2c_adap); | ||
886 | break; | ||
887 | #endif | ||
888 | #ifdef HAVE_NXT200X | ||
889 | case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180: | ||
890 | dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap); | ||
891 | break; | ||
572 | #endif | 892 | #endif |
573 | default: | 893 | default: |
574 | printk("%s: Huh? unknown DVB card?\n",dev->name); | 894 | printk("%s: Huh? unknown DVB card?\n",dev->name); |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 77b627eb6483..e9ec69efb4c9 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -55,7 +55,7 @@ static void ts_reset_encoder(struct saa7134_dev* dev) | |||
55 | 55 | ||
56 | saa_writeb(SAA7134_SPECIAL_MODE, 0x00); | 56 | saa_writeb(SAA7134_SPECIAL_MODE, 0x00); |
57 | msleep(10); | 57 | msleep(10); |
58 | saa_writeb(SAA7134_SPECIAL_MODE, 0x01); | 58 | saa_writeb(SAA7134_SPECIAL_MODE, 0x01); |
59 | msleep(100); | 59 | msleep(100); |
60 | dev->empress_started = 0; | 60 | dev->empress_started = 0; |
61 | } | 61 | } |
@@ -65,7 +65,7 @@ static int ts_init_encoder(struct saa7134_dev* dev) | |||
65 | ts_reset_encoder(dev); | 65 | ts_reset_encoder(dev); |
66 | saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL); | 66 | saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL); |
67 | dev->empress_started = 1; | 67 | dev->empress_started = 1; |
68 | return 0; | 68 | return 0; |
69 | } | 69 | } |
70 | 70 | ||
71 | /* ------------------------------------------------------------------ */ | 71 | /* ------------------------------------------------------------------ */ |
@@ -169,7 +169,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file, | |||
169 | struct v4l2_capability *cap = arg; | 169 | struct v4l2_capability *cap = arg; |
170 | 170 | ||
171 | memset(cap,0,sizeof(*cap)); | 171 | memset(cap,0,sizeof(*cap)); |
172 | strcpy(cap->driver, "saa7134"); | 172 | strcpy(cap->driver, "saa7134"); |
173 | strlcpy(cap->card, saa7134_boards[dev->board].name, | 173 | strlcpy(cap->card, saa7134_boards[dev->board].name, |
174 | sizeof(cap->card)); | 174 | sizeof(cap->card)); |
175 | sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); | 175 | sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); |
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index 711aa8e85fac..7575043f0874 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c | |||
@@ -239,7 +239,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
239 | unsigned char data; | 239 | unsigned char data; |
240 | int addr,rc,i,byte; | 240 | int addr,rc,i,byte; |
241 | 241 | ||
242 | status = i2c_get_status(dev); | 242 | status = i2c_get_status(dev); |
243 | if (!i2c_is_idle(status)) | 243 | if (!i2c_is_idle(status)) |
244 | if (!i2c_reset(dev)) | 244 | if (!i2c_reset(dev)) |
245 | return -EIO; | 245 | return -EIO; |
@@ -296,7 +296,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
296 | rc = -EIO; | 296 | rc = -EIO; |
297 | if (!i2c_is_busy_wait(dev)) | 297 | if (!i2c_is_busy_wait(dev)) |
298 | goto err; | 298 | goto err; |
299 | status = i2c_get_status(dev); | 299 | status = i2c_get_status(dev); |
300 | if (i2c_is_error(status)) | 300 | if (i2c_is_error(status)) |
301 | goto err; | 301 | goto err; |
302 | /* ensure that the bus is idle for at least one bit slot */ | 302 | /* ensure that the bus is idle for at least one bit slot */ |
@@ -335,6 +335,20 @@ static int attach_inform(struct i2c_client *client) | |||
335 | d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", | 335 | d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", |
336 | client->driver->name, client->addr, client->name); | 336 | client->driver->name, client->addr, client->name); |
337 | 337 | ||
338 | /* Am I an i2c remote control? */ | ||
339 | |||
340 | switch (client->addr) { | ||
341 | case 0x7a: | ||
342 | case 0x47: | ||
343 | { | ||
344 | struct IR_i2c *ir = i2c_get_clientdata(client); | ||
345 | d1printk("%s i2c IR detected (%s).\n", | ||
346 | client->driver->name,ir->phys); | ||
347 | saa7134_set_i2c_ir(dev,ir); | ||
348 | break; | ||
349 | } | ||
350 | } | ||
351 | |||
338 | if (!client->driver->command) | 352 | if (!client->driver->command) |
339 | return 0; | 353 | return 0; |
340 | 354 | ||
@@ -348,12 +362,12 @@ static int attach_inform(struct i2c_client *client) | |||
348 | 362 | ||
349 | client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup); | 363 | client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup); |
350 | } | 364 | } |
351 | } | 365 | } |
352 | 366 | ||
353 | if (tuner != UNSET) { | 367 | if (tuner != UNSET) { |
354 | 368 | ||
355 | tun_setup.type = tuner; | 369 | tun_setup.type = tuner; |
356 | tun_setup.addr = saa7134_boards[dev->board].tuner_addr; | 370 | tun_setup.addr = saa7134_boards[dev->board].tuner_addr; |
357 | 371 | ||
358 | if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) { | 372 | if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) { |
359 | 373 | ||
@@ -361,11 +375,11 @@ static int attach_inform(struct i2c_client *client) | |||
361 | 375 | ||
362 | client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup); | 376 | client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup); |
363 | } | 377 | } |
364 | } | 378 | } |
365 | 379 | ||
366 | client->driver->command(client, TDA9887_SET_CONFIG, &conf); | 380 | client->driver->command(client, TDA9887_SET_CONFIG, &conf); |
367 | 381 | ||
368 | return 0; | 382 | return 0; |
369 | } | 383 | } |
370 | 384 | ||
371 | static struct i2c_algorithm saa7134_algo = { | 385 | static struct i2c_algorithm saa7134_algo = { |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 242cb235cf92..329accda6d45 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -39,6 +39,8 @@ MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); | |||
39 | 39 | ||
40 | #define dprintk(fmt, arg...) if (ir_debug) \ | 40 | #define dprintk(fmt, arg...) if (ir_debug) \ |
41 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) | 41 | printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) |
42 | #define i2cdprintk(fmt, arg...) if (ir_debug) \ | ||
43 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) | ||
42 | 44 | ||
43 | /* ---------------------------------------------------------------------- */ | 45 | /* ---------------------------------------------------------------------- */ |
44 | 46 | ||
@@ -114,24 +116,24 @@ static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = { | |||
114 | /* Alfons Geser <a.geser@cox.net> | 116 | /* Alfons Geser <a.geser@cox.net> |
115 | * updates from Job D. R. Borges <jobdrb@ig.com.br> */ | 117 | * updates from Job D. R. Borges <jobdrb@ig.com.br> */ |
116 | static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = { | 118 | static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = { |
117 | [ 18 ] = KEY_POWER, | 119 | [ 18 ] = KEY_POWER, |
118 | [ 1 ] = KEY_TV, // DVR | 120 | [ 1 ] = KEY_TV, // DVR |
119 | [ 21 ] = KEY_DVD, // DVD | 121 | [ 21 ] = KEY_DVD, // DVD |
120 | [ 23 ] = KEY_AUDIO, // music | 122 | [ 23 ] = KEY_AUDIO, // music |
121 | // DVR mode / DVD mode / music mode | 123 | // DVR mode / DVD mode / music mode |
122 | 124 | ||
123 | [ 27 ] = KEY_MUTE, // mute | 125 | [ 27 ] = KEY_MUTE, // mute |
124 | [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek | 126 | [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek |
125 | [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek | 127 | [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek |
126 | [ 22 ] = KEY_ZOOM, // full screen | 128 | [ 22 ] = KEY_ZOOM, // full screen |
127 | [ 28 ] = KEY_VIDEO, // video source / eject / delall | 129 | [ 28 ] = KEY_VIDEO, // video source / eject / delall |
128 | [ 29 ] = KEY_RESTART, // playback / angle / del | 130 | [ 29 ] = KEY_RESTART, // playback / angle / del |
129 | [ 47 ] = KEY_SEARCH, // scan / menu / playlist | 131 | [ 47 ] = KEY_SEARCH, // scan / menu / playlist |
130 | [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo | 132 | [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo |
131 | 133 | ||
132 | [ 49 ] = KEY_HELP, // help | 134 | [ 49 ] = KEY_HELP, // help |
133 | [ 50 ] = KEY_MODE, // num/memo | 135 | [ 50 ] = KEY_MODE, // num/memo |
134 | [ 51 ] = KEY_ESC, // cancel | 136 | [ 51 ] = KEY_ESC, // cancel |
135 | 137 | ||
136 | [ 12 ] = KEY_UP, // up | 138 | [ 12 ] = KEY_UP, // up |
137 | [ 16 ] = KEY_DOWN, // down | 139 | [ 16 ] = KEY_DOWN, // down |
@@ -148,24 +150,24 @@ static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = { | |||
148 | [ 45 ] = KEY_PLAY, // play | 150 | [ 45 ] = KEY_PLAY, // play |
149 | [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle | 151 | [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle |
150 | 152 | ||
151 | [ 0 ] = KEY_KP0, | 153 | [ 0 ] = KEY_KP0, |
152 | [ 5 ] = KEY_KP1, | 154 | [ 5 ] = KEY_KP1, |
153 | [ 6 ] = KEY_KP2, | 155 | [ 6 ] = KEY_KP2, |
154 | [ 7 ] = KEY_KP3, | 156 | [ 7 ] = KEY_KP3, |
155 | [ 9 ] = KEY_KP4, | 157 | [ 9 ] = KEY_KP4, |
156 | [ 10 ] = KEY_KP5, | 158 | [ 10 ] = KEY_KP5, |
157 | [ 11 ] = KEY_KP6, | 159 | [ 11 ] = KEY_KP6, |
158 | [ 13 ] = KEY_KP7, | 160 | [ 13 ] = KEY_KP7, |
159 | [ 14 ] = KEY_KP8, | 161 | [ 14 ] = KEY_KP8, |
160 | [ 15 ] = KEY_KP9, | 162 | [ 15 ] = KEY_KP9, |
161 | 163 | ||
162 | [ 42 ] = KEY_VOLUMEUP, | 164 | [ 42 ] = KEY_VOLUMEUP, |
163 | [ 17 ] = KEY_VOLUMEDOWN, | 165 | [ 17 ] = KEY_VOLUMEDOWN, |
164 | [ 24 ] = KEY_CHANNELUP, // CH.tracking up | 166 | [ 24 ] = KEY_CHANNELUP, // CH.tracking up |
165 | [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down | 167 | [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down |
166 | 168 | ||
167 | [ 19 ] = KEY_KPENTER, // enter | 169 | [ 19 ] = KEY_KPENTER, // enter |
168 | [ 33 ] = KEY_KPDOT, // . (decimal dot) | 170 | [ 33 ] = KEY_KPDOT, // . (decimal dot) |
169 | }; | 171 | }; |
170 | 172 | ||
171 | static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = { | 173 | static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = { |
@@ -401,7 +403,183 @@ static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = { | |||
401 | 403 | ||
402 | // 0x1d unused ? | 404 | // 0x1d unused ? |
403 | }; | 405 | }; |
404 | /* ---------------------------------------------------------------------- */ | 406 | |
407 | |||
408 | /* Mike Baikov <mike@baikov.com> */ | ||
409 | static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = { | ||
410 | |||
411 | [ 33 ] = KEY_POWER, | ||
412 | [ 105] = KEY_TV, | ||
413 | [ 51 ] = KEY_KP0, | ||
414 | [ 81 ] = KEY_KP1, | ||
415 | [ 49 ] = KEY_KP2, | ||
416 | [ 113] = KEY_KP3, | ||
417 | [ 59 ] = KEY_KP4, | ||
418 | [ 88 ] = KEY_KP5, | ||
419 | [ 65 ] = KEY_KP6, | ||
420 | [ 72 ] = KEY_KP7, | ||
421 | [ 48 ] = KEY_KP8, | ||
422 | [ 83 ] = KEY_KP9, | ||
423 | [ 115] = KEY_AGAIN, /* LOOP */ | ||
424 | [ 10 ] = KEY_AUDIO, | ||
425 | [ 97 ] = KEY_PRINT, /* PREVIEW */ | ||
426 | [ 122] = KEY_VIDEO, | ||
427 | [ 32 ] = KEY_CHANNELUP, | ||
428 | [ 64 ] = KEY_CHANNELDOWN, | ||
429 | [ 24 ] = KEY_VOLUMEDOWN, | ||
430 | [ 80 ] = KEY_VOLUMEUP, | ||
431 | [ 16 ] = KEY_MUTE, | ||
432 | [ 74 ] = KEY_SEARCH, | ||
433 | [ 123] = KEY_SHUFFLE, /* SNAPSHOT */ | ||
434 | [ 34 ] = KEY_RECORD, | ||
435 | [ 98 ] = KEY_STOP, | ||
436 | [ 120] = KEY_PLAY, | ||
437 | [ 57 ] = KEY_REWIND, | ||
438 | [ 89 ] = KEY_PAUSE, | ||
439 | [ 25 ] = KEY_FORWARD, | ||
440 | [ 9 ] = KEY_ZOOM, | ||
441 | |||
442 | [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */ | ||
443 | [ 26 ] = KEY_F22, /* MIN TIMESHIFT */ | ||
444 | [ 58 ] = KEY_F23, /* TIMESHIFT */ | ||
445 | [ 112] = KEY_F24, /* NORMAL TIMESHIFT */ | ||
446 | }; | ||
447 | |||
448 | static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { | ||
449 | [ 0x3 ] = KEY_POWER, | ||
450 | [ 0x6f ] = KEY_MUTE, | ||
451 | [ 0x10 ] = KEY_BACKSPACE, /* Recall */ | ||
452 | |||
453 | [ 0x11 ] = KEY_KP0, | ||
454 | [ 0x4 ] = KEY_KP1, | ||
455 | [ 0x5 ] = KEY_KP2, | ||
456 | [ 0x6 ] = KEY_KP3, | ||
457 | [ 0x8 ] = KEY_KP4, | ||
458 | [ 0x9 ] = KEY_KP5, | ||
459 | [ 0xa ] = KEY_KP6, | ||
460 | [ 0xc ] = KEY_KP7, | ||
461 | [ 0xd ] = KEY_KP8, | ||
462 | [ 0xe ] = KEY_KP9, | ||
463 | [ 0x12 ] = KEY_KPDOT, /* 100+ */ | ||
464 | |||
465 | [ 0x7 ] = KEY_VOLUMEUP, | ||
466 | [ 0xb ] = KEY_VOLUMEDOWN, | ||
467 | [ 0x1a ] = KEY_KPPLUS, | ||
468 | [ 0x18 ] = KEY_KPMINUS, | ||
469 | [ 0x15 ] = KEY_UP, | ||
470 | [ 0x1d ] = KEY_DOWN, | ||
471 | [ 0xf ] = KEY_CHANNELUP, | ||
472 | [ 0x13 ] = KEY_CHANNELDOWN, | ||
473 | [ 0x48 ] = KEY_ZOOM, | ||
474 | |||
475 | [ 0x1b ] = KEY_VIDEO, /* Video source */ | ||
476 | [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */ | ||
477 | [ 0x19 ] = KEY_SEARCH, /* Auto Scan */ | ||
478 | |||
479 | [ 0x4b ] = KEY_RECORD, | ||
480 | [ 0x46 ] = KEY_PLAY, | ||
481 | [ 0x45 ] = KEY_PAUSE, /* Pause */ | ||
482 | [ 0x44 ] = KEY_STOP, | ||
483 | [ 0x40 ] = KEY_FORWARD, /* Forward ? */ | ||
484 | [ 0x42 ] = KEY_REWIND, /* Backward ? */ | ||
485 | |||
486 | }; | ||
487 | |||
488 | static IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = { | ||
489 | [ 0x59 ] = KEY_MUTE, | ||
490 | [ 0x4a ] = KEY_POWER, | ||
491 | |||
492 | [ 0x18 ] = KEY_TEXT, | ||
493 | [ 0x26 ] = KEY_TV, | ||
494 | [ 0x3d ] = KEY_PRINT, | ||
495 | |||
496 | [ 0x48 ] = KEY_RED, | ||
497 | [ 0x04 ] = KEY_GREEN, | ||
498 | [ 0x11 ] = KEY_YELLOW, | ||
499 | [ 0x00 ] = KEY_BLUE, | ||
500 | |||
501 | [ 0x2d ] = KEY_VOLUMEUP, | ||
502 | [ 0x1e ] = KEY_VOLUMEDOWN, | ||
503 | |||
504 | [ 0x49 ] = KEY_MENU, | ||
505 | |||
506 | [ 0x16 ] = KEY_CHANNELUP, | ||
507 | [ 0x17 ] = KEY_CHANNELDOWN, | ||
508 | |||
509 | [ 0x20 ] = KEY_UP, | ||
510 | [ 0x21 ] = KEY_DOWN, | ||
511 | [ 0x22 ] = KEY_LEFT, | ||
512 | [ 0x23 ] = KEY_RIGHT, | ||
513 | [ 0x0d ] = KEY_SELECT, | ||
514 | |||
515 | |||
516 | |||
517 | [ 0x08 ] = KEY_BACK, | ||
518 | [ 0x07 ] = KEY_REFRESH, | ||
519 | |||
520 | [ 0x2f ] = KEY_ZOOM, | ||
521 | [ 0x29 ] = KEY_RECORD, | ||
522 | |||
523 | [ 0x4b ] = KEY_PAUSE, | ||
524 | [ 0x4d ] = KEY_REWIND, | ||
525 | [ 0x2e ] = KEY_PLAY, | ||
526 | [ 0x4e ] = KEY_FORWARD, | ||
527 | [ 0x53 ] = KEY_PREVIOUS, | ||
528 | [ 0x4c ] = KEY_STOP, | ||
529 | [ 0x54 ] = KEY_NEXT, | ||
530 | |||
531 | [ 0x69 ] = KEY_KP0, | ||
532 | [ 0x6a ] = KEY_KP1, | ||
533 | [ 0x6b ] = KEY_KP2, | ||
534 | [ 0x6c ] = KEY_KP3, | ||
535 | [ 0x6d ] = KEY_KP4, | ||
536 | [ 0x6e ] = KEY_KP5, | ||
537 | [ 0x6f ] = KEY_KP6, | ||
538 | [ 0x70 ] = KEY_KP7, | ||
539 | [ 0x71 ] = KEY_KP8, | ||
540 | [ 0x72 ] = KEY_KP9, | ||
541 | |||
542 | [ 0x74 ] = KEY_CHANNEL, | ||
543 | [ 0x0a ] = KEY_BACKSPACE, | ||
544 | }; | ||
545 | |||
546 | /* Mapping for the 28 key remote control as seen at | ||
547 | http://www.sednacomputer.com/photo/cardbus-tv.jpg | ||
548 | Pavel Mihaylov <bin@bash.info> */ | ||
549 | static IR_KEYTAB_TYPE pctv_sedna_codes[IR_KEYTAB_SIZE] = { | ||
550 | [ 0 ] = KEY_KP0, | ||
551 | [ 1 ] = KEY_KP1, | ||
552 | [ 2 ] = KEY_KP2, | ||
553 | [ 3 ] = KEY_KP3, | ||
554 | [ 4 ] = KEY_KP4, | ||
555 | [ 5 ] = KEY_KP5, | ||
556 | [ 6 ] = KEY_KP6, | ||
557 | [ 7 ] = KEY_KP7, | ||
558 | [ 8 ] = KEY_KP8, | ||
559 | [ 9 ] = KEY_KP9, | ||
560 | |||
561 | [ 0x0a ] = KEY_AGAIN, /* Recall */ | ||
562 | [ 0x0b ] = KEY_CHANNELUP, | ||
563 | [ 0x0c ] = KEY_VOLUMEUP, | ||
564 | [ 0x0d ] = KEY_MODE, /* Stereo */ | ||
565 | [ 0x0e ] = KEY_STOP, | ||
566 | [ 0x0f ] = KEY_PREVIOUSSONG, | ||
567 | [ 0x10 ] = KEY_ZOOM, | ||
568 | [ 0x11 ] = KEY_TUNER, /* Source */ | ||
569 | [ 0x12 ] = KEY_POWER, | ||
570 | [ 0x13 ] = KEY_MUTE, | ||
571 | [ 0x15 ] = KEY_CHANNELDOWN, | ||
572 | [ 0x18 ] = KEY_VOLUMEDOWN, | ||
573 | [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */ | ||
574 | [ 0x1a ] = KEY_NEXTSONG, | ||
575 | [ 0x1b ] = KEY_TEXT, /* Time Shift */ | ||
576 | [ 0x1c ] = KEY_RADIO, /* FM Radio */ | ||
577 | [ 0x1d ] = KEY_RECORD, | ||
578 | [ 0x1e ] = KEY_PAUSE, | ||
579 | }; | ||
580 | |||
581 | |||
582 | /* -------------------- GPIO generic keycode builder -------------------- */ | ||
405 | 583 | ||
406 | static int build_key(struct saa7134_dev *dev) | 584 | static int build_key(struct saa7134_dev *dev) |
407 | { | 585 | { |
@@ -413,13 +591,13 @@ static int build_key(struct saa7134_dev *dev) | |||
413 | saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN); | 591 | saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN); |
414 | 592 | ||
415 | gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); | 593 | gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); |
416 | if (ir->polling) { | 594 | if (ir->polling) { |
417 | if (ir->last_gpio == gpio) | 595 | if (ir->last_gpio == gpio) |
418 | return 0; | 596 | return 0; |
419 | ir->last_gpio = gpio; | 597 | ir->last_gpio = gpio; |
420 | } | 598 | } |
421 | 599 | ||
422 | data = ir_extract_bits(gpio, ir->mask_keycode); | 600 | data = ir_extract_bits(gpio, ir->mask_keycode); |
423 | dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", | 601 | dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", |
424 | gpio, ir->mask_keycode, data); | 602 | gpio, ir->mask_keycode, data); |
425 | 603 | ||
@@ -432,13 +610,87 @@ static int build_key(struct saa7134_dev *dev) | |||
432 | return 0; | 610 | return 0; |
433 | } | 611 | } |
434 | 612 | ||
435 | /* ---------------------------------------------------------------------- */ | 613 | /* --------------------- Chip specific I2C key builders ----------------- */ |
614 | |||
615 | static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
616 | { | ||
617 | unsigned char b; | ||
618 | |||
619 | /* poll IR chip */ | ||
620 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | ||
621 | i2cdprintk("read error\n"); | ||
622 | return -EIO; | ||
623 | } | ||
624 | |||
625 | /* no button press */ | ||
626 | if (b==0) | ||
627 | return 0; | ||
628 | |||
629 | /* repeating */ | ||
630 | if (b & 0x80) | ||
631 | return 1; | ||
632 | |||
633 | *ir_key = b; | ||
634 | *ir_raw = b; | ||
635 | return 1; | ||
636 | } | ||
637 | |||
638 | /* The new pinnacle PCTV remote (with the colored buttons) | ||
639 | * | ||
640 | * Ricardo Cerqueira <v4l@cerqueira.org> | ||
641 | */ | ||
642 | |||
643 | static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
644 | { | ||
645 | unsigned char b[4]; | ||
646 | unsigned int start = 0,parity = 0,code = 0; | ||
647 | |||
648 | /* poll IR chip */ | ||
649 | if (4 != i2c_master_recv(&ir->c,b,4)) { | ||
650 | i2cdprintk("read error\n"); | ||
651 | return -EIO; | ||
652 | } | ||
653 | |||
654 | for (start = 0; start<4; start++) { | ||
655 | if (b[start] == 0x80) { | ||
656 | code=b[(start+3)%4]; | ||
657 | parity=b[(start+2)%4]; | ||
658 | } | ||
659 | } | ||
660 | |||
661 | /* Empty Request */ | ||
662 | if (parity==0) | ||
663 | return 0; | ||
664 | |||
665 | /* Repeating... */ | ||
666 | if (ir->old == parity) | ||
667 | return 0; | ||
668 | |||
669 | |||
670 | ir->old = parity; | ||
671 | |||
672 | /* Reduce code value to fit inside IR_KEYTAB_SIZE | ||
673 | * | ||
674 | * this is the only value that results in 42 unique | ||
675 | * codes < 128 | ||
676 | */ | ||
677 | |||
678 | code %= 0x88; | ||
679 | |||
680 | *ir_raw = code; | ||
681 | *ir_key = code; | ||
682 | |||
683 | i2cdprintk("Pinnacle PCTV key %02x\n", code); | ||
684 | |||
685 | return 1; | ||
686 | } | ||
687 | |||
436 | 688 | ||
437 | void saa7134_input_irq(struct saa7134_dev *dev) | 689 | void saa7134_input_irq(struct saa7134_dev *dev) |
438 | { | 690 | { |
439 | struct saa7134_ir *ir = dev->remote; | 691 | struct saa7134_ir *ir = dev->remote; |
440 | 692 | ||
441 | if (!ir->polling) | 693 | if (!ir->polling) |
442 | build_key(dev); | 694 | build_key(dev); |
443 | } | 695 | } |
444 | 696 | ||
@@ -464,7 +716,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
464 | int polling = 0; | 716 | int polling = 0; |
465 | int ir_type = IR_TYPE_OTHER; | 717 | int ir_type = IR_TYPE_OTHER; |
466 | 718 | ||
467 | if (!dev->has_remote) | 719 | if (dev->has_remote != SAA7134_REMOTE_GPIO) |
468 | return -ENODEV; | 720 | return -ENODEV; |
469 | if (disable_ir) | 721 | if (disable_ir) |
470 | return -ENODEV; | 722 | return -ENODEV; |
@@ -473,7 +725,8 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
473 | switch (dev->board) { | 725 | switch (dev->board) { |
474 | case SAA7134_BOARD_FLYVIDEO2000: | 726 | case SAA7134_BOARD_FLYVIDEO2000: |
475 | case SAA7134_BOARD_FLYVIDEO3000: | 727 | case SAA7134_BOARD_FLYVIDEO3000: |
476 | case SAA7134_BOARD_FLYTVPLATINUM_FM: | 728 | case SAA7134_BOARD_FLYTVPLATINUM_FM: |
729 | case SAA7134_BOARD_FLYTVPLATINUM_MINI2: | ||
477 | ir_codes = flyvideo_codes; | 730 | ir_codes = flyvideo_codes; |
478 | mask_keycode = 0xEC00000; | 731 | mask_keycode = 0xEC00000; |
479 | mask_keydown = 0x0040000; | 732 | mask_keydown = 0x0040000; |
@@ -514,14 +767,33 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
514 | saa_setb(SAA7134_GPIO_GPMODE0, 0x4); | 767 | saa_setb(SAA7134_GPIO_GPMODE0, 0x4); |
515 | saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); | 768 | saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); |
516 | break; | 769 | break; |
770 | case SAA7134_BOARD_KWORLD_TERMINATOR: | ||
771 | ir_codes = avacssmart_codes; | ||
772 | mask_keycode = 0x00001f; | ||
773 | mask_keyup = 0x000060; | ||
774 | polling = 50; // ms | ||
775 | break; | ||
517 | case SAA7134_BOARD_MANLI_MTV001: | 776 | case SAA7134_BOARD_MANLI_MTV001: |
518 | case SAA7134_BOARD_MANLI_MTV002: | 777 | case SAA7134_BOARD_MANLI_MTV002: |
778 | case SAA7134_BOARD_BEHOLD_409FM: | ||
519 | ir_codes = manli_codes; | 779 | ir_codes = manli_codes; |
520 | mask_keycode = 0x001f00; | 780 | mask_keycode = 0x001f00; |
521 | mask_keyup = 0x004000; | 781 | mask_keyup = 0x004000; |
522 | mask_keydown = 0x002000; | ||
523 | polling = 50; // ms | 782 | polling = 50; // ms |
524 | break; | 783 | break; |
784 | case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS: | ||
785 | ir_codes = pctv_sedna_codes; | ||
786 | mask_keycode = 0x001f00; | ||
787 | mask_keyup = 0x004000; | ||
788 | polling = 50; // ms | ||
789 | break; | ||
790 | case SAA7134_BOARD_GOTVIEW_7135: | ||
791 | ir_codes = gotview7135_codes; | ||
792 | mask_keycode = 0x0003EC; | ||
793 | mask_keyup = 0x008000; | ||
794 | mask_keydown = 0x000010; | ||
795 | polling = 50; // ms | ||
796 | break; | ||
525 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: | 797 | case SAA7134_BOARD_VIDEOMATE_TV_PVR: |
526 | case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: | 798 | case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: |
527 | ir_codes = videomate_tv_pvr_codes; | 799 | ir_codes = videomate_tv_pvr_codes; |
@@ -529,6 +801,12 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
529 | mask_keyup = 0x400000; | 801 | mask_keyup = 0x400000; |
530 | polling = 50; // ms | 802 | polling = 50; // ms |
531 | break; | 803 | break; |
804 | case SAA7134_BOARD_VIDEOMATE_DVBT_300: | ||
805 | case SAA7134_BOARD_VIDEOMATE_DVBT_200: | ||
806 | ir_codes = videomate_tv_pvr_codes; | ||
807 | mask_keycode = 0x003F00; | ||
808 | mask_keyup = 0x040000; | ||
809 | break; | ||
532 | } | 810 | } |
533 | if (NULL == ir_codes) { | 811 | if (NULL == ir_codes) { |
534 | printk("%s: Oops: IR config error [card=%d]\n", | 812 | printk("%s: Oops: IR config error [card=%d]\n", |
@@ -548,7 +826,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) | |||
548 | ir->mask_keycode = mask_keycode; | 826 | ir->mask_keycode = mask_keycode; |
549 | ir->mask_keydown = mask_keydown; | 827 | ir->mask_keydown = mask_keydown; |
550 | ir->mask_keyup = mask_keyup; | 828 | ir->mask_keyup = mask_keyup; |
551 | ir->polling = polling; | 829 | ir->polling = polling; |
552 | 830 | ||
553 | /* init input device */ | 831 | /* init input device */ |
554 | snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", | 832 | snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", |
@@ -596,6 +874,31 @@ void saa7134_input_fini(struct saa7134_dev *dev) | |||
596 | dev->remote = NULL; | 874 | dev->remote = NULL; |
597 | } | 875 | } |
598 | 876 | ||
877 | void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) | ||
878 | { | ||
879 | if (disable_ir) { | ||
880 | dprintk("Found supported i2c remote, but IR has been disabled\n"); | ||
881 | ir->get_key=NULL; | ||
882 | return; | ||
883 | } | ||
884 | |||
885 | switch (dev->board) { | ||
886 | case SAA7134_BOARD_PINNACLE_PCTV_110i: | ||
887 | snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); | ||
888 | ir->get_key = get_key_pinnacle; | ||
889 | ir->ir_codes = ir_codes_pinnacle; | ||
890 | break; | ||
891 | case SAA7134_BOARD_UPMOST_PURPLE_TV: | ||
892 | snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV"); | ||
893 | ir->get_key = get_key_purpletv; | ||
894 | ir->ir_codes = ir_codes_purpletv; | ||
895 | break; | ||
896 | default: | ||
897 | dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board); | ||
898 | break; | ||
899 | } | ||
900 | |||
901 | } | ||
599 | /* ---------------------------------------------------------------------- | 902 | /* ---------------------------------------------------------------------- |
600 | * Local variables: | 903 | * Local variables: |
601 | * c-basic-offset: 8 | 904 | * c-basic-offset: 8 |
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c index c20630c82f1c..fd53dfcc1644 100644 --- a/drivers/media/video/saa7134/saa7134-oss.c +++ b/drivers/media/video/saa7134/saa7134-oss.c | |||
@@ -44,6 +44,7 @@ MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)"); | |||
44 | #define dprintk(fmt, arg...) if (oss_debug) \ | 44 | #define dprintk(fmt, arg...) if (oss_debug) \ |
45 | printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg) | 45 | printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg) |
46 | 46 | ||
47 | |||
47 | /* ------------------------------------------------------------------ */ | 48 | /* ------------------------------------------------------------------ */ |
48 | 49 | ||
49 | static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) | 50 | static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) |
@@ -58,12 +59,12 @@ static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) | |||
58 | if ((blksize * blocks) > 1024*1024) | 59 | if ((blksize * blocks) > 1024*1024) |
59 | blocks = 1024*1024 / blksize; | 60 | blocks = 1024*1024 / blksize; |
60 | 61 | ||
61 | dev->oss.blocks = blocks; | 62 | dev->dmasound.blocks = blocks; |
62 | dev->oss.blksize = blksize; | 63 | dev->dmasound.blksize = blksize; |
63 | dev->oss.bufsize = blksize * blocks; | 64 | dev->dmasound.bufsize = blksize * blocks; |
64 | 65 | ||
65 | dprintk("buffer config: %d blocks / %d bytes, %d kB total\n", | 66 | dprintk("buffer config: %d blocks / %d bytes, %d kB total\n", |
66 | blocks,blksize,blksize * blocks / 1024); | 67 | blocks,blksize,blksize * blocks / 1024); |
67 | return 0; | 68 | return 0; |
68 | } | 69 | } |
69 | 70 | ||
@@ -71,11 +72,11 @@ static int dsp_buffer_init(struct saa7134_dev *dev) | |||
71 | { | 72 | { |
72 | int err; | 73 | int err; |
73 | 74 | ||
74 | if (!dev->oss.bufsize) | 75 | if (!dev->dmasound.bufsize) |
75 | BUG(); | 76 | BUG(); |
76 | videobuf_dma_init(&dev->oss.dma); | 77 | videobuf_dma_init(&dev->dmasound.dma); |
77 | err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE, | 78 | err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE, |
78 | (dev->oss.bufsize + PAGE_SIZE) >> PAGE_SHIFT); | 79 | (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT); |
79 | if (0 != err) | 80 | if (0 != err) |
80 | return err; | 81 | return err; |
81 | return 0; | 82 | return 0; |
@@ -83,26 +84,26 @@ static int dsp_buffer_init(struct saa7134_dev *dev) | |||
83 | 84 | ||
84 | static int dsp_buffer_free(struct saa7134_dev *dev) | 85 | static int dsp_buffer_free(struct saa7134_dev *dev) |
85 | { | 86 | { |
86 | if (!dev->oss.blksize) | 87 | if (!dev->dmasound.blksize) |
87 | BUG(); | 88 | BUG(); |
88 | videobuf_dma_free(&dev->oss.dma); | 89 | videobuf_dma_free(&dev->dmasound.dma); |
89 | dev->oss.blocks = 0; | 90 | dev->dmasound.blocks = 0; |
90 | dev->oss.blksize = 0; | 91 | dev->dmasound.blksize = 0; |
91 | dev->oss.bufsize = 0; | 92 | dev->dmasound.bufsize = 0; |
92 | return 0; | 93 | return 0; |
93 | } | 94 | } |
94 | 95 | ||
95 | static void dsp_dma_start(struct saa7134_dev *dev) | 96 | static void dsp_dma_start(struct saa7134_dev *dev) |
96 | { | 97 | { |
97 | dev->oss.dma_blk = 0; | 98 | dev->dmasound.dma_blk = 0; |
98 | dev->oss.dma_running = 1; | 99 | dev->dmasound.dma_running = 1; |
99 | saa7134_set_dmabits(dev); | 100 | saa7134_set_dmabits(dev); |
100 | } | 101 | } |
101 | 102 | ||
102 | static void dsp_dma_stop(struct saa7134_dev *dev) | 103 | static void dsp_dma_stop(struct saa7134_dev *dev) |
103 | { | 104 | { |
104 | dev->oss.dma_blk = -1; | 105 | dev->dmasound.dma_blk = -1; |
105 | dev->oss.dma_running = 0; | 106 | dev->dmasound.dma_running = 0; |
106 | saa7134_set_dmabits(dev); | 107 | saa7134_set_dmabits(dev); |
107 | } | 108 | } |
108 | 109 | ||
@@ -113,18 +114,18 @@ static int dsp_rec_start(struct saa7134_dev *dev) | |||
113 | unsigned long flags; | 114 | unsigned long flags; |
114 | 115 | ||
115 | /* prepare buffer */ | 116 | /* prepare buffer */ |
116 | if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma))) | 117 | if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma))) |
117 | return err; | 118 | return err; |
118 | if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->oss.pt))) | 119 | if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) |
119 | goto fail1; | 120 | goto fail1; |
120 | if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->oss.pt, | 121 | if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt, |
121 | dev->oss.dma.sglist, | 122 | dev->dmasound.dma.sglist, |
122 | dev->oss.dma.sglen, | 123 | dev->dmasound.dma.sglen, |
123 | 0))) | 124 | 0))) |
124 | goto fail2; | 125 | goto fail2; |
125 | 126 | ||
126 | /* sample format */ | 127 | /* sample format */ |
127 | switch (dev->oss.afmt) { | 128 | switch (dev->dmasound.afmt) { |
128 | case AFMT_U8: | 129 | case AFMT_U8: |
129 | case AFMT_S8: fmt = 0x00; break; | 130 | case AFMT_S8: fmt = 0x00; break; |
130 | case AFMT_U16_LE: | 131 | case AFMT_U16_LE: |
@@ -136,14 +137,14 @@ static int dsp_rec_start(struct saa7134_dev *dev) | |||
136 | goto fail2; | 137 | goto fail2; |
137 | } | 138 | } |
138 | 139 | ||
139 | switch (dev->oss.afmt) { | 140 | switch (dev->dmasound.afmt) { |
140 | case AFMT_S8: | 141 | case AFMT_S8: |
141 | case AFMT_S16_LE: | 142 | case AFMT_S16_LE: |
142 | case AFMT_S16_BE: sign = 1; break; | 143 | case AFMT_S16_BE: sign = 1; break; |
143 | default: sign = 0; break; | 144 | default: sign = 0; break; |
144 | } | 145 | } |
145 | 146 | ||
146 | switch (dev->oss.afmt) { | 147 | switch (dev->dmasound.afmt) { |
147 | case AFMT_U16_BE: | 148 | case AFMT_U16_BE: |
148 | case AFMT_S16_BE: bswap = 1; break; | 149 | case AFMT_S16_BE: bswap = 1; break; |
149 | default: bswap = 0; break; | 150 | default: bswap = 0; break; |
@@ -151,58 +152,58 @@ static int dsp_rec_start(struct saa7134_dev *dev) | |||
151 | 152 | ||
152 | switch (dev->pci->device) { | 153 | switch (dev->pci->device) { |
153 | case PCI_DEVICE_ID_PHILIPS_SAA7134: | 154 | case PCI_DEVICE_ID_PHILIPS_SAA7134: |
154 | if (1 == dev->oss.channels) | 155 | if (1 == dev->dmasound.channels) |
155 | fmt |= (1 << 3); | 156 | fmt |= (1 << 3); |
156 | if (2 == dev->oss.channels) | 157 | if (2 == dev->dmasound.channels) |
157 | fmt |= (3 << 3); | 158 | fmt |= (3 << 3); |
158 | if (sign) | 159 | if (sign) |
159 | fmt |= 0x04; | 160 | fmt |= 0x04; |
160 | fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80; | 161 | fmt |= (TV == dev->dmasound.input) ? 0xc0 : 0x80; |
161 | 162 | ||
162 | saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->oss.blksize - 1) & 0x0000ff)); | 163 | saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff)); |
163 | saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->oss.blksize - 1) & 0x00ff00) >> 8); | 164 | saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8); |
164 | saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->oss.blksize - 1) & 0xff0000) >> 16); | 165 | saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16); |
165 | saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt); | 166 | saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt); |
166 | 167 | ||
167 | break; | 168 | break; |
168 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | 169 | case PCI_DEVICE_ID_PHILIPS_SAA7133: |
169 | case PCI_DEVICE_ID_PHILIPS_SAA7135: | 170 | case PCI_DEVICE_ID_PHILIPS_SAA7135: |
170 | if (1 == dev->oss.channels) | 171 | if (1 == dev->dmasound.channels) |
171 | fmt |= (1 << 4); | 172 | fmt |= (1 << 4); |
172 | if (2 == dev->oss.channels) | 173 | if (2 == dev->dmasound.channels) |
173 | fmt |= (2 << 4); | 174 | fmt |= (2 << 4); |
174 | if (!sign) | 175 | if (!sign) |
175 | fmt |= 0x04; | 176 | fmt |= 0x04; |
176 | saa_writel(0x588 >> 2, dev->oss.blksize -4); | 177 | saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -4); |
177 | saa_writel(0x58c >> 2, 0x543210 | (fmt << 24)); | 178 | saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24)); |
178 | break; | 179 | break; |
179 | } | 180 | } |
180 | dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n", | 181 | dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n", |
181 | dev->oss.afmt, dev->oss.channels, fmt, | 182 | dev->dmasound.afmt, dev->dmasound.channels, fmt, |
182 | bswap ? 'b' : '-'); | 183 | bswap ? 'b' : '-'); |
183 | 184 | ||
184 | /* dma: setup channel 6 (= AUDIO) */ | 185 | /* dma: setup channel 6 (= AUDIO) */ |
185 | control = SAA7134_RS_CONTROL_BURST_16 | | 186 | control = SAA7134_RS_CONTROL_BURST_16 | |
186 | SAA7134_RS_CONTROL_ME | | 187 | SAA7134_RS_CONTROL_ME | |
187 | (dev->oss.pt.dma >> 12); | 188 | (dev->dmasound.pt.dma >> 12); |
188 | if (bswap) | 189 | if (bswap) |
189 | control |= SAA7134_RS_CONTROL_BSWAP; | 190 | control |= SAA7134_RS_CONTROL_BSWAP; |
190 | saa_writel(SAA7134_RS_BA1(6),0); | 191 | saa_writel(SAA7134_RS_BA1(6),0); |
191 | saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize); | 192 | saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize); |
192 | saa_writel(SAA7134_RS_PITCH(6),0); | 193 | saa_writel(SAA7134_RS_PITCH(6),0); |
193 | saa_writel(SAA7134_RS_CONTROL(6),control); | 194 | saa_writel(SAA7134_RS_CONTROL(6),control); |
194 | 195 | ||
195 | /* start dma */ | 196 | /* start dma */ |
196 | dev->oss.recording_on = 1; | 197 | dev->dmasound.recording_on = 1; |
197 | spin_lock_irqsave(&dev->slock,flags); | 198 | spin_lock_irqsave(&dev->slock,flags); |
198 | dsp_dma_start(dev); | 199 | dsp_dma_start(dev); |
199 | spin_unlock_irqrestore(&dev->slock,flags); | 200 | spin_unlock_irqrestore(&dev->slock,flags); |
200 | return 0; | 201 | return 0; |
201 | 202 | ||
202 | fail2: | 203 | fail2: |
203 | saa7134_pgtable_free(dev->pci,&dev->oss.pt); | 204 | saa7134_pgtable_free(dev->pci,&dev->dmasound.pt); |
204 | fail1: | 205 | fail1: |
205 | videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma); | 206 | videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma); |
206 | return err; | 207 | return err; |
207 | } | 208 | } |
208 | 209 | ||
@@ -210,17 +211,17 @@ static int dsp_rec_stop(struct saa7134_dev *dev) | |||
210 | { | 211 | { |
211 | unsigned long flags; | 212 | unsigned long flags; |
212 | 213 | ||
213 | dprintk("rec_stop dma_blk=%d\n",dev->oss.dma_blk); | 214 | dprintk("rec_stop dma_blk=%d\n",dev->dmasound.dma_blk); |
214 | 215 | ||
215 | /* stop dma */ | 216 | /* stop dma */ |
216 | dev->oss.recording_on = 0; | 217 | dev->dmasound.recording_on = 0; |
217 | spin_lock_irqsave(&dev->slock,flags); | 218 | spin_lock_irqsave(&dev->slock,flags); |
218 | dsp_dma_stop(dev); | 219 | dsp_dma_stop(dev); |
219 | spin_unlock_irqrestore(&dev->slock,flags); | 220 | spin_unlock_irqrestore(&dev->slock,flags); |
220 | 221 | ||
221 | /* unlock buffer */ | 222 | /* unlock buffer */ |
222 | saa7134_pgtable_free(dev->pci,&dev->oss.pt); | 223 | saa7134_pgtable_free(dev->pci,&dev->dmasound.pt); |
223 | videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma); | 224 | videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma); |
224 | return 0; | 225 | return 0; |
225 | } | 226 | } |
226 | 227 | ||
@@ -235,35 +236,35 @@ static int dsp_open(struct inode *inode, struct file *file) | |||
235 | 236 | ||
236 | list_for_each(list,&saa7134_devlist) { | 237 | list_for_each(list,&saa7134_devlist) { |
237 | h = list_entry(list, struct saa7134_dev, devlist); | 238 | h = list_entry(list, struct saa7134_dev, devlist); |
238 | if (h->oss.minor_dsp == minor) | 239 | if (h->dmasound.minor_dsp == minor) |
239 | dev = h; | 240 | dev = h; |
240 | } | 241 | } |
241 | if (NULL == dev) | 242 | if (NULL == dev) |
242 | return -ENODEV; | 243 | return -ENODEV; |
243 | 244 | ||
244 | down(&dev->oss.lock); | 245 | down(&dev->dmasound.lock); |
245 | err = -EBUSY; | 246 | err = -EBUSY; |
246 | if (dev->oss.users_dsp) | 247 | if (dev->dmasound.users_dsp) |
247 | goto fail1; | 248 | goto fail1; |
248 | dev->oss.users_dsp++; | 249 | dev->dmasound.users_dsp++; |
249 | file->private_data = dev; | 250 | file->private_data = dev; |
250 | 251 | ||
251 | dev->oss.afmt = AFMT_U8; | 252 | dev->dmasound.afmt = AFMT_U8; |
252 | dev->oss.channels = 1; | 253 | dev->dmasound.channels = 1; |
253 | dev->oss.read_count = 0; | 254 | dev->dmasound.read_count = 0; |
254 | dev->oss.read_offset = 0; | 255 | dev->dmasound.read_offset = 0; |
255 | dsp_buffer_conf(dev,PAGE_SIZE,64); | 256 | dsp_buffer_conf(dev,PAGE_SIZE,64); |
256 | err = dsp_buffer_init(dev); | 257 | err = dsp_buffer_init(dev); |
257 | if (0 != err) | 258 | if (0 != err) |
258 | goto fail2; | 259 | goto fail2; |
259 | 260 | ||
260 | up(&dev->oss.lock); | 261 | up(&dev->dmasound.lock); |
261 | return 0; | 262 | return 0; |
262 | 263 | ||
263 | fail2: | 264 | fail2: |
264 | dev->oss.users_dsp--; | 265 | dev->dmasound.users_dsp--; |
265 | fail1: | 266 | fail1: |
266 | up(&dev->oss.lock); | 267 | up(&dev->dmasound.lock); |
267 | return err; | 268 | return err; |
268 | } | 269 | } |
269 | 270 | ||
@@ -271,13 +272,13 @@ static int dsp_release(struct inode *inode, struct file *file) | |||
271 | { | 272 | { |
272 | struct saa7134_dev *dev = file->private_data; | 273 | struct saa7134_dev *dev = file->private_data; |
273 | 274 | ||
274 | down(&dev->oss.lock); | 275 | down(&dev->dmasound.lock); |
275 | if (dev->oss.recording_on) | 276 | if (dev->dmasound.recording_on) |
276 | dsp_rec_stop(dev); | 277 | dsp_rec_stop(dev); |
277 | dsp_buffer_free(dev); | 278 | dsp_buffer_free(dev); |
278 | dev->oss.users_dsp--; | 279 | dev->dmasound.users_dsp--; |
279 | file->private_data = NULL; | 280 | file->private_data = NULL; |
280 | up(&dev->oss.lock); | 281 | up(&dev->dmasound.lock); |
281 | return 0; | 282 | return 0; |
282 | } | 283 | } |
283 | 284 | ||
@@ -290,12 +291,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer, | |||
290 | unsigned long flags; | 291 | unsigned long flags; |
291 | int err,ret = 0; | 292 | int err,ret = 0; |
292 | 293 | ||
293 | add_wait_queue(&dev->oss.wq, &wait); | 294 | add_wait_queue(&dev->dmasound.wq, &wait); |
294 | down(&dev->oss.lock); | 295 | down(&dev->dmasound.lock); |
295 | while (count > 0) { | 296 | while (count > 0) { |
296 | /* wait for data if needed */ | 297 | /* wait for data if needed */ |
297 | if (0 == dev->oss.read_count) { | 298 | if (0 == dev->dmasound.read_count) { |
298 | if (!dev->oss.recording_on) { | 299 | if (!dev->dmasound.recording_on) { |
299 | err = dsp_rec_start(dev); | 300 | err = dsp_rec_start(dev); |
300 | if (err < 0) { | 301 | if (err < 0) { |
301 | if (0 == ret) | 302 | if (0 == ret) |
@@ -303,8 +304,8 @@ static ssize_t dsp_read(struct file *file, char __user *buffer, | |||
303 | break; | 304 | break; |
304 | } | 305 | } |
305 | } | 306 | } |
306 | if (dev->oss.recording_on && | 307 | if (dev->dmasound.recording_on && |
307 | !dev->oss.dma_running) { | 308 | !dev->dmasound.dma_running) { |
308 | /* recover from overruns */ | 309 | /* recover from overruns */ |
309 | spin_lock_irqsave(&dev->slock,flags); | 310 | spin_lock_irqsave(&dev->slock,flags); |
310 | dsp_dma_start(dev); | 311 | dsp_dma_start(dev); |
@@ -315,12 +316,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer, | |||
315 | ret = -EAGAIN; | 316 | ret = -EAGAIN; |
316 | break; | 317 | break; |
317 | } | 318 | } |
318 | up(&dev->oss.lock); | 319 | up(&dev->dmasound.lock); |
319 | set_current_state(TASK_INTERRUPTIBLE); | 320 | set_current_state(TASK_INTERRUPTIBLE); |
320 | if (0 == dev->oss.read_count) | 321 | if (0 == dev->dmasound.read_count) |
321 | schedule(); | 322 | schedule(); |
322 | set_current_state(TASK_RUNNING); | 323 | set_current_state(TASK_RUNNING); |
323 | down(&dev->oss.lock); | 324 | down(&dev->dmasound.lock); |
324 | if (signal_pending(current)) { | 325 | if (signal_pending(current)) { |
325 | if (0 == ret) | 326 | if (0 == ret) |
326 | ret = -EINTR; | 327 | ret = -EINTR; |
@@ -330,12 +331,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer, | |||
330 | 331 | ||
331 | /* copy data to userspace */ | 332 | /* copy data to userspace */ |
332 | bytes = count; | 333 | bytes = count; |
333 | if (bytes > dev->oss.read_count) | 334 | if (bytes > dev->dmasound.read_count) |
334 | bytes = dev->oss.read_count; | 335 | bytes = dev->dmasound.read_count; |
335 | if (bytes > dev->oss.bufsize - dev->oss.read_offset) | 336 | if (bytes > dev->dmasound.bufsize - dev->dmasound.read_offset) |
336 | bytes = dev->oss.bufsize - dev->oss.read_offset; | 337 | bytes = dev->dmasound.bufsize - dev->dmasound.read_offset; |
337 | if (copy_to_user(buffer + ret, | 338 | if (copy_to_user(buffer + ret, |
338 | dev->oss.dma.vmalloc + dev->oss.read_offset, | 339 | dev->dmasound.dma.vmalloc + dev->dmasound.read_offset, |
339 | bytes)) { | 340 | bytes)) { |
340 | if (0 == ret) | 341 | if (0 == ret) |
341 | ret = -EFAULT; | 342 | ret = -EFAULT; |
@@ -344,13 +345,13 @@ static ssize_t dsp_read(struct file *file, char __user *buffer, | |||
344 | 345 | ||
345 | ret += bytes; | 346 | ret += bytes; |
346 | count -= bytes; | 347 | count -= bytes; |
347 | dev->oss.read_count -= bytes; | 348 | dev->dmasound.read_count -= bytes; |
348 | dev->oss.read_offset += bytes; | 349 | dev->dmasound.read_offset += bytes; |
349 | if (dev->oss.read_offset == dev->oss.bufsize) | 350 | if (dev->dmasound.read_offset == dev->dmasound.bufsize) |
350 | dev->oss.read_offset = 0; | 351 | dev->dmasound.read_offset = 0; |
351 | } | 352 | } |
352 | up(&dev->oss.lock); | 353 | up(&dev->dmasound.lock); |
353 | remove_wait_queue(&dev->oss.wq, &wait); | 354 | remove_wait_queue(&dev->dmasound.wq, &wait); |
354 | return ret; | 355 | return ret; |
355 | } | 356 | } |
356 | 357 | ||
@@ -370,53 +371,53 @@ static int dsp_ioctl(struct inode *inode, struct file *file, | |||
370 | 371 | ||
371 | if (oss_debug > 1) | 372 | if (oss_debug > 1) |
372 | saa7134_print_ioctl(dev->name,cmd); | 373 | saa7134_print_ioctl(dev->name,cmd); |
373 | switch (cmd) { | 374 | switch (cmd) { |
374 | case OSS_GETVERSION: | 375 | case OSS_GETVERSION: |
375 | return put_user(SOUND_VERSION, p); | 376 | return put_user(SOUND_VERSION, p); |
376 | case SNDCTL_DSP_GETCAPS: | 377 | case SNDCTL_DSP_GETCAPS: |
377 | return 0; | 378 | return 0; |
378 | 379 | ||
379 | case SNDCTL_DSP_SPEED: | 380 | case SNDCTL_DSP_SPEED: |
380 | if (get_user(val, p)) | 381 | if (get_user(val, p)) |
381 | return -EFAULT; | 382 | return -EFAULT; |
382 | /* fall through */ | 383 | /* fall through */ |
383 | case SOUND_PCM_READ_RATE: | 384 | case SOUND_PCM_READ_RATE: |
384 | return put_user(dev->oss.rate, p); | 385 | return put_user(dev->dmasound.rate, p); |
385 | 386 | ||
386 | case SNDCTL_DSP_STEREO: | 387 | case SNDCTL_DSP_STEREO: |
387 | if (get_user(val, p)) | 388 | if (get_user(val, p)) |
388 | return -EFAULT; | 389 | return -EFAULT; |
389 | down(&dev->oss.lock); | 390 | down(&dev->dmasound.lock); |
390 | dev->oss.channels = val ? 2 : 1; | 391 | dev->dmasound.channels = val ? 2 : 1; |
391 | if (dev->oss.recording_on) { | 392 | if (dev->dmasound.recording_on) { |
392 | dsp_rec_stop(dev); | 393 | dsp_rec_stop(dev); |
393 | dsp_rec_start(dev); | 394 | dsp_rec_start(dev); |
394 | } | 395 | } |
395 | up(&dev->oss.lock); | 396 | up(&dev->dmasound.lock); |
396 | return put_user(dev->oss.channels-1, p); | 397 | return put_user(dev->dmasound.channels-1, p); |
397 | 398 | ||
398 | case SNDCTL_DSP_CHANNELS: | 399 | case SNDCTL_DSP_CHANNELS: |
399 | if (get_user(val, p)) | 400 | if (get_user(val, p)) |
400 | return -EFAULT; | 401 | return -EFAULT; |
401 | if (val != 1 && val != 2) | 402 | if (val != 1 && val != 2) |
402 | return -EINVAL; | 403 | return -EINVAL; |
403 | down(&dev->oss.lock); | 404 | down(&dev->dmasound.lock); |
404 | dev->oss.channels = val; | 405 | dev->dmasound.channels = val; |
405 | if (dev->oss.recording_on) { | 406 | if (dev->dmasound.recording_on) { |
406 | dsp_rec_stop(dev); | 407 | dsp_rec_stop(dev); |
407 | dsp_rec_start(dev); | 408 | dsp_rec_start(dev); |
408 | } | 409 | } |
409 | up(&dev->oss.lock); | 410 | up(&dev->dmasound.lock); |
410 | /* fall through */ | 411 | /* fall through */ |
411 | case SOUND_PCM_READ_CHANNELS: | 412 | case SOUND_PCM_READ_CHANNELS: |
412 | return put_user(dev->oss.channels, p); | 413 | return put_user(dev->dmasound.channels, p); |
413 | 414 | ||
414 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | 415 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ |
415 | return put_user(AFMT_U8 | AFMT_S8 | | 416 | return put_user(AFMT_U8 | AFMT_S8 | |
416 | AFMT_U16_LE | AFMT_U16_BE | | 417 | AFMT_U16_LE | AFMT_U16_BE | |
417 | AFMT_S16_LE | AFMT_S16_BE, p); | 418 | AFMT_S16_LE | AFMT_S16_BE, p); |
418 | 419 | ||
419 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */ | 420 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */ |
420 | if (get_user(val, p)) | 421 | if (get_user(val, p)) |
421 | return -EFAULT; | 422 | return -EFAULT; |
422 | switch (val) { | 423 | switch (val) { |
@@ -429,20 +430,20 @@ static int dsp_ioctl(struct inode *inode, struct file *file, | |||
429 | case AFMT_U16_BE: | 430 | case AFMT_U16_BE: |
430 | case AFMT_S16_LE: | 431 | case AFMT_S16_LE: |
431 | case AFMT_S16_BE: | 432 | case AFMT_S16_BE: |
432 | down(&dev->oss.lock); | 433 | down(&dev->dmasound.lock); |
433 | dev->oss.afmt = val; | 434 | dev->dmasound.afmt = val; |
434 | if (dev->oss.recording_on) { | 435 | if (dev->dmasound.recording_on) { |
435 | dsp_rec_stop(dev); | 436 | dsp_rec_stop(dev); |
436 | dsp_rec_start(dev); | 437 | dsp_rec_start(dev); |
437 | } | 438 | } |
438 | up(&dev->oss.lock); | 439 | up(&dev->dmasound.lock); |
439 | return put_user(dev->oss.afmt, p); | 440 | return put_user(dev->dmasound.afmt, p); |
440 | default: | 441 | default: |
441 | return -EINVAL; | 442 | return -EINVAL; |
442 | } | 443 | } |
443 | 444 | ||
444 | case SOUND_PCM_READ_BITS: | 445 | case SOUND_PCM_READ_BITS: |
445 | switch (dev->oss.afmt) { | 446 | switch (dev->dmasound.afmt) { |
446 | case AFMT_U8: | 447 | case AFMT_U8: |
447 | case AFMT_S8: | 448 | case AFMT_S8: |
448 | return put_user(8, p); | 449 | return put_user(8, p); |
@@ -455,23 +456,23 @@ static int dsp_ioctl(struct inode *inode, struct file *file, | |||
455 | return -EINVAL; | 456 | return -EINVAL; |
456 | } | 457 | } |
457 | 458 | ||
458 | case SNDCTL_DSP_NONBLOCK: | 459 | case SNDCTL_DSP_NONBLOCK: |
459 | file->f_flags |= O_NONBLOCK; | 460 | file->f_flags |= O_NONBLOCK; |
460 | return 0; | 461 | return 0; |
461 | 462 | ||
462 | case SNDCTL_DSP_RESET: | 463 | case SNDCTL_DSP_RESET: |
463 | down(&dev->oss.lock); | 464 | down(&dev->dmasound.lock); |
464 | if (dev->oss.recording_on) | 465 | if (dev->dmasound.recording_on) |
465 | dsp_rec_stop(dev); | 466 | dsp_rec_stop(dev); |
466 | up(&dev->oss.lock); | 467 | up(&dev->dmasound.lock); |
467 | return 0; | 468 | return 0; |
468 | case SNDCTL_DSP_GETBLKSIZE: | 469 | case SNDCTL_DSP_GETBLKSIZE: |
469 | return put_user(dev->oss.blksize, p); | 470 | return put_user(dev->dmasound.blksize, p); |
470 | 471 | ||
471 | case SNDCTL_DSP_SETFRAGMENT: | 472 | case SNDCTL_DSP_SETFRAGMENT: |
472 | if (get_user(val, p)) | 473 | if (get_user(val, p)) |
473 | return -EFAULT; | 474 | return -EFAULT; |
474 | if (dev->oss.recording_on) | 475 | if (dev->dmasound.recording_on) |
475 | return -EBUSY; | 476 | return -EBUSY; |
476 | dsp_buffer_free(dev); | 477 | dsp_buffer_free(dev); |
477 | /* used to be arg >> 16 instead of val >> 16; fixed */ | 478 | /* used to be arg >> 16 instead of val >> 16; fixed */ |
@@ -479,16 +480,16 @@ static int dsp_ioctl(struct inode *inode, struct file *file, | |||
479 | dsp_buffer_init(dev); | 480 | dsp_buffer_init(dev); |
480 | return 0; | 481 | return 0; |
481 | 482 | ||
482 | case SNDCTL_DSP_SYNC: | 483 | case SNDCTL_DSP_SYNC: |
483 | /* NOP */ | 484 | /* NOP */ |
484 | return 0; | 485 | return 0; |
485 | 486 | ||
486 | case SNDCTL_DSP_GETISPACE: | 487 | case SNDCTL_DSP_GETISPACE: |
487 | { | 488 | { |
488 | audio_buf_info info; | 489 | audio_buf_info info; |
489 | info.fragsize = dev->oss.blksize; | 490 | info.fragsize = dev->dmasound.blksize; |
490 | info.fragstotal = dev->oss.blocks; | 491 | info.fragstotal = dev->dmasound.blocks; |
491 | info.bytes = dev->oss.read_count; | 492 | info.bytes = dev->dmasound.read_count; |
492 | info.fragments = info.bytes / info.fragsize; | 493 | info.fragments = info.bytes / info.fragsize; |
493 | if (copy_to_user(argp, &info, sizeof(info))) | 494 | if (copy_to_user(argp, &info, sizeof(info))) |
494 | return -EFAULT; | 495 | return -EFAULT; |
@@ -504,13 +505,13 @@ static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait) | |||
504 | struct saa7134_dev *dev = file->private_data; | 505 | struct saa7134_dev *dev = file->private_data; |
505 | unsigned int mask = 0; | 506 | unsigned int mask = 0; |
506 | 507 | ||
507 | poll_wait(file, &dev->oss.wq, wait); | 508 | poll_wait(file, &dev->dmasound.wq, wait); |
508 | 509 | ||
509 | if (0 == dev->oss.read_count) { | 510 | if (0 == dev->dmasound.read_count) { |
510 | down(&dev->oss.lock); | 511 | down(&dev->dmasound.lock); |
511 | if (!dev->oss.recording_on) | 512 | if (!dev->dmasound.recording_on) |
512 | dsp_rec_start(dev); | 513 | dsp_rec_start(dev); |
513 | up(&dev->oss.lock); | 514 | up(&dev->dmasound.lock); |
514 | } else | 515 | } else |
515 | mask |= (POLLIN | POLLRDNORM); | 516 | mask |= (POLLIN | POLLRDNORM); |
516 | return mask; | 517 | return mask; |
@@ -534,7 +535,7 @@ mixer_recsrc_7134(struct saa7134_dev *dev) | |||
534 | { | 535 | { |
535 | int analog_io,rate; | 536 | int analog_io,rate; |
536 | 537 | ||
537 | switch (dev->oss.input) { | 538 | switch (dev->dmasound.input) { |
538 | case TV: | 539 | case TV: |
539 | saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0); | 540 | saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0); |
540 | saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00); | 541 | saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00); |
@@ -542,8 +543,8 @@ mixer_recsrc_7134(struct saa7134_dev *dev) | |||
542 | case LINE1: | 543 | case LINE1: |
543 | case LINE2: | 544 | case LINE2: |
544 | case LINE2_LEFT: | 545 | case LINE2_LEFT: |
545 | analog_io = (LINE1 == dev->oss.input) ? 0x00 : 0x08; | 546 | analog_io = (LINE1 == dev->dmasound.input) ? 0x00 : 0x08; |
546 | rate = (32000 == dev->oss.rate) ? 0x01 : 0x03; | 547 | rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03; |
547 | saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io); | 548 | saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io); |
548 | saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80); | 549 | saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80); |
549 | saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate); | 550 | saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate); |
@@ -559,10 +560,10 @@ mixer_recsrc_7133(struct saa7134_dev *dev) | |||
559 | 560 | ||
560 | xbarin = 0x03; // adc | 561 | xbarin = 0x03; // adc |
561 | anabar = 0; | 562 | anabar = 0; |
562 | switch (dev->oss.input) { | 563 | switch (dev->dmasound.input) { |
563 | case TV: | 564 | case TV: |
564 | xbarin = 0; // Demodulator | 565 | xbarin = 0; // Demodulator |
565 | anabar = 2; // DACs | 566 | anabar = 2; // DACs |
566 | break; | 567 | break; |
567 | case LINE1: | 568 | case LINE1: |
568 | anabar = 0; // aux1, aux1 | 569 | anabar = 0; // aux1, aux1 |
@@ -585,9 +586,9 @@ mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src) | |||
585 | { | 586 | { |
586 | static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" }; | 587 | static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" }; |
587 | 588 | ||
588 | dev->oss.count++; | 589 | dev->dmasound.count++; |
589 | dev->oss.input = src; | 590 | dev->dmasound.input = src; |
590 | dprintk("mixer input = %s\n",iname[dev->oss.input]); | 591 | dprintk("mixer input = %s\n",iname[dev->dmasound.input]); |
591 | 592 | ||
592 | switch (dev->pci->device) { | 593 | switch (dev->pci->device) { |
593 | case PCI_DEVICE_ID_PHILIPS_SAA7134: | 594 | case PCI_DEVICE_ID_PHILIPS_SAA7134: |
@@ -639,7 +640,7 @@ static int mixer_open(struct inode *inode, struct file *file) | |||
639 | 640 | ||
640 | list_for_each(list,&saa7134_devlist) { | 641 | list_for_each(list,&saa7134_devlist) { |
641 | h = list_entry(list, struct saa7134_dev, devlist); | 642 | h = list_entry(list, struct saa7134_dev, devlist); |
642 | if (h->oss.minor_mixer == minor) | 643 | if (h->dmasound.minor_mixer == minor) |
643 | dev = h; | 644 | dev = h; |
644 | } | 645 | } |
645 | if (NULL == dev) | 646 | if (NULL == dev) |
@@ -666,28 +667,28 @@ static int mixer_ioctl(struct inode *inode, struct file *file, | |||
666 | 667 | ||
667 | if (oss_debug > 1) | 668 | if (oss_debug > 1) |
668 | saa7134_print_ioctl(dev->name,cmd); | 669 | saa7134_print_ioctl(dev->name,cmd); |
669 | switch (cmd) { | 670 | switch (cmd) { |
670 | case OSS_GETVERSION: | 671 | case OSS_GETVERSION: |
671 | return put_user(SOUND_VERSION, p); | 672 | return put_user(SOUND_VERSION, p); |
672 | case SOUND_MIXER_INFO: | 673 | case SOUND_MIXER_INFO: |
673 | { | 674 | { |
674 | mixer_info info; | 675 | mixer_info info; |
675 | memset(&info,0,sizeof(info)); | 676 | memset(&info,0,sizeof(info)); |
676 | strlcpy(info.id, "TV audio", sizeof(info.id)); | 677 | strlcpy(info.id, "TV audio", sizeof(info.id)); |
677 | strlcpy(info.name, dev->name, sizeof(info.name)); | 678 | strlcpy(info.name, dev->name, sizeof(info.name)); |
678 | info.modify_counter = dev->oss.count; | 679 | info.modify_counter = dev->dmasound.count; |
679 | if (copy_to_user(argp, &info, sizeof(info))) | 680 | if (copy_to_user(argp, &info, sizeof(info))) |
680 | return -EFAULT; | 681 | return -EFAULT; |
681 | return 0; | 682 | return 0; |
682 | } | 683 | } |
683 | case SOUND_OLD_MIXER_INFO: | 684 | case SOUND_OLD_MIXER_INFO: |
684 | { | 685 | { |
685 | _old_mixer_info info; | 686 | _old_mixer_info info; |
686 | memset(&info,0,sizeof(info)); | 687 | memset(&info,0,sizeof(info)); |
687 | strlcpy(info.id, "TV audio", sizeof(info.id)); | 688 | strlcpy(info.id, "TV audio", sizeof(info.id)); |
688 | strlcpy(info.name, dev->name, sizeof(info.name)); | 689 | strlcpy(info.name, dev->name, sizeof(info.name)); |
689 | if (copy_to_user(argp, &info, sizeof(info))) | 690 | if (copy_to_user(argp, &info, sizeof(info))) |
690 | return -EFAULT; | 691 | return -EFAULT; |
691 | return 0; | 692 | return 0; |
692 | } | 693 | } |
693 | case MIXER_READ(SOUND_MIXER_CAPS): | 694 | case MIXER_READ(SOUND_MIXER_CAPS): |
@@ -697,26 +698,26 @@ static int mixer_ioctl(struct inode *inode, struct file *file, | |||
697 | case MIXER_READ(SOUND_MIXER_RECMASK): | 698 | case MIXER_READ(SOUND_MIXER_RECMASK): |
698 | case MIXER_READ(SOUND_MIXER_DEVMASK): | 699 | case MIXER_READ(SOUND_MIXER_DEVMASK): |
699 | val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2; | 700 | val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2; |
700 | if (32000 == dev->oss.rate) | 701 | if (32000 == dev->dmasound.rate) |
701 | val |= SOUND_MASK_VIDEO; | 702 | val |= SOUND_MASK_VIDEO; |
702 | return put_user(val, p); | 703 | return put_user(val, p); |
703 | 704 | ||
704 | case MIXER_WRITE(SOUND_MIXER_RECSRC): | 705 | case MIXER_WRITE(SOUND_MIXER_RECSRC): |
705 | if (get_user(val, p)) | 706 | if (get_user(val, p)) |
706 | return -EFAULT; | 707 | return -EFAULT; |
707 | input = dev->oss.input; | 708 | input = dev->dmasound.input; |
708 | if (32000 == dev->oss.rate && | 709 | if (32000 == dev->dmasound.rate && |
709 | val & SOUND_MASK_VIDEO && dev->oss.input != TV) | 710 | val & SOUND_MASK_VIDEO && dev->dmasound.input != TV) |
710 | input = TV; | 711 | input = TV; |
711 | if (val & SOUND_MASK_LINE1 && dev->oss.input != LINE1) | 712 | if (val & SOUND_MASK_LINE1 && dev->dmasound.input != LINE1) |
712 | input = LINE1; | 713 | input = LINE1; |
713 | if (val & SOUND_MASK_LINE2 && dev->oss.input != LINE2) | 714 | if (val & SOUND_MASK_LINE2 && dev->dmasound.input != LINE2) |
714 | input = LINE2; | 715 | input = LINE2; |
715 | if (input != dev->oss.input) | 716 | if (input != dev->dmasound.input) |
716 | mixer_recsrc(dev,input); | 717 | mixer_recsrc(dev,input); |
717 | /* fall throuth */ | 718 | /* fall throuth */ |
718 | case MIXER_READ(SOUND_MIXER_RECSRC): | 719 | case MIXER_READ(SOUND_MIXER_RECSRC): |
719 | switch (dev->oss.input) { | 720 | switch (dev->dmasound.input) { |
720 | case TV: ret = SOUND_MASK_VIDEO; break; | 721 | case TV: ret = SOUND_MASK_VIDEO; break; |
721 | case LINE1: ret = SOUND_MASK_LINE1; break; | 722 | case LINE1: ret = SOUND_MASK_LINE1; break; |
722 | case LINE2: ret = SOUND_MASK_LINE2; break; | 723 | case LINE2: ret = SOUND_MASK_LINE2; break; |
@@ -726,7 +727,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file, | |||
726 | 727 | ||
727 | case MIXER_WRITE(SOUND_MIXER_VIDEO): | 728 | case MIXER_WRITE(SOUND_MIXER_VIDEO): |
728 | case MIXER_READ(SOUND_MIXER_VIDEO): | 729 | case MIXER_READ(SOUND_MIXER_VIDEO): |
729 | if (32000 != dev->oss.rate) | 730 | if (32000 != dev->dmasound.rate) |
730 | return -EINVAL; | 731 | return -EINVAL; |
731 | return put_user(100 | 100 << 8, p); | 732 | return put_user(100 | 100 << 8, p); |
732 | 733 | ||
@@ -735,22 +736,22 @@ static int mixer_ioctl(struct inode *inode, struct file *file, | |||
735 | return -EFAULT; | 736 | return -EFAULT; |
736 | val &= 0xff; | 737 | val &= 0xff; |
737 | val = (val <= 50) ? 50 : 100; | 738 | val = (val <= 50) ? 50 : 100; |
738 | dev->oss.line1 = val; | 739 | dev->dmasound.line1 = val; |
739 | mixer_level(dev,LINE1,dev->oss.line1); | 740 | mixer_level(dev,LINE1,dev->dmasound.line1); |
740 | /* fall throuth */ | 741 | /* fall throuth */ |
741 | case MIXER_READ(SOUND_MIXER_LINE1): | 742 | case MIXER_READ(SOUND_MIXER_LINE1): |
742 | return put_user(dev->oss.line1 | dev->oss.line1 << 8, p); | 743 | return put_user(dev->dmasound.line1 | dev->dmasound.line1 << 8, p); |
743 | 744 | ||
744 | case MIXER_WRITE(SOUND_MIXER_LINE2): | 745 | case MIXER_WRITE(SOUND_MIXER_LINE2): |
745 | if (get_user(val, p)) | 746 | if (get_user(val, p)) |
746 | return -EFAULT; | 747 | return -EFAULT; |
747 | val &= 0xff; | 748 | val &= 0xff; |
748 | val = (val <= 50) ? 50 : 100; | 749 | val = (val <= 50) ? 50 : 100; |
749 | dev->oss.line2 = val; | 750 | dev->dmasound.line2 = val; |
750 | mixer_level(dev,LINE2,dev->oss.line2); | 751 | mixer_level(dev,LINE2,dev->dmasound.line2); |
751 | /* fall throuth */ | 752 | /* fall throuth */ |
752 | case MIXER_READ(SOUND_MIXER_LINE2): | 753 | case MIXER_READ(SOUND_MIXER_LINE2): |
753 | return put_user(dev->oss.line2 | dev->oss.line2 << 8, p); | 754 | return put_user(dev->dmasound.line2 | dev->dmasound.line2 << 8, p); |
754 | 755 | ||
755 | default: | 756 | default: |
756 | return -EINVAL; | 757 | return -EINVAL; |
@@ -770,8 +771,8 @@ struct file_operations saa7134_mixer_fops = { | |||
770 | int saa7134_oss_init1(struct saa7134_dev *dev) | 771 | int saa7134_oss_init1(struct saa7134_dev *dev) |
771 | { | 772 | { |
772 | /* general */ | 773 | /* general */ |
773 | init_MUTEX(&dev->oss.lock); | 774 | init_MUTEX(&dev->dmasound.lock); |
774 | init_waitqueue_head(&dev->oss.wq); | 775 | init_waitqueue_head(&dev->dmasound.wq); |
775 | 776 | ||
776 | switch (dev->pci->device) { | 777 | switch (dev->pci->device) { |
777 | case PCI_DEVICE_ID_PHILIPS_SAA7133: | 778 | case PCI_DEVICE_ID_PHILIPS_SAA7133: |
@@ -783,17 +784,17 @@ int saa7134_oss_init1(struct saa7134_dev *dev) | |||
783 | } | 784 | } |
784 | 785 | ||
785 | /* dsp */ | 786 | /* dsp */ |
786 | dev->oss.rate = 32000; | 787 | dev->dmasound.rate = 32000; |
787 | if (oss_rate) | 788 | if (oss_rate) |
788 | dev->oss.rate = oss_rate; | 789 | dev->dmasound.rate = oss_rate; |
789 | dev->oss.rate = (dev->oss.rate > 40000) ? 48000 : 32000; | 790 | dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000; |
790 | 791 | ||
791 | /* mixer */ | 792 | /* mixer */ |
792 | dev->oss.line1 = 50; | 793 | dev->dmasound.line1 = 50; |
793 | dev->oss.line2 = 50; | 794 | dev->dmasound.line2 = 50; |
794 | mixer_level(dev,LINE1,dev->oss.line1); | 795 | mixer_level(dev,LINE1,dev->dmasound.line1); |
795 | mixer_level(dev,LINE2,dev->oss.line2); | 796 | mixer_level(dev,LINE2,dev->dmasound.line2); |
796 | mixer_recsrc(dev, (dev->oss.rate == 32000) ? TV : LINE2); | 797 | mixer_recsrc(dev, (dev->dmasound.rate == 32000) ? TV : LINE2); |
797 | 798 | ||
798 | return 0; | 799 | return 0; |
799 | } | 800 | } |
@@ -809,7 +810,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status) | |||
809 | int next_blk, reg = 0; | 810 | int next_blk, reg = 0; |
810 | 811 | ||
811 | spin_lock(&dev->slock); | 812 | spin_lock(&dev->slock); |
812 | if (UNSET == dev->oss.dma_blk) { | 813 | if (UNSET == dev->dmasound.dma_blk) { |
813 | dprintk("irq: recording stopped\n"); | 814 | dprintk("irq: recording stopped\n"); |
814 | goto done; | 815 | goto done; |
815 | } | 816 | } |
@@ -817,11 +818,11 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status) | |||
817 | dprintk("irq: lost %ld\n", (status >> 24) & 0x0f); | 818 | dprintk("irq: lost %ld\n", (status >> 24) & 0x0f); |
818 | if (0 == (status & 0x10000000)) { | 819 | if (0 == (status & 0x10000000)) { |
819 | /* odd */ | 820 | /* odd */ |
820 | if (0 == (dev->oss.dma_blk & 0x01)) | 821 | if (0 == (dev->dmasound.dma_blk & 0x01)) |
821 | reg = SAA7134_RS_BA1(6); | 822 | reg = SAA7134_RS_BA1(6); |
822 | } else { | 823 | } else { |
823 | /* even */ | 824 | /* even */ |
824 | if (1 == (dev->oss.dma_blk & 0x01)) | 825 | if (1 == (dev->dmasound.dma_blk & 0x01)) |
825 | reg = SAA7134_RS_BA2(6); | 826 | reg = SAA7134_RS_BA2(6); |
826 | } | 827 | } |
827 | if (0 == reg) { | 828 | if (0 == reg) { |
@@ -829,25 +830,25 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status) | |||
829 | (status & 0x10000000) ? "even" : "odd"); | 830 | (status & 0x10000000) ? "even" : "odd"); |
830 | goto done; | 831 | goto done; |
831 | } | 832 | } |
832 | if (dev->oss.read_count >= dev->oss.blksize * (dev->oss.blocks-2)) { | 833 | if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) { |
833 | dprintk("irq: overrun [full=%d/%d]\n",dev->oss.read_count, | 834 | dprintk("irq: overrun [full=%d/%d]\n",dev->dmasound.read_count, |
834 | dev->oss.bufsize); | 835 | dev->dmasound.bufsize); |
835 | dsp_dma_stop(dev); | 836 | dsp_dma_stop(dev); |
836 | goto done; | 837 | goto done; |
837 | } | 838 | } |
838 | 839 | ||
839 | /* next block addr */ | 840 | /* next block addr */ |
840 | next_blk = (dev->oss.dma_blk + 2) % dev->oss.blocks; | 841 | next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks; |
841 | saa_writel(reg,next_blk * dev->oss.blksize); | 842 | saa_writel(reg,next_blk * dev->dmasound.blksize); |
842 | if (oss_debug > 2) | 843 | if (oss_debug > 2) |
843 | dprintk("irq: ok, %s, next_blk=%d, addr=%x\n", | 844 | dprintk("irq: ok, %s, next_blk=%d, addr=%x\n", |
844 | (status & 0x10000000) ? "even" : "odd ", next_blk, | 845 | (status & 0x10000000) ? "even" : "odd ", next_blk, |
845 | next_blk * dev->oss.blksize); | 846 | next_blk * dev->dmasound.blksize); |
846 | 847 | ||
847 | /* update status & wake waiting readers */ | 848 | /* update status & wake waiting readers */ |
848 | dev->oss.dma_blk = (dev->oss.dma_blk + 1) % dev->oss.blocks; | 849 | dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks; |
849 | dev->oss.read_count += dev->oss.blksize; | 850 | dev->dmasound.read_count += dev->dmasound.blksize; |
850 | wake_up(&dev->oss.wq); | 851 | wake_up(&dev->dmasound.wq); |
851 | 852 | ||
852 | done: | 853 | done: |
853 | spin_unlock(&dev->slock); | 854 | spin_unlock(&dev->slock); |
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h index ae0c7a165390..ac6431ba4fc3 100644 --- a/drivers/media/video/saa7134/saa7134-reg.h +++ b/drivers/media/video/saa7134/saa7134-reg.h | |||
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | /* DMA channels, n = 0 ... 6 */ | 28 | /* DMA channels, n = 0 ... 6 */ |
29 | #define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n) | 29 | #define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n) |
30 | #define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n) | 30 | #define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n) |
31 | #define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n) | 31 | #define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n) |
32 | #define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n) | 32 | #define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n) |
33 | #define SAA7134_RS_CONTROL_WSWAP (0x01 << 25) | 33 | #define SAA7134_RS_CONTROL_WSWAP (0x01 << 25) |
@@ -43,16 +43,24 @@ | |||
43 | #define SAA7134_FIFO_SIZE (0x2a0 >> 2) | 43 | #define SAA7134_FIFO_SIZE (0x2a0 >> 2) |
44 | #define SAA7134_THRESHOULD (0x2a4 >> 2) | 44 | #define SAA7134_THRESHOULD (0x2a4 >> 2) |
45 | 45 | ||
46 | #define SAA7133_NUM_SAMPLES (0x588 >> 2) | ||
47 | #define SAA7133_AUDIO_CHANNEL (0x58c >> 2) | ||
48 | #define SAA7133_AUDIO_FORMAT (0x58f >> 2) | ||
49 | #define SAA7133_DIGITAL_OUTPUT_SEL1 (0x46c >> 2) | ||
50 | #define SAA7133_DIGITAL_OUTPUT_SEL2 (0x470 >> 2) | ||
51 | #define SAA7133_DIGITAL_INPUT_XBAR1 (0x464 >> 2) | ||
52 | #define SAA7133_ANALOG_IO_SELECT (0x594 >> 2) | ||
53 | |||
46 | /* main control */ | 54 | /* main control */ |
47 | #define SAA7134_MAIN_CTRL (0x2a8 >> 2) | 55 | #define SAA7134_MAIN_CTRL (0x2a8 >> 2) |
48 | #define SAA7134_MAIN_CTRL_VPLLE (1 << 15) | 56 | #define SAA7134_MAIN_CTRL_VPLLE (1 << 15) |
49 | #define SAA7134_MAIN_CTRL_APLLE (1 << 14) | 57 | #define SAA7134_MAIN_CTRL_APLLE (1 << 14) |
50 | #define SAA7134_MAIN_CTRL_EXOSC (1 << 13) | 58 | #define SAA7134_MAIN_CTRL_EXOSC (1 << 13) |
51 | #define SAA7134_MAIN_CTRL_EVFE1 (1 << 12) | 59 | #define SAA7134_MAIN_CTRL_EVFE1 (1 << 12) |
52 | #define SAA7134_MAIN_CTRL_EVFE2 (1 << 11) | 60 | #define SAA7134_MAIN_CTRL_EVFE2 (1 << 11) |
53 | #define SAA7134_MAIN_CTRL_ESFE (1 << 10) | 61 | #define SAA7134_MAIN_CTRL_ESFE (1 << 10) |
54 | #define SAA7134_MAIN_CTRL_EBADC (1 << 9) | 62 | #define SAA7134_MAIN_CTRL_EBADC (1 << 9) |
55 | #define SAA7134_MAIN_CTRL_EBDAC (1 << 8) | 63 | #define SAA7134_MAIN_CTRL_EBDAC (1 << 8) |
56 | #define SAA7134_MAIN_CTRL_TE6 (1 << 6) | 64 | #define SAA7134_MAIN_CTRL_TE6 (1 << 6) |
57 | #define SAA7134_MAIN_CTRL_TE5 (1 << 5) | 65 | #define SAA7134_MAIN_CTRL_TE5 (1 << 5) |
58 | #define SAA7134_MAIN_CTRL_TE4 (1 << 4) | 66 | #define SAA7134_MAIN_CTRL_TE4 (1 << 4) |
@@ -348,6 +356,7 @@ | |||
348 | 356 | ||
349 | /* test modes */ | 357 | /* test modes */ |
350 | #define SAA7134_SPECIAL_MODE 0x1d0 | 358 | #define SAA7134_SPECIAL_MODE 0x1d0 |
359 | #define SAA7134_PRODUCTION_TEST_MODE 0x1d1 | ||
351 | 360 | ||
352 | /* audio -- saa7133 + saa7135 only */ | 361 | /* audio -- saa7133 + saa7135 only */ |
353 | #define SAA7135_DSP_RWSTATE 0x580 | 362 | #define SAA7135_DSP_RWSTATE 0x580 |
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c index 463885601ab4..470903e2f5e5 100644 --- a/drivers/media/video/saa7134/saa7134-ts.c +++ b/drivers/media/video/saa7134/saa7134-ts.c | |||
@@ -46,17 +46,11 @@ static int buffer_activate(struct saa7134_dev *dev, | |||
46 | struct saa7134_buf *buf, | 46 | struct saa7134_buf *buf, |
47 | struct saa7134_buf *next) | 47 | struct saa7134_buf *next) |
48 | { | 48 | { |
49 | u32 control; | ||
50 | 49 | ||
51 | dprintk("buffer_activate [%p]",buf); | 50 | dprintk("buffer_activate [%p]",buf); |
52 | buf->vb.state = STATE_ACTIVE; | 51 | buf->vb.state = STATE_ACTIVE; |
53 | buf->top_seen = 0; | 52 | buf->top_seen = 0; |
54 | 53 | ||
55 | /* dma: setup channel 5 (= TS) */ | ||
56 | control = SAA7134_RS_CONTROL_BURST_16 | | ||
57 | SAA7134_RS_CONTROL_ME | | ||
58 | (buf->pt->dma >> 12); | ||
59 | |||
60 | if (NULL == next) | 54 | if (NULL == next) |
61 | next = buf; | 55 | next = buf; |
62 | if (V4L2_FIELD_TOP == buf->vb.field) { | 56 | if (V4L2_FIELD_TOP == buf->vb.field) { |
@@ -68,8 +62,6 @@ static int buffer_activate(struct saa7134_dev *dev, | |||
68 | saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next)); | 62 | saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next)); |
69 | saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); | 63 | saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); |
70 | } | 64 | } |
71 | saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE); | ||
72 | saa_writel(SAA7134_RS_CONTROL(5),control); | ||
73 | 65 | ||
74 | /* start DMA */ | 66 | /* start DMA */ |
75 | saa7134_set_dmabits(dev); | 67 | saa7134_set_dmabits(dev); |
@@ -84,6 +76,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
84 | struct saa7134_dev *dev = q->priv_data; | 76 | struct saa7134_dev *dev = q->priv_data; |
85 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); | 77 | struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); |
86 | unsigned int lines, llength, size; | 78 | unsigned int lines, llength, size; |
79 | u32 control; | ||
87 | int err; | 80 | int err; |
88 | 81 | ||
89 | dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); | 82 | dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); |
@@ -115,6 +108,18 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
115 | if (err) | 108 | if (err) |
116 | goto oops; | 109 | goto oops; |
117 | } | 110 | } |
111 | |||
112 | /* dma: setup channel 5 (= TS) */ | ||
113 | control = SAA7134_RS_CONTROL_BURST_16 | | ||
114 | SAA7134_RS_CONTROL_ME | | ||
115 | (buf->pt->dma >> 12); | ||
116 | |||
117 | saa_writeb(SAA7134_TS_DMA0, ((lines-1)&0xff)); | ||
118 | saa_writeb(SAA7134_TS_DMA1, (((lines-1)>>8)&0xff)); | ||
119 | saa_writeb(SAA7134_TS_DMA2, ((((lines-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */ | ||
120 | saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE); | ||
121 | saa_writel(SAA7134_RS_CONTROL(5),control); | ||
122 | |||
118 | buf->vb.state = STATE_PREPARED; | 123 | buf->vb.state = STATE_PREPARED; |
119 | buf->activate = buffer_activate; | 124 | buf->activate = buffer_activate; |
120 | buf->vb.field = field; | 125 | buf->vb.field = field; |
@@ -164,11 +169,11 @@ EXPORT_SYMBOL_GPL(saa7134_ts_qops); | |||
164 | /* ----------------------------------------------------------- */ | 169 | /* ----------------------------------------------------------- */ |
165 | /* exported stuff */ | 170 | /* exported stuff */ |
166 | 171 | ||
167 | static unsigned int tsbufs = 4; | 172 | static unsigned int tsbufs = 8; |
168 | module_param(tsbufs, int, 0444); | 173 | module_param(tsbufs, int, 0444); |
169 | MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); | 174 | MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); |
170 | 175 | ||
171 | static unsigned int ts_nr_packets = 30; | 176 | static unsigned int ts_nr_packets = 64; |
172 | module_param(ts_nr_packets, int, 0444); | 177 | module_param(ts_nr_packets, int, 0444); |
173 | MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)"); | 178 | MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)"); |
174 | 179 | ||
@@ -220,10 +225,10 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) | |||
220 | if (dev->ts_q.curr) { | 225 | if (dev->ts_q.curr) { |
221 | field = dev->ts_q.curr->vb.field; | 226 | field = dev->ts_q.curr->vb.field; |
222 | if (field == V4L2_FIELD_TOP) { | 227 | if (field == V4L2_FIELD_TOP) { |
223 | if ((status & 0x100000) != 0x100000) | 228 | if ((status & 0x100000) != 0x000000) |
224 | goto done; | 229 | goto done; |
225 | } else { | 230 | } else { |
226 | if ((status & 0x100000) != 0x000000) | 231 | if ((status & 0x100000) != 0x100000) |
227 | goto done; | 232 | goto done; |
228 | } | 233 | } |
229 | saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE); | 234 | saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE); |
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index 61a2d6b50eef..93268427750d 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c | |||
@@ -207,6 +207,10 @@ static void tvaudio_setcarrier(struct saa7134_dev *dev, | |||
207 | saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary)); | 207 | saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary)); |
208 | } | 208 | } |
209 | 209 | ||
210 | #define SAA7134_MUTE_MASK 0xbb | ||
211 | #define SAA7134_MUTE_ANALOG 0x04 | ||
212 | #define SAA7134_MUTE_I2S 0x40 | ||
213 | |||
210 | static void mute_input_7134(struct saa7134_dev *dev) | 214 | static void mute_input_7134(struct saa7134_dev *dev) |
211 | { | 215 | { |
212 | unsigned int mute; | 216 | unsigned int mute; |
@@ -241,7 +245,11 @@ static void mute_input_7134(struct saa7134_dev *dev) | |||
241 | 245 | ||
242 | if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device) | 246 | if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device) |
243 | /* 7134 mute */ | 247 | /* 7134 mute */ |
244 | saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xbf : 0xbb); | 248 | saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? |
249 | SAA7134_MUTE_MASK | | ||
250 | SAA7134_MUTE_ANALOG | | ||
251 | SAA7134_MUTE_I2S : | ||
252 | SAA7134_MUTE_MASK); | ||
245 | 253 | ||
246 | /* switch internal audio mux */ | 254 | /* switch internal audio mux */ |
247 | switch (in->amux) { | 255 | switch (in->amux) { |
@@ -753,17 +761,17 @@ static int mute_input_7133(struct saa7134_dev *dev) | |||
753 | 761 | ||
754 | 762 | ||
755 | /* switch gpio-connected external audio mux */ | 763 | /* switch gpio-connected external audio mux */ |
756 | if (0 != card(dev).gpiomask) { | 764 | if (0 != card(dev).gpiomask) { |
757 | mask = card(dev).gpiomask; | 765 | mask = card(dev).gpiomask; |
758 | 766 | ||
759 | if (card(dev).mute.name && dev->ctl_mute) | 767 | if (card(dev).mute.name && dev->ctl_mute) |
760 | in = &card(dev).mute; | 768 | in = &card(dev).mute; |
761 | else | 769 | else |
762 | in = dev->input; | 770 | in = dev->input; |
763 | 771 | ||
764 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask); | 772 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask); |
765 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio); | 773 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio); |
766 | saa7134_track_gpio(dev,in->name); | 774 | saa7134_track_gpio(dev,in->name); |
767 | } | 775 | } |
768 | 776 | ||
769 | return 0; | 777 | return 0; |
@@ -1016,9 +1024,12 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev) | |||
1016 | return 0; | 1024 | return 0; |
1017 | } | 1025 | } |
1018 | 1026 | ||
1027 | EXPORT_SYMBOL(saa_dsp_writel); | ||
1028 | |||
1019 | /* ----------------------------------------------------------- */ | 1029 | /* ----------------------------------------------------------- */ |
1020 | /* | 1030 | /* |
1021 | * Local variables: | 1031 | * Local variables: |
1022 | * c-basic-offset: 8 | 1032 | * c-basic-offset: 8 |
1023 | * End: | 1033 | * End: |
1024 | */ | 1034 | */ |
1035 | |||
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 35e5e85f669a..45c852df13ed 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c | |||
@@ -30,6 +30,9 @@ | |||
30 | #include "saa7134-reg.h" | 30 | #include "saa7134-reg.h" |
31 | #include "saa7134.h" | 31 | #include "saa7134.h" |
32 | 32 | ||
33 | /* Include V4L1 specific functions. Should be removed soon */ | ||
34 | #include <linux/videodev.h> | ||
35 | |||
33 | /* ------------------------------------------------------------------ */ | 36 | /* ------------------------------------------------------------------ */ |
34 | 37 | ||
35 | static unsigned int video_debug = 0; | 38 | static unsigned int video_debug = 0; |
@@ -48,6 +51,43 @@ MODULE_PARM_DESC(noninterlaced,"video input is noninterlaced"); | |||
48 | printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg) | 51 | printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg) |
49 | 52 | ||
50 | /* ------------------------------------------------------------------ */ | 53 | /* ------------------------------------------------------------------ */ |
54 | /* Defines for Video Output Port Register at address 0x191 */ | ||
55 | |||
56 | /* Bit 0: VIP code T bit polarity */ | ||
57 | |||
58 | #define VP_T_CODE_P_NON_INVERTED 0x00 | ||
59 | #define VP_T_CODE_P_INVERTED 0x01 | ||
60 | |||
61 | /* ------------------------------------------------------------------ */ | ||
62 | /* Defines for Video Output Port Register at address 0x195 */ | ||
63 | |||
64 | /* Bit 2: Video output clock delay control */ | ||
65 | |||
66 | #define VP_CLK_CTRL2_NOT_DELAYED 0x00 | ||
67 | #define VP_CLK_CTRL2_DELAYED 0x04 | ||
68 | |||
69 | /* Bit 1: Video output clock invert control */ | ||
70 | |||
71 | #define VP_CLK_CTRL1_NON_INVERTED 0x00 | ||
72 | #define VP_CLK_CTRL1_INVERTED 0x02 | ||
73 | |||
74 | /* ------------------------------------------------------------------ */ | ||
75 | /* Defines for Video Output Port Register at address 0x196 */ | ||
76 | |||
77 | /* Bits 2 to 0: VSYNC pin video vertical sync type */ | ||
78 | |||
79 | #define VP_VS_TYPE_MASK 0x07 | ||
80 | |||
81 | #define VP_VS_TYPE_OFF 0x00 | ||
82 | #define VP_VS_TYPE_V123 0x01 | ||
83 | #define VP_VS_TYPE_V_ITU 0x02 | ||
84 | #define VP_VS_TYPE_VGATE_L 0x03 | ||
85 | #define VP_VS_TYPE_RESERVED1 0x04 | ||
86 | #define VP_VS_TYPE_RESERVED2 0x05 | ||
87 | #define VP_VS_TYPE_F_ITU 0x06 | ||
88 | #define VP_VS_TYPE_SC_FID 0x07 | ||
89 | |||
90 | /* ------------------------------------------------------------------ */ | ||
51 | /* data structs for video */ | 91 | /* data structs for video */ |
52 | 92 | ||
53 | static int video_out[][9] = { | 93 | static int video_out[][9] = { |
@@ -273,12 +313,12 @@ static struct saa7134_tvnorm tvnorms[] = { | |||
273 | 313 | ||
274 | .h_start = 0, | 314 | .h_start = 0, |
275 | .h_stop = 719, | 315 | .h_stop = 719, |
276 | .video_v_start = 23, | 316 | .video_v_start = 23, |
277 | .video_v_stop = 262, | 317 | .video_v_stop = 262, |
278 | .vbi_v_start_0 = 10, | 318 | .vbi_v_start_0 = 10, |
279 | .vbi_v_stop_0 = 21, | 319 | .vbi_v_stop_0 = 21, |
280 | .vbi_v_start_1 = 273, | 320 | .vbi_v_start_1 = 273, |
281 | .src_timing = 7, | 321 | .src_timing = 7, |
282 | 322 | ||
283 | .sync_control = 0x18, | 323 | .sync_control = 0x18, |
284 | .luma_control = 0x40, | 324 | .luma_control = 0x40, |
@@ -622,7 +662,7 @@ static void set_size(struct saa7134_dev *dev, int task, | |||
622 | prescale = 1; | 662 | prescale = 1; |
623 | xscale = 1024 * dev->crop_current.width / prescale / width; | 663 | xscale = 1024 * dev->crop_current.width / prescale / width; |
624 | yscale = 512 * div * dev->crop_current.height / height; | 664 | yscale = 512 * div * dev->crop_current.height / height; |
625 | dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale); | 665 | dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale); |
626 | set_h_prescale(dev,task,prescale); | 666 | set_h_prescale(dev,task,prescale); |
627 | saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff); | 667 | saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff); |
628 | saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8); | 668 | saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8); |
@@ -752,20 +792,20 @@ static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win) | |||
752 | maxh = dev->crop_current.height; | 792 | maxh = dev->crop_current.height; |
753 | 793 | ||
754 | if (V4L2_FIELD_ANY == field) { | 794 | if (V4L2_FIELD_ANY == field) { |
755 | field = (win->w.height > maxh/2) | 795 | field = (win->w.height > maxh/2) |
756 | ? V4L2_FIELD_INTERLACED | 796 | ? V4L2_FIELD_INTERLACED |
757 | : V4L2_FIELD_TOP; | 797 | : V4L2_FIELD_TOP; |
758 | } | 798 | } |
759 | switch (field) { | 799 | switch (field) { |
760 | case V4L2_FIELD_TOP: | 800 | case V4L2_FIELD_TOP: |
761 | case V4L2_FIELD_BOTTOM: | 801 | case V4L2_FIELD_BOTTOM: |
762 | maxh = maxh / 2; | 802 | maxh = maxh / 2; |
763 | break; | 803 | break; |
764 | case V4L2_FIELD_INTERLACED: | 804 | case V4L2_FIELD_INTERLACED: |
765 | break; | 805 | break; |
766 | default: | 806 | default: |
767 | return -EINVAL; | 807 | return -EINVAL; |
768 | } | 808 | } |
769 | 809 | ||
770 | win->field = field; | 810 | win->field = field; |
771 | if (win->w.width > maxw) | 811 | if (win->w.width > maxw) |
@@ -1306,13 +1346,13 @@ video_poll(struct file *file, struct poll_table_struct *wait) | |||
1306 | if (res_locked(fh->dev,RESOURCE_VIDEO)) { | 1346 | if (res_locked(fh->dev,RESOURCE_VIDEO)) { |
1307 | up(&fh->cap.lock); | 1347 | up(&fh->cap.lock); |
1308 | return POLLERR; | 1348 | return POLLERR; |
1309 | } | 1349 | } |
1310 | if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { | 1350 | if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { |
1311 | up(&fh->cap.lock); | 1351 | up(&fh->cap.lock); |
1312 | return POLLERR; | 1352 | return POLLERR; |
1313 | } | 1353 | } |
1314 | fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); | 1354 | fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); |
1315 | fh->cap.read_off = 0; | 1355 | fh->cap.read_off = 0; |
1316 | } | 1356 | } |
1317 | up(&fh->cap.lock); | 1357 | up(&fh->cap.lock); |
1318 | buf = fh->cap.read_buf; | 1358 | buf = fh->cap.read_buf; |
@@ -1666,9 +1706,10 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1666 | case VIDIOC_QUERYCAP: | 1706 | case VIDIOC_QUERYCAP: |
1667 | { | 1707 | { |
1668 | struct v4l2_capability *cap = arg; | 1708 | struct v4l2_capability *cap = arg; |
1709 | unsigned int tuner_type = dev->tuner_type; | ||
1669 | 1710 | ||
1670 | memset(cap,0,sizeof(*cap)); | 1711 | memset(cap,0,sizeof(*cap)); |
1671 | strcpy(cap->driver, "saa7134"); | 1712 | strcpy(cap->driver, "saa7134"); |
1672 | strlcpy(cap->card, saa7134_boards[dev->board].name, | 1713 | strlcpy(cap->card, saa7134_boards[dev->board].name, |
1673 | sizeof(cap->card)); | 1714 | sizeof(cap->card)); |
1674 | sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); | 1715 | sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); |
@@ -1677,9 +1718,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1677 | V4L2_CAP_VIDEO_CAPTURE | | 1718 | V4L2_CAP_VIDEO_CAPTURE | |
1678 | V4L2_CAP_VIDEO_OVERLAY | | 1719 | V4L2_CAP_VIDEO_OVERLAY | |
1679 | V4L2_CAP_VBI_CAPTURE | | 1720 | V4L2_CAP_VBI_CAPTURE | |
1680 | V4L2_CAP_TUNER | | ||
1681 | V4L2_CAP_READWRITE | | 1721 | V4L2_CAP_READWRITE | |
1682 | V4L2_CAP_STREAMING; | 1722 | V4L2_CAP_STREAMING | |
1723 | V4L2_CAP_TUNER; | ||
1724 | |||
1725 | if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) | ||
1726 | cap->capabilities &= ~V4L2_CAP_TUNER; | ||
1727 | |||
1683 | return 0; | 1728 | return 0; |
1684 | } | 1729 | } |
1685 | 1730 | ||
@@ -1793,9 +1838,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1793 | crop->c.height = b->top - crop->c.top + b->height; | 1838 | crop->c.height = b->top - crop->c.top + b->height; |
1794 | 1839 | ||
1795 | if (crop->c.left < b->left) | 1840 | if (crop->c.left < b->left) |
1796 | crop->c.top = b->left; | 1841 | crop->c.left = b->left; |
1797 | if (crop->c.left > b->left + b->width) | 1842 | if (crop->c.left > b->left + b->width) |
1798 | crop->c.top = b->left + b->width; | 1843 | crop->c.left = b->left + b->width; |
1799 | if (crop->c.width > b->left - crop->c.left + b->width) | 1844 | if (crop->c.width > b->left - crop->c.left + b->width) |
1800 | crop->c.width = b->left - crop->c.left + b->width; | 1845 | crop->c.width = b->left - crop->c.left + b->width; |
1801 | 1846 | ||
@@ -1817,6 +1862,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1817 | break; | 1862 | break; |
1818 | if (NULL != card_in(dev,n).name) { | 1863 | if (NULL != card_in(dev,n).name) { |
1819 | strcpy(t->name, "Television"); | 1864 | strcpy(t->name, "Television"); |
1865 | t->type = V4L2_TUNER_ANALOG_TV; | ||
1820 | t->capability = V4L2_TUNER_CAP_NORM | | 1866 | t->capability = V4L2_TUNER_CAP_NORM | |
1821 | V4L2_TUNER_CAP_STEREO | | 1867 | V4L2_TUNER_CAP_STEREO | |
1822 | V4L2_TUNER_CAP_LANG1 | | 1868 | V4L2_TUNER_CAP_LANG1 | |
@@ -1892,26 +1938,26 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1892 | } | 1938 | } |
1893 | case VIDIOC_S_AUDIO: | 1939 | case VIDIOC_S_AUDIO: |
1894 | return 0; | 1940 | return 0; |
1895 | case VIDIOC_G_PARM: | 1941 | case VIDIOC_G_PARM: |
1896 | { | 1942 | { |
1897 | struct v4l2_captureparm *parm = arg; | 1943 | struct v4l2_captureparm *parm = arg; |
1898 | memset(parm,0,sizeof(*parm)); | 1944 | memset(parm,0,sizeof(*parm)); |
1899 | return 0; | 1945 | return 0; |
1900 | } | 1946 | } |
1901 | 1947 | ||
1902 | case VIDIOC_G_PRIORITY: | 1948 | case VIDIOC_G_PRIORITY: |
1903 | { | 1949 | { |
1904 | enum v4l2_priority *p = arg; | 1950 | enum v4l2_priority *p = arg; |
1905 | 1951 | ||
1906 | *p = v4l2_prio_max(&dev->prio); | 1952 | *p = v4l2_prio_max(&dev->prio); |
1907 | return 0; | 1953 | return 0; |
1908 | } | 1954 | } |
1909 | case VIDIOC_S_PRIORITY: | 1955 | case VIDIOC_S_PRIORITY: |
1910 | { | 1956 | { |
1911 | enum v4l2_priority *prio = arg; | 1957 | enum v4l2_priority *prio = arg; |
1912 | 1958 | ||
1913 | return v4l2_prio_change(&dev->prio, &fh->prio, *prio); | 1959 | return v4l2_prio_change(&dev->prio, &fh->prio, *prio); |
1914 | } | 1960 | } |
1915 | 1961 | ||
1916 | /* --- preview ioctls ---------------------------------------- */ | 1962 | /* --- preview ioctls ---------------------------------------- */ |
1917 | case VIDIOC_ENUM_FMT: | 1963 | case VIDIOC_ENUM_FMT: |
@@ -2018,7 +2064,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
2018 | struct v4l2_format *f = arg; | 2064 | struct v4l2_format *f = arg; |
2019 | return saa7134_try_fmt(dev,fh,f); | 2065 | return saa7134_try_fmt(dev,fh,f); |
2020 | } | 2066 | } |
2021 | 2067 | #ifdef HAVE_V4L1 | |
2022 | case VIDIOCGMBUF: | 2068 | case VIDIOCGMBUF: |
2023 | { | 2069 | { |
2024 | struct video_mbuf *mbuf = arg; | 2070 | struct video_mbuf *mbuf = arg; |
@@ -2043,6 +2089,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
2043 | } | 2089 | } |
2044 | return 0; | 2090 | return 0; |
2045 | } | 2091 | } |
2092 | #endif | ||
2046 | case VIDIOC_REQBUFS: | 2093 | case VIDIOC_REQBUFS: |
2047 | return videobuf_reqbufs(saa7134_queue(fh),arg); | 2094 | return videobuf_reqbufs(saa7134_queue(fh),arg); |
2048 | 2095 | ||
@@ -2060,7 +2107,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
2060 | { | 2107 | { |
2061 | int res = saa7134_resource(fh); | 2108 | int res = saa7134_resource(fh); |
2062 | 2109 | ||
2063 | if (!res_get(dev,fh,res)) | 2110 | if (!res_get(dev,fh,res)) |
2064 | return -EBUSY; | 2111 | return -EBUSY; |
2065 | return videobuf_streamon(saa7134_queue(fh)); | 2112 | return videobuf_streamon(saa7134_queue(fh)); |
2066 | } | 2113 | } |
@@ -2102,7 +2149,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
2102 | struct v4l2_capability *cap = arg; | 2149 | struct v4l2_capability *cap = arg; |
2103 | 2150 | ||
2104 | memset(cap,0,sizeof(*cap)); | 2151 | memset(cap,0,sizeof(*cap)); |
2105 | strcpy(cap->driver, "saa7134"); | 2152 | strcpy(cap->driver, "saa7134"); |
2106 | strlcpy(cap->card, saa7134_boards[dev->board].name, | 2153 | strlcpy(cap->card, saa7134_boards[dev->board].name, |
2107 | sizeof(cap->card)); | 2154 | sizeof(cap->card)); |
2108 | sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); | 2155 | sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); |
@@ -2119,6 +2166,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
2119 | 2166 | ||
2120 | memset(t,0,sizeof(*t)); | 2167 | memset(t,0,sizeof(*t)); |
2121 | strcpy(t->name, "Radio"); | 2168 | strcpy(t->name, "Radio"); |
2169 | t->type = V4L2_TUNER_RADIO; | ||
2122 | 2170 | ||
2123 | saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); | 2171 | saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); |
2124 | 2172 | ||
@@ -2233,7 +2281,7 @@ struct video_device saa7134_video_template = | |||
2233 | { | 2281 | { |
2234 | .name = "saa7134-video", | 2282 | .name = "saa7134-video", |
2235 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| | 2283 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| |
2236 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, | 2284 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, |
2237 | .hardware = 0, | 2285 | .hardware = 0, |
2238 | .fops = &video_fops, | 2286 | .fops = &video_fops, |
2239 | .minor = -1, | 2287 | .minor = -1, |
@@ -2280,7 +2328,7 @@ int saa7134_video_init1(struct saa7134_dev *dev) | |||
2280 | dev->tda9887_conf |= TDA9887_AUTOMUTE; | 2328 | dev->tda9887_conf |= TDA9887_AUTOMUTE; |
2281 | dev->automute = 0; | 2329 | dev->automute = 0; |
2282 | 2330 | ||
2283 | INIT_LIST_HEAD(&dev->video_q.queue); | 2331 | INIT_LIST_HEAD(&dev->video_q.queue); |
2284 | init_timer(&dev->video_q.timeout); | 2332 | init_timer(&dev->video_q.timeout); |
2285 | dev->video_q.timeout.function = saa7134_buffer_timeout; | 2333 | dev->video_q.timeout.function = saa7134_buffer_timeout; |
2286 | dev->video_q.timeout.data = (unsigned long)(&dev->video_q); | 2334 | dev->video_q.timeout.data = (unsigned long)(&dev->video_q); |
@@ -2289,13 +2337,28 @@ int saa7134_video_init1(struct saa7134_dev *dev) | |||
2289 | if (saa7134_boards[dev->board].video_out) { | 2337 | if (saa7134_boards[dev->board].video_out) { |
2290 | /* enable video output */ | 2338 | /* enable video output */ |
2291 | int vo = saa7134_boards[dev->board].video_out; | 2339 | int vo = saa7134_boards[dev->board].video_out; |
2340 | int video_reg; | ||
2341 | unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts; | ||
2292 | saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]); | 2342 | saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]); |
2293 | saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_out[vo][1]); | 2343 | video_reg = video_out[vo][1]; |
2344 | if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED) | ||
2345 | video_reg &= ~VP_T_CODE_P_INVERTED; | ||
2346 | saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg); | ||
2294 | saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]); | 2347 | saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]); |
2295 | saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]); | 2348 | saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]); |
2296 | saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]); | 2349 | saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]); |
2297 | saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_out[vo][5]); | 2350 | video_reg = video_out[vo][5]; |
2298 | saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_out[vo][6]); | 2351 | if (vid_port_opts & SET_CLOCK_NOT_DELAYED) |
2352 | video_reg &= ~VP_CLK_CTRL2_DELAYED; | ||
2353 | if (vid_port_opts & SET_CLOCK_INVERTED) | ||
2354 | video_reg |= VP_CLK_CTRL1_INVERTED; | ||
2355 | saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_reg); | ||
2356 | video_reg = video_out[vo][6]; | ||
2357 | if (vid_port_opts & SET_VSYNC_OFF) { | ||
2358 | video_reg &= ~VP_VS_TYPE_MASK; | ||
2359 | video_reg |= VP_VS_TYPE_OFF; | ||
2360 | } | ||
2361 | saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_reg); | ||
2299 | saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]); | 2362 | saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]); |
2300 | saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]); | 2363 | saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]); |
2301 | } | 2364 | } |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 860b89530e2a..fb9727471661 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -24,16 +24,18 @@ | |||
24 | 24 | ||
25 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
27 | #include <linux/videodev.h> | 27 | #include <linux/videodev2.h> |
28 | #include <linux/kdev_t.h> | 28 | #include <linux/kdev_t.h> |
29 | #include <linux/input.h> | 29 | #include <linux/input.h> |
30 | #include <linux/notifier.h> | ||
31 | #include <linux/delay.h> | ||
30 | 32 | ||
31 | #include <asm/io.h> | 33 | #include <asm/io.h> |
32 | 34 | ||
33 | #include <media/tuner.h> | 35 | #include <media/tuner.h> |
34 | #include <media/audiochip.h> | 36 | #include <media/audiochip.h> |
35 | #include <media/id.h> | ||
36 | #include <media/ir-common.h> | 37 | #include <media/ir-common.h> |
38 | #include <media/ir-kbd-i2c.h> | ||
37 | #include <media/video-buf.h> | 39 | #include <media/video-buf.h> |
38 | #include <media/video-buf-dvb.h> | 40 | #include <media/video-buf-dvb.h> |
39 | 41 | ||
@@ -45,6 +47,10 @@ | |||
45 | #endif | 47 | #endif |
46 | #define UNSET (-1U) | 48 | #define UNSET (-1U) |
47 | 49 | ||
50 | #include <sound/driver.h> | ||
51 | #include <sound/core.h> | ||
52 | #include <sound/pcm.h> | ||
53 | |||
48 | /* ----------------------------------------------------------- */ | 54 | /* ----------------------------------------------------------- */ |
49 | /* enums */ | 55 | /* enums */ |
50 | 56 | ||
@@ -187,10 +193,39 @@ struct saa7134_format { | |||
187 | #define SAA7134_BOARD_FLYTV_DIGIMATRIX 64 | 193 | #define SAA7134_BOARD_FLYTV_DIGIMATRIX 64 |
188 | #define SAA7134_BOARD_KWORLD_TERMINATOR 65 | 194 | #define SAA7134_BOARD_KWORLD_TERMINATOR 65 |
189 | #define SAA7134_BOARD_YUAN_TUN900 66 | 195 | #define SAA7134_BOARD_YUAN_TUN900 66 |
196 | #define SAA7134_BOARD_BEHOLD_409FM 67 | ||
197 | #define SAA7134_BOARD_GOTVIEW_7135 68 | ||
198 | #define SAA7134_BOARD_PHILIPS_EUROPA 69 | ||
199 | #define SAA7134_BOARD_VIDEOMATE_DVBT_300 70 | ||
200 | #define SAA7134_BOARD_VIDEOMATE_DVBT_200 71 | ||
201 | #define SAA7134_BOARD_RTD_VFG7350 72 | ||
202 | #define SAA7134_BOARD_RTD_VFG7330 73 | ||
203 | #define SAA7134_BOARD_FLYTVPLATINUM_MINI2 74 | ||
204 | #define SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180 75 | ||
205 | #define SAA7134_BOARD_MONSTERTV_MOBILE 76 | ||
206 | #define SAA7134_BOARD_PINNACLE_PCTV_110i 77 | ||
207 | #define SAA7134_BOARD_ASUSTeK_P7131_DUAL 78 | ||
208 | #define SAA7134_BOARD_SEDNA_PC_TV_CARDBUS 79 | ||
209 | #define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80 | ||
210 | #define SAA7134_BOARD_PHILIPS_TIGER 81 | ||
190 | 211 | ||
191 | #define SAA7134_MAXBOARDS 8 | 212 | #define SAA7134_MAXBOARDS 8 |
192 | #define SAA7134_INPUT_MAX 8 | 213 | #define SAA7134_INPUT_MAX 8 |
193 | 214 | ||
215 | /* ----------------------------------------------------------- */ | ||
216 | /* Since we support 2 remote types, lets tell them apart */ | ||
217 | |||
218 | #define SAA7134_REMOTE_GPIO 1 | ||
219 | #define SAA7134_REMOTE_I2C 2 | ||
220 | |||
221 | /* ----------------------------------------------------------- */ | ||
222 | /* Video Output Port Register Initialization Options */ | ||
223 | |||
224 | #define SET_T_CODE_POLARITY_NON_INVERTED (1 << 0) | ||
225 | #define SET_CLOCK_NOT_DELAYED (1 << 1) | ||
226 | #define SET_CLOCK_INVERTED (1 << 2) | ||
227 | #define SET_VSYNC_OFF (1 << 3) | ||
228 | |||
194 | struct saa7134_input { | 229 | struct saa7134_input { |
195 | char *name; | 230 | char *name; |
196 | unsigned int vmux; | 231 | unsigned int vmux; |
@@ -226,6 +261,7 @@ struct saa7134_board { | |||
226 | /* peripheral I/O */ | 261 | /* peripheral I/O */ |
227 | enum saa7134_video_out video_out; | 262 | enum saa7134_video_out video_out; |
228 | enum saa7134_mpeg_type mpeg; | 263 | enum saa7134_mpeg_type mpeg; |
264 | unsigned int vid_port_opts; | ||
229 | }; | 265 | }; |
230 | 266 | ||
231 | #define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name) | 267 | #define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name) |
@@ -319,9 +355,9 @@ struct saa7134_fh { | |||
319 | struct saa7134_pgtable pt_vbi; | 355 | struct saa7134_pgtable pt_vbi; |
320 | }; | 356 | }; |
321 | 357 | ||
322 | /* oss dsp status */ | 358 | /* dmasound dsp status */ |
323 | struct saa7134_oss { | 359 | struct saa7134_dmasound { |
324 | struct semaphore lock; | 360 | struct semaphore lock; |
325 | int minor_mixer; | 361 | int minor_mixer; |
326 | int minor_dsp; | 362 | int minor_dsp; |
327 | unsigned int users_dsp; | 363 | unsigned int users_dsp; |
@@ -347,6 +383,7 @@ struct saa7134_oss { | |||
347 | unsigned int dma_blk; | 383 | unsigned int dma_blk; |
348 | unsigned int read_offset; | 384 | unsigned int read_offset; |
349 | unsigned int read_count; | 385 | unsigned int read_count; |
386 | snd_pcm_substream_t *substream; | ||
350 | }; | 387 | }; |
351 | 388 | ||
352 | /* IR input */ | 389 | /* IR input */ |
@@ -358,9 +395,9 @@ struct saa7134_ir { | |||
358 | u32 mask_keycode; | 395 | u32 mask_keycode; |
359 | u32 mask_keydown; | 396 | u32 mask_keydown; |
360 | u32 mask_keyup; | 397 | u32 mask_keyup; |
361 | int polling; | 398 | int polling; |
362 | u32 last_gpio; | 399 | u32 last_gpio; |
363 | struct timer_list timer; | 400 | struct timer_list timer; |
364 | }; | 401 | }; |
365 | 402 | ||
366 | /* ts/mpeg status */ | 403 | /* ts/mpeg status */ |
@@ -383,8 +420,8 @@ struct saa7134_mpeg_ops { | |||
383 | /* global device status */ | 420 | /* global device status */ |
384 | struct saa7134_dev { | 421 | struct saa7134_dev { |
385 | struct list_head devlist; | 422 | struct list_head devlist; |
386 | struct semaphore lock; | 423 | struct semaphore lock; |
387 | spinlock_t slock; | 424 | spinlock_t slock; |
388 | #ifdef VIDIOC_G_PRIORITY | 425 | #ifdef VIDIOC_G_PRIORITY |
389 | struct v4l2_prio_state prio; | 426 | struct v4l2_prio_state prio; |
390 | #endif | 427 | #endif |
@@ -394,7 +431,7 @@ struct saa7134_dev { | |||
394 | struct video_device *video_dev; | 431 | struct video_device *video_dev; |
395 | struct video_device *radio_dev; | 432 | struct video_device *radio_dev; |
396 | struct video_device *vbi_dev; | 433 | struct video_device *vbi_dev; |
397 | struct saa7134_oss oss; | 434 | struct saa7134_dmasound dmasound; |
398 | 435 | ||
399 | /* infrared remote */ | 436 | /* infrared remote */ |
400 | int has_remote; | 437 | int has_remote; |
@@ -421,7 +458,7 @@ struct saa7134_dev { | |||
421 | /* i2c i/o */ | 458 | /* i2c i/o */ |
422 | struct i2c_adapter i2c_adap; | 459 | struct i2c_adapter i2c_adap; |
423 | struct i2c_client i2c_client; | 460 | struct i2c_client i2c_client; |
424 | unsigned char eedata[64]; | 461 | unsigned char eedata[128]; |
425 | 462 | ||
426 | /* video overlay */ | 463 | /* video overlay */ |
427 | struct v4l2_framebuffer ovbuf; | 464 | struct v4l2_framebuffer ovbuf; |
@@ -626,6 +663,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status); | |||
626 | int saa7134_input_init1(struct saa7134_dev *dev); | 663 | int saa7134_input_init1(struct saa7134_dev *dev); |
627 | void saa7134_input_fini(struct saa7134_dev *dev); | 664 | void saa7134_input_fini(struct saa7134_dev *dev); |
628 | void saa7134_input_irq(struct saa7134_dev *dev); | 665 | void saa7134_input_irq(struct saa7134_dev *dev); |
666 | void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir); | ||
629 | 667 | ||
630 | /* | 668 | /* |
631 | * Local variables: | 669 | * Local variables: |
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 255b6088ebf9..d32737dd2142 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c | |||
@@ -50,7 +50,6 @@ | |||
50 | 50 | ||
51 | #include "bttv.h" | 51 | #include "bttv.h" |
52 | #include <media/audiochip.h> | 52 | #include <media/audiochip.h> |
53 | #include <media/id.h> | ||
54 | 53 | ||
55 | #ifndef VIDEO_AUDIO_BALANCE | 54 | #ifndef VIDEO_AUDIO_BALANCE |
56 | # define VIDEO_AUDIO_BALANCE 32 | 55 | # define VIDEO_AUDIO_BALANCE 32 |
@@ -310,9 +309,9 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind) | |||
310 | memset(t,0,sizeof *t); | 309 | memset(t,0,sizeof *t); |
311 | 310 | ||
312 | client = &t->c; | 311 | client = &t->c; |
313 | memcpy(client,&client_template,sizeof(struct i2c_client)); | 312 | memcpy(client,&client_template,sizeof(struct i2c_client)); |
314 | client->adapter = adap; | 313 | client->adapter = adap; |
315 | client->addr = addr; | 314 | client->addr = addr; |
316 | i2c_set_clientdata(client, t); | 315 | i2c_set_clientdata(client, t); |
317 | 316 | ||
318 | do_tda7432_init(client); | 317 | do_tda7432_init(client); |
@@ -472,7 +471,7 @@ static int tda7432_command(struct i2c_client *client, | |||
472 | } | 471 | } |
473 | } | 472 | } |
474 | 473 | ||
475 | t->muted=(va->flags & VIDEO_AUDIO_MUTE); | 474 | t->muted=(va->flags & VIDEO_AUDIO_MUTE); |
476 | if (t->muted) | 475 | if (t->muted) |
477 | { | 476 | { |
478 | /* Mute & update balance*/ | 477 | /* Mute & update balance*/ |
@@ -503,12 +502,12 @@ static int tda7432_command(struct i2c_client *client, | |||
503 | 502 | ||
504 | static struct i2c_driver driver = { | 503 | static struct i2c_driver driver = { |
505 | .owner = THIS_MODULE, | 504 | .owner = THIS_MODULE, |
506 | .name = "i2c tda7432 driver", | 505 | .name = "i2c tda7432 driver", |
507 | .id = I2C_DRIVERID_TDA7432, | 506 | .id = I2C_DRIVERID_TDA7432, |
508 | .flags = I2C_DF_NOTIFY, | 507 | .flags = I2C_DF_NOTIFY, |
509 | .attach_adapter = tda7432_probe, | 508 | .attach_adapter = tda7432_probe, |
510 | .detach_client = tda7432_detach, | 509 | .detach_client = tda7432_detach, |
511 | .command = tda7432_command, | 510 | .command = tda7432_command, |
512 | }; | 511 | }; |
513 | 512 | ||
514 | static struct i2c_client client_template = | 513 | static struct i2c_client client_template = |
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index c65f0c7680a2..b2dfe07e9f9d 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c | |||
@@ -1,172 +1,406 @@ | |||
1 | /* | 1 | /* |
2 | * | 2 | |
3 | * i2c tv tuner chip device driver | 3 | i2c tv tuner chip device driver |
4 | * controls the philips tda8290+75 tuner chip combo. | 4 | controls the philips tda8290+75 tuner chip combo. |
5 | */ | 5 | |
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
6 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
7 | #include <linux/videodev.h> | 22 | #include <linux/videodev.h> |
8 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
9 | #include <media/tuner.h> | 24 | #include <media/tuner.h> |
10 | 25 | ||
11 | #define I2C_ADDR_TDA8290 0x4b | ||
12 | #define I2C_ADDR_TDA8275 0x61 | ||
13 | |||
14 | /* ---------------------------------------------------------------------- */ | 26 | /* ---------------------------------------------------------------------- */ |
15 | 27 | ||
16 | struct freq_entry { | 28 | struct tda827x_data { |
17 | u16 freq; | 29 | u32 lomax; |
18 | u8 value; | 30 | u8 spd; |
31 | u8 bs; | ||
32 | u8 bp; | ||
33 | u8 cp; | ||
34 | u8 gc3; | ||
35 | u8 div1p5; | ||
19 | }; | 36 | }; |
20 | 37 | ||
21 | static struct freq_entry band_table[] = { | 38 | /* Note lomax entry is lo / 62500 */ |
22 | { 0x2DF4, 0x1C }, | 39 | |
23 | { 0x2574, 0x14 }, | 40 | static struct tda827x_data tda827x_analog[] = { |
24 | { 0x22B4, 0x0C }, | 41 | { .lomax = 992, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 62 MHz */ |
25 | { 0x20D4, 0x0B }, | 42 | { .lomax = 1056, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 66 MHz */ |
26 | { 0x1E74, 0x3B }, | 43 | { .lomax = 1216, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 76 MHz */ |
27 | { 0x1C34, 0x33 }, | 44 | { .lomax = 1344, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 84 MHz */ |
28 | { 0x16F4, 0x5B }, | 45 | { .lomax = 1488, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 93 MHz */ |
29 | { 0x1454, 0x53 }, | 46 | { .lomax = 1568, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 98 MHz */ |
30 | { 0x12D4, 0x52 }, | 47 | { .lomax = 1744, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 109 MHz */ |
31 | { 0x1034, 0x4A }, | 48 | { .lomax = 1968, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 123 MHz */ |
32 | { 0x0EE4, 0x7A }, | 49 | { .lomax = 2128, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 133 MHz */ |
33 | { 0x0D34, 0x72 }, | 50 | { .lomax = 2416, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 151 MHz */ |
34 | { 0x0B54, 0x9A }, | 51 | { .lomax = 2464, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 154 MHz */ |
35 | { 0x0914, 0x91 }, | 52 | { .lomax = 2896, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 181 MHz */ |
36 | { 0x07F4, 0x89 }, | 53 | { .lomax = 2960, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 185 MHz */ |
37 | { 0x0774, 0xB9 }, | 54 | { .lomax = 3472, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 217 MHz */ |
38 | { 0x067B, 0xB1 }, | 55 | { .lomax = 3904, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 244 MHz */ |
39 | { 0x0634, 0xD9 }, | 56 | { .lomax = 4240, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 265 MHz */ |
40 | { 0x05A4, 0xD8 }, // FM radio | 57 | { .lomax = 4832, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 302 MHz */ |
41 | { 0x0494, 0xD0 }, | 58 | { .lomax = 5184, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 324 MHz */ |
42 | { 0x03BC, 0xC8 }, | 59 | { .lomax = 5920, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 370 MHz */ |
43 | { 0x0394, 0xF8 }, // 57250000 Hz | 60 | { .lomax = 7264, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 454 MHz */ |
44 | { 0x0000, 0xF0 }, // 0 | 61 | { .lomax = 7888, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 493 MHz */ |
62 | { .lomax = 8480, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 530 MHz */ | ||
63 | { .lomax = 8864, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 554 MHz */ | ||
64 | { .lomax = 9664, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 604 MHz */ | ||
65 | { .lomax = 11088, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 696 MHz */ | ||
66 | { .lomax = 11840, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 740 MHz */ | ||
67 | { .lomax = 13120, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 820 MHz */ | ||
68 | { .lomax = 13840, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 865 MHz */ | ||
69 | { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} /* End */ | ||
45 | }; | 70 | }; |
46 | 71 | ||
47 | static struct freq_entry div_table[] = { | 72 | static void tda827x_tune(struct i2c_client *c, u16 ifc, unsigned int freq) |
48 | { 0x1C34, 3 }, | 73 | { |
49 | { 0x0D34, 2 }, | 74 | unsigned char tuner_reg[8]; |
50 | { 0x067B, 1 }, | 75 | unsigned char reg2[2]; |
51 | { 0x0000, 0 }, | 76 | u32 N; |
52 | }; | 77 | int i; |
78 | struct tuner *t = i2c_get_clientdata(c); | ||
79 | struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0}; | ||
53 | 80 | ||
54 | static struct freq_entry agc_table[] = { | 81 | if (t->mode == V4L2_TUNER_RADIO) |
55 | { 0x22B4, 0x8F }, | 82 | freq = freq / 1000; |
56 | { 0x0B54, 0x9F }, | ||
57 | { 0x09A4, 0x8F }, | ||
58 | { 0x0554, 0x9F }, | ||
59 | { 0x0000, 0xBF }, | ||
60 | }; | ||
61 | 83 | ||
62 | static __u8 get_freq_entry( struct freq_entry* table, __u16 freq) | 84 | N = freq + ifc; |
63 | { | 85 | i = 0; |
64 | while(table->freq && table->freq > freq) | 86 | while (tda827x_analog[i].lomax < N) { |
65 | table++; | 87 | if(tda827x_analog[i + 1].lomax == 0) |
66 | return table->value; | 88 | break; |
67 | } | 89 | i++; |
90 | } | ||
91 | |||
92 | N = N << tda827x_analog[i].spd; | ||
93 | |||
94 | tuner_reg[0] = 0; | ||
95 | tuner_reg[1] = (unsigned char)(N>>8); | ||
96 | tuner_reg[2] = (unsigned char) N; | ||
97 | tuner_reg[3] = 0x40; | ||
98 | tuner_reg[4] = 0x52 + (t->tda827x_lpsel << 5); | ||
99 | tuner_reg[5] = (tda827x_analog[i].spd << 6) + (tda827x_analog[i].div1p5 <<5) + | ||
100 | (tda827x_analog[i].bs <<3) + tda827x_analog[i].bp; | ||
101 | tuner_reg[6] = 0x8f + (tda827x_analog[i].gc3 << 4); | ||
102 | tuner_reg[7] = 0x8f; | ||
103 | |||
104 | msg.buf = tuner_reg; | ||
105 | msg.len = 8; | ||
106 | i2c_transfer(c->adapter, &msg, 1); | ||
107 | |||
108 | msg.buf= reg2; | ||
109 | msg.len = 2; | ||
110 | reg2[0] = 0x80; | ||
111 | reg2[1] = 0; | ||
112 | i2c_transfer(c->adapter, &msg, 1); | ||
113 | |||
114 | reg2[0] = 0x60; | ||
115 | reg2[1] = 0xbf; | ||
116 | i2c_transfer(c->adapter, &msg, 1); | ||
117 | |||
118 | reg2[0] = 0x30; | ||
119 | reg2[1] = tuner_reg[4] + 0x80; | ||
120 | i2c_transfer(c->adapter, &msg, 1); | ||
121 | |||
122 | msleep(1); | ||
123 | reg2[0] = 0x30; | ||
124 | reg2[1] = tuner_reg[4] + 4; | ||
125 | i2c_transfer(c->adapter, &msg, 1); | ||
126 | |||
127 | msleep(1); | ||
128 | reg2[0] = 0x30; | ||
129 | reg2[1] = tuner_reg[4]; | ||
130 | i2c_transfer(c->adapter, &msg, 1); | ||
68 | 131 | ||
69 | /* ---------------------------------------------------------------------- */ | 132 | msleep(550); |
133 | reg2[0] = 0x30; | ||
134 | reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_analog[i].cp ; | ||
135 | i2c_transfer(c->adapter, &msg, 1); | ||
70 | 136 | ||
71 | static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 }; | 137 | reg2[0] = 0x60; |
72 | static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 }; | 138 | reg2[1] = 0x3f; |
73 | static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00, | 139 | i2c_transfer(c->adapter, &msg, 1); |
74 | 0xfC, 0x04, 0xA3, 0x3F, | ||
75 | 0x2A, 0x04, 0xFF, 0x00, | ||
76 | 0x00, 0x40 }; | ||
77 | static unsigned char i2c_set_VS[2] = { 0x30, 0x6F }; | ||
78 | static unsigned char i2c_set_GP01_CF[2] = { 0x20, 0x0B }; | ||
79 | static unsigned char i2c_tda8290_reset[2] = { 0x00, 0x00 }; | ||
80 | static unsigned char i2c_tda8290_standby[2] = { 0x00, 0x02 }; | ||
81 | static unsigned char i2c_gainset_off[2] = { 0x28, 0x14 }; | ||
82 | static unsigned char i2c_gainset_on[2] = { 0x28, 0x54 }; | ||
83 | static unsigned char i2c_agc3_00[2] = { 0x80, 0x00 }; | ||
84 | static unsigned char i2c_agc2_BF[2] = { 0x60, 0xBF }; | ||
85 | static unsigned char i2c_cb1_D0[2] = { 0x30, 0xD0 }; | ||
86 | static unsigned char i2c_cb1_D2[2] = { 0x30, 0xD2 }; | ||
87 | static unsigned char i2c_cb1_56[2] = { 0x30, 0x56 }; | ||
88 | static unsigned char i2c_cb1_52[2] = { 0x30, 0x52 }; | ||
89 | static unsigned char i2c_cb1_50[2] = { 0x30, 0x50 }; | ||
90 | static unsigned char i2c_agc2_7F[2] = { 0x60, 0x7F }; | ||
91 | static unsigned char i2c_agc3_08[2] = { 0x80, 0x08 }; | ||
92 | |||
93 | static struct i2c_msg i2c_msg_init[] = { | ||
94 | { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_init_tda8275), i2c_init_tda8275 }, | ||
95 | { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge }, | ||
96 | { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_VS), i2c_set_VS }, | ||
97 | { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_GP01_CF), i2c_set_GP01_CF }, | ||
98 | }; | ||
99 | 140 | ||
100 | static struct i2c_msg i2c_msg_prolog[] = { | 141 | reg2[0] = 0x80; |
101 | // { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_easy_mode), i2c_easy_mode }, | 142 | reg2[1] = 0x08; // Vsync en |
102 | { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_off), i2c_gainset_off }, | 143 | i2c_transfer(c->adapter, &msg, 1); |
103 | { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_reset), i2c_tda8290_reset }, | 144 | } |
104 | { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge }, | ||
105 | }; | ||
106 | 145 | ||
107 | static struct i2c_msg i2c_msg_config[] = { | 146 | static void tda827x_agcf(struct i2c_client *c) |
108 | // { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_set_freq), i2c_set_freq }, | 147 | { |
109 | { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_00), i2c_agc3_00 }, | 148 | struct tuner *t = i2c_get_clientdata(c); |
110 | { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_BF), i2c_agc2_BF }, | 149 | unsigned char data[] = {0x80, 0x0c}; |
111 | { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D2), i2c_cb1_D2 }, | 150 | struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data, |
112 | { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_56), i2c_cb1_56 }, | 151 | .flags = 0, .len = 2}; |
113 | { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_52), i2c_cb1_52 }, | 152 | i2c_transfer(c->adapter, &msg, 1); |
114 | }; | 153 | } |
115 | 154 | ||
116 | static struct i2c_msg i2c_msg_epilog[] = { | 155 | /* ---------------------------------------------------------------------- */ |
117 | { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_50), i2c_cb1_50 }, | 156 | |
118 | { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_7F), i2c_agc2_7F }, | 157 | struct tda827xa_data { |
119 | { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_08), i2c_agc3_08 }, | 158 | u32 lomax; |
120 | { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge }, | 159 | u8 svco; |
121 | { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_on), i2c_gainset_on }, | 160 | u8 spd; |
161 | u8 scr; | ||
162 | u8 sbs; | ||
163 | u8 gc3; | ||
122 | }; | 164 | }; |
123 | 165 | ||
124 | static struct i2c_msg i2c_msg_standby[] = { | 166 | static struct tda827xa_data tda827xa_analog[] = { |
125 | { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge }, | 167 | { .lomax = 910, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3}, /* 56.875 MHz */ |
126 | { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D0), i2c_cb1_D0 }, | 168 | { .lomax = 1076, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 67.25 MHz */ |
127 | { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge }, | 169 | { .lomax = 1300, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 81.25 MHz */ |
128 | { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_standby), i2c_tda8290_standby }, | 170 | { .lomax = 1560, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 97.5 MHz */ |
171 | { .lomax = 1820, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, /* 113.75 MHz */ | ||
172 | { .lomax = 2152, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 134.5 MHz */ | ||
173 | { .lomax = 2464, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 154 MHz */ | ||
174 | { .lomax = 2600, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 162.5 MHz */ | ||
175 | { .lomax = 2928, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 183 MHz */ | ||
176 | { .lomax = 3120, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, /* 195 MHz */ | ||
177 | { .lomax = 3640, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3}, /* 227.5 MHz */ | ||
178 | { .lomax = 4304, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3}, /* 269 MHz */ | ||
179 | { .lomax = 5200, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, /* 325 MHz */ | ||
180 | { .lomax = 6240, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 390 MHz */ | ||
181 | { .lomax = 7280, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 455 MHz */ | ||
182 | { .lomax = 8320, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 520 MHz */ | ||
183 | { .lomax = 8608, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, /* 538 MHz */ | ||
184 | { .lomax = 8864, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 554 MHz */ | ||
185 | { .lomax = 9920, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 620 MHz */ | ||
186 | { .lomax = 10400, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 650 MHz */ | ||
187 | { .lomax = 11200, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 700 MHz */ | ||
188 | { .lomax = 12480, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 780 MHz */ | ||
189 | { .lomax = 13120, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 820 MHz */ | ||
190 | { .lomax = 13920, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 870 MHz */ | ||
191 | { .lomax = 14576, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, /* 911 MHz */ | ||
192 | { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */ | ||
129 | }; | 193 | }; |
130 | 194 | ||
131 | static int tda8290_tune(struct i2c_client *c) | 195 | static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq) |
132 | { | 196 | { |
197 | unsigned char tuner_reg[14]; | ||
198 | unsigned char reg2[2]; | ||
199 | u32 N; | ||
200 | int i; | ||
133 | struct tuner *t = i2c_get_clientdata(c); | 201 | struct tuner *t = i2c_get_clientdata(c); |
134 | struct i2c_msg easy_mode = | 202 | struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0}; |
135 | { I2C_ADDR_TDA8290, 0, 2, t->i2c_easy_mode }; | ||
136 | struct i2c_msg set_freq = | ||
137 | { I2C_ADDR_TDA8275, 0, 8, t->i2c_set_freq }; | ||
138 | 203 | ||
139 | i2c_transfer(c->adapter, &easy_mode, 1); | 204 | if (t->mode == V4L2_TUNER_RADIO) |
140 | i2c_transfer(c->adapter, i2c_msg_prolog, ARRAY_SIZE(i2c_msg_prolog)); | 205 | freq = freq / 1000; |
141 | 206 | ||
142 | i2c_transfer(c->adapter, &set_freq, 1); | 207 | N = freq + ifc; |
143 | i2c_transfer(c->adapter, i2c_msg_config, ARRAY_SIZE(i2c_msg_config)); | 208 | i = 0; |
209 | while (tda827xa_analog[i].lomax < N) { | ||
210 | if(tda827xa_analog[i + 1].lomax == 0) | ||
211 | break; | ||
212 | i++; | ||
213 | } | ||
214 | |||
215 | N = N << tda827xa_analog[i].spd; | ||
216 | |||
217 | tuner_reg[0] = 0; | ||
218 | tuner_reg[1] = (unsigned char)(N>>8); | ||
219 | tuner_reg[2] = (unsigned char) N; | ||
220 | tuner_reg[3] = 0; | ||
221 | tuner_reg[4] = 0x16; | ||
222 | tuner_reg[5] = (tda827xa_analog[i].spd << 5) + (tda827xa_analog[i].svco << 3) + | ||
223 | tda827xa_analog[i].sbs; | ||
224 | tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4); | ||
225 | tuner_reg[7] = 0x0c; | ||
226 | tuner_reg[8] = 4; | ||
227 | tuner_reg[9] = 0x20; | ||
228 | tuner_reg[10] = 0xff; | ||
229 | tuner_reg[11] = 0xe0; | ||
230 | tuner_reg[12] = 0; | ||
231 | tuner_reg[13] = 0x39 + (t->tda827x_lpsel << 1); | ||
232 | |||
233 | msg.buf = tuner_reg; | ||
234 | msg.len = 14; | ||
235 | i2c_transfer(c->adapter, &msg, 1); | ||
236 | |||
237 | msg.buf= reg2; | ||
238 | msg.len = 2; | ||
239 | reg2[0] = 0x60; | ||
240 | reg2[1] = 0x3c; | ||
241 | i2c_transfer(c->adapter, &msg, 1); | ||
242 | |||
243 | reg2[0] = 0xa0; | ||
244 | reg2[1] = 0xc0; | ||
245 | i2c_transfer(c->adapter, &msg, 1); | ||
246 | |||
247 | msleep(2); | ||
248 | reg2[0] = 0x30; | ||
249 | reg2[1] = 0x10 + tda827xa_analog[i].scr; | ||
250 | i2c_transfer(c->adapter, &msg, 1); | ||
144 | 251 | ||
145 | msleep(550); | 252 | msleep(550); |
146 | i2c_transfer(c->adapter, i2c_msg_epilog, ARRAY_SIZE(i2c_msg_epilog)); | 253 | reg2[0] = 0x50; |
147 | return 0; | 254 | reg2[1] = 0x8f + (tda827xa_analog[i].gc3 << 4); |
255 | i2c_transfer(c->adapter, &msg, 1); | ||
256 | |||
257 | reg2[0] = 0x80; | ||
258 | reg2[1] = 0x28; | ||
259 | i2c_transfer(c->adapter, &msg, 1); | ||
260 | |||
261 | reg2[0] = 0xb0; | ||
262 | reg2[1] = 0x01; | ||
263 | i2c_transfer(c->adapter, &msg, 1); | ||
264 | |||
265 | reg2[0] = 0xc0; | ||
266 | reg2[1] = 0x19 + (t->tda827x_lpsel << 1); | ||
267 | i2c_transfer(c->adapter, &msg, 1); | ||
148 | } | 268 | } |
149 | 269 | ||
150 | static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq) | 270 | static void tda827xa_agcf(struct i2c_client *c) |
151 | { | 271 | { |
152 | u32 N; | 272 | struct tuner *t = i2c_get_clientdata(c); |
273 | unsigned char data[] = {0x80, 0x2c}; | ||
274 | struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data, | ||
275 | .flags = 0, .len = 2}; | ||
276 | i2c_transfer(c->adapter, &msg, 1); | ||
277 | } | ||
153 | 278 | ||
154 | if (t->mode == V4L2_TUNER_RADIO) | 279 | /*---------------------------------------------------------------------*/ |
155 | freq = freq / 1000; | ||
156 | 280 | ||
157 | N = (((freq<<3)+ifc)&0x3fffc); | 281 | static void tda8290_i2c_bridge(struct i2c_client *c, int close) |
158 | 282 | { | |
159 | N = N >> get_freq_entry(div_table, freq); | 283 | unsigned char enable[2] = { 0x21, 0xC0 }; |
160 | t->i2c_set_freq[0] = 0; | 284 | unsigned char disable[2] = { 0x21, 0x80 }; |
161 | t->i2c_set_freq[1] = (unsigned char)(N>>8); | 285 | unsigned char *msg; |
162 | t->i2c_set_freq[2] = (unsigned char) N; | 286 | if(close) { |
163 | t->i2c_set_freq[3] = 0x40; | 287 | msg = enable; |
164 | t->i2c_set_freq[4] = 0x52; | 288 | i2c_master_send(c, msg, 2); |
165 | t->i2c_set_freq[5] = get_freq_entry(band_table, freq); | 289 | /* let the bridge stabilize */ |
166 | t->i2c_set_freq[6] = get_freq_entry(agc_table, freq); | 290 | msleep(20); |
167 | t->i2c_set_freq[7] = 0x8f; | 291 | } else { |
292 | msg = disable; | ||
293 | i2c_master_send(c, msg, 2); | ||
294 | } | ||
168 | } | 295 | } |
169 | 296 | ||
297 | /*---------------------------------------------------------------------*/ | ||
298 | |||
299 | static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) | ||
300 | { | ||
301 | struct tuner *t = i2c_get_clientdata(c); | ||
302 | unsigned char soft_reset[] = { 0x00, 0x00 }; | ||
303 | unsigned char easy_mode[] = { 0x01, t->tda8290_easy_mode }; | ||
304 | unsigned char expert_mode[] = { 0x01, 0x80 }; | ||
305 | unsigned char gainset_off[] = { 0x28, 0x14 }; | ||
306 | unsigned char if_agc_spd[] = { 0x0f, 0x88 }; | ||
307 | unsigned char adc_head_6[] = { 0x05, 0x04 }; | ||
308 | unsigned char adc_head_9[] = { 0x05, 0x02 }; | ||
309 | unsigned char adc_head_12[] = { 0x05, 0x01 }; | ||
310 | unsigned char pll_bw_nom[] = { 0x0d, 0x47 }; | ||
311 | unsigned char pll_bw_low[] = { 0x0d, 0x27 }; | ||
312 | unsigned char gainset_2[] = { 0x28, 0x64 }; | ||
313 | unsigned char agc_rst_on[] = { 0x0e, 0x0b }; | ||
314 | unsigned char agc_rst_off[] = { 0x0e, 0x09 }; | ||
315 | unsigned char if_agc_set[] = { 0x0f, 0x81 }; | ||
316 | unsigned char addr_adc_sat = 0x1a; | ||
317 | unsigned char addr_agc_stat = 0x1d; | ||
318 | unsigned char addr_pll_stat = 0x1b; | ||
319 | unsigned char adc_sat, agc_stat, | ||
320 | pll_stat; | ||
321 | |||
322 | i2c_master_send(c, easy_mode, 2); | ||
323 | i2c_master_send(c, soft_reset, 2); | ||
324 | msleep(1); | ||
325 | |||
326 | expert_mode[1] = t->tda8290_easy_mode + 0x80; | ||
327 | i2c_master_send(c, expert_mode, 2); | ||
328 | i2c_master_send(c, gainset_off, 2); | ||
329 | i2c_master_send(c, if_agc_spd, 2); | ||
330 | if (t->tda8290_easy_mode & 0x60) | ||
331 | i2c_master_send(c, adc_head_9, 2); | ||
332 | else | ||
333 | i2c_master_send(c, adc_head_6, 2); | ||
334 | i2c_master_send(c, pll_bw_nom, 2); | ||
335 | |||
336 | tda8290_i2c_bridge(c, 1); | ||
337 | if (t->tda827x_ver != 0) | ||
338 | tda827xa_tune(c, ifc, freq); | ||
339 | else | ||
340 | tda827x_tune(c, ifc, freq); | ||
341 | /* adjust headroom resp. gain */ | ||
342 | i2c_master_send(c, &addr_adc_sat, 1); | ||
343 | i2c_master_recv(c, &adc_sat, 1); | ||
344 | i2c_master_send(c, &addr_agc_stat, 1); | ||
345 | i2c_master_recv(c, &agc_stat, 1); | ||
346 | i2c_master_send(c, &addr_pll_stat, 1); | ||
347 | i2c_master_recv(c, &pll_stat, 1); | ||
348 | if (pll_stat & 0x80) | ||
349 | tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat); | ||
350 | else | ||
351 | tuner_dbg("tda8290 not locked, no signal?\n"); | ||
352 | if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) { | ||
353 | tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n", | ||
354 | agc_stat, adc_sat, pll_stat & 0x80); | ||
355 | i2c_master_send(c, gainset_2, 2); | ||
356 | msleep(100); | ||
357 | i2c_master_send(c, &addr_agc_stat, 1); | ||
358 | i2c_master_recv(c, &agc_stat, 1); | ||
359 | i2c_master_send(c, &addr_pll_stat, 1); | ||
360 | i2c_master_recv(c, &pll_stat, 1); | ||
361 | if ((agc_stat > 115) || !(pll_stat & 0x80)) { | ||
362 | tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n", | ||
363 | agc_stat, pll_stat & 0x80); | ||
364 | if (t->tda827x_ver != 0) | ||
365 | tda827xa_agcf(c); | ||
366 | else | ||
367 | tda827x_agcf(c); | ||
368 | msleep(100); | ||
369 | i2c_master_send(c, &addr_agc_stat, 1); | ||
370 | i2c_master_recv(c, &agc_stat, 1); | ||
371 | i2c_master_send(c, &addr_pll_stat, 1); | ||
372 | i2c_master_recv(c, &pll_stat, 1); | ||
373 | if((agc_stat > 115) || !(pll_stat & 0x80)) { | ||
374 | tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat); | ||
375 | i2c_master_send(c, adc_head_12, 2); | ||
376 | i2c_master_send(c, pll_bw_low, 2); | ||
377 | msleep(100); | ||
378 | } | ||
379 | } | ||
380 | } | ||
381 | |||
382 | /* l/ l' deadlock? */ | ||
383 | if(t->tda8290_easy_mode & 0x60) { | ||
384 | i2c_master_send(c, &addr_adc_sat, 1); | ||
385 | i2c_master_recv(c, &adc_sat, 1); | ||
386 | i2c_master_send(c, &addr_pll_stat, 1); | ||
387 | i2c_master_recv(c, &pll_stat, 1); | ||
388 | if ((adc_sat > 20) || !(pll_stat & 0x80)) { | ||
389 | tuner_dbg("trying to resolve SECAM L deadlock\n"); | ||
390 | i2c_master_send(c, agc_rst_on, 2); | ||
391 | msleep(40); | ||
392 | i2c_master_send(c, agc_rst_off, 2); | ||
393 | } | ||
394 | } | ||
395 | |||
396 | tda8290_i2c_bridge(c, 0); | ||
397 | i2c_master_send(c, if_agc_set, 2); | ||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | |||
402 | /*---------------------------------------------------------------------*/ | ||
403 | |||
170 | #define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) | 404 | #define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) |
171 | #define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) | 405 | #define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) |
172 | #define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H) | 406 | #define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H) |
@@ -174,20 +408,37 @@ static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq) | |||
174 | 408 | ||
175 | static void set_audio(struct tuner *t) | 409 | static void set_audio(struct tuner *t) |
176 | { | 410 | { |
177 | t->i2c_easy_mode[0] = 0x01; | 411 | char* mode; |
178 | 412 | ||
179 | if (t->std & V4L2_STD_MN) | 413 | t->tda827x_lpsel = 0; |
180 | t->i2c_easy_mode[1] = 0x01; | 414 | mode = "xx"; |
181 | else if (t->std & V4L2_STD_B) | 415 | if (t->std & V4L2_STD_MN) { |
182 | t->i2c_easy_mode[1] = 0x02; | 416 | t->sgIF = 92; |
183 | else if (t->std & V4L2_STD_GH) | 417 | t->tda8290_easy_mode = 0x01; |
184 | t->i2c_easy_mode[1] = 0x04; | 418 | t->tda827x_lpsel = 1; |
185 | else if (t->std & V4L2_STD_PAL_I) | 419 | mode = "MN"; |
186 | t->i2c_easy_mode[1] = 0x08; | 420 | } else if (t->std & V4L2_STD_B) { |
187 | else if (t->std & V4L2_STD_DK) | 421 | t->sgIF = 108; |
188 | t->i2c_easy_mode[1] = 0x10; | 422 | t->tda8290_easy_mode = 0x02; |
189 | else if (t->std & V4L2_STD_SECAM_L) | 423 | mode = "B"; |
190 | t->i2c_easy_mode[1] = 0x20; | 424 | } else if (t->std & V4L2_STD_GH) { |
425 | t->sgIF = 124; | ||
426 | t->tda8290_easy_mode = 0x04; | ||
427 | mode = "GH"; | ||
428 | } else if (t->std & V4L2_STD_PAL_I) { | ||
429 | t->sgIF = 124; | ||
430 | t->tda8290_easy_mode = 0x08; | ||
431 | mode = "I"; | ||
432 | } else if (t->std & V4L2_STD_DK) { | ||
433 | t->sgIF = 124; | ||
434 | t->tda8290_easy_mode = 0x10; | ||
435 | mode = "DK"; | ||
436 | } else if (t->std & V4L2_STD_SECAM_L) { | ||
437 | t->sgIF = 124; | ||
438 | t->tda8290_easy_mode = 0x20; | ||
439 | mode = "L"; | ||
440 | } | ||
441 | tuner_dbg("setting tda8290 to system %s\n", mode); | ||
191 | } | 442 | } |
192 | 443 | ||
193 | static void set_tv_freq(struct i2c_client *c, unsigned int freq) | 444 | static void set_tv_freq(struct i2c_client *c, unsigned int freq) |
@@ -195,15 +446,13 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
195 | struct tuner *t = i2c_get_clientdata(c); | 446 | struct tuner *t = i2c_get_clientdata(c); |
196 | 447 | ||
197 | set_audio(t); | 448 | set_audio(t); |
198 | set_frequency(t, 864, freq); | 449 | tda8290_tune(c, t->sgIF, freq); |
199 | tda8290_tune(c); | ||
200 | } | 450 | } |
201 | 451 | ||
202 | static void set_radio_freq(struct i2c_client *c, unsigned int freq) | 452 | static void set_radio_freq(struct i2c_client *c, unsigned int freq) |
203 | { | 453 | { |
204 | struct tuner *t = i2c_get_clientdata(c); | 454 | /* if frequency is 5.5 MHz */ |
205 | set_frequency(t, 704, freq); | 455 | tda8290_tune(c, 88, freq); |
206 | tda8290_tune(c); | ||
207 | } | 456 | } |
208 | 457 | ||
209 | static int has_signal(struct i2c_client *c) | 458 | static int has_signal(struct i2c_client *c) |
@@ -216,27 +465,145 @@ static int has_signal(struct i2c_client *c) | |||
216 | return (afc & 0x80)? 65535:0; | 465 | return (afc & 0x80)? 65535:0; |
217 | } | 466 | } |
218 | 467 | ||
468 | /*---------------------------------------------------------------------*/ | ||
469 | |||
219 | static void standby(struct i2c_client *c) | 470 | static void standby(struct i2c_client *c) |
220 | { | 471 | { |
221 | i2c_transfer(c->adapter, i2c_msg_standby, ARRAY_SIZE(i2c_msg_standby)); | 472 | struct tuner *t = i2c_get_clientdata(c); |
473 | unsigned char cb1[] = { 0x30, 0xD0 }; | ||
474 | unsigned char tda8290_standby[] = { 0x00, 0x02 }; | ||
475 | struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, .buf=cb1, .len = 2}; | ||
476 | |||
477 | tda8290_i2c_bridge(c, 1); | ||
478 | if (t->tda827x_ver != 0) | ||
479 | cb1[1] = 0x90; | ||
480 | i2c_transfer(c->adapter, &msg, 1); | ||
481 | tda8290_i2c_bridge(c, 0); | ||
482 | i2c_master_send(c, tda8290_standby, 2); | ||
222 | } | 483 | } |
223 | 484 | ||
224 | int tda8290_init(struct i2c_client *c) | 485 | |
486 | static void tda8290_init_if(struct i2c_client *c) | ||
487 | { | ||
488 | unsigned char set_VS[] = { 0x30, 0x6F }; | ||
489 | unsigned char set_GP01_CF[] = { 0x20, 0x0B }; | ||
490 | |||
491 | i2c_master_send(c, set_VS, 2); | ||
492 | i2c_master_send(c, set_GP01_CF, 2); | ||
493 | } | ||
494 | |||
495 | static void tda8290_init_tuner(struct i2c_client *c) | ||
225 | { | 496 | { |
226 | struct tuner *t = i2c_get_clientdata(c); | 497 | struct tuner *t = i2c_get_clientdata(c); |
498 | unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf, | ||
499 | 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 }; | ||
500 | unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b, | ||
501 | 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b }; | ||
502 | struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, | ||
503 | .buf=tda8275_init, .len = 14}; | ||
504 | if (t->tda827x_ver != 0) | ||
505 | msg.buf = tda8275a_init; | ||
506 | |||
507 | tda8290_i2c_bridge(c, 1); | ||
508 | i2c_transfer(c->adapter, &msg, 1); | ||
509 | tda8290_i2c_bridge(c, 0); | ||
510 | } | ||
227 | 511 | ||
228 | strlcpy(c->name, "tda8290+75", sizeof(c->name)); | 512 | /*---------------------------------------------------------------------*/ |
513 | |||
514 | int tda8290_init(struct i2c_client *c) | ||
515 | { | ||
516 | struct tuner *t = i2c_get_clientdata(c); | ||
517 | u8 data; | ||
518 | int i, ret, tuners_found; | ||
519 | u32 tuner_addrs; | ||
520 | struct i2c_msg msg = {.flags=I2C_M_RD, .buf=&data, .len = 1}; | ||
521 | |||
522 | tda8290_i2c_bridge(c, 1); | ||
523 | /* probe for tuner chip */ | ||
524 | tuners_found = 0; | ||
525 | tuner_addrs = 0; | ||
526 | for (i=0x60; i<= 0x63; i++) { | ||
527 | msg.addr = i; | ||
528 | ret = i2c_transfer(c->adapter, &msg, 1); | ||
529 | if (ret == 1) { | ||
530 | tuners_found++; | ||
531 | tuner_addrs = (tuner_addrs << 8) + i; | ||
532 | } | ||
533 | } | ||
534 | /* if there is more than one tuner, we expect the right one is | ||
535 | behind the bridge and we choose the highest address that doesn't | ||
536 | give a response now | ||
537 | */ | ||
538 | tda8290_i2c_bridge(c, 0); | ||
539 | if(tuners_found > 1) | ||
540 | for (i = 0; i < tuners_found; i++) { | ||
541 | msg.addr = tuner_addrs & 0xff; | ||
542 | ret = i2c_transfer(c->adapter, &msg, 1); | ||
543 | if(ret == 1) | ||
544 | tuner_addrs = tuner_addrs >> 8; | ||
545 | else | ||
546 | break; | ||
547 | } | ||
548 | if (tuner_addrs == 0) { | ||
549 | tuner_addrs = 0x61; | ||
550 | tuner_info ("could not clearly identify tuner address, defaulting to %x\n", | ||
551 | tuner_addrs); | ||
552 | } else { | ||
553 | tuner_addrs = tuner_addrs & 0xff; | ||
554 | tuner_info ("setting tuner address to %x\n", tuner_addrs); | ||
555 | } | ||
556 | t->tda827x_addr = tuner_addrs; | ||
557 | msg.addr = tuner_addrs; | ||
558 | |||
559 | tda8290_i2c_bridge(c, 1); | ||
560 | ret = i2c_transfer(c->adapter, &msg, 1); | ||
561 | if( ret != 1) | ||
562 | tuner_warn ("TDA827x access failed!\n"); | ||
563 | if ((data & 0x3c) == 0) { | ||
564 | strlcpy(c->name, "tda8290+75", sizeof(c->name)); | ||
565 | t->tda827x_ver = 0; | ||
566 | } else { | ||
567 | strlcpy(c->name, "tda8290+75a", sizeof(c->name)); | ||
568 | t->tda827x_ver = 2; | ||
569 | } | ||
229 | tuner_info("tuner: type set to %s\n", c->name); | 570 | tuner_info("tuner: type set to %s\n", c->name); |
571 | |||
230 | t->tv_freq = set_tv_freq; | 572 | t->tv_freq = set_tv_freq; |
231 | t->radio_freq = set_radio_freq; | 573 | t->radio_freq = set_radio_freq; |
232 | t->has_signal = has_signal; | 574 | t->has_signal = has_signal; |
233 | t->standby = standby; | 575 | t->standby = standby; |
576 | t->tda827x_lpsel = 0; | ||
234 | 577 | ||
235 | i2c_master_send(c, i2c_enable_bridge, ARRAY_SIZE(i2c_enable_bridge)); | 578 | tda8290_init_tuner(c); |
236 | i2c_transfer(c->adapter, i2c_msg_init, ARRAY_SIZE(i2c_msg_init)); | 579 | tda8290_init_if(c); |
237 | return 0; | 580 | return 0; |
238 | } | 581 | } |
239 | 582 | ||
583 | int tda8290_probe(struct i2c_client *c) | ||
584 | { | ||
585 | unsigned char soft_reset[] = { 0x00, 0x00 }; | ||
586 | unsigned char easy_mode_b[] = { 0x01, 0x02 }; | ||
587 | unsigned char easy_mode_g[] = { 0x01, 0x04 }; | ||
588 | unsigned char addr_dto_lsb = 0x07; | ||
589 | unsigned char data; | ||
590 | |||
591 | i2c_master_send(c, easy_mode_b, 2); | ||
592 | i2c_master_send(c, soft_reset, 2); | ||
593 | i2c_master_send(c, &addr_dto_lsb, 1); | ||
594 | i2c_master_recv(c, &data, 1); | ||
595 | if (data == 0) { | ||
596 | i2c_master_send(c, easy_mode_g, 2); | ||
597 | i2c_master_send(c, soft_reset, 2); | ||
598 | i2c_master_send(c, &addr_dto_lsb, 1); | ||
599 | i2c_master_recv(c, &data, 1); | ||
600 | if (data == 0x7b) { | ||
601 | return 0; | ||
602 | } | ||
603 | } | ||
604 | return -1; | ||
605 | } | ||
606 | |||
240 | /* | 607 | /* |
241 | * Overrides for Emacs so that we follow Linus's tabbing style. | 608 | * Overrides for Emacs so that we follow Linus's tabbing style. |
242 | * --------------------------------------------------------------------------- | 609 | * --------------------------------------------------------------------------- |
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 7e3dcdb262b0..a5e37dc91f39 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c | |||
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | #include "bttv.h" | 33 | #include "bttv.h" |
34 | #include <media/audiochip.h> | 34 | #include <media/audiochip.h> |
35 | #include <media/id.h> | ||
36 | 35 | ||
37 | static int debug; /* insmod parameter */ | 36 | static int debug; /* insmod parameter */ |
38 | module_param(debug, int, S_IRUGO | S_IWUSR); | 37 | module_param(debug, int, S_IRUGO | S_IWUSR); |
@@ -126,20 +125,20 @@ static int tda9875_write(struct i2c_client *client, int subaddr, unsigned char v | |||
126 | 125 | ||
127 | static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg) | 126 | static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg) |
128 | { | 127 | { |
129 | unsigned char write[1]; | 128 | unsigned char write[1]; |
130 | unsigned char read[1]; | 129 | unsigned char read[1]; |
131 | struct i2c_msg msgs[2] = { | 130 | struct i2c_msg msgs[2] = { |
132 | { addr, 0, 1, write }, | 131 | { addr, 0, 1, write }, |
133 | { addr, I2C_M_RD, 1, read } | 132 | { addr, I2C_M_RD, 1, read } |
134 | }; | 133 | }; |
135 | write[0] = reg; | 134 | write[0] = reg; |
136 | 135 | ||
137 | if (2 != i2c_transfer(adap,msgs,2)) { | 136 | if (2 != i2c_transfer(adap,msgs,2)) { |
138 | printk(KERN_WARNING "tda9875: I/O error (read2)\n"); | 137 | printk(KERN_WARNING "tda9875: I/O error (read2)\n"); |
139 | return -1; | 138 | return -1; |
140 | } | 139 | } |
141 | dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]); | 140 | dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]); |
142 | return read[0]; | 141 | return read[0]; |
143 | } | 142 | } |
144 | 143 | ||
145 | static void tda9875_set(struct i2c_client *client) | 144 | static void tda9875_set(struct i2c_client *client) |
@@ -184,7 +183,7 @@ static void do_tda9875_init(struct i2c_client *client) | |||
184 | tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/ | 183 | tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/ |
185 | tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/ | 184 | tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/ |
186 | tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/ | 185 | tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/ |
187 | tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */ | 186 | tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */ |
188 | tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */ | 187 | tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */ |
189 | tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */ | 188 | tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */ |
190 | tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/ | 189 | tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/ |
@@ -200,7 +199,7 @@ static void do_tda9875_init(struct i2c_client *client) | |||
200 | 199 | ||
201 | t->mode=AUDIO_UNMUTE; | 200 | t->mode=AUDIO_UNMUTE; |
202 | t->lvol=t->rvol =0; /* 0dB */ | 201 | t->lvol=t->rvol =0; /* 0dB */ |
203 | t->bass=0; /* 0dB */ | 202 | t->bass=0; /* 0dB */ |
204 | t->treble=0; /* 0dB */ | 203 | t->treble=0; /* 0dB */ |
205 | tda9875_set(client); | 204 | tda9875_set(client); |
206 | 205 | ||
@@ -239,9 +238,9 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind) | |||
239 | memset(t,0,sizeof *t); | 238 | memset(t,0,sizeof *t); |
240 | 239 | ||
241 | client = &t->c; | 240 | client = &t->c; |
242 | memcpy(client,&client_template,sizeof(struct i2c_client)); | 241 | memcpy(client,&client_template,sizeof(struct i2c_client)); |
243 | client->adapter = adap; | 242 | client->adapter = adap; |
244 | client->addr = addr; | 243 | client->addr = addr; |
245 | i2c_set_clientdata(client, t); | 244 | i2c_set_clientdata(client, t); |
246 | 245 | ||
247 | if(!tda9875_checkit(adap,addr)) { | 246 | if(!tda9875_checkit(adap,addr)) { |
@@ -287,7 +286,7 @@ static int tda9875_command(struct i2c_client *client, | |||
287 | dprintk("In tda9875_command...\n"); | 286 | dprintk("In tda9875_command...\n"); |
288 | 287 | ||
289 | switch (cmd) { | 288 | switch (cmd) { |
290 | /* --- v4l ioctls --- */ | 289 | /* --- v4l ioctls --- */ |
291 | /* take care: bttv does userspace copying, we'll get a | 290 | /* take care: bttv does userspace copying, we'll get a |
292 | kernel pointer here... */ | 291 | kernel pointer here... */ |
293 | case VIDIOCGAUDIO: | 292 | case VIDIOCGAUDIO: |
@@ -355,7 +354,7 @@ static int tda9875_command(struct i2c_client *client, | |||
355 | //printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble); | 354 | //printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble); |
356 | 355 | ||
357 | 356 | ||
358 | tda9875_set(client); | 357 | tda9875_set(client); |
359 | 358 | ||
360 | break; | 359 | break; |
361 | 360 | ||
@@ -374,18 +373,18 @@ static int tda9875_command(struct i2c_client *client, | |||
374 | 373 | ||
375 | static struct i2c_driver driver = { | 374 | static struct i2c_driver driver = { |
376 | .owner = THIS_MODULE, | 375 | .owner = THIS_MODULE, |
377 | .name = "i2c tda9875 driver", | 376 | .name = "i2c tda9875 driver", |
378 | .id = I2C_DRIVERID_TDA9875, | 377 | .id = I2C_DRIVERID_TDA9875, |
379 | .flags = I2C_DF_NOTIFY, | 378 | .flags = I2C_DF_NOTIFY, |
380 | .attach_adapter = tda9875_probe, | 379 | .attach_adapter = tda9875_probe, |
381 | .detach_client = tda9875_detach, | 380 | .detach_client = tda9875_detach, |
382 | .command = tda9875_command, | 381 | .command = tda9875_command, |
383 | }; | 382 | }; |
384 | 383 | ||
385 | static struct i2c_client client_template = | 384 | static struct i2c_client client_template = |
386 | { | 385 | { |
387 | .name = "tda9875", | 386 | .name = "tda9875", |
388 | .driver = &driver, | 387 | .driver = &driver, |
389 | }; | 388 | }; |
390 | 389 | ||
391 | static int __init tda9875_init(void) | 390 | static int __init tda9875_init(void) |
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 94053f149ddf..4249127c0a1d 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | #include <media/audiochip.h> | 12 | #include <media/audiochip.h> |
13 | #include <media/tuner.h> | 13 | #include <media/tuner.h> |
14 | #include <media/id.h> | ||
15 | 14 | ||
16 | /* Chips: | 15 | /* Chips: |
17 | TDA9885 (PAL, NTSC) | 16 | TDA9885 (PAL, NTSC) |
@@ -44,8 +43,13 @@ MODULE_LICENSE("GPL"); | |||
44 | /* ---------------------------------------------------------------------- */ | 43 | /* ---------------------------------------------------------------------- */ |
45 | 44 | ||
46 | #define UNSET (-1U) | 45 | #define UNSET (-1U) |
47 | #define PREFIX "tda9885/6/7: " | 46 | #define tda9887_info(fmt, arg...) do {\ |
48 | #define dprintk if (debug) printk | 47 | printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \ |
48 | i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0) | ||
49 | #define tda9887_dbg(fmt, arg...) do {\ | ||
50 | if (debug) \ | ||
51 | printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \ | ||
52 | i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0) | ||
49 | 53 | ||
50 | struct tda9887 { | 54 | struct tda9887 { |
51 | struct i2c_client client; | 55 | struct i2c_client client; |
@@ -55,6 +59,7 @@ struct tda9887 { | |||
55 | unsigned int pinnacle_id; | 59 | unsigned int pinnacle_id; |
56 | unsigned int using_v4l2; | 60 | unsigned int using_v4l2; |
57 | unsigned int radio_mode; | 61 | unsigned int radio_mode; |
62 | unsigned char data[4]; | ||
58 | }; | 63 | }; |
59 | 64 | ||
60 | struct tvnorm { | 65 | struct tvnorm { |
@@ -180,7 +185,8 @@ static struct tvnorm tvnorms[] = { | |||
180 | .name = "SECAM-L", | 185 | .name = "SECAM-L", |
181 | .b = ( cPositiveAmTV | | 186 | .b = ( cPositiveAmTV | |
182 | cQSS ), | 187 | cQSS ), |
183 | .e = ( cAudioIF_6_5 | | 188 | .e = ( cGating_36 | |
189 | cAudioIF_6_5 | | ||
184 | cVideoIF_38_90 ), | 190 | cVideoIF_38_90 ), |
185 | },{ | 191 | },{ |
186 | .std = V4L2_STD_SECAM_DK, | 192 | .std = V4L2_STD_SECAM_DK, |
@@ -236,7 +242,7 @@ static struct tvnorm radio_mono = { | |||
236 | 242 | ||
237 | /* ---------------------------------------------------------------------- */ | 243 | /* ---------------------------------------------------------------------- */ |
238 | 244 | ||
239 | static void dump_read_message(unsigned char *buf) | 245 | static void dump_read_message(struct tda9887 *t, unsigned char *buf) |
240 | { | 246 | { |
241 | static char *afc[16] = { | 247 | static char *afc[16] = { |
242 | "- 12.5 kHz", | 248 | "- 12.5 kHz", |
@@ -256,15 +262,15 @@ static void dump_read_message(unsigned char *buf) | |||
256 | "+ 37.5 kHz", | 262 | "+ 37.5 kHz", |
257 | "+ 12.5 kHz", | 263 | "+ 12.5 kHz", |
258 | }; | 264 | }; |
259 | printk(PREFIX "read: 0x%2x\n", buf[0]); | 265 | tda9887_info("read: 0x%2x\n", buf[0]); |
260 | printk(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no"); | 266 | tda9887_info(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no"); |
261 | printk(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]); | 267 | tda9887_info(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]); |
262 | printk(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low"); | 268 | tda9887_info(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low"); |
263 | printk(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out"); | 269 | tda9887_info(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out"); |
264 | printk(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low"); | 270 | tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low"); |
265 | } | 271 | } |
266 | 272 | ||
267 | static void dump_write_message(unsigned char *buf) | 273 | static void dump_write_message(struct tda9887 *t, unsigned char *buf) |
268 | { | 274 | { |
269 | static char *sound[4] = { | 275 | static char *sound[4] = { |
270 | "AM/TV", | 276 | "AM/TV", |
@@ -304,58 +310,58 @@ static void dump_write_message(unsigned char *buf) | |||
304 | "44 MHz", | 310 | "44 MHz", |
305 | }; | 311 | }; |
306 | 312 | ||
307 | printk(PREFIX "write: byte B 0x%02x\n",buf[1]); | 313 | tda9887_info("write: byte B 0x%02x\n",buf[1]); |
308 | printk(" B0 video mode : %s\n", | 314 | tda9887_info(" B0 video mode : %s\n", |
309 | (buf[1] & 0x01) ? "video trap" : "sound trap"); | 315 | (buf[1] & 0x01) ? "video trap" : "sound trap"); |
310 | printk(" B1 auto mute fm : %s\n", | 316 | tda9887_info(" B1 auto mute fm : %s\n", |
311 | (buf[1] & 0x02) ? "yes" : "no"); | 317 | (buf[1] & 0x02) ? "yes" : "no"); |
312 | printk(" B2 carrier mode : %s\n", | 318 | tda9887_info(" B2 carrier mode : %s\n", |
313 | (buf[1] & 0x04) ? "QSS" : "Intercarrier"); | 319 | (buf[1] & 0x04) ? "QSS" : "Intercarrier"); |
314 | printk(" B3-4 tv sound/radio : %s\n", | 320 | tda9887_info(" B3-4 tv sound/radio : %s\n", |
315 | sound[(buf[1] & 0x18) >> 3]); | 321 | sound[(buf[1] & 0x18) >> 3]); |
316 | printk(" B5 force mute audio: %s\n", | 322 | tda9887_info(" B5 force mute audio: %s\n", |
317 | (buf[1] & 0x20) ? "yes" : "no"); | 323 | (buf[1] & 0x20) ? "yes" : "no"); |
318 | printk(" B6 output port 1 : %s\n", | 324 | tda9887_info(" B6 output port 1 : %s\n", |
319 | (buf[1] & 0x40) ? "high (inactive)" : "low (active)"); | 325 | (buf[1] & 0x40) ? "high (inactive)" : "low (active)"); |
320 | printk(" B7 output port 2 : %s\n", | 326 | tda9887_info(" B7 output port 2 : %s\n", |
321 | (buf[1] & 0x80) ? "high (inactive)" : "low (active)"); | 327 | (buf[1] & 0x80) ? "high (inactive)" : "low (active)"); |
322 | 328 | ||
323 | printk(PREFIX "write: byte C 0x%02x\n",buf[2]); | 329 | tda9887_info("write: byte C 0x%02x\n",buf[2]); |
324 | printk(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]); | 330 | tda9887_info(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]); |
325 | printk(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]); | 331 | tda9887_info(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]); |
326 | printk(" C7 audio gain : %s\n", | 332 | tda9887_info(" C7 audio gain : %s\n", |
327 | (buf[2] & 0x80) ? "-6" : "0"); | 333 | (buf[2] & 0x80) ? "-6" : "0"); |
328 | 334 | ||
329 | printk(PREFIX "write: byte E 0x%02x\n",buf[3]); | 335 | tda9887_info("write: byte E 0x%02x\n",buf[3]); |
330 | printk(" E0-1 sound carrier : %s\n", | 336 | tda9887_info(" E0-1 sound carrier : %s\n", |
331 | carrier[(buf[3] & 0x03)]); | 337 | carrier[(buf[3] & 0x03)]); |
332 | printk(" E6 l pll ganting : %s\n", | 338 | tda9887_info(" E6 l pll gating : %s\n", |
333 | (buf[3] & 0x40) ? "36" : "13"); | 339 | (buf[3] & 0x40) ? "36" : "13"); |
334 | 340 | ||
335 | if (buf[1] & 0x08) { | 341 | if (buf[1] & 0x08) { |
336 | /* radio */ | 342 | /* radio */ |
337 | printk(" E2-4 video if : %s\n", | 343 | tda9887_info(" E2-4 video if : %s\n", |
338 | rif[(buf[3] & 0x0c) >> 2]); | 344 | rif[(buf[3] & 0x0c) >> 2]); |
339 | printk(" E7 vif agc output : %s\n", | 345 | tda9887_info(" E7 vif agc output : %s\n", |
340 | (buf[3] & 0x80) | 346 | (buf[3] & 0x80) |
341 | ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio") | 347 | ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio") |
342 | : "fm radio carrier afc"); | 348 | : "fm radio carrier afc"); |
343 | } else { | 349 | } else { |
344 | /* video */ | 350 | /* video */ |
345 | printk(" E2-4 video if : %s\n", | 351 | tda9887_info(" E2-4 video if : %s\n", |
346 | vif[(buf[3] & 0x1c) >> 2]); | 352 | vif[(buf[3] & 0x1c) >> 2]); |
347 | printk(" E5 tuner gain : %s\n", | 353 | tda9887_info(" E5 tuner gain : %s\n", |
348 | (buf[3] & 0x80) | 354 | (buf[3] & 0x80) |
349 | ? ((buf[3] & 0x20) ? "external" : "normal") | 355 | ? ((buf[3] & 0x20) ? "external" : "normal") |
350 | : ((buf[3] & 0x20) ? "minimum" : "normal")); | 356 | : ((buf[3] & 0x20) ? "minimum" : "normal")); |
351 | printk(" E7 vif agc output : %s\n", | 357 | tda9887_info(" E7 vif agc output : %s\n", |
352 | (buf[3] & 0x80) | 358 | (buf[3] & 0x80) |
353 | ? ((buf[3] & 0x20) | 359 | ? ((buf[3] & 0x20) |
354 | ? "pin3 port, pin22 vif agc out" | 360 | ? "pin3 port, pin22 vif agc out" |
355 | : "pin22 port, pin3 vif acg ext in") | 361 | : "pin22 port, pin3 vif acg ext in") |
356 | : "pin3+pin22 port"); | 362 | : "pin3+pin22 port"); |
357 | } | 363 | } |
358 | printk("--\n"); | 364 | tda9887_info("--\n"); |
359 | } | 365 | } |
360 | 366 | ||
361 | /* ---------------------------------------------------------------------- */ | 367 | /* ---------------------------------------------------------------------- */ |
@@ -379,11 +385,11 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) | |||
379 | } | 385 | } |
380 | } | 386 | } |
381 | if (NULL == norm) { | 387 | if (NULL == norm) { |
382 | dprintk(PREFIX "Unsupported tvnorm entry - audio muted\n"); | 388 | tda9887_dbg("Unsupported tvnorm entry - audio muted\n"); |
383 | return -1; | 389 | return -1; |
384 | } | 390 | } |
385 | 391 | ||
386 | dprintk(PREFIX "configure for: %s\n",norm->name); | 392 | tda9887_dbg("configure for: %s\n",norm->name); |
387 | buf[1] = norm->b; | 393 | buf[1] = norm->b; |
388 | buf[2] = norm->c; | 394 | buf[2] = norm->c; |
389 | buf[3] = norm->e; | 395 | buf[3] = norm->e; |
@@ -458,6 +464,8 @@ static int tda9887_set_config(struct tda9887 *t, char *buf) | |||
458 | break; | 464 | break; |
459 | } | 465 | } |
460 | } | 466 | } |
467 | if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) | ||
468 | buf[1] &= ~cQSS; | ||
461 | return 0; | 469 | return 0; |
462 | } | 470 | } |
463 | 471 | ||
@@ -475,11 +483,11 @@ static int tda9887_set_pinnacle(struct tda9887 *t, char *buf) | |||
475 | } | 483 | } |
476 | } | 484 | } |
477 | if (t->std & V4L2_STD_525_60) { | 485 | if (t->std & V4L2_STD_525_60) { |
478 | if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) { | 486 | if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) { |
479 | bCarrierMode = cIntercarrier; | 487 | bCarrierMode = cIntercarrier; |
480 | } else { | 488 | } else { |
481 | bCarrierMode = cQSS; | 489 | bCarrierMode = cQSS; |
482 | } | 490 | } |
483 | } | 491 | } |
484 | 492 | ||
485 | if (bCarrierMode != UNSET) { | 493 | if (bCarrierMode != UNSET) { |
@@ -505,26 +513,26 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
505 | case 'B': | 513 | case 'B': |
506 | case 'g': | 514 | case 'g': |
507 | case 'G': | 515 | case 'G': |
508 | dprintk(PREFIX "insmod fixup: PAL => PAL-BG\n"); | 516 | tda9887_dbg("insmod fixup: PAL => PAL-BG\n"); |
509 | t->std = V4L2_STD_PAL_BG; | 517 | t->std = V4L2_STD_PAL_BG; |
510 | break; | 518 | break; |
511 | case 'i': | 519 | case 'i': |
512 | case 'I': | 520 | case 'I': |
513 | dprintk(PREFIX "insmod fixup: PAL => PAL-I\n"); | 521 | tda9887_dbg("insmod fixup: PAL => PAL-I\n"); |
514 | t->std = V4L2_STD_PAL_I; | 522 | t->std = V4L2_STD_PAL_I; |
515 | break; | 523 | break; |
516 | case 'd': | 524 | case 'd': |
517 | case 'D': | 525 | case 'D': |
518 | case 'k': | 526 | case 'k': |
519 | case 'K': | 527 | case 'K': |
520 | dprintk(PREFIX "insmod fixup: PAL => PAL-DK\n"); | 528 | tda9887_dbg("insmod fixup: PAL => PAL-DK\n"); |
521 | t->std = V4L2_STD_PAL_DK; | 529 | t->std = V4L2_STD_PAL_DK; |
522 | break; | 530 | break; |
523 | case '-': | 531 | case '-': |
524 | /* default parameter, do nothing */ | 532 | /* default parameter, do nothing */ |
525 | break; | 533 | break; |
526 | default: | 534 | default: |
527 | printk(PREFIX "pal= argument not recognised\n"); | 535 | tda9887_info("pal= argument not recognised\n"); |
528 | break; | 536 | break; |
529 | } | 537 | } |
530 | } | 538 | } |
@@ -534,19 +542,19 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
534 | case 'D': | 542 | case 'D': |
535 | case 'k': | 543 | case 'k': |
536 | case 'K': | 544 | case 'K': |
537 | dprintk(PREFIX "insmod fixup: SECAM => SECAM-DK\n"); | 545 | tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n"); |
538 | t->std = V4L2_STD_SECAM_DK; | 546 | t->std = V4L2_STD_SECAM_DK; |
539 | break; | 547 | break; |
540 | case 'l': | 548 | case 'l': |
541 | case 'L': | 549 | case 'L': |
542 | dprintk(PREFIX "insmod fixup: SECAM => SECAM-L\n"); | 550 | tda9887_dbg("insmod fixup: SECAM => SECAM-L\n"); |
543 | t->std = V4L2_STD_SECAM_L; | 551 | t->std = V4L2_STD_SECAM_L; |
544 | break; | 552 | break; |
545 | case '-': | 553 | case '-': |
546 | /* default parameter, do nothing */ | 554 | /* default parameter, do nothing */ |
547 | break; | 555 | break; |
548 | default: | 556 | default: |
549 | printk(PREFIX "secam= argument not recognised\n"); | 557 | tda9887_info("secam= argument not recognised\n"); |
550 | break; | 558 | break; |
551 | } | 559 | } |
552 | } | 560 | } |
@@ -559,41 +567,40 @@ static int tda9887_status(struct tda9887 *t) | |||
559 | int rc; | 567 | int rc; |
560 | 568 | ||
561 | memset(buf,0,sizeof(buf)); | 569 | memset(buf,0,sizeof(buf)); |
562 | if (1 != (rc = i2c_master_recv(&t->client,buf,1))) | 570 | if (1 != (rc = i2c_master_recv(&t->client,buf,1))) |
563 | printk(PREFIX "i2c i/o error: rc == %d (should be 1)\n",rc); | 571 | tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc); |
564 | dump_read_message(buf); | 572 | dump_read_message(t, buf); |
565 | return 0; | 573 | return 0; |
566 | } | 574 | } |
567 | 575 | ||
568 | static int tda9887_configure(struct tda9887 *t) | 576 | static int tda9887_configure(struct tda9887 *t) |
569 | { | 577 | { |
570 | unsigned char buf[4]; | ||
571 | int rc; | 578 | int rc; |
572 | 579 | ||
573 | memset(buf,0,sizeof(buf)); | 580 | memset(t->data,0,sizeof(t->data)); |
574 | tda9887_set_tvnorm(t,buf); | 581 | tda9887_set_tvnorm(t,t->data); |
575 | 582 | ||
576 | buf[1] |= cOutputPort1Inactive; | 583 | t->data[1] |= cOutputPort1Inactive; |
577 | buf[1] |= cOutputPort2Inactive; | 584 | t->data[1] |= cOutputPort2Inactive; |
578 | 585 | ||
579 | if (UNSET != t->pinnacle_id) { | 586 | if (UNSET != t->pinnacle_id) { |
580 | tda9887_set_pinnacle(t,buf); | 587 | tda9887_set_pinnacle(t,t->data); |
581 | } | 588 | } |
582 | tda9887_set_config(t,buf); | 589 | tda9887_set_config(t,t->data); |
583 | tda9887_set_insmod(t,buf); | 590 | tda9887_set_insmod(t,t->data); |
584 | 591 | ||
585 | if (t->mode == T_STANDBY) { | 592 | if (t->mode == T_STANDBY) { |
586 | buf[1] |= cForcedMuteAudioON; | 593 | t->data[1] |= cForcedMuteAudioON; |
587 | } | 594 | } |
588 | 595 | ||
589 | 596 | ||
590 | dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n", | 597 | tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", |
591 | buf[1],buf[2],buf[3]); | 598 | t->data[1],t->data[2],t->data[3]); |
592 | if (debug > 1) | 599 | if (debug > 1) |
593 | dump_write_message(buf); | 600 | dump_write_message(t, t->data); |
594 | 601 | ||
595 | if (4 != (rc = i2c_master_send(&t->client,buf,4))) | 602 | if (4 != (rc = i2c_master_send(&t->client,t->data,4))) |
596 | printk(PREFIX "i2c i/o error: rc == %d (should be 4)\n",rc); | 603 | tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc); |
597 | 604 | ||
598 | if (debug > 2) { | 605 | if (debug > 2) { |
599 | msleep_interruptible(1000); | 606 | msleep_interruptible(1000); |
@@ -608,13 +615,11 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) | |||
608 | { | 615 | { |
609 | struct tda9887 *t; | 616 | struct tda9887 *t; |
610 | 617 | ||
611 | client_template.adapter = adap; | 618 | client_template.adapter = adap; |
612 | client_template.addr = addr; | 619 | client_template.addr = addr; |
613 | |||
614 | printk(PREFIX "chip found @ 0x%x\n", addr<<1); | ||
615 | 620 | ||
616 | if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) | 621 | if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) |
617 | return -ENOMEM; | 622 | return -ENOMEM; |
618 | memset(t,0,sizeof(*t)); | 623 | memset(t,0,sizeof(*t)); |
619 | 624 | ||
620 | t->client = client_template; | 625 | t->client = client_template; |
@@ -622,6 +627,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) | |||
622 | t->pinnacle_id = UNSET; | 627 | t->pinnacle_id = UNSET; |
623 | t->radio_mode = V4L2_TUNER_MODE_STEREO; | 628 | t->radio_mode = V4L2_TUNER_MODE_STEREO; |
624 | 629 | ||
630 | tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name); | ||
631 | |||
625 | i2c_set_clientdata(&t->client, t); | 632 | i2c_set_clientdata(&t->client, t); |
626 | i2c_attach_client(&t->client); | 633 | i2c_attach_client(&t->client); |
627 | 634 | ||
@@ -655,18 +662,18 @@ static int tda9887_detach(struct i2c_client *client) | |||
655 | } | 662 | } |
656 | 663 | ||
657 | #define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ | 664 | #define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ |
658 | printk(PREFIX "switching to v4l2\n"); \ | 665 | tda9887_info("switching to v4l2\n"); \ |
659 | t->using_v4l2 = 1; | 666 | t->using_v4l2 = 1; |
660 | #define CHECK_V4L2 if (t->using_v4l2) { if (debug) \ | 667 | #define CHECK_V4L2 if (t->using_v4l2) { if (debug) \ |
661 | printk(PREFIX "ignore v4l1 call\n"); \ | 668 | tda9887_info("ignore v4l1 call\n"); \ |
662 | return 0; } | 669 | return 0; } |
663 | 670 | ||
664 | static int | 671 | static int |
665 | tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) | 672 | tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) |
666 | { | 673 | { |
667 | struct tda9887 *t = i2c_get_clientdata(client); | 674 | struct tda9887 *t = i2c_get_clientdata(client); |
668 | 675 | ||
669 | switch (cmd) { | 676 | switch (cmd) { |
670 | 677 | ||
671 | /* --- configuration --- */ | 678 | /* --- configuration --- */ |
672 | case AUDC_SET_RADIO: | 679 | case AUDC_SET_RADIO: |
@@ -777,6 +784,11 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
777 | } | 784 | } |
778 | break; | 785 | break; |
779 | } | 786 | } |
787 | case VIDIOC_LOG_STATUS: | ||
788 | { | ||
789 | tda9887_info("Data bytes: b=%02x c=%02x e=%02x\n", t->data[1], t->data[2], t->data[3]); | ||
790 | break; | ||
791 | } | ||
780 | default: | 792 | default: |
781 | /* nothing */ | 793 | /* nothing */ |
782 | break; | 794 | break; |
@@ -786,7 +798,10 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
786 | 798 | ||
787 | static int tda9887_suspend(struct device * dev, pm_message_t state) | 799 | static int tda9887_suspend(struct device * dev, pm_message_t state) |
788 | { | 800 | { |
789 | dprintk("tda9887: suspend\n"); | 801 | struct i2c_client *c = container_of(dev, struct i2c_client, dev); |
802 | struct tda9887 *t = i2c_get_clientdata(c); | ||
803 | |||
804 | tda9887_dbg("suspend\n"); | ||
790 | return 0; | 805 | return 0; |
791 | } | 806 | } |
792 | 807 | ||
@@ -795,7 +810,7 @@ static int tda9887_resume(struct device * dev) | |||
795 | struct i2c_client *c = container_of(dev, struct i2c_client, dev); | 810 | struct i2c_client *c = container_of(dev, struct i2c_client, dev); |
796 | struct tda9887 *t = i2c_get_clientdata(c); | 811 | struct tda9887 *t = i2c_get_clientdata(c); |
797 | 812 | ||
798 | dprintk("tda9887: resume\n"); | 813 | tda9887_dbg("resume\n"); |
799 | tda9887_configure(t); | 814 | tda9887_configure(t); |
800 | return 0; | 815 | return 0; |
801 | } | 816 | } |
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c index 38bf50943798..a9375ef05de1 100644 --- a/drivers/media/video/tea5767.c +++ b/drivers/media/video/tea5767.c | |||
@@ -117,10 +117,10 @@ | |||
117 | #define TEA5767_RESERVED_MASK 0xff | 117 | #define TEA5767_RESERVED_MASK 0xff |
118 | 118 | ||
119 | enum tea5767_xtal_freq { | 119 | enum tea5767_xtal_freq { |
120 | TEA5767_LOW_LO_32768 = 0, | 120 | TEA5767_LOW_LO_32768 = 0, |
121 | TEA5767_HIGH_LO_32768 = 1, | 121 | TEA5767_HIGH_LO_32768 = 1, |
122 | TEA5767_LOW_LO_13MHz = 2, | 122 | TEA5767_LOW_LO_13MHz = 2, |
123 | TEA5767_HIGH_LO_13MHz = 3, | 123 | TEA5767_HIGH_LO_13MHz = 3, |
124 | }; | 124 | }; |
125 | 125 | ||
126 | 126 | ||
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index ad85bef1c3d5..73c4041c35d7 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | /* standard i2c insmod options */ | 29 | /* standard i2c insmod options */ |
30 | static unsigned short normal_i2c[] = { | 30 | static unsigned short normal_i2c[] = { |
31 | 0x4b, /* tda8290 */ | 31 | 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */ |
32 | 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, | 32 | 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, |
33 | 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, | 33 | 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, |
34 | I2C_CLIENT_END | 34 | I2C_CLIENT_END |
@@ -189,6 +189,13 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
189 | i2c_master_send(c, buffer, 4); | 189 | i2c_master_send(c, buffer, 4); |
190 | default_tuner_init(c); | 190 | default_tuner_init(c); |
191 | break; | 191 | break; |
192 | case TUNER_PHILIPS_TD1316: | ||
193 | buffer[0] = 0x0b; | ||
194 | buffer[1] = 0xdc; | ||
195 | buffer[2] = 0x86; | ||
196 | buffer[3] = 0xa4; | ||
197 | i2c_master_send(c,buffer,4); | ||
198 | default_tuner_init(c); | ||
192 | default: | 199 | default: |
193 | default_tuner_init(c); | 200 | default_tuner_init(c); |
194 | break; | 201 | break; |
@@ -215,9 +222,9 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup) | |||
215 | { | 222 | { |
216 | struct tuner *t = i2c_get_clientdata(c); | 223 | struct tuner *t = i2c_get_clientdata(c); |
217 | 224 | ||
218 | if ((tun_setup->addr == ADDR_UNSET && | 225 | if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET && |
219 | (t->mode_mask & tun_setup->mode_mask)) || | 226 | (t->mode_mask & tun_setup->mode_mask)) || |
220 | tun_setup->addr == c->addr) { | 227 | tun_setup->addr == c->addr)) { |
221 | set_type(c, tun_setup->type, tun_setup->mode_mask); | 228 | set_type(c, tun_setup->type, tun_setup->mode_mask); |
222 | } | 229 | } |
223 | } | 230 | } |
@@ -341,23 +348,33 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
341 | t->audmode = V4L2_TUNER_MODE_STEREO; | 348 | t->audmode = V4L2_TUNER_MODE_STEREO; |
342 | t->mode_mask = T_UNINITIALIZED; | 349 | t->mode_mask = T_UNINITIALIZED; |
343 | 350 | ||
344 | |||
345 | tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name); | ||
346 | |||
347 | if (show_i2c) { | 351 | if (show_i2c) { |
348 | unsigned char buffer[16]; | 352 | unsigned char buffer[16]; |
349 | int i,rc; | 353 | int i,rc; |
350 | 354 | ||
351 | memset(buffer, 0, sizeof(buffer)); | 355 | memset(buffer, 0, sizeof(buffer)); |
352 | rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer)); | 356 | rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer)); |
353 | printk("tuner-%04x I2C RECV = ",addr); | 357 | tuner_info("I2C RECV = "); |
354 | for (i=0;i<rc;i++) | 358 | for (i=0;i<rc;i++) |
355 | printk("%02x ",buffer[i]); | 359 | printk("%02x ",buffer[i]); |
356 | printk("\n"); | 360 | printk("\n"); |
357 | } | 361 | } |
358 | /* TEA5767 autodetection code - only for addr = 0xc0 */ | 362 | /* TEA5767 autodetection code - only for addr = 0xc0 */ |
359 | if (!no_autodetect) { | 363 | if (!no_autodetect) { |
360 | if (addr == 0x60) { | 364 | switch (addr) { |
365 | case 0x42: | ||
366 | case 0x43: | ||
367 | case 0x4a: | ||
368 | case 0x4b: | ||
369 | /* If chip is not tda8290, don't register. | ||
370 | since it can be tda9887*/ | ||
371 | if (tda8290_probe(&t->i2c) != 0) { | ||
372 | tuner_dbg("chip at addr %x is not a tda8290\n", addr); | ||
373 | kfree(t); | ||
374 | return 0; | ||
375 | } | ||
376 | break; | ||
377 | case 0x60: | ||
361 | if (tea5767_autodetection(&t->i2c) != EINVAL) { | 378 | if (tea5767_autodetection(&t->i2c) != EINVAL) { |
362 | t->type = TUNER_TEA5767; | 379 | t->type = TUNER_TEA5767; |
363 | t->mode_mask = T_RADIO; | 380 | t->mode_mask = T_RADIO; |
@@ -365,10 +382,9 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
365 | t->freq = 87.5 * 16; /* Sets freq to FM range */ | 382 | t->freq = 87.5 * 16; /* Sets freq to FM range */ |
366 | default_mode_mask &= ~T_RADIO; | 383 | default_mode_mask &= ~T_RADIO; |
367 | 384 | ||
368 | i2c_attach_client (&t->i2c); | 385 | goto register_client; |
369 | set_type(&t->i2c,t->type, t->mode_mask); | ||
370 | return 0; | ||
371 | } | 386 | } |
387 | break; | ||
372 | } | 388 | } |
373 | } | 389 | } |
374 | 390 | ||
@@ -381,6 +397,8 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
381 | } | 397 | } |
382 | 398 | ||
383 | /* Should be just before return */ | 399 | /* Should be just before return */ |
400 | register_client: | ||
401 | tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name); | ||
384 | i2c_attach_client (&t->i2c); | 402 | i2c_attach_client (&t->i2c); |
385 | set_type (&t->i2c,t->type, t->mode_mask); | 403 | set_type (&t->i2c,t->type, t->mode_mask); |
386 | return 0; | 404 | return 0; |
@@ -425,23 +443,23 @@ static int tuner_detach(struct i2c_client *client) | |||
425 | 443 | ||
426 | static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd) | 444 | static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd) |
427 | { | 445 | { |
428 | if (mode == t->mode) | 446 | if (mode == t->mode) |
429 | return 0; | 447 | return 0; |
430 | 448 | ||
431 | t->mode = mode; | 449 | t->mode = mode; |
432 | 450 | ||
433 | if (check_mode(t, cmd) == EINVAL) { | 451 | if (check_mode(t, cmd) == EINVAL) { |
434 | t->mode = T_STANDBY; | 452 | t->mode = T_STANDBY; |
435 | if (t->standby) | 453 | if (t->standby) |
436 | t->standby (client); | 454 | t->standby (client); |
437 | return EINVAL; | 455 | return EINVAL; |
438 | } | 456 | } |
439 | return 0; | 457 | return 0; |
440 | } | 458 | } |
441 | 459 | ||
442 | #define switch_v4l2() if (!t->using_v4l2) \ | 460 | #define switch_v4l2() if (!t->using_v4l2) \ |
443 | tuner_dbg("switching to v4l2\n"); \ | 461 | tuner_dbg("switching to v4l2\n"); \ |
444 | t->using_v4l2 = 1; | 462 | t->using_v4l2 = 1; |
445 | 463 | ||
446 | static inline int check_v4l2(struct tuner *t) | 464 | static inline int check_v4l2(struct tuner *t) |
447 | { | 465 | { |
@@ -479,8 +497,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
479 | break; | 497 | break; |
480 | } | 498 | } |
481 | case AUDC_CONFIG_PINNACLE: | 499 | case AUDC_CONFIG_PINNACLE: |
482 | if (check_mode(t, "AUDC_CONFIG_PINNACLE") == EINVAL) | ||
483 | return 0; | ||
484 | switch (*iarg) { | 500 | switch (*iarg) { |
485 | case 2: | 501 | case 2: |
486 | tuner_dbg("pinnacle pal\n"); | 502 | tuner_dbg("pinnacle pal\n"); |
@@ -616,7 +632,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
616 | switch_v4l2(); | 632 | switch_v4l2(); |
617 | if (V4L2_TUNER_RADIO == f->type && | 633 | if (V4L2_TUNER_RADIO == f->type && |
618 | V4L2_TUNER_RADIO != t->mode) { | 634 | V4L2_TUNER_RADIO != t->mode) { |
619 | if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") | 635 | if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") |
620 | == EINVAL) | 636 | == EINVAL) |
621 | return 0; | 637 | return 0; |
622 | } | 638 | } |
@@ -688,7 +704,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
688 | break; | 704 | break; |
689 | } | 705 | } |
690 | default: | 706 | default: |
691 | tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp=0x%02x,nr=%d,sz=%d)\n", | 707 | tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp='%c',nr=%d,sz=%d)\n", |
692 | cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd), | 708 | cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd), |
693 | _IOC_NR(cmd), _IOC_SIZE(cmd)); | 709 | _IOC_NR(cmd), _IOC_SIZE(cmd)); |
694 | break; | 710 | break; |
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index 8edd73abe1d8..d832205818f2 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c | |||
@@ -102,7 +102,7 @@ struct tunertype | |||
102 | */ | 102 | */ |
103 | static struct tunertype tuners[] = { | 103 | static struct tunertype tuners[] = { |
104 | /* 0-9 */ | 104 | /* 0-9 */ |
105 | { "Temic PAL (4002 FH5)", TEMIC, PAL, | 105 | { "Temic PAL (4002 FH5)", TEMIC, PAL, |
106 | 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623}, | 106 | 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623}, |
107 | { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I, | 107 | { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I, |
108 | 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, | 108 | 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, |
@@ -118,41 +118,41 @@ static struct tunertype tuners[] = { | |||
118 | 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732}, | 118 | 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732}, |
119 | { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I, | 119 | { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I, |
120 | 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623}, | 120 | 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623}, |
121 | { "Temic NTSC (4036 FY5)", TEMIC, NTSC, | 121 | { "Temic NTSC (4036 FY5)", TEMIC, NTSC, |
122 | 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732}, | 122 | 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732}, |
123 | { "Alps HSBH1", TEMIC, NTSC, | 123 | { "Alps HSBH1", TEMIC, NTSC, |
124 | 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, | 124 | 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, |
125 | 125 | ||
126 | /* 10-19 */ | 126 | /* 10-19 */ |
127 | { "Alps TSBE1", TEMIC, PAL, | 127 | { "Alps TSBE1", TEMIC, PAL, |
128 | 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, | 128 | 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, |
129 | { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */ | 129 | { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */ |
130 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632}, | 130 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632}, |
131 | { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ | 131 | { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ |
132 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622}, | 132 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622}, |
133 | { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ | 133 | { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ |
134 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608}, | 134 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608}, |
135 | { "Temic PAL_BG (4006FH5)", TEMIC, PAL, | 135 | { "Temic PAL_BG (4006FH5)", TEMIC, PAL, |
136 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | 136 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, |
137 | { "Alps TSCH6", Alps, NTSC, | 137 | { "Alps TSCH6", Alps, NTSC, |
138 | 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732}, | 138 | 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732}, |
139 | { "Temic PAL_DK (4016 FY5)", TEMIC, PAL, | 139 | { "Temic PAL_DK (4016 FY5)", TEMIC, PAL, |
140 | 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623}, | 140 | 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623}, |
141 | { "Philips NTSC_M (MK2)", Philips, NTSC, | 141 | { "Philips NTSC_M (MK2)", Philips, NTSC, |
142 | 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, | 142 | 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, |
143 | { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I, | 143 | { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I, |
144 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, | 144 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, |
145 | { "Temic PAL* auto (4006 FN5)", TEMIC, PAL, | 145 | { "Temic PAL* auto (4006 FN5)", TEMIC, PAL, |
146 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, | 146 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, |
147 | 147 | ||
148 | /* 20-29 */ | 148 | /* 20-29 */ |
149 | { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL, | 149 | { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL, |
150 | 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, | 150 | 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, |
151 | { "Temic NTSC (4039 FR5)", TEMIC, NTSC, | 151 | { "Temic NTSC (4039 FR5)", TEMIC, NTSC, |
152 | 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, | 152 | 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, |
153 | { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL, | 153 | { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL, |
154 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, | 154 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, |
155 | { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL, | 155 | { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL, |
156 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | 156 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, |
157 | { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL, | 157 | { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL, |
158 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | 158 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, |
@@ -173,21 +173,21 @@ static struct tunertype tuners[] = { | |||
173 | { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */ | 173 | { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */ |
174 | 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 }, | 174 | 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 }, |
175 | { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */ | 175 | { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */ |
176 | 16*169,16*464,0xA0,0x90,0x30,0x8e,623}, | 176 | 16*169,16*464,0xA0,0x90,0x30,0x8e,623}, |
177 | { "MT20xx universal", Microtune, PAL|NTSC, | 177 | { "MT20xx universal", Microtune, PAL|NTSC, |
178 | /* see mt20xx.c for details */ }, | 178 | /* see mt20xx.c for details */ }, |
179 | { "Temic PAL_BG (4106 FH5)", TEMIC, PAL, | 179 | { "Temic PAL_BG (4106 FH5)", TEMIC, PAL, |
180 | 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, | 180 | 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, |
181 | { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL, | 181 | { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL, |
182 | 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623}, | 182 | 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623}, |
183 | { "Temic NTSC (4136 FY5)", TEMIC, NTSC, | 183 | { "Temic NTSC (4136 FY5)", TEMIC, NTSC, |
184 | 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, | 184 | 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, |
185 | { "LG PAL (newer TAPC series)", LGINNOTEK, PAL, | 185 | { "LG PAL (newer TAPC series)", LGINNOTEK, PAL, |
186 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623}, | 186 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623}, |
187 | { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL, | 187 | { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL, |
188 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, | 188 | 16*158.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, |
189 | { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC, | 189 | { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC, |
190 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732}, | 190 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732}, |
191 | 191 | ||
192 | /* 40-49 */ | 192 | /* 40-49 */ |
193 | { "HITACHI V7-J180AT", HITACHI, NTSC, | 193 | { "HITACHI V7-J180AT", HITACHI, NTSC, |
@@ -196,24 +196,24 @@ static struct tunertype tuners[] = { | |||
196 | 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623}, | 196 | 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623}, |
197 | { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC, | 197 | { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC, |
198 | 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732}, | 198 | 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732}, |
199 | { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC, | 199 | { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC, |
200 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, | 200 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, |
201 | { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC, | 201 | { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC, |
202 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, | 202 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, |
203 | { "Microtune 4049 FM5", Microtune, PAL, | 203 | { "Microtune 4049 FM5", Microtune, PAL, |
204 | 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623}, | 204 | 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623}, |
205 | { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC, | 205 | { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC, |
206 | 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940}, | 206 | 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940}, |
207 | { "LG NTSC (TAPE series)", LGINNOTEK, NTSC, | 207 | { "LG NTSC (TAPE series)", LGINNOTEK, NTSC, |
208 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, | 208 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, |
209 | { "Tenna TNF 8831 BGFF)", Philips, PAL, | 209 | { "Tenna TNF 8831 BGFF)", Philips, PAL, |
210 | 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, | 210 | 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, |
211 | { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC, | 211 | { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC, |
212 | 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732}, | 212 | 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732}, |
213 | 213 | ||
214 | /* 50-59 */ | 214 | /* 50-59 */ |
215 | { "TCL 2002N", TCL, NTSC, | 215 | { "TCL 2002N", TCL, NTSC, |
216 | 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732}, | 216 | 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732}, |
217 | { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL, | 217 | { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL, |
218 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, | 218 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, |
219 | { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC, | 219 | { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC, |
@@ -222,8 +222,8 @@ static struct tunertype tuners[] = { | |||
222 | 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */ | 222 | 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */ |
223 | { "tda8290+75", Philips, PAL|NTSC, | 223 | { "tda8290+75", Philips, PAL|NTSC, |
224 | /* see tda8290.c for details */ }, | 224 | /* see tda8290.c for details */ }, |
225 | { "LG PAL (TAPE series)", LGINNOTEK, PAL, | 225 | { "TCL 2002MB", TCL, PAL, |
226 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, | 226 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, |
227 | { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, | 227 | { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, |
228 | 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, | 228 | 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, |
229 | { "Philips FQ1236A MK4", Philips, NTSC, | 229 | { "Philips FQ1236A MK4", Philips, NTSC, |
@@ -233,21 +233,25 @@ static struct tunertype tuners[] = { | |||
233 | { "Ymec TVision TVF-5533MF", Philips, NTSC, | 233 | { "Ymec TVision TVF-5533MF", Philips, NTSC, |
234 | 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, | 234 | 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, |
235 | 235 | ||
236 | /* 60-66 */ | 236 | /* 60-68 */ |
237 | { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, | 237 | { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, |
238 | 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, | 238 | 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, |
239 | { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL, | 239 | { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL, |
240 | 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, | 240 | 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, |
241 | { "Philips TEA5767HN FM Radio", Philips, RADIO, | 241 | { "Philips TEA5767HN FM Radio", Philips, RADIO, |
242 | /* see tea5767.c for details */}, | 242 | /* see tea5767.c for details */}, |
243 | { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, | 243 | { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, |
244 | 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, | 244 | 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, |
245 | { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC, | 245 | { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC, |
246 | 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732}, | 246 | 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732}, |
247 | { "Ymec TVF66T5-B/DFF", Philips, PAL, | 247 | { "Ymec TVF66T5-B/DFF", Philips, PAL, |
248 | 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623}, | 248 | 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623}, |
249 | { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC, | 249 | { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC, |
250 | 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 }, | 250 | 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 }, |
251 | { "Philips TD1316 Hybrid Tuner", Philips, PAL, | ||
252 | 16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 }, | ||
253 | { "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC, | ||
254 | 16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 }, | ||
251 | }; | 255 | }; |
252 | 256 | ||
253 | unsigned const int tuner_count = ARRAY_SIZE(tuners); | 257 | unsigned const int tuner_count = ARRAY_SIZE(tuners); |
@@ -277,7 +281,7 @@ static int tuner_stereo(struct i2c_client *c) | |||
277 | status = tuner_getstatus (c); | 281 | status = tuner_getstatus (c); |
278 | 282 | ||
279 | switch (t->type) { | 283 | switch (t->type) { |
280 | case TUNER_PHILIPS_FM1216ME_MK3: | 284 | case TUNER_PHILIPS_FM1216ME_MK3: |
281 | case TUNER_PHILIPS_FM1236_MK3: | 285 | case TUNER_PHILIPS_FM1236_MK3: |
282 | case TUNER_PHILIPS_FM1256_IH3: | 286 | case TUNER_PHILIPS_FM1256_IH3: |
283 | stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); | 287 | stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); |
@@ -295,10 +299,10 @@ static int tuner_stereo(struct i2c_client *c) | |||
295 | static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | 299 | static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) |
296 | { | 300 | { |
297 | struct tuner *t = i2c_get_clientdata(c); | 301 | struct tuner *t = i2c_get_clientdata(c); |
298 | u8 config; | 302 | u8 config, tuneraddr; |
299 | u16 div; | 303 | u16 div; |
300 | struct tunertype *tun; | 304 | struct tunertype *tun; |
301 | unsigned char buffer[4]; | 305 | unsigned char buffer[4]; |
302 | int rc; | 306 | int rc; |
303 | 307 | ||
304 | tun = &tuners[t->type]; | 308 | tun = &tuners[t->type]; |
@@ -373,6 +377,31 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
373 | /* Set the charge pump for fast tuning */ | 377 | /* Set the charge pump for fast tuning */ |
374 | tun->config |= TUNER_CHARGE_PUMP; | 378 | tun->config |= TUNER_CHARGE_PUMP; |
375 | break; | 379 | break; |
380 | |||
381 | case TUNER_PHILIPS_TUV1236D: | ||
382 | /* 0x40 -> ATSC antenna input 1 */ | ||
383 | /* 0x48 -> ATSC antenna input 2 */ | ||
384 | /* 0x00 -> NTSC antenna input 1 */ | ||
385 | /* 0x08 -> NTSC antenna input 2 */ | ||
386 | buffer[0] = 0x14; | ||
387 | buffer[1] = 0x00; | ||
388 | buffer[2] = 0x17; | ||
389 | buffer[3] = 0x00; | ||
390 | config &= ~0x40; | ||
391 | if (t->std & V4L2_STD_ATSC) { | ||
392 | config |= 0x40; | ||
393 | buffer[1] = 0x04; | ||
394 | } | ||
395 | /* set to the correct mode (analog or digital) */ | ||
396 | tuneraddr = c->addr; | ||
397 | c->addr = 0x0a; | ||
398 | if (2 != (rc = i2c_master_send(c,&buffer[0],2))) | ||
399 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc); | ||
400 | if (2 != (rc = i2c_master_send(c,&buffer[2],2))) | ||
401 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc); | ||
402 | c->addr = tuneraddr; | ||
403 | /* FIXME: input */ | ||
404 | break; | ||
376 | } | 405 | } |
377 | 406 | ||
378 | /* | 407 | /* |
@@ -404,7 +433,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
404 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | 433 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", |
405 | buffer[0],buffer[1],buffer[2],buffer[3]); | 434 | buffer[0],buffer[1],buffer[2],buffer[3]); |
406 | 435 | ||
407 | if (4 != (rc = i2c_master_send(c,buffer,4))) | 436 | if (4 != (rc = i2c_master_send(c,buffer,4))) |
408 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | 437 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); |
409 | 438 | ||
410 | if (t->type == TUNER_MICROTUNE_4042FI5) { | 439 | if (t->type == TUNER_MICROTUNE_4042FI5) { |
@@ -443,7 +472,7 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
443 | { | 472 | { |
444 | struct tunertype *tun; | 473 | struct tunertype *tun; |
445 | struct tuner *t = i2c_get_clientdata(c); | 474 | struct tuner *t = i2c_get_clientdata(c); |
446 | unsigned char buffer[4]; | 475 | unsigned char buffer[4]; |
447 | unsigned div; | 476 | unsigned div; |
448 | int rc; | 477 | int rc; |
449 | 478 | ||
@@ -476,13 +505,13 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) | |||
476 | buffer[3] = 0xa4; | 505 | buffer[3] = 0xa4; |
477 | break; | 506 | break; |
478 | } | 507 | } |
479 | buffer[0] = (div>>8) & 0x7f; | 508 | buffer[0] = (div>>8) & 0x7f; |
480 | buffer[1] = div & 0xff; | 509 | buffer[1] = div & 0xff; |
481 | 510 | ||
482 | tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", | 511 | tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", |
483 | buffer[0],buffer[1],buffer[2],buffer[3]); | 512 | buffer[0],buffer[1],buffer[2],buffer[3]); |
484 | 513 | ||
485 | if (4 != (rc = i2c_master_send(c,buffer,4))) | 514 | if (4 != (rc = i2c_master_send(c,buffer,4))) |
486 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | 515 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); |
487 | } | 516 | } |
488 | 517 | ||
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 1c31ef52f863..c31bf28b73fe 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
32 | 32 | ||
33 | #include <media/audiochip.h> | 33 | #include <media/audiochip.h> |
34 | #include <media/id.h> | ||
35 | 34 | ||
36 | #include "tvaudio.h" | 35 | #include "tvaudio.h" |
37 | 36 | ||
@@ -458,8 +457,8 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode) | |||
458 | #define TDA9855_LOUD 1<<5 /* Loudness, 1==off */ | 457 | #define TDA9855_LOUD 1<<5 /* Loudness, 1==off */ |
459 | #define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */ | 458 | #define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */ |
460 | /* Bits 0 to 3 select various combinations | 459 | /* Bits 0 to 3 select various combinations |
461 | * of line in and line out, only the | 460 | * of line in and line out, only the |
462 | * interesting ones are defined */ | 461 | * interesting ones are defined */ |
463 | #define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */ | 462 | #define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */ |
464 | #define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */ | 463 | #define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */ |
465 | 464 | ||
@@ -1028,7 +1027,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip) | |||
1028 | #define TEA6300_TR 0x03 /* treble */ | 1027 | #define TEA6300_TR 0x03 /* treble */ |
1029 | #define TEA6300_FA 0x04 /* fader control */ | 1028 | #define TEA6300_FA 0x04 /* fader control */ |
1030 | #define TEA6300_S 0x05 /* switch register */ | 1029 | #define TEA6300_S 0x05 /* switch register */ |
1031 | /* values for those registers: */ | 1030 | /* values for those registers: */ |
1032 | #define TEA6300_S_SA 0x01 /* stereo A input */ | 1031 | #define TEA6300_S_SA 0x01 /* stereo A input */ |
1033 | #define TEA6300_S_SB 0x02 /* stereo B */ | 1032 | #define TEA6300_S_SB 0x02 /* stereo B */ |
1034 | #define TEA6300_S_SC 0x04 /* stereo C */ | 1033 | #define TEA6300_S_SC 0x04 /* stereo C */ |
@@ -1042,7 +1041,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip) | |||
1042 | #define TEA6320_BA 0x05 /* bass (0-4) */ | 1041 | #define TEA6320_BA 0x05 /* bass (0-4) */ |
1043 | #define TEA6320_TR 0x06 /* treble (0-4) */ | 1042 | #define TEA6320_TR 0x06 /* treble (0-4) */ |
1044 | #define TEA6320_S 0x07 /* switch register */ | 1043 | #define TEA6320_S 0x07 /* switch register */ |
1045 | /* values for those registers: */ | 1044 | /* values for those registers: */ |
1046 | #define TEA6320_S_SA 0x07 /* stereo A input */ | 1045 | #define TEA6320_S_SA 0x07 /* stereo A input */ |
1047 | #define TEA6320_S_SB 0x06 /* stereo B */ | 1046 | #define TEA6320_S_SB 0x06 /* stereo B */ |
1048 | #define TEA6320_S_SC 0x05 /* stereo C */ | 1047 | #define TEA6320_S_SC 0x05 /* stereo C */ |
@@ -1082,7 +1081,7 @@ static int tea6320_initialize(struct CHIPSTATE * chip) | |||
1082 | #define TDA8425_BA 0x02 /* bass */ | 1081 | #define TDA8425_BA 0x02 /* bass */ |
1083 | #define TDA8425_TR 0x03 /* treble */ | 1082 | #define TDA8425_TR 0x03 /* treble */ |
1084 | #define TDA8425_S1 0x08 /* switch functions */ | 1083 | #define TDA8425_S1 0x08 /* switch functions */ |
1085 | /* values for those registers: */ | 1084 | /* values for those registers: */ |
1086 | #define TDA8425_S1_OFF 0xEE /* audio off (mute on) */ | 1085 | #define TDA8425_S1_OFF 0xEE /* audio off (mute on) */ |
1087 | #define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */ | 1086 | #define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */ |
1088 | #define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */ | 1087 | #define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */ |
@@ -1148,7 +1147,7 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode) | |||
1148 | 1147 | ||
1149 | /* bit definition of the RESET register, I2C data. */ | 1148 | /* bit definition of the RESET register, I2C data. */ |
1150 | #define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */ | 1149 | #define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */ |
1151 | /* code of remote controller */ | 1150 | /* code of remote controller */ |
1152 | #define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */ | 1151 | #define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */ |
1153 | #define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */ | 1152 | #define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */ |
1154 | #define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */ | 1153 | #define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */ |
@@ -1281,7 +1280,7 @@ static struct CHIPDESC chiplist[] = { | |||
1281 | .setmode = tda9840_setmode, | 1280 | .setmode = tda9840_setmode, |
1282 | .checkmode = generic_checkmode, | 1281 | .checkmode = generic_checkmode, |
1283 | 1282 | ||
1284 | .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN | 1283 | .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN |
1285 | /* ,TDA9840_SW, TDA9840_MONO */} } | 1284 | /* ,TDA9840_SW, TDA9840_MONO */} } |
1286 | }, | 1285 | }, |
1287 | { | 1286 | { |
@@ -1438,7 +1437,7 @@ static struct CHIPDESC chiplist[] = { | |||
1438 | }, | 1437 | }, |
1439 | { | 1438 | { |
1440 | .name = "pic16c54 (PV951)", | 1439 | .name = "pic16c54 (PV951)", |
1441 | .id = I2C_DRIVERID_PIC16C54_PV951, | 1440 | .id = I2C_DRIVERID_PIC16C54_PV9, |
1442 | .insmodopt = &pic16c54, | 1441 | .insmodopt = &pic16c54, |
1443 | .addr_lo = I2C_PIC16C54 >> 1, | 1442 | .addr_lo = I2C_PIC16C54 >> 1, |
1444 | .addr_hi = I2C_PIC16C54>> 1, | 1443 | .addr_hi = I2C_PIC16C54>> 1, |
@@ -1467,7 +1466,7 @@ static struct CHIPDESC chiplist[] = { | |||
1467 | .setmode = ta8874z_setmode, | 1466 | .setmode = ta8874z_setmode, |
1468 | .checkmode = generic_checkmode, | 1467 | .checkmode = generic_checkmode, |
1469 | 1468 | ||
1470 | .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}, | 1469 | .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}, |
1471 | }, | 1470 | }, |
1472 | { .name = NULL } /* EOF */ | 1471 | { .name = NULL } /* EOF */ |
1473 | }; | 1472 | }; |
@@ -1486,8 +1485,8 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1486 | return -ENOMEM; | 1485 | return -ENOMEM; |
1487 | memset(chip,0,sizeof(*chip)); | 1486 | memset(chip,0,sizeof(*chip)); |
1488 | memcpy(&chip->c,&client_template,sizeof(struct i2c_client)); | 1487 | memcpy(&chip->c,&client_template,sizeof(struct i2c_client)); |
1489 | chip->c.adapter = adap; | 1488 | chip->c.adapter = adap; |
1490 | chip->c.addr = addr; | 1489 | chip->c.addr = addr; |
1491 | i2c_set_clientdata(&chip->c, chip); | 1490 | i2c_set_clientdata(&chip->c, chip); |
1492 | 1491 | ||
1493 | /* find description for the chip */ | 1492 | /* find description for the chip */ |
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 5344d5592199..72e8741e8b59 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c | |||
@@ -6,12 +6,12 @@ | |||
6 | * which are: | 6 | * which are: |
7 | 7 | ||
8 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) | 8 | Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) |
9 | & Marcus Metzler (mocm@thp.uni-koeln.de) | 9 | & Marcus Metzler (mocm@thp.uni-koeln.de) |
10 | (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> | 10 | (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> |
11 | 11 | ||
12 | * Adjustments to fit a more general model and all bugs: | 12 | * Adjustments to fit a more general model and all bugs: |
13 | 13 | ||
14 | Copyright (C) 2003 John Klar <linpvr at projectplasma.com> | 14 | Copyright (C) 2003 John Klar <linpvr at projectplasma.com> |
15 | 15 | ||
16 | * This program is free software; you can redistribute it and/or modify | 16 | * This program is free software; you can redistribute it and/or modify |
17 | * it under the terms of the GNU General Public License as published by | 17 | * it under the terms of the GNU General Public License as published by |
@@ -40,6 +40,7 @@ | |||
40 | 40 | ||
41 | #include <media/tuner.h> | 41 | #include <media/tuner.h> |
42 | #include <media/tveeprom.h> | 42 | #include <media/tveeprom.h> |
43 | #include <media/audiochip.h> | ||
43 | 44 | ||
44 | MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); | 45 | MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); |
45 | MODULE_AUTHOR("John Klar"); | 46 | MODULE_AUTHOR("John Klar"); |
@@ -53,14 +54,14 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); | |||
53 | 54 | ||
54 | #define tveeprom_info(fmt, arg...) do {\ | 55 | #define tveeprom_info(fmt, arg...) do {\ |
55 | printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ | 56 | printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ |
56 | c->adapter->nr, c->addr , ##arg); } while (0) | 57 | c->adapter->nr, c->addr , ##arg); } while (0) |
57 | #define tveeprom_warn(fmt, arg...) do {\ | 58 | #define tveeprom_warn(fmt, arg...) do {\ |
58 | printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \ | 59 | printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \ |
59 | c->adapter->nr, c->addr , ##arg); } while (0) | 60 | c->adapter->nr, c->addr , ##arg); } while (0) |
60 | #define tveeprom_dbg(fmt, arg...) do {\ | 61 | #define tveeprom_dbg(fmt, arg...) do {\ |
61 | if (debug) \ | 62 | if (debug) \ |
62 | printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ | 63 | printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ |
63 | c->adapter->nr, c->addr , ##arg); } while (0) | 64 | c->adapter->nr, c->addr , ##arg); } while (0) |
64 | 65 | ||
65 | 66 | ||
66 | /* ----------------------------------------------------------------------- */ | 67 | /* ----------------------------------------------------------------------- */ |
@@ -134,8 +135,8 @@ hauppauge_tuner[] = | |||
134 | { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" }, | 135 | { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" }, |
135 | { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" }, | 136 | { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" }, |
136 | { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" }, | 137 | { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" }, |
137 | { TUNER_PHILIPS_NTSC, "Philips TD1536" }, | 138 | { TUNER_PHILIPS_NTSC, "Philips TD1536" }, |
138 | { TUNER_PHILIPS_NTSC, "Philips TD1536D" }, | 139 | { TUNER_PHILIPS_NTSC, "Philips TD1536D" }, |
139 | { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */ | 140 | { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */ |
140 | { TUNER_ABSENT, "Philips FI1256MP" }, | 141 | { TUNER_ABSENT, "Philips FI1256MP" }, |
141 | /* 40-49 */ | 142 | /* 40-49 */ |
@@ -189,7 +190,7 @@ hauppauge_tuner[] = | |||
189 | { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, | 190 | { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, |
190 | { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"}, | 191 | { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"}, |
191 | { TUNER_TCL_2002N, "TCL 2002N 6A"}, | 192 | { TUNER_TCL_2002N, "TCL 2002N 6A"}, |
192 | { TUNER_ABSENT, "Philips FQ1236 MK3"}, | 193 | { TUNER_PHILIPS_FM1236_MK3, "Philips FQ1236 MK3"}, |
193 | { TUNER_ABSENT, "Samsung TCPN 2121P30A"}, | 194 | { TUNER_ABSENT, "Samsung TCPN 2121P30A"}, |
194 | { TUNER_ABSENT, "Samsung TCPE 4121P30A"}, | 195 | { TUNER_ABSENT, "Samsung TCPE 4121P30A"}, |
195 | { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"}, | 196 | { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"}, |
@@ -200,95 +201,137 @@ hauppauge_tuner[] = | |||
200 | { TUNER_ABSENT, "Philips FQ1286A MK4"}, | 201 | { TUNER_ABSENT, "Philips FQ1286A MK4"}, |
201 | { TUNER_ABSENT, "Philips FQ1216ME MK5"}, | 202 | { TUNER_ABSENT, "Philips FQ1216ME MK5"}, |
202 | { TUNER_ABSENT, "Philips FQ1236 MK5"}, | 203 | { TUNER_ABSENT, "Philips FQ1236 MK5"}, |
203 | { TUNER_ABSENT, "Unspecified"}, | 204 | { TUNER_ABSENT, "Samsung TCPG_6121P30A"}, |
204 | { TUNER_LG_PAL_TAPE, "LG PAL (TAPE Series)"}, | 205 | { TUNER_TCL_2002MB, "TCL 2002MB_3H"}, |
205 | { TUNER_ABSENT, "Unspecified"}, | 206 | { TUNER_ABSENT, "TCL 2002MI_3H"}, |
206 | { TUNER_TCL_2002N, "TCL 2002N 5H"}, | 207 | { TUNER_TCL_2002N, "TCL 2002N 5H"}, |
207 | /* 100-103 */ | 208 | /* 100-109 */ |
208 | { TUNER_ABSENT, "Unspecified"}, | 209 | { TUNER_ABSENT, "Philips FMD1216ME"}, |
209 | { TUNER_TEA5767, "Philips TEA5767HN FM Radio"}, | 210 | { TUNER_TEA5767, "Philips TEA5768HL FM Radio"}, |
210 | { TUNER_ABSENT, "Unspecified"}, | 211 | { TUNER_ABSENT, "Panasonic ENV57H12D5"}, |
211 | { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05 4"}, | 212 | { TUNER_ABSENT, "TCL MFNM05-4"}, |
213 | { TUNER_ABSENT, "TCL MNM05-4"}, | ||
214 | { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"}, | ||
215 | { TUNER_ABSENT, "TCL MQNM05-4"}, | ||
216 | { TUNER_ABSENT, "LG TAPC-W701D"}, | ||
217 | { TUNER_ABSENT, "TCL 9886P-WM"}, | ||
218 | { TUNER_ABSENT, "TCL 1676NM-WM"}, | ||
212 | }; | 219 | }; |
213 | 220 | ||
214 | /* This list is supplied by Hauppauge. Thanks! */ | 221 | static struct HAUPPAUGE_AUDIOIC |
215 | static const char *audioIC[] = { | 222 | { |
216 | /* 0-4 */ | 223 | enum audiochip id; |
217 | "None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C", | 224 | char *name; |
218 | /* 5-9 */ | 225 | } |
219 | "MSP3410D", "MSP3415", "MSP3430", "MSP3438", "CS5331", | 226 | audioIC[] = |
220 | /* 10-14 */ | 227 | { |
221 | "MSP3435", "MSP3440", "MSP3445", "MSP3411", "MSP3416", | 228 | /* 0-4 */ |
222 | /* 15-19 */ | 229 | {AUDIO_CHIP_NONE, "None"}, |
223 | "MSP3425", "MSP3451", "MSP3418", "Type 0x12", "OKI7716", | 230 | {AUDIO_CHIP_TEA6300, "TEA6300"}, |
224 | /* 20-24 */ | 231 | {AUDIO_CHIP_TEA6300, "TEA6320"}, |
225 | "MSP4410", "MSP4420", "MSP4440", "MSP4450", "MSP4408", | 232 | {AUDIO_CHIP_TDA985X, "TDA9850"}, |
226 | /* 25-29 */ | 233 | {AUDIO_CHIP_MSP34XX, "MSP3400C"}, |
227 | "MSP4418", "MSP4428", "MSP4448", "MSP4458", "Type 0x1d", | 234 | /* 5-9 */ |
228 | /* 30-34 */ | 235 | {AUDIO_CHIP_MSP34XX, "MSP3410D"}, |
229 | "CX880", "CX881", "CX883", "CX882", "CX25840", | 236 | {AUDIO_CHIP_MSP34XX, "MSP3415"}, |
230 | /* 35-38 */ | 237 | {AUDIO_CHIP_MSP34XX, "MSP3430"}, |
231 | "CX25841", "CX25842", "CX25843", "CX23418", | 238 | {AUDIO_CHIP_UNKNOWN, "MSP3438"}, |
239 | {AUDIO_CHIP_UNKNOWN, "CS5331"}, | ||
240 | /* 10-14 */ | ||
241 | {AUDIO_CHIP_MSP34XX, "MSP3435"}, | ||
242 | {AUDIO_CHIP_MSP34XX, "MSP3440"}, | ||
243 | {AUDIO_CHIP_MSP34XX, "MSP3445"}, | ||
244 | {AUDIO_CHIP_UNKNOWN, "MSP3411"}, | ||
245 | {AUDIO_CHIP_UNKNOWN, "MSP3416"}, | ||
246 | /* 15-19 */ | ||
247 | {AUDIO_CHIP_MSP34XX, "MSP3425"}, | ||
248 | {AUDIO_CHIP_UNKNOWN, "MSP3451"}, | ||
249 | {AUDIO_CHIP_UNKNOWN, "MSP3418"}, | ||
250 | {AUDIO_CHIP_UNKNOWN, "Type 0x12"}, | ||
251 | {AUDIO_CHIP_UNKNOWN, "OKI7716"}, | ||
252 | /* 20-24 */ | ||
253 | {AUDIO_CHIP_UNKNOWN, "MSP4410"}, | ||
254 | {AUDIO_CHIP_UNKNOWN, "MSP4420"}, | ||
255 | {AUDIO_CHIP_UNKNOWN, "MSP4440"}, | ||
256 | {AUDIO_CHIP_UNKNOWN, "MSP4450"}, | ||
257 | {AUDIO_CHIP_UNKNOWN, "MSP4408"}, | ||
258 | /* 25-29 */ | ||
259 | {AUDIO_CHIP_UNKNOWN, "MSP4418"}, | ||
260 | {AUDIO_CHIP_UNKNOWN, "MSP4428"}, | ||
261 | {AUDIO_CHIP_UNKNOWN, "MSP4448"}, | ||
262 | {AUDIO_CHIP_UNKNOWN, "MSP4458"}, | ||
263 | {AUDIO_CHIP_UNKNOWN, "Type 0x1d"}, | ||
264 | /* 30-34 */ | ||
265 | {AUDIO_CHIP_INTERNAL, "CX880"}, | ||
266 | {AUDIO_CHIP_INTERNAL, "CX881"}, | ||
267 | {AUDIO_CHIP_INTERNAL, "CX883"}, | ||
268 | {AUDIO_CHIP_INTERNAL, "CX882"}, | ||
269 | {AUDIO_CHIP_INTERNAL, "CX25840"}, | ||
270 | /* 35-38 */ | ||
271 | {AUDIO_CHIP_INTERNAL, "CX25841"}, | ||
272 | {AUDIO_CHIP_INTERNAL, "CX25842"}, | ||
273 | {AUDIO_CHIP_INTERNAL, "CX25843"}, | ||
274 | {AUDIO_CHIP_INTERNAL, "CX23418"}, | ||
232 | }; | 275 | }; |
233 | 276 | ||
234 | /* This list is supplied by Hauppauge. Thanks! */ | 277 | /* This list is supplied by Hauppauge. Thanks! */ |
235 | static const char *decoderIC[] = { | 278 | static const char *decoderIC[] = { |
236 | /* 0-4 */ | 279 | /* 0-4 */ |
237 | "None", "BT815", "BT817", "BT819", "BT815A", | 280 | "None", "BT815", "BT817", "BT819", "BT815A", |
238 | /* 5-9 */ | 281 | /* 5-9 */ |
239 | "BT817A", "BT819A", "BT827", "BT829", "BT848", | 282 | "BT817A", "BT819A", "BT827", "BT829", "BT848", |
240 | /* 10-14 */ | 283 | /* 10-14 */ |
241 | "BT848A", "BT849A", "BT829A", "BT827A", "BT878", | 284 | "BT848A", "BT849A", "BT829A", "BT827A", "BT878", |
242 | /* 15-19 */ | 285 | /* 15-19 */ |
243 | "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115", | 286 | "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115", |
244 | /* 20-24 */ | 287 | /* 20-24 */ |
245 | "CX880", "CX881", "CX883", "SAA7111", "SAA7113", | 288 | "CX880", "CX881", "CX883", "SAA7111", "SAA7113", |
246 | /* 25-29 */ | 289 | /* 25-29 */ |
247 | "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842", | 290 | "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842", |
248 | /* 30-31 */ | 291 | /* 30-31 */ |
249 | "CX25843", "CX23418", | 292 | "CX25843", "CX23418", |
250 | }; | 293 | }; |
251 | 294 | ||
252 | static int hasRadioTuner(int tunerType) | 295 | static int hasRadioTuner(int tunerType) |
253 | { | 296 | { |
254 | switch (tunerType) { | 297 | switch (tunerType) { |
255 | case 18: //PNPEnv_TUNER_FR1236_MK2: | 298 | case 18: //PNPEnv_TUNER_FR1236_MK2: |
256 | case 23: //PNPEnv_TUNER_FM1236: | 299 | case 23: //PNPEnv_TUNER_FM1236: |
257 | case 38: //PNPEnv_TUNER_FMR1236: | 300 | case 38: //PNPEnv_TUNER_FMR1236: |
258 | case 16: //PNPEnv_TUNER_FR1216_MK2: | 301 | case 16: //PNPEnv_TUNER_FR1216_MK2: |
259 | case 19: //PNPEnv_TUNER_FR1246_MK2: | 302 | case 19: //PNPEnv_TUNER_FR1246_MK2: |
260 | case 21: //PNPEnv_TUNER_FM1216: | 303 | case 21: //PNPEnv_TUNER_FM1216: |
261 | case 24: //PNPEnv_TUNER_FM1246: | 304 | case 24: //PNPEnv_TUNER_FM1246: |
262 | case 17: //PNPEnv_TUNER_FR1216MF_MK2: | 305 | case 17: //PNPEnv_TUNER_FR1216MF_MK2: |
263 | case 22: //PNPEnv_TUNER_FM1216MF: | 306 | case 22: //PNPEnv_TUNER_FM1216MF: |
264 | case 20: //PNPEnv_TUNER_FR1256_MK2: | 307 | case 20: //PNPEnv_TUNER_FR1256_MK2: |
265 | case 25: //PNPEnv_TUNER_FM1256: | 308 | case 25: //PNPEnv_TUNER_FM1256: |
266 | case 33: //PNPEnv_TUNER_4039FR5: | 309 | case 33: //PNPEnv_TUNER_4039FR5: |
267 | case 42: //PNPEnv_TUNER_4009FR5: | 310 | case 42: //PNPEnv_TUNER_4009FR5: |
268 | case 52: //PNPEnv_TUNER_4049FM5: | 311 | case 52: //PNPEnv_TUNER_4049FM5: |
269 | case 54: //PNPEnv_TUNER_4049FM5_AltI2C: | 312 | case 54: //PNPEnv_TUNER_4049FM5_AltI2C: |
270 | case 44: //PNPEnv_TUNER_4009FN5: | 313 | case 44: //PNPEnv_TUNER_4009FN5: |
271 | case 31: //PNPEnv_TUNER_TCPB9085P: | 314 | case 31: //PNPEnv_TUNER_TCPB9085P: |
272 | case 30: //PNPEnv_TUNER_TCPN9085D: | 315 | case 30: //PNPEnv_TUNER_TCPN9085D: |
273 | case 46: //PNPEnv_TUNER_TP18NSR01F: | 316 | case 46: //PNPEnv_TUNER_TP18NSR01F: |
274 | case 47: //PNPEnv_TUNER_TP18PSB01D: | 317 | case 47: //PNPEnv_TUNER_TP18PSB01D: |
275 | case 49: //PNPEnv_TUNER_TAPC_I001D: | 318 | case 49: //PNPEnv_TUNER_TAPC_I001D: |
276 | case 60: //PNPEnv_TUNER_TAPE_S001D_MK3: | 319 | case 60: //PNPEnv_TUNER_TAPE_S001D_MK3: |
277 | case 57: //PNPEnv_TUNER_FM1216ME_MK3: | 320 | case 57: //PNPEnv_TUNER_FM1216ME_MK3: |
278 | case 59: //PNPEnv_TUNER_FM1216MP_MK3: | 321 | case 59: //PNPEnv_TUNER_FM1216MP_MK3: |
279 | case 58: //PNPEnv_TUNER_FM1236_MK3: | 322 | case 58: //PNPEnv_TUNER_FM1236_MK3: |
280 | case 68: //PNPEnv_TUNER_TAPE_H001F_MK3: | 323 | case 68: //PNPEnv_TUNER_TAPE_H001F_MK3: |
281 | case 61: //PNPEnv_TUNER_TAPE_M001D_MK3: | 324 | case 61: //PNPEnv_TUNER_TAPE_M001D_MK3: |
282 | case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM: | 325 | case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM: |
283 | case 89: //PNPEnv_TUNER_TCL_MFPE05_2: | 326 | case 89: //PNPEnv_TUNER_TCL_MFPE05_2: |
284 | case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4: | 327 | case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4: |
285 | return 1; | 328 | return 1; |
286 | } | 329 | } |
287 | return 0; | 330 | return 0; |
288 | } | 331 | } |
289 | 332 | ||
290 | void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | 333 | void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, |
291 | unsigned char *eeprom_data) | 334 | unsigned char *eeprom_data) |
292 | { | 335 | { |
293 | /* ---------------------------------------------- | 336 | /* ---------------------------------------------- |
294 | ** The hauppauge eeprom format is tagged | 337 | ** The hauppauge eeprom format is tagged |
@@ -312,19 +355,27 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
312 | ** # of inputs/outputs ??? | 355 | ** # of inputs/outputs ??? |
313 | */ | 356 | */ |
314 | 357 | ||
315 | int i, j, len, done, beenhere, tag; | 358 | int i, j, len, done, beenhere, tag,start; |
316 | 359 | ||
317 | int tuner1 = 0, t_format1 = 0; | 360 | int tuner1 = 0, t_format1 = 0, audioic=-1; |
318 | char *t_name1 = NULL; | 361 | char *t_name1 = NULL; |
319 | const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" }; | 362 | const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" }; |
320 | 363 | ||
321 | int tuner2 = 0, t_format2 = 0; | 364 | int tuner2 = 0, t_format2 = 0; |
322 | char *t_name2 = NULL; | 365 | char *t_name2 = NULL; |
323 | const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" }; | 366 | const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" }; |
324 | 367 | ||
325 | memset(tvee, 0, sizeof(*tvee)); | 368 | memset(tvee, 0, sizeof(*tvee)); |
326 | done = len = beenhere = 0; | 369 | done = len = beenhere = 0; |
327 | for (i = 0; !done && i < 256; i += len) { | 370 | |
371 | /* Hack for processing eeprom for em28xx */ | ||
372 | if ((eeprom_data[0]==0x1a)&&(eeprom_data[1]==0xeb)&& | ||
373 | (eeprom_data[2]==0x67)&&(eeprom_data[3]==0x95)) | ||
374 | start=0xa0; | ||
375 | else | ||
376 | start=0; | ||
377 | |||
378 | for (i = start; !done && i < 256; i += len) { | ||
328 | if (eeprom_data[i] == 0x84) { | 379 | if (eeprom_data[i] == 0x84) { |
329 | len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8); | 380 | len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8); |
330 | i += 3; | 381 | i += 3; |
@@ -338,28 +389,28 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
338 | ++i; | 389 | ++i; |
339 | } else { | 390 | } else { |
340 | tveeprom_warn("Encountered bad packet header [%02x]. " | 391 | tveeprom_warn("Encountered bad packet header [%02x]. " |
341 | "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]); | 392 | "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]); |
342 | return; | 393 | return; |
343 | } | 394 | } |
344 | 395 | ||
345 | if (debug) { | 396 | if (debug) { |
346 | tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1); | 397 | tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1); |
347 | for(j = 1; j < len; j++) { | 398 | for(j = 1; j < len; j++) { |
348 | printk(" %02x", eeprom_data[i + j]); | 399 | printk(" %02x", eeprom_data[i + j]); |
349 | } | 400 | } |
350 | printk("\n"); | 401 | printk("\n"); |
351 | } | 402 | } |
352 | 403 | ||
353 | /* process by tag */ | 404 | /* process by tag */ |
354 | tag = eeprom_data[i]; | 405 | tag = eeprom_data[i]; |
355 | switch (tag) { | 406 | switch (tag) { |
356 | case 0x00: | 407 | case 0x00: |
357 | /* tag: 'Comprehensive' */ | 408 | /* tag: 'Comprehensive' */ |
358 | tuner1 = eeprom_data[i+6]; | 409 | tuner1 = eeprom_data[i+6]; |
359 | t_format1 = eeprom_data[i+5]; | 410 | t_format1 = eeprom_data[i+5]; |
360 | tvee->has_radio = eeprom_data[i+len-1]; | 411 | tvee->has_radio = eeprom_data[i+len-1]; |
361 | /* old style tag, don't know how to detect | 412 | /* old style tag, don't know how to detect |
362 | IR presence, mark as unknown. */ | 413 | IR presence, mark as unknown. */ |
363 | tvee->has_ir = 2; | 414 | tvee->has_ir = 2; |
364 | tvee->model = | 415 | tvee->model = |
365 | eeprom_data[i+8] + | 416 | eeprom_data[i+8] + |
@@ -370,7 +421,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
370 | break; | 421 | break; |
371 | 422 | ||
372 | case 0x01: | 423 | case 0x01: |
373 | /* tag: 'SerialID' */ | 424 | /* tag: 'SerialID' */ |
374 | tvee->serial_number = | 425 | tvee->serial_number = |
375 | eeprom_data[i+6] + | 426 | eeprom_data[i+6] + |
376 | (eeprom_data[i+7] << 8) + | 427 | (eeprom_data[i+7] << 8) + |
@@ -378,17 +429,21 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
378 | break; | 429 | break; |
379 | 430 | ||
380 | case 0x02: | 431 | case 0x02: |
381 | /* tag 'AudioInfo' | 432 | /* tag 'AudioInfo' |
382 | Note mask with 0x7F, high bit used on some older models | 433 | Note mask with 0x7F, high bit used on some older models |
383 | to indicate 4052 mux was removed in favor of using MSP | 434 | to indicate 4052 mux was removed in favor of using MSP |
384 | inputs directly. */ | 435 | inputs directly. */ |
385 | tvee->audio_processor = eeprom_data[i+2] & 0x7f; | 436 | audioic = eeprom_data[i+2] & 0x7f; |
437 | if (audioic < sizeof(audioIC)/sizeof(*audioIC)) | ||
438 | tvee->audio_processor = audioIC[audioic].id; | ||
439 | else | ||
440 | tvee->audio_processor = AUDIO_CHIP_UNKNOWN; | ||
386 | break; | 441 | break; |
387 | 442 | ||
388 | /* case 0x03: tag 'EEInfo' */ | 443 | /* case 0x03: tag 'EEInfo' */ |
389 | 444 | ||
390 | case 0x04: | 445 | case 0x04: |
391 | /* tag 'SerialID2' */ | 446 | /* tag 'SerialID2' */ |
392 | tvee->serial_number = | 447 | tvee->serial_number = |
393 | eeprom_data[i+5] + | 448 | eeprom_data[i+5] + |
394 | (eeprom_data[i+6] << 8) + | 449 | (eeprom_data[i+6] << 8) + |
@@ -396,15 +451,20 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
396 | break; | 451 | break; |
397 | 452 | ||
398 | case 0x05: | 453 | case 0x05: |
399 | /* tag 'Audio2' | 454 | /* tag 'Audio2' |
400 | Note mask with 0x7F, high bit used on some older models | 455 | Note mask with 0x7F, high bit used on some older models |
401 | to indicate 4052 mux was removed in favor of using MSP | 456 | to indicate 4052 mux was removed in favor of using MSP |
402 | inputs directly. */ | 457 | inputs directly. */ |
403 | tvee->audio_processor = eeprom_data[i+1] & 0x7f; | 458 | audioic = eeprom_data[i+1] & 0x7f; |
459 | if (audioic < sizeof(audioIC)/sizeof(*audioIC)) | ||
460 | tvee->audio_processor = audioIC[audioic].id; | ||
461 | else | ||
462 | tvee->audio_processor = AUDIO_CHIP_UNKNOWN; | ||
463 | |||
404 | break; | 464 | break; |
405 | 465 | ||
406 | case 0x06: | 466 | case 0x06: |
407 | /* tag 'ModelRev' */ | 467 | /* tag 'ModelRev' */ |
408 | tvee->model = | 468 | tvee->model = |
409 | eeprom_data[i+1] + | 469 | eeprom_data[i+1] + |
410 | (eeprom_data[i+2] << 8); | 470 | (eeprom_data[i+2] << 8); |
@@ -414,55 +474,55 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
414 | break; | 474 | break; |
415 | 475 | ||
416 | case 0x07: | 476 | case 0x07: |
417 | /* tag 'Details': according to Hauppauge not interesting | 477 | /* tag 'Details': according to Hauppauge not interesting |
418 | on any PCI-era or later boards. */ | 478 | on any PCI-era or later boards. */ |
419 | break; | 479 | break; |
420 | 480 | ||
421 | /* there is no tag 0x08 defined */ | 481 | /* there is no tag 0x08 defined */ |
422 | 482 | ||
423 | case 0x09: | 483 | case 0x09: |
424 | /* tag 'Video' */ | 484 | /* tag 'Video' */ |
425 | tvee->decoder_processor = eeprom_data[i + 1]; | 485 | tvee->decoder_processor = eeprom_data[i + 1]; |
426 | break; | 486 | break; |
427 | 487 | ||
428 | case 0x0a: | 488 | case 0x0a: |
429 | /* tag 'Tuner' */ | 489 | /* tag 'Tuner' */ |
430 | if (beenhere == 0) { | 490 | if (beenhere == 0) { |
431 | tuner1 = eeprom_data[i+2]; | 491 | tuner1 = eeprom_data[i+2]; |
432 | t_format1 = eeprom_data[i+1]; | 492 | t_format1 = eeprom_data[i+1]; |
433 | beenhere = 1; | 493 | beenhere = 1; |
434 | } else { | 494 | } else { |
435 | /* a second (radio) tuner may be present */ | 495 | /* a second (radio) tuner may be present */ |
436 | tuner2 = eeprom_data[i+2]; | 496 | tuner2 = eeprom_data[i+2]; |
437 | t_format2 = eeprom_data[i+1]; | 497 | t_format2 = eeprom_data[i+1]; |
438 | if (t_format2 == 0) { /* not a TV tuner? */ | 498 | if (t_format2 == 0) { /* not a TV tuner? */ |
439 | tvee->has_radio = 1; /* must be radio */ | 499 | tvee->has_radio = 1; /* must be radio */ |
440 | } | 500 | } |
441 | } | 501 | } |
442 | break; | 502 | break; |
443 | 503 | ||
444 | case 0x0b: | 504 | case 0x0b: |
445 | /* tag 'Inputs': according to Hauppauge this is specific | 505 | /* tag 'Inputs': according to Hauppauge this is specific |
446 | to each driver family, so no good assumptions can be | 506 | to each driver family, so no good assumptions can be |
447 | made. */ | 507 | made. */ |
448 | break; | 508 | break; |
449 | 509 | ||
450 | /* case 0x0c: tag 'Balun' */ | 510 | /* case 0x0c: tag 'Balun' */ |
451 | /* case 0x0d: tag 'Teletext' */ | 511 | /* case 0x0d: tag 'Teletext' */ |
452 | 512 | ||
453 | case 0x0e: | 513 | case 0x0e: |
454 | /* tag: 'Radio' */ | 514 | /* tag: 'Radio' */ |
455 | tvee->has_radio = eeprom_data[i+1]; | 515 | tvee->has_radio = eeprom_data[i+1]; |
456 | break; | 516 | break; |
457 | 517 | ||
458 | case 0x0f: | 518 | case 0x0f: |
459 | /* tag 'IRInfo' */ | 519 | /* tag 'IRInfo' */ |
460 | tvee->has_ir = eeprom_data[i+1]; | 520 | tvee->has_ir = eeprom_data[i+1]; |
461 | break; | 521 | break; |
462 | 522 | ||
463 | /* case 0x10: tag 'VBIInfo' */ | 523 | /* case 0x10: tag 'VBIInfo' */ |
464 | /* case 0x11: tag 'QCInfo' */ | 524 | /* case 0x11: tag 'QCInfo' */ |
465 | /* case 0x12: tag 'InfoBits' */ | 525 | /* case 0x12: tag 'InfoBits' */ |
466 | 526 | ||
467 | default: | 527 | default: |
468 | tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag); | 528 | tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag); |
@@ -483,11 +543,11 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
483 | tvee->rev_str[4] = 0; | 543 | tvee->rev_str[4] = 0; |
484 | } | 544 | } |
485 | 545 | ||
486 | if (hasRadioTuner(tuner1) && !tvee->has_radio) { | 546 | if (hasRadioTuner(tuner1) && !tvee->has_radio) { |
487 | tveeprom_info("The eeprom says no radio is present, but the tuner type\n"); | 547 | tveeprom_info("The eeprom says no radio is present, but the tuner type\n"); |
488 | tveeprom_info("indicates otherwise. I will assume that radio is present.\n"); | 548 | tveeprom_info("indicates otherwise. I will assume that radio is present.\n"); |
489 | tvee->has_radio = 1; | 549 | tvee->has_radio = 1; |
490 | } | 550 | } |
491 | 551 | ||
492 | if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) { | 552 | if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) { |
493 | tvee->tuner_type = hauppauge_tuner[tuner1].id; | 553 | tvee->tuner_type = hauppauge_tuner[tuner1].id; |
@@ -510,45 +570,53 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
510 | tvee->tuner_formats |= hauppauge_tuner_fmt[i].id; | 570 | tvee->tuner_formats |= hauppauge_tuner_fmt[i].id; |
511 | t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name; | 571 | t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name; |
512 | } | 572 | } |
513 | if (t_format2 & (1 << i)) { | 573 | if (t_format2 & (1 << i)) { |
514 | tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id; | 574 | tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id; |
515 | t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name; | 575 | t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name; |
516 | } | 576 | } |
517 | } | 577 | } |
518 | 578 | ||
519 | tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n", | 579 | tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n", |
520 | tvee->model, tvee->rev_str, tvee->serial_number); | 580 | tvee->model, tvee->rev_str, tvee->serial_number); |
521 | tveeprom_info("tuner model is %s (idx %d, type %d)\n", | 581 | tveeprom_info("tuner model is %s (idx %d, type %d)\n", |
522 | t_name1, tuner1, tvee->tuner_type); | 582 | t_name1, tuner1, tvee->tuner_type); |
523 | tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", | 583 | tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", |
524 | t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3], | 584 | t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3], |
525 | t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7], | 585 | t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7], |
526 | t_format1); | 586 | t_format1); |
527 | if (tuner2) { | 587 | if (tuner2) { |
528 | tveeprom_info("second tuner model is %s (idx %d, type %d)\n", | 588 | tveeprom_info("second tuner model is %s (idx %d, type %d)\n", |
529 | t_name2, tuner2, tvee->tuner2_type); | 589 | t_name2, tuner2, tvee->tuner2_type); |
530 | } | 590 | } |
531 | if (t_format2) { | 591 | if (t_format2) { |
532 | tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", | 592 | tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", |
533 | t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3], | 593 | t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3], |
534 | t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7], | 594 | t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7], |
535 | t_format2); | 595 | t_format2); |
536 | } | 596 | } |
537 | tveeprom_info("audio processor is %s (idx %d)\n", | 597 | if (audioic<0) { |
538 | STRM(audioIC, tvee->audio_processor), | 598 | tveeprom_info("audio processor is unknown (no idx)\n"); |
539 | tvee->audio_processor); | 599 | tvee->audio_processor=AUDIO_CHIP_UNKNOWN; |
540 | if (tvee->decoder_processor) { | 600 | } else { |
541 | tveeprom_info("decoder processor is %s (idx %d)\n", | 601 | if (audioic < sizeof(audioIC)/sizeof(*audioIC)) |
542 | STRM(decoderIC, tvee->decoder_processor), | 602 | tveeprom_info("audio processor is %s (idx %d)\n", |
543 | tvee->decoder_processor); | 603 | audioIC[audioic].name,audioic); |
544 | } | 604 | else |
545 | if (tvee->has_ir == 2) | 605 | tveeprom_info("audio processor is unknown (idx %d)\n", |
546 | tveeprom_info("has %sradio\n", | 606 | audioic); |
547 | tvee->has_radio ? "" : "no "); | 607 | } |
548 | else | 608 | if (tvee->decoder_processor) { |
549 | tveeprom_info("has %sradio, has %sIR remote\n", | 609 | tveeprom_info("decoder processor is %s (idx %d)\n", |
550 | tvee->has_radio ? "" : "no ", | 610 | STRM(decoderIC, tvee->decoder_processor), |
551 | tvee->has_ir ? "" : "no "); | 611 | tvee->decoder_processor); |
612 | } | ||
613 | if (tvee->has_ir == 2) | ||
614 | tveeprom_info("has %sradio\n", | ||
615 | tvee->has_radio ? "" : "no "); | ||
616 | else | ||
617 | tveeprom_info("has %sradio, has %sIR remote\n", | ||
618 | tvee->has_radio ? "" : "no ", | ||
619 | tvee->has_ir ? "" : "no "); | ||
552 | } | 620 | } |
553 | EXPORT_SYMBOL(tveeprom_hauppauge_analog); | 621 | EXPORT_SYMBOL(tveeprom_hauppauge_analog); |
554 | 622 | ||
@@ -569,18 +637,18 @@ int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len) | |||
569 | tveeprom_warn("i2c eeprom read error (err=%d)\n", err); | 637 | tveeprom_warn("i2c eeprom read error (err=%d)\n", err); |
570 | return -1; | 638 | return -1; |
571 | } | 639 | } |
572 | if (debug) { | 640 | if (debug) { |
573 | int i; | 641 | int i; |
574 | 642 | ||
575 | tveeprom_info("full 256-byte eeprom dump:\n"); | 643 | tveeprom_info("full 256-byte eeprom dump:\n"); |
576 | for (i = 0; i < len; i++) { | 644 | for (i = 0; i < len; i++) { |
577 | if (0 == (i % 16)) | 645 | if (0 == (i % 16)) |
578 | tveeprom_info("%02x:", i); | 646 | tveeprom_info("%02x:", i); |
579 | printk(" %02x", eedata[i]); | 647 | printk(" %02x", eedata[i]); |
580 | if (15 == (i % 16)) | 648 | if (15 == (i % 16)) |
581 | printk("\n"); | 649 | printk("\n"); |
582 | } | 650 | } |
583 | } | 651 | } |
584 | return 0; | 652 | return 0; |
585 | } | 653 | } |
586 | EXPORT_SYMBOL(tveeprom_read); | 654 | EXPORT_SYMBOL(tveeprom_read); |
@@ -590,10 +658,6 @@ EXPORT_SYMBOL(tveeprom_read); | |||
590 | /* run, just call the exported tveeprom_* directly, there is no point in */ | 658 | /* run, just call the exported tveeprom_* directly, there is no point in */ |
591 | /* using the indirect way via i2c_driver->command() */ | 659 | /* using the indirect way via i2c_driver->command() */ |
592 | 660 | ||
593 | #ifndef I2C_DRIVERID_TVEEPROM | ||
594 | # define I2C_DRIVERID_TVEEPROM I2C_DRIVERID_EXP2 | ||
595 | #endif | ||
596 | |||
597 | static unsigned short normal_i2c[] = { | 661 | static unsigned short normal_i2c[] = { |
598 | 0xa0 >> 1, | 662 | 0xa0 >> 1, |
599 | I2C_CLIENT_END, | 663 | I2C_CLIENT_END, |
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c index d86e08ebddfc..8318bd1aad00 100644 --- a/drivers/media/video/tvmixer.c +++ b/drivers/media/video/tvmixer.c | |||
@@ -79,7 +79,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm | |||
79 | { | 79 | { |
80 | struct video_audio va; | 80 | struct video_audio va; |
81 | int left,right,ret,val = 0; | 81 | int left,right,ret,val = 0; |
82 | struct TVMIXER *mix = file->private_data; | 82 | struct TVMIXER *mix = file->private_data; |
83 | struct i2c_client *client = mix->dev; | 83 | struct i2c_client *client = mix->dev; |
84 | void __user *argp = (void __user *)arg; | 84 | void __user *argp = (void __user *)arg; |
85 | int __user *p = argp; | 85 | int __user *p = argp; |
@@ -87,25 +87,25 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm | |||
87 | if (NULL == client) | 87 | if (NULL == client) |
88 | return -ENODEV; | 88 | return -ENODEV; |
89 | 89 | ||
90 | if (cmd == SOUND_MIXER_INFO) { | 90 | if (cmd == SOUND_MIXER_INFO) { |
91 | mixer_info info; | 91 | mixer_info info; |
92 | strlcpy(info.id, "tv card", sizeof(info.id)); | 92 | strlcpy(info.id, "tv card", sizeof(info.id)); |
93 | strlcpy(info.name, client->name, sizeof(info.name)); | 93 | strlcpy(info.name, client->name, sizeof(info.name)); |
94 | info.modify_counter = 42 /* FIXME */; | 94 | info.modify_counter = 42 /* FIXME */; |
95 | if (copy_to_user(argp, &info, sizeof(info))) | 95 | if (copy_to_user(argp, &info, sizeof(info))) |
96 | return -EFAULT; | 96 | return -EFAULT; |
97 | return 0; | 97 | return 0; |
98 | } | 98 | } |
99 | if (cmd == SOUND_OLD_MIXER_INFO) { | 99 | if (cmd == SOUND_OLD_MIXER_INFO) { |
100 | _old_mixer_info info; | 100 | _old_mixer_info info; |
101 | strlcpy(info.id, "tv card", sizeof(info.id)); | 101 | strlcpy(info.id, "tv card", sizeof(info.id)); |
102 | strlcpy(info.name, client->name, sizeof(info.name)); | 102 | strlcpy(info.name, client->name, sizeof(info.name)); |
103 | if (copy_to_user(argp, &info, sizeof(info))) | 103 | if (copy_to_user(argp, &info, sizeof(info))) |
104 | return -EFAULT; | 104 | return -EFAULT; |
105 | return 0; | 105 | return 0; |
106 | } | 106 | } |
107 | if (cmd == OSS_GETVERSION) | 107 | if (cmd == OSS_GETVERSION) |
108 | return put_user(SOUND_VERSION, p); | 108 | return put_user(SOUND_VERSION, p); |
109 | 109 | ||
110 | if (_SIOC_DIR(cmd) & _SIOC_WRITE) | 110 | if (_SIOC_DIR(cmd) & _SIOC_WRITE) |
111 | if (get_user(val, p)) | 111 | if (get_user(val, p)) |
@@ -181,8 +181,8 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm | |||
181 | 181 | ||
182 | static int tvmixer_open(struct inode *inode, struct file *file) | 182 | static int tvmixer_open(struct inode *inode, struct file *file) |
183 | { | 183 | { |
184 | int i, minor = iminor(inode); | 184 | int i, minor = iminor(inode); |
185 | struct TVMIXER *mix = NULL; | 185 | struct TVMIXER *mix = NULL; |
186 | struct i2c_client *client = NULL; | 186 | struct i2c_client *client = NULL; |
187 | 187 | ||
188 | for (i = 0; i < DEV_MAX; i++) { | 188 | for (i = 0; i < DEV_MAX; i++) { |
@@ -204,7 +204,7 @@ static int tvmixer_open(struct inode *inode, struct file *file) | |||
204 | #endif | 204 | #endif |
205 | if (client->adapter->owner) | 205 | if (client->adapter->owner) |
206 | try_module_get(client->adapter->owner); | 206 | try_module_get(client->adapter->owner); |
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | static int tvmixer_release(struct inode *inode, struct file *file) | 210 | static int tvmixer_release(struct inode *inode, struct file *file) |
@@ -231,15 +231,15 @@ static struct i2c_driver driver = { | |||
231 | .owner = THIS_MODULE, | 231 | .owner = THIS_MODULE, |
232 | #endif | 232 | #endif |
233 | .name = "tv card mixer driver", | 233 | .name = "tv card mixer driver", |
234 | .id = I2C_DRIVERID_TVMIXER, | 234 | .id = I2C_DRIVERID_TVMIXER, |
235 | #ifdef I2C_DF_DUMMY | 235 | #ifdef I2C_DF_DUMMY |
236 | .flags = I2C_DF_DUMMY, | 236 | .flags = I2C_DF_DUMMY, |
237 | #else | 237 | #else |
238 | .flags = I2C_DF_NOTIFY, | 238 | .flags = I2C_DF_NOTIFY, |
239 | .detach_adapter = tvmixer_adapters, | 239 | .detach_adapter = tvmixer_adapters, |
240 | #endif | 240 | #endif |
241 | .attach_adapter = tvmixer_adapters, | 241 | .attach_adapter = tvmixer_adapters, |
242 | .detach_client = tvmixer_clients, | 242 | .detach_client = tvmixer_clients, |
243 | }; | 243 | }; |
244 | 244 | ||
245 | static struct file_operations tvmixer_fops = { | 245 | static struct file_operations tvmixer_fops = { |
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c new file mode 100644 index 000000000000..81e6d4494e7d --- /dev/null +++ b/drivers/media/video/tvp5150.c | |||
@@ -0,0 +1,829 @@ | |||
1 | /* | ||
2 | * tvp5150 - Texas Instruments TVP5150A(M) video decoder driver | ||
3 | * | ||
4 | * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) | ||
5 | * This code is placed under the terms of the GNU General Public License | ||
6 | */ | ||
7 | |||
8 | #include <linux/i2c.h> | ||
9 | #include <linux/videodev.h> | ||
10 | #include <linux/delay.h> | ||
11 | #include <linux/video_decoder.h> | ||
12 | |||
13 | #include "tvp5150_reg.h" | ||
14 | |||
15 | MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); /* standard i2c insmod options */ | ||
16 | MODULE_AUTHOR("Mauro Carvalho Chehab"); | ||
17 | MODULE_LICENSE("GPL"); | ||
18 | |||
19 | static unsigned short normal_i2c[] = { | ||
20 | 0xb8 >> 1, | ||
21 | 0xba >> 1, | ||
22 | I2C_CLIENT_END | ||
23 | }; | ||
24 | |||
25 | I2C_CLIENT_INSMOD; | ||
26 | |||
27 | static int debug = 0; | ||
28 | module_param(debug, int, 0); | ||
29 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | ||
30 | |||
31 | #define dprintk(num, format, args...) \ | ||
32 | do { \ | ||
33 | if (debug >= num) \ | ||
34 | printk(format , ##args); \ | ||
35 | } while (0) | ||
36 | |||
37 | /* supported controls */ | ||
38 | static struct v4l2_queryctrl tvp5150_qctrl[] = { | ||
39 | { | ||
40 | .id = V4L2_CID_BRIGHTNESS, | ||
41 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
42 | .name = "Brightness", | ||
43 | .minimum = 0, | ||
44 | .maximum = 255, | ||
45 | .step = 1, | ||
46 | .default_value = 0, | ||
47 | .flags = 0, | ||
48 | }, { | ||
49 | .id = V4L2_CID_CONTRAST, | ||
50 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
51 | .name = "Contrast", | ||
52 | .minimum = 0, | ||
53 | .maximum = 255, | ||
54 | .step = 0x1, | ||
55 | .default_value = 0x10, | ||
56 | .flags = 0, | ||
57 | }, { | ||
58 | .id = V4L2_CID_SATURATION, | ||
59 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
60 | .name = "Saturation", | ||
61 | .minimum = 0, | ||
62 | .maximum = 255, | ||
63 | .step = 0x1, | ||
64 | .default_value = 0x10, | ||
65 | .flags = 0, | ||
66 | }, { | ||
67 | .id = V4L2_CID_HUE, | ||
68 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
69 | .name = "Hue", | ||
70 | .minimum = -128, | ||
71 | .maximum = 127, | ||
72 | .step = 0x1, | ||
73 | .default_value = 0x10, | ||
74 | .flags = 0, | ||
75 | } | ||
76 | }; | ||
77 | |||
78 | struct tvp5150 { | ||
79 | struct i2c_client *client; | ||
80 | |||
81 | int norm; | ||
82 | int input; | ||
83 | int enable; | ||
84 | int bright; | ||
85 | int contrast; | ||
86 | int hue; | ||
87 | int sat; | ||
88 | }; | ||
89 | |||
90 | static inline int tvp5150_read(struct i2c_client *c, unsigned char addr) | ||
91 | { | ||
92 | unsigned char buffer[1]; | ||
93 | int rc; | ||
94 | |||
95 | buffer[0] = addr; | ||
96 | if (1 != (rc = i2c_master_send(c, buffer, 1))) | ||
97 | dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc); | ||
98 | |||
99 | msleep(10); | ||
100 | |||
101 | if (1 != (rc = i2c_master_recv(c, buffer, 1))) | ||
102 | dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc); | ||
103 | |||
104 | return (buffer[0]); | ||
105 | } | ||
106 | |||
107 | static inline void tvp5150_write(struct i2c_client *c, unsigned char addr, | ||
108 | unsigned char value) | ||
109 | { | ||
110 | unsigned char buffer[2]; | ||
111 | int rc; | ||
112 | /* struct tvp5150 *core = i2c_get_clientdata(c); */ | ||
113 | |||
114 | buffer[0] = addr; | ||
115 | buffer[1] = value; | ||
116 | dprintk(1, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]); | ||
117 | if (2 != (rc = i2c_master_send(c, buffer, 2))) | ||
118 | dprintk(0, "i2c i/o error: rc == %d (should be 2)\n", rc); | ||
119 | } | ||
120 | |||
121 | static void dump_reg(struct i2c_client *c) | ||
122 | { | ||
123 | printk("tvp5150: Video input source selection #1 = 0x%02x\n", | ||
124 | tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1)); | ||
125 | printk("tvp5150: Analog channel controls = 0x%02x\n", | ||
126 | tvp5150_read(c, TVP5150_ANAL_CHL_CTL)); | ||
127 | printk("tvp5150: Operation mode controls = 0x%02x\n", | ||
128 | tvp5150_read(c, TVP5150_OP_MODE_CTL)); | ||
129 | printk("tvp5150: Miscellaneous controls = 0x%02x\n", | ||
130 | tvp5150_read(c, TVP5150_MISC_CTL)); | ||
131 | printk("tvp5150: Autoswitch mask: TVP5150A / TVP5150AM = 0x%02x\n", | ||
132 | tvp5150_read(c, TVP5150_AUTOSW_MSK)); | ||
133 | printk("tvp5150: Color killer threshold control = 0x%02x\n", | ||
134 | tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL)); | ||
135 | printk("tvp5150: Luminance processing control #1 = 0x%02x\n", | ||
136 | tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1)); | ||
137 | printk("tvp5150: Luminance processing control #2 = 0x%02x\n", | ||
138 | tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2)); | ||
139 | printk("tvp5150: Brightness control = 0x%02x\n", | ||
140 | tvp5150_read(c, TVP5150_BRIGHT_CTL)); | ||
141 | printk("tvp5150: Color saturation control = 0x%02x\n", | ||
142 | tvp5150_read(c, TVP5150_SATURATION_CTL)); | ||
143 | printk("tvp5150: Hue control = 0x%02x\n", | ||
144 | tvp5150_read(c, TVP5150_HUE_CTL)); | ||
145 | printk("tvp5150: Contrast control = 0x%02x\n", | ||
146 | tvp5150_read(c, TVP5150_CONTRAST_CTL)); | ||
147 | printk("tvp5150: Outputs and data rates select = 0x%02x\n", | ||
148 | tvp5150_read(c, TVP5150_DATA_RATE_SEL)); | ||
149 | printk("tvp5150: Luminance processing control #3 = 0x%02x\n", | ||
150 | tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3)); | ||
151 | printk("tvp5150: Configuration shared pins = 0x%02x\n", | ||
152 | tvp5150_read(c, TVP5150_CONF_SHARED_PIN)); | ||
153 | printk("tvp5150: Active video cropping start MSB = 0x%02x\n", | ||
154 | tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB)); | ||
155 | printk("tvp5150: Active video cropping start LSB = 0x%02x\n", | ||
156 | tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB)); | ||
157 | printk("tvp5150: Active video cropping stop MSB = 0x%02x\n", | ||
158 | tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB)); | ||
159 | printk("tvp5150: Active video cropping stop LSB = 0x%02x\n", | ||
160 | tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB)); | ||
161 | printk("tvp5150: Genlock/RTC = 0x%02x\n", | ||
162 | tvp5150_read(c, TVP5150_GENLOCK)); | ||
163 | printk("tvp5150: Horizontal sync start = 0x%02x\n", | ||
164 | tvp5150_read(c, TVP5150_HORIZ_SYNC_START)); | ||
165 | printk("tvp5150: Vertical blanking start = 0x%02x\n", | ||
166 | tvp5150_read(c, TVP5150_VERT_BLANKING_START)); | ||
167 | printk("tvp5150: Vertical blanking stop = 0x%02x\n", | ||
168 | tvp5150_read(c, TVP5150_VERT_BLANKING_STOP)); | ||
169 | printk("tvp5150: Chrominance processing control #1 = 0x%02x\n", | ||
170 | tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1)); | ||
171 | printk("tvp5150: Chrominance processing control #2 = 0x%02x\n", | ||
172 | tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2)); | ||
173 | printk("tvp5150: Interrupt reset register B = 0x%02x\n", | ||
174 | tvp5150_read(c, TVP5150_INT_RESET_REG_B)); | ||
175 | printk("tvp5150: Interrupt enable register B = 0x%02x\n", | ||
176 | tvp5150_read(c, TVP5150_INT_ENABLE_REG_B)); | ||
177 | printk("tvp5150: Interrupt configuration register B = 0x%02x\n", | ||
178 | tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B)); | ||
179 | printk("tvp5150: Video standard = 0x%02x\n", | ||
180 | tvp5150_read(c, TVP5150_VIDEO_STD)); | ||
181 | printk("tvp5150: Cb gain factor = 0x%02x\n", | ||
182 | tvp5150_read(c, TVP5150_CB_GAIN_FACT)); | ||
183 | printk("tvp5150: Cr gain factor = 0x%02x\n", | ||
184 | tvp5150_read(c, TVP5150_CR_GAIN_FACTOR)); | ||
185 | printk("tvp5150: Macrovision on counter = 0x%02x\n", | ||
186 | tvp5150_read(c, TVP5150_MACROVISION_ON_CTR)); | ||
187 | printk("tvp5150: Macrovision off counter = 0x%02x\n", | ||
188 | tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR)); | ||
189 | printk("tvp5150: revision select (TVP5150AM1 only) = 0x%02x\n", | ||
190 | tvp5150_read(c, TVP5150_REV_SELECT)); | ||
191 | printk("tvp5150: MSB of device ID = 0x%02x\n", | ||
192 | tvp5150_read(c, TVP5150_MSB_DEV_ID)); | ||
193 | printk("tvp5150: LSB of device ID = 0x%02x\n", | ||
194 | tvp5150_read(c, TVP5150_LSB_DEV_ID)); | ||
195 | printk("tvp5150: ROM major version = 0x%02x\n", | ||
196 | tvp5150_read(c, TVP5150_ROM_MAJOR_VER)); | ||
197 | printk("tvp5150: ROM minor version = 0x%02x\n", | ||
198 | tvp5150_read(c, TVP5150_ROM_MINOR_VER)); | ||
199 | printk("tvp5150: Vertical line count MSB = 0x%02x\n", | ||
200 | tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB)); | ||
201 | printk("tvp5150: Vertical line count LSB = 0x%02x\n", | ||
202 | tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB)); | ||
203 | printk("tvp5150: Interrupt status register B = 0x%02x\n", | ||
204 | tvp5150_read(c, TVP5150_INT_STATUS_REG_B)); | ||
205 | printk("tvp5150: Interrupt active register B = 0x%02x\n", | ||
206 | tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B)); | ||
207 | printk("tvp5150: Status register #1 = 0x%02x\n", | ||
208 | tvp5150_read(c, TVP5150_STATUS_REG_1)); | ||
209 | printk("tvp5150: Status register #2 = 0x%02x\n", | ||
210 | tvp5150_read(c, TVP5150_STATUS_REG_2)); | ||
211 | printk("tvp5150: Status register #3 = 0x%02x\n", | ||
212 | tvp5150_read(c, TVP5150_STATUS_REG_3)); | ||
213 | printk("tvp5150: Status register #4 = 0x%02x\n", | ||
214 | tvp5150_read(c, TVP5150_STATUS_REG_4)); | ||
215 | printk("tvp5150: Status register #5 = 0x%02x\n", | ||
216 | tvp5150_read(c, TVP5150_STATUS_REG_5)); | ||
217 | printk("tvp5150: Closed caption data registers = 0x%02x\n", | ||
218 | tvp5150_read(c, TVP5150_CC_DATA_REG1)); | ||
219 | printk("tvp5150: Closed caption data registers = 0x%02x\n", | ||
220 | tvp5150_read(c, TVP5150_CC_DATA_REG2)); | ||
221 | printk("tvp5150: Closed caption data registers = 0x%02x\n", | ||
222 | tvp5150_read(c, TVP5150_CC_DATA_REG3)); | ||
223 | printk("tvp5150: Closed caption data registers = 0x%02x\n", | ||
224 | tvp5150_read(c, TVP5150_CC_DATA_REG4)); | ||
225 | printk("tvp5150: WSS data registers = 0x%02x\n", | ||
226 | tvp5150_read(c, TVP5150_WSS_DATA_REG1)); | ||
227 | printk("tvp5150: WSS data registers = 0x%02x\n", | ||
228 | tvp5150_read(c, TVP5150_WSS_DATA_REG2)); | ||
229 | printk("tvp5150: WSS data registers = 0x%02x\n", | ||
230 | tvp5150_read(c, TVP5150_WSS_DATA_REG3)); | ||
231 | printk("tvp5150: WSS data registers = 0x%02x\n", | ||
232 | tvp5150_read(c, TVP5150_WSS_DATA_REG4)); | ||
233 | printk("tvp5150: WSS data registers = 0x%02x\n", | ||
234 | tvp5150_read(c, TVP5150_WSS_DATA_REG5)); | ||
235 | printk("tvp5150: WSS data registers = 0x%02x\n", | ||
236 | tvp5150_read(c, TVP5150_WSS_DATA_REG6)); | ||
237 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
238 | tvp5150_read(c, TVP5150_VPS_DATA_REG1)); | ||
239 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
240 | tvp5150_read(c, TVP5150_VPS_DATA_REG2)); | ||
241 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
242 | tvp5150_read(c, TVP5150_VPS_DATA_REG3)); | ||
243 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
244 | tvp5150_read(c, TVP5150_VPS_DATA_REG4)); | ||
245 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
246 | tvp5150_read(c, TVP5150_VPS_DATA_REG5)); | ||
247 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
248 | tvp5150_read(c, TVP5150_VPS_DATA_REG6)); | ||
249 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
250 | tvp5150_read(c, TVP5150_VPS_DATA_REG7)); | ||
251 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
252 | tvp5150_read(c, TVP5150_VPS_DATA_REG8)); | ||
253 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
254 | tvp5150_read(c, TVP5150_VPS_DATA_REG9)); | ||
255 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
256 | tvp5150_read(c, TVP5150_VPS_DATA_REG10)); | ||
257 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
258 | tvp5150_read(c, TVP5150_VPS_DATA_REG11)); | ||
259 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
260 | tvp5150_read(c, TVP5150_VPS_DATA_REG12)); | ||
261 | printk("tvp5150: VPS data registers = 0x%02x\n", | ||
262 | tvp5150_read(c, TVP5150_VPS_DATA_REG13)); | ||
263 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
264 | tvp5150_read(c, TVP5150_VITC_DATA_REG1)); | ||
265 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
266 | tvp5150_read(c, TVP5150_VITC_DATA_REG2)); | ||
267 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
268 | tvp5150_read(c, TVP5150_VITC_DATA_REG3)); | ||
269 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
270 | tvp5150_read(c, TVP5150_VITC_DATA_REG4)); | ||
271 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
272 | tvp5150_read(c, TVP5150_VITC_DATA_REG5)); | ||
273 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
274 | tvp5150_read(c, TVP5150_VITC_DATA_REG6)); | ||
275 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
276 | tvp5150_read(c, TVP5150_VITC_DATA_REG7)); | ||
277 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
278 | tvp5150_read(c, TVP5150_VITC_DATA_REG8)); | ||
279 | printk("tvp5150: VITC data registers = 0x%02x\n", | ||
280 | tvp5150_read(c, TVP5150_VITC_DATA_REG9)); | ||
281 | printk("tvp5150: VBI FIFO read data = 0x%02x\n", | ||
282 | tvp5150_read(c, TVP5150_VBI_FIFO_READ_DATA)); | ||
283 | printk("tvp5150: Teletext filter 1 = 0x%02x\n", | ||
284 | tvp5150_read(c, TVP5150_TELETEXT_FIL_1_1)); | ||
285 | printk("tvp5150: Teletext filter 1 = 0x%02x\n", | ||
286 | tvp5150_read(c, TVP5150_TELETEXT_FIL_1_2)); | ||
287 | printk("tvp5150: Teletext filter 1 = 0x%02x\n", | ||
288 | tvp5150_read(c, TVP5150_TELETEXT_FIL_1_3)); | ||
289 | printk("tvp5150: Teletext filter 1 = 0x%02x\n", | ||
290 | tvp5150_read(c, TVP5150_TELETEXT_FIL_1_4)); | ||
291 | printk("tvp5150: Teletext filter 1 = 0x%02x\n", | ||
292 | tvp5150_read(c, TVP5150_TELETEXT_FIL_1_5)); | ||
293 | printk("tvp5150: Teletext filter 2 = 0x%02x\n", | ||
294 | tvp5150_read(c, TVP5150_TELETEXT_FIL_2_1)); | ||
295 | printk("tvp5150: Teletext filter 2 = 0x%02x\n", | ||
296 | tvp5150_read(c, TVP5150_TELETEXT_FIL_2_2)); | ||
297 | printk("tvp5150: Teletext filter 2 = 0x%02x\n", | ||
298 | tvp5150_read(c, TVP5150_TELETEXT_FIL_2_3)); | ||
299 | printk("tvp5150: Teletext filter 2 = 0x%02x\n", | ||
300 | tvp5150_read(c, TVP5150_TELETEXT_FIL_2_4)); | ||
301 | printk("tvp5150: Teletext filter 2 = 0x%02x\n", | ||
302 | tvp5150_read(c, TVP5150_TELETEXT_FIL_2_5)); | ||
303 | printk("tvp5150: Teletext filter enable = 0x%02x\n", | ||
304 | tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA)); | ||
305 | printk("tvp5150: Interrupt status register A = 0x%02x\n", | ||
306 | tvp5150_read(c, TVP5150_INT_STATUS_REG_A)); | ||
307 | printk("tvp5150: Interrupt enable register A = 0x%02x\n", | ||
308 | tvp5150_read(c, TVP5150_INT_ENABLE_REG_A)); | ||
309 | printk("tvp5150: Interrupt configuration = 0x%02x\n", | ||
310 | tvp5150_read(c, TVP5150_INT_CONF)); | ||
311 | printk("tvp5150: VDP configuration RAM data = 0x%02x\n", | ||
312 | tvp5150_read(c, TVP5150_VDP_CONF_RAM_DATA)); | ||
313 | printk("tvp5150: Configuration RAM address low byte = 0x%02x\n", | ||
314 | tvp5150_read(c, TVP5150_CONF_RAM_ADDR_LOW)); | ||
315 | printk("tvp5150: Configuration RAM address high byte = 0x%02x\n", | ||
316 | tvp5150_read(c, TVP5150_CONF_RAM_ADDR_HIGH)); | ||
317 | printk("tvp5150: VDP status register = 0x%02x\n", | ||
318 | tvp5150_read(c, TVP5150_VDP_STATUS_REG)); | ||
319 | printk("tvp5150: FIFO word count = 0x%02x\n", | ||
320 | tvp5150_read(c, TVP5150_FIFO_WORD_COUNT)); | ||
321 | printk("tvp5150: FIFO interrupt threshold = 0x%02x\n", | ||
322 | tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD)); | ||
323 | printk("tvp5150: FIFO reset = 0x%02x\n", | ||
324 | tvp5150_read(c, TVP5150_FIFO_RESET)); | ||
325 | printk("tvp5150: Line number interrupt = 0x%02x\n", | ||
326 | tvp5150_read(c, TVP5150_LINE_NUMBER_INT)); | ||
327 | printk("tvp5150: Pixel alignment register low byte = 0x%02x\n", | ||
328 | tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW)); | ||
329 | printk("tvp5150: Pixel alignment register high byte = 0x%02x\n", | ||
330 | tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH)); | ||
331 | printk("tvp5150: FIFO output control = 0x%02x\n", | ||
332 | tvp5150_read(c, TVP5150_FIFO_OUT_CTRL)); | ||
333 | printk("tvp5150: Full field enable 1 = 0x%02x\n", | ||
334 | tvp5150_read(c, TVP5150_FULL_FIELD_ENA_1)); | ||
335 | printk("tvp5150: Full field enable 2 = 0x%02x\n", | ||
336 | tvp5150_read(c, TVP5150_FULL_FIELD_ENA_2)); | ||
337 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
338 | tvp5150_read(c, TVP5150_LINE_MODE_REG_1)); | ||
339 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
340 | tvp5150_read(c, TVP5150_LINE_MODE_REG_2)); | ||
341 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
342 | tvp5150_read(c, TVP5150_LINE_MODE_REG_3)); | ||
343 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
344 | tvp5150_read(c, TVP5150_LINE_MODE_REG_4)); | ||
345 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
346 | tvp5150_read(c, TVP5150_LINE_MODE_REG_5)); | ||
347 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
348 | tvp5150_read(c, TVP5150_LINE_MODE_REG_6)); | ||
349 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
350 | tvp5150_read(c, TVP5150_LINE_MODE_REG_7)); | ||
351 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
352 | tvp5150_read(c, TVP5150_LINE_MODE_REG_8)); | ||
353 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
354 | tvp5150_read(c, TVP5150_LINE_MODE_REG_9)); | ||
355 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
356 | tvp5150_read(c, TVP5150_LINE_MODE_REG_10)); | ||
357 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
358 | tvp5150_read(c, TVP5150_LINE_MODE_REG_11)); | ||
359 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
360 | tvp5150_read(c, TVP5150_LINE_MODE_REG_12)); | ||
361 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
362 | tvp5150_read(c, TVP5150_LINE_MODE_REG_13)); | ||
363 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
364 | tvp5150_read(c, TVP5150_LINE_MODE_REG_14)); | ||
365 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
366 | tvp5150_read(c, TVP5150_LINE_MODE_REG_15)); | ||
367 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
368 | tvp5150_read(c, TVP5150_LINE_MODE_REG_16)); | ||
369 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
370 | tvp5150_read(c, TVP5150_LINE_MODE_REG_17)); | ||
371 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
372 | tvp5150_read(c, TVP5150_LINE_MODE_REG_18)); | ||
373 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
374 | tvp5150_read(c, TVP5150_LINE_MODE_REG_19)); | ||
375 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
376 | tvp5150_read(c, TVP5150_LINE_MODE_REG_20)); | ||
377 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
378 | tvp5150_read(c, TVP5150_LINE_MODE_REG_21)); | ||
379 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
380 | tvp5150_read(c, TVP5150_LINE_MODE_REG_22)); | ||
381 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
382 | tvp5150_read(c, TVP5150_LINE_MODE_REG_23)); | ||
383 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
384 | tvp5150_read(c, TVP5150_LINE_MODE_REG_24)); | ||
385 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
386 | tvp5150_read(c, TVP5150_LINE_MODE_REG_25)); | ||
387 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
388 | tvp5150_read(c, TVP5150_LINE_MODE_REG_27)); | ||
389 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
390 | tvp5150_read(c, TVP5150_LINE_MODE_REG_28)); | ||
391 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
392 | tvp5150_read(c, TVP5150_LINE_MODE_REG_29)); | ||
393 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
394 | tvp5150_read(c, TVP5150_LINE_MODE_REG_30)); | ||
395 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
396 | tvp5150_read(c, TVP5150_LINE_MODE_REG_31)); | ||
397 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
398 | tvp5150_read(c, TVP5150_LINE_MODE_REG_32)); | ||
399 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
400 | tvp5150_read(c, TVP5150_LINE_MODE_REG_33)); | ||
401 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
402 | tvp5150_read(c, TVP5150_LINE_MODE_REG_34)); | ||
403 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
404 | tvp5150_read(c, TVP5150_LINE_MODE_REG_35)); | ||
405 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
406 | tvp5150_read(c, TVP5150_LINE_MODE_REG_36)); | ||
407 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
408 | tvp5150_read(c, TVP5150_LINE_MODE_REG_37)); | ||
409 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
410 | tvp5150_read(c, TVP5150_LINE_MODE_REG_38)); | ||
411 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
412 | tvp5150_read(c, TVP5150_LINE_MODE_REG_39)); | ||
413 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
414 | tvp5150_read(c, TVP5150_LINE_MODE_REG_40)); | ||
415 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
416 | tvp5150_read(c, TVP5150_LINE_MODE_REG_41)); | ||
417 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
418 | tvp5150_read(c, TVP5150_LINE_MODE_REG_42)); | ||
419 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
420 | tvp5150_read(c, TVP5150_LINE_MODE_REG_43)); | ||
421 | printk("tvp5150: Line mode registers = 0x%02x\n", | ||
422 | tvp5150_read(c, TVP5150_LINE_MODE_REG_44)); | ||
423 | printk("tvp5150: Full field mode register = 0x%02x\n", | ||
424 | tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG)); | ||
425 | } | ||
426 | |||
427 | /**************************************************************************** | ||
428 | Basic functions | ||
429 | ****************************************************************************/ | ||
430 | enum tvp5150_input { | ||
431 | TVP5150_ANALOG_CH0 = 0, | ||
432 | TVP5150_SVIDEO = 1, | ||
433 | TVP5150_ANALOG_CH1 = 2, | ||
434 | TVP5150_BLACK_SCREEN = 8 | ||
435 | }; | ||
436 | |||
437 | static inline void tvp5150_selmux(struct i2c_client *c, | ||
438 | enum tvp5150_input input) | ||
439 | { | ||
440 | struct tvp5150 *decoder = i2c_get_clientdata(c); | ||
441 | |||
442 | if (!decoder->enable) | ||
443 | input |= TVP5150_BLACK_SCREEN; | ||
444 | |||
445 | tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input); | ||
446 | }; | ||
447 | |||
448 | static inline void tvp5150_reset(struct i2c_client *c) | ||
449 | { | ||
450 | struct tvp5150 *decoder = i2c_get_clientdata(c); | ||
451 | |||
452 | tvp5150_write(c, TVP5150_CONF_SHARED_PIN, 2); | ||
453 | |||
454 | /* Automatic offset and AGC enabled */ | ||
455 | tvp5150_write(c, TVP5150_ANAL_CHL_CTL, 0x15); | ||
456 | |||
457 | /* Normal Operation */ | ||
458 | // tvp5150_write(c, TVP5150_OP_MODE_CTL, 0x00); | ||
459 | |||
460 | /* Activate YCrCb output 0x9 or 0xd ? */ | ||
461 | tvp5150_write(c, TVP5150_MISC_CTL, 0x6f); | ||
462 | |||
463 | /* Activates video std autodetection for all standards */ | ||
464 | tvp5150_write(c, TVP5150_AUTOSW_MSK, 0x0); | ||
465 | |||
466 | /* Default format: 0x47, 4:2:2: 0x40 */ | ||
467 | tvp5150_write(c, TVP5150_DATA_RATE_SEL, 0x47); | ||
468 | |||
469 | tvp5150_selmux(c, decoder->input); | ||
470 | |||
471 | tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_1, 0x0c); | ||
472 | tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_2, 0x54); | ||
473 | |||
474 | tvp5150_write(c, 0x27, 0x20); /* ?????????? */ | ||
475 | |||
476 | tvp5150_write(c, TVP5150_VIDEO_STD, 0x0); /* Auto switch */ | ||
477 | |||
478 | tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8); | ||
479 | tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8); | ||
480 | tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8); | ||
481 | tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8); | ||
482 | }; | ||
483 | |||
484 | static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) | ||
485 | { | ||
486 | /* struct tvp5150 *decoder = i2c_get_clientdata(c); */ | ||
487 | |||
488 | switch (ctrl->id) { | ||
489 | case V4L2_CID_BRIGHTNESS: | ||
490 | ctrl->value = tvp5150_read(c, TVP5150_BRIGHT_CTL); | ||
491 | return 0; | ||
492 | case V4L2_CID_CONTRAST: | ||
493 | ctrl->value = tvp5150_read(c, TVP5150_CONTRAST_CTL); | ||
494 | return 0; | ||
495 | case V4L2_CID_SATURATION: | ||
496 | ctrl->value = tvp5150_read(c, TVP5150_SATURATION_CTL); | ||
497 | return 0; | ||
498 | case V4L2_CID_HUE: | ||
499 | ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL); | ||
500 | return 0; | ||
501 | default: | ||
502 | return -EINVAL; | ||
503 | } | ||
504 | } | ||
505 | |||
506 | static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) | ||
507 | { | ||
508 | /* struct tvp5150 *decoder = i2c_get_clientdata(c); */ | ||
509 | |||
510 | switch (ctrl->id) { | ||
511 | case V4L2_CID_BRIGHTNESS: | ||
512 | tvp5150_write(c, TVP5150_BRIGHT_CTL, ctrl->value); | ||
513 | return 0; | ||
514 | case V4L2_CID_CONTRAST: | ||
515 | tvp5150_write(c, TVP5150_CONTRAST_CTL, ctrl->value); | ||
516 | return 0; | ||
517 | case V4L2_CID_SATURATION: | ||
518 | tvp5150_write(c, TVP5150_SATURATION_CTL, ctrl->value); | ||
519 | return 0; | ||
520 | case V4L2_CID_HUE: | ||
521 | tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value); | ||
522 | return 0; | ||
523 | default: | ||
524 | return -EINVAL; | ||
525 | } | ||
526 | } | ||
527 | |||
528 | /**************************************************************************** | ||
529 | I2C Command | ||
530 | ****************************************************************************/ | ||
531 | static int tvp5150_command(struct i2c_client *client, | ||
532 | unsigned int cmd, void *arg) | ||
533 | { | ||
534 | struct tvp5150 *decoder = i2c_get_clientdata(client); | ||
535 | |||
536 | switch (cmd) { | ||
537 | |||
538 | case 0: | ||
539 | case DECODER_INIT: | ||
540 | tvp5150_reset(client); | ||
541 | break; | ||
542 | |||
543 | case DECODER_DUMP: | ||
544 | dump_reg(client); | ||
545 | break; | ||
546 | |||
547 | case DECODER_GET_CAPABILITIES: | ||
548 | { | ||
549 | struct video_decoder_capability *cap = arg; | ||
550 | |||
551 | cap->flags = VIDEO_DECODER_PAL | | ||
552 | VIDEO_DECODER_NTSC | | ||
553 | VIDEO_DECODER_SECAM | | ||
554 | VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR; | ||
555 | cap->inputs = 3; | ||
556 | cap->outputs = 1; | ||
557 | break; | ||
558 | } | ||
559 | case DECODER_GET_STATUS: | ||
560 | { | ||
561 | break; | ||
562 | } | ||
563 | |||
564 | case DECODER_SET_GPIO: | ||
565 | break; | ||
566 | |||
567 | case DECODER_SET_VBI_BYPASS: | ||
568 | break; | ||
569 | |||
570 | case DECODER_SET_NORM: | ||
571 | { | ||
572 | int *iarg = arg; | ||
573 | |||
574 | switch (*iarg) { | ||
575 | |||
576 | case VIDEO_MODE_NTSC: | ||
577 | break; | ||
578 | |||
579 | case VIDEO_MODE_PAL: | ||
580 | break; | ||
581 | |||
582 | case VIDEO_MODE_SECAM: | ||
583 | break; | ||
584 | |||
585 | case VIDEO_MODE_AUTO: | ||
586 | break; | ||
587 | |||
588 | default: | ||
589 | return -EINVAL; | ||
590 | |||
591 | } | ||
592 | decoder->norm = *iarg; | ||
593 | break; | ||
594 | } | ||
595 | case DECODER_SET_INPUT: | ||
596 | { | ||
597 | int *iarg = arg; | ||
598 | if (*iarg < 0 || *iarg > 3) { | ||
599 | return -EINVAL; | ||
600 | } | ||
601 | |||
602 | decoder->input = *iarg; | ||
603 | tvp5150_selmux(client, decoder->input); | ||
604 | |||
605 | break; | ||
606 | } | ||
607 | case DECODER_SET_OUTPUT: | ||
608 | { | ||
609 | int *iarg = arg; | ||
610 | |||
611 | /* not much choice of outputs */ | ||
612 | if (*iarg != 0) { | ||
613 | return -EINVAL; | ||
614 | } | ||
615 | break; | ||
616 | } | ||
617 | case DECODER_ENABLE_OUTPUT: | ||
618 | { | ||
619 | int *iarg = arg; | ||
620 | |||
621 | decoder->enable = (*iarg != 0); | ||
622 | |||
623 | tvp5150_selmux(client, decoder->input); | ||
624 | |||
625 | break; | ||
626 | } | ||
627 | case VIDIOC_QUERYCTRL: | ||
628 | { | ||
629 | struct v4l2_queryctrl *qc = arg; | ||
630 | u8 i, n; | ||
631 | |||
632 | dprintk(1, KERN_DEBUG "VIDIOC_QUERYCTRL"); | ||
633 | |||
634 | n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]); | ||
635 | for (i = 0; i < n; i++) | ||
636 | if (qc->id && qc->id == tvp5150_qctrl[i].id) { | ||
637 | memcpy(qc, &(tvp5150_qctrl[i]), | ||
638 | sizeof(*qc)); | ||
639 | return 0; | ||
640 | } | ||
641 | |||
642 | return -EINVAL; | ||
643 | } | ||
644 | case VIDIOC_G_CTRL: | ||
645 | { | ||
646 | struct v4l2_control *ctrl = arg; | ||
647 | dprintk(1, KERN_DEBUG "VIDIOC_G_CTRL"); | ||
648 | |||
649 | return tvp5150_get_ctrl(client, ctrl); | ||
650 | } | ||
651 | case VIDIOC_S_CTRL_OLD: /* ??? */ | ||
652 | case VIDIOC_S_CTRL: | ||
653 | { | ||
654 | struct v4l2_control *ctrl = arg; | ||
655 | u8 i, n; | ||
656 | dprintk(1, KERN_DEBUG "VIDIOC_S_CTRL"); | ||
657 | n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]); | ||
658 | for (i = 0; i < n; i++) | ||
659 | if (ctrl->id == tvp5150_qctrl[i].id) { | ||
660 | if (ctrl->value < | ||
661 | tvp5150_qctrl[i].minimum | ||
662 | || ctrl->value > | ||
663 | tvp5150_qctrl[i].maximum) | ||
664 | return -ERANGE; | ||
665 | dprintk(1, | ||
666 | KERN_DEBUG | ||
667 | "VIDIOC_S_CTRL: id=%d, value=%d", | ||
668 | ctrl->id, ctrl->value); | ||
669 | return tvp5150_set_ctrl(client, ctrl); | ||
670 | } | ||
671 | return -EINVAL; | ||
672 | } | ||
673 | |||
674 | case DECODER_SET_PICTURE: | ||
675 | { | ||
676 | struct video_picture *pic = arg; | ||
677 | if (decoder->bright != pic->brightness) { | ||
678 | /* We want 0 to 255 we get 0-65535 */ | ||
679 | decoder->bright = pic->brightness; | ||
680 | tvp5150_write(client, TVP5150_BRIGHT_CTL, | ||
681 | decoder->bright >> 8); | ||
682 | } | ||
683 | if (decoder->contrast != pic->contrast) { | ||
684 | /* We want 0 to 255 we get 0-65535 */ | ||
685 | decoder->contrast = pic->contrast; | ||
686 | tvp5150_write(client, TVP5150_CONTRAST_CTL, | ||
687 | decoder->contrast >> 8); | ||
688 | } | ||
689 | if (decoder->sat != pic->colour) { | ||
690 | /* We want 0 to 255 we get 0-65535 */ | ||
691 | decoder->sat = pic->colour; | ||
692 | tvp5150_write(client, TVP5150_SATURATION_CTL, | ||
693 | decoder->contrast >> 8); | ||
694 | } | ||
695 | if (decoder->hue != pic->hue) { | ||
696 | /* We want -128 to 127 we get 0-65535 */ | ||
697 | decoder->hue = pic->hue; | ||
698 | tvp5150_write(client, TVP5150_HUE_CTL, | ||
699 | (decoder->hue - 32768) >> 8); | ||
700 | } | ||
701 | break; | ||
702 | } | ||
703 | default: | ||
704 | return -EINVAL; | ||
705 | } | ||
706 | |||
707 | return 0; | ||
708 | } | ||
709 | |||
710 | /**************************************************************************** | ||
711 | I2C Client & Driver | ||
712 | ****************************************************************************/ | ||
713 | static struct i2c_driver driver; | ||
714 | |||
715 | static struct i2c_client client_template = { | ||
716 | .name = "(unset)", | ||
717 | .flags = I2C_CLIENT_ALLOW_USE, | ||
718 | .driver = &driver, | ||
719 | }; | ||
720 | |||
721 | static int tvp5150_detect_client(struct i2c_adapter *adapter, | ||
722 | int address, int kind) | ||
723 | { | ||
724 | struct i2c_client *client; | ||
725 | struct tvp5150 *core; | ||
726 | int rv; | ||
727 | |||
728 | dprintk(1, | ||
729 | KERN_INFO | ||
730 | "tvp5150.c: detecting tvp5150 client on address 0x%x\n", | ||
731 | address << 1); | ||
732 | |||
733 | client_template.adapter = adapter; | ||
734 | client_template.addr = address; | ||
735 | |||
736 | /* Check if the adapter supports the needed features */ | ||
737 | if (!i2c_check_functionality | ||
738 | (adapter, | ||
739 | I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | ||
740 | return 0; | ||
741 | |||
742 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
743 | if (client == 0) | ||
744 | return -ENOMEM; | ||
745 | memcpy(client, &client_template, sizeof(struct i2c_client)); | ||
746 | |||
747 | core = kmalloc(sizeof(struct tvp5150), GFP_KERNEL); | ||
748 | if (core == 0) { | ||
749 | kfree(client); | ||
750 | return -ENOMEM; | ||
751 | } | ||
752 | memset(core, 0, sizeof(struct tvp5150)); | ||
753 | i2c_set_clientdata(client, core); | ||
754 | |||
755 | rv = i2c_attach_client(client); | ||
756 | |||
757 | core->norm = VIDEO_MODE_AUTO; | ||
758 | core->input = 2; | ||
759 | core->enable = 1; | ||
760 | core->bright = 32768; | ||
761 | core->contrast = 32768; | ||
762 | core->hue = 32768; | ||
763 | core->sat = 32768; | ||
764 | |||
765 | if (rv) { | ||
766 | kfree(client); | ||
767 | kfree(core); | ||
768 | return rv; | ||
769 | } | ||
770 | |||
771 | if (debug > 1) | ||
772 | dump_reg(client); | ||
773 | |||
774 | return 0; | ||
775 | } | ||
776 | |||
777 | static int tvp5150_attach_adapter(struct i2c_adapter *adapter) | ||
778 | { | ||
779 | dprintk(1, | ||
780 | KERN_INFO | ||
781 | "tvp5150.c: starting probe for adapter %s (0x%x)\n", | ||
782 | adapter->name, adapter->id); | ||
783 | return i2c_probe(adapter, &addr_data, &tvp5150_detect_client); | ||
784 | } | ||
785 | |||
786 | static int tvp5150_detach_client(struct i2c_client *client) | ||
787 | { | ||
788 | struct tvp5150 *decoder = i2c_get_clientdata(client); | ||
789 | int err; | ||
790 | |||
791 | err = i2c_detach_client(client); | ||
792 | if (err) { | ||
793 | return err; | ||
794 | } | ||
795 | |||
796 | kfree(decoder); | ||
797 | kfree(client); | ||
798 | |||
799 | return 0; | ||
800 | } | ||
801 | |||
802 | /* ----------------------------------------------------------------------- */ | ||
803 | |||
804 | static struct i2c_driver driver = { | ||
805 | .owner = THIS_MODULE, | ||
806 | .name = "tvp5150", | ||
807 | |||
808 | /* FIXME */ | ||
809 | .id = I2C_DRIVERID_SAA7110, | ||
810 | .flags = I2C_DF_NOTIFY, | ||
811 | |||
812 | .attach_adapter = tvp5150_attach_adapter, | ||
813 | .detach_client = tvp5150_detach_client, | ||
814 | |||
815 | .command = tvp5150_command, | ||
816 | }; | ||
817 | |||
818 | static int __init tvp5150_init(void) | ||
819 | { | ||
820 | return i2c_add_driver(&driver); | ||
821 | } | ||
822 | |||
823 | static void __exit tvp5150_exit(void) | ||
824 | { | ||
825 | i2c_del_driver(&driver); | ||
826 | } | ||
827 | |||
828 | module_init(tvp5150_init); | ||
829 | module_exit(tvp5150_exit); | ||
diff --git a/drivers/media/video/tvp5150_reg.h b/drivers/media/video/tvp5150_reg.h new file mode 100644 index 000000000000..cd45c1ded786 --- /dev/null +++ b/drivers/media/video/tvp5150_reg.h | |||
@@ -0,0 +1,173 @@ | |||
1 | #define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */ | ||
2 | #define TVP5150_ANAL_CHL_CTL 0x01 /* Analog channel controls */ | ||
3 | #define TVP5150_OP_MODE_CTL 0x02 /* Operation mode controls */ | ||
4 | #define TVP5150_MISC_CTL 0x03 /* Miscellaneous controls */ | ||
5 | #define TVP5150_AUTOSW_MSK 0x04 /* Autoswitch mask: TVP5150A / TVP5150AM */ | ||
6 | |||
7 | /* Reserved 05h */ | ||
8 | |||
9 | #define TVP5150_COLOR_KIL_THSH_CTL 0x06 /* Color killer threshold control */ | ||
10 | #define TVP5150_LUMA_PROC_CTL_1 0x07 /* Luminance processing control #1 */ | ||
11 | #define TVP5150_LUMA_PROC_CTL_2 0x08 /* Luminance processing control #2 */ | ||
12 | #define TVP5150_BRIGHT_CTL 0x09 /* Brightness control */ | ||
13 | #define TVP5150_SATURATION_CTL 0x0a /* Color saturation control */ | ||
14 | #define TVP5150_HUE_CTL 0x0b /* Hue control */ | ||
15 | #define TVP5150_CONTRAST_CTL 0x0c /* Contrast control */ | ||
16 | #define TVP5150_DATA_RATE_SEL 0x0d /* Outputs and data rates select */ | ||
17 | #define TVP5150_LUMA_PROC_CTL_3 0x0e /* Luminance processing control #3 */ | ||
18 | #define TVP5150_CONF_SHARED_PIN 0x0f /* Configuration shared pins */ | ||
19 | |||
20 | /* Reserved 10h */ | ||
21 | |||
22 | #define TVP5150_ACT_VD_CROP_ST_MSB 0x11 /* Active video cropping start MSB */ | ||
23 | #define TVP5150_ACT_VD_CROP_ST_LSB 0x12 /* Active video cropping start LSB */ | ||
24 | #define TVP5150_ACT_VD_CROP_STP_MSB 0x13 /* Active video cropping stop MSB */ | ||
25 | #define TVP5150_ACT_VD_CROP_STP_LSB 0x14 /* Active video cropping stop LSB */ | ||
26 | #define TVP5150_GENLOCK 0x15 /* Genlock/RTC */ | ||
27 | #define TVP5150_HORIZ_SYNC_START 0x16 /* Horizontal sync start */ | ||
28 | |||
29 | /* Reserved 17h */ | ||
30 | |||
31 | #define TVP5150_VERT_BLANKING_START 0x18 /* Vertical blanking start */ | ||
32 | #define TVP5150_VERT_BLANKING_STOP 0x19 /* Vertical blanking stop */ | ||
33 | #define TVP5150_CHROMA_PROC_CTL_1 0x1a /* Chrominance processing control #1 */ | ||
34 | #define TVP5150_CHROMA_PROC_CTL_2 0x1b /* Chrominance processing control #2 */ | ||
35 | #define TVP5150_INT_RESET_REG_B 0x1c /* Interrupt reset register B */ | ||
36 | #define TVP5150_INT_ENABLE_REG_B 0x1d /* Interrupt enable register B */ | ||
37 | #define TVP5150_INTT_CONFIG_REG_B 0x1e /* Interrupt configuration register B */ | ||
38 | |||
39 | /* Reserved 1Fh-27h */ | ||
40 | |||
41 | #define TVP5150_VIDEO_STD 0x28 /* Video standard */ | ||
42 | |||
43 | /* Reserved 29h-2bh */ | ||
44 | |||
45 | #define TVP5150_CB_GAIN_FACT 0x2c /* Cb gain factor */ | ||
46 | #define TVP5150_CR_GAIN_FACTOR 0x2d /* Cr gain factor */ | ||
47 | #define TVP5150_MACROVISION_ON_CTR 0x2e /* Macrovision on counter */ | ||
48 | #define TVP5150_MACROVISION_OFF_CTR 0x2f /* Macrovision off counter */ | ||
49 | #define TVP5150_REV_SELECT 0x30 /* revision select (TVP5150AM1 only) */ | ||
50 | |||
51 | /* Reserved 31h-7Fh */ | ||
52 | |||
53 | #define TVP5150_MSB_DEV_ID 0x80 /* MSB of device ID */ | ||
54 | #define TVP5150_LSB_DEV_ID 0x81 /* LSB of device ID */ | ||
55 | #define TVP5150_ROM_MAJOR_VER 0x82 /* ROM major version */ | ||
56 | #define TVP5150_ROM_MINOR_VER 0x83 /* ROM minor version */ | ||
57 | #define TVP5150_VERT_LN_COUNT_MSB 0x84 /* Vertical line count MSB */ | ||
58 | #define TVP5150_VERT_LN_COUNT_LSB 0x85 /* Vertical line count LSB */ | ||
59 | #define TVP5150_INT_STATUS_REG_B 0x86 /* Interrupt status register B */ | ||
60 | #define TVP5150_INT_ACTIVE_REG_B 0x87 /* Interrupt active register B */ | ||
61 | #define TVP5150_STATUS_REG_1 0x88 /* Status register #1 */ | ||
62 | #define TVP5150_STATUS_REG_2 0x89 /* Status register #2 */ | ||
63 | #define TVP5150_STATUS_REG_3 0x8a /* Status register #3 */ | ||
64 | #define TVP5150_STATUS_REG_4 0x8b /* Status register #4 */ | ||
65 | #define TVP5150_STATUS_REG_5 0x8c /* Status register #5 */ | ||
66 | /* Reserved 8Dh-8Fh */ | ||
67 | #define TVP5150_CC_DATA_REG1 0x90 /* Closed caption data registers */ | ||
68 | #define TVP5150_CC_DATA_REG2 0x91 /* Closed caption data registers */ | ||
69 | #define TVP5150_CC_DATA_REG3 0x92 /* Closed caption data registers */ | ||
70 | #define TVP5150_CC_DATA_REG4 0x93 /* Closed caption data registers */ | ||
71 | #define TVP5150_WSS_DATA_REG1 0X94 /* WSS data registers */ | ||
72 | #define TVP5150_WSS_DATA_REG2 0X95 /* WSS data registers */ | ||
73 | #define TVP5150_WSS_DATA_REG3 0X96 /* WSS data registers */ | ||
74 | #define TVP5150_WSS_DATA_REG4 0X97 /* WSS data registers */ | ||
75 | #define TVP5150_WSS_DATA_REG5 0X98 /* WSS data registers */ | ||
76 | #define TVP5150_WSS_DATA_REG6 0X99 /* WSS data registers */ | ||
77 | #define TVP5150_VPS_DATA_REG1 0x9a /* VPS data registers */ | ||
78 | #define TVP5150_VPS_DATA_REG2 0x9b /* VPS data registers */ | ||
79 | #define TVP5150_VPS_DATA_REG3 0x9c /* VPS data registers */ | ||
80 | #define TVP5150_VPS_DATA_REG4 0x9d /* VPS data registers */ | ||
81 | #define TVP5150_VPS_DATA_REG5 0x9e /* VPS data registers */ | ||
82 | #define TVP5150_VPS_DATA_REG6 0x9f /* VPS data registers */ | ||
83 | #define TVP5150_VPS_DATA_REG7 0xa0 /* VPS data registers */ | ||
84 | #define TVP5150_VPS_DATA_REG8 0xa1 /* VPS data registers */ | ||
85 | #define TVP5150_VPS_DATA_REG9 0xa2 /* VPS data registers */ | ||
86 | #define TVP5150_VPS_DATA_REG10 0xa3 /* VPS data registers */ | ||
87 | #define TVP5150_VPS_DATA_REG11 0xa4 /* VPS data registers */ | ||
88 | #define TVP5150_VPS_DATA_REG12 0xa5 /* VPS data registers */ | ||
89 | #define TVP5150_VPS_DATA_REG13 0xa6 /* VPS data registers */ | ||
90 | #define TVP5150_VITC_DATA_REG1 0xa7 /* VITC data registers */ | ||
91 | #define TVP5150_VITC_DATA_REG2 0xa8 /* VITC data registers */ | ||
92 | #define TVP5150_VITC_DATA_REG3 0xa9 /* VITC data registers */ | ||
93 | #define TVP5150_VITC_DATA_REG4 0xaa /* VITC data registers */ | ||
94 | #define TVP5150_VITC_DATA_REG5 0xab /* VITC data registers */ | ||
95 | #define TVP5150_VITC_DATA_REG6 0xac /* VITC data registers */ | ||
96 | #define TVP5150_VITC_DATA_REG7 0xad /* VITC data registers */ | ||
97 | #define TVP5150_VITC_DATA_REG8 0xae /* VITC data registers */ | ||
98 | #define TVP5150_VITC_DATA_REG9 0xaf /* VITC data registers */ | ||
99 | #define TVP5150_VBI_FIFO_READ_DATA 0xb0 /* VBI FIFO read data */ | ||
100 | #define TVP5150_TELETEXT_FIL_1_1 0xb1 /* Teletext filter 1 */ | ||
101 | #define TVP5150_TELETEXT_FIL_1_2 0xb2 /* Teletext filter 1 */ | ||
102 | #define TVP5150_TELETEXT_FIL_1_3 0xb3 /* Teletext filter 1 */ | ||
103 | #define TVP5150_TELETEXT_FIL_1_4 0xb4 /* Teletext filter 1 */ | ||
104 | #define TVP5150_TELETEXT_FIL_1_5 0xb5 /* Teletext filter 1 */ | ||
105 | #define TVP5150_TELETEXT_FIL_2_1 0xb6 /* Teletext filter 2 */ | ||
106 | #define TVP5150_TELETEXT_FIL_2_2 0xb7 /* Teletext filter 2 */ | ||
107 | #define TVP5150_TELETEXT_FIL_2_3 0xb8 /* Teletext filter 2 */ | ||
108 | #define TVP5150_TELETEXT_FIL_2_4 0xb9 /* Teletext filter 2 */ | ||
109 | #define TVP5150_TELETEXT_FIL_2_5 0xba /* Teletext filter 2 */ | ||
110 | #define TVP5150_TELETEXT_FIL_ENA 0xbb /* Teletext filter enable */ | ||
111 | /* Reserved BCh-BFh */ | ||
112 | #define TVP5150_INT_STATUS_REG_A 0xc0 /* Interrupt status register A */ | ||
113 | #define TVP5150_INT_ENABLE_REG_A 0xc1 /* Interrupt enable register A */ | ||
114 | #define TVP5150_INT_CONF 0xc2 /* Interrupt configuration */ | ||
115 | #define TVP5150_VDP_CONF_RAM_DATA 0xc3 /* VDP configuration RAM data */ | ||
116 | #define TVP5150_CONF_RAM_ADDR_LOW 0xc4 /* Configuration RAM address low byte */ | ||
117 | #define TVP5150_CONF_RAM_ADDR_HIGH 0xc5 /* Configuration RAM address high byte */ | ||
118 | #define TVP5150_VDP_STATUS_REG 0xc6 /* VDP status register */ | ||
119 | #define TVP5150_FIFO_WORD_COUNT 0xc7 /* FIFO word count */ | ||
120 | #define TVP5150_FIFO_INT_THRESHOLD 0xc8 /* FIFO interrupt threshold */ | ||
121 | #define TVP5150_FIFO_RESET 0xc9 /* FIFO reset */ | ||
122 | #define TVP5150_LINE_NUMBER_INT 0xca /* Line number interrupt */ | ||
123 | #define TVP5150_PIX_ALIGN_REG_LOW 0xcb /* Pixel alignment register low byte */ | ||
124 | #define TVP5150_PIX_ALIGN_REG_HIGH 0xcc /* Pixel alignment register high byte */ | ||
125 | #define TVP5150_FIFO_OUT_CTRL 0xcd /* FIFO output control */ | ||
126 | /* Reserved CEh */ | ||
127 | #define TVP5150_FULL_FIELD_ENA_1 0xcf /* Full field enable 1 */ | ||
128 | #define TVP5150_FULL_FIELD_ENA_2 0xd0 /* Full field enable 2 */ | ||
129 | #define TVP5150_LINE_MODE_REG_1 0xd1 /* Line mode registers */ | ||
130 | #define TVP5150_LINE_MODE_REG_2 0xd2 /* Line mode registers */ | ||
131 | #define TVP5150_LINE_MODE_REG_3 0xd3 /* Line mode registers */ | ||
132 | #define TVP5150_LINE_MODE_REG_4 0xd4 /* Line mode registers */ | ||
133 | #define TVP5150_LINE_MODE_REG_5 0xd5 /* Line mode registers */ | ||
134 | #define TVP5150_LINE_MODE_REG_6 0xd6 /* Line mode registers */ | ||
135 | #define TVP5150_LINE_MODE_REG_7 0xd7 /* Line mode registers */ | ||
136 | #define TVP5150_LINE_MODE_REG_8 0xd8 /* Line mode registers */ | ||
137 | #define TVP5150_LINE_MODE_REG_9 0xd9 /* Line mode registers */ | ||
138 | #define TVP5150_LINE_MODE_REG_10 0xda /* Line mode registers */ | ||
139 | #define TVP5150_LINE_MODE_REG_11 0xdb /* Line mode registers */ | ||
140 | #define TVP5150_LINE_MODE_REG_12 0xdc /* Line mode registers */ | ||
141 | #define TVP5150_LINE_MODE_REG_13 0xdd /* Line mode registers */ | ||
142 | #define TVP5150_LINE_MODE_REG_14 0xde /* Line mode registers */ | ||
143 | #define TVP5150_LINE_MODE_REG_15 0xdf /* Line mode registers */ | ||
144 | #define TVP5150_LINE_MODE_REG_16 0xe0 /* Line mode registers */ | ||
145 | #define TVP5150_LINE_MODE_REG_17 0xe1 /* Line mode registers */ | ||
146 | #define TVP5150_LINE_MODE_REG_18 0xe2 /* Line mode registers */ | ||
147 | #define TVP5150_LINE_MODE_REG_19 0xe3 /* Line mode registers */ | ||
148 | #define TVP5150_LINE_MODE_REG_20 0xe4 /* Line mode registers */ | ||
149 | #define TVP5150_LINE_MODE_REG_21 0xe5 /* Line mode registers */ | ||
150 | #define TVP5150_LINE_MODE_REG_22 0xe6 /* Line mode registers */ | ||
151 | #define TVP5150_LINE_MODE_REG_23 0xe7 /* Line mode registers */ | ||
152 | #define TVP5150_LINE_MODE_REG_24 0xe8 /* Line mode registers */ | ||
153 | #define TVP5150_LINE_MODE_REG_25 0xe9 /* Line mode registers */ | ||
154 | #define TVP5150_LINE_MODE_REG_27 0xea /* Line mode registers */ | ||
155 | #define TVP5150_LINE_MODE_REG_28 0xeb /* Line mode registers */ | ||
156 | #define TVP5150_LINE_MODE_REG_29 0xec /* Line mode registers */ | ||
157 | #define TVP5150_LINE_MODE_REG_30 0xed /* Line mode registers */ | ||
158 | #define TVP5150_LINE_MODE_REG_31 0xee /* Line mode registers */ | ||
159 | #define TVP5150_LINE_MODE_REG_32 0xef /* Line mode registers */ | ||
160 | #define TVP5150_LINE_MODE_REG_33 0xf0 /* Line mode registers */ | ||
161 | #define TVP5150_LINE_MODE_REG_34 0xf1 /* Line mode registers */ | ||
162 | #define TVP5150_LINE_MODE_REG_35 0xf2 /* Line mode registers */ | ||
163 | #define TVP5150_LINE_MODE_REG_36 0xf3 /* Line mode registers */ | ||
164 | #define TVP5150_LINE_MODE_REG_37 0xf4 /* Line mode registers */ | ||
165 | #define TVP5150_LINE_MODE_REG_38 0xf5 /* Line mode registers */ | ||
166 | #define TVP5150_LINE_MODE_REG_39 0xf6 /* Line mode registers */ | ||
167 | #define TVP5150_LINE_MODE_REG_40 0xf7 /* Line mode registers */ | ||
168 | #define TVP5150_LINE_MODE_REG_41 0xf8 /* Line mode registers */ | ||
169 | #define TVP5150_LINE_MODE_REG_42 0xf9 /* Line mode registers */ | ||
170 | #define TVP5150_LINE_MODE_REG_43 0xfa /* Line mode registers */ | ||
171 | #define TVP5150_LINE_MODE_REG_44 0xfb /* Line mode registers */ | ||
172 | #define TVP5150_FULL_FIELD_MODE_REG 0xfc /* Full field mode register */ | ||
173 | /* Reserved FDh-FFh */ | ||
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index d679ca23ded7..4134549d11a8 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c | |||
@@ -708,7 +708,7 @@ v4l_compat_translate_ioctl(struct inode *inode, | |||
708 | } | 708 | } |
709 | case VIDIOCGFREQ: /* get frequency */ | 709 | case VIDIOCGFREQ: /* get frequency */ |
710 | { | 710 | { |
711 | int *freq = arg; | 711 | unsigned long *freq = arg; |
712 | 712 | ||
713 | freq2.tuner = 0; | 713 | freq2.tuner = 0; |
714 | err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); | 714 | err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); |
@@ -720,7 +720,7 @@ v4l_compat_translate_ioctl(struct inode *inode, | |||
720 | } | 720 | } |
721 | case VIDIOCSFREQ: /* set frequency */ | 721 | case VIDIOCSFREQ: /* set frequency */ |
722 | { | 722 | { |
723 | int *freq = arg; | 723 | unsigned long *freq = arg; |
724 | 724 | ||
725 | freq2.tuner = 0; | 725 | freq2.tuner = 0; |
726 | drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); | 726 | drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); |
@@ -960,7 +960,7 @@ v4l_compat_translate_ioctl(struct inode *inode, | |||
960 | fmt->start[1] = fmt2->fmt.vbi.start[1]; | 960 | fmt->start[1] = fmt2->fmt.vbi.start[1]; |
961 | fmt->count[1] = fmt2->fmt.vbi.count[1]; | 961 | fmt->count[1] = fmt2->fmt.vbi.count[1]; |
962 | fmt->flags = fmt2->fmt.vbi.flags & 0x03; | 962 | fmt->flags = fmt2->fmt.vbi.flags & 0x03; |
963 | break; | 963 | break; |
964 | } | 964 | } |
965 | case VIDIOCSVBIFMT: | 965 | case VIDIOCSVBIFMT: |
966 | { | 966 | { |
diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c index 574b8e36f3c6..acfd3a103f35 100644 --- a/drivers/media/video/video-buf.c +++ b/drivers/media/video/video-buf.c | |||
@@ -147,7 +147,7 @@ int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction, | |||
147 | data,size,dma->nr_pages); | 147 | data,size,dma->nr_pages); |
148 | 148 | ||
149 | down_read(¤t->mm->mmap_sem); | 149 | down_read(¤t->mm->mmap_sem); |
150 | err = get_user_pages(current,current->mm, | 150 | err = get_user_pages(current,current->mm, |
151 | data & PAGE_MASK, dma->nr_pages, | 151 | data & PAGE_MASK, dma->nr_pages, |
152 | rw == READ, 1, /* force */ | 152 | rw == READ, 1, /* force */ |
153 | dma->pages, NULL); | 153 | dma->pages, NULL); |
@@ -750,9 +750,9 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data, | |||
750 | { | 750 | { |
751 | enum v4l2_field field; | 751 | enum v4l2_field field; |
752 | unsigned long flags; | 752 | unsigned long flags; |
753 | int retval; | 753 | int retval; |
754 | 754 | ||
755 | /* setup stuff */ | 755 | /* setup stuff */ |
756 | retval = -ENOMEM; | 756 | retval = -ENOMEM; |
757 | q->read_buf = videobuf_alloc(q->msize); | 757 | q->read_buf = videobuf_alloc(q->msize); |
758 | if (NULL == q->read_buf) | 758 | if (NULL == q->read_buf) |
@@ -760,18 +760,18 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data, | |||
760 | 760 | ||
761 | q->read_buf->memory = V4L2_MEMORY_USERPTR; | 761 | q->read_buf->memory = V4L2_MEMORY_USERPTR; |
762 | q->read_buf->baddr = (unsigned long)data; | 762 | q->read_buf->baddr = (unsigned long)data; |
763 | q->read_buf->bsize = count; | 763 | q->read_buf->bsize = count; |
764 | field = videobuf_next_field(q); | 764 | field = videobuf_next_field(q); |
765 | retval = q->ops->buf_prepare(q,q->read_buf,field); | 765 | retval = q->ops->buf_prepare(q,q->read_buf,field); |
766 | if (0 != retval) | 766 | if (0 != retval) |
767 | goto done; | 767 | goto done; |
768 | 768 | ||
769 | /* start capture & wait */ | 769 | /* start capture & wait */ |
770 | spin_lock_irqsave(q->irqlock,flags); | 770 | spin_lock_irqsave(q->irqlock,flags); |
771 | q->ops->buf_queue(q,q->read_buf); | 771 | q->ops->buf_queue(q,q->read_buf); |
772 | spin_unlock_irqrestore(q->irqlock,flags); | 772 | spin_unlock_irqrestore(q->irqlock,flags); |
773 | retval = videobuf_waiton(q->read_buf,0,0); | 773 | retval = videobuf_waiton(q->read_buf,0,0); |
774 | if (0 == retval) { | 774 | if (0 == retval) { |
775 | videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); | 775 | videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); |
776 | if (STATE_ERROR == q->read_buf->state) | 776 | if (STATE_ERROR == q->read_buf->state) |
777 | retval = -EIO; | 777 | retval = -EIO; |
@@ -828,7 +828,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, | |||
828 | } | 828 | } |
829 | 829 | ||
830 | /* wait until capture is done */ | 830 | /* wait until capture is done */ |
831 | retval = videobuf_waiton(q->read_buf, nonblocking, 1); | 831 | retval = videobuf_waiton(q->read_buf, nonblocking, 1); |
832 | if (0 != retval) | 832 | if (0 != retval) |
833 | goto done; | 833 | goto done; |
834 | videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); | 834 | videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); |
@@ -1096,7 +1096,7 @@ videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr, | |||
1096 | 1096 | ||
1097 | dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n", | 1097 | dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n", |
1098 | vaddr,vma->vm_start,vma->vm_end); | 1098 | vaddr,vma->vm_start,vma->vm_end); |
1099 | if (vaddr > vma->vm_end) | 1099 | if (vaddr > vma->vm_end) |
1100 | return NOPAGE_SIGBUS; | 1100 | return NOPAGE_SIGBUS; |
1101 | page = alloc_page(GFP_USER); | 1101 | page = alloc_page(GFP_USER); |
1102 | if (!page) | 1102 | if (!page) |
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c new file mode 100644 index 000000000000..22f286222004 --- /dev/null +++ b/drivers/media/video/wm8775.c | |||
@@ -0,0 +1,254 @@ | |||
1 | /* | ||
2 | * wm8775 - driver version 0.0.1 | ||
3 | * | ||
4 | * Copyright (C) 2004 Ulf Eklund <ivtv at eklund.to> | ||
5 | * | ||
6 | * Based on saa7115 driver | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/types.h> | ||
26 | #include <linux/ioctl.h> | ||
27 | #include <asm/uaccess.h> | ||
28 | #include <linux/i2c.h> | ||
29 | #include <linux/i2c-id.h> | ||
30 | #include <linux/videodev.h> | ||
31 | #include <media/audiochip.h> | ||
32 | |||
33 | MODULE_DESCRIPTION("wm8775 driver"); | ||
34 | MODULE_AUTHOR("Ulf Eklund"); | ||
35 | MODULE_LICENSE("GPL"); | ||
36 | |||
37 | #define wm8775_err(fmt, arg...) do { \ | ||
38 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \ | ||
39 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
40 | #define wm8775_info(fmt, arg...) do { \ | ||
41 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \ | ||
42 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
43 | |||
44 | |||
45 | static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END }; | ||
46 | |||
47 | |||
48 | I2C_CLIENT_INSMOD; | ||
49 | |||
50 | /* ----------------------------------------------------------------------- */ | ||
51 | |||
52 | enum { | ||
53 | R7 = 7, R11 = 11, | ||
54 | R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R23 = 23, | ||
55 | TOT_REGS | ||
56 | }; | ||
57 | |||
58 | struct wm8775_state { | ||
59 | u8 input; /* Last selected input (0-0xf) */ | ||
60 | u8 muted; | ||
61 | }; | ||
62 | |||
63 | static int wm8775_write(struct i2c_client *client, int reg, u16 val) | ||
64 | { | ||
65 | int i; | ||
66 | |||
67 | if (reg < 0 || reg >= TOT_REGS) { | ||
68 | wm8775_err("Invalid register R%d\n", reg); | ||
69 | return -1; | ||
70 | } | ||
71 | |||
72 | for (i = 0; i < 3; i++) { | ||
73 | if (i2c_smbus_write_byte_data(client, (reg << 1) | | ||
74 | (val >> 8), val & 0xff) == 0) { | ||
75 | return 0; | ||
76 | } | ||
77 | } | ||
78 | wm8775_err("I2C: cannot write %03x to register R%d\n", val, reg); | ||
79 | return -1; | ||
80 | } | ||
81 | |||
82 | static int wm8775_command(struct i2c_client *client, unsigned int cmd, | ||
83 | void *arg) | ||
84 | { | ||
85 | struct wm8775_state *state = i2c_get_clientdata(client); | ||
86 | int *input = arg; | ||
87 | |||
88 | switch (cmd) { | ||
89 | case AUDC_SET_INPUT: | ||
90 | wm8775_write(client, R21, 0x0c0); | ||
91 | wm8775_write(client, R14, 0x1d4); | ||
92 | wm8775_write(client, R15, 0x1d4); | ||
93 | |||
94 | if (*input == AUDIO_RADIO) { | ||
95 | wm8775_write(client, R21, 0x108); | ||
96 | state->input = 8; | ||
97 | state->muted = 0; | ||
98 | break; | ||
99 | } | ||
100 | if (*input == AUDIO_MUTE) { | ||
101 | state->muted = 1; | ||
102 | break; | ||
103 | } | ||
104 | if (*input == AUDIO_UNMUTE) { | ||
105 | wm8775_write(client, R21, 0x100 + state->input); | ||
106 | state->muted = 0; | ||
107 | break; | ||
108 | } | ||
109 | /* All other inputs... */ | ||
110 | wm8775_write(client, R21, 0x102); | ||
111 | state->input = 2; | ||
112 | state->muted = 0; | ||
113 | break; | ||
114 | |||
115 | case VIDIOC_LOG_STATUS: | ||
116 | wm8775_info("Input: %s%s\n", | ||
117 | state->input == 8 ? "radio" : "default", | ||
118 | state->muted ? " (muted)" : ""); | ||
119 | break; | ||
120 | |||
121 | case VIDIOC_S_FREQUENCY: | ||
122 | /* If I remove this, then it can happen that I have no | ||
123 | sound the first time I tune from static to a valid channel. | ||
124 | It's difficult to reproduce and is almost certainly related | ||
125 | to the zero cross detect circuit. */ | ||
126 | wm8775_write(client, R21, 0x0c0); | ||
127 | wm8775_write(client, R14, 0x1d4); | ||
128 | wm8775_write(client, R15, 0x1d4); | ||
129 | wm8775_write(client, R21, 0x100 + state->input); | ||
130 | break; | ||
131 | |||
132 | default: | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | /* ----------------------------------------------------------------------- */ | ||
139 | |||
140 | /* i2c implementation */ | ||
141 | |||
142 | /* | ||
143 | * Generic i2c probe | ||
144 | * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' | ||
145 | */ | ||
146 | |||
147 | static struct i2c_driver i2c_driver; | ||
148 | |||
149 | static int wm8775_attach(struct i2c_adapter *adapter, int address, int kind) | ||
150 | { | ||
151 | struct i2c_client *client; | ||
152 | struct wm8775_state *state; | ||
153 | |||
154 | /* Check if the adapter supports the needed features */ | ||
155 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
156 | return 0; | ||
157 | |||
158 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
159 | if (client == 0) | ||
160 | return -ENOMEM; | ||
161 | |||
162 | memset(client, 0, sizeof(struct i2c_client)); | ||
163 | client->addr = address; | ||
164 | client->adapter = adapter; | ||
165 | client->driver = &i2c_driver; | ||
166 | client->flags = I2C_CLIENT_ALLOW_USE; | ||
167 | snprintf(client->name, sizeof(client->name) - 1, "wm8775"); | ||
168 | |||
169 | wm8775_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name); | ||
170 | |||
171 | state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL); | ||
172 | if (state == NULL) { | ||
173 | kfree(client); | ||
174 | return -ENOMEM; | ||
175 | } | ||
176 | state->input = 2; | ||
177 | state->muted = 0; | ||
178 | i2c_set_clientdata(client, state); | ||
179 | |||
180 | /* initialize wm8775 */ | ||
181 | wm8775_write(client, R23, 0x000); /* RESET */ | ||
182 | wm8775_write(client, R7, 0x000); /* Disable zero cross detect timeout */ | ||
183 | wm8775_write(client, R11, 0x021); /* Left justified, 24-bit mode */ | ||
184 | wm8775_write(client, R12, 0x102); /* Master mode, clock ratio 256fs */ | ||
185 | wm8775_write(client, R13, 0x000); /* Powered up */ | ||
186 | wm8775_write(client, R14, 0x1d4); /* ADC gain +2.5dB, enable zero cross */ | ||
187 | wm8775_write(client, R15, 0x1d4); /* ADC gain +2.5dB, enable zero cross */ | ||
188 | wm8775_write(client, R16, 0x1bf); /* ALC Stereo, ALC target level -1dB FS */ | ||
189 | /* max gain +8dB */ | ||
190 | wm8775_write(client, R17, 0x185); /* Enable gain control, use zero cross */ | ||
191 | /* detection, ALC hold time 42.6 ms */ | ||
192 | wm8775_write(client, R18, 0x0a2); /* ALC gain ramp up delay 34 s, */ | ||
193 | /* ALC gain ramp down delay 33 ms */ | ||
194 | wm8775_write(client, R19, 0x005); /* Enable noise gate, threshold -72dBfs */ | ||
195 | wm8775_write(client, R20, 0x07a); /* Transient window 4ms, lower PGA gain */ | ||
196 | /* limit -1dB */ | ||
197 | wm8775_write(client, R21, 0x102); /* LRBOTH = 1, use input 2. */ | ||
198 | i2c_attach_client(client); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static int wm8775_probe(struct i2c_adapter *adapter) | ||
204 | { | ||
205 | #ifdef I2C_CLASS_TV_ANALOG | ||
206 | if (adapter->class & I2C_CLASS_TV_ANALOG) | ||
207 | #else | ||
208 | if (adapter->id == I2C_HW_B_BT848) | ||
209 | #endif | ||
210 | return i2c_probe(adapter, &addr_data, wm8775_attach); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static int wm8775_detach(struct i2c_client *client) | ||
215 | { | ||
216 | int err; | ||
217 | |||
218 | err = i2c_detach_client(client); | ||
219 | if (err) { | ||
220 | return err; | ||
221 | } | ||
222 | kfree(client); | ||
223 | |||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | /* ----------------------------------------------------------------------- */ | ||
228 | |||
229 | /* i2c implementation */ | ||
230 | static struct i2c_driver i2c_driver = { | ||
231 | .name = "wm8775", | ||
232 | |||
233 | .id = I2C_DRIVERID_WM8775, | ||
234 | .flags = I2C_DF_NOTIFY, | ||
235 | |||
236 | .attach_adapter = wm8775_probe, | ||
237 | .detach_client = wm8775_detach, | ||
238 | .command = wm8775_command, | ||
239 | .owner = THIS_MODULE, | ||
240 | }; | ||
241 | |||
242 | |||
243 | static int __init wm8775_init_module(void) | ||
244 | { | ||
245 | return i2c_add_driver(&i2c_driver); | ||
246 | } | ||
247 | |||
248 | static void __exit wm8775_cleanup_module(void) | ||
249 | { | ||
250 | i2c_del_driver(&i2c_driver); | ||
251 | } | ||
252 | |||
253 | module_init(wm8775_init_module); | ||
254 | module_exit(wm8775_cleanup_module); | ||
diff --git a/drivers/media/video/zr36016.c b/drivers/media/video/zr36016.c index d4740a89cea1..4ed898585c70 100644 --- a/drivers/media/video/zr36016.c +++ b/drivers/media/video/zr36016.c | |||
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | #define ZR016_VERSION "v0.7" | 27 | #define ZR016_VERSION "v0.7" |
28 | 28 | ||
29 | #include <linux/version.h> | ||
30 | #include <linux/module.h> | 29 | #include <linux/module.h> |
31 | #include <linux/init.h> | 30 | #include <linux/init.h> |
32 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
diff --git a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c index 13b1e7b6fd6e..0144576a6123 100644 --- a/drivers/media/video/zr36050.c +++ b/drivers/media/video/zr36050.c | |||
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | #define ZR050_VERSION "v0.7.1" | 27 | #define ZR050_VERSION "v0.7.1" |
28 | 28 | ||
29 | #include <linux/version.h> | ||
30 | #include <linux/module.h> | 29 | #include <linux/module.h> |
31 | #include <linux/init.h> | 30 | #include <linux/init.h> |
32 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c index b50dc403e6db..129744a07abd 100644 --- a/drivers/media/video/zr36060.c +++ b/drivers/media/video/zr36060.c | |||
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | #define ZR060_VERSION "v0.7" | 27 | #define ZR060_VERSION "v0.7" |
28 | 28 | ||
29 | #include <linux/version.h> | ||
30 | #include <linux/module.h> | 29 | #include <linux/module.h> |
31 | #include <linux/init.h> | 30 | #include <linux/init.h> |
32 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |