aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/tuner-xc2028.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/tuner-xc2028.c')
-rw-r--r--drivers/media/video/tuner-xc2028.c88
1 files changed, 51 insertions, 37 deletions
diff --git a/drivers/media/video/tuner-xc2028.c b/drivers/media/video/tuner-xc2028.c
index 9743331c895c..cf72f22986a4 100644
--- a/drivers/media/video/tuner-xc2028.c
+++ b/drivers/media/video/tuner-xc2028.c
@@ -50,6 +50,7 @@ static DEFINE_MUTEX(xc2028_list_mutex);
50struct firmware_description { 50struct firmware_description {
51 unsigned int type; 51 unsigned int type;
52 v4l2_std_id id; 52 v4l2_std_id id;
53 __u16 int_freq;
53 unsigned char *ptr; 54 unsigned char *ptr;
54 unsigned int size; 55 unsigned int size;
55}; 56};
@@ -58,6 +59,7 @@ struct firmware_properties {
58 unsigned int type; 59 unsigned int type;
59 v4l2_std_id id; 60 v4l2_std_id id;
60 v4l2_std_id std_req; 61 v4l2_std_id std_req;
62 __u16 int_freq;
61 unsigned int scode_table; 63 unsigned int scode_table;
62 int scode_nr; 64 int scode_nr;
63}; 65};
@@ -301,6 +303,7 @@ static int load_all_firmwares(struct dvb_frontend *fe)
301 while (p < endp) { 303 while (p < endp) {
302 __u32 type, size; 304 __u32 type, size;
303 v4l2_std_id id; 305 v4l2_std_id id;
306 __u16 int_freq = 0;
304 307
305 n++; 308 n++;
306 if (n >= n_array) { 309 if (n >= n_array) {
@@ -321,6 +324,11 @@ static int load_all_firmwares(struct dvb_frontend *fe)
321 id = le64_to_cpu(*(v4l2_std_id *) p); 324 id = le64_to_cpu(*(v4l2_std_id *) p);
322 p += sizeof(id); 325 p += sizeof(id);
323 326
327 if (type & HAS_IF) {
328 int_freq = le16_to_cpu(*(__u16 *) p);
329 p += sizeof(int_freq);
330 }
331
324 size = le32_to_cpu(*(__u32 *) p); 332 size = le32_to_cpu(*(__u32 *) p);
325 p += sizeof(size); 333 p += sizeof(size);
326 334
@@ -351,6 +359,7 @@ static int load_all_firmwares(struct dvb_frontend *fe)
351 priv->firm[n].type = type; 359 priv->firm[n].type = type;
352 priv->firm[n].id = id; 360 priv->firm[n].id = id;
353 priv->firm[n].size = size; 361 priv->firm[n].size = size;
362 priv->firm[n].int_freq = int_freq;
354 363
355 p += size; 364 p += size;
356 } 365 }
@@ -565,7 +574,7 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type,
565} 574}
566 575
567static int load_scode(struct dvb_frontend *fe, unsigned int type, 576static int load_scode(struct dvb_frontend *fe, unsigned int type,
568 v4l2_std_id *id, int scode) 577 v4l2_std_id *id, __u16 int_freq, int scode)
569{ 578{
570 struct xc2028_data *priv = fe->tuner_priv; 579 struct xc2028_data *priv = fe->tuner_priv;
571 int pos, rc; 580 int pos, rc;
@@ -573,17 +582,34 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type,
573 582
574 tuner_dbg("%s called\n", __FUNCTION__); 583 tuner_dbg("%s called\n", __FUNCTION__);
575 584
576 pos = seek_firmware(fe, type, id); 585 if (!int_freq) {
577 if (pos < 0) 586 pos = seek_firmware(fe, type, id);
578 return pos; 587 if (pos < 0)
588 return pos;
589 } else {
590 for (pos = 0; pos < priv->firm_size; pos++) {
591 if ((priv->firm[pos].int_freq == int_freq) &&
592 (type & HAS_IF))
593 break;
594 }
595 if (pos == priv->firm_size)
596 return -ENOENT;
597 }
579 598
580 p = priv->firm[pos].ptr; 599 p = priv->firm[pos].ptr;
581 600
582 /* 16 SCODE entries per file; each SCODE entry is 12 bytes and 601 if (type & HAS_IF) {
583 * has a 2-byte size header in the firmware format. */ 602 if (priv->firm[pos].size != 12 * 16 || scode >= 16)
584 if (priv->firm[pos].size != 14 * 16 || scode >= 16 || 603 return -EINVAL;
585 le16_to_cpu(*(__u16 *)(p + 14 * scode)) != 12) 604 p += 12 * scode;
586 return -EINVAL; 605 } else {
606 /* 16 SCODE entries per file; each SCODE entry is 12 bytes and
607 * has a 2-byte size header in the firmware format. */
608 if (priv->firm[pos].size != 14 * 16 || scode >= 16 ||
609 le16_to_cpu(*(__u16 *)(p + 14 * scode)) != 12)
610 return -EINVAL;
611 p += 14 * scode + 2;
612 }
587 613
588 tuner_info("Loading SCODE for type="); 614 tuner_info("Loading SCODE for type=");
589 dump_firm_type(priv->firm[pos].type); 615 dump_firm_type(priv->firm[pos].type);
@@ -597,7 +623,7 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type,
597 if (rc < 0) 623 if (rc < 0)
598 return -EIO; 624 return -EIO;
599 625
600 rc = i2c_send(priv, p + 14 * scode + 2, 12); 626 rc = i2c_send(priv, p, 12);
601 if (rc < 0) 627 if (rc < 0)
602 return -EIO; 628 return -EIO;
603 629
@@ -609,7 +635,7 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type,
609} 635}
610 636
611static int check_firmware(struct dvb_frontend *fe, unsigned int type, 637static int check_firmware(struct dvb_frontend *fe, unsigned int type,
612 v4l2_std_id std) 638 v4l2_std_id std, __u16 int_freq)
613{ 639{
614 struct xc2028_data *priv = fe->tuner_priv; 640 struct xc2028_data *priv = fe->tuner_priv;
615 struct firmware_properties new_fw; 641 struct firmware_properties new_fw;
@@ -639,6 +665,7 @@ retry:
639 new_fw.std_req = std; 665 new_fw.std_req = std;
640 new_fw.scode_table = SCODE | priv->ctrl.scode_table; 666 new_fw.scode_table = SCODE | priv->ctrl.scode_table;
641 new_fw.scode_nr = 0; 667 new_fw.scode_nr = 0;
668 new_fw.int_freq = int_freq;
642 669
643 tuner_dbg("checking firmware, user requested type="); 670 tuner_dbg("checking firmware, user requested type=");
644 if (debug) { 671 if (debug) {
@@ -719,8 +746,8 @@ skip_std_specific:
719 /* Load SCODE firmware, if exists */ 746 /* Load SCODE firmware, if exists */
720 tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr); 747 tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr);
721 748
722 rc = load_scode(fe, new_fw.type | new_fw.scode_table, 749 rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
723 &new_fw.id, new_fw.scode_nr); 750 new_fw.int_freq, new_fw.scode_nr);
724 751
725check_device: 752check_device:
726 if (xc2028_get_reg(priv, 0x0004, &version) < 0 || 753 if (xc2028_get_reg(priv, 0x0004, &version) < 0 ||
@@ -810,9 +837,10 @@ ret:
810#define DIV 15625 837#define DIV 15625
811 838
812static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, 839static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
813 enum tuner_mode new_mode, 840 enum tuner_mode new_mode,
814 unsigned int type, 841 unsigned int type,
815 v4l2_std_id std) 842 v4l2_std_id std,
843 u16 int_freq)
816{ 844{
817 struct xc2028_data *priv = fe->tuner_priv; 845 struct xc2028_data *priv = fe->tuner_priv;
818 int rc = -EINVAL; 846 int rc = -EINVAL;
@@ -825,7 +853,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
825 853
826 tuner_dbg("should set frequency %d kHz\n", freq / 1000); 854 tuner_dbg("should set frequency %d kHz\n", freq / 1000);
827 855
828 if (check_firmware(fe, type, std) < 0) 856 if (check_firmware(fe, type, std, int_freq) < 0)
829 goto ret; 857 goto ret;
830 858
831 /* On some cases xc2028 can disable video output, if 859 /* On some cases xc2028 can disable video output, if
@@ -896,7 +924,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe,
896 if (priv->ctrl.input1) 924 if (priv->ctrl.input1)
897 type |= INPUT1; 925 type |= INPUT1;
898 return generic_set_freq(fe, (625l * p->frequency) / 10, 926 return generic_set_freq(fe, (625l * p->frequency) / 10,
899 T_ANALOG_TV, type, 0); 927 T_ANALOG_TV, type, 0, 0);
900 } 928 }
901 929
902 /* if std is not defined, choose one */ 930 /* if std is not defined, choose one */
@@ -911,22 +939,9 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe,
911 p->std |= parse_audio_std_option(); 939 p->std |= parse_audio_std_option();
912 940
913 return generic_set_freq(fe, 62500l * p->frequency, 941 return generic_set_freq(fe, 62500l * p->frequency,
914 T_ANALOG_TV, type, p->std); 942 T_ANALOG_TV, type, p->std, 0);
915} 943}
916 944
917static unsigned int demod_type [] = {
918 [XC3028_FE_DEFAULT] = 0,
919 [XC3028_FE_LG60] = LG60,
920 [XC3028_FE_ATI638] = ATI638,
921 [XC3028_FE_OREN538] = OREN538,
922 [XC3028_FE_OREN36] = OREN36,
923 [XC3028_FE_TOYOTA388] = TOYOTA388,
924 [XC3028_FE_TOYOTA794] = TOYOTA794,
925 [XC3028_FE_DIBCOM52] = DIBCOM52,
926 [XC3028_FE_ZARLINK456] = ZARLINK456,
927 [XC3028_FE_CHINA] = CHINA,
928};
929
930static int xc2028_set_params(struct dvb_frontend *fe, 945static int xc2028_set_params(struct dvb_frontend *fe,
931 struct dvb_frontend_parameters *p) 946 struct dvb_frontend_parameters *p)
932{ 947{
@@ -978,13 +993,12 @@ static int xc2028_set_params(struct dvb_frontend *fe,
978 tuner_err("error: bandwidth not supported.\n"); 993 tuner_err("error: bandwidth not supported.\n");
979 }; 994 };
980 995
981 if (priv->ctrl.demod < 0 || priv->ctrl.demod > ARRAY_SIZE(demod_type)) 996 /* All S-code tables need a 200kHz shift */
982 tuner_err("error: demod type invalid. Assuming default.\n"); 997 if (priv->ctrl.demod)
983 else 998 priv->ctrl.demod += 200;
984 type |= demod_type[priv->ctrl.demod];
985 999
986 return generic_set_freq(fe, p->frequency, 1000 return generic_set_freq(fe, p->frequency,
987 T_DIGITAL_TV, type, 0); 1001 T_DIGITAL_TV, type, 0, priv->ctrl.demod);
988} 1002}
989 1003
990static int xc2028_sleep(struct dvb_frontend *fe) 1004static int xc2028_sleep(struct dvb_frontend *fe)