diff options
-rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 81 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 90 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-dvb.c | 20 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 12 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 22 |
5 files changed, 150 insertions, 75 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index ed50b4e55264..13ffde281067 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -436,19 +436,25 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table); | |||
436 | 436 | ||
437 | /* Board Hauppauge WinTV HVR 900 analog */ | 437 | /* Board Hauppauge WinTV HVR 900 analog */ |
438 | struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { | 438 | struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { |
439 | { -1, -1, 6}, | 439 | {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10}, |
440 | {EM28XX_R08_GPIO, 0x2d, 10}, | 440 | {0x05, 0xff, 0x10, 10}, |
441 | {EM28XX_R08_GPIO, 0x3d, 5}, | 441 | { -1, -1, -1, -1}, |
442 | { -1, -1, -1}, | ||
443 | }; | 442 | }; |
443 | |||
444 | /* Board Hauppauge WinTV HVR 900 digital */ | 444 | /* Board Hauppauge WinTV HVR 900 digital */ |
445 | struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { | 445 | struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { |
446 | { -1, -1, 6}, | 446 | {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10}, |
447 | {EM28XX_R08_GPIO, 0x2e, 6}, | 447 | {EM2880_R04_GPO, 0x04, 0x0f, 10}, |
448 | {EM28XX_R08_GPIO, 0x3e, 6}, | 448 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, |
449 | {EM2880_R04_GPO, 0x04, 10}, | 449 | { -1, -1, -1, -1}, |
450 | {EM2880_R04_GPO, 0x0c, 10}, | 450 | }; |
451 | { -1, -1, -1}, | 451 | |
452 | /* Board Hauppauge WinTV HVR 900 tuner_callback */ | ||
453 | struct em28xx_reg_seq hauppauge_wintv_hvr_900_tuner_callback[] = { | ||
454 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | ||
455 | {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10}, | ||
456 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | ||
457 | { -1, -1, -1, -1}, | ||
452 | }; | 458 | }; |
453 | 459 | ||
454 | /* | 460 | /* |
@@ -469,7 +475,6 @@ int em28xx_tuner_callback(void *ptr, int command, int arg) | |||
469 | { | 475 | { |
470 | int rc = 0; | 476 | int rc = 0; |
471 | struct em28xx *dev = ptr; | 477 | struct em28xx *dev = ptr; |
472 | struct em28xx_reg_seq *gpio; | ||
473 | 478 | ||
474 | if (dev->tuner_type != TUNER_XC2028) | 479 | if (dev->tuner_type != TUNER_XC2028) |
475 | return 0; | 480 | return 0; |
@@ -478,32 +483,10 @@ int em28xx_tuner_callback(void *ptr, int command, int arg) | |||
478 | return 0; | 483 | return 0; |
479 | 484 | ||
480 | if (dev->mode == EM28XX_ANALOG_MODE) | 485 | if (dev->mode == EM28XX_ANALOG_MODE) |
481 | gpio = dev->analog_gpio; | 486 | rc = em28xx_gpio_set(dev, dev->tun_analog_gpio); |
482 | else | 487 | else |
483 | gpio = dev->digital_gpio; | 488 | rc = em28xx_gpio_set(dev, dev->tun_digital_gpio); |
484 | 489 | ||
485 | /* djh - Not sure if these are still required */ | ||
486 | dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); | ||
487 | if (dev->mode == EM28XX_ANALOG_MODE) | ||
488 | dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1); | ||
489 | else | ||
490 | dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1); | ||
491 | msleep(6); | ||
492 | |||
493 | if (!gpio) | ||
494 | return rc; | ||
495 | |||
496 | /* Send GPIO reset sequences specified at board entry */ | ||
497 | while (gpio->sleep >= 0) { | ||
498 | if (gpio->reg >= 0) | ||
499 | rc = dev->em28xx_write_regs(dev, | ||
500 | gpio->reg, | ||
501 | &gpio->val, 1); | ||
502 | if (gpio->sleep > 0) | ||
503 | msleep(gpio->sleep); | ||
504 | |||
505 | gpio++; | ||
506 | } | ||
507 | return rc; | 490 | return rc; |
508 | } | 491 | } |
509 | EXPORT_SYMBOL_GPL(em28xx_tuner_callback); | 492 | EXPORT_SYMBOL_GPL(em28xx_tuner_callback); |
@@ -527,6 +510,10 @@ void em28xx_pre_card_setup(struct em28xx *dev) | |||
527 | { | 510 | { |
528 | int rc; | 511 | int rc; |
529 | 512 | ||
513 | rc = em28xx_read_reg(dev, EM2880_R04_GPO); | ||
514 | if (rc >= 0) | ||
515 | dev->reg_gpo = rc; | ||
516 | |||
530 | dev->wait_after_write = 5; | 517 | dev->wait_after_write = 5; |
531 | rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); | 518 | rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); |
532 | if (rc > 0) { | 519 | if (rc > 0) { |
@@ -547,24 +534,24 @@ void em28xx_pre_card_setup(struct em28xx *dev) | |||
547 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | 534 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: |
548 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | 535 | case EM2880_BOARD_TERRATEC_HYBRID_XS: |
549 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: | 536 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: |
550 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); | 537 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); |
551 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | 538 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); |
552 | em28xx_write_regs(dev, 0x08, "\xff", 1); | ||
553 | em28xx_write_regs(dev, 0x04, "\x00", 1); | ||
554 | msleep(100); | ||
555 | em28xx_write_regs(dev, 0x04, "\x08", 1); | ||
556 | msleep(100); | ||
557 | em28xx_write_regs(dev, 0x08, "\xff", 1); | ||
558 | msleep(50); | ||
559 | em28xx_write_regs(dev, 0x08, "\x2d", 1); | ||
560 | msleep(50); | 539 | msleep(50); |
561 | em28xx_write_regs(dev, 0x08, "\x3d", 1); | ||
562 | 540 | ||
563 | dev->analog_gpio = hauppauge_wintv_hvr_900_analog; | 541 | /* Sets GPO/GPIO sequences for this device */ |
564 | dev->digital_gpio = hauppauge_wintv_hvr_900_digital; | 542 | dev->analog_gpio = hauppauge_wintv_hvr_900_analog; |
543 | dev->digital_gpio = hauppauge_wintv_hvr_900_digital; | ||
544 | dev->tun_analog_gpio = hauppauge_wintv_hvr_900_tuner_callback; | ||
545 | dev->tun_digital_gpio = hauppauge_wintv_hvr_900_tuner_callback; | ||
565 | 546 | ||
566 | break; | 547 | break; |
567 | } | 548 | } |
549 | |||
550 | em28xx_gpio_set(dev, dev->tun_analog_gpio); | ||
551 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | ||
552 | |||
553 | /* Unlock device */ | ||
554 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | ||
568 | } | 555 | } |
569 | 556 | ||
570 | void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | 557 | void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index bd7794f4fd74..db40358c773b 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -134,7 +134,10 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
134 | unsigned char *bufs; | 134 | unsigned char *bufs; |
135 | 135 | ||
136 | if (dev->state & DEV_DISCONNECTED) | 136 | if (dev->state & DEV_DISCONNECTED) |
137 | return(-ENODEV); | 137 | return -ENODEV; |
138 | |||
139 | if (len < 1) | ||
140 | return -EINVAL; | ||
138 | 141 | ||
139 | bufs = kmalloc(len, GFP_KERNEL); | 142 | bufs = kmalloc(len, GFP_KERNEL); |
140 | 143 | ||
@@ -162,7 +165,23 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
162 | 165 | ||
163 | int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len) | 166 | int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len) |
164 | { | 167 | { |
165 | return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len); | 168 | int rc; |
169 | |||
170 | rc = em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len); | ||
171 | |||
172 | /* Stores GPO/GPIO values at the cache, if changed | ||
173 | Only write values should be stored, since input on a GPIO | ||
174 | register will return the input bits. | ||
175 | Not sure what happens on reading GPO register. | ||
176 | */ | ||
177 | if (rc >= 0) { | ||
178 | if (reg == EM2880_R04_GPO) | ||
179 | dev->reg_gpo = buf[0]; | ||
180 | else if (reg == EM28XX_R08_GPIO) | ||
181 | dev->reg_gpio = buf[0]; | ||
182 | } | ||
183 | |||
184 | return rc; | ||
166 | } | 185 | } |
167 | 186 | ||
168 | /* | 187 | /* |
@@ -176,12 +195,19 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, | |||
176 | int oldval; | 195 | int oldval; |
177 | u8 newval; | 196 | u8 newval; |
178 | 197 | ||
179 | oldval = em28xx_read_reg(dev, reg); | 198 | /* Uses cache for gpo/gpio registers */ |
199 | if (reg == EM2880_R04_GPO) | ||
200 | oldval = dev->reg_gpo; | ||
201 | else if (reg == EM28XX_R08_GPIO) | ||
202 | oldval = dev->reg_gpio; | ||
203 | else | ||
204 | oldval = em28xx_read_reg(dev, reg); | ||
180 | 205 | ||
181 | if (oldval < 0) | 206 | if (oldval < 0) |
182 | return oldval; | 207 | return oldval; |
183 | 208 | ||
184 | newval = (((u8) oldval) & ~bitmask) | (val & bitmask); | 209 | newval = (((u8) oldval) & ~bitmask) | (val & bitmask); |
210 | |||
185 | return em28xx_write_regs(dev, reg, &newval, 1); | 211 | return em28xx_write_regs(dev, reg, &newval, 1); |
186 | } | 212 | } |
187 | 213 | ||
@@ -472,6 +498,57 @@ int em28xx_set_alternate(struct em28xx *dev) | |||
472 | return 0; | 498 | return 0; |
473 | } | 499 | } |
474 | 500 | ||
501 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio) | ||
502 | { | ||
503 | int rc = 0; | ||
504 | |||
505 | if (!gpio) | ||
506 | return rc; | ||
507 | |||
508 | dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); | ||
509 | if (dev->mode == EM28XX_ANALOG_MODE) | ||
510 | dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1); | ||
511 | else | ||
512 | dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1); | ||
513 | msleep(6); | ||
514 | |||
515 | /* Send GPIO reset sequences specified at board entry */ | ||
516 | while (gpio->sleep >= 0) { | ||
517 | if (gpio->reg >= 0) { | ||
518 | rc = em28xx_write_reg_bits(dev, | ||
519 | gpio->reg, | ||
520 | gpio->val, | ||
521 | gpio->mask); | ||
522 | if (rc < 0) | ||
523 | return rc; | ||
524 | } | ||
525 | if (gpio->sleep > 0) | ||
526 | msleep(gpio->sleep); | ||
527 | |||
528 | gpio++; | ||
529 | } | ||
530 | return rc; | ||
531 | } | ||
532 | |||
533 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode) | ||
534 | { | ||
535 | if (dev->mode == set_mode) | ||
536 | return 0; | ||
537 | |||
538 | if (set_mode == EM28XX_MODE_UNDEFINED) { | ||
539 | dev->mode = set_mode; | ||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | dev->mode = set_mode; | ||
544 | |||
545 | if (dev->mode == EM28XX_DIGITAL_MODE) | ||
546 | return em28xx_gpio_set(dev, dev->digital_gpio); | ||
547 | else | ||
548 | return em28xx_gpio_set(dev, dev->analog_gpio); | ||
549 | } | ||
550 | EXPORT_SYMBOL_GPL(em28xx_set_mode); | ||
551 | |||
475 | /* ------------------------------------------------------------------ | 552 | /* ------------------------------------------------------------------ |
476 | URB control | 553 | URB control |
477 | ------------------------------------------------------------------*/ | 554 | ------------------------------------------------------------------*/ |
@@ -548,8 +625,7 @@ EXPORT_SYMBOL_GPL(em28xx_uninit_isoc); | |||
548 | */ | 625 | */ |
549 | int em28xx_init_isoc(struct em28xx *dev, int max_packets, | 626 | int em28xx_init_isoc(struct em28xx *dev, int max_packets, |
550 | int num_bufs, int max_pkt_size, | 627 | int num_bufs, int max_pkt_size, |
551 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb), | 628 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb)) |
552 | int cap_type) | ||
553 | { | 629 | { |
554 | struct em28xx_dmaqueue *dma_q = &dev->vidq; | 630 | struct em28xx_dmaqueue *dma_q = &dev->vidq; |
555 | int i; | 631 | int i; |
@@ -612,7 +688,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, | |||
612 | should also be using 'desc.bInterval' | 688 | should also be using 'desc.bInterval' |
613 | */ | 689 | */ |
614 | pipe = usb_rcvisocpipe(dev->udev, | 690 | pipe = usb_rcvisocpipe(dev->udev, |
615 | cap_type == EM28XX_ANALOG_CAPTURE ? 0x82 : 0x84); | 691 | dev->mode == EM28XX_ANALOG_MODE ? 0x82 : 0x84); |
616 | 692 | ||
617 | usb_fill_int_urb(urb, dev->udev, pipe, | 693 | usb_fill_int_urb(urb, dev->udev, pipe, |
618 | dev->isoc_ctl.transfer_buffer[i], sb_size, | 694 | dev->isoc_ctl.transfer_buffer[i], sb_size, |
@@ -632,7 +708,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, | |||
632 | 708 | ||
633 | init_waitqueue_head(&dma_q->wq); | 709 | init_waitqueue_head(&dma_q->wq); |
634 | 710 | ||
635 | em28xx_capture_start(dev, cap_type); | 711 | em28xx_capture_start(dev, 1); |
636 | 712 | ||
637 | /* submit urbs and enables IRQ */ | 713 | /* submit urbs and enables IRQ */ |
638 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { | 714 | for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { |
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 39581d976e01..2e9ec626b609 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -137,14 +137,17 @@ static inline int dvb_isoc_copy(struct em28xx *dev, struct urb *urb) | |||
137 | 137 | ||
138 | static int start_streaming(struct em28xx_dvb *dvb) | 138 | static int start_streaming(struct em28xx_dvb *dvb) |
139 | { | 139 | { |
140 | int rc; | ||
140 | struct em28xx *dev = dvb->adapter.priv; | 141 | struct em28xx *dev = dvb->adapter.priv; |
141 | 142 | ||
142 | usb_set_interface(dev->udev, 0, 1); | 143 | usb_set_interface(dev->udev, 0, 1); |
143 | dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); | 144 | rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); |
145 | if (rc < 0) | ||
146 | return rc; | ||
144 | 147 | ||
145 | return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS, | 148 | return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS, |
146 | EM28XX_DVB_NUM_BUFS, EM28XX_DVB_MAX_PACKETSIZE, | 149 | EM28XX_DVB_NUM_BUFS, EM28XX_DVB_MAX_PACKETSIZE, |
147 | dvb_isoc_copy, EM28XX_DIGITAL_CAPTURE); | 150 | dvb_isoc_copy); |
148 | } | 151 | } |
149 | 152 | ||
150 | static int stop_streaming(struct em28xx_dvb *dvb) | 153 | static int stop_streaming(struct em28xx_dvb *dvb) |
@@ -152,6 +155,9 @@ static int stop_streaming(struct em28xx_dvb *dvb) | |||
152 | struct em28xx *dev = dvb->adapter.priv; | 155 | struct em28xx *dev = dvb->adapter.priv; |
153 | 156 | ||
154 | em28xx_uninit_isoc(dev); | 157 | em28xx_uninit_isoc(dev); |
158 | |||
159 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | ||
160 | |||
155 | return 0; | 161 | return 0; |
156 | } | 162 | } |
157 | 163 | ||
@@ -368,13 +374,10 @@ static int dvb_init(struct em28xx *dev) | |||
368 | } | 374 | } |
369 | dev->dvb = dvb; | 375 | dev->dvb = dvb; |
370 | 376 | ||
377 | em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | ||
371 | /* init frontend */ | 378 | /* init frontend */ |
372 | switch (dev->model) { | 379 | switch (dev->model) { |
373 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: | 380 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: |
374 | /* Enable lgdt330x */ | ||
375 | dev->mode = EM28XX_DIGITAL_MODE; | ||
376 | em28xx_tuner_callback(dev, XC2028_TUNER_RESET, 0); | ||
377 | |||
378 | dvb->frontend = dvb_attach(lgdt330x_attach, | 381 | dvb->frontend = dvb_attach(lgdt330x_attach, |
379 | &em2880_lgdt3303_dev, | 382 | &em2880_lgdt3303_dev, |
380 | &dev->i2c_adap); | 383 | &dev->i2c_adap); |
@@ -384,9 +387,6 @@ static int dvb_init(struct em28xx *dev) | |||
384 | } | 387 | } |
385 | break; | 388 | break; |
386 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | 389 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: |
387 | /* Enable zl10353 */ | ||
388 | dev->mode = EM28XX_DIGITAL_MODE; | ||
389 | em28xx_tuner_callback(dev, XC2028_TUNER_RESET, 0); | ||
390 | dvb->frontend = dvb_attach(zl10353_attach, | 390 | dvb->frontend = dvb_attach(zl10353_attach, |
391 | &em28xx_zl10353_with_xc3028, | 391 | &em28xx_zl10353_with_xc3028, |
392 | &dev->i2c_adap); | 392 | &dev->i2c_adap); |
@@ -415,10 +415,12 @@ static int dvb_init(struct em28xx *dev) | |||
415 | if (result < 0) | 415 | if (result < 0) |
416 | goto out_free; | 416 | goto out_free; |
417 | 417 | ||
418 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | ||
418 | printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); | 419 | printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); |
419 | return 0; | 420 | return 0; |
420 | 421 | ||
421 | out_free: | 422 | out_free: |
423 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | ||
422 | kfree(dvb); | 424 | kfree(dvb); |
423 | dev->dvb = NULL; | 425 | dev->dvb = NULL; |
424 | return result; | 426 | return result; |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index fb533fda2198..4ffd064c402a 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -461,7 +461,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
461 | if (urb_init) { | 461 | if (urb_init) { |
462 | rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS, | 462 | rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS, |
463 | EM28XX_NUM_BUFS, dev->max_pkt_size, | 463 | EM28XX_NUM_BUFS, dev->max_pkt_size, |
464 | em28xx_isoc_copy, EM28XX_ANALOG_CAPTURE); | 464 | em28xx_isoc_copy); |
465 | if (rc < 0) | 465 | if (rc < 0) |
466 | goto fail; | 466 | goto fail; |
467 | } | 467 | } |
@@ -1534,8 +1534,8 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1534 | em28xx_videodbg("open minor=%d type=%s users=%d\n", | 1534 | em28xx_videodbg("open minor=%d type=%s users=%d\n", |
1535 | minor, v4l2_type_names[fh_type], dev->users); | 1535 | minor, v4l2_type_names[fh_type], dev->users); |
1536 | 1536 | ||
1537 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); | ||
1538 | 1537 | ||
1538 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); | ||
1539 | if (!fh) { | 1539 | if (!fh) { |
1540 | em28xx_errdev("em28xx-video.c: Out of memory?!\n"); | 1540 | em28xx_errdev("em28xx-video.c: Out of memory?!\n"); |
1541 | return -ENOMEM; | 1541 | return -ENOMEM; |
@@ -1552,9 +1552,15 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1552 | dev->hscale = 0; | 1552 | dev->hscale = 0; |
1553 | dev->vscale = 0; | 1553 | dev->vscale = 0; |
1554 | 1554 | ||
1555 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | ||
1555 | em28xx_set_alternate(dev); | 1556 | em28xx_set_alternate(dev); |
1556 | em28xx_resolution_set(dev); | 1557 | em28xx_resolution_set(dev); |
1557 | 1558 | ||
1559 | /* Needed, since GPIO might have disabled power of | ||
1560 | some i2c device | ||
1561 | */ | ||
1562 | em28xx_config_i2c(dev); | ||
1563 | |||
1558 | } | 1564 | } |
1559 | if (fh->radio) { | 1565 | if (fh->radio) { |
1560 | em28xx_videodbg("video_open: setting radio device\n"); | 1566 | em28xx_videodbg("video_open: setting radio device\n"); |
@@ -1568,6 +1574,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1568 | sizeof(struct em28xx_buffer), fh); | 1574 | sizeof(struct em28xx_buffer), fh); |
1569 | 1575 | ||
1570 | mutex_unlock(&dev->lock); | 1576 | mutex_unlock(&dev->lock); |
1577 | |||
1571 | return errCode; | 1578 | return errCode; |
1572 | } | 1579 | } |
1573 | 1580 | ||
@@ -1647,6 +1654,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | |||
1647 | 1654 | ||
1648 | /* do this before setting alternate! */ | 1655 | /* do this before setting alternate! */ |
1649 | em28xx_uninit_isoc(dev); | 1656 | em28xx_uninit_isoc(dev); |
1657 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | ||
1650 | 1658 | ||
1651 | /* set alternate 0 */ | 1659 | /* set alternate 0 */ |
1652 | dev->alt = 0; | 1660 | dev->alt = 0; |
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index e4a56d8dfcf4..e0d119c22810 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -110,6 +110,7 @@ | |||
110 | #define EM2800_I2C_WRITE_TIMEOUT 20 | 110 | #define EM2800_I2C_WRITE_TIMEOUT 20 |
111 | 111 | ||
112 | enum em28xx_mode { | 112 | enum em28xx_mode { |
113 | EM28XX_MODE_UNDEFINED, | ||
113 | EM28XX_ANALOG_MODE, | 114 | EM28XX_ANALOG_MODE, |
114 | EM28XX_DIGITAL_MODE, | 115 | EM28XX_DIGITAL_MODE, |
115 | }; | 116 | }; |
@@ -228,7 +229,7 @@ enum em28xx_decoder { | |||
228 | 229 | ||
229 | struct em28xx_reg_seq { | 230 | struct em28xx_reg_seq { |
230 | int reg; | 231 | int reg; |
231 | unsigned char val; | 232 | unsigned char val, mask; |
232 | int sleep; | 233 | int sleep; |
233 | }; | 234 | }; |
234 | 235 | ||
@@ -274,12 +275,6 @@ enum em28xx_dev_state { | |||
274 | DEV_MISCONFIGURED = 0x04, | 275 | DEV_MISCONFIGURED = 0x04, |
275 | }; | 276 | }; |
276 | 277 | ||
277 | enum em28xx_capture_mode { | ||
278 | EM28XX_CAPTURE_OFF = 0, | ||
279 | EM28XX_ANALOG_CAPTURE, | ||
280 | EM28XX_DIGITAL_CAPTURE, | ||
281 | }; | ||
282 | |||
283 | #define EM28XX_AUDIO_BUFS 5 | 278 | #define EM28XX_AUDIO_BUFS 5 |
284 | #define EM28XX_NUM_AUDIO_PACKETS 64 | 279 | #define EM28XX_NUM_AUDIO_PACKETS 64 |
285 | #define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */ | 280 | #define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */ |
@@ -335,9 +330,12 @@ struct em28xx { | |||
335 | /* Some older em28xx chips needs a waiting time after writing */ | 330 | /* Some older em28xx chips needs a waiting time after writing */ |
336 | unsigned int wait_after_write; | 331 | unsigned int wait_after_write; |
337 | 332 | ||
338 | /* GPIO sequences for tuner callback */ | 333 | /* GPIO sequences for analog and digital mode */ |
339 | struct em28xx_reg_seq *analog_gpio, *digital_gpio; | 334 | struct em28xx_reg_seq *analog_gpio, *digital_gpio; |
340 | 335 | ||
336 | /* GPIO sequences for tuner callbacks */ | ||
337 | struct em28xx_reg_seq *tun_analog_gpio, *tun_digital_gpio; | ||
338 | |||
341 | int video_inputs; /* number of video inputs */ | 339 | int video_inputs; /* number of video inputs */ |
342 | struct list_head devlist; | 340 | struct list_head devlist; |
343 | 341 | ||
@@ -415,6 +413,9 @@ struct em28xx { | |||
415 | 413 | ||
416 | enum em28xx_mode mode; | 414 | enum em28xx_mode mode; |
417 | 415 | ||
416 | /* Caches GPO and GPIO registers */ | ||
417 | unsigned char reg_gpo, reg_gpio; | ||
418 | |||
418 | struct em28xx_dvb *dvb; | 419 | struct em28xx_dvb *dvb; |
419 | }; | 420 | }; |
420 | 421 | ||
@@ -455,9 +456,10 @@ int em28xx_resolution_set(struct em28xx *dev); | |||
455 | int em28xx_set_alternate(struct em28xx *dev); | 456 | int em28xx_set_alternate(struct em28xx *dev); |
456 | int em28xx_init_isoc(struct em28xx *dev, int max_packets, | 457 | int em28xx_init_isoc(struct em28xx *dev, int max_packets, |
457 | int num_bufs, int max_pkt_size, | 458 | int num_bufs, int max_pkt_size, |
458 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb), | 459 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb)); |
459 | int cap_type); | ||
460 | void em28xx_uninit_isoc(struct em28xx *dev); | 460 | void em28xx_uninit_isoc(struct em28xx *dev); |
461 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); | ||
462 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); | ||
461 | 463 | ||
462 | /* Provided by em28xx-video.c */ | 464 | /* Provided by em28xx-video.c */ |
463 | int em28xx_register_extension(struct em28xx_ops *dev); | 465 | int em28xx_register_extension(struct em28xx_ops *dev); |