Commit c634920a authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb

* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (310 commits)
  V4L/DVB (6316): Change list_for_each+list_entry to list_for_each_entry
  V4L/DVB (6315): pvrusb2: Change list_for_each+list_entry to list_for_each_entry
  V4L/DVB (6314): saa7134: Replace list_for_each+list_entry with list_for_each_entry
  V4L/DVB (6313): ivtv: Replace list_for_each+list_entry with list_for_each_entry
  V4L/DVB (6312): cx88: Replace list_for_each+list_entry with list_for_each_entry
  V4L/DVB (6311): dvb: Replace list_for_each+list_entry with list_for_each_entry
  V4L/DVB (6308): V4L: zc0301, remove bad usage of ERESTARTSYS
  V4L/DVB (6307): V4L: w9968cf, remove bad usage of ERESTARTSYS
  V4L/DVB (6306): Few clenups for saa7134 resume code
  V4L/DVB (6305): V4L: videobuf-core.c avoid NULL dereferences in videobuf-core
  V4L/DVB (6301): pvrusb: Update DEBUGIFC sysfs to kernel 2.6.13+
  V4L/DVB (6300): CodingStyle cleanup
  V4L/DVB (6299): dvb: Add dependencies for VIDEOBUF_DVB
  V4L/DVB (6297): cx23885: remove wrong Kconfig selection of VIDEOBUF
  V4L/DVB (6296): dib0700: add support for AverMedia DVB-T Express card
  V4L/DVB (6295): saa7134: add autodetection for KWorld ATSC-115
  V4L/DVB (6293): V4L: convert struct class_device to struct device
  V4L/DVB (6292): videobuf_core init always require callback implementation
  V4L/DVB (6291): Fix: avoid oops on some SMP machines
  V4L/DVB (6290): remove videobuf_set_pci_ops
  ...
parents 6abd2c86 a991f44b
......@@ -150,7 +150,7 @@ Some very frequently asked questions about linuxtv-dvb
- saa7146_vv: SAA7146 video and vbi functions. These are only needed
for full-featured cards.
- video-buf: capture helper module for the saa7146_vv driver. This
- videobuf-dma-sg: capture helper module for the saa7146_vv driver. This
one is responsible to handle capture buffers.
- dvb-ttpci: The main driver for AV7110 based, full-featured
......
......@@ -147,3 +147,4 @@
146 -> SSAI Ultrasound Video Interface [414a:5353]
147 -> VoodooTV 200 (USA) [121a:3000]
148 -> DViCO FusionHDTV 2 [dbc0:d200]
149 -> Typhoon TV-Tuner PCI (50684)
0 -> UNKNOWN/GENERIC [0070:3400]
1 -> Hauppauge WinTV-HVR1800lp [0070:7600]
2 -> Hauppauge WinTV-HVR1800 [0070:7800,0070:7801]
3 -> Hauppauge WinTV-HVR1250 [0070:7911]
4 -> DViCO FusionHDTV5 Express [18ac:d500]
......@@ -88,11 +88,11 @@
87 -> ADS Instant TV Duo Cardbus PTV331 [0331:1421]
88 -> Tevion/KWorld DVB-T 220RF [17de:7201]
89 -> ELSA EX-VISION 700TV [1048:226c]
90 -> Kworld ATSC110 [17de:7350]
90 -> Kworld ATSC110/115 [17de:7350,17de:7352]
91 -> AVerMedia A169 B [1461:7360]
92 -> AVerMedia A169 B1 [1461:6360]
93 -> Medion 7134 Bridge #2 [16be:0005]
94 -> LifeView FlyDVB-T Hybrid Cardbus [5168:3306,5168:3502]
94 -> LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB [5168:3306,5168:3502,4e42:3502]
95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138]
96 -> Medion Md8800 Quadro [16be:0007,16be:0008]
97 -> LifeView FlyDVB-S /Acorp TV134DS [5168:0300,4e42:0300]
......@@ -115,3 +115,4 @@
114 -> KWorld DVB-T 210 [17de:7250]
115 -> Sabrent PCMCIA TV-PCB05 [0919:2003]
116 -> 10MOONS TM300 TV Card [1131:2304]
117 -> Avermedia Super 007 [1461:f01d]
......@@ -69,13 +69,79 @@ source "drivers/media/common/Kconfig"
config VIDEO_TUNER
tristate
depends on I2C
select TUNER_MT20XX if !VIDEO_TUNER_CUSTOMIZE
select TUNER_TDA8290 if !VIDEO_TUNER_CUSTOMIZE
select TUNER_TEA5761 if !VIDEO_TUNER_CUSTOMIZE
select TUNER_TEA5767 if !VIDEO_TUNER_CUSTOMIZE
select TUNER_SIMPLE if !VIDEO_TUNER_CUSTOMIZE
menuconfig VIDEO_TUNER_CUSTOMIZE
bool "Customize analog tuner modules to build"
depends on VIDEO_TUNER
help
This allows the user to deselect tuner drivers unnecessary
for their hardware from the build. Use this option with care
as deselecting tuner drivers which are in fact necessary will
result in V4L devices which cannot be tuned due to lack of
driver support
If unsure say N.
if VIDEO_TUNER_CUSTOMIZE
config TUNER_MT20XX
tristate "Microtune 2032 / 2050 tuners"
depends on I2C
default m if VIDEO_TUNER_CUSTOMIZE
help
Say Y here to include support for the MT2032 / MT2050 tuner.
config TUNER_TDA8290
tristate "TDA 8290+8275(a) tuner combo"
depends on I2C
default m if VIDEO_TUNER_CUSTOMIZE
help
Say Y here to include support for Philips TDA8290+8275(a) tuner.
config TUNER_TEA5761
tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
depends on I2C && EXPERIMENTAL
default m if VIDEO_TUNER_CUSTOMIZE
help
Say Y here to include support for the Philips TEA5761 radio tuner.
config TUNER_TEA5767
tristate "TEA 5767 radio tuner"
depends on I2C
default m if VIDEO_TUNER_CUSTOMIZE
help
Say Y here to include support for the Philips TEA5767 radio tuner.
config TUNER_SIMPLE
tristate "Simple tuner support"
depends on I2C
default m if VIDEO_TUNER_CUSTOMIZE
help
Say Y here to include support for various simple tuners.
config VIDEO_BUF
endif # VIDEO_TUNER_CUSTOMIZE
config VIDEOBUF_GEN
tristate
config VIDEOBUF_DMA_SG
depends on PCI
select VIDEOBUF_GEN
tristate
config VIDEOBUF_VMALLOC
select VIDEOBUF_GEN
tristate
config VIDEO_BUF_DVB
config VIDEOBUF_DVB
tristate
select VIDEOBUF_GEN
select VIDEOBUF_DMA_SG
config VIDEO_BTCX
tristate
......
......@@ -5,5 +5,5 @@ config VIDEO_SAA7146
config VIDEO_SAA7146_VV
tristate
depends on VIDEO_DEV
select VIDEO_BUF
select VIDEOBUF_DMA_SG
select VIDEO_SAA7146
......@@ -21,7 +21,6 @@
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/jiffies.h>
#include <media/ir-common.h>
......
......@@ -20,7 +20,6 @@
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/input.h>
#include <media/ir-common.h>
......@@ -1783,3 +1782,64 @@ IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_tt_1500);
/* DViCO FUSION HDTV MCE remote */
IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE] = {
[ 0x0b ] = KEY_1,
[ 0x17 ] = KEY_2,
[ 0x1b ] = KEY_3,
[ 0x07 ] = KEY_4,
[ 0x50 ] = KEY_5,
[ 0x54 ] = KEY_6,
[ 0x48 ] = KEY_7,
[ 0x4c ] = KEY_8,
[ 0x58 ] = KEY_9,
[ 0x03 ] = KEY_0,
[ 0x5e ] = KEY_OK,
[ 0x51 ] = KEY_UP,
[ 0x53 ] = KEY_DOWN,
[ 0x5b ] = KEY_LEFT,
[ 0x5f ] = KEY_RIGHT,
[ 0x02 ] = KEY_TV, /* Labeled DTV on remote */
[ 0x0e ] = KEY_MP3,
[ 0x1a ] = KEY_DVD,
[ 0x1e ] = KEY_FAVORITES, /* Labeled CPF on remote */
[ 0x16 ] = KEY_SETUP,
[ 0x46 ] = KEY_POWER2, /* TV On/Off button on remote */
[ 0x0a ] = KEY_EPG, /* Labeled Guide on remote */
[ 0x49 ] = KEY_BACK,
[ 0x59 ] = KEY_INFO, /* Labeled MORE on remote */
[ 0x4d ] = KEY_MENU, /* Labeled DVDMENU on remote */
[ 0x55 ] = KEY_CYCLEWINDOWS, /* Labeled ALT-TAB on remote */
[ 0x0f ] = KEY_PREVIOUSSONG, /* Labeled |<< REPLAY on remote */
[ 0x12 ] = KEY_NEXTSONG, /* Labeled >>| SKIP on remote */
[ 0x42 ] = KEY_ENTER, /* Labeled START with a green
* MS windows logo on remote */
[ 0x15 ] = KEY_VOLUMEUP,
[ 0x05 ] = KEY_VOLUMEDOWN,
[ 0x11 ] = KEY_CHANNELUP,
[ 0x09 ] = KEY_CHANNELDOWN,
[ 0x52 ] = KEY_CAMERA,
[ 0x5a ] = KEY_TUNER,
[ 0x19 ] = KEY_OPEN,
[ 0x13 ] = KEY_MODE, /* 4:3 16:9 select */
[ 0x1f ] = KEY_ZOOM,
[ 0x43 ] = KEY_REWIND,
[ 0x47 ] = KEY_PLAYPAUSE,
[ 0x4f ] = KEY_FASTFORWARD,
[ 0x57 ] = KEY_MUTE,
[ 0x0d ] = KEY_STOP,
[ 0x01 ] = KEY_RECORD,
[ 0x4e ] = KEY_POWER,
};
EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce);
......@@ -100,7 +100,7 @@ int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
* general helper functions
****************************************************************************/
/* this is videobuf_vmalloc_to_sg() from video-buf.c
/* this is videobuf_vmalloc_to_sg() from videobuf-dma-sg.c
make sure virt has been allocated with vmalloc_32(), otherwise the BUG()
may be triggered on highmem machines */
static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
......@@ -248,10 +248,11 @@ int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt
static irqreturn_t interrupt_hw(int irq, void *dev_id)
{
struct saa7146_dev *dev = dev_id;
u32 isr = 0;
u32 isr;
u32 ack_isr;
/* read out the interrupt status register */
isr = saa7146_read(dev, ISR);
ack_isr = isr = saa7146_read(dev, ISR);
/* is this our interrupt? */
if ( 0 == isr ) {
......@@ -259,8 +260,6 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id)
return IRQ_NONE;
}
saa7146_write(dev, ISR, isr);
if( 0 != (dev->ext)) {
if( 0 != (dev->ext->irq_mask & isr )) {
if( 0 != dev->ext->irq_func ) {
......@@ -283,21 +282,16 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id)
isr &= ~MASK_28;
}
if (0 != (isr & (MASK_16|MASK_17))) {
u32 status = saa7146_read(dev, I2C_STATUS);
if( (0x3 == (status & 0x3)) || (0 == (status & 0x1)) ) {
SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
/* only wake up if we expect something */
if( 0 != dev->i2c_op ) {
u32 psr = (saa7146_read(dev, PSR) >> 16) & 0x2;
u32 ssr = (saa7146_read(dev, SSR) >> 17) & 0x1f;
DEB_I2C(("irq: i2c, status: 0x%08x, psr:0x%02x, ssr:0x%02x).\n",status,psr,ssr));
dev->i2c_op = 0;
wake_up(&dev->i2c_wq);
} else {
DEB_I2C(("unexpected irq: i2c, status: 0x%08x, isr %#x\n",status, isr));
}
SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
/* only wake up if we expect something */
if (0 != dev->i2c_op) {
dev->i2c_op = 0;
wake_up(&dev->i2c_wq);
} else {
DEB_I2C(("unhandled irq: i2c, status: 0x%08x, isr %#x\n",status, isr));
u32 psr = saa7146_read(dev, PSR);
u32 ssr = saa7146_read(dev, SSR);
printk(KERN_WARNING "%s: unexpected i2c irq: isr %08x psr %08x ssr %08x\n",
dev->name, isr, psr, ssr);
}
isr &= ~(MASK_16|MASK_17);
}
......@@ -306,6 +300,7 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id)
ERR(("disabling interrupt source(s)!\n"));
SAA7146_IER_DISABLE(dev,isr);
}
saa7146_write(dev, ISR, ack_isr);
return IRQ_HANDLED;
}
......@@ -548,7 +543,6 @@ EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
EXPORT_SYMBOL_GPL(saa7146_setgpio);
EXPORT_SYMBOL_GPL(saa7146_i2c_transfer);
EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare);
EXPORT_SYMBOL_GPL(saa7146_debug);
......
......@@ -53,13 +53,14 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q,
struct saa7146_buf *buf)
{
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
DEB_EE(("dev:%p, buf:%p\n",dev,buf));
BUG_ON(in_interrupt());
videobuf_waiton(&buf->vb,0,0);
videobuf_dma_unmap(q, &buf->vb.dma);
videobuf_dma_free(&buf->vb.dma);
videobuf_dma_unmap(q, dma);
videobuf_dma_free(dma);
buf->vb.state = STATE_NEEDS_INIT;
}
......
......@@ -202,7 +202,8 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
/* a signal arrived */
return -ERESTARTSYS;
printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for end of xfer\n");
printk(KERN_WARNING "%s %s [irq]: timed out waiting for end of xfer\n",
dev->name, __FUNCTION__);
return -EIO;
}
status = saa7146_read(dev, I2C_STATUS);
......@@ -219,7 +220,8 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
break;
}
if (time_after(jiffies,timeout)) {
printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for MC2\n");
printk(KERN_WARNING "%s %s: timed out waiting for MC2\n",
dev->name, __FUNCTION__);
return -EIO;
}
}
......@@ -235,7 +237,8 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
/* this is normal when probing the bus
* (no answer from nonexisistant device...)
*/
DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n"));
printk(KERN_WARNING "%s %s [poll]: timed out waiting for end of xfer\n",
dev->name, __FUNCTION__);
return -EIO;
}
if (++trial < 50 && short_delay)
......@@ -246,8 +249,16 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
}
/* give a detailed status report */
if ( 0 != (status & SAA7146_I2C_ERR)) {
if ( 0 != (status & (SAA7146_I2C_SPERR | SAA7146_I2C_APERR |
SAA7146_I2C_DTERR | SAA7146_I2C_DRERR |
SAA7146_I2C_AL | SAA7146_I2C_ERR |
SAA7146_I2C_BUSY)) ) {
if ( 0 == (status & SAA7146_I2C_ERR) ||
0 == (status & SAA7146_I2C_BUSY) ) {
/* it may take some time until ERR goes high - ignore */
DEB_I2C(("unexpected i2c status %04x\n", status));
}
if( 0 != (status & SAA7146_I2C_SPERR) ) {
DEB_I2C(("error due to invalid start/stop condition.\n"));
}
......@@ -277,7 +288,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d
return 0;
}
int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, int num, int retries)
static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, int num, int retries)
{
int i = 0, count = 0;
u32* buffer = dev->d_i2c.cpu_addr;
......
......@@ -165,7 +165,7 @@ static void saa7146_set_vbi_capture(struct saa7146_dev *dev, struct saa7146_buf
/* we don't wait here for the first field anymore. this is different from the video
capture and might cause that the first buffer is only half filled (with only
one field). but since this is some sort of streaming data, this is not that negative.
but by doing this, we can use the whole engine from video-buf.c... */
but by doing this, we can use the whole engine from videobuf-dma-sg.c... */
/*
WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait);
......@@ -239,6 +239,8 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
saa7146_dma_free(dev,q,buf);
if (STATE_NEEDS_INIT == buf->vb.state) {
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
buf->vb.width = llength;
buf->vb.height = lines;
buf->vb.size = size;
......@@ -250,7 +252,8 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
err = videobuf_iolock(q,&buf->vb, NULL);
if (err)
goto oops;
err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2], buf->vb.dma.sglist, buf->vb.dma.sglen);
err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2],
dma->sglist, dma->sglen);
if (0 != err)
return err;
}
......@@ -404,7 +407,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file)
fh->vbi_fmt.start[1] = 312;
fh->vbi_fmt.count[1] = 16;
videobuf_queue_init(&fh->vbi_q, &vbi_qops,
videobuf_queue_pci_init(&fh->vbi_q, &vbi_qops,
dev->pci, &dev->slock,
V4L2_BUF_TYPE_VBI_CAPTURE,
V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
......
......@@ -594,8 +594,9 @@ static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf)
{
struct pci_dev *pci = dev->pci;
struct scatterlist *list = buf->vb.dma.sglist;
int length = buf->vb.dma.sglen;
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
struct scatterlist *list = dma->sglist;
int length = dma->sglen;
struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length));
......@@ -655,7 +656,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
/* if we have a user buffer, the first page may not be
aligned to a page boundary. */
pt1->offset = buf->vb.dma.sglist->offset;
pt1->offset = list->offset;
pt2->offset = pt1->offset+o1;
pt3->offset = pt1->offset+o2;
......@@ -1211,6 +1212,8 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
mutex_unlock(&q->lock);
return err;
}
gbuffers = err;
memset(mbuf,0,sizeof(*mbuf));
mbuf->frames = gbuffers;
mbuf->size = gbuffers * gbufsize;
......@@ -1411,7 +1414,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
videobuf_queue_init(&fh->video_q, &video_qops,
videobuf_queue_pci_init(&fh->video_q, &video_qops,
dev->pci, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_INTERLACED,
......
......@@ -28,7 +28,6 @@
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <asm/io.h>
......
......@@ -149,11 +149,10 @@ void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin,
void bt878_stop(struct bt878 *bt);
#if defined(__powerpc__) /* big-endian */
extern __inline__ void io_st_le32(volatile unsigned __iomem *addr, unsigned val)
static inline void io_st_le32(volatile unsigned __iomem *addr, unsigned val)
{
__asm__ __volatile__("stwbrx %1,0,%2":"=m"(*addr):"r"(val),
"r"(addr));
__asm__ __volatile__("eieio":::"memory");
st_le32(addr, val);
eieio();
}
#define bmtwrite(dat,adr) io_st_le32((adr),(dat))
......
......@@ -21,7 +21,6 @@
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/device.h>
......
......@@ -548,19 +548,19 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct
{
struct dvb_device *dvbdev = file->private_data;
struct cinergyt2 *cinergyt2 = dvbdev->priv;
unsigned int mask = 0;
unsigned int mask = 0;
if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
poll_wait(file, &cinergyt2->poll_wq, wait);
if (cinergyt2->pending_fe_events != 0)
if (cinergyt2->pending_fe_events != 0)
mask |= (POLLIN | POLLRDNORM | POLLPRI);
mutex_unlock(&cinergyt2->sem);
return mask;
return mask;
}
......@@ -1008,6 +1008,8 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
cinergyt2_sleep(cinergyt2, 1);
mutex_unlock(&cinergyt2->sem);
mutex_unlock(&cinergyt2->wq_sem);
return 0;
}
......
......@@ -24,7 +24,6 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/poll.h>
#include <linux/ioctl.h>
#include <linux/wait.h>
......
......@@ -32,11 +32,11 @@
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include "dvb_ca_en50221.h"
#include "dvb_ringbuffer.h"
......@@ -140,13 +140,7 @@ struct dvb_ca_private {
wait_queue_head_t wait_queue;
/* PID of the monitoring thread */
pid_t thread_pid;
/* Wait queue used when shutting thread down */
wait_queue_head_t thread_queue;
/* Flag indicating when thread should exit */
unsigned int exit:1;
struct task_struct *thread;
/* Flag indicating if the CA device is open */
unsigned int open:1;
......@@ -902,27 +896,9 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
ca->wakeup = 1;
mb();
wake_up_interruptible(&ca->thread_queue);
wake_up_process(ca->thread);
}
/**
* Used by the CA thread to determine if an early wakeup is necessary
*
* @param ca CA instance.
*/
static int dvb_ca_en50221_thread_should_wakeup(struct dvb_ca_private *ca)
{
if (ca->wakeup) {
ca->wakeup = 0;
return 1;
}
if (ca->exit)
return 1;
return 0;
}
/**
* Update the delay used by the thread.
*
......@@ -982,7 +958,6 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
static int dvb_ca_en50221_thread(void *data)
{
struct dvb_ca_private *ca = data;
char name[15];
int slot;
int flags;
int status;
......@@ -991,28 +966,17 @@ static int dvb_ca_en50221_thread(void *data)
dprintk("%s\n", __FUNCTION__);
/* setup kernel thread */
snprintf(name, sizeof(name), "kdvb-ca-%i:%i", ca->dvbdev->adapter->num, ca->dvbdev->id);
lock_kernel();
daemonize(name);
sigfillset(&current->blocked);
unlock_kernel();
/* choose the correct initial delay */
dvb_ca_en50221_thread_update_delay(ca);
/* main loop */
while (!ca->exit) {
while (!kthread_should_stop()) {
/* sleep for a bit */
if (!ca->wakeup) {
flags = wait_event_interruptible_timeout(ca->thread_queue,
dvb_ca_en50221_thread_should_wakeup(ca),
ca->delay);
if ((flags == -ERESTARTSYS) || ca->exit) {
/* got signal or quitting */
break;
}
while (!ca->wakeup) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(ca->delay);
if (kthread_should_stop())
return 0;
}
ca->wakeup = 0;
......@@ -1181,10 +1145,6 @@ static int dvb_ca_en50221_thread(void *data)
}
}
/* completed */
ca->thread_pid = 0;
mb();
wake_up_interruptible(&ca->thread_queue);
return 0;
}
......@@ -1536,8 +1496,10 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
return -EIO;
err = dvb_generic_open(inode, file);
if (err < 0)
if (err < 0) {
module_put(ca->pub->owner);
return err;
}
for (i = 0; i < ca->slot_count; i++) {
......@@ -1570,7 +1532,7 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev = file->private_data;
struct dvb_ca_private *ca = dvbdev->priv;
int err = 0;
int err;
dprintk("%s\n", __FUNCTION__);
......@@ -1582,7 +1544,7 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
module_put(ca->pub->owner);
return 0;
return err;
}
......@@ -1682,9 +1644,6 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
goto error;
}
init_waitqueue_head(&ca->wait_queue);
ca->thread_pid = 0;
init_waitqueue_head(&ca->thread_queue);
ca->exit = 0;
ca->open = 0;
ca->wakeup = 0;
ca->next_read_slot = 0;
......@@ -1710,14 +1669,14 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
mb();
/* create a kthread for monitoring this CA device */
ret = kernel_thread(dvb_ca_en50221_thread, ca, 0);
if (ret < 0) {
printk("dvb_ca_init: failed to start kernel_thread (%d)\n", ret);
ca->thread = kthread_run(dvb_ca_en50221_thread, ca, "kdvb-ca-%i:%i",
ca->dvbdev->adapter->num, ca->dvbdev->id);
if (IS_ERR(ca->thread)) {
ret = PTR_ERR(ca->thread);
printk("dvb_ca_init: failed to start kernel_thread (%d)\n",
ret);
goto error;
}
ca->thread_pid = ret;
return 0;
error:
......@@ -1748,17 +1707,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
dprintk("%s\n", __FUNCTION__);
/* shutdown the thread if there was one */
if (ca->thread_pid) {
if (kill_proc(ca->thread_pid, 0, 1) == -ESRCH) {
printk("dvb_ca_release adapter %d: thread PID %d already died\n",
ca->dvbdev->adapter->num, ca->thread_pid);
} else {
ca->exit = 1;
mb();
dvb_ca_en50221_thread_wakeup(ca);
wait_event_interruptible(ca->thread_queue, ca->thread_pid == 0);
}
}
kthread_stop(ca->thread);
for (i = 0; i < ca->slot_count; i++) {
dvb_ca_en50221_slot_shutdown(ca, i);
......
......@@ -373,13 +373,10 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed,
static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
{
struct dvb_demux_feed *feed;
struct list_head *pos, *head = &demux->feed_list;
u16 pid = ts_pid(buf);
int dvr_done = 0;
list_for_each(pos, head) {
feed = list_entry(pos, struct dvb_demux_feed, list_head);
list_for_each_entry(feed, &demux->feed_list, list_head) {
if ((feed->pid != pid) && (feed->pid != 0x2000))
continue;
......
......@@ -32,7 +32,6 @@
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/list.h>
#include <linux/freezer.h>
#include <linux/jiffies.h>
......@@ -43,7 +42,7 @@
#include "dvbdev.h"
static int dvb_frontend_debug;
static int dvb_shutdown_timeout = 5;
static int dvb_shutdown_timeout;
static int dvb_force_auto_inversion;
static int dvb_override_tune_delay;
static int dvb_powerdown_on_sleep = 1;
......@@ -138,7 +137,7 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
dprintk ("%s\n", __FUNCTION__);
if (down_interruptible (&events->sem))
if (mutex_lock_interruptible (&events->mtx))
return;
wp = (events->eventw + 1) % MAX_EVENT;
......@@ -159,7 +158,7 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
events->eventw = wp;
up (&events->sem);
mutex_unlock(&events->mtx);
e->status = status;
......@@ -197,7 +196,7 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
return ret;
}
if (down_interruptible (&events->sem))
if (mutex_lock_interruptible (&events->mtx))
return -ERESTARTSYS;
memcpy (event, &events->events[events->eventr],
......@@ -205,7 +204,7 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
events->eventr = (events->eventr + 1) % MAX_EVENT;
up (&events->sem);
mutex_unlock(&events->mtx);
return 0;
}
......@@ -574,10 +573,9 @@ static int dvb_frontend_thread(void *data)
dvb_frontend_swzigzag(fe);
}
if (dvb_shutdown_timeout) {
if (dvb_powerdown_on_sleep)
if (fe->ops.set_voltage)
fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
if (dvb_powerdown_on_sleep) {
if (fe->ops.set_voltage)
fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
if (fe->ops.tuner_ops.sleep) {
fe->ops.tuner_ops.sleep(fe);
if (fe->ops.i2c_gate_ctrl)
......@@ -697,6 +695,65 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
return 0;
}
static void dvb_frontend_get_frequeny_limits(struct dvb_frontend *fe,
u32 *freq_min, u32 *freq_max)
{
*freq_min = max(fe->ops.info.frequency_min, fe->ops.tuner_ops.info.frequency_min);
if (fe->ops.info.frequency_max == 0)
*freq_max = fe->ops.tuner_ops.info.frequency_max;
else if (fe->ops.tuner_ops.info.frequency_max == 0)
*freq_max = fe->ops.info.frequency_max;
else
*freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max);
if (*freq_min == 0 || *freq_max == 0)
printk(KERN_WARNING "DVB: frontend %u frequency limits undefined - fix the driver\n",
fe->dvb->num);
}
static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
struct dvb_frontend_parameters *parms)
{
u32 freq_min;
u32 freq_max;
/* range check: frequency */
dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max);
if ((freq_min && parms->frequency < freq_min) ||
(freq_max && parms->frequency > freq_max)) {
printk(KERN_WARNING "DVB: frontend %u frequency %u out of range (%u..%u)\n",
fe->dvb->num, parms->frequency, freq_min, freq_max);
return -EINVAL;
}
/* range check: symbol rate */
if (fe->ops.info.type == FE_QPSK) {
if ((fe->ops.info.symbol_rate_min &&
parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) ||
(fe->ops.info.symbol_rate_max &&
parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) {
printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n",
fe->dvb->num, parms->u.qpsk.symbol_rate,
fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
return -EINVAL;
}
} else if (fe->ops.info.type == FE_QAM) {
if ((fe->ops.info.symbol_rate_min &&
parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) ||
(fe->ops.info.symbol_rate_max &&
parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) {
printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n",
fe->dvb->num, parms->u.qam.symbol_rate,
fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
return -EINVAL;
}
}
return 0;
}
static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg)
{
......@@ -707,7 +764,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
dprintk ("%s\n", __FUNCTION__);
if (!fe || fepriv->exit)
if (fepriv->exit)
return -ENODEV;
if ((file->f_flags & O_ACCMODE) == O_RDONLY &&
......@@ -722,6 +779,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
case FE_GET_INFO: {
struct dvb_frontend_info* info = parg;
memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info));
dvb_frontend_get_frequeny_limits(fe, &info->frequency_min, &info->frequency_max);
/* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't
* do it, it is done for it. */
......@@ -883,6 +941,11 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
case FE_SET_FRONTEND: {
struct dvb_frontend_tune_settings fetunesettings;
if (dvb_frontend_check_parameters(fe, parg) < 0) {
err = -EINVAL;
break;
}
memcpy (&fepriv->parameters, parg,
sizeof (struct dvb_frontend_parameters));
......@@ -992,18 +1055,15 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
dprintk ("%s\n", __FUNCTION__);
if ((ret = dvb_generic_open (inode, file)) < 0)
return ret;
if (fe->ops.ts_bus_ctrl) {
if ((ret = fe->ops.ts_bus_ctrl (fe, 1)) < 0) {
dvb_generic_release (inode, file);
if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
return ret;
}
}
if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
if ((ret = dvb_generic_open (inode, file)) < 0)
goto err1;
if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
/* normal tune mode when opened R/W */
fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT;
fepriv->tone = -1;
......@@ -1011,13 +1071,20 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
ret = dvb_frontend_start (fe);
if (ret)
dvb_generic_release (inode, file);
goto err2;
/* empty event queue */
fepriv->events.eventr = fepriv->events.eventw = 0;
}
return ret;
err2:
dvb_generic_release(inode, file);
err1:
if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl(fe, 0);
return ret;
}
static int dvb_frontend_release(struct inode *inode, struct file *file)
......@@ -1032,16 +1099,18 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
if ((file->f_flags & O_ACCMODE) != O_RDONLY)
fepriv->release_jiffies = jiffies;
if (fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl (fe, 0);
ret = dvb_generic_release (inode, file);
if (dvbdev->users==-1 && fepriv->exit==1) {
fops_put(file->f_op);
file->f_op = NULL;
wake_up(&dvbdev->wait_queue);
if (dvbdev->users == -1) {
if (fepriv->exit == 1) {
fops_put(file->f_op);
file->f_op = NULL;
wake_up(&dvbdev->wait_queue);
}
if (fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl(fe, 0);
}
return ret;
}
......@@ -1080,7 +1149,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
init_MUTEX (&fepriv->sem);
init_waitqueue_head (&fepriv->wait_queue);
init_waitqueue_head (&fepriv->events.wait_queue);
init_MUTEX (&fepriv->events.sem);
mutex_init(&fepriv->events.mtx);
fe->dvb = dvb;
fepriv->inversion = INVERSION_OFF;
......
......@@ -35,6 +35,7 @@
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/dvb/frontend.h>
......@@ -61,6 +62,13 @@ struct dvb_tuner_info {
u32 bandwidth_step;
};
struct analog_parameters {
unsigned int frequency;
unsigned int mode;
unsigned int audmode;
u64 std;
};
struct dvb_tuner_ops {
struct dvb_tuner_info info;
......@@ -71,6 +79,7 @@ struct dvb_tuner_ops {
/** This is for simple PLLs - set all parameters in one go. */
int (*set_params)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
int (*set_analog_params)(struct dvb_frontend *fe, struct analog_parameters *p);
/** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */
int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len);
......@@ -79,7 +88,9 @@ struct dvb_tuner_ops {
int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
#define TUNER_STATUS_LOCKED 1
#define TUNER_STATUS_STEREO 2
int (*get_status)(struct dvb_frontend *fe, u32 *status);
int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength);
/** These are provided seperately from set_params in order to facilitate silicon
* tuners which require sophisticated tuning loops, controlling each parameter seperately. */
......@@ -142,7 +153,7 @@ struct dvb_fe_events {
int eventr;
int overflow;
wait_queue_head_t wait_queue;
struct semaphore sem;
struct mutex mtx;
};
struct dvb_frontend {
......
......@@ -357,11 +357,6 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
static unsigned char *ule_where = ule_hist, ule_dump = 0;
#endif
if (dev == NULL) {
printk( KERN_ERR "NO netdev struct!\n" );
return;
}
/* For all TS cells in current buffer.
* Appearently, we are called for every single TS cell.
*/
......@@ -800,8 +795,8 @@ static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
}
static void dvb_net_sec(struct net_device *dev, const u8 *pkt, int
pkt_len)
static void dvb_net_sec(struct net_device *dev,
const u8 *pkt, int pkt_len)
{
u8 *eth;
struct sk_buff *skb;
......@@ -1446,18 +1441,9 @@ static int dvb_net_close(struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data;
struct dvb_net *dvbnet = dvbdev->priv;
if (!dvbdev)
return -ENODEV;
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
dvbdev->readers++;
} else {
dvbdev->writers++;
}
dvbdev->users++;
dvb_generic_release(inode, file);
if(dvbdev->users == 1 && dvbnet->exit==1) {
if(dvbdev->users == 1 && dvbnet->exit == 1) {
fops_put(file->f_op);
file->f_op = NULL;
wake_up(&dvbdev->wait_queue);
......
......@@ -25,7 +25,6 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
......@@ -59,18 +58,13 @@ static struct class *dvb_class;
static struct dvb_device* dvbdev_find_device (int minor)
{
struct list_head *entry;
struct dvb_adapter *adap;
list_for_each (entry, &dvb_adapter_list) {
struct list_head *entry0;
struct dvb_adapter *adap;
adap = list_entry (entry, struct dvb_adapter, list_head);
list_for_each (entry0, &adap->device_list) {
struct dvb_device *dev;
dev = list_entry (entry0, struct dvb_device, list_head);
list_for_each_entry(adap, &dvb_adapter_list, list_head) {
struct dvb_device *dev;
list_for_each_entry(dev, &adap->device_list, list_head)
if (nums2minor(adap->num, dev->type, dev->id) == minor)
return dev;
}
}
return NULL;
......@@ -180,13 +174,10 @@ static int dvbdev_get_free_id (struct dvb_adapter *adap, int type)
u32 id = 0;
while (id < DVB_MAX_IDS) {
struct list_head *entry;
list_for_each (entry, &adap->device_list) {
struct dvb_device *dev;
dev = list_entry (entry, struct dvb_device, list_head);
struct dvb_device *dev;
list_for_each_entry(dev, &adap->device_list, list_head)
if (dev->type == type && dev->id == id)
goto skip;
}
return id;
skip:
id++;
......@@ -200,7 +191,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
{
struct dvb_device *dvbdev;
struct file_operations *dvbdevfops;
struct class_device *clsdev;
struct device *clsdev;
int id;
mutex_lock(&dvbdev_register_lock);
......@@ -242,10 +233,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
mutex_unlock(&dvbdev_register_lock);
clsdev = class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR,
nums2minor(adap->num, type, id)),
adap->device, "dvb%d.%s%d", adap->num,
dnames[type], id);
clsdev = device_create(dvb_class, adap->device,
MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
"dvb%d.%s%d", adap->num, dnames[type], id);
if (IS_ERR(clsdev)) {
printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
__FUNCTION__, adap->num, dnames[type], id, PTR_ERR(clsdev));
......@@ -266,8 +256,8 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
if (!dvbdev)
return;
class_device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
dvbdev->type, dvbdev->id)));
device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
dvbdev->type, dvbdev->id)));
list_del (&dvbdev->list_head);
kfree (dvbdev->fops);
......@@ -281,13 +271,10 @@ static int dvbdev_get_free_adapter_num (void)
int num = 0;
while (num < DVB_MAX_ADAPTERS) {
struct list_head *entry;
list_for_each (entry, &dvb_adapter_list) {
struct dvb_adapter *adap;
adap = list_entry (entry, struct dvb_adapter, list_head);
struct dvb_adapter *adap;
list_for_each_entry(adap, &dvb_adapter_list, list_head)
if (adap->num == num)
goto skip;
}
return num;
skip:
num++;
......
......@@ -74,6 +74,8 @@ config DVB_USB_DIB0700
select DVB_DIB7000M
select DVB_DIB3000MC
select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE
select DVB_TUNER_MT2266 if !DVB_FE_CUSTOMISE
select DVB_TUNER_DIB0070
help
Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
USB bridge is also present in devices having the DiB7700 DVB-T-USB
......
......@@ -30,17 +30,19 @@ extern int dvb_usb_dib0700_debug;
// 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
// 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
// 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " )
#define REQUEST_SET_RC 0x11
#define REQUEST_GET_VERSION 0x15
struct dib0700_state {
u8 channel_state;
u16 mt2060_if1[2];
u8 rc_toggle;
u8 is_dib7000pc;
};
extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3);
extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen);
extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw);
extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
extern struct i2c_algorithm dib0700_i2c_algo;
......@@ -50,5 +52,4 @@ extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device
extern int dib0700_device_count;
extern struct dvb_usb_device_properties dib0700_devices[];
extern struct usb_device_id dib0700_usb_id_table[];
#endif
......@@ -13,6 +13,10 @@ int dvb_usb_dib0700_debug;
module_param_named(debug,dvb_usb_dib0700_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS);
static int dvb_usb_dib0700_ir_proto = 1;
module_param(dvb_usb_dib0700_ir_proto, int, 0644);
MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6).");
/* expecting rx buffer: request data[0] data[1] ... data[2] */
static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
{
......@@ -32,7 +36,7 @@ static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
}
/* expecting tx buffer: request data[0] ... data[n] (n <= 4) */
static int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
{
u16 index, value;
int status;
......@@ -260,14 +264,29 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
return dib0700_ctrl_wr(adap->dev, b, 4);
}
static int dib0700_rc_setup(struct dvb_usb_device *d)
{
u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0};
int i = dib0700_ctrl_wr(d, rc_setup, 3);
if (i<0) {
err("ir protocol setup failed");
return -1;
}
return 0;
}
static int dib0700_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
int i;
struct dvb_usb_device *dev;
for (i = 0; i < dib0700_device_count; i++)
if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE, NULL) == 0)
if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE, &dev) == 0)
{
dib0700_rc_setup(dev);
return 0;
}
return -ENODEV;
}
......
This diff is collapsed.
/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
* Typhoon/ Yuan DVB-T USB2.0 receiver.
* Typhoon/ Yuan/ Miglia DVB-T USB2.0 receiver.
*
* Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
*
......@@ -96,6 +96,7 @@ static struct dvb_usb_device_properties dtt200u_properties;
static struct dvb_usb_device_properties wt220u_fc_properties;
static struct dvb_usb_device_properties wt220u_properties;
static struct dvb_usb_device_properties wt220u_zl0353_properties;
static struct dvb_usb_device_properties wt220u_miglia_properties;
static int dtt200u_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
......@@ -103,7 +104,8 @@ static int dtt200u_usb_probe(struct usb_interface *intf,
if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE,NULL) == 0 ||
dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE,NULL) == 0 ||
dvb_usb_device_init(intf,&wt220u_fc_properties,THIS_MODULE,NULL) == 0 ||
dvb_usb_device_init(intf,&wt220u_zl0353_properties,THIS_MODULE,NULL) == 0)
dvb_usb_device_init(intf,&wt220u_zl0353_properties,THIS_MODULE,NULL) == 0 ||
dvb_usb_device_init(intf,&wt220u_miglia_properties,THIS_MODULE,NULL) == 0)
return 0;
return -ENODEV;
......@@ -119,6 +121,7 @@ static struct usb_device_id dtt200u_usb_table [] = {
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_COLD) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_WARM) },
{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZAP250_COLD) },
{ USB_DEVICE(USB_VID_MIGLIA, USB_PID_WT220U_ZAP250_COLD) },
{ 0 },
};
MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
......@@ -303,6 +306,25 @@ static struct dvb_usb_device_properties wt220u_zl0353_properties = {
}
};
static struct dvb_usb_device_properties wt220u_miglia_properties = {
.usb_ctrl = CYPRESS_FX2,
.firmware = "dvb-usb-wt220u-miglia-01.fw",
.num_adapters = 1,
.generic_bulk_ctrl_endpoint = 0x01,
.num_device_descs = 1,
.devices = {
{ .name = "WideView WT-220U PenType Receiver (Miglia)",
.cold_ids = { &dtt200u_usb_table[9], NULL },
/* This device turns into WT220U_ZL0353_WARM when fw
has been uploaded */
.warm_ids = { NULL },
},
{ NULL },
}
};
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver dtt200u_usb_driver = {
.name = "dvb_usb_dtt200u",
......@@ -333,6 +355,6 @@ module_init(dtt200u_usb_module_init);
module_exit(dtt200u_usb_module_exit);
MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D DVB-T USB2.0 devices");
MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL");
......@@ -12,7 +12,7 @@
/* Vendor IDs */
#define USB_VID_ADSTECH 0x06e1
#define USB_VID_AFATECH 0x15a4
#define USB_VID_ALCOR_MICRO 0x058f
#define USB_VID_ALCOR_MICRO 0x058f
#define USB_VID_ALINK 0x05e3
#define USB_VID_ANCHOR 0x0547
#define USB_VID_ANUBIS_ELECTRONIC 0x10fd
......@@ -34,6 +34,7 @@
#define USB_VID_LEADTEK 0x0413
#define USB_VID_LITEON 0x04ca
#define USB_VID_MEDION 0x1660
#define USB_VID_MIGLIA 0x18f3
#define USB_VID_MSI 0x0db0
#define USB_VID_OPERA1 0x695c
#define USB_VID_PINNACLE 0x2304
......@@ -58,6 +59,7 @@
#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
#define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78
#define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80
#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
......@@ -66,6 +68,9 @@
#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
#define USB_PID_DIBCOM_STK7700P 0x1e14
#define USB_PID_DIBCOM_STK7700P_PC 0x1e78
#define USB_PID_DIBCOM_STK7700D 0x1ef0
#define USB_PID_DIBCOM_STK7070P 0x1ebc
#define USB_PID_DIBCOM_STK7070PD 0x1ebe
#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
#define USB_PID_DPOSH_M9206_COLD 0x9206
#define USB_PID_DPOSH_M9206_WARM 0xa090
......@@ -115,8 +120,17 @@
#define USB_PID_HAUPPAUGE_NOVA_T_500_2 0x9950
#define USB_PID_HAUPPAUGE_NOVA_T_STICK 0x7050
#define USB_PID_HAUPPAUGE_NOVA_T_STICK_2 0x7060
#define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580
#define USB_PID_AVERMEDIA_EXPRESS 0xb568
#define USB_PID_AVERMEDIA_VOLAR 0xa807
#define USB_PID_AVERMEDIA_VOLAR_2 0xb808
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
#define USB_PID_PINNACLE_PCTV2000E 0x022c
#define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228
#define USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T 0x0229
#define USB_PID_PCTV_200E 0x020e
#define USB_PID_PCTV_400E 0x020f
#define USB_PID_PCTV_450E 0x0222
#define USB_PID_NEBULA_DIGITV 0x0201
#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820
#define USB_PID_DVICO_BLUEBIRD_LG064F_COLD 0xd500
......@@ -136,9 +150,6 @@
#define USB_PID_MSI_MEGASKY580_55801 0x5581
#define USB_PID_KYE_DVB_T_COLD 0x701e
#define USB_PID_KYE_DVB_T_WARM 0x701f
#define USB_PID_PCTV_200E 0x020e
#define USB_PID_PCTV_400E 0x020f
#define USB_PID_PCTV_450E 0x0222
#define USB_PID_LITEON_DVB_T_COLD 0xf000
#define USB_PID_LITEON_DVB_T_WARM 0xf001
#define USB_PID_DIGIVOX_MINI_SL_COLD 0xe360
......@@ -148,8 +159,11 @@
#define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025
#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026
#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00
#define USB_PID_GENPIX_8PSK_COLD 0x0200
#define USB_PID_GENPIX_8PSK_WARM 0x0201
#define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200
#define USB_PID_GENPIX_8PSK_REV_1_WARM 0x0201
#define USB_PID_GENPIX_8PSK_REV_2 0x0202
#define USB_PID_GENPIX_SKYWALKER_1 0x0203
#define USB_PID_GENPIX_SKYWALKER_CW3K 0x0204
#define USB_PID_SIGMATEK_DVB_110 0x6610
#define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513
#define USB_PID_OPERA1_COLD 0x2830
......
......@@ -24,7 +24,7 @@ MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0
static int dvb_usb_force_pid_filter_usage;
module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444);
MODULE_PARM_DESC(disable_rc_polling, "force all dvb-usb-devices to use a PID filter, if any (default: 0).");
MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID filter, if any (default: 0).");
static int dvb_usb_adapter_init(struct dvb_usb_device *d)
{
......
/* DVB USB compliant Linux driver for the
* - GENPIX 8pks/qpsk USB2.0 DVB-S module
* - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
*
* Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
* Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
* Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com)
*
* Thanks to GENPIX for the sample code used to implement this module.
*
......@@ -17,27 +18,39 @@
struct gp8psk_fe_state {
struct dvb_frontend fe;
struct dvb_usb_device *d;
u8 lock;
u16 snr;
unsigned long next_snr_check;
unsigned long next_status_check;
unsigned long status_check_interval;
};
static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
{
u8 buf[6];
if (time_after(jiffies,st->next_status_check)) {
gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0,0,&st->lock,1);
gp8psk_usb_in_op(st->d, GET_SIGNAL_STRENGTH, 0,0,buf,6);
st->snr = (buf[1]) << 8 | buf[0];
st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
}
return 0;
}
static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
{
struct gp8psk_fe_state *st = fe->demodulator_priv;
u8 lock;
gp8psk_fe_update_status(st);
if (gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0, 0, &lock,1))
return -EINVAL;
if (lock)
if (st->lock)
*status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
else
*status = 0;
if (*status & FE_HAS_LOCK)
st->status_check_interval = 1000;
else
st->status_check_interval = 100;
return 0;
}
......@@ -60,33 +73,29 @@ static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
{
struct gp8psk_fe_state *st = fe->demodulator_priv;
u8 buf[2];
if (time_after(jiffies,st->next_snr_check)) {
gp8psk_usb_in_op(st->d,GET_SIGNAL_STRENGTH,0,0,buf,2);
*snr = (int)(buf[1]) << 8 | buf[0];
/* snr is reported in dBu*256 */
/* snr / 38.4 ~= 100% strength */
/* snr * 17 returns 100% strength as 65535 */
if (*snr <= 3855)
*snr = (*snr<<4) + *snr; // snr * 17
else
*snr = 65535;
st->next_snr_check = jiffies + (10*HZ)/1000;
} else {
*snr = st->snr;
}
gp8psk_fe_update_status(st);
/* snr is reported in dBu*256 */
*snr = st->snr;
return 0;
}
static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
{
return gp8psk_fe_read_snr(fe, strength);
struct gp8psk_fe_state *st = fe->demodulator_priv;
gp8psk_fe_update_status(st);
/* snr is reported in dBu*256 */
/* snr / 38.4 ~= 100% strength */
/* snr * 17 returns 100% strength as 65535 */
if (st->snr > 0xf00)
*strength = 0xffff;
else
*strength = (st->snr << 4) + st->snr; /* snr*17 */
return 0;
}
static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
{
tune->min_delay_ms = 800;
tune->min_delay_ms = 200;
return 0;
}
......@@ -124,7 +133,9 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
gp8psk_usb_out_op(state->d,TUNE_8PSK,0,0,cmd,10);
state->next_snr_check = jiffies;
state->lock = 0;
state->next_status_check = jiffies;
state->status_check_interval = 200;
return 0;
}
......@@ -190,6 +201,12 @@ static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t volt
return 0;
}
static int gp8psk_fe_enable_high_lnb_voltage(struct dvb_frontend* fe, long onoff)
{
struct gp8psk_fe_state* state = fe->demodulator_priv;
return gp8psk_usb_out_op(state->d, USE_EXTRA_VOLT, onoff, 0,NULL,0);
}
static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
{
struct gp8psk_fe_state* state = fe->demodulator_priv;
......@@ -235,10 +252,10 @@ struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
static struct dvb_frontend_ops gp8psk_fe_ops = {
.info = {
.name = "Genpix 8psk-USB DVB-S",
.name = "Genpix 8psk-to-USB2 DVB-S",
.type = FE_QPSK,
.frequency_min = 950000,
.frequency_max = 2150000,
.frequency_min = 800000,
.frequency_max = 2250000,
.frequency_stepsize = 100,
.symbol_rate_min = 1000000,
.symbol_rate_max = 45000000,
......@@ -269,4 +286,5 @@ static struct dvb_frontend_ops gp8psk_fe_ops = {
.set_tone = gp8psk_fe_set_tone,
.set_voltage = gp8psk_fe_set_voltage,
.dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd,
.enable_high_lnb_voltage = gp8psk_fe_enable_high_lnb_voltage
};
/* DVB USB compliant Linux driver for the
* - GENPIX 8pks/qpsk USB2.0 DVB-S module
* - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
*
* Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
* Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
* Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com)
*
* Thanks to GENPIX for the sample code used to implement this module.
*
......@@ -40,7 +41,7 @@ int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8
}
if (ret < 0 || ret != blen) {
warn("usb in operation failed.");
warn("usb in %d operation failed.", req);
ret = -EIO;
} else
ret = 0;
......@@ -97,10 +98,10 @@ static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0))
goto out_rel_fw;
info("downloaidng bcm4500 firmware from file '%s'",bcm4500_firmware);
info("downloading bcm4500 firmware from file '%s'",bcm4500_firmware);
ptr = fw->data;
buf = kmalloc(512, GFP_KERNEL | GFP_DMA);
buf = kmalloc(64, GFP_KERNEL | GFP_DMA);
while (ptr[0] != 0xff) {
u16 buflen = ptr[0] + 4;
......@@ -129,25 +130,34 @@ static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
{
u8 status, buf;
int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
if (onoff) {
gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
if (! (status & 0x01)) /* started */
if (! (status & bm8pskStarted)) { /* started */
if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
gp8psk_usb_out_op(d, CW3K_INIT, 1, 0, NULL, 0);
if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
return -EINVAL;
}
if (! (status & 0x02)) /* BCM4500 firmware loaded */
if(gp8psk_load_bcm4500fw(d))
return EINVAL;
if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
if (! (status & bm8pskFW_Loaded)) /* BCM4500 firmware loaded */
if(gp8psk_load_bcm4500fw(d))
return EINVAL;
if (! (status & 0x04)) /* LNB Power */
if (! (status & bmIntersilOn)) /* LNB Power */
if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0,
&buf, 1))
return EINVAL;
/* Set DVB mode */
if(gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
return -EINVAL;
gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
/* Set DVB mode to 1 */
if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
if (gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
return EINVAL;
/* Abort possible TS (if previous tune crashed) */
if (gp8psk_usb_out_op(d, ARM_TRANSFER, 0, 0, NULL, 0))
return EINVAL;
} else {
/* Turn off LNB power */
if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1))
......@@ -155,11 +165,28 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
/* Turn off 8psk power */
if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
return -EINVAL;
if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
gp8psk_usb_out_op(d, CW3K_INIT, 0, 0, NULL, 0);
}
return 0;
}
int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
{
u8 buf;
int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
/* Turn off 8psk power */
if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
return -EINVAL;
/* Turn On 8psk power */
if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
return -EINVAL;
/* load BCM4500 firmware */
if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
if (gp8psk_load_bcm4500fw(d))
return EINVAL;
return 0;
}
static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
......@@ -177,12 +204,22 @@ static struct dvb_usb_device_properties gp8psk_properties;
static int gp8psk_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL);
int ret;
struct usb_device *udev = interface_to_usbdev(intf);
ret = dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL);
if (ret == 0) {
info("found Genpix USB device pID = %x (hex)",
le16_to_cpu(udev->descriptor.idProduct));
}
return ret;
}
static struct usb_device_id gp8psk_usb_table [] = {
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_COLD) },
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_WARM) },
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_COLD) },
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) },
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) },
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) },
{ USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) },
{ 0 },
};
MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
......@@ -213,12 +250,24 @@ static struct dvb_usb_device_properties gp8psk_properties = {
.generic_bulk_ctrl_endpoint = 0x01,
.num_device_descs = 1,
.num_device_descs = 4,
.devices = {
{ .name = "Genpix 8PSK-USB DVB-S USB2.0 receiver",
{ .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver",
.cold_ids = { &gp8psk_usb_table[0], NULL },
.warm_ids = { &gp8psk_usb_table[1], NULL },
},
{ .name = "Genpix 8PSK-to-USB2 Rev.2 DVB-S receiver",
.cold_ids = { NULL },
.warm_ids = { &gp8psk_usb_table[2], NULL },
},
{ .name = "Genpix SkyWalker-1 DVB-S receiver",
.cold_ids = { NULL },
.warm_ids = { &gp8psk_usb_table[3], NULL },
},
{ .name = "Genpix SkyWalker-CW3K DVB-S receiver",
.cold_ids = { NULL },
.warm_ids = { &gp8psk_usb_table[4], NULL },
},
{ NULL },
}
};
......@@ -253,6 +302,6 @@ module_init(gp8psk_usb_module_init);
module_exit(gp8psk_usb_module_exit);
MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
MODULE_DESCRIPTION("Driver for Genpix 8psk-USB DVB-S USB2.0");
MODULE_VERSION("1.0");
MODULE_DESCRIPTION("Driver for Genpix 8psk-to-USB2 DVB-S");
MODULE_VERSION("1.1");
MODULE_LICENSE("GPL");
/* DVB USB compliant Linux driver for the
* - GENPIX 8pks/qpsk USB2.0 DVB-S module
* - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
*
* Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
* Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
*
* Thanks to GENPIX for the sample code used to implement this module.
*
......@@ -30,21 +31,37 @@ extern int dvb_usb_gp8psk_debug;
#define TH_COMMAND_IN 0xC0
#define TH_COMMAND_OUT 0xC1
/* command bytes */
#define GET_8PSK_CONFIG 0x80
/* gp8psk commands */
#define GET_8PSK_CONFIG 0x80 /* in */
#define SET_8PSK_CONFIG 0x81
#define I2C_WRITE 0x83
#define I2C_READ 0x84
#define ARM_TRANSFER 0x85
#define TUNE_8PSK 0x86
#define GET_SIGNAL_STRENGTH 0x87
#define GET_SIGNAL_STRENGTH 0x87 /* in */
#define LOAD_BCM4500 0x88
#define BOOT_8PSK 0x89
#define START_INTERSIL 0x8A
#define BOOT_8PSK 0x89 /* in */
#define START_INTERSIL 0x8A /* in */
#define SET_LNB_VOLTAGE 0x8B
#define SET_22KHZ_TONE 0x8C
#define SEND_DISEQC_COMMAND 0x8D
#define SET_DVB_MODE 0x8E
#define SET_DN_SWITCH 0x8F
#define GET_SIGNAL_LOCK 0x90
#define GET_SIGNAL_LOCK 0x90 /* in */
#define GET_SERIAL_NUMBER 0x93 /* in */
#define USE_EXTRA_VOLT 0x94
#define CW3K_INIT 0x9d
/* PSK_configuration bits */
#define bm8pskStarted 0x01
#define bm8pskFW_Loaded 0x02
#define bmIntersilOn 0x04
#define bmDVBmode 0x08
#define bm22kHz 0x10
#define bmSEL18V 0x20
#define bmDCtuned 0x40
#define bmArmed 0x80
/* Satellite modulation modes */
#define ADV_MOD_DVB_QPSK 0 /* DVB-S QPSK */
......@@ -75,5 +92,6 @@ extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
u16 index, u8 *b, int blen);
extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);
#endif
......@@ -159,7 +159,7 @@ static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
return 0;
}
for (i = 0; i < sizeof(vp7045_rc_keys)/sizeof(struct dvb_usb_rc_key); i++)
for (i = 0; i < ARRAY_SIZE(vp7045_rc_keys); i++)
if (vp7045_rc_keys[i].data == key) {
*state = REMOTE_KEY_PRESSED;
*event = vp7045_rc_keys[i].event;
......
......@@ -283,6 +283,14 @@ config DVB_LGDT330X
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
config DVB_S5H1409
tristate "Samsung S5H1409 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
comment "Tuners/PLL support"
depends on DVB_CORE
......@@ -291,7 +299,7 @@ config DVB_PLL
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
This module driver a number of tuners based on PLL chips with a
This module drives a number of tuners based on PLL chips with a
common I2C interface. Say Y when you want to support these tuners.
config DVB_TDA826X
......@@ -322,6 +330,29 @@ config DVB_TUNER_MT2060
help
A driver for the silicon IF tuner MT2060 from Microtune.
config DVB_TUNER_MT2266
tristate "Microtune MT2266 silicon tuner"
depends on I2C
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon baseband tuner MT2266 from Microtune.
config DVB_TUNER_MT2131
tristate "Microtune MT2131 silicon tuner"
depends on I2C
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon baseband tuner MT2131 from Microtune.
config DVB_TUNER_DIB0070
tristate "DiBcom DiB0070 silicon base-band tuner"
depends on I2C
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon baseband tuner DiB0070 from DiBcom.
This device is only used inside a SiP called togther with a
demodulator for now.
comment "Miscellaneous devices"
depends on DVB_CORE
......
......@@ -40,5 +40,9 @@ obj-$(CONFIG_DVB_TDA10086) += tda10086.o
obj-$(CONFIG_DVB_TDA826X) += tda826x.o
obj-$(CONFIG_DVB_TDA827X) += tda827x.o
obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
obj-$(CONFIG_DVB_TUNER_MT2266) += mt2266.o
obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o
obj-$(CONFIG_DVB_TUA6100) += tua6100.o
obj-$(CONFIG_DVB_TUNER_MT2131) += mt2131.o
obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
......@@ -33,7 +33,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/jiffies.h>
......
......@@ -23,7 +23,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/slab.h>
#include "dvb_frontend.h"
......
......@@ -25,7 +25,6 @@
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include "dvb_frontend.h"
......
......@@ -23,7 +23,6 @@
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include "dvb_frontend.h"
......
This diff is collapsed.
/*
* Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner.
*
* Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
*
* 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, version 2.
*/
#ifndef DIB0070_H
#define DIB0070_H
struct dvb_frontend;
struct i2c_adapter;
#define DEFAULT_DIB0070_I2C_ADDRESS 0x60
struct dib0070_config {
u8 i2c_address;
/* tuner pins controlled externally */
int (*reset) (struct dvb_frontend *, int);
int (*sleep) (struct dvb_frontend *, int);
/* offset in kHz */
int freq_offset_khz_uhf;
int freq_offset_khz_vhf;
u8 osc_buffer_state; /* 0= normal, 1= tri-state */
u32 clock_khz;
u8 clock_pad_drive; /* (Drive + 1) * 2mA */
u8 invert_iq; /* invert Q - in case I or Q is inverted on the board */
u8 force_crystal_mode; /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */
u8 flip_chip;
};
extern struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open);
extern u16 dib0070_wbd_offset(struct dvb_frontend *);
#endif
......@@ -23,7 +23,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/string.h>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -9,6 +9,7 @@ struct dib7000p_config {
u8 tuner_is_baseband;
int (*update_lna) (struct dvb_frontend *, u16 agc_global);
u8 agc_config_count;
struct dibx000_agc_config *agc;
struct dibx000_bandwidth_config *bw;
......@@ -27,20 +28,19 @@ struct dib7000p_config {
u8 quartz_direct;
u8 spur_protect;
int (*agc_control) (struct dvb_frontend *, u8 before);
};
#define DEFAULT_DIB7000P_I2C_ADDRESS 18
extern struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
extern struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
/* TODO
extern INT dib7000p_set_gpio(struct dibDemod *demod, UCHAR num, UCHAR dir, UCHAR val);
extern INT dib7000p_enable_vbg_voltage(struct dibDemod *demod);
extern void dib7000p_set_hostbus_diversity(struct dibDemod *demod, UCHAR onoff);
extern USHORT dib7000p_get_current_agc_global(struct dibDemod *demod);
*/
extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
#endif
......@@ -111,6 +111,8 @@ struct dibx000_bandwidth_config {
u32 ifreq;
u32 timf;
u32 xtal_hz;
};
enum dibx000_adc_states {
......@@ -122,56 +124,17 @@ enum dibx000_adc_states {
DIBX000_VBG_DISABLE,
};
#define BW_INDEX_TO_KHZ(v) ( (v) == BANDWIDTH_8_MHZ ? 8000 : \
#define BANDWIDTH_TO_KHZ(v) ( (v) == BANDWIDTH_8_MHZ ? 8000 : \
(v) == BANDWIDTH_7_MHZ ? 7000 : \
(v) == BANDWIDTH_6_MHZ ? 6000 : 8000 )
/* Chip output mode. */
#define OUTMODE_HIGH_Z 0
#define OUTMODE_MPEG2_PAR_GATED_CLK 1
#define OUTMODE_MPEG2_PAR_CONT_CLK 2
#define OUTMODE_MPEG2_SERIAL 7
#define OUTMODE_DIVERSITY 4
#define OUTMODE_MPEG2_FIFO 5
/* I hope I can get rid of the following kludge in the near future */
struct dibx000_ofdm_channel {
u32 RF_kHz;
u8 Bw;
s16 nfft;
s16 guard;
s16 nqam;
s16 vit_hrch;
s16 vit_select_hp;
s16 vit_alpha;
s16 vit_code_rate_hp;
s16 vit_code_rate_lp;
u8 intlv_native;
};
#define FEP2DIB(fep,ch) \
(ch)->RF_kHz = (fep)->frequency / 1000; \
(ch)->Bw = (fep)->u.ofdm.bandwidth; \
(ch)->nfft = (fep)->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ? -1 : (fep)->u.ofdm.transmission_mode; \
(ch)->guard = (fep)->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ? -1 : (fep)->u.ofdm.guard_interval; \
(ch)->nqam = (fep)->u.ofdm.constellation == QAM_AUTO ? -1 : (fep)->u.ofdm.constellation == QAM_64 ? 2 : (fep)->u.ofdm.constellation; \
(ch)->vit_hrch = 0; /* linux-dvb is not prepared for HIERARCHICAL TRANSMISSION */ \
(ch)->vit_select_hp = 1; \
(ch)->vit_alpha = 1; \
(ch)->vit_code_rate_hp = (fep)->u.ofdm.code_rate_HP == FEC_AUTO ? -1 : (fep)->u.ofdm.code_rate_HP; \
(ch)->vit_code_rate_lp = (fep)->u.ofdm.code_rate_LP == FEC_AUTO ? -1 : (fep)->u.ofdm.code_rate_LP; \
(ch)->intlv_native = 1;
#define INIT_OFDM_CHANNEL(ch) do {\
(ch)->Bw = 0; \
(ch)->nfft = -1; \
(ch)->guard = -1; \
(ch)->nqam = -1; \
(ch)->vit_hrch = -1; \
(ch)->vit_select_hp = -1; \
(ch)->vit_alpha = -1; \
(ch)->vit_code_rate_hp = -1; \
(ch)->vit_code_rate_lp = -1; \
} while (0)
#define OUTMODE_HIGH_Z 0
#define OUTMODE_MPEG2_PAR_GATED_CLK 1
#define OUTMODE_MPEG2_PAR_CONT_CLK 2
#define OUTMODE_MPEG2_SERIAL 7
#define OUTMODE_DIVERSITY 4
#define OUTMODE_MPEG2_FIFO 5
#define OUTMODE_ANALOG_ADC 6
#endif
This diff is collapsed.
......@@ -20,7 +20,6 @@
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
......
......@@ -29,7 +29,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/slab.h>
......
......@@ -23,7 +23,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/slab.h>
#include "dvb_frontend.h"
......
......@@ -35,7 +35,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/string.h>
......
......@@ -28,7 +28,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/slab.h>
......
......@@ -22,7 +22,6 @@
/* In that file, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <linux/dvb/frontend.h>
#include <linux/i2c.h>
......
This diff is collapsed.
/*
* Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
*
* Copyright (c) 2006 Steven Toth <stoth@hauppauge.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
* 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 02139, USA.
*/
#ifndef __MT2131_H__
#define __MT2131_H__
struct dvb_frontend;
struct i2c_adapter;
struct mt2131_config {
u8 i2c_address;
u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
};
#if defined(CONFIG_DVB_TUNER_MT2131) || (defined(CONFIG_DVB_TUNER_MT2131_MODULE) && defined(MODULE))
extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
struct mt2131_config *cfg,
u16 if1);
#else
static inline struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
struct mt2131_config *cfg,
u16 if1)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
return NULL;
}
#endif /* CONFIG_DVB_TUNER_MT2131 */
#endif /* __MT2131_H__ */
/*
* Local variables:
* c-basic-offset: 8
*/
/*
* Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
*
* Copyright (c) 2006 Steven Toth <stoth@hauppauge.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
* 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 02139, USA.
*/
#ifndef __MT2131_PRIV_H__
#define __MT2131_PRIV_H__
/* Regs */
#define MT2131_PWR 0x07
#define MT2131_UPC_1 0x0b
#define MT2131_AGC_RL 0x10
#define MT2131_MISC_2 0x15
/* frequency values in KHz */
#define MT2131_IF1 1220
#define MT2131_IF2 44000
#define MT2131_FREF 16000
struct mt2131_priv {
struct mt2131_config *cfg;
struct i2c_adapter *i2c;
u32 frequency;
u32 bandwidth;
};
#endif /* __MT2131_PRIV_H__ */
/*
* Local variables:
* c-basic-offset: 8
*/
This diff is collapsed.
/*
* Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
*
* Copyright (c) 2007 Olivier DANET <odanet@caramail.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
* 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.
*/
#ifndef MT2266_H
#define MT2266_H
struct dvb_frontend;
struct i2c_adapter;
struct mt2266_config {
u8 i2c_address;
};
#if defined(CONFIG_DVB_TUNER_MT2266) || (defined(CONFIG_DVB_TUNER_MT2266_MODULE) && defined(MODULE))
extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg);
#else
static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
return NULL;
}
#endif // CONFIG_DVB_TUNER_MT2266
#endif
......@@ -28,7 +28,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/slab.h>
......
......@@ -32,7 +32,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/string.h>
......
......@@ -44,7 +44,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/string.h>
......
......@@ -36,7 +36,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/string.h>
......
......@@ -32,7 +32,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/string.h>
......
This diff is collapsed.
This diff is collapsed.
......@@ -29,7 +29,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/delay.h>
......
......@@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/string.h>
......
......@@ -680,8 +680,8 @@ static struct dvb_frontend_ops stv0297_ops = {
.info = {
.name = "ST STV0297 DVB-C",
.type = FE_QAM,
.frequency_min = 64000000,
.frequency_max = 1300000000,
.frequency_min = 47000000,
.frequency_max = 862000000,
.frequency_stepsize = 62500,
.symbol_rate_min = 870000,
.symbol_rate_max = 11700000,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment