aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@kernellabs.com>2009-07-25 16:39:54 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-07-27 16:52:29 -0400
commitd0962382cf6ca55e5a33413b39a10fe2f56bae78 (patch)
tree025b9110d48396b0059e2c1cb7fdf7d7e4725679 /drivers/media/common
parente7490d5962ad7959c0597cd55c97ff7eae3acf82 (diff)
[media] xc4000: add code to do standard and scode firmware loading
Add code to handle firmware blobs for the standard and scode. Note there appears to be some issue with loading the DTV8 standard firmware, probably related to direct/indirect mode. Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/common')
-rw-r--r--drivers/media/common/tuners/xc4000.c341
1 files changed, 332 insertions, 9 deletions
diff --git a/drivers/media/common/tuners/xc4000.c b/drivers/media/common/tuners/xc4000.c
index 6d5ab599e83a..19973887312a 100644
--- a/drivers/media/common/tuners/xc4000.c
+++ b/drivers/media/common/tuners/xc4000.c
@@ -36,7 +36,7 @@
36#include "tuner-i2c.h" 36#include "tuner-i2c.h"
37#include "tuner-xc2028-types.h" 37#include "tuner-xc2028-types.h"
38 38
39static int debug; 39static int debug=1;
40module_param(debug, int, 0644); 40module_param(debug, int, 0644);
41MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); 41MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
42 42
@@ -52,8 +52,8 @@ static LIST_HEAD(hybrid_tuner_instance_list);
52#define dprintk(level, fmt, arg...) if (debug >= level) \ 52#define dprintk(level, fmt, arg...) if (debug >= level) \
53 printk(KERN_INFO "%s: " fmt, "xc4000", ## arg) 53 printk(KERN_INFO "%s: " fmt, "xc4000", ## arg)
54 54
55#define XC4000_DEFAULT_FIRMWARE "xc4000-01.fw" 55#define XC4000_DEFAULT_FIRMWARE "xc4000-02.fw"
56#define XC4000_DEFAULT_FIRMWARE_SIZE 8434 56#define XC4000_DEFAULT_FIRMWARE_SIZE 18643
57 57
58 58
59/* struct for storing firmware table */ 59/* struct for storing firmware table */
@@ -85,6 +85,10 @@ struct xc4000_priv {
85 u32 bandwidth; 85 u32 bandwidth;
86 u8 video_standard; 86 u8 video_standard;
87 u8 rf_mode; 87 u8 rf_mode;
88// struct xc2028_ctrl ctrl;
89 struct firmware_properties cur_fw;
90 __u16 hwmodel;
91 __u16 hwvers;
88}; 92};
89 93
90/* Misc Defines */ 94/* Misc Defines */
@@ -568,6 +572,73 @@ static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
568 return XC_RESULT_SUCCESS; 572 return XC_RESULT_SUCCESS;
569} 573}
570 574
575#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
576static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
577{
578 if (type & BASE)
579 printk("BASE ");
580 if (type & INIT1)
581 printk("INIT1 ");
582 if (type & F8MHZ)
583 printk("F8MHZ ");
584 if (type & MTS)
585 printk("MTS ");
586 if (type & D2620)
587 printk("D2620 ");
588 if (type & D2633)
589 printk("D2633 ");
590 if (type & DTV6)
591 printk("DTV6 ");
592 if (type & QAM)
593 printk("QAM ");
594 if (type & DTV7)
595 printk("DTV7 ");
596 if (type & DTV78)
597 printk("DTV78 ");
598 if (type & DTV8)
599 printk("DTV8 ");
600 if (type & FM)
601 printk("FM ");
602 if (type & INPUT1)
603 printk("INPUT1 ");
604 if (type & LCD)
605 printk("LCD ");
606 if (type & NOGD)
607 printk("NOGD ");
608 if (type & MONO)
609 printk("MONO ");
610 if (type & ATSC)
611 printk("ATSC ");
612 if (type & IF)
613 printk("IF ");
614 if (type & LG60)
615 printk("LG60 ");
616 if (type & ATI638)
617 printk("ATI638 ");
618 if (type & OREN538)
619 printk("OREN538 ");
620 if (type & OREN36)
621 printk("OREN36 ");
622 if (type & TOYOTA388)
623 printk("TOYOTA388 ");
624 if (type & TOYOTA794)
625 printk("TOYOTA794 ");
626 if (type & DIBCOM52)
627 printk("DIBCOM52 ");
628 if (type & ZARLINK456)
629 printk("ZARLINK456 ");
630 if (type & CHINA)
631 printk("CHINA ");
632 if (type & F6MHZ)
633 printk("F6MHZ ");
634 if (type & INPUT2)
635 printk("INPUT2 ");
636 if (type & SCODE)
637 printk("SCODE ");
638 if (type & HAS_IF)
639 printk("HAS_IF_%d ", int_freq);
640}
641
571static int seek_firmware(struct dvb_frontend *fe, unsigned int type, 642static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
572 v4l2_std_id *id) 643 v4l2_std_id *id)
573{ 644{
@@ -577,7 +648,7 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
577 648
578 printk("%s called, want type=", __func__); 649 printk("%s called, want type=", __func__);
579 if (debug) { 650 if (debug) {
580// dump_firm_type(type); 651 dump_firm_type(type);
581 printk("(%x), id %016llx.\n", type, (unsigned long long)*id); 652 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
582 } 653 }
583 654
@@ -653,8 +724,10 @@ found:
653ret: 724ret:
654 printk("%s firmware for type=", (i < 0) ? "Can't find" : "Found"); 725 printk("%s firmware for type=", (i < 0) ? "Can't find" : "Found");
655 if (debug) { 726 if (debug) {
656// dump_firm_type(type); 727 dump_firm_type(type);
657 printk("(%x), id %016llx.\n", type, (unsigned long long)*id); 728 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
729 if (i < 0)
730 dump_stack();
658 } 731 }
659 return i; 732 return i;
660} 733}
@@ -680,7 +753,6 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type,
680 p = priv->firm[pos].ptr; 753 p = priv->firm[pos].ptr;
681 754
682 rc = xc_load_i2c_sequence(fe, p); 755 rc = xc_load_i2c_sequence(fe, p);
683 printk("load i2c sequence result=%d\n", rc);
684 756
685 return rc; 757 return rc;
686} 758}
@@ -791,9 +863,10 @@ static int xc4000_fwupload(struct dvb_frontend *fe)
791 rc = -ENOMEM; 863 rc = -ENOMEM;
792 goto err; 864 goto err;
793 } 865 }
794 printk("Reading firmware type "); 866
795 if (debug) { 867 if (debug) {
796// dump_firm_type_and_int_freq(type, int_freq); 868 printk("Reading firmware type ");
869 dump_firm_type_and_int_freq(type, int_freq);
797 printk("(%x), id %llx, size=%d.\n", 870 printk("(%x), id %llx, size=%d.\n",
798 type, (unsigned long long)id, size); 871 type, (unsigned long long)id, size);
799 } 872 }
@@ -832,6 +905,253 @@ done:
832 return rc; 905 return rc;
833} 906}
834 907
908static int load_scode(struct dvb_frontend *fe, unsigned int type,
909 v4l2_std_id *id, __u16 int_freq, int scode)
910{
911 struct xc4000_priv *priv = fe->tuner_priv;
912 int pos, rc;
913 unsigned char *p;
914 u8 direct_mode[4];
915 u8 indirect_mode[5];
916
917 dprintk(1, "%s called\n", __func__);
918
919 if (!int_freq) {
920 pos = seek_firmware(fe, type, id);
921 if (pos < 0)
922 return pos;
923 } else {
924 for (pos = 0; pos < priv->firm_size; pos++) {
925 if ((priv->firm[pos].int_freq == int_freq) &&
926 (priv->firm[pos].type & HAS_IF))
927 break;
928 }
929 if (pos == priv->firm_size)
930 return -ENOENT;
931 }
932
933 p = priv->firm[pos].ptr;
934
935 if (priv->firm[pos].type & HAS_IF) {
936 if (priv->firm[pos].size != 12 * 16 || scode >= 16)
937 return -EINVAL;
938 p += 12 * scode;
939 } else {
940 /* 16 SCODE entries per file; each SCODE entry is 12 bytes and
941 * has a 2-byte size header in the firmware format. */
942 if (priv->firm[pos].size != 14 * 16 || scode >= 16 ||
943 le16_to_cpu(*(__u16 *)(p + 14 * scode)) != 12)
944 return -EINVAL;
945 p += 14 * scode + 2;
946 }
947
948 tuner_info("Loading SCODE for type=");
949 dump_firm_type_and_int_freq(priv->firm[pos].type,
950 priv->firm[pos].int_freq);
951 printk("(%x), id %016llx.\n", priv->firm[pos].type,
952 (unsigned long long)*id);
953
954
955 /* Enter direct-mode */
956 memset(direct_mode, 0, sizeof(direct_mode));
957 direct_mode[1] = 0x05;
958 rc = xc_send_i2c_data(priv, direct_mode, sizeof(direct_mode));
959 if (rc < 0)
960 return -EIO;
961
962 rc = xc_send_i2c_data(priv, p, 12);
963 if (rc != XC_RESULT_SUCCESS)
964 return -EIO;
965
966 /* Switch back to indirect-mode */
967 memset(indirect_mode, 0, sizeof(indirect_mode));
968 indirect_mode[4] = 0x88;
969 rc = xc_send_i2c_data(priv, indirect_mode, sizeof(indirect_mode));
970 if (rc < 0)
971 return -EIO;
972
973 return 0;
974}
975
976static int check_firmware(struct dvb_frontend *fe, unsigned int type,
977 v4l2_std_id std, __u16 int_freq)
978{
979 struct xc4000_priv *priv = fe->tuner_priv;
980 struct firmware_properties new_fw;
981 int rc = 0, is_retry = 0;
982 u16 version, hwmodel;
983 v4l2_std_id std0;
984 u8 hw_major, hw_minor, fw_major, fw_minor;
985
986 dprintk(1, "%s called\n", __func__);
987
988 if (!priv->firm) {
989 rc = xc4000_fwupload(fe);
990 if (rc < 0)
991 return rc;
992 }
993
994#ifdef DJH_DEBUG
995 if (priv->ctrl.mts && !(type & FM))
996 type |= MTS;
997#endif
998
999retry:
1000 new_fw.type = type;
1001 new_fw.id = std;
1002 new_fw.std_req = std;
1003// new_fw.scode_table = SCODE | priv->ctrl.scode_table;
1004 new_fw.scode_table = SCODE;
1005 new_fw.scode_nr = 0;
1006 new_fw.int_freq = int_freq;
1007
1008 dprintk(1, "checking firmware, user requested type=");
1009 if (debug) {
1010 dump_firm_type(new_fw.type);
1011 printk("(%x), id %016llx, ", new_fw.type,
1012 (unsigned long long)new_fw.std_req);
1013 if (!int_freq) {
1014 printk("scode_tbl ");
1015#ifdef DJH_DEBUG
1016 dump_firm_type(priv->ctrl.scode_table);
1017 printk("(%x), ", priv->ctrl.scode_table);
1018#endif
1019 } else
1020 printk("int_freq %d, ", new_fw.int_freq);
1021 printk("scode_nr %d\n", new_fw.scode_nr);
1022 }
1023
1024 /* No need to reload base firmware if it matches */
1025 if (((BASE | new_fw.type) & BASE_TYPES) ==
1026 (priv->cur_fw.type & BASE_TYPES)) {
1027 dprintk(1, "BASE firmware not changed.\n");
1028 goto skip_base;
1029 }
1030
1031 /* Updating BASE - forget about all currently loaded firmware */
1032 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
1033
1034 /* Reset is needed before loading firmware */
1035 rc = xc4000_TunerReset(fe);
1036 if (rc < 0)
1037 goto fail;
1038
1039 /* BASE firmwares are all std0 */
1040 std0 = 0;
1041 rc = load_firmware(fe, BASE | new_fw.type, &std0);
1042 if (rc < 0) {
1043 printk("Error %d while loading base firmware\n", rc);
1044 goto fail;
1045 }
1046
1047 /* Load INIT1, if needed */
1048 dprintk(1, "Load init1 firmware, if exists\n");
1049
1050 rc = load_firmware(fe, BASE | INIT1 | new_fw.type, &std0);
1051 if (rc == -ENOENT)
1052 rc = load_firmware(fe, (BASE | INIT1 | new_fw.type) & ~F8MHZ,
1053 &std0);
1054 if (rc < 0 && rc != -ENOENT) {
1055 tuner_err("Error %d while loading init1 firmware\n",
1056 rc);
1057 goto fail;
1058 }
1059
1060skip_base:
1061 /*
1062 * No need to reload standard specific firmware if base firmware
1063 * was not reloaded and requested video standards have not changed.
1064 */
1065 if (priv->cur_fw.type == (BASE | new_fw.type) &&
1066 priv->cur_fw.std_req == std) {
1067 dprintk(1, "Std-specific firmware already loaded.\n");
1068 goto skip_std_specific;
1069 }
1070
1071 /* Reloading std-specific firmware forces a SCODE update */
1072 priv->cur_fw.scode_table = 0;
1073
1074 rc = load_firmware(fe, new_fw.type, &new_fw.id);
1075 if (rc == -ENOENT)
1076 rc = load_firmware(fe, new_fw.type & ~F8MHZ, &new_fw.id);
1077
1078 if (rc < 0)
1079 goto fail;
1080
1081skip_std_specific:
1082 if (priv->cur_fw.scode_table == new_fw.scode_table &&
1083 priv->cur_fw.scode_nr == new_fw.scode_nr) {
1084 dprintk(1, "SCODE firmware already loaded.\n");
1085 goto check_device;
1086 }
1087
1088 if (new_fw.type & FM)
1089 goto check_device;
1090
1091 /* Load SCODE firmware, if exists */
1092 dprintk(1, "Trying to load scode %d\n", new_fw.scode_nr);
1093
1094 rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
1095 new_fw.int_freq, new_fw.scode_nr);
1096
1097check_device:
1098 rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
1099
1100 if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
1101 &fw_minor) != XC_RESULT_SUCCESS) {
1102 printk("Unable to read tuner registers.\n");
1103 goto fail;
1104 }
1105
1106 dprintk(1, "Device is Xceive %d version %d.%d, "
1107 "firmware version %d.%d\n",
1108 hwmodel, hw_major, hw_minor, fw_major, fw_minor);
1109
1110 /* Check firmware version against what we downloaded. */
1111#ifdef DJH_DEBUG
1112 if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
1113 printk("Incorrect readback of firmware version %x.\n",
1114 (version & 0xff));
1115 goto fail;
1116 }
1117#endif
1118
1119 /* Check that the tuner hardware model remains consistent over time. */
1120 if (priv->hwmodel == 0 && hwmodel == 4000) {
1121 priv->hwmodel = hwmodel;
1122 priv->hwvers = version & 0xff00;
1123 } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
1124 priv->hwvers != (version & 0xff00)) {
1125 printk("Read invalid device hardware information - tuner "
1126 "hung?\n");
1127 goto fail;
1128 }
1129
1130 memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
1131
1132 /*
1133 * By setting BASE in cur_fw.type only after successfully loading all
1134 * firmwares, we can:
1135 * 1. Identify that BASE firmware with type=0 has been loaded;
1136 * 2. Tell whether BASE firmware was just changed the next time through.
1137 */
1138 priv->cur_fw.type |= BASE;
1139
1140 return 0;
1141
1142fail:
1143 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
1144 if (!is_retry) {
1145 msleep(50);
1146 is_retry = 1;
1147 dprintk(1, "Retrying firmware load\n");
1148 goto retry;
1149 }
1150
1151 if (rc == -ENOENT)
1152 rc = -EINVAL;
1153 return rc;
1154}
835 1155
836static void xc_debug_dump(struct xc4000_priv *priv) 1156static void xc_debug_dump(struct xc4000_priv *priv)
837{ 1157{
@@ -1295,6 +1615,7 @@ struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1295 1615
1296 /* FIXME: For now, load the firmware at startup. We will remove this 1616 /* FIXME: For now, load the firmware at startup. We will remove this
1297 before the code goes to production... */ 1617 before the code goes to production... */
1618#ifdef DJH_DEBUG
1298 xc4000_fwupload(fe); 1619 xc4000_fwupload(fe);
1299 printk("xc4000_fwupload done\n"); 1620 printk("xc4000_fwupload done\n");
1300 1621
@@ -1308,11 +1629,13 @@ struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1308 } 1629 }
1309 1630
1310 /* Load INIT1, if needed */ 1631 /* Load INIT1, if needed */
1311 tuner_dbg("Load init1 firmware, if exists\n"); 1632 dprintk("Load init1 firmware, if exists\n");
1312 1633
1313// rc = load_firmware(fe, BASE | INIT1 | new_fw.type, &std0); 1634// rc = load_firmware(fe, BASE | INIT1 | new_fw.type, &std0);
1314 rc = load_firmware(fe, BASE | INIT1, &std0); 1635 rc = load_firmware(fe, BASE | INIT1, &std0);
1315 printk("init1 load result %x\n", rc); 1636 printk("init1 load result %x\n", rc);
1637#endif
1638 check_firmware(fe, DTV8, 0, 5400);
1316 1639
1317 if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS) 1640 if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
1318 goto fail; 1641 goto fail;