diff options
| -rw-r--r-- | drivers/media/radio/radio-gemtek.c | 260 |
1 files changed, 146 insertions, 114 deletions
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 36c4be6622c7..b04b6a7fff7c 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c | |||
| @@ -161,137 +161,157 @@ static int gemtek_getsigstr(struct gemtek_device *dev) | |||
| 161 | return 1; /* signal present */ | 161 | return 1; /* signal present */ |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | static int gemtek_do_ioctl(struct inode *inode, struct file *file, | 164 | static int vidioc_querycap(struct file *file, void *priv, |
| 165 | unsigned int cmd, void *arg) | 165 | struct v4l2_capability *v) |
| 166 | { | ||
| 167 | strlcpy(v->driver, "radio-gemtek", sizeof(v->driver)); | ||
| 168 | strlcpy(v->card, "GemTek", sizeof(v->card)); | ||
| 169 | sprintf(v->bus_info, "ISA"); | ||
| 170 | v->version = RADIO_VERSION; | ||
| 171 | v->capabilities = V4L2_CAP_TUNER; | ||
| 172 | return 0; | ||
| 173 | } | ||
| 174 | |||
| 175 | static int vidioc_g_tuner(struct file *file, void *priv, | ||
| 176 | struct v4l2_tuner *v) | ||
| 166 | { | 177 | { |
| 167 | struct video_device *dev = video_devdata(file); | 178 | struct video_device *dev = video_devdata(file); |
| 168 | struct gemtek_device *rt=dev->priv; | 179 | struct gemtek_device *rt = dev->priv; |
| 169 | 180 | ||
| 170 | switch(cmd) | 181 | if (v->index > 0) |
| 171 | { | 182 | return -EINVAL; |
| 172 | case VIDIOC_QUERYCAP: | ||
| 173 | { | ||
| 174 | struct v4l2_capability *v = arg; | ||
| 175 | memset(v,0,sizeof(*v)); | ||
| 176 | strlcpy(v->driver, "radio-gemtek", sizeof (v->driver)); | ||
| 177 | strlcpy(v->card, "GemTek", sizeof (v->card)); | ||
| 178 | sprintf(v->bus_info,"ISA"); | ||
| 179 | v->version = RADIO_VERSION; | ||
| 180 | v->capabilities = V4L2_CAP_TUNER; | ||
| 181 | 183 | ||
| 182 | return 0; | 184 | strcpy(v->name, "FM"); |
| 183 | } | 185 | v->type = V4L2_TUNER_RADIO; |
| 184 | case VIDIOC_G_TUNER: | 186 | v->rangelow = (87*16000); |
| 185 | { | 187 | v->rangehigh = (108*16000); |
| 186 | struct v4l2_tuner *v = arg; | 188 | v->rxsubchans = V4L2_TUNER_SUB_MONO; |
| 189 | v->capability = V4L2_TUNER_CAP_LOW; | ||
| 190 | v->audmode = V4L2_TUNER_MODE_MONO; | ||
| 191 | v->signal = 0xffff*gemtek_getsigstr(rt); | ||
| 192 | return 0; | ||
| 193 | } | ||
| 194 | |||
| 195 | static int vidioc_s_tuner(struct file *file, void *priv, | ||
| 196 | struct v4l2_tuner *v) | ||
| 197 | { | ||
| 198 | if (v->index > 0) | ||
| 199 | return -EINVAL; | ||
| 200 | return 0; | ||
| 201 | } | ||
| 187 | 202 | ||
| 188 | if (v->index > 0) | 203 | static int vidioc_s_frequency(struct file *file, void *priv, |
| 189 | return -EINVAL; | 204 | struct v4l2_frequency *f) |
| 205 | { | ||
| 206 | struct video_device *dev = video_devdata(file); | ||
| 207 | struct gemtek_device *rt = dev->priv; | ||
| 190 | 208 | ||
| 191 | memset(v,0,sizeof(*v)); | 209 | rt->curfreq = f->frequency; |
| 192 | strcpy(v->name, "FM"); | 210 | /* needs to be called twice in order for getsigstr to work */ |
| 193 | v->type = V4L2_TUNER_RADIO; | 211 | gemtek_setfreq(rt, rt->curfreq); |
| 212 | gemtek_setfreq(rt, rt->curfreq); | ||
| 213 | return 0; | ||
| 214 | } | ||
| 194 | 215 | ||
| 195 | v->rangelow=(87*16000); | 216 | static int vidioc_g_frequency(struct file *file, void *priv, |
| 196 | v->rangehigh=(108*16000); | 217 | struct v4l2_frequency *f) |
| 197 | v->rxsubchans =V4L2_TUNER_SUB_MONO; | 218 | { |
| 198 | v->capability=V4L2_TUNER_CAP_LOW; | 219 | struct video_device *dev = video_devdata(file); |
| 199 | v->audmode = V4L2_TUNER_MODE_MONO; | 220 | struct gemtek_device *rt = dev->priv; |
| 200 | v->signal=0xFFFF*gemtek_getsigstr(rt); | ||
| 201 | 221 | ||
| 202 | return 0; | 222 | f->type = V4L2_TUNER_RADIO; |
| 203 | } | 223 | f->frequency = rt->curfreq; |
| 204 | case VIDIOC_S_TUNER: | 224 | return 0; |
| 205 | { | 225 | } |
| 206 | struct v4l2_tuner *v = arg; | ||
| 207 | 226 | ||
| 208 | if (v->index > 0) | 227 | static int vidioc_queryctrl(struct file *file, void *priv, |
| 209 | return -EINVAL; | 228 | struct v4l2_queryctrl *qc) |
| 229 | { | ||
| 230 | int i; | ||
| 210 | 231 | ||
| 232 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | ||
| 233 | if (qc->id && qc->id == radio_qctrl[i].id) { | ||
| 234 | memcpy(qc, &(radio_qctrl[i]), | ||
| 235 | sizeof(*qc)); | ||
| 211 | return 0; | 236 | return 0; |
| 212 | } | 237 | } |
| 213 | case VIDIOC_S_FREQUENCY: | 238 | } |
| 214 | { | 239 | return -EINVAL; |
| 215 | struct v4l2_frequency *f = arg; | 240 | } |
| 216 | |||
| 217 | rt->curfreq = f->frequency; | ||
| 218 | /* needs to be called twice in order for getsigstr to work */ | ||
| 219 | gemtek_setfreq(rt, rt->curfreq); | ||
| 220 | gemtek_setfreq(rt, rt->curfreq); | ||
| 221 | return 0; | ||
| 222 | } | ||
| 223 | case VIDIOC_G_FREQUENCY: | ||
| 224 | { | ||
| 225 | struct v4l2_frequency *f = arg; | ||
| 226 | 241 | ||
| 227 | f->type = V4L2_TUNER_RADIO; | 242 | static int vidioc_g_ctrl(struct file *file, void *priv, |
| 228 | f->frequency = rt->curfreq; | 243 | struct v4l2_control *ctrl) |
| 244 | { | ||
| 245 | struct video_device *dev = video_devdata(file); | ||
| 246 | struct gemtek_device *rt = dev->priv; | ||
| 229 | 247 | ||
| 230 | return 0; | 248 | switch (ctrl->id) { |
| 231 | } | 249 | case V4L2_CID_AUDIO_MUTE: |
| 232 | case VIDIOC_QUERYCTRL: | 250 | ctrl->value = rt->muted; |
| 233 | { | 251 | return 0; |
| 234 | struct v4l2_queryctrl *qc = arg; | 252 | case V4L2_CID_AUDIO_VOLUME: |
| 235 | int i; | 253 | if (rt->muted) |
| 236 | 254 | ctrl->value = 0; | |
| 237 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | 255 | else |
| 238 | if (qc->id && qc->id == radio_qctrl[i].id) { | 256 | ctrl->value = 65535; |
| 239 | memcpy(qc, &(radio_qctrl[i]), | 257 | return 0; |
| 240 | sizeof(*qc)); | 258 | } |
| 241 | return (0); | 259 | return -EINVAL; |
| 242 | } | 260 | } |
| 243 | } | 261 | |
| 244 | return -EINVAL; | 262 | static int vidioc_s_ctrl(struct file *file, void *priv, |
| 245 | } | 263 | struct v4l2_control *ctrl) |
| 246 | case VIDIOC_G_CTRL: | 264 | { |
| 247 | { | 265 | struct video_device *dev = video_devdata(file); |
| 248 | struct v4l2_control *ctrl= arg; | 266 | struct gemtek_device *rt = dev->priv; |
| 249 | 267 | ||
| 250 | switch (ctrl->id) { | 268 | switch (ctrl->id) { |
| 251 | case V4L2_CID_AUDIO_MUTE: | 269 | case V4L2_CID_AUDIO_MUTE: |
| 252 | ctrl->value=rt->muted; | 270 | if (ctrl->value) |
| 253 | return (0); | 271 | gemtek_mute(rt); |
| 254 | case V4L2_CID_AUDIO_VOLUME: | 272 | else |
| 255 | if (rt->muted) | 273 | gemtek_unmute(rt); |
| 256 | ctrl->value=0; | 274 | return 0; |
| 257 | else | 275 | case V4L2_CID_AUDIO_VOLUME: |
| 258 | ctrl->value=65535; | 276 | if (ctrl->value) |
| 259 | return (0); | 277 | gemtek_unmute(rt); |
| 260 | } | 278 | else |
| 261 | return -EINVAL; | 279 | gemtek_mute(rt); |
| 262 | } | 280 | return 0; |
| 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 | } | ||
| 285 | default: | ||
| 286 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | ||
| 287 | gemtek_do_ioctl); | ||
| 288 | } | 281 | } |
| 282 | return -EINVAL; | ||
| 289 | } | 283 | } |
| 290 | 284 | ||
| 291 | static int gemtek_ioctl(struct inode *inode, struct file *file, | 285 | static int vidioc_g_audio (struct file *file, void *priv, |
| 292 | unsigned int cmd, unsigned long arg) | 286 | struct v4l2_audio *a) |
| 293 | { | 287 | { |
| 294 | return video_usercopy(inode, file, cmd, arg, gemtek_do_ioctl); | 288 | if (a->index > 1) |
| 289 | return -EINVAL; | ||
| 290 | |||
| 291 | strcpy(a->name, "Radio"); | ||
| 292 | a->capability = V4L2_AUDCAP_STEREO; | ||
| 293 | return 0; | ||
| 294 | } | ||
| 295 | |||
| 296 | static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) | ||
| 297 | { | ||
| 298 | *i = 0; | ||
| 299 | return 0; | ||
| 300 | } | ||
| 301 | |||
| 302 | static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) | ||
| 303 | { | ||
| 304 | if (i != 0) | ||
| 305 | return -EINVAL; | ||
| 306 | return 0; | ||
| 307 | } | ||
| 308 | |||
| 309 | static int vidioc_s_audio(struct file *file, void *priv, | ||
| 310 | struct v4l2_audio *a) | ||
| 311 | { | ||
| 312 | if (a->index != 0) | ||
| 313 | return -EINVAL; | ||
| 314 | return 0; | ||
| 295 | } | 315 | } |
| 296 | 316 | ||
| 297 | static struct gemtek_device gemtek_unit; | 317 | static struct gemtek_device gemtek_unit; |
| @@ -300,7 +320,7 @@ static const struct file_operations gemtek_fops = { | |||
| 300 | .owner = THIS_MODULE, | 320 | .owner = THIS_MODULE, |
| 301 | .open = video_exclusive_open, | 321 | .open = video_exclusive_open, |
| 302 | .release = video_exclusive_release, | 322 | .release = video_exclusive_release, |
| 303 | .ioctl = gemtek_ioctl, | 323 | .ioctl = video_ioctl2, |
| 304 | .compat_ioctl = v4l_compat_ioctl32, | 324 | .compat_ioctl = v4l_compat_ioctl32, |
| 305 | .llseek = no_llseek, | 325 | .llseek = no_llseek, |
| 306 | }; | 326 | }; |
| @@ -312,6 +332,18 @@ static struct video_device gemtek_radio= | |||
| 312 | .type = VID_TYPE_TUNER, | 332 | .type = VID_TYPE_TUNER, |
| 313 | .hardware = 0, | 333 | .hardware = 0, |
| 314 | .fops = &gemtek_fops, | 334 | .fops = &gemtek_fops, |
| 335 | .vidioc_querycap = vidioc_querycap, | ||
| 336 | .vidioc_g_tuner = vidioc_g_tuner, | ||
| 337 | .vidioc_s_tuner = vidioc_s_tuner, | ||
| 338 | .vidioc_g_audio = vidioc_g_audio, | ||
| 339 | .vidioc_s_audio = vidioc_s_audio, | ||
| 340 | .vidioc_g_input = vidioc_g_input, | ||
| 341 | .vidioc_s_input = vidioc_s_input, | ||
| 342 | .vidioc_g_frequency = vidioc_g_frequency, | ||
| 343 | .vidioc_s_frequency = vidioc_s_frequency, | ||
| 344 | .vidioc_queryctrl = vidioc_queryctrl, | ||
| 345 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
| 346 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
| 315 | }; | 347 | }; |
| 316 | 348 | ||
| 317 | static int __init gemtek_init(void) | 349 | static int __init gemtek_init(void) |
