All pastes #148127 Raw Edit

Stuff

public c v1 · immutable
#148127 ·published 2006-08-24 22:07 UTC
rendered paste body
diff -r 19981e560c9f linux/drivers/media/video/cx88/cx88-alsa.c--- a/linux/drivers/media/video/cx88/cx88-alsa.c	Thu Aug 24 14:08:31 2006 -0700+++ b/linux/drivers/media/video/cx88/cx88-alsa.c	Thu Aug 24 15:04:06 2006 -0700@@ -174,7 +174,7 @@ static int _cx88_start_audio_dma(snd_cx8  	dprintk(1,"Enabling IRQ, setting mask from 0x%x to 0x%x\n",chip->core->pci_irqmask,(chip->core->pci_irqmask | 0x02)); 	/* enable irqs */-	cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | 0x02);+	cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | MO_INT_AUDINT);   	/* Enables corresponding bits at AUD_INT_STAT */@@ -207,7 +207,7 @@ static int _cx88_stop_audio_dma(snd_cx88 	cx_clear(MO_AUD_DMACNTRL, 0x11);  	/* disable irqs */-	cx_clear(MO_PCI_INTMSK, 0x02);+	cx_clear(MO_PCI_INTMSK, MO_INT_AUDINT); 	cx_clear(MO_AUD_INTMSK, 			(1<<16)| 			(1<<12)|@@ -295,7 +295,7 @@ static irqreturn_t cx8801_irq(int irq, v 	int loop, handled = 0;  	for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {-		status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x02);+		status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | MO_INT_AUDINT); 		if (0 == status) 			goto out; 		dprintk( 3, "cx8801_irq\n" );@@ -304,8 +304,9 @@ static irqreturn_t cx8801_irq(int irq, v 		handled = 1; 		cx_write(MO_PCI_INTSTAT, status); -		if (status & 0x02)-		{+		if (status & core->pci_irqmask)+			cx88_core_irq(core, status);+		if (status & MO_INT_AUDINT) { 			dprintk( 2, "    ALSA IRQ handling\n" ); 			cx8801_aud_irq(chip); 		}@@ -822,6 +823,8 @@ static int __devinit snd_cx88_create(str 	chip->irq = pci->irq; 	synchronize_irq(chip->irq); +	/*	I2C Initialization	*/+	cx88_devs_init(core, pci); 	snd_card_set_dev(card, &pci->dev);  	*rchip = chip;diff -r 19981e560c9f linux/drivers/media/video/cx88/cx88-core.c--- a/linux/drivers/media/video/cx88/cx88-core.c	Thu Aug 24 14:08:31 2006 -0700+++ b/linux/drivers/media/video/cx88/cx88-core.c	Thu Aug 24 15:04:06 2006 -0700@@ -548,6 +548,11 @@ int cx88_core_irq(struct cx88_core *core 		cx88_ir_irq(core); 		handled++; 	}+	if (status & (MO_INT_I2CDONE | MO_INT_I2CRACK)) {+		core->int_status = status & (MO_INT_I2CRACK | MO_INT_I2CDONE);+		wake_up(&core->i2c_wq);+		handled++;+	} 	if (!handled) 		cx88_print_irqbits(core->name, "irq pci", 				   cx88_pci_irqs, status,@@ -1110,6 +1115,7 @@ struct cx88_core* cx88_core_get(struct p 	core->pci_bus  = pci->bus->number; 	core->pci_slot = PCI_SLOT(pci->devfn); 	core->pci_irqmask = 0x00fc00;+	core->pci_irqmask = 0x00fc00 | MO_INT_I2CDONE | MO_INT_I2CRACK; 	mutex_init(&core->lock);  	core->nr = cx88_devcount++;@@ -1168,12 +1174,7 @@ struct cx88_core* cx88_core_get(struct p 	core->tda9887_conf = cx88_boards[core->board].tda9887_conf;  	/* init hardware */-	cx88_reset(core);-	cx88_i2c_init(core,pci);-	cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);-	cx88_card_setup(core);-	cx88_ir_init(core,pci);-+	/*	moved alongwith i2c init	*/ 	mutex_unlock(&devlist); 	return core; @@ -1203,6 +1204,21 @@ void cx88_core_put(struct cx88_core *cor 	kfree(core); } +void cx88_devs_init(struct cx88_core *core, struct pci_dev *pci)+{+	/*	init	*/+	if (!core->initialized) {+		init_waitqueue_head(&core->i2c_wq);+		cx88_reset(core);+		cx88_i2c_init(core, pci);+		cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);+		cx88_card_setup(core);+		cx88_ir_init(core, pci);+		core->initialized = 1;+	}+}+EXPORT_SYMBOL(cx88_devs_init);+ /* ------------------------------------------------------------------ */  EXPORT_SYMBOL(cx88_print_irqbits);diff -r 19981e560c9f linux/drivers/media/video/cx88/cx88-i2c.c--- a/linux/drivers/media/video/cx88/cx88-i2c.c	Thu Aug 24 14:08:31 2006 -0700+++ b/linux/drivers/media/video/cx88/cx88-i2c.c	Thu Aug 24 15:04:06 2006 -0700@@ -6,6 +6,7 @@ 			   & Marcus Metzler (mocm@thp.uni-koeln.de)     (c) 2002 Yurij Sysoev <yurij@naturesoft.net>     (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>+    (C) 2006 Manu Abraham <abraham.manu@gmail.com>      This program is free software; you can redistribute it and/or modify     it under the terms of the GNU General Public License as published by@@ -46,6 +47,139 @@ MODULE_PARM_DESC(i2c_scan,"scan i2c bus   #define dprintk(level,fmt, arg...)	if (i2c_debug >= level) \ 	printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)++/* ---------------------------------------------------------------------------- */+/*	CX88 I2C Routines							*/++#define CX88_HW_I2C	(MO_I2C_MODE |	\+			 MO_I2C_SYNC |	\+			 MO_I2C_SCL  |	\+			 MO_I2C_SDA)++static int cx88_ack_wait(struct cx88_core *core)+{+	int ret = 0;++	if (wait_event_interruptible_timeout(core->i2c_wq,+					     core->int_status,+					     msecs_to_jiffies(50)) == -ERESTARTSYS) {++		dprintk(1, "I/O Error\n");+		ret = -EREMOTEIO;+	}+	if (core->int_status & MO_INT_I2CRACK) {+		dprintk(1, "I2CRACK\n");+		core->int_status &= ~MO_INT_I2CRACK;+	} else {+		dprintk(1, "ACK fail\n");+		return -EREMOTEIO;+	}+	if (core->int_status & MO_INT_I2CDONE) {+		dprintk(1, "I2CDONE\n");+		ret = 1;+	}+	core->int_status &= ~MO_INT_I2CDONE;++	return ret;+}++/*	Hardware I2C Enable	*/+static void cx88_i2c_enable(struct cx88_core *core)+{+	cx_set(MO_PCI_INTMSK, MO_INT_I2CDONE | MO_INT_I2CRACK);+}++static int cx88_i2c_write(struct cx88_core *core, const struct i2c_msg *msg, int last)+{+	u32 txd;+	int i;++	if (0 == msg->len)+		return -EINVAL;++	txd = (msg->addr << 25) | (msg->buf[0] << 16)+				| CX88_HW_I2C;++	if (msg->len > 1 || !last)+		txd |= MO_I2C_NOSTOP;+	cx_write(MO_I2C, txd);+	msleep_interruptible(1);+	if (cx88_ack_wait(core) < 0)+		return -EREMOTEIO;++	for (i = 1; i < msg->len; i++) {+		txd = (msg->buf[i] << 24) | CX88_HW_I2C+					  | MO_I2C_NOS1B;++		if (i < msg->len - 1 || !last)+			txd |= MO_I2C_NOSTOP;+		cx_write(MO_I2C, txd);+		if (cx88_ack_wait(core) < 0)+			return -EREMOTEIO;+	}+	return msg->len;+}++static int cx88_i2c_read(struct cx88_core *core, const struct i2c_msg *msg, int last)+{+	u32 txd, i;++	for (i = 0; i < msg->len; i++) {+		txd = (msg->addr << 25) | (1 << 24)+					| CX88_HW_I2C;++		if (i < msg->len - 1)+			txd |= MO_I2C_W3BRA;+		if (i < msg->len - 1 || !last)+			txd |= MO_I2C_NOSTOP;+		if (i)+			txd |= MO_I2C_NOS1B;++		cx_write(MO_I2C, txd);+		msleep_interruptible(1);+		if (cx88_ack_wait(core) < 0)+			return -EREMOTEIO;++		msg->buf[i] = ((u32) cx_read(MO_I2C) >> 8) & 0xff;+	}+	return msg->len;+}++static int cx88_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)+{+	struct cx88_core *core = i2c_get_adapdata(adapter);+	int ret = 0;+	int i;++	for (i = 0 ; i < num; i++) {+		if (msgs[i].flags & I2C_M_RD)+			ret = cx88_i2c_read(core, &msgs[i], i + 1 == num);+		else+			ret = cx88_i2c_write(core, &msgs[i], i + 1 == num);+		if (ret < 0)+			return ret;+	}+	return num;+}++static u32 cx88_i2c_func(struct i2c_adapter *adapter)+{+	return I2C_FUNC_SMBUS_EMUL;+}++#define I2C_HW_B_CX88		0x1c++static struct i2c_algorithm cx88_i2c_algo = {+	.master_xfer		= cx88_i2c_xfer,+	.functionality		= cx88_i2c_func,+};++static struct i2c_adapter cx88_i2c_adapter = {+	.owner			= THIS_MODULE,+	.name			= "CX88 I2C",+	.id			= I2C_HW_B_CX88,+	.algo			= &cx88_i2c_algo,+};  /* ----------------------------------------------------------------------- */ @@ -92,7 +226,6 @@ static int cx8800_bit_getsda(void *data) }  /* ----------------------------------------------------------------------- */- static int attach_inform(struct i2c_client *client) { 	struct tuner_setup tun_setup;@@ -159,6 +292,7 @@ void cx88_call_i2c_clients(struct cx88_c #endif 		i2c_clients_command(&core->i2c_adap, cmd, arg); }+EXPORT_SYMBOL(cx88_call_i2c_clients);  static struct i2c_algo_bit_data cx8800_i2c_algo_template = { 	.setsda  = cx8800_bit_setsda,@@ -212,16 +346,43 @@ static void do_i2c_scan(char *name, stru /* init + register i2c algo-bit adapter */ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) {-	memcpy(&core->i2c_adap, &cx8800_i2c_adap_template,-	       sizeof(core->i2c_adap));-	memcpy(&core->i2c_algo, &cx8800_i2c_algo_template,-	       sizeof(core->i2c_algo));-	memcpy(&core->i2c_client, &cx8800_i2c_client_template,-	       sizeof(core->i2c_client));-+	core->i2c_hw = 1; // Temporary testing+	if (core->i2c_hw) {+		dprintk(1, "I2C intializing\n");+		core->int_status = 0;+		memcpy(&core->i2c_adap, &cx88_i2c_adapter,+		       sizeof (struct i2c_adapter));++		memcpy(&core->i2c_client, &cx8800_i2c_client_template,+			sizeof (core->i2c_client));++		i2c_set_adapdata(&core->i2c_adap, core);+		core->i2c_algo.data = core;+		core->i2c_client.adapter = &core->i2c_adap;+		core->i2c_rc = i2c_add_adapter(&core->i2c_adap);+		cx88_i2c_enable(core);+	} else {+		dprintk(1, "Bitbanging initializing\n");+		memcpy(&core->i2c_adap, &cx8800_i2c_adap_template,+			sizeof(core->i2c_adap));++		memcpy(&core->i2c_algo, &cx8800_i2c_algo_template,+			sizeof(core->i2c_algo));+		memcpy(&core->i2c_client, &cx8800_i2c_client_template,+			sizeof(core->i2c_client));++		i2c_set_adapdata(&core->i2c_adap,core);+		core->i2c_adap.algo_data = &core->i2c_algo;+		core->i2c_client.adapter = &core->i2c_adap;++		cx8800_bit_setscl(core,1);+		cx8800_bit_setsda(core,1);+		core->i2c_rc = i2c_bit_add_bus(&core->i2c_adap);++	} #ifdef I2C_CLASS_TV_ANALOG 	if (core->tuner_type != TUNER_ABSENT)-		core->i2c_adap.class |= I2C_CLASS_TV_ANALOG;+			core->i2c_adap.class |= I2C_CLASS_TV_ANALOG; #endif #ifdef I2C_CLASS_TV_DIGITAL 	if (cx88_boards[core->board].dvb)@@ -233,14 +394,7 @@ int cx88_i2c_init(struct cx88_core *core #endif 	strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); 	core->i2c_algo.data = core;-	i2c_set_adapdata(&core->i2c_adap,core);-	core->i2c_adap.algo_data = &core->i2c_algo;-	core->i2c_client.adapter = &core->i2c_adap;--	cx8800_bit_setscl(core,1);-	cx8800_bit_setsda(core,1);--	core->i2c_rc = i2c_bit_add_bus(&core->i2c_adap);+ 	if (0 == core->i2c_rc) { 		dprintk(1, "i2c register ok\n"); 		if (i2c_scan)@@ -249,13 +403,10 @@ int cx88_i2c_init(struct cx88_core *core 		printk("%s: i2c register FAILED\n", core->name); 	return core->i2c_rc; }-+EXPORT_SYMBOL(cx88_i2c_init); /* ----------------------------------------------------------------------- */--EXPORT_SYMBOL(cx88_call_i2c_clients);- /*- * Local variables:- * c-basic-offset: 8- * End:- */+* Local variables:+* c-basic-offset: 8+* End:+*/diff -r 19981e560c9f linux/drivers/media/video/cx88/cx88-mpeg.c--- a/linux/drivers/media/video/cx88/cx88-mpeg.c	Thu Aug 24 14:08:31 2006 -0700+++ b/linux/drivers/media/video/cx88/cx88-mpeg.c	Thu Aug 24 15:04:06 2006 -0700@@ -127,7 +127,7 @@ static int cx8802_start_dma(struct cx880  	/* enable irqs */ 	dprintk( 1, "setting the interrupt mask\n" );-	cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);+	cx_set(MO_PCI_INTMSK, core->pci_irqmask | MO_INT_TSINT); 	cx_set(MO_TS_INTMSK,  0x1f0011); #if 0 	cx_write(MO_TS_INTMSK,  0x0f0011);@@ -400,7 +400,8 @@ static irqreturn_t cx8802_irq(int irq, v 	int loop, handled = 0;  	for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {-		status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04);+		status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | MO_INT_TSINT);+ 		if (0 == status) 			goto out; 		dprintk( 1, "cx8802_irq\n" );@@ -410,10 +411,10 @@ static irqreturn_t cx8802_irq(int irq, v 		cx_write(MO_PCI_INTSTAT, status);  		if (status & core->pci_irqmask)-			cx88_core_irq(core,status);-		if (status & 0x04)+			cx88_core_irq(core, status);+		if (status & MO_INT_TSINT) 			cx8802_mpeg_irq(dev);-	};+	} 	if (MAX_IRQ_LOOP == loop) { 		dprintk( 0, "clearing mask\n" ); 		printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",@@ -475,8 +476,11 @@ int cx8802_init_common(struct cx8802_dev 	} 	cx_set(MO_PCI_INTMSK, core->pci_irqmask); +	/*	init	*/+	cx88_devs_init(core, dev->pci); 	/* everything worked */ 	pci_set_drvdata(dev->pci,dev);+ 	return 0; } diff -r 19981e560c9f linux/drivers/media/video/cx88/cx88-reg.h--- a/linux/drivers/media/video/cx88/cx88-reg.h	Thu Aug 24 14:08:31 2006 -0700+++ b/linux/drivers/media/video/cx88/cx88-reg.h	Thu Aug 24 15:04:06 2006 -0700@@ -6,6 +6,7 @@ 		  2001 Michael Eskin 		  2002 Yurij Sysoev <yurij@naturesoft.net> 		  2003 Gerd Knorr <kraxel@bytesex.org>+    Copyright (C) 2006 Manu Abraham <abraham.manu@gmail.com>      This program is free software; you can redistribute it and/or modify     it under the terms of the GNU General Public License as published by@@ -76,8 +77,20 @@ #define MO_PDMA_DCNTRL      0x20001C // Destination control #define MO_LD_SSID          0x200030 // Load subsystem ID #define MO_DEV_CNTRL2       0x200034 // Device control+ #define MO_PCI_INTMSK       0x200040 // PCI interrupt mask #define MO_PCI_INTSTAT      0x200044 // PCI interrupt status+#define MO_INT_I2CRACK		(1 << 17)+#define MO_INT_I2CDONE		(1 << 16)+#define MO_INT_DSTDMAINT	(1 <<  7)+#define MO_INT_SRCDMAINT	(1 <<  6)+#define MO_INT_TM1INT		(1 <<  5)+#define MO_INT_HSTINT		(1 <<  4)+#define MO_INT_VIPINT		(1 <<  3)+#define MO_INT_TSINT		(1 <<  2)+#define MO_INT_AUDINT		(1 <<  1)+#define MO_INT_VIDINT		(1 <<  0)+ #define MO_PCI_INTMSTAT     0x200048 // PCI interrupt masked status #define MO_VID_INTMSK       0x200050 // Video interrupt mask #define MO_VID_INTSTAT      0x200054 // Video interrupt status@@ -514,12 +527,22 @@ /* i2c bus registers                                                      */  #define MO_I2C              0x368000 // I2C data/control-#define MO_I2C_DIV          (0xf<<4)+#define MO_I2C_DB0	    (0xff<<24)+#define MO_I2C_DB1	    (0xff<<16)+#define MO_I2C_DB2	    (0xff<<8)+#define MO_I2C_MODE	    (1<<7)+#define MO_I2C_RATE	    (1<<6)+#define MO_I2C_NOSTOP	    (1<<5)+#define MO_I2C_NOS1B	    (1<<4) #define MO_I2C_SYNC         (1<<3)-#define MO_I2C_W3B          (1<<2)+#define MO_I2C_W3BRA	    (1<<2) #define MO_I2C_SCL          (1<<1) #define MO_I2C_SDA          (1<<0) +enum cx88_i2crate {+	CX88_I2CRATE_LOW,+	CX88_I2CRATE_HIGH,+};  /* ---------------------------------------------------------------------- */ /* general purpose host registers                                         */@@ -576,7 +599,7 @@ #define RISC_CNT_INC		 0x00010000 #define RISC_CNT_RSVR		 0x00020000 #define RISC_CNT_RESET		 0x00030000-#define RISC_JMP_SRP         	 0x01+#define RISC_JMP_SRP		 0x01   /* ---------------------------------------------------------------------- */diff -r 19981e560c9f linux/drivers/media/video/cx88/cx88-video.c--- a/linux/drivers/media/video/cx88/cx88-video.c	Thu Aug 24 14:08:31 2006 -0700+++ b/linux/drivers/media/video/cx88/cx88-video.c	Thu Aug 24 15:04:06 2006 -0700@@ -2039,17 +2039,18 @@ static irqreturn_t cx8800_irq(int irq, v 	int loop, handled = 0;  	for (loop = 0; loop < 10; loop++) {-		status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x01);+		status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | MO_INT_VIDINT);+ 		if (0 == status) 			goto out; 		cx_write(MO_PCI_INTSTAT, status); 		handled = 1;  		if (status & core->pci_irqmask)-			cx88_core_irq(core,status);-		if (status & 0x01)+			cx88_core_irq(core, status);+		if (status & MO_INT_VIDINT) 			cx8800_vid_irq(dev);-	};+	} 	if (10 == loop) { 		printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n", 		       core->name);@@ -2219,6 +2220,8 @@ static int __devinit cx8800_initdev(stru 	} 	cx_set(MO_PCI_INTMSK, core->pci_irqmask); +	/*	I2C Initialization	*/+	cx88_devs_init(core, pci_dev); 	/* load and configure helper modules */ 	if (TUNER_ABSENT != core->tuner_type) 		request_module("tuner");@@ -2310,6 +2313,7 @@ static void __devexit cx8800_finidev(str 	pci_disable_device(pci_dev);  	/* unregister stuff */+	i2c_del_adapter(&core->i2c_adap);  	free_irq(pci_dev->irq, dev); 	cx8800_unregister_video(dev);diff -r 19981e560c9f linux/drivers/media/video/cx88/cx88.h--- a/linux/drivers/media/video/cx88/cx88.h	Thu Aug 24 14:08:31 2006 -0700+++ b/linux/drivers/media/video/cx88/cx88.h	Thu Aug 24 15:04:06 2006 -0700@@ -239,6 +239,8 @@ struct cx88_board { 	struct cx88_input       radio; 	unsigned int            blackbird:1; 	unsigned int            dvb:1;+	unsigned int		hw_i2c;+	enum cx88_i2crate	i2c_rate; };  struct cx88_subid {@@ -319,7 +321,7 @@ struct cx88_core { #ifdef HAVE_VIDEO_BUF_DVB 	struct dvb_pll_desc        *pll_desc; 	unsigned int               pll_addr;-	int 			   (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);+	int			   (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); #endif  	/* state info */@@ -345,6 +347,12 @@ struct cx88_core {  	/* cx88-video needs to access cx8802 for hybrid tuner pll access. */ 	struct cx8802_dev          *dvbdev;++	u32			int_status;+	wait_queue_head_t	i2c_wq;+	enum cx88_i2crate	tx_rate;+	u32			i2c_hw;+	int			initialized; };  struct cx8800_dev;@@ -638,6 +646,7 @@ extern int cx88_do_ioctl(struct inode *i 				void *arg, v4l2_kioctl driver_ioctl); extern const u32 cx88_user_ctrls[]; extern int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl);+extern void cx88_devs_init(struct cx88_core *core, struct pci_dev *pci);  /*  * Local variables: