diff options
author | HIRANO Takahito <hiranotaka@zng.info> | 2010-04-07 10:48:48 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-19 11:57:32 -0400 |
commit | 4d1f413e820c7e1402475eea254e2bc82d98de35 (patch) | |
tree | 206e8f18587cb7bdd0cc5713df4c612a0a437363 /drivers/media/dvb | |
parent | 2f7908848642c177b16b71a2ed52b57d614637ef (diff) |
V4L/DVB: pt1: Support Earthsoft PT2
Support Earthsoft PT2.
Signed-off-by: HIRANO Takahito <hiranotaka@zng.info>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r-- | drivers/media/dvb/pt1/pt1.c | 271 | ||||
-rw-r--r-- | drivers/media/dvb/pt1/va1j5jf8007s.c | 32 | ||||
-rw-r--r-- | drivers/media/dvb/pt1/va1j5jf8007s.h | 8 | ||||
-rw-r--r-- | drivers/media/dvb/pt1/va1j5jf8007t.c | 31 | ||||
-rw-r--r-- | drivers/media/dvb/pt1/va1j5jf8007t.h | 8 |
5 files changed, 278 insertions, 72 deletions
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c index 6aded234aa61..69ad94934ec2 100644 --- a/drivers/media/dvb/pt1/pt1.c +++ b/drivers/media/dvb/pt1/pt1.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * driver for Earthsoft PT1 | 2 | * driver for Earthsoft PT1/PT2 |
3 | * | 3 | * |
4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> | 4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> |
5 | * | 5 | * |
@@ -77,6 +77,10 @@ struct pt1 { | |||
77 | struct pt1_adapter *adaps[PT1_NR_ADAPS]; | 77 | struct pt1_adapter *adaps[PT1_NR_ADAPS]; |
78 | struct pt1_table *tables; | 78 | struct pt1_table *tables; |
79 | struct task_struct *kthread; | 79 | struct task_struct *kthread; |
80 | |||
81 | struct mutex lock; | ||
82 | int power; | ||
83 | int reset; | ||
80 | }; | 84 | }; |
81 | 85 | ||
82 | struct pt1_adapter { | 86 | struct pt1_adapter { |
@@ -95,6 +99,11 @@ struct pt1_adapter { | |||
95 | struct dvb_frontend *fe; | 99 | struct dvb_frontend *fe; |
96 | int (*orig_set_voltage)(struct dvb_frontend *fe, | 100 | int (*orig_set_voltage)(struct dvb_frontend *fe, |
97 | fe_sec_voltage_t voltage); | 101 | fe_sec_voltage_t voltage); |
102 | int (*orig_sleep)(struct dvb_frontend *fe); | ||
103 | int (*orig_init)(struct dvb_frontend *fe); | ||
104 | |||
105 | fe_sec_voltage_t voltage; | ||
106 | int sleep; | ||
98 | }; | 107 | }; |
99 | 108 | ||
100 | #define pt1_printk(level, pt1, format, arg...) \ | 109 | #define pt1_printk(level, pt1, format, arg...) \ |
@@ -219,8 +228,10 @@ static int pt1_do_enable_ram(struct pt1 *pt1) | |||
219 | static int pt1_enable_ram(struct pt1 *pt1) | 228 | static int pt1_enable_ram(struct pt1 *pt1) |
220 | { | 229 | { |
221 | int i, ret; | 230 | int i, ret; |
231 | int phase; | ||
222 | schedule_timeout_uninterruptible((HZ + 999) / 1000); | 232 | schedule_timeout_uninterruptible((HZ + 999) / 1000); |
223 | for (i = 0; i < 10; i++) { | 233 | phase = pt1->pdev->device == 0x211a ? 128 : 166; |
234 | for (i = 0; i < phase; i++) { | ||
224 | ret = pt1_do_enable_ram(pt1); | 235 | ret = pt1_do_enable_ram(pt1); |
225 | if (ret < 0) | 236 | if (ret < 0) |
226 | return ret; | 237 | return ret; |
@@ -485,33 +496,47 @@ static int pt1_stop_feed(struct dvb_demux_feed *feed) | |||
485 | } | 496 | } |
486 | 497 | ||
487 | static void | 498 | static void |
488 | pt1_set_power(struct pt1 *pt1, int power, int lnb, int reset) | 499 | pt1_update_power(struct pt1 *pt1) |
489 | { | 500 | { |
490 | pt1_write_reg(pt1, 1, power | lnb << 1 | !reset << 3); | 501 | int bits; |
502 | int i; | ||
503 | struct pt1_adapter *adap; | ||
504 | static const int sleep_bits[] = { | ||
505 | 1 << 4, | ||
506 | 1 << 6 | 1 << 7, | ||
507 | 1 << 5, | ||
508 | 1 << 6 | 1 << 8, | ||
509 | }; | ||
510 | |||
511 | bits = pt1->power | !pt1->reset << 3; | ||
512 | mutex_lock(&pt1->lock); | ||
513 | for (i = 0; i < PT1_NR_ADAPS; i++) { | ||
514 | adap = pt1->adaps[i]; | ||
515 | switch (adap->voltage) { | ||
516 | case SEC_VOLTAGE_13: /* actually 11V */ | ||
517 | bits |= 1 << 1; | ||
518 | break; | ||
519 | case SEC_VOLTAGE_18: /* actually 15V */ | ||
520 | bits |= 1 << 1 | 1 << 2; | ||
521 | break; | ||
522 | default: | ||
523 | break; | ||
524 | } | ||
525 | |||
526 | /* XXX: The bits should be changed depending on adap->sleep. */ | ||
527 | bits |= sleep_bits[i]; | ||
528 | } | ||
529 | pt1_write_reg(pt1, 1, bits); | ||
530 | mutex_unlock(&pt1->lock); | ||
491 | } | 531 | } |
492 | 532 | ||
493 | static int pt1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 533 | static int pt1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) |
494 | { | 534 | { |
495 | struct pt1_adapter *adap; | 535 | struct pt1_adapter *adap; |
496 | int lnb; | ||
497 | 536 | ||
498 | adap = container_of(fe->dvb, struct pt1_adapter, adap); | 537 | adap = container_of(fe->dvb, struct pt1_adapter, adap); |
499 | 538 | adap->voltage = voltage; | |
500 | switch (voltage) { | 539 | pt1_update_power(adap->pt1); |
501 | case SEC_VOLTAGE_13: /* actually 11V */ | ||
502 | lnb = 2; | ||
503 | break; | ||
504 | case SEC_VOLTAGE_18: /* actually 15V */ | ||
505 | lnb = 3; | ||
506 | break; | ||
507 | case SEC_VOLTAGE_OFF: | ||
508 | lnb = 0; | ||
509 | break; | ||
510 | default: | ||
511 | return -EINVAL; | ||
512 | } | ||
513 | |||
514 | pt1_set_power(adap->pt1, 1, lnb, 0); | ||
515 | 540 | ||
516 | if (adap->orig_set_voltage) | 541 | if (adap->orig_set_voltage) |
517 | return adap->orig_set_voltage(fe, voltage); | 542 | return adap->orig_set_voltage(fe, voltage); |
@@ -519,9 +544,37 @@ static int pt1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | |||
519 | return 0; | 544 | return 0; |
520 | } | 545 | } |
521 | 546 | ||
547 | static int pt1_sleep(struct dvb_frontend *fe) | ||
548 | { | ||
549 | struct pt1_adapter *adap; | ||
550 | |||
551 | adap = container_of(fe->dvb, struct pt1_adapter, adap); | ||
552 | adap->sleep = 1; | ||
553 | pt1_update_power(adap->pt1); | ||
554 | |||
555 | if (adap->orig_sleep) | ||
556 | return adap->orig_sleep(fe); | ||
557 | else | ||
558 | return 0; | ||
559 | } | ||
560 | |||
561 | static int pt1_wakeup(struct dvb_frontend *fe) | ||
562 | { | ||
563 | struct pt1_adapter *adap; | ||
564 | |||
565 | adap = container_of(fe->dvb, struct pt1_adapter, adap); | ||
566 | adap->sleep = 0; | ||
567 | pt1_update_power(adap->pt1); | ||
568 | schedule_timeout_uninterruptible((HZ + 999) / 1000); | ||
569 | |||
570 | if (adap->orig_init) | ||
571 | return adap->orig_init(fe); | ||
572 | else | ||
573 | return 0; | ||
574 | } | ||
575 | |||
522 | static void pt1_free_adapter(struct pt1_adapter *adap) | 576 | static void pt1_free_adapter(struct pt1_adapter *adap) |
523 | { | 577 | { |
524 | dvb_unregister_frontend(adap->fe); | ||
525 | dvb_net_release(&adap->net); | 578 | dvb_net_release(&adap->net); |
526 | adap->demux.dmx.close(&adap->demux.dmx); | 579 | adap->demux.dmx.close(&adap->demux.dmx); |
527 | dvb_dmxdev_release(&adap->dmxdev); | 580 | dvb_dmxdev_release(&adap->dmxdev); |
@@ -534,7 +587,7 @@ static void pt1_free_adapter(struct pt1_adapter *adap) | |||
534 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 587 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
535 | 588 | ||
536 | static struct pt1_adapter * | 589 | static struct pt1_adapter * |
537 | pt1_alloc_adapter(struct pt1 *pt1, struct dvb_frontend *fe) | 590 | pt1_alloc_adapter(struct pt1 *pt1) |
538 | { | 591 | { |
539 | struct pt1_adapter *adap; | 592 | struct pt1_adapter *adap; |
540 | void *buf; | 593 | void *buf; |
@@ -551,8 +604,8 @@ pt1_alloc_adapter(struct pt1 *pt1, struct dvb_frontend *fe) | |||
551 | 604 | ||
552 | adap->pt1 = pt1; | 605 | adap->pt1 = pt1; |
553 | 606 | ||
554 | adap->orig_set_voltage = fe->ops.set_voltage; | 607 | adap->voltage = SEC_VOLTAGE_OFF; |
555 | fe->ops.set_voltage = pt1_set_voltage; | 608 | adap->sleep = 1; |
556 | 609 | ||
557 | buf = (u8 *)__get_free_page(GFP_KERNEL); | 610 | buf = (u8 *)__get_free_page(GFP_KERNEL); |
558 | if (!buf) { | 611 | if (!buf) { |
@@ -593,17 +646,8 @@ pt1_alloc_adapter(struct pt1 *pt1, struct dvb_frontend *fe) | |||
593 | 646 | ||
594 | dvb_net_init(dvb_adap, &adap->net, &demux->dmx); | 647 | dvb_net_init(dvb_adap, &adap->net, &demux->dmx); |
595 | 648 | ||
596 | ret = dvb_register_frontend(dvb_adap, fe); | ||
597 | if (ret < 0) | ||
598 | goto err_net_release; | ||
599 | adap->fe = fe; | ||
600 | |||
601 | return adap; | 649 | return adap; |
602 | 650 | ||
603 | err_net_release: | ||
604 | dvb_net_release(&adap->net); | ||
605 | adap->demux.dmx.close(&adap->demux.dmx); | ||
606 | dvb_dmxdev_release(&adap->dmxdev); | ||
607 | err_dmx_release: | 651 | err_dmx_release: |
608 | dvb_dmx_release(demux); | 652 | dvb_dmx_release(demux); |
609 | err_unregister_adapter: | 653 | err_unregister_adapter: |
@@ -623,6 +667,62 @@ static void pt1_cleanup_adapters(struct pt1 *pt1) | |||
623 | pt1_free_adapter(pt1->adaps[i]); | 667 | pt1_free_adapter(pt1->adaps[i]); |
624 | } | 668 | } |
625 | 669 | ||
670 | static int pt1_init_adapters(struct pt1 *pt1) | ||
671 | { | ||
672 | int i; | ||
673 | struct pt1_adapter *adap; | ||
674 | int ret; | ||
675 | |||
676 | for (i = 0; i < PT1_NR_ADAPS; i++) { | ||
677 | adap = pt1_alloc_adapter(pt1); | ||
678 | if (IS_ERR(adap)) { | ||
679 | ret = PTR_ERR(adap); | ||
680 | goto err; | ||
681 | } | ||
682 | |||
683 | adap->index = i; | ||
684 | pt1->adaps[i] = adap; | ||
685 | } | ||
686 | return 0; | ||
687 | |||
688 | err: | ||
689 | while (i--) | ||
690 | pt1_free_adapter(pt1->adaps[i]); | ||
691 | |||
692 | return ret; | ||
693 | } | ||
694 | |||
695 | static void pt1_cleanup_frontend(struct pt1_adapter *adap) | ||
696 | { | ||
697 | dvb_unregister_frontend(adap->fe); | ||
698 | } | ||
699 | |||
700 | static int pt1_init_frontend(struct pt1_adapter *adap, struct dvb_frontend *fe) | ||
701 | { | ||
702 | int ret; | ||
703 | |||
704 | adap->orig_set_voltage = fe->ops.set_voltage; | ||
705 | adap->orig_sleep = fe->ops.sleep; | ||
706 | adap->orig_init = fe->ops.init; | ||
707 | fe->ops.set_voltage = pt1_set_voltage; | ||
708 | fe->ops.sleep = pt1_sleep; | ||
709 | fe->ops.init = pt1_wakeup; | ||
710 | |||
711 | ret = dvb_register_frontend(&adap->adap, fe); | ||
712 | if (ret < 0) | ||
713 | return ret; | ||
714 | |||
715 | adap->fe = fe; | ||
716 | return 0; | ||
717 | } | ||
718 | |||
719 | static void pt1_cleanup_frontends(struct pt1 *pt1) | ||
720 | { | ||
721 | int i; | ||
722 | for (i = 0; i < PT1_NR_ADAPS; i++) | ||
723 | pt1_cleanup_frontend(pt1->adaps[i]); | ||
724 | } | ||
725 | |||
626 | struct pt1_config { | 726 | struct pt1_config { |
627 | struct va1j5jf8007s_config va1j5jf8007s_config; | 727 | struct va1j5jf8007s_config va1j5jf8007s_config; |
628 | struct va1j5jf8007t_config va1j5jf8007t_config; | 728 | struct va1j5jf8007t_config va1j5jf8007t_config; |
@@ -630,29 +730,63 @@ struct pt1_config { | |||
630 | 730 | ||
631 | static const struct pt1_config pt1_configs[2] = { | 731 | static const struct pt1_config pt1_configs[2] = { |
632 | { | 732 | { |
633 | { .demod_address = 0x1b }, | 733 | { |
634 | { .demod_address = 0x1a }, | 734 | .demod_address = 0x1b, |
735 | .frequency = VA1J5JF8007S_20MHZ, | ||
736 | }, | ||
737 | { | ||
738 | .demod_address = 0x1a, | ||
739 | .frequency = VA1J5JF8007T_20MHZ, | ||
740 | }, | ||
635 | }, { | 741 | }, { |
636 | { .demod_address = 0x19 }, | 742 | { |
637 | { .demod_address = 0x18 }, | 743 | .demod_address = 0x19, |
744 | .frequency = VA1J5JF8007S_20MHZ, | ||
745 | }, | ||
746 | { | ||
747 | .demod_address = 0x18, | ||
748 | .frequency = VA1J5JF8007T_20MHZ, | ||
749 | }, | ||
638 | }, | 750 | }, |
639 | }; | 751 | }; |
640 | 752 | ||
641 | static int pt1_init_adapters(struct pt1 *pt1) | 753 | static const struct pt1_config pt2_configs[2] = { |
754 | { | ||
755 | { | ||
756 | .demod_address = 0x1b, | ||
757 | .frequency = VA1J5JF8007S_25MHZ, | ||
758 | }, | ||
759 | { | ||
760 | .demod_address = 0x1a, | ||
761 | .frequency = VA1J5JF8007T_25MHZ, | ||
762 | }, | ||
763 | }, { | ||
764 | { | ||
765 | .demod_address = 0x19, | ||
766 | .frequency = VA1J5JF8007S_25MHZ, | ||
767 | }, | ||
768 | { | ||
769 | .demod_address = 0x18, | ||
770 | .frequency = VA1J5JF8007T_25MHZ, | ||
771 | }, | ||
772 | }, | ||
773 | }; | ||
774 | |||
775 | static int pt1_init_frontends(struct pt1 *pt1) | ||
642 | { | 776 | { |
643 | int i, j; | 777 | int i, j; |
644 | struct i2c_adapter *i2c_adap; | 778 | struct i2c_adapter *i2c_adap; |
645 | const struct pt1_config *config; | 779 | const struct pt1_config *configs, *config; |
646 | struct dvb_frontend *fe[4]; | 780 | struct dvb_frontend *fe[4]; |
647 | struct pt1_adapter *adap; | ||
648 | int ret; | 781 | int ret; |
649 | 782 | ||
650 | i = 0; | 783 | i = 0; |
651 | j = 0; | 784 | j = 0; |
652 | 785 | ||
653 | i2c_adap = &pt1->i2c_adap; | 786 | i2c_adap = &pt1->i2c_adap; |
787 | configs = pt1->pdev->device == 0x211a ? pt1_configs : pt2_configs; | ||
654 | do { | 788 | do { |
655 | config = &pt1_configs[i / 2]; | 789 | config = &configs[i / 2]; |
656 | 790 | ||
657 | fe[i] = va1j5jf8007s_attach(&config->va1j5jf8007s_config, | 791 | fe[i] = va1j5jf8007s_attach(&config->va1j5jf8007s_config, |
658 | i2c_adap); | 792 | i2c_adap); |
@@ -681,11 +815,9 @@ static int pt1_init_adapters(struct pt1 *pt1) | |||
681 | } while (i < 4); | 815 | } while (i < 4); |
682 | 816 | ||
683 | do { | 817 | do { |
684 | adap = pt1_alloc_adapter(pt1, fe[j]); | 818 | ret = pt1_init_frontend(pt1->adaps[j], fe[j]); |
685 | if (IS_ERR(adap)) | 819 | if (ret < 0) |
686 | goto err; | 820 | goto err; |
687 | adap->index = j; | ||
688 | pt1->adaps[j] = adap; | ||
689 | } while (++j < 4); | 821 | } while (++j < 4); |
690 | 822 | ||
691 | return 0; | 823 | return 0; |
@@ -695,7 +827,7 @@ err: | |||
695 | fe[i]->ops.release(fe[i]); | 827 | fe[i]->ops.release(fe[i]); |
696 | 828 | ||
697 | while (j--) | 829 | while (j--) |
698 | pt1_free_adapter(pt1->adaps[j]); | 830 | dvb_unregister_frontend(fe[j]); |
699 | 831 | ||
700 | return ret; | 832 | return ret; |
701 | } | 833 | } |
@@ -890,9 +1022,12 @@ static void __devexit pt1_remove(struct pci_dev *pdev) | |||
890 | 1022 | ||
891 | kthread_stop(pt1->kthread); | 1023 | kthread_stop(pt1->kthread); |
892 | pt1_cleanup_tables(pt1); | 1024 | pt1_cleanup_tables(pt1); |
893 | pt1_cleanup_adapters(pt1); | 1025 | pt1_cleanup_frontends(pt1); |
894 | pt1_disable_ram(pt1); | 1026 | pt1_disable_ram(pt1); |
895 | pt1_set_power(pt1, 0, 0, 1); | 1027 | pt1->power = 0; |
1028 | pt1->reset = 1; | ||
1029 | pt1_update_power(pt1); | ||
1030 | pt1_cleanup_adapters(pt1); | ||
896 | i2c_del_adapter(&pt1->i2c_adap); | 1031 | i2c_del_adapter(&pt1->i2c_adap); |
897 | pci_set_drvdata(pdev, NULL); | 1032 | pci_set_drvdata(pdev, NULL); |
898 | kfree(pt1); | 1033 | kfree(pt1); |
@@ -936,10 +1071,21 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
936 | goto err_pci_iounmap; | 1071 | goto err_pci_iounmap; |
937 | } | 1072 | } |
938 | 1073 | ||
1074 | mutex_init(&pt1->lock); | ||
939 | pt1->pdev = pdev; | 1075 | pt1->pdev = pdev; |
940 | pt1->regs = regs; | 1076 | pt1->regs = regs; |
941 | pci_set_drvdata(pdev, pt1); | 1077 | pci_set_drvdata(pdev, pt1); |
942 | 1078 | ||
1079 | ret = pt1_init_adapters(pt1); | ||
1080 | if (ret < 0) | ||
1081 | goto err_kfree; | ||
1082 | |||
1083 | mutex_init(&pt1->lock); | ||
1084 | |||
1085 | pt1->power = 0; | ||
1086 | pt1->reset = 1; | ||
1087 | pt1_update_power(pt1); | ||
1088 | |||
943 | i2c_adap = &pt1->i2c_adap; | 1089 | i2c_adap = &pt1->i2c_adap; |
944 | i2c_adap->class = I2C_CLASS_TV_DIGITAL; | 1090 | i2c_adap->class = I2C_CLASS_TV_DIGITAL; |
945 | i2c_adap->algo = &pt1_i2c_algo; | 1091 | i2c_adap->algo = &pt1_i2c_algo; |
@@ -948,9 +1094,7 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
948 | i2c_set_adapdata(i2c_adap, pt1); | 1094 | i2c_set_adapdata(i2c_adap, pt1); |
949 | ret = i2c_add_adapter(i2c_adap); | 1095 | ret = i2c_add_adapter(i2c_adap); |
950 | if (ret < 0) | 1096 | if (ret < 0) |
951 | goto err_kfree; | 1097 | goto err_pt1_cleanup_adapters; |
952 | |||
953 | pt1_set_power(pt1, 0, 0, 1); | ||
954 | 1098 | ||
955 | pt1_i2c_init(pt1); | 1099 | pt1_i2c_init(pt1); |
956 | pt1_i2c_wait(pt1); | 1100 | pt1_i2c_wait(pt1); |
@@ -979,19 +1123,21 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
979 | 1123 | ||
980 | pt1_init_streams(pt1); | 1124 | pt1_init_streams(pt1); |
981 | 1125 | ||
982 | pt1_set_power(pt1, 1, 0, 1); | 1126 | pt1->power = 1; |
1127 | pt1_update_power(pt1); | ||
983 | schedule_timeout_uninterruptible((HZ + 49) / 50); | 1128 | schedule_timeout_uninterruptible((HZ + 49) / 50); |
984 | 1129 | ||
985 | pt1_set_power(pt1, 1, 0, 0); | 1130 | pt1->reset = 0; |
1131 | pt1_update_power(pt1); | ||
986 | schedule_timeout_uninterruptible((HZ + 999) / 1000); | 1132 | schedule_timeout_uninterruptible((HZ + 999) / 1000); |
987 | 1133 | ||
988 | ret = pt1_init_adapters(pt1); | 1134 | ret = pt1_init_frontends(pt1); |
989 | if (ret < 0) | 1135 | if (ret < 0) |
990 | goto err_pt1_disable_ram; | 1136 | goto err_pt1_disable_ram; |
991 | 1137 | ||
992 | ret = pt1_init_tables(pt1); | 1138 | ret = pt1_init_tables(pt1); |
993 | if (ret < 0) | 1139 | if (ret < 0) |
994 | goto err_pt1_cleanup_adapters; | 1140 | goto err_pt1_cleanup_frontends; |
995 | 1141 | ||
996 | kthread = kthread_run(pt1_thread, pt1, "pt1"); | 1142 | kthread = kthread_run(pt1_thread, pt1, "pt1"); |
997 | if (IS_ERR(kthread)) { | 1143 | if (IS_ERR(kthread)) { |
@@ -1004,11 +1150,15 @@ pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1004 | 1150 | ||
1005 | err_pt1_cleanup_tables: | 1151 | err_pt1_cleanup_tables: |
1006 | pt1_cleanup_tables(pt1); | 1152 | pt1_cleanup_tables(pt1); |
1007 | err_pt1_cleanup_adapters: | 1153 | err_pt1_cleanup_frontends: |
1008 | pt1_cleanup_adapters(pt1); | 1154 | pt1_cleanup_frontends(pt1); |
1009 | err_pt1_disable_ram: | 1155 | err_pt1_disable_ram: |
1010 | pt1_disable_ram(pt1); | 1156 | pt1_disable_ram(pt1); |
1011 | pt1_set_power(pt1, 0, 0, 1); | 1157 | pt1->power = 0; |
1158 | pt1->reset = 1; | ||
1159 | pt1_update_power(pt1); | ||
1160 | err_pt1_cleanup_adapters: | ||
1161 | pt1_cleanup_adapters(pt1); | ||
1012 | err_i2c_del_adapter: | 1162 | err_i2c_del_adapter: |
1013 | i2c_del_adapter(i2c_adap); | 1163 | i2c_del_adapter(i2c_adap); |
1014 | err_kfree: | 1164 | err_kfree: |
@@ -1027,6 +1177,7 @@ err: | |||
1027 | 1177 | ||
1028 | static struct pci_device_id pt1_id_table[] = { | 1178 | static struct pci_device_id pt1_id_table[] = { |
1029 | { PCI_DEVICE(0x10ee, 0x211a) }, | 1179 | { PCI_DEVICE(0x10ee, 0x211a) }, |
1180 | { PCI_DEVICE(0x10ee, 0x222a) }, | ||
1030 | { }, | 1181 | { }, |
1031 | }; | 1182 | }; |
1032 | MODULE_DEVICE_TABLE(pci, pt1_id_table); | 1183 | MODULE_DEVICE_TABLE(pci, pt1_id_table); |
@@ -1054,5 +1205,5 @@ module_init(pt1_init); | |||
1054 | module_exit(pt1_cleanup); | 1205 | module_exit(pt1_cleanup); |
1055 | 1206 | ||
1056 | MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>"); | 1207 | MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>"); |
1057 | MODULE_DESCRIPTION("Earthsoft PT1 Driver"); | 1208 | MODULE_DESCRIPTION("Earthsoft PT1/PT2 Driver"); |
1058 | MODULE_LICENSE("GPL"); | 1209 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.c b/drivers/media/dvb/pt1/va1j5jf8007s.c index fc6594996e79..451641c0c1d2 100644 --- a/drivers/media/dvb/pt1/va1j5jf8007s.c +++ b/drivers/media/dvb/pt1/va1j5jf8007s.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * ISDB-S driver for VA1J5JF8007 | 2 | * ISDB-S driver for VA1J5JF8007/VA1J5JF8011 |
3 | * | 3 | * |
4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> | 4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> |
5 | * | 5 | * |
@@ -580,7 +580,7 @@ static void va1j5jf8007s_release(struct dvb_frontend *fe) | |||
580 | 580 | ||
581 | static struct dvb_frontend_ops va1j5jf8007s_ops = { | 581 | static struct dvb_frontend_ops va1j5jf8007s_ops = { |
582 | .info = { | 582 | .info = { |
583 | .name = "VA1J5JF8007 ISDB-S", | 583 | .name = "VA1J5JF8007/VA1J5JF8011 ISDB-S", |
584 | .type = FE_QPSK, | 584 | .type = FE_QPSK, |
585 | .frequency_min = 950000, | 585 | .frequency_min = 950000, |
586 | .frequency_max = 2150000, | 586 | .frequency_max = 2150000, |
@@ -628,28 +628,50 @@ static int va1j5jf8007s_prepare_1(struct va1j5jf8007s_state *state) | |||
628 | return 0; | 628 | return 0; |
629 | } | 629 | } |
630 | 630 | ||
631 | static const u8 va1j5jf8007s_prepare_bufs[][2] = { | 631 | static const u8 va1j5jf8007s_20mhz_prepare_bufs[][2] = { |
632 | {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, | 632 | {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, |
633 | {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, | 633 | {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, |
634 | {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, | 634 | {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, |
635 | {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0}, | 635 | {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0}, |
636 | }; | 636 | }; |
637 | 637 | ||
638 | static const u8 va1j5jf8007s_25mhz_prepare_bufs[][2] = { | ||
639 | {0x04, 0x02}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, {0x1c, 0x0a}, | ||
640 | {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, {0x52, 0x89}, | ||
641 | {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, {0x87, 0x04}, | ||
642 | {0x8e, 0x26}, {0xa3, 0xf7}, {0xa5, 0xc0}, | ||
643 | }; | ||
644 | |||
638 | static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state *state) | 645 | static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state *state) |
639 | { | 646 | { |
647 | const u8 (*bufs)[2]; | ||
648 | int size; | ||
640 | u8 addr; | 649 | u8 addr; |
641 | u8 buf[2]; | 650 | u8 buf[2]; |
642 | struct i2c_msg msg; | 651 | struct i2c_msg msg; |
643 | int i; | 652 | int i; |
644 | 653 | ||
654 | switch (state->config->frequency) { | ||
655 | case VA1J5JF8007S_20MHZ: | ||
656 | bufs = va1j5jf8007s_20mhz_prepare_bufs; | ||
657 | size = ARRAY_SIZE(va1j5jf8007s_20mhz_prepare_bufs); | ||
658 | break; | ||
659 | case VA1J5JF8007S_25MHZ: | ||
660 | bufs = va1j5jf8007s_25mhz_prepare_bufs; | ||
661 | size = ARRAY_SIZE(va1j5jf8007s_25mhz_prepare_bufs); | ||
662 | break; | ||
663 | default: | ||
664 | return -EINVAL; | ||
665 | } | ||
666 | |||
645 | addr = state->config->demod_address; | 667 | addr = state->config->demod_address; |
646 | 668 | ||
647 | msg.addr = addr; | 669 | msg.addr = addr; |
648 | msg.flags = 0; | 670 | msg.flags = 0; |
649 | msg.len = 2; | 671 | msg.len = 2; |
650 | msg.buf = buf; | 672 | msg.buf = buf; |
651 | for (i = 0; i < ARRAY_SIZE(va1j5jf8007s_prepare_bufs); i++) { | 673 | for (i = 0; i < size; i++) { |
652 | memcpy(buf, va1j5jf8007s_prepare_bufs[i], sizeof(buf)); | 674 | memcpy(buf, bufs[i], sizeof(buf)); |
653 | if (i2c_transfer(state->adap, &msg, 1) != 1) | 675 | if (i2c_transfer(state->adap, &msg, 1) != 1) |
654 | return -EREMOTEIO; | 676 | return -EREMOTEIO; |
655 | } | 677 | } |
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.h b/drivers/media/dvb/pt1/va1j5jf8007s.h index aa228a816353..b7d6f05a0e02 100644 --- a/drivers/media/dvb/pt1/va1j5jf8007s.h +++ b/drivers/media/dvb/pt1/va1j5jf8007s.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * ISDB-S driver for VA1J5JF8007 | 2 | * ISDB-S driver for VA1J5JF8007/VA1J5JF8011 |
3 | * | 3 | * |
4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> | 4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> |
5 | * | 5 | * |
@@ -24,8 +24,14 @@ | |||
24 | #ifndef VA1J5JF8007S_H | 24 | #ifndef VA1J5JF8007S_H |
25 | #define VA1J5JF8007S_H | 25 | #define VA1J5JF8007S_H |
26 | 26 | ||
27 | enum va1j5jf8007s_frequency { | ||
28 | VA1J5JF8007S_20MHZ, | ||
29 | VA1J5JF8007S_25MHZ, | ||
30 | }; | ||
31 | |||
27 | struct va1j5jf8007s_config { | 32 | struct va1j5jf8007s_config { |
28 | u8 demod_address; | 33 | u8 demod_address; |
34 | enum va1j5jf8007s_frequency frequency; | ||
29 | }; | 35 | }; |
30 | 36 | ||
31 | struct i2c_adapter; | 37 | struct i2c_adapter; |
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.c b/drivers/media/dvb/pt1/va1j5jf8007t.c index 3db4f3e34e8f..0f085c3e571b 100644 --- a/drivers/media/dvb/pt1/va1j5jf8007t.c +++ b/drivers/media/dvb/pt1/va1j5jf8007t.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * ISDB-T driver for VA1J5JF8007 | 2 | * ISDB-T driver for VA1J5JF8007/VA1J5JF8011 |
3 | * | 3 | * |
4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> | 4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> |
5 | * | 5 | * |
@@ -429,7 +429,7 @@ static void va1j5jf8007t_release(struct dvb_frontend *fe) | |||
429 | 429 | ||
430 | static struct dvb_frontend_ops va1j5jf8007t_ops = { | 430 | static struct dvb_frontend_ops va1j5jf8007t_ops = { |
431 | .info = { | 431 | .info = { |
432 | .name = "VA1J5JF8007 ISDB-T", | 432 | .name = "VA1J5JF8007/VA1J5JF8011 ISDB-T", |
433 | .type = FE_OFDM, | 433 | .type = FE_OFDM, |
434 | .frequency_min = 90000000, | 434 | .frequency_min = 90000000, |
435 | .frequency_max = 770000000, | 435 | .frequency_max = 770000000, |
@@ -448,29 +448,50 @@ static struct dvb_frontend_ops va1j5jf8007t_ops = { | |||
448 | .release = va1j5jf8007t_release, | 448 | .release = va1j5jf8007t_release, |
449 | }; | 449 | }; |
450 | 450 | ||
451 | static const u8 va1j5jf8007t_prepare_bufs[][2] = { | 451 | static const u8 va1j5jf8007t_20mhz_prepare_bufs[][2] = { |
452 | {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, | 452 | {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, |
453 | {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00}, | 453 | {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00}, |
454 | {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03}, | 454 | {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03}, |
455 | {0xef, 0x01} | 455 | {0xef, 0x01} |
456 | }; | 456 | }; |
457 | 457 | ||
458 | static const u8 va1j5jf8007t_25mhz_prepare_bufs[][2] = { | ||
459 | {0x03, 0x90}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, {0x22, 0x83}, | ||
460 | {0x3a, 0x00}, {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x0a}, {0x76, 0x4c}, | ||
461 | {0x77, 0x03}, {0xef, 0x01} | ||
462 | }; | ||
463 | |||
458 | int va1j5jf8007t_prepare(struct dvb_frontend *fe) | 464 | int va1j5jf8007t_prepare(struct dvb_frontend *fe) |
459 | { | 465 | { |
460 | struct va1j5jf8007t_state *state; | 466 | struct va1j5jf8007t_state *state; |
467 | const u8 (*bufs)[2]; | ||
468 | int size; | ||
461 | u8 buf[2]; | 469 | u8 buf[2]; |
462 | struct i2c_msg msg; | 470 | struct i2c_msg msg; |
463 | int i; | 471 | int i; |
464 | 472 | ||
465 | state = fe->demodulator_priv; | 473 | state = fe->demodulator_priv; |
466 | 474 | ||
475 | switch (state->config->frequency) { | ||
476 | case VA1J5JF8007T_20MHZ: | ||
477 | bufs = va1j5jf8007t_20mhz_prepare_bufs; | ||
478 | size = ARRAY_SIZE(va1j5jf8007t_20mhz_prepare_bufs); | ||
479 | break; | ||
480 | case VA1J5JF8007T_25MHZ: | ||
481 | bufs = va1j5jf8007t_25mhz_prepare_bufs; | ||
482 | size = ARRAY_SIZE(va1j5jf8007t_25mhz_prepare_bufs); | ||
483 | break; | ||
484 | default: | ||
485 | return -EINVAL; | ||
486 | } | ||
487 | |||
467 | msg.addr = state->config->demod_address; | 488 | msg.addr = state->config->demod_address; |
468 | msg.flags = 0; | 489 | msg.flags = 0; |
469 | msg.len = sizeof(buf); | 490 | msg.len = sizeof(buf); |
470 | msg.buf = buf; | 491 | msg.buf = buf; |
471 | 492 | ||
472 | for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_prepare_bufs); i++) { | 493 | for (i = 0; i < size; i++) { |
473 | memcpy(buf, va1j5jf8007t_prepare_bufs[i], sizeof(buf)); | 494 | memcpy(buf, bufs[i], sizeof(buf)); |
474 | if (i2c_transfer(state->adap, &msg, 1) != 1) | 495 | if (i2c_transfer(state->adap, &msg, 1) != 1) |
475 | return -EREMOTEIO; | 496 | return -EREMOTEIO; |
476 | } | 497 | } |
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.h b/drivers/media/dvb/pt1/va1j5jf8007t.h index ed49906f7769..2903be519ef5 100644 --- a/drivers/media/dvb/pt1/va1j5jf8007t.h +++ b/drivers/media/dvb/pt1/va1j5jf8007t.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * ISDB-T driver for VA1J5JF8007 | 2 | * ISDB-T driver for VA1J5JF8007/VA1J5JF8011 |
3 | * | 3 | * |
4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> | 4 | * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> |
5 | * | 5 | * |
@@ -24,8 +24,14 @@ | |||
24 | #ifndef VA1J5JF8007T_H | 24 | #ifndef VA1J5JF8007T_H |
25 | #define VA1J5JF8007T_H | 25 | #define VA1J5JF8007T_H |
26 | 26 | ||
27 | enum va1j5jf8007t_frequency { | ||
28 | VA1J5JF8007T_20MHZ, | ||
29 | VA1J5JF8007T_25MHZ, | ||
30 | }; | ||
31 | |||
27 | struct va1j5jf8007t_config { | 32 | struct va1j5jf8007t_config { |
28 | u8 demod_address; | 33 | u8 demod_address; |
34 | enum va1j5jf8007t_frequency frequency; | ||
29 | }; | 35 | }; |
30 | 36 | ||
31 | struct i2c_adapter; | 37 | struct i2c_adapter; |