diff options
Diffstat (limited to 'drivers/media/radio/radio-gemtek.c')
-rw-r--r-- | drivers/media/radio/radio-gemtek.c | 165 |
1 files changed, 116 insertions, 49 deletions
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 162f37d8bf96..730fe16126cb 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c | |||
@@ -13,6 +13,7 @@ | |||
13 | * | 13 | * |
14 | * TODO: Allow for more than one of these foolish entities :-) | 14 | * TODO: Allow for more than one of these foolish entities :-) |
15 | * | 15 | * |
16 | * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> | ||
16 | */ | 17 | */ |
17 | 18 | ||
18 | #include <linux/module.h> /* Modules */ | 19 | #include <linux/module.h> /* Modules */ |
@@ -21,11 +22,32 @@ | |||
21 | #include <linux/delay.h> /* udelay */ | 22 | #include <linux/delay.h> /* udelay */ |
22 | #include <asm/io.h> /* outb, outb_p */ | 23 | #include <asm/io.h> /* outb, outb_p */ |
23 | #include <asm/uaccess.h> /* copy to/from user */ | 24 | #include <asm/uaccess.h> /* copy to/from user */ |
24 | #include <linux/videodev.h> /* kernel radio structs */ | 25 | #include <linux/videodev2.h> /* kernel radio structs */ |
25 | #include <media/v4l2-common.h> | 26 | #include <media/v4l2-common.h> |
26 | #include <linux/config.h> /* CONFIG_RADIO_GEMTEK_PORT */ | ||
27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
28 | 28 | ||
29 | #include <linux/version.h> /* for KERNEL_VERSION MACRO */ | ||
30 | #define RADIO_VERSION KERNEL_VERSION(0,0,2) | ||
31 | |||
32 | static struct v4l2_queryctrl radio_qctrl[] = { | ||
33 | { | ||
34 | .id = V4L2_CID_AUDIO_MUTE, | ||
35 | .name = "Mute", | ||
36 | .minimum = 0, | ||
37 | .maximum = 1, | ||
38 | .default_value = 1, | ||
39 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
40 | },{ | ||
41 | .id = V4L2_CID_AUDIO_VOLUME, | ||
42 | .name = "Volume", | ||
43 | .minimum = 0, | ||
44 | .maximum = 65535, | ||
45 | .step = 65535, | ||
46 | .default_value = 0xff, | ||
47 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
48 | } | ||
49 | }; | ||
50 | |||
29 | #ifndef CONFIG_RADIO_GEMTEK_PORT | 51 | #ifndef CONFIG_RADIO_GEMTEK_PORT |
30 | #define CONFIG_RADIO_GEMTEK_PORT -1 | 52 | #define CONFIG_RADIO_GEMTEK_PORT -1 |
31 | #endif | 53 | #endif |
@@ -147,77 +169,122 @@ static int gemtek_do_ioctl(struct inode *inode, struct file *file, | |||
147 | 169 | ||
148 | switch(cmd) | 170 | switch(cmd) |
149 | { | 171 | { |
150 | case VIDIOCGCAP: | 172 | case VIDIOC_QUERYCAP: |
151 | { | 173 | { |
152 | struct video_capability *v = arg; | 174 | struct v4l2_capability *v = arg; |
153 | memset(v,0,sizeof(*v)); | 175 | memset(v,0,sizeof(*v)); |
154 | v->type=VID_TYPE_TUNER; | 176 | strlcpy(v->driver, "radio-gemtek", sizeof (v->driver)); |
155 | v->channels=1; | 177 | strlcpy(v->card, "GemTek", sizeof (v->card)); |
156 | v->audios=1; | 178 | sprintf(v->bus_info,"ISA"); |
157 | strcpy(v->name, "GemTek"); | 179 | v->version = RADIO_VERSION; |
180 | v->capabilities = V4L2_CAP_TUNER; | ||
181 | |||
158 | return 0; | 182 | return 0; |
159 | } | 183 | } |
160 | case VIDIOCGTUNER: | 184 | case VIDIOC_G_TUNER: |
161 | { | 185 | { |
162 | struct video_tuner *v = arg; | 186 | struct v4l2_tuner *v = arg; |
163 | if(v->tuner) /* Only 1 tuner */ | 187 | |
188 | if (v->index > 0) | ||
164 | return -EINVAL; | 189 | return -EINVAL; |
165 | v->rangelow=87*16000; | 190 | |
166 | v->rangehigh=108*16000; | 191 | memset(v,0,sizeof(*v)); |
167 | v->flags=VIDEO_TUNER_LOW; | ||
168 | v->mode=VIDEO_MODE_AUTO; | ||
169 | v->signal=0xFFFF*gemtek_getsigstr(rt); | ||
170 | strcpy(v->name, "FM"); | 192 | strcpy(v->name, "FM"); |
193 | v->type = V4L2_TUNER_RADIO; | ||
194 | |||
195 | v->rangelow=(87*16000); | ||
196 | v->rangehigh=(108*16000); | ||
197 | v->rxsubchans =V4L2_TUNER_SUB_MONO; | ||
198 | v->capability=V4L2_TUNER_CAP_LOW; | ||
199 | v->audmode = V4L2_TUNER_MODE_MONO; | ||
200 | v->signal=0xFFFF*gemtek_getsigstr(rt); | ||
201 | |||
171 | return 0; | 202 | return 0; |
172 | } | 203 | } |
173 | case VIDIOCSTUNER: | 204 | case VIDIOC_S_TUNER: |
174 | { | 205 | { |
175 | struct video_tuner *v = arg; | 206 | struct v4l2_tuner *v = arg; |
176 | if(v->tuner!=0) | 207 | |
208 | if (v->index > 0) | ||
177 | return -EINVAL; | 209 | return -EINVAL; |
178 | /* Only 1 tuner so no setting needed ! */ | 210 | |
179 | return 0; | ||
180 | } | ||
181 | case VIDIOCGFREQ: | ||
182 | { | ||
183 | unsigned long *freq = arg; | ||
184 | *freq = rt->curfreq; | ||
185 | return 0; | 211 | return 0; |
186 | } | 212 | } |
187 | case VIDIOCSFREQ: | 213 | case VIDIOC_S_FREQUENCY: |
188 | { | 214 | { |
189 | unsigned long *freq = arg; | 215 | struct v4l2_frequency *f = arg; |
190 | rt->curfreq = *freq; | 216 | |
217 | rt->curfreq = f->frequency; | ||
191 | /* needs to be called twice in order for getsigstr to work */ | 218 | /* needs to be called twice in order for getsigstr to work */ |
192 | gemtek_setfreq(rt, rt->curfreq); | 219 | gemtek_setfreq(rt, rt->curfreq); |
193 | gemtek_setfreq(rt, rt->curfreq); | 220 | gemtek_setfreq(rt, rt->curfreq); |
194 | return 0; | 221 | return 0; |
195 | } | 222 | } |
196 | case VIDIOCGAUDIO: | 223 | case VIDIOC_G_FREQUENCY: |
197 | { | ||
198 | struct video_audio *v = arg; | ||
199 | memset(v,0, sizeof(*v)); | ||
200 | v->flags|=VIDEO_AUDIO_MUTABLE; | ||
201 | v->volume=1; | ||
202 | v->step=65535; | ||
203 | strcpy(v->name, "Radio"); | ||
204 | return 0; | ||
205 | } | ||
206 | case VIDIOCSAUDIO: | ||
207 | { | 224 | { |
208 | struct video_audio *v = arg; | 225 | struct v4l2_frequency *f = arg; |
209 | if(v->audio) | ||
210 | return -EINVAL; | ||
211 | 226 | ||
212 | if(v->flags&VIDEO_AUDIO_MUTE) | 227 | f->type = V4L2_TUNER_RADIO; |
213 | gemtek_mute(rt); | 228 | f->frequency = rt->curfreq; |
214 | else | ||
215 | gemtek_unmute(rt); | ||
216 | 229 | ||
217 | return 0; | 230 | return 0; |
218 | } | 231 | } |
232 | case VIDIOC_QUERYCTRL: | ||
233 | { | ||
234 | struct v4l2_queryctrl *qc = arg; | ||
235 | int i; | ||
236 | |||
237 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | ||
238 | if (qc->id && qc->id == radio_qctrl[i].id) { | ||
239 | memcpy(qc, &(radio_qctrl[i]), | ||
240 | sizeof(*qc)); | ||
241 | return (0); | ||
242 | } | ||
243 | } | ||
244 | return -EINVAL; | ||
245 | } | ||
246 | case VIDIOC_G_CTRL: | ||
247 | { | ||
248 | struct v4l2_control *ctrl= arg; | ||
249 | |||
250 | switch (ctrl->id) { | ||
251 | case V4L2_CID_AUDIO_MUTE: | ||
252 | ctrl->value=rt->muted; | ||
253 | return (0); | ||
254 | case V4L2_CID_AUDIO_VOLUME: | ||
255 | if (rt->muted) | ||
256 | ctrl->value=0; | ||
257 | else | ||
258 | ctrl->value=65535; | ||
259 | return (0); | ||
260 | } | ||
261 | return -EINVAL; | ||
262 | } | ||
263 | case VIDIOC_S_CTRL: | ||
264 | { | ||
265 | struct v4l2_control *ctrl= arg; | ||
266 | |||
267 | switch (ctrl->id) { | ||
268 | case V4L2_CID_AUDIO_MUTE: | ||
269 | if (ctrl->value) { | ||
270 | gemtek_mute(rt); | ||
271 | } else { | ||
272 | gemtek_unmute(rt); | ||
273 | } | ||
274 | return (0); | ||
275 | case V4L2_CID_AUDIO_VOLUME: | ||
276 | if (ctrl->value) { | ||
277 | gemtek_unmute(rt); | ||
278 | } else { | ||
279 | gemtek_mute(rt); | ||
280 | } | ||
281 | return (0); | ||
282 | } | ||
283 | return -EINVAL; | ||
284 | } | ||
219 | default: | 285 | default: |
220 | return -ENOIOCTLCMD; | 286 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, |
287 | gemtek_do_ioctl); | ||
221 | } | 288 | } |
222 | } | 289 | } |
223 | 290 | ||
@@ -243,7 +310,7 @@ static struct video_device gemtek_radio= | |||
243 | .owner = THIS_MODULE, | 310 | .owner = THIS_MODULE, |
244 | .name = "GemTek radio", | 311 | .name = "GemTek radio", |
245 | .type = VID_TYPE_TUNER, | 312 | .type = VID_TYPE_TUNER, |
246 | .hardware = VID_HARDWARE_GEMTEK, | 313 | .hardware = 0, |
247 | .fops = &gemtek_fops, | 314 | .fops = &gemtek_fops, |
248 | }; | 315 | }; |
249 | 316 | ||