2007-03-12 02:44:05 +03:00
/*
* Driver for the Conexant CX23885 PCIe bridge
*
2008-09-04 00:12:12 +04:00
* Copyright ( c ) 2006 Steven Toth < stoth @ linuxtv . org >
2007-03-12 02:44:05 +03:00
*
* 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
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
*
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include <linux/init.h>
# include <linux/list.h>
# include <linux/module.h>
# include <linux/moduleparam.h>
# include <linux/kmod.h>
# include <linux/kernel.h>
# include <linux/slab.h>
# include <linux/interrupt.h>
# include <linux/delay.h>
# include <asm/div64.h>
2011-01-25 23:04:00 +03:00
# include <linux/firmware.h>
2007-03-12 02:44:05 +03:00
# include "cx23885.h"
2009-03-03 18:06:09 +03:00
# include "cimax2.h"
2011-01-25 23:04:00 +03:00
# include "altera-ci.h"
2009-09-27 06:17:30 +04:00
# include "cx23888-ir.h"
2009-09-28 02:51:50 +04:00
# include "cx23885-ir.h"
2010-07-19 08:35:46 +04:00
# include "cx23885-av.h"
2009-09-28 03:55:41 +04:00
# include "cx23885-input.h"
2007-03-12 02:44:05 +03:00
MODULE_DESCRIPTION ( " Driver for cx23885 based TV cards " ) ;
2008-09-04 00:12:12 +04:00
MODULE_AUTHOR ( " Steven Toth <stoth@linuxtv.org> " ) ;
2007-03-12 02:44:05 +03:00
MODULE_LICENSE ( " GPL " ) ;
[media] Stop using linux/version.h on most video drivers
All the modified drivers didn't have any version increment since
Jan, 1 2011. Several of them didn't have any version increment
for a long time, even having new features and important bug fixes
happening.
As we're now filling the QUERYCAP version with the current Kernel
Release, we don't need to maintain a per-driver version control
anymore. So, let's just use the default.
In order to preserve the Kernel module version history, a
KERNEL_VERSION() macro were added to all modified drivers, and
the extraver number were incremented.
I opted to preserve the per-driver version control to a few
pwc, pvrusb2, s2255, s5p-fimc and sh_vou.
A few drivers are still using the legacy way to handle ioctl's.
So, we can't do such change on them, otherwise, they'll break.
Those are: uvc, et61x251 and sn9c102.
The rationale is that the per-driver version control seems to be
actively maintained on those.
Yet, I think that the better for them would be to just use the
default version numbering, instead of doing that by themselves.
While here, removed a few uneeded include linux/version.h
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2011-06-24 21:45:49 +04:00
MODULE_VERSION ( CX23885_VERSION ) ;
2007-03-12 02:44:05 +03:00
2008-01-12 17:36:36 +03:00
static unsigned int debug ;
2008-10-17 03:18:44 +04:00
module_param ( debug , int , 0644 ) ;
MODULE_PARM_DESC ( debug , " enable debug messages " ) ;
2007-03-12 02:44:05 +03:00
static unsigned int card [ ] = { [ 0 . . . ( CX23885_MAXBOARDS - 1 ) ] = UNSET } ;
module_param_array ( card , int , NULL , 0444 ) ;
2008-10-17 03:18:44 +04:00
MODULE_PARM_DESC ( card , " card type " ) ;
2007-03-12 02:44:05 +03:00
2008-01-12 17:36:36 +03:00
# define dprintk(level, fmt, arg...)\
do { if ( debug > = level ) \
printk ( KERN_DEBUG " %s/0: " fmt , dev - > name , # # arg ) ; \
} while ( 0 )
2007-03-12 02:44:05 +03:00
static unsigned int cx23885_devcount ;
# define NO_SYNC_LINE (-1U)
/* FIXME, these allocations will change when
* analog arrives . The be reviewed .
* CX23887 Assumptions
* 1 line = 16 bytes of CDT
* cmds size = 80
* cdt size = 16 * linesize
* iqsize = 64
* maxlines = 6
*
* Address Space :
* 0x00000000 0x00008fff FIFO clusters
* 0x00010000 0x000104af Channel Management Data Structures
* 0x000104b0 0x000104ff Free
* 0x00010500 0x000108bf 15 channels * iqsize
* 0x000108c0 0x000108ff Free
* 0x00010900 0x00010e9f IQ ' s + Cluster Descriptor Tables
* 15 channels * ( iqsize + ( maxlines * linesize ) )
* 0x00010ea0 0x00010 xxx Free
*/
2008-07-02 04:18:00 +04:00
static struct sram_channel cx23885_sram_channels [ ] = {
2007-03-12 02:44:05 +03:00
[ SRAM_CH01 ] = {
2008-01-10 08:16:41 +03:00
. name = " VID A " ,
. cmds_start = 0x10000 ,
2008-07-01 17:43:27 +04:00
. ctrl_start = 0x10380 ,
. cdt = 0x104c0 ,
2008-01-10 08:16:41 +03:00
. fifo_start = 0x40 ,
. fifo_size = 0x2800 ,
2007-03-12 02:44:05 +03:00
. ptr1_reg = DMA1_PTR1 ,
. ptr2_reg = DMA1_PTR2 ,
. cnt1_reg = DMA1_CNT1 ,
. cnt2_reg = DMA1_CNT2 ,
} ,
[ SRAM_CH02 ] = {
. name = " ch2 " ,
. cmds_start = 0x0 ,
. ctrl_start = 0x0 ,
. cdt = 0x0 ,
. fifo_start = 0x0 ,
. fifo_size = 0x0 ,
. ptr1_reg = DMA2_PTR1 ,
. ptr2_reg = DMA2_PTR2 ,
. cnt1_reg = DMA2_CNT1 ,
. cnt2_reg = DMA2_CNT2 ,
} ,
[ SRAM_CH03 ] = {
2008-01-10 08:16:41 +03:00
. name = " TS1 B " ,
. cmds_start = 0x100A0 ,
2008-07-01 17:43:27 +04:00
. ctrl_start = 0x10400 ,
. cdt = 0x10580 ,
2008-01-10 08:16:41 +03:00
. fifo_start = 0x5000 ,
. fifo_size = 0x1000 ,
2007-03-12 02:44:05 +03:00
. ptr1_reg = DMA3_PTR1 ,
. ptr2_reg = DMA3_PTR2 ,
. cnt1_reg = DMA3_CNT1 ,
. cnt2_reg = DMA3_CNT2 ,
} ,
[ SRAM_CH04 ] = {
. name = " ch4 " ,
. cmds_start = 0x0 ,
. ctrl_start = 0x0 ,
. cdt = 0x0 ,
. fifo_start = 0x0 ,
. fifo_size = 0x0 ,
. ptr1_reg = DMA4_PTR1 ,
. ptr2_reg = DMA4_PTR2 ,
. cnt1_reg = DMA4_CNT1 ,
. cnt2_reg = DMA4_CNT2 ,
} ,
[ SRAM_CH05 ] = {
. name = " ch5 " ,
. cmds_start = 0x0 ,
. ctrl_start = 0x0 ,
. cdt = 0x0 ,
. fifo_start = 0x0 ,
. fifo_size = 0x0 ,
. ptr1_reg = DMA5_PTR1 ,
. ptr2_reg = DMA5_PTR2 ,
. cnt1_reg = DMA5_CNT1 ,
. cnt2_reg = DMA5_CNT2 ,
} ,
[ SRAM_CH06 ] = {
. name = " TS2 C " ,
. cmds_start = 0x10140 ,
2008-07-01 17:43:27 +04:00
. ctrl_start = 0x10440 ,
. cdt = 0x105e0 ,
2007-03-12 02:44:05 +03:00
. fifo_start = 0x6000 ,
. fifo_size = 0x1000 ,
. ptr1_reg = DMA5_PTR1 ,
. ptr2_reg = DMA5_PTR2 ,
. cnt1_reg = DMA5_CNT1 ,
. cnt2_reg = DMA5_CNT2 ,
} ,
[ SRAM_CH07 ] = {
. name = " ch7 " ,
2011-10-10 18:09:52 +04:00
. name = " TV Audio " ,
. cmds_start = 0x10190 ,
. ctrl_start = 0x10480 ,
. cdt = 0x10a00 ,
. fifo_start = 0x7000 ,
. fifo_size = 0x1000 ,
2007-03-12 02:44:05 +03:00
. ptr1_reg = DMA6_PTR1 ,
. ptr2_reg = DMA6_PTR2 ,
. cnt1_reg = DMA6_CNT1 ,
. cnt2_reg = DMA6_CNT2 ,
} ,
[ SRAM_CH08 ] = {
. name = " ch8 " ,
. cmds_start = 0x0 ,
. ctrl_start = 0x0 ,
. cdt = 0x0 ,
. fifo_start = 0x0 ,
. fifo_size = 0x0 ,
. ptr1_reg = DMA7_PTR1 ,
. ptr2_reg = DMA7_PTR2 ,
. cnt1_reg = DMA7_CNT1 ,
. cnt2_reg = DMA7_CNT2 ,
} ,
[ SRAM_CH09 ] = {
. name = " ch9 " ,
. cmds_start = 0x0 ,
. ctrl_start = 0x0 ,
. cdt = 0x0 ,
. fifo_start = 0x0 ,
. fifo_size = 0x0 ,
. ptr1_reg = DMA8_PTR1 ,
. ptr2_reg = DMA8_PTR2 ,
. cnt1_reg = DMA8_CNT1 ,
. cnt2_reg = DMA8_CNT2 ,
} ,
} ;
2008-07-02 04:18:00 +04:00
static struct sram_channel cx23887_sram_channels [ ] = {
[ SRAM_CH01 ] = {
. name = " VID A " ,
. cmds_start = 0x10000 ,
. ctrl_start = 0x105b0 ,
. cdt = 0x107b0 ,
. fifo_start = 0x40 ,
. fifo_size = 0x2800 ,
. ptr1_reg = DMA1_PTR1 ,
. ptr2_reg = DMA1_PTR2 ,
. cnt1_reg = DMA1_CNT1 ,
. cnt2_reg = DMA1_CNT2 ,
} ,
[ SRAM_CH02 ] = {
. name = " ch2 " ,
. cmds_start = 0x0 ,
. ctrl_start = 0x0 ,
. cdt = 0x0 ,
. fifo_start = 0x0 ,
. fifo_size = 0x0 ,
. ptr1_reg = DMA2_PTR1 ,
. ptr2_reg = DMA2_PTR2 ,
. cnt1_reg = DMA2_CNT1 ,
. cnt2_reg = DMA2_CNT2 ,
} ,
[ SRAM_CH03 ] = {
. name = " TS1 B " ,
. cmds_start = 0x100A0 ,
. ctrl_start = 0x10630 ,
. cdt = 0x10870 ,
. fifo_start = 0x5000 ,
. fifo_size = 0x1000 ,
. ptr1_reg = DMA3_PTR1 ,
. ptr2_reg = DMA3_PTR2 ,
. cnt1_reg = DMA3_CNT1 ,
. cnt2_reg = DMA3_CNT2 ,
} ,
[ SRAM_CH04 ] = {
. name = " ch4 " ,
. cmds_start = 0x0 ,
. ctrl_start = 0x0 ,
. cdt = 0x0 ,
. fifo_start = 0x0 ,
. fifo_size = 0x0 ,
. ptr1_reg = DMA4_PTR1 ,
. ptr2_reg = DMA4_PTR2 ,
. cnt1_reg = DMA4_CNT1 ,
. cnt2_reg = DMA4_CNT2 ,
} ,
[ SRAM_CH05 ] = {
. name = " ch5 " ,
. cmds_start = 0x0 ,
. ctrl_start = 0x0 ,
. cdt = 0x0 ,
. fifo_start = 0x0 ,
. fifo_size = 0x0 ,
. ptr1_reg = DMA5_PTR1 ,
. ptr2_reg = DMA5_PTR2 ,
. cnt1_reg = DMA5_CNT1 ,
. cnt2_reg = DMA5_CNT2 ,
} ,
[ SRAM_CH06 ] = {
. name = " TS2 C " ,
. cmds_start = 0x10140 ,
. ctrl_start = 0x10670 ,
. cdt = 0x108d0 ,
. fifo_start = 0x6000 ,
. fifo_size = 0x1000 ,
. ptr1_reg = DMA5_PTR1 ,
. ptr2_reg = DMA5_PTR2 ,
. cnt1_reg = DMA5_CNT1 ,
. cnt2_reg = DMA5_CNT2 ,
} ,
[ SRAM_CH07 ] = {
. name = " ch7 " ,
. cmds_start = 0x0 ,
. ctrl_start = 0x0 ,
. cdt = 0x0 ,
. fifo_start = 0x0 ,
. fifo_size = 0x0 ,
. ptr1_reg = DMA6_PTR1 ,
. ptr2_reg = DMA6_PTR2 ,
. cnt1_reg = DMA6_CNT1 ,
. cnt2_reg = DMA6_CNT2 ,
} ,
[ SRAM_CH08 ] = {
. name = " ch8 " ,
. cmds_start = 0x0 ,
. ctrl_start = 0x0 ,
. cdt = 0x0 ,
. fifo_start = 0x0 ,
. fifo_size = 0x0 ,
. ptr1_reg = DMA7_PTR1 ,
. ptr2_reg = DMA7_PTR2 ,
. cnt1_reg = DMA7_CNT1 ,
. cnt2_reg = DMA7_CNT2 ,
} ,
[ SRAM_CH09 ] = {
. name = " ch9 " ,
. cmds_start = 0x0 ,
. ctrl_start = 0x0 ,
. cdt = 0x0 ,
. fifo_start = 0x0 ,
. fifo_size = 0x0 ,
. ptr1_reg = DMA8_PTR1 ,
. ptr2_reg = DMA8_PTR2 ,
. cnt1_reg = DMA8_CNT1 ,
. cnt2_reg = DMA8_CNT2 ,
} ,
} ;
2010-07-19 08:19:43 +04:00
void cx23885_irq_add ( struct cx23885_dev * dev , u32 mask )
{
unsigned long flags ;
spin_lock_irqsave ( & dev - > pci_irqmask_lock , flags ) ;
dev - > pci_irqmask | = mask ;
spin_unlock_irqrestore ( & dev - > pci_irqmask_lock , flags ) ;
}
void cx23885_irq_add_enable ( struct cx23885_dev * dev , u32 mask )
{
unsigned long flags ;
spin_lock_irqsave ( & dev - > pci_irqmask_lock , flags ) ;
dev - > pci_irqmask | = mask ;
cx_set ( PCI_INT_MSK , mask ) ;
spin_unlock_irqrestore ( & dev - > pci_irqmask_lock , flags ) ;
}
void cx23885_irq_enable ( struct cx23885_dev * dev , u32 mask )
{
u32 v ;
unsigned long flags ;
spin_lock_irqsave ( & dev - > pci_irqmask_lock , flags ) ;
v = mask & dev - > pci_irqmask ;
if ( v )
cx_set ( PCI_INT_MSK , v ) ;
spin_unlock_irqrestore ( & dev - > pci_irqmask_lock , flags ) ;
}
static inline void cx23885_irq_enable_all ( struct cx23885_dev * dev )
{
cx23885_irq_enable ( dev , 0xffffffff ) ;
}
void cx23885_irq_disable ( struct cx23885_dev * dev , u32 mask )
{
unsigned long flags ;
spin_lock_irqsave ( & dev - > pci_irqmask_lock , flags ) ;
cx_clear ( PCI_INT_MSK , mask ) ;
spin_unlock_irqrestore ( & dev - > pci_irqmask_lock , flags ) ;
}
static inline void cx23885_irq_disable_all ( struct cx23885_dev * dev )
{
cx23885_irq_disable ( dev , 0xffffffff ) ;
}
void cx23885_irq_remove ( struct cx23885_dev * dev , u32 mask )
{
unsigned long flags ;
spin_lock_irqsave ( & dev - > pci_irqmask_lock , flags ) ;
dev - > pci_irqmask & = ~ mask ;
cx_clear ( PCI_INT_MSK , mask ) ;
spin_unlock_irqrestore ( & dev - > pci_irqmask_lock , flags ) ;
}
static u32 cx23885_irq_get_mask ( struct cx23885_dev * dev )
{
u32 v ;
unsigned long flags ;
spin_lock_irqsave ( & dev - > pci_irqmask_lock , flags ) ;
v = cx_read ( PCI_INT_MSK ) ;
spin_unlock_irqrestore ( & dev - > pci_irqmask_lock , flags ) ;
return v ;
}
2007-03-12 02:44:05 +03:00
static int cx23885_risc_decode ( u32 risc )
{
static char * instr [ 16 ] = {
2008-01-14 05:42:44 +03:00
[ RISC_SYNC > > 28 ] = " sync " ,
[ RISC_WRITE > > 28 ] = " write " ,
[ RISC_WRITEC > > 28 ] = " writec " ,
[ RISC_READ > > 28 ] = " read " ,
[ RISC_READC > > 28 ] = " readc " ,
[ RISC_JUMP > > 28 ] = " jump " ,
[ RISC_SKIP > > 28 ] = " skip " ,
[ RISC_WRITERM > > 28 ] = " writerm " ,
[ RISC_WRITECM > > 28 ] = " writecm " ,
[ RISC_WRITECR > > 28 ] = " writecr " ,
2007-03-12 02:44:05 +03:00
} ;
static int incr [ 16 ] = {
2008-01-14 05:42:44 +03:00
[ RISC_WRITE > > 28 ] = 3 ,
[ RISC_JUMP > > 28 ] = 3 ,
[ RISC_SKIP > > 28 ] = 1 ,
[ RISC_SYNC > > 28 ] = 1 ,
[ RISC_WRITERM > > 28 ] = 3 ,
[ RISC_WRITECM > > 28 ] = 3 ,
[ RISC_WRITECR > > 28 ] = 4 ,
2007-03-12 02:44:05 +03:00
} ;
static char * bits [ ] = {
" 12 " , " 13 " , " 14 " , " resync " ,
" cnt0 " , " cnt1 " , " 18 " , " 19 " ,
" 20 " , " 21 " , " 22 " , " 23 " ,
" irq1 " , " irq2 " , " eol " , " sol " ,
} ;
int i ;
printk ( " 0x%08x [ %s " , risc ,
instr [ risc > > 28 ] ? instr [ risc > > 28 ] : " INVALID " ) ;
2007-03-21 05:00:18 +03:00
for ( i = ARRAY_SIZE ( bits ) - 1 ; i > = 0 ; i - - )
2007-03-12 02:44:05 +03:00
if ( risc & ( 1 < < ( i + 12 ) ) )
2007-03-21 05:00:18 +03:00
printk ( " %s " , bits [ i ] ) ;
2007-03-12 02:44:05 +03:00
printk ( " count=%d ] \n " , risc & 0xfff ) ;
return incr [ risc > > 28 ] ? incr [ risc > > 28 ] : 1 ;
}
2008-01-10 09:40:49 +03:00
void cx23885_wakeup ( struct cx23885_tsport * port ,
2007-11-05 20:07:20 +03:00
struct cx23885_dmaqueue * q , u32 count )
2007-03-12 02:44:05 +03:00
{
struct cx23885_dev * dev = port - > dev ;
struct cx23885_buffer * buf ;
int bc ;
for ( bc = 0 ; ; bc + + ) {
if ( list_empty ( & q - > active ) )
break ;
buf = list_entry ( q - > active . next ,
struct cx23885_buffer , vb . queue ) ;
2007-09-05 04:32:41 +04:00
2007-03-12 02:44:05 +03:00
/* count comes from the hw and is is 16bit wide --
* this trick handles wrap - arounds correctly for
* up to 32767 buffers in flight . . . */
if ( ( s16 ) ( count - buf - > count ) < 0 )
break ;
2007-09-05 04:32:41 +04:00
2007-03-12 02:44:05 +03:00
do_gettimeofday ( & buf - > vb . ts ) ;
2007-03-21 05:00:18 +03:00
dprintk ( 2 , " [%p/%d] wakeup reg=%d buf=%d \n " , buf , buf - > vb . i ,
2007-03-12 02:44:05 +03:00
count , buf - > count ) ;
2007-11-07 02:02:36 +03:00
buf - > vb . state = VIDEOBUF_DONE ;
2007-03-12 02:44:05 +03:00
list_del ( & buf - > vb . queue ) ;
wake_up ( & buf - > vb . done ) ;
}
2008-10-17 03:18:44 +04:00
if ( list_empty ( & q - > active ) )
2007-03-12 02:44:05 +03:00
del_timer ( & q - > timeout ) ;
2008-10-17 03:18:44 +04:00
else
2007-03-21 05:00:18 +03:00
mod_timer ( & q - > timeout , jiffies + BUFFER_TIMEOUT ) ;
2007-03-12 02:44:05 +03:00
if ( bc ! = 1 )
2008-10-17 03:18:44 +04:00
printk ( KERN_WARNING " %s: %d buffers handled (should be 1) \n " ,
2008-04-09 06:20:00 +04:00
__func__ , bc ) ;
2007-03-12 02:44:05 +03:00
}
2008-01-10 09:40:49 +03:00
int cx23885_sram_channel_setup ( struct cx23885_dev * dev ,
2007-11-05 20:07:20 +03:00
struct sram_channel * ch ,
unsigned int bpl , u32 risc )
2007-03-12 02:44:05 +03:00
{
2007-03-21 05:00:18 +03:00
unsigned int i , lines ;
2007-03-12 02:44:05 +03:00
u32 cdt ;
2008-10-17 03:18:44 +04:00
if ( ch - > cmds_start = = 0 ) {
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() Erasing channel [%s] \n " , __func__ ,
2007-03-21 05:00:18 +03:00
ch - > name ) ;
2007-03-12 02:44:05 +03:00
cx_write ( ch - > ptr1_reg , 0 ) ;
cx_write ( ch - > ptr2_reg , 0 ) ;
cx_write ( ch - > cnt2_reg , 0 ) ;
cx_write ( ch - > cnt1_reg , 0 ) ;
return 0 ;
} else {
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() Configuring channel [%s] \n " , __func__ ,
2007-03-21 05:00:18 +03:00
ch - > name ) ;
2007-03-12 02:44:05 +03:00
}
bpl = ( bpl + 7 ) & ~ 7 ; /* alignment */
cdt = ch - > cdt ;
lines = ch - > fifo_size / bpl ;
if ( lines > 6 )
lines = 6 ;
BUG_ON ( lines < 2 ) ;
2008-06-22 21:19:59 +04:00
cx_write ( 8 + 0 , RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC ) ;
cx_write ( 8 + 4 , 8 ) ;
cx_write ( 8 + 8 , 0 ) ;
2007-03-12 02:44:05 +03:00
/* write CDT */
for ( i = 0 ; i < lines ; i + + ) {
2008-04-09 06:20:00 +04:00
dprintk ( 2 , " %s() 0x%08x <- 0x%08x \n " , __func__ , cdt + 16 * i ,
2007-03-21 05:00:18 +03:00
ch - > fifo_start + bpl * i ) ;
2007-03-12 02:44:05 +03:00
cx_write ( cdt + 16 * i , ch - > fifo_start + bpl * i ) ;
cx_write ( cdt + 16 * i + 4 , 0 ) ;
cx_write ( cdt + 16 * i + 8 , 0 ) ;
cx_write ( cdt + 16 * i + 12 , 0 ) ;
}
/* write CMDS */
if ( ch - > jumponly )
2008-10-17 03:18:44 +04:00
cx_write ( ch - > cmds_start + 0 , 8 ) ;
2007-03-12 02:44:05 +03:00
else
2008-10-17 03:18:44 +04:00
cx_write ( ch - > cmds_start + 0 , risc ) ;
2007-03-12 02:44:05 +03:00
cx_write ( ch - > cmds_start + 4 , 0 ) ; /* 64 bits 63-32 */
cx_write ( ch - > cmds_start + 8 , cdt ) ;
cx_write ( ch - > cmds_start + 12 , ( lines * 16 ) > > 3 ) ;
cx_write ( ch - > cmds_start + 16 , ch - > ctrl_start ) ;
if ( ch - > jumponly )
2008-10-17 03:18:44 +04:00
cx_write ( ch - > cmds_start + 20 , 0x80000000 | ( 64 > > 2 ) ) ;
2007-03-12 02:44:05 +03:00
else
cx_write ( ch - > cmds_start + 20 , 64 > > 2 ) ;
for ( i = 24 ; i < 80 ; i + = 4 )
cx_write ( ch - > cmds_start + i , 0 ) ;
/* fill registers */
cx_write ( ch - > ptr1_reg , ch - > fifo_start ) ;
cx_write ( ch - > ptr2_reg , cdt ) ;
cx_write ( ch - > cnt2_reg , ( lines * 16 ) > > 3 ) ;
2008-10-17 03:18:44 +04:00
cx_write ( ch - > cnt1_reg , ( bpl > > 3 ) - 1 ) ;
2007-03-12 02:44:05 +03:00
2008-10-17 03:18:44 +04:00
dprintk ( 2 , " [bridge %d] sram setup %s: bpl=%d lines=%d \n " ,
2007-03-20 01:22:41 +03:00
dev - > bridge ,
2007-03-12 02:44:05 +03:00
ch - > name ,
bpl ,
lines ) ;
return 0 ;
}
2008-01-10 09:40:49 +03:00
void cx23885_sram_channel_dump ( struct cx23885_dev * dev ,
2007-11-05 20:07:20 +03:00
struct sram_channel * ch )
2007-03-12 02:44:05 +03:00
{
static char * name [ ] = {
" init risc lo " ,
" init risc hi " ,
" cdt base " ,
" cdt size " ,
" iq base " ,
" iq size " ,
" risc pc lo " ,
" risc pc hi " ,
" iq wr ptr " ,
" iq rd ptr " ,
" cdt current " ,
" pci target lo " ,
" pci target hi " ,
" line / byte " ,
} ;
u32 risc ;
2007-03-21 05:00:18 +03:00
unsigned int i , j , n ;
2007-03-12 02:44:05 +03:00
2008-10-17 03:18:44 +04:00
printk ( KERN_WARNING " %s: %s - dma channel status dump \n " ,
2007-03-12 02:44:05 +03:00
dev - > name , ch - > name ) ;
for ( i = 0 ; i < ARRAY_SIZE ( name ) ; i + + )
2008-10-17 03:18:44 +04:00
printk ( KERN_WARNING " %s: cmds: %-15s: 0x%08x \n " ,
2007-03-12 02:44:05 +03:00
dev - > name , name [ i ] ,
cx_read ( ch - > cmds_start + 4 * i ) ) ;
for ( i = 0 ; i < 4 ; i + + ) {
2007-03-21 05:00:18 +03:00
risc = cx_read ( ch - > cmds_start + 4 * ( i + 14 ) ) ;
2008-10-17 03:18:44 +04:00
printk ( KERN_WARNING " %s: risc%d: " , dev - > name , i ) ;
2007-03-12 02:44:05 +03:00
cx23885_risc_decode ( risc ) ;
}
for ( i = 0 ; i < ( 64 > > 2 ) ; i + = n ) {
2007-03-21 05:00:18 +03:00
risc = cx_read ( ch - > ctrl_start + 4 * i ) ;
/* No consideration for bits 63-32 */
2008-10-17 03:18:44 +04:00
printk ( KERN_WARNING " %s: (0x%08x) iq %x: " , dev - > name ,
2007-03-21 05:00:18 +03:00
ch - > ctrl_start + 4 * i , i ) ;
2007-03-12 02:44:05 +03:00
n = cx23885_risc_decode ( risc ) ;
for ( j = 1 ; j < n ; j + + ) {
2007-03-21 05:00:18 +03:00
risc = cx_read ( ch - > ctrl_start + 4 * ( i + j ) ) ;
2008-10-17 03:18:44 +04:00
printk ( KERN_WARNING " %s: iq %x: 0x%08x [ arg #%d ] \n " ,
2007-03-12 02:44:05 +03:00
dev - > name , i + j , risc , j ) ;
}
}
2008-10-17 03:18:44 +04:00
printk ( KERN_WARNING " %s: fifo: 0x%08x -> 0x%x \n " ,
2007-03-12 02:44:05 +03:00
dev - > name , ch - > fifo_start , ch - > fifo_start + ch - > fifo_size ) ;
2008-10-17 03:18:44 +04:00
printk ( KERN_WARNING " %s: ctrl: 0x%08x -> 0x%x \n " ,
2007-03-21 05:00:18 +03:00
dev - > name , ch - > ctrl_start , ch - > ctrl_start + 6 * 16 ) ;
2008-10-17 03:18:44 +04:00
printk ( KERN_WARNING " %s: ptr1_reg: 0x%08x \n " ,
2007-03-12 02:44:05 +03:00
dev - > name , cx_read ( ch - > ptr1_reg ) ) ;
2008-10-17 03:18:44 +04:00
printk ( KERN_WARNING " %s: ptr2_reg: 0x%08x \n " ,
2007-03-12 02:44:05 +03:00
dev - > name , cx_read ( ch - > ptr2_reg ) ) ;
2008-10-17 03:18:44 +04:00
printk ( KERN_WARNING " %s: cnt1_reg: 0x%08x \n " ,
2007-03-12 02:44:05 +03:00
dev - > name , cx_read ( ch - > cnt1_reg ) ) ;
2008-10-17 03:18:44 +04:00
printk ( KERN_WARNING " %s: cnt2_reg: 0x%08x \n " ,
2007-03-12 02:44:05 +03:00
dev - > name , cx_read ( ch - > cnt2_reg ) ) ;
}
2007-11-05 20:07:20 +03:00
static void cx23885_risc_disasm ( struct cx23885_tsport * port ,
struct btcx_riscmem * risc )
2007-03-12 02:44:05 +03:00
{
struct cx23885_dev * dev = port - > dev ;
2007-03-21 05:00:18 +03:00
unsigned int i , j , n ;
2007-03-12 02:44:05 +03:00
2008-10-17 03:18:44 +04:00
printk ( KERN_INFO " %s: risc disasm: %p [dma=0x%08lx] \n " ,
2007-03-12 02:44:05 +03:00
dev - > name , risc - > cpu , ( unsigned long ) risc - > dma ) ;
for ( i = 0 ; i < ( risc - > size > > 2 ) ; i + = n ) {
2008-10-17 03:18:44 +04:00
printk ( KERN_INFO " %s: %04d: " , dev - > name , i ) ;
2008-06-22 21:19:59 +04:00
n = cx23885_risc_decode ( le32_to_cpu ( risc - > cpu [ i ] ) ) ;
2007-03-12 02:44:05 +03:00
for ( j = 1 ; j < n ; j + + )
2008-10-17 03:18:44 +04:00
printk ( KERN_INFO " %s: %04d: 0x%08x [ arg #%d ] \n " ,
2007-03-21 05:00:18 +03:00
dev - > name , i + j , risc - > cpu [ i + j ] , j ) ;
2008-06-22 21:19:59 +04:00
if ( risc - > cpu [ i ] = = cpu_to_le32 ( RISC_JUMP ) )
2007-03-12 02:44:05 +03:00
break ;
}
}
2007-11-05 20:07:20 +03:00
static void cx23885_shutdown ( struct cx23885_dev * dev )
2007-03-12 02:44:05 +03:00
{
/* disable RISC controller */
cx_write ( DEV_CNTRL2 , 0 ) ;
/* Disable all IR activity */
cx_write ( IR_CNTRL_REG , 0 ) ;
/* Disable Video A/B activity */
cx_write ( VID_A_DMA_CTL , 0 ) ;
cx_write ( VID_B_DMA_CTL , 0 ) ;
cx_write ( VID_C_DMA_CTL , 0 ) ;
/* Disable Audio activity */
cx_write ( AUD_INT_DMA_CTL , 0 ) ;
cx_write ( AUD_EXT_DMA_CTL , 0 ) ;
/* Disable Serial port */
cx_write ( UART_CTL , 0 ) ;
/* Disable Interrupts */
2010-07-19 08:19:43 +04:00
cx23885_irq_disable_all ( dev ) ;
2007-03-12 02:44:05 +03:00
cx_write ( VID_A_INT_MSK , 0 ) ;
cx_write ( VID_B_INT_MSK , 0 ) ;
cx_write ( VID_C_INT_MSK , 0 ) ;
cx_write ( AUDIO_INT_INT_MSK , 0 ) ;
cx_write ( AUDIO_EXT_INT_MSK , 0 ) ;
}
2007-11-05 20:07:20 +03:00
static void cx23885_reset ( struct cx23885_dev * dev )
2007-03-12 02:44:05 +03:00
{
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() \n " , __func__ ) ;
2007-03-12 02:44:05 +03:00
cx23885_shutdown ( dev ) ;
cx_write ( PCI_INT_STAT , 0xffffffff ) ;
cx_write ( VID_A_INT_STAT , 0xffffffff ) ;
cx_write ( VID_B_INT_STAT , 0xffffffff ) ;
cx_write ( VID_C_INT_STAT , 0xffffffff ) ;
cx_write ( AUDIO_INT_INT_STAT , 0xffffffff ) ;
cx_write ( AUDIO_EXT_INT_STAT , 0xffffffff ) ;
cx_write ( CLK_DELAY , cx_read ( CLK_DELAY ) & 0x80000000 ) ;
2008-06-28 07:52:45 +04:00
cx_write ( PAD_CTRL , 0x00500300 ) ;
2007-03-12 02:44:05 +03:00
mdelay ( 100 ) ;
2008-01-10 09:40:49 +03:00
cx23885_sram_channel_setup ( dev , & dev - > sram_channels [ SRAM_CH01 ] ,
720 * 4 , 0 ) ;
cx23885_sram_channel_setup ( dev , & dev - > sram_channels [ SRAM_CH02 ] , 128 , 0 ) ;
cx23885_sram_channel_setup ( dev , & dev - > sram_channels [ SRAM_CH03 ] ,
188 * 4 , 0 ) ;
cx23885_sram_channel_setup ( dev , & dev - > sram_channels [ SRAM_CH04 ] , 128 , 0 ) ;
cx23885_sram_channel_setup ( dev , & dev - > sram_channels [ SRAM_CH05 ] , 128 , 0 ) ;
cx23885_sram_channel_setup ( dev , & dev - > sram_channels [ SRAM_CH06 ] ,
188 * 4 , 0 ) ;
cx23885_sram_channel_setup ( dev , & dev - > sram_channels [ SRAM_CH07 ] , 128 , 0 ) ;
cx23885_sram_channel_setup ( dev , & dev - > sram_channels [ SRAM_CH08 ] , 128 , 0 ) ;
cx23885_sram_channel_setup ( dev , & dev - > sram_channels [ SRAM_CH09 ] , 128 , 0 ) ;
2007-03-12 02:44:05 +03:00
2007-09-09 04:31:56 +04:00
cx23885_gpio_setup ( dev ) ;
2007-03-12 02:44:05 +03:00
}
static int cx23885_pci_quirks ( struct cx23885_dev * dev )
{
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() \n " , __func__ ) ;
2007-03-12 02:44:05 +03:00
2007-09-05 04:50:49 +04:00
/* The cx23885 bridge has a weird bug which causes NMI to be asserted
* when DMA begins if RDR_TLCTL0 bit4 is not cleared . It does not
* occur on the cx23887 bridge .
*/
2008-10-17 03:18:44 +04:00
if ( dev - > bridge = = CX23885_BRIDGE_885 )
2007-03-12 02:44:05 +03:00
cx_clear ( RDR_TLCTL0 , 1 < < 4 ) ;
2007-08-23 03:52:21 +04:00
2007-03-12 02:44:05 +03:00
return 0 ;
}
static int get_resources ( struct cx23885_dev * dev )
{
2008-10-17 03:18:44 +04:00
if ( request_mem_region ( pci_resource_start ( dev - > pci , 0 ) ,
pci_resource_len ( dev - > pci , 0 ) ,
2007-03-21 05:00:18 +03:00
dev - > name ) )
2007-03-12 02:44:05 +03:00
return 0 ;
printk ( KERN_ERR " %s: can't get MMIO memory @ 0x%llx \n " ,
2008-10-17 03:18:44 +04:00
dev - > name , ( unsigned long long ) pci_resource_start ( dev - > pci , 0 ) ) ;
2007-03-12 02:44:05 +03:00
return - EBUSY ;
}
static void cx23885_timeout ( unsigned long data ) ;
2008-01-10 09:40:49 +03:00
int cx23885_risc_stopper ( struct pci_dev * pci , struct btcx_riscmem * risc ,
2007-11-05 20:07:20 +03:00
u32 reg , u32 mask , u32 value ) ;
2007-03-12 02:44:05 +03:00
2008-10-17 03:18:44 +04:00
static int cx23885_init_tsport ( struct cx23885_dev * dev ,
struct cx23885_tsport * port , int portno )
2007-03-12 02:44:05 +03:00
{
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s(portno=%d) \n " , __func__ , portno ) ;
2007-09-09 04:31:56 +04:00
/* Transport bus init dma queue - Common settings */
port - > dma_ctl_val = 0x11 ; /* Enable RISC controller and Fifo */
port - > ts_int_msk_val = 0x1111 ; /* TS port bits for RISC */
2008-01-14 05:42:44 +03:00
port - > vld_misc_val = 0x0 ;
port - > hw_sop_ctrl_val = ( 0x47 < < 16 | 188 < < 4 ) ;
2007-09-09 04:31:56 +04:00
spin_lock_init ( & port - > slock ) ;
port - > dev = dev ;
port - > nr = portno ;
INIT_LIST_HEAD ( & port - > mpegq . active ) ;
INIT_LIST_HEAD ( & port - > mpegq . queued ) ;
port - > mpegq . timeout . function = cx23885_timeout ;
port - > mpegq . timeout . data = ( unsigned long ) port ;
init_timer ( & port - > mpegq . timeout ) ;
2008-10-11 19:25:25 +04:00
mutex_init ( & port - > frontends . lock ) ;
2008-10-15 20:43:41 +04:00
INIT_LIST_HEAD ( & port - > frontends . felist ) ;
2008-10-11 19:25:25 +04:00
port - > frontends . active_fe_id = 0 ;
2008-10-11 19:27:06 +04:00
/* This should be hardcoded allow a single frontend
* attachment to this tsport , keeping the - dvb . c
* code clean and safe .
*/
2008-10-17 03:18:44 +04:00
if ( ! port - > num_frontends )
2008-10-11 19:27:06 +04:00
port - > num_frontends = 1 ;
2008-10-17 03:18:44 +04:00
switch ( portno ) {
2007-09-09 04:31:56 +04:00
case 1 :
port - > reg_gpcnt = VID_B_GPCNT ;
port - > reg_gpcnt_ctl = VID_B_GPCNT_CTL ;
port - > reg_dma_ctl = VID_B_DMA_CTL ;
port - > reg_lngth = VID_B_LNGTH ;
port - > reg_hw_sop_ctrl = VID_B_HW_SOP_CTL ;
port - > reg_gen_ctrl = VID_B_GEN_CTL ;
port - > reg_bd_pkt_status = VID_B_BD_PKT_STATUS ;
port - > reg_sop_status = VID_B_SOP_STATUS ;
port - > reg_fifo_ovfl_stat = VID_B_FIFO_OVFL_STAT ;
port - > reg_vld_misc = VID_B_VLD_MISC ;
port - > reg_ts_clk_en = VID_B_TS_CLK_EN ;
port - > reg_src_sel = VID_B_SRC_SEL ;
port - > reg_ts_int_msk = VID_B_INT_MSK ;
2008-01-14 05:42:44 +03:00
port - > reg_ts_int_stat = VID_B_INT_STAT ;
2007-09-09 04:31:56 +04:00
port - > sram_chno = SRAM_CH03 ; /* VID_B */
port - > pci_irqmask = 0x02 ; /* VID_B bit1 */
break ;
case 2 :
port - > reg_gpcnt = VID_C_GPCNT ;
port - > reg_gpcnt_ctl = VID_C_GPCNT_CTL ;
port - > reg_dma_ctl = VID_C_DMA_CTL ;
port - > reg_lngth = VID_C_LNGTH ;
port - > reg_hw_sop_ctrl = VID_C_HW_SOP_CTL ;
port - > reg_gen_ctrl = VID_C_GEN_CTL ;
port - > reg_bd_pkt_status = VID_C_BD_PKT_STATUS ;
port - > reg_sop_status = VID_C_SOP_STATUS ;
port - > reg_fifo_ovfl_stat = VID_C_FIFO_OVFL_STAT ;
port - > reg_vld_misc = VID_C_VLD_MISC ;
port - > reg_ts_clk_en = VID_C_TS_CLK_EN ;
port - > reg_src_sel = 0 ;
port - > reg_ts_int_msk = VID_C_INT_MSK ;
port - > reg_ts_int_stat = VID_C_INT_STAT ;
port - > sram_chno = SRAM_CH06 ; /* VID_C */
port - > pci_irqmask = 0x04 ; /* VID_C bit2 */
2007-03-12 02:44:05 +03:00
break ;
2007-09-09 04:31:56 +04:00
default :
BUG ( ) ;
2007-03-12 02:44:05 +03:00
}
2007-09-09 04:31:56 +04:00
cx23885_risc_stopper ( dev - > pci , & port - > mpegq . stopper ,
port - > reg_dma_ctl , port - > dma_ctl_val , 0x00 ) ;
2007-03-12 02:44:05 +03:00
return 0 ;
}
2008-01-10 08:06:35 +03:00
static void cx23885_dev_checkrevision ( struct cx23885_dev * dev )
{
switch ( cx_read ( RDR_CFG2 ) & 0xff ) {
case 0x00 :
/* cx23885 */
dev - > hwrevision = 0xa0 ;
break ;
case 0x01 :
/* CX23885-12Z */
dev - > hwrevision = 0xa1 ;
break ;
case 0x02 :
2009-07-20 22:40:31 +04:00
/* CX23885-13Z/14Z */
2008-01-10 08:06:35 +03:00
dev - > hwrevision = 0xb0 ;
break ;
case 0x03 :
2009-07-20 22:40:31 +04:00
if ( dev - > pci - > device = = 0x8880 ) {
/* CX23888-21Z/22Z */
dev - > hwrevision = 0xc0 ;
} else {
/* CX23885-14Z */
dev - > hwrevision = 0xa4 ;
}
break ;
case 0x04 :
if ( dev - > pci - > device = = 0x8880 ) {
/* CX23888-31Z */
dev - > hwrevision = 0xd0 ;
} else {
/* CX23885-15Z, CX23888-31Z */
dev - > hwrevision = 0xa5 ;
}
2008-01-10 08:06:35 +03:00
break ;
case 0x0e :
/* CX23887-15Z */
dev - > hwrevision = 0xc0 ;
2010-10-02 01:13:41 +04:00
break ;
2008-01-10 08:06:35 +03:00
case 0x0f :
/* CX23887-14Z */
dev - > hwrevision = 0xb1 ;
break ;
default :
printk ( KERN_ERR " %s() New hardware revision found 0x%x \n " ,
2008-04-09 06:20:00 +04:00
__func__ , dev - > hwrevision ) ;
2008-01-10 08:06:35 +03:00
}
if ( dev - > hwrevision )
printk ( KERN_INFO " %s() Hardware revision = 0x%02x \n " ,
2008-04-09 06:20:00 +04:00
__func__ , dev - > hwrevision ) ;
2008-01-10 08:06:35 +03:00
else
printk ( KERN_ERR " %s() Hardware revision unknown 0x%x \n " ,
2008-04-09 06:20:00 +04:00
__func__ , dev - > hwrevision ) ;
2008-01-10 08:06:35 +03:00
}
2009-09-27 06:17:30 +04:00
/* Find the first v4l2_subdev member of the group id in hw */
struct v4l2_subdev * cx23885_find_hw ( struct cx23885_dev * dev , u32 hw )
{
struct v4l2_subdev * result = NULL ;
struct v4l2_subdev * sd ;
spin_lock ( & dev - > v4l2_dev . lock ) ;
v4l2_device_for_each_subdev ( sd , & dev - > v4l2_dev ) {
if ( sd - > grp_id = = hw ) {
result = sd ;
break ;
}
}
spin_unlock ( & dev - > v4l2_dev . lock ) ;
return result ;
}
2007-03-12 02:44:05 +03:00
static int cx23885_dev_setup ( struct cx23885_dev * dev )
{
int i ;
2010-07-19 08:19:43 +04:00
spin_lock_init ( & dev - > pci_irqmask_lock ) ;
2007-03-12 02:44:05 +03:00
mutex_init ( & dev - > lock ) ;
2009-09-16 20:08:06 +04:00
mutex_init ( & dev - > gpio_lock ) ;
2007-03-12 02:44:05 +03:00
atomic_inc ( & dev - > refcount ) ;
dev - > nr = cx23885_devcount + + ;
2007-09-08 22:07:02 +04:00
sprintf ( dev - > name , " cx23885[%d] " , dev - > nr ) ;
/* Configure the internal memory */
2008-10-17 03:18:44 +04:00
if ( dev - > pci - > device = = 0x8880 ) {
2009-07-20 22:40:31 +04:00
/* Could be 887 or 888, assume a default */
2007-09-08 22:07:02 +04:00
dev - > bridge = CX23885_BRIDGE_887 ;
2008-01-10 08:24:27 +03:00
/* Apply a sensible clock frequency for the PCIe bridge */
dev - > clk_freq = 25000000 ;
2008-07-02 04:18:00 +04:00
dev - > sram_channels = cx23887_sram_channels ;
2007-09-08 22:07:02 +04:00
} else
2008-10-17 03:18:44 +04:00
if ( dev - > pci - > device = = 0x8852 ) {
2007-09-08 22:07:02 +04:00
dev - > bridge = CX23885_BRIDGE_885 ;
2008-01-10 08:24:27 +03:00
/* Apply a sensible clock frequency for the PCIe bridge */
dev - > clk_freq = 28000000 ;
2008-07-02 04:18:00 +04:00
dev - > sram_channels = cx23885_sram_channels ;
2007-09-08 22:07:02 +04:00
} else
BUG ( ) ;
dprintk ( 1 , " %s() Memory configured for PCIe bridge type %d \n " ,
2008-04-09 06:20:00 +04:00
__func__ , dev - > bridge ) ;
2007-09-08 22:07:02 +04:00
/* board config */
dev - > board = UNSET ;
if ( card [ dev - > nr ] < cx23885_bcount )
dev - > board = card [ dev - > nr ] ;
for ( i = 0 ; UNSET = = dev - > board & & i < cx23885_idcount ; i + + )
if ( dev - > pci - > subsystem_vendor = = cx23885_subids [ i ] . subvendor & &
dev - > pci - > subsystem_device = = cx23885_subids [ i ] . subdevice )
dev - > board = cx23885_subids [ i ] . card ;
if ( UNSET = = dev - > board ) {
dev - > board = CX23885_BOARD_UNKNOWN ;
cx23885_card_list ( dev ) ;
}
2008-01-10 08:24:27 +03:00
/* If the user specific a clk freq override, apply it */
if ( cx23885_boards [ dev - > board ] . clk_freq > 0 )
dev - > clk_freq = cx23885_boards [ dev - > board ] . clk_freq ;
2007-03-12 02:44:05 +03:00
dev - > pci_bus = dev - > pci - > bus - > number ;
dev - > pci_slot = PCI_SLOT ( dev - > pci - > devfn ) ;
2010-07-19 08:19:43 +04:00
cx23885_irq_add ( dev , 0x001f00 ) ;
2007-03-12 02:44:05 +03:00
/* External Master 1 Bus */
dev - > i2c_bus [ 0 ] . nr = 0 ;
dev - > i2c_bus [ 0 ] . dev = dev ;
dev - > i2c_bus [ 0 ] . reg_stat = I2C1_STAT ;
dev - > i2c_bus [ 0 ] . reg_ctrl = I2C1_CTRL ;
dev - > i2c_bus [ 0 ] . reg_addr = I2C1_ADDR ;
dev - > i2c_bus [ 0 ] . reg_rdata = I2C1_RDATA ;
dev - > i2c_bus [ 0 ] . reg_wdata = I2C1_WDATA ;
dev - > i2c_bus [ 0 ] . i2c_period = ( 0x9d < < 24 ) ; /* 100kHz */
/* External Master 2 Bus */
dev - > i2c_bus [ 1 ] . nr = 1 ;
dev - > i2c_bus [ 1 ] . dev = dev ;
dev - > i2c_bus [ 1 ] . reg_stat = I2C2_STAT ;
dev - > i2c_bus [ 1 ] . reg_ctrl = I2C2_CTRL ;
dev - > i2c_bus [ 1 ] . reg_addr = I2C2_ADDR ;
dev - > i2c_bus [ 1 ] . reg_rdata = I2C2_RDATA ;
dev - > i2c_bus [ 1 ] . reg_wdata = I2C2_WDATA ;
dev - > i2c_bus [ 1 ] . i2c_period = ( 0x9d < < 24 ) ; /* 100kHz */
/* Internal Master 3 Bus */
dev - > i2c_bus [ 2 ] . nr = 2 ;
dev - > i2c_bus [ 2 ] . dev = dev ;
dev - > i2c_bus [ 2 ] . reg_stat = I2C3_STAT ;
dev - > i2c_bus [ 2 ] . reg_ctrl = I2C3_CTRL ;
2007-03-16 17:48:33 +03:00
dev - > i2c_bus [ 2 ] . reg_addr = I2C3_ADDR ;
2007-03-12 02:44:05 +03:00
dev - > i2c_bus [ 2 ] . reg_rdata = I2C3_RDATA ;
dev - > i2c_bus [ 2 ] . reg_wdata = I2C3_WDATA ;
dev - > i2c_bus [ 2 ] . i2c_period = ( 0x07 < < 24 ) ; /* 1.95MHz */
2008-01-14 05:42:44 +03:00
if ( ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_DVB ) | |
( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_ENCODER ) )
2007-09-09 04:31:56 +04:00
cx23885_init_tsport ( dev , & dev - > ts1 , 1 ) ;
2007-09-08 22:07:02 +04:00
2008-01-14 05:42:44 +03:00
if ( ( cx23885_boards [ dev - > board ] . portc = = CX23885_MPEG_DVB ) | |
( cx23885_boards [ dev - > board ] . portc = = CX23885_MPEG_ENCODER ) )
2007-09-09 04:31:56 +04:00
cx23885_init_tsport ( dev , & dev - > ts2 , 2 ) ;
2007-03-12 02:44:05 +03:00
if ( get_resources ( dev ) < 0 ) {
printk ( KERN_ERR " CORE %s No more PCIe resources for "
2007-03-21 05:00:18 +03:00
" subsystem: %04x:%04x \n " ,
dev - > name , dev - > pci - > subsystem_vendor ,
dev - > pci - > subsystem_device ) ;
2007-03-12 02:44:05 +03:00
cx23885_devcount - - ;
2007-10-13 18:49:52 +04:00
return - ENODEV ;
2007-03-12 02:44:05 +03:00
}
/* PCIe stuff */
2008-10-17 03:18:44 +04:00
dev - > lmmio = ioremap ( pci_resource_start ( dev - > pci , 0 ) ,
pci_resource_len ( dev - > pci , 0 ) ) ;
2007-03-12 02:44:05 +03:00
dev - > bmmio = ( u8 __iomem * ) dev - > lmmio ;
printk ( KERN_INFO " CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s] \n " ,
2007-03-21 05:00:18 +03:00
dev - > name , dev - > pci - > subsystem_vendor ,
dev - > pci - > subsystem_device , cx23885_boards [ dev - > board ] . name ,
dev - > board , card [ dev - > nr ] = = dev - > board ?
" insmod option " : " autodetected " ) ;
2007-03-12 02:44:05 +03:00
2007-08-23 03:52:21 +04:00
cx23885_pci_quirks ( dev ) ;
2008-01-10 09:40:49 +03:00
/* Assume some sensible defaults */
dev - > tuner_type = cx23885_boards [ dev - > board ] . tuner_type ;
dev - > tuner_addr = cx23885_boards [ dev - > board ] . tuner_addr ;
2011-01-25 23:05:00 +03:00
dev - > tuner_bus = cx23885_boards [ dev - > board ] . tuner_bus ;
2008-01-10 09:40:49 +03:00
dev - > radio_type = cx23885_boards [ dev - > board ] . radio_type ;
dev - > radio_addr = cx23885_boards [ dev - > board ] . radio_addr ;
2011-01-25 23:05:00 +03:00
dprintk ( 1 , " %s() tuner_type = 0x%x tuner_addr = 0x%x tuner_bus = %d \n " ,
__func__ , dev - > tuner_type , dev - > tuner_addr , dev - > tuner_bus ) ;
2008-01-10 09:40:49 +03:00
dprintk ( 1 , " %s() radio_type = 0x%x radio_addr = 0x%x \n " ,
2008-04-09 06:20:00 +04:00
__func__ , dev - > radio_type , dev - > radio_addr ) ;
2008-01-10 09:40:49 +03:00
2009-06-26 06:43:31 +04:00
/* The cx23417 encoder has GPIO's that need to be initialised
* before DVB , so that demodulators and tuners are out of
* reset before DVB uses them .
*/
if ( ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_ENCODER ) | |
( cx23885_boards [ dev - > board ] . portc = = CX23885_MPEG_ENCODER ) )
cx23885_mc417_init ( dev ) ;
2007-03-12 02:44:05 +03:00
/* init hardware */
cx23885_reset ( dev ) ;
cx23885_i2c_register ( & dev - > i2c_bus [ 0 ] ) ;
cx23885_i2c_register ( & dev - > i2c_bus [ 1 ] ) ;
cx23885_i2c_register ( & dev - > i2c_bus [ 2 ] ) ;
cx23885_card_setup ( dev ) ;
2009-10-05 17:48:17 +04:00
call_all ( dev , core , s_power , 0 ) ;
2007-03-12 02:44:05 +03:00
cx23885_ir_init ( dev ) ;
2008-01-10 09:40:49 +03:00
if ( cx23885_boards [ dev - > board ] . porta = = CX23885_ANALOG_VIDEO ) {
if ( cx23885_video_register ( dev ) < 0 ) {
printk ( KERN_ERR " %s() Failed to register analog "
2008-04-09 06:20:00 +04:00
" video adapters on VID_A \n " , __func__ ) ;
2008-01-10 09:40:49 +03:00
}
}
if ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_DVB ) {
2011-01-25 23:06:00 +03:00
if ( cx23885_boards [ dev - > board ] . num_fds_portb )
dev - > ts1 . num_frontends =
cx23885_boards [ dev - > board ] . num_fds_portb ;
2007-09-09 04:31:56 +04:00
if ( cx23885_dvb_register ( & dev - > ts1 ) < 0 ) {
printk ( KERN_ERR " %s() Failed to register dvb adapters on VID_B \n " ,
2008-04-09 06:20:00 +04:00
__func__ ) ;
2007-09-09 04:31:56 +04:00
}
2008-01-14 05:42:44 +03:00
} else
if ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_ENCODER ) {
if ( cx23885_417_register ( dev ) < 0 ) {
printk ( KERN_ERR
" %s() Failed to register 417 on VID_B \n " ,
__func__ ) ;
}
2007-09-08 22:07:02 +04:00
}
2008-01-10 09:40:49 +03:00
if ( cx23885_boards [ dev - > board ] . portc = = CX23885_MPEG_DVB ) {
2011-01-25 23:06:00 +03:00
if ( cx23885_boards [ dev - > board ] . num_fds_portc )
dev - > ts2 . num_frontends =
cx23885_boards [ dev - > board ] . num_fds_portc ;
2007-09-09 04:31:56 +04:00
if ( cx23885_dvb_register ( & dev - > ts2 ) < 0 ) {
2008-01-14 05:42:44 +03:00
printk ( KERN_ERR
" %s() Failed to register dvb on VID_C \n " ,
__func__ ) ;
}
} else
if ( cx23885_boards [ dev - > board ] . portc = = CX23885_MPEG_ENCODER ) {
if ( cx23885_417_register ( dev ) < 0 ) {
printk ( KERN_ERR
" %s() Failed to register 417 on VID_C \n " ,
2008-04-09 06:20:00 +04:00
__func__ ) ;
2007-09-09 04:31:56 +04:00
}
2007-03-12 02:44:05 +03:00
}
2008-01-10 08:06:35 +03:00
cx23885_dev_checkrevision ( dev ) ;
2011-01-25 23:07:00 +03:00
/* disable MSI for NetUP cards, otherwise CI is not working */
if ( cx23885_boards [ dev - > board ] . ci_type > 0 )
cx_clear ( RDR_RDRCTL1 , 1 < < 8 ) ;
2007-03-12 02:44:05 +03:00
return 0 ;
}
2007-11-05 20:07:20 +03:00
static void cx23885_dev_unregister ( struct cx23885_dev * dev )
2007-03-12 02:44:05 +03:00
{
2008-10-17 03:18:44 +04:00
release_mem_region ( pci_resource_start ( dev - > pci , 0 ) ,
pci_resource_len ( dev - > pci , 0 ) ) ;
2007-03-12 02:44:05 +03:00
if ( ! atomic_dec_and_test ( & dev - > refcount ) )
return ;
2008-01-10 09:40:49 +03:00
if ( cx23885_boards [ dev - > board ] . porta = = CX23885_ANALOG_VIDEO )
cx23885_video_unregister ( dev ) ;
2008-01-14 05:42:44 +03:00
if ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_DVB )
2007-09-09 04:31:56 +04:00
cx23885_dvb_unregister ( & dev - > ts1 ) ;
2008-01-14 05:42:44 +03:00
if ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_ENCODER )
cx23885_417_unregister ( dev ) ;
if ( cx23885_boards [ dev - > board ] . portc = = CX23885_MPEG_DVB )
2007-09-09 04:31:56 +04:00
cx23885_dvb_unregister ( & dev - > ts2 ) ;
2008-01-14 05:42:44 +03:00
if ( cx23885_boards [ dev - > board ] . portc = = CX23885_MPEG_ENCODER )
cx23885_417_unregister ( dev ) ;
2007-03-12 02:44:05 +03:00
cx23885_i2c_unregister ( & dev - > i2c_bus [ 2 ] ) ;
cx23885_i2c_unregister ( & dev - > i2c_bus [ 1 ] ) ;
cx23885_i2c_unregister ( & dev - > i2c_bus [ 0 ] ) ;
iounmap ( dev - > lmmio ) ;
}
2008-10-17 03:18:44 +04:00
static __le32 * cx23885_risc_field ( __le32 * rp , struct scatterlist * sglist ,
2007-03-21 05:00:18 +03:00
unsigned int offset , u32 sync_line ,
unsigned int bpl , unsigned int padding ,
2011-10-10 18:09:52 +04:00
unsigned int lines , unsigned int lpi )
2007-03-12 02:44:05 +03:00
{
struct scatterlist * sg ;
2011-10-10 18:09:52 +04:00
unsigned int line , todo , sol ;
2007-03-12 02:44:05 +03:00
/* sync instruction */
if ( sync_line ! = NO_SYNC_LINE )
* ( rp + + ) = cpu_to_le32 ( RISC_RESYNC | sync_line ) ;
/* scan lines */
sg = sglist ;
for ( line = 0 ; line < lines ; line + + ) {
while ( offset & & offset > = sg_dma_len ( sg ) ) {
offset - = sg_dma_len ( sg ) ;
sg + + ;
}
2011-10-10 18:09:52 +04:00
if ( lpi & & line > 0 & & ! ( line % lpi ) )
sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC ;
else
sol = RISC_SOL ;
2007-03-12 02:44:05 +03:00
if ( bpl < = sg_dma_len ( sg ) - offset ) {
/* fits into current chunk */
2011-10-10 18:09:52 +04:00
* ( rp + + ) = cpu_to_le32 ( RISC_WRITE | sol | RISC_EOL | bpl ) ;
2008-10-17 03:18:44 +04:00
* ( rp + + ) = cpu_to_le32 ( sg_dma_address ( sg ) + offset ) ;
* ( rp + + ) = cpu_to_le32 ( 0 ) ; /* bits 63-32 */
offset + = bpl ;
2007-03-12 02:44:05 +03:00
} else {
/* scanline needs to be split */
todo = bpl ;
2011-10-10 18:09:52 +04:00
* ( rp + + ) = cpu_to_le32 ( RISC_WRITE | sol |
2007-03-12 02:44:05 +03:00
( sg_dma_len ( sg ) - offset ) ) ;
2008-10-17 03:18:44 +04:00
* ( rp + + ) = cpu_to_le32 ( sg_dma_address ( sg ) + offset ) ;
* ( rp + + ) = cpu_to_le32 ( 0 ) ; /* bits 63-32 */
2007-03-12 02:44:05 +03:00
todo - = ( sg_dma_len ( sg ) - offset ) ;
offset = 0 ;
sg + + ;
while ( todo > sg_dma_len ( sg ) ) {
2008-10-17 03:18:44 +04:00
* ( rp + + ) = cpu_to_le32 ( RISC_WRITE |
2007-03-12 02:44:05 +03:00
sg_dma_len ( sg ) ) ;
2008-10-17 03:18:44 +04:00
* ( rp + + ) = cpu_to_le32 ( sg_dma_address ( sg ) ) ;
* ( rp + + ) = cpu_to_le32 ( 0 ) ; /* bits 63-32 */
2007-03-12 02:44:05 +03:00
todo - = sg_dma_len ( sg ) ;
sg + + ;
}
2008-10-17 03:18:44 +04:00
* ( rp + + ) = cpu_to_le32 ( RISC_WRITE | RISC_EOL | todo ) ;
* ( rp + + ) = cpu_to_le32 ( sg_dma_address ( sg ) ) ;
* ( rp + + ) = cpu_to_le32 ( 0 ) ; /* bits 63-32 */
2007-03-12 02:44:05 +03:00
offset + = todo ;
}
offset + = padding ;
}
return rp ;
}
2008-01-10 09:40:49 +03:00
int cx23885_risc_buffer ( struct pci_dev * pci , struct btcx_riscmem * risc ,
struct scatterlist * sglist , unsigned int top_offset ,
unsigned int bottom_offset , unsigned int bpl ,
unsigned int padding , unsigned int lines )
{
u32 instructions , fields ;
2008-05-21 07:31:51 +04:00
__le32 * rp ;
2008-01-10 09:40:49 +03:00
int rc ;
fields = 0 ;
if ( UNSET ! = top_offset )
fields + + ;
if ( UNSET ! = bottom_offset )
fields + + ;
/* estimate risc mem: worst case is one write per page border +
one write per scan line + syncs + jump ( all 2 dwords ) . Padding
can cause next bpl to start close to a page border . First DMA
region may be smaller than PAGE_SIZE */
/* write and jump need and extra dword */
2008-10-17 03:18:44 +04:00
instructions = fields * ( 1 + ( ( bpl + padding ) * lines )
/ PAGE_SIZE + lines ) ;
2008-01-10 09:40:49 +03:00
instructions + = 2 ;
2008-10-17 03:18:44 +04:00
rc = btcx_riscmem_alloc ( pci , risc , instructions * 12 ) ;
if ( rc < 0 )
2008-01-10 09:40:49 +03:00
return rc ;
/* write risc instructions */
rp = risc - > cpu ;
if ( UNSET ! = top_offset )
rp = cx23885_risc_field ( rp , sglist , top_offset , 0 ,
2011-10-10 18:09:52 +04:00
bpl , padding , lines , 0 ) ;
2008-01-10 09:40:49 +03:00
if ( UNSET ! = bottom_offset )
rp = cx23885_risc_field ( rp , sglist , bottom_offset , 0x200 ,
2011-10-10 18:09:52 +04:00
bpl , padding , lines , 0 ) ;
2008-01-10 09:40:49 +03:00
/* save pointer to jmp instruction address */
risc - > jmp = rp ;
2008-10-17 03:18:44 +04:00
BUG_ON ( ( risc - > jmp - risc - > cpu + 2 ) * sizeof ( * risc - > cpu ) > risc - > size ) ;
2008-01-10 09:40:49 +03:00
return 0 ;
}
2007-03-12 02:44:05 +03:00
2011-10-10 18:09:52 +04:00
int cx23885_risc_databuffer ( struct pci_dev * pci ,
2007-11-05 20:07:20 +03:00
struct btcx_riscmem * risc ,
struct scatterlist * sglist ,
unsigned int bpl ,
2011-10-10 18:09:52 +04:00
unsigned int lines , unsigned int lpi )
2007-03-12 02:44:05 +03:00
{
u32 instructions ;
2008-05-21 07:31:51 +04:00
__le32 * rp ;
2007-03-12 02:44:05 +03:00
int rc ;
/* estimate risc mem: worst case is one write per page border +
one write per scan line + syncs + jump ( all 2 dwords ) . Here
there is no padding and no sync . First DMA region may be smaller
than PAGE_SIZE */
/* Jump and write need an extra dword */
instructions = 1 + ( bpl * lines ) / PAGE_SIZE + lines ;
instructions + = 1 ;
2008-10-17 03:18:44 +04:00
rc = btcx_riscmem_alloc ( pci , risc , instructions * 12 ) ;
if ( rc < 0 )
2007-03-12 02:44:05 +03:00
return rc ;
/* write risc instructions */
rp = risc - > cpu ;
2011-10-10 18:09:52 +04:00
rp = cx23885_risc_field ( rp , sglist , 0 , NO_SYNC_LINE ,
bpl , 0 , lines , lpi ) ;
2007-03-12 02:44:05 +03:00
/* save pointer to jmp instruction address */
risc - > jmp = rp ;
2008-10-17 03:18:44 +04:00
BUG_ON ( ( risc - > jmp - risc - > cpu + 2 ) * sizeof ( * risc - > cpu ) > risc - > size ) ;
2007-03-12 02:44:05 +03:00
return 0 ;
}
2008-01-10 09:40:49 +03:00
int cx23885_risc_stopper ( struct pci_dev * pci , struct btcx_riscmem * risc ,
2007-11-05 20:07:20 +03:00
u32 reg , u32 mask , u32 value )
2007-03-12 02:44:05 +03:00
{
2008-05-21 07:31:51 +04:00
__le32 * rp ;
2007-03-12 02:44:05 +03:00
int rc ;
2008-10-17 03:18:44 +04:00
rc = btcx_riscmem_alloc ( pci , risc , 4 * 16 ) ;
if ( rc < 0 )
2007-03-12 02:44:05 +03:00
return rc ;
/* write risc instructions */
rp = risc - > cpu ;
* ( rp + + ) = cpu_to_le32 ( RISC_WRITECR | RISC_IRQ2 ) ;
* ( rp + + ) = cpu_to_le32 ( reg ) ;
* ( rp + + ) = cpu_to_le32 ( value ) ;
* ( rp + + ) = cpu_to_le32 ( mask ) ;
* ( rp + + ) = cpu_to_le32 ( RISC_JUMP ) ;
* ( rp + + ) = cpu_to_le32 ( risc - > dma ) ;
* ( rp + + ) = cpu_to_le32 ( 0 ) ; /* bits 63-32 */
return 0 ;
}
void cx23885_free_buffer ( struct videobuf_queue * q , struct cx23885_buffer * buf )
{
2007-10-04 12:28:45 +04:00
struct videobuf_dmabuf * dma = videobuf_to_dma ( & buf - > vb ) ;
2007-03-12 02:44:05 +03:00
BUG_ON ( in_interrupt ( ) ) ;
2010-09-26 16:01:26 +04:00
videobuf_waiton ( q , & buf - > vb , 0 , 0 ) ;
2010-05-11 17:36:30 +04:00
videobuf_dma_unmap ( q - > dev , dma ) ;
2007-10-04 12:28:45 +04:00
videobuf_dma_free ( dma ) ;
2008-04-22 21:46:02 +04:00
btcx_riscmem_free ( to_pci_dev ( q - > dev ) , & buf - > risc ) ;
2007-11-07 02:02:36 +03:00
buf - > vb . state = VIDEOBUF_NEEDS_INIT ;
2007-03-12 02:44:05 +03:00
}
2008-01-10 09:40:49 +03:00
static void cx23885_tsport_reg_dump ( struct cx23885_tsport * port )
{
struct cx23885_dev * dev = port - > dev ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() Register Dump \n " , __func__ ) ;
dprintk ( 1 , " %s() DEV_CNTRL2 0x%08X \n " , __func__ ,
2008-01-10 09:40:49 +03:00
cx_read ( DEV_CNTRL2 ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() PCI_INT_MSK 0x%08X \n " , __func__ ,
2010-07-19 08:19:43 +04:00
cx23885_irq_get_mask ( dev ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() AUD_INT_INT_MSK 0x%08X \n " , __func__ ,
2008-01-10 09:40:49 +03:00
cx_read ( AUDIO_INT_INT_MSK ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() AUD_INT_DMA_CTL 0x%08X \n " , __func__ ,
2008-01-10 09:40:49 +03:00
cx_read ( AUD_INT_DMA_CTL ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() AUD_EXT_INT_MSK 0x%08X \n " , __func__ ,
2008-01-10 09:40:49 +03:00
cx_read ( AUDIO_EXT_INT_MSK ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() AUD_EXT_DMA_CTL 0x%08X \n " , __func__ ,
2008-01-10 09:40:49 +03:00
cx_read ( AUD_EXT_DMA_CTL ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() PAD_CTRL 0x%08X \n " , __func__ ,
2008-01-10 09:40:49 +03:00
cx_read ( PAD_CTRL ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() ALT_PIN_OUT_SEL 0x%08X \n " , __func__ ,
2008-01-10 09:40:49 +03:00
cx_read ( ALT_PIN_OUT_SEL ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() GPIO2 0x%08X \n " , __func__ ,
2008-01-10 09:40:49 +03:00
cx_read ( GPIO2 ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() gpcnt(0x%08X) 0x%08X \n " , __func__ ,
2008-01-10 09:40:49 +03:00
port - > reg_gpcnt , cx_read ( port - > reg_gpcnt ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() gpcnt_ctl(0x%08X) 0x%08x \n " , __func__ ,
2008-01-10 09:40:49 +03:00
port - > reg_gpcnt_ctl , cx_read ( port - > reg_gpcnt_ctl ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() dma_ctl(0x%08X) 0x%08x \n " , __func__ ,
2008-01-10 09:40:49 +03:00
port - > reg_dma_ctl , cx_read ( port - > reg_dma_ctl ) ) ;
2008-07-01 03:54:34 +04:00
if ( port - > reg_src_sel )
dprintk ( 1 , " %s() src_sel(0x%08X) 0x%08x \n " , __func__ ,
port - > reg_src_sel , cx_read ( port - > reg_src_sel ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() lngth(0x%08X) 0x%08x \n " , __func__ ,
2008-01-10 09:40:49 +03:00
port - > reg_lngth , cx_read ( port - > reg_lngth ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() hw_sop_ctrl(0x%08X) 0x%08x \n " , __func__ ,
2008-01-10 09:40:49 +03:00
port - > reg_hw_sop_ctrl , cx_read ( port - > reg_hw_sop_ctrl ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() gen_ctrl(0x%08X) 0x%08x \n " , __func__ ,
2008-01-10 09:40:49 +03:00
port - > reg_gen_ctrl , cx_read ( port - > reg_gen_ctrl ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() bd_pkt_status(0x%08X) 0x%08x \n " , __func__ ,
2008-01-10 09:40:49 +03:00
port - > reg_bd_pkt_status , cx_read ( port - > reg_bd_pkt_status ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() sop_status(0x%08X) 0x%08x \n " , __func__ ,
2008-01-10 09:40:49 +03:00
port - > reg_sop_status , cx_read ( port - > reg_sop_status ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() fifo_ovfl_stat(0x%08X) 0x%08x \n " , __func__ ,
2008-01-10 09:40:49 +03:00
port - > reg_fifo_ovfl_stat , cx_read ( port - > reg_fifo_ovfl_stat ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() vld_misc(0x%08X) 0x%08x \n " , __func__ ,
2008-01-10 09:40:49 +03:00
port - > reg_vld_misc , cx_read ( port - > reg_vld_misc ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() ts_clk_en(0x%08X) 0x%08x \n " , __func__ ,
2008-01-10 09:40:49 +03:00
port - > reg_ts_clk_en , cx_read ( port - > reg_ts_clk_en ) ) ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() ts_int_msk(0x%08X) 0x%08x \n " , __func__ ,
2008-01-10 09:40:49 +03:00
port - > reg_ts_int_msk , cx_read ( port - > reg_ts_int_msk ) ) ;
}
2007-03-12 02:44:05 +03:00
static int cx23885_start_dma ( struct cx23885_tsport * port ,
2007-03-21 05:00:18 +03:00
struct cx23885_dmaqueue * q ,
struct cx23885_buffer * buf )
2007-03-12 02:44:05 +03:00
{
struct cx23885_dev * dev = port - > dev ;
2008-01-14 05:44:47 +03:00
u32 reg ;
2007-03-12 02:44:05 +03:00
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() w: %d, h: %d, f: %d \n " , __func__ ,
2007-03-21 05:00:18 +03:00
buf - > vb . width , buf - > vb . height , buf - > vb . field ) ;
2007-03-12 02:44:05 +03:00
2008-07-01 17:43:27 +04:00
/* Stop the fifo and risc engine for this port */
cx_clear ( port - > reg_dma_ctl , port - > dma_ctl_val ) ;
2007-03-12 02:44:05 +03:00
/* setup fifo + format */
cx23885_sram_channel_setup ( dev ,
2008-10-17 03:18:44 +04:00
& dev - > sram_channels [ port - > sram_chno ] ,
2007-03-21 05:00:18 +03:00
port - > ts_packet_size , buf - > risc . dma ) ;
2008-10-17 03:18:44 +04:00
if ( debug > 5 ) {
cx23885_sram_channel_dump ( dev ,
& dev - > sram_channels [ port - > sram_chno ] ) ;
2007-03-12 02:44:05 +03:00
cx23885_risc_disasm ( port , & buf - > risc ) ;
2007-03-20 00:01:07 +03:00
}
2007-03-12 02:44:05 +03:00
/* write TS length to chip */
cx_write ( port - > reg_lngth , buf - > vb . width ) ;
2008-10-17 03:18:44 +04:00
if ( ( ! ( cx23885_boards [ dev - > board ] . portb & CX23885_MPEG_DVB ) ) & &
( ! ( cx23885_boards [ dev - > board ] . portc & CX23885_MPEG_DVB ) ) ) {
printk ( " %s() Unsupported .portb/c (0x%08x)/(0x%08x) \n " ,
2008-04-09 06:20:00 +04:00
__func__ ,
2007-09-06 23:07:49 +04:00
cx23885_boards [ dev - > board ] . portb ,
2008-10-17 03:18:44 +04:00
cx23885_boards [ dev - > board ] . portc ) ;
2007-03-12 02:44:05 +03:00
return - EINVAL ;
}
2008-01-14 05:44:47 +03:00
if ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_ENCODER )
cx23885_av_clk ( dev , 0 ) ;
2007-03-12 02:44:05 +03:00
udelay ( 100 ) ;
2007-09-08 22:07:02 +04:00
/* If the port supports SRC SELECT, configure it */
2008-10-17 03:18:44 +04:00
if ( port - > reg_src_sel )
2007-09-08 22:07:02 +04:00
cx_write ( port - > reg_src_sel , port - > src_sel_val ) ;
2008-01-14 05:42:44 +03:00
cx_write ( port - > reg_hw_sop_ctrl , port - > hw_sop_ctrl_val ) ;
2007-03-12 02:44:05 +03:00
cx_write ( port - > reg_ts_clk_en , port - > ts_clk_en_val ) ;
2008-01-14 05:42:44 +03:00
cx_write ( port - > reg_vld_misc , port - > vld_misc_val ) ;
2007-03-12 02:44:05 +03:00
cx_write ( port - > reg_gen_ctrl , port - > gen_ctrl_val ) ;
udelay ( 100 ) ;
2008-10-17 03:18:44 +04:00
/* NOTE: this is 2 (reserved) for portb, does it matter? */
2007-03-12 02:44:05 +03:00
/* reset counter to zero */
cx_write ( port - > reg_gpcnt_ctl , 3 ) ;
q - > count = 1 ;
2008-06-28 07:58:35 +04:00
/* Set VIDB pins to input */
if ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_DVB ) {
reg = cx_read ( PAD_CTRL ) ;
reg & = ~ 0x3 ; /* Clear TS1_OE & TS1_SOP_OE */
cx_write ( PAD_CTRL , reg ) ;
}
/* Set VIDC pins to input */
if ( cx23885_boards [ dev - > board ] . portc = = CX23885_MPEG_DVB ) {
reg = cx_read ( PAD_CTRL ) ;
reg & = ~ 0x4 ; /* Clear TS2_SOP_OE */
cx_write ( PAD_CTRL , reg ) ;
}
if ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_ENCODER ) {
2008-01-14 05:44:47 +03:00
reg = cx_read ( PAD_CTRL ) ;
reg = reg & ~ 0x1 ; /* Clear TS1_OE */
/* FIXME, bit 2 writing here is questionable */
/* set TS1_SOP_OE and TS1_OE_HI */
reg = reg | 0xa ;
cx_write ( PAD_CTRL , reg ) ;
/* FIXME and these two registers should be documented. */
cx_write ( CLK_DELAY , cx_read ( CLK_DELAY ) | 0x80000011 ) ;
cx_write ( ALT_PIN_OUT_SEL , 0x10100045 ) ;
}
2008-10-17 03:18:44 +04:00
switch ( dev - > bridge ) {
2007-03-12 02:44:05 +03:00
case CX23885_BRIDGE_885 :
2007-03-19 23:46:03 +03:00
case CX23885_BRIDGE_887 :
2009-07-20 22:40:31 +04:00
case CX23885_BRIDGE_888 :
2007-03-12 02:44:05 +03:00
/* enable irqs */
2008-10-17 03:18:44 +04:00
dprintk ( 1 , " %s() enabling TS int's and DMA \n " , __func__ ) ;
2007-03-12 02:44:05 +03:00
cx_set ( port - > reg_ts_int_msk , port - > ts_int_msk_val ) ;
cx_set ( port - > reg_dma_ctl , port - > dma_ctl_val ) ;
2010-07-19 08:19:43 +04:00
cx23885_irq_add ( dev , port - > pci_irqmask ) ;
cx23885_irq_enable_all ( dev ) ;
2007-03-12 02:44:05 +03:00
break ;
default :
2007-09-08 22:07:02 +04:00
BUG ( ) ;
2007-03-12 02:44:05 +03:00
}
cx_set ( DEV_CNTRL2 , ( 1 < < 5 ) ) ; /* Enable RISC controller */
2008-01-14 05:44:47 +03:00
if ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_ENCODER )
cx23885_av_clk ( dev , 1 ) ;
2008-01-10 09:40:49 +03:00
if ( debug > 4 )
cx23885_tsport_reg_dump ( port ) ;
2007-03-12 02:44:05 +03:00
return 0 ;
}
static int cx23885_stop_dma ( struct cx23885_tsport * port )
{
struct cx23885_dev * dev = port - > dev ;
2008-01-14 05:44:47 +03:00
u32 reg ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s() \n " , __func__ ) ;
2007-03-12 02:44:05 +03:00
/* Stop interrupts and DMA */
cx_clear ( port - > reg_ts_int_msk , port - > ts_int_msk_val ) ;
cx_clear ( port - > reg_dma_ctl , port - > dma_ctl_val ) ;
2008-06-28 07:58:35 +04:00
if ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_ENCODER ) {
2008-01-14 05:44:47 +03:00
reg = cx_read ( PAD_CTRL ) ;
/* Set TS1_OE */
reg = reg | 0x1 ;
/* clear TS1_SOP_OE and TS1_OE_HI */
reg = reg & ~ 0xa ;
cx_write ( PAD_CTRL , reg ) ;
cx_write ( port - > reg_src_sel , 0 ) ;
cx_write ( port - > reg_gen_ctrl , 8 ) ;
}
if ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_ENCODER )
cx23885_av_clk ( dev , 0 ) ;
2007-03-12 02:44:05 +03:00
return 0 ;
}
2008-01-10 09:40:49 +03:00
int cx23885_restart_queue ( struct cx23885_tsport * port ,
2007-03-12 02:44:05 +03:00
struct cx23885_dmaqueue * q )
{
struct cx23885_dev * dev = port - > dev ;
struct cx23885_buffer * buf ;
2008-04-09 06:20:00 +04:00
dprintk ( 5 , " %s() \n " , __func__ ) ;
2008-10-17 03:18:44 +04:00
if ( list_empty ( & q - > active ) ) {
2007-03-21 05:00:18 +03:00
struct cx23885_buffer * prev ;
prev = NULL ;
2007-03-12 02:44:05 +03:00
2008-04-09 06:20:00 +04:00
dprintk ( 5 , " %s() queue is empty \n " , __func__ ) ;
2007-03-12 02:44:05 +03:00
2007-03-21 05:00:18 +03:00
for ( ; ; ) {
if ( list_empty ( & q - > queued ) )
return 0 ;
buf = list_entry ( q - > queued . next , struct cx23885_buffer ,
vb . queue ) ;
if ( NULL = = prev ) {
list_del ( & buf - > vb . queue ) ;
list_add_tail ( & buf - > vb . queue , & q - > active ) ;
cx23885_start_dma ( port , q , buf ) ;
2007-11-07 02:02:36 +03:00
buf - > vb . state = VIDEOBUF_ACTIVE ;
2007-03-21 05:00:18 +03:00
buf - > count = q - > count + + ;
mod_timer ( & q - > timeout , jiffies + BUFFER_TIMEOUT ) ;
2008-10-17 03:18:44 +04:00
dprintk ( 5 , " [%p/%d] restart_queue - f/active \n " ,
2007-03-21 05:00:18 +03:00
buf , buf - > vb . i ) ;
} else if ( prev - > vb . width = = buf - > vb . width & &
prev - > vb . height = = buf - > vb . height & &
prev - > fmt = = buf - > fmt ) {
list_del ( & buf - > vb . queue ) ;
list_add_tail ( & buf - > vb . queue , & q - > active ) ;
2007-11-07 02:02:36 +03:00
buf - > vb . state = VIDEOBUF_ACTIVE ;
2007-03-21 05:00:18 +03:00
buf - > count = q - > count + + ;
prev - > risc . jmp [ 1 ] = cpu_to_le32 ( buf - > risc . dma ) ;
2008-10-17 03:18:44 +04:00
/* 64 bit bits 63-32 */
prev - > risc . jmp [ 2 ] = cpu_to_le32 ( 0 ) ;
dprintk ( 5 , " [%p/%d] restart_queue - m/active \n " ,
2007-03-21 05:00:18 +03:00
buf , buf - > vb . i ) ;
} else {
return 0 ;
}
prev = buf ;
}
2007-03-12 02:44:05 +03:00
return 0 ;
}
buf = list_entry ( q - > active . next , struct cx23885_buffer , vb . queue ) ;
2007-03-21 05:00:18 +03:00
dprintk ( 2 , " restart_queue [%p/%d]: restart dma \n " ,
2007-03-12 02:44:05 +03:00
buf , buf - > vb . i ) ;
cx23885_start_dma ( port , q , buf ) ;
2007-10-10 12:37:43 +04:00
list_for_each_entry ( buf , & q - > active , vb . queue )
2007-03-12 02:44:05 +03:00
buf - > count = q - > count + + ;
2007-03-21 05:00:18 +03:00
mod_timer ( & q - > timeout , jiffies + BUFFER_TIMEOUT ) ;
2007-03-12 02:44:05 +03:00
return 0 ;
}
/* ------------------------------------------------------------------ */
int cx23885_buf_prepare ( struct videobuf_queue * q , struct cx23885_tsport * port ,
struct cx23885_buffer * buf , enum v4l2_field field )
{
struct cx23885_dev * dev = port - > dev ;
int size = port - > ts_packet_size * port - > ts_packet_count ;
int rc ;
2008-04-09 06:20:00 +04:00
dprintk ( 1 , " %s: %p \n " , __func__ , buf ) ;
2007-03-12 02:44:05 +03:00
if ( 0 ! = buf - > vb . baddr & & buf - > vb . bsize < size )
return - EINVAL ;
2007-11-07 02:02:36 +03:00
if ( VIDEOBUF_NEEDS_INIT = = buf - > vb . state ) {
2007-03-12 02:44:05 +03:00
buf - > vb . width = port - > ts_packet_size ;
buf - > vb . height = port - > ts_packet_count ;
buf - > vb . size = size ;
buf - > vb . field = field /*V4L2_FIELD_TOP*/ ;
2008-10-17 03:18:44 +04:00
rc = videobuf_iolock ( q , & buf - > vb , NULL ) ;
if ( 0 ! = rc )
2007-03-12 02:44:05 +03:00
goto fail ;
cx23885_risc_databuffer ( dev - > pci , & buf - > risc ,
2007-10-04 12:28:45 +04:00
videobuf_to_dma ( & buf - > vb ) - > sglist ,
2011-10-10 18:09:52 +04:00
buf - > vb . width , buf - > vb . height , 0 ) ;
2007-03-12 02:44:05 +03:00
}
2007-11-07 02:02:36 +03:00
buf - > vb . state = VIDEOBUF_PREPARED ;
2007-03-12 02:44:05 +03:00
return 0 ;
fail :
2007-03-21 05:00:18 +03:00
cx23885_free_buffer ( q , buf ) ;
2007-03-12 02:44:05 +03:00
return rc ;
}
void cx23885_buf_queue ( struct cx23885_tsport * port , struct cx23885_buffer * buf )
{
struct cx23885_buffer * prev ;
struct cx23885_dev * dev = port - > dev ;
struct cx23885_dmaqueue * cx88q = & port - > mpegq ;
/* add jump to stopper */
buf - > risc . jmp [ 0 ] = cpu_to_le32 ( RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC ) ;
buf - > risc . jmp [ 1 ] = cpu_to_le32 ( cx88q - > stopper . dma ) ;
buf - > risc . jmp [ 2 ] = cpu_to_le32 ( 0 ) ; /* bits 63-32 */
if ( list_empty ( & cx88q - > active ) ) {
2008-10-17 03:18:44 +04:00
dprintk ( 1 , " queue is empty - first active \n " ) ;
2007-03-21 05:00:18 +03:00
list_add_tail ( & buf - > vb . queue , & cx88q - > active ) ;
2007-03-12 02:44:05 +03:00
cx23885_start_dma ( port , cx88q , buf ) ;
2007-11-07 02:02:36 +03:00
buf - > vb . state = VIDEOBUF_ACTIVE ;
2007-03-12 02:44:05 +03:00
buf - > count = cx88q - > count + + ;
2007-03-21 05:00:18 +03:00
mod_timer ( & cx88q - > timeout , jiffies + BUFFER_TIMEOUT ) ;
dprintk ( 1 , " [%p/%d] %s - first active \n " ,
2008-04-09 06:20:00 +04:00
buf , buf - > vb . i , __func__ ) ;
2007-03-12 02:44:05 +03:00
} else {
2008-10-17 03:18:44 +04:00
dprintk ( 1 , " queue is not empty - append to active \n " ) ;
2007-03-21 05:00:18 +03:00
prev = list_entry ( cx88q - > active . prev , struct cx23885_buffer ,
vb . queue ) ;
list_add_tail ( & buf - > vb . queue , & cx88q - > active ) ;
2007-11-07 02:02:36 +03:00
buf - > vb . state = VIDEOBUF_ACTIVE ;
2007-03-12 02:44:05 +03:00
buf - > count = cx88q - > count + + ;
prev - > risc . jmp [ 1 ] = cpu_to_le32 ( buf - > risc . dma ) ;
prev - > risc . jmp [ 2 ] = cpu_to_le32 ( 0 ) ; /* 64 bit bits 63-32 */
2008-10-17 03:18:44 +04:00
dprintk ( 1 , " [%p/%d] %s - append to active \n " ,
2008-04-09 06:20:00 +04:00
buf , buf - > vb . i , __func__ ) ;
2007-03-12 02:44:05 +03:00
}
}
/* ----------------------------------------------------------- */
2007-03-21 05:00:18 +03:00
static void do_cancel_buffers ( struct cx23885_tsport * port , char * reason ,
int restart )
2007-03-12 02:44:05 +03:00
{
struct cx23885_dev * dev = port - > dev ;
struct cx23885_dmaqueue * q = & port - > mpegq ;
struct cx23885_buffer * buf ;
unsigned long flags ;
2007-03-21 05:00:18 +03:00
spin_lock_irqsave ( & port - > slock , flags ) ;
2007-03-12 02:44:05 +03:00
while ( ! list_empty ( & q - > active ) ) {
2007-03-21 05:00:18 +03:00
buf = list_entry ( q - > active . next , struct cx23885_buffer ,
vb . queue ) ;
2007-03-12 02:44:05 +03:00
list_del ( & buf - > vb . queue ) ;
2007-11-07 02:02:36 +03:00
buf - > vb . state = VIDEOBUF_ERROR ;
2007-03-12 02:44:05 +03:00
wake_up ( & buf - > vb . done ) ;
2007-03-21 05:00:18 +03:00
dprintk ( 1 , " [%p/%d] %s - dma=0x%08lx \n " ,
2007-03-12 02:44:05 +03:00
buf , buf - > vb . i , reason , ( unsigned long ) buf - > risc . dma ) ;
}
2007-03-21 05:00:18 +03:00
if ( restart ) {
2008-10-17 03:18:44 +04:00
dprintk ( 1 , " restarting queue \n " ) ;
2007-03-12 02:44:05 +03:00
cx23885_restart_queue ( port , q ) ;
}
2007-03-21 05:00:18 +03:00
spin_unlock_irqrestore ( & port - > slock , flags ) ;
2007-03-12 02:44:05 +03:00
}
2008-01-14 05:42:44 +03:00
void cx23885_cancel_buffers ( struct cx23885_tsport * port )
{
struct cx23885_dev * dev = port - > dev ;
struct cx23885_dmaqueue * q = & port - > mpegq ;
2008-07-21 23:20:32 +04:00
dprintk ( 1 , " %s() \n " , __func__ ) ;
2008-01-14 05:42:44 +03:00
del_timer_sync ( & q - > timeout ) ;
cx23885_stop_dma ( port ) ;
do_cancel_buffers ( port , " cancel " , 0 ) ;
}
2007-03-12 02:44:05 +03:00
static void cx23885_timeout ( unsigned long data )
{
struct cx23885_tsport * port = ( struct cx23885_tsport * ) data ;
struct cx23885_dev * dev = port - > dev ;
2008-10-17 03:18:44 +04:00
dprintk ( 1 , " %s() \n " , __func__ ) ;
2007-03-12 02:44:05 +03:00
if ( debug > 5 )
2008-10-17 03:18:44 +04:00
cx23885_sram_channel_dump ( dev ,
& dev - > sram_channels [ port - > sram_chno ] ) ;
2007-03-20 00:01:07 +03:00
2007-03-12 02:44:05 +03:00
cx23885_stop_dma ( port ) ;
do_cancel_buffers ( port , " timeout " , 1 ) ;
}
2008-01-14 05:42:44 +03:00
int cx23885_irq_417 ( struct cx23885_dev * dev , u32 status )
{
/* FIXME: port1 assumption here. */
struct cx23885_tsport * port = & dev - > ts1 ;
int count = 0 ;
int handled = 0 ;
if ( status = = 0 )
return handled ;
count = cx_read ( port - > reg_gpcnt ) ;
dprintk ( 7 , " status: 0x%08x mask: 0x%08x count: 0x%x \n " ,
status , cx_read ( port - > reg_ts_int_msk ) , count ) ;
if ( ( status & VID_B_MSK_BAD_PKT ) | |
( status & VID_B_MSK_OPC_ERR ) | |
( status & VID_B_MSK_VBI_OPC_ERR ) | |
( status & VID_B_MSK_SYNC ) | |
( status & VID_B_MSK_VBI_SYNC ) | |
( status & VID_B_MSK_OF ) | |
( status & VID_B_MSK_VBI_OF ) ) {
printk ( KERN_ERR " %s: V4L mpeg risc op code error, status "
" = 0x%x \n " , dev - > name , status ) ;
if ( status & VID_B_MSK_BAD_PKT )
dprintk ( 1 , " VID_B_MSK_BAD_PKT \n " ) ;
if ( status & VID_B_MSK_OPC_ERR )
dprintk ( 1 , " VID_B_MSK_OPC_ERR \n " ) ;
if ( status & VID_B_MSK_VBI_OPC_ERR )
dprintk ( 1 , " VID_B_MSK_VBI_OPC_ERR \n " ) ;
if ( status & VID_B_MSK_SYNC )
dprintk ( 1 , " VID_B_MSK_SYNC \n " ) ;
if ( status & VID_B_MSK_VBI_SYNC )
dprintk ( 1 , " VID_B_MSK_VBI_SYNC \n " ) ;
if ( status & VID_B_MSK_OF )
dprintk ( 1 , " VID_B_MSK_OF \n " ) ;
if ( status & VID_B_MSK_VBI_OF )
dprintk ( 1 , " VID_B_MSK_VBI_OF \n " ) ;
cx_clear ( port - > reg_dma_ctl , port - > dma_ctl_val ) ;
cx23885_sram_channel_dump ( dev ,
& dev - > sram_channels [ port - > sram_chno ] ) ;
cx23885_417_check_encoder ( dev ) ;
} else if ( status & VID_B_MSK_RISCI1 ) {
dprintk ( 7 , " VID_B_MSK_RISCI1 \n " ) ;
spin_lock ( & port - > slock ) ;
cx23885_wakeup ( port , & port - > mpegq , count ) ;
spin_unlock ( & port - > slock ) ;
} else if ( status & VID_B_MSK_RISCI2 ) {
dprintk ( 7 , " VID_B_MSK_RISCI2 \n " ) ;
spin_lock ( & port - > slock ) ;
cx23885_restart_queue ( port , & port - > mpegq ) ;
spin_unlock ( & port - > slock ) ;
}
if ( status ) {
cx_write ( port - > reg_ts_int_stat , status ) ;
handled = 1 ;
}
return handled ;
}
2007-09-09 04:31:56 +04:00
static int cx23885_irq_ts ( struct cx23885_tsport * port , u32 status )
{
struct cx23885_dev * dev = port - > dev ;
int handled = 0 ;
u32 count ;
2008-01-14 05:42:44 +03:00
if ( ( status & VID_BC_MSK_OPC_ERR ) | |
( status & VID_BC_MSK_BAD_PKT ) | |
( status & VID_BC_MSK_SYNC ) | |
2008-10-17 03:18:44 +04:00
( status & VID_BC_MSK_OF ) ) {
2007-09-09 04:31:56 +04:00
if ( status & VID_BC_MSK_OPC_ERR )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (VID_BC_MSK_OPC_ERR 0x%08x) \n " ,
VID_BC_MSK_OPC_ERR ) ;
2007-09-09 04:31:56 +04:00
if ( status & VID_BC_MSK_BAD_PKT )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (VID_BC_MSK_BAD_PKT 0x%08x) \n " ,
VID_BC_MSK_BAD_PKT ) ;
2007-09-09 04:31:56 +04:00
if ( status & VID_BC_MSK_SYNC )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (VID_BC_MSK_SYNC 0x%08x) \n " ,
VID_BC_MSK_SYNC ) ;
2007-09-09 04:31:56 +04:00
if ( status & VID_BC_MSK_OF )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (VID_BC_MSK_OF 0x%08x) \n " ,
VID_BC_MSK_OF ) ;
2007-09-09 04:31:56 +04:00
printk ( KERN_ERR " %s: mpeg risc op code error \n " , dev - > name ) ;
cx_clear ( port - > reg_dma_ctl , port - > dma_ctl_val ) ;
2008-01-14 05:42:44 +03:00
cx23885_sram_channel_dump ( dev ,
& dev - > sram_channels [ port - > sram_chno ] ) ;
2007-09-09 04:31:56 +04:00
} else if ( status & VID_BC_MSK_RISCI1 ) {
dprintk ( 7 , " (RISCI1 0x%08x) \n " , VID_BC_MSK_RISCI1 ) ;
spin_lock ( & port - > slock ) ;
count = cx_read ( port - > reg_gpcnt ) ;
cx23885_wakeup ( port , & port - > mpegq , count ) ;
spin_unlock ( & port - > slock ) ;
} else if ( status & VID_BC_MSK_RISCI2 ) {
dprintk ( 7 , " (RISCI2 0x%08x) \n " , VID_BC_MSK_RISCI2 ) ;
spin_lock ( & port - > slock ) ;
cx23885_restart_queue ( port , & port - > mpegq ) ;
spin_unlock ( & port - > slock ) ;
}
if ( status ) {
cx_write ( port - > reg_ts_int_stat , status ) ;
handled = 1 ;
}
return handled ;
}
2007-03-12 02:57:52 +03:00
static irqreturn_t cx23885_irq ( int irq , void * dev_id )
2007-03-12 02:44:05 +03:00
{
struct cx23885_dev * dev = dev_id ;
2007-09-09 04:31:56 +04:00
struct cx23885_tsport * ts1 = & dev - > ts1 ;
struct cx23885_tsport * ts2 = & dev - > ts2 ;
2007-03-12 02:44:05 +03:00
u32 pci_status , pci_mask ;
2008-01-10 09:40:49 +03:00
u32 vida_status , vida_mask ;
2011-10-10 18:09:52 +04:00
u32 audint_status , audint_mask ;
2007-09-08 21:21:03 +04:00
u32 ts1_status , ts1_mask ;
2007-03-12 02:44:05 +03:00
u32 ts2_status , ts2_mask ;
2008-01-10 09:40:49 +03:00
int vida_count = 0 , ts1_count = 0 , ts2_count = 0 , handled = 0 ;
2011-10-10 18:09:52 +04:00
int audint_count = 0 ;
2010-07-19 07:41:41 +04:00
bool subdev_handled ;
2007-03-12 02:44:05 +03:00
pci_status = cx_read ( PCI_INT_STAT ) ;
2010-07-19 08:19:43 +04:00
pci_mask = cx23885_irq_get_mask ( dev ) ;
2008-01-10 09:40:49 +03:00
vida_status = cx_read ( VID_A_INT_STAT ) ;
vida_mask = cx_read ( VID_A_INT_MSK ) ;
2011-10-10 18:09:52 +04:00
audint_status = cx_read ( AUDIO_INT_INT_STAT ) ;
audint_mask = cx_read ( AUDIO_INT_INT_MSK ) ;
2007-09-08 21:21:03 +04:00
ts1_status = cx_read ( VID_B_INT_STAT ) ;
ts1_mask = cx_read ( VID_B_INT_MSK ) ;
2007-03-12 02:44:05 +03:00
ts2_status = cx_read ( VID_C_INT_STAT ) ;
ts2_mask = cx_read ( VID_C_INT_MSK ) ;
2008-10-17 03:18:44 +04:00
if ( ( pci_status = = 0 ) & & ( ts2_status = = 0 ) & & ( ts1_status = = 0 ) )
2007-03-12 02:44:05 +03:00
goto out ;
2008-01-10 09:40:49 +03:00
vida_count = cx_read ( VID_A_GPCNT ) ;
2011-10-10 18:09:52 +04:00
audint_count = cx_read ( AUD_INT_A_GPCNT ) ;
2007-09-09 04:31:56 +04:00
ts1_count = cx_read ( ts1 - > reg_gpcnt ) ;
ts2_count = cx_read ( ts2 - > reg_gpcnt ) ;
2008-01-10 09:40:49 +03:00
dprintk ( 7 , " pci_status: 0x%08x pci_mask: 0x%08x \n " ,
pci_status , pci_mask ) ;
dprintk ( 7 , " vida_status: 0x%08x vida_mask: 0x%08x count: 0x%x \n " ,
vida_status , vida_mask , vida_count ) ;
2011-10-10 18:09:52 +04:00
dprintk ( 7 , " audint_status: 0x%08x audint_mask: 0x%08x count: 0x%x \n " ,
audint_status , audint_mask , audint_count ) ;
2008-01-10 09:40:49 +03:00
dprintk ( 7 , " ts1_status: 0x%08x ts1_mask: 0x%08x count: 0x%x \n " ,
ts1_status , ts1_mask , ts1_count ) ;
dprintk ( 7 , " ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x \n " ,
ts2_status , ts2_mask , ts2_count ) ;
2007-03-12 02:44:05 +03:00
2009-09-28 02:51:50 +04:00
if ( pci_status & ( PCI_MSK_RISC_RD | PCI_MSK_RISC_WR |
PCI_MSK_AL_RD | PCI_MSK_AL_WR | PCI_MSK_APB_DMA |
PCI_MSK_VID_C | PCI_MSK_VID_B | PCI_MSK_VID_A |
PCI_MSK_AUD_INT | PCI_MSK_AUD_EXT |
PCI_MSK_GPIO0 | PCI_MSK_GPIO1 |
2010-07-19 07:41:41 +04:00
PCI_MSK_AV_CORE | PCI_MSK_IR ) ) {
2007-03-12 02:44:05 +03:00
if ( pci_status & PCI_MSK_RISC_RD )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (PCI_MSK_RISC_RD 0x%08x) \n " ,
PCI_MSK_RISC_RD ) ;
2007-03-12 02:44:05 +03:00
if ( pci_status & PCI_MSK_RISC_WR )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (PCI_MSK_RISC_WR 0x%08x) \n " ,
PCI_MSK_RISC_WR ) ;
2007-03-12 02:44:05 +03:00
if ( pci_status & PCI_MSK_AL_RD )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (PCI_MSK_AL_RD 0x%08x) \n " ,
PCI_MSK_AL_RD ) ;
2007-03-12 02:44:05 +03:00
if ( pci_status & PCI_MSK_AL_WR )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (PCI_MSK_AL_WR 0x%08x) \n " ,
PCI_MSK_AL_WR ) ;
2007-03-12 02:44:05 +03:00
if ( pci_status & PCI_MSK_APB_DMA )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (PCI_MSK_APB_DMA 0x%08x) \n " ,
PCI_MSK_APB_DMA ) ;
2007-03-12 02:44:05 +03:00
if ( pci_status & PCI_MSK_VID_C )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (PCI_MSK_VID_C 0x%08x) \n " ,
PCI_MSK_VID_C ) ;
2007-03-12 02:44:05 +03:00
if ( pci_status & PCI_MSK_VID_B )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (PCI_MSK_VID_B 0x%08x) \n " ,
PCI_MSK_VID_B ) ;
2007-03-12 02:44:05 +03:00
if ( pci_status & PCI_MSK_VID_A )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (PCI_MSK_VID_A 0x%08x) \n " ,
PCI_MSK_VID_A ) ;
2007-03-12 02:44:05 +03:00
if ( pci_status & PCI_MSK_AUD_INT )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (PCI_MSK_AUD_INT 0x%08x) \n " ,
PCI_MSK_AUD_INT ) ;
2007-03-12 02:44:05 +03:00
if ( pci_status & PCI_MSK_AUD_EXT )
2008-10-17 03:18:44 +04:00
dprintk ( 7 , " (PCI_MSK_AUD_EXT 0x%08x) \n " ,
PCI_MSK_AUD_EXT ) ;
2007-03-12 02:44:05 +03:00
2009-03-03 18:06:09 +03:00
if ( pci_status & PCI_MSK_GPIO0 )
dprintk ( 7 , " (PCI_MSK_GPIO0 0x%08x) \n " ,
PCI_MSK_GPIO0 ) ;
if ( pci_status & PCI_MSK_GPIO1 )
dprintk ( 7 , " (PCI_MSK_GPIO1 0x%08x) \n " ,
PCI_MSK_GPIO1 ) ;
2009-09-28 02:51:50 +04:00
2010-07-19 07:41:41 +04:00
if ( pci_status & PCI_MSK_AV_CORE )
dprintk ( 7 , " (PCI_MSK_AV_CORE 0x%08x) \n " ,
PCI_MSK_AV_CORE ) ;
2009-09-28 02:51:50 +04:00
if ( pci_status & PCI_MSK_IR )
dprintk ( 7 , " (PCI_MSK_IR 0x%08x) \n " ,
PCI_MSK_IR ) ;
2007-03-12 02:44:05 +03:00
}
2011-01-25 23:04:00 +03:00
if ( cx23885_boards [ dev - > board ] . ci_type = = 1 & &
( pci_status & ( PCI_MSK_GPIO1 | PCI_MSK_GPIO0 ) ) )
handled + = netup_ci_slot_status ( dev , pci_status ) ;
2009-04-30 03:49:12 +04:00
2011-01-25 23:04:00 +03:00
if ( cx23885_boards [ dev - > board ] . ci_type = = 2 & &
( pci_status & PCI_MSK_GPIO0 ) )
handled + = altera_ci_irq ( dev ) ;
2009-03-03 18:06:09 +03:00
2008-01-10 09:40:49 +03:00
if ( ts1_status ) {
if ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_DVB )
handled + = cx23885_irq_ts ( ts1 , ts1_status ) ;
2008-01-14 05:42:44 +03:00
else
if ( cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_ENCODER )
handled + = cx23885_irq_417 ( dev , ts1_status ) ;
2008-01-10 09:40:49 +03:00
}
if ( ts2_status ) {
if ( cx23885_boards [ dev - > board ] . portc = = CX23885_MPEG_DVB )
handled + = cx23885_irq_ts ( ts2 , ts2_status ) ;
2008-01-14 05:42:44 +03:00
else
if ( cx23885_boards [ dev - > board ] . portc = = CX23885_MPEG_ENCODER )
handled + = cx23885_irq_417 ( dev , ts2_status ) ;
2008-01-10 09:40:49 +03:00
}
2007-09-08 21:21:03 +04:00
2008-01-10 09:40:49 +03:00
if ( vida_status )
handled + = cx23885_video_irq ( dev , vida_status ) ;
2007-09-08 21:21:03 +04:00
2011-10-10 18:09:52 +04:00
if ( audint_status )
handled + = cx23885_audio_irq ( dev , audint_status , audint_mask ) ;
2009-09-28 02:51:50 +04:00
if ( pci_status & PCI_MSK_IR ) {
2010-07-19 07:41:41 +04:00
subdev_handled = false ;
2010-07-19 03:54:52 +04:00
v4l2_subdev_call ( dev - > sd_ir , core , interrupt_service_routine ,
2010-07-19 07:41:41 +04:00
pci_status , & subdev_handled ) ;
if ( subdev_handled )
handled + + ;
}
2010-07-19 08:35:46 +04:00
if ( ( pci_status & pci_mask ) & PCI_MSK_AV_CORE ) {
cx23885_irq_disable ( dev , PCI_MSK_AV_CORE ) ;
if ( ! schedule_work ( & dev - > cx25840_work ) )
printk ( KERN_ERR " %s: failed to set up deferred work for "
" AV Core/IR interrupt. Interrupt is disabled "
" and won't be re-enabled \n " , dev - > name ) ;
handled + + ;
2009-09-28 02:51:50 +04:00
}
2007-09-08 21:21:03 +04:00
if ( handled )
cx_write ( PCI_INT_STAT , pci_status ) ;
2007-03-12 02:44:05 +03:00
out :
return IRQ_RETVAL ( handled ) ;
}
2009-09-28 02:51:50 +04:00
static void cx23885_v4l2_dev_notify ( struct v4l2_subdev * sd ,
unsigned int notification , void * arg )
{
struct cx23885_dev * dev ;
if ( sd = = NULL )
return ;
dev = to_cx23885 ( sd - > v4l2_dev ) ;
switch ( notification ) {
2010-07-19 08:35:46 +04:00
case V4L2_SUBDEV_IR_RX_NOTIFY : /* Possibly called in an IRQ context */
2009-09-28 02:51:50 +04:00
if ( sd = = dev - > sd_ir )
cx23885_ir_rx_v4l2_dev_notify ( sd , * ( u32 * ) arg ) ;
break ;
2010-07-19 08:35:46 +04:00
case V4L2_SUBDEV_IR_TX_NOTIFY : /* Possibly called in an IRQ context */
2009-09-28 02:51:50 +04:00
if ( sd = = dev - > sd_ir )
cx23885_ir_tx_v4l2_dev_notify ( sd , * ( u32 * ) arg ) ;
break ;
}
}
static void cx23885_v4l2_dev_notify_init ( struct cx23885_dev * dev )
{
2010-07-19 08:35:46 +04:00
INIT_WORK ( & dev - > cx25840_work , cx23885_av_work_handler ) ;
2009-09-28 02:51:50 +04:00
INIT_WORK ( & dev - > ir_rx_work , cx23885_ir_rx_work_handler ) ;
INIT_WORK ( & dev - > ir_tx_work , cx23885_ir_tx_work_handler ) ;
dev - > v4l2_dev . notify = cx23885_v4l2_dev_notify ;
}
2009-05-11 20:37:26 +04:00
static inline int encoder_on_portb ( struct cx23885_dev * dev )
2009-05-02 18:29:50 +04:00
{
return cx23885_boards [ dev - > board ] . portb = = CX23885_MPEG_ENCODER ;
}
2009-05-11 20:37:26 +04:00
static inline int encoder_on_portc ( struct cx23885_dev * dev )
2009-05-02 18:29:50 +04:00
{
return cx23885_boards [ dev - > board ] . portc = = CX23885_MPEG_ENCODER ;
}
/* Mask represents 32 different GPIOs, GPIO's are split into multiple
* registers depending on the board configuration ( and whether the
* 417 encoder ( wi it ' s own GPIO ' s ) are present . Each GPIO bit will
* be pushed into the correct hardware register , regardless of the
* physical location . Certain registers are shared so we sanity check
* and report errors if we think we ' re tampering with a GPIo that might
* be assigned to the encoder ( and used for the host bus ) .
*
* GPIO 2 thru 0 - On the cx23885 bridge
* GPIO 18 thru 3 - On the cx23417 host bus interface
* GPIO 23 thru 19 - On the cx25840 a / v core
*/
void cx23885_gpio_set ( struct cx23885_dev * dev , u32 mask )
{
if ( mask & 0x7 )
cx_set ( GP0_IO , mask & 0x7 ) ;
if ( mask & 0x0007fff8 ) {
if ( encoder_on_portb ( dev ) | | encoder_on_portc ( dev ) )
printk ( KERN_ERR
" %s: Setting GPIO on encoder ports \n " ,
dev - > name ) ;
cx_set ( MC417_RWD , ( mask & 0x0007fff8 ) > > 3 ) ;
}
/* TODO: 23-19 */
if ( mask & 0x00f80000 )
printk ( KERN_INFO " %s: Unsupported \n " , dev - > name ) ;
}
void cx23885_gpio_clear ( struct cx23885_dev * dev , u32 mask )
{
if ( mask & 0x00000007 )
cx_clear ( GP0_IO , mask & 0x7 ) ;
if ( mask & 0x0007fff8 ) {
if ( encoder_on_portb ( dev ) | | encoder_on_portc ( dev ) )
printk ( KERN_ERR
" %s: Clearing GPIO moving on encoder ports \n " ,
dev - > name ) ;
cx_clear ( MC417_RWD , ( mask & 0x7fff8 ) > > 3 ) ;
}
/* TODO: 23-19 */
if ( mask & 0x00f80000 )
printk ( KERN_INFO " %s: Unsupported \n " , dev - > name ) ;
}
2009-11-25 02:16:04 +03:00
u32 cx23885_gpio_get ( struct cx23885_dev * dev , u32 mask )
{
if ( mask & 0x00000007 )
return ( cx_read ( GP0_IO ) > > 8 ) & mask & 0x7 ;
if ( mask & 0x0007fff8 ) {
if ( encoder_on_portb ( dev ) | | encoder_on_portc ( dev ) )
printk ( KERN_ERR
" %s: Reading GPIO moving on encoder ports \n " ,
dev - > name ) ;
return ( cx_read ( MC417_RWD ) & ( ( mask & 0x7fff8 ) > > 3 ) ) < < 3 ;
}
/* TODO: 23-19 */
if ( mask & 0x00f80000 )
printk ( KERN_INFO " %s: Unsupported \n " , dev - > name ) ;
return 0 ;
}
2009-05-02 18:29:50 +04:00
void cx23885_gpio_enable ( struct cx23885_dev * dev , u32 mask , int asoutput )
{
if ( ( mask & 0x00000007 ) & & asoutput )
cx_set ( GP0_IO , ( mask & 0x7 ) < < 16 ) ;
else if ( ( mask & 0x00000007 ) & & ! asoutput )
cx_clear ( GP0_IO , ( mask & 0x7 ) < < 16 ) ;
if ( mask & 0x0007fff8 ) {
if ( encoder_on_portb ( dev ) | | encoder_on_portc ( dev ) )
printk ( KERN_ERR
" %s: Enabling GPIO on encoder ports \n " ,
dev - > name ) ;
}
/* MC417_OEN is active low for output, write 1 for an input */
if ( ( mask & 0x0007fff8 ) & & asoutput )
cx_clear ( MC417_OEN , ( mask & 0x7fff8 ) > > 3 ) ;
else if ( ( mask & 0x0007fff8 ) & & ! asoutput )
cx_set ( MC417_OEN , ( mask & 0x7fff8 ) > > 3 ) ;
/* TODO: 23-19 */
}
2007-03-12 02:44:05 +03:00
static int __devinit cx23885_initdev ( struct pci_dev * pci_dev ,
2007-03-21 05:00:18 +03:00
const struct pci_device_id * pci_id )
2007-03-12 02:44:05 +03:00
{
struct cx23885_dev * dev ;
int err ;
2007-03-21 05:00:18 +03:00
dev = kzalloc ( sizeof ( * dev ) , GFP_KERNEL ) ;
2007-03-12 02:44:05 +03:00
if ( NULL = = dev )
return - ENOMEM ;
2009-03-13 14:02:43 +03:00
err = v4l2_device_register ( & pci_dev - > dev , & dev - > v4l2_dev ) ;
if ( err < 0 )
goto fail_free ;
2009-09-28 02:51:50 +04:00
/* Prepare to handle notifications from subdevices */
cx23885_v4l2_dev_notify_init ( dev ) ;
2007-03-12 02:44:05 +03:00
/* pci init */
dev - > pci = pci_dev ;
if ( pci_enable_device ( pci_dev ) ) {
err = - EIO ;
2009-03-13 14:02:43 +03:00
goto fail_unreg ;
2007-03-12 02:44:05 +03:00
}
if ( cx23885_dev_setup ( dev ) < 0 ) {
err = - EINVAL ;
2009-03-13 14:02:43 +03:00
goto fail_unreg ;
2007-03-12 02:44:05 +03:00
}
/* print pci info */
2011-03-21 17:35:56 +03:00
dev - > pci_rev = pci_dev - > revision ;
2007-03-12 02:44:05 +03:00
pci_read_config_byte ( pci_dev , PCI_LATENCY_TIMER , & dev - > pci_lat ) ;
printk ( KERN_INFO " %s/0: found at %s, rev: %d, irq: %d, "
" latency: %d, mmio: 0x%llx \n " , dev - > name ,
pci_name ( pci_dev ) , dev - > pci_rev , pci_dev - > irq ,
2008-01-14 05:44:47 +03:00
dev - > pci_lat ,
( unsigned long long ) pci_resource_start ( pci_dev , 0 ) ) ;
2007-03-12 02:44:05 +03:00
pci_set_master ( pci_dev ) ;
if ( ! pci_dma_supported ( pci_dev , 0xffffffff ) ) {
printk ( " %s/0: Oops: no 32bit PCI DMA ??? \n " , dev - > name ) ;
err = - EIO ;
goto fail_irq ;
}
2011-06-30 01:36:19 +04:00
err = request_irq ( pci_dev - > irq , cx23885_irq ,
IRQF_SHARED | IRQF_DISABLED , dev - > name , dev ) ;
2007-03-12 02:44:05 +03:00
if ( err < 0 ) {
printk ( KERN_ERR " %s: can't get IRQ %d \n " ,
dev - > name , pci_dev - > irq ) ;
goto fail_irq ;
}
2009-03-13 19:24:19 +03:00
switch ( dev - > board ) {
case CX23885_BOARD_NETUP_DUAL_DVBS2_CI :
2011-01-25 23:04:00 +03:00
cx23885_irq_add_enable ( dev , PCI_MSK_GPIO1 | PCI_MSK_GPIO0 ) ;
break ;
case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF :
cx23885_irq_add_enable ( dev , PCI_MSK_GPIO0 ) ;
2009-03-13 19:24:19 +03:00
break ;
}
2009-03-03 18:06:09 +03:00
2009-09-28 02:51:50 +04:00
/*
* The CX2388 [ 58 ] IR controller can start firing interrupts when
* enabled , so these have to take place after the cx23885_irq ( ) handler
* is hooked up by the call to request_irq ( ) above .
*/
cx23885_ir_pci_int_enable ( dev ) ;
2009-09-28 03:55:41 +04:00
cx23885_input_init ( dev ) ;
2009-09-28 02:51:50 +04:00
2007-03-12 02:44:05 +03:00
return 0 ;
fail_irq :
cx23885_dev_unregister ( dev ) ;
2009-03-13 14:02:43 +03:00
fail_unreg :
v4l2_device_unregister ( & dev - > v4l2_dev ) ;
2007-03-12 02:44:05 +03:00
fail_free :
kfree ( dev ) ;
return err ;
}
static void __devexit cx23885_finidev ( struct pci_dev * pci_dev )
{
2009-03-13 14:02:43 +03:00
struct v4l2_device * v4l2_dev = pci_get_drvdata ( pci_dev ) ;
struct cx23885_dev * dev = to_cx23885 ( v4l2_dev ) ;
2007-03-12 02:44:05 +03:00
2009-09-28 03:55:41 +04:00
cx23885_input_fini ( dev ) ;
2009-09-28 02:51:50 +04:00
cx23885_ir_fini ( dev ) ;
2007-03-12 02:44:05 +03:00
2009-09-28 02:51:50 +04:00
cx23885_shutdown ( dev ) ;
2009-09-27 06:17:30 +04:00
2007-03-12 02:44:05 +03:00
pci_disable_device ( pci_dev ) ;
/* unregister stuff */
free_irq ( pci_dev - > irq , dev ) ;
cx23885_dev_unregister ( dev ) ;
2009-03-13 14:02:43 +03:00
v4l2_device_unregister ( v4l2_dev ) ;
2007-03-12 02:44:05 +03:00
kfree ( dev ) ;
}
static struct pci_device_id cx23885_pci_tbl [ ] = {
{
/* CX23885 */
. vendor = 0x14f1 ,
. device = 0x8852 ,
. subvendor = PCI_ANY_ID ,
. subdevice = PCI_ANY_ID ,
2008-10-17 03:18:44 +04:00
} , {
2007-03-12 02:44:05 +03:00
/* CX23887 Rev 2 */
. vendor = 0x14f1 ,
. device = 0x8880 ,
. subvendor = PCI_ANY_ID ,
. subdevice = PCI_ANY_ID ,
2008-10-17 03:18:44 +04:00
} , {
2007-03-12 02:44:05 +03:00
/* --- end of list --- */
}
} ;
MODULE_DEVICE_TABLE ( pci , cx23885_pci_tbl ) ;
static struct pci_driver cx23885_pci_driver = {
. name = " cx23885 " ,
. id_table = cx23885_pci_tbl ,
. probe = cx23885_initdev ,
. remove = __devexit_p ( cx23885_finidev ) ,
/* TODO */
. suspend = NULL ,
. resume = NULL ,
} ;
2009-11-04 21:28:33 +03:00
static int __init cx23885_init ( void )
2007-03-12 02:44:05 +03:00
{
[media] Stop using linux/version.h on most video drivers
All the modified drivers didn't have any version increment since
Jan, 1 2011. Several of them didn't have any version increment
for a long time, even having new features and important bug fixes
happening.
As we're now filling the QUERYCAP version with the current Kernel
Release, we don't need to maintain a per-driver version control
anymore. So, let's just use the default.
In order to preserve the Kernel module version history, a
KERNEL_VERSION() macro were added to all modified drivers, and
the extraver number were incremented.
I opted to preserve the per-driver version control to a few
pwc, pvrusb2, s2255, s5p-fimc and sh_vou.
A few drivers are still using the legacy way to handle ioctl's.
So, we can't do such change on them, otherwise, they'll break.
Those are: uvc, et61x251 and sn9c102.
The rationale is that the per-driver version control seems to be
actively maintained on those.
Yet, I think that the better for them would be to just use the
default version numbering, instead of doing that by themselves.
While here, removed a few uneeded include linux/version.h
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2011-06-24 21:45:49 +04:00
printk ( KERN_INFO " cx23885 driver version %s loaded \n " ,
CX23885_VERSION ) ;
2007-03-12 02:44:05 +03:00
return pci_register_driver ( & cx23885_pci_driver ) ;
}
2009-11-04 21:28:33 +03:00
static void __exit cx23885_fini ( void )
2007-03-12 02:44:05 +03:00
{
pci_unregister_driver ( & cx23885_pci_driver ) ;
}
module_init ( cx23885_init ) ;
module_exit ( cx23885_fini ) ;