diff options
Diffstat (limited to 'sound/pci/fm801.c')
-rw-r--r-- | sound/pci/fm801.c | 371 |
1 files changed, 79 insertions, 292 deletions
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index e1baad74ea4b..eacd4901a308 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -38,7 +38,6 @@ | |||
38 | 38 | ||
39 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL | 39 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
40 | #include <sound/tea575x-tuner.h> | 40 | #include <sound/tea575x-tuner.h> |
41 | #define TEA575X_RADIO 1 | ||
42 | #endif | 41 | #endif |
43 | 42 | ||
44 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); | 43 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); |
@@ -53,7 +52,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card * | |||
53 | /* | 52 | /* |
54 | * Enable TEA575x tuner | 53 | * Enable TEA575x tuner |
55 | * 1 = MediaForte 256-PCS | 54 | * 1 = MediaForte 256-PCS |
56 | * 2 = MediaForte 256-PCPR | 55 | * 2 = MediaForte 256-PCP |
57 | * 3 = MediaForte 64-PCR | 56 | * 3 = MediaForte 64-PCR |
58 | * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card | 57 | * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card |
59 | * High 16-bits are video (radio) device number + 1 | 58 | * High 16-bits are video (radio) device number + 1 |
@@ -67,7 +66,7 @@ MODULE_PARM_DESC(id, "ID string for the FM801 soundcard."); | |||
67 | module_param_array(enable, bool, NULL, 0444); | 66 | module_param_array(enable, bool, NULL, 0444); |
68 | MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); | 67 | MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); |
69 | module_param_array(tea575x_tuner, int, NULL, 0444); | 68 | module_param_array(tea575x_tuner, int, NULL, 0444); |
70 | MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (1 = SF256-PCS, 2=SF256-PCPR, 3=SF64-PCR, +16=tuner-only)."); | 69 | MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only)."); |
71 | 70 | ||
72 | #define TUNER_ONLY (1<<4) | 71 | #define TUNER_ONLY (1<<4) |
73 | #define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF) | 72 | #define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF) |
@@ -196,7 +195,7 @@ struct fm801 { | |||
196 | spinlock_t reg_lock; | 195 | spinlock_t reg_lock; |
197 | struct snd_info_entry *proc_entry; | 196 | struct snd_info_entry *proc_entry; |
198 | 197 | ||
199 | #ifdef TEA575X_RADIO | 198 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
200 | struct snd_tea575x tea; | 199 | struct snd_tea575x tea; |
201 | #endif | 200 | #endif |
202 | 201 | ||
@@ -715,310 +714,89 @@ static int __devinit snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pc | |||
715 | * TEA5757 radio | 714 | * TEA5757 radio |
716 | */ | 715 | */ |
717 | 716 | ||
718 | #ifdef TEA575X_RADIO | 717 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
719 | |||
720 | /* 256PCS GPIO numbers */ | ||
721 | #define TEA_256PCS_DATA 1 | ||
722 | #define TEA_256PCS_WRITE_ENABLE 2 /* inverted */ | ||
723 | #define TEA_256PCS_BUS_CLOCK 3 | ||
724 | |||
725 | static void snd_fm801_tea575x_256pcs_write(struct snd_tea575x *tea, unsigned int val) | ||
726 | { | ||
727 | struct fm801 *chip = tea->private_data; | ||
728 | unsigned short reg; | ||
729 | int i = 25; | ||
730 | 718 | ||
731 | spin_lock_irq(&chip->reg_lock); | 719 | /* GPIO to TEA575x maps */ |
732 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | 720 | struct snd_fm801_tea575x_gpio { |
733 | /* use GPIO lines and set write enable bit */ | 721 | u8 data, clk, wren, most; |
734 | reg |= FM801_GPIO_GS(TEA_256PCS_DATA) | | 722 | char *name; |
735 | FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) | | 723 | }; |
736 | FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK); | ||
737 | /* all of lines are in the write direction */ | ||
738 | /* clear data and clock lines */ | ||
739 | reg &= ~(FM801_GPIO_GD(TEA_256PCS_DATA) | | ||
740 | FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) | | ||
741 | FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) | | ||
742 | FM801_GPIO_GP(TEA_256PCS_DATA) | | ||
743 | FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK) | | ||
744 | FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE)); | ||
745 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
746 | udelay(1); | ||
747 | |||
748 | while (i--) { | ||
749 | if (val & (1 << i)) | ||
750 | reg |= FM801_GPIO_GP(TEA_256PCS_DATA); | ||
751 | else | ||
752 | reg &= ~FM801_GPIO_GP(TEA_256PCS_DATA); | ||
753 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
754 | udelay(1); | ||
755 | reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK); | ||
756 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
757 | reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK); | ||
758 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
759 | udelay(1); | ||
760 | } | ||
761 | 724 | ||
762 | /* and reset the write enable bit */ | 725 | static struct snd_fm801_tea575x_gpio snd_fm801_tea575x_gpios[] = { |
763 | reg |= FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE) | | 726 | { .data = 1, .clk = 3, .wren = 2, .most = 0, .name = "SF256-PCS" }, |
764 | FM801_GPIO_GP(TEA_256PCS_DATA); | 727 | { .data = 1, .clk = 0, .wren = 2, .most = 3, .name = "SF256-PCP" }, |
765 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 728 | { .data = 2, .clk = 0, .wren = 1, .most = 3, .name = "SF64-PCR" }, |
766 | spin_unlock_irq(&chip->reg_lock); | 729 | }; |
767 | } | ||
768 | 730 | ||
769 | static unsigned int snd_fm801_tea575x_256pcs_read(struct snd_tea575x *tea) | 731 | static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins) |
770 | { | 732 | { |
771 | struct fm801 *chip = tea->private_data; | 733 | struct fm801 *chip = tea->private_data; |
772 | unsigned short reg; | 734 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); |
773 | unsigned int val = 0; | 735 | struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1]; |
774 | int i; | ||
775 | |||
776 | spin_lock_irq(&chip->reg_lock); | ||
777 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | ||
778 | /* use GPIO lines, set data direction to input */ | ||
779 | reg |= FM801_GPIO_GS(TEA_256PCS_DATA) | | ||
780 | FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) | | ||
781 | FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK) | | ||
782 | FM801_GPIO_GD(TEA_256PCS_DATA) | | ||
783 | FM801_GPIO_GP(TEA_256PCS_DATA) | | ||
784 | FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE); | ||
785 | /* all of lines are in the write direction, except data */ | ||
786 | /* clear data, write enable and clock lines */ | ||
787 | reg &= ~(FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) | | ||
788 | FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) | | ||
789 | FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK)); | ||
790 | |||
791 | for (i = 0; i < 24; i++) { | ||
792 | reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK); | ||
793 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
794 | udelay(1); | ||
795 | reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK); | ||
796 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
797 | udelay(1); | ||
798 | val <<= 1; | ||
799 | if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCS_DATA)) | ||
800 | val |= 1; | ||
801 | } | ||
802 | 736 | ||
803 | spin_unlock_irq(&chip->reg_lock); | 737 | reg &= ~(FM801_GPIO_GP(gpio.data) | |
738 | FM801_GPIO_GP(gpio.clk) | | ||
739 | FM801_GPIO_GP(gpio.wren)); | ||
804 | 740 | ||
805 | return val; | 741 | reg |= (pins & TEA575X_DATA) ? FM801_GPIO_GP(gpio.data) : 0; |
806 | } | 742 | reg |= (pins & TEA575X_CLK) ? FM801_GPIO_GP(gpio.clk) : 0; |
743 | /* WRITE_ENABLE is inverted */ | ||
744 | reg |= (pins & TEA575X_WREN) ? 0 : FM801_GPIO_GP(gpio.wren); | ||
807 | 745 | ||
808 | /* 256PCPR GPIO numbers */ | ||
809 | #define TEA_256PCPR_BUS_CLOCK 0 | ||
810 | #define TEA_256PCPR_DATA 1 | ||
811 | #define TEA_256PCPR_WRITE_ENABLE 2 /* inverted */ | ||
812 | |||
813 | static void snd_fm801_tea575x_256pcpr_write(struct snd_tea575x *tea, unsigned int val) | ||
814 | { | ||
815 | struct fm801 *chip = tea->private_data; | ||
816 | unsigned short reg; | ||
817 | int i = 25; | ||
818 | |||
819 | spin_lock_irq(&chip->reg_lock); | ||
820 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | ||
821 | /* use GPIO lines and set write enable bit */ | ||
822 | reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) | | ||
823 | FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) | | ||
824 | FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK); | ||
825 | /* all of lines are in the write direction */ | ||
826 | /* clear data and clock lines */ | ||
827 | reg &= ~(FM801_GPIO_GD(TEA_256PCPR_DATA) | | ||
828 | FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) | | ||
829 | FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) | | ||
830 | FM801_GPIO_GP(TEA_256PCPR_DATA) | | ||
831 | FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK) | | ||
832 | FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE)); | ||
833 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 746 | outw(reg, FM801_REG(chip, GPIO_CTRL)); |
834 | udelay(1); | ||
835 | |||
836 | while (i--) { | ||
837 | if (val & (1 << i)) | ||
838 | reg |= FM801_GPIO_GP(TEA_256PCPR_DATA); | ||
839 | else | ||
840 | reg &= ~FM801_GPIO_GP(TEA_256PCPR_DATA); | ||
841 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
842 | udelay(1); | ||
843 | reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK); | ||
844 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
845 | reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK); | ||
846 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
847 | udelay(1); | ||
848 | } | ||
849 | |||
850 | /* and reset the write enable bit */ | ||
851 | reg |= FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE) | | ||
852 | FM801_GPIO_GP(TEA_256PCPR_DATA); | ||
853 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
854 | spin_unlock_irq(&chip->reg_lock); | ||
855 | } | 747 | } |
856 | 748 | ||
857 | static unsigned int snd_fm801_tea575x_256pcpr_read(struct snd_tea575x *tea) | 749 | static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea) |
858 | { | 750 | { |
859 | struct fm801 *chip = tea->private_data; | 751 | struct fm801 *chip = tea->private_data; |
860 | unsigned short reg; | 752 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); |
861 | unsigned int val = 0; | 753 | struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1]; |
862 | int i; | ||
863 | |||
864 | spin_lock_irq(&chip->reg_lock); | ||
865 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | ||
866 | /* use GPIO lines, set data direction to input */ | ||
867 | reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) | | ||
868 | FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) | | ||
869 | FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK) | | ||
870 | FM801_GPIO_GD(TEA_256PCPR_DATA) | | ||
871 | FM801_GPIO_GP(TEA_256PCPR_DATA) | | ||
872 | FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE); | ||
873 | /* all of lines are in the write direction, except data */ | ||
874 | /* clear data, write enable and clock lines */ | ||
875 | reg &= ~(FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) | | ||
876 | FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) | | ||
877 | FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK)); | ||
878 | |||
879 | for (i = 0; i < 24; i++) { | ||
880 | reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK); | ||
881 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
882 | udelay(1); | ||
883 | reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK); | ||
884 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
885 | udelay(1); | ||
886 | val <<= 1; | ||
887 | if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCPR_DATA)) | ||
888 | val |= 1; | ||
889 | } | ||
890 | 754 | ||
891 | spin_unlock_irq(&chip->reg_lock); | 755 | return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 | |
892 | 756 | (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0; | |
893 | return val; | ||
894 | } | 757 | } |
895 | 758 | ||
896 | /* 64PCR GPIO numbers */ | 759 | static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output) |
897 | #define TEA_64PCR_BUS_CLOCK 0 | ||
898 | #define TEA_64PCR_WRITE_ENABLE 1 /* inverted */ | ||
899 | #define TEA_64PCR_DATA 2 | ||
900 | |||
901 | static void snd_fm801_tea575x_64pcr_write(struct snd_tea575x *tea, unsigned int val) | ||
902 | { | 760 | { |
903 | struct fm801 *chip = tea->private_data; | 761 | struct fm801 *chip = tea->private_data; |
904 | unsigned short reg; | 762 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); |
905 | int i = 25; | 763 | struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1]; |
906 | 764 | ||
907 | spin_lock_irq(&chip->reg_lock); | ||
908 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | ||
909 | /* use GPIO lines and set write enable bit */ | 765 | /* use GPIO lines and set write enable bit */ |
910 | reg |= FM801_GPIO_GS(TEA_64PCR_DATA) | | 766 | reg |= FM801_GPIO_GS(gpio.data) | |
911 | FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) | | 767 | FM801_GPIO_GS(gpio.wren) | |
912 | FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK); | 768 | FM801_GPIO_GS(gpio.clk) | |
913 | /* all of lines are in the write direction */ | 769 | FM801_GPIO_GS(gpio.most); |
914 | /* clear data and clock lines */ | 770 | if (output) { |
915 | reg &= ~(FM801_GPIO_GD(TEA_64PCR_DATA) | | 771 | /* all of lines are in the write direction */ |
916 | FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) | | 772 | /* clear data and clock lines */ |
917 | FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) | | 773 | reg &= ~(FM801_GPIO_GD(gpio.data) | |
918 | FM801_GPIO_GP(TEA_64PCR_DATA) | | 774 | FM801_GPIO_GD(gpio.wren) | |
919 | FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK) | | 775 | FM801_GPIO_GD(gpio.clk) | |
920 | FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE)); | 776 | FM801_GPIO_GP(gpio.data) | |
921 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 777 | FM801_GPIO_GP(gpio.clk) | |
922 | udelay(1); | 778 | FM801_GPIO_GP(gpio.wren)); |
923 | 779 | } else { | |
924 | while (i--) { | 780 | /* use GPIO lines, set data direction to input */ |
925 | if (val & (1 << i)) | 781 | reg |= FM801_GPIO_GD(gpio.data) | |
926 | reg |= FM801_GPIO_GP(TEA_64PCR_DATA); | 782 | FM801_GPIO_GD(gpio.most) | |
927 | else | 783 | FM801_GPIO_GP(gpio.data) | |
928 | reg &= ~FM801_GPIO_GP(TEA_64PCR_DATA); | 784 | FM801_GPIO_GP(gpio.most) | |
929 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 785 | FM801_GPIO_GP(gpio.wren); |
930 | udelay(1); | 786 | /* all of lines are in the write direction, except data */ |
931 | reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); | 787 | /* clear data, write enable and clock lines */ |
932 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 788 | reg &= ~(FM801_GPIO_GD(gpio.wren) | |
933 | reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); | 789 | FM801_GPIO_GD(gpio.clk) | |
934 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 790 | FM801_GPIO_GP(gpio.clk)); |
935 | udelay(1); | ||
936 | } | 791 | } |
937 | 792 | ||
938 | /* and reset the write enable bit */ | ||
939 | reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE) | | ||
940 | FM801_GPIO_GP(TEA_64PCR_DATA); | ||
941 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 793 | outw(reg, FM801_REG(chip, GPIO_CTRL)); |
942 | spin_unlock_irq(&chip->reg_lock); | ||
943 | } | ||
944 | |||
945 | static unsigned int snd_fm801_tea575x_64pcr_read(struct snd_tea575x *tea) | ||
946 | { | ||
947 | struct fm801 *chip = tea->private_data; | ||
948 | unsigned short reg; | ||
949 | unsigned int val = 0; | ||
950 | int i; | ||
951 | |||
952 | spin_lock_irq(&chip->reg_lock); | ||
953 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | ||
954 | /* use GPIO lines, set data direction to input */ | ||
955 | reg |= FM801_GPIO_GS(TEA_64PCR_DATA) | | ||
956 | FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) | | ||
957 | FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK) | | ||
958 | FM801_GPIO_GD(TEA_64PCR_DATA) | | ||
959 | FM801_GPIO_GP(TEA_64PCR_DATA) | | ||
960 | FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE); | ||
961 | /* all of lines are in the write direction, except data */ | ||
962 | /* clear data, write enable and clock lines */ | ||
963 | reg &= ~(FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) | | ||
964 | FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) | | ||
965 | FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK)); | ||
966 | |||
967 | for (i = 0; i < 24; i++) { | ||
968 | reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); | ||
969 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
970 | udelay(1); | ||
971 | reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); | ||
972 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
973 | udelay(1); | ||
974 | val <<= 1; | ||
975 | if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_64PCR_DATA)) | ||
976 | val |= 1; | ||
977 | } | ||
978 | |||
979 | spin_unlock_irq(&chip->reg_lock); | ||
980 | |||
981 | return val; | ||
982 | } | 794 | } |
983 | 795 | ||
984 | static void snd_fm801_tea575x_64pcr_mute(struct snd_tea575x *tea, | 796 | static struct snd_tea575x_ops snd_fm801_tea_ops = { |
985 | unsigned int mute) | 797 | .set_pins = snd_fm801_tea575x_set_pins, |
986 | { | 798 | .get_pins = snd_fm801_tea575x_get_pins, |
987 | struct fm801 *chip = tea->private_data; | 799 | .set_direction = snd_fm801_tea575x_set_direction, |
988 | unsigned short reg; | ||
989 | |||
990 | spin_lock_irq(&chip->reg_lock); | ||
991 | |||
992 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | ||
993 | if (mute) | ||
994 | /* 0xf800 (mute) */ | ||
995 | reg &= ~FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE); | ||
996 | else | ||
997 | /* 0xf802 (unmute) */ | ||
998 | reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE); | ||
999 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
1000 | udelay(1); | ||
1001 | |||
1002 | spin_unlock_irq(&chip->reg_lock); | ||
1003 | } | ||
1004 | |||
1005 | static struct snd_tea575x_ops snd_fm801_tea_ops[3] = { | ||
1006 | { | ||
1007 | /* 1 = MediaForte 256-PCS */ | ||
1008 | .write = snd_fm801_tea575x_256pcs_write, | ||
1009 | .read = snd_fm801_tea575x_256pcs_read, | ||
1010 | }, | ||
1011 | { | ||
1012 | /* 2 = MediaForte 256-PCPR */ | ||
1013 | .write = snd_fm801_tea575x_256pcpr_write, | ||
1014 | .read = snd_fm801_tea575x_256pcpr_read, | ||
1015 | }, | ||
1016 | { | ||
1017 | /* 3 = MediaForte 64-PCR */ | ||
1018 | .write = snd_fm801_tea575x_64pcr_write, | ||
1019 | .read = snd_fm801_tea575x_64pcr_read, | ||
1020 | .mute = snd_fm801_tea575x_64pcr_mute, | ||
1021 | } | ||
1022 | }; | 800 | }; |
1023 | #endif | 801 | #endif |
1024 | 802 | ||
@@ -1371,7 +1149,7 @@ static int snd_fm801_free(struct fm801 *chip) | |||
1371 | outw(cmdw, FM801_REG(chip, IRQ_MASK)); | 1149 | outw(cmdw, FM801_REG(chip, IRQ_MASK)); |
1372 | 1150 | ||
1373 | __end_hw: | 1151 | __end_hw: |
1374 | #ifdef TEA575X_RADIO | 1152 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
1375 | snd_tea575x_exit(&chip->tea); | 1153 | snd_tea575x_exit(&chip->tea); |
1376 | #endif | 1154 | #endif |
1377 | if (chip->irq >= 0) | 1155 | if (chip->irq >= 0) |
@@ -1450,16 +1228,25 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
1450 | 1228 | ||
1451 | snd_card_set_dev(card, &pci->dev); | 1229 | snd_card_set_dev(card, &pci->dev); |
1452 | 1230 | ||
1453 | #ifdef TEA575X_RADIO | 1231 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
1232 | chip->tea.private_data = chip; | ||
1233 | chip->tea.ops = &snd_fm801_tea_ops; | ||
1234 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); | ||
1454 | if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && | 1235 | if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && |
1455 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { | 1236 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { |
1456 | chip->tea.dev_nr = tea575x_tuner >> 16; | 1237 | if (snd_tea575x_init(&chip->tea)) |
1457 | chip->tea.card = card; | 1238 | snd_printk(KERN_ERR "TEA575x radio not found\n"); |
1458 | chip->tea.freq_fixup = 10700; | 1239 | } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) |
1459 | chip->tea.private_data = chip; | 1240 | /* autodetect tuner connection */ |
1460 | chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & TUNER_TYPE_MASK) - 1]; | 1241 | for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { |
1461 | snd_tea575x_init(&chip->tea); | 1242 | chip->tea575x_tuner = tea575x_tuner; |
1462 | } | 1243 | if (!snd_tea575x_init(&chip->tea)) { |
1244 | snd_printk(KERN_INFO "detected TEA575x radio type %s\n", | ||
1245 | snd_fm801_tea575x_gpios[tea575x_tuner - 1].name); | ||
1246 | break; | ||
1247 | } | ||
1248 | } | ||
1249 | strlcpy(chip->tea.card, snd_fm801_tea575x_gpios[(tea575x_tuner & TUNER_TYPE_MASK) - 1].name, sizeof(chip->tea.card)); | ||
1463 | #endif | 1250 | #endif |
1464 | 1251 | ||
1465 | *rchip = chip; | 1252 | *rchip = chip; |