diff options
-rw-r--r-- | include/sound/tea575x-tuner.h | 6 | ||||
-rw-r--r-- | sound/i2c/other/tea575x-tuner.c | 52 |
2 files changed, 42 insertions, 16 deletions
diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h index 5718a02d3afb..3d6cdd80df59 100644 --- a/include/sound/tea575x-tuner.h +++ b/include/sound/tea575x-tuner.h | |||
@@ -38,8 +38,10 @@ struct snd_tea575x { | |||
38 | struct snd_card *card; | 38 | struct snd_card *card; |
39 | struct video_device *vd; /* video device */ | 39 | struct video_device *vd; /* video device */ |
40 | int dev_nr; /* requested device number + 1 */ | 40 | int dev_nr; /* requested device number + 1 */ |
41 | int tea5759; /* 5759 chip is present */ | 41 | bool tea5759; /* 5759 chip is present */ |
42 | int mute; /* Device is muted? */ | 42 | bool mute; /* Device is muted? */ |
43 | bool stereo; /* receiving stereo */ | ||
44 | bool tuned; /* tuned to a station */ | ||
43 | unsigned int freq_fixup; /* crystal onboard */ | 45 | unsigned int freq_fixup; /* crystal onboard */ |
44 | unsigned int val; /* hw value */ | 46 | unsigned int val; /* hw value */ |
45 | unsigned long freq; /* frequency */ | 47 | unsigned long freq; /* frequency */ |
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index ee538f1ae846..9f35f378a17d 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c | |||
@@ -37,8 +37,8 @@ static int radio_nr = -1; | |||
37 | module_param(radio_nr, int, 0); | 37 | module_param(radio_nr, int, 0); |
38 | 38 | ||
39 | #define RADIO_VERSION KERNEL_VERSION(0, 0, 2) | 39 | #define RADIO_VERSION KERNEL_VERSION(0, 0, 2) |
40 | #define FREQ_LO (87 * 16000) | 40 | #define FREQ_LO (50UL * 16000) |
41 | #define FREQ_HI (108 * 16000) | 41 | #define FREQ_HI (150UL * 16000) |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * definitions | 44 | * definitions |
@@ -77,15 +77,29 @@ static struct v4l2_queryctrl radio_qctrl[] = { | |||
77 | * lowlevel part | 77 | * lowlevel part |
78 | */ | 78 | */ |
79 | 79 | ||
80 | static void snd_tea575x_get_freq(struct snd_tea575x *tea) | ||
81 | { | ||
82 | unsigned long freq; | ||
83 | |||
84 | freq = tea->ops->read(tea) & TEA575X_BIT_FREQ_MASK; | ||
85 | /* freq *= 12.5 */ | ||
86 | freq *= 125; | ||
87 | freq /= 10; | ||
88 | /* crystal fixup */ | ||
89 | if (tea->tea5759) | ||
90 | freq += tea->freq_fixup; | ||
91 | else | ||
92 | freq -= tea->freq_fixup; | ||
93 | |||
94 | tea->freq = freq * 16; /* from kHz */ | ||
95 | } | ||
96 | |||
80 | static void snd_tea575x_set_freq(struct snd_tea575x *tea) | 97 | static void snd_tea575x_set_freq(struct snd_tea575x *tea) |
81 | { | 98 | { |
82 | unsigned long freq; | 99 | unsigned long freq; |
83 | 100 | ||
84 | freq = tea->freq / 16; /* to kHz */ | 101 | freq = clamp(tea->freq, FREQ_LO, FREQ_HI); |
85 | if (freq > 108000) | 102 | freq /= 16; /* to kHz */ |
86 | freq = 108000; | ||
87 | if (freq < 87000) | ||
88 | freq = 87000; | ||
89 | /* crystal fixup */ | 103 | /* crystal fixup */ |
90 | if (tea->tea5759) | 104 | if (tea->tea5759) |
91 | freq -= tea->freq_fixup; | 105 | freq -= tea->freq_fixup; |
@@ -109,29 +123,33 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
109 | { | 123 | { |
110 | struct snd_tea575x *tea = video_drvdata(file); | 124 | struct snd_tea575x *tea = video_drvdata(file); |
111 | 125 | ||
112 | strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757"); | ||
113 | strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver)); | 126 | strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver)); |
114 | strlcpy(v->card, "Maestro Radio", sizeof(v->card)); | 127 | strlcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757", sizeof(v->card)); |
115 | sprintf(v->bus_info, "PCI"); | 128 | sprintf(v->bus_info, "PCI"); |
116 | v->version = RADIO_VERSION; | 129 | v->version = RADIO_VERSION; |
117 | v->capabilities = V4L2_CAP_TUNER; | 130 | v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; |
118 | return 0; | 131 | return 0; |
119 | } | 132 | } |
120 | 133 | ||
121 | static int vidioc_g_tuner(struct file *file, void *priv, | 134 | static int vidioc_g_tuner(struct file *file, void *priv, |
122 | struct v4l2_tuner *v) | 135 | struct v4l2_tuner *v) |
123 | { | 136 | { |
137 | struct snd_tea575x *tea = video_drvdata(file); | ||
138 | |||
124 | if (v->index > 0) | 139 | if (v->index > 0) |
125 | return -EINVAL; | 140 | return -EINVAL; |
126 | 141 | ||
142 | tea->ops->read(tea); | ||
143 | |||
127 | strcpy(v->name, "FM"); | 144 | strcpy(v->name, "FM"); |
128 | v->type = V4L2_TUNER_RADIO; | 145 | v->type = V4L2_TUNER_RADIO; |
146 | v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; | ||
129 | v->rangelow = FREQ_LO; | 147 | v->rangelow = FREQ_LO; |
130 | v->rangehigh = FREQ_HI; | 148 | v->rangehigh = FREQ_HI; |
131 | v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; | 149 | v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; |
132 | v->capability = V4L2_TUNER_CAP_LOW; | 150 | v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO; |
133 | v->audmode = V4L2_TUNER_MODE_MONO; | 151 | v->signal = tea->tuned ? 0xffff : 0; |
134 | v->signal = 0xffff; | 152 | |
135 | return 0; | 153 | return 0; |
136 | } | 154 | } |
137 | 155 | ||
@@ -148,7 +166,10 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
148 | { | 166 | { |
149 | struct snd_tea575x *tea = video_drvdata(file); | 167 | struct snd_tea575x *tea = video_drvdata(file); |
150 | 168 | ||
169 | if (f->tuner != 0) | ||
170 | return -EINVAL; | ||
151 | f->type = V4L2_TUNER_RADIO; | 171 | f->type = V4L2_TUNER_RADIO; |
172 | snd_tea575x_get_freq(tea); | ||
152 | f->frequency = tea->freq; | 173 | f->frequency = tea->freq; |
153 | return 0; | 174 | return 0; |
154 | } | 175 | } |
@@ -158,6 +179,9 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
158 | { | 179 | { |
159 | struct snd_tea575x *tea = video_drvdata(file); | 180 | struct snd_tea575x *tea = video_drvdata(file); |
160 | 181 | ||
182 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
183 | return -EINVAL; | ||
184 | |||
161 | if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) | 185 | if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) |
162 | return -EINVAL; | 186 | return -EINVAL; |
163 | 187 | ||