diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-17 00:15:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-17 00:15:42 -0400 |
commit | 0dd5198672dd2bbeb933862e1fc82162e0b636be (patch) | |
tree | c9efed20d90603c4d1626c21bd7aab1e7fc74a58 /drivers/media/common | |
parent | c868d550115b9ccc0027c67265b9520790f05601 (diff) | |
parent | 11c635a25b9f3a5d87409ce46cf2e05c500251ec (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (425 commits)
V4L/DVB (11870): gspca - main: VIDIOC_ENUM_FRAMESIZES ioctl added.
V4L/DVB (12004): poll method lose race condition
V4L/DVB (11894): flexcop-pci: dmesg visible names broken
V4L/DVB (11892): Siano: smsendian - declare function as extern
V4L/DVB (11891): Siano: smscore - bind the GPIO SMS protocol
V4L/DVB (11890): Siano: smscore - remove redundant code
V4L/DVB (11889): Siano: smsdvb - add DVB v3 events
V4L/DVB (11888): Siano: smsusb - remove redundant ifdef
V4L/DVB (11887): Siano: smscards - add board (target) events
V4L/DVB (11886): Siano: smscore - fix some new GPIO definitions names
V4L/DVB (11885): Siano: Add new GPIO management interface
V4L/DVB (11884): Siano: smssdio - revert to stand alone module
V4L/DVB (11883): Siano: cards - add two additional (USB) devices
V4L/DVB (11824): Siano: smsusb - change exit func debug msg
V4L/DVB (11823): Siano: smsusb - fix typo in module description
V4L/DVB (11822): Siano: smscore - bug fix at get_device_mode
V4L/DVB (11821): Siano: smscore - fix isdb-t firmware name
V4L/DVB (11820): Siano: smscore - fix byte ordering bug
V4L/DVB (11819): Siano: smscore - fix get_common_buffer bug
V4L/DVB (11818): Siano: smscards - assign gpio to HPG targets
...
Diffstat (limited to 'drivers/media/common')
-rw-r--r-- | drivers/media/common/tuners/tuner-simple.c | 44 | ||||
-rw-r--r-- | drivers/media/common/tuners/tuner-types.c | 59 | ||||
-rw-r--r-- | drivers/media/common/tuners/tuner-xc2028.c | 56 | ||||
-rw-r--r-- | drivers/media/common/tuners/xc5000.c | 264 |
4 files changed, 258 insertions, 165 deletions
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c index 78412c9c424a..149d54cdf7b9 100644 --- a/drivers/media/common/tuners/tuner-simple.c +++ b/drivers/media/common/tuners/tuner-simple.c | |||
@@ -416,6 +416,24 @@ static int simple_std_setup(struct dvb_frontend *fe, | |||
416 | return 0; | 416 | return 0; |
417 | } | 417 | } |
418 | 418 | ||
419 | static int simple_set_aux_byte(struct dvb_frontend *fe, u8 config, u8 aux) | ||
420 | { | ||
421 | struct tuner_simple_priv *priv = fe->tuner_priv; | ||
422 | int rc; | ||
423 | u8 buffer[2]; | ||
424 | |||
425 | buffer[0] = (config & ~0x38) | 0x18; | ||
426 | buffer[1] = aux; | ||
427 | |||
428 | tuner_dbg("setting aux byte: 0x%02x 0x%02x\n", buffer[0], buffer[1]); | ||
429 | |||
430 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2); | ||
431 | if (2 != rc) | ||
432 | tuner_warn("i2c i/o error: rc == %d (should be 2)\n", rc); | ||
433 | |||
434 | return rc == 2 ? 0 : rc; | ||
435 | } | ||
436 | |||
419 | static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, | 437 | static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, |
420 | u16 div, u8 config, u8 cb) | 438 | u16 div, u8 config, u8 cb) |
421 | { | 439 | { |
@@ -424,17 +442,10 @@ static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer, | |||
424 | 442 | ||
425 | switch (priv->type) { | 443 | switch (priv->type) { |
426 | case TUNER_LG_TDVS_H06XF: | 444 | case TUNER_LG_TDVS_H06XF: |
427 | /* Set the Auxiliary Byte. */ | 445 | simple_set_aux_byte(fe, config, 0x20); |
428 | buffer[0] = buffer[2]; | 446 | break; |
429 | buffer[0] &= ~0x20; | 447 | case TUNER_PHILIPS_FQ1216LME_MK3: |
430 | buffer[0] |= 0x18; | 448 | simple_set_aux_byte(fe, config, 0x60); /* External AGC */ |
431 | buffer[1] = 0x20; | ||
432 | tuner_dbg("tv 0x%02x 0x%02x\n", buffer[0], buffer[1]); | ||
433 | |||
434 | rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2); | ||
435 | if (2 != rc) | ||
436 | tuner_warn("i2c i/o error: rc == %d " | ||
437 | "(should be 2)\n", rc); | ||
438 | break; | 449 | break; |
439 | case TUNER_MICROTUNE_4042FI5: | 450 | case TUNER_MICROTUNE_4042FI5: |
440 | { | 451 | { |
@@ -506,6 +517,11 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer) | |||
506 | case TUNER_THOMSON_DTT761X: | 517 | case TUNER_THOMSON_DTT761X: |
507 | buffer[3] = 0x39; | 518 | buffer[3] = 0x39; |
508 | break; | 519 | break; |
520 | case TUNER_PHILIPS_FQ1216LME_MK3: | ||
521 | tuner_err("This tuner doesn't have FM\n"); | ||
522 | /* Set the low band for sanity, since it covers 88-108 MHz */ | ||
523 | buffer[3] = 0x01; | ||
524 | break; | ||
509 | case TUNER_MICROTUNE_4049FM5: | 525 | case TUNER_MICROTUNE_4049FM5: |
510 | default: | 526 | default: |
511 | buffer[3] = 0xa4; | 527 | buffer[3] = 0xa4; |
@@ -678,12 +694,12 @@ static int simple_set_radio_freq(struct dvb_frontend *fe, | |||
678 | return 0; | 694 | return 0; |
679 | } | 695 | } |
680 | 696 | ||
681 | /* Bandswitch byte */ | ||
682 | simple_radio_bandswitch(fe, &buffer[0]); | ||
683 | |||
684 | buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) | | 697 | buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) | |
685 | TUNER_RATIO_SELECT_50; /* 50 kHz step */ | 698 | TUNER_RATIO_SELECT_50; /* 50 kHz step */ |
686 | 699 | ||
700 | /* Bandswitch byte */ | ||
701 | simple_radio_bandswitch(fe, &buffer[0]); | ||
702 | |||
687 | /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps | 703 | /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps |
688 | freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) = | 704 | freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) = |
689 | freq * (1/800) */ | 705 | freq * (1/800) */ |
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c index 7c0bc064c008..6a7f1a417c27 100644 --- a/drivers/media/common/tuners/tuner-types.c +++ b/drivers/media/common/tuners/tuner-types.c | |||
@@ -578,6 +578,31 @@ static struct tuner_params tuner_fm1216me_mk3_params[] = { | |||
578 | }, | 578 | }, |
579 | }; | 579 | }; |
580 | 580 | ||
581 | /* ------------ TUNER_PHILIPS_FM1216MK5 - Philips PAL ------------ */ | ||
582 | |||
583 | static struct tuner_range tuner_fm1216mk5_pal_ranges[] = { | ||
584 | { 16 * 158.00 /*MHz*/, 0xce, 0x01, }, | ||
585 | { 16 * 441.00 /*MHz*/, 0xce, 0x02, }, | ||
586 | { 16 * 864.00 , 0xce, 0x04, }, | ||
587 | }; | ||
588 | |||
589 | static struct tuner_params tuner_fm1216mk5_params[] = { | ||
590 | { | ||
591 | .type = TUNER_PARAM_TYPE_PAL, | ||
592 | .ranges = tuner_fm1216mk5_pal_ranges, | ||
593 | .count = ARRAY_SIZE(tuner_fm1216mk5_pal_ranges), | ||
594 | .cb_first_if_lower_freq = 1, | ||
595 | .has_tda9887 = 1, | ||
596 | .port1_active = 1, | ||
597 | .port2_active = 1, | ||
598 | .port2_invert_for_secam_lc = 1, | ||
599 | .port1_fm_high_sensitivity = 1, | ||
600 | .default_top_mid = -2, | ||
601 | .default_top_secam_mid = -2, | ||
602 | .default_top_secam_high = -2, | ||
603 | }, | ||
604 | }; | ||
605 | |||
581 | /* ------------ TUNER_LG_NTSC_NEW_TAPC - LGINNOTEK NTSC ------------ */ | 606 | /* ------------ TUNER_LG_NTSC_NEW_TAPC - LGINNOTEK NTSC ------------ */ |
582 | 607 | ||
583 | static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = { | 608 | static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = { |
@@ -1254,6 +1279,28 @@ static struct tuner_params tuner_tcl_mf02gip_5n_params[] = { | |||
1254 | }, | 1279 | }, |
1255 | }; | 1280 | }; |
1256 | 1281 | ||
1282 | /* 80-89 */ | ||
1283 | /* --------- TUNER_PHILIPS_FQ1216LME_MK3 -- active loopthrough, no FM ------- */ | ||
1284 | |||
1285 | static struct tuner_params tuner_fq1216lme_mk3_params[] = { | ||
1286 | { | ||
1287 | .type = TUNER_PARAM_TYPE_PAL, | ||
1288 | .ranges = tuner_fm1216me_mk3_pal_ranges, | ||
1289 | .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges), | ||
1290 | .cb_first_if_lower_freq = 1, /* not specified, but safe to do */ | ||
1291 | .has_tda9887 = 1, /* TDA9886 */ | ||
1292 | .port1_active = 1, | ||
1293 | .port2_active = 1, | ||
1294 | .port2_invert_for_secam_lc = 1, | ||
1295 | .default_top_low = 4, | ||
1296 | .default_top_mid = 4, | ||
1297 | .default_top_high = 4, | ||
1298 | .default_top_secam_low = 4, | ||
1299 | .default_top_secam_mid = 4, | ||
1300 | .default_top_secam_high = 4, | ||
1301 | }, | ||
1302 | }; | ||
1303 | |||
1257 | /* --------------------------------------------------------------------- */ | 1304 | /* --------------------------------------------------------------------- */ |
1258 | 1305 | ||
1259 | struct tunertype tuners[] = { | 1306 | struct tunertype tuners[] = { |
@@ -1694,6 +1741,18 @@ struct tunertype tuners[] = { | |||
1694 | .initdata = tua603x_agc112, | 1741 | .initdata = tua603x_agc112, |
1695 | .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 }, | 1742 | .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 }, |
1696 | }, | 1743 | }, |
1744 | [TUNER_PHILIPS_FM1216MK5] = { /* Philips PAL */ | ||
1745 | .name = "Philips PAL/SECAM multi (FM1216 MK5)", | ||
1746 | .params = tuner_fm1216mk5_params, | ||
1747 | .count = ARRAY_SIZE(tuner_fm1216mk5_params), | ||
1748 | }, | ||
1749 | |||
1750 | /* 80-89 */ | ||
1751 | [TUNER_PHILIPS_FQ1216LME_MK3] = { /* PAL/SECAM, Loop-thru, no FM */ | ||
1752 | .name = "Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough", | ||
1753 | .params = tuner_fq1216lme_mk3_params, | ||
1754 | .count = ARRAY_SIZE(tuner_fq1216lme_mk3_params), | ||
1755 | }, | ||
1697 | }; | 1756 | }; |
1698 | EXPORT_SYMBOL(tuners); | 1757 | EXPORT_SYMBOL(tuners); |
1699 | 1758 | ||
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 7636c33bc1e9..b6da9c3873fe 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c | |||
@@ -30,7 +30,7 @@ MODULE_PARM_DESC(debug, "enable verbose debug messages"); | |||
30 | 30 | ||
31 | static int no_poweroff; | 31 | static int no_poweroff; |
32 | module_param(no_poweroff, int, 0644); | 32 | module_param(no_poweroff, int, 0644); |
33 | MODULE_PARM_DESC(debug, "0 (default) powers device off when not used.\n" | 33 | MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n" |
34 | "1 keep device energized and with tuner ready all the times.\n" | 34 | "1 keep device energized and with tuner ready all the times.\n" |
35 | " Faster, but consumes more power and keeps the device hotter\n"); | 35 | " Faster, but consumes more power and keeps the device hotter\n"); |
36 | 36 | ||
@@ -272,7 +272,7 @@ static int load_all_firmwares(struct dvb_frontend *fe) | |||
272 | fname = firmware_name; | 272 | fname = firmware_name; |
273 | 273 | ||
274 | tuner_dbg("Reading firmware %s\n", fname); | 274 | tuner_dbg("Reading firmware %s\n", fname); |
275 | rc = request_firmware(&fw, fname, &priv->i2c_props.adap->dev); | 275 | rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent); |
276 | if (rc < 0) { | 276 | if (rc < 0) { |
277 | if (rc == -ENOENT) | 277 | if (rc == -ENOENT) |
278 | tuner_err("Error: firmware %s not found.\n", | 278 | tuner_err("Error: firmware %s not found.\n", |
@@ -917,22 +917,29 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, | |||
917 | * that xc2028 will be in a safe state. | 917 | * that xc2028 will be in a safe state. |
918 | * Maybe this might also be needed for DTV. | 918 | * Maybe this might also be needed for DTV. |
919 | */ | 919 | */ |
920 | if (new_mode == T_ANALOG_TV) { | 920 | if (new_mode == T_ANALOG_TV) |
921 | rc = send_seq(priv, {0x00, 0x00}); | 921 | rc = send_seq(priv, {0x00, 0x00}); |
922 | } else if (priv->cur_fw.type & ATSC) { | 922 | |
923 | offset = 1750000; | 923 | /* |
924 | } else { | 924 | * Digital modes require an offset to adjust to the |
925 | offset = 2750000; | 925 | * proper frequency. |
926 | * Analog modes require offset = 0 | ||
927 | */ | ||
928 | if (new_mode == T_DIGITAL_TV) { | ||
929 | /* Sets the offset according with firmware */ | ||
930 | if (priv->cur_fw.type & DTV6) | ||
931 | offset = 1750000; | ||
932 | else if (priv->cur_fw.type & DTV7) | ||
933 | offset = 2250000; | ||
934 | else /* DTV8 or DTV78 */ | ||
935 | offset = 2750000; | ||
936 | |||
926 | /* | 937 | /* |
927 | * We must adjust the offset by 500kHz in two cases in order | 938 | * We must adjust the offset by 500kHz when |
928 | * to correctly center the IF output: | 939 | * tuning a 7MHz VHF channel with DTV78 firmware |
929 | * 1) When the ZARLINK456 or DIBCOM52 tables were explicitly | 940 | * (used in Australia, Italy and Germany) |
930 | * selected and a 7MHz channel is tuned; | ||
931 | * 2) When tuning a VHF channel with DTV78 firmware. | ||
932 | */ | 941 | */ |
933 | if (((priv->cur_fw.type & DTV7) && | 942 | if ((priv->cur_fw.type & DTV78) && freq < 470000000) |
934 | (priv->cur_fw.scode_table & (ZARLINK456 | DIBCOM52))) || | ||
935 | ((priv->cur_fw.type & DTV78) && freq < 470000000)) | ||
936 | offset -= 500000; | 943 | offset -= 500000; |
937 | } | 944 | } |
938 | 945 | ||
@@ -991,7 +998,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe, | |||
991 | if (priv->ctrl.input1) | 998 | if (priv->ctrl.input1) |
992 | type |= INPUT1; | 999 | type |= INPUT1; |
993 | return generic_set_freq(fe, (625l * p->frequency) / 10, | 1000 | return generic_set_freq(fe, (625l * p->frequency) / 10, |
994 | T_ANALOG_TV, type, 0, 0); | 1001 | T_RADIO, type, 0, 0); |
995 | } | 1002 | } |
996 | 1003 | ||
997 | /* if std is not defined, choose one */ | 1004 | /* if std is not defined, choose one */ |
@@ -1022,21 +1029,20 @@ static int xc2028_set_params(struct dvb_frontend *fe, | |||
1022 | switch(fe->ops.info.type) { | 1029 | switch(fe->ops.info.type) { |
1023 | case FE_OFDM: | 1030 | case FE_OFDM: |
1024 | bw = p->u.ofdm.bandwidth; | 1031 | bw = p->u.ofdm.bandwidth; |
1025 | break; | 1032 | /* |
1026 | case FE_QAM: | 1033 | * The only countries with 6MHz seem to be Taiwan/Uruguay. |
1027 | tuner_info("WARN: There are some reports that " | 1034 | * Both seem to require QAM firmware for OFDM decoding |
1028 | "QAM 6 MHz doesn't work.\n" | 1035 | * Tested in Taiwan by Terry Wu <terrywu2009@gmail.com> |
1029 | "If this works for you, please report by " | 1036 | */ |
1030 | "e-mail to: v4l-dvb-maintainer@linuxtv.org\n"); | 1037 | if (bw == BANDWIDTH_6_MHZ) |
1031 | bw = BANDWIDTH_6_MHZ; | 1038 | type |= QAM; |
1032 | type |= QAM; | ||
1033 | break; | 1039 | break; |
1034 | case FE_ATSC: | 1040 | case FE_ATSC: |
1035 | bw = BANDWIDTH_6_MHZ; | 1041 | bw = BANDWIDTH_6_MHZ; |
1036 | /* The only ATSC firmware (at least on v2.7) is D2633 */ | 1042 | /* The only ATSC firmware (at least on v2.7) is D2633 */ |
1037 | type |= ATSC | D2633; | 1043 | type |= ATSC | D2633; |
1038 | break; | 1044 | break; |
1039 | /* DVB-S is not supported */ | 1045 | /* DVB-S and pure QAM (FE_QAM) are not supported */ |
1040 | default: | 1046 | default: |
1041 | return -EINVAL; | 1047 | return -EINVAL; |
1042 | } | 1048 | } |
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index b54598550dc4..f4ffcdc9b848 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2007 Xceive Corporation | 4 | * Copyright (c) 2007 Xceive Corporation |
5 | * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org> | 5 | * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org> |
6 | * Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * 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 | * it under the terms of the GNU General Public License as published by |
@@ -36,14 +37,20 @@ static int debug; | |||
36 | module_param(debug, int, 0644); | 37 | module_param(debug, int, 0644); |
37 | MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); | 38 | MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); |
38 | 39 | ||
40 | static int no_poweroff; | ||
41 | module_param(no_poweroff, int, 0644); | ||
42 | MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n" | ||
43 | "\t\t1 keep device energized and with tuner ready all the times.\n" | ||
44 | "\t\tFaster, but consumes more power and keeps the device hotter"); | ||
45 | |||
39 | static DEFINE_MUTEX(xc5000_list_mutex); | 46 | static DEFINE_MUTEX(xc5000_list_mutex); |
40 | static LIST_HEAD(hybrid_tuner_instance_list); | 47 | static LIST_HEAD(hybrid_tuner_instance_list); |
41 | 48 | ||
42 | #define dprintk(level, fmt, arg...) if (debug >= level) \ | 49 | #define dprintk(level, fmt, arg...) if (debug >= level) \ |
43 | printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) | 50 | printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) |
44 | 51 | ||
45 | #define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw" | 52 | #define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.6.114.fw" |
46 | #define XC5000_DEFAULT_FIRMWARE_SIZE 12332 | 53 | #define XC5000_DEFAULT_FIRMWARE_SIZE 12401 |
47 | 54 | ||
48 | struct xc5000_priv { | 55 | struct xc5000_priv { |
49 | struct tuner_i2c_props i2c_props; | 56 | struct tuner_i2c_props i2c_props; |
@@ -83,11 +90,11 @@ struct xc5000_priv { | |||
83 | #define XREG_D_CODE 0x04 | 90 | #define XREG_D_CODE 0x04 |
84 | #define XREG_IF_OUT 0x05 | 91 | #define XREG_IF_OUT 0x05 |
85 | #define XREG_SEEK_MODE 0x07 | 92 | #define XREG_SEEK_MODE 0x07 |
86 | #define XREG_POWER_DOWN 0x0A | 93 | #define XREG_POWER_DOWN 0x0A /* Obsolete */ |
87 | #define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */ | 94 | #define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */ |
88 | #define XREG_SMOOTHEDCVBS 0x0E | 95 | #define XREG_SMOOTHEDCVBS 0x0E |
89 | #define XREG_XTALFREQ 0x0F | 96 | #define XREG_XTALFREQ 0x0F |
90 | #define XREG_FINERFFREQ 0x10 | 97 | #define XREG_FINERFREQ 0x10 |
91 | #define XREG_DDIMODE 0x11 | 98 | #define XREG_DDIMODE 0x11 |
92 | 99 | ||
93 | #define XREG_ADC_ENV 0x00 | 100 | #define XREG_ADC_ENV 0x00 |
@@ -100,6 +107,7 @@ struct xc5000_priv { | |||
100 | #define XREG_VERSION 0x07 | 107 | #define XREG_VERSION 0x07 |
101 | #define XREG_PRODUCT_ID 0x08 | 108 | #define XREG_PRODUCT_ID 0x08 |
102 | #define XREG_BUSY 0x09 | 109 | #define XREG_BUSY 0x09 |
110 | #define XREG_BUILD 0x0D | ||
103 | 111 | ||
104 | /* | 112 | /* |
105 | Basic firmware description. This will remain with | 113 | Basic firmware description. This will remain with |
@@ -191,27 +199,36 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { | |||
191 | {"FM Radio-INPUT1", 0x0208, 0x9002} | 199 | {"FM Radio-INPUT1", 0x0208, 0x9002} |
192 | }; | 200 | }; |
193 | 201 | ||
194 | static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); | 202 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); |
195 | static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len); | 203 | static int xc5000_is_firmware_loaded(struct dvb_frontend *fe); |
196 | static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len); | 204 | static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val); |
197 | static void xc5000_TunerReset(struct dvb_frontend *fe); | 205 | static int xc5000_TunerReset(struct dvb_frontend *fe); |
198 | 206 | ||
199 | static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) | 207 | static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) |
200 | { | 208 | { |
201 | return xc5000_writeregs(priv, buf, len) | 209 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, |
202 | ? XC_RESULT_I2C_WRITE_FAILURE : XC_RESULT_SUCCESS; | 210 | .flags = 0, .buf = buf, .len = len }; |
211 | |||
212 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { | ||
213 | printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", len); | ||
214 | return XC_RESULT_I2C_WRITE_FAILURE; | ||
215 | } | ||
216 | return XC_RESULT_SUCCESS; | ||
203 | } | 217 | } |
204 | 218 | ||
219 | /* This routine is never used because the only time we read data from the | ||
220 | i2c bus is when we read registers, and we want that to be an atomic i2c | ||
221 | transaction in case we are on a multi-master bus */ | ||
205 | static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) | 222 | static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len) |
206 | { | 223 | { |
207 | return xc5000_readregs(priv, buf, len) | 224 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, |
208 | ? XC_RESULT_I2C_READ_FAILURE : XC_RESULT_SUCCESS; | 225 | .flags = I2C_M_RD, .buf = buf, .len = len }; |
209 | } | ||
210 | 226 | ||
211 | static int xc_reset(struct dvb_frontend *fe) | 227 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { |
212 | { | 228 | printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", len); |
213 | xc5000_TunerReset(fe); | 229 | return -EREMOTEIO; |
214 | return XC_RESULT_SUCCESS; | 230 | } |
231 | return 0; | ||
215 | } | 232 | } |
216 | 233 | ||
217 | static void xc_wait(int wait_ms) | 234 | static void xc_wait(int wait_ms) |
@@ -219,7 +236,7 @@ static void xc_wait(int wait_ms) | |||
219 | msleep(wait_ms); | 236 | msleep(wait_ms); |
220 | } | 237 | } |
221 | 238 | ||
222 | static void xc5000_TunerReset(struct dvb_frontend *fe) | 239 | static int xc5000_TunerReset(struct dvb_frontend *fe) |
223 | { | 240 | { |
224 | struct xc5000_priv *priv = fe->tuner_priv; | 241 | struct xc5000_priv *priv = fe->tuner_priv; |
225 | int ret; | 242 | int ret; |
@@ -232,16 +249,21 @@ static void xc5000_TunerReset(struct dvb_frontend *fe) | |||
232 | priv->i2c_props.adap->algo_data, | 249 | priv->i2c_props.adap->algo_data, |
233 | DVB_FRONTEND_COMPONENT_TUNER, | 250 | DVB_FRONTEND_COMPONENT_TUNER, |
234 | XC5000_TUNER_RESET, 0); | 251 | XC5000_TUNER_RESET, 0); |
235 | if (ret) | 252 | if (ret) { |
236 | printk(KERN_ERR "xc5000: reset failed\n"); | 253 | printk(KERN_ERR "xc5000: reset failed\n"); |
237 | } else | 254 | return XC_RESULT_RESET_FAILURE; |
255 | } | ||
256 | } else { | ||
238 | printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n"); | 257 | printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n"); |
258 | return XC_RESULT_RESET_FAILURE; | ||
259 | } | ||
260 | return XC_RESULT_SUCCESS; | ||
239 | } | 261 | } |
240 | 262 | ||
241 | static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) | 263 | static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) |
242 | { | 264 | { |
243 | u8 buf[4]; | 265 | u8 buf[4]; |
244 | int WatchDogTimer = 5; | 266 | int WatchDogTimer = 100; |
245 | int result; | 267 | int result; |
246 | 268 | ||
247 | buf[0] = (regAddr >> 8) & 0xFF; | 269 | buf[0] = (regAddr >> 8) & 0xFF; |
@@ -263,7 +285,7 @@ static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) | |||
263 | /* busy flag cleared */ | 285 | /* busy flag cleared */ |
264 | break; | 286 | break; |
265 | } else { | 287 | } else { |
266 | xc_wait(100); /* wait 5 ms */ | 288 | xc_wait(5); /* wait 5 ms */ |
267 | WatchDogTimer--; | 289 | WatchDogTimer--; |
268 | } | 290 | } |
269 | } | 291 | } |
@@ -276,25 +298,6 @@ static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData) | |||
276 | return result; | 298 | return result; |
277 | } | 299 | } |
278 | 300 | ||
279 | static int xc_read_reg(struct xc5000_priv *priv, u16 regAddr, u16 *i2cData) | ||
280 | { | ||
281 | u8 buf[2]; | ||
282 | int result; | ||
283 | |||
284 | buf[0] = (regAddr >> 8) & 0xFF; | ||
285 | buf[1] = regAddr & 0xFF; | ||
286 | result = xc_send_i2c_data(priv, buf, 2); | ||
287 | if (result != XC_RESULT_SUCCESS) | ||
288 | return result; | ||
289 | |||
290 | result = xc_read_i2c_data(priv, buf, 2); | ||
291 | if (result != XC_RESULT_SUCCESS) | ||
292 | return result; | ||
293 | |||
294 | *i2cData = buf[0] * 256 + buf[1]; | ||
295 | return result; | ||
296 | } | ||
297 | |||
298 | static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) | 301 | static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) |
299 | { | 302 | { |
300 | struct xc5000_priv *priv = fe->tuner_priv; | 303 | struct xc5000_priv *priv = fe->tuner_priv; |
@@ -309,7 +312,7 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence) | |||
309 | len = i2c_sequence[index] * 256 + i2c_sequence[index+1]; | 312 | len = i2c_sequence[index] * 256 + i2c_sequence[index+1]; |
310 | if (len == 0x0000) { | 313 | if (len == 0x0000) { |
311 | /* RESET command */ | 314 | /* RESET command */ |
312 | result = xc_reset(fe); | 315 | result = xc5000_TunerReset(fe); |
313 | index += 2; | 316 | index += 2; |
314 | if (result != XC_RESULT_SUCCESS) | 317 | if (result != XC_RESULT_SUCCESS) |
315 | return result; | 318 | return result; |
@@ -371,15 +374,6 @@ static int xc_SetTVStandard(struct xc5000_priv *priv, | |||
371 | return ret; | 374 | return ret; |
372 | } | 375 | } |
373 | 376 | ||
374 | static int xc_shutdown(struct xc5000_priv *priv) | ||
375 | { | ||
376 | return XC_RESULT_SUCCESS; | ||
377 | /* Fixme: cannot bring tuner back alive once shutdown | ||
378 | * without reloading the driver modules. | ||
379 | * return xc_write_reg(priv, XREG_POWER_DOWN, 0); | ||
380 | */ | ||
381 | } | ||
382 | |||
383 | static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) | 377 | static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) |
384 | { | 378 | { |
385 | dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode, | 379 | dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode, |
@@ -408,7 +402,10 @@ static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz) | |||
408 | 402 | ||
409 | freq_code = (u16)(freq_hz / 15625); | 403 | freq_code = (u16)(freq_hz / 15625); |
410 | 404 | ||
411 | return xc_write_reg(priv, XREG_RF_FREQ, freq_code); | 405 | /* Starting in firmware version 1.1.44, Xceive recommends using the |
406 | FINERFREQ for all normal tuning (the doc indicates reg 0x03 should | ||
407 | only be used for fast scanning for channel lock) */ | ||
408 | return xc_write_reg(priv, XREG_FINERFREQ, freq_code); | ||
412 | } | 409 | } |
413 | 410 | ||
414 | 411 | ||
@@ -424,7 +421,7 @@ static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz) | |||
424 | 421 | ||
425 | static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope) | 422 | static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope) |
426 | { | 423 | { |
427 | return xc_read_reg(priv, XREG_ADC_ENV, adc_envelope); | 424 | return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope); |
428 | } | 425 | } |
429 | 426 | ||
430 | static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) | 427 | static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) |
@@ -433,8 +430,8 @@ static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) | |||
433 | u16 regData; | 430 | u16 regData; |
434 | u32 tmp; | 431 | u32 tmp; |
435 | 432 | ||
436 | result = xc_read_reg(priv, XREG_FREQ_ERROR, ®Data); | 433 | result = xc5000_readreg(priv, XREG_FREQ_ERROR, ®Data); |
437 | if (result) | 434 | if (result != XC_RESULT_SUCCESS) |
438 | return result; | 435 | return result; |
439 | 436 | ||
440 | tmp = (u32)regData; | 437 | tmp = (u32)regData; |
@@ -444,7 +441,7 @@ static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz) | |||
444 | 441 | ||
445 | static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status) | 442 | static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status) |
446 | { | 443 | { |
447 | return xc_read_reg(priv, XREG_LOCK, lock_status); | 444 | return xc5000_readreg(priv, XREG_LOCK, lock_status); |
448 | } | 445 | } |
449 | 446 | ||
450 | static int xc_get_version(struct xc5000_priv *priv, | 447 | static int xc_get_version(struct xc5000_priv *priv, |
@@ -454,8 +451,8 @@ static int xc_get_version(struct xc5000_priv *priv, | |||
454 | u16 data; | 451 | u16 data; |
455 | int result; | 452 | int result; |
456 | 453 | ||
457 | result = xc_read_reg(priv, XREG_VERSION, &data); | 454 | result = xc5000_readreg(priv, XREG_VERSION, &data); |
458 | if (result) | 455 | if (result != XC_RESULT_SUCCESS) |
459 | return result; | 456 | return result; |
460 | 457 | ||
461 | (*hw_majorversion) = (data >> 12) & 0x0F; | 458 | (*hw_majorversion) = (data >> 12) & 0x0F; |
@@ -466,13 +463,18 @@ static int xc_get_version(struct xc5000_priv *priv, | |||
466 | return 0; | 463 | return 0; |
467 | } | 464 | } |
468 | 465 | ||
466 | static int xc_get_buildversion(struct xc5000_priv *priv, u16 *buildrev) | ||
467 | { | ||
468 | return xc5000_readreg(priv, XREG_BUILD, buildrev); | ||
469 | } | ||
470 | |||
469 | static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) | 471 | static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) |
470 | { | 472 | { |
471 | u16 regData; | 473 | u16 regData; |
472 | int result; | 474 | int result; |
473 | 475 | ||
474 | result = xc_read_reg(priv, XREG_HSYNC_FREQ, ®Data); | 476 | result = xc5000_readreg(priv, XREG_HSYNC_FREQ, ®Data); |
475 | if (result) | 477 | if (result != XC_RESULT_SUCCESS) |
476 | return result; | 478 | return result; |
477 | 479 | ||
478 | (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100; | 480 | (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100; |
@@ -481,12 +483,12 @@ static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz) | |||
481 | 483 | ||
482 | static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines) | 484 | static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines) |
483 | { | 485 | { |
484 | return xc_read_reg(priv, XREG_FRAME_LINES, frame_lines); | 486 | return xc5000_readreg(priv, XREG_FRAME_LINES, frame_lines); |
485 | } | 487 | } |
486 | 488 | ||
487 | static int xc_get_quality(struct xc5000_priv *priv, u16 *quality) | 489 | static int xc_get_quality(struct xc5000_priv *priv, u16 *quality) |
488 | { | 490 | { |
489 | return xc_read_reg(priv, XREG_QUALITY, quality); | 491 | return xc5000_readreg(priv, XREG_QUALITY, quality); |
490 | } | 492 | } |
491 | 493 | ||
492 | static u16 WaitForLock(struct xc5000_priv *priv) | 494 | static u16 WaitForLock(struct xc5000_priv *priv) |
@@ -504,7 +506,9 @@ static u16 WaitForLock(struct xc5000_priv *priv) | |||
504 | return lockState; | 506 | return lockState; |
505 | } | 507 | } |
506 | 508 | ||
507 | static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz) | 509 | #define XC_TUNE_ANALOG 0 |
510 | #define XC_TUNE_DIGITAL 1 | ||
511 | static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode) | ||
508 | { | 512 | { |
509 | int found = 0; | 513 | int found = 0; |
510 | 514 | ||
@@ -513,8 +517,10 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz) | |||
513 | if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS) | 517 | if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS) |
514 | return 0; | 518 | return 0; |
515 | 519 | ||
516 | if (WaitForLock(priv) == 1) | 520 | if (mode == XC_TUNE_ANALOG) { |
517 | found = 1; | 521 | if (WaitForLock(priv) == 1) |
522 | found = 1; | ||
523 | } | ||
518 | 524 | ||
519 | return found; | 525 | return found; |
520 | } | 526 | } |
@@ -536,32 +542,7 @@ static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val) | |||
536 | } | 542 | } |
537 | 543 | ||
538 | *val = (bval[0] << 8) | bval[1]; | 544 | *val = (bval[0] << 8) | bval[1]; |
539 | return 0; | 545 | return XC_RESULT_SUCCESS; |
540 | } | ||
541 | |||
542 | static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len) | ||
543 | { | ||
544 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, | ||
545 | .flags = 0, .buf = buf, .len = len }; | ||
546 | |||
547 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { | ||
548 | printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", | ||
549 | (int)len); | ||
550 | return -EREMOTEIO; | ||
551 | } | ||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len) | ||
556 | { | ||
557 | struct i2c_msg msg = { .addr = priv->i2c_props.addr, | ||
558 | .flags = I2C_M_RD, .buf = buf, .len = len }; | ||
559 | |||
560 | if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) { | ||
561 | printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", (int)len); | ||
562 | return -EREMOTEIO; | ||
563 | } | ||
564 | return 0; | ||
565 | } | 546 | } |
566 | 547 | ||
567 | static int xc5000_fwupload(struct dvb_frontend *fe) | 548 | static int xc5000_fwupload(struct dvb_frontend *fe) |
@@ -575,13 +556,13 @@ static int xc5000_fwupload(struct dvb_frontend *fe) | |||
575 | XC5000_DEFAULT_FIRMWARE); | 556 | XC5000_DEFAULT_FIRMWARE); |
576 | 557 | ||
577 | ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, | 558 | ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, |
578 | &priv->i2c_props.adap->dev); | 559 | priv->i2c_props.adap->dev.parent); |
579 | if (ret) { | 560 | if (ret) { |
580 | printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); | 561 | printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n"); |
581 | ret = XC_RESULT_RESET_FAILURE; | 562 | ret = XC_RESULT_RESET_FAILURE; |
582 | goto out; | 563 | goto out; |
583 | } else { | 564 | } else { |
584 | printk(KERN_INFO "xc5000: firmware read %Zu bytes.\n", | 565 | printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n", |
585 | fw->size); | 566 | fw->size); |
586 | ret = XC_RESULT_SUCCESS; | 567 | ret = XC_RESULT_SUCCESS; |
587 | } | 568 | } |
@@ -590,8 +571,9 @@ static int xc5000_fwupload(struct dvb_frontend *fe) | |||
590 | printk(KERN_ERR "xc5000: firmware incorrect size\n"); | 571 | printk(KERN_ERR "xc5000: firmware incorrect size\n"); |
591 | ret = XC_RESULT_RESET_FAILURE; | 572 | ret = XC_RESULT_RESET_FAILURE; |
592 | } else { | 573 | } else { |
593 | printk(KERN_INFO "xc5000: firmware upload\n"); | 574 | printk(KERN_INFO "xc5000: firmware uploading...\n"); |
594 | ret = xc_load_i2c_sequence(fe, fw->data); | 575 | ret = xc_load_i2c_sequence(fe, fw->data); |
576 | printk(KERN_INFO "xc5000: firmware upload complete...\n"); | ||
595 | } | 577 | } |
596 | 578 | ||
597 | out: | 579 | out: |
@@ -609,6 +591,7 @@ static void xc_debug_dump(struct xc5000_priv *priv) | |||
609 | u16 quality; | 591 | u16 quality; |
610 | u8 hw_majorversion = 0, hw_minorversion = 0; | 592 | u8 hw_majorversion = 0, hw_minorversion = 0; |
611 | u8 fw_majorversion = 0, fw_minorversion = 0; | 593 | u8 fw_majorversion = 0, fw_minorversion = 0; |
594 | u16 fw_buildversion = 0; | ||
612 | 595 | ||
613 | /* Wait for stats to stabilize. | 596 | /* Wait for stats to stabilize. |
614 | * Frame Lines needs two frame times after initial lock | 597 | * Frame Lines needs two frame times after initial lock |
@@ -628,9 +611,10 @@ static void xc_debug_dump(struct xc5000_priv *priv) | |||
628 | 611 | ||
629 | xc_get_version(priv, &hw_majorversion, &hw_minorversion, | 612 | xc_get_version(priv, &hw_majorversion, &hw_minorversion, |
630 | &fw_majorversion, &fw_minorversion); | 613 | &fw_majorversion, &fw_minorversion); |
631 | dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n", | 614 | xc_get_buildversion(priv, &fw_buildversion); |
615 | dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x.%04x\n", | ||
632 | hw_majorversion, hw_minorversion, | 616 | hw_majorversion, hw_minorversion, |
633 | fw_majorversion, fw_minorversion); | 617 | fw_majorversion, fw_minorversion, fw_buildversion); |
634 | 618 | ||
635 | xc_get_hsync_freq(priv, &hsync_freq_hz); | 619 | xc_get_hsync_freq(priv, &hsync_freq_hz); |
636 | dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz); | 620 | dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz); |
@@ -648,27 +632,57 @@ static int xc5000_set_params(struct dvb_frontend *fe, | |||
648 | struct xc5000_priv *priv = fe->tuner_priv; | 632 | struct xc5000_priv *priv = fe->tuner_priv; |
649 | int ret; | 633 | int ret; |
650 | 634 | ||
635 | if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) | ||
636 | xc_load_fw_and_init_tuner(fe); | ||
637 | |||
651 | dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); | 638 | dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); |
652 | 639 | ||
653 | switch (params->u.vsb.modulation) { | 640 | if (fe->ops.info.type == FE_ATSC) { |
654 | case VSB_8: | 641 | dprintk(1, "%s() ATSC\n", __func__); |
655 | case VSB_16: | 642 | switch (params->u.vsb.modulation) { |
656 | dprintk(1, "%s() VSB modulation\n", __func__); | 643 | case VSB_8: |
644 | case VSB_16: | ||
645 | dprintk(1, "%s() VSB modulation\n", __func__); | ||
646 | priv->rf_mode = XC_RF_MODE_AIR; | ||
647 | priv->freq_hz = params->frequency - 1750000; | ||
648 | priv->bandwidth = BANDWIDTH_6_MHZ; | ||
649 | priv->video_standard = DTV6; | ||
650 | break; | ||
651 | case QAM_64: | ||
652 | case QAM_256: | ||
653 | case QAM_AUTO: | ||
654 | dprintk(1, "%s() QAM modulation\n", __func__); | ||
655 | priv->rf_mode = XC_RF_MODE_CABLE; | ||
656 | priv->freq_hz = params->frequency - 1750000; | ||
657 | priv->bandwidth = BANDWIDTH_6_MHZ; | ||
658 | priv->video_standard = DTV6; | ||
659 | break; | ||
660 | default: | ||
661 | return -EINVAL; | ||
662 | } | ||
663 | } else if (fe->ops.info.type == FE_OFDM) { | ||
664 | dprintk(1, "%s() OFDM\n", __func__); | ||
665 | switch (params->u.ofdm.bandwidth) { | ||
666 | case BANDWIDTH_6_MHZ: | ||
667 | priv->bandwidth = BANDWIDTH_6_MHZ; | ||
668 | priv->video_standard = DTV6; | ||
669 | priv->freq_hz = params->frequency - 1750000; | ||
670 | break; | ||
671 | case BANDWIDTH_7_MHZ: | ||
672 | printk(KERN_ERR "xc5000 bandwidth 7MHz not supported\n"); | ||
673 | return -EINVAL; | ||
674 | case BANDWIDTH_8_MHZ: | ||
675 | priv->bandwidth = BANDWIDTH_8_MHZ; | ||
676 | priv->video_standard = DTV8; | ||
677 | priv->freq_hz = params->frequency - 2750000; | ||
678 | break; | ||
679 | default: | ||
680 | printk(KERN_ERR "xc5000 bandwidth not set!\n"); | ||
681 | return -EINVAL; | ||
682 | } | ||
657 | priv->rf_mode = XC_RF_MODE_AIR; | 683 | priv->rf_mode = XC_RF_MODE_AIR; |
658 | priv->freq_hz = params->frequency - 1750000; | 684 | } else { |
659 | priv->bandwidth = BANDWIDTH_6_MHZ; | 685 | printk(KERN_ERR "xc5000 modulation type not supported!\n"); |
660 | priv->video_standard = DTV6; | ||
661 | break; | ||
662 | case QAM_64: | ||
663 | case QAM_256: | ||
664 | case QAM_AUTO: | ||
665 | dprintk(1, "%s() QAM modulation\n", __func__); | ||
666 | priv->rf_mode = XC_RF_MODE_CABLE; | ||
667 | priv->freq_hz = params->frequency - 1750000; | ||
668 | priv->bandwidth = BANDWIDTH_6_MHZ; | ||
669 | priv->video_standard = DTV6; | ||
670 | break; | ||
671 | default: | ||
672 | return -EINVAL; | 686 | return -EINVAL; |
673 | } | 687 | } |
674 | 688 | ||
@@ -698,7 +712,7 @@ static int xc5000_set_params(struct dvb_frontend *fe, | |||
698 | return -EIO; | 712 | return -EIO; |
699 | } | 713 | } |
700 | 714 | ||
701 | xc_tune_channel(priv, priv->freq_hz); | 715 | xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL); |
702 | 716 | ||
703 | if (debug) | 717 | if (debug) |
704 | xc_debug_dump(priv); | 718 | xc_debug_dump(priv); |
@@ -725,8 +739,6 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe) | |||
725 | return ret; | 739 | return ret; |
726 | } | 740 | } |
727 | 741 | ||
728 | static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); | ||
729 | |||
730 | static int xc5000_set_analog_params(struct dvb_frontend *fe, | 742 | static int xc5000_set_analog_params(struct dvb_frontend *fe, |
731 | struct analog_parameters *params) | 743 | struct analog_parameters *params) |
732 | { | 744 | { |
@@ -807,7 +819,7 @@ tune_channel: | |||
807 | return -EREMOTEIO; | 819 | return -EREMOTEIO; |
808 | } | 820 | } |
809 | 821 | ||
810 | xc_tune_channel(priv, priv->freq_hz); | 822 | xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG); |
811 | 823 | ||
812 | if (debug) | 824 | if (debug) |
813 | xc_debug_dump(priv); | 825 | xc_debug_dump(priv); |
@@ -875,18 +887,18 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe) | |||
875 | 887 | ||
876 | static int xc5000_sleep(struct dvb_frontend *fe) | 888 | static int xc5000_sleep(struct dvb_frontend *fe) |
877 | { | 889 | { |
878 | struct xc5000_priv *priv = fe->tuner_priv; | ||
879 | int ret; | 890 | int ret; |
880 | 891 | ||
881 | dprintk(1, "%s()\n", __func__); | 892 | dprintk(1, "%s()\n", __func__); |
882 | 893 | ||
883 | /* On Pinnacle PCTV HD 800i, the tuner cannot be reinitialized | 894 | /* Avoid firmware reload on slow devices */ |
884 | * once shutdown without reloading the driver. Maybe I am not | 895 | if (no_poweroff) |
885 | * doing something right. | 896 | return 0; |
886 | * | ||
887 | */ | ||
888 | 897 | ||
889 | ret = xc_shutdown(priv); | 898 | /* According to Xceive technical support, the "powerdown" register |
899 | was removed in newer versions of the firmware. The "supported" | ||
900 | way to sleep the tuner is to pull the reset pin low for 10ms */ | ||
901 | ret = xc5000_TunerReset(fe); | ||
890 | if (ret != XC_RESULT_SUCCESS) { | 902 | if (ret != XC_RESULT_SUCCESS) { |
891 | printk(KERN_ERR | 903 | printk(KERN_ERR |
892 | "xc5000: %s() unable to shutdown tuner\n", | 904 | "xc5000: %s() unable to shutdown tuner\n", |
@@ -991,7 +1003,7 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | |||
991 | /* Check if firmware has been loaded. It is possible that another | 1003 | /* Check if firmware has been loaded. It is possible that another |
992 | instance of the driver has loaded the firmware. | 1004 | instance of the driver has loaded the firmware. |
993 | */ | 1005 | */ |
994 | if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) | 1006 | if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS) |
995 | goto fail; | 1007 | goto fail; |
996 | 1008 | ||
997 | switch (id) { | 1009 | switch (id) { |