diff options
Diffstat (limited to 'drivers/media/video/cx88/cx88-video.c')
-rw-r--r-- | drivers/media/video/cx88/cx88-video.c | 388 |
1 files changed, 218 insertions, 170 deletions
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 5f58c103198a..61d4b29ec302 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: cx88-video.c,v 1.82 2005/07/22 05:13:34 mkrufky Exp $ | ||
3 | * | 2 | * |
4 | * device driver for Conexant 2388x based TV cards | 3 | * device driver for Conexant 2388x based TV cards |
5 | * video4linux video interface | 4 | * video4linux video interface |
@@ -66,7 +65,7 @@ module_param(vid_limit,int,0644); | |||
66 | MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); | 65 | MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); |
67 | 66 | ||
68 | #define dprintk(level,fmt, arg...) if (video_debug >= level) \ | 67 | #define dprintk(level,fmt, arg...) if (video_debug >= level) \ |
69 | printk(KERN_DEBUG "%s/0: " fmt, dev->core->name , ## arg) | 68 | printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) |
70 | 69 | ||
71 | /* ------------------------------------------------------------------ */ | 70 | /* ------------------------------------------------------------------ */ |
72 | 71 | ||
@@ -326,22 +325,23 @@ static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls); | |||
326 | 325 | ||
327 | static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bit) | 326 | static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bit) |
328 | { | 327 | { |
328 | struct cx88_core *core = dev->core; | ||
329 | if (fh->resources & bit) | 329 | if (fh->resources & bit) |
330 | /* have it already allocated */ | 330 | /* have it already allocated */ |
331 | return 1; | 331 | return 1; |
332 | 332 | ||
333 | /* is it free? */ | 333 | /* is it free? */ |
334 | down(&dev->lock); | 334 | down(&core->lock); |
335 | if (dev->resources & bit) { | 335 | if (dev->resources & bit) { |
336 | /* no, someone else uses it */ | 336 | /* no, someone else uses it */ |
337 | up(&dev->lock); | 337 | up(&core->lock); |
338 | return 0; | 338 | return 0; |
339 | } | 339 | } |
340 | /* it's free, grab it */ | 340 | /* it's free, grab it */ |
341 | fh->resources |= bit; | 341 | fh->resources |= bit; |
342 | dev->resources |= bit; | 342 | dev->resources |= bit; |
343 | dprintk(1,"res: get %d\n",bit); | 343 | dprintk(1,"res: get %d\n",bit); |
344 | up(&dev->lock); | 344 | up(&core->lock); |
345 | return 1; | 345 | return 1; |
346 | } | 346 | } |
347 | 347 | ||
@@ -360,27 +360,29 @@ int res_locked(struct cx8800_dev *dev, unsigned int bit) | |||
360 | static | 360 | static |
361 | void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits) | 361 | void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits) |
362 | { | 362 | { |
363 | struct cx88_core *core = dev->core; | ||
363 | if ((fh->resources & bits) != bits) | 364 | if ((fh->resources & bits) != bits) |
364 | BUG(); | 365 | BUG(); |
365 | 366 | ||
366 | down(&dev->lock); | 367 | down(&core->lock); |
367 | fh->resources &= ~bits; | 368 | fh->resources &= ~bits; |
368 | dev->resources &= ~bits; | 369 | dev->resources &= ~bits; |
369 | dprintk(1,"res: put %d\n",bits); | 370 | dprintk(1,"res: put %d\n",bits); |
370 | up(&dev->lock); | 371 | up(&core->lock); |
371 | } | 372 | } |
372 | 373 | ||
373 | /* ------------------------------------------------------------------ */ | 374 | /* ------------------------------------------------------------------ */ |
374 | 375 | ||
375 | static int video_mux(struct cx8800_dev *dev, unsigned int input) | 376 | /* static int video_mux(struct cx8800_dev *dev, unsigned int input) */ |
377 | static int video_mux(struct cx88_core *core, unsigned int input) | ||
376 | { | 378 | { |
377 | struct cx88_core *core = dev->core; | 379 | /* struct cx88_core *core = dev->core; */ |
378 | 380 | ||
379 | dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n", | 381 | dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n", |
380 | input, INPUT(input)->vmux, | 382 | input, INPUT(input)->vmux, |
381 | INPUT(input)->gpio0,INPUT(input)->gpio1, | 383 | INPUT(input)->gpio0,INPUT(input)->gpio1, |
382 | INPUT(input)->gpio2,INPUT(input)->gpio3); | 384 | INPUT(input)->gpio2,INPUT(input)->gpio3); |
383 | dev->core->input = input; | 385 | core->input = input; |
384 | cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input)->vmux << 14); | 386 | cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input)->vmux << 14); |
385 | cx_write(MO_GP3_IO, INPUT(input)->gpio3); | 387 | cx_write(MO_GP3_IO, INPUT(input)->gpio3); |
386 | cx_write(MO_GP0_IO, INPUT(input)->gpio0); | 388 | cx_write(MO_GP0_IO, INPUT(input)->gpio0); |
@@ -413,9 +415,9 @@ static int start_video_dma(struct cx8800_dev *dev, | |||
413 | struct cx88_core *core = dev->core; | 415 | struct cx88_core *core = dev->core; |
414 | 416 | ||
415 | /* setup fifo + format */ | 417 | /* setup fifo + format */ |
416 | cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH21], | 418 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21], |
417 | buf->bpl, buf->risc.dma); | 419 | buf->bpl, buf->risc.dma); |
418 | cx88_set_scale(dev->core, buf->vb.width, buf->vb.height, buf->vb.field); | 420 | cx88_set_scale(core, buf->vb.width, buf->vb.height, buf->vb.field); |
419 | cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma); | 421 | cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma); |
420 | 422 | ||
421 | /* reset counter */ | 423 | /* reset counter */ |
@@ -424,6 +426,14 @@ static int start_video_dma(struct cx8800_dev *dev, | |||
424 | 426 | ||
425 | /* enable irqs */ | 427 | /* enable irqs */ |
426 | cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01); | 428 | cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01); |
429 | |||
430 | /* Enables corresponding bits at PCI_INT_STAT: | ||
431 | bits 0 to 4: video, audio, transport stream, VIP, Host | ||
432 | bit 7: timer | ||
433 | bits 8 and 9: DMA complete for: SRC, DST | ||
434 | bits 10 and 11: BERR signal asserted for RISC: RD, WR | ||
435 | bits 12 to 15: BERR signal asserted for: BRDG, SRC, DST, IPB | ||
436 | */ | ||
427 | cx_set(MO_VID_INTMSK, 0x0f0011); | 437 | cx_set(MO_VID_INTMSK, 0x0f0011); |
428 | 438 | ||
429 | /* enable capture */ | 439 | /* enable capture */ |
@@ -431,7 +441,7 @@ static int start_video_dma(struct cx8800_dev *dev, | |||
431 | 441 | ||
432 | /* start dma */ | 442 | /* start dma */ |
433 | cx_set(MO_DEV_CNTRL2, (1<<5)); | 443 | cx_set(MO_DEV_CNTRL2, (1<<5)); |
434 | cx_set(MO_VID_DMACNTRL, 0x11); | 444 | cx_set(MO_VID_DMACNTRL, 0x11); /* Planar Y and packed FIFO and RISC enable */ |
435 | 445 | ||
436 | return 0; | 446 | return 0; |
437 | } | 447 | } |
@@ -455,6 +465,7 @@ static int stop_video_dma(struct cx8800_dev *dev) | |||
455 | static int restart_video_queue(struct cx8800_dev *dev, | 465 | static int restart_video_queue(struct cx8800_dev *dev, |
456 | struct cx88_dmaqueue *q) | 466 | struct cx88_dmaqueue *q) |
457 | { | 467 | { |
468 | struct cx88_core *core = dev->core; | ||
458 | struct cx88_buffer *buf, *prev; | 469 | struct cx88_buffer *buf, *prev; |
459 | struct list_head *item; | 470 | struct list_head *item; |
460 | 471 | ||
@@ -524,12 +535,13 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | |||
524 | { | 535 | { |
525 | struct cx8800_fh *fh = q->priv_data; | 536 | struct cx8800_fh *fh = q->priv_data; |
526 | struct cx8800_dev *dev = fh->dev; | 537 | struct cx8800_dev *dev = fh->dev; |
538 | struct cx88_core *core = dev->core; | ||
527 | struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); | 539 | struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); |
528 | int rc, init_buffer = 0; | 540 | int rc, init_buffer = 0; |
529 | 541 | ||
530 | BUG_ON(NULL == fh->fmt); | 542 | BUG_ON(NULL == fh->fmt); |
531 | if (fh->width < 48 || fh->width > norm_maxw(dev->core->tvnorm) || | 543 | if (fh->width < 48 || fh->width > norm_maxw(core->tvnorm) || |
532 | fh->height < 32 || fh->height > norm_maxh(dev->core->tvnorm)) | 544 | fh->height < 32 || fh->height > norm_maxh(core->tvnorm)) |
533 | return -EINVAL; | 545 | return -EINVAL; |
534 | buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; | 546 | buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; |
535 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 547 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) |
@@ -609,6 +621,7 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | |||
609 | struct cx88_buffer *prev; | 621 | struct cx88_buffer *prev; |
610 | struct cx8800_fh *fh = vq->priv_data; | 622 | struct cx8800_fh *fh = vq->priv_data; |
611 | struct cx8800_dev *dev = fh->dev; | 623 | struct cx8800_dev *dev = fh->dev; |
624 | struct cx88_core *core = dev->core; | ||
612 | struct cx88_dmaqueue *q = &dev->vidq; | 625 | struct cx88_dmaqueue *q = &dev->vidq; |
613 | 626 | ||
614 | /* add jump to stopper */ | 627 | /* add jump to stopper */ |
@@ -701,6 +714,7 @@ static int video_open(struct inode *inode, struct file *file) | |||
701 | { | 714 | { |
702 | int minor = iminor(inode); | 715 | int minor = iminor(inode); |
703 | struct cx8800_dev *h,*dev = NULL; | 716 | struct cx8800_dev *h,*dev = NULL; |
717 | struct cx88_core *core; | ||
704 | struct cx8800_fh *fh; | 718 | struct cx8800_fh *fh; |
705 | struct list_head *list; | 719 | struct list_head *list; |
706 | enum v4l2_buf_type type = 0; | 720 | enum v4l2_buf_type type = 0; |
@@ -725,6 +739,8 @@ static int video_open(struct inode *inode, struct file *file) | |||
725 | if (NULL == dev) | 739 | if (NULL == dev) |
726 | return -ENODEV; | 740 | return -ENODEV; |
727 | 741 | ||
742 | core = dev->core; | ||
743 | |||
728 | dprintk(1,"open minor=%d radio=%d type=%s\n", | 744 | dprintk(1,"open minor=%d radio=%d type=%s\n", |
729 | minor,radio,v4l2_type_names[type]); | 745 | minor,radio,v4l2_type_names[type]); |
730 | 746 | ||
@@ -755,17 +771,16 @@ static int video_open(struct inode *inode, struct file *file) | |||
755 | fh); | 771 | fh); |
756 | 772 | ||
757 | if (fh->radio) { | 773 | if (fh->radio) { |
758 | struct cx88_core *core = dev->core; | ||
759 | int board = core->board; | 774 | int board = core->board; |
760 | dprintk(1,"video_open: setting radio device\n"); | 775 | dprintk(1,"video_open: setting radio device\n"); |
761 | cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3); | 776 | cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3); |
762 | cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0); | 777 | cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0); |
763 | cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1); | 778 | cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1); |
764 | cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2); | 779 | cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2); |
765 | dev->core->tvaudio = WW_FM; | 780 | core->tvaudio = WW_FM; |
766 | cx88_set_tvaudio(core); | 781 | cx88_set_tvaudio(core); |
767 | cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); | 782 | cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); |
768 | cx88_call_i2c_clients(dev->core,AUDC_SET_RADIO,NULL); | 783 | cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); |
769 | } | 784 | } |
770 | 785 | ||
771 | return 0; | 786 | return 0; |
@@ -857,6 +872,9 @@ static int video_release(struct inode *inode, struct file *file) | |||
857 | videobuf_mmap_free(&fh->vbiq); | 872 | videobuf_mmap_free(&fh->vbiq); |
858 | file->private_data = NULL; | 873 | file->private_data = NULL; |
859 | kfree(fh); | 874 | kfree(fh); |
875 | |||
876 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); | ||
877 | |||
860 | return 0; | 878 | return 0; |
861 | } | 879 | } |
862 | 880 | ||
@@ -870,9 +888,10 @@ video_mmap(struct file *file, struct vm_area_struct * vma) | |||
870 | 888 | ||
871 | /* ------------------------------------------------------------------ */ | 889 | /* ------------------------------------------------------------------ */ |
872 | 890 | ||
873 | static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) | 891 | /* static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) */ |
892 | static int get_control(struct cx88_core *core, struct v4l2_control *ctl) | ||
874 | { | 893 | { |
875 | struct cx88_core *core = dev->core; | 894 | /* struct cx88_core *core = dev->core; */ |
876 | struct cx88_ctrl *c = NULL; | 895 | struct cx88_ctrl *c = NULL; |
877 | u32 value; | 896 | u32 value; |
878 | int i; | 897 | int i; |
@@ -898,9 +917,10 @@ static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) | |||
898 | return 0; | 917 | return 0; |
899 | } | 918 | } |
900 | 919 | ||
901 | static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) | 920 | /* static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) */ |
921 | static int set_control(struct cx88_core *core, struct v4l2_control *ctl) | ||
902 | { | 922 | { |
903 | struct cx88_core *core = dev->core; | 923 | /* struct cx88_core *core = dev->core; */ |
904 | struct cx88_ctrl *c = NULL; | 924 | struct cx88_ctrl *c = NULL; |
905 | u32 v_sat_value; | 925 | u32 v_sat_value; |
906 | u32 value; | 926 | u32 value; |
@@ -913,9 +933,9 @@ static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) | |||
913 | return -EINVAL; | 933 | return -EINVAL; |
914 | 934 | ||
915 | if (ctl->value < c->v.minimum) | 935 | if (ctl->value < c->v.minimum) |
916 | return -ERANGE; | 936 | ctl->value = c->v.minimum; |
917 | if (ctl->value > c->v.maximum) | 937 | if (ctl->value > c->v.maximum) |
918 | return -ERANGE; | 938 | ctl->value = c->v.maximum; |
919 | switch (ctl->id) { | 939 | switch (ctl->id) { |
920 | case V4L2_CID_AUDIO_BALANCE: | 940 | case V4L2_CID_AUDIO_BALANCE: |
921 | value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; | 941 | value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; |
@@ -946,7 +966,8 @@ static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) | |||
946 | return 0; | 966 | return 0; |
947 | } | 967 | } |
948 | 968 | ||
949 | static void init_controls(struct cx8800_dev *dev) | 969 | /* static void init_controls(struct cx8800_dev *dev) */ |
970 | static void init_controls(struct cx88_core *core) | ||
950 | { | 971 | { |
951 | static struct v4l2_control mute = { | 972 | static struct v4l2_control mute = { |
952 | .id = V4L2_CID_AUDIO_MUTE, | 973 | .id = V4L2_CID_AUDIO_MUTE, |
@@ -969,11 +990,11 @@ static void init_controls(struct cx8800_dev *dev) | |||
969 | .value = 0x80, | 990 | .value = 0x80, |
970 | }; | 991 | }; |
971 | 992 | ||
972 | set_control(dev,&mute); | 993 | set_control(core,&mute); |
973 | set_control(dev,&volume); | 994 | set_control(core,&volume); |
974 | set_control(dev,&hue); | 995 | set_control(core,&hue); |
975 | set_control(dev,&contrast); | 996 | set_control(core,&contrast); |
976 | set_control(dev,&brightness); | 997 | set_control(core,&brightness); |
977 | } | 998 | } |
978 | 999 | ||
979 | /* ------------------------------------------------------------------ */ | 1000 | /* ------------------------------------------------------------------ */ |
@@ -1004,6 +1025,8 @@ static int cx8800_g_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh, | |||
1004 | static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh, | 1025 | static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh, |
1005 | struct v4l2_format *f) | 1026 | struct v4l2_format *f) |
1006 | { | 1027 | { |
1028 | struct cx88_core *core = dev->core; | ||
1029 | |||
1007 | switch (f->type) { | 1030 | switch (f->type) { |
1008 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1031 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1009 | { | 1032 | { |
@@ -1016,8 +1039,8 @@ static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh, | |||
1016 | return -EINVAL; | 1039 | return -EINVAL; |
1017 | 1040 | ||
1018 | field = f->fmt.pix.field; | 1041 | field = f->fmt.pix.field; |
1019 | maxw = norm_maxw(dev->core->tvnorm); | 1042 | maxw = norm_maxw(core->tvnorm); |
1020 | maxh = norm_maxh(dev->core->tvnorm); | 1043 | maxh = norm_maxh(core->tvnorm); |
1021 | 1044 | ||
1022 | if (V4L2_FIELD_ANY == field) { | 1045 | if (V4L2_FIELD_ANY == field) { |
1023 | field = (f->fmt.pix.height > maxh/2) | 1046 | field = (f->fmt.pix.height > maxh/2) |
@@ -1101,12 +1124,14 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1101 | if (video_debug > 1) | 1124 | if (video_debug > 1) |
1102 | cx88_print_ioctl(core->name,cmd); | 1125 | cx88_print_ioctl(core->name,cmd); |
1103 | switch (cmd) { | 1126 | switch (cmd) { |
1127 | |||
1128 | /* --- capabilities ------------------------------------------ */ | ||
1104 | case VIDIOC_QUERYCAP: | 1129 | case VIDIOC_QUERYCAP: |
1105 | { | 1130 | { |
1106 | struct v4l2_capability *cap = arg; | 1131 | struct v4l2_capability *cap = arg; |
1107 | 1132 | ||
1108 | memset(cap,0,sizeof(*cap)); | 1133 | memset(cap,0,sizeof(*cap)); |
1109 | strcpy(cap->driver, "cx8800"); | 1134 | strcpy(cap->driver, "cx8800"); |
1110 | strlcpy(cap->card, cx88_boards[core->board].name, | 1135 | strlcpy(cap->card, cx88_boards[core->board].name, |
1111 | sizeof(cap->card)); | 1136 | sizeof(cap->card)); |
1112 | sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); | 1137 | sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); |
@@ -1116,12 +1141,128 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1116 | V4L2_CAP_READWRITE | | 1141 | V4L2_CAP_READWRITE | |
1117 | V4L2_CAP_STREAMING | | 1142 | V4L2_CAP_STREAMING | |
1118 | V4L2_CAP_VBI_CAPTURE | | 1143 | V4L2_CAP_VBI_CAPTURE | |
1144 | V4L2_CAP_VIDEO_OVERLAY | | ||
1119 | 0; | 1145 | 0; |
1120 | if (UNSET != core->tuner_type) | 1146 | if (UNSET != core->tuner_type) |
1121 | cap->capabilities |= V4L2_CAP_TUNER; | 1147 | cap->capabilities |= V4L2_CAP_TUNER; |
1122 | return 0; | 1148 | return 0; |
1123 | } | 1149 | } |
1124 | 1150 | ||
1151 | /* --- capture ioctls ---------------------------------------- */ | ||
1152 | case VIDIOC_ENUM_FMT: | ||
1153 | { | ||
1154 | struct v4l2_fmtdesc *f = arg; | ||
1155 | enum v4l2_buf_type type; | ||
1156 | unsigned int index; | ||
1157 | |||
1158 | index = f->index; | ||
1159 | type = f->type; | ||
1160 | switch (type) { | ||
1161 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
1162 | if (index >= ARRAY_SIZE(formats)) | ||
1163 | return -EINVAL; | ||
1164 | memset(f,0,sizeof(*f)); | ||
1165 | f->index = index; | ||
1166 | f->type = type; | ||
1167 | strlcpy(f->description,formats[index].name,sizeof(f->description)); | ||
1168 | f->pixelformat = formats[index].fourcc; | ||
1169 | break; | ||
1170 | default: | ||
1171 | return -EINVAL; | ||
1172 | } | ||
1173 | return 0; | ||
1174 | } | ||
1175 | case VIDIOC_G_FMT: | ||
1176 | { | ||
1177 | struct v4l2_format *f = arg; | ||
1178 | return cx8800_g_fmt(dev,fh,f); | ||
1179 | } | ||
1180 | case VIDIOC_S_FMT: | ||
1181 | { | ||
1182 | struct v4l2_format *f = arg; | ||
1183 | return cx8800_s_fmt(dev,fh,f); | ||
1184 | } | ||
1185 | case VIDIOC_TRY_FMT: | ||
1186 | { | ||
1187 | struct v4l2_format *f = arg; | ||
1188 | return cx8800_try_fmt(dev,fh,f); | ||
1189 | } | ||
1190 | |||
1191 | /* --- streaming capture ------------------------------------- */ | ||
1192 | case VIDIOCGMBUF: | ||
1193 | { | ||
1194 | struct video_mbuf *mbuf = arg; | ||
1195 | struct videobuf_queue *q; | ||
1196 | struct v4l2_requestbuffers req; | ||
1197 | unsigned int i; | ||
1198 | |||
1199 | q = get_queue(fh); | ||
1200 | memset(&req,0,sizeof(req)); | ||
1201 | req.type = q->type; | ||
1202 | req.count = 8; | ||
1203 | req.memory = V4L2_MEMORY_MMAP; | ||
1204 | err = videobuf_reqbufs(q,&req); | ||
1205 | if (err < 0) | ||
1206 | return err; | ||
1207 | memset(mbuf,0,sizeof(*mbuf)); | ||
1208 | mbuf->frames = req.count; | ||
1209 | mbuf->size = 0; | ||
1210 | for (i = 0; i < mbuf->frames; i++) { | ||
1211 | mbuf->offsets[i] = q->bufs[i]->boff; | ||
1212 | mbuf->size += q->bufs[i]->bsize; | ||
1213 | } | ||
1214 | return 0; | ||
1215 | } | ||
1216 | case VIDIOC_REQBUFS: | ||
1217 | return videobuf_reqbufs(get_queue(fh), arg); | ||
1218 | |||
1219 | case VIDIOC_QUERYBUF: | ||
1220 | return videobuf_querybuf(get_queue(fh), arg); | ||
1221 | |||
1222 | case VIDIOC_QBUF: | ||
1223 | return videobuf_qbuf(get_queue(fh), arg); | ||
1224 | |||
1225 | case VIDIOC_DQBUF: | ||
1226 | return videobuf_dqbuf(get_queue(fh), arg, | ||
1227 | file->f_flags & O_NONBLOCK); | ||
1228 | |||
1229 | case VIDIOC_STREAMON: | ||
1230 | { | ||
1231 | int res = get_ressource(fh); | ||
1232 | |||
1233 | if (!res_get(dev,fh,res)) | ||
1234 | return -EBUSY; | ||
1235 | return videobuf_streamon(get_queue(fh)); | ||
1236 | } | ||
1237 | case VIDIOC_STREAMOFF: | ||
1238 | { | ||
1239 | int res = get_ressource(fh); | ||
1240 | |||
1241 | err = videobuf_streamoff(get_queue(fh)); | ||
1242 | if (err < 0) | ||
1243 | return err; | ||
1244 | res_free(dev,fh,res); | ||
1245 | return 0; | ||
1246 | } | ||
1247 | |||
1248 | default: | ||
1249 | return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl ); | ||
1250 | } | ||
1251 | return 0; | ||
1252 | } | ||
1253 | |||
1254 | int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | ||
1255 | struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl) | ||
1256 | { | ||
1257 | int err; | ||
1258 | |||
1259 | if (video_debug > 1) | ||
1260 | cx88_print_ioctl(core->name,cmd); | ||
1261 | printk( KERN_INFO "CORE IOCTL: 0x%x\n", cmd ); | ||
1262 | cx88_print_ioctl(core->name,cmd); | ||
1263 | dprintk( 1, "CORE IOCTL: 0x%x\n", cmd ); | ||
1264 | |||
1265 | switch (cmd) { | ||
1125 | /* ---------- tv norms ---------- */ | 1266 | /* ---------- tv norms ---------- */ |
1126 | case VIDIOC_ENUMSTD: | 1267 | case VIDIOC_ENUMSTD: |
1127 | { | 1268 | { |
@@ -1156,9 +1297,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1156 | if (i == ARRAY_SIZE(tvnorms)) | 1297 | if (i == ARRAY_SIZE(tvnorms)) |
1157 | return -EINVAL; | 1298 | return -EINVAL; |
1158 | 1299 | ||
1159 | down(&dev->lock); | 1300 | down(&core->lock); |
1160 | cx88_set_tvnorm(dev->core,&tvnorms[i]); | 1301 | cx88_set_tvnorm(core,&tvnorms[i]); |
1161 | up(&dev->lock); | 1302 | up(&core->lock); |
1162 | return 0; | 1303 | return 0; |
1163 | } | 1304 | } |
1164 | 1305 | ||
@@ -1199,7 +1340,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1199 | { | 1340 | { |
1200 | unsigned int *i = arg; | 1341 | unsigned int *i = arg; |
1201 | 1342 | ||
1202 | *i = dev->core->input; | 1343 | *i = core->input; |
1203 | return 0; | 1344 | return 0; |
1204 | } | 1345 | } |
1205 | case VIDIOC_S_INPUT: | 1346 | case VIDIOC_S_INPUT: |
@@ -1208,55 +1349,15 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1208 | 1349 | ||
1209 | if (*i >= 4) | 1350 | if (*i >= 4) |
1210 | return -EINVAL; | 1351 | return -EINVAL; |
1211 | down(&dev->lock); | 1352 | down(&core->lock); |
1212 | cx88_newstation(core); | 1353 | cx88_newstation(core); |
1213 | video_mux(dev,*i); | 1354 | video_mux(core,*i); |
1214 | up(&dev->lock); | 1355 | up(&core->lock); |
1215 | return 0; | 1356 | return 0; |
1216 | } | 1357 | } |
1217 | 1358 | ||
1218 | 1359 | ||
1219 | 1360 | ||
1220 | /* --- capture ioctls ---------------------------------------- */ | ||
1221 | case VIDIOC_ENUM_FMT: | ||
1222 | { | ||
1223 | struct v4l2_fmtdesc *f = arg; | ||
1224 | enum v4l2_buf_type type; | ||
1225 | unsigned int index; | ||
1226 | |||
1227 | index = f->index; | ||
1228 | type = f->type; | ||
1229 | switch (type) { | ||
1230 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
1231 | if (index >= ARRAY_SIZE(formats)) | ||
1232 | return -EINVAL; | ||
1233 | memset(f,0,sizeof(*f)); | ||
1234 | f->index = index; | ||
1235 | f->type = type; | ||
1236 | strlcpy(f->description,formats[index].name,sizeof(f->description)); | ||
1237 | f->pixelformat = formats[index].fourcc; | ||
1238 | break; | ||
1239 | default: | ||
1240 | return -EINVAL; | ||
1241 | } | ||
1242 | return 0; | ||
1243 | } | ||
1244 | case VIDIOC_G_FMT: | ||
1245 | { | ||
1246 | struct v4l2_format *f = arg; | ||
1247 | return cx8800_g_fmt(dev,fh,f); | ||
1248 | } | ||
1249 | case VIDIOC_S_FMT: | ||
1250 | { | ||
1251 | struct v4l2_format *f = arg; | ||
1252 | return cx8800_s_fmt(dev,fh,f); | ||
1253 | } | ||
1254 | case VIDIOC_TRY_FMT: | ||
1255 | { | ||
1256 | struct v4l2_format *f = arg; | ||
1257 | return cx8800_try_fmt(dev,fh,f); | ||
1258 | } | ||
1259 | |||
1260 | /* --- controls ---------------------------------------------- */ | 1361 | /* --- controls ---------------------------------------------- */ |
1261 | case VIDIOC_QUERYCTRL: | 1362 | case VIDIOC_QUERYCTRL: |
1262 | { | 1363 | { |
@@ -1277,9 +1378,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1277 | return 0; | 1378 | return 0; |
1278 | } | 1379 | } |
1279 | case VIDIOC_G_CTRL: | 1380 | case VIDIOC_G_CTRL: |
1280 | return get_control(dev,arg); | 1381 | return get_control(core,arg); |
1281 | case VIDIOC_S_CTRL: | 1382 | case VIDIOC_S_CTRL: |
1282 | return set_control(dev,arg); | 1383 | return set_control(core,arg); |
1283 | 1384 | ||
1284 | /* --- tuner ioctls ------------------------------------------ */ | 1385 | /* --- tuner ioctls ------------------------------------------ */ |
1285 | case VIDIOC_G_TUNER: | 1386 | case VIDIOC_G_TUNER: |
@@ -1323,10 +1424,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1323 | if (UNSET == core->tuner_type) | 1424 | if (UNSET == core->tuner_type) |
1324 | return -EINVAL; | 1425 | return -EINVAL; |
1325 | 1426 | ||
1326 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1427 | /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */ |
1327 | f->frequency = dev->freq; | 1428 | f->type = radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
1429 | f->frequency = core->freq; | ||
1328 | 1430 | ||
1329 | cx88_call_i2c_clients(dev->core,VIDIOC_G_FREQUENCY,f); | 1431 | cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f); |
1330 | 1432 | ||
1331 | return 0; | 1433 | return 0; |
1332 | } | 1434 | } |
@@ -1338,83 +1440,26 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1338 | return -EINVAL; | 1440 | return -EINVAL; |
1339 | if (f->tuner != 0) | 1441 | if (f->tuner != 0) |
1340 | return -EINVAL; | 1442 | return -EINVAL; |
1341 | if (0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV) | 1443 | if (0 == radio && f->type != V4L2_TUNER_ANALOG_TV) |
1342 | return -EINVAL; | 1444 | return -EINVAL; |
1343 | if (1 == fh->radio && f->type != V4L2_TUNER_RADIO) | 1445 | if (1 == radio && f->type != V4L2_TUNER_RADIO) |
1344 | return -EINVAL; | 1446 | return -EINVAL; |
1345 | down(&dev->lock); | 1447 | down(&core->lock); |
1346 | dev->freq = f->frequency; | 1448 | core->freq = f->frequency; |
1347 | cx88_newstation(core); | 1449 | cx88_newstation(core); |
1348 | cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f); | 1450 | cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f); |
1349 | 1451 | ||
1350 | /* When changing channels it is required to reset TVAUDIO */ | 1452 | /* When changing channels it is required to reset TVAUDIO */ |
1351 | msleep (10); | 1453 | msleep (10); |
1352 | cx88_set_tvaudio(core); | 1454 | cx88_set_tvaudio(core); |
1353 | 1455 | ||
1354 | up(&dev->lock); | 1456 | up(&core->lock); |
1355 | return 0; | ||
1356 | } | ||
1357 | |||
1358 | /* --- streaming capture ------------------------------------- */ | ||
1359 | case VIDIOCGMBUF: | ||
1360 | { | ||
1361 | struct video_mbuf *mbuf = arg; | ||
1362 | struct videobuf_queue *q; | ||
1363 | struct v4l2_requestbuffers req; | ||
1364 | unsigned int i; | ||
1365 | |||
1366 | q = get_queue(fh); | ||
1367 | memset(&req,0,sizeof(req)); | ||
1368 | req.type = q->type; | ||
1369 | req.count = 8; | ||
1370 | req.memory = V4L2_MEMORY_MMAP; | ||
1371 | err = videobuf_reqbufs(q,&req); | ||
1372 | if (err < 0) | ||
1373 | return err; | ||
1374 | memset(mbuf,0,sizeof(*mbuf)); | ||
1375 | mbuf->frames = req.count; | ||
1376 | mbuf->size = 0; | ||
1377 | for (i = 0; i < mbuf->frames; i++) { | ||
1378 | mbuf->offsets[i] = q->bufs[i]->boff; | ||
1379 | mbuf->size += q->bufs[i]->bsize; | ||
1380 | } | ||
1381 | return 0; | ||
1382 | } | ||
1383 | case VIDIOC_REQBUFS: | ||
1384 | return videobuf_reqbufs(get_queue(fh), arg); | ||
1385 | |||
1386 | case VIDIOC_QUERYBUF: | ||
1387 | return videobuf_querybuf(get_queue(fh), arg); | ||
1388 | |||
1389 | case VIDIOC_QBUF: | ||
1390 | return videobuf_qbuf(get_queue(fh), arg); | ||
1391 | |||
1392 | case VIDIOC_DQBUF: | ||
1393 | return videobuf_dqbuf(get_queue(fh), arg, | ||
1394 | file->f_flags & O_NONBLOCK); | ||
1395 | |||
1396 | case VIDIOC_STREAMON: | ||
1397 | { | ||
1398 | int res = get_ressource(fh); | ||
1399 | |||
1400 | if (!res_get(dev,fh,res)) | ||
1401 | return -EBUSY; | ||
1402 | return videobuf_streamon(get_queue(fh)); | ||
1403 | } | ||
1404 | case VIDIOC_STREAMOFF: | ||
1405 | { | ||
1406 | int res = get_ressource(fh); | ||
1407 | |||
1408 | err = videobuf_streamoff(get_queue(fh)); | ||
1409 | if (err < 0) | ||
1410 | return err; | ||
1411 | res_free(dev,fh,res); | ||
1412 | return 0; | 1457 | return 0; |
1413 | } | 1458 | } |
1414 | 1459 | ||
1415 | default: | 1460 | default: |
1416 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | 1461 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, |
1417 | video_do_ioctl); | 1462 | driver_ioctl); |
1418 | } | 1463 | } |
1419 | return 0; | 1464 | return 0; |
1420 | } | 1465 | } |
@@ -1461,7 +1506,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
1461 | memset(t,0,sizeof(*t)); | 1506 | memset(t,0,sizeof(*t)); |
1462 | strcpy(t->name, "Radio"); | 1507 | strcpy(t->name, "Radio"); |
1463 | 1508 | ||
1464 | cx88_call_i2c_clients(dev->core,VIDIOC_G_TUNER,t); | 1509 | cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t); |
1465 | return 0; | 1510 | return 0; |
1466 | } | 1511 | } |
1467 | case VIDIOC_ENUMINPUT: | 1512 | case VIDIOC_ENUMINPUT: |
@@ -1501,8 +1546,8 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
1501 | if (v->tuner) /* Only tuner 0 */ | 1546 | if (v->tuner) /* Only tuner 0 */ |
1502 | return -EINVAL; | 1547 | return -EINVAL; |
1503 | 1548 | ||
1504 | cx88_call_i2c_clients(dev->core,VIDIOCSTUNER,v); | 1549 | cx88_call_i2c_clients(core,VIDIOCSTUNER,v); |
1505 | return 0; | 1550 | return 0; |
1506 | } | 1551 | } |
1507 | case VIDIOC_S_TUNER: | 1552 | case VIDIOC_S_TUNER: |
1508 | { | 1553 | { |
@@ -1511,7 +1556,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, | |||
1511 | if (0 != t->index) | 1556 | if (0 != t->index) |
1512 | return -EINVAL; | 1557 | return -EINVAL; |
1513 | 1558 | ||
1514 | cx88_call_i2c_clients(dev->core,VIDIOC_S_TUNER,t); | 1559 | cx88_call_i2c_clients(core,VIDIOC_S_TUNER,t); |
1515 | 1560 | ||
1516 | return 0; | 1561 | return 0; |
1517 | } | 1562 | } |
@@ -1569,7 +1614,7 @@ static void cx8800_vid_timeout(unsigned long data) | |||
1569 | struct cx88_buffer *buf; | 1614 | struct cx88_buffer *buf; |
1570 | unsigned long flags; | 1615 | unsigned long flags; |
1571 | 1616 | ||
1572 | cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]); | 1617 | cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]); |
1573 | 1618 | ||
1574 | cx_clear(MO_VID_DMACNTRL, 0x11); | 1619 | cx_clear(MO_VID_DMACNTRL, 0x11); |
1575 | cx_clear(VID_CAPTURE_CONTROL, 0x06); | 1620 | cx_clear(VID_CAPTURE_CONTROL, 0x06); |
@@ -1614,14 +1659,14 @@ static void cx8800_vid_irq(struct cx8800_dev *dev) | |||
1614 | printk(KERN_WARNING "%s/0: video risc op code error\n",core->name); | 1659 | printk(KERN_WARNING "%s/0: video risc op code error\n",core->name); |
1615 | cx_clear(MO_VID_DMACNTRL, 0x11); | 1660 | cx_clear(MO_VID_DMACNTRL, 0x11); |
1616 | cx_clear(VID_CAPTURE_CONTROL, 0x06); | 1661 | cx_clear(VID_CAPTURE_CONTROL, 0x06); |
1617 | cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]); | 1662 | cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]); |
1618 | } | 1663 | } |
1619 | 1664 | ||
1620 | /* risc1 y */ | 1665 | /* risc1 y */ |
1621 | if (status & 0x01) { | 1666 | if (status & 0x01) { |
1622 | spin_lock(&dev->slock); | 1667 | spin_lock(&dev->slock); |
1623 | count = cx_read(MO_VIDY_GPCNT); | 1668 | count = cx_read(MO_VIDY_GPCNT); |
1624 | cx88_wakeup(dev->core, &dev->vidq, count); | 1669 | cx88_wakeup(core, &dev->vidq, count); |
1625 | spin_unlock(&dev->slock); | 1670 | spin_unlock(&dev->slock); |
1626 | } | 1671 | } |
1627 | 1672 | ||
@@ -1629,7 +1674,7 @@ static void cx8800_vid_irq(struct cx8800_dev *dev) | |||
1629 | if (status & 0x08) { | 1674 | if (status & 0x08) { |
1630 | spin_lock(&dev->slock); | 1675 | spin_lock(&dev->slock); |
1631 | count = cx_read(MO_VBI_GPCNT); | 1676 | count = cx_read(MO_VBI_GPCNT); |
1632 | cx88_wakeup(dev->core, &dev->vbiq, count); | 1677 | cx88_wakeup(core, &dev->vbiq, count); |
1633 | spin_unlock(&dev->slock); | 1678 | spin_unlock(&dev->slock); |
1634 | } | 1679 | } |
1635 | 1680 | ||
@@ -1798,7 +1843,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1798 | } | 1843 | } |
1799 | 1844 | ||
1800 | /* initialize driver struct */ | 1845 | /* initialize driver struct */ |
1801 | init_MUTEX(&dev->lock); | ||
1802 | spin_lock_init(&dev->slock); | 1846 | spin_lock_init(&dev->slock); |
1803 | core->tvnorm = tvnorms; | 1847 | core->tvnorm = tvnorms; |
1804 | 1848 | ||
@@ -1835,6 +1879,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1835 | request_module("tuner"); | 1879 | request_module("tuner"); |
1836 | if (core->tda9887_conf) | 1880 | if (core->tda9887_conf) |
1837 | request_module("tda9887"); | 1881 | request_module("tda9887"); |
1882 | |||
1838 | /* register v4l devices */ | 1883 | /* register v4l devices */ |
1839 | dev->video_dev = cx88_vdev_init(core,dev->pci, | 1884 | dev->video_dev = cx88_vdev_init(core,dev->pci, |
1840 | &cx8800_video_template,"video"); | 1885 | &cx8800_video_template,"video"); |
@@ -1878,11 +1923,11 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, | |||
1878 | pci_set_drvdata(pci_dev,dev); | 1923 | pci_set_drvdata(pci_dev,dev); |
1879 | 1924 | ||
1880 | /* initial device configuration */ | 1925 | /* initial device configuration */ |
1881 | down(&dev->lock); | 1926 | down(&core->lock); |
1882 | init_controls(dev); | 1927 | init_controls(core); |
1883 | cx88_set_tvnorm(dev->core,tvnorms); | 1928 | cx88_set_tvnorm(core,tvnorms); |
1884 | video_mux(dev,0); | 1929 | video_mux(core,0); |
1885 | up(&dev->lock); | 1930 | up(&core->lock); |
1886 | 1931 | ||
1887 | /* start tvaudio thread */ | 1932 | /* start tvaudio thread */ |
1888 | if (core->tuner_type != TUNER_ABSENT) | 1933 | if (core->tuner_type != TUNER_ABSENT) |
@@ -1902,14 +1947,15 @@ fail_free: | |||
1902 | static void __devexit cx8800_finidev(struct pci_dev *pci_dev) | 1947 | static void __devexit cx8800_finidev(struct pci_dev *pci_dev) |
1903 | { | 1948 | { |
1904 | struct cx8800_dev *dev = pci_get_drvdata(pci_dev); | 1949 | struct cx8800_dev *dev = pci_get_drvdata(pci_dev); |
1950 | struct cx88_core *core = dev->core; | ||
1905 | 1951 | ||
1906 | /* stop thread */ | 1952 | /* stop thread */ |
1907 | if (dev->core->kthread) { | 1953 | if (core->kthread) { |
1908 | kthread_stop(dev->core->kthread); | 1954 | kthread_stop(core->kthread); |
1909 | dev->core->kthread = NULL; | 1955 | core->kthread = NULL; |
1910 | } | 1956 | } |
1911 | 1957 | ||
1912 | cx88_shutdown(dev->core); /* FIXME */ | 1958 | cx88_shutdown(core); /* FIXME */ |
1913 | pci_disable_device(pci_dev); | 1959 | pci_disable_device(pci_dev); |
1914 | 1960 | ||
1915 | /* unregister stuff */ | 1961 | /* unregister stuff */ |
@@ -1921,7 +1967,7 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev) | |||
1921 | /* free memory */ | 1967 | /* free memory */ |
1922 | btcx_riscmem_free(dev->pci,&dev->vidq.stopper); | 1968 | btcx_riscmem_free(dev->pci,&dev->vidq.stopper); |
1923 | list_del(&dev->devlist); | 1969 | list_del(&dev->devlist); |
1924 | cx88_core_put(dev->core,dev->pci); | 1970 | cx88_core_put(core,dev->pci); |
1925 | kfree(dev); | 1971 | kfree(dev); |
1926 | } | 1972 | } |
1927 | 1973 | ||
@@ -1945,7 +1991,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) | |||
1945 | spin_unlock(&dev->slock); | 1991 | spin_unlock(&dev->slock); |
1946 | 1992 | ||
1947 | /* FIXME -- shutdown device */ | 1993 | /* FIXME -- shutdown device */ |
1948 | cx88_shutdown(dev->core); | 1994 | cx88_shutdown(core); |
1949 | 1995 | ||
1950 | pci_save_state(pci_dev); | 1996 | pci_save_state(pci_dev); |
1951 | if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) { | 1997 | if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) { |
@@ -1968,7 +2014,7 @@ static int cx8800_resume(struct pci_dev *pci_dev) | |||
1968 | pci_restore_state(pci_dev); | 2014 | pci_restore_state(pci_dev); |
1969 | 2015 | ||
1970 | /* FIXME: re-initialize hardware */ | 2016 | /* FIXME: re-initialize hardware */ |
1971 | cx88_reset(dev->core); | 2017 | cx88_reset(core); |
1972 | 2018 | ||
1973 | /* restart video+vbi capture */ | 2019 | /* restart video+vbi capture */ |
1974 | spin_lock(&dev->slock); | 2020 | spin_lock(&dev->slock); |
@@ -2030,6 +2076,8 @@ static void cx8800_fini(void) | |||
2030 | module_init(cx8800_init); | 2076 | module_init(cx8800_init); |
2031 | module_exit(cx8800_fini); | 2077 | module_exit(cx8800_fini); |
2032 | 2078 | ||
2079 | EXPORT_SYMBOL(cx88_do_ioctl); | ||
2080 | |||
2033 | /* ----------------------------------------------------------- */ | 2081 | /* ----------------------------------------------------------- */ |
2034 | /* | 2082 | /* |
2035 | * Local variables: | 2083 | * Local variables: |