aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@kernellabs.com>2009-07-19 23:54:57 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-07-27 16:52:28 -0400
commit11091a31fbf7496294795ca72d69db0233857d94 (patch)
tree1e8fd6bd0fefe8ebdb75f2666c9beb88be1de345 /drivers/media/common
parent85ec9d7193a0d98e1c2af78d3a2110dd96c6cf02 (diff)
[media] xc4000: pull in firmware management code from xc3028
Switch over to using the firmware management routines from the tuner-xc2028, since that has support for scodes, etc. This code still requires signficant cleanup, and at this point the base firmware does not load properly (i2c write errors about 300 bytes in). 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.c424
1 files changed, 393 insertions, 31 deletions
diff --git a/drivers/media/common/tuners/xc4000.c b/drivers/media/common/tuners/xc4000.c
index 68f5e2beee1e..98ec80abb047 100644
--- a/drivers/media/common/tuners/xc4000.c
+++ b/drivers/media/common/tuners/xc4000.c
@@ -28,11 +28,13 @@
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/dvb/frontend.h> 29#include <linux/dvb/frontend.h>
30#include <linux/i2c.h> 30#include <linux/i2c.h>
31#include <asm/unaligned.h>
31 32
32#include "dvb_frontend.h" 33#include "dvb_frontend.h"
33 34
34#include "xc4000.h" 35#include "xc4000.h"
35#include "tuner-i2c.h" 36#include "tuner-i2c.h"
37#include "tuner-xc2028-types.h"
36 38
37static int debug; 39static int debug;
38module_param(debug, int, 0644); 40module_param(debug, int, 0644);
@@ -50,13 +52,34 @@ static LIST_HEAD(hybrid_tuner_instance_list);
50#define dprintk(level, fmt, arg...) if (debug >= level) \ 52#define dprintk(level, fmt, arg...) if (debug >= level) \
51 printk(KERN_INFO "%s: " fmt, "xc4000", ## arg) 53 printk(KERN_INFO "%s: " fmt, "xc4000", ## arg)
52 54
53#define XC4000_DEFAULT_FIRMWARE "dvb-fe-xc4000-1.4.26.fw" 55#define XC4000_DEFAULT_FIRMWARE "xc4000-01.fw"
54#define XC4000_DEFAULT_FIRMWARE_SIZE 8236 56#define XC4000_DEFAULT_FIRMWARE_SIZE 8434
57
58
59/* struct for storing firmware table */
60struct firmware_description {
61 unsigned int type;
62 v4l2_std_id id;
63 __u16 int_freq;
64 unsigned char *ptr;
65 unsigned int size;
66};
67
68struct firmware_properties {
69 unsigned int type;
70 v4l2_std_id id;
71 v4l2_std_id std_req;
72 __u16 int_freq;
73 unsigned int scode_table;
74 int scode_nr;
75};
55 76
56struct xc4000_priv { 77struct xc4000_priv {
57 struct tuner_i2c_props i2c_props; 78 struct tuner_i2c_props i2c_props;
58 struct list_head hybrid_tuner_instance_list; 79 struct list_head hybrid_tuner_instance_list;
59 80 struct firmware_description *firm;
81 int firm_size;
82 __u16 firm_version;
60 u32 if_khz; 83 u32 if_khz;
61 u32 freq_hz; 84 u32 freq_hz;
62 u32 bandwidth; 85 u32 bandwidth;
@@ -167,10 +190,6 @@ struct XC_TV_STANDARD {
167#define DK_SECAM_A2MONO 14 190#define DK_SECAM_A2MONO 14
168#define L_SECAM_NICAM 15 191#define L_SECAM_NICAM 15
169#define LC_SECAM_NICAM 16 192#define LC_SECAM_NICAM 16
170#define DTV6 17
171#define DTV8 18
172#define DTV7_8 19
173#define DTV7 20
174#define FM_Radio_INPUT2 21 193#define FM_Radio_INPUT2 21
175#define FM_Radio_INPUT1 22 194#define FM_Radio_INPUT1 22
176 195
@@ -575,42 +594,358 @@ static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
575 return XC_RESULT_SUCCESS; 594 return XC_RESULT_SUCCESS;
576} 595}
577 596
597
598static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
599 v4l2_std_id *id)
600{
601 struct xc4000_priv *priv = fe->tuner_priv;
602 int i, best_i = -1, best_nr_matches = 0;
603 unsigned int type_mask = 0;
604
605 printk("%s called, want type=", __func__);
606 if (debug) {
607// dump_firm_type(type);
608 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
609 }
610
611 if (!priv->firm) {
612 printk("Error! firmware not loaded\n");
613 return -EINVAL;
614 }
615
616 if (((type & ~SCODE) == 0) && (*id == 0))
617 *id = V4L2_STD_PAL;
618
619 if (type & BASE)
620 type_mask = BASE_TYPES;
621 else if (type & SCODE) {
622 type &= SCODE_TYPES;
623 type_mask = SCODE_TYPES & ~HAS_IF;
624 } else if (type & DTV_TYPES)
625 type_mask = DTV_TYPES;
626 else if (type & STD_SPECIFIC_TYPES)
627 type_mask = STD_SPECIFIC_TYPES;
628
629 type &= type_mask;
630
631 if (!(type & SCODE))
632 type_mask = ~0;
633
634 /* Seek for exact match */
635 for (i = 0; i < priv->firm_size; i++) {
636 if ((type == (priv->firm[i].type & type_mask)) &&
637 (*id == priv->firm[i].id))
638 goto found;
639 }
640
641 /* Seek for generic video standard match */
642 for (i = 0; i < priv->firm_size; i++) {
643 v4l2_std_id match_mask;
644 int nr_matches;
645
646 if (type != (priv->firm[i].type & type_mask))
647 continue;
648
649 match_mask = *id & priv->firm[i].id;
650 if (!match_mask)
651 continue;
652
653 if ((*id & match_mask) == *id)
654 goto found; /* Supports all the requested standards */
655
656 nr_matches = hweight64(match_mask);
657 if (nr_matches > best_nr_matches) {
658 best_nr_matches = nr_matches;
659 best_i = i;
660 }
661 }
662
663 if (best_nr_matches > 0) {
664 printk("Selecting best matching firmware (%d bits) for "
665 "type=", best_nr_matches);
666// dump_firm_type(type);
667 printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
668 i = best_i;
669 goto found;
670 }
671
672 /*FIXME: Would make sense to seek for type "hint" match ? */
673
674 i = -ENOENT;
675 goto ret;
676
677found:
678 *id = priv->firm[i].id;
679
680ret:
681 printk("%s firmware for type=", (i < 0) ? "Can't find" : "Found");
682 if (debug) {
683// dump_firm_type(type);
684 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
685 }
686 return i;
687}
688
689static int load_firmware(struct dvb_frontend *fe, unsigned int type,
690 v4l2_std_id *id)
691{
692 struct xc4000_priv *priv = fe->tuner_priv;
693 int pos, rc;
694 unsigned char *p, *endp, buf[XC_MAX_I2C_WRITE_LENGTH];
695
696 printk("%s called\n", __func__);
697
698 pos = seek_firmware(fe, type, id);
699 if (pos < 0)
700 return pos;
701
702 printk("Loading firmware for type=");
703// dump_firm_type(priv->firm[pos].type);
704 printk("(%x), id %016llx.\n", priv->firm[pos].type,
705 (unsigned long long)*id);
706
707 p = priv->firm[pos].ptr;
708 endp = p + priv->firm[pos].size;
709
710 while (p < endp) {
711 __u16 size;
712
713 printk("block %02x %02x %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3], p[4], p[5]);
714
715 /* Checks if there's enough bytes to read */
716 if (p + sizeof(size) > endp) {
717 printk("Firmware chunk size is wrong\n");
718 return -EINVAL;
719 }
720
721 size = be16_to_cpu(*(__u16 *) p);
722 p += sizeof(size);
723
724 printk("djh size=%x\n", size);
725
726 if (size == 0xffff)
727 return 0;
728
729 if (!size) {
730 /* Special callback command received */
731 rc = xc4000_TunerReset(fe);
732 if (rc != XC_RESULT_SUCCESS) {
733 printk("Error at RESET code %d\n",
734 (*p) & 0x7f);
735 return -EINVAL;
736 }
737 continue;
738 }
739 if (size >= 0xff00) {
740 switch (size) {
741#ifdef DJH_XXX
742 case 0xff00:
743 rc = do_tuner_callback(fe, XC2028_RESET_CLK, 0);
744 if (rc < 0) {
745 printk("Error at RESET code %d\n",
746 (*p) & 0x7f);
747 return -EINVAL;
748 }
749 break;
750#endif
751 default:
752 printk("Invalid RESET code %d\n",
753 size & 0x7f);
754 return -EINVAL;
755
756 }
757 continue;
758 }
759
760 /* Checks for a sleep command */
761 if (size & 0x8000) {
762 printk("djh doing msleep for %x\n", (size & 0x7fff));
763 msleep(size & 0x7fff);
764 continue;
765 }
766
767 if ((size + p > endp)) {
768 printk("missing bytes: need %d, have %d\n",
769 size, (int)(endp - p));
770 return -EINVAL;
771 }
772
773 buf[0] = *p;
774 p++;
775 size--;
776
777 /* Sends message chunks */
778 printk("djh final size %d\n", size);
779 while (size > 0) {
780 int len = (size < XC_MAX_I2C_WRITE_LENGTH - 1) ?
781 size : XC_MAX_I2C_WRITE_LENGTH - 1;
782
783 memcpy(buf + 1, p, len);
784
785// rc = i2c_send(priv, buf, len + 1);
786 printk("djh sending %d\n", len + 1);
787 rc = xc_send_i2c_data(priv, buf, len + 1);
788 if (rc < 0) {
789 printk("%d returned from send\n", rc);
790 return -EINVAL;
791 }
792
793 p += len;
794 size -= len;
795 }
796 }
797 return 0;
798}
799
800//static int load_all_firmwares(struct dvb_frontend *fe)
578static int xc4000_fwupload(struct dvb_frontend *fe) 801static int xc4000_fwupload(struct dvb_frontend *fe)
579{ 802{
580 struct xc4000_priv *priv = fe->tuner_priv; 803 struct xc4000_priv *priv = fe->tuner_priv;
581 const struct firmware *fw; 804 const struct firmware *fw = NULL;
582 int ret; 805 const unsigned char *p, *endp;
806 int rc = 0;
807 int n, n_array;
808 char name[33];
809 char *fname;
810
811 printk("%s called\n", __func__);
812
813 fname = XC4000_DEFAULT_FIRMWARE;
814
815 printk("Reading firmware %s\n", fname);
816 rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
817 if (rc < 0) {
818 if (rc == -ENOENT)
819 printk("Error: firmware %s not found.\n",
820 fname);
821 else
822 printk("Error %d while requesting firmware %s \n",
823 rc, fname);
583 824
584 /* request the firmware, this will block and timeout */ 825 return rc;
585 printk(KERN_INFO "xc4000: waiting for firmware upload (%s)...\n", 826 }
586 XC4000_DEFAULT_FIRMWARE); 827 p = fw->data;
828 endp = p + fw->size;
587 829
588 ret = request_firmware(&fw, XC4000_DEFAULT_FIRMWARE, 830 if (fw->size < sizeof(name) - 1 + 2 + 2) {
589 priv->i2c_props.adap->dev.parent); 831 printk("Error: firmware file %s has invalid size!\n",
590 if (ret) { 832 fname);
591 printk(KERN_ERR "xc4000: Upload failed. (file not found?)\n"); 833 goto corrupt;
592 ret = XC_RESULT_RESET_FAILURE;
593 goto out;
594 } else {
595 printk(KERN_DEBUG "xc4000: firmware read %Zu bytes.\n",
596 fw->size);
597 ret = XC_RESULT_SUCCESS;
598 } 834 }
599 835
600 if (fw->size != XC4000_DEFAULT_FIRMWARE_SIZE) { 836 memcpy(name, p, sizeof(name) - 1);
601 printk(KERN_ERR "xc4000: firmware incorrect size\n"); 837 name[sizeof(name) - 1] = 0;
602 ret = XC_RESULT_RESET_FAILURE; 838 p += sizeof(name) - 1;
603 } else { 839
604 printk(KERN_INFO "xc4000: firmware uploading...\n"); 840 priv->firm_version = get_unaligned_le16(p);
605 ret = xc_load_i2c_sequence(fe, fw->data); 841 p += 2;
606 printk(KERN_INFO "xc4000: firmware upload complete...\n"); 842
843 n_array = get_unaligned_le16(p);
844 p += 2;
845
846 printk("Loading %d firmware images from %s, type: %s, ver %d.%d\n",
847 n_array, fname, name,
848 priv->firm_version >> 8, priv->firm_version & 0xff);
849
850 priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
851 if (priv->firm == NULL) {
852 printk("Not enough memory to load firmware file.\n");
853 rc = -ENOMEM;
854 goto err;
855 }
856 priv->firm_size = n_array;
857
858 n = -1;
859 while (p < endp) {
860 __u32 type, size;
861 v4l2_std_id id;
862 __u16 int_freq = 0;
863
864 n++;
865 if (n >= n_array) {
866 printk("More firmware images in file than "
867 "were expected!\n");
868 goto corrupt;
869 }
870
871 /* Checks if there's enough bytes to read */
872 if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
873 goto header;
874
875 type = get_unaligned_le32(p);
876 p += sizeof(type);
877
878 id = get_unaligned_le64(p);
879 p += sizeof(id);
880
881 if (type & HAS_IF) {
882 int_freq = get_unaligned_le16(p);
883 p += sizeof(int_freq);
884 if (endp - p < sizeof(size))
885 goto header;
886 }
887
888 size = get_unaligned_le32(p);
889 p += sizeof(size);
890
891 if (!size || size > endp - p) {
892 printk("Firmware type ");
893// dump_firm_type(type);
894 printk("(%x), id %llx is corrupted "
895 "(size=%d, expected %d)\n",
896 type, (unsigned long long)id,
897 (unsigned)(endp - p), size);
898 goto corrupt;
899 }
900
901 priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
902 if (priv->firm[n].ptr == NULL) {
903 printk("Not enough memory to load firmware file.\n");
904 rc = -ENOMEM;
905 goto err;
906 }
907 printk("Reading firmware type ");
908 if (debug) {
909// dump_firm_type_and_int_freq(type, int_freq);
910 printk("(%x), id %llx, size=%d.\n",
911 type, (unsigned long long)id, size);
912 }
913
914 memcpy(priv->firm[n].ptr, p, size);
915 priv->firm[n].type = type;
916 priv->firm[n].id = id;
917 priv->firm[n].size = size;
918 priv->firm[n].int_freq = int_freq;
919
920 p += size;
607 } 921 }
608 922
609out: 923 if (n + 1 != priv->firm_size) {
924 printk("Firmware file is incomplete!\n");
925 goto corrupt;
926 }
927
928 goto done;
929
930header:
931 printk("Firmware header is incomplete!\n");
932corrupt:
933 rc = -EINVAL;
934 printk("Error: firmware file is corrupted!\n");
935
936err:
937 printk("Releasing partially loaded firmware file.\n");
938// free_firmware(priv);
939
940done:
610 release_firmware(fw); 941 release_firmware(fw);
611 return ret; 942 if (rc == 0)
943 printk("Firmware files loaded.\n");
944
945 return rc;
612} 946}
613 947
948
614static void xc_debug_dump(struct xc4000_priv *priv) 949static void xc_debug_dump(struct xc4000_priv *priv)
615{ 950{
616 u16 adc_envelope; 951 u16 adc_envelope;
@@ -1002,7 +1337,9 @@ struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1002{ 1337{
1003 struct xc4000_priv *priv = NULL; 1338 struct xc4000_priv *priv = NULL;
1004 int instance; 1339 int instance;
1340 v4l2_std_id std0;
1005 u16 id = 0; 1341 u16 id = 0;
1342 int rc;
1006 1343
1007 dprintk(1, "%s(%d-%04x)\n", __func__, 1344 dprintk(1, "%s(%d-%04x)\n", __func__,
1008 i2c ? i2c_adapter_id(i2c) : -1, 1345 i2c ? i2c_adapter_id(i2c) : -1,
@@ -1069,6 +1406,31 @@ struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1069 memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops, 1406 memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
1070 sizeof(struct dvb_tuner_ops)); 1407 sizeof(struct dvb_tuner_ops));
1071 1408
1409 /* FIXME: For now, load the firmware at startup. We will remove this
1410 before the code goes to production... */
1411 xc4000_fwupload(fe);
1412 printk("xc4000_fwupload done\n");
1413
1414 std0 = 0;
1415// rc = load_firmware(fe, BASE | new_fw.type, &std0);
1416 rc = load_firmware(fe, BASE, &std0);
1417 if (rc < 0) {
1418 tuner_err("Error %d while loading base firmware\n",
1419 rc);
1420 goto fail;
1421 }
1422
1423 /* Load INIT1, if needed */
1424 tuner_dbg("Load init1 firmware, if exists\n");
1425
1426// rc = load_firmware(fe, BASE | INIT1 | new_fw.type, &std0);
1427 rc = load_firmware(fe, INIT1, &std0);
1428 printk("init1 load result %x\n", rc);
1429
1430 if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
1431 goto fail;
1432 printk("djh id is now %x\n", id);
1433
1072 return fe; 1434 return fe;
1073fail: 1435fail:
1074 mutex_unlock(&xc4000_list_mutex); 1436 mutex_unlock(&xc4000_list_mutex);