diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2007-11-04 08:53:09 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:01:59 -0500 |
commit | 92de1f16d15a30831d1685949aeb76c99032ef23 (patch) | |
tree | 6186c07bf328ab2a28fd19be31a9e4918f8562e3 /drivers/media | |
parent | 159ffe77cd9b1cd7c80c416b5635bdad7e3d7d55 (diff) |
V4L/DVB (6555): tuner: reorder functions to prepare for i2c conversion
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/tuner-core.c | 438 |
1 files changed, 223 insertions, 215 deletions
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 4f2bd2dd15c7..48b2d46048ab 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -585,221 +585,6 @@ static void tuner_status(struct dvb_frontend *fe) | |||
585 | 585 | ||
586 | /* ---------------------------------------------------------------------- */ | 586 | /* ---------------------------------------------------------------------- */ |
587 | 587 | ||
588 | LIST_HEAD(tuner_list); | ||
589 | |||
590 | /* Search for existing radio and/or TV tuners on the given I2C adapter. | ||
591 | Note that when this function is called from tuner_attach you can be | ||
592 | certain no other devices will be added/deleted at the same time, I2C | ||
593 | core protects against that. */ | ||
594 | static void tuner_lookup(struct i2c_adapter *adap, | ||
595 | struct tuner **radio, struct tuner **tv) | ||
596 | { | ||
597 | struct tuner *pos; | ||
598 | |||
599 | *radio = NULL; | ||
600 | *tv = NULL; | ||
601 | |||
602 | list_for_each_entry(pos, &tuner_list, list) { | ||
603 | int mode_mask; | ||
604 | |||
605 | if (pos->i2c->adapter != adap || | ||
606 | pos->i2c->driver->id != I2C_DRIVERID_TUNER) | ||
607 | continue; | ||
608 | |||
609 | mode_mask = pos->mode_mask & ~T_STANDBY; | ||
610 | if (*radio == NULL && mode_mask == T_RADIO) | ||
611 | *radio = pos; | ||
612 | /* Note: currently TDA9887 is the only demod-only | ||
613 | device. If other devices appear then we need to | ||
614 | make this test more general. */ | ||
615 | else if (*tv == NULL && pos->type != TUNER_TDA9887 && | ||
616 | (pos->mode_mask & (T_ANALOG_TV | T_DIGITAL_TV))) | ||
617 | *tv = pos; | ||
618 | } | ||
619 | } | ||
620 | |||
621 | /* During client attach, set_type is called by adapter's attach_inform callback. | ||
622 | set_type must then be completed by tuner_attach. | ||
623 | */ | ||
624 | static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | ||
625 | { | ||
626 | struct i2c_client *client; | ||
627 | struct tuner *t; | ||
628 | struct tuner *radio; | ||
629 | struct tuner *tv; | ||
630 | |||
631 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
632 | if (NULL == client) | ||
633 | return -ENOMEM; | ||
634 | |||
635 | t = kzalloc(sizeof(struct tuner), GFP_KERNEL); | ||
636 | if (NULL == t) { | ||
637 | kfree(client); | ||
638 | return -ENOMEM; | ||
639 | } | ||
640 | t->i2c = client; | ||
641 | client_template.adapter = adap; | ||
642 | client_template.addr = addr; | ||
643 | memcpy(client, &client_template, sizeof(struct i2c_client)); | ||
644 | i2c_set_clientdata(client, t); | ||
645 | t->type = UNSET; | ||
646 | t->audmode = V4L2_TUNER_MODE_STEREO; | ||
647 | t->mode_mask = T_UNINITIALIZED; | ||
648 | |||
649 | if (show_i2c) { | ||
650 | unsigned char buffer[16]; | ||
651 | int i,rc; | ||
652 | |||
653 | memset(buffer, 0, sizeof(buffer)); | ||
654 | rc = i2c_master_recv(client, buffer, sizeof(buffer)); | ||
655 | tuner_info("I2C RECV = "); | ||
656 | for (i=0;i<rc;i++) | ||
657 | printk("%02x ",buffer[i]); | ||
658 | printk("\n"); | ||
659 | } | ||
660 | /* HACK: This test were added to avoid tuner to probe tda9840 and tea6415c on the MXB card */ | ||
661 | if (adap->id == I2C_HW_SAA7146 && addr < 0x4a) | ||
662 | return -ENODEV; | ||
663 | |||
664 | /* autodetection code based on the i2c addr */ | ||
665 | if (!no_autodetect) { | ||
666 | switch (addr) { | ||
667 | case 0x10: | ||
668 | if (tea5761_autodetection(t->i2c->adapter, t->i2c->addr) != EINVAL) { | ||
669 | t->type = TUNER_TEA5761; | ||
670 | t->mode_mask = T_RADIO; | ||
671 | t->mode = T_STANDBY; | ||
672 | t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ | ||
673 | tuner_lookup(t->i2c->adapter, &radio, &tv); | ||
674 | if (tv) | ||
675 | tv->mode_mask &= ~T_RADIO; | ||
676 | |||
677 | goto register_client; | ||
678 | } | ||
679 | break; | ||
680 | case 0x42: | ||
681 | case 0x43: | ||
682 | case 0x4a: | ||
683 | case 0x4b: | ||
684 | /* If chip is not tda8290, don't register. | ||
685 | since it can be tda9887*/ | ||
686 | if (tda829x_probe(t) == 0) { | ||
687 | tuner_dbg("tda829x detected\n"); | ||
688 | } else { | ||
689 | /* Default is being tda9887 */ | ||
690 | t->type = TUNER_TDA9887; | ||
691 | t->mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; | ||
692 | t->mode = T_STANDBY; | ||
693 | goto register_client; | ||
694 | } | ||
695 | break; | ||
696 | case 0x60: | ||
697 | if (tea5767_autodetection(t->i2c->adapter, t->i2c->addr) != EINVAL) { | ||
698 | t->type = TUNER_TEA5767; | ||
699 | t->mode_mask = T_RADIO; | ||
700 | t->mode = T_STANDBY; | ||
701 | t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ | ||
702 | tuner_lookup(t->i2c->adapter, &radio, &tv); | ||
703 | if (tv) | ||
704 | tv->mode_mask &= ~T_RADIO; | ||
705 | |||
706 | goto register_client; | ||
707 | } | ||
708 | break; | ||
709 | } | ||
710 | } | ||
711 | |||
712 | /* Initializes only the first TV tuner on this adapter. Why only the | ||
713 | first? Because there are some devices (notably the ones with TI | ||
714 | tuners) that have more than one i2c address for the *same* device. | ||
715 | Experience shows that, except for just one case, the first | ||
716 | address is the right one. The exception is a Russian tuner | ||
717 | (ACORP_Y878F). So, the desired behavior is just to enable the | ||
718 | first found TV tuner. */ | ||
719 | tuner_lookup(t->i2c->adapter, &radio, &tv); | ||
720 | if (tv == NULL) { | ||
721 | t->mode_mask = T_ANALOG_TV | T_DIGITAL_TV; | ||
722 | if (radio == NULL) | ||
723 | t->mode_mask |= T_RADIO; | ||
724 | tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask); | ||
725 | t->tv_freq = 400 * 16; /* Sets freq to VHF High */ | ||
726 | t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ | ||
727 | } | ||
728 | |||
729 | /* Should be just before return */ | ||
730 | register_client: | ||
731 | tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name); | ||
732 | |||
733 | /* Sets a default mode */ | ||
734 | if (t->mode_mask & T_ANALOG_TV) { | ||
735 | t->mode = T_ANALOG_TV; | ||
736 | } else if (t->mode_mask & T_RADIO) { | ||
737 | t->mode = T_RADIO; | ||
738 | } else { | ||
739 | t->mode = T_DIGITAL_TV; | ||
740 | } | ||
741 | |||
742 | i2c_attach_client (client); | ||
743 | set_type (client,t->type, t->mode_mask, t->config, t->tuner_callback); | ||
744 | return 0; | ||
745 | } | ||
746 | |||
747 | static int tuner_probe(struct i2c_adapter *adap) | ||
748 | { | ||
749 | if (0 != addr) { | ||
750 | normal_i2c[0] = addr; | ||
751 | normal_i2c[1] = I2C_CLIENT_END; | ||
752 | } | ||
753 | |||
754 | /* HACK: Ignore 0x6b and 0x6f on cx88 boards. | ||
755 | * FusionHDTV5 RT Gold has an ir receiver at 0x6b | ||
756 | * and an RTC at 0x6f which can get corrupted if probed. | ||
757 | */ | ||
758 | if ((adap->id == I2C_HW_B_CX2388x) || | ||
759 | (adap->id == I2C_HW_B_CX23885)) { | ||
760 | unsigned int i = 0; | ||
761 | |||
762 | while (i < I2C_CLIENT_MAX_OPTS && ignore[i] != I2C_CLIENT_END) | ||
763 | i += 2; | ||
764 | if (i + 4 < I2C_CLIENT_MAX_OPTS) { | ||
765 | ignore[i+0] = adap->nr; | ||
766 | ignore[i+1] = 0x6b; | ||
767 | ignore[i+2] = adap->nr; | ||
768 | ignore[i+3] = 0x6f; | ||
769 | ignore[i+4] = I2C_CLIENT_END; | ||
770 | } else | ||
771 | printk(KERN_WARNING "tuner: " | ||
772 | "too many options specified " | ||
773 | "in i2c probe ignore list!\n"); | ||
774 | } | ||
775 | |||
776 | if (adap->class & I2C_CLASS_TV_ANALOG) | ||
777 | return i2c_probe(adap, &addr_data, tuner_attach); | ||
778 | return 0; | ||
779 | } | ||
780 | |||
781 | static int tuner_detach(struct i2c_client *client) | ||
782 | { | ||
783 | struct tuner *t = i2c_get_clientdata(client); | ||
784 | struct analog_tuner_ops *ops = t->fe.ops.analog_demod_ops; | ||
785 | int err; | ||
786 | |||
787 | err = i2c_detach_client(t->i2c); | ||
788 | if (err) { | ||
789 | tuner_warn | ||
790 | ("Client deregistration failed, client not detached.\n"); | ||
791 | return err; | ||
792 | } | ||
793 | |||
794 | if (ops && ops->release) | ||
795 | ops->release(&t->fe); | ||
796 | |||
797 | list_del(&t->list); | ||
798 | kfree(t); | ||
799 | kfree(client); | ||
800 | return 0; | ||
801 | } | ||
802 | |||
803 | /* | 588 | /* |
804 | * Switch tuner to other mode. If tuner support both tv and radio, | 589 | * Switch tuner to other mode. If tuner support both tv and radio, |
805 | * set another frequency to some value (This is needed for some pal | 590 | * set another frequency to some value (This is needed for some pal |
@@ -1156,6 +941,229 @@ static int tuner_resume(struct i2c_client *c) | |||
1156 | return 0; | 941 | return 0; |
1157 | } | 942 | } |
1158 | 943 | ||
944 | /* ---------------------------------------------------------------------- */ | ||
945 | |||
946 | LIST_HEAD(tuner_list); | ||
947 | |||
948 | /* Search for existing radio and/or TV tuners on the given I2C adapter. | ||
949 | Note that when this function is called from tuner_attach you can be | ||
950 | certain no other devices will be added/deleted at the same time, I2C | ||
951 | core protects against that. */ | ||
952 | static void tuner_lookup(struct i2c_adapter *adap, | ||
953 | struct tuner **radio, struct tuner **tv) | ||
954 | { | ||
955 | struct tuner *pos; | ||
956 | |||
957 | *radio = NULL; | ||
958 | *tv = NULL; | ||
959 | |||
960 | list_for_each_entry(pos, &tuner_list, list) { | ||
961 | int mode_mask; | ||
962 | |||
963 | if (pos->i2c->adapter != adap || | ||
964 | pos->i2c->driver->id != I2C_DRIVERID_TUNER) | ||
965 | continue; | ||
966 | |||
967 | mode_mask = pos->mode_mask & ~T_STANDBY; | ||
968 | if (*radio == NULL && mode_mask == T_RADIO) | ||
969 | *radio = pos; | ||
970 | /* Note: currently TDA9887 is the only demod-only | ||
971 | device. If other devices appear then we need to | ||
972 | make this test more general. */ | ||
973 | else if (*tv == NULL && pos->type != TUNER_TDA9887 && | ||
974 | (pos->mode_mask & (T_ANALOG_TV | T_DIGITAL_TV))) | ||
975 | *tv = pos; | ||
976 | } | ||
977 | } | ||
978 | |||
979 | /* During client attach, set_type is called by adapter's attach_inform callback. | ||
980 | set_type must then be completed by tuner_attach. | ||
981 | */ | ||
982 | static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | ||
983 | { | ||
984 | struct i2c_client *client; | ||
985 | struct tuner *t; | ||
986 | struct tuner *radio; | ||
987 | struct tuner *tv; | ||
988 | |||
989 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
990 | if (NULL == client) | ||
991 | return -ENOMEM; | ||
992 | |||
993 | t = kzalloc(sizeof(struct tuner), GFP_KERNEL); | ||
994 | if (NULL == t) { | ||
995 | kfree(client); | ||
996 | return -ENOMEM; | ||
997 | } | ||
998 | t->i2c = client; | ||
999 | client_template.adapter = adap; | ||
1000 | client_template.addr = addr; | ||
1001 | memcpy(client, &client_template, sizeof(struct i2c_client)); | ||
1002 | i2c_set_clientdata(client, t); | ||
1003 | t->type = UNSET; | ||
1004 | t->audmode = V4L2_TUNER_MODE_STEREO; | ||
1005 | t->mode_mask = T_UNINITIALIZED; | ||
1006 | |||
1007 | if (show_i2c) { | ||
1008 | unsigned char buffer[16]; | ||
1009 | int i, rc; | ||
1010 | |||
1011 | memset(buffer, 0, sizeof(buffer)); | ||
1012 | rc = i2c_master_recv(client, buffer, sizeof(buffer)); | ||
1013 | tuner_info("I2C RECV = "); | ||
1014 | for (i = 0; i < rc; i++) | ||
1015 | printk(KERN_CONT "%02x ", buffer[i]); | ||
1016 | printk("\n"); | ||
1017 | } | ||
1018 | /* HACK: This test were added to avoid tuner to probe tda9840 and | ||
1019 | tea6415c on the MXB card */ | ||
1020 | if (adap->id == I2C_HW_SAA7146 && addr < 0x4a) | ||
1021 | return -ENODEV; | ||
1022 | |||
1023 | /* autodetection code based on the i2c addr */ | ||
1024 | if (!no_autodetect) { | ||
1025 | switch (addr) { | ||
1026 | case 0x10: | ||
1027 | if (tea5761_autodetection(t->i2c->adapter, t->i2c->addr) | ||
1028 | != EINVAL) { | ||
1029 | t->type = TUNER_TEA5761; | ||
1030 | t->mode_mask = T_RADIO; | ||
1031 | t->mode = T_STANDBY; | ||
1032 | /* Sets freq to FM range */ | ||
1033 | t->radio_freq = 87.5 * 16000; | ||
1034 | tuner_lookup(t->i2c->adapter, &radio, &tv); | ||
1035 | if (tv) | ||
1036 | tv->mode_mask &= ~T_RADIO; | ||
1037 | |||
1038 | goto register_client; | ||
1039 | } | ||
1040 | break; | ||
1041 | case 0x42: | ||
1042 | case 0x43: | ||
1043 | case 0x4a: | ||
1044 | case 0x4b: | ||
1045 | /* If chip is not tda8290, don't register. | ||
1046 | since it can be tda9887*/ | ||
1047 | if (tda829x_probe(t) == 0) { | ||
1048 | tuner_dbg("tda829x detected\n"); | ||
1049 | } else { | ||
1050 | /* Default is being tda9887 */ | ||
1051 | t->type = TUNER_TDA9887; | ||
1052 | t->mode_mask = T_RADIO | T_ANALOG_TV | | ||
1053 | T_DIGITAL_TV; | ||
1054 | t->mode = T_STANDBY; | ||
1055 | goto register_client; | ||
1056 | } | ||
1057 | break; | ||
1058 | case 0x60: | ||
1059 | if (tea5767_autodetection(t->i2c->adapter, t->i2c->addr) | ||
1060 | != EINVAL) { | ||
1061 | t->type = TUNER_TEA5767; | ||
1062 | t->mode_mask = T_RADIO; | ||
1063 | t->mode = T_STANDBY; | ||
1064 | /* Sets freq to FM range */ | ||
1065 | t->radio_freq = 87.5 * 16000; | ||
1066 | tuner_lookup(t->i2c->adapter, &radio, &tv); | ||
1067 | if (tv) | ||
1068 | tv->mode_mask &= ~T_RADIO; | ||
1069 | |||
1070 | goto register_client; | ||
1071 | } | ||
1072 | break; | ||
1073 | } | ||
1074 | } | ||
1075 | |||
1076 | /* Initializes only the first TV tuner on this adapter. Why only the | ||
1077 | first? Because there are some devices (notably the ones with TI | ||
1078 | tuners) that have more than one i2c address for the *same* device. | ||
1079 | Experience shows that, except for just one case, the first | ||
1080 | address is the right one. The exception is a Russian tuner | ||
1081 | (ACORP_Y878F). So, the desired behavior is just to enable the | ||
1082 | first found TV tuner. */ | ||
1083 | tuner_lookup(t->i2c->adapter, &radio, &tv); | ||
1084 | if (tv == NULL) { | ||
1085 | t->mode_mask = T_ANALOG_TV | T_DIGITAL_TV; | ||
1086 | if (radio == NULL) | ||
1087 | t->mode_mask |= T_RADIO; | ||
1088 | tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask); | ||
1089 | t->tv_freq = 400 * 16; /* Sets freq to VHF High */ | ||
1090 | t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */ | ||
1091 | } | ||
1092 | |||
1093 | /* Should be just before return */ | ||
1094 | register_client: | ||
1095 | tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name); | ||
1096 | |||
1097 | /* Sets a default mode */ | ||
1098 | if (t->mode_mask & T_ANALOG_TV) { | ||
1099 | t->mode = T_ANALOG_TV; | ||
1100 | } else if (t->mode_mask & T_RADIO) { | ||
1101 | t->mode = T_RADIO; | ||
1102 | } else { | ||
1103 | t->mode = T_DIGITAL_TV; | ||
1104 | } | ||
1105 | |||
1106 | i2c_attach_client(client); | ||
1107 | set_type(client, t->type, t->mode_mask, t->config, t->tuner_callback); | ||
1108 | return 0; | ||
1109 | } | ||
1110 | |||
1111 | static int tuner_probe(struct i2c_adapter *adap) | ||
1112 | { | ||
1113 | if (0 != addr) { | ||
1114 | normal_i2c[0] = addr; | ||
1115 | normal_i2c[1] = I2C_CLIENT_END; | ||
1116 | } | ||
1117 | |||
1118 | /* HACK: Ignore 0x6b and 0x6f on cx88 boards. | ||
1119 | * FusionHDTV5 RT Gold has an ir receiver at 0x6b | ||
1120 | * and an RTC at 0x6f which can get corrupted if probed. | ||
1121 | */ | ||
1122 | if ((adap->id == I2C_HW_B_CX2388x) || | ||
1123 | (adap->id == I2C_HW_B_CX23885)) { | ||
1124 | unsigned int i = 0; | ||
1125 | |||
1126 | while (i < I2C_CLIENT_MAX_OPTS && ignore[i] != I2C_CLIENT_END) | ||
1127 | i += 2; | ||
1128 | if (i + 4 < I2C_CLIENT_MAX_OPTS) { | ||
1129 | ignore[i+0] = adap->nr; | ||
1130 | ignore[i+1] = 0x6b; | ||
1131 | ignore[i+2] = adap->nr; | ||
1132 | ignore[i+3] = 0x6f; | ||
1133 | ignore[i+4] = I2C_CLIENT_END; | ||
1134 | } else | ||
1135 | printk(KERN_WARNING "tuner: " | ||
1136 | "too many options specified " | ||
1137 | "in i2c probe ignore list!\n"); | ||
1138 | } | ||
1139 | |||
1140 | if (adap->class & I2C_CLASS_TV_ANALOG) | ||
1141 | return i2c_probe(adap, &addr_data, tuner_attach); | ||
1142 | return 0; | ||
1143 | } | ||
1144 | |||
1145 | static int tuner_detach(struct i2c_client *client) | ||
1146 | { | ||
1147 | struct tuner *t = i2c_get_clientdata(client); | ||
1148 | struct analog_tuner_ops *ops = t->fe.ops.analog_demod_ops; | ||
1149 | int err; | ||
1150 | |||
1151 | err = i2c_detach_client(t->i2c); | ||
1152 | if (err) { | ||
1153 | tuner_warn | ||
1154 | ("Client deregistration failed, client not detached.\n"); | ||
1155 | return err; | ||
1156 | } | ||
1157 | |||
1158 | if (ops && ops->release) | ||
1159 | ops->release(&t->fe); | ||
1160 | |||
1161 | list_del(&t->list); | ||
1162 | kfree(t); | ||
1163 | kfree(client); | ||
1164 | return 0; | ||
1165 | } | ||
1166 | |||
1159 | /* ----------------------------------------------------------------------- */ | 1167 | /* ----------------------------------------------------------------------- */ |
1160 | 1168 | ||
1161 | static struct i2c_driver driver = { | 1169 | static struct i2c_driver driver = { |