diff options
Diffstat (limited to 'drivers/media/radio/radio-trust.c')
| -rw-r--r-- | drivers/media/radio/radio-trust.c | 256 |
1 files changed, 139 insertions, 117 deletions
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index 6d7f1e7116ea..c27c629d99df 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c | |||
| @@ -192,144 +192,154 @@ static void tr_setfreq(unsigned long f) | |||
| 192 | write_i2c(5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0); | 192 | write_i2c(5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0); |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | static int tr_do_ioctl(struct inode *inode, struct file *file, | 195 | static int vidioc_querycap(struct file *file, void *priv, |
| 196 | unsigned int cmd, void *arg) | 196 | struct v4l2_capability *v) |
| 197 | { | 197 | { |
| 198 | switch(cmd) | 198 | strlcpy(v->driver, "radio-trust", sizeof(v->driver)); |
| 199 | { | 199 | strlcpy(v->card, "Trust FM Radio", sizeof(v->card)); |
| 200 | case VIDIOC_QUERYCAP: | 200 | sprintf(v->bus_info, "ISA"); |
| 201 | { | 201 | v->version = RADIO_VERSION; |
| 202 | struct v4l2_capability *v = arg; | 202 | v->capabilities = V4L2_CAP_TUNER; |
| 203 | memset(v,0,sizeof(*v)); | 203 | return 0; |
| 204 | strlcpy(v->driver, "radio-trust", sizeof (v->driver)); | 204 | } |
| 205 | strlcpy(v->card, "Trust FM Radio", sizeof (v->card)); | ||
| 206 | sprintf(v->bus_info,"ISA"); | ||
| 207 | v->version = RADIO_VERSION; | ||
| 208 | v->capabilities = V4L2_CAP_TUNER; | ||
| 209 | 205 | ||
| 210 | return 0; | 206 | static int vidioc_g_tuner(struct file *file, void *priv, |
| 211 | } | 207 | struct v4l2_tuner *v) |
| 212 | case VIDIOC_G_TUNER: | 208 | { |
| 213 | { | 209 | if (v->index > 0) |
| 214 | struct v4l2_tuner *v = arg; | 210 | return -EINVAL; |
| 215 | |||
| 216 | if (v->index > 0) | ||
| 217 | return -EINVAL; | ||
| 218 | |||
| 219 | memset(v,0,sizeof(*v)); | ||
| 220 | strcpy(v->name, "FM"); | ||
| 221 | v->type = V4L2_TUNER_RADIO; | ||
| 222 | |||
| 223 | v->rangelow=(87.5*16000); | ||
| 224 | v->rangehigh=(108*16000); | ||
| 225 | v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; | ||
| 226 | v->capability=V4L2_TUNER_CAP_LOW; | ||
| 227 | if(tr_getstereo()) | ||
| 228 | v->audmode = V4L2_TUNER_MODE_STEREO; | ||
| 229 | else | ||
| 230 | v->audmode = V4L2_TUNER_MODE_MONO; | ||
| 231 | v->signal=tr_getsigstr(); | ||
| 232 | 211 | ||
| 233 | return 0; | 212 | strcpy(v->name, "FM"); |
| 234 | } | 213 | v->type = V4L2_TUNER_RADIO; |
| 235 | case VIDIOC_S_TUNER: | 214 | v->rangelow = (87.5*16000); |
| 236 | { | 215 | v->rangehigh = (108*16000); |
| 237 | struct v4l2_tuner *v = arg; | 216 | v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; |
| 217 | v->capability = V4L2_TUNER_CAP_LOW; | ||
| 218 | if (tr_getstereo()) | ||
| 219 | v->audmode = V4L2_TUNER_MODE_STEREO; | ||
| 220 | else | ||
| 221 | v->audmode = V4L2_TUNER_MODE_MONO; | ||
| 222 | v->signal = tr_getsigstr(); | ||
| 223 | return 0; | ||
| 224 | } | ||
| 225 | |||
| 226 | static int vidioc_s_tuner(struct file *file, void *priv, | ||
| 227 | struct v4l2_tuner *v) | ||
| 228 | { | ||
| 229 | if (v->index > 0) | ||
| 230 | return -EINVAL; | ||
| 238 | 231 | ||
| 239 | if (v->index > 0) | 232 | return 0; |
| 240 | return -EINVAL; | 233 | } |
| 241 | 234 | ||
| 242 | return 0; | 235 | static int vidioc_s_frequency(struct file *file, void *priv, |
| 243 | } | 236 | struct v4l2_frequency *f) |
| 244 | case VIDIOC_S_FREQUENCY: | 237 | { |
| 245 | { | 238 | curfreq = f->frequency; |
| 246 | struct v4l2_frequency *f = arg; | 239 | tr_setfreq(curfreq); |
| 240 | return 0; | ||
| 241 | } | ||
| 247 | 242 | ||
| 248 | curfreq = f->frequency; | 243 | static int vidioc_g_frequency(struct file *file, void *priv, |
| 249 | tr_setfreq(curfreq); | 244 | struct v4l2_frequency *f) |
| 250 | return 0; | 245 | { |
| 251 | } | 246 | f->type = V4L2_TUNER_RADIO; |
| 252 | case VIDIOC_G_FREQUENCY: | 247 | f->frequency = curfreq; |
| 253 | { | 248 | return 0; |
| 254 | struct v4l2_frequency *f = arg; | 249 | } |
| 255 | 250 | ||
| 256 | f->type = V4L2_TUNER_RADIO; | 251 | static int vidioc_queryctrl(struct file *file, void *priv, |
| 257 | f->frequency = curfreq; | 252 | struct v4l2_queryctrl *qc) |
| 253 | { | ||
| 254 | int i; | ||
| 258 | 255 | ||
| 256 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | ||
| 257 | if (qc->id && qc->id == radio_qctrl[i].id) { | ||
| 258 | memcpy(qc, &(radio_qctrl[i]), | ||
| 259 | sizeof(*qc)); | ||
| 259 | return 0; | 260 | return 0; |
| 260 | } | 261 | } |
| 261 | case VIDIOC_QUERYCTRL: | 262 | } |
| 262 | { | 263 | return -EINVAL; |
| 263 | struct v4l2_queryctrl *qc = arg; | 264 | } |
| 264 | int i; | 265 | |
| 265 | 266 | static int vidioc_g_ctrl(struct file *file, void *priv, | |
| 266 | for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { | 267 | struct v4l2_control *ctrl) |
| 267 | if (qc->id && qc->id == radio_qctrl[i].id) { | 268 | { |
| 268 | memcpy(qc, &(radio_qctrl[i]), | 269 | switch (ctrl->id) { |
| 269 | sizeof(*qc)); | 270 | case V4L2_CID_AUDIO_MUTE: |
| 270 | return (0); | 271 | ctrl->value = curmute; |
| 271 | } | 272 | return 0; |
| 272 | } | 273 | case V4L2_CID_AUDIO_VOLUME: |
| 273 | return -EINVAL; | 274 | ctrl->value = curvol * 2048; |
| 274 | } | 275 | return 0; |
| 275 | case VIDIOC_G_CTRL: | 276 | case V4L2_CID_AUDIO_BASS: |
| 276 | { | 277 | ctrl->value = curbass * 4370; |
| 277 | struct v4l2_control *ctrl= arg; | 278 | return 0; |
| 278 | 279 | case V4L2_CID_AUDIO_TREBLE: | |
| 279 | switch (ctrl->id) { | 280 | ctrl->value = curtreble * 4370; |
| 280 | case V4L2_CID_AUDIO_MUTE: | 281 | return 0; |
| 281 | ctrl->value=curmute; | 282 | } |
| 282 | return (0); | 283 | return -EINVAL; |
| 283 | case V4L2_CID_AUDIO_VOLUME: | 284 | } |
| 284 | ctrl->value= curvol * 2048; | ||
| 285 | return (0); | ||
| 286 | case V4L2_CID_AUDIO_BASS: | ||
| 287 | ctrl->value= curbass * 4370; | ||
| 288 | return (0); | ||
| 289 | case V4L2_CID_AUDIO_TREBLE: | ||
| 290 | ctrl->value= curtreble * 4370; | ||
| 291 | return (0); | ||
| 292 | } | ||
| 293 | return -EINVAL; | ||
| 294 | } | ||
| 295 | case VIDIOC_S_CTRL: | ||
| 296 | { | ||
| 297 | struct v4l2_control *ctrl= arg; | ||
| 298 | |||
| 299 | switch (ctrl->id) { | ||
| 300 | case V4L2_CID_AUDIO_MUTE: | ||
| 301 | tr_setmute(ctrl->value); | ||
| 302 | return 0; | ||
| 303 | case V4L2_CID_AUDIO_VOLUME: | ||
| 304 | tr_setvol(ctrl->value); | ||
| 305 | return 0; | ||
| 306 | case V4L2_CID_AUDIO_BASS: | ||
| 307 | tr_setbass(ctrl->value); | ||
| 308 | return 0; | ||
| 309 | case V4L2_CID_AUDIO_TREBLE: | ||
| 310 | tr_settreble(ctrl->value); | ||
| 311 | return (0); | ||
| 312 | } | ||
| 313 | return -EINVAL; | ||
| 314 | } | ||
| 315 | 285 | ||
| 316 | default: | 286 | static int vidioc_s_ctrl(struct file *file, void *priv, |
| 317 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | 287 | struct v4l2_control *ctrl) |
| 318 | tr_do_ioctl); | 288 | { |
| 289 | switch (ctrl->id) { | ||
| 290 | case V4L2_CID_AUDIO_MUTE: | ||
| 291 | tr_setmute(ctrl->value); | ||
| 292 | return 0; | ||
| 293 | case V4L2_CID_AUDIO_VOLUME: | ||
| 294 | tr_setvol(ctrl->value); | ||
| 295 | return 0; | ||
| 296 | case V4L2_CID_AUDIO_BASS: | ||
| 297 | tr_setbass(ctrl->value); | ||
| 298 | return 0; | ||
| 299 | case V4L2_CID_AUDIO_TREBLE: | ||
| 300 | tr_settreble(ctrl->value); | ||
| 301 | return 0; | ||
| 319 | } | 302 | } |
| 303 | return -EINVAL; | ||
| 320 | } | 304 | } |
| 321 | 305 | ||
| 322 | static int tr_ioctl(struct inode *inode, struct file *file, | 306 | static int vidioc_g_audio(struct file *file, void *priv, |
| 323 | unsigned int cmd, unsigned long arg) | 307 | struct v4l2_audio *a) |
| 324 | { | 308 | { |
| 325 | return video_usercopy(inode, file, cmd, arg, tr_do_ioctl); | 309 | if (a->index > 1) |
| 310 | return -EINVAL; | ||
| 311 | |||
| 312 | strcpy(a->name, "Radio"); | ||
| 313 | a->capability = V4L2_AUDCAP_STEREO; | ||
| 314 | return 0; | ||
| 315 | } | ||
| 316 | |||
| 317 | static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) | ||
| 318 | { | ||
| 319 | *i = 0; | ||
| 320 | return 0; | ||
| 321 | } | ||
| 322 | |||
| 323 | static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) | ||
| 324 | { | ||
| 325 | if (i != 0) | ||
| 326 | return -EINVAL; | ||
| 327 | return 0; | ||
| 328 | } | ||
| 329 | |||
| 330 | static int vidioc_s_audio(struct file *file, void *priv, | ||
| 331 | struct v4l2_audio *a) | ||
| 332 | { | ||
| 333 | if (a->index != 0) | ||
| 334 | return -EINVAL; | ||
| 335 | return 0; | ||
| 326 | } | 336 | } |
| 327 | 337 | ||
| 328 | static const struct file_operations trust_fops = { | 338 | static const struct file_operations trust_fops = { |
| 329 | .owner = THIS_MODULE, | 339 | .owner = THIS_MODULE, |
| 330 | .open = video_exclusive_open, | 340 | .open = video_exclusive_open, |
| 331 | .release = video_exclusive_release, | 341 | .release = video_exclusive_release, |
| 332 | .ioctl = tr_ioctl, | 342 | .ioctl = video_ioctl2, |
| 333 | .compat_ioctl = v4l_compat_ioctl32, | 343 | .compat_ioctl = v4l_compat_ioctl32, |
| 334 | .llseek = no_llseek, | 344 | .llseek = no_llseek, |
| 335 | }; | 345 | }; |
| @@ -341,6 +351,18 @@ static struct video_device trust_radio= | |||
| 341 | .type = VID_TYPE_TUNER, | 351 | .type = VID_TYPE_TUNER, |
| 342 | .hardware = 0, | 352 | .hardware = 0, |
| 343 | .fops = &trust_fops, | 353 | .fops = &trust_fops, |
| 354 | .vidioc_querycap = vidioc_querycap, | ||
| 355 | .vidioc_g_tuner = vidioc_g_tuner, | ||
| 356 | .vidioc_s_tuner = vidioc_s_tuner, | ||
| 357 | .vidioc_g_frequency = vidioc_g_frequency, | ||
| 358 | .vidioc_s_frequency = vidioc_s_frequency, | ||
| 359 | .vidioc_queryctrl = vidioc_queryctrl, | ||
| 360 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
| 361 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
| 362 | .vidioc_g_audio = vidioc_g_audio, | ||
| 363 | .vidioc_s_audio = vidioc_s_audio, | ||
| 364 | .vidioc_g_input = vidioc_g_input, | ||
| 365 | .vidioc_s_input = vidioc_s_input, | ||
| 344 | }; | 366 | }; |
| 345 | 367 | ||
| 346 | static int __init trust_init(void) | 368 | static int __init trust_init(void) |
