comparison driver/pt1_pci.c @ 9:07b2fc07ff48

updated to current driver to support signal strength.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Mon, 23 Feb 2009 14:28:35 +0900
parents 67e8eca28a80
children eb694d8e4c7e
comparison
equal deleted inserted replaced
8:6da603afd363 9:07b2fc07ff48
65 }; 65 };
66 MODULE_DEVICE_TABLE(pci, pt1_pci_tbl); 66 MODULE_DEVICE_TABLE(pci, pt1_pci_tbl);
67 #define DEV_NAME "pt1video" 67 #define DEV_NAME "pt1video"
68 68
69 #define MAX_READ_BLOCK 4 // 1度に読み出す最大DMAバッファ数 69 #define MAX_READ_BLOCK 4 // 1度に読み出す最大DMAバッファ数
70 #define MAX_PCI_DEVICE 64 // 最大64枚 70 #define MAX_PCI_DEVICE 128 // 最大64枚
71 #define DMA_SIZE 4096 // DMAバッファサイズ 71 #define DMA_SIZE 4096 // DMAバッファサイズ
72 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) 72 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
73 #define DMA_RING_SIZE 64 // RINGサイズ 73 #define DMA_RING_SIZE 128 // RINGサイズ
74 #define DMA_RING_MAX 511 // 1RINGにいくつ詰めるか(1023はNGで511まで) 74 #define DMA_RING_MAX 511 // 1RINGにいくつ詰めるか(1023はNGで511まで)
75 #define CHANEL_DMA_SIZE (1*1024*1024) // 地デジ用(16Mbps) 75 #define CHANEL_DMA_SIZE (2*1024*1024) // 地デジ用(16Mbps)
76 #define BS_CHANEL_DMA_SIZE (1*1024*1024) // BS用(32Mbps) 76 #define BS_CHANEL_DMA_SIZE (4*1024*1024) // BS用(32Mbps)
77 #else 77 #else
78 #define DMA_RING_SIZE 28 // RINGサイズ 78 #define DMA_RING_SIZE 28 // RINGサイズ
79 #define DMA_RING_MAX 511 // 1RINGにいくつ詰めるか(1023はNGで511まで) 79 #define DMA_RING_MAX 511 // 1RINGにいくつ詰めるか(1023はNGで511まで)
80 #define CHANEL_DMA_SIZE (1*128*1024) // 地デジ用(16Mbps) 80 #define CHANEL_DMA_SIZE (1*128*1024) // 地デジ用(16Mbps)
81 #define BS_CHANEL_DMA_SIZE (1*128*1024) // BS用(32Mbps) 81 #define BS_CHANEL_DMA_SIZE (1*128*1024) // BS用(32Mbps)
134 int real_chanel[MAX_CHANNEL] = {0, 2, 1, 3}; 134 int real_chanel[MAX_CHANNEL] = {0, 2, 1, 3};
135 int channeltype[MAX_CHANNEL] = {CHANNEL_TYPE_ISDB_S, CHANNEL_TYPE_ISDB_S, 135 int channeltype[MAX_CHANNEL] = {CHANNEL_TYPE_ISDB_S, CHANNEL_TYPE_ISDB_S,
136 CHANNEL_TYPE_ISDB_T, CHANNEL_TYPE_ISDB_T}; 136 CHANNEL_TYPE_ISDB_T, CHANNEL_TYPE_ISDB_T};
137 137
138 static PT1_DEVICE *device[MAX_PCI_DEVICE]; 138 static PT1_DEVICE *device[MAX_PCI_DEVICE];
139 static struct class *pt1video_class;
139 140
140 #define PT1MAJOR 251 141 #define PT1MAJOR 251
141 #define DRIVERNAME "pt1video" 142 #define DRIVERNAME "pt1video"
142 143
143 static void reset_dma(PT1_DEVICE *dev_conf) 144 static void reset_dma(PT1_DEVICE *dev_conf)
151 152
152 // データ初期化 153 // データ初期化
153 for(ring_pos = 0 ; ring_pos < DMA_RING_SIZE ; ring_pos++){ 154 for(ring_pos = 0 ; ring_pos < DMA_RING_SIZE ; ring_pos++){
154 for(data_pos = 0 ; data_pos < DMA_RING_MAX ; data_pos++){ 155 for(data_pos = 0 ; data_pos < DMA_RING_MAX ; data_pos++){
155 dataptr = dev_conf->dmactl[ring_pos].data[data_pos]; 156 dataptr = dev_conf->dmactl[ring_pos].data[data_pos];
156 // データあり? 157 dataptr[(DMA_SIZE / sizeof(__u32)) - 2] = 0;
157 if(dataptr[(DMA_SIZE / sizeof(__u32)) - 2] == 0){
158 break ;
159 }
160 } 158 }
161 } 159 }
162 // 転送カウンタをリセット 160 // 転送カウンタをリセット
163 writel(0x00000010, dev_conf->regs); 161 writel(0x00000010, dev_conf->regs);
164 // 転送カウンタをインクリメント 162 // 転送カウンタをインクリメント
293 291
294 for(lp = 0 ; lp < MAX_PCI_DEVICE ; lp++){ 292 for(lp = 0 ; lp < MAX_PCI_DEVICE ; lp++){
295 if(device[lp] == NULL){ 293 if(device[lp] == NULL){
296 return -EIO ; 294 return -EIO ;
297 } 295 }
298 printk(KERN_INFO "(%d)base_minor=%d: MAX=%d(%d)\n",
299 lp, device[lp]->base_minor,
300 (device[lp]->base_minor + MAX_CHANNEL), minor);
301 if((device[lp]->base_minor <= minor) && 296 if((device[lp]->base_minor <= minor) &&
302 ((device[lp]->base_minor + MAX_CHANNEL) > minor)){ 297 ((device[lp]->base_minor + MAX_CHANNEL) > minor)){
303 mutex_lock(&device[lp]->lock); 298 mutex_lock(&device[lp]->lock);
304 for(lp2 = 0 ; lp2 < MAX_CHANNEL ; lp2++){ 299 for(lp2 = 0 ; lp2 < MAX_CHANNEL ; lp2++){
305 channel = device[lp]->channel[lp2] ; 300 channel = device[lp]->channel[lp2] ;
306 printk(KERN_INFO "Minor(%d:%d)\n", channel->minor, minor);
307 if(channel->minor == minor){ 301 if(channel->minor == minor){
308 if(channel->valid == TRUE){ 302 if(channel->valid == TRUE){
309 mutex_unlock(&device[lp]->lock); 303 mutex_unlock(&device[lp]->lock);
310 return -EIO ; 304 return -EIO ;
311 } 305 }
376 copy_to_user(buf, channel->buf, size); 370 copy_to_user(buf, channel->buf, size);
377 channel->size = 0 ; 371 channel->size = 0 ;
378 } 372 }
379 } 373 }
380 // 読み終わったかつ使用しているのがが4K以下 374 // 読み終わったかつ使用しているのがが4K以下
381 if((channel->req_dma == TRUE) && (channel->size < DMA_SIZE)){ 375 if(channel->req_dma == TRUE){
382 channel->req_dma = FALSE ; 376 channel->req_dma = FALSE ;
383 wake_up(&channel->ptr->dma_wait_q); 377 wake_up(&channel->ptr->dma_wait_q);
384 } 378 }
385 mutex_unlock(&channel->lock); 379 mutex_unlock(&channel->lock);
386 return size ; 380 return size ;
390 384
391 switch(channel->type){ 385 switch(channel->type){
392 case CHANNEL_TYPE_ISDB_S: 386 case CHANNEL_TYPE_ISDB_S:
393 { 387 {
394 ISDB_S_TMCC tmcc ; 388 ISDB_S_TMCC tmcc ;
395 int lp ;
396
397 if(bs_tune(channel->ptr->regs, 389 if(bs_tune(channel->ptr->regs,
398 &channel->ptr->lock, 390 &channel->ptr->lock,
399 channel->address, 391 channel->address,
400 freq->frequencyno, 392 freq->frequencyno,
401 &tmcc) < 0){ 393 &tmcc) < 0){
402 return -EIO ; 394 return -EIO ;
403 } 395 }
404 printk(KERN_INFO "cn = (%x:%x)\n", (tmcc.cn[0] & 0xFF),
405 (tmcc.cn[1] & 0xFF));
406 printk(KERN_INFO "agc = (%x)\n", (tmcc.agc & 0xFF));
407 396
408 #if 0 397 #if 0
409 printk(KERN_INFO "clockmargin = (%x)\n", (tmcc.clockmargin & 0xFF)); 398 printk(KERN_INFO "clockmargin = (%x)\n", (tmcc.clockmargin & 0xFF));
410 printk(KERN_INFO "carriermargin = (%x)\n", (tmcc.carriermargin & 0xFF)); 399 printk(KERN_INFO "carriermargin = (%x)\n", (tmcc.carriermargin & 0xFF));
411 400
440 return 0 ; 429 return 0 ;
441 } 430 }
442 static int pt1_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) 431 static int pt1_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg)
443 { 432 {
444 PT1_CHANNEL *channel = file->private_data; 433 PT1_CHANNEL *channel = file->private_data;
434 int signal ;
445 435
446 switch(cmd){ 436 switch(cmd){
447 case SET_CHANNEL: 437 case SET_CHANNEL:
448 { 438 {
449 FREQUENCY freq ; 439 FREQUENCY freq ;
453 case START_REC: 443 case START_REC:
454 SetStream(channel->ptr->regs, channel->channel, TRUE); 444 SetStream(channel->ptr->regs, channel->channel, TRUE);
455 return 0 ; 445 return 0 ;
456 case STOP_REC: 446 case STOP_REC:
457 SetStream(channel->ptr->regs, channel->channel, FALSE); 447 SetStream(channel->ptr->regs, channel->channel, FALSE);
448 return 0 ;
449 case GET_SIGNAL_STRENGTH:
450 switch(channel->type){
451 case CHANNEL_TYPE_ISDB_S:
452 {
453 signal = isdb_s_read_signal_strength(channel->ptr->regs,
454 &channel->ptr->lock,
455 channel->address);
456 }
457 break ;
458 case CHANNEL_TYPE_ISDB_T:
459 // calc C/N
460 signal = isdb_t_read_signal_strength(channel->ptr->regs,
461 &channel->ptr->lock, channel->address);
462 break ;
463 }
464 copy_to_user(arg, &signal, sizeof(int));
465 return 0 ;
466 case LNB_ENABLE:
467 if(lnb){
468 settuner_reset(channel->ptr->regs, lnb, TUNER_POWER_ON_RESET_DISABLE);
469 }
470 return 0 ;
471 case LNB_DISABLE:
472 if(lnb){
473 settuner_reset(channel->ptr->regs, LNB_OFF, TUNER_POWER_ON_RESET_DISABLE);
474 }
458 return 0 ; 475 return 0 ;
459 } 476 }
460 return -EINVAL; 477 return -EINVAL;
461 } 478 }
462 479
604 } 621 }
605 // チューナリセット 622 // チューナリセット
606 settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_ON_RESET_ENABLE); 623 settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_ON_RESET_ENABLE);
607 schedule_timeout_interruptible(msecs_to_jiffies(50)); 624 schedule_timeout_interruptible(msecs_to_jiffies(50));
608 625
609 settuner_reset(dev_conf->regs, lnb, TUNER_POWER_ON_RESET_DISABLE); 626 settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_ON_RESET_DISABLE);
610 schedule_timeout_interruptible(msecs_to_jiffies(10)); 627 schedule_timeout_interruptible(msecs_to_jiffies(10));
611 mutex_init(&dev_conf->lock); 628 mutex_init(&dev_conf->lock);
612 629
613 // Tuner 初期化処理 630 // Tuner 初期化処理
614 for(lp = 0 ; lp < MAX_TUNER ; lp++){ 631 for(lp = 0 ; lp < MAX_TUNER ; lp++){
636 minor = MINOR(dev_conf->dev) ; 653 minor = MINOR(dev_conf->dev) ;
637 dev_conf->base_minor = minor ; 654 dev_conf->base_minor = minor ;
638 for(lp = 0 ; lp < MAX_PCI_DEVICE ; lp++){ 655 for(lp = 0 ; lp < MAX_PCI_DEVICE ; lp++){
639 if(device[lp] == NULL){ 656 if(device[lp] == NULL){
640 device[lp] = dev_conf ; 657 device[lp] = dev_conf ;
641 printk(KERN_INFO "Alloc[%d]\n", lp);
642 break ; 658 break ;
643 } 659 }
644 } 660 }
645 for(lp = 0 ; lp < MAX_CHANNEL ; lp++){ 661 for(lp = 0 ; lp < MAX_CHANNEL ; lp++){
646 cdev_init(&dev_conf->cdev[lp], &pt1_fops); 662 cdev_init(&dev_conf->cdev[lp], &pt1_fops);
655 mutex_init(&channel->lock); 671 mutex_init(&channel->lock);
656 // 待ち状態を解除 672 // 待ち状態を解除
657 channel->req_dma = FALSE ; 673 channel->req_dma = FALSE ;
658 // マイナー番号設定 674 // マイナー番号設定
659 channel->minor = MINOR(dev_conf->dev) + lp ; 675 channel->minor = MINOR(dev_conf->dev) + lp ;
660 printk(KERN_INFO "Minor[%d]\n", channel->minor);
661 // 対象のI2Cデバイス 676 // 対象のI2Cデバイス
662 channel->address = i2c_address[lp] ; 677 channel->address = i2c_address[lp] ;
663 channel->type = channeltype[lp] ; 678 channel->type = channeltype[lp] ;
664 // 実際のチューナ番号 679 // 実際のチューナ番号
665 channel->channel = real_chanel[lp] ; 680 channel->channel = real_chanel[lp] ;
680 break ; 695 break ;
681 } 696 }
682 if(channel->buf == NULL){ 697 if(channel->buf == NULL){
683 goto out_err_v4l; 698 goto out_err_v4l;
684 } 699 }
700 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
701 device_create(pt1video_class, NULL, MKDEV(MAJOR(dev_conf->dev),
702 (MINOR(dev_conf->dev) + lp)), NULL,
703 "pt1video%u", MINOR(dev_conf->dev) + lp);
704 #else
705 device_create(pt1video_class, NULL, MKDEV(MAJOR(dev_conf->dev),
706 (MINOR(dev_conf->dev) + lp)),
707 "pt1video%u", MINOR(dev_conf->dev) + lp);
708 #endif
709
685 #if 0 710 #if 0
686 dev_conf->vdev[lp] = video_device_alloc(); 711 dev_conf->vdev[lp] = video_device_alloc();
687 memcpy(dev_conf->vdev[lp], &pt1_template, sizeof(pt1_template)); 712 memcpy(dev_conf->vdev[lp], &pt1_template, sizeof(pt1_template));
688 video_set_drvdata(dev_conf->vdev[lp], channel); 713 video_set_drvdata(dev_conf->vdev[lp], channel);
689 video_register_device(dev_conf->vdev[lp], VFL_TYPE_GRABBER, -1); 714 video_register_device(dev_conf->vdev[lp], VFL_TYPE_GRABBER, -1);
745 if(dev_conf->channel[lp] != NULL){ 770 if(dev_conf->channel[lp] != NULL){
746 cdev_del(&dev_conf->cdev[lp]); 771 cdev_del(&dev_conf->cdev[lp]);
747 kfree(dev_conf->channel[lp]->buf); 772 kfree(dev_conf->channel[lp]->buf);
748 kfree(dev_conf->channel[lp]); 773 kfree(dev_conf->channel[lp]);
749 } 774 }
775 device_destroy(pt1video_class,
776 MKDEV(MAJOR(dev_conf->dev), (MINOR(dev_conf->dev) + lp)));
750 } 777 }
751 unregister_chrdev_region(dev_conf->dev, MAX_CHANNEL); 778 unregister_chrdev_region(dev_conf->dev, MAX_CHANNEL);
752 writel(0xb0b0000, dev_conf->regs); 779 writel(0xb0b0000, dev_conf->regs);
753 writel(0, dev_conf->regs + 4); 780 writel(0, dev_conf->regs + 4);
754 settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_OFF); 781 settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_OFF);
786 }; 813 };
787 814
788 815
789 static int __init pt1_pci_init(void) 816 static int __init pt1_pci_init(void)
790 { 817 {
818 pt1video_class = class_create(THIS_MODULE, DRIVERNAME);
819 if (IS_ERR(pt1video_class))
820 return PTR_ERR(pt1video_class);
791 return pci_register_driver(&pt1_driver); 821 return pci_register_driver(&pt1_driver);
792 } 822 }
793 823
794 824
795 static void __exit pt1_pci_cleanup(void) 825 static void __exit pt1_pci_cleanup(void)
796 { 826 {
827 class_destroy(pt1video_class);
797 pci_unregister_driver (&pt1_driver); 828 pci_unregister_driver (&pt1_driver);
798 } 829 }
799 830
800 module_init(pt1_pci_init); 831 module_init(pt1_pci_init);
801 module_exit(pt1_pci_cleanup); 832 module_exit(pt1_pci_cleanup);