diff 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
line wrap: on
line diff
--- a/driver/pt1_pci.c	Mon Feb 23 03:06:17 2009 +0900
+++ b/driver/pt1_pci.c	Mon Feb 23 14:28:35 2009 +0900
@@ -67,13 +67,13 @@
 #define		DEV_NAME	"pt1video"
 
 #define		MAX_READ_BLOCK	4			// 1度に読み出す最大DMAバッファ数
-#define		MAX_PCI_DEVICE		64		// 最大64枚
+#define		MAX_PCI_DEVICE		128		// 最大64枚
 #define		DMA_SIZE	4096			// DMAバッファサイズ
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) 
-#define		DMA_RING_SIZE	64			// RINGサイズ
+#define		DMA_RING_SIZE	128			// RINGサイズ
 #define		DMA_RING_MAX	511			// 1RINGにいくつ詰めるか(1023はNGで511まで)
-#define		CHANEL_DMA_SIZE	(1*1024*1024)	// 地デジ用(16Mbps)
-#define		BS_CHANEL_DMA_SIZE	(1*1024*1024)	// BS用(32Mbps)
+#define		CHANEL_DMA_SIZE	(2*1024*1024)	// 地デジ用(16Mbps)
+#define		BS_CHANEL_DMA_SIZE	(4*1024*1024)	// BS用(32Mbps)
 #else
 #define		DMA_RING_SIZE	28			// RINGサイズ
 #define		DMA_RING_MAX	511			// 1RINGにいくつ詰めるか(1023はNGで511まで)
@@ -136,6 +136,7 @@
 									CHANNEL_TYPE_ISDB_T, CHANNEL_TYPE_ISDB_T};
 
 static	PT1_DEVICE	*device[MAX_PCI_DEVICE];
+static struct class	*pt1video_class;
 
 #define		PT1MAJOR	251
 #define		DRIVERNAME	"pt1video"
@@ -153,10 +154,7 @@
 	for(ring_pos = 0 ; ring_pos < DMA_RING_SIZE ; ring_pos++){
 		for(data_pos = 0 ; data_pos < DMA_RING_MAX ; data_pos++){
 			dataptr = dev_conf->dmactl[ring_pos].data[data_pos];
-			// データあり?
-			if(dataptr[(DMA_SIZE / sizeof(__u32)) - 2] == 0){
-				break ;
-			}
+			dataptr[(DMA_SIZE / sizeof(__u32)) - 2] = 0;
 		}
 	}
 	// 転送カウンタをリセット
@@ -295,15 +293,11 @@
 		if(device[lp] == NULL){
 			return -EIO ;
 		}
-		printk(KERN_INFO "(%d)base_minor=%d: MAX=%d(%d)\n",
-				lp, device[lp]->base_minor,
-				(device[lp]->base_minor + MAX_CHANNEL), minor);
 		if((device[lp]->base_minor <= minor) &&
 			((device[lp]->base_minor + MAX_CHANNEL) > minor)){
 			mutex_lock(&device[lp]->lock);
 			for(lp2 = 0 ; lp2 < MAX_CHANNEL ; lp2++){
 				channel = device[lp]->channel[lp2] ;
-				printk(KERN_INFO "Minor(%d:%d)\n", channel->minor, minor);
 				if(channel->minor == minor){
 					if(channel->valid == TRUE){
 						mutex_unlock(&device[lp]->lock);
@@ -378,7 +372,7 @@
 		}
 	}
 	// 読み終わったかつ使用しているのがが4K以下
-	if((channel->req_dma == TRUE) && (channel->size < DMA_SIZE)){
+	if(channel->req_dma == TRUE){
 		channel->req_dma = FALSE ;
 		wake_up(&channel->ptr->dma_wait_q);
 	}
@@ -392,8 +386,6 @@
 		case CHANNEL_TYPE_ISDB_S:
 			{
 				ISDB_S_TMCC		tmcc ;
-				int				lp ;
-
 				if(bs_tune(channel->ptr->regs,
 						&channel->ptr->lock,
 						channel->address,
@@ -401,9 +393,6 @@
 						&tmcc) < 0){
 					return -EIO ;
 				}
-				printk(KERN_INFO "cn = (%x:%x)\n", (tmcc.cn[0] & 0xFF),
-						(tmcc.cn[1] & 0xFF));
-				printk(KERN_INFO "agc = (%x)\n", (tmcc.agc & 0xFF));
 
 #if 0
 				printk(KERN_INFO "clockmargin = (%x)\n", (tmcc.clockmargin & 0xFF));
@@ -442,6 +431,7 @@
 static	int	pt1_ioctl(struct inode *inode, struct file  *file, unsigned int cmd, void *arg)
 {
 	PT1_CHANNEL	*channel = file->private_data;
+	int			signal ;
 
 	switch(cmd){
 		case SET_CHANNEL:
@@ -456,6 +446,33 @@
 		case STOP_REC:
 			SetStream(channel->ptr->regs, channel->channel, FALSE);
 			return 0 ;
+		case GET_SIGNAL_STRENGTH:
+			switch(channel->type){
+				case CHANNEL_TYPE_ISDB_S:
+					{
+						signal = isdb_s_read_signal_strength(channel->ptr->regs,
+													&channel->ptr->lock,
+													channel->address);
+					}
+					break ;
+				case CHANNEL_TYPE_ISDB_T:
+                	// calc C/N
+					signal = isdb_t_read_signal_strength(channel->ptr->regs, 
+												&channel->ptr->lock, channel->address);
+					break ;
+			}
+			copy_to_user(arg, &signal, sizeof(int));
+			return 0 ;
+		case LNB_ENABLE:
+			if(lnb){
+				settuner_reset(channel->ptr->regs, lnb, TUNER_POWER_ON_RESET_DISABLE);
+			}
+			return 0 ;
+		case LNB_DISABLE:
+			if(lnb){
+				settuner_reset(channel->ptr->regs, LNB_OFF, TUNER_POWER_ON_RESET_DISABLE);
+			}
+			return 0 ;
 	}
 	return -EINVAL;
 }
@@ -606,7 +623,7 @@
 	settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_ON_RESET_ENABLE);
 	schedule_timeout_interruptible(msecs_to_jiffies(50));
 
-	settuner_reset(dev_conf->regs, lnb, TUNER_POWER_ON_RESET_DISABLE);
+	settuner_reset(dev_conf->regs, LNB_OFF, TUNER_POWER_ON_RESET_DISABLE);
 	schedule_timeout_interruptible(msecs_to_jiffies(10));
 	mutex_init(&dev_conf->lock);
 
@@ -638,7 +655,6 @@
 	for(lp = 0 ; lp < MAX_PCI_DEVICE ; lp++){
 		if(device[lp] == NULL){
 			device[lp] = dev_conf ;
-			printk(KERN_INFO "Alloc[%d]\n", lp);
 			break ;
 		}
 	}
@@ -657,7 +673,6 @@
 		channel->req_dma = FALSE ;
 		// マイナー番号設定
 		channel->minor = MINOR(dev_conf->dev) + lp ;
-		printk(KERN_INFO "Minor[%d]\n", channel->minor);
 		// 対象のI2Cデバイス
 		channel->address = i2c_address[lp] ;
 		channel->type = channeltype[lp] ;
@@ -682,6 +697,16 @@
 		if(channel->buf == NULL){
 			goto out_err_v4l;
 		}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+		device_create(pt1video_class, NULL, MKDEV(MAJOR(dev_conf->dev),
+						(MINOR(dev_conf->dev) + lp)), NULL,
+						"pt1video%u", MINOR(dev_conf->dev) + lp);
+#else
+		device_create(pt1video_class, NULL, MKDEV(MAJOR(dev_conf->dev),
+						(MINOR(dev_conf->dev) + lp)),
+						"pt1video%u", MINOR(dev_conf->dev) + lp);
+#endif
+
 #if 0
 		dev_conf->vdev[lp] = video_device_alloc();
 		memcpy(dev_conf->vdev[lp], &pt1_template, sizeof(pt1_template));
@@ -747,6 +772,8 @@
 				kfree(dev_conf->channel[lp]->buf);
 				kfree(dev_conf->channel[lp]);
 			}
+			device_destroy(pt1video_class, 
+							MKDEV(MAJOR(dev_conf->dev), (MINOR(dev_conf->dev) + lp)));
 		}
 		unregister_chrdev_region(dev_conf->dev, MAX_CHANNEL);
 		writel(0xb0b0000, dev_conf->regs);
@@ -788,12 +815,16 @@
 
 static int __init pt1_pci_init(void)
 {
+	pt1video_class = class_create(THIS_MODULE, DRIVERNAME);
+	if (IS_ERR(pt1video_class))
+		return PTR_ERR(pt1video_class);
 	return pci_register_driver(&pt1_driver);
 }
 
 
 static void __exit pt1_pci_cleanup(void)
 {
+	class_destroy(pt1video_class);
 	pci_unregister_driver (&pt1_driver);
 }