diff options
-rw-r--r-- | drivers/media/radio/Kconfig | 2 | ||||
-rw-r--r-- | drivers/media/radio/radio-typhoon.c | 170 |
2 files changed, 117 insertions, 55 deletions
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 79d6b1bcd1a4..e64f0aae7dea 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
@@ -286,7 +286,7 @@ config RADIO_TRUST_PORT | |||
286 | 286 | ||
287 | config RADIO_TYPHOON | 287 | config RADIO_TYPHOON |
288 | tristate "Typhoon Radio (a.k.a. EcoRadio)" | 288 | tristate "Typhoon Radio (a.k.a. EcoRadio)" |
289 | depends on ISA && VIDEO_V4L1 | 289 | depends on ISA && VIDEO_V4L2 |
290 | ---help--- | 290 | ---help--- |
291 | Choose Y here if you have one of these FM radio cards, and then fill | 291 | Choose Y here if you have one of these FM radio cards, and then fill |
292 | in the port address and the frequency used for muting below. | 292 | in the port address and the frequency used for muting below. |
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 2835c8947f0a..f8b732bc9a05 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c | |||
@@ -27,6 +27,8 @@ | |||
27 | * value where I do expect just noise and turn the speaker volume down. | 27 | * value where I do expect just noise and turn the speaker volume down. |
28 | * The frequency change is necessary since the card never seems to be | 28 | * The frequency change is necessary since the card never seems to be |
29 | * completely silent. | 29 | * completely silent. |
30 | * | ||
31 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | ||
30 | */ | 32 | */ |
31 | 33 | ||
32 | #include <linux/module.h> /* Modules */ | 34 | #include <linux/module.h> /* Modules */ |
@@ -35,10 +37,32 @@ | |||
35 | #include <linux/proc_fs.h> /* radio card status report */ | 37 | #include <linux/proc_fs.h> /* radio card status report */ |
36 | #include <asm/io.h> /* outb, outb_p */ | 38 | #include <asm/io.h> /* outb, outb_p */ |
37 | #include <asm/uaccess.h> /* copy to/from user */ | 39 | #include <asm/uaccess.h> /* copy to/from user */ |
38 | #include <linux/videodev.h> /* kernel radio structs */ | 40 | #include <linux/videodev2.h> /* kernel radio structs */ |
39 | #include <media/v4l2-common.h> | 41 | #include <media/v4l2-common.h> |
40 | 42 | ||
41 | #define BANNER "Typhoon Radio Card driver v0.1\n" | 43 | #include <linux/version.h> /* for KERNEL_VERSION MACRO */ |
44 | #define RADIO_VERSION KERNEL_VERSION(0,1,1) | ||
45 | #define BANNER "Typhoon Radio Card driver v0.1.1\n" | ||
46 | |||
47 | static struct v4l2_queryctrl radio_qctrl[] = { | ||
48 | { | ||
49 | .id = V4L2_CID_AUDIO_MUTE, | ||
50 | .name = "Mute", | ||
51 | .minimum = 0, | ||
52 | .maximum = 1, | ||
53 | .default_value = 1, | ||
54 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
55 | },{ | ||
56 | .id = V4L2_CID_AUDIO_VOLUME, | ||
57 | .name = "Volume", | ||
58 | .minimum = 0, | ||
59 | .maximum = 65535, | ||
60 | .step = 1<<14, | ||
61 | .default_value = 0xff, | ||
62 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
63 | } | ||
64 | }; | ||
65 | |||
42 | 66 | ||
43 | #ifndef CONFIG_RADIO_TYPHOON_PORT | 67 | #ifndef CONFIG_RADIO_TYPHOON_PORT |
44 | #define CONFIG_RADIO_TYPHOON_PORT -1 | 68 | #define CONFIG_RADIO_TYPHOON_PORT -1 |
@@ -170,76 +194,114 @@ static int typhoon_do_ioctl(struct inode *inode, struct file *file, | |||
170 | struct typhoon_device *typhoon = dev->priv; | 194 | struct typhoon_device *typhoon = dev->priv; |
171 | 195 | ||
172 | switch (cmd) { | 196 | switch (cmd) { |
173 | case VIDIOCGCAP: | 197 | case VIDIOC_QUERYCAP: |
174 | { | 198 | { |
175 | struct video_capability *v = arg; | 199 | struct v4l2_capability *v = arg; |
176 | memset(v,0,sizeof(*v)); | 200 | memset(v,0,sizeof(*v)); |
177 | v->type = VID_TYPE_TUNER; | 201 | strlcpy(v->driver, "radio-typhoon", sizeof (v->driver)); |
178 | v->channels = 1; | 202 | strlcpy(v->card, "Typhoon Radio", sizeof (v->card)); |
179 | v->audios = 1; | 203 | sprintf(v->bus_info,"ISA"); |
180 | strcpy(v->name, "Typhoon Radio"); | 204 | v->version = RADIO_VERSION; |
205 | v->capabilities = V4L2_CAP_TUNER; | ||
206 | |||
181 | return 0; | 207 | return 0; |
182 | } | 208 | } |
183 | case VIDIOCGTUNER: | 209 | case VIDIOC_G_TUNER: |
184 | { | 210 | { |
185 | struct video_tuner *v = arg; | 211 | struct v4l2_tuner *v = arg; |
186 | if (v->tuner) /* Only 1 tuner */ | 212 | |
213 | if (v->index > 0) | ||
187 | return -EINVAL; | 214 | return -EINVAL; |
188 | v->rangelow = 875 * 1600; | 215 | |
189 | v->rangehigh = 1080 * 1600; | 216 | memset(v,0,sizeof(*v)); |
190 | v->flags = VIDEO_TUNER_LOW; | ||
191 | v->mode = VIDEO_MODE_AUTO; | ||
192 | v->signal = 0xFFFF; /* We can't get the signal strength */ | ||
193 | strcpy(v->name, "FM"); | 217 | strcpy(v->name, "FM"); |
218 | v->type = V4L2_TUNER_RADIO; | ||
219 | |||
220 | v->rangelow=(87.5*16000); | ||
221 | v->rangehigh=(108*16000); | ||
222 | v->rxsubchans =V4L2_TUNER_SUB_MONO; | ||
223 | v->capability=V4L2_TUNER_CAP_LOW; | ||
224 | v->audmode = V4L2_TUNER_MODE_MONO; | ||
225 | v->signal = 0xFFFF; /* We can't get the signal strength */ | ||
226 | |||
194 | return 0; | 227 | return 0; |
195 | } | 228 | } |
196 | case VIDIOCSTUNER: | 229 | case VIDIOC_S_TUNER: |
197 | { | 230 | { |
198 | struct video_tuner *v = arg; | 231 | struct v4l2_tuner *v = arg; |
199 | if (v->tuner != 0) | 232 | |
233 | if (v->index > 0) | ||
200 | return -EINVAL; | 234 | return -EINVAL; |
201 | /* Only 1 tuner so no setting needed ! */ | 235 | |
202 | return 0; | 236 | return 0; |
203 | } | 237 | } |
204 | case VIDIOCGFREQ: | 238 | case VIDIOC_S_FREQUENCY: |
205 | { | ||
206 | unsigned long *freq = arg; | ||
207 | *freq = typhoon->curfreq; | ||
208 | return 0; | ||
209 | } | ||
210 | case VIDIOCSFREQ: | ||
211 | { | ||
212 | unsigned long *freq = arg; | ||
213 | typhoon->curfreq = *freq; | ||
214 | typhoon_setfreq(typhoon, typhoon->curfreq); | ||
215 | return 0; | ||
216 | } | ||
217 | case VIDIOCGAUDIO: | ||
218 | { | 239 | { |
219 | struct video_audio *v = arg; | 240 | struct v4l2_frequency *f = arg; |
220 | memset(v, 0, sizeof(*v)); | 241 | |
221 | v->flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME; | 242 | typhoon->curfreq = f->frequency; |
222 | v->mode |= VIDEO_SOUND_MONO; | 243 | typhoon_setfreq(typhoon, typhoon->curfreq); |
223 | v->volume = typhoon->curvol; | ||
224 | v->step = 1 << 14; | ||
225 | strcpy(v->name, "Typhoon Radio"); | ||
226 | return 0; | 244 | return 0; |
227 | } | 245 | } |
228 | case VIDIOCSAUDIO: | 246 | case VIDIOC_G_FREQUENCY: |
229 | { | 247 | { |
230 | struct video_audio *v = arg; | 248 | struct v4l2_frequency *f = arg; |
231 | if (v->audio) | 249 | |
232 | return -EINVAL; | 250 | f->type = V4L2_TUNER_RADIO; |
233 | if (v->flags & VIDEO_AUDIO_MUTE) | 251 | f->frequency = typhoon->curfreq; |
234 | typhoon_mute(typhoon); | 252 | |
235 | else | ||
236 | typhoon_unmute(typhoon); | ||
237 | if (v->flags & VIDEO_AUDIO_VOLUME) | ||
238 | typhoon_setvol(typhoon, v->volume); | ||
239 | return 0; | 253 | return 0; |
240 | } | 254 | } |
241 | default: | 255 | case VIDIOC_QUERYCTRL: |
242 | return -ENOIOCTLCMD; | 256 | { |
257 | struct v4l2_queryctrl *qc = arg; | ||
258 | int i; | ||
259 | |||
260 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | ||
261 | if (qc->id && qc->id == radio_qctrl[i].id) { | ||
262 | memcpy(qc, &(radio_qctrl[i]), | ||
263 | sizeof(*qc)); | ||
264 | return (0); | ||
265 | } | ||
266 | } | ||
267 | return -EINVAL; | ||
268 | } | ||
269 | case VIDIOC_G_CTRL: | ||
270 | { | ||
271 | struct v4l2_control *ctrl= arg; | ||
272 | |||
273 | switch (ctrl->id) { | ||
274 | case V4L2_CID_AUDIO_MUTE: | ||
275 | ctrl->value=typhoon->muted; | ||
276 | return (0); | ||
277 | case V4L2_CID_AUDIO_VOLUME: | ||
278 | ctrl->value=typhoon->curvol; | ||
279 | return (0); | ||
280 | } | ||
281 | return -EINVAL; | ||
282 | } | ||
283 | case VIDIOC_S_CTRL: | ||
284 | { | ||
285 | struct v4l2_control *ctrl= arg; | ||
286 | |||
287 | switch (ctrl->id) { | ||
288 | case V4L2_CID_AUDIO_MUTE: | ||
289 | if (ctrl->value) { | ||
290 | typhoon_mute(typhoon); | ||
291 | } else { | ||
292 | typhoon_unmute(typhoon); | ||
293 | } | ||
294 | return (0); | ||
295 | case V4L2_CID_AUDIO_VOLUME: | ||
296 | typhoon_setvol(typhoon, ctrl->value); | ||
297 | return (0); | ||
298 | } | ||
299 | return -EINVAL; | ||
300 | } | ||
301 | |||
302 | default: | ||
303 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | ||
304 | typhon_do_ioctl); | ||
243 | } | 305 | } |
244 | } | 306 | } |
245 | 307 | ||
@@ -270,7 +332,7 @@ static struct video_device typhoon_radio = | |||
270 | .owner = THIS_MODULE, | 332 | .owner = THIS_MODULE, |
271 | .name = "Typhoon Radio", | 333 | .name = "Typhoon Radio", |
272 | .type = VID_TYPE_TUNER, | 334 | .type = VID_TYPE_TUNER, |
273 | .hardware = VID_HARDWARE_TYPHOON, | 335 | .hardware = 0, |
274 | .fops = &typhoon_fops, | 336 | .fops = &typhoon_fops, |
275 | }; | 337 | }; |
276 | 338 | ||