diff options
Diffstat (limited to 'linux/drivers')
263 files changed, 9932 insertions, 3050 deletions
diff --git a/linux/drivers/media/Kconfig b/linux/drivers/media/Kconfig index 1f7244cff..128bb9cd5 100644 --- a/linux/drivers/media/Kconfig +++ b/linux/drivers/media/Kconfig @@ -30,7 +30,7 @@ config VIDEO_V4L2_COMMON depends on (I2C || I2C=n) && VIDEO_DEV default (I2C || I2C=n) && VIDEO_DEV -config VIDEO_V4L1 +config VIDEO_ALLOW_V4L1 bool "Enable Video For Linux API 1 (DEPRECATED)" depends on VIDEO_DEV && VIDEO_V4L2_COMMON default VIDEO_DEV && VIDEO_V4L2_COMMON @@ -59,10 +59,15 @@ config VIDEO_V4L1_COMPAT If you are unsure as to whether this is required, answer Y. config VIDEO_V4L2 - bool + tristate depends on VIDEO_DEV && VIDEO_V4L2_COMMON default VIDEO_DEV && VIDEO_V4L2_COMMON +config VIDEO_V4L1 + tristate + depends on VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1 + default VIDEO_DEV && VIDEO_V4L2_COMMON && VIDEO_ALLOW_V4L1 + source "drivers/media/video/Kconfig" source "drivers/media/radio/Kconfig" diff --git a/linux/drivers/media/common/ir-keymaps.c b/linux/drivers/media/common/ir-keymaps.c index 4e5db8cd5..64d3df831 100644 --- a/linux/drivers/media/common/ir-keymaps.c +++ b/linux/drivers/media/common/ir-keymaps.c @@ -772,7 +772,11 @@ IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = { [ 0x12 ] = KEY_CHANNELUP, // Channel + [ 0x13 ] = KEY_CHANNELDOWN, // Channel - [ 0x06 ] = KEY_AGAIN, // Recall - [ 0x10 ] = KEY_ENTER, // Enter + [ 0x10 ] = KEY_ENTER, // Enter + + [ 0x19 ] = KEY_BACK, // Rewind ( <<< ) + [ 0x1f ] = KEY_FORWARD, // Forward ( >>> ) + [ 0x0a ] = KEY_ANGLE, // (no label, may be used as the PAUSE button) }; EXPORT_SYMBOL_GPL(ir_codes_flyvideo); diff --git a/linux/drivers/media/common/saa7146_core.c b/linux/drivers/media/common/saa7146_core.c index c24723a67..973989dd4 100644 --- a/linux/drivers/media/common/saa7146_core.c +++ b/linux/drivers/media/common/saa7146_core.c @@ -74,7 +74,7 @@ static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev, if (err) { printk(KERN_ERR "%s: %s timed out while waiting for " "registers getting programmed\n", - dev->name, __FUNCTION__); + dev->name, __func__); return -ETIMEDOUT; } msleep(1); @@ -89,7 +89,7 @@ static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev, saa7146_read(dev, MC2); if (err) { DEB_S(("%s: %s timed out while waiting for transfer " - "completion\n", dev->name, __FUNCTION__)); + "completion\n", dev->name, __func__)); return -ETIMEDOUT; } msleep(1); @@ -111,7 +111,7 @@ static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev, if (!loops--) { printk(KERN_ERR "%s: %s timed out while waiting for " "registers getting programmed\n", - dev->name, __FUNCTION__); + dev->name, __func__); return -ETIMEDOUT; } udelay(1); @@ -125,7 +125,7 @@ static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev, saa7146_read(dev, MC2); if (!loops--) { DEB_S(("%s: %s timed out while waiting for transfer " - "completion\n", dev->name, __FUNCTION__)); + "completion\n", dev->name, __func__)); return -ETIMEDOUT; } udelay(5); @@ -310,25 +310,22 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id) return IRQ_NONE; } - if( NULL != (dev->ext)) { - if( 0 != (dev->ext->irq_mask & isr )) { - if( NULL != dev->ext->irq_func ) { + if (dev->ext) { + if (dev->ext->irq_mask & isr) { + if (dev->ext->irq_func) dev->ext->irq_func(dev, &isr); - } isr &= ~dev->ext->irq_mask; } } if (0 != (isr & (MASK_27))) { DEB_INT(("irq: RPS0 (0x%08x).\n",isr)); - if( NULL != dev->vv_data && NULL != dev->vv_callback) { + if (dev->vv_data && dev->vv_callback) dev->vv_callback(dev,isr); - } isr &= ~MASK_27; } if (0 != (isr & (MASK_28))) { - if( NULL != dev->vv_data && NULL != dev->vv_callback) { + if (dev->vv_data && dev->vv_callback) dev->vv_callback(dev,isr); - } isr &= ~MASK_28; } if (0 != (isr & (MASK_16|MASK_17))) { diff --git a/linux/drivers/media/common/saa7146_fops.c b/linux/drivers/media/common/saa7146_fops.c index fee81488f..ac035cbcf 100644 --- a/linux/drivers/media/common/saa7146_fops.c +++ b/linux/drivers/media/common/saa7146_fops.c @@ -273,7 +273,7 @@ static int fops_open(struct inode *inode, struct file *file) result = 0; out: - if( fh != NULL && result != 0 ) { + if (fh && result != 0) { kfree(fh); file->private_data = NULL; } diff --git a/linux/drivers/media/common/saa7146_i2c.c b/linux/drivers/media/common/saa7146_i2c.c index 40527fa6c..a2447ff60 100644 --- a/linux/drivers/media/common/saa7146_i2c.c +++ b/linux/drivers/media/common/saa7146_i2c.c @@ -204,7 +204,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d return -ERESTARTSYS; printk(KERN_WARNING "%s %s [irq]: timed out waiting for end of xfer\n", - dev->name, __FUNCTION__); + dev->name, __func__); return -EIO; } status = saa7146_read(dev, I2C_STATUS); @@ -222,7 +222,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d } if (time_after(jiffies,timeout)) { printk(KERN_WARNING "%s %s: timed out waiting for MC2\n", - dev->name, __FUNCTION__); + dev->name, __func__); return -EIO; } } @@ -239,7 +239,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d * (no answer from nonexisistant device...) */ printk(KERN_WARNING "%s %s [poll]: timed out waiting for end of xfer\n", - dev->name, __FUNCTION__); + dev->name, __func__); return -EIO; } if (++trial < 50 && short_delay) diff --git a/linux/drivers/media/dvb/b2c2/Kconfig b/linux/drivers/media/dvb/b2c2/Kconfig index 8193d88d1..6ec5afba1 100644 --- a/linux/drivers/media/dvb/b2c2/Kconfig +++ b/linux/drivers/media/dvb/b2c2/Kconfig @@ -10,6 +10,8 @@ config DVB_B2C2_FLEXCOP select DVB_BCM3510 if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE select TUNER_SIMPLE if !DVB_FE_CUSTOMISE + select DVB_S5H1420 if !DVB_FE_CUSTOMISE + select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE select DVB_ISL6421 if !DVB_FE_CUSTOMISE select DVB_CX24123 if !DVB_FE_CUSTOMISE help diff --git a/linux/drivers/media/dvb/b2c2/flexcop-dma.c b/linux/drivers/media/dvb/b2c2/flexcop-dma.c index f0b134a16..1df246a7f 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-dma.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-dma.c @@ -112,7 +112,7 @@ static int flexcop_dma_remap(struct flexcop_device *fc, { flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c; flexcop_ibi_value v = fc->read_ibi_reg(fc,r); - deb_info("%s\n",__FUNCTION__); + deb_info("%s\n",__func__); v.dma_0xc.remap_enable = onoff; fc->write_ibi_reg(fc,r,v); return 0; @@ -162,7 +162,7 @@ int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_remap(fc,dma_idx,0); - deb_info("%s\n",__FUNCTION__); + deb_info("%s\n",__func__); v.dma_0x4_write.dmatimer = cycles; fc->write_ibi_reg(fc,r,v); return 0; diff --git a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 6759c3ad2..7b0ea3bdf 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -19,6 +19,9 @@ #include "dvb-pll.h" #include "tuner-simple.h" +#include "s5h1420.h" +#include "itd1000.h" + #include "cx24123.h" #include "cx24113.h" @@ -249,7 +252,7 @@ static struct stv0299_config samsung_tbmu24112_config = { .mclk = 88000000UL, .invert = 0, .skip_reinit = 0, - .lock_output = STV0229_LOCKOUTPUT_LK, + .lock_output = STV0299_LOCKOUTPUT_LK, .volt13_op0_op1 = STV0299_VOLT13_OP1, .min_delay_ms = 100, .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, @@ -482,6 +485,18 @@ static struct stv0297_config alps_tdee4_stv0297_config = { }; +/* SkyStar2 rev2.7 (a/u) */ +static struct s5h1420_config skystar2_rev2_7_s5h1420_config = { + .demod_address = 0x53, + .invert = 1, + .repeated_start_workaround = 1, +}; + +static struct itd1000_config skystar2_rev2_7_itd1000_config = { + .i2c_address = 0x61, +}; + +/* SkyStar2 rev2.8 */ static struct cx24123_config skystar2_rev2_8_cx24123_config = { .demod_address = 0x55, .dont_use_pll = 1, @@ -500,6 +515,39 @@ int flexcop_frontend_init(struct flexcop_device *fc) struct i2c_adapter *i2c = &fc->fc_i2c_adap[0].i2c_adap; struct i2c_adapter *i2c_tuner; + /* enable no_base_addr - no repeated start when reading */ + fc->fc_i2c_adap[0].no_base_addr = 1; + fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config, i2c); + if (fc->fe != NULL) { + flexcop_ibi_value r108; + i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe); + ops = &fc->fe->ops; + + fc->fe_sleep = ops->sleep; + ops->sleep = flexcop_sleep; + + fc->dev_type = FC_SKY_REV27; + + /* enable no_base_addr - no repeated start when reading */ + fc->fc_i2c_adap[2].no_base_addr = 1; + if (dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, 0x08, 1, 1) == NULL) + err("ISL6421 could NOT be attached"); + else + info("ISL6421 successfully attached"); + + /* the ITD1000 requires a lower i2c clock - it slows down the stuff for everyone - but is it a problem ? */ + r108.raw = 0x00000506; + fc->write_ibi_reg(fc, tw_sm_c_108, r108); + if (i2c_tuner) { + if (dvb_attach(itd1000_attach, fc->fe, i2c_tuner, &skystar2_rev2_7_itd1000_config) == NULL) + err("ITD1000 could NOT be attached"); + else + info("ITD1000 successfully attached"); + } + goto fe_found; + } + fc->fc_i2c_adap[0].no_base_addr = 0; /* for the next devices we need it again */ + /* try the sky v2.8 (cx24123, isl6421) */ fc->fe = dvb_attach(cx24123_attach, &skystar2_rev2_8_cx24123_config, i2c); diff --git a/linux/drivers/media/dvb/b2c2/flexcop-sram.c b/linux/drivers/media/dvb/b2c2/flexcop-sram.c index 4d978c01e..cfb196ef7 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-sram.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-sram.c @@ -90,7 +90,7 @@ static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 * }; if (retries == 0) - printk("%s: SRAM timeout\n", __FUNCTION__); + printk("%s: SRAM timeout\n", __func__); write_reg_dw(adapter, 0x700, command); @@ -115,7 +115,7 @@ static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, }; if (retries == 0) - printk("%s: SRAM timeout\n", __FUNCTION__); + printk("%s: SRAM timeout\n", __func__); write_reg_dw(adapter, 0x700, command); @@ -127,7 +127,7 @@ static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, }; if (retries == 0) - printk("%s: SRAM timeout\n", __FUNCTION__); + printk("%s: SRAM timeout\n", __func__); value = read_reg_dw(adapter, 0x700) >> 0x10; @@ -240,13 +240,13 @@ static void sram_init(struct adapter *adapter) adapter->dw_sram_type = tmp & 0x30000; - ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type); + ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type); } else { adapter->dw_sram_type = 0x10000; - ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type); + ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type); } /* return value is never used? */ @@ -257,7 +257,7 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr) { u8 tmp1, tmp2; - dprintk("%s: mask = %x, addr = %x\n", __FUNCTION__, mask, addr); + dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr); sram_set_size(adapter, mask); sram_init(adapter); @@ -275,7 +275,7 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr) sram_read(adapter, addr, &tmp2, 1); sram_read(adapter, addr, &tmp2, 1); - dprintk("%s: wrote 0xa5, read 0x%2x\n", __FUNCTION__, tmp2); + dprintk("%s: wrote 0xa5, read 0x%2x\n", __func__, tmp2); if (tmp2 != 0xa5) return 0; @@ -293,7 +293,7 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr) sram_read(adapter, addr, &tmp2, 1); sram_read(adapter, addr, &tmp2, 1); - dprintk("%s: wrote 0x5a, read 0x%2x\n", __FUNCTION__, tmp2); + dprintk("%s: wrote 0x5a, read 0x%2x\n", __func__, tmp2); if (tmp2 != 0x5a) return 0; @@ -340,7 +340,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc) tmp3 = read_reg_dw(adapter, 0x71c); - dprintk("%s: tmp3 = %x\n", __FUNCTION__, tmp3); + dprintk("%s: tmp3 = %x\n", __func__, tmp3); write_reg_dw(adapter, 0x71c, tmp2); @@ -351,7 +351,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc) sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); - dprintk("%s: sram size = 32K\n", __FUNCTION__); + dprintk("%s: sram size = 32K\n", __func__); return 32; } @@ -361,7 +361,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc) sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); - dprintk("%s: sram size = 128K\n", __FUNCTION__); + dprintk("%s: sram size = 128K\n", __func__); return 128; } @@ -371,7 +371,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc) sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); - dprintk("%s: sram size = 64K\n", __FUNCTION__); + dprintk("%s: sram size = 64K\n", __func__); return 64; } @@ -381,7 +381,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc) sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); - dprintk("%s: sram size = 32K\n", __FUNCTION__); + dprintk("%s: sram size = 32K\n", __func__); return 32; } @@ -390,7 +390,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc) sram_init(adapter); write_reg_dw(adapter, 0x208, tmp); - dprintk("%s: SRAM detection failed. Set to 32K \n", __FUNCTION__); + dprintk("%s: SRAM detection failed. Set to 32K \n", __func__); return 0; } diff --git a/linux/drivers/media/dvb/b2c2/flexcop.c b/linux/drivers/media/dvb/b2c2/flexcop.c index 205146c24..5f79c8dc3 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop.c +++ b/linux/drivers/media/dvb/b2c2/flexcop.c @@ -49,6 +49,8 @@ module_param_named(debug, b2c2_flexcop_debug, int, 0644); MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS); #undef DEBSTATUS +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + /* global zero for ibi values */ flexcop_ibi_value ibi_zero; @@ -66,8 +68,10 @@ static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) static int flexcop_dvb_init(struct flexcop_device *fc) { - int ret; - if ((ret = dvb_register_adapter(&fc->dvb_adapter,"FlexCop Digital TV device",fc->owner,fc->dev)) < 0) { + int ret = dvb_register_adapter(&fc->dvb_adapter, + "FlexCop Digital TV device", fc->owner, + fc->dev, adapter_nr); + if (ret < 0) { err("error registering DVB adapter"); return ret; } diff --git a/linux/drivers/media/dvb/bt8xx/dst.c b/linux/drivers/media/dvb/bt8xx/dst.c index 307ff35bd..75711bde2 100644 --- a/linux/drivers/media/dvb/bt8xx/dst.c +++ b/linux/drivers/media/dvb/bt8xx/dst.c @@ -1290,7 +1290,7 @@ static int dst_get_signal(struct dst_state *state) { int retval; u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb }; - //dprintk("%s: Getting Signal strength and other parameters\n", __FUNCTION__); + //dprintk("%s: Getting Signal strength and other parameters\n", __func__); if ((state->diseq_flags & ATTEMPT_TUNE) == 0) { state->decode_lock = state->decode_strength = state->decode_snr = 0; return 0; diff --git a/linux/drivers/media/dvb/bt8xx/dst_ca.c b/linux/drivers/media/dvb/bt8xx/dst_ca.c index ce64629fc..0b462e7bb 100644 --- a/linux/drivers/media/dvb/bt8xx/dst_ca.c +++ b/linux/drivers/media/dvb/bt8xx/dst_ca.c @@ -36,13 +36,13 @@ #define dprintk(x, y, z, format, arg...) do { \ if (z) { \ if ((x > DST_CA_ERROR) && (x > y)) \ - printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg); \ + printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ else if ((x > DST_CA_NOTICE) && (x > y)) \ - printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg); \ + printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ else if ((x > DST_CA_INFO) && (x > y)) \ - printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg); \ + printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ else if ((x > DST_CA_DEBUG) && (x > y)) \ - printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg); \ + printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ } else { \ if (x > y) \ printk(format, ## arg); \ @@ -162,7 +162,7 @@ static int ca_get_app_info(struct dst_state *state) dprintk(verbose, DST_CA_INFO, 1, " ================================ CI Module Application Info ======================================"); dprintk(verbose, DST_CA_INFO, 1, " Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]", state->messages[7], (state->messages[8] << 8) | state->messages[9], - (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12])); + (state->messages[10] << 8) | state->messages[11], __func__, (char *)(&state->messages[12])); dprintk(verbose, DST_CA_INFO, 1, " =================================================================================================="); // Transform dst message to correct application_info message diff --git a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c index de0de894b..27d092448 100644 --- a/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/linux/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -41,6 +41,8 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + #define dprintk( args... ) \ do { \ if (debug) printk(KERN_DEBUG args); \ @@ -672,7 +674,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) state->dst_ca = NULL; /* DST is not a frontend, attaching the ASIC */ if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) { - printk("%s: Could not find a Twinhan DST.\n", __FUNCTION__); + printk("%s: Could not find a Twinhan DST.\n", __func__); break; } /* Attach other DST peripherals if any */ @@ -718,7 +720,10 @@ static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) { int result; - if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE, &card->bt->dev->dev)) < 0) { + result = dvb_register_adapter(&card->dvb_adapter, card->card_name, + THIS_MODULE, &card->bt->dev->dev, + adapter_nr); + if (result < 0) { printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); return result; } diff --git a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c index c33afb6ea..728197340 100644 --- a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -61,6 +61,8 @@ static int debug; module_param_named(debug, debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) #define dprintk(level, args...) \ do { \ @@ -74,7 +76,7 @@ do { \ do { \ if ((debug & level)) { \ printk("%s: %s(): ", KBUILD_MODNAME, \ - __FUNCTION__); \ + __func__); \ printk(args); } \ } while (0) #endif @@ -1004,7 +1006,10 @@ static int cinergyt2_probe (struct usb_interface *intf, return -ENOMEM; } - if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE, &cinergyt2->udev->dev)) < 0) { + err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, + THIS_MODULE, &cinergyt2->udev->dev, + adapter_nr); + if (err < 0) { kfree(cinergyt2); return err; } diff --git a/linux/drivers/media/dvb/dvb-core/dmxdev.c b/linux/drivers/media/dvb/dvb-core/dmxdev.c index 716735f03..df5bef6a2 100644 --- a/linux/drivers/media/dvb/dvb-core/dmxdev.c +++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c @@ -126,7 +126,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) struct dmxdev *dmxdev = dvbdev->priv; struct dmx_frontend *front; - dprintk("function : %s\n", __FUNCTION__); + dprintk("function : %s\n", __func__); if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; @@ -259,6 +259,39 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count, return ret; } +static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev, + unsigned long size) +{ + struct dvb_ringbuffer *buf = &dmxdev->dvr_buffer; + void *newmem; + void *oldmem; + + dprintk("function : %s\n", __func__); + + if (buf->size == size) + return 0; + if (!size) + return -EINVAL; + + newmem = vmalloc(size); + if (!newmem) + return -ENOMEM; + + oldmem = buf->data; + + spin_lock_irq(&dmxdev->lock); + buf->data = newmem; + buf->size = size; + + /* reset and not flush in case the buffer shrinks */ + dvb_ringbuffer_reset(buf); + spin_unlock_irq(&dmxdev->lock); + + vfree(oldmem); + + return 0; +} + static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter *dmxdevfilter, int state) { @@ -271,28 +304,32 @@ static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, unsigned long size) { struct dvb_ringbuffer *buf = &dmxdevfilter->buffer; - void *mem; + void *newmem; + void *oldmem; if (buf->size == size) return 0; + if (!size) + return -EINVAL; if (dmxdevfilter->state >= DMXDEV_STATE_GO) return -EBUSY; + + newmem = vmalloc(size); + if (!newmem) + return -ENOMEM; + + oldmem = buf->data; + spin_lock_irq(&dmxdevfilter->dev->lock); - mem = buf->data; - buf->data = NULL; + buf->data = newmem; buf->size = size; - dvb_ringbuffer_flush(buf); + + /* reset and not flush in case the buffer shrinks */ + dvb_ringbuffer_reset(buf); spin_unlock_irq(&dmxdevfilter->dev->lock); - vfree(mem); - if (buf->size) { - mem = vmalloc(dmxdevfilter->buffer.size); - if (!mem) - return -ENOMEM; - spin_lock_irq(&dmxdevfilter->dev->lock); - buf->data = mem; - spin_unlock_irq(&dmxdevfilter->dev->lock); - } + vfree(oldmem); + return 0; } @@ -551,7 +588,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) dvb_dmxdev_section_callback); if (ret < 0) { printk("DVB (%s): could not alloc feed\n", - __FUNCTION__); + __func__); return ret; } @@ -559,7 +596,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) (para->flags & DMX_CHECK_CRC) ? 1 : 0); if (ret < 0) { printk("DVB (%s): could not set feed\n", - __FUNCTION__); + __func__); dvb_dmxdev_feed_restart(filter); return ret; } @@ -734,7 +771,7 @@ static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter, struct dmx_sct_filter_params *params) { - dprintk("function : %s\n", __FUNCTION__); + dprintk("function : %s\n", __func__); dvb_dmxdev_filter_stop(dmxdevfilter); @@ -1009,6 +1046,7 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, { struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; + unsigned long arg = (unsigned long)parg; int ret; if (mutex_lock_interruptible(&dmxdev->mutex)) @@ -1016,8 +1054,7 @@ static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, switch (cmd) { case DMX_SET_BUFFER_SIZE: - // FIXME: implement - ret = 0; + ret = dvb_dvr_set_buffer_size(dmxdev, arg); break; default: @@ -1040,7 +1077,7 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait) struct dmxdev *dmxdev = dvbdev->priv; unsigned int mask = 0; - dprintk("function : %s\n", __FUNCTION__); + dprintk("function : %s\n", __func__); poll_wait(file, &dmxdev->dvr_buffer.queue, wait); diff --git a/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 588a12597..8e197b831 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -251,7 +251,7 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot, unsigned long timeout; unsigned long start; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* loop until timeout elapsed */ start = jiffies; @@ -264,7 +264,7 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot, /* if we got the flags, it was successful! */ if (res & waitfor) { - dprintk("%s succeeded timeout:%lu\n", __FUNCTION__, jiffies - start); + dprintk("%s succeeded timeout:%lu\n", __func__, jiffies - start); return 0; } @@ -277,7 +277,7 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot, msleep(1); } - dprintk("%s failed timeout:%lu\n", __FUNCTION__, jiffies - start); + dprintk("%s failed timeout:%lu\n", __func__, jiffies - start); /* if we get here, we've timed out */ return -ETIMEDOUT; @@ -298,7 +298,7 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot) int buf_size; u8 buf[2]; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* we'll be determining these during this function */ ca->slot_info[slot].da_irq_supported = 0; @@ -550,7 +550,7 @@ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot) { int configoption; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* set the config option */ ca->pub->write_attribute_mem(ca->pub, slot, @@ -588,7 +588,7 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * eb u8 buf[HOST_LINK_BUF_SIZE]; int i; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* check if we have space for a link buf in the rx_buffer */ if (ebuf == NULL) { @@ -709,7 +709,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b int status; int i; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); // sanity check @@ -786,7 +786,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq); */ static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot) { - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); ca->pub->slot_shutdown(ca->pub, slot); ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; @@ -893,7 +893,7 @@ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot) static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca) { - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); ca->wakeup = 1; mb(); @@ -965,7 +965,7 @@ static int dvb_ca_en50221_thread(void *data) int pktcount; void *rxbuf; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* choose the correct initial delay */ dvb_ca_en50221_thread_update_delay(ca); @@ -1173,7 +1173,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file, int err = 0; int slot; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); switch (cmd) { case CA_RESET: @@ -1267,7 +1267,7 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file, unsigned long timeout; int written; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* Incoming packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */ if (count < 2) @@ -1402,7 +1402,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, int pktlen; int dispose = 0; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* Outgoing packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */ if (count < 2) @@ -1491,7 +1491,7 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) int err; int i; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); if (!try_module_get(ca->pub->owner)) return -EIO; @@ -1535,7 +1535,7 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) struct dvb_ca_private *ca = dvbdev->priv; int err; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* mark the CA device as closed */ ca->open = 0; @@ -1565,7 +1565,7 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait) int slot; int result = 0; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) { mask |= POLLIN; @@ -1627,7 +1627,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, struct dvb_ca_private *ca = NULL; int i; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); if (slot_count < 1) return -EINVAL; @@ -1705,7 +1705,7 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) struct dvb_ca_private *ca = pubca->private; int i; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* shutdown the thread if there was one */ kthread_stop(ca->thread); diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.c b/linux/drivers/media/dvb/dvb-core/dvb_demux.c index 988d14302..934e15fff 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.c @@ -553,7 +553,7 @@ static void dvb_demux_feed_add(struct dvb_demux_feed *feed) spin_lock_irq(&feed->demux->lock); if (dvb_demux_feed_find(feed)) { printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n", - __FUNCTION__, feed->type, feed->state, feed->pid); + __func__, feed->type, feed->state, feed->pid); goto out; } @@ -567,7 +567,7 @@ static void dvb_demux_feed_del(struct dvb_demux_feed *feed) spin_lock_irq(&feed->demux->lock); if (!(dvb_demux_feed_find(feed))) { printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n", - __FUNCTION__, feed->type, feed->state, feed->pid); + __func__, feed->type, feed->state, feed->pid); goto out; } diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 54cc2637b..c1855f562 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -140,7 +140,7 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) struct dvb_frontend_event *e; int wp; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (mutex_lock_interruptible (&events->mtx)) return; @@ -176,7 +176,7 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe, struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_fe_events *events = &fepriv->events; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (events->overflow) { events->overflow = 0; @@ -242,7 +242,7 @@ static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepr { int q2; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (locked) (fepriv->quality) = (fepriv->quality * 220 + 36*256) / 256; @@ -334,7 +334,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra dprintk("%s: drift:%i inversion:%i auto_step:%i " "auto_sub_step:%i started_auto_step:%i\n", - __FUNCTION__, fepriv->lnb_drift, fepriv->inversion, + __func__, fepriv->lnb_drift, fepriv->inversion, fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step); /* set the frontend itself */ @@ -516,7 +516,7 @@ static int dvb_frontend_thread(void *data) fe_status_t s; struct dvb_frontend_parameters *params; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); fepriv->check_wrapped = 0; fepriv->quality = 0; @@ -608,7 +608,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); fepriv->exit = 1; mb(); @@ -676,7 +676,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe) struct dvb_frontend_private *fepriv = fe->frontend_priv; struct task_struct *fe_thread; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (fepriv->thread) { if (!fepriv->exit) @@ -774,7 +774,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, struct dvb_frontend_private *fepriv = fe->frontend_priv; int err = -EOPNOTSUPP; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (fepriv->exit) return -ENODEV; @@ -906,7 +906,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, int i; u8 last = 1; if (dvb_frontend_debug) - printk("%s switch command: 0x%04lx\n", __FUNCTION__, cmd); + printk("%s switch command: 0x%04lx\n", __func__, cmd); do_gettimeofday(&nexttime); if (dvb_frontend_debug) memcpy(&tv[0], &nexttime, sizeof(struct timeval)); @@ -930,7 +930,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, } if (dvb_frontend_debug) { printk("%s(%d): switch delay (should be 32k followed by all 8k\n", - __FUNCTION__, fe->dvb->num); + __func__, fe->dvb->num); for (i = 1; i < 10; i++) printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i])); } @@ -1048,7 +1048,7 @@ static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struc struct dvb_frontend *fe = dvbdev->priv; struct dvb_frontend_private *fepriv = fe->frontend_priv; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); poll_wait (file, &fepriv->events.wait_queue, wait); @@ -1065,7 +1065,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) struct dvb_frontend_private *fepriv = fe->frontend_priv; int ret; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) { if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0) @@ -1106,7 +1106,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) struct dvb_frontend_private *fepriv = fe->frontend_priv; int ret; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if ((file->f_flags & O_ACCMODE) != O_RDONLY) fepriv->release_jiffies = jiffies; @@ -1146,7 +1146,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, .kernel_ioctl = dvb_frontend_ioctl }; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (mutex_lock_interruptible(&frontend_mutex)) return -ERESTARTSYS; @@ -1180,7 +1180,7 @@ EXPORT_SYMBOL(dvb_register_frontend); int dvb_unregister_frontend(struct dvb_frontend* fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); mutex_lock(&frontend_mutex); dvb_frontend_stop (fe); diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.c b/linux/drivers/media/dvb/dvb-core/dvb_net.c index 627096688..04c9e00b0 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_net.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_net.c @@ -810,8 +810,8 @@ static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len, { struct net_device *dev = feed->priv; - if (buffer2 != 0) - printk(KERN_WARNING "buffer2 not 0: %p.\n", buffer2); + if (buffer2) + printk(KERN_WARNING "buffer2 not NULL: %p.\n", buffer2); if (buffer1_len > 32768) printk(KERN_WARNING "length > 32k: %zu.\n", buffer1_len); /* printk("TS callback: %u bytes, %u TS cells @ %p.\n", @@ -991,17 +991,17 @@ static int dvb_net_feed_start(struct net_device *dev) struct dmx_demux *demux = priv->demux; unsigned char *mac = (unsigned char *) dev->dev_addr; - dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode); + dprintk("%s: rx_mode %i\n", __func__, priv->rx_mode); mutex_lock(&priv->mutex); if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0]) - printk("%s: BUG %d\n", __FUNCTION__, __LINE__); + printk("%s: BUG %d\n", __func__, __LINE__); priv->secfeed=NULL; priv->secfilter=NULL; priv->tsfeed = NULL; if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) { - dprintk("%s: alloc secfeed\n", __FUNCTION__); + dprintk("%s: alloc secfeed\n", __func__); ret=demux->allocate_section_feed(demux, &priv->secfeed, dvb_net_sec_callback); if (ret<0) { @@ -1019,38 +1019,38 @@ static int dvb_net_feed_start(struct net_device *dev) } if (priv->rx_mode != RX_MODE_PROMISC) { - dprintk("%s: set secfilter\n", __FUNCTION__); + dprintk("%s: set secfilter\n", __func__); dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_normal); } switch (priv->rx_mode) { case RX_MODE_MULTI: for (i = 0; i < priv->multi_num; i++) { - dprintk("%s: set multi_secfilter[%d]\n", __FUNCTION__, i); + dprintk("%s: set multi_secfilter[%d]\n", __func__, i); dvb_net_filter_sec_set(dev, &priv->multi_secfilter[i], priv->multi_macs[i], mask_normal); } break; case RX_MODE_ALL_MULTI: priv->multi_num=1; - dprintk("%s: set multi_secfilter[0]\n", __FUNCTION__); + dprintk("%s: set multi_secfilter[0]\n", __func__); dvb_net_filter_sec_set(dev, &priv->multi_secfilter[0], mac_allmulti, mask_allmulti); break; case RX_MODE_PROMISC: priv->multi_num=0; - dprintk("%s: set secfilter\n", __FUNCTION__); + dprintk("%s: set secfilter\n", __func__); dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_promisc); break; } - dprintk("%s: start filtering\n", __FUNCTION__); + dprintk("%s: start filtering\n", __func__); priv->secfeed->start_filtering(priv->secfeed); } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) { struct timespec timeout = { 0, 10000000 }; // 10 msec /* we have payloads encapsulated in TS */ - dprintk("%s: alloc tsfeed\n", __FUNCTION__); + dprintk("%s: alloc tsfeed\n", __func__); ret = demux->allocate_ts_feed(demux, &priv->tsfeed, dvb_net_ts_callback); if (ret < 0) { printk("%s: could not allocate ts feed\n", dev->name); @@ -1074,7 +1074,7 @@ static int dvb_net_feed_start(struct net_device *dev) goto error; } - dprintk("%s: start filtering\n", __FUNCTION__); + dprintk("%s: start filtering\n", __func__); priv->tsfeed->start_filtering(priv->tsfeed); } else ret = -EINVAL; @@ -1089,17 +1089,17 @@ static int dvb_net_feed_stop(struct net_device *dev) struct dvb_net_priv *priv = dev->priv; int i, ret = 0; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); mutex_lock(&priv->mutex); if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) { if (priv->secfeed) { if (priv->secfeed->is_filtering) { - dprintk("%s: stop secfeed\n", __FUNCTION__); + dprintk("%s: stop secfeed\n", __func__); priv->secfeed->stop_filtering(priv->secfeed); } if (priv->secfilter) { - dprintk("%s: release secfilter\n", __FUNCTION__); + dprintk("%s: release secfilter\n", __func__); priv->secfeed->release_filter(priv->secfeed, priv->secfilter); priv->secfilter=NULL; @@ -1108,7 +1108,7 @@ static int dvb_net_feed_stop(struct net_device *dev) for (i=0; i<priv->multi_num; i++) { if (priv->multi_secfilter[i]) { dprintk("%s: release multi_filter[%d]\n", - __FUNCTION__, i); + __func__, i); priv->secfeed->release_filter(priv->secfeed, priv->multi_secfilter[i]); priv->multi_secfilter[i] = NULL; @@ -1122,7 +1122,7 @@ static int dvb_net_feed_stop(struct net_device *dev) } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) { if (priv->tsfeed) { if (priv->tsfeed->is_filtering) { - dprintk("%s: stop tsfeed\n", __FUNCTION__); + dprintk("%s: stop tsfeed\n", __func__); priv->tsfeed->stop_filtering(priv->tsfeed); } priv->demux->release_ts_feed(priv->demux, priv->tsfeed); diff --git a/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.c index ac9d93cf8..872985b79 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.c @@ -90,7 +90,11 @@ void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf) rbuf->error = 0; } - +void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf) +{ + rbuf->pread = rbuf->pwrite = 0; + rbuf->error = 0; +} void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf) { diff --git a/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.h index d97714e75..890826262 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.h +++ b/linux/drivers/media/dvb/dvb-core/dvb_ringbuffer.h @@ -69,6 +69,7 @@ struct dvb_ringbuffer { ** to lock read or write operations. ** Two or more readers must be locked against each other. ** Flushing the buffer counts as a read operation. +** Resetting the buffer counts as a read and write operation. ** Two or more writers must be locked against each other. */ @@ -85,6 +86,13 @@ extern ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf); extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf); +/* +** Reset the read and write pointers to zero and flush the buffer +** This counts as a read and write operation +*/ +extern void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf); + + /* read routines & macros */ /* ---------------------- */ /* flush buffer */ diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index c70cee304..3439ccec6 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -52,7 +52,6 @@ static const char * const dnames[] = { "net", "osd" }; -#define DVB_MAX_ADAPTERS 8 #define DVB_MAX_IDS 4 #define nums2minor(num,type,id) ((num << 6) | (id << 4) | type) #define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64) @@ -211,7 +210,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, if ((id = dvbdev_get_free_id (adap, type)) < 0){ mutex_unlock(&dvbdev_register_lock); *pdvbdev = NULL; - printk(KERN_ERR "%s: couldn't find free device id\n", __FUNCTION__); + printk(KERN_ERR "%s: couldn't find free device id\n", __func__); return -ENFILE; } @@ -250,7 +249,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, "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)); + __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); return PTR_ERR(clsdev); } @@ -277,18 +276,25 @@ void dvb_unregister_device(struct dvb_device *dvbdev) } EXPORT_SYMBOL(dvb_unregister_device); +static int dvbdev_check_free_adapter_num(int num) +{ + struct list_head *entry; + list_for_each(entry, &dvb_adapter_list) { + struct dvb_adapter *adap; + adap = list_entry(entry, struct dvb_adapter, list_head); + if (adap->num == num) + return 0; + } + return 1; +} static int dvbdev_get_free_adapter_num (void) { int num = 0; while (num < DVB_MAX_ADAPTERS) { - struct dvb_adapter *adap; - list_for_each_entry(adap, &dvb_adapter_list, list_head) - if (adap->num == num) - goto skip; - return num; -skip: + if (dvbdev_check_free_adapter_num(num)) + return num; num++; } @@ -296,13 +302,28 @@ skip: } -int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct module *module, struct device *device) +int dvb_register_adapter(struct dvb_adapter *adap, const char *name, + struct module *module, struct device *device, + short *adapter_nums) { - int num; + int i, num; mutex_lock(&dvbdev_register_lock); - if ((num = dvbdev_get_free_adapter_num ()) < 0) { + for (i = 0; i < DVB_MAX_ADAPTERS; ++i) { + num = adapter_nums[i]; + if (num >= 0 && num < DVB_MAX_ADAPTERS) { + /* use the one the driver asked for */ + if (dvbdev_check_free_adapter_num(num)) + break; + } else { + num = dvbdev_get_free_adapter_num(); + break; + } + num = -1; + } + + if (num < 0) { mutex_unlock(&dvbdev_register_lock); return -ENFILE; } diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.h b/linux/drivers/media/dvb/dvb-core/dvbdev.h index 6dff10ebf..5f9a737c6 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.h +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.h @@ -31,6 +31,10 @@ #define DVB_MAJOR 212 +#define DVB_MAX_ADAPTERS 8 + +#define DVB_UNSET (-1) + #define DVB_DEVICE_VIDEO 0 #define DVB_DEVICE_AUDIO 1 #define DVB_DEVICE_SEC 2 @@ -41,6 +45,11 @@ #define DVB_DEVICE_NET 7 #define DVB_DEVICE_OSD 8 +#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr) \ + static short adapter_nr[] = \ + {[0 ... (DVB_MAX_ADAPTERS - 1)] = DVB_UNSET }; \ + module_param_array(adapter_nr, short, NULL, 0444); \ + MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers") struct dvb_adapter { int num; @@ -78,7 +87,9 @@ struct dvb_device { }; -extern int dvb_register_adapter (struct dvb_adapter *adap, const char *name, struct module *module, struct device *device); +extern int dvb_register_adapter(struct dvb_adapter *adap, const char *name, + struct module *module, struct device *device, + short *adapter_nums); extern int dvb_unregister_adapter (struct dvb_adapter *adap); extern int dvb_register_device (struct dvb_adapter *adap, diff --git a/linux/drivers/media/dvb/dvb-usb/a800.c b/linux/drivers/media/dvb/dvb-usb/a800.c index 16df0a3f9..de7194ee7 100644 --- a/linux/drivers/media/dvb/dvb-usb/a800.c +++ b/linux/drivers/media/dvb/dvb-usb/a800.c @@ -18,6 +18,9 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS); + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + #define deb_rc(args...) dprintk(debug,0x01,args) static int a800_power_ctrl(struct dvb_usb_device *d, int onoff) @@ -94,7 +97,8 @@ static struct dvb_usb_device_properties a800_properties; static int a800_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE,NULL); + return dvb_usb_device_init(intf, &a800_properties, + THIS_MODULE, NULL, adapter_nr); } /* do not change the order of the ID table */ diff --git a/linux/drivers/media/dvb/dvb-usb/af9005.c b/linux/drivers/media/dvb/dvb-usb/af9005.c index 042bccd0e..04270dd3d 100644 --- a/linux/drivers/media/dvb/dvb-usb/af9005.c +++ b/linux/drivers/media/dvb/dvb-usb/af9005.c @@ -39,6 +39,8 @@ int dvb_usb_af9005_dump_eeprom = 0; module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0); MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom."); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + /* remote control decoder */ int (*rc_decode) (struct dvb_usb_device * d, u8 * data, int len, u32 * event, int *state); @@ -1020,7 +1022,8 @@ static struct dvb_usb_device_properties af9005_properties; static int af9005_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf, &af9005_properties, THIS_MODULE, NULL); + return dvb_usb_device_init(intf, &af9005_properties, + THIS_MODULE, NULL, adapter_nr); } static struct usb_device_id af9005_usb_table[] = { diff --git a/linux/drivers/media/dvb/dvb-usb/au6610.c b/linux/drivers/media/dvb/dvb-usb/au6610.c index 4800a5004..578a27d14 100644 --- a/linux/drivers/media/dvb/dvb-usb/au6610.c +++ b/linux/drivers/media/dvb/dvb-usb/au6610.c @@ -19,6 +19,8 @@ static int dvb_usb_au6610_debug; module_param_named(debug, dvb_usb_au6610_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr, u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) { @@ -163,7 +165,9 @@ static int au6610_probe(struct usb_interface *intf, if (intf->num_altsetting < AU6610_ALTSETTING_COUNT) return -ENODEV; - if ((ret = dvb_usb_device_init(intf, &au6610_properties, THIS_MODULE, &d)) == 0) { + ret = dvb_usb_device_init(intf, &au6610_properties, THIS_MODULE, &d, + adapter_nr); + if (ret == 0) { alt = usb_altnum_to_altsetting(intf, AU6610_ALTSETTING); if (alt == NULL) { diff --git a/linux/drivers/media/dvb/dvb-usb/cxusb.c b/linux/drivers/media/dvb/dvb-usb/cxusb.c index 84d8a915d..ddfa0cff7 100644 --- a/linux/drivers/media/dvb/dvb-usb/cxusb.c +++ b/linux/drivers/media/dvb/dvb-usb/cxusb.c @@ -33,13 +33,15 @@ #include "mt352_priv.h" #include "zl10353.h" #include "tuner-xc2028.h" -#include "tuner-xc2028-types.h" #include "tuner-simple.h" /* debug */ static int dvb_usb_cxusb_debug; module_param_named(debug, dvb_usb_cxusb_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + #define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args) #define deb_i2c(args...) if (d->udev->descriptor.idVendor == USB_VID_MEDION) \ dprintk(dvb_usb_cxusb_debug,0x01,args) @@ -492,14 +494,14 @@ static int dvico_bluebird_xc2028_callback(void *ptr, int command, int arg) switch (command) { case XC2028_TUNER_RESET: - deb_info("%s: XC2028_TUNER_RESET %d\n", __FUNCTION__, arg); + deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg); cxusb_bluebird_gpio_pulse(d, 0x01, 1); break; case XC2028_RESET_CLK: - deb_info("%s: XC2028_RESET_CLK %d\n", __FUNCTION__, arg); + deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg); break; default: - deb_info("%s: unknown command %d, arg %d\n", __FUNCTION__, + deb_info("%s: unknown command %d, arg %d\n", __func__, command, arg); return -EINVAL; } @@ -518,7 +520,7 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap) static struct xc2028_ctrl ctl = { .fname = "xc3028-dvico-au-01.fw", .max_len = 64, - .scode_table = ZARLINK456, + .scode_table = XC3028_FE_ZARLINK456, }; fe = dvb_attach(xc2028_attach, adap->fe, &cfg); @@ -723,16 +725,24 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope static int cxusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - if (dvb_usb_device_init(intf,&cxusb_medion_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&cxusb_bluebird_lgh064f_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&cxusb_bluebird_dee1601_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&cxusb_bluebird_lgz201_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&cxusb_bluebird_dtt7579_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&cxusb_bluebird_dualdig4_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&cxusb_bluebird_nano2_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&cxusb_bluebird_nano2_needsfirmware_properties,THIS_MODULE,NULL) == 0) { + if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, + &cxusb_bluebird_nano2_needsfirmware_properties, + THIS_MODULE, NULL, adapter_nr)) return 0; - } return -EINVAL; } diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_core.c b/linux/drivers/media/dvb/dvb-usb/dib0700_core.c index 9d3217983..a2162fda5 100644 --- a/linux/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/linux/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -17,6 +17,8 @@ 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)."); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + /* expecting rx buffer: request data[0] data[1] ... data[2] */ static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen) { @@ -289,7 +291,8 @@ static int dib0700_probe(struct usb_interface *intf, #endif for (i = 0; i < dib0700_device_count; i++) - if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE, &dev) == 0) + if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE, + &dev, adapter_nr) == 0) { dib0700_rc_setup(dev); return 0; diff --git a/linux/drivers/media/dvb/dvb-usb/dibusb-mb.c b/linux/drivers/media/dvb/dvb-usb/dibusb-mb.c index 0d0edece8..2ac86685d 100644 --- a/linux/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/linux/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -14,6 +14,8 @@ */ #include "dibusb.h" +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + static int dib3000mb_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) { struct dvb_usb_adapter *adap = fe->dvb->priv; @@ -107,10 +109,14 @@ static struct dvb_usb_device_properties artec_t1_usb2_properties; static int dibusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&artec_t1_usb2_properties,THIS_MODULE,NULL) == 0) + if (0 == dvb_usb_device_init(intf, &dibusb1_1_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &dibusb1_1_an2235_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &dibusb2_0b_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &artec_t1_usb2_properties, + THIS_MODULE, NULL, adapter_nr)) return 0; return -EINVAL; diff --git a/linux/drivers/media/dvb/dvb-usb/dibusb-mc.c b/linux/drivers/media/dvb/dvb-usb/dibusb-mc.c index 8fa2b6908..b1658ac6b 100644 --- a/linux/drivers/media/dvb/dvb-usb/dibusb-mc.c +++ b/linux/drivers/media/dvb/dvb-usb/dibusb-mc.c @@ -14,13 +14,16 @@ */ #include "dibusb.h" +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + /* USB Driver stuff */ static struct dvb_usb_device_properties dibusb_mc_properties; static int dibusb_mc_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE,NULL); + return dvb_usb_device_init(intf, &dibusb_mc_properties, THIS_MODULE, + NULL, adapter_nr); } /* do not change the order of the ID table */ diff --git a/linux/drivers/media/dvb/dvb-usb/digitv.c b/linux/drivers/media/dvb/dvb-usb/digitv.c index 382ffaa1e..1394b3e6b 100644 --- a/linux/drivers/media/dvb/dvb-usb/digitv.c +++ b/linux/drivers/media/dvb/dvb-usb/digitv.c @@ -20,6 +20,9 @@ static int dvb_usb_digitv_debug; module_param_named(debug,dvb_usb_digitv_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + #define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args) static int digitv_ctrl_msg(struct dvb_usb_device *d, @@ -256,8 +259,9 @@ static int digitv_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct dvb_usb_device *d; - int ret; - if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) { + int ret = dvb_usb_device_init(intf, &digitv_properties, THIS_MODULE, &d, + adapter_nr); + if (ret == 0) { u8 b[4] = { 0 }; if (d != NULL) { /* do that only when the firmware is loaded */ diff --git a/linux/drivers/media/dvb/dvb-usb/dtt200u.c b/linux/drivers/media/dvb/dvb-usb/dtt200u.c index 24ccd5a4d..5fcae7925 100644 --- a/linux/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/linux/drivers/media/dvb/dvb-usb/dtt200u.c @@ -18,6 +18,8 @@ int dvb_usb_dtt200u_debug; module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff) { u8 b = SET_INIT; @@ -101,11 +103,16 @@ static struct dvb_usb_device_properties wt220u_miglia_properties; static int dtt200u_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - 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_miglia_properties,THIS_MODULE,NULL) == 0) + if (0 == dvb_usb_device_init(intf, &dtt200u_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &wt220u_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &wt220u_fc_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &wt220u_zl0353_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &wt220u_miglia_properties, + THIS_MODULE, NULL, adapter_nr)) return 0; return -ENODEV; diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-common.h index 35ab68f6d..6b7b2a892 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-common.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-common.h @@ -40,7 +40,8 @@ extern int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap); extern int dvb_usb_i2c_init(struct dvb_usb_device *); extern int dvb_usb_i2c_exit(struct dvb_usb_device *); -extern int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap); +extern int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, + short *adapter_nums); extern int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap); extern int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap); extern int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap); diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c index 4561a672d..ce8cd0c5d 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c @@ -77,12 +77,13 @@ static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) return dvb_usb_ctrl_feed(dvbdmxfeed,0); } -int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap) +int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) { - int ret; + int ret = dvb_register_adapter(&adap->dvb_adap, adap->dev->desc->name, + adap->dev->owner, &adap->dev->udev->dev, + adapter_nums); - if ((ret = dvb_register_adapter(&adap->dvb_adap, adap->dev->desc->name, - adap->dev->owner, &adap->dev->udev->dev)) < 0) { + if (ret < 0) { deb_info("dvb_register_adapter failed: error %d", ret); goto err; } diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c index cdd717c3f..e331db8c7 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-init.c @@ -26,7 +26,7 @@ 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(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) +static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) { struct dvb_usb_adapter *adap; int ret,n; @@ -72,7 +72,7 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d) } if ((ret = dvb_usb_adapter_stream_init(adap)) || - (ret = dvb_usb_adapter_dvb_init(adap)) || + (ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) || (ret = dvb_usb_adapter_frontend_init(adap))) { return ret; } @@ -122,7 +122,7 @@ static int dvb_usb_exit(struct dvb_usb_device *d) return 0; } -static int dvb_usb_init(struct dvb_usb_device *d) +static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums) { int ret = 0; @@ -143,7 +143,7 @@ static int dvb_usb_init(struct dvb_usb_device *d) dvb_usb_device_power_ctrl(d, 1); if ((ret = dvb_usb_i2c_init(d)) || - (ret = dvb_usb_adapter_init(d))) { + (ret = dvb_usb_adapter_init(d, adapter_nums))) { dvb_usb_exit(d); return ret; } @@ -213,8 +213,10 @@ int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff) /* * USB */ -int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_device_properties - *props, struct module *owner,struct dvb_usb_device **du) +int dvb_usb_device_init(struct usb_interface *intf, + struct dvb_usb_device_properties *props, + struct module *owner, struct dvb_usb_device **du, + short *adapter_nums) { struct usb_device *udev = interface_to_usbdev(intf); struct dvb_usb_device *d = NULL; @@ -254,7 +256,7 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_device_proper if (du != NULL) *du = d; - ret = dvb_usb_init(d); + ret = dvb_usb_init(d, adapter_nums); if (ret == 0) info("%s successfully initialized and connected.",desc->name); diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h index cc5d432bc..f8528bf74 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -387,7 +387,10 @@ struct dvb_usb_device { void *priv; }; -extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_device_properties *, struct module *, struct dvb_usb_device **); +extern int dvb_usb_device_init(struct usb_interface *, + struct dvb_usb_device_properties *, + struct module *, struct dvb_usb_device **, + short *adapter_nums); extern void dvb_usb_device_exit(struct usb_interface *); /* the generic read/write method for device control */ diff --git a/linux/drivers/media/dvb/dvb-usb/gl861.c b/linux/drivers/media/dvb/dvb-usb/gl861.c index 8f26ede0c..cc90a3054 100644 --- a/linux/drivers/media/dvb/dvb-usb/gl861.c +++ b/linux/drivers/media/dvb/dvb-usb/gl861.c @@ -16,6 +16,8 @@ static int dvb_usb_gl861_debug; module_param_named(debug,dvb_usb_gl861_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) { @@ -140,7 +142,9 @@ static int gl861_probe(struct usb_interface *intf, if (intf->num_altsetting < 2) return -ENODEV; - if ((ret = dvb_usb_device_init(intf, &gl861_properties, THIS_MODULE, &d)) == 0) { + ret = dvb_usb_device_init(intf, &gl861_properties, THIS_MODULE, &d, + adapter_nr); + if (ret == 0) { alt = usb_altnum_to_altsetting(intf, 0); if (alt == NULL) { diff --git a/linux/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/linux/drivers/media/dvb/dvb-usb/gp8psk-fe.c index e37142d92..262a858c3 100644 --- a/linux/drivers/media/dvb/dvb-usb/gp8psk-fe.c +++ b/linux/drivers/media/dvb/dvb-usb/gp8psk-fe.c @@ -152,7 +152,7 @@ static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe, { struct gp8psk_fe_state *st = fe->demodulator_priv; - deb_fe("%s\n",__FUNCTION__); + deb_fe("%s\n",__func__); if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0, m->msg, m->msg_len)) { @@ -167,7 +167,7 @@ static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe, struct gp8psk_fe_state *st = fe->demodulator_priv; u8 cmd; - deb_fe("%s\n",__FUNCTION__); + deb_fe("%s\n",__func__); /* These commands are certainly wrong */ cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01; diff --git a/linux/drivers/media/dvb/dvb-usb/gp8psk.c b/linux/drivers/media/dvb/dvb-usb/gp8psk.c index 54ecee36d..cc99e1cab 100644 --- a/linux/drivers/media/dvb/dvb-usb/gp8psk.c +++ b/linux/drivers/media/dvb/dvb-usb/gp8psk.c @@ -22,6 +22,8 @@ int dvb_usb_gp8psk_debug; module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) { int ret = 0,try = 0; @@ -208,7 +210,8 @@ static int gp8psk_usb_probe(struct usb_interface *intf, { int ret; struct usb_device *udev = interface_to_usbdev(intf); - ret = dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL); + ret = dvb_usb_device_init(intf, &gp8psk_properties, + THIS_MODULE, NULL, adapter_nr); if (ret == 0) { info("found Genpix USB device pID = %x (hex)", le16_to_cpu(udev->descriptor.idProduct)); diff --git a/linux/drivers/media/dvb/dvb-usb/m920x.c b/linux/drivers/media/dvb/dvb-usb/m920x.c index 503598127..7597c4b78 100644 --- a/linux/drivers/media/dvb/dvb-usb/m920x.c +++ b/linux/drivers/media/dvb/dvb-usb/m920x.c @@ -22,6 +22,8 @@ static int dvb_usb_m920x_debug; module_param_named(debug,dvb_usb_m920x_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid); static inline int m920x_read(struct usb_device *udev, u8 request, u16 value, @@ -477,7 +479,7 @@ static struct qt1010_config m920x_qt1010_config = { /* Callbacks for DVB USB */ static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap) { - deb("%s\n",__FUNCTION__); + deb("%s\n",__func__); if ((adap->fe = dvb_attach(mt352_attach, &m920x_mt352_config, @@ -489,7 +491,7 @@ static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap) static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap) { - deb("%s\n",__FUNCTION__); + deb("%s\n",__func__); if ((adap->fe = dvb_attach(tda10046_attach, &m920x_tda10046_08_config, @@ -501,7 +503,7 @@ static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap) static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap) { - deb("%s\n",__FUNCTION__); + deb("%s\n",__func__); if ((adap->fe = dvb_attach(tda10046_attach, &m920x_tda10046_0b_config, @@ -513,7 +515,7 @@ static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap) static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap) { - deb("%s\n",__FUNCTION__); + deb("%s\n",__func__); if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL) return -ENODEV; @@ -523,7 +525,7 @@ static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap) static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap) { - deb("%s\n",__FUNCTION__); + deb("%s\n",__func__); if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL) return -ENODEV; @@ -533,7 +535,7 @@ static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap) static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap) { - deb("%s\n",__FUNCTION__); + deb("%s\n",__func__); if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL) return -ENODEV; @@ -618,27 +620,31 @@ static int m920x_probe(struct usb_interface *intf, * multi-tuner device */ - if ((ret = dvb_usb_device_init(intf, &megasky_properties, - THIS_MODULE, &d)) == 0) { + ret = dvb_usb_device_init(intf, &megasky_properties, + THIS_MODULE, &d, adapter_nr); + if (ret == 0) { rc_init_seq = megasky_rc_init; goto found; } - if ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties, - THIS_MODULE, &d)) == 0) { + ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties, + THIS_MODULE, &d, adapter_nr); + if (ret == 0) { /* No remote control, so no rc_init_seq */ goto found; } /* This configures both tuners on the TV Walker Twin */ - if ((ret = dvb_usb_device_init(intf, &tvwalkertwin_properties, - THIS_MODULE, &d)) == 0) { + ret = dvb_usb_device_init(intf, &tvwalkertwin_properties, + THIS_MODULE, &d, adapter_nr); + if (ret == 0) { rc_init_seq = tvwalkertwin_rc_init; goto found; } - if ((ret = dvb_usb_device_init(intf, &dposh_properties, - THIS_MODULE, &d)) == 0) { + ret = dvb_usb_device_init(intf, &dposh_properties, + THIS_MODULE, &d, adapter_nr); + if (ret == 0) { /* Remote controller not supported yet. */ goto found; } diff --git a/linux/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/linux/drivers/media/dvb/dvb-usb/nova-t-usb2.c index f0aadc8a2..a346040ca 100644 --- a/linux/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/linux/drivers/media/dvb/dvb-usb/nova-t-usb2.c @@ -15,6 +15,8 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + #define deb_rc(args...) dprintk(debug,0x01,args) #define deb_ee(args...) dprintk(debug,0x02,args) @@ -142,7 +144,8 @@ static struct dvb_usb_device_properties nova_t_properties; static int nova_t_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE,NULL); + return dvb_usb_device_init(intf, &nova_t_properties, + THIS_MODULE, NULL, adapter_nr); } /* do not change the order of the ID table */ diff --git a/linux/drivers/media/dvb/dvb-usb/opera1.c b/linux/drivers/media/dvb/dvb-usb/opera1.c index 78f55fd69..cba064615 100644 --- a/linux/drivers/media/dvb/dvb-usb/opera1.c +++ b/linux/drivers/media/dvb/dvb-usb/opera1.c @@ -45,6 +45,9 @@ module_param_named(debug, dvb_usb_opera1_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))." DVB_USB_DEBUG_STATUS); + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + #if 0 struct mutex mymutex; #endif @@ -254,7 +257,7 @@ static struct stv0299_config opera1_stv0299_config = { .mclk = 88000000UL, .invert = 1, .skip_reinit = 0, - .lock_output = STV0229_LOCKOUTPUT_0, + .lock_output = STV0299_LOCKOUTPUT_0, .volt13_op0_op1 = STV0299_VOLT13_OP0, .inittab = opera1_inittab, .set_symbol_rate = opera1_stv0299_set_symbol_rate, @@ -559,7 +562,8 @@ static int opera1_probe(struct usb_interface *intf, return -EINVAL; } - if (dvb_usb_device_init(intf, &opera1_properties, THIS_MODULE, NULL) != 0) + if (0 != dvb_usb_device_init(intf, &opera1_properties, + THIS_MODULE, NULL, adapter_nr)) return -EINVAL; return 0; } diff --git a/linux/drivers/media/dvb/dvb-usb/ttusb2.c b/linux/drivers/media/dvb/dvb-usb/ttusb2.c index 572760414..e79a26473 100644 --- a/linux/drivers/media/dvb/dvb-usb/ttusb2.c +++ b/linux/drivers/media/dvb/dvb-usb/ttusb2.c @@ -37,6 +37,8 @@ static int dvb_usb_ttusb2_debug; module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + struct ttusb2_state { u8 id; }; @@ -151,6 +153,7 @@ static struct tda10086_config tda10086_config = { .demod_address = 0x0e, .invert = 0, .diseqc_tone = 1, + .xtal_freq = TDA10086_XTAL_16M, }; static int ttusb2_frontend_attach(struct dvb_usb_adapter *adap) @@ -187,8 +190,10 @@ static struct dvb_usb_device_properties ttusb2_properties_s2400; static int ttusb2_probe(struct usb_interface *intf, const struct usb_device_id *id) { - if (dvb_usb_device_init(intf, &ttusb2_properties, THIS_MODULE, NULL) == 0 || - dvb_usb_device_init(intf, &ttusb2_properties_s2400, THIS_MODULE, NULL) == 0) + if (0 == dvb_usb_device_init(intf, &ttusb2_properties, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400, + THIS_MODULE, NULL, adapter_nr)) return 0; return -ENODEV; } diff --git a/linux/drivers/media/dvb/dvb-usb/umt-010.c b/linux/drivers/media/dvb/dvb-usb/umt-010.c index f0aff4b0d..ca850d266 100644 --- a/linux/drivers/media/dvb/dvb-usb/umt-010.c +++ b/linux/drivers/media/dvb/dvb-usb/umt-010.c @@ -13,6 +13,8 @@ #include "mt352.h" +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + static int umt_mt352_demod_init(struct dvb_frontend *fe) { static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d }; @@ -75,7 +77,8 @@ static struct dvb_usb_device_properties umt_properties; static int umt_probe(struct usb_interface *intf, const struct usb_device_id *id) { - if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE,NULL) == 0) + if (0 == dvb_usb_device_init(intf, &umt_properties, + THIS_MODULE, NULL, adapter_nr)) return 0; return -EINVAL; } diff --git a/linux/drivers/media/dvb/dvb-usb/vp702x-fe.c b/linux/drivers/media/dvb/dvb-usb/vp702x-fe.c index c3fdc7cd0..ccc7e4452 100644 --- a/linux/drivers/media/dvb/dvb-usb/vp702x-fe.c +++ b/linux/drivers/media/dvb/dvb-usb/vp702x-fe.c @@ -67,7 +67,7 @@ static int vp702x_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) { struct vp702x_fe_state *st = fe->demodulator_priv; vp702x_fe_refresh_state(st); - deb_fe("%s\n",__FUNCTION__); + deb_fe("%s\n",__func__); if (st->lock == 0) *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER; @@ -121,7 +121,7 @@ static int vp702x_fe_read_snr(struct dvb_frontend* fe, u16 *snr) static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) { - deb_fe("%s\n",__FUNCTION__); + deb_fe("%s\n",__func__); tune->min_delay_ms = 2000; return 0; } @@ -183,21 +183,21 @@ static int vp702x_fe_set_frontend(struct dvb_frontend* fe, static int vp702x_fe_init(struct dvb_frontend *fe) { struct vp702x_fe_state *st = fe->demodulator_priv; - deb_fe("%s\n",__FUNCTION__); + deb_fe("%s\n",__func__); vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0); return 0; } static int vp702x_fe_sleep(struct dvb_frontend *fe) { - deb_fe("%s\n",__FUNCTION__); + deb_fe("%s\n",__func__); return 0; } static int vp702x_fe_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) { - deb_fe("%s\n",__FUNCTION__); + deb_fe("%s\n",__func__); return 0; } @@ -208,7 +208,7 @@ static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, u8 cmd[8],ibuf[10]; memset(cmd,0,8); - deb_fe("%s\n",__FUNCTION__); + deb_fe("%s\n",__func__); if (m->msg_len > 4) return -EINVAL; @@ -230,7 +230,7 @@ static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) { - deb_fe("%s\n",__FUNCTION__); + deb_fe("%s\n",__func__); return 0; } @@ -238,7 +238,7 @@ static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) { struct vp702x_fe_state *st = fe->demodulator_priv; u8 ibuf[10]; - deb_fe("%s\n",__FUNCTION__); + deb_fe("%s\n",__func__); st->tone_mode = tone; @@ -263,7 +263,7 @@ static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t { struct vp702x_fe_state *st = fe->demodulator_priv; u8 ibuf[10]; - deb_fe("%s\n",__FUNCTION__); + deb_fe("%s\n",__func__); st->voltage = voltage; diff --git a/linux/drivers/media/dvb/dvb-usb/vp702x.c b/linux/drivers/media/dvb/dvb-usb/vp702x.c index 28b7011f2..9d286d430 100644 --- a/linux/drivers/media/dvb/dvb-usb/vp702x.c +++ b/linux/drivers/media/dvb/dvb-usb/vp702x.c @@ -21,6 +21,8 @@ int dvb_usb_vp702x_debug; module_param_named(debug,dvb_usb_vp702x_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + struct vp702x_state { int pid_filter_count; int pid_filter_can_bypass; @@ -285,7 +287,8 @@ static struct dvb_usb_device_properties vp702x_properties; static int vp702x_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf,&vp702x_properties,THIS_MODULE,NULL); + return dvb_usb_device_init(intf, &vp702x_properties, + THIS_MODULE, NULL, adapter_nr); } static struct usb_device_id vp702x_usb_table [] = { diff --git a/linux/drivers/media/dvb/dvb-usb/vp7045.c b/linux/drivers/media/dvb/dvb-usb/vp7045.c index 9d244e603..b45498911 100644 --- a/linux/drivers/media/dvb/dvb-usb/vp7045.c +++ b/linux/drivers/media/dvb/dvb-usb/vp7045.c @@ -18,6 +18,9 @@ static int dvb_usb_vp7045_debug; module_param_named(debug,dvb_usb_vp7045_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + #define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args) #define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args) #define deb_rc(args...) dprintk(dvb_usb_vp7045_debug,0x04,args) @@ -227,7 +230,8 @@ static struct dvb_usb_device_properties vp7045_properties; static int vp7045_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE,NULL); + return dvb_usb_device_init(intf, &vp7045_properties, + THIS_MODULE, NULL, adapter_nr); } static struct usb_device_id vp7045_usb_table [] = { diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index 0209644f2..68fab616f 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -188,6 +188,14 @@ config DVB_DIB7000P A DVB-T tuner module. Designed for mobile usage. Say Y when you want to support this frontend. +config DVB_TDA10048 + tristate "Philips TDA10048HN based" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + select FW_LOADER + help + A DVB-T tuner module. Say Y when you want to support this frontend. + comment "DVB-C (cable) frontends" depends on DVB_CORE @@ -291,6 +299,14 @@ config DVB_S5H1409 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. +config DVB_AU8522 + tristate "Auvitek AU8522 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 @@ -369,6 +385,11 @@ config DVB_TUNER_XC5000 This device is only used inside a SiP called togther with a demodulator for now. +config DVB_TUNER_ITD1000 + tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + comment "Miscellaneous devices" depends on DVB_CORE diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile index 23304b377..2f873fc0f 100644 --- a/linux/drivers/media/dvb/frontends/Makefile +++ b/linux/drivers/media/dvb/frontends/Makefile @@ -52,3 +52,6 @@ obj-$(CONFIG_DVB_TUA6100) += tua6100.o obj-$(CONFIG_DVB_TUNER_MT2131) += mt2131.o obj-$(CONFIG_DVB_S5H1409) += s5h1409.o obj-$(CONFIG_DVB_TUNER_XC5000) += xc5000.o +obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o +obj-$(CONFIG_DVB_AU8522) += au8522.o +obj-$(CONFIG_DVB_TDA10048) += tda10048.o diff --git a/linux/drivers/media/dvb/frontends/au8522.c b/linux/drivers/media/dvb/frontends/au8522.c new file mode 100644 index 000000000..d536454b6 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/au8522.c @@ -0,0 +1,698 @@ +/* + Auvitek AU8522 QAM/8VSB demodulator driver + + Copyright (C) 2008 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. + +*/ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include "dvb_frontend.h" +#include "dvb-pll.h" +#include "au8522.h" + +struct au8522_state { + + struct i2c_adapter *i2c; + + /* configuration settings */ + const struct au8522_config *config; + + struct dvb_frontend frontend; + + u32 current_frequency; + fe_modulation_t current_modulation; + +}; + +static int debug; + +#define dprintk(arg...) do { \ + if (debug) \ + printk(arg); \ + } while (0) + +/* 16 bit registers, 8 bit values */ +static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) +{ + int ret; + u8 buf [] = { reg >> 8, reg & 0xff, data }; + + struct i2c_msg msg = { .addr = state->config->demod_address, + .flags = 0, .buf = buf, .len = 3 }; + + ret = i2c_transfer(state->i2c, &msg, 1); + + if (ret != 1) + printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " + "ret == %i)\n", __func__, reg, data, ret); + + return (ret != 1) ? -1 : 0; +} + +static u8 au8522_readreg(struct au8522_state *state, u16 reg) +{ + int ret; + u8 b0 [] = { reg >> 8, reg & 0xff }; + u8 b1 [] = { 0 }; + + struct i2c_msg msg [] = { + { .addr = state->config->demod_address, .flags = 0, + .buf = b0, .len = 2 }, + { .addr = state->config->demod_address, .flags = I2C_M_RD, + .buf = b1, .len = 1 } }; + + ret = i2c_transfer(state->i2c, msg, 2); + + if (ret != 2) + printk(KERN_ERR "%s: readreg error (ret == %i)\n", + __func__, ret); + return b1[0]; +} + +static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct au8522_state *state = fe->demodulator_priv; + + dprintk("%s(%d)\n", __func__, enable); + + if (enable) + return au8522_writereg(state, 0x106, 1); + else + return au8522_writereg(state, 0x106, 0); +} + +struct mse2snr_tab { + u16 val; + u16 data; +}; + +/* VSB SNR lookup table */ +static struct mse2snr_tab vsb_mse2snr_tab[] = { + { 0, 270 }, + { 2, 250 }, + { 3, 240 }, + { 5, 230 }, + { 7, 220 }, + { 9, 210 }, + { 12, 200 }, + { 13, 195 }, + { 15, 190 }, + { 17, 185 }, + { 19, 180 }, + { 21, 175 }, + { 24, 170 }, + { 27, 165 }, + { 31, 160 }, + { 32, 158 }, + { 33, 156 }, + { 36, 152 }, + { 37, 150 }, + { 39, 148 }, + { 40, 146 }, + { 41, 144 }, + { 43, 142 }, + { 44, 140 }, + { 48, 135 }, + { 50, 130 }, + { 43, 142 }, + { 53, 125 }, + { 56, 120 }, + { 256, 115 }, +}; + +/* QAM64 SNR lookup table */ +static struct mse2snr_tab qam64_mse2snr_tab[] = { + { 15, 0 }, + { 16, 290 }, + { 17, 288 }, + { 18, 286 }, + { 19, 284 }, + { 20, 282 }, + { 21, 281 }, + { 22, 279 }, + { 23, 277 }, + { 24, 275 }, + { 25, 273 }, + { 26, 271 }, + { 27, 269 }, + { 28, 268 }, + { 29, 266 }, + { 30, 264 }, + { 31, 262 }, + { 32, 260 }, + { 33, 259 }, + { 34, 258 }, + { 35, 256 }, + { 36, 255 }, + { 37, 254 }, + { 38, 252 }, + { 39, 251 }, + { 40, 250 }, + { 41, 249 }, + { 42, 248 }, + { 43, 246 }, + { 44, 245 }, + { 45, 244 }, + { 46, 242 }, + { 47, 241 }, + { 48, 240 }, + { 50, 239 }, + { 51, 238 }, + { 53, 237 }, + { 54, 236 }, + { 56, 235 }, + { 57, 234 }, + { 59, 233 }, + { 60, 232 }, + { 62, 231 }, + { 63, 230 }, + { 65, 229 }, + { 67, 228 }, + { 68, 227 }, + { 70, 226 }, + { 71, 225 }, + { 73, 224 }, + { 74, 223 }, + { 76, 222 }, + { 78, 221 }, + { 80, 220 }, + { 82, 219 }, + { 85, 218 }, + { 88, 217 }, + { 90, 216 }, + { 92, 215 }, + { 93, 214 }, + { 94, 212 }, + { 95, 211 }, + { 97, 210 }, + { 99, 209 }, + { 101, 208 }, + { 102, 207 }, + { 104, 206 }, + { 107, 205 }, + { 111, 204 }, + { 114, 203 }, + { 118, 202 }, + { 122, 201 }, + { 125, 200 }, + { 128, 199 }, + { 130, 198 }, + { 132, 197 }, + { 256, 190 }, +}; + +/* QAM256 SNR lookup table */ +static struct mse2snr_tab qam256_mse2snr_tab[] = { + { 16, 0 }, + { 17, 400 }, + { 18, 398 }, + { 19, 396 }, + { 20, 394 }, + { 21, 392 }, + { 22, 390 }, + { 23, 388 }, + { 24, 386 }, + { 25, 384 }, + { 26, 382 }, + { 27, 380 }, + { 28, 379 }, + { 29, 378 }, + { 30, 377 }, + { 31, 376 }, + { 32, 375 }, + { 33, 374 }, + { 34, 373 }, + { 35, 372 }, + { 36, 371 }, + { 37, 370 }, + { 38, 362 }, + { 39, 354 }, + { 40, 346 }, + { 41, 338 }, + { 42, 330 }, + { 43, 328 }, + { 44, 326 }, + { 45, 324 }, + { 46, 322 }, + { 47, 320 }, + { 48, 319 }, + { 49, 318 }, + { 50, 317 }, + { 51, 316 }, + { 52, 315 }, + { 53, 314 }, + { 54, 313 }, + { 55, 312 }, + { 56, 311 }, + { 57, 310 }, + { 58, 308 }, + { 59, 306 }, + { 60, 304 }, + { 61, 302 }, + { 62, 300 }, + { 63, 298 }, + { 65, 295 }, + { 68, 294 }, + { 70, 293 }, + { 73, 292 }, + { 76, 291 }, + { 78, 290 }, + { 79, 289 }, + { 81, 288 }, + { 82, 287 }, + { 83, 286 }, + { 84, 285 }, + { 85, 284 }, + { 86, 283 }, + { 88, 282 }, + { 89, 281 }, + { 256, 280 }, +}; + +static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse, + u16 *snr) +{ + int i, ret = -EINVAL; + dprintk("%s()\n", __func__); + + for (i = 0; i < sz; i++) { + if (mse < tab[i].val) { + *snr = tab[i].data; + ret = 0; + break; + } + } + dprintk("%s() snr=%d\n", __func__, *snr); + return ret; +} + +/* VSB Modulation table */ +static struct { + u16 reg; + u16 data; +} VSB_mod_tab[] = { + { 0x8090, 0x84 }, + { 0x4092, 0x11 }, + { 0x2005, 0x00 }, + { 0x8091, 0x80 }, + { 0x80a3, 0x0c }, + { 0x80a4, 0xe8 }, + { 0x8081, 0xc4 }, + { 0x80a5, 0x40 }, + { 0x80a7, 0x40 }, + { 0x80a6, 0x67 }, + { 0x8262, 0x20 }, + { 0x821c, 0x30 }, + { 0x80d8, 0x1a }, + { 0x8227, 0xa0 }, + { 0x8121, 0xff }, + { 0x80a8, 0xf0 }, + { 0x80a9, 0x05 }, + { 0x80aa, 0x77 }, + { 0x80ab, 0xf0 }, + { 0x80ac, 0x05 }, + { 0x80ad, 0x77 }, + { 0x80ae, 0x41 }, + { 0x80af, 0x66 }, + { 0x821b, 0xcc }, + { 0x821d, 0x80 }, + { 0x80b5, 0xfb }, + { 0x80b6, 0x8e }, + { 0x80b7, 0x39 }, + { 0x80a4, 0xe8 }, + { 0x8231, 0x13 }, +}; + +/* QAM Modulation table */ +static struct { + u16 reg; + u16 data; +} QAM_mod_tab[] = { + { 0x80a3, 0x09 }, + { 0x80a4, 0x00 }, + { 0x8081, 0xc4 }, + { 0x80a5, 0x40 }, + { 0x80b5, 0xfb }, + { 0x80b6, 0x8e }, + { 0x80b7, 0x39 }, + { 0x80aa, 0x77 }, + { 0x80ad, 0x77 }, + { 0x80a6, 0x67 }, + { 0x8262, 0x20 }, + { 0x821c, 0x30 }, + { 0x80b8, 0x3e }, + { 0x80b9, 0xf0 }, + { 0x80ba, 0x01 }, + { 0x80bb, 0x18 }, + { 0x80bc, 0x50 }, + { 0x80bd, 0x00 }, + { 0x80be, 0xea }, + { 0x80bf, 0xef }, + { 0x80c0, 0xfc }, + { 0x80c1, 0xbd }, + { 0x80c2, 0x1f }, + { 0x80c3, 0xfc }, + { 0x80c4, 0xdd }, + { 0x80c5, 0xaf }, + { 0x80c6, 0x00 }, + { 0x80c7, 0x38 }, + { 0x80c8, 0x30 }, + { 0x80c9, 0x05 }, + { 0x80ca, 0x4a }, + { 0x80cb, 0xd0 }, + { 0x80cc, 0x01 }, + { 0x80cd, 0xd9 }, + { 0x80ce, 0x6f }, + { 0x80cf, 0xf9 }, + { 0x80d0, 0x70 }, + { 0x80d1, 0xdf }, + { 0x80d2, 0xf7 }, + { 0x80d3, 0xc2 }, + { 0x80d4, 0xdf }, + { 0x80d5, 0x02 }, + { 0x80d6, 0x9a }, + { 0x80d7, 0xd0 }, + { 0x8250, 0x0d }, + { 0x8251, 0xcd }, + { 0x8252, 0xe0 }, + { 0x8253, 0x05 }, + { 0x8254, 0xa7 }, + { 0x8255, 0xff }, + { 0x8256, 0xed }, + { 0x8257, 0x5b }, + { 0x8258, 0xae }, + { 0x8259, 0xe6 }, + { 0x825a, 0x3d }, + { 0x825b, 0x0f }, + { 0x825c, 0x0d }, + { 0x825d, 0xea }, + { 0x825e, 0xf2 }, + { 0x825f, 0x51 }, + { 0x8260, 0xf5 }, + { 0x8261, 0x06 }, + { 0x821a, 0x00 }, + { 0x8546, 0x40 }, + { 0x8210, 0x26 }, + { 0x8211, 0xf6 }, + { 0x8212, 0x84 }, + { 0x8213, 0x02 }, + { 0x8502, 0x01 }, + { 0x8121, 0x04 }, + { 0x8122, 0x04 }, + { 0x852e, 0x10 }, + { 0x80a4, 0xca }, + { 0x80a7, 0x40 }, + { 0x8526, 0x01 }, +}; + +static int au8522_enable_modulation(struct dvb_frontend *fe, + fe_modulation_t m) +{ + struct au8522_state *state = fe->demodulator_priv; + int i; + + dprintk("%s(0x%08x)\n", __func__, m); + + switch (m) { + case VSB_8: + dprintk("%s() VSB_8\n", __func__); + for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++) + au8522_writereg(state, + VSB_mod_tab[i].reg, + VSB_mod_tab[i].data); + break; + case QAM_64: + case QAM_256: + dprintk("%s() QAM 64/256\n", __func__); + for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++) + au8522_writereg(state, + QAM_mod_tab[i].reg, + QAM_mod_tab[i].data); + break; + default: + dprintk("%s() Invalid modulation\n", __func__); + return -EINVAL; + } + + state->current_modulation = m; + + return 0; +} + +/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ +static int au8522_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct au8522_state *state = fe->demodulator_priv; + + dprintk("%s(frequency=%d)\n", __func__, p->frequency); + + state->current_frequency = p->frequency; + + au8522_enable_modulation(fe, p->u.vsb.modulation); + + /* Allow the demod to settle */ + msleep(100); + + if (fe->ops.tuner_ops.set_params) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + fe->ops.tuner_ops.set_params(fe, p); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + + return 0; +} + +/* Reset the demod hardware and reset all of the configuration registers + to a default state. */ +static int au8522_init(struct dvb_frontend *fe) +{ + struct au8522_state *state = fe->demodulator_priv; + dprintk("%s()\n", __func__); + + au8522_writereg(state, 0xa4, 1 << 5); + + au8522_i2c_gate_ctrl(fe, 1); + + return 0; +} + +static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct au8522_state *state = fe->demodulator_priv; + u8 reg; + u32 tuner_status = 0; + + *status = 0; + + if (state->current_modulation == VSB_8) { + dprintk("%s() Checking VSB_8\n", __func__); + reg = au8522_readreg(state, 0x4088); + if (reg & 0x01) + *status |= FE_HAS_VITERBI; + if (reg & 0x02) + *status |= FE_HAS_LOCK | FE_HAS_SYNC; + } else { + dprintk("%s() Checking QAM\n", __func__); + reg = au8522_readreg(state, 0x4541); + if (reg & 0x80) + *status |= FE_HAS_VITERBI; + if (reg & 0x20) + *status |= FE_HAS_LOCK | FE_HAS_SYNC; + } + + switch (state->config->status_mode) { + case AU8522_DEMODLOCKING: + dprintk("%s() DEMODLOCKING\n", __func__); + if (*status & FE_HAS_VITERBI) + *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; + break; + case AU8522_TUNERLOCKING: + /* Get the tuner status */ + dprintk("%s() TUNERLOCKING\n", __func__); + if (fe->ops.tuner_ops.get_status) { + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + fe->ops.tuner_ops.get_status(fe, &tuner_status); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + if (tuner_status) + *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; + break; + } + + dprintk("%s() status 0x%08x\n", __func__, *status); + + return 0; +} + +static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct au8522_state *state = fe->demodulator_priv; + int ret = -EINVAL; + + dprintk("%s()\n", __func__); + + if (state->current_modulation == QAM_256) + ret = au8522_mse2snr_lookup(qam256_mse2snr_tab, + ARRAY_SIZE(qam256_mse2snr_tab), + au8522_readreg(state, 0x4522), + snr); + else if (state->current_modulation == QAM_64) + ret = au8522_mse2snr_lookup(qam64_mse2snr_tab, + ARRAY_SIZE(qam64_mse2snr_tab), + au8522_readreg(state, 0x4522), + snr); + else /* VSB_8 */ + ret = au8522_mse2snr_lookup(vsb_mse2snr_tab, + ARRAY_SIZE(vsb_mse2snr_tab), + au8522_readreg(state, 0x4311), + snr); + + return ret; +} + +static int au8522_read_signal_strength(struct dvb_frontend *fe, + u16 *signal_strength) +{ + return au8522_read_snr(fe, signal_strength); +} + +static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct au8522_state *state = fe->demodulator_priv; + + if (state->current_modulation == VSB_8) + *ucblocks = au8522_readreg(state, 0x4087); + else + *ucblocks = au8522_readreg(state, 0x4543); + + return 0; +} + +static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + return au8522_read_ucblocks(fe, ber); +} + +static int au8522_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct au8522_state *state = fe->demodulator_priv; + + p->frequency = state->current_frequency; + p->u.vsb.modulation = state->current_modulation; + + return 0; +} + +static int au8522_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *tune) +{ + tune->min_delay_ms = 1000; + return 0; +} + +static void au8522_release(struct dvb_frontend *fe) +{ + struct au8522_state *state = fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops au8522_ops; + +struct dvb_frontend *au8522_attach(const struct au8522_config *config, + struct i2c_adapter *i2c) +{ + struct au8522_state *state = NULL; + + /* allocate memory for the internal state */ + state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL); + if (state == NULL) + goto error; + + /* setup the state */ + state->config = config; + state->i2c = i2c; +#if 0 + /* check if the demod exists */ + reg = au8522_readreg(state, 0x04); + if ((reg != 0x0066) && (reg != 0x007f)) + goto error; +#endif + /* create dvb_frontend */ + memcpy(&state->frontend.ops, &au8522_ops, + sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + + if (au8522_init(&state->frontend) != 0) { + printk(KERN_ERR "%s: Failed to initialize correctly\n", + __func__); + goto error; + } + + /* Note: Leaving the I2C gate open here. */ + au8522_i2c_gate_ctrl(&state->frontend, 1); + + return &state->frontend; + +error: + kfree(state); + return NULL; +} +EXPORT_SYMBOL(au8522_attach); + +static struct dvb_frontend_ops au8522_ops = { + + .info = { + .name = "Auvitek AU8522 QAM/8VSB Frontend", + .type = FE_ATSC, + .frequency_min = 54000000, + .frequency_max = 858000000, + .frequency_stepsize = 62500, + .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB + }, + + .init = au8522_init, + .i2c_gate_ctrl = au8522_i2c_gate_ctrl, + .set_frontend = au8522_set_frontend, + .get_frontend = au8522_get_frontend, + .get_tune_settings = au8522_get_tune_settings, + .read_status = au8522_read_status, + .read_ber = au8522_read_ber, + .read_signal_strength = au8522_read_signal_strength, + .read_snr = au8522_read_snr, + .read_ucblocks = au8522_read_ucblocks, + .release = au8522_release, +}; + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Enable verbose debug messages"); + +MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver"); +MODULE_AUTHOR("Steven Toth"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/frontends/au8522.h b/linux/drivers/media/dvb/frontends/au8522.h new file mode 100644 index 000000000..d7affa3cd --- /dev/null +++ b/linux/drivers/media/dvb/frontends/au8522.h @@ -0,0 +1,56 @@ +/* + Auvitek AU8522 QAM/8VSB demodulator driver + + Copyright (C) 2008 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 __AU8522_H__ +#define __AU8522_H__ + +#include <linux/dvb/frontend.h> + +struct au8522_config { + /* the demodulator's i2c address */ + u8 demod_address; + + /* Return lock status based on tuner lock, or demod lock */ +#define AU8522_TUNERLOCKING 0 +#define AU8522_DEMODLOCKING 1 + u8 status_mode; +}; + +#if defined(CONFIG_DVB_AU8522) || \ + (defined(CONFIG_DVB_AU8522_MODULE) && defined(MODULE)) +extern struct dvb_frontend *au8522_attach(const struct au8522_config *config, + struct i2c_adapter *i2c); +#else +static inline +struct dvb_frontend *au8522_attach(const struct au8522_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_AU8522 */ + +#endif /* __AU8522_H__ */ + +/* + * Local variables: + * c-basic-offset: 8 + */ diff --git a/linux/drivers/media/dvb/frontends/bcm3510.c b/linux/drivers/media/dvb/frontends/bcm3510.c index 0e2253dd6..ca9a55ae9 100644 --- a/linux/drivers/media/dvb/frontends/bcm3510.c +++ b/linux/drivers/media/dvb/frontends/bcm3510.c @@ -98,7 +98,7 @@ static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n", - __FUNCTION__, state->config->demod_address, reg, err); + __func__, state->config->demod_address, reg, err); return -EREMOTEIO; } @@ -117,7 +117,7 @@ static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 l if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) { deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n", - __FUNCTION__, state->config->demod_address, reg, err); + __func__, state->config->demod_address, reg, err); return -EREMOTEIO; } deb_i2c("i2c rd %02x: ",reg); diff --git a/linux/drivers/media/dvb/frontends/bcm3510.h b/linux/drivers/media/dvb/frontends/bcm3510.h index 7e4f95e17..f4575c0cc 100644 --- a/linux/drivers/media/dvb/frontends/bcm3510.h +++ b/linux/drivers/media/dvb/frontends/bcm3510.h @@ -41,7 +41,7 @@ extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, static inline struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_BCM3510 diff --git a/linux/drivers/media/dvb/frontends/bsbe1.h b/linux/drivers/media/dvb/frontends/bsbe1.h index d8f65738e..5e431ebd0 100644 --- a/linux/drivers/media/dvb/frontends/bsbe1.h +++ b/linux/drivers/media/dvb/frontends/bsbe1.h @@ -1,5 +1,5 @@ /* - * bsbe1.h - ALPS BSBE1 tuner support (moved from av7110.c) + * bsbe1.h - ALPS BSBE1 tuner support * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -26,44 +26,24 @@ #define BSBE1_H static u8 alps_bsbe1_inittab[] = { - 0x01, 0x15, - 0x02, 0x30, - 0x03, 0x00, + 0x01, 0x15, /* XTAL = 4MHz, VCO = 352 MHz */ + 0x02, 0x30, /* MCLK = 88 MHz */ + 0x03, 0x00, /* ACR output 0 */ 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x40, /* DAC not used, set to high impendance mode */ - 0x07, 0x00, /* DAC LSB */ + 0x05, 0x05, /* I2CT = 0, SCLT = 1, SDAT = 1 */ + 0x06, 0x00, /* DAC output 0 */ 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ - 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ - 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ - 0x10, 0x3f, // AGC2 0x3d - 0x11, 0x84, - 0x12, 0xb9, - 0x15, 0xc9, // lock detector threshold - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 - 0x29, 0x1e, // 1/2 threshold - 0x2a, 0x14, // 2/3 threshold - 0x2b, 0x0f, // 3/4 threshold - 0x2c, 0x09, // 5/6 threshold - 0x2d, 0x05, // 7/8 threshold - 0x2e, 0x01, - 0x31, 0x1f, // test all FECs - 0x32, 0x19, // viterbi and synchro search - 0x33, 0xfc, // rs control - 0x34, 0x93, // error control - 0x0f, 0x92, + 0x0c, 0x51, /* OP1/OP0 normal, val = 1 (LNB power on) */ + 0x0d, 0x82, /* DC offset compensation = on, beta_agc1 = 2 */ + 0x0f, 0x92, /* AGC1R */ + 0x10, 0x34, /* AGC2O */ + 0x11, 0x84, /* TLSR */ + 0x12, 0xb9, /* CFD */ + 0x15, 0xc9, /* lock detector threshold */ + 0x28, 0x00, /* out imp: normal, type: parallel, FEC mode: QPSK */ + 0x33, 0xfc, /* RS control */ + 0x34, 0x93, /* count viterbi bit errors per 2E18 bytes */ 0xff, 0xff }; @@ -100,11 +80,11 @@ static int alps_bsbe1_tuner_set_params(struct dvb_frontend* fe, struct dvb_front if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL; - div = (params->frequency + (125 - 1)) / 125; // round correctly + div = params->frequency / 1000; data[0] = (div >> 8) & 0x7f; data[1] = div & 0xff; - data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; - data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; + data[2] = 0x80 | ((div & 0x18000) >> 10) | 0x1; + data[3] = 0xe0; if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); diff --git a/linux/drivers/media/dvb/frontends/bsru6.h b/linux/drivers/media/dvb/frontends/bsru6.h index e231cd84b..45a6dfd8e 100644 --- a/linux/drivers/media/dvb/frontends/bsru6.h +++ b/linux/drivers/media/dvb/frontends/bsru6.h @@ -133,7 +133,7 @@ static struct stv0299_config alps_bsru6_config = { .mclk = 88000000UL, .invert = 1, .skip_reinit = 0, - .lock_output = STV0229_LOCKOUTPUT_1, + .lock_output = STV0299_LOCKOUTPUT_1, .volt13_op0_op1 = STV0299_VOLT13_OP1, .min_delay_ms = 100, .set_symbol_rate = alps_bsru6_set_symbol_rate, diff --git a/linux/drivers/media/dvb/frontends/cx22700.c b/linux/drivers/media/dvb/frontends/cx22700.c index 11a4968f1..ace5cb171 100644 --- a/linux/drivers/media/dvb/frontends/cx22700.c +++ b/linux/drivers/media/dvb/frontends/cx22700.c @@ -73,13 +73,13 @@ static int cx22700_writereg (struct cx22700_state* state, u8 reg, u8 data) u8 buf [] = { reg, data }; struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); ret = i2c_transfer (state->i2c, &msg, 1); if (ret != 1) printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", - __FUNCTION__, reg, data, ret); + __func__, reg, data, ret); return (ret != 1) ? -1 : 0; } @@ -92,7 +92,7 @@ static int cx22700_readreg (struct cx22700_state* state, u8 reg) struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); ret = i2c_transfer (state->i2c, msg, 2); @@ -105,7 +105,7 @@ static int cx22700_set_inversion (struct cx22700_state* state, int inversion) { u8 val; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); switch (inversion) { case INVERSION_AUTO: @@ -127,7 +127,7 @@ static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_paramet static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 }; u8 val; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (p->code_rate_HP < FEC_1_2 || p->code_rate_HP > FEC_7_8) return -EINVAL; @@ -191,7 +191,7 @@ static int cx22700_get_tps (struct cx22700_state* state, struct dvb_ofdm_paramet FEC_5_6, FEC_7_8 }; u8 val; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (!(cx22700_readreg(state, 0x07) & 0x20)) /* tps valid? */ return -EAGAIN; diff --git a/linux/drivers/media/dvb/frontends/cx22700.h b/linux/drivers/media/dvb/frontends/cx22700.h index 7ac33690c..4757a930c 100644 --- a/linux/drivers/media/dvb/frontends/cx22700.h +++ b/linux/drivers/media/dvb/frontends/cx22700.h @@ -38,7 +38,7 @@ extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, static inline struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_CX22700 diff --git a/linux/drivers/media/dvb/frontends/cx22702.c b/linux/drivers/media/dvb/frontends/cx22702.c index 406c4cfa8..cc1db4e37 100644 --- a/linux/drivers/media/dvb/frontends/cx22702.c +++ b/linux/drivers/media/dvb/frontends/cx22702.c @@ -90,7 +90,7 @@ static int cx22702_writereg (struct cx22702_state* state, u8 reg, u8 data) if (ret != 1) printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", - __FUNCTION__, reg, data, ret); + __func__, reg, data, ret); return (ret != 1) ? -1 : 0; } @@ -108,7 +108,7 @@ static u8 cx22702_readreg (struct cx22702_state* state, u8 reg) ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) - printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); + printk("%s: readreg error (ret == %i)\n", __func__, ret); return b1[0]; } @@ -195,7 +195,7 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) { struct cx22702_state* state = fe->demodulator_priv; - dprintk ("%s(%d)\n", __FUNCTION__, enable); + dprintk ("%s(%d)\n", __func__, enable); if (enable) return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe); else @@ -228,7 +228,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet cx22702_writereg(state, 0x0C, cx22702_readreg(state, 0x0C) &0xcf ); break; default: - dprintk ("%s: invalid bandwidth\n",__FUNCTION__); + dprintk ("%s: invalid bandwidth\n",__func__); return -EINVAL; } @@ -250,7 +250,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc ); cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 ); cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */ - dprintk("%s: Autodetecting\n",__FUNCTION__); + dprintk("%s: Autodetecting\n",__func__); return 0; } @@ -261,7 +261,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet case QAM_16: val = (val&0xe7)|0x08; break; case QAM_64: val = (val&0xe7)|0x10; break; default: - dprintk ("%s: invalid constellation\n",__FUNCTION__); + dprintk ("%s: invalid constellation\n",__func__); return -EINVAL; } switch(p->u.ofdm.hierarchy_information) { @@ -270,7 +270,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet case HIERARCHY_2: val = (val&0xf8)|2; break; case HIERARCHY_4: val = (val&0xf8)|3; break; default: - dprintk ("%s: invalid hierarchy\n",__FUNCTION__); + dprintk ("%s: invalid hierarchy\n",__func__); return -EINVAL; } cx22702_writereg (state, 0x06, val); @@ -284,7 +284,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet case FEC_5_6: val = (val&0xc7)|0x18; break; case FEC_7_8: val = (val&0xc7)|0x20; break; default: - dprintk ("%s: invalid code_rate_HP\n",__FUNCTION__); + dprintk ("%s: invalid code_rate_HP\n",__func__); return -EINVAL; } switch(p->u.ofdm.code_rate_LP) { @@ -295,7 +295,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet case FEC_5_6: val = (val&0xf8)|3; break; case FEC_7_8: val = (val&0xf8)|4; break; default: - dprintk ("%s: invalid code_rate_LP\n",__FUNCTION__); + dprintk ("%s: invalid code_rate_LP\n",__func__); return -EINVAL; } cx22702_writereg (state, 0x07, val); @@ -307,14 +307,14 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet case GUARD_INTERVAL_1_8: val = (val&0xf3)|0x08; break; case GUARD_INTERVAL_1_4: val = (val&0xf3)|0x0c; break; default: - dprintk ("%s: invalid guard_interval\n",__FUNCTION__); + dprintk ("%s: invalid guard_interval\n",__func__); return -EINVAL; } switch(p->u.ofdm.transmission_mode) { case TRANSMISSION_MODE_2K: val = (val&0xfc); break; case TRANSMISSION_MODE_8K: val = (val&0xfc)|1; break; default: - dprintk ("%s: invalid transmission_mode\n",__FUNCTION__); + dprintk ("%s: invalid transmission_mode\n",__func__); return -EINVAL; } cx22702_writereg(state, 0x08, val); @@ -360,7 +360,7 @@ static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status) reg23 = cx22702_readreg (state, 0x23); dprintk ("%s: status demod=0x%02x agc=0x%02x\n" - ,__FUNCTION__,reg0A,reg23); + ,__func__,reg0A,reg23); if(reg0A & 0x10) { *status |= FE_HAS_LOCK; diff --git a/linux/drivers/media/dvb/frontends/cx22702.h b/linux/drivers/media/dvb/frontends/cx22702.h index 9cd64da6e..8af766a31 100644 --- a/linux/drivers/media/dvb/frontends/cx22702.h +++ b/linux/drivers/media/dvb/frontends/cx22702.h @@ -48,7 +48,7 @@ extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, static inline struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_CX22702 diff --git a/linux/drivers/media/dvb/frontends/cx24110.c b/linux/drivers/media/dvb/frontends/cx24110.c index b03d8283c..87ae29db0 100644 --- a/linux/drivers/media/dvb/frontends/cx24110.c +++ b/linux/drivers/media/dvb/frontends/cx24110.c @@ -121,7 +121,7 @@ static int cx24110_writereg (struct cx24110_state* state, int reg, int data) if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { dprintk ("%s: writereg error (err == %i, reg == 0x%02x," - " data == 0x%02x)\n", __FUNCTION__, err, reg, data); + " data == 0x%02x)\n", __func__, err, reg, data); return -EREMOTEIO; } @@ -247,7 +247,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; int i; - dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); + dprintk("cx24110 debug: entering %s(%d)\n",__func__,srate); if (srate>90999000UL/2) srate=90999000UL/2; if (srate<500000) @@ -358,7 +358,7 @@ static int cx24110_initfe(struct dvb_frontend* fe) /* fixme (low): error handling */ int i; - dprintk("%s: init chip\n", __FUNCTION__); + dprintk("%s: init chip\n", __func__); for(i = 0; i < ARRAY_SIZE(cx24110_regdata); i++) { cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data); diff --git a/linux/drivers/media/dvb/frontends/cx24110.h b/linux/drivers/media/dvb/frontends/cx24110.h index 0ca3af4db..1792adb23 100644 --- a/linux/drivers/media/dvb/frontends/cx24110.h +++ b/linux/drivers/media/dvb/frontends/cx24110.h @@ -48,7 +48,7 @@ extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, static inline struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_CX24110 diff --git a/linux/drivers/media/dvb/frontends/dib3000.h b/linux/drivers/media/dvb/frontends/dib3000.h index a6d3854a6..ba917359f 100644 --- a/linux/drivers/media/dvb/frontends/dib3000.h +++ b/linux/drivers/media/dvb/frontends/dib3000.h @@ -48,7 +48,7 @@ extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config static inline struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_DIB3000MB diff --git a/linux/drivers/media/dvb/frontends/dib3000mc.h b/linux/drivers/media/dvb/frontends/dib3000mc.h index 72d475760..4142ed7a4 100644 --- a/linux/drivers/media/dvb/frontends/dib3000mc.h +++ b/linux/drivers/media/dvb/frontends/dib3000mc.h @@ -44,7 +44,7 @@ extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i #else static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_DIB3000MC diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.h b/linux/drivers/media/dvb/frontends/dvb-pll.h index 435146d9f..872ca29e7 100644 --- a/linux/drivers/media/dvb/frontends/dvb-pll.h +++ b/linux/drivers/media/dvb/frontends/dvb-pll.h @@ -43,7 +43,7 @@ static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, unsigned int pll_desc_id) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif diff --git a/linux/drivers/media/dvb/frontends/isl6405.h b/linux/drivers/media/dvb/frontends/isl6405.h index 9d4001a22..1c793d375 100644 --- a/linux/drivers/media/dvb/frontends/isl6405.h +++ b/linux/drivers/media/dvb/frontends/isl6405.h @@ -66,7 +66,7 @@ static inline struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, u8 override_set, u8 override_clear) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif /* CONFIG_DVB_ISL6405 */ diff --git a/linux/drivers/media/dvb/frontends/isl6421.h b/linux/drivers/media/dvb/frontends/isl6421.h index ea7f78a7d..47e4518a0 100644 --- a/linux/drivers/media/dvb/frontends/isl6421.h +++ b/linux/drivers/media/dvb/frontends/isl6421.h @@ -47,7 +47,7 @@ extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_a static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, u8 override_set, u8 override_clear) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_ISL6421 diff --git a/linux/drivers/media/dvb/frontends/itd1000.c b/linux/drivers/media/dvb/frontends/itd1000.c new file mode 100644 index 000000000..abcd0ddae --- /dev/null +++ b/linux/drivers/media/dvb/frontends/itd1000.c @@ -0,0 +1,408 @@ +/* + * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite" + * + * Copyright (c) 2007-8 Patrick Boettcher <pb@linuxtv.org> + * + * 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.= + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/delay.h> +#include <linux/dvb/frontend.h> +#include <linux/i2c.h> + +#include "dvb_frontend.h" + +#include "itd1000.h" +#include "itd1000_priv.h" + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); + +#define deb(args...) do { \ + if (debug) { \ + printk(KERN_DEBUG "ITD1000: " args);\ + printk("\n"); \ + } \ +} while (0) + +#define warn(args...) do { \ + printk(KERN_WARNING "ITD1000: " args); \ + printk("\n"); \ +} while (0) + +#define info(args...) do { \ + printk(KERN_INFO "ITD1000: " args); \ + printk("\n"); \ +} while (0) + +/* don't write more than one byte with flexcop behind */ +static int itd1000_write_regs(struct itd1000_state *state, u8 reg, u8 v[], u8 len) +{ + u8 buf[1+len]; + struct i2c_msg msg = { + .addr = state->cfg->i2c_address, .flags = 0, .buf = buf, .len = len+1 + }; + buf[0] = reg; + memcpy(&buf[1], v, len); + + /* deb("wr %02x: %02x", reg, v[0]); */ + + if (i2c_transfer(state->i2c, &msg, 1) != 1) { + printk(KERN_WARNING "itd1000 I2C write failed\n"); + return -EREMOTEIO; + } + return 0; +} + +static int itd1000_read_reg(struct itd1000_state *state, u8 reg) +{ + u8 val; + struct i2c_msg msg[2] = { + { .addr = state->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, + { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = &val, .len = 1 }, + }; + + /* ugly flexcop workaround */ + itd1000_write_regs(state, (reg - 1) & 0xff, &state->shadow[(reg - 1) & 0xff], 1); + + if (i2c_transfer(state->i2c, msg, 2) != 2) { + warn("itd1000 I2C read failed"); + return -EREMOTEIO; + } + return val; +} + +static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v) +{ + int ret = itd1000_write_regs(state, r, &v, 1); + state->shadow[r] = v; + return ret; +} + +#if 0 +static void reg_dump(struct itd1000_state *state) +{ + int i; + for (i = 0x65; i < 0x9c; i++) + printk(KERN_DEBUG "ITD: %02x: %02x\n", i, itd1000_read_reg(state, i)); +} +#endif + +static struct { + u32 symbol_rate; + u8 pgaext : 4; /* PLLFH */ + u8 bbgvmin : 4; /* BBGVMIN */ +} itd1000_lpf_pga[] = { + { 0, 0x8, 0x3 }, + { 5200000, 0x8, 0x3 }, + { 12200000, 0x4, 0x3 }, + { 15400000, 0x2, 0x3 }, + { 19800000, 0x2, 0x3 }, + { 21500000, 0x2, 0x3 }, + { 24500000, 0x2, 0x3 }, + { 28400000, 0x2, 0x3 }, + { 33400000, 0x2, 0x3 }, + { 34400000, 0x1, 0x4 }, + { 34400000, 0x1, 0x4 }, + { 38400000, 0x1, 0x4 }, + { 38400000, 0x1, 0x4 }, + { 40400000, 0x1, 0x4 }, + { 45400000, 0x1, 0x4 }, +}; + +static void itd1000_set_lpf_bw(struct itd1000_state *state, u32 symbol_rate) +{ + u8 i; + u8 con1 = itd1000_read_reg(state, CON1) & 0xfd; + u8 pllfh = itd1000_read_reg(state, PLLFH) & 0x0f; + u8 bbgvmin = itd1000_read_reg(state, BBGVMIN) & 0xf0; + u8 bw = itd1000_read_reg(state, BW) & 0xf0; + + deb("symbol_rate = %d", symbol_rate); + + /* not sure what is that ? - starting to download the table */ + itd1000_write_reg(state, CON1, con1 | (1 << 1)); + + for (i = 0; i < ARRAY_SIZE(itd1000_lpf_pga); i++) + if (symbol_rate < itd1000_lpf_pga[i].symbol_rate) { + deb("symrate: index: %d pgaext: %x, bbgvmin: %x", i, itd1000_lpf_pga[i].pgaext, itd1000_lpf_pga[i].bbgvmin); + itd1000_write_reg(state, PLLFH, pllfh | (itd1000_lpf_pga[i].pgaext << 4)); + itd1000_write_reg(state, BBGVMIN, bbgvmin | (itd1000_lpf_pga[i].bbgvmin)); + itd1000_write_reg(state, BW, bw | (i & 0x0f)); + break; + } + + itd1000_write_reg(state, CON1, con1 | (0 << 1)); +} + +static struct { + u8 vcorg; + u32 fmax_rg; +} itd1000_vcorg[] = { + { 1, 920000 }, + { 2, 971000 }, + { 3, 1031000 }, + { 4, 1091000 }, + { 5, 1171000 }, + { 6, 1281000 }, + { 7, 1381000 }, + { 8, 500000 }, /* this is intentional. */ + { 9, 1451000 }, + { 10, 1531000 }, + { 11, 1631000 }, + { 12, 1741000 }, + { 13, 1891000 }, + { 14, 2071000 }, + { 15, 2250000 }, +}; + +static void itd1000_set_vco(struct itd1000_state *state, u32 freq_khz) +{ + u8 i; + u8 gvbb_i2c = itd1000_read_reg(state, GVBB_I2C) & 0xbf; + u8 vco_chp1_i2c = itd1000_read_reg(state, VCO_CHP1_I2C) & 0x0f; + u8 adcout; + + /* reserved bit again (reset ?) */ + itd1000_write_reg(state, GVBB_I2C, gvbb_i2c | (1 << 6)); + + for (i = 0; i < ARRAY_SIZE(itd1000_vcorg); i++) { + if (freq_khz < itd1000_vcorg[i].fmax_rg) { + itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | (itd1000_vcorg[i].vcorg << 4)); + msleep(1); + + adcout = itd1000_read_reg(state, PLLLOCK) & 0x0f; + + deb("VCO: %dkHz: %d -> ADCOUT: %d %02x", freq_khz, itd1000_vcorg[i].vcorg, adcout, vco_chp1_i2c); + + if (adcout > 13) { + if (!(itd1000_vcorg[i].vcorg == 7 || itd1000_vcorg[i].vcorg == 15)) + itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg + 1) << 4)); + } else if (adcout < 2) { + if (!(itd1000_vcorg[i].vcorg == 1 || itd1000_vcorg[i].vcorg == 9)) + itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg - 1) << 4)); + } + break; + } + } +} + +struct { + u32 freq; + u8 values[10]; /* RFTR, RFST1 - RFST9 */ +} itd1000_fre_values[] = { + { 1075000, { 0x59, 0x1d, 0x1c, 0x17, 0x16, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, + { 1250000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, + { 1450000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, + { 1650000, { 0x69, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, + { 1750000, { 0x69, 0x1e, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, + { 1850000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } }, + { 1900000, { 0x69, 0x1d, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } }, + { 1950000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0d, 0x0b, 0x0a } }, + { 2050000, { 0x69, 0x1e, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0b, 0x0a } }, + { 2150000, { 0x69, 0x1d, 0x1c, 0x17, 0x15, 0x14, 0x13, 0x0f, 0x0e, 0x0b } } +}; + + +#define FREF 16 + +static void itd1000_set_lo(struct itd1000_state *state, u32 freq_khz) +{ + int i, j; + u32 plln, pllf; + u64 tmp; + + plln = (freq_khz * 1000) / 2 / FREF; + + /* Compute the factional part times 1000 */ + tmp = plln % 1000000; + plln /= 1000000; + + tmp *= 1048576; + do_div(tmp, 1000000); + pllf = (u32) tmp; + + state->frequency = ((plln * 1000) + (pllf * 1000)/1048576) * 2*FREF; + deb("frequency: %dkHz (wanted) %dkHz (set), PLLF = %d, PLLN = %d", freq_khz, state->frequency, pllf, plln); + + itd1000_write_reg(state, PLLNH, 0x80); /* PLLNH */; + itd1000_write_reg(state, PLLNL, plln & 0xff); + itd1000_write_reg(state, PLLFH, (itd1000_read_reg(state, PLLFH) & 0xf0) | ((pllf >> 16) & 0x0f)); + itd1000_write_reg(state, PLLFM, (pllf >> 8) & 0xff); + itd1000_write_reg(state, PLLFL, (pllf >> 0) & 0xff); + + for (i = 0; i < ARRAY_SIZE(itd1000_fre_values); i++) { + if (freq_khz <= itd1000_fre_values[i].freq) { + deb("fre_values: %d", i); + itd1000_write_reg(state, RFTR, itd1000_fre_values[i].values[0]); + for (j = 0; j < 9; j++) + itd1000_write_reg(state, RFST1+j, itd1000_fre_values[i].values[j+1]); + break; + } + } + + itd1000_set_vco(state, freq_khz); +} + +static int itd1000_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) +{ + struct itd1000_state *state = fe->tuner_priv; + u8 pllcon1; + + itd1000_set_lo(state, p->frequency); + itd1000_set_lpf_bw(state, p->u.qpsk.symbol_rate); + + pllcon1 = itd1000_read_reg(state, PLLCON1) & 0x7f; + itd1000_write_reg(state, PLLCON1, pllcon1 | (1 << 7)); + itd1000_write_reg(state, PLLCON1, pllcon1); + + return 0; +} + +static int itd1000_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct itd1000_state *state = fe->tuner_priv; + *frequency = state->frequency; + return 0; +} + +static int itd1000_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) +{ + return 0; +} + +static u8 itd1000_init_tab[][2] = { + { PLLCON1, 0x65 }, /* Register does not change */ + { PLLNH, 0x80 }, /* Bits [7:6] do not change */ + { RESERVED_0X6D, 0x3b }, + { VCO_CHP2_I2C, 0x12 }, + { 0x72, 0xf9 }, /* No such regsister defined */ + { RESERVED_0X73, 0xff }, + { RESERVED_0X74, 0xb2 }, + { RESERVED_0X75, 0xc7 }, + { EXTGVBBRF, 0xf0 }, + { DIVAGCCK, 0x80 }, + { BBTR, 0xa0 }, + { RESERVED_0X7E, 0x4f }, + { 0x82, 0x88 }, /* No such regsister defined */ + { 0x83, 0x80 }, /* No such regsister defined */ + { 0x84, 0x80 }, /* No such regsister defined */ + { RESERVED_0X85, 0x74 }, + { RESERVED_0X86, 0xff }, + { RESERVED_0X88, 0x02 }, + { RESERVED_0X89, 0x16 }, + { RFST0, 0x1f }, + { RESERVED_0X94, 0x66 }, + { RESERVED_0X95, 0x66 }, + { RESERVED_0X96, 0x77 }, + { RESERVED_0X97, 0x99 }, + { RESERVED_0X98, 0xff }, + { RESERVED_0X99, 0xfc }, + { RESERVED_0X9A, 0xba }, + { RESERVED_0X9B, 0xaa }, +}; + +static u8 itd1000_reinit_tab[][2] = { + { VCO_CHP1_I2C, 0x8a }, + { BW, 0x87 }, + { GVBB_I2C, 0x03 }, + { BBGVMIN, 0x03 }, + { CON1, 0x2e }, +}; + + +static int itd1000_init(struct dvb_frontend *fe) +{ + struct itd1000_state *state = fe->tuner_priv; + int i; + + for (i = 0; i < ARRAY_SIZE(itd1000_init_tab); i++) + itd1000_write_reg(state, itd1000_init_tab[i][0], itd1000_init_tab[i][1]); + + for (i = 0; i < ARRAY_SIZE(itd1000_reinit_tab); i++) + itd1000_write_reg(state, itd1000_reinit_tab[i][0], itd1000_reinit_tab[i][1]); + + return 0; +} + +static int itd1000_sleep(struct dvb_frontend *fe) +{ + return 0; +} + +static int itd1000_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; + return 0; +} + +static const struct dvb_tuner_ops itd1000_tuner_ops = { + .info = { + .name = "Integrant ITD1000", + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_step = 125, /* kHz for QPSK frontends */ + }, + + .release = itd1000_release, + + .init = itd1000_init, + .sleep = itd1000_sleep, + + .set_params = itd1000_set_parameters, + .get_frequency = itd1000_get_frequency, + .get_bandwidth = itd1000_get_bandwidth +}; + + +struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg) +{ + struct itd1000_state *state = NULL; + u8 i = 0; + + state = kzalloc(sizeof(struct itd1000_state), GFP_KERNEL); + if (state == NULL) + return NULL; + + state->cfg = cfg; + state->i2c = i2c; + + i = itd1000_read_reg(state, 0); + if (i != 0) { + kfree(state); + return NULL; + } + info("successfully identified (ID: %d)", i); + + memset(state->shadow, 0xff, sizeof(state->shadow)); + for (i = 0x65; i < 0x9c; i++) + state->shadow[i] = itd1000_read_reg(state, i); + + memcpy(&fe->ops.tuner_ops, &itd1000_tuner_ops, sizeof(struct dvb_tuner_ops)); + + fe->tuner_priv = state; + + return fe; +} +EXPORT_SYMBOL(itd1000_attach); + +MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>"); +MODULE_DESCRIPTION("Integrant ITD1000 driver"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/frontends/itd1000.h b/linux/drivers/media/dvb/frontends/itd1000.h new file mode 100644 index 000000000..5e18df071 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/itd1000.h @@ -0,0 +1,42 @@ +/* + * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite" + * + * Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org> + * + * 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 ITD1000_H +#define ITD1000_H + +struct dvb_frontend; +struct i2c_adapter; + +struct itd1000_config { + u8 i2c_address; +}; + +#if defined(CONFIG_DVB_TUNER_ITD1000) || (defined(CONFIG_DVB_TUNER_ITD1000_MODULE) && defined(MODULE)) +extern struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg); +#else +static inline struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif diff --git a/linux/drivers/media/dvb/frontends/itd1000_priv.h b/linux/drivers/media/dvb/frontends/itd1000_priv.h new file mode 100644 index 000000000..8cdc54e57 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/itd1000_priv.h @@ -0,0 +1,88 @@ +/* + * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite" + * + * Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org> + * + * 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 ITD1000_PRIV_H +#define ITD1000_PRIV_H + +struct itd1000_state { + struct itd1000_config *cfg; + struct i2c_adapter *i2c; + + u32 frequency; /* contains the value resulting from the LO-setting */ + + /* ugly workaround for flexcop's incapable i2c-controller + * FIXME, if possible + */ + u8 shadow[255]; +}; + +enum itd1000_register { + VCO_CHP1 = 0x65, + VCO_CHP2, + PLLCON1, + PLLNH, + PLLNL, + PLLFH, + PLLFM, + PLLFL, + RESERVED_0X6D, + PLLLOCK, + VCO_CHP2_I2C, + VCO_CHP1_I2C, + BW, + RESERVED_0X73 = 0x73, + RESERVED_0X74, + RESERVED_0X75, + GVBB, + GVRF, + GVBB_I2C, + EXTGVBBRF, + DIVAGCCK, + BBTR, + RFTR, + BBGVMIN, + RESERVED_0X7E, + RESERVED_0X85 = 0x85, + RESERVED_0X86, + CON1, + RESERVED_0X88, + RESERVED_0X89, + RFST0, + RFST1, + RFST2, + RFST3, + RFST4, + RFST5, + RFST6, + RFST7, + RFST8, + RFST9, + RESERVED_0X94, + RESERVED_0X95, + RESERVED_0X96, + RESERVED_0X97, + RESERVED_0X98, + RESERVED_0X99, + RESERVED_0X9A, + RESERVED_0X9B, +}; + +#endif diff --git a/linux/drivers/media/dvb/frontends/l64781.c b/linux/drivers/media/dvb/frontends/l64781.c index 443d9045d..e1e70e9e0 100644 --- a/linux/drivers/media/dvb/frontends/l64781.c +++ b/linux/drivers/media/dvb/frontends/l64781.c @@ -57,7 +57,7 @@ static int l64781_writereg (struct l64781_state* state, u8 reg, u8 data) if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) dprintk ("%s: write_reg error (reg == %02x) = %02x!\n", - __FUNCTION__, reg, ret); + __func__, reg, ret); return (ret != 1) ? -1 : 0; } diff --git a/linux/drivers/media/dvb/frontends/l64781.h b/linux/drivers/media/dvb/frontends/l64781.h index cd15f76ff..1305a9e7f 100644 --- a/linux/drivers/media/dvb/frontends/l64781.h +++ b/linux/drivers/media/dvb/frontends/l64781.h @@ -38,7 +38,7 @@ extern struct dvb_frontend* l64781_attach(const struct l64781_config* config, static inline struct dvb_frontend* l64781_attach(const struct l64781_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_L64781 diff --git a/linux/drivers/media/dvb/frontends/lgdt330x.c b/linux/drivers/media/dvb/frontends/lgdt330x.c index 033b5a18d..3a3658238 100644 --- a/linux/drivers/media/dvb/frontends/lgdt330x.c +++ b/linux/drivers/media/dvb/frontends/lgdt330x.c @@ -89,7 +89,7 @@ static int i2c_write_demod_bytes (struct lgdt330x_state* state, for (i=0; i<len-1; i+=2){ if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __FUNCTION__, msg.buf[0], msg.buf[1], err); + printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __func__, msg.buf[0], msg.buf[1], err); if (err < 0) return err; else @@ -118,7 +118,7 @@ static u8 i2c_read_demod_bytes (struct lgdt330x_state* state, int ret; ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) { - printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __FUNCTION__, state->config->demod_address, reg, ret); + printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __func__, state->config->demod_address, reg, ret); } else { ret = 0; } @@ -257,7 +257,7 @@ static int lgdt330x_init(struct dvb_frontend* fe) printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n"); err = -ENODEV; } - dprintk("%s entered as %s\n", __FUNCTION__, chip_name); + dprintk("%s entered as %s\n", __func__, chip_name); if (err < 0) return err; return lgdt330x_SwReset(state); @@ -335,7 +335,7 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, if (state->current_modulation != param->u.vsb.modulation) { switch(param->u.vsb.modulation) { case VSB_8: - dprintk("%s: VSB_8 MODE\n", __FUNCTION__); + dprintk("%s: VSB_8 MODE\n", __func__); /* Select VSB mode */ top_ctrl_cfg[1] = 0x03; @@ -351,7 +351,7 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, break; case QAM_64: - dprintk("%s: QAM_64 MODE\n", __FUNCTION__); + dprintk("%s: QAM_64 MODE\n", __func__); /* Select QAM_64 mode */ top_ctrl_cfg[1] = 0x00; @@ -367,7 +367,7 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, break; case QAM_256: - dprintk("%s: QAM_256 MODE\n", __FUNCTION__); + dprintk("%s: QAM_256 MODE\n", __func__); /* Select QAM_256 mode */ top_ctrl_cfg[1] = 0x01; @@ -382,7 +382,7 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, } break; default: - printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation); + printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __func__, param->u.vsb.modulation); return -1; } /* @@ -432,7 +432,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) /* AGC status register */ i2c_read_demod_bytes(state, AGC_STATUS, buf, 1); - dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]); + dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]); if ((buf[0] & 0x0c) == 0x8){ /* Test signal does not exist flag */ /* as well as the AGC lock flag. */ @@ -446,7 +446,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) */ /* signal status */ i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf)); - dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]); + dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __func__, buf[0], buf[1], buf[2]); #if 0 /* Alternative method to check for a signal */ @@ -468,7 +468,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) /* Carrier Recovery Lock Status Register */ i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1); - dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]); + dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]); switch (state->current_modulation) { case QAM_256: case QAM_64: @@ -481,7 +481,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) *status |= FE_HAS_CARRIER; break; default: - printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__); + printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__); } return 0; @@ -500,7 +500,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status) if (err < 0) return err; - dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]); + dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]); if ((buf[0] & 0x21) == 0x01){ /* Test input signal does not exist flag */ /* as well as the AGC lock flag. */ @@ -509,7 +509,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status) /* Carrier Recovery Lock Status Register */ i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1); - dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]); + dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]); switch (state->current_modulation) { case QAM_256: case QAM_64: @@ -540,7 +540,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status) } break; default: - printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__); + printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__); } return 0; } @@ -614,14 +614,14 @@ static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr) break; default: printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n", - __FUNCTION__); + __func__); return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */ } state->snr = calculate_snr(noise, c); *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */ - dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __FUNCTION__, noise, + dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise, state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16); return 0; @@ -658,14 +658,14 @@ static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr) break; default: printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n", - __FUNCTION__); + __func__); return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */ } state->snr = calculate_snr(noise, c); *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */ - dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __FUNCTION__, noise, + dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise, state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16); return 0; @@ -750,7 +750,7 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, error: kfree(state); - dprintk("%s: ERROR\n",__FUNCTION__); + dprintk("%s: ERROR\n",__func__); return NULL; } diff --git a/linux/drivers/media/dvb/frontends/lgdt330x.h b/linux/drivers/media/dvb/frontends/lgdt330x.h index 995059004..9012504f0 100644 --- a/linux/drivers/media/dvb/frontends/lgdt330x.h +++ b/linux/drivers/media/dvb/frontends/lgdt330x.h @@ -59,7 +59,7 @@ extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config static inline struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_LGDT330X diff --git a/linux/drivers/media/dvb/frontends/lnbp21.h b/linux/drivers/media/dvb/frontends/lnbp21.h index 68906acf7..8fe094bd9 100644 --- a/linux/drivers/media/dvb/frontends/lnbp21.h +++ b/linux/drivers/media/dvb/frontends/lnbp21.h @@ -45,7 +45,7 @@ extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_ad #else static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_LNBP21 diff --git a/linux/drivers/media/dvb/frontends/mt2060.h b/linux/drivers/media/dvb/frontends/mt2060.h index 0a86eab3a..acba0058f 100644 --- a/linux/drivers/media/dvb/frontends/mt2060.h +++ b/linux/drivers/media/dvb/frontends/mt2060.h @@ -35,7 +35,7 @@ extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_a #else static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_TUNER_MT2060 diff --git a/linux/drivers/media/dvb/frontends/mt2131.c b/linux/drivers/media/dvb/frontends/mt2131.c index 47e081c2e..becc409d9 100644 --- a/linux/drivers/media/dvb/frontends/mt2131.c +++ b/linux/drivers/media/dvb/frontends/mt2131.c @@ -111,7 +111,7 @@ static int mt2131_set_params(struct dvb_frontend *fe, priv->bandwidth = 0; freq = params->frequency / 1000; // Hz -> kHz - dprintk(1, "%s() freq=%d\n", __FUNCTION__, freq); + dprintk(1, "%s() freq=%d\n", __func__, freq); f_lo1 = freq + MT2131_IF1 * 1000; f_lo1 = (f_lo1 / 250) * 250; @@ -188,7 +188,7 @@ static int mt2131_set_params(struct dvb_frontend *fe, static int mt2131_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct mt2131_priv *priv = fe->tuner_priv; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); *frequency = priv->frequency; return 0; } @@ -196,7 +196,7 @@ static int mt2131_get_frequency(struct dvb_frontend *fe, u32 *frequency) static int mt2131_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) { struct mt2131_priv *priv = fe->tuner_priv; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); *bandwidth = priv->bandwidth; return 0; } @@ -215,7 +215,7 @@ static int mt2131_get_status(struct dvb_frontend *fe, u32 *status) mt2131_readreg(priv, 0x09, &afc_status); dprintk(1, "%s() - LO Status = 0x%x, AFC Status = 0x%x\n", - __FUNCTION__, lock_status, afc_status); + __func__, lock_status, afc_status); return 0; } @@ -224,7 +224,7 @@ static int mt2131_init(struct dvb_frontend *fe) { struct mt2131_priv *priv = fe->tuner_priv; int ret; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); if ((ret = mt2131_writeregs(priv, mt2131_config1, sizeof(mt2131_config1))) < 0) @@ -244,7 +244,7 @@ static int mt2131_init(struct dvb_frontend *fe) static int mt2131_release(struct dvb_frontend *fe) { - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); kfree(fe->tuner_priv); fe->tuner_priv = NULL; return 0; @@ -274,7 +274,7 @@ struct dvb_frontend * mt2131_attach(struct dvb_frontend *fe, struct mt2131_priv *priv = NULL; u8 id = 0; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); priv = kzalloc(sizeof(struct mt2131_priv), GFP_KERNEL); if (priv == NULL) diff --git a/linux/drivers/media/dvb/frontends/mt2131.h b/linux/drivers/media/dvb/frontends/mt2131.h index 1e4ffe7dc..606d8576b 100644 --- a/linux/drivers/media/dvb/frontends/mt2131.h +++ b/linux/drivers/media/dvb/frontends/mt2131.h @@ -41,7 +41,7 @@ static inline struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe, struct mt2131_config *cfg, u16 if1) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif /* CONFIG_DVB_TUNER_MT2131 */ diff --git a/linux/drivers/media/dvb/frontends/mt2266.h b/linux/drivers/media/dvb/frontends/mt2266.h index f31dd613a..c5113efe3 100644 --- a/linux/drivers/media/dvb/frontends/mt2266.h +++ b/linux/drivers/media/dvb/frontends/mt2266.h @@ -29,7 +29,7 @@ extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_a #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__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_TUNER_MT2266 diff --git a/linux/drivers/media/dvb/frontends/mt312.c b/linux/drivers/media/dvb/frontends/mt312.c index 1638301fb..081ca3398 100644 --- a/linux/drivers/media/dvb/frontends/mt312.c +++ b/linux/drivers/media/dvb/frontends/mt312.c @@ -1,7 +1,8 @@ /* - Driver for Zarlink VP310/MT312 Satellite Channel Decoder + Driver for Zarlink VP310/MT312/ZL10313 Satellite Channel Decoder Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org> + Copyright (C) 2008 Matthias Schwarzott <zzam@gentoo.org> 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 @@ -43,7 +44,8 @@ struct mt312_state { struct dvb_frontend frontend; u8 id; - u8 frequency; + unsigned long xtal; + u8 freq_mult; }; static int debug; @@ -53,12 +55,11 @@ static int debug; printk(KERN_DEBUG "mt312: " args); \ } while (0) -#define MT312_SYS_CLK 90000000UL /* 90 MHz */ -#define MT312_LPOWER_SYS_CLK 60000000UL /* 60 MHz */ #define MT312_PLL_CLK 10000000UL /* 10 MHz */ +#define MT312_PLL_CLK_10_111 10111000UL /* 10.111 MHz */ static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg, - void *buf, const size_t count) + u8 *buf, const size_t count) { int ret; struct i2c_msg msg[2]; @@ -76,7 +77,7 @@ static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg, ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) { - printk(KERN_ERR "%s: ret == %d\n", __FUNCTION__, ret); + printk(KERN_ERR "%s: ret == %d\n", __func__, ret); return -EREMOTEIO; } @@ -84,7 +85,7 @@ static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg, int i; dprintk("R(%d):", reg & 0x7f); for (i = 0; i < count; i++) - printk(" %02x", ((const u8 *) buf)[i]); + printk(" %02x", buf[i]); printk("\n"); } @@ -92,7 +93,7 @@ static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg, } static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg, - const void *src, const size_t count) + const u8 *src, const size_t count) { int ret; u8 buf[count + 1]; @@ -102,7 +103,7 @@ static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg, int i; dprintk("W(%d):", reg & 0x7f); for (i = 0; i < count; i++) - printk(" %02x", ((const u8 *) src)[i]); + printk(" %02x", src[i]); printk("\n"); } @@ -117,7 +118,7 @@ static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg, ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) { - dprintk("%s: ret == %d\n", __FUNCTION__, ret); + dprintk("%s: ret == %d\n", __func__, ret); return -EREMOTEIO; } @@ -209,7 +210,7 @@ static int mt312_get_symbol_rate(struct mt312_state *state, u32 *sr) dprintk("sym_rat_op=%d dec_ratio=%d\n", sym_rat_op, dec_ratio); dprintk("*sr(manual) = %lu\n", - (((MT312_PLL_CLK * 8192) / (sym_rat_op + 8192)) * + (((state->xtal * 8192) / (sym_rat_op + 8192)) * 2) - dec_ratio); } @@ -242,7 +243,7 @@ static int mt312_initfe(struct dvb_frontend *fe) /* wake up */ ret = mt312_writereg(state, CONFIG, - (state->frequency == 60 ? 0x88 : 0x8c)); + (state->freq_mult == 6 ? 0x88 : 0x8c)); if (ret < 0) return ret; @@ -265,12 +266,37 @@ static int mt312_initfe(struct dvb_frontend *fe) return ret; } + switch (state->id) { + case ID_ZL10313: + /* enable ADC */ + ret = mt312_writereg(state, GPP_CTRL, 0x80); + if (ret < 0) + return ret; + + /* configure ZL10313 for optimal ADC performance */ + buf[0] = 0x80; + buf[1] = 0xB0; + ret = mt312_write(state, HW_CTRL, buf, 2); + if (ret < 0) + return ret; + + /* enable MPEG output and ADCs */ + ret = mt312_writereg(state, HW_CTRL, 0x00); + if (ret < 0) + return ret; + + ret = mt312_writereg(state, MPEG_CTRL, 0x00); + if (ret < 0) + return ret; + + break; + } + /* SYS_CLK */ - buf[0] = mt312_div((state->frequency == 60 ? MT312_LPOWER_SYS_CLK : - MT312_SYS_CLK) * 2, 1000000); + buf[0] = mt312_div(state->xtal * state->freq_mult * 2, 1000000); /* DISEQC_RATIO */ - buf[1] = mt312_div(MT312_PLL_CLK, 15000 * 4); + buf[1] = mt312_div(state->xtal, 22000 * 4); ret = mt312_write(state, SYS_CLK, buf, sizeof(buf)); if (ret < 0) @@ -280,7 +306,17 @@ static int mt312_initfe(struct dvb_frontend *fe) if (ret < 0) return ret; - ret = mt312_writereg(state, OP_CTRL, 0x53); + /* different MOCLK polarity */ + switch (state->id) { + case ID_ZL10313: + buf[0] = 0x33; + break; + default: + buf[0] = 0x53; + break; + } + + ret = mt312_writereg(state, OP_CTRL, buf[0]); if (ret < 0) return ret; @@ -323,6 +359,9 @@ static int mt312_send_master_cmd(struct dvb_frontend *fe, if (ret < 0) return ret; + /* is there a better way to wait for message to be transmitted */ + msleep(100); + /* set DISEQC_MODE[2:0] to zero if a return message is expected */ if (c->msg[0] & 0x02) { ret = mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40)); @@ -383,11 +422,16 @@ static int mt312_set_voltage(struct dvb_frontend *fe, const fe_sec_voltage_t v) { struct mt312_state *state = fe->demodulator_priv; const u8 volt_tab[3] = { 0x00, 0x40, 0x00 }; + u8 val; if (v > SEC_VOLTAGE_OFF) return -EINVAL; - return mt312_writereg(state, DISEQC_MODE, volt_tab[v]); + val = volt_tab[v]; + if (state->config->voltage_inverted) + val ^= 0x40; + + return mt312_writereg(state, DISEQC_MODE, val); } static int mt312_read_status(struct dvb_frontend *fe, fe_status_t *s) @@ -463,7 +507,7 @@ static int mt312_read_snr(struct dvb_frontend *fe, u16 *snr) int ret; u8 buf[2]; - ret = mt312_read(state, M_SNR_H, &buf, sizeof(buf)); + ret = mt312_read(state, M_SNR_H, buf, sizeof(buf)); if (ret < 0) return ret; @@ -478,7 +522,7 @@ static int mt312_read_ucblocks(struct dvb_frontend *fe, u32 *ubc) int ret; u8 buf[2]; - ret = mt312_read(state, RS_UBC_H, &buf, sizeof(buf)); + ret = mt312_read(state, RS_UBC_H, buf, sizeof(buf)); if (ret < 0) return ret; @@ -499,7 +543,7 @@ static int mt312_set_frontend(struct dvb_frontend *fe, { 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f }; const u8 inv_tab[3] = { 0x00, 0x40, 0x80 }; - dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency); + dprintk("%s: Freq %d\n", __func__, p->frequency); if ((p->frequency < fe->ops.info.frequency_min) || (p->frequency > fe->ops.info.frequency_max)) @@ -532,17 +576,17 @@ static int mt312_set_frontend(struct dvb_frontend *fe, return ret; if (p->u.qpsk.symbol_rate >= 30000000) { /* Note that 30MS/s should use 90MHz */ - if ((config_val & 0x0c) == 0x08) { + if (state->freq_mult == 6) { /* We are running 60MHz */ - state->frequency = 90; + state->freq_mult = 9; ret = mt312_initfe(fe); if (ret < 0) return ret; } } else { - if ((config_val & 0x0c) == 0x0C) { + if (state->freq_mult == 9) { /* We are running 90MHz */ - state->frequency = 60; + state->freq_mult = 6; ret = mt312_initfe(fe); if (ret < 0) return ret; @@ -551,6 +595,7 @@ static int mt312_set_frontend(struct dvb_frontend *fe, break; case ID_MT312: + case ID_ZL10313: break; default: @@ -616,11 +661,29 @@ static int mt312_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) { struct mt312_state *state = fe->demodulator_priv; - if (enable) { - return mt312_writereg(state, GPP_CTRL, 0x40); - } else { - return mt312_writereg(state, GPP_CTRL, 0x00); + u8 val = 0x00; + int ret; + + switch (state->id) { + case ID_ZL10313: + ret = mt312_readreg(state, GPP_CTRL, &val); + if (ret < 0) + goto error; + + /* preserve this bit to not accidently shutdown ADC */ + val &= 0x80; + break; } + + if (enable) + val |= 0x40; + else + val &= ~0x40; + + ret = mt312_writereg(state, GPP_CTRL, val); + +error: + return ret; } static int mt312_sleep(struct dvb_frontend *fe) @@ -634,6 +697,18 @@ static int mt312_sleep(struct dvb_frontend *fe) if (ret < 0) return ret; + if (state->id == ID_ZL10313) { + /* reset ADC */ + ret = mt312_writereg(state, GPP_CTRL, 0x00); + if (ret < 0) + return ret; + + /* full shutdown of ADCs, mpeg bus tristated */ + ret = mt312_writereg(state, HW_CTRL, 0x0d); + if (ret < 0) + return ret; + } + ret = mt312_readreg(state, CONFIG, &config); if (ret < 0) return ret; @@ -661,6 +736,7 @@ static void mt312_release(struct dvb_frontend *fe) kfree(state); } +#define MT312_SYS_CLK 90000000UL /* 90 MHz */ static struct dvb_frontend_ops vp310_mt312_ops = { .info = { @@ -668,8 +744,8 @@ static struct dvb_frontend_ops vp310_mt312_ops = { .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, - .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128, - .symbol_rate_min = MT312_SYS_CLK / 128, + .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128, /* FIXME: adjust freq to real used xtal */ + .symbol_rate_min = MT312_SYS_CLK / 128, /* FIXME as above */ .symbol_rate_max = MT312_SYS_CLK / 2, .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | @@ -726,14 +802,21 @@ struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config, switch (state->id) { case ID_VP310: strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S"); - state->frequency = 90; + state->xtal = MT312_PLL_CLK; + state->freq_mult = 9; break; case ID_MT312: strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S"); - state->frequency = 60; + state->xtal = MT312_PLL_CLK; + state->freq_mult = 6; + break; + case ID_ZL10313: + strcpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S"); + state->xtal = MT312_PLL_CLK_10_111; + state->freq_mult = 9; break; default: - printk(KERN_WARNING "Only Zarlink VP310/MT312" + printk(KERN_WARNING "Only Zarlink VP310/MT312/ZL10313" " are supported chips.\n"); goto error; } @@ -749,7 +832,7 @@ EXPORT_SYMBOL(vp310_mt312_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); -MODULE_DESCRIPTION("Zarlink VP310/MT312 DVB-S Demodulator driver"); +MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver"); MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>"); MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/frontends/mt312.h b/linux/drivers/media/dvb/frontends/mt312.h index f17cb93ba..96338f0c4 100644 --- a/linux/drivers/media/dvb/frontends/mt312.h +++ b/linux/drivers/media/dvb/frontends/mt312.h @@ -31,6 +31,9 @@ struct mt312_config { /* the demodulator's i2c address */ u8 demod_address; + + /* inverted voltage setting */ + int voltage_inverted:1; }; #if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE)) @@ -40,7 +43,7 @@ struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config, static inline struct dvb_frontend *vp310_mt312_attach( const struct mt312_config *config, struct i2c_adapter *i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif /* CONFIG_DVB_MT312 */ diff --git a/linux/drivers/media/dvb/frontends/mt312_priv.h b/linux/drivers/media/dvb/frontends/mt312_priv.h index 5e0b95b53..a3959f94d 100644 --- a/linux/drivers/media/dvb/frontends/mt312_priv.h +++ b/linux/drivers/media/dvb/frontends/mt312_priv.h @@ -110,6 +110,8 @@ enum mt312_reg_addr { VIT_ERRPER_H = 83, VIT_ERRPER_M = 84, VIT_ERRPER_L = 85, + HW_CTRL = 84, /* ZL10313 only */ + MPEG_CTRL = 85, /* ZL10313 only */ VIT_SETUP = 86, VIT_REF0 = 87, VIT_REF1 = 88, @@ -156,7 +158,8 @@ enum mt312_reg_addr { enum mt312_model_id { ID_VP310 = 1, - ID_MT312 = 3 + ID_MT312 = 3, + ID_ZL10313 = 5, }; #endif /* DVB_FRONTENDS_MT312_PRIV */ diff --git a/linux/drivers/media/dvb/frontends/mt352.c b/linux/drivers/media/dvb/frontends/mt352.c index f9eb120c0..0bc03d9c7 100644 --- a/linux/drivers/media/dvb/frontends/mt352.c +++ b/linux/drivers/media/dvb/frontends/mt352.c @@ -96,7 +96,7 @@ static int mt352_read_register(struct mt352_state* state, u8 reg) if (ret != 2) { printk("%s: readreg error (reg=%d, ret==%i)\n", - __FUNCTION__, reg, ret); + __func__, reg, ret); return ret; } @@ -136,7 +136,7 @@ static void mt352_calc_nominal_rate(struct mt352_state* state, value = 64 * bw * (1<<16) / (7 * 8); value = value * 1000 / adc_clock; dprintk("%s: bw %d, adc_clock %d => 0x%x\n", - __FUNCTION__, bw, adc_clock, value); + __func__, bw, adc_clock, value); buf[0] = msb(value); buf[1] = lsb(value); } @@ -162,7 +162,7 @@ static void mt352_calc_input_freq(struct mt352_state* state, } value = -16374 * ife / adc_clock; dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n", - __FUNCTION__, if2, ife, adc_clock, value, value & 0x3fff); + __func__, if2, ife, adc_clock, value, value & 0x3fff); buf[0] = msb(value); buf[1] = lsb(value); } @@ -522,7 +522,7 @@ static int mt352_init(struct dvb_frontend* fe) static u8 mt352_reset_attach [] = { RESET, 0xC0 }; - dprintk("%s: hello\n",__FUNCTION__); + dprintk("%s: hello\n",__func__); if ((mt352_read_register(state, CLOCK_CTL) & 0x10) == 0 || (mt352_read_register(state, CONFIG) & 0x20) == 0) { diff --git a/linux/drivers/media/dvb/frontends/mt352.h b/linux/drivers/media/dvb/frontends/mt352.h index e9964081f..595092f9f 100644 --- a/linux/drivers/media/dvb/frontends/mt352.h +++ b/linux/drivers/media/dvb/frontends/mt352.h @@ -58,7 +58,7 @@ extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, static inline struct dvb_frontend* mt352_attach(const struct mt352_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_MT352 diff --git a/linux/drivers/media/dvb/frontends/nxt200x.c b/linux/drivers/media/dvb/frontends/nxt200x.c index 8808d781f..9172843dd 100644 --- a/linux/drivers/media/dvb/frontends/nxt200x.c +++ b/linux/drivers/media/dvb/frontends/nxt200x.c @@ -75,7 +75,7 @@ static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n", - __FUNCTION__, addr, err); + __func__, addr, err); return -EREMOTEIO; } return 0; @@ -88,7 +88,7 @@ static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len) if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n", - __FUNCTION__, addr, err); + __func__, addr, err); return -EREMOTEIO; } return 0; @@ -105,7 +105,7 @@ static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, u8 *buf, u8 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n", - __FUNCTION__, state->config->demod_address, err); + __func__, state->config->demod_address, err); return -EREMOTEIO; } return 0; @@ -122,7 +122,7 @@ static u8 nxt200x_readbytes (struct nxt200x_state* state, u8 reg, u8* buf, u8 le if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) { printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n", - __FUNCTION__, state->config->demod_address, err); + __func__, state->config->demod_address, err); return -EREMOTEIO; } return 0; @@ -147,7 +147,7 @@ static u16 nxt200x_crc(u16 crc, u8 c) static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len) { u8 attr, len2, buf; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* set mutli register register */ nxt200x_writebytes(state, 0x35, ®, 1); @@ -208,7 +208,7 @@ static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* d { int i; u8 buf, len2, attr; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* set mutli register register */ nxt200x_writebytes(state, 0x35, ®, 1); @@ -255,7 +255,7 @@ static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* d static void nxt200x_microcontroller_stop (struct nxt200x_state* state) { u8 buf, stopval, counter = 0; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* set correct stop value */ switch (state->demod_chip) { @@ -288,7 +288,7 @@ static void nxt200x_microcontroller_stop (struct nxt200x_state* state) static void nxt200x_microcontroller_start (struct nxt200x_state* state) { u8 buf; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); buf = 0x00; nxt200x_writebytes(state, 0x22, &buf, 1); @@ -298,7 +298,7 @@ static void nxt2004_microcontroller_init (struct nxt200x_state* state) { u8 buf[9]; u8 counter = 0; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); buf[0] = 0x00; nxt200x_writebytes(state, 0x2b, buf, 1); @@ -329,7 +329,7 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data) { u8 buf, count = 0; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[1], data[2], data[3], data[4]); @@ -388,7 +388,7 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data) static void nxt200x_agc_reset(struct nxt200x_state* state) { u8 buf; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); switch (state->demod_chip) { case NXT2002: @@ -417,7 +417,7 @@ static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware u8 buf[3], written = 0, chunkpos = 0; u16 rambase, position, crc = 0; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); dprintk("Firmware is %zu bytes\n", fw->size); /* Get the RAM base for this nxt2002 */ @@ -484,7 +484,7 @@ static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware u8 buf[3]; u16 rambase, position, crc=0; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); dprintk("Firmware is %zu bytes\n", fw->size); /* set rambase */ diff --git a/linux/drivers/media/dvb/frontends/nxt200x.h b/linux/drivers/media/dvb/frontends/nxt200x.h index bb0ef58d7..f3c845837 100644 --- a/linux/drivers/media/dvb/frontends/nxt200x.h +++ b/linux/drivers/media/dvb/frontends/nxt200x.h @@ -49,7 +49,7 @@ extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, static inline struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_NXT200X diff --git a/linux/drivers/media/dvb/frontends/nxt6000.h b/linux/drivers/media/dvb/frontends/nxt6000.h index 13d225183..878eb38a0 100644 --- a/linux/drivers/media/dvb/frontends/nxt6000.h +++ b/linux/drivers/media/dvb/frontends/nxt6000.h @@ -40,7 +40,7 @@ extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, static inline struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_NXT6000 diff --git a/linux/drivers/media/dvb/frontends/or51132.c b/linux/drivers/media/dvb/frontends/or51132.c index 1d2d28ce8..8a64cb43e 100644 --- a/linux/drivers/media/dvb/frontends/or51132.c +++ b/linux/drivers/media/dvb/frontends/or51132.c @@ -419,7 +419,7 @@ static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) *status = 0; return -EREMOTEIO; } - dprintk("%s: read_status %04x\n", __FUNCTION__, reg); + dprintk("%s: read_status %04x\n", __func__, reg); if (reg & 0x0100) /* Receiver Lock */ *status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI| @@ -504,14 +504,14 @@ start: if (retry--) goto start; return -EREMOTEIO; } - dprintk("%s: modulation %02x, NTSC rej O%s\n", __FUNCTION__, + dprintk("%s: modulation %02x, NTSC rej O%s\n", __func__, reg&0xff, reg&0x1000?"n":"ff"); /* Calculate SNR using noise, c, and NTSC rejection correction */ state->snr = calculate_snr(noise, c) - usK; *snr = (state->snr) >> 16; - dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __FUNCTION__, noise, + dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise, state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16); return 0; diff --git a/linux/drivers/media/dvb/frontends/or51132.h b/linux/drivers/media/dvb/frontends/or51132.h index add24f0a7..1b8e04d97 100644 --- a/linux/drivers/media/dvb/frontends/or51132.h +++ b/linux/drivers/media/dvb/frontends/or51132.h @@ -41,7 +41,7 @@ extern struct dvb_frontend* or51132_attach(const struct or51132_config* config, static inline struct dvb_frontend* or51132_attach(const struct or51132_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_OR51132 diff --git a/linux/drivers/media/dvb/frontends/or51211.c b/linux/drivers/media/dvb/frontends/or51211.c index 6a6b0d727..7eaa47655 100644 --- a/linux/drivers/media/dvb/frontends/or51211.c +++ b/linux/drivers/media/dvb/frontends/or51211.c @@ -307,19 +307,19 @@ static int or51211_read_snr(struct dvb_frontend* fe, u16* snr) if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) { printk(KERN_WARNING "%s: error writing snr reg\n", - __FUNCTION__); + __func__); return -1; } if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { printk(KERN_WARNING "%s: read_status read error\n", - __FUNCTION__); + __func__); return -1; } state->snr = calculate_snr(rec_buf[0], 89599047); *snr = (state->snr) >> 16; - dprintk("%s: noise = 0x%02x, snr = %d.%02d dB\n", __FUNCTION__, rec_buf[0], + dprintk("%s: noise = 0x%02x, snr = %d.%02d dB\n", __func__, rec_buf[0], state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16); return 0; diff --git a/linux/drivers/media/dvb/frontends/or51211.h b/linux/drivers/media/dvb/frontends/or51211.h index 8aad8402d..3ce0508b8 100644 --- a/linux/drivers/media/dvb/frontends/or51211.h +++ b/linux/drivers/media/dvb/frontends/or51211.h @@ -44,7 +44,7 @@ extern struct dvb_frontend* or51211_attach(const struct or51211_config* config, static inline struct dvb_frontend* or51211_attach(const struct or51211_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_OR51211 diff --git a/linux/drivers/media/dvb/frontends/qt1010.h b/linux/drivers/media/dvb/frontends/qt1010.h index 3ab4aa045..cff6a7ca5 100644 --- a/linux/drivers/media/dvb/frontends/qt1010.h +++ b/linux/drivers/media/dvb/frontends/qt1010.h @@ -45,7 +45,7 @@ static inline struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct qt1010_config *cfg) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_TUNER_QT1010 diff --git a/linux/drivers/media/dvb/frontends/s5h1409.c b/linux/drivers/media/dvb/frontends/s5h1409.c index 1ca250378..b999ec424 100644 --- a/linux/drivers/media/dvb/frontends/s5h1409.c +++ b/linux/drivers/media/dvb/frontends/s5h1409.c @@ -312,7 +312,7 @@ static int s5h1409_writereg(struct s5h1409_state* state, u8 reg, u16 data) if (ret != 1) printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " - "ret == %i)\n", __FUNCTION__, reg, data, ret); + "ret == %i)\n", __func__, reg, data, ret); return (ret != 1) ? -1 : 0; } @@ -332,7 +332,7 @@ static u16 s5h1409_readreg(struct s5h1409_state* state, u8 reg) ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) - printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); + printk("%s: readreg error (ret == %i)\n", __func__, ret); return (b1[0] << 8) | b1[1]; } @@ -340,7 +340,7 @@ static int s5h1409_softreset(struct dvb_frontend* fe) { struct s5h1409_state* state = fe->demodulator_priv; - dprintk("%s()\n", __FUNCTION__); + dprintk("%s()\n", __func__); s5h1409_writereg(state, 0xf5, 0); s5h1409_writereg(state, 0xf5, 1); @@ -356,7 +356,7 @@ static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz) { struct s5h1409_state* state = fe->demodulator_priv; - dprintk("%s(%d KHz)\n", __FUNCTION__, KHz); + dprintk("%s(%d KHz)\n", __func__, KHz); switch (KHz) { case 4000: @@ -381,7 +381,7 @@ static int s5h1409_set_spectralinversion(struct dvb_frontend* fe, int inverted) { struct s5h1409_state* state = fe->demodulator_priv; - dprintk("%s(%d)\n", __FUNCTION__, inverted); + dprintk("%s(%d)\n", __func__, inverted); if(inverted == 1) return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */ @@ -394,25 +394,25 @@ static int s5h1409_enable_modulation(struct dvb_frontend* fe, { struct s5h1409_state* state = fe->demodulator_priv; - dprintk("%s(0x%08x)\n", __FUNCTION__, m); + dprintk("%s(0x%08x)\n", __func__, m); switch(m) { case VSB_8: - dprintk("%s() VSB_8\n", __FUNCTION__); + dprintk("%s() VSB_8\n", __func__); if (state->if_freq != S5H1409_VSB_IF_FREQ) s5h1409_set_if_freq(fe, S5H1409_VSB_IF_FREQ); s5h1409_writereg(state, 0xf4, 0); break; case QAM_64: case QAM_256: - dprintk("%s() QAM_AUTO (64/256)\n", __FUNCTION__); + dprintk("%s() QAM_AUTO (64/256)\n", __func__); if (state->if_freq != S5H1409_QAM_IF_FREQ) s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ); s5h1409_writereg(state, 0xf4, 1); s5h1409_writereg(state, 0x85, 0x110); break; default: - dprintk("%s() Invalid modulation\n", __FUNCTION__); + dprintk("%s() Invalid modulation\n", __func__); return -EINVAL; } @@ -426,7 +426,7 @@ static int s5h1409_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) { struct s5h1409_state* state = fe->demodulator_priv; - dprintk("%s(%d)\n", __FUNCTION__, enable); + dprintk("%s(%d)\n", __func__, enable); if (enable) return s5h1409_writereg(state, 0xf3, 1); @@ -438,7 +438,7 @@ static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable) { struct s5h1409_state* state = fe->demodulator_priv; - dprintk("%s(%d)\n", __FUNCTION__, enable); + dprintk("%s(%d)\n", __func__, enable); if (enable) return s5h1409_writereg(state, 0xe3, @@ -452,7 +452,7 @@ static int s5h1409_sleep(struct dvb_frontend* fe, int enable) { struct s5h1409_state* state = fe->demodulator_priv; - dprintk("%s(%d)\n", __FUNCTION__, enable); + dprintk("%s(%d)\n", __func__, enable); return s5h1409_writereg(state, 0xf2, enable); } @@ -461,7 +461,7 @@ static int s5h1409_register_reset(struct dvb_frontend* fe) { struct s5h1409_state* state = fe->demodulator_priv; - dprintk("%s()\n", __FUNCTION__); + dprintk("%s()\n", __func__); return s5h1409_writereg(state, 0xfa, 0); } @@ -534,7 +534,7 @@ static int s5h1409_set_frontend (struct dvb_frontend* fe, { struct s5h1409_state* state = fe->demodulator_priv; - dprintk("%s(frequency=%d)\n", __FUNCTION__, p->frequency); + dprintk("%s(frequency=%d)\n", __func__, p->frequency); s5h1409_softreset(fe); @@ -565,7 +565,7 @@ static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode) struct s5h1409_state *state = fe->demodulator_priv; u16 val; - dprintk("%s(%d)\n", __FUNCTION__, mode); + dprintk("%s(%d)\n", __func__, mode); val = s5h1409_readreg(state, 0xac) & 0xcfff; switch (mode) { @@ -573,7 +573,7 @@ static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode) val |= 0x0000; break; case S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK: - dprintk("%s(%d) Mode1 or Defaulting\n", __FUNCTION__, mode); + dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode); val |= 0x1000; break; case S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK: @@ -597,7 +597,7 @@ static int s5h1409_init (struct dvb_frontend* fe) int i; struct s5h1409_state* state = fe->demodulator_priv; - dprintk("%s()\n", __FUNCTION__); + dprintk("%s()\n", __func__); s5h1409_sleep(fe, 0); s5h1409_register_reset(fe); @@ -663,7 +663,7 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status) break; } - dprintk("%s() status 0x%08x\n", __FUNCTION__, *status); + dprintk("%s() status 0x%08x\n", __func__, *status); return 0; } @@ -671,7 +671,7 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status) static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) { int i, ret = -EINVAL; - dprintk("%s()\n", __FUNCTION__); + dprintk("%s()\n", __func__); for (i=0; i < ARRAY_SIZE(qam256_snr_tab); i++) { if (v < qam256_snr_tab[i].val) { @@ -686,7 +686,7 @@ static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) { int i, ret = -EINVAL; - dprintk("%s()\n", __FUNCTION__); + dprintk("%s()\n", __func__); for (i=0; i < ARRAY_SIZE(qam64_snr_tab); i++) { if (v < qam64_snr_tab[i].val) { @@ -701,7 +701,7 @@ static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) { int i, ret = -EINVAL; - dprintk("%s()\n", __FUNCTION__); + dprintk("%s()\n", __func__); for (i=0; i < ARRAY_SIZE(vsb_snr_tab); i++) { if (v > vsb_snr_tab[i].val) { @@ -710,7 +710,7 @@ static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v) break; } } - dprintk("%s() snr=%d\n", __FUNCTION__, *snr); + dprintk("%s() snr=%d\n", __func__, *snr); return ret; } @@ -718,7 +718,7 @@ static int s5h1409_read_snr(struct dvb_frontend* fe, u16* snr) { struct s5h1409_state* state = fe->demodulator_priv; u16 reg; - dprintk("%s()\n", __FUNCTION__); + dprintk("%s()\n", __func__); switch(state->current_modulation) { case QAM_64: @@ -812,7 +812,7 @@ struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config, if (s5h1409_init(&state->frontend) != 0) { printk(KERN_ERR "%s: Failed to initialize correctly\n", - __FUNCTION__); + __func__); goto error; } diff --git a/linux/drivers/media/dvb/frontends/s5h1409.h b/linux/drivers/media/dvb/frontends/s5h1409.h index f0bb13fe8..59f433596 100644 --- a/linux/drivers/media/dvb/frontends/s5h1409.h +++ b/linux/drivers/media/dvb/frontends/s5h1409.h @@ -67,7 +67,7 @@ extern struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config, static inline struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif /* CONFIG_DVB_S5H1409 */ diff --git a/linux/drivers/media/dvb/frontends/s5h1420.c b/linux/drivers/media/dvb/frontends/s5h1420.c index 7c64af91e..4f4f8f918 100644 --- a/linux/drivers/media/dvb/frontends/s5h1420.c +++ b/linux/drivers/media/dvb/frontends/s5h1420.c @@ -1,24 +1,26 @@ /* -Driver for Samsung S5H1420 QPSK Demodulator - -Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> - -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. - -*/ + * Driver for + * Samsung S5H1420 and + * PnpNetwork PN1010 QPSK Demodulator + * + * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> + * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org> + * + * 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. + */ #include <linux/kernel.h> #include <linux/module.h> @@ -29,23 +31,35 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include <linux/jiffies.h> #include <asm/div64.h> -#include "dvb_frontend.h" -#include "s5h1420.h" +#include <linux/i2c.h> +#include "dvb_frontend.h" +#include "s5h1420.h" +#include "s5h1420_priv.h" #define TONE_FREQ 22000 struct s5h1420_state { struct i2c_adapter* i2c; const struct s5h1420_config* config; + struct dvb_frontend frontend; + struct i2c_adapter tuner_i2c_adapter; + + u8 CON_1_val; u8 postlocked:1; u32 fclk; u32 tunedfreq; fe_code_rate_t fec_inner; u32 symbol_rate; + + /* FIXME: ugly workaround for flexcop's incapable i2c-controller + * it does not support repeated-start, workaround: write addr-1 + * and then read + */ + u8 shadow[255]; }; static u32 s5h1420_getsymbolrate(struct s5h1420_state* state); @@ -54,43 +68,65 @@ static int s5h1420_get_tune_settings(struct dvb_frontend* fe, static int debug; -#define dprintk if (debug) printk +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "enable debugging"); + +#define dprintk(x...) do { \ + if (debug) \ + printk(KERN_DEBUG "S5H1420: " x); \ +} while (0) + +static u8 s5h1420_readreg(struct s5h1420_state *state, u8 reg) +{ + int ret; + u8 b[2]; + struct i2c_msg msg[] = { + { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = 2 }, + { .addr = state->config->demod_address, .flags = 0, .buf = ®, .len = 1 }, + { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = 1 }, + }; + + b[0] = (reg - 1) & 0xff; + b[1] = state->shadow[(reg - 1) & 0xff]; + + if (state->config->repeated_start_workaround) { + ret = i2c_transfer(state->i2c, msg, 3); + if (ret != 3) + return ret; + } else { + ret = i2c_transfer(state->i2c, &msg[1], 2); + if (ret != 2) + return ret; + } + + /* dprintk("rd(%02x): %02x %02x\n", state->config->demod_address, reg, b[0]); */ + + return b[0]; +} static int s5h1420_writereg (struct s5h1420_state* state, u8 reg, u8 data) { - u8 buf [] = { reg, data }; + u8 buf[] = { reg, data }; struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; int err; - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data); + /* dprintk("wr(%02x): %02x %02x\n", state->config->demod_address, reg, data); */ + err = i2c_transfer(state->i2c, &msg, 1); + if (err != 1) { + dprintk("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data); return -EREMOTEIO; } + state->shadow[reg] = data; return 0; } -static u8 s5h1420_readreg (struct s5h1420_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg1 = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }; - struct i2c_msg msg2 = { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 }; - - if ((ret = i2c_transfer (state->i2c, &msg1, 1)) != 1) - return ret; - - if ((ret = i2c_transfer (state->i2c, &msg2, 1)) != 1) - return ret; - - return b1[0]; -} - static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) { struct s5h1420_state* state = fe->demodulator_priv; + dprintk("enter %s\n", __func__); + switch(voltage) { case SEC_VOLTAGE_13: s5h1420_writereg(state, 0x3c, @@ -106,6 +142,7 @@ static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag break; } + dprintk("leave %s\n", __func__); return 0; } @@ -113,6 +150,7 @@ static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) { struct s5h1420_state* state = fe->demodulator_priv; + dprintk("enter %s\n", __func__); switch(tone) { case SEC_TONE_ON: s5h1420_writereg(state, 0x3b, @@ -124,6 +162,7 @@ static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01); break; } + dprintk("leave %s\n", __func__); return 0; } @@ -137,6 +176,7 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, unsigned long timeout; int result = 0; + dprintk("enter %s\n", __func__); if (cmd->msg_len > 8) return -EINVAL; @@ -168,6 +208,7 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, /* restore original settings */ s5h1420_writereg(state, 0x3b, val); msleep(15); + dprintk("leave %s\n", __func__); return result; } @@ -289,6 +330,8 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status) struct s5h1420_state* state = fe->demodulator_priv; u8 val; + dprintk("enter %s\n", __func__); + if (status == NULL) return -EINVAL; @@ -297,13 +340,13 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status) /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert the inversion, wait a bit and check again */ - if (*status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI)) { - val = s5h1420_readreg(state, 0x32); + if (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI)) { + val = s5h1420_readreg(state, Vit10); if ((val & 0x07) == 0x03) { if (val & 0x08) - s5h1420_writereg(state, 0x31, 0x13); + s5h1420_writereg(state, Vit09, 0x13); else - s5h1420_writereg(state, 0x31, 0x1b); + s5h1420_writereg(state, Vit09, 0x1b); /* wait a bit then update lock status */ mdelay(200); @@ -312,68 +355,77 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status) } /* perform post lock setup */ - if ((*status & FE_HAS_LOCK) && (!state->postlocked)) { + if ((*status & FE_HAS_LOCK) && !state->postlocked) { /* calculate the data rate */ u32 tmp = s5h1420_getsymbolrate(state); - switch(s5h1420_readreg(state, 0x32) & 0x07) { - case 0: - tmp = (tmp * 2 * 1) / 2; - break; - - case 1: - tmp = (tmp * 2 * 2) / 3; - break; - - case 2: - tmp = (tmp * 2 * 3) / 4; - break; - - case 3: - tmp = (tmp * 2 * 5) / 6; - break; - - case 4: - tmp = (tmp * 2 * 6) / 7; - break; - - case 5: - tmp = (tmp * 2 * 7) / 8; - break; + switch (s5h1420_readreg(state, Vit10) & 0x07) { + case 0: tmp = (tmp * 2 * 1) / 2; break; + case 1: tmp = (tmp * 2 * 2) / 3; break; + case 2: tmp = (tmp * 2 * 3) / 4; break; + case 3: tmp = (tmp * 2 * 5) / 6; break; + case 4: tmp = (tmp * 2 * 6) / 7; break; + case 5: tmp = (tmp * 2 * 7) / 8; break; } + if (tmp == 0) { - printk("s5h1420: avoided division by 0\n"); + printk(KERN_ERR "s5h1420: avoided division by 0\n"); tmp = 1; } tmp = state->fclk / tmp; + /* set the MPEG_CLK_INTL for the calculated data rate */ - if (tmp < 4) + if (tmp < 2) val = 0x00; - else if (tmp < 8) + else if (tmp < 5) val = 0x01; - else if (tmp < 12) + else if (tmp < 9) val = 0x02; - else if (tmp < 16) + else if (tmp < 13) val = 0x03; - else if (tmp < 24) + else if (tmp < 17) val = 0x04; - else if (tmp < 32) + else if (tmp < 25) val = 0x05; - else + else if (tmp < 33) val = 0x06; - s5h1420_writereg(state, 0x22, val); - - /* DC freeze */ - s5h1420_writereg(state, 0x1f, s5h1420_readreg(state, 0x1f) | 0x01); - - /* kicker disable + remove DC offset */ - s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) & 0x6f); + else + val = 0x07; + dprintk("for MPEG_CLK_INTL %d %x\n", tmp, val); + + s5h1420_writereg(state, FEC01, 0x18); + s5h1420_writereg(state, FEC01, 0x10); + s5h1420_writereg(state, FEC01, val); + + /* Enable "MPEG_Out" */ + val = s5h1420_readreg(state, Mpeg02); + s5h1420_writereg(state, Mpeg02, val | (1 << 6)); + + /* kicker disable */ + val = s5h1420_readreg(state, QPSK01) & 0x7f; + s5h1420_writereg(state, QPSK01, val); + + /* DC freeze TODO it was never activated by default or it can stay activated */ +#if 0 + val = s5h1420_readreg(state, 0x1f); + s5h1420_writereg(state, 0x1f, val | 0x01); +#endif + + if (s5h1420_getsymbolrate(state) >= 20000000) { + s5h1420_writereg(state, Loop04, 0x8a); + s5h1420_writereg(state, Loop05, 0x6a); + } else { + s5h1420_writereg(state, Loop04, 0x58); + s5h1420_writereg(state, Loop05, 0x27); + } /* post-lock processing has been done! */ state->postlocked = 1; } + dprintk("leave %s\n", __func__); + return 0; } @@ -414,6 +466,7 @@ static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) static void s5h1420_reset(struct s5h1420_state* state) { + dprintk("%s\n", __func__); s5h1420_writereg (state, 0x01, 0x08); s5h1420_writereg (state, 0x01, 0x00); udelay(10); @@ -422,54 +475,79 @@ static void s5h1420_reset(struct s5h1420_state* state) static void s5h1420_setsymbolrate(struct s5h1420_state* state, struct dvb_frontend_parameters *p) { + u8 v; u64 val; + dprintk("enter %s\n", __func__); + val = ((u64) p->u.qpsk.symbol_rate / 1000ULL) * (1ULL<<24); - if (p->u.qpsk.symbol_rate <= 21000000) { + if (p->u.qpsk.symbol_rate < 29000000) val *= 2; - } do_div(val, (state->fclk / 1000)); - s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0x7f); - s5h1420_writereg(state, 0x11, val >> 16); - s5h1420_writereg(state, 0x12, val >> 8); - s5h1420_writereg(state, 0x13, val & 0xff); - s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x80); + dprintk("symbol rate register: %06llx\n", val); + + v = s5h1420_readreg(state, Loop01); + s5h1420_writereg(state, Loop01, v & 0x7f); + s5h1420_writereg(state, Tnco01, val >> 16); + s5h1420_writereg(state, Tnco02, val >> 8); + s5h1420_writereg(state, Tnco03, val & 0xff); + s5h1420_writereg(state, Loop01, v | 0x80); + dprintk("leave %s\n", __func__); } static u32 s5h1420_getsymbolrate(struct s5h1420_state* state) { +#if 0 + /* TODO getsymbolrate gives strange values - something is wrong with + * configuring the read + */ + u64 val = 0; + u8 v; int sampling = 2; - if (s5h1420_readreg(state, 0x05) & 0x2) - sampling = 1; + v = s5h1420_readreg(state, QPSK02); + s5h1420_writereg(state, QPSK02, v | 0x08); + val = s5h1420_readreg(state, Tnco01) << 16; + val |= s5h1420_readreg(state, Tnco02) << 8; + val |= s5h1420_readreg(state, Tnco03); + s5h1420_writereg(state, QPSK02, v & 0xf7); - s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08); - val = s5h1420_readreg(state, 0x11) << 16; - val |= s5h1420_readreg(state, 0x12) << 8; - val |= s5h1420_readreg(state, 0x13); - s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7); + dprintk("get_symbolrate: raw: %x\n", val); - val *= (state->fclk / 1000ULL); - do_div(val, ((1<<24) * sampling)); + val *= (state->fclk / 1000); + if (s5h1420_readreg(state, QPSK01) & 0x2) + do_div(val, 1 << 24); + else + do_div(val, 1 << 25); + dprintk("get_symbolrate: %d\n", (u32) (val * 1000ULL)); return (u32) (val * 1000ULL); +#endif + return state->symbol_rate; } static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset) { int val; + u8 v; + + dprintk("enter %s\n", __func__); /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so * divide fclk by 1000000 to get the correct value. */ val = -(int) ((freqoffset * (1<<24)) / (state->fclk / 1000000)); - s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0xbf); - s5h1420_writereg(state, 0x0e, val >> 16); - s5h1420_writereg(state, 0x0f, val >> 8); - s5h1420_writereg(state, 0x10, val & 0xff); - s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x40); + dprintk("phase rotator/freqoffset: %d %06x\n", freqoffset, val); + + v = s5h1420_readreg(state, Loop01); + s5h1420_writereg(state, Loop01, v & 0xbf); + s5h1420_writereg(state, Pnco01, val >> 16); + s5h1420_writereg(state, Pnco02, val >> 8); + s5h1420_writereg(state, Pnco03, val & 0xff); + s5h1420_writereg(state, Loop01, v | 0x40); + dprintk("leave %s\n", __func__); } static int s5h1420_getfreqoffset(struct s5h1420_state* state) @@ -496,52 +574,53 @@ static void s5h1420_setfec_inversion(struct s5h1420_state* state, struct dvb_frontend_parameters *p) { u8 inversion = 0; + u8 vit08, vit09; + + dprintk("enter %s\n", __func__); - if (p->inversion == INVERSION_OFF) { + if (p->inversion == INVERSION_OFF) inversion = state->config->invert ? 0x08 : 0; - } else if (p->inversion == INVERSION_ON) { + else if (p->inversion == INVERSION_ON) inversion = state->config->invert ? 0 : 0x08; - } if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) { - s5h1420_writereg(state, 0x30, 0x3f); - s5h1420_writereg(state, 0x31, 0x00 | inversion); + vit08 = 0x3f; + vit09 = 0; } else { switch(p->u.qpsk.fec_inner) { case FEC_1_2: - s5h1420_writereg(state, 0x30, 0x01); - s5h1420_writereg(state, 0x31, 0x10 | inversion); + vit08 = 0x01; vit09 = 0x10; break; case FEC_2_3: - s5h1420_writereg(state, 0x30, 0x02); - s5h1420_writereg(state, 0x31, 0x11 | inversion); + vit08 = 0x02; vit09 = 0x11; break; case FEC_3_4: - s5h1420_writereg(state, 0x30, 0x04); - s5h1420_writereg(state, 0x31, 0x12 | inversion); + vit08 = 0x04; vit09 = 0x12; break; case FEC_5_6: - s5h1420_writereg(state, 0x30, 0x08); - s5h1420_writereg(state, 0x31, 0x13 | inversion); + vit08 = 0x08; vit09 = 0x13; break; case FEC_6_7: - s5h1420_writereg(state, 0x30, 0x10); - s5h1420_writereg(state, 0x31, 0x14 | inversion); + vit08 = 0x10; vit09 = 0x14; break; case FEC_7_8: - s5h1420_writereg(state, 0x30, 0x20); - s5h1420_writereg(state, 0x31, 0x15 | inversion); + vit08 = 0x20; vit09 = 0x15; break; default: return; } } + vit09 |= inversion; + dprintk("fec: %02x %02x\n", vit08, vit09); + s5h1420_writereg(state, Vit08, vit08); + s5h1420_writereg(state, Vit09, vit09); + dprintk("leave %s\n", __func__); } static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state) @@ -583,16 +662,19 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, struct s5h1420_state* state = fe->demodulator_priv; int frequency_delta; struct dvb_frontend_tune_settings fesettings; + uint8_t clock_settting; + + dprintk("enter %s\n", __func__); /* check if we should do a fast-tune */ memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters)); s5h1420_get_tune_settings(fe, &fesettings); frequency_delta = p->frequency - state->tunedfreq; if ((frequency_delta > -fesettings.max_drift) && - (frequency_delta < fesettings.max_drift) && - (frequency_delta != 0) && - (state->fec_inner == p->u.qpsk.fec_inner) && - (state->symbol_rate == p->u.qpsk.symbol_rate)) { + (frequency_delta < fesettings.max_drift) && + (frequency_delta != 0) && + (state->fec_inner == p->u.qpsk.fec_inner) && + (state->symbol_rate == p->u.qpsk.symbol_rate)) { if (fe->ops.tuner_ops.set_params) { fe->ops.tuner_ops.set_params(fe, p); @@ -606,54 +688,93 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, } else { s5h1420_setfreqoffset(state, 0); } + dprintk("simple tune\n"); return 0; } + dprintk("tuning demod\n"); /* first of all, software reset */ s5h1420_reset(state); /* set s5h1420 fclk PLL according to desired symbol rate */ - if (p->u.qpsk.symbol_rate > 28000000) { - state->fclk = 88000000; - s5h1420_writereg(state, 0x03, 0x50); - s5h1420_writereg(state, 0x04, 0x40); - s5h1420_writereg(state, 0x05, 0xae); - } else if (p->u.qpsk.symbol_rate > 21000000) { + if (p->u.qpsk.symbol_rate > 33000000) + state->fclk = 80000000; + else if (p->u.qpsk.symbol_rate > 28500000) state->fclk = 59000000; - s5h1420_writereg(state, 0x03, 0x33); - s5h1420_writereg(state, 0x04, 0x40); - s5h1420_writereg(state, 0x05, 0xae); - } else { + else if (p->u.qpsk.symbol_rate > 25000000) + state->fclk = 86000000; + else if (p->u.qpsk.symbol_rate > 1900000) state->fclk = 88000000; - s5h1420_writereg(state, 0x03, 0x50); - s5h1420_writereg(state, 0x04, 0x40); - s5h1420_writereg(state, 0x05, 0xac); + else + state->fclk = 44000000; + + /* Clock */ + switch (state->fclk) { + default: + case 88000000: + clock_settting = 80; + break; + case 86000000: + clock_settting = 78; + break; + case 80000000: + clock_settting = 72; + break; + case 59000000: + clock_settting = 51; + break; + case 44000000: + clock_settting = 36; + break; } + dprintk("pll01: %d, ToneFreq: %d\n", state->fclk/1000000 - 8, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32)); + s5h1420_writereg(state, PLL01, state->fclk/1000000 - 8); + s5h1420_writereg(state, PLL02, 0x40); + s5h1420_writereg(state, DiS01, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32)); - /* set misc registers */ - s5h1420_writereg(state, 0x02, 0x00); - s5h1420_writereg(state, 0x06, 0x00); - s5h1420_writereg(state, 0x07, 0xb0); - s5h1420_writereg(state, 0x0a, 0xe7); - s5h1420_writereg(state, 0x0b, 0x78); - s5h1420_writereg(state, 0x0c, 0x48); - s5h1420_writereg(state, 0x0d, 0x6b); - s5h1420_writereg(state, 0x2e, 0x8e); - s5h1420_writereg(state, 0x35, 0x33); - s5h1420_writereg(state, 0x38, 0x01); - s5h1420_writereg(state, 0x39, 0x7d); - s5h1420_writereg(state, 0x3a, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32)); - s5h1420_writereg(state, 0x3c, 0x00); - s5h1420_writereg(state, 0x45, 0x61); - s5h1420_writereg(state, 0x46, 0x1d); + /* TODO DC offset removal, config parameter ? */ + if (p->u.qpsk.symbol_rate > 29000000) + s5h1420_writereg(state, QPSK01, 0xae | 0x10); + else + s5h1420_writereg(state, QPSK01, 0xac | 0x10); - /* start QPSK */ - s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1); + /* set misc registers */ + s5h1420_writereg(state, CON_1, 0x00); + s5h1420_writereg(state, QPSK02, 0x00); + s5h1420_writereg(state, Pre01, 0xb0); + + s5h1420_writereg(state, Loop01, 0xF0); + s5h1420_writereg(state, Loop02, 0x2a); /* e7 for s5h1420 */ + s5h1420_writereg(state, Loop03, 0x79); /* 78 for s5h1420 */ + if (p->u.qpsk.symbol_rate > 20000000) + s5h1420_writereg(state, Loop04, 0x79); + else + s5h1420_writereg(state, Loop04, 0x58); + s5h1420_writereg(state, Loop05, 0x6b); + + if (p->u.qpsk.symbol_rate >= 8000000) + s5h1420_writereg(state, Post01, (0 << 6) | 0x10); + else if (p->u.qpsk.symbol_rate >= 4000000) + s5h1420_writereg(state, Post01, (1 << 6) | 0x10); + else + s5h1420_writereg(state, Post01, (3 << 6) | 0x10); + + s5h1420_writereg(state, Monitor12, 0x00); /* unfreeze DC compensation */ + + s5h1420_writereg(state, Sync01, 0x33); + s5h1420_writereg(state, Mpeg01, state->config->cdclk_polarity); + s5h1420_writereg(state, Mpeg02, 0x3d); /* Parallel output more, disabled -> enabled later */ + s5h1420_writereg(state, Err01, 0x03); /* 0x1d for s5h1420 */ + + s5h1420_writereg(state, Vit06, 0x6e); /* 0x8e for s5h1420 */ + s5h1420_writereg(state, DiS03, 0x00); + s5h1420_writereg(state, Rf01, 0x61); /* Tuner i2c address - for the gate controller */ /* set tuner PLL */ if (fe->ops.tuner_ops.set_params) { fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); s5h1420_setfreqoffset(state, 0); } @@ -661,10 +782,15 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, s5h1420_setsymbolrate(state, p); s5h1420_setfec_inversion(state, p); + /* start QPSK */ + s5h1420_writereg(state, QPSK01, s5h1420_readreg(state, QPSK01) | 1); + state->fec_inner = p->u.qpsk.fec_inner; state->symbol_rate = p->u.qpsk.symbol_rate; state->postlocked = 0; state->tunedfreq = p->frequency; + + dprintk("leave %s\n", __func__); return 0; } @@ -717,11 +843,10 @@ static int s5h1420_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) { struct s5h1420_state* state = fe->demodulator_priv; - if (enable) { - return s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); - } else { - return s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe); - } + if (enable) + return s5h1420_writereg(state, 0x02, state->CON_1_val | 1); + else + return s5h1420_writereg(state, 0x02, state->CON_1_val & 0xfe); } static int s5h1420_init (struct dvb_frontend* fe) @@ -729,7 +854,8 @@ static int s5h1420_init (struct dvb_frontend* fe) struct s5h1420_state* state = fe->demodulator_priv; /* disable power down and do reset */ - s5h1420_writereg(state, 0x02, 0x10); + state->CON_1_val = 0x10; + s5h1420_writereg(state, 0x02, state->CON_1_val); msleep(10); s5h1420_reset(state); @@ -739,26 +865,60 @@ static int s5h1420_init (struct dvb_frontend* fe) static int s5h1420_sleep(struct dvb_frontend* fe) { struct s5h1420_state* state = fe->demodulator_priv; - - return s5h1420_writereg(state, 0x02, 0x12); + state->CON_1_val = 0x12; + return s5h1420_writereg(state, 0x02, state->CON_1_val); } static void s5h1420_release(struct dvb_frontend* fe) { struct s5h1420_state* state = fe->demodulator_priv; + i2c_del_adapter(&state->tuner_i2c_adapter); kfree(state); } -static struct dvb_frontend_ops s5h1420_ops; +static u32 s5h1420_tuner_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static int s5h1420_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) +{ + struct s5h1420_state *state = i2c_get_adapdata(i2c_adap); + struct i2c_msg m[1 + num]; + u8 tx_open[2] = { CON_1, state->CON_1_val | 1 }; /* repeater stops once there was a stop condition */ + + memset(m, 0, sizeof(struct i2c_msg) * (1 + num)); + + m[0].addr = state->config->demod_address; + m[0].buf = tx_open; + m[0].len = 2; + + memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); -struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, - struct i2c_adapter* i2c) + return i2c_transfer(state->i2c, m, 1+num) == 1 + num ? num : -EIO; +} + +static struct i2c_algorithm s5h1420_tuner_i2c_algo = { + .master_xfer = s5h1420_tuner_i2c_tuner_xfer, + .functionality = s5h1420_tuner_i2c_func, +}; + +struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe) { - struct s5h1420_state* state = NULL; - u8 identity; + struct s5h1420_state *state = fe->demodulator_priv; + return &state->tuner_i2c_adapter; +} +EXPORT_SYMBOL(s5h1420_get_tuner_i2c_adapter); + +static struct dvb_frontend_ops s5h1420_ops; +struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, + struct i2c_adapter *i2c) +{ /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct s5h1420_state), GFP_KERNEL); + struct s5h1420_state *state = kzalloc(sizeof(struct s5h1420_state), GFP_KERNEL); + u8 i; + if (state == NULL) goto error; @@ -772,24 +932,42 @@ struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, state->symbol_rate = 0; /* check if the demod is there + identify it */ - identity = s5h1420_readreg(state, 0x00); - if (identity != 0x03) + i = s5h1420_readreg(state, ID01); + if (i != 0x03) goto error; + memset(state->shadow, 0xff, sizeof(state->shadow)); + + for (i = 0; i < 0x50; i++) + state->shadow[i] = s5h1420_readreg(state, i); + /* create dvb_frontend */ memcpy(&state->frontend.ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; + + /* create tuner i2c adapter */ + strncpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus", I2C_NAME_SIZE); + state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, + state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo; + state->tuner_i2c_adapter.algo_data = NULL; + i2c_set_adapdata(&state->tuner_i2c_adapter, state); + if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) { + printk(KERN_ERR "S5H1420/PN1010: tuner i2c bus could not be initialized\n"); + goto error; + } + return &state->frontend; error: kfree(state); return NULL; } +EXPORT_SYMBOL(s5h1420_attach); static struct dvb_frontend_ops s5h1420_ops = { .info = { - .name = "Samsung S5H1420 DVB-S", + .name = "Samsung S5H1420/PnpNetwork PN1010 DVB-S", .type = FE_QPSK, .frequency_min = 950000, .frequency_max = 2150000, @@ -826,10 +1004,6 @@ static struct dvb_frontend_ops s5h1420_ops = { .set_voltage = s5h1420_set_voltage, }; -module_param(debug, int, 0644); - -MODULE_DESCRIPTION("Samsung S5H1420 DVB-S Demodulator driver"); -MODULE_AUTHOR("Andrew de Quincey"); +MODULE_DESCRIPTION("Samsung S5H1420/PnpNetwork PN1010 DVB-S Demodulator driver"); +MODULE_AUTHOR("Andrew de Quincey, Patrick Boettcher"); MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(s5h1420_attach); diff --git a/linux/drivers/media/dvb/frontends/s5h1420.h b/linux/drivers/media/dvb/frontends/s5h1420.h index 1555870f7..4c913f142 100644 --- a/linux/drivers/media/dvb/frontends/s5h1420.h +++ b/linux/drivers/media/dvb/frontends/s5h1420.h @@ -1,25 +1,26 @@ /* - Driver for S5H1420 QPSK Demodulators - - Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> - - 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. - -*/ - + * Driver for + * Samsung S5H1420 and + * PnpNetwork PN1010 QPSK Demodulator + * + * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> + * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org> + * + * 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 S5H1420_H #define S5H1420_H @@ -31,17 +32,26 @@ struct s5h1420_config u8 demod_address; /* does the inversion require inversion? */ - u8 invert:1; + u8 invert : 1; + + u8 repeated_start_workaround : 1; + u8 cdclk_polarity : 1; /* 1 == falling edge, 0 == raising edge */ }; #if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE)) -extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, - struct i2c_adapter* i2c); +extern struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, + struct i2c_adapter *i2c); +extern struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe); #else -static inline struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, - struct i2c_adapter* i2c) +static inline struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} + +static inline struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); return NULL; } #endif // CONFIG_DVB_S5H1420 diff --git a/linux/drivers/media/dvb/frontends/s5h1420_priv.h b/linux/drivers/media/dvb/frontends/s5h1420_priv.h new file mode 100644 index 000000000..7962bbfb6 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/s5h1420_priv.h @@ -0,0 +1,380 @@ +/* + * Driver for + * Samsung S5H1420 and + * PnpNetwork PN1010 QPSK Demodulator + * + * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> + * Copyright (C) 2005 Patrick Boettcher <pb@linuxtv.org> + * + * 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 S5H1420_PRIV +#define S5H1420_PRIV + +#include <asm/types.h> + +enum s5h1420_register { + ID01 = 0x00, + CON_0 = 0x01, + CON_1 = 0x02, + PLL01 = 0x03, + PLL02 = 0x04, + QPSK01 = 0x05, + QPSK02 = 0x06, + Pre01 = 0x07, + Post01 = 0x08, + Loop01 = 0x09, + Loop02 = 0x0a, + Loop03 = 0x0b, + Loop04 = 0x0c, + Loop05 = 0x0d, + Pnco01 = 0x0e, + Pnco02 = 0x0f, + Pnco03 = 0x10, + Tnco01 = 0x11, + Tnco02 = 0x12, + Tnco03 = 0x13, + Monitor01 = 0x14, + Monitor02 = 0x15, + Monitor03 = 0x16, + Monitor04 = 0x17, + Monitor05 = 0x18, + Monitor06 = 0x19, + Monitor07 = 0x1a, + Monitor12 = 0x1f, + + FEC01 = 0x22, + Soft01 = 0x23, + Soft02 = 0x24, + Soft03 = 0x25, + Soft04 = 0x26, + Soft05 = 0x27, + Soft06 = 0x28, + Vit01 = 0x29, + Vit02 = 0x2a, + Vit03 = 0x2b, + Vit04 = 0x2c, + Vit05 = 0x2d, + Vit06 = 0x2e, + Vit07 = 0x2f, + Vit08 = 0x30, + Vit09 = 0x31, + Vit10 = 0x32, + Vit11 = 0x33, + Vit12 = 0x34, + Sync01 = 0x35, + Sync02 = 0x36, + Rs01 = 0x37, + Mpeg01 = 0x38, + Mpeg02 = 0x39, + DiS01 = 0x3a, + DiS02 = 0x3b, + DiS03 = 0x3c, + DiS04 = 0x3d, + DiS05 = 0x3e, + DiS06 = 0x3f, + DiS07 = 0x40, + DiS08 = 0x41, + DiS09 = 0x42, + DiS10 = 0x43, + DiS11 = 0x44, + Rf01 = 0x45, + Err01 = 0x46, + Err02 = 0x47, + Err03 = 0x48, + Err04 = 0x49, +}; + +#if 0 + +regsiter mapping follows + +/* ID01 */ +#define PN1010_ID 7, 0 + +/* CON_0 */ +#define QPSK_ONLY 4, 4 +#define SOFT_RST 3, 3 /* System soft reset mode (active high) [1] Enable [0] Disable */ +#define CLK_MODE 2, 2 +#define BPSK_QPSK 1, 1 +#define DSS_DVB 0, 0 /* DSS/DVB mode selection [1] DSS [0] DVB */ + +/* CON_1 */ +#define ADC_SPD 6, 6 +#define PLL_OEN 5, 5 +#define SER_SEL 4, 4 +#define XTAL_OEN 3, 3 +#define Q_TEST 2, 2 +#define PWR_DN 1, 1 /* Power down mode [1] Power down enable, [0] Power down disable */ +#define I2C_RPT 0, 0 /* I2C repeater control [1] I2C repeater enable, [0] I2C repeater disable. + * Note: The master should be set this bit to "1" in order to interface with the tuner. + * When the master is not communicated with the tuner, this bit should be set to "0" */ + +/* PLL programming information + * Fout = ((M+8)*Fin)/((P+2)*2^S), Fin = 4 MHz */ +/* PLL01 */ +#define M 7, 0 + +/* PLL02 */ +#define P 5, 0 +#define S 7, 6 + +/* QPSK01 */ +#define KICK_EN 7, 7 /* [1] PLL Kicker enable [0] Disable */ +#define ROLL_OFF 6, 6 +#define SCALE_EN 5, 5 +#define DC_EN 4, 4 /* DC offset remove [1] Enable [0] Disable */ +#define VMODE 3, 3 +#define TGL_MSB 2, 2 +#define MODE_QPSK 1, 1 /* QPSK operation mode [1] 1 sampling/1 symbol [0] 2 sampling/1 symbol */ +#define Q_SRESET_N 0, 0 /* QPSK start signal [1] Start [0] Idle */ + +/* QPSK02 */ +#define DUMP_ACC 3, 3 /* Dump phase loop filter & timing loop filter accumulator [0 and then 1] + * The read operation enabled, when user set DUMP_ACC "0" and then "1". */ +#define DC_WIN 2, 0 /* Window position from MSB (0 <= DC_WIN <= 7) */ + +/* AGC Controls */ +/* Pre01 */ +#define PRE_TH 4, 0 /* PRE-AGC threshold */ +#define INV_PULSE 7, 7 /* PWM signal is reversed [1] PWM signal active low [0] PWM signal active high */ + +/* Post01 */ +#define RRC_SCALE 7, 6 +#define POST_TH 5, 0 /* POST-AGC threshold */ + +/* Loop Controls */ +/* Loop01 */ +#define WT_TNCO 7, 7 /* Write TNCO center frequency [0 and then 1] The write operation enabled, when user set WT_TNCO "0" and then "1" */ +#define WT_PNCO 6, 6 /* Write PNCO center frequency [0 and then 1] The write operation enabled, when user set WT_PNCO "0" and then "1" */ + +/* Loop02 */ +#define LOOP_OUT 7, 7 /* Loop filter monitoring selection [1] Loop filter accumulator + NCO [0] Loop filter accumulator */ +#define KICK_VAL 6, 4 /* The value that gets injected into the accumulator when a "kick" is needed. */ +#define KICK_MUL 3, 0 /* The number of bits KICK_VAL is up-shifted (2^N) before it is injected into the accumulator. */ + +/* Loop03 */ +#define IGA_PLF 7, 4 /* Phase loop, integral gain (2^IGA_PLF) in the acquisition mode */ +#define PGA_PLF 3, 0 /* Phase loop, proportional gain (2^PGA_PLF) in the acquisition mode (default +8 added) */ + +/* Loop04 */ +#define IGT_PLF 7, 4 /* Integral gain in the tracking mode */ +#define PGT_PLF 3, 0 /* Phase loop, proportional gain in the tracking mode (default +8 added) */ + +/* Loop 05 */ +#define IG_TLF 7, 4 /* Timing loop, integral gain */ +#define PG_TLF 3, 0 /* Timing loop, proportional gain (default +8 added) */ + +/* NCO controls + * LOOP_OUT [1] Read PLF accumulator + PNCO, LOOP_OUT [0] Read PLF accumulator */ +/* Pnco01 */ +#define PNCO0 7, 0 +/* Pnco02 */ +#define PNCO1 7, 0 +/* Pnco03 */ +#define PNCO2 7, 0 + +/* LOOP_OUT [1], Read TLF accumulator + TNCO, LOOP_OUT [0], Read TLF accumulator */ +/* Tnco01 */ +#define TNCO0 7, 0 +/* Tnco02 */ +#define TNCO1 7, 0 +/* Tnco03 */ +#define TNCO2 7, 0 + +/* Monitor01 */ +#define A_SCL 3, 3 +#define TLOCK 1, 1 /* Timing loop lock (Symbol sync) [1] Timing loop has locked [0] Timing loop has not locked */ +#define PLOCK 0, 0 /* Phase loop lock (Carrier sync) [1] Phase loop has locked [0] Phase loop has not locked */ + +/* Monitor02 */ +#define PRE_LEVEL 7, 0 /* PRE-AGC gain level */ + +/* Monitor03 */ +#define POST_LEVEL 7, 0 /* POST-AGC gain level */ + +/* Monitor04 */ +#define DC_I_LEVEL 7, 0 /* DC offset of I samples */ + +/* Monitor05 */ +#define DC_Q_LEVEL 7, 0 /* DC offset of Q samples */ + +/* Monitor06 */ +#define PLOCK_CNT 7, 0 + +/* Monitor07 */ +#define TLOCK_CNT 7, 0 + +/* Monitor12 */ +#define QPSK_OUT 6, 1 /* QPSK output monitoring */ +#define DC_FREEZE 0, 0 /* [1] Do not update DC_OFFSET */ + +/* FEC Block */ +/* FEC01 */ +#define DERAND_BPAS 6, 6 +#define RS_BPAS 5, 5 +#define FEC_SRST_CNTL 4, 4 +#define FEC_SRESET 3, 3 +#define MPEG_CLK_INTL 2, 0 + /* Tmp=(FMClk/FSR) x (1 / (2xCR)); FMClk: System Clock Frequency, FSR: Symbol Rate, CR: Code Rate + * 0: 1 < Tmp <= 2, 4: 13 < Tmp <= 17, + * 1: 2 < Tmp <= 5, 5: 17 < Tmp <= 25, + * 2: 5 < Tmp <= 9, 6: 25 < Tmp <= 33, + * 3: 9 < Tmp <= 13, 7: 33 < Tmp */ + +/* Soft01 */ +#define ST_VAL_R12 2, 0 +#define STEP_R12 5, 3 +#define STEP_R23 5, 3 +#define STEP_R34 5, 3 +#define STEP_R56 5, 3 +#define STEP_R67 5, 3 +#define STEP_R78 5, 3 +/* Soft02 */ +#define ST_VAL_R23 7, 0 +/* Soft03 */ +#define ST_VAL_R34 7, 0 +/* Soft04 */ +#define ST_VAL_R56 7, 0 +/* Soft05 */ +#define ST_VAL_R67 7, 0 +/* Soft06 */ +#define ST_VAL_R78 7, 0 + +/* Vit01 */ +#define RENORM_R12 7, 0 +/* Vit02 */ +#define RENORM_R23 7, 0 +/* Vit03 */ +#define RENORM_R34 7, 0 +/* Vit04 */ +#define RENORM_R56 7, 0 +/* Vit05 */ +#define RENORM_R67 7, 0 +/* Vit06 */ +#define RENORM_R78 7, 0 +/* Vit07 */ +#define RENORM_PRD 7, 0 + +/* Vit08 */ +#define VIT_IN_SR78 7, 7 +#define VIT_IN_SR34 6, 6 +#define VIT_SR78 5, 5 +#define VIT_SR67 4, 4 +#define VIT_SR56 3, 3 +#define VIT_SR34 2, 2 +#define VIT_SR23 1, 1 /* .... */ +#define VIT_SR12 0, 0 /* Include CR 1/2 in search */ + +/* Vit09 */ +#define PARM_FIX 4, 4 /* Parameter fix mode: [1] Known parameter [0] Unknown parameter */ +#define VIT_INV_SPECPARM_FIX 3, 3 /* Initial spectrum information */ +#define VIT_FR 2, 0 /* Start synchronization search at code rate as follows */ + #define VIT_CR_12 0x00 + #define VIT_CR_23 0x01 + #define VIT_CR_34 0x02 + #define VIT_CR_56 0x03 + #define VIT_CR_67 0x04 + #define VIT_CR_78 0x05 + +/* Vit10 */ +#define INV_SPEC_STS 3, 3 /* Spectrum information monitoring [1] Inv spectrum [0] Not inv spectrum */ +#define VIT_CR 2, 0 /* Viterbi decoder current code rate [0] R=1/2 [1] R=2/3 [2] R=3/4 [3] R=5/6 [4] R=6/7 [5] R=7/8 */ + +/* Vit11 */ +#define VIT_CER 7, 0 + +/* Vit12 */ +#define RENORM_RAT 7, 0 + +/* Sync01 */ +#define SYNC_MISS_TH 7, 4 /* Sync byte detector?s miss threshold */ +#define SYNC_HIT_TH 3, 0 /* Sync byte detector?s hit threshold This value should be greater than 2 */ + +/* Sync02 */ +#define BYTE_SYNC 5, 5 /* [1] Acquire byte sync [0] Not acquire byte sync */ +#define SYNC_BYTE_STS 4, 2 +#define VIT_SRCH_STS 1, 1 +#define VIT_SYNC 0, 0 /* [1] Viterbi decoder is in sync [0] Viterbi decoder is out of sync */ + +/* Rs01 */ +#define RS_ERR 3, 0 +#define PKT_ERR 4, 4 + +/* Mpeg01 */ +#define ERR_POL 3, 3 /* Packet error polarity [1] Active low [0] Active high */ +#define SYNC_POL 2, 2 /* Sync polarity [1] Active low [0] Active high */ +#define VALID_POL 1, 1 /* Data valid polarity [1] Active low [0] Active high */ +#define CDCLK_POL 0, 0 /* CDCLK polarity [1] Falling edge event [0] Rising edge event */ + +/* Mpeg02 */ +#define MPEG_OEN 6, 6 +#define DOUT_CONT 5, 5 +#define ERR_CONT 4, 4 +#define CLK_CONT 3, 3 /* Clock continuous mode [1] Continuous clock, [0] Clock is enable during payload data transfer */ +#define ENVELOPE 2, 2 +#define SER_PAR 1, 1 /* Serial / Parallel mode [1] Serial mode, [0] Parallel mode */ +#define DSS_SYNC 0, 0 /* DSS sync mode [1] Output sync, [0] No output sync */ + +/* DiS01 */ +#define TONE_FREQ 7, 0 /* Tone frequency ratio ftone = fclk / (TONE_FREQ x 32) */ + +/* DiS02 */ +#define RCV_EN 7, 7 /* DiSEqC receive enable mode [1] Receive enable [0] Receive disable */ +#define DIS_LENGTH 6, 4 /* Message length */ +#define DIS_RDY 3, 3 /* Data Transfer ready / finish [1] Ready [0] Finish */ +#define SWITCH_CON 2, 2 /* Satellite switch in tone burst mode [1] Satellite B [0] Satellite A */ +#define LNB_CON 1, 0 /* LNB control mode, [0] Continuous mode, [1] Tone burst mode, [2] DiSEqC mode, [3] Reserved */ + +/* DiS03 */ +#define OLF_N 2, 2 /* [1] Disable [0] OLF (active low) */ +#define LNB_DN 1, 1 /* [1] LNB down [0] Disable (active high) */ +#define V18_13V 0, 0 /* 13V/18V select register (0=13V, 1=18V) */ + +/* DiS04 .. DiS11*/ +#define LNB_MESGE0 7, 0 +#define LNB_MESGE1 7, 0 +#define LNB_MESGE2 7, 0 +#define LNB_MESGE3 7, 0 +#define LNB_MESGE4 7, 0 +#define LNB_MESGE5 7, 0 +#define LNB_MESGE6 7, 0 +#define LNB_MESGE7 7, 0 + +/* Rf01 */ +#define SLAVE_ADDR 6, 0 /* RF tuner slave Address (SOC VERSION) */ + +/* Err01 */ +#define ALARM_MODE 4, 4 +#define ERR_CNT_PRD 3, 2 +#define ERR_SRC 1, 0 /* Error monitoring source */ + #define QPSK_BIT_ERRORS 0x0 + #define VITERBI_BIT_ERRORS 0x1 + #define VITERBI_BYTE_ERRORS 0x2 + #define PACKET_ERRORS 0x3 + +/* Err02 */ +#define ERR_CNT_L 7, 0 /* Error counter value register (LSB 8 bits) */ + +/* Err03 */ +#define ERR_CNT_H 7, 0 /* Error counter value register (MSB 8 bits) */ + +/* Err04 */ +#define PARITY_ERR 7, 0 /* Error flag for DiSEqC receive data */ + +#endif + +#endif diff --git a/linux/drivers/media/dvb/frontends/sp8870.c b/linux/drivers/media/dvb/frontends/sp8870.c index f5b3bfc00..aa78aa14a 100644 --- a/linux/drivers/media/dvb/frontends/sp8870.c +++ b/linux/drivers/media/dvb/frontends/sp8870.c @@ -70,7 +70,7 @@ static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data) int err; if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data); + dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data); return -EREMOTEIO; } @@ -88,7 +88,7 @@ static int sp8870_readreg (struct sp8870_state* state, u16 reg) ret = i2c_transfer (state->i2c, msg, 2); if (ret != 2) { - dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); + dprintk("%s: readreg error (ret == %i)\n", __func__, ret); return -1; } @@ -104,7 +104,7 @@ static int sp8870_firmware_upload (struct sp8870_state* state, const struct firm int tx_len; int err = 0; - dprintk ("%s: ...\n", __FUNCTION__); + dprintk ("%s: ...\n", __func__); if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET) return -EINVAL; @@ -131,14 +131,14 @@ static int sp8870_firmware_upload (struct sp8870_state* state, const struct firm msg.buf = tx_buf; msg.len = tx_len + 2; if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk("%s: firmware upload failed!\n", __FUNCTION__); - printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err); + printk("%s: firmware upload failed!\n", __func__); + printk ("%s: i2c error (err == %i)\n", __func__, err); return err; } fw_pos += tx_len; } - dprintk ("%s: done!\n", __FUNCTION__); + dprintk ("%s: done!\n", __func__); return 0; }; @@ -310,7 +310,7 @@ static int sp8870_init (struct dvb_frontend* fe) if (state->initialised) return 0; state->initialised = 1; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); /* request the firmware, this will block until someone uploads it */ @@ -475,7 +475,7 @@ static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_par int trials = 0; int check_count = 0; - dprintk("%s: frequency = %i\n", __FUNCTION__, p->frequency); + dprintk("%s: frequency = %i\n", __func__, p->frequency); for (trials = 1; trials <= MAXTRIALS; trials++) { @@ -487,7 +487,7 @@ static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_par valid = sp8870_read_data_valid_signal(state); if (valid) { dprintk("%s: delay = %i usec\n", - __FUNCTION__, check_count * 10); + __func__, check_count * 10); break; } udelay(10); @@ -497,20 +497,20 @@ static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_par } if (!valid) { - printk("%s: firmware crash!!!!!!\n", __FUNCTION__); + printk("%s: firmware crash!!!!!!\n", __func__); return -EIO; } if (debug) { if (valid) { if (trials > 1) { - printk("%s: firmware lockup!!!\n", __FUNCTION__); - printk("%s: recovered after %i trial(s))\n", __FUNCTION__, trials - 1); + printk("%s: firmware lockup!!!\n", __func__); + printk("%s: recovered after %i trial(s))\n", __func__, trials - 1); lockups++; } } switches++; - printk("%s: switches = %i lockups = %i\n", __FUNCTION__, switches, lockups); + printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups); } return 0; diff --git a/linux/drivers/media/dvb/frontends/sp8870.h b/linux/drivers/media/dvb/frontends/sp8870.h index 909cefe71..a764a793c 100644 --- a/linux/drivers/media/dvb/frontends/sp8870.h +++ b/linux/drivers/media/dvb/frontends/sp8870.h @@ -42,7 +42,7 @@ extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, static inline struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_SP8870 diff --git a/linux/drivers/media/dvb/frontends/sp887x.c b/linux/drivers/media/dvb/frontends/sp887x.c index 1aa2539f5..49f55877f 100644 --- a/linux/drivers/media/dvb/frontends/sp887x.c +++ b/linux/drivers/media/dvb/frontends/sp887x.c @@ -43,7 +43,7 @@ static int i2c_writebytes (struct sp887x_state* state, u8 *buf, u8 len) if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { printk ("%s: i2c write error (addr %02x, err == %i)\n", - __FUNCTION__, state->config->demod_address, err); + __func__, state->config->demod_address, err); return -EREMOTEIO; } @@ -65,7 +65,7 @@ static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data) { printk("%s: writereg error " "(reg %03x, data %03x, ret == %i)\n", - __FUNCTION__, reg & 0xffff, data & 0xffff, ret); + __func__, reg & 0xffff, data & 0xffff, ret); return ret; } } @@ -82,7 +82,7 @@ static int sp887x_readreg (struct sp887x_state* state, u16 reg) { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 }}; if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); + printk("%s: readreg error (ret == %i)\n", __func__, ret); return -1; } @@ -91,7 +91,7 @@ static int sp887x_readreg (struct sp887x_state* state, u16 reg) static void sp887x_microcontroller_stop (struct sp887x_state* state) { - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); sp887x_writereg(state, 0xf08, 0x000); sp887x_writereg(state, 0xf09, 0x000); @@ -101,7 +101,7 @@ static void sp887x_microcontroller_stop (struct sp887x_state* state) static void sp887x_microcontroller_start (struct sp887x_state* state) { - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); sp887x_writereg(state, 0xf08, 0x000); sp887x_writereg(state, 0xf09, 0x000); @@ -112,7 +112,7 @@ static void sp887x_microcontroller_start (struct sp887x_state* state) static void sp887x_setup_agc (struct sp887x_state* state) { /* setup AGC parameters */ - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); sp887x_writereg(state, 0x33c, 0x054); sp887x_writereg(state, 0x33b, 0x04c); sp887x_writereg(state, 0x328, 0x000); @@ -142,7 +142,7 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware int fw_size = fw->size; unsigned char *mem = fw->data; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* ignore the first 10 bytes, then we expect 0x4000 bytes of firmware */ if (fw_size < FW_SIZE+10) @@ -155,7 +155,7 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware sp887x_microcontroller_stop (state); - printk ("%s: firmware upload... ", __FUNCTION__); + printk ("%s: firmware upload... ", __func__); /* setup write pointer to -1 (end of memory) */ /* bit 0x8000 in address is set to enable 13bit mode */ @@ -181,7 +181,7 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware if ((err = i2c_writebytes (state, buf, c+2)) < 0) { printk ("failed.\n"); - printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err); + printk ("%s: i2c error (err == %i)\n", __func__, err); return err; } } diff --git a/linux/drivers/media/dvb/frontends/sp887x.h b/linux/drivers/media/dvb/frontends/sp887x.h index 7ee78d7d9..04eff6e0e 100644 --- a/linux/drivers/media/dvb/frontends/sp887x.h +++ b/linux/drivers/media/dvb/frontends/sp887x.h @@ -24,7 +24,7 @@ extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, static inline struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_SP887X diff --git a/linux/drivers/media/dvb/frontends/stv0297.c b/linux/drivers/media/dvb/frontends/stv0297.c index cd8f74b57..1c5a0ae82 100644 --- a/linux/drivers/media/dvb/frontends/stv0297.c +++ b/linux/drivers/media/dvb/frontends/stv0297.c @@ -58,7 +58,7 @@ static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data) if (ret != 1) dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __FUNCTION__, reg, data, ret); + "ret == %i)\n", __func__, reg, data, ret); return (ret != 1) ? -1 : 0; } @@ -75,16 +75,16 @@ static int stv0297_readreg(struct stv0297_state *state, u8 reg) // this device needs a STOP between the register and data if (state->config->stop_during_read) { if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret); return -1; } if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret); return -1; } } else { if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret); return -1; } } @@ -115,16 +115,16 @@ static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len // this device needs a STOP between the register and data if (state->config->stop_during_read) { if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret); return -1; } if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret); return -1; } } else { if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); + dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret); return -1; } } diff --git a/linux/drivers/media/dvb/frontends/stv0297.h b/linux/drivers/media/dvb/frontends/stv0297.h index 69f4515df..3f8f9468f 100644 --- a/linux/drivers/media/dvb/frontends/stv0297.h +++ b/linux/drivers/media/dvb/frontends/stv0297.h @@ -49,7 +49,7 @@ extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, static inline struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_STV0297 diff --git a/linux/drivers/media/dvb/frontends/stv0299.c b/linux/drivers/media/dvb/frontends/stv0299.c index 035dd7ba6..17556183e 100644 --- a/linux/drivers/media/dvb/frontends/stv0299.c +++ b/linux/drivers/media/dvb/frontends/stv0299.c @@ -86,7 +86,7 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data) if (ret != 1) dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __FUNCTION__, reg, data, ret); + "ret == %i)\n", __func__, reg, data, ret); return (ret != 1) ? -EREMOTEIO : 0; } @@ -113,7 +113,7 @@ static u8 stv0299_readreg (struct stv0299_state* state, u8 reg) if (ret != 2) dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", - __FUNCTION__, reg, ret); + __func__, reg, ret); return b1[0]; } @@ -127,14 +127,14 @@ static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len ret = i2c_transfer (state->i2c, msg, 2); if (ret != 2) - dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); + dprintk("%s: readreg error (ret == %i)\n", __func__, ret); return ret == 2 ? 0 : ret; } static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) { - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); switch (fec) { case FEC_AUTO: @@ -174,7 +174,7 @@ static fe_code_rate_t stv0299_get_fec (struct stv0299_state* state) FEC_7_8, FEC_1_2 }; u8 index; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); index = stv0299_readreg (state, 0x1b); index &= 0x7; @@ -189,11 +189,11 @@ static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout) { unsigned long start = jiffies; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); while (stv0299_readreg(state, 0x0a) & 1) { if (jiffies - start > timeout) { - dprintk ("%s: timeout!!\n", __FUNCTION__); + dprintk ("%s: timeout!!\n", __func__); return -ETIMEDOUT; } msleep(10); @@ -206,11 +206,11 @@ static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout) { unsigned long start = jiffies; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) { if (jiffies - start > timeout) { - dprintk ("%s: timeout!!\n", __FUNCTION__); + dprintk ("%s: timeout!!\n", __func__); return -ETIMEDOUT; } msleep(10); @@ -245,7 +245,7 @@ static int stv0299_get_symbolrate (struct stv0299_state* state) u8 sfr[3]; s8 rtf; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); stv0299_readregs (state, 0x1f, sfr, 3); stv0299_readregs (state, 0x1a, (u8 *)&rtf, 1); @@ -257,8 +257,8 @@ static int stv0299_get_symbolrate (struct stv0299_state* state) offset = (s32) rtf * (srate / 4096L); offset /= 128; - dprintk ("%s : srate = %i\n", __FUNCTION__, srate); - dprintk ("%s : ofset = %i\n", __FUNCTION__, offset); + dprintk ("%s : srate = %i\n", __func__, srate); + dprintk ("%s : ofset = %i\n", __func__, offset); srate += offset; @@ -276,7 +276,7 @@ static int stv0299_send_diseqc_msg (struct dvb_frontend* fe, u8 val; int i; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (stv0299_wait_diseqc_idle (state, 100) < 0) return -ETIMEDOUT; @@ -305,7 +305,7 @@ static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t struct stv0299_state* state = fe->demodulator_priv; u8 val; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (stv0299_wait_diseqc_idle (state, 100) < 0) return -ETIMEDOUT; @@ -355,7 +355,7 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag u8 reg0x08; u8 reg0x0c; - dprintk("%s: %s\n", __FUNCTION__, + dprintk("%s: %s\n", __func__, voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); @@ -366,26 +366,32 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag * H/V switching over OP0, OP1 and OP2 are LNB power enable bits */ reg0x0c &= 0x0f; - - if (voltage == SEC_VOLTAGE_OFF) { - stv0299_writeregI (state, 0x0c, 0x00); /* LNB power off! */ - return stv0299_writeregI (state, 0x08, 0x00); /* LNB power off! */ - } - - stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6)); + reg0x08 = (reg0x08 & 0x3f) | (state->config->lock_output << 6); switch (voltage) { case SEC_VOLTAGE_13: - if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0) reg0x0c |= 0x10; - else reg0x0c |= 0x40; - - return stv0299_writeregI(state, 0x0c, reg0x0c); - + if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0) + reg0x0c |= 0x10; /* OP1 off, OP0 on */ + else + reg0x0c |= 0x40; /* OP1 on, OP0 off */ + break; case SEC_VOLTAGE_18: - return stv0299_writeregI(state, 0x0c, reg0x0c | 0x50); + reg0x0c |= 0x50; /* OP1 on, OP0 on */ + break; + case SEC_VOLTAGE_OFF: + /* LNB power off! */ + reg0x08 = 0x00; + reg0x0c = 0x00; + break; default: return -EINVAL; }; + + if (state->config->op0_off) + reg0x0c &= ~0x10; + + stv0299_writeregI(state, 0x08, reg0x08); + return stv0299_writeregI(state, 0x0c, reg0x0c); } static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd) @@ -408,7 +414,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd = cmd << 1; if (debug_legacy_dish_switch) - printk ("%s switch command: 0x%04lx\n",__FUNCTION__, cmd); + printk ("%s switch command: 0x%04lx\n",__func__, cmd); do_gettimeofday (&nexttime); if (debug_legacy_dish_switch) @@ -433,7 +439,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long } if (debug_legacy_dish_switch) { printk ("%s(%d): switch delay (should be 32k followed by all 8k\n", - __FUNCTION__, fe->dvb->num); + __func__, fe->dvb->num); for (i = 1; i < 10; i++) printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i])); } @@ -445,11 +451,20 @@ static int stv0299_init (struct dvb_frontend* fe) { struct stv0299_state* state = fe->demodulator_priv; int i; + u8 reg; + u8 val; dprintk("stv0299: init chip\n"); - for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2) - stv0299_writeregI(state, state->config->inittab[i], state->config->inittab[i+1]); + for (i = 0; ; i += 2) { + reg = state->config->inittab[i]; + val = state->config->inittab[i+1]; + if (reg == 0xff && val == 0xff) + break; + if (reg == 0x0c && state->config->op0_off) + val &= ~0x10; + stv0299_writeregI(state, reg, val); + } return 0; } @@ -461,7 +476,7 @@ static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status) u8 signal = 0xff - stv0299_readreg (state, 0x18); u8 sync = stv0299_readreg (state, 0x1b); - dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __FUNCTION__, sync); + dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync); *status = 0; if (signal > 10) @@ -499,7 +514,7 @@ static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength) s32 signal = 0xffff - ((stv0299_readreg (state, 0x18) << 8) | stv0299_readreg (state, 0x19)); - dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __FUNCTION__, + dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __func__, stv0299_readreg (state, 0x18), stv0299_readreg (state, 0x19), (int) signal); @@ -536,7 +551,7 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par struct stv0299_state* state = fe->demodulator_priv; int invval = 0; - dprintk ("%s : FE_SET_FRONTEND\n", __FUNCTION__); + dprintk ("%s : FE_SET_FRONTEND\n", __func__); // set the inversion if (p->inversion == INVERSION_OFF) invval = 0; diff --git a/linux/drivers/media/dvb/frontends/stv0299.h b/linux/drivers/media/dvb/frontends/stv0299.h index 33df94959..3282f4302 100644 --- a/linux/drivers/media/dvb/frontends/stv0299.h +++ b/linux/drivers/media/dvb/frontends/stv0299.h @@ -48,10 +48,10 @@ #include <linux/dvb/frontend.h> #include "dvb_frontend.h" -#define STV0229_LOCKOUTPUT_0 0 -#define STV0229_LOCKOUTPUT_1 1 -#define STV0229_LOCKOUTPUT_CF 2 -#define STV0229_LOCKOUTPUT_LK 3 +#define STV0299_LOCKOUTPUT_0 0 +#define STV0299_LOCKOUTPUT_1 1 +#define STV0299_LOCKOUTPUT_CF 2 +#define STV0299_LOCKOUTPUT_LK 3 #define STV0299_VOLT13_OP0 0 #define STV0299_VOLT13_OP1 1 @@ -82,6 +82,9 @@ struct stv0299_config /* Is 13v controlled by OP0 or OP1? */ u8 volt13_op0_op1:1; + /* Turn-off OP0? */ + u8 op0_off:1; + /* minimum delay before retuning */ int min_delay_ms; @@ -96,7 +99,7 @@ extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, static inline struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_STV0299 diff --git a/linux/drivers/media/dvb/frontends/tda10021.c b/linux/drivers/media/dvb/frontends/tda10021.c index 68a1103c9..c6f90f33a 100644 --- a/linux/drivers/media/dvb/frontends/tda10021.c +++ b/linux/drivers/media/dvb/frontends/tda10021.c @@ -79,7 +79,7 @@ static int _tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data) if (ret != 1) printk("DVB: TDA10021(%d): %s, writereg error " "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", - state->frontend.dvb->num, __FUNCTION__, reg, data, ret); + state->frontend.dvb->num, __func__, reg, data, ret); msleep(10); return (ret != 1) ? -EREMOTEIO : 0; @@ -97,7 +97,7 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) // Don't print an error message if the id is read. if (ret != 2 && reg != 0x1a) printk("DVB: TDA10021: %s: readreg error (ret == %i)\n", - __FUNCTION__, ret); + __func__, ret); return b1[0]; } diff --git a/linux/drivers/media/dvb/frontends/tda10023.c b/linux/drivers/media/dvb/frontends/tda10023.c index b565bc2d7..3195a80a9 100644 --- a/linux/drivers/media/dvb/frontends/tda10023.c +++ b/linux/drivers/media/dvb/frontends/tda10023.c @@ -122,7 +122,7 @@ static u8 tda10023_readreg (struct tda10023_state* state, u8 reg) ret = i2c_transfer (state->i2c, msg, 2); if (ret != 2) printk("DVB: TDA10023: %s: readreg error (ret == %i)\n", - __FUNCTION__, ret); + __func__, ret); return b1[0]; } @@ -136,7 +136,7 @@ static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data) if (ret != 1) printk("DVB: TDA10023(%d): %s, writereg error " "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", - state->frontend.dvb->num, __FUNCTION__, reg, data, ret); + state->frontend.dvb->num, __func__, reg, data, ret); return (ret != 1) ? -EREMOTEIO : 0; } diff --git a/linux/drivers/media/dvb/frontends/tda1002x.h b/linux/drivers/media/dvb/frontends/tda1002x.h index e9094d812..1bcc0d44b 100644 --- a/linux/drivers/media/dvb/frontends/tda1002x.h +++ b/linux/drivers/media/dvb/frontends/tda1002x.h @@ -40,7 +40,7 @@ extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, struct i2c_adapter* i2c, u8 pwm) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_TDA10021 @@ -52,7 +52,7 @@ extern struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config static inline struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, struct i2c_adapter* i2c, u8 pwm) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_TDA10023 diff --git a/linux/drivers/media/dvb/frontends/tda10048.c b/linux/drivers/media/dvb/frontends/tda10048.c new file mode 100644 index 000000000..2b9b1d93c --- /dev/null +++ b/linux/drivers/media/dvb/frontends/tda10048.c @@ -0,0 +1,710 @@ +/* + NXP TDA10048HN DVB OFDM demodulator driver + + Copyright (C) 2008 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. + +*/ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include "dvb_frontend.h" +#include "tda10048.h" + +#define TDA10048_DEFAULT_FIRMWARE "dvb-fe-tda10048-1.0.fw" +#define TDA10048_DEFAULT_FIRMWARE_SIZE 24878 + +/* Register name definitions */ +#define TDA10048_IDENTITY 0x00 +#define TDA10048_VERSION 0x01 +#define TDA10048_DSP_CODE_CPT 0x0C +#define TDA10048_DSP_CODE_IN 0x0E +#define TDA10048_IN_CONF1 0x10 +#define TDA10048_IN_CONF2 0x11 +#define TDA10048_IN_CONF3 0x12 +#define TDA10048_OUT_CONF1 0x14 +#define TDA10048_OUT_CONF2 0x15 +#define TDA10048_OUT_CONF3 0x16 +#define TDA10048_AUTO 0x18 +#define TDA10048_SYNC_STATUS 0x1A +#define TDA10048_CONF_C4_1 0x1E +#define TDA10048_CONF_C4_2 0x1F +#define TDA10048_CODE_IN_RAM 0x20 +#define TDA10048_CHANNEL_INFO_1_R 0x22 +#define TDA10048_CHANNEL_INFO_2_R 0x23 +#define TDA10048_CHANNEL_INFO1 0x24 +#define TDA10048_CHANNEL_INFO2 0x25 +#define TDA10048_TIME_ERROR_R 0x26 +#define TDA10048_TIME_ERROR 0x27 +#define TDA10048_FREQ_ERROR_LSB_R 0x28 +#define TDA10048_FREQ_ERROR_MSB_R 0x29 +#define TDA10048_FREQ_ERROR_LSB 0x2A +#define TDA10048_FREQ_ERROR_MSB 0x2B +#define TDA10048_IT_SEL 0x30 +#define TDA10048_IT_STAT 0x32 +#define TDA10048_DSP_AD_LSB 0x3C +#define TDA10048_DSP_AD_MSB 0x3D +#define TDA10048_DSP_REF_LSB 0x3E +#define TDA10048_DSP_REF_MSB 0x3F +#define TDA10048_CONF_TRISTATE1 0x44 +#define TDA10048_CONF_TRISTATE2 0x45 +#define TDA10048_CONF_POLARITY 0x46 +#define TDA10048_GPIO_SP_DS0 0x48 +#define TDA10048_GPIO_SP_DS1 0x49 +#define TDA10048_GPIO_SP_DS2 0x4A +#define TDA10048_GPIO_SP_DS3 0x4B +#define TDA10048_GPIO_OUT_SEL 0x4C +#define TDA10048_GPIO_SELECT 0x4D +#define TDA10048_IC_MODE 0x4E +#define TDA10048_CONF_XO 0x50 +#define TDA10048_CONF_PLL1 0x51 +#define TDA10048_CONF_PLL2 0x52 +#define TDA10048_CONF_PLL3 0x53 +#define TDA10048_CONF_ADC 0x54 +#define TDA10048_CONF_ADC_2 0x55 +#define TDA10048_CONF_C1_1 0x60 +#define TDA10048_CONF_C1_3 0x62 +#define TDA10048_AGC_CONF 0x70 +#define TDA10048_AGC_THRESHOLD_LSB 0x72 +#define TDA10048_AGC_THRESHOLD_MSB 0x73 +#define TDA10048_AGC_RENORM 0x74 +#define TDA10048_AGC_GAINS 0x76 +#define TDA10048_AGC_TUN_MIN 0x78 +#define TDA10048_AGC_TUN_MAX 0x79 +#define TDA10048_AGC_IF_MIN 0x7A +#define TDA10048_AGC_IF_MAX 0x7B +#define TDA10048_AGC_TUN_LEVEL 0x7E +#define TDA10048_AGC_IF_LEVEL 0x7F +#define TDA10048_DIG_AGC_LEVEL 0x81 +#define TDA10048_FREQ_PHY2_LSB 0x86 +#define TDA10048_FREQ_PHY2_MSB 0x87 +#define TDA10048_TIME_INVWREF_LSB 0x88 +#define TDA10048_TIME_INVWREF_MSB 0x89 +#define TDA10048_TIME_WREF_LSB 0x8A +#define TDA10048_TIME_WREF_MID1 0x8B +#define TDA10048_TIME_WREF_MID2 0x8C +#define TDA10048_TIME_WREF_MSB 0x8D +#define TDA10048_NP_OUT 0xA2 +#define TDA10048_CELL_ID_LSB 0xA4 +#define TDA10048_CELL_ID_MSB 0xA5 +#define TDA10048_EXTTPS_ODD 0xAA +#define TDA10048_EXTTPS_EVEN 0xAB +#define TDA10048_TPS_LENGTH 0xAC +#define TDA10048_FREE_REG_1 0xB2 +#define TDA10048_FREE_REG_2 0xB3 +#define TDA10048_CONF_C3_1 0xC0 +#define TDA10048_CYBER_CTRL 0xC2 +#define TDA10048_CBER_NMAX_LSB 0xC4 +#define TDA10048_CBER_NMAX_MSB 0xC5 +#define TDA10048_CBER_LSB 0xC6 +#define TDA10048_CBER_MSB 0xC7 +#define TDA10048_VBER_LSB 0xC8 +#define TDA10048_VBER_MID 0xC9 +#define TDA10048_VBER_MSB 0xCA +#define TDA10048_CYBER_LUT 0xCC +#define TDA10048_UNCOR_CTRL 0xCD +#define TDA10048_UNCOR_CPT_LSB 0xCE +#define TDA10048_UNCOR_CPT_MSB 0xCF +#define TDA10048_SOFT_IT_C3 0xD6 +#define TDA10048_CONF_TS2 0xE0 +#define TDA10048_CONF_TS1 0xE1 + +static unsigned int debug; + +#define dprintk(level, fmt, arg...)\ + do { if (debug >= level)\ + printk(KERN_DEBUG "tda10048: " fmt, ## arg);\ + } while (0) + +struct tda10048_state { + + struct i2c_adapter *i2c; + + /* configuration settings */ + const struct tda10048_config *config; + struct dvb_frontend frontend; + + int fwloaded; +}; + +static struct init_tab { + u8 reg; + u16 data; +} init_tab[] = { + { TDA10048_CONF_PLL1, 0x08 }, + { TDA10048_CONF_ADC_2, 0x00 }, + { TDA10048_CONF_C4_1, 0x00 }, + { TDA10048_CONF_PLL1, 0x0f }, + { TDA10048_CONF_PLL2, 0x0a }, + { TDA10048_CONF_PLL3, 0x43 }, + { TDA10048_FREQ_PHY2_LSB, 0x02 }, + { TDA10048_FREQ_PHY2_MSB, 0x0a }, + { TDA10048_TIME_WREF_LSB, 0xbd }, + { TDA10048_TIME_WREF_MID1, 0xe4 }, + { TDA10048_TIME_WREF_MID2, 0xa8 }, + { TDA10048_TIME_WREF_MSB, 0x02 }, + { TDA10048_TIME_INVWREF_LSB, 0x04 }, + { TDA10048_TIME_INVWREF_MSB, 0x06 }, + { TDA10048_CONF_C4_1, 0x00 }, + { TDA10048_CONF_C1_1, 0xa8 }, + { TDA10048_AGC_CONF, 0x16 }, + { TDA10048_CONF_C1_3, 0x0b }, + { TDA10048_AGC_TUN_MIN, 0x00 }, + { TDA10048_AGC_TUN_MAX, 0xff }, + { TDA10048_AGC_IF_MIN, 0x00 }, + { TDA10048_AGC_IF_MAX, 0xff }, + { TDA10048_AGC_THRESHOLD_MSB, 0x00 }, + { TDA10048_AGC_THRESHOLD_LSB, 0x70 }, + { TDA10048_CYBER_CTRL, 0x38 }, + { TDA10048_AGC_GAINS, 0x12 }, + { TDA10048_CONF_XO, 0x00 }, + { TDA10048_CONF_TS1, 0x07 }, + { TDA10048_IC_MODE, 0x00 }, + { TDA10048_CONF_TS2, 0xc0 }, + { TDA10048_CONF_TRISTATE1, 0x21 }, + { TDA10048_CONF_TRISTATE2, 0x00 }, + { TDA10048_CONF_POLARITY, 0x00 }, + { TDA10048_CONF_C4_2, 0x04 }, + { TDA10048_CONF_ADC, 0x60 }, + { TDA10048_CONF_ADC_2, 0x10 }, + { TDA10048_CONF_ADC, 0x60 }, + { TDA10048_CONF_ADC_2, 0x00 }, + { TDA10048_CONF_C1_1, 0xa8 }, + { TDA10048_UNCOR_CTRL, 0x00 }, + { TDA10048_CONF_C4_2, 0x04 }, +}; + +static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) +{ + int ret; + u8 buf [] = { reg, data }; + struct i2c_msg msg = { + .addr = state->config->demod_address, + .flags = 0, .buf = buf, .len = 2 }; + + dprintk(2, "%s(reg = 0x%02x, data = 0x%02x)\n", __func__, reg, data); + + ret = i2c_transfer(state->i2c, &msg, 1); + + if (ret != 1) + printk("%s: writereg error (ret == %i)\n", __func__, ret); + + return (ret != 1) ? -1 : 0; +} + +static u8 tda10048_readreg(struct tda10048_state *state, u8 reg) +{ + int ret; + u8 b0 [] = { reg }; + u8 b1 [] = { 0 }; + struct i2c_msg msg [] = { + { .addr = state->config->demod_address, + .flags = 0, .buf = b0, .len = 1 }, + { .addr = state->config->demod_address, + .flags = I2C_M_RD, .buf = b1, .len = 1 } }; + + dprintk(2, "%s(reg = 0x%02x)\n", __func__, reg); + + ret = i2c_transfer(state->i2c, msg, 2); + + if (ret != 2) + printk(KERN_ERR "%s: readreg error (ret == %i)\n", + __func__, ret); + + return b1[0]; +} + +static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg, + u8 *data, u16 len) +{ + int ret = -EREMOTEIO; + struct i2c_msg msg; + u8 *buf; + + dprintk(2, "%s(%d, ?, len = %d)\n", __func__, reg, len); + + buf = kmalloc(len + 1, GFP_KERNEL); + if (buf == NULL) { + ret = -ENOMEM; + goto error; + } + + *buf = reg; + memcpy(buf + 1, data, len); + + msg.addr = state->config->demod_address; + msg.flags = 0; + msg.buf = buf; + msg.len = len + 1; + + dprintk(2, "%s(): write len = %d\n", + __func__, msg.len); + + ret = i2c_transfer(state->i2c, &msg, 1); + if (ret != 1) { + printk(KERN_ERR "%s(): writereg error err %i\n", + __func__, ret); + ret = -EREMOTEIO; + } + +error: + kfree(buf); + + return ret; +} + +static int tda10048_firmware_upload(struct dvb_frontend *fe) +{ + struct tda10048_state *state = fe->demodulator_priv; + const struct firmware *fw; + int ret; + int pos = 0; + int cnt; + u8 wlen = state->config->fwbulkwritelen; + + if ((wlen != TDA10048_BULKWRITE_200) && (wlen != TDA10048_BULKWRITE_50)) + wlen = TDA10048_BULKWRITE_200; + + /* request the firmware, this will block and timeout */ + printk(KERN_INFO "%s: waiting for firmware upload (%s)...\n", + __func__, + TDA10048_DEFAULT_FIRMWARE); + + ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE, + &state->i2c->dev); + if (ret) { + printk(KERN_ERR "%s: Upload failed. (file not found?)\n", + __func__); + return -EIO; + } else { + printk(KERN_INFO "%s: firmware read %Zu bytes.\n", + __func__, + fw->size); + ret = 0; + } + + if (fw->size != TDA10048_DEFAULT_FIRMWARE_SIZE) { + printk(KERN_ERR "%s: firmware incorrect size\n", __func__); + return -EIO; + } else { + printk(KERN_INFO "%s: firmware uploading\n", __func__); + + /* Soft reset */ + tda10048_writereg(state, TDA10048_CONF_TRISTATE1, + tda10048_readreg(state, TDA10048_CONF_TRISTATE1) + & 0xfe); + tda10048_writereg(state, TDA10048_CONF_TRISTATE1, + tda10048_readreg(state, TDA10048_CONF_TRISTATE1) + | 0x01); + + /* Put the demod into host download mode */ + tda10048_writereg(state, TDA10048_CONF_C4_1, + tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xf9); + + /* Boot the DSP */ + tda10048_writereg(state, TDA10048_CONF_C4_1, + tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x08); + + /* Prepare for download */ + tda10048_writereg(state, TDA10048_DSP_CODE_CPT, 0); + + /* Download the firmware payload */ + while (pos < fw->size) { + + if ((fw->size - pos) > wlen) + cnt = wlen; + else + cnt = fw->size - pos; + + tda10048_writeregbulk(state, TDA10048_DSP_CODE_IN, + &fw->data[pos], cnt); + + pos += cnt; + } + + ret = -EIO; + /* Wait up to 250ms for the DSP to boot */ + for (cnt = 0; cnt < 250 ; cnt += 10) { + + msleep(10); + + if (tda10048_readreg(state, TDA10048_SYNC_STATUS) + & 0x40) { + ret = 0; + break; + } + } + } + + release_firmware(fw); + + if (ret == 0) { + printk(KERN_INFO "%s: firmware uploaded\n", __func__); + state->fwloaded = 1; + } else + printk(KERN_ERR "%s: firmware upload failed\n", __func__); + + return ret; +} + +static int tda10048_set_inversion(struct dvb_frontend *fe, int inversion) +{ + struct tda10048_state *state = fe->demodulator_priv; + + dprintk(1, "%s(%d)\n", __func__, inversion); + + if (inversion == TDA10048_INVERSION_ON) + tda10048_writereg(state, TDA10048_CONF_C1_1, + tda10048_readreg(state, TDA10048_CONF_C1_1) | 0x20); + else + tda10048_writereg(state, TDA10048_CONF_C1_1, + tda10048_readreg(state, TDA10048_CONF_C1_1) & 0xdf); + + return 0; +} + +/* Retrieve the demod settings */ +static int tda10048_get_tps(struct tda10048_state *state, + struct dvb_ofdm_parameters *p) +{ + u8 val; + + /* Make sure the TPS regs are valid */ + if (!(tda10048_readreg(state, TDA10048_AUTO) & 0x01)) + return -EAGAIN; + + val = tda10048_readreg(state, TDA10048_OUT_CONF2); + switch ((val & 0x60) >> 5) { + case 0: p->constellation = QPSK; break; + case 1: p->constellation = QAM_16; break; + case 2: p->constellation = QAM_64; break; + } + switch ((val & 0x18) >> 3) { + case 0: p->hierarchy_information = HIERARCHY_NONE; break; + case 1: p->hierarchy_information = HIERARCHY_1; break; + case 2: p->hierarchy_information = HIERARCHY_2; break; + case 3: p->hierarchy_information = HIERARCHY_4; break; + } + switch (val & 0x07) { + case 0: p->code_rate_HP = FEC_1_2; break; + case 1: p->code_rate_HP = FEC_2_3; break; + case 2: p->code_rate_HP = FEC_3_4; break; + case 3: p->code_rate_HP = FEC_5_6; break; + case 4: p->code_rate_HP = FEC_7_8; break; + } + + val = tda10048_readreg(state, TDA10048_OUT_CONF3); + switch (val & 0x07) { + case 0: p->code_rate_LP = FEC_1_2; break; + case 1: p->code_rate_LP = FEC_2_3; break; + case 2: p->code_rate_LP = FEC_3_4; break; + case 3: p->code_rate_LP = FEC_5_6; break; + case 4: p->code_rate_LP = FEC_7_8; break; + } + + val = tda10048_readreg(state, TDA10048_OUT_CONF1); + switch ((val & 0x0c) >> 2) { + case 0: p->guard_interval = GUARD_INTERVAL_1_32; break; + case 1: p->guard_interval = GUARD_INTERVAL_1_16; break; + case 2: p->guard_interval = GUARD_INTERVAL_1_8; break; + case 3: p->guard_interval = GUARD_INTERVAL_1_4; break; + } + switch (val & 0x02) { + case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break; + case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break; + } + + return 0; +} + +static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct tda10048_state *state = fe->demodulator_priv; + dprintk(1, "%s(%d)\n", __func__, enable); + + if (enable) + return tda10048_writereg(state, TDA10048_CONF_C4_1, + tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02); + else + return tda10048_writereg(state, TDA10048_CONF_C4_1, + tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xfd); +} + +static int tda10048_output_mode(struct dvb_frontend *fe, int serial) +{ + struct tda10048_state *state = fe->demodulator_priv; + dprintk(1, "%s(%d)\n", __func__, serial); + + /* Ensure pins are out of tri-state */ + tda10048_writereg(state, TDA10048_CONF_TRISTATE1, 0x21); + tda10048_writereg(state, TDA10048_CONF_TRISTATE2, 0x00); + + if (serial) { + tda10048_writereg(state, TDA10048_IC_MODE, 0x80 | 0x20); + tda10048_writereg(state, TDA10048_CONF_TS2, 0xc0); + } else { + tda10048_writereg(state, TDA10048_IC_MODE, 0x00); + tda10048_writereg(state, TDA10048_CONF_TS2, 0x01); + } + + return 0; +} + +/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ +/* TODO: Support manual tuning with specific params */ +static int tda10048_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct tda10048_state *state = fe->demodulator_priv; + + dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency); + + if (fe->ops.tuner_ops.set_params) { + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + fe->ops.tuner_ops.set_params(fe, p); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + + /* Enable demod TPS auto detection and begin acquisition */ + tda10048_writereg(state, TDA10048_AUTO, 0x57); + + return 0; +} + +/* Establish sane defaults and load firmware. */ +static int tda10048_init(struct dvb_frontend *fe) +{ + struct tda10048_state *state = fe->demodulator_priv; + int ret = 0, i; + + dprintk(1, "%s()\n", __func__); + + /* Apply register defaults */ + for (i = 0; i < ARRAY_SIZE(init_tab); i++) + tda10048_writereg(state, init_tab[i].reg, init_tab[i].data); + + if (state->fwloaded == 0) + ret = tda10048_firmware_upload(fe); + + /* Set either serial or parallel */ + tda10048_output_mode(fe, state->config->output_mode); + + /* set inversion */ + tda10048_set_inversion(fe, state->config->inversion); + + /* Ensure we leave the gate closed */ + tda10048_i2c_gate_ctrl(fe, 0); + + return ret; +} + +static int tda10048_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct tda10048_state *state = fe->demodulator_priv; + u8 reg; + + *status = 0; + + reg = tda10048_readreg(state, TDA10048_SYNC_STATUS); + + dprintk(1, "%s() status =0x%02x\n", __func__, reg); + + if (reg & 0x02) + *status |= FE_HAS_CARRIER; + + if (reg & 0x04) + *status |= FE_HAS_SIGNAL; + + if (reg & 0x08) { + *status |= FE_HAS_LOCK; + *status |= FE_HAS_VITERBI; + *status |= FE_HAS_SYNC; + } + + return 0; +} + +static int tda10048_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct tda10048_state *state = fe->demodulator_priv; + + dprintk(1, "%s()\n", __func__); + + /* TODO: A reset may be required here */ + *ber = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 | + tda10048_readreg(state, TDA10048_CBER_LSB); + + return 0; +} + +static int tda10048_read_signal_strength(struct dvb_frontend *fe, + u16 *signal_strength) +{ + struct tda10048_state *state = fe->demodulator_priv; + u16 v; + + dprintk(1, "%s()\n", __func__); + + v = tda10048_readreg(state, TDA10048_NP_OUT); + if (v == 0) + *signal_strength = 100; + else { + /* TODO: Apply .db math for correct values */ + *signal_strength = v; + } + + return 0; +} + +static int tda10048_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct tda10048_state *state = fe->demodulator_priv; + + dprintk(1, "%s()\n", __func__); + + /* TODO: This result should be the same as signal strength */ + *snr = tda10048_readreg(state, TDA10048_NP_OUT); + + return 0; +} + +static int tda10048_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct tda10048_state *state = fe->demodulator_priv; + + dprintk(1, "%s()\n", __func__); +#if 0 + /* Reset and begin counting */ + tda10048_writereg(state, TDA10048_UNCOR_CTRL, 0x01); + msleep(10); +#endif + + *ucblocks = tda10048_readreg(state, TDA10048_UNCOR_CPT_MSB) << 8 | + tda10048_readreg(state, TDA10048_UNCOR_CPT_LSB); + + return 0; +} + +static int tda10048_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct tda10048_state *state = fe->demodulator_priv; + + dprintk(1, "%s()\n", __func__); + + p->inversion = tda10048_readreg(state, TDA10048_CONF_C1_1) + & 0x20 ? INVERSION_ON : INVERSION_OFF; + + return tda10048_get_tps(state, &p->u.ofdm); +} + +static int tda10048_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *tune) +{ + tune->min_delay_ms = 1000; + return 0; +} + +static void tda10048_release(struct dvb_frontend *fe) +{ + struct tda10048_state *state = fe->demodulator_priv; + dprintk(1, "%s()\n", __func__); + kfree(state); +} + +static struct dvb_frontend_ops tda10048_ops; + +struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, + struct i2c_adapter *i2c) +{ + struct tda10048_state *state = NULL; + + dprintk(1, "%s()\n", __func__); + + /* allocate memory for the internal state */ + state = kmalloc(sizeof(struct tda10048_state), GFP_KERNEL); + if (state == NULL) + goto error; + + /* setup the state */ + state->config = config; + state->i2c = i2c; + state->fwloaded = 0; + + /* check if the demod is present */ + if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048) + goto error; + + /* create dvb_frontend */ + memcpy(&state->frontend.ops, &tda10048_ops, + sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + + /* Leave the gate closed */ + tda10048_i2c_gate_ctrl(&state->frontend, 0); + + return &state->frontend; + +error: + kfree(state); + return NULL; +} +EXPORT_SYMBOL(tda10048_attach); + +static struct dvb_frontend_ops tda10048_ops = { + + .info = { + .name = "NXP TDA10048HN DVB-T", + .type = FE_OFDM, + .frequency_min = 177000000, + .frequency_max = 858000000, + .frequency_stepsize = 166666, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER + }, + + .release = tda10048_release, + .init = tda10048_init, + .i2c_gate_ctrl = tda10048_i2c_gate_ctrl, + .set_frontend = tda10048_set_frontend, + .get_frontend = tda10048_get_frontend, + .get_tune_settings = tda10048_get_tune_settings, + .read_status = tda10048_read_status, + .read_ber = tda10048_read_ber, + .read_signal_strength = tda10048_read_signal_strength, + .read_snr = tda10048_read_snr, + .read_ucblocks = tda10048_read_ucblocks, +}; + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Enable verbose debug messages"); + +MODULE_DESCRIPTION("NXP TDA10048HN DVB-T Demodulator driver"); +MODULE_AUTHOR("Steven Toth"); +MODULE_LICENSE("GPL"); + diff --git a/linux/drivers/media/dvb/frontends/tda10048.h b/linux/drivers/media/dvb/frontends/tda10048.h new file mode 100644 index 000000000..2b5c78e62 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/tda10048.h @@ -0,0 +1,63 @@ +/* + NXP TDA10048HN DVB OFDM demodulator driver + + Copyright (C) 2008 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 TDA10048_H +#define TDA10048_H + +#include <linux/dvb/frontend.h> +#include <linux/firmware.h> + +struct tda10048_config { + + /* the demodulator's i2c address */ + u8 demod_address; + + /* serial/parallel output */ +#define TDA10048_PARALLEL_OUTPUT 0 +#define TDA10048_SERIAL_OUTPUT 1 + u8 output_mode; + +#define TDA10048_BULKWRITE_200 200 +#define TDA10048_BULKWRITE_50 50 + u8 fwbulkwritelen; + + /* Spectral Inversion */ +#define TDA10048_INVERSION_OFF 0 +#define TDA10048_INVERSION_ON 1 + u8 inversion; +}; + +#if defined(CONFIG_DVB_TDA10048) || \ + (defined(CONFIG_DVB_TDA10048_MODULE) && defined(MODULE)) +extern struct dvb_frontend *tda10048_attach( + const struct tda10048_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend *tda10048_attach( + const struct tda10048_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_TDA10048 */ + +#endif /* TDA10048_H */ diff --git a/linux/drivers/media/dvb/frontends/tda1004x.c b/linux/drivers/media/dvb/frontends/tda1004x.c index 8415a8a52..499738463 100644 --- a/linux/drivers/media/dvb/frontends/tda1004x.c +++ b/linux/drivers/media/dvb/frontends/tda1004x.c @@ -131,16 +131,16 @@ static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data) u8 buf[] = { reg, data }; struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 }; - dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data); + dprintk("%s: reg=0x%x, data=0x%x\n", __func__, reg, data); msg.addr = state->config->demod_address; ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n", - __FUNCTION__, reg, data, ret); + __func__, reg, data, ret); - dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__, + dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__, reg, data, ret); return (ret != 1) ? -1 : 0; } @@ -153,19 +153,19 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg) struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 }, { .flags = I2C_M_RD, .buf = b1, .len = 1 }}; - dprintk("%s: reg=0x%x\n", __FUNCTION__, reg); + dprintk("%s: reg=0x%x\n", __func__, reg); msg[0].addr = state->config->demod_address; msg[1].addr = state->config->demod_address; ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) { - dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg, + dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret); return -1; } - dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__, + dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__, reg, b1[0], ret); return b1[0]; } @@ -173,7 +173,7 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg) static int tda1004x_write_mask(struct tda1004x_state *state, int reg, int mask, int data) { int val; - dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __FUNCTION__, reg, + dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __func__, reg, mask, data); // read a byte and check @@ -194,7 +194,7 @@ static int tda1004x_write_buf(struct tda1004x_state *state, int reg, unsigned ch int i; int result; - dprintk("%s: reg=0x%x, len=0x%x\n", __FUNCTION__, reg, len); + dprintk("%s: reg=0x%x, len=0x%x\n", __func__, reg, len); result = 0; for (i = 0; i < len; i++) { @@ -209,7 +209,7 @@ static int tda1004x_write_buf(struct tda1004x_state *state, int reg, unsigned ch static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state) { int result; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2); msleep(20); @@ -218,7 +218,7 @@ static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state) static int tda1004x_disable_tuner_i2c(struct tda1004x_state *state) { - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); return tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 0); } @@ -345,7 +345,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state, } pos += tx_size; - dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos); + dprintk("%s: fw_pos=0x%x\n", __func__, pos); } // give the DSP a chance to settle 03/10/05 Hac msleep(100); @@ -444,10 +444,10 @@ static void tda10046_init_plls(struct dvb_frontend* fe) tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3 } if (state->config->xtal_freq == TDA10046_XTAL_4M ) { - dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); + dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __func__); tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 } else { - dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__); + dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __func__); tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3 } if(tda10046_clk53m) @@ -488,7 +488,7 @@ static int tda10046_fwupload(struct dvb_frontend* fe) if (state->config->xtal_freq == TDA10046_XTAL_4M) { tda1004x_write_byteI(state, TDA1004X_CONFC4, 0); } else { - dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __FUNCTION__); + dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__); tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); } tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); @@ -594,7 +594,7 @@ static int tda10045_init(struct dvb_frontend* fe) { struct tda1004x_state* state = fe->demodulator_priv; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); if (tda10045_fwupload(fe)) { printk("tda1004x: firmware upload failed\n"); @@ -624,7 +624,7 @@ static int tda10045_init(struct dvb_frontend* fe) static int tda10046_init(struct dvb_frontend* fe) { struct tda1004x_state* state = fe->demodulator_priv; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); if (tda10046_fwupload(fe)) { printk("tda1004x: firmware upload failed\n"); @@ -686,7 +686,7 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, int tmp; int inversion; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); if (state->demod_type == TDA1004X_DEMOD_TDA10046) { // setup auto offset @@ -881,7 +881,7 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete { struct tda1004x_state* state = fe->demodulator_priv; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); // inversion status fe_params->inversion = INVERSION_OFF; @@ -989,7 +989,7 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status int cber; int vber; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); // read status status = tda1004x_read_byte(state, TDA1004X_STATUS_CD); @@ -1048,7 +1048,7 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status } // success - dprintk("%s: fe_status=0x%x\n", __FUNCTION__, *fe_status); + dprintk("%s: fe_status=0x%x\n", __func__, *fe_status); return 0; } @@ -1058,7 +1058,7 @@ static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal) int tmp; int reg = 0; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); // determine the register to use switch (state->demod_type) { @@ -1077,7 +1077,7 @@ static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal) return -EIO; *signal = (tmp << 8) | tmp; - dprintk("%s: signal=0x%x\n", __FUNCTION__, *signal); + dprintk("%s: signal=0x%x\n", __func__, *signal); return 0; } @@ -1086,7 +1086,7 @@ static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr) struct tda1004x_state* state = fe->demodulator_priv; int tmp; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); // read it tmp = tda1004x_read_byte(state, TDA1004X_SNR); @@ -1095,7 +1095,7 @@ static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr) tmp = 255 - tmp; *snr = ((tmp << 8) | tmp); - dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr); + dprintk("%s: snr=0x%x\n", __func__, *snr); return 0; } @@ -1106,7 +1106,7 @@ static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) int tmp2; int counter; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); // read the UCBLOCKS and reset counter = 0; @@ -1132,7 +1132,7 @@ static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) else *ucblocks = 0xffffffff; - dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks); + dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks); return 0; } @@ -1141,7 +1141,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber) struct tda1004x_state* state = fe->demodulator_priv; int tmp; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); // read it in tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB); @@ -1155,7 +1155,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber) // The address 0x20 should be read to cope with a TDA10046 bug tda1004x_read_byte(state, TDA1004X_CBER_RESET); - dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber); + dprintk("%s: ber=0x%x\n", __func__, *ber); return 0; } diff --git a/linux/drivers/media/dvb/frontends/tda1004x.h b/linux/drivers/media/dvb/frontends/tda1004x.h index ebb2c5f5a..4e27ffb0f 100644 --- a/linux/drivers/media/dvb/frontends/tda1004x.h +++ b/linux/drivers/media/dvb/frontends/tda1004x.h @@ -127,13 +127,13 @@ extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config static inline struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } static inline struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_TDA1004X diff --git a/linux/drivers/media/dvb/frontends/tda10086.c b/linux/drivers/media/dvb/frontends/tda10086.c index a4b48bdf2..c749f96c2 100644 --- a/linux/drivers/media/dvb/frontends/tda10086.c +++ b/linux/drivers/media/dvb/frontends/tda10086.c @@ -61,7 +61,7 @@ static int tda10086_write_byte(struct tda10086_state *state, int reg, int data) if (ret != 1) dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n", - __FUNCTION__, reg, data, ret); + __func__, reg, data, ret); return (ret != 1) ? ret : 0; } @@ -79,7 +79,7 @@ static int tda10086_read_byte(struct tda10086_state *state, int reg) ret = i2c_transfer(state->i2c, msg, 2); if (ret != 2) { - dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg, + dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret); return ret; } @@ -91,16 +91,16 @@ static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask, { int val; - // read a byte and check + /* read a byte and check */ val = tda10086_read_byte(state, reg); if (val < 0) return val; - // mask if off + /* mask if off */ val = val & ~mask; val |= data & 0xff; - // write it out again + /* write it out again */ return tda10086_write_byte(state, reg, val); } @@ -109,62 +109,67 @@ static int tda10086_init(struct dvb_frontend* fe) struct tda10086_state* state = fe->demodulator_priv; u8 t22k_off = 0x80; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (state->config->diseqc_tone) t22k_off = 0; - // reset + /* reset */ tda10086_write_byte(state, 0x00, 0x00); msleep(10); - // misc setup + /* misc setup */ tda10086_write_byte(state, 0x01, 0x94); - tda10086_write_byte(state, 0x02, 0x35); // NOTE: TT drivers appear to disable CSWP + tda10086_write_byte(state, 0x02, 0x35); /* NOTE: TT drivers appear to disable CSWP */ tda10086_write_byte(state, 0x03, 0xe4); tda10086_write_byte(state, 0x04, 0x43); tda10086_write_byte(state, 0x0c, 0x0c); - tda10086_write_byte(state, 0x1b, 0xb0); // noise threshold - tda10086_write_byte(state, 0x20, 0x89); // misc - tda10086_write_byte(state, 0x30, 0x04); // acquisition period length - tda10086_write_byte(state, 0x32, 0x00); // irq off - tda10086_write_byte(state, 0x31, 0x56); // setup AFC - - // setup PLL (assumes 16Mhz XIN) - tda10086_write_byte(state, 0x55, 0x2c); // misc PLL setup - tda10086_write_byte(state, 0x3a, 0x0b); // M=12 - tda10086_write_byte(state, 0x3b, 0x01); // P=2 - tda10086_write_mask(state, 0x55, 0x20, 0x00); // powerup PLL - - // setup TS interface + tda10086_write_byte(state, 0x1b, 0xb0); /* noise threshold */ + tda10086_write_byte(state, 0x20, 0x89); /* misc */ + tda10086_write_byte(state, 0x30, 0x04); /* acquisition period length */ + tda10086_write_byte(state, 0x32, 0x00); /* irq off */ + tda10086_write_byte(state, 0x31, 0x56); /* setup AFC */ + + /* setup PLL (this assumes SACLK = 96MHz) */ + tda10086_write_byte(state, 0x55, 0x2c); /* misc PLL setup */ + if (state->config->xtal_freq == TDA10086_XTAL_16M) { + tda10086_write_byte(state, 0x3a, 0x0b); /* M=12 */ + tda10086_write_byte(state, 0x3b, 0x01); /* P=2 */ + } else { + tda10086_write_byte(state, 0x3a, 0x17); /* M=24 */ + tda10086_write_byte(state, 0x3b, 0x00); /* P=1 */ + } + tda10086_write_mask(state, 0x55, 0x20, 0x00); /* powerup PLL */ + + /* setup TS interface */ tda10086_write_byte(state, 0x11, 0x81); tda10086_write_byte(state, 0x12, 0x81); - tda10086_write_byte(state, 0x19, 0x40); // parallel mode A + MSBFIRST - tda10086_write_byte(state, 0x56, 0x80); // powerdown WPLL - unused in the mode we use - tda10086_write_byte(state, 0x57, 0x08); // bypass WPLL - unused in the mode we use + tda10086_write_byte(state, 0x19, 0x40); /* parallel mode A + MSBFIRST */ + tda10086_write_byte(state, 0x56, 0x80); /* powerdown WPLL - unused in the mode we use */ + tda10086_write_byte(state, 0x57, 0x08); /* bypass WPLL - unused in the mode we use */ tda10086_write_byte(state, 0x10, 0x2a); - // setup ADC - tda10086_write_byte(state, 0x58, 0x61); // ADC setup - tda10086_write_mask(state, 0x58, 0x01, 0x00); // powerup ADC + /* setup ADC */ + tda10086_write_byte(state, 0x58, 0x61); /* ADC setup */ + tda10086_write_mask(state, 0x58, 0x01, 0x00); /* powerup ADC */ - // setup AGC + /* setup AGC */ tda10086_write_byte(state, 0x05, 0x0B); tda10086_write_byte(state, 0x37, 0x63); - tda10086_write_byte(state, 0x3f, 0x0a); // NOTE: flydvb varies it + tda10086_write_byte(state, 0x3f, 0x0a); /* NOTE: flydvb varies it */ tda10086_write_byte(state, 0x40, 0x64); tda10086_write_byte(state, 0x41, 0x4f); tda10086_write_byte(state, 0x42, 0x43); - // setup viterbi - tda10086_write_byte(state, 0x1a, 0x11); // VBER 10^6, DVB, QPSK + /* setup viterbi */ + tda10086_write_byte(state, 0x1a, 0x11); /* VBER 10^6, DVB, QPSK */ - // setup carrier recovery + /* setup carrier recovery */ tda10086_write_byte(state, 0x3d, 0x80); - // setup SEC - tda10086_write_byte(state, 0x36, t22k_off); // all SEC off, 22k tone - tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); // } tone frequency - tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); // } + /* setup SEC */ + tda10086_write_byte(state, 0x36, t22k_off); /* all SEC off, 22k tone */ + tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); + tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); return 0; } @@ -174,7 +179,7 @@ static void tda10086_diseqc_wait(struct tda10086_state *state) unsigned long timeout = jiffies + msecs_to_jiffies(200); while (!(tda10086_read_byte(state, 0x50) & 0x01)) { if(time_after(jiffies, timeout)) { - printk("%s: diseqc queue not ready, command may be lost.\n", __FUNCTION__); + printk("%s: diseqc queue not ready, command may be lost.\n", __func__); break; } msleep(10); @@ -186,7 +191,7 @@ static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) struct tda10086_state* state = fe->demodulator_priv; u8 t22k_off = 0x80; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (state->config->diseqc_tone) t22k_off = 0; @@ -212,7 +217,7 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe, u8 oldval; u8 t22k_off = 0x80; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (state->config->diseqc_tone) t22k_off = 0; @@ -240,7 +245,7 @@ static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minic u8 oldval = tda10086_read_byte(state, 0x36); u8 t22k_off = 0x80; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (state->config->diseqc_tone) t22k_off = 0; @@ -267,7 +272,7 @@ static int tda10086_set_inversion(struct tda10086_state *state, { u8 invval = 0x80; - dprintk ("%s %i %i\n", __FUNCTION__, fe_params->inversion, state->config->invert); + dprintk ("%s %i %i\n", __func__, fe_params->inversion, state->config->invert); switch(fe_params->inversion) { case INVERSION_OFF: @@ -301,9 +306,9 @@ static int tda10086_set_symbol_rate(struct tda10086_state *state, u32 bdri; u32 symbol_rate = fe_params->u.qpsk.symbol_rate; - dprintk ("%s %i\n", __FUNCTION__, symbol_rate); + dprintk ("%s %i\n", __func__, symbol_rate); - // setup the decimation and anti-aliasing filters.. + /* setup the decimation and anti-aliasing filters.. */ if (symbol_rate < (u32) (SACLK * 0.0137)) { dfn=4; afs=1; @@ -340,13 +345,13 @@ static int tda10086_set_symbol_rate(struct tda10086_state *state, byp=1; } - // calculate BDR + /* calculate BDR */ big = (1ULL<<21) * ((u64) symbol_rate/1000ULL) * (1ULL<<dfn); big += ((SACLK/1000ULL)-1ULL); do_div(big, (SACLK/1000ULL)); bdr = big & 0xfffff; - // calculate BDRI + /* calculate BDRI */ tmp = (1<<dfn)*(symbol_rate/1000); bdri = ((32 * (SACLK/1000)) + (tmp-1)) / tmp; @@ -367,7 +372,7 @@ static int tda10086_set_fec(struct tda10086_state *state, { u8 fecval; - dprintk ("%s %i\n", __FUNCTION__, fe_params->u.qpsk.fec_inner); + dprintk ("%s %i\n", __func__, fe_params->u.qpsk.fec_inner); switch(fe_params->u.qpsk.fec_inner) { case FEC_1_2: @@ -413,13 +418,13 @@ static int tda10086_set_frontend(struct dvb_frontend* fe, u32 freq = 0; int freqoff; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); - // modify parameters for tuning + /* modify parameters for tuning */ tda10086_write_byte(state, 0x02, 0x35); state->has_lock = false; - // set params + /* set params */ if (fe->ops.tuner_ops.set_params) { fe->ops.tuner_ops.set_params(fe, fe_params); if (fe->ops.i2c_gate_ctrl) @@ -431,7 +436,7 @@ static int tda10086_set_frontend(struct dvb_frontend* fe, fe->ops.i2c_gate_ctrl(fe, 0); } - // calcluate the frequency offset (in *Hz* not kHz) + /* calcluate the frequency offset (in *Hz* not kHz) */ freqoff = fe_params->frequency - freq; freqoff = ((1<<16) * freqoff) / (SACLK/1000); tda10086_write_byte(state, 0x3d, 0x80 | ((freqoff >> 8) & 0x7f)); @@ -444,7 +449,7 @@ static int tda10086_set_frontend(struct dvb_frontend* fe, if ((ret = tda10086_set_fec(state, fe_params)) < 0) return ret; - // soft reset + disable TS output until lock + /* soft reset + disable TS output until lock */ tda10086_write_mask(state, 0x10, 0x40, 0x40); tda10086_write_mask(state, 0x00, 0x01, 0x00); @@ -460,13 +465,13 @@ static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa int tmp; u64 tmp64; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); - // check for invalid symbol rate + /* check for invalid symbol rate */ if (fe_params->u.qpsk.symbol_rate < 500000) return -EINVAL; - // calculate the updated frequency (note: we convert from Hz->kHz) + /* calculate the updated frequency (note: we convert from Hz->kHz) */ tmp64 = tda10086_read_byte(state, 0x52); tmp64 |= (tda10086_read_byte(state, 0x51) << 8); if (tmp64 & 0x8000) @@ -475,7 +480,7 @@ static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa do_div(tmp64, (1ULL<<15) * (1ULL<<1)); fe_params->frequency = (int) state->frequency + (int) tmp64; - // the inversion + /* the inversion */ val = tda10086_read_byte(state, 0x0c); if (val & 0x80) { switch(val & 0x40) { @@ -506,7 +511,7 @@ static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa } } - // calculate the updated symbol rate + /* calculate the updated symbol rate */ tmp = tda10086_read_byte(state, 0x1d); if (tmp & 0x80) tmp |= 0xffffff00; @@ -514,7 +519,7 @@ static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa tmp = ((state->symbol_rate/1000) * tmp) / (1000000/1000); fe_params->u.qpsk.symbol_rate = state->symbol_rate + tmp; - // the FEC + /* the FEC */ val = (tda10086_read_byte(state, 0x0d) & 0x70) >> 4; switch(val) { case 0x00: @@ -551,7 +556,7 @@ static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status) struct tda10086_state* state = fe->demodulator_priv; u8 val; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); val = tda10086_read_byte(state, 0x0e); *fe_status = 0; @@ -567,7 +572,7 @@ static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status) *fe_status |= FE_HAS_LOCK; if (!state->has_lock) { state->has_lock = true; - // modify parameters for stable reception + /* modify parameters for stable reception */ tda10086_write_byte(state, 0x02, 0x00); } } @@ -580,7 +585,7 @@ static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal) struct tda10086_state* state = fe->demodulator_priv; u8 _str; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); _str = 0xff - tda10086_read_byte(state, 0x43); *signal = (_str << 8) | _str; @@ -593,7 +598,7 @@ static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr) struct tda10086_state* state = fe->demodulator_priv; u8 _snr; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); _snr = 0xff - tda10086_read_byte(state, 0x1c); *snr = (_snr << 8) | _snr; @@ -605,12 +610,12 @@ static int tda10086_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) { struct tda10086_state* state = fe->demodulator_priv; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); - // read it + /* read it */ *ucblocks = tda10086_read_byte(state, 0x18) & 0x7f; - // reset counter + /* reset counter */ tda10086_write_byte(state, 0x18, 0x00); tda10086_write_byte(state, 0x18, 0x80); @@ -621,9 +626,9 @@ static int tda10086_read_ber(struct dvb_frontend* fe, u32* ber) { struct tda10086_state* state = fe->demodulator_priv; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); - // read it + /* read it */ *ber = 0; *ber |= tda10086_read_byte(state, 0x15); *ber |= tda10086_read_byte(state, 0x16) << 8; @@ -636,7 +641,7 @@ static int tda10086_sleep(struct dvb_frontend* fe) { struct tda10086_state* state = fe->demodulator_priv; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); tda10086_write_mask(state, 0x00, 0x08, 0x08); @@ -647,7 +652,7 @@ static int tda10086_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) { struct tda10086_state* state = fe->demodulator_priv; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); if (enable) { tda10086_write_mask(state, 0x00, 0x10, 0x10); @@ -738,7 +743,7 @@ struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, { struct tda10086_state *state; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __func__); /* allocate memory for the internal state */ state = kmalloc(sizeof(struct tda10086_state), GFP_KERNEL); diff --git a/linux/drivers/media/dvb/frontends/tda10086.h b/linux/drivers/media/dvb/frontends/tda10086.h index eeceaeee7..61148c558 100644 --- a/linux/drivers/media/dvb/frontends/tda10086.h +++ b/linux/drivers/media/dvb/frontends/tda10086.h @@ -26,6 +26,11 @@ #include <linux/dvb/frontend.h> #include <linux/firmware.h> +enum tda10086_xtal { + TDA10086_XTAL_16M, + TDA10086_XTAL_4M +}; + struct tda10086_config { /* the demodulator's i2c address */ @@ -36,6 +41,9 @@ struct tda10086_config /* do we need the diseqc signal with carrier? */ u8 diseqc_tone; + + /* frequency of the reference xtal */ + enum tda10086_xtal xtal_freq; }; #if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE)) @@ -45,9 +53,9 @@ extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config static inline struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -#endif // CONFIG_DVB_TDA10086 +#endif /* CONFIG_DVB_TDA10086 */ -#endif // TDA10086_H +#endif /* TDA10086_H */ diff --git a/linux/drivers/media/dvb/frontends/tda18271-priv.h b/linux/drivers/media/dvb/frontends/tda18271-priv.h index 808b89c40..8ceeca081 100644 --- a/linux/drivers/media/dvb/frontends/tda18271-priv.h +++ b/linux/drivers/media/dvb/frontends/tda18271-priv.h @@ -148,7 +148,7 @@ extern int tda18271_debug; #define DBG_CAL 16 #define tda_printk(kern, fmt, arg...) \ - printk(kern "%s: " fmt, __FUNCTION__, ##arg) + printk(kern "%s: " fmt, __func__, ##arg) #define dprintk(kern, lvl, fmt, arg...) do {\ if (tda18271_debug & lvl) \ diff --git a/linux/drivers/media/dvb/frontends/tda18271.h b/linux/drivers/media/dvb/frontends/tda18271.h index b547318c9..0e7af8d05 100644 --- a/linux/drivers/media/dvb/frontends/tda18271.h +++ b/linux/drivers/media/dvb/frontends/tda18271.h @@ -91,7 +91,7 @@ static inline struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct tda18271_config *cfg) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif diff --git a/linux/drivers/media/dvb/frontends/tda8083.c b/linux/drivers/media/dvb/frontends/tda8083.c index 011b74f79..5b843b2e6 100644 --- a/linux/drivers/media/dvb/frontends/tda8083.c +++ b/linux/drivers/media/dvb/frontends/tda8083.c @@ -68,7 +68,7 @@ static int tda8083_writereg (struct tda8083_state* state, u8 reg, u8 data) if (ret != 1) dprintk ("%s: writereg error (reg %02x, ret == %i)\n", - __FUNCTION__, reg, ret); + __func__, reg, ret); return (ret != 1) ? -1 : 0; } @@ -83,7 +83,7 @@ static int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len if (ret != 2) dprintk ("%s: readreg error (reg %02x, ret == %i)\n", - __FUNCTION__, reg1, ret); + __func__, reg1, ret); return ret == 2 ? 0 : -1; } diff --git a/linux/drivers/media/dvb/frontends/tda8083.h b/linux/drivers/media/dvb/frontends/tda8083.h index 2d3307999..5a03c14a1 100644 --- a/linux/drivers/media/dvb/frontends/tda8083.h +++ b/linux/drivers/media/dvb/frontends/tda8083.h @@ -42,7 +42,7 @@ extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, static inline struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_TDA8083 diff --git a/linux/drivers/media/dvb/frontends/tda826x.c b/linux/drivers/media/dvb/frontends/tda826x.c index 71c486b4e..596fc4275 100644 --- a/linux/drivers/media/dvb/frontends/tda826x.c +++ b/linux/drivers/media/dvb/frontends/tda826x.c @@ -55,7 +55,7 @@ static int tda826x_sleep(struct dvb_frontend *fe) u8 buf [] = { 0x00, 0x8d }; struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 2 }; - dprintk("%s:\n", __FUNCTION__); + dprintk("%s:\n", __func__); if (!priv->has_loopthrough) buf[1] = 0xad; @@ -63,7 +63,7 @@ static int tda826x_sleep(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) { - dprintk("%s: i2c error\n", __FUNCTION__); + dprintk("%s: i2c error\n", __func__); } if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -76,13 +76,24 @@ static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_param struct tda826x_priv *priv = fe->tuner_priv; int ret; u32 div; + u32 ksyms; + u32 bandwidth; u8 buf [11]; struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 11 }; - dprintk("%s:\n", __FUNCTION__); + dprintk("%s:\n", __func__); div = (params->frequency + (1000-1)) / 1000; + /* BW = ((1 + RO) * SR/2 + 5) * 1.3 [SR in MSPS, BW in MHz] */ + /* with R0 = 0.35 and some transformations: */ + ksyms = params->u.qpsk.symbol_rate / 1000; + bandwidth = (878 * ksyms + 6500000) / 1000000 + 1; + if (bandwidth < 5) + bandwidth = 5; + else if (bandwidth > 36) + bandwidth = 36; + buf[0] = 0x00; // subaddress buf[1] = 0x09; // powerdown RSSI + the magic value 1 if (!priv->has_loopthrough) @@ -90,7 +101,7 @@ static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_param buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO buf[3] = div >> 7; buf[4] = div << 1; - buf[5] = 0x77; // baseband cut-off 19 MHz + buf[5] = ((bandwidth - 5) << 3) | 7; /* baseband cut-off */ buf[6] = 0xfe; // baseband gain 9 db + no RF attenuation buf[7] = 0x83; // charge pumps at high, tests off buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports. @@ -100,7 +111,7 @@ static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_param if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) { - dprintk("%s: i2c error\n", __FUNCTION__); + dprintk("%s: i2c error\n", __func__); } if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -139,7 +150,7 @@ struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2 }; int ret; - dprintk("%s:\n", __FUNCTION__); + dprintk("%s:\n", __func__); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); diff --git a/linux/drivers/media/dvb/frontends/tda826x.h b/linux/drivers/media/dvb/frontends/tda826x.h index ad9981195..89e97926a 100644 --- a/linux/drivers/media/dvb/frontends/tda826x.h +++ b/linux/drivers/media/dvb/frontends/tda826x.h @@ -45,7 +45,7 @@ static inline struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, int has_loopthrough) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_TDA826X diff --git a/linux/drivers/media/dvb/frontends/tda827x.h b/linux/drivers/media/dvb/frontends/tda827x.h index cd3032f98..b73c23570 100644 --- a/linux/drivers/media/dvb/frontends/tda827x.h +++ b/linux/drivers/media/dvb/frontends/tda827x.h @@ -61,7 +61,7 @@ static inline struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct tda827x_config *cfg) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_TDA827X diff --git a/linux/drivers/media/dvb/frontends/tua6100.c b/linux/drivers/media/dvb/frontends/tua6100.c index 34e7c93f3..dfa7fa150 100644 --- a/linux/drivers/media/dvb/frontends/tua6100.c +++ b/linux/drivers/media/dvb/frontends/tua6100.c @@ -59,7 +59,7 @@ static int tua6100_sleep(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) { - printk("%s: i2c error\n", __FUNCTION__); + printk("%s: i2c error\n", __func__); } if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); diff --git a/linux/drivers/media/dvb/frontends/tua6100.h b/linux/drivers/media/dvb/frontends/tua6100.h index 03a665e7d..f83dbd5e4 100644 --- a/linux/drivers/media/dvb/frontends/tua6100.h +++ b/linux/drivers/media/dvb/frontends/tua6100.h @@ -39,7 +39,7 @@ extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, st #else static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_TUA6100 diff --git a/linux/drivers/media/dvb/frontends/ves1820.c b/linux/drivers/media/dvb/frontends/ves1820.c index 8791701c8..a184597f1 100644 --- a/linux/drivers/media/dvb/frontends/ves1820.c +++ b/linux/drivers/media/dvb/frontends/ves1820.c @@ -66,7 +66,7 @@ static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data) if (ret != 1) printk("ves1820: %s(): writereg error (reg == 0x%02x, " - "val == 0x%02x, ret == %i)\n", __FUNCTION__, reg, data, ret); + "val == 0x%02x, ret == %i)\n", __func__, reg, data, ret); return (ret != 1) ? -EREMOTEIO : 0; } @@ -85,7 +85,7 @@ static u8 ves1820_readreg(struct ves1820_state *state, u8 reg) if (ret != 2) printk("ves1820: %s(): readreg error (reg == 0x%02x, " - "ret == %i)\n", __FUNCTION__, reg, ret); + "ret == %i)\n", __func__, reg, ret); return b1[0]; } diff --git a/linux/drivers/media/dvb/frontends/ves1820.h b/linux/drivers/media/dvb/frontends/ves1820.h index e4a2a3240..e902ed634 100644 --- a/linux/drivers/media/dvb/frontends/ves1820.h +++ b/linux/drivers/media/dvb/frontends/ves1820.h @@ -48,7 +48,7 @@ extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, static inline struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, struct i2c_adapter* i2c, u8 pwm) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_VES1820 diff --git a/linux/drivers/media/dvb/frontends/ves1x93.c b/linux/drivers/media/dvb/frontends/ves1x93.c index c041c81f9..bd558960b 100644 --- a/linux/drivers/media/dvb/frontends/ves1x93.c +++ b/linux/drivers/media/dvb/frontends/ves1x93.c @@ -98,7 +98,7 @@ static int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data) int err; if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data); + dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data); return -EREMOTEIO; } @@ -179,7 +179,7 @@ static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate) u32 tmp; u32 FIN; - dprintk("%s: srate == %d\n", __FUNCTION__, (unsigned int) srate); + dprintk("%s: srate == %d\n", __func__, (unsigned int) srate); if (srate > state->config->xin/2) srate = state->config->xin/2; @@ -266,7 +266,7 @@ static int ves1x93_init (struct dvb_frontend* fe) int i; int val; - dprintk("%s: init chip\n", __FUNCTION__); + dprintk("%s: init chip\n", __func__); for (i = 0; i < state->tab_size; i++) { if (state->init_1x93_wtab[i]) { diff --git a/linux/drivers/media/dvb/frontends/ves1x93.h b/linux/drivers/media/dvb/frontends/ves1x93.h index d507f8966..8a5a49e80 100644 --- a/linux/drivers/media/dvb/frontends/ves1x93.h +++ b/linux/drivers/media/dvb/frontends/ves1x93.h @@ -47,7 +47,7 @@ extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, static inline struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, struct i2c_adapter* i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_VES1X93 diff --git a/linux/drivers/media/dvb/frontends/xc5000.c b/linux/drivers/media/dvb/frontends/xc5000.c index e50924d97..c832f39ab 100644 --- a/linux/drivers/media/dvb/frontends/xc5000.c +++ b/linux/drivers/media/dvb/frontends/xc5000.c @@ -209,7 +209,7 @@ static void xc5000_TunerReset(struct dvb_frontend *fe) struct xc5000_priv *priv = fe->tuner_priv; int ret; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); if (priv->cfg->tuner_callback) { ret = priv->cfg->tuner_callback(priv->cfg->priv, @@ -330,7 +330,7 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, u8 i2c_sequence[]) static int xc_initialize(struct xc5000_priv *priv) { - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); return xc_write_reg(priv, XREG_INIT, 0); } @@ -338,9 +338,9 @@ static int xc_SetTVStandard(struct xc5000_priv *priv, u16 VideoMode, u16 AudioMode) { int ret; - dprintk(1, "%s(0x%04x,0x%04x)\n", __FUNCTION__, VideoMode, AudioMode); + dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode); dprintk(1, "%s() Standard = %s\n", - __FUNCTION__, + __func__, XC5000_Standard[priv->video_standard].Name); ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode); @@ -361,7 +361,7 @@ static int xc_shutdown(struct xc5000_priv *priv) static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) { - dprintk(1, "%s(%d) Source = %s\n", __FUNCTION__, rf_mode, + dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode, rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE"); if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) @@ -369,7 +369,7 @@ static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode) rf_mode = XC_RF_MODE_CABLE; printk(KERN_ERR "%s(), Invalid mode, defaulting to CABLE", - __FUNCTION__); + __func__); } return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode); } @@ -380,7 +380,7 @@ static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz) { u16 freq_code; - dprintk(1, "%s(%u)\n", __FUNCTION__, freq_hz); + dprintk(1, "%s(%u)\n", __func__, freq_hz); if ((freq_hz > xc5000_tuner_ops.info.frequency_max) || (freq_hz < xc5000_tuner_ops.info.frequency_min)) @@ -415,7 +415,7 @@ static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz) { u32 freq_code = (freq_khz * 1024)/1000; dprintk(1, "%s(freq_khz = %d) freq_code = 0x%x\n", - __FUNCTION__, freq_khz, freq_code); + __func__, freq_khz, freq_code); return xc_write_reg(priv, XREG_IF_OUT, freq_code); } @@ -507,7 +507,7 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz) { int found = 0; - dprintk(1, "%s(%u)\n", __FUNCTION__, freq_hz); + dprintk(1, "%s(%u)\n", __func__, freq_hz); if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS) return 0; @@ -646,12 +646,12 @@ static int xc5000_set_params(struct dvb_frontend *fe, struct xc5000_priv *priv = fe->tuner_priv; int ret; - dprintk(1, "%s() frequency=%d (Hz)\n", __FUNCTION__, params->frequency); + dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); switch(params->u.vsb.modulation) { case VSB_8: case VSB_16: - dprintk(1, "%s() VSB modulation\n", __FUNCTION__); + dprintk(1, "%s() VSB modulation\n", __func__); priv->rf_mode = XC_RF_MODE_AIR; priv->freq_hz = params->frequency - 1750000; priv->bandwidth = BANDWIDTH_6_MHZ; @@ -660,7 +660,7 @@ static int xc5000_set_params(struct dvb_frontend *fe, case QAM_64: case QAM_256: case QAM_AUTO: - dprintk(1, "%s() QAM modulation\n", __FUNCTION__); + dprintk(1, "%s() QAM modulation\n", __func__); priv->rf_mode = XC_RF_MODE_CABLE; priv->freq_hz = params->frequency - 1750000; priv->bandwidth = BANDWIDTH_6_MHZ; @@ -671,7 +671,7 @@ static int xc5000_set_params(struct dvb_frontend *fe, } dprintk(1, "%s() frequency=%d (compensated)\n", - __FUNCTION__, priv->freq_hz); + __func__, priv->freq_hz); ret = xc_SetSignalSource(priv, priv->rf_mode); if (ret != XC_RESULT_SUCCESS) { @@ -716,7 +716,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, xc_load_fw_and_init_tuner(fe); dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", - __FUNCTION__, params->frequency); + __func__, params->frequency); priv->rf_mode = XC_RF_MODE_CABLE; /* Fix me: it could be air. */ @@ -794,7 +794,7 @@ tune_channel: static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq) { struct xc5000_priv *priv = fe->tuner_priv; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); *freq = priv->freq_hz; return 0; } @@ -802,7 +802,7 @@ static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq) static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw) { struct xc5000_priv *priv = fe->tuner_priv; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); *bw = priv->bandwidth; return 0; @@ -815,7 +815,7 @@ static int xc5000_get_status(struct dvb_frontend *fe, u32 *status) xc_get_lock_status(priv, &lock_status); - dprintk(1, "%s() lock_status = 0x%08x\n", __FUNCTION__, lock_status); + dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status); *status = lock_status; @@ -855,7 +855,7 @@ static int xc5000_sleep(struct dvb_frontend *fe) struct xc5000_priv *priv = fe->tuner_priv; int ret; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); /* On Pinnacle PCTV HD 800i, the tuner cannot be reinitialized * once shutdown without reloading the driver. Maybe I am not @@ -867,7 +867,7 @@ static int xc5000_sleep(struct dvb_frontend *fe) if(ret != XC_RESULT_SUCCESS) { printk(KERN_ERR "xc5000: %s() unable to shutdown tuner\n", - __FUNCTION__); + __func__); return -EREMOTEIO; } else { @@ -879,7 +879,7 @@ static int xc5000_sleep(struct dvb_frontend *fe) static int xc5000_init(struct dvb_frontend *fe) { struct xc5000_priv *priv = fe->tuner_priv; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) { printk(KERN_ERR "xc5000: Unable to initialise tuner\n"); @@ -894,7 +894,7 @@ static int xc5000_init(struct dvb_frontend *fe) static int xc5000_release(struct dvb_frontend *fe) { - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); kfree(fe->tuner_priv); fe->tuner_priv = NULL; return 0; @@ -926,7 +926,7 @@ struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe, struct xc5000_priv *priv = NULL; u16 id = 0; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); priv = kzalloc(sizeof(struct xc5000_priv), GFP_KERNEL); if (priv == NULL) diff --git a/linux/drivers/media/dvb/frontends/xc5000.h b/linux/drivers/media/dvb/frontends/xc5000.h index 32a5f1c86..b890883a0 100644 --- a/linux/drivers/media/dvb/frontends/xc5000.h +++ b/linux/drivers/media/dvb/frontends/xc5000.h @@ -55,7 +55,7 @@ static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct xc5000_config *cfg) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif // CONFIG_DVB_TUNER_XC5000 diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c index 1ae9f0ef1..11160a3ee 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.c +++ b/linux/drivers/media/dvb/frontends/zl10353.c @@ -91,7 +91,7 @@ static int zl10353_read_register(struct zl10353_state *state, u8 reg) if (ret != 2) { printk("%s: readreg error (reg=%d, ret==%i)\n", - __FUNCTION__, reg, ret); + __func__, reg, ret); return ret; } @@ -157,7 +157,7 @@ static void zl10353_calc_nominal_rate(struct dvb_frontend *fe, *nominal_rate = value; dprintk("%s: bw %d, adc_clock %d => 0x%x\n", - __FUNCTION__, bw, adc_clock, *nominal_rate); + __func__, bw, adc_clock, *nominal_rate); } static void zl10353_calc_input_freq(struct dvb_frontend *fe, @@ -186,7 +186,7 @@ static void zl10353_calc_input_freq(struct dvb_frontend *fe, *input_freq = -value; dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n", - __FUNCTION__, if2, ife, adc_clock, -(int)value, *input_freq); + __func__, if2, ife, adc_clock, -(int)value, *input_freq); } static int zl10353_sleep(struct dvb_frontend *fe) diff --git a/linux/drivers/media/dvb/frontends/zl10353.h b/linux/drivers/media/dvb/frontends/zl10353.h index fc734c22b..fdbb88ff7 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.h +++ b/linux/drivers/media/dvb/frontends/zl10353.h @@ -47,7 +47,7 @@ extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, static inline struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, struct i2c_adapter *i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif /* CONFIG_DVB_ZL10353 */ diff --git a/linux/drivers/media/dvb/pluto2/pluto2.c b/linux/drivers/media/dvb/pluto2/pluto2.c index b104e63eb..33a98f0f0 100644 --- a/linux/drivers/media/dvb/pluto2/pluto2.c +++ b/linux/drivers/media/dvb/pluto2/pluto2.c @@ -39,6 +39,8 @@ #include "dvbdev.h" #include "tda1004x.h" +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + #define DRIVER_NAME "pluto2" #define REG_PIDn(n) ((n) << 2) /* PID n pattern registers */ @@ -666,7 +668,8 @@ static int __devinit pluto2_probe(struct pci_dev *pdev, goto err_pluto_hw_exit; /* dvb */ - ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE, &pdev->dev); + ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, + THIS_MODULE, &pdev->dev, adapter_nr); if (ret < 0) goto err_i2c_del_adapter; diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index 35b0814e0..5a747a569 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -112,6 +112,8 @@ MODULE_PARM_DESC(wss_cfg_16_9, "WSS 16:9 - default 0x0007 - bit 15: disable, 14: module_param(tv_standard, int, 0444); MODULE_PARM_DESC(tv_standard, "TV standard: 0 PAL (default), 1 NTSC"); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + static void restart_feeds(struct av7110 *av7110); static int av7110_num; @@ -359,7 +361,7 @@ static inline void start_debi_dma(struct av7110 *av7110, int dir, { dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len); if (saa7146_wait_for_debi_done(av7110->dev, 0)) { - printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__); + printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __func__); return; } @@ -497,7 +499,7 @@ static void gpioirq(unsigned long data) saa7146_read(av7110->dev, SSR)); if (saa7146_wait_for_debi_done(av7110->dev, 0)) { - printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __FUNCTION__); + printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __func__); BUG(); /* maybe we should try resetting the debi? */ } @@ -827,7 +829,7 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) if (ret != 0 || handle >= 32) { printk("dvb-ttpci: %s error buf %04x %04x %04x %04x " "ret %d handle %04x\n", - __FUNCTION__, buf[0], buf[1], buf[2], buf[3], + __func__, buf[0], buf[1], buf[2], buf[3], ret, handle); dvbdmxfilter->hw_handle = 0xffff; if (!ret) @@ -854,7 +856,7 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) handle = dvbdmxfilter->hw_handle; if (handle >= 32) { printk("%s tried to stop invalid filter %04x, filter type = %x\n", - __FUNCTION__, handle, dvbdmxfilter->type); + __func__, handle, dvbdmxfilter->type); return -EINVAL; } @@ -867,7 +869,7 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) if (ret != 0 || answ[1] != handle) { printk("dvb-ttpci: %s error cmd %04x %04x %04x ret %x " "resp %04x %04x pid %d\n", - __FUNCTION__, buf[0], buf[1], buf[2], ret, + __func__, buf[0], buf[1], buf[2], ret, answ[0], answ[1], dvbdmxfilter->feed->pid); if (!ret) ret = -1; @@ -1122,7 +1124,7 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4); if (ret) { - printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__); + printk(KERN_ERR "%s: av7110_fw_request error\n", __func__); return ret; } dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n", @@ -2461,7 +2463,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, goto err_kfree_0; ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, - THIS_MODULE, &dev->pci->dev); + THIS_MODULE, &dev->pci->dev, adapter_nr); if (ret < 0) goto err_put_firmware_1; diff --git a/linux/drivers/media/dvb/ttpci/av7110.h b/linux/drivers/media/dvb/ttpci/av7110.h index 5bb48ab1c..290ffc188 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.h +++ b/linux/drivers/media/dvb/ttpci/av7110.h @@ -44,7 +44,7 @@ extern int av7110_debug; #define dprintk(level,args...) \ - do { if ((av7110_debug & level)) { printk("dvb-ttpci: %s(): ", __FUNCTION__); printk(args); } } while (0) + do { if ((av7110_debug & level)) { printk("dvb-ttpci: %s(): ", __func__); printk(args); } } while (0) #define MAXFILT 32 diff --git a/linux/drivers/media/dvb/ttpci/av7110_hw.c b/linux/drivers/media/dvb/ttpci/av7110_hw.c index a0d7acd9e..ec049bb6e 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_hw.c +++ b/linux/drivers/media/dvb/ttpci/av7110_hw.c @@ -53,11 +53,11 @@ int av7110_debiwrite(struct av7110 *av7110, u32 config, struct saa7146_dev *dev = av7110->dev; if (count <= 0 || count > 32764) { - printk("%s: invalid count %d\n", __FUNCTION__, count); + printk("%s: invalid count %d\n", __func__, count); return -1; } if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) { - printk("%s: wait_for_debi_done failed\n", __FUNCTION__); + printk("%s: wait_for_debi_done failed\n", __func__); return -1; } saa7146_write(dev, DEBI_CONFIG, config); @@ -76,11 +76,11 @@ u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, int count) u32 result = 0; if (count > 32764 || count <= 0) { - printk("%s: invalid count %d\n", __FUNCTION__, count); + printk("%s: invalid count %d\n", __func__, count); return 0; } if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) { - printk("%s: wait_for_debi_done #1 failed\n", __FUNCTION__); + printk("%s: wait_for_debi_done #1 failed\n", __func__); return 0; } saa7146_write(dev, DEBI_AD, av7110->debi_bus); @@ -91,7 +91,7 @@ u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, int count) if (count > 4) return count; if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) { - printk("%s: wait_for_debi_done #2 failed\n", __FUNCTION__); + printk("%s: wait_for_debi_done #2 failed\n", __func__); return 0; } @@ -332,7 +332,7 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags) break; if (err) { printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n", - __FUNCTION__, stat & flags); + __func__, stat & flags); return -ETIMEDOUT; } msleep(1); @@ -362,7 +362,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) break; if (err) { - printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__); + printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __func__); av7110->arm_errors++; return -ETIMEDOUT; } @@ -379,7 +379,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0) break; if (err) { - printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); + printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __func__); return -ETIMEDOUT; } msleep(1); @@ -419,14 +419,14 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); if (stat & flags[0]) { printk(KERN_ERR "%s: %s QUEUE overflow\n", - __FUNCTION__, type); + __func__, type); return -1; } if ((stat & flags[1]) == 0) break; if (err) { printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n", - __FUNCTION__, type); + __func__, type); return -ETIMEDOUT; } msleep(1); @@ -454,7 +454,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) break; if (err) { printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n", - __FUNCTION__, (buf[0] >> 8) & 0xff); + __func__, (buf[0] >> 8) & 0xff); return -ETIMEDOUT; } msleep(1); @@ -462,11 +462,11 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); if (stat & GPMQOver) { - printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __FUNCTION__); + printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __func__); return -ENOSPC; } else if (stat & OSDQOver) { - printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __FUNCTION__); + printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __func__); return -ENOSPC; } #endif @@ -491,7 +491,7 @@ static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) mutex_unlock(&av7110->dcomlock); if (ret && ret!=-ERESTARTSYS) printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n", - __FUNCTION__, ret); + __func__, ret); return ret; } @@ -575,7 +575,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) break; if (err) { - printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__); + printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __func__); mutex_unlock(&av7110->dcomlock); return -ETIMEDOUT; } @@ -591,7 +591,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0) break; if (err) { - printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); + printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __func__); mutex_unlock(&av7110->dcomlock); return -ETIMEDOUT; } @@ -602,12 +602,12 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, #ifdef COM_DEBUG stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); if (stat & GPMQOver) { - printk(KERN_ERR "%s: GPMQOver\n", __FUNCTION__); + printk(KERN_ERR "%s: GPMQOver\n", __func__); mutex_unlock(&av7110->dcomlock); return -1; } else if (stat & OSDQOver) { - printk(KERN_ERR "%s: OSDQOver\n", __FUNCTION__); + printk(KERN_ERR "%s: OSDQOver\n", __func__); mutex_unlock(&av7110->dcomlock); return -1; } @@ -741,7 +741,7 @@ static int FlushText(struct av7110 *av7110) break; if (err) { printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n", - __FUNCTION__); + __func__); mutex_unlock(&av7110->dcomlock); return -ETIMEDOUT; } @@ -768,7 +768,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf) break; if (ret) { printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n", - __FUNCTION__); + __func__); mutex_unlock(&av7110->dcomlock); return -ETIMEDOUT; } @@ -782,7 +782,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf) break; if (ret) { printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n", - __FUNCTION__); + __func__); mutex_unlock(&av7110->dcomlock); return -ETIMEDOUT; } diff --git a/linux/drivers/media/dvb/ttpci/av7110_ir.c b/linux/drivers/media/dvb/ttpci/av7110_ir.c index 9097646a3..18171c051 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_ir.c +++ b/linux/drivers/media/dvb/ttpci/av7110_ir.c @@ -133,7 +133,7 @@ static void av7110_emit_key(unsigned long parm) break; default: - printk("%s invalid protocol %x\n", __FUNCTION__, ir->protocol); + printk("%s invalid protocol %x\n", __func__, ir->protocol); return; } @@ -143,7 +143,7 @@ static void av7110_emit_key(unsigned long parm) keycode = ir->key_map[data]; dprintk(16, "%s: code %08x -> addr %i data 0x%02x -> keycode %i\n", - __FUNCTION__, ircom, addr, data, keycode); + __func__, ircom, addr, data, keycode); /* check device address */ if (!(ir->device_mask & (1 << addr))) @@ -151,7 +151,7 @@ static void av7110_emit_key(unsigned long parm) if (!keycode) { printk ("%s: code %08x -> addr %i data 0x%02x -> unknown key!\n", - __FUNCTION__, ircom, addr, data); + __func__, ircom, addr, data); return; } diff --git a/linux/drivers/media/dvb/ttpci/av7110_v4l.c b/linux/drivers/media/dvb/ttpci/av7110_v4l.c index e2f066fb7..b4a0cc5dc 100644 --- a/linux/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/linux/drivers/media/dvb/ttpci/av7110_v4l.c @@ -573,7 +573,7 @@ static int av7110_vbi_reset(struct inode *inode, struct file *file) struct saa7146_dev *dev = fh->dev; struct av7110 *av7110 = (struct av7110*) dev->ext_priv; - dprintk(2, "%s\n", __FUNCTION__); + dprintk(2, "%s\n", __func__); av7110->wssMode = 0; av7110->wssData = 0; if (FW_VERSION(av7110->arm_app) < 0x2623) @@ -590,7 +590,7 @@ static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size struct v4l2_sliced_vbi_data d; int rc; - dprintk(2, "%s\n", __FUNCTION__); + dprintk(2, "%s\n", __func__); if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d) return -EINVAL; if (copy_from_user(&d, data, count)) diff --git a/linux/drivers/media/dvb/ttpci/budget-av.c b/linux/drivers/media/dvb/ttpci/budget-av.c index 2d64d557b..b30a5288e 100644 --- a/linux/drivers/media/dvb/ttpci/budget-av.c +++ b/linux/drivers/media/dvb/ttpci/budget-av.c @@ -178,7 +178,7 @@ static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 addre udelay(1); result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0); - if ((result == -ETIMEDOUT) || ((result == 0xff) && ((address & 3) < 2))) { + if (result == -ETIMEDOUT) { ciintf_slot_shutdown(ca, slot); printk(KERN_INFO "budget-av: cam ejected 3\n"); return -ETIMEDOUT; @@ -577,7 +577,7 @@ static struct stv0299_config typhoon_config = { .mclk = 88000000UL, .invert = 0, .skip_reinit = 0, - .lock_output = STV0229_LOCKOUTPUT_1, + .lock_output = STV0299_LOCKOUTPUT_1, .volt13_op0_op1 = STV0299_VOLT13_OP0, .min_delay_ms = 100, .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, @@ -590,7 +590,7 @@ static struct stv0299_config cinergy_1200s_config = { .mclk = 88000000UL, .invert = 0, .skip_reinit = 0, - .lock_output = STV0229_LOCKOUTPUT_0, + .lock_output = STV0299_LOCKOUTPUT_0, .volt13_op0_op1 = STV0299_VOLT13_OP0, .min_delay_ms = 100, .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, @@ -602,7 +602,7 @@ static struct stv0299_config cinergy_1200s_1894_0010_config = { .mclk = 88000000UL, .invert = 1, .skip_reinit = 0, - .lock_output = STV0229_LOCKOUTPUT_1, + .lock_output = STV0299_LOCKOUTPUT_1, .volt13_op0_op1 = STV0299_VOLT13_OP0, .min_delay_ms = 100, .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, @@ -869,7 +869,7 @@ static struct stv0299_config philips_sd1878_config = { .mclk = 88000000UL, .invert = 0, .skip_reinit = 0, - .lock_output = STV0229_LOCKOUTPUT_1, + .lock_output = STV0299_LOCKOUTPUT_1, .volt13_op0_op1 = STV0299_VOLT13_OP0, .min_delay_ms = 100, .set_symbol_rate = philips_sd1878_ci_set_symbol_rate, @@ -941,6 +941,12 @@ static void frontend_init(struct budget_av *budget_av) switch (saa->pci->subsystem_device) { case SUBID_DVBS_KNC1: + /* + * maybe that setting is needed for other dvb-s cards as well, + * but so far it has been only confirmed for this type + */ + budget_av->reinitialise_demod = 1; + /* fall through */ case SUBID_DVBS_KNC1_PLUS: case SUBID_DVBS_EASYWATCH_1: if (saa->pci->subsystem_vendor == 0x1894) { diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index c35ad070c..8c6ba2edc 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -738,7 +738,7 @@ static struct stv0299_config philips_su1278_tt_config = { .mclk = 64000000UL, .invert = 0, .skip_reinit = 1, - .lock_output = STV0229_LOCKOUTPUT_1, + .lock_output = STV0299_LOCKOUTPUT_1, .volt13_op0_op1 = STV0299_VOLT13_OP1, .min_delay_ms = 50, .set_symbol_rate = philips_su1278_tt_set_symbol_rate, @@ -1131,7 +1131,7 @@ static void frontend_init(struct budget_ci *budget_ci) budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) { - printk("%s: No LNBP21 found!\n", __FUNCTION__); + printk("%s: No LNBP21 found!\n", __func__); dvb_frontend_detach(budget_ci->budget.dvb_frontend); budget_ci->budget.dvb_frontend = NULL; } diff --git a/linux/drivers/media/dvb/ttpci/budget-core.c b/linux/drivers/media/dvb/ttpci/budget-core.c index 0252081f0..18cac4b12 100644 --- a/linux/drivers/media/dvb/ttpci/budget-core.c +++ b/linux/drivers/media/dvb/ttpci/budget-core.c @@ -57,6 +57,8 @@ module_param_named(bufsize, dma_buffer_size, int, 0444); MODULE_PARM_DESC(debug, "Turn on/off budget debugging (default:off)."); MODULE_PARM_DESC(bufsize, "DMA buffer size in KB, default: 188, min: 188, max: 1410 (Activy: 564)"); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + /**************************************************************************** * TT budget / WinTV Nova ****************************************************************************/ @@ -223,7 +225,7 @@ static void vpeirq(unsigned long data) if (budget->buffer_warnings && time_after(jiffies, budget->buffer_warning_time)) { printk("%s %s: used %d times >80%% of buffer (%u bytes now)\n", - budget->dev->name, __FUNCTION__, budget->buffer_warnings, count); + budget->dev->name, __func__, budget->buffer_warnings, count); budget->buffer_warning_time = jiffies + BUFFER_WARNING_WAIT; budget->buffer_warnings = 0; } @@ -471,9 +473,10 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, budget->buffer_width, budget->buffer_height); printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); - if ((ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner, &budget->dev->pci->dev)) < 0) { + ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, + owner, &budget->dev->pci->dev, adapter_nr); + if (ret < 0) return ret; - } /* set dd1 stream a & b */ saa7146_write(dev, DD1_STREAM_B, 0x00000000); diff --git a/linux/drivers/media/dvb/ttpci/budget.c b/linux/drivers/media/dvb/ttpci/budget.c index 14b00f57b..2293d80c6 100644 --- a/linux/drivers/media/dvb/ttpci/budget.c +++ b/linux/drivers/media/dvb/ttpci/budget.c @@ -45,6 +45,7 @@ #include "tda826x.h" #include "lnbp21.h" #include "bsru6.h" +#include "bsbe1.h" static int diseqc_method; module_param(diseqc_method, int, 0444); @@ -257,11 +258,17 @@ static struct ves1820_config alps_tdbe2_config = { static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { - struct budget* budget = (struct budget*) fe->dvb->priv; + struct budget *budget = fe->dvb->priv; + u8 *tuner_addr = fe->tuner_priv; u32 div; u8 cfg, cpump, band_select; u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; + struct i2c_msg msg = { .flags = 0, .buf = data, .len = sizeof(data) }; + + if (tuner_addr) + msg.addr = *tuner_addr; + else + msg.addr = 0x61; div = (36125000 + params->frequency) / 166666; @@ -292,6 +299,12 @@ static struct l64781_config grundig_29504_401_config = { .demod_address = 0x55, }; +static struct l64781_config grundig_29504_401_config_activy = { + .demod_address = 0x54, +}; + +static u8 tuner_address_grundig_29504_401_activy = 0x60; + static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) { struct budget* budget = (struct budget*) fe->dvb->priv; @@ -346,14 +359,48 @@ static int s5h1420_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend static struct s5h1420_config s5h1420_config = { .demod_address = 0x53, .invert = 1, + .cdclk_polarity = 1, }; static struct tda10086_config tda10086_config = { .demod_address = 0x0e, .invert = 0, .diseqc_tone = 1, + .xtal_freq = TDA10086_XTAL_16M, }; +static struct stv0299_config alps_bsru6_config_activy = { + .demod_address = 0x68, + .inittab = alps_bsru6_inittab, + .mclk = 88000000UL, + .invert = 1, + .op0_off = 1, + .min_delay_ms = 100, + .set_symbol_rate = alps_bsru6_set_symbol_rate, +}; + +static struct stv0299_config alps_bsbe1_config_activy = { + .demod_address = 0x68, + .inittab = alps_bsbe1_inittab, + .mclk = 88000000UL, + .invert = 1, + .op0_off = 1, + .min_delay_ms = 100, + .set_symbol_rate = alps_bsbe1_set_symbol_rate, +}; + + +static int i2c_readreg(struct i2c_adapter *i2c, u8 adr, u8 reg) +{ + u8 val; + struct i2c_msg msg[] = { + { .addr = adr, .flags = 0, .buf = ®, .len = 1 }, + { .addr = adr, .flags = I2C_M_RD, .buf = &val, .len = 1 } + }; + + return (i2c_transfer(i2c, msg, 2) != 2) ? -EIO : val; +} + static u8 read_pwm(struct budget* budget) { u8 b = 0xff; @@ -369,6 +416,8 @@ static u8 read_pwm(struct budget* budget) static void frontend_init(struct budget *budget) { + (void)alps_bsbe1_config; /* avoid warning */ + switch(budget->dev->pci->subsystem_device) { case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) case 0x1013: @@ -414,15 +463,43 @@ static void frontend_init(struct budget *budget) } break; - case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059)) - budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; - budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; + case 0x4f60: /* Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/tsa5059) */ + { + int subtype = i2c_readreg(&budget->i2c_adap, 0x50, 0x67); + + if (subtype < 0) + break; + /* fixme: find a better way to identify the card */ + if (subtype < 0x36) { + /* assume ALPS BSRU6 */ + budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config_activy, &budget->i2c_adap); + if (budget->dvb_frontend) { + printk(KERN_INFO "budget: tuner ALPS BSRU6 detected\n"); + budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; + budget->dvb_frontend->tuner_priv = &budget->i2c_adap; + budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; + budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; + break; + } + } else { + /* assume ALPS BSBE1 */ + /* reset tuner */ + saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTLO); + msleep(50); + saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTHI); + msleep(250); + budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config_activy, &budget->i2c_adap); + if (budget->dvb_frontend) { + printk(KERN_INFO "budget: tuner ALPS BSBE1 detected\n"); + budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; + budget->dvb_frontend->tuner_priv = &budget->i2c_adap; + budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; + budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; + break; + } } break; + } case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522)) budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap); @@ -433,12 +510,20 @@ static void frontend_init(struct budget *budget) } break; + case 0x5f61: /* Fujitsu Siemens Activy Budget-T PCI rev GR (L64781/Grundig 29504-401(tsa5060)) */ + budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config_activy, &budget->i2c_adap); + if (budget->dvb_frontend) { + budget->dvb_frontend->tuner_priv = &tuner_address_grundig_29504_401_activy; + budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; + } + break; + case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) budget->dvb_frontend = dvb_attach(s5h1420_attach, &s5h1420_config, &budget->i2c_adap); if (budget->dvb_frontend) { budget->dvb_frontend->ops.tuner_ops.set_params = s5h1420_tuner_set_params; if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) { - printk("%s: No LNBP21 found!\n", __FUNCTION__); + printk("%s: No LNBP21 found!\n", __func__); goto error_out; } break; @@ -454,9 +539,9 @@ static void frontend_init(struct budget *budget) budget->dvb_frontend = dvb_attach(tda10086_attach, &tda10086_config, &budget->i2c_adap); if (budget->dvb_frontend) { if (dvb_attach(tda826x_attach, budget->dvb_frontend, 0x60, &budget->i2c_adap, 0) == NULL) - printk("%s: No tda826x found!\n", __FUNCTION__); + printk("%s: No tda826x found!\n", __func__); if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) { - printk("%s: No LNBP21 found!\n", __FUNCTION__); + printk("%s: No LNBP21 found!\n", __func__); goto error_out; } break; @@ -537,6 +622,7 @@ MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC); MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT); MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY); MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY); +MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY); static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003), @@ -547,6 +633,7 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018), MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), + MAKE_EXTENSION_PCI(fsact, 0x1131, 0x5f61), { .vendor = 0, } diff --git a/linux/drivers/media/dvb/ttpci/budget.h b/linux/drivers/media/dvb/ttpci/budget.h index 94922db7a..0e8e596d6 100644 --- a/linux/drivers/media/dvb/ttpci/budget.h +++ b/linux/drivers/media/dvb/ttpci/budget.h @@ -1,3 +1,4 @@ + #ifndef __BUDGET_DVB__ #define __BUDGET_DVB__ @@ -25,10 +26,10 @@ extern int budget_debug; #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) #define dprintk(level,args...) \ - do { if ((budget_debug & level)) { printk("%s: %s(): ",__stringify(KBUILD_MODNAME), __FUNCTION__); printk(args); } } while (0) + do { if ((budget_debug & level)) { printk("%s: %s(): ",__stringify(KBUILD_MODNAME), __func__); printk(args); } } while (0) #else #define dprintk(level,args...) \ - do { if ((budget_debug & level)) { printk("%s: %s(): ", KBUILD_MODNAME, __FUNCTION__); printk(args); } } while (0) + do { if ((budget_debug & level)) { printk("%s: %s(): ", KBUILD_MODNAME, __func__); printk(args); } } while (0) #endif struct budget_info { diff --git a/linux/drivers/media/dvb/ttpci/ttpci-eeprom.c b/linux/drivers/media/dvb/ttpci/ttpci-eeprom.c index d6f43269e..bb3ba8153 100644 --- a/linux/drivers/media/dvb/ttpci/ttpci-eeprom.c +++ b/linux/drivers/media/dvb/ttpci/ttpci-eeprom.c @@ -95,7 +95,7 @@ static int ttpci_eeprom_read_encodedMAC(struct i2c_adapter *adapter, u8 * encode { .addr = 0x50, .flags = I2C_M_RD, .buf = encodedMAC, .len = 20 } }; - /* dprintk("%s\n", __FUNCTION__); */ + /* dprintk("%s\n", __func__); */ ret = i2c_transfer(adapter, msg, 2); diff --git a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 2e1572fb9..6716ab2b1 100644 --- a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -59,10 +59,11 @@ */ static int debug; - module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + #define dprintk(x...) do { if (debug) printk(KERN_DEBUG x); } while (0) #define ISO_BUF_COUNT 4 @@ -161,12 +162,12 @@ static int ttusb_cmd(struct ttusb *ttusb, (u8 *) data, len, &actual_len, 1000); if (err != 0) { dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n", - __FUNCTION__, err); + __func__, err); mutex_unlock(&ttusb->semusb); return err; } if (actual_len != len) { - dprintk("%s: only wrote %d of %d bytes\n", __FUNCTION__, + dprintk("%s: only wrote %d of %d bytes\n", __func__, actual_len, len); mutex_unlock(&ttusb->semusb); return -1; @@ -176,7 +177,7 @@ static int ttusb_cmd(struct ttusb *ttusb, ttusb->last_result, 32, &actual_len, 1000); if (err != 0) { - printk("%s: failed, receive error %d\n", __FUNCTION__, + printk("%s: failed, receive error %d\n", __func__, err); mutex_unlock(&ttusb->semusb); return err; @@ -237,7 +238,7 @@ static int ttusb_i2c_msg(struct ttusb *ttusb, if (err || b[0] != 0x55 || b[1] != id) { dprintk ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ", - __FUNCTION__, err, id); + __func__, err, id); return -EREMOTEIO; } @@ -281,7 +282,7 @@ static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num snd_buf, snd_len, rcv_buf, rcv_len); if (err < rcv_len) { - dprintk("%s: i == %i\n", __FUNCTION__, i); + dprintk("%s: i == %i\n", __func__, i); break; } @@ -335,7 +336,7 @@ static int ttusb_boot_dsp(struct ttusb *ttusb) done: if (err) { dprintk("%s: usb_bulk_msg() failed, return value %i!\n", - __FUNCTION__, err); + __func__, err); } return err; @@ -435,7 +436,7 @@ static int ttusb_init_controller(struct ttusb *ttusb) if ((err = ttusb_result(ttusb, get_version, sizeof(get_version)))) return err; - dprintk("%s: stc-version: %c%c%c%c%c\n", __FUNCTION__, + dprintk("%s: stc-version: %c%c%c%c%c\n", __func__, get_version[4], get_version[5], get_version[6], get_version[7], get_version[8]); @@ -445,7 +446,7 @@ static int ttusb_init_controller(struct ttusb *ttusb) memcmp(get_version + 4, "V 2.2", 5)) { printk ("%s: unknown STC version %c%c%c%c%c, please report!\n", - __FUNCTION__, get_version[4], get_version[5], + __func__, get_version[4], get_version[5], get_version[6], get_version[7], get_version[8]); } @@ -461,7 +462,7 @@ static int ttusb_init_controller(struct ttusb *ttusb) ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version)); if (err) return err; - printk("%s: dsp-version: %c%c%c\n", __FUNCTION__, + printk("%s: dsp-version: %c%c%c\n", __func__, get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]); return 0; } @@ -484,7 +485,7 @@ static int ttusb_send_diseqc(struct dvb_frontend* fe, /* Diseqc */ if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) { dprintk("%s: usb_bulk_msg() failed, return value %i!\n", - __FUNCTION__, err); + __func__, err); } return err; @@ -502,7 +503,7 @@ static int ttusb_update_lnb(struct ttusb *ttusb) /* SetLNB */ if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) { dprintk("%s: usb_bulk_msg() failed, return value %i!\n", - __FUNCTION__, err); + __func__, err); } return err; @@ -536,7 +537,7 @@ static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq) err = ttusb_cmd(ttusb, b, sizeof(b), 0); if (err) { dprintk("%s: usb_bulk_msg() failed, return value %i!\n", - __FUNCTION__, err); + __func__, err); } } #endif @@ -562,7 +563,7 @@ static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack, csum ^= le16_to_cpup((u16 *) (muxpack + i)); if (csum) { printk("%s: muxpack with incorrect checksum, ignoring\n", - __FUNCTION__); + __func__); numinvalid++; return; } @@ -571,7 +572,7 @@ static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack, cc &= 0x7FFF; if ((cc != ttusb->cc) && (ttusb->cc != -1)) printk("%s: cc discontinuity (%d frames missing)\n", - __FUNCTION__, (cc - ttusb->cc) & 0x7FFF); + __func__, (cc - ttusb->cc) & 0x7FFF); ttusb->cc = (cc + 1) & 0x7FFF; if (muxpack[0] & 0x80) { #ifdef TTUSB_HWSECTIONS @@ -621,7 +622,7 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len) int maxwork = 1024; while (len) { if (!(maxwork--)) { - printk("%s: too much work\n", __FUNCTION__); + printk("%s: too much work\n", __func__); break; } @@ -640,7 +641,7 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len) #else if (ttusb->insync) { printk("%s: lost sync.\n", - __FUNCTION__); + __func__); ttusb->insync = 0; } #endif @@ -699,7 +700,7 @@ static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len) else { dprintk ("%s: invalid state: first byte is %x\n", - __FUNCTION__, + __func__, ttusb->muxpack[0]); ttusb->mux_state = 0; } @@ -752,7 +753,7 @@ static void ttusb_iso_irq(struct urb *urb) #if 0 /* keep */ printk("%s: status %d, errcount == %d, length == %i\n", - __FUNCTION__, + __func__, urb->status, urb->error_count, urb->actual_length); #endif @@ -845,7 +846,7 @@ static int ttusb_start_iso_xfer(struct ttusb *ttusb) int i, j, err, buffer_offset = 0; if (ttusb->iso_streaming) { - printk("%s: iso xfer already running!\n", __FUNCTION__); + printk("%s: iso xfer already running!\n", __func__); return 0; } @@ -881,7 +882,7 @@ static int ttusb_start_iso_xfer(struct ttusb *ttusb) ttusb_stop_iso_xfer(ttusb); printk ("%s: failed urb submission (%i: err = %i)!\n", - __FUNCTION__, i, err); + __func__, i, err); return err; } } @@ -1325,7 +1326,7 @@ static struct stv0299_config alps_stv0299_config = { .mclk = 88000000UL, .invert = 1, .skip_reinit = 0, - .lock_output = STV0229_LOCKOUTPUT_1, + .lock_output = STV0299_LOCKOUTPUT_1, .volt13_op0_op1 = STV0299_VOLT13_OP1, .min_delay_ms = 100, .set_symbol_rate = alps_stv0299_set_symbol_rate, @@ -1655,7 +1656,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i struct ttusb *ttusb; int result; - dprintk("%s: TTUSB DVB connected\n", __FUNCTION__); + dprintk("%s: TTUSB DVB connected\n", __func__); udev = interface_to_usbdev(intf); @@ -1681,7 +1682,10 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i mutex_unlock(&ttusb->semi2c); - if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE, &udev->dev)) < 0) { + result = dvb_register_adapter(&ttusb->adapter, + "Technotrend/Hauppauge Nova-USB", + THIS_MODULE, &udev->dev, adapter_nr); + if (result < 0) { ttusb_free_iso_urbs(ttusb); kfree(ttusb); return result; @@ -1785,7 +1789,7 @@ static void ttusb_disconnect(struct usb_interface *intf) kfree(ttusb); - dprintk("%s: TTUSB DVB disconnected\n", __FUNCTION__); + dprintk("%s: TTUSB DVB disconnected\n", __func__); } static struct usb_device_id ttusb_table[] = { diff --git a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c index f6667cf3d..cb930e37e 100644 --- a/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/linux/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -55,6 +55,8 @@ MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)"); module_param(enable_rc, int, 0644); MODULE_PARM_DESC(enable_rc, "Turn on/off IR remote control(default: off)"); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + #define dprintk if (debug) printk #define DRIVER_NAME "TechnoTrend/Hauppauge DEC USB" @@ -232,11 +234,11 @@ static void ttusb_dec_handle_irq( struct urb *urb) case -ETIME: /* this urb is dead, cleanup */ dprintk("%s:urb shutting down with status: %d\n", - __FUNCTION__, urb->status); + __func__, urb->status); return; default: dprintk("%s:nonzero status received: %d\n", - __FUNCTION__,urb->status); + __func__,urb->status); goto exit; } @@ -250,7 +252,7 @@ static void ttusb_dec_handle_irq( struct urb *urb) * keyrepeat signal is recieved for lets say 200ms. * this should/could be added later ... * for now lets report each signal as a key down and up*/ - dprintk("%s:rc signal:%d\n", __FUNCTION__, buffer[4]); + dprintk("%s:rc signal:%d\n", __func__, buffer[4]); input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1); input_sync(dec->rc_input_dev); input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0); @@ -260,7 +262,7 @@ static void ttusb_dec_handle_irq( struct urb *urb) exit: retval = usb_submit_urb(urb, GFP_ATOMIC); if(retval) printk("%s - usb_commit_urb failed with result: %d\n", - __FUNCTION__, retval); + __func__, retval); } static u16 crc16(u16 crc, const u8 *buf, size_t len) @@ -283,7 +285,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, int result, actual_len, i; u8 *b; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL); if (!b) @@ -291,7 +293,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if ((result = mutex_lock_interruptible(&dec->usb_mutex))) { kfree(b); - printk("%s: Failed to lock usb mutex.\n", __FUNCTION__); + printk("%s: Failed to lock usb mutex.\n", __func__); return result; } @@ -304,7 +306,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, memcpy(&b[4], params, param_length); if (debug) { - printk("%s: command: ", __FUNCTION__); + printk("%s: command: ", __func__); for (i = 0; i < param_length + 4; i++) printk("0x%02X ", b[i]); printk("\n"); @@ -315,7 +317,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (result) { printk("%s: command bulk message failed: error %d\n", - __FUNCTION__, result); + __func__, result); mutex_unlock(&dec->usb_mutex); kfree(b); return result; @@ -326,13 +328,13 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (result) { printk("%s: result bulk message failed: error %d\n", - __FUNCTION__, result); + __func__, result); mutex_unlock(&dec->usb_mutex); kfree(b); return result; } else { if (debug) { - printk("%s: result: ", __FUNCTION__); + printk("%s: result: ", __func__); for (i = 0; i < actual_len; i++) printk("0x%02X ", b[i]); printk("\n"); @@ -358,7 +360,7 @@ static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, int result; unsigned int tmp; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c); if (result) @@ -415,7 +417,7 @@ static void ttusb_dec_set_pids(struct ttusb_dec *dec) u16 audio = htons(dec->pid[DMX_PES_AUDIO]); u16 video = htons(dec->pid[DMX_PES_VIDEO]); - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); memcpy(&b[0], &pcr, 2); memcpy(&b[2], &audio, 2); @@ -434,12 +436,12 @@ static void ttusb_dec_set_pids(struct ttusb_dec *dec) static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length) { if (length < 8) { - printk("%s: packet too short - discarding\n", __FUNCTION__); + printk("%s: packet too short - discarding\n", __func__); return; } if (length > 8 + MAX_PVA_LENGTH) { - printk("%s: packet too long - discarding\n", __FUNCTION__); + printk("%s: packet too long - discarding\n", __func__); return; } @@ -522,7 +524,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length) break; default: - printk("%s: unknown PVA type: %02x.\n", __FUNCTION__, + printk("%s: unknown PVA type: %02x.\n", __func__, pva[2]); break; } @@ -561,7 +563,7 @@ static void ttusb_dec_process_packet(struct ttusb_dec *dec) u16 packet_id; if (dec->packet_length % 2) { - printk("%s: odd sized packet - discarding\n", __FUNCTION__); + printk("%s: odd sized packet - discarding\n", __func__); return; } @@ -569,7 +571,7 @@ static void ttusb_dec_process_packet(struct ttusb_dec *dec) csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]); if (csum) { - printk("%s: checksum failed - discarding\n", __FUNCTION__); + printk("%s: checksum failed - discarding\n", __func__); return; } @@ -578,7 +580,7 @@ static void ttusb_dec_process_packet(struct ttusb_dec *dec) if ((packet_id != dec->next_packet_id) && dec->next_packet_id) { printk("%s: warning: lost packets between %u and %u\n", - __FUNCTION__, dec->next_packet_id - 1, packet_id); + __func__, dec->next_packet_id - 1, packet_id); } if (packet_id == 0xffff) @@ -667,7 +669,7 @@ static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b, dec->packet_state = 7; } else { printk("%s: unknown packet type: " - "%02x%02x\n", __FUNCTION__, + "%02x%02x\n", __func__, dec->packet[0], dec->packet[1]); dec->packet_state = 0; } @@ -739,7 +741,7 @@ static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b, default: printk("%s: illegal packet state encountered.\n", - __FUNCTION__); + __func__); dec->packet_state = 0; } } @@ -811,7 +813,7 @@ static void ttusb_dec_process_urb(struct urb *urb) } else { /* -ENOENT is expected when unlinking urbs */ if (urb->status != -ENOENT) - dprintk("%s: urb error: %d\n", __FUNCTION__, + dprintk("%s: urb error: %d\n", __func__, urb->status); } @@ -823,7 +825,7 @@ static void ttusb_dec_setup_urbs(struct ttusb_dec *dec) { int i, j, buffer_offset = 0; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); for (i = 0; i < ISO_BUF_COUNT; i++) { int frame_offset = 0; @@ -853,7 +855,7 @@ static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec) { int i; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); if (mutex_lock_interruptible(&dec->iso_mutex)) return; @@ -908,7 +910,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) { int i, result; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); if (mutex_lock_interruptible(&dec->iso_mutex)) return -EAGAIN; @@ -924,7 +926,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) if ((result = usb_submit_urb(dec->iso_urb[i], GFP_ATOMIC))) { printk("%s: failed urb submission %d: " - "error %d\n", __FUNCTION__, i, result); + "error %d\n", __func__, i, result); while (i) { usb_kill_urb(dec->iso_urb[i - 1]); @@ -951,7 +953,7 @@ static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed) u8 b0[] = { 0x05 }; int result = 0; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); dprintk(" ts_type:"); @@ -1031,7 +1033,7 @@ static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed) unsigned long flags; u8 x = 1; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); pid = htons(dvbdmxfeed->pid); memcpy(&b0[0], &pid, 2); @@ -1071,7 +1073,7 @@ static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed) { struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); if (!dvbdmx->dmx.frontend) return -EINVAL; @@ -1132,7 +1134,7 @@ static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed) static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed) { - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); switch (dvbdmxfeed->type) { case DMX_TYPE_TS: @@ -1151,7 +1153,7 @@ static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec) { int i; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); for (i = 0; i < ISO_BUF_COUNT; i++) usb_free_urb(dec->iso_urb[i]); @@ -1166,7 +1168,7 @@ static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec) { int i; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); dec->iso_buffer = pci_alloc_consistent(NULL, ISO_FRAME_SIZE * @@ -1233,7 +1235,7 @@ static int ttusb_init_rc( struct ttusb_dec *dec) dec->rc_input_dev = input_dev; if (usb_submit_urb(dec->irq_urb, GFP_KERNEL)) - printk("%s: usb_submit_urb failed\n",__FUNCTION__); + printk("%s: usb_submit_urb failed\n",__func__); /* enable irq pipe */ ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL); @@ -1242,7 +1244,7 @@ static int ttusb_init_rc( struct ttusb_dec *dec) static void ttusb_dec_init_v_pes(struct ttusb_dec *dec) { - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); dec->v_pes[0] = 0x00; dec->v_pes[1] = 0x00; @@ -1252,7 +1254,7 @@ static void ttusb_dec_init_v_pes(struct ttusb_dec *dec) static int ttusb_dec_init_usb(struct ttusb_dec *dec) { - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); mutex_init(&dec->usb_mutex); mutex_init(&dec->iso_mutex); @@ -1300,11 +1302,11 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) u32 crc32_csum, crc32_check, tmp; const struct firmware *fw_entry = NULL; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) { printk(KERN_ERR "%s: Firmware (%s) unavailable.\n", - __FUNCTION__, dec->firmware_name); + __func__, dec->firmware_name); return 1; } @@ -1313,7 +1315,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) if (firmware_size < 60) { printk("%s: firmware size too small for DSP code (%zu < 60).\n", - __FUNCTION__, firmware_size); + __func__, firmware_size); release_firmware(fw_entry); return -1; } @@ -1327,7 +1329,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) if (crc32_csum != crc32_check) { printk("%s: crc32 check of DSP code failed (calculated " "0x%08x != 0x%08x in file), file invalid.\n", - __FUNCTION__, crc32_csum, crc32_check); + __func__, crc32_csum, crc32_check); release_firmware(fw_entry); return -1; } @@ -1395,7 +1397,7 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) int result; unsigned int mode, model, version; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); result = ttusb_dec_get_stb_state(dec, &mode, &model, &version); @@ -1434,7 +1436,7 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) default: printk(KERN_ERR "%s: unknown model returned " "by firmware (%08x) - please report\n", - __FUNCTION__, model); + __func__, model); return -1; break; } @@ -1453,12 +1455,14 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) { int result; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); if ((result = dvb_register_adapter(&dec->adapter, - dec->model_name, THIS_MODULE, &dec->udev->dev)) < 0) { + dec->model_name, THIS_MODULE, + &dec->udev->dev, + adapter_nr)) < 0) { printk("%s: dvb_register_adapter failed: error %d\n", - __FUNCTION__, result); + __func__, result); return result; } @@ -1473,7 +1477,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) dec->demux.write_to_decoder = NULL; if ((result = dvb_dmx_init(&dec->demux)) < 0) { - printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__, + printk("%s: dvb_dmx_init failed: error %d\n", __func__, result); dvb_unregister_adapter(&dec->adapter); @@ -1487,7 +1491,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) if ((result = dvb_dmxdev_init(&dec->dmxdev, &dec->adapter)) < 0) { printk("%s: dvb_dmxdev_init failed: error %d\n", - __FUNCTION__, result); + __func__, result); dvb_dmx_release(&dec->demux); dvb_unregister_adapter(&dec->adapter); @@ -1499,7 +1503,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx, &dec->frontend)) < 0) { - printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__, + printk("%s: dvb_dmx_init failed: error %d\n", __func__, result); dvb_dmxdev_release(&dec->dmxdev); @@ -1511,7 +1515,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx, &dec->frontend)) < 0) { - printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__, + printk("%s: dvb_dmx_init failed: error %d\n", __func__, result); dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend); @@ -1529,7 +1533,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) static void ttusb_dec_exit_dvb(struct ttusb_dec *dec) { - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); dvb_net_release(&dec->dvb_net); dec->demux.dmx.close(&dec->demux.dmx); @@ -1547,7 +1551,7 @@ static void ttusb_dec_exit_dvb(struct ttusb_dec *dec) static void ttusb_dec_exit_rc(struct ttusb_dec *dec) { - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); /* we have to check whether the irq URB is already submitted. * As the irq is submitted after the interface is changed, * this is the best method i figured out. @@ -1571,7 +1575,7 @@ static void ttusb_dec_exit_usb(struct ttusb_dec *dec) { int i; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); dec->iso_stream_count = 0; @@ -1631,12 +1635,12 @@ static int ttusb_dec_probe(struct usb_interface *intf, struct usb_device *udev; struct ttusb_dec *dec; - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); udev = interface_to_usbdev(intf); if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) { - printk("%s: couldn't allocate memory.\n", __FUNCTION__); + printk("%s: couldn't allocate memory.\n", __func__); return -ENOMEM; } @@ -1711,7 +1715,7 @@ static void ttusb_dec_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); - dprintk("%s\n", __FUNCTION__); + dprintk("%s\n", __func__); if (dec->active) { ttusb_dec_exit_tasklet(dec); @@ -1768,7 +1772,7 @@ static int __init ttusb_dec_init(void) int result; if ((result = usb_register(&ttusb_dec_driver)) < 0) { - printk("%s: initialisation failed: error %d.\n", __FUNCTION__, + printk("%s: initialisation failed: error %d.\n", __func__, result); return result; } diff --git a/linux/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/linux/drivers/media/dvb/ttusb-dec/ttusbdecfe.c index a6fb1d6a7..eb5eaeccd 100644 --- a/linux/drivers/media/dvb/ttusb-dec/ttusbdecfe.c +++ b/linux/drivers/media/dvb/ttusb-dec/ttusbdecfe.c @@ -53,7 +53,7 @@ static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status) return ret; if(len != 4) { - printk(KERN_ERR "%s: unexpected reply\n", __FUNCTION__); + printk(KERN_ERR "%s: unexpected reply\n", __func__); return -EIO; } @@ -70,7 +70,7 @@ static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status) break; default: pr_info("%s: returned unknown value: %d\n", - __FUNCTION__, result[3]); + __func__, result[3]); return -EIO; } diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index 83333734e..9f4207edc 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -532,8 +532,7 @@ static int si470x_get_register(struct si470x_device *radio, int regnr) retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); if (retval >= 0) - radio->registers[regnr] = be16_to_cpu(get_unaligned( - (unsigned short *) &buf[1])); + radio->registers[regnr] = get_unaligned_be16(&buf[1]); return (retval < 0) ? -EINVAL : 0; } @@ -548,8 +547,7 @@ static int si470x_set_register(struct si470x_device *radio, int regnr) int retval; buf[0] = REGISTER_REPORT(regnr); - put_unaligned(cpu_to_be16(radio->registers[regnr]), - (unsigned short *) &buf[1]); + put_unaligned_be16(radio->registers[regnr], &buf[1]); retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); @@ -572,9 +570,8 @@ static int si470x_get_all_registers(struct si470x_device *radio) if (retval >= 0) for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) - radio->registers[regnr] = be16_to_cpu(get_unaligned( - (unsigned short *) - &buf[regnr * RADIO_REGISTER_SIZE + 1])); + radio->registers[regnr] = get_unaligned_be16( + &buf[regnr * RADIO_REGISTER_SIZE + 1]); return (retval < 0) ? -EINVAL : 0; } @@ -605,8 +602,7 @@ static int si470x_get_rds_registers(struct si470x_device *radio) if (retval >= 0) for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) radio->registers[STATUSRSSI + regnr] = - be16_to_cpu(get_unaligned((unsigned short *) - &buf[regnr * RADIO_REGISTER_SIZE + 1])); + get_unaligned_be16(&buf[regnr * RADIO_REGISTER_SIZE + 1]); return (retval < 0) ? -EINVAL : 0; } @@ -854,7 +850,7 @@ static void si470x_rds(struct si470x_device *radio) }; /* Fill the V4L2 RDS buffer */ - put_unaligned(cpu_to_le16(rds), (unsigned short *) &tmpbuf); + put_unaligned_le16(rds, &tmpbuf); tmpbuf[2] = blocknum; /* offset name */ tmpbuf[2] |= blocknum << 3; /* received offset */ if (bler > max_rds_errors) diff --git a/linux/drivers/media/radio/radio-typhoon.c b/linux/drivers/media/radio/radio-typhoon.c index 22c999461..5db38526e 100644 --- a/linux/drivers/media/radio/radio-typhoon.c +++ b/linux/drivers/media/radio/radio-typhoon.c @@ -35,6 +35,7 @@ #include <linux/init.h> /* Initdata */ #include <linux/ioport.h> /* request_region */ #include <linux/proc_fs.h> /* radio card status report */ +#include <linux/seq_file.h> #include <asm/io.h> /* outb, outb_p */ #include <asm/uaccess.h> /* copy to/from user */ #include "compat.h" @@ -98,9 +99,6 @@ static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency); static void typhoon_mute(struct typhoon_device *dev); static void typhoon_unmute(struct typhoon_device *dev); static int typhoon_setvol(struct typhoon_device *dev, int vol); -#ifdef CONFIG_RADIO_TYPHOON_PROC_FS -static int typhoon_get_info(char *buf, char **start, off_t offset, int len); -#endif static void typhoon_setvol_generic(struct typhoon_device *dev, int vol) { @@ -373,30 +371,39 @@ static struct video_device typhoon_radio = #ifdef CONFIG_RADIO_TYPHOON_PROC_FS -static int typhoon_get_info(char *buf, char **start, off_t offset, int len) +static int typhoon_proc_show(struct seq_file *m, void *v) { - char *out = buf; - #ifdef MODULE #define MODULEPROCSTRING "Driver loaded as a module" #else #define MODULEPROCSTRING "Driver compiled into kernel" #endif - /* output must be kept under PAGE_SIZE */ - out += sprintf(out, BANNER); - out += sprintf(out, "Load type: " MODULEPROCSTRING "\n\n"); - out += sprintf(out, "frequency = %lu kHz\n", + seq_puts(m, BANNER); + seq_puts(m, "Load type: " MODULEPROCSTRING "\n\n"); + seq_printf(m, "frequency = %lu kHz\n", typhoon_unit.curfreq >> 4); - out += sprintf(out, "volume = %d\n", typhoon_unit.curvol); - out += sprintf(out, "mute = %s\n", typhoon_unit.muted ? + seq_printf(m, "volume = %d\n", typhoon_unit.curvol); + seq_printf(m, "mute = %s\n", typhoon_unit.muted ? "on" : "off"); - out += sprintf(out, "iobase = 0x%x\n", typhoon_unit.iobase); - out += sprintf(out, "mute frequency = %lu kHz\n", + seq_printf(m, "iobase = 0x%x\n", typhoon_unit.iobase); + seq_printf(m, "mute frequency = %lu kHz\n", typhoon_unit.mutefreq >> 4); - return out - buf; + return 0; } +static int typhoon_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, typhoon_proc_show, NULL); +} + +static const struct file_operations typhoon_proc_fops = { + .owner = THIS_MODULE, + .open = typhoon_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif /* CONFIG_RADIO_TYPHOON_PROC_FS */ MODULE_AUTHOR("Dr. Henrik Seidel"); @@ -457,8 +464,7 @@ static int __init typhoon_init(void) typhoon_mute(&typhoon_unit); #ifdef CONFIG_RADIO_TYPHOON_PROC_FS - if (!create_proc_info_entry("driver/radio-typhoon", 0, NULL, - typhoon_get_info)) + if (!proc_create("driver/radio-typhoon", 0, NULL, &typhoon_proc_fops)) printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n"); #endif diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index de6a6208e..fe9a4cc14 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -270,6 +270,15 @@ config VIDEO_SAA711X To compile this driver as a module, choose M here: the module will be called saa7115. +config VIDEO_SAA717X + tristate "Philips SAA7171/3/4 audio/video decoders" + depends on VIDEO_V4L2 && I2C + ---help--- + Support for the Philips SAA7171/3/4 audio/video decoders. + + To compile this driver as a module, choose M here: the + module will be called saa717x. + config VIDEO_SAA7191 tristate "Philips SAA7191 video decoder" depends on VIDEO_V4L1 && I2C @@ -689,6 +698,8 @@ source "drivers/media/video/cx88/Kconfig" source "drivers/media/video/cx23885/Kconfig" +source "drivers/media/video/au0828/Kconfig" + source "drivers/media/video/ivtv/Kconfig" config VIDEO_M32R_AR diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 53d4dbf50..f190c0702 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o obj-$(CONFIG_VIDEO_SAA7111) += saa7111.o obj-$(CONFIG_VIDEO_SAA7114) += saa7114.o obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o +obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o @@ -143,5 +144,7 @@ obj-$(CONFIG_SOC_CAMERA) += soc_camera.o obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o +obj-$(CONFIG_VIDEO_AU0828) += au0828/ + EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends diff --git a/linux/drivers/media/video/adv7170.c b/linux/drivers/media/video/adv7170.c index 0d15ce53d..54ef7aa63 100644 --- a/linux/drivers/media/video/adv7170.c +++ b/linux/drivers/media/video/adv7170.c @@ -409,7 +409,7 @@ adv7170_detect_client (struct i2c_adapter *adapter, return 0; client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == 0) + if (!client) return -ENOMEM; client->addr = address; client->adapter = adapter; diff --git a/linux/drivers/media/video/adv7175.c b/linux/drivers/media/video/adv7175.c index 86345ba5c..b8618c021 100644 --- a/linux/drivers/media/video/adv7175.c +++ b/linux/drivers/media/video/adv7175.c @@ -427,7 +427,7 @@ adv7175_detect_client (struct i2c_adapter *adapter, return 0; client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == 0) + if (!client) return -ENOMEM; client->addr = address; client->adapter = adapter; diff --git a/linux/drivers/media/video/au0828/Kconfig b/linux/drivers/media/video/au0828/Kconfig new file mode 100644 index 000000000..f04c80bc8 --- /dev/null +++ b/linux/drivers/media/video/au0828/Kconfig @@ -0,0 +1,13 @@ + +config VIDEO_AU0828 + tristate "Auvitek AU0828 support" + depends on VIDEO_DEV && I2C && INPUT + select I2C_ALGOBIT + select DVB_AU8522 if !DVB_FE_CUSTOMIZE + select DVB_TUNER_XC5000 if !DVB_FE_CUSTOMIZE + ---help--- + This is a video4linux driver for Auvitek's USB device. + + To compile this driver as a module, choose M here: the + module will be called au0828 + diff --git a/linux/drivers/media/video/au0828/Makefile b/linux/drivers/media/video/au0828/Makefile new file mode 100644 index 000000000..9f4f572c8 --- /dev/null +++ b/linux/drivers/media/video/au0828/Makefile @@ -0,0 +1,9 @@ +au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o + +obj-$(CONFIG_VIDEO_AU0828) += au0828.o + +EXTRA_CFLAGS += -Idrivers/media/video +EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core +EXTRA_CFLAGS += -Idrivers/media/dvb/frontends + +EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) diff --git a/linux/drivers/media/video/au0828/au0828-cards.c b/linux/drivers/media/video/au0828/au0828-cards.c new file mode 100644 index 000000000..8ca91f814 --- /dev/null +++ b/linux/drivers/media/video/au0828/au0828-cards.c @@ -0,0 +1,182 @@ +/* + * Driver for the Auvitek USB bridge + * + * Copyright (c) 2008 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. + */ + +#include "au0828.h" +#include "au0828-cards.h" + +struct au0828_board au0828_boards[] = { + [AU0828_BOARD_UNKNOWN] = { + .name = "Unknown board", + }, + [AU0828_BOARD_HAUPPAUGE_HVR850] = { + .name = "Hauppauge HVR850", + }, + [AU0828_BOARD_HAUPPAUGE_HVR950Q] = { + .name = "Hauppauge HVR950Q", + }, + [AU0828_BOARD_DVICO_FUSIONHDTV7] = { + .name = "DViCO FusionHDTV USB", + }, +}; +const unsigned int au0828_bcount = ARRAY_SIZE(au0828_boards); + +/* Tuner callback function for au0828 boards. Currently only needed + * for HVR1500Q, which has an xc5000 tuner. + */ +int au0828_tuner_callback(void *priv, int command, int arg) +{ + struct au0828_dev *dev = priv; + + dprintk(1, "%s()\n", __func__); + + switch (dev->board) { + case AU0828_BOARD_HAUPPAUGE_HVR850: + case AU0828_BOARD_HAUPPAUGE_HVR950Q: + case AU0828_BOARD_DVICO_FUSIONHDTV7: + if (command == 0) { + /* Tuner Reset Command from xc5000 */ + /* Drive the tuner into reset and out */ + au0828_clear(dev, REG_001, 2); + mdelay(200); + au0828_set(dev, REG_001, 2); + mdelay(50); + return 0; + } else { + printk(KERN_ERR + "%s(): Unknown command.\n", __func__); + return -EINVAL; + } + break; + } + + return 0; /* Should never be here */ +} + +static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data) +{ + struct tveeprom tv; + + tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data); + + /* Make sure we support the board model */ + switch (tv.model) { + case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */ + case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */ + break; + default: + printk(KERN_WARNING "%s: warning: " + "unknown hauppauge model #%d\n", __func__, tv.model); + break; + } + + printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n", + __func__, tv.model); +} + +void au0828_card_setup(struct au0828_dev *dev) +{ + static u8 eeprom[256]; + + dprintk(1, "%s()\n", __func__); + + if (dev->i2c_rc == 0) { + dev->i2c_client.addr = 0xa0 >> 1; + tveeprom_read(&dev->i2c_client, eeprom, sizeof(eeprom)); + } + + switch (dev->board) { + case AU0828_BOARD_HAUPPAUGE_HVR850: + case AU0828_BOARD_HAUPPAUGE_HVR950Q: + if (dev->i2c_rc == 0) + hauppauge_eeprom(dev, eeprom+0xa0); + break; + } +} + +/* + * The bridge has between 8 and 12 gpios. + * Regs 1 and 0 deal with output enables. + * Regs 3 and 2 deal with direction. + */ +void au0828_gpio_setup(struct au0828_dev *dev) +{ + dprintk(1, "%s()\n", __func__); + + switch (dev->board) { + case AU0828_BOARD_HAUPPAUGE_HVR850: + case AU0828_BOARD_HAUPPAUGE_HVR950Q: + /* GPIO's + * 4 - CS5340 + * 5 - AU8522 Demodulator + * 6 - eeprom W/P + * 9 - XC5000 Tuner + */ + + /* Into reset */ + au0828_write(dev, REG_003, 0x02); + au0828_write(dev, REG_002, 0x88 | 0x20); + au0828_write(dev, REG_001, 0x0); + au0828_write(dev, REG_000, 0x0); + msleep(100); + + /* Out of reset */ + au0828_write(dev, REG_003, 0x02); + au0828_write(dev, REG_001, 0x02); + au0828_write(dev, REG_002, 0x88 | 0x20); + au0828_write(dev, REG_000, 0x88 | 0x20 | 0x40); + msleep(250); + break; + case AU0828_BOARD_DVICO_FUSIONHDTV7: + /* GPIO's + * 6 - ? + * 8 - AU8522 Demodulator + * 9 - XC5000 Tuner + */ + + /* Into reset */ + au0828_write(dev, REG_003, 0x02); + au0828_write(dev, REG_002, 0xa0); + au0828_write(dev, REG_001, 0x0); + au0828_write(dev, REG_000, 0x0); + msleep(100); + + /* Out of reset */ + au0828_write(dev, REG_003, 0x02); + au0828_write(dev, REG_002, 0xa0); + au0828_write(dev, REG_001, 0x02); + au0828_write(dev, REG_000, 0xa0); + msleep(250); + break; + } +} + +/* table of devices that work with this driver */ +struct usb_device_id au0828_usb_id_table [] = { + { USB_DEVICE(0x2040, 0x7200), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, + { USB_DEVICE(0x2040, 0x7240), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR850 }, + { USB_DEVICE(0x0fe9, 0xd620), + .driver_info = AU0828_BOARD_DVICO_FUSIONHDTV7 }, + { }, +}; + +MODULE_DEVICE_TABLE(usb, au0828_usb_id_table); diff --git a/linux/drivers/media/video/au0828/au0828-cards.h b/linux/drivers/media/video/au0828/au0828-cards.h new file mode 100644 index 000000000..118629771 --- /dev/null +++ b/linux/drivers/media/video/au0828/au0828-cards.h @@ -0,0 +1,26 @@ +/* + * Driver for the Auvitek USB bridge + * + * Copyright (c) 2008 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. + */ + +#define AU0828_BOARD_UNKNOWN 0 +#define AU0828_BOARD_HAUPPAUGE_HVR950Q 1 +#define AU0828_BOARD_HAUPPAUGE_HVR850 2 +#define AU0828_BOARD_DVICO_FUSIONHDTV7 3 + diff --git a/linux/drivers/media/video/au0828/au0828-core.c b/linux/drivers/media/video/au0828/au0828-core.c new file mode 100644 index 000000000..b3a4346b1 --- /dev/null +++ b/linux/drivers/media/video/au0828/au0828-core.c @@ -0,0 +1,277 @@ +/* + * Driver for the Auvitek USB bridge + * + * Copyright (c) 2008 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. + */ + +#include <linux/module.h> +#include <linux/videodev2.h> +#include <media/v4l2-common.h> +#include "compat.h" +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 15) +#include <linux/mutex.h> +#endif + +#include "au0828.h" + +/* + * 1 = General debug messages + * 2 = USB handling + * 4 = I2C related + * 8 = Bridge related + */ +unsigned int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "enable debug messages"); + +unsigned int usb_debug; +module_param(usb_debug, int, 0644); +MODULE_PARM_DESC(usb_debug, "enable usb debug messages"); + +unsigned int bridge_debug; +module_param(bridge_debug, int, 0644); +MODULE_PARM_DESC(bridge_debug, "enable bridge debug messages"); + +#define _AU0828_BULKPIPE 0x03 +#define _BULKPIPESIZE 0xffff + +static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value, + u16 index, unsigned char *cp, u16 size); +static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value, + u16 index, unsigned char *cp, u16 size); + +/* USB Direction */ +#define CMD_REQUEST_IN 0x00 +#define CMD_REQUEST_OUT 0x01 + +u32 au0828_readreg(struct au0828_dev *dev, u16 reg) +{ + recv_control_msg(dev, CMD_REQUEST_IN, 0, reg, dev->ctrlmsg, 1); + dprintk(8, "%s(0x%x) = 0x%x\n", __func__, reg, dev->ctrlmsg[0]); + return dev->ctrlmsg[0]; +} + +u32 au0828_writereg(struct au0828_dev *dev, u16 reg, u32 val) +{ + dprintk(8, "%s(0x%x, 0x%x)\n", __func__, reg, val); + return send_control_msg(dev, CMD_REQUEST_OUT, val, reg, + dev->ctrlmsg, 0); +} + +static void cmd_msg_dump(struct au0828_dev *dev) +{ + int i; + + for (i = 0; i < sizeof(dev->ctrlmsg); i += 16) + dprintk(2, "%s() %02x %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x\n", + __func__, + dev->ctrlmsg[i+0], dev->ctrlmsg[i+1], + dev->ctrlmsg[i+2], dev->ctrlmsg[i+3], + dev->ctrlmsg[i+4], dev->ctrlmsg[i+5], + dev->ctrlmsg[i+6], dev->ctrlmsg[i+7], + dev->ctrlmsg[i+8], dev->ctrlmsg[i+9], + dev->ctrlmsg[i+10], dev->ctrlmsg[i+11], + dev->ctrlmsg[i+12], dev->ctrlmsg[i+13], + dev->ctrlmsg[i+14], dev->ctrlmsg[i+15]); +} + +static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value, + u16 index, unsigned char *cp, u16 size) +{ + int status = -ENODEV; + mutex_lock(&dev->mutex); + if (dev->usbdev) { + + /* cp must be memory that has been allocated by kmalloc */ + status = usb_control_msg(dev->usbdev, + usb_sndctrlpipe(dev->usbdev, 0), + request, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, + cp, size, 1000); + + status = min(status, 0); + + if (status < 0) { + printk(KERN_ERR "%s() Failed sending control message, error %d.\n", + __func__, status); + } + + } + mutex_unlock(&dev->mutex); + return status; +} + +static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value, + u16 index, unsigned char *cp, u16 size) +{ + int status = -ENODEV; + mutex_lock(&dev->mutex); + if (dev->usbdev) { + + memset(dev->ctrlmsg, 0, sizeof(dev->ctrlmsg)); + + /* cp must be memory that has been allocated by kmalloc */ + status = usb_control_msg(dev->usbdev, + usb_rcvctrlpipe(dev->usbdev, 0), + request, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, + cp, size, 1000); + + status = min(status, 0); + + if (status < 0) { + printk(KERN_ERR "%s() Failed receiving control message, error %d.\n", + __func__, status); + } else + cmd_msg_dump(dev); + } + mutex_unlock(&dev->mutex); + return status; +} + +static void au0828_usb_disconnect(struct usb_interface *interface) +{ + struct au0828_dev *dev = usb_get_intfdata(interface); + + dprintk(1, "%s()\n", __func__); + + /* Digital TV */ + au0828_dvb_unregister(dev); + + /* I2C */ + au0828_i2c_unregister(dev); + + usb_set_intfdata(interface, NULL); + + mutex_lock(&dev->mutex); + dev->usbdev = NULL; + mutex_unlock(&dev->mutex); + + kfree(dev); + +} + +static int au0828_usb_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + int ifnum; + struct au0828_dev *dev; + struct usb_device *usbdev = interface_to_usbdev(interface); + + ifnum = interface->altsetting->desc.bInterfaceNumber; + + if (ifnum != 0) + return -ENODEV; + + dprintk(1, "%s() vendor id 0x%x device id 0x%x ifnum:%d\n", __func__, + le16_to_cpu(usbdev->descriptor.idVendor), + le16_to_cpu(usbdev->descriptor.idProduct), + ifnum); + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) { + printk(KERN_ERR "%s() Unable to allocate memory\n", __func__); + return -ENOMEM; + } + + mutex_init(&dev->mutex); + mutex_init(&dev->dvb.lock); + dev->usbdev = usbdev; + dev->board = id->driver_info; + + usb_set_intfdata(interface, dev); + + /* Power Up the bridge */ + au0828_write(dev, REG_600, 1 << 4); + + /* Bring up the GPIO's and supporting devices */ + au0828_gpio_setup(dev); + + /* I2C */ + au0828_i2c_register(dev); + + /* Setup */ + au0828_card_setup(dev); + + /* Digital TV */ + au0828_dvb_register(dev); + + printk(KERN_INFO "Registered device AU0828 [%s]\n", + au0828_boards[dev->board].name == NULL ? "Unset" : + au0828_boards[dev->board].name); + + return 0; +} + +static struct usb_driver au0828_usb_driver = { + .name = DRIVER_NAME, + .probe = au0828_usb_probe, + .disconnect = au0828_usb_disconnect, + .id_table = au0828_usb_id_table, +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 15) + .owner = THIS_MODULE, +#endif +}; + +static int __init au0828_init(void) +{ + int ret; + + if (debug) + printk(KERN_INFO "%s() Debugging is enabled\n", __func__); + + if (usb_debug) { + printk(KERN_INFO "%s() USB Debugging is enabled\n", __func__); + debug |= 2; + } + + if (i2c_debug) { + printk(KERN_INFO "%s() I2C Debugging is enabled\n", __func__); + debug |= 4; + } + + if (bridge_debug) { + printk(KERN_INFO "%s() Bridge Debugging is enabled\n", + __func__); + debug |= 8; + } + + printk(KERN_INFO "au0828 driver loaded\n"); + + ret = usb_register(&au0828_usb_driver); + if (ret) + printk(KERN_ERR "usb_register failed, error = %d\n", ret); + + return ret; +} + +static void __exit au0828_exit(void) +{ + usb_deregister(&au0828_usb_driver); +} + +module_init(au0828_init); +module_exit(au0828_exit); + +MODULE_DESCRIPTION("Driver for Auvitek AU0828 based products"); +MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>"); +MODULE_LICENSE("GPL"); + diff --git a/linux/drivers/media/video/au0828/au0828-dvb.c b/linux/drivers/media/video/au0828/au0828-dvb.c new file mode 100644 index 000000000..f911bbac6 --- /dev/null +++ b/linux/drivers/media/video/au0828/au0828-dvb.c @@ -0,0 +1,402 @@ +/* + * Driver for the Auvitek USB bridge + * + * Copyright (c) 2008 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. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/suspend.h> +#include <media/v4l2-common.h> +#include "compat.h" + +#include "au0828.h" +#include "au8522.h" +#include "xc5000.h" + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +#define _AU0828_BULKPIPE 0x83 +#define _BULKPIPESIZE 0xe522 + +static struct au8522_config hauppauge_hvr950q_config = { + .demod_address = 0x8e >> 1, + .status_mode = AU8522_DEMODLOCKING, +}; + +static struct xc5000_config hauppauge_hvr950q_tunerconfig = { + .i2c_address = 0x61, + .if_khz = 6000, + .tuner_callback = au0828_tuner_callback +}; + +/*-------------------------------------------------------------------*/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void urb_completion(struct urb *purb, struct pt_regs *regs) +#else +static void urb_completion(struct urb *purb) +#endif +{ + u8 *ptr; + struct au0828_dev *dev = purb->context; + int ptype = usb_pipetype(purb->pipe); + + dprintk(2, "%s()\n", __func__); + + if (!dev) + return; + + if (dev->urb_streaming == 0) + return; + + if (ptype != PIPE_BULK) { + printk(KERN_ERR "%s() Unsupported URB type %d\n", + __func__, ptype); + return; + } + + ptr = (u8 *)purb->transfer_buffer; + + /* Feed the transport payload into the kernel demux */ + dvb_dmx_swfilter_packets(&dev->dvb.demux, + purb->transfer_buffer, purb->actual_length / 188); + + /* Clean the buffer before we requeue */ + memset(purb->transfer_buffer, 0, URB_BUFSIZE); + + /* Requeue URB */ + usb_submit_urb(purb, GFP_ATOMIC); +} + +static int stop_urb_transfer(struct au0828_dev *dev) +{ + int i; + + dprintk(2, "%s()\n", __func__); + + for (i = 0; i < URB_COUNT; i++) { + usb_kill_urb(dev->urbs[i]); + kfree(dev->urbs[i]->transfer_buffer); + usb_free_urb(dev->urbs[i]); + } + + dev->urb_streaming = 0; + + return 0; +} + +static int start_urb_transfer(struct au0828_dev *dev) +{ + struct urb *purb; + int i, ret = -ENOMEM; + + dprintk(2, "%s()\n", __func__); + + if (dev->urb_streaming) { + dprintk(2, "%s: iso xfer already running!\n", __func__); + return 0; + } + + for (i = 0; i < URB_COUNT; i++) { + + dev->urbs[i] = usb_alloc_urb(0, GFP_KERNEL); + if (!dev->urbs[i]) + goto err; + + purb = dev->urbs[i]; + + purb->transfer_buffer = kzalloc(URB_BUFSIZE, GFP_KERNEL); + if (!purb->transfer_buffer) { + usb_free_urb(purb); + dev->urbs[i] = 0; + goto err; + } + + purb->status = -EINPROGRESS; + usb_fill_bulk_urb(purb, + dev->usbdev, + usb_rcvbulkpipe(dev->usbdev, _AU0828_BULKPIPE), + purb->transfer_buffer, + URB_BUFSIZE, + urb_completion, + dev); + + } + + for (i = 0; i < URB_COUNT; i++) { + ret = usb_submit_urb(dev->urbs[i], GFP_ATOMIC); + if (ret != 0) { + stop_urb_transfer(dev); + printk(KERN_ERR "%s: failed urb submission, " + "err = %d\n", __func__, ret); + return ret; + } + } + + dev->urb_streaming = 1; + ret = 0; + +err: + return ret; +} + +static int au0828_dvb_start_feed(struct dvb_demux_feed *feed) +{ + struct dvb_demux *demux = feed->demux; + struct au0828_dev *dev = (struct au0828_dev *) demux->priv; + struct au0828_dvb *dvb = &dev->dvb; + int ret = 0; + + dprintk(1, "%s()\n", __func__); + + if (!demux->dmx.frontend) + return -EINVAL; + + if (dvb) { + mutex_lock(&dvb->lock); + if (dvb->feeding++ == 0) { + /* Start transport */ + au0828_write(dev, 0x608, 0x90); + au0828_write(dev, 0x609, 0x72); + au0828_write(dev, 0x60a, 0x71); + au0828_write(dev, 0x60b, 0x01); + ret = start_urb_transfer(dev); + } + mutex_unlock(&dvb->lock); + } + + return ret; +} + +static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed) +{ + struct dvb_demux *demux = feed->demux; + struct au0828_dev *dev = (struct au0828_dev *) demux->priv; + struct au0828_dvb *dvb = &dev->dvb; + int ret = 0; + + dprintk(1, "%s()\n", __func__); + + if (dvb) { + mutex_lock(&dvb->lock); + if (--dvb->feeding == 0) { + /* Stop transport */ + au0828_write(dev, 0x608, 0x00); + au0828_write(dev, 0x609, 0x00); + au0828_write(dev, 0x60a, 0x00); + au0828_write(dev, 0x60b, 0x00); + ret = stop_urb_transfer(dev); + } + mutex_unlock(&dvb->lock); + } + + return ret; +} + +int dvb_register(struct au0828_dev *dev) +{ + struct au0828_dvb *dvb = &dev->dvb; + int result; + + dprintk(1, "%s()\n", __func__); + + /* register adapter */ + result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE, + &dev->usbdev->dev, adapter_nr); + if (result < 0) { + printk(KERN_ERR "%s: dvb_register_adapter failed " + "(errno = %d)\n", DRIVER_NAME, result); + goto fail_adapter; + } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) + dvb->adapter.priv = dev; + + /* register frontend */ + result = dvb_register_frontend(&dvb->adapter, dvb->frontend); +#else + dvb->adapter->priv = dev; + + /* register frontend */ + result = dvb_register_frontend(dvb->adapter, dvb->frontend); +#endif + if (result < 0) { + printk(KERN_ERR "%s: dvb_register_frontend failed " + "(errno = %d)\n", DRIVER_NAME, result); + goto fail_frontend; + } + + /* register demux stuff */ + dvb->demux.dmx.capabilities = + DMX_TS_FILTERING | DMX_SECTION_FILTERING | + DMX_MEMORY_BASED_FILTERING; + dvb->demux.priv = dev; + dvb->demux.filternum = 256; + dvb->demux.feednum = 256; + dvb->demux.start_feed = au0828_dvb_start_feed; + dvb->demux.stop_feed = au0828_dvb_stop_feed; + result = dvb_dmx_init(&dvb->demux); + if (result < 0) { + printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n", + DRIVER_NAME, result); + goto fail_dmx; + } + + dvb->dmxdev.filternum = 256; + dvb->dmxdev.demux = &dvb->demux.dmx; + dvb->dmxdev.capabilities = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) + result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); +#else + result = dvb_dmxdev_init(&dvb->dmxdev, dvb->adapter); +#endif + if (result < 0) { + printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n", + DRIVER_NAME, result); + goto fail_dmxdev; + } + + dvb->fe_hw.source = DMX_FRONTEND_0; + result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); + if (result < 0) { + printk(KERN_ERR "%s: add_frontend failed " + "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result); + goto fail_fe_hw; + } + + dvb->fe_mem.source = DMX_MEMORY_FE; + result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); + if (result < 0) { + printk(KERN_ERR "%s: add_frontend failed " + "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result); + goto fail_fe_mem; + } + + result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); + if (result < 0) { + printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n", + DRIVER_NAME, result); + goto fail_fe_conn; + } + + /* register network adapter */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) + dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); +#else + dvb_net_init(dvb->adapter, &dvb->net, &dvb->demux.dmx); +#endif + return 0; + +fail_fe_conn: + dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); +fail_fe_mem: + dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); +fail_fe_hw: + dvb_dmxdev_release(&dvb->dmxdev); +fail_dmxdev: + dvb_dmx_release(&dvb->demux); +fail_dmx: + dvb_unregister_frontend(dvb->frontend); +fail_frontend: + dvb_frontend_detach(dvb->frontend); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) + dvb_unregister_adapter(&dvb->adapter); +#else + dvb_unregister_adapter(dvb->adapter); +#endif +fail_adapter: + return result; +} + +void au0828_dvb_unregister(struct au0828_dev *dev) +{ + struct au0828_dvb *dvb = &dev->dvb; + + dprintk(1, "%s()\n", __func__); + + if (dvb->frontend == NULL) + return; + + dvb_net_release(&dvb->net); + dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); + dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); + dvb_dmxdev_release(&dvb->dmxdev); + dvb_dmx_release(&dvb->demux); + dvb_unregister_frontend(dvb->frontend); + dvb_frontend_detach(dvb->frontend); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) + dvb_unregister_adapter(&dvb->adapter); +#else + dvb_unregister_adapter(dvb->adapter); +#endif +} + +/* All the DVB attach calls go here, this function get's modified + * for each new card. No other function in this file needs + * to change. + */ +int au0828_dvb_register(struct au0828_dev *dev) +{ + struct au0828_dvb *dvb = &dev->dvb; + int ret; + + dprintk(1, "%s()\n", __func__); + + /* init frontend */ + switch (dev->board) { + case AU0828_BOARD_HAUPPAUGE_HVR850: + case AU0828_BOARD_HAUPPAUGE_HVR950Q: + case AU0828_BOARD_DVICO_FUSIONHDTV7: + dvb->frontend = dvb_attach(au8522_attach, + &hauppauge_hvr950q_config, + &dev->i2c_adap); + if (dvb->frontend != NULL) { + hauppauge_hvr950q_tunerconfig.priv = dev; + dvb_attach(xc5000_attach, dvb->frontend, + &dev->i2c_adap, + &hauppauge_hvr950q_tunerconfig); + } + break; + default: + printk(KERN_WARNING "The frontend of your DVB/ATSC card " + "isn't supported yet\n"); + break; + } + if (NULL == dvb->frontend) { + printk(KERN_ERR "%s() Frontend initialization failed\n", + __func__); + return -1; + } + + /* Put the analog decoder in standby to keep it quiet */ + au0828_call_i2c_clients(dev, TUNER_SET_STANDBY, NULL); + + if (dvb->frontend->ops.analog_ops.standby) + dvb->frontend->ops.analog_ops.standby(dvb->frontend); + + /* register everything */ + ret = dvb_register(dev); + if (ret < 0) { + if (dvb->frontend->ops.release) + dvb->frontend->ops.release(dvb->frontend); + return ret; + } + + return 0; +} + diff --git a/linux/drivers/media/video/au0828/au0828-i2c.c b/linux/drivers/media/video/au0828/au0828-i2c.c new file mode 100644 index 000000000..08d2a6080 --- /dev/null +++ b/linux/drivers/media/video/au0828/au0828-i2c.c @@ -0,0 +1,388 @@ +/* + * Driver for the Auvitek AU0828 USB bridge + * + * Copyright (c) 2008 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. + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/io.h> + +#include "compat.h" +#include "au0828.h" + +#include <media/v4l2-common.h> + +unsigned int i2c_debug; +module_param(i2c_debug, int, 0444); +MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); + +unsigned int i2c_scan; +module_param(i2c_scan, int, 0444); +MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); + +#define I2C_WAIT_DELAY 512 +#define I2C_WAIT_RETRY 64 + +static inline int i2c_slave_did_write_ack(struct i2c_adapter *i2c_adap) +{ + struct au0828_dev *dev = i2c_adap->algo_data; + return au0828_read(dev, REG_201) & 0x08 ? 0 : 1; +} + +static inline int i2c_slave_did_read_ack(struct i2c_adapter *i2c_adap) +{ + struct au0828_dev *dev = i2c_adap->algo_data; + return au0828_read(dev, REG_201) & 0x02 ? 0 : 1; +} + +static int i2c_wait_read_ack(struct i2c_adapter *i2c_adap) +{ + int count; + + for (count = 0; count < I2C_WAIT_RETRY; count++) { + if (!i2c_slave_did_read_ack(i2c_adap)) + break; + udelay(I2C_WAIT_DELAY); + } + + if (I2C_WAIT_RETRY == count) + return 0; + + return 1; +} + +static inline int i2c_is_read_busy(struct i2c_adapter *i2c_adap) +{ + struct au0828_dev *dev = i2c_adap->algo_data; + return au0828_read(dev, REG_201) & 0x01 ? 0 : 1; +} + +static int i2c_wait_read_done(struct i2c_adapter *i2c_adap) +{ + int count; + + for (count = 0; count < I2C_WAIT_RETRY; count++) { + if (!i2c_is_read_busy(i2c_adap)) + break; + udelay(I2C_WAIT_DELAY); + } + + if (I2C_WAIT_RETRY == count) + return 0; + + return 1; +} + +static inline int i2c_is_write_done(struct i2c_adapter *i2c_adap) +{ + struct au0828_dev *dev = i2c_adap->algo_data; + return au0828_read(dev, REG_201) & 0x04 ? 1 : 0; +} + +static int i2c_wait_write_done(struct i2c_adapter *i2c_adap) +{ + int count; + + for (count = 0; count < I2C_WAIT_RETRY; count++) { + if (i2c_is_write_done(i2c_adap)) + break; + udelay(I2C_WAIT_DELAY); + } + + if (I2C_WAIT_RETRY == count) + return 0; + + return 1; +} + +static inline int i2c_is_busy(struct i2c_adapter *i2c_adap) +{ + struct au0828_dev *dev = i2c_adap->algo_data; + return au0828_read(dev, REG_201) & 0x10 ? 1 : 0; +} + +static int i2c_wait_done(struct i2c_adapter *i2c_adap) +{ + int count; + + for (count = 0; count < I2C_WAIT_RETRY; count++) { + if (!i2c_is_busy(i2c_adap)) + break; + udelay(I2C_WAIT_DELAY); + } + + if (I2C_WAIT_RETRY == count) + return 0; + + return 1; +} + +/* FIXME: Implement join handling correctly */ +static int i2c_sendbytes(struct i2c_adapter *i2c_adap, + const struct i2c_msg *msg, int joined_rlen) +{ + int i, strobe = 0; + struct au0828_dev *dev = i2c_adap->algo_data; + + dprintk(4, "%s()\n", __func__); + + au0828_write(dev, REG_2FF, 0x01); + au0828_write(dev, REG_202, 0x07); + + /* Hardware needs 8 bit addresses */ + au0828_write(dev, REG_203, msg->addr << 1); + + dprintk(4, "SEND: %02x\n", msg->addr); + + for (i = 0; i < msg->len;) { + + dprintk(4, " %02x\n", msg->buf[i]); + + au0828_write(dev, REG_205, msg->buf[i]); + + strobe++; + i++; + + if ((strobe >= 4) || (i >= msg->len)) { + + /* Strobe the byte into the bus */ + if (i < msg->len) + au0828_write(dev, REG_200, 0x41); + else + au0828_write(dev, REG_200, 0x01); + + /* Reset strobe trigger */ + strobe = 0; + + if (!i2c_wait_write_done(i2c_adap)) + return -EIO; + + } + + } + if (!i2c_wait_done(i2c_adap)) + return -EIO; + + dprintk(4, "\n"); + + return msg->len; +} + +/* FIXME: Implement join handling correctly */ +static int i2c_readbytes(struct i2c_adapter *i2c_adap, + const struct i2c_msg *msg, int joined) +{ + struct au0828_dev *dev = i2c_adap->algo_data; + int i; + + dprintk(4, "%s()\n", __func__); + + au0828_write(dev, REG_2FF, 0x01); + au0828_write(dev, REG_202, 0x07); + + /* Hardware needs 8 bit addresses */ + au0828_write(dev, REG_203, msg->addr << 1); + + dprintk(4, " RECV:\n"); + + /* Deal with i2c_scan */ + if (msg->len == 0) { + au0828_write(dev, REG_200, 0x20); + if (i2c_wait_read_ack(i2c_adap)) + return -EIO; + return 0; + } + + for (i = 0; i < msg->len;) { + + i++; + + if (i < msg->len) + au0828_write(dev, REG_200, 0x60); + else + au0828_write(dev, REG_200, 0x20); + + if (!i2c_wait_read_done(i2c_adap)) + return -EIO; + + msg->buf[i-1] = au0828_read(dev, REG_209) & 0xff; + + dprintk(4, " %02x\n", msg->buf[i-1]); + } + if (!i2c_wait_done(i2c_adap)) + return -EIO; + + dprintk(4, "\n"); + + return msg->len; +} + +static int i2c_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, int num) +{ + int i, retval = 0; + + dprintk(4, "%s(num = %d)\n", __func__, num); + + for (i = 0; i < num; i++) { + dprintk(4, "%s(num = %d) addr = 0x%02x len = 0x%x\n", + __func__, num, msgs[i].addr, msgs[i].len); + if (msgs[i].flags & I2C_M_RD) { + /* read */ + retval = i2c_readbytes(i2c_adap, &msgs[i], 0); + } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && + msgs[i].addr == msgs[i + 1].addr) { + /* write then read from same address */ + retval = i2c_sendbytes(i2c_adap, &msgs[i], + msgs[i + 1].len); + if (retval < 0) + goto err; + i++; + retval = i2c_readbytes(i2c_adap, &msgs[i], 1); + } else { + /* write */ + retval = i2c_sendbytes(i2c_adap, &msgs[i], 0); + } + if (retval < 0) + goto err; + } + return num; + +err: + return retval; +} + +static int attach_inform(struct i2c_client *client) +{ + dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", + client->driver->driver.name, client->addr, client->name); + + if (!client->driver->command) + return 0; + + return 0; +} + +static int detach_inform(struct i2c_client *client) +{ + dprintk(1, "i2c detach [client=%s]\n", client->name); + + return 0; +} + +void au0828_call_i2c_clients(struct au0828_dev *dev, + unsigned int cmd, void *arg) +{ + if (dev->i2c_rc != 0) + return; + + i2c_clients_command(&dev->i2c_adap, cmd, arg); +} + +static u32 au0828_functionality(struct i2c_adapter *adap) +{ + return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; +} + +static struct i2c_algorithm au0828_i2c_algo_template = { + .master_xfer = i2c_xfer, + .functionality = au0828_functionality, +}; + +/* ----------------------------------------------------------------------- */ + +static struct i2c_adapter au0828_i2c_adap_template = { + .name = DRIVER_NAME, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) + .owner = THIS_MODULE, +#endif + .id = I2C_HW_B_AU0828, + .algo = &au0828_i2c_algo_template, + .class = I2C_CLASS_TV_ANALOG, + .client_register = attach_inform, + .client_unregister = detach_inform, +}; + +static struct i2c_client au0828_i2c_client_template = { + .name = "au0828 internal", +}; + +static char *i2c_devs[128] = { + [0x8e >> 1] = "au8522", + [0xa0 >> 1] = "eeprom", + [0xc2 >> 1] = "tuner/xc5000", +}; + +static void do_i2c_scan(char *name, struct i2c_client *c) +{ + unsigned char buf; + int i, rc; + + for (i = 0; i < 128; i++) { + c->addr = i; + rc = i2c_master_recv(c, &buf, 0); + if (rc < 0) + continue; + printk(KERN_INFO "%s: i2c scan: found device @ 0x%x [%s]\n", + name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); + } +} + +/* init + register i2c algo-bit adapter */ +int au0828_i2c_register(struct au0828_dev *dev) +{ + dprintk(1, "%s()\n", __func__); + + memcpy(&dev->i2c_adap, &au0828_i2c_adap_template, + sizeof(dev->i2c_adap)); + memcpy(&dev->i2c_algo, &au0828_i2c_algo_template, + sizeof(dev->i2c_algo)); + memcpy(&dev->i2c_client, &au0828_i2c_client_template, + sizeof(dev->i2c_client)); + + dev->i2c_adap.dev.parent = &dev->usbdev->dev; + + strlcpy(dev->i2c_adap.name, DRIVER_NAME, + sizeof(dev->i2c_adap.name)); + + dev->i2c_algo.data = dev; + dev->i2c_adap.algo_data = dev; + i2c_set_adapdata(&dev->i2c_adap, dev); + i2c_add_adapter(&dev->i2c_adap); + + dev->i2c_client.adapter = &dev->i2c_adap; + + if (0 == dev->i2c_rc) { + printk(KERN_INFO "%s: i2c bus registered\n", DRIVER_NAME); + if (i2c_scan) + do_i2c_scan(DRIVER_NAME, &dev->i2c_client); + } else + printk(KERN_INFO "%s: i2c bus register FAILED\n", DRIVER_NAME); + + return dev->i2c_rc; +} + +int au0828_i2c_unregister(struct au0828_dev *dev) +{ + i2c_del_adapter(&dev->i2c_adap); + return 0; +} + diff --git a/linux/drivers/media/video/au0828/au0828-reg.h b/linux/drivers/media/video/au0828/au0828-reg.h new file mode 100644 index 000000000..398275508 --- /dev/null +++ b/linux/drivers/media/video/au0828/au0828-reg.h @@ -0,0 +1,38 @@ +/* + * Driver for the Auvitek USB bridge + * + * Copyright (c) 2008 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. + */ + +/* We'll start to rename these registers once we have a better + * understanding of their meaning. + */ +#define REG_000 0x000 +#define REG_001 0x001 +#define REG_002 0x002 +#define REG_003 0x003 + +#define REG_200 0x200 +#define REG_201 0x201 +#define REG_202 0x202 +#define REG_203 0x203 +#define REG_205 0x205 +#define REG_209 0x209 +#define REG_2FF 0x2ff + +#define REG_600 0x600 diff --git a/linux/drivers/media/video/au0828/au0828.h b/linux/drivers/media/video/au0828/au0828.h new file mode 100644 index 000000000..4b0ad1b3e --- /dev/null +++ b/linux/drivers/media/video/au0828/au0828.h @@ -0,0 +1,137 @@ +/* + * Driver for the Auvitek AU0828 USB bridge + * + * Copyright (c) 2008 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. + */ + +#include <linux/usb.h> +#include <linux/i2c.h> +#include <linux/i2c-algo-bit.h> +#include <media/tveeprom.h> + +/* DVB */ +#include "demux.h" +#include "dmxdev.h" +#include "dvb_demux.h" +#include "dvb_frontend.h" +#include "dvb_net.h" +#include "dvbdev.h" + +#include "au0828-reg.h" +#include "au0828-cards.h" + +#define DRIVER_NAME "au0828" +#define URB_COUNT 16 +#define URB_BUFSIZE (0xe522) + +struct au0828_board { + char *name; +}; + +struct au0828_dvb { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 15) + struct mutex lock; +#else + struct semaphore lock; +#endif + struct dvb_adapter adapter; + struct dvb_frontend *frontend; + struct dvb_demux demux; + struct dmxdev dmxdev; + struct dmx_frontend fe_hw; + struct dmx_frontend fe_mem; + struct dvb_net net; + int feeding; +}; + +struct au0828_dev { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 15) + struct mutex mutex; +#else + struct semaphore mutex; +#endif + struct usb_device *usbdev; + int board; + u8 ctrlmsg[64]; + + /* I2C */ + struct i2c_adapter i2c_adap; + struct i2c_algo_bit_data i2c_algo; + struct i2c_client i2c_client; + u32 i2c_rc; + + /* Digital */ + struct au0828_dvb dvb; + + /* USB / URB Related */ + int urb_streaming; + struct urb *urbs[URB_COUNT]; + +}; + +struct au0828_buff { + struct au0828_dev *dev; + struct urb *purb; + struct list_head buff_list; +}; + +/* ----------------------------------------------------------- */ +#define au0828_read(dev, reg) au0828_readreg(dev, reg) +#define au0828_write(dev, reg, value) au0828_writereg(dev, reg, value) +#define au0828_andor(dev, reg, mask, value) \ + au0828_writereg(dev, reg, \ + (au0828_readreg(dev, reg) & ~(mask)) | ((value) & (mask))) + +#define au0828_set(dev, reg, bit) au0828_andor(dev, (reg), (bit), (bit)) +#define au0828_clear(dev, reg, bit) au0828_andor(dev, (reg), (bit), 0) + +/* ----------------------------------------------------------- */ +/* au0828-core.c */ +extern u32 au0828_read(struct au0828_dev *dev, u16 reg); +extern u32 au0828_write(struct au0828_dev *dev, u16 reg, u32 val); +extern unsigned int debug; +extern unsigned int usb_debug; +extern unsigned int bridge_debug; + +/* ----------------------------------------------------------- */ +/* au0828-cards.c */ +extern struct au0828_board au0828_boards[]; +extern struct usb_device_id au0828_usb_id_table[]; +extern const unsigned int au0828_bcount; +extern void au0828_gpio_setup(struct au0828_dev *dev); +extern int au0828_tuner_callback(void *priv, int command, int arg); +extern void au0828_card_setup(struct au0828_dev *dev); + +/* ----------------------------------------------------------- */ +/* au0828-i2c.c */ +extern int au0828_i2c_register(struct au0828_dev *dev); +extern int au0828_i2c_unregister(struct au0828_dev *dev); +extern void au0828_call_i2c_clients(struct au0828_dev *dev, + unsigned int cmd, void *arg); +extern unsigned int i2c_debug; + +/* ----------------------------------------------------------- */ +/* au0828-dvb.c */ +extern int au0828_dvb_register(struct au0828_dev *dev); +extern void au0828_dvb_unregister(struct au0828_dev *dev); + +#define dprintk(level, fmt, arg...)\ + do { if (debug & level)\ + printk(KERN_DEBUG DRIVER_NAME "/0: " fmt, ## arg);\ + } while (0) + diff --git a/linux/drivers/media/video/bt819.c b/linux/drivers/media/video/bt819.c index 9264e2cff..402bccaf7 100644 --- a/linux/drivers/media/video/bt819.c +++ b/linux/drivers/media/video/bt819.c @@ -525,7 +525,7 @@ bt819_detect_client (struct i2c_adapter *adapter, return 0; client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == 0) + if (!client) return -ENOMEM; client->addr = address; client->adapter = adapter; diff --git a/linux/drivers/media/video/bt856.c b/linux/drivers/media/video/bt856.c index 7abfad9a4..50ca987ad 100644 --- a/linux/drivers/media/video/bt856.c +++ b/linux/drivers/media/video/bt856.c @@ -312,7 +312,7 @@ bt856_detect_client (struct i2c_adapter *adapter, return 0; client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == 0) + if (!client) return -ENOMEM; client->addr = address; client->adapter = adapter; diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c index c1173a94a..303422115 100644 --- a/linux/drivers/media/video/bt8xx/bttv-driver.c +++ b/linux/drivers/media/video/bt8xx/bttv-driver.c @@ -3506,6 +3506,9 @@ static int radio_release(struct inode *inode, struct file *file) struct bttv *btv = fh->btv; struct rds_command cmd; + file->private_data = NULL; + kfree(fh); + btv->radio_user--; bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd); diff --git a/linux/drivers/media/video/c-qcam.c b/linux/drivers/media/video/c-qcam.c index 479ef617b..a5f5b8a4a 100644 --- a/linux/drivers/media/video/c-qcam.c +++ b/linux/drivers/media/video/c-qcam.c @@ -39,6 +39,7 @@ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) #include <linux/mutex.h> #endif +#include <linux/jiffies.h> #include <asm/uaccess.h> @@ -102,7 +103,8 @@ static unsigned int qcam_await_ready1(struct qcam_device *qcam, unsigned long oldjiffies = jiffies; unsigned int i; - for (oldjiffies = jiffies; (jiffies - oldjiffies) < msecs_to_jiffies(40); ) + for (oldjiffies = jiffies; + time_before(jiffies, oldjiffies + msecs_to_jiffies(40)); ) if (qcam_ready1(qcam) == value) return 0; @@ -127,7 +129,8 @@ static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value) unsigned long oldjiffies = jiffies; unsigned int i; - for (oldjiffies = jiffies; (jiffies - oldjiffies) < msecs_to_jiffies(40); ) + for (oldjiffies = jiffies; + time_before(jiffies, oldjiffies + msecs_to_jiffies(40)); ) if (qcam_ready2(qcam) == value) return 0; diff --git a/linux/drivers/media/video/cpia.h b/linux/drivers/media/video/cpia.h index 107234853..d579b5edb 100644 --- a/linux/drivers/media/video/cpia.h +++ b/linux/drivers/media/video/cpia.h @@ -423,11 +423,11 @@ void cpia_unregister_camera(struct cam_data *cam); /* ErrorCode */ #define ERROR_FLICKER_BELOW_MIN_EXP 0x01 /*flicker exposure got below minimum exposure */ #define ALOG(fmt,args...) printk(fmt, ##args) -#define LOG(fmt,args...) ALOG(KERN_INFO __FILE__ ":%s(%d):" fmt, __FUNCTION__ , __LINE__ , ##args) +#define LOG(fmt,args...) ALOG(KERN_INFO __FILE__ ":%s(%d):" fmt, __func__ , __LINE__ , ##args) #ifdef _CPIA_DEBUG_ #define ADBG(fmt,args...) printk(fmt, jiffies, ##args) -#define DBG(fmt,args...) ADBG(KERN_DEBUG __FILE__" (%ld):%s(%d):" fmt, __FUNCTION__, __LINE__ , ##args) +#define DBG(fmt,args...) ADBG(KERN_DEBUG __FILE__" (%ld):%s(%d):" fmt, __func__, __LINE__ , ##args) #else #define DBG(fmn,args...) do {} while(0) #endif diff --git a/linux/drivers/media/video/cpia2/cpia2_core.c b/linux/drivers/media/video/cpia2/cpia2_core.c index a439a56c3..c8b9fdb70 100644 --- a/linux/drivers/media/video/cpia2/cpia2_core.c +++ b/linux/drivers/media/video/cpia2/cpia2_core.c @@ -570,7 +570,7 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd) block_name[block_index]); break; default: - LOG("%s: invalid request mode\n",__FUNCTION__); + LOG("%s: invalid request mode\n",__func__); return -EINVAL; } @@ -952,7 +952,7 @@ static int set_default_user_mode(struct camera_data *cam) frame_rate = CPIA2_VP_FRAMERATE_30; break; default: - LOG("%s: Invalid sensor flag value 0x%0X\n",__FUNCTION__, + LOG("%s: Invalid sensor flag value 0x%0X\n",__func__, cam->params.version.sensor_flags); return -EINVAL; } @@ -2356,12 +2356,12 @@ long cpia2_read(struct camera_data *cam, } if (!buf) { - ERR("%s: buffer NULL\n",__FUNCTION__); + ERR("%s: buffer NULL\n",__func__); return -EINVAL; } if (!cam) { - ERR("%s: Internal error, camera_data NULL!\n",__FUNCTION__); + ERR("%s: Internal error, camera_data NULL!\n",__func__); return -EINVAL; } @@ -2370,7 +2370,7 @@ long cpia2_read(struct camera_data *cam, return -ERESTARTSYS; if (!cam->present) { - LOG("%s: camera removed\n",__FUNCTION__); + LOG("%s: camera removed\n",__func__); mutex_unlock(&cam->busy_lock); return 0; /* EOF */ } @@ -2434,7 +2434,7 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp, unsigned int status=0; if(!cam) { - ERR("%s: Internal error, camera_data not found!\n",__FUNCTION__); + ERR("%s: Internal error, camera_data not found!\n",__func__); return POLLERR; } diff --git a/linux/drivers/media/video/cpia_usb.c b/linux/drivers/media/video/cpia_usb.c index 0d974be34..781999632 100644 --- a/linux/drivers/media/video/cpia_usb.c +++ b/linux/drivers/media/video/cpia_usb.c @@ -174,7 +174,7 @@ static void cpia_usb_complete(struct urb *urb) /* resubmit */ urb->dev = ucpia->dev; if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0) - printk(KERN_ERR "%s: usb_submit_urb ret %d\n", __FUNCTION__, i); + printk(KERN_ERR "%s: usb_submit_urb ret %d\n", __func__, i); } static int cpia_usb_open(void *privdata) diff --git a/linux/drivers/media/video/cx23885/Kconfig b/linux/drivers/media/video/cx23885/Kconfig index 1fd326fe4..ca5fbce3a 100644 --- a/linux/drivers/media/video/cx23885/Kconfig +++ b/linux/drivers/media/video/cx23885/Kconfig @@ -8,6 +8,7 @@ config VIDEO_CX23885 select VIDEO_TVEEPROM select VIDEO_IR select VIDEOBUF_DVB + select VIDEO_CX25840 select DVB_TUNER_MT2131 if !DVB_FE_CUSTOMISE select DVB_S5H1409 if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE @@ -16,6 +17,7 @@ config VIDEO_CX23885 select TUNER_TDA8290 if !DVB_FE_CUSTOMIZE select DVB_TDA18271 if !DVB_FE_CUSTOMIZE select DVB_TUNER_XC5000 if !DVB_FE_CUSTOMIZE + select DVB_TDA10048 if !DVB_FE_CUSTOMIZE ---help--- This is a video4linux driver for Conexant 23885 based TV cards. diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index 8a4d5143f..0c25b7dd1 100644 --- a/linux/drivers/media/video/cx23885/cx23885-cards.c +++ b/linux/drivers/media/video/cx23885/cx23885-cards.c @@ -131,6 +131,14 @@ struct cx23885_board cx23885_boards[] = { .name = "Hauppauge WinTV-HVR1500", .portc = CX23885_MPEG_DVB, }, + [CX23885_BOARD_HAUPPAUGE_HVR1200] = { + .name = "Hauppauge WinTV-HVR1200", + .portc = CX23885_MPEG_DVB, + }, + [CX23885_BOARD_HAUPPAUGE_HVR1700] = { + .name = "Hauppauge WinTV-HVR1700", + .portc = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -182,6 +190,14 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x0070, .subdevice = 0x7717, .card = CX23885_BOARD_HAUPPAUGE_HVR1500, + }, { + .subvendor = 0x0070, + .subdevice = 0x71d1, + .card = CX23885_BOARD_HAUPPAUGE_HVR1200, + }, { + .subvendor = 0x0070, + .subdevice = 0x8101, + .card = CX23885_BOARD_HAUPPAUGE_HVR1700, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -236,6 +252,9 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) case 79561: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ case 79571: /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, ATSC and Basic analog */ case 79671: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */ + case 81519: + /* WinTV-HVR1700 (PCIe, Retail, No IR, half height, + * DVB-T and MPEG2 HW Encoder */ break; default: printk("%s: warning: unknown hauppauge model #%d\n", dev->name, tv.model); @@ -265,7 +284,7 @@ int cx23885_tuner_callback(void *priv, int command, int arg) } else { printk(KERN_ERR - "%s(): Unknow command.\n", __FUNCTION__); + "%s(): Unknow command.\n", __func__); return -EINVAL; } break; @@ -315,6 +334,38 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) cx_set(GP0_IO, 0x00040004); mdelay(20); break; + case CX23885_BOARD_HAUPPAUGE_HVR1200: + /* GPIO-0 tda10048 demodulator reset */ + /* GPIO-2 tda18271 tuner reset */ + + /* Put the parts into reset and back */ + cx_set(GP0_IO, 0x00050000); + mdelay(20); + cx_clear(GP0_IO, 0x00000005); + mdelay(20); + cx_set(GP0_IO, 0x00050005); + break; + case CX23885_BOARD_HAUPPAUGE_HVR1700: + /* GPIO-0 TDA10048 demodulator reset */ + /* GPIO-2 TDA8295A Reset */ + /* GPIO-3-10 cx23417 data0-7 */ + /* GPIO-11-14 cx23417 addr0-3 */ + /* GPIO-15-18 cx23417 READY, CS, RD, WR */ + + /* The following GPIO's are on the interna AVCore (cx25840) */ + /* GPIO-19 IR_RX */ + /* GPIO-20 IR_TX 416/DVBT Select */ + /* GPIO-21 IIS DAT */ + /* GPIO-22 IIS WCLK */ + /* GPIO-23 IIS BCLK */ + + /* Put the parts into reset and back */ + cx_set(GP0_IO, 0x00050000); + mdelay(20); + cx_clear(GP0_IO, 0x00000005); + mdelay(20); + cx_set(GP0_IO, 0x00050005); + break; } } @@ -325,6 +376,7 @@ int cx23885_ir_init(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500Q: case CX23885_BOARD_HAUPPAUGE_HVR1800: + case CX23885_BOARD_HAUPPAUGE_HVR1200: /* FIXME: Implement me */ break; } @@ -354,6 +406,8 @@ void cx23885_card_setup(struct cx23885_dev *dev) break; case CX23885_BOARD_HAUPPAUGE_HVR1800: case CX23885_BOARD_HAUPPAUGE_HVR1800lp: + case CX23885_BOARD_HAUPPAUGE_HVR1200: + case CX23885_BOARD_HAUPPAUGE_HVR1700: if (dev->i2c_bus[0].i2c_rc == 0) hauppauge_eeprom(dev, eeprom+0xc0); break; @@ -370,12 +424,24 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1500Q: case CX23885_BOARD_HAUPPAUGE_HVR1800: case CX23885_BOARD_HAUPPAUGE_HVR1800lp: + case CX23885_BOARD_HAUPPAUGE_HVR1200: + case CX23885_BOARD_HAUPPAUGE_HVR1700: default: ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; } + /* Certain boards support analog, or require the avcore to be + * loaded, ensure this happens. + */ + switch (dev->board) { + case CX23885_BOARD_HAUPPAUGE_HVR1800: + case CX23885_BOARD_HAUPPAUGE_HVR1800lp: + case CX23885_BOARD_HAUPPAUGE_HVR1700: + request_module("cx25840"); + break; + } } /* ------------------------------------------------------------------ */ diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c index 9408d2cd2..968b31716 100644 --- a/linux/drivers/media/video/cx23885/cx23885-core.c +++ b/linux/drivers/media/video/cx23885/cx23885-core.c @@ -261,7 +261,7 @@ void cx23885_wakeup(struct cx23885_tsport *port, } if (bc != 1) printk("%s: %d buffers handled (should be 1)\n", - __FUNCTION__, bc); + __func__, bc); } int cx23885_sram_channel_setup(struct cx23885_dev *dev, @@ -273,7 +273,7 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, if (ch->cmds_start == 0) { - dprintk(1, "%s() Erasing channel [%s]\n", __FUNCTION__, + dprintk(1, "%s() Erasing channel [%s]\n", __func__, ch->name); cx_write(ch->ptr1_reg, 0); cx_write(ch->ptr2_reg, 0); @@ -281,7 +281,7 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, cx_write(ch->cnt1_reg, 0); return 0; } else { - dprintk(1, "%s() Configuring channel [%s]\n", __FUNCTION__, + dprintk(1, "%s() Configuring channel [%s]\n", __func__, ch->name); } @@ -298,7 +298,7 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, /* write CDT */ for (i = 0; i < lines; i++) { - dprintk(2, "%s() 0x%08x <- 0x%08x\n", __FUNCTION__, cdt + 16*i, + dprintk(2, "%s() 0x%08x <- 0x%08x\n", __func__, cdt + 16*i, ch->fifo_start + bpl*i); cx_write(cdt + 16*i, ch->fifo_start + bpl*i); cx_write(cdt + 16*i + 4, 0); @@ -450,7 +450,7 @@ static void cx23885_shutdown(struct cx23885_dev *dev) static void cx23885_reset(struct cx23885_dev *dev) { - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); cx23885_shutdown(dev); @@ -483,7 +483,7 @@ static void cx23885_reset(struct cx23885_dev *dev) static int cx23885_pci_quirks(struct cx23885_dev *dev) { - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); /* 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 @@ -514,7 +514,7 @@ int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *port, int portno) { - dprintk(1, "%s(portno=%d)\n", __FUNCTION__, portno); + dprintk(1, "%s(portno=%d)\n", __func__, portno); /* Transport bus init dma queue - Common settings */ port->dma_ctl_val = 0x11; /* Enable RISC controller and Fifo */ @@ -605,14 +605,14 @@ static void cx23885_dev_checkrevision(struct cx23885_dev *dev) break; default: printk(KERN_ERR "%s() New hardware revision found 0x%x\n", - __FUNCTION__, dev->hwrevision); + __func__, dev->hwrevision); } if (dev->hwrevision) printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", - __FUNCTION__, dev->hwrevision); + __func__, dev->hwrevision); else printk(KERN_ERR "%s() Hardware revision unknown 0x%x\n", - __FUNCTION__, dev->hwrevision); + __func__, dev->hwrevision); } static int cx23885_dev_setup(struct cx23885_dev *dev) @@ -645,7 +645,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) BUG(); dprintk(1, "%s() Memory configured for PCIe bridge type %d\n", - __FUNCTION__, dev->bridge); + __func__, dev->bridge); /* board config */ dev->board = UNSET; @@ -735,9 +735,9 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) dev->radio_addr = cx23885_boards[dev->board].radio_addr; dprintk(1, "%s() tuner_type = 0x%x tuner_addr = 0x%x\n", - __FUNCTION__, dev->tuner_type, dev->tuner_addr); + __func__, dev->tuner_type, dev->tuner_addr); dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n", - __FUNCTION__, dev->radio_type, dev->radio_addr); + __func__, dev->radio_type, dev->radio_addr); /* init hardware */ cx23885_reset(dev); @@ -745,28 +745,28 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) cx23885_i2c_register(&dev->i2c_bus[0]); cx23885_i2c_register(&dev->i2c_bus[1]); cx23885_i2c_register(&dev->i2c_bus[2]); - cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); cx23885_card_setup(dev); + cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL); cx23885_ir_init(dev); if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { if (cx23885_video_register(dev) < 0) { printk(KERN_ERR "%s() Failed to register analog " - "video adapters on VID_A\n", __FUNCTION__); + "video adapters on VID_A\n", __func__); } } if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { if (cx23885_dvb_register(&dev->ts1) < 0) { printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n", - __FUNCTION__); + __func__); } } if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { if (cx23885_dvb_register(&dev->ts2) < 0) { printk(KERN_ERR "%s() Failed to register dvb adapters on VID_C\n", - __FUNCTION__); + __func__); } } @@ -961,50 +961,50 @@ static void cx23885_tsport_reg_dump(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; - dprintk(1, "%s() Register Dump\n", __FUNCTION__); - dprintk(1, "%s() DEV_CNTRL2 0x%08X\n", __FUNCTION__, + dprintk(1, "%s() Register Dump\n", __func__); + dprintk(1, "%s() DEV_CNTRL2 0x%08X\n", __func__, cx_read(DEV_CNTRL2)); - dprintk(1, "%s() PCI_INT_MSK 0x%08X\n", __FUNCTION__, + dprintk(1, "%s() PCI_INT_MSK 0x%08X\n", __func__, cx_read(PCI_INT_MSK)); - dprintk(1, "%s() AUD_INT_INT_MSK 0x%08X\n", __FUNCTION__, + dprintk(1, "%s() AUD_INT_INT_MSK 0x%08X\n", __func__, cx_read(AUDIO_INT_INT_MSK)); - dprintk(1, "%s() AUD_INT_DMA_CTL 0x%08X\n", __FUNCTION__, + dprintk(1, "%s() AUD_INT_DMA_CTL 0x%08X\n", __func__, cx_read(AUD_INT_DMA_CTL)); - dprintk(1, "%s() AUD_EXT_INT_MSK 0x%08X\n", __FUNCTION__, + dprintk(1, "%s() AUD_EXT_INT_MSK 0x%08X\n", __func__, cx_read(AUDIO_EXT_INT_MSK)); - dprintk(1, "%s() AUD_EXT_DMA_CTL 0x%08X\n", __FUNCTION__, + dprintk(1, "%s() AUD_EXT_DMA_CTL 0x%08X\n", __func__, cx_read(AUD_EXT_DMA_CTL)); - dprintk(1, "%s() PAD_CTRL 0x%08X\n", __FUNCTION__, + dprintk(1, "%s() PAD_CTRL 0x%08X\n", __func__, cx_read(PAD_CTRL)); - dprintk(1, "%s() ALT_PIN_OUT_SEL 0x%08X\n", __FUNCTION__, + dprintk(1, "%s() ALT_PIN_OUT_SEL 0x%08X\n", __func__, cx_read(ALT_PIN_OUT_SEL)); - dprintk(1, "%s() GPIO2 0x%08X\n", __FUNCTION__, + dprintk(1, "%s() GPIO2 0x%08X\n", __func__, cx_read(GPIO2)); - dprintk(1, "%s() gpcnt(0x%08X) 0x%08X\n", __FUNCTION__, + dprintk(1, "%s() gpcnt(0x%08X) 0x%08X\n", __func__, port->reg_gpcnt, cx_read(port->reg_gpcnt)); - dprintk(1, "%s() gpcnt_ctl(0x%08X) 0x%08x\n", __FUNCTION__, + dprintk(1, "%s() gpcnt_ctl(0x%08X) 0x%08x\n", __func__, port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl)); - dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __FUNCTION__, + dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __func__, port->reg_dma_ctl, cx_read(port->reg_dma_ctl)); - dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __FUNCTION__, + dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__, port->reg_src_sel, cx_read(port->reg_src_sel)); - dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __FUNCTION__, + dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __func__, port->reg_lngth, cx_read(port->reg_lngth)); - dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __FUNCTION__, + dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __func__, port->reg_hw_sop_ctrl, cx_read(port->reg_hw_sop_ctrl)); - dprintk(1, "%s() gen_ctrl(0x%08X) 0x%08x\n", __FUNCTION__, + dprintk(1, "%s() gen_ctrl(0x%08X) 0x%08x\n", __func__, port->reg_gen_ctrl, cx_read(port->reg_gen_ctrl)); - dprintk(1, "%s() bd_pkt_status(0x%08X) 0x%08x\n", __FUNCTION__, + dprintk(1, "%s() bd_pkt_status(0x%08X) 0x%08x\n", __func__, port->reg_bd_pkt_status, cx_read(port->reg_bd_pkt_status)); - dprintk(1, "%s() sop_status(0x%08X) 0x%08x\n", __FUNCTION__, + dprintk(1, "%s() sop_status(0x%08X) 0x%08x\n", __func__, port->reg_sop_status, cx_read(port->reg_sop_status)); - dprintk(1, "%s() fifo_ovfl_stat(0x%08X) 0x%08x\n", __FUNCTION__, + dprintk(1, "%s() fifo_ovfl_stat(0x%08X) 0x%08x\n", __func__, port->reg_fifo_ovfl_stat, cx_read(port->reg_fifo_ovfl_stat)); - dprintk(1, "%s() vld_misc(0x%08X) 0x%08x\n", __FUNCTION__, + dprintk(1, "%s() vld_misc(0x%08X) 0x%08x\n", __func__, port->reg_vld_misc, cx_read(port->reg_vld_misc)); - dprintk(1, "%s() ts_clk_en(0x%08X) 0x%08x\n", __FUNCTION__, + dprintk(1, "%s() ts_clk_en(0x%08X) 0x%08x\n", __func__, port->reg_ts_clk_en, cx_read(port->reg_ts_clk_en)); - dprintk(1, "%s() ts_int_msk(0x%08X) 0x%08x\n", __FUNCTION__, + dprintk(1, "%s() ts_int_msk(0x%08X) 0x%08x\n", __func__, port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk)); } @@ -1014,7 +1014,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, { struct cx23885_dev *dev = port->dev; - dprintk(1, "%s() w: %d, h: %d, f: %d\n", __FUNCTION__, + dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__, buf->vb.width, buf->vb.height, buf->vb.field); /* setup fifo + format */ @@ -1032,7 +1032,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, if ( (!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) ) { printk( "%s() Failed. Unsupported value in .portb/c (0x%08x)/(0x%08x)\n", - __FUNCTION__, + __func__, cx23885_boards[dev->board].portb, cx23885_boards[dev->board].portc ); return -EINVAL; @@ -1059,7 +1059,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, case CX23885_BRIDGE_885: case CX23885_BRIDGE_887: /* enable irqs */ - dprintk(1, "%s() enabling TS int's and DMA\n", __FUNCTION__ ); + dprintk(1, "%s() enabling TS int's and DMA\n", __func__ ); cx_set(port->reg_ts_int_msk, port->ts_int_msk_val); cx_set(port->reg_dma_ctl, port->dma_ctl_val); cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask); @@ -1079,7 +1079,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port, static int cx23885_stop_dma(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); /* Stop interrupts and DMA */ cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val); @@ -1094,13 +1094,13 @@ int cx23885_restart_queue(struct cx23885_tsport *port, struct cx23885_dev *dev = port->dev; struct cx23885_buffer *buf; - dprintk(5, "%s()\n", __FUNCTION__); + dprintk(5, "%s()\n", __func__); if (list_empty(&q->active)) { struct cx23885_buffer *prev; prev = NULL; - dprintk(5, "%s() queue is empty\n", __FUNCTION__); + dprintk(5, "%s() queue is empty\n", __func__); for (;;) { if (list_empty(&q->queued)) @@ -1155,7 +1155,7 @@ int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, int size = port->ts_packet_size * port->ts_packet_count; int rc; - dprintk(1, "%s: %p\n", __FUNCTION__, buf); + dprintk(1, "%s: %p\n", __func__, buf); if (0 != buf->vb.baddr && buf->vb.bsize < size) return -EINVAL; @@ -1198,7 +1198,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) buf->count = cx88q->count++; mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT); dprintk(1, "[%p/%d] %s - first active\n", - buf, buf->vb.i, __FUNCTION__); + buf, buf->vb.i, __func__); } else { dprintk( 1, "queue is not empty - append to active\n" ); prev = list_entry(cx88q->active.prev, struct cx23885_buffer, @@ -1209,7 +1209,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ dprintk( 1, "[%p/%d] %s - append to active\n", - buf, buf->vb.i, __FUNCTION__); + buf, buf->vb.i, __func__); } } @@ -1258,7 +1258,7 @@ static void cx23885_timeout(unsigned long data) struct cx23885_tsport *port = (struct cx23885_tsport *)data; struct cx23885_dev *dev = port->dev; - dprintk(1, "%s()\n",__FUNCTION__); + dprintk(1, "%s()\n",__func__); if (debug > 5) cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]); diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c index 382558866..5923f214e 100644 --- a/linux/drivers/media/video/cx23885/cx23885-dvb.c +++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c @@ -37,9 +37,9 @@ #include "tda18271.h" #include "lgdt330x.h" #include "xc5000.h" +#include "tda10048.h" #include "dvb-pll.h" #include "tuner-xc2028.h" -#include "tuner-xc2028-types.h" #include "tuner-simple.h" static unsigned int debug; @@ -55,6 +55,8 @@ static unsigned int alt_tuner; module_param(alt_tuner, int, 0644); MODULE_PARM_DESC(alt_tuner, "Enable alternate tuner configuration"); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + /* ------------------------------------------------------------------ */ static int dvb_buf_setup(struct videobuf_queue *q, @@ -106,6 +108,13 @@ static struct s5h1409_config hauppauge_generic_config = { .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, }; +static struct tda10048_config hauppauge_hvr1200_config = { + .demod_address = 0x10 >> 1, + .output_mode = TDA10048_SERIAL_OUTPUT, + .fwbulkwritelen = TDA10048_BULKWRITE_200, + .inversion = TDA10048_INVERSION_ON +}; + static struct s5h1409_config hauppauge_ezqam_config = { .demod_address = 0x32 >> 1, .output_mode = S5H1409_SERIAL_OUTPUT, @@ -177,6 +186,10 @@ static struct tda18271_config hauppauge_tda18271_config = { .gate = TDA18271_GATE_ANALOG, }; +static struct tda18271_config hauppauge_hvr1200_tuner_config = { + .gate = TDA18271_GATE_ANALOG, +}; + static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) { struct cx23885_tsport *port = ptr; @@ -186,7 +199,7 @@ static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) case XC2028_TUNER_RESET: /* Send the tuner in then out of reset */ /* GPIO-2 xc3028 tuner */ - dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __FUNCTION__, arg); + dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __func__, arg); cx_set(GP0_IO, 0x00040000); cx_clear(GP0_IO, 0x00000004); @@ -196,10 +209,10 @@ static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) msleep(5); break; case XC2028_RESET_CLK: - dprintk(1, "%s: XC2028_RESET_CLK %d\n", __FUNCTION__, arg); + dprintk(1, "%s: XC2028_RESET_CLK %d\n", __func__, arg); break; default: - dprintk(1, "%s: unknown command %d, arg %d\n", __FUNCTION__, + dprintk(1, "%s: unknown command %d, arg %d\n", __func__, command, arg); return -EINVAL; } @@ -307,7 +320,7 @@ static int dvb_register(struct cx23885_tsport *port) static struct xc2028_ctrl ctl = { .fname = "xc3028-v27.fw", .max_len = 64, - .scode_table = OREN538, + .scode_table = XC3028_FE_OREN538, }; fe = dvb_attach(xc2028_attach, @@ -316,6 +329,21 @@ static int dvb_register(struct cx23885_tsport *port) fe->ops.tuner_ops.set_config(fe, &ctl); } break; + case CX23885_BOARD_HAUPPAUGE_HVR1200: + case CX23885_BOARD_HAUPPAUGE_HVR1700: + i2c_bus = &dev->i2c_bus[0]; + port->dvb.frontend = dvb_attach(tda10048_attach, + &hauppauge_hvr1200_config, + &i2c_bus->i2c_adap); + if (port->dvb.frontend != NULL) { + dvb_attach(tda829x_attach, port->dvb.frontend, + &dev->i2c_bus[1].i2c_adap, 0x42, + &tda829x_no_probe); + dvb_attach(tda18271_attach, port->dvb.frontend, + 0x60, &dev->i2c_bus[1].i2c_adap, + &hauppauge_hvr1200_tuner_config); + } + break; default: printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", dev->name); @@ -334,7 +362,7 @@ static int dvb_register(struct cx23885_tsport *port) /* register everything */ return videobuf_dvb_register(&port->dvb, THIS_MODULE, port, - &dev->pci->dev); + &dev->pci->dev, adapter_nr); } int cx23885_dvb_register(struct cx23885_tsport *port) @@ -342,7 +370,7 @@ int cx23885_dvb_register(struct cx23885_tsport *port) struct cx23885_dev *dev = port->dev; int err; - dprintk(1, "%s\n", __FUNCTION__); + dprintk(1, "%s\n", __func__); dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", dev->board, dev->name, @@ -358,7 +386,7 @@ int cx23885_dvb_register(struct cx23885_tsport *port) sizeof(struct cx23885_buffer), port); err = dvb_register(port); if (err != 0) - printk("%s() dvb_register failed err = %d\n", __FUNCTION__, err); + printk("%s() dvb_register failed err = %d\n", __func__, err); return err; } diff --git a/linux/drivers/media/video/cx23885/cx23885-i2c.c b/linux/drivers/media/video/cx23885/cx23885-i2c.c index ab83c88a9..972c58cc9 100644 --- a/linux/drivers/media/video/cx23885/cx23885-i2c.c +++ b/linux/drivers/media/video/cx23885/cx23885-i2c.c @@ -88,10 +88,10 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, int retval, cnt; if (joined_rlen) - dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __FUNCTION__, + dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__, msg->len, joined_rlen); else - dprintk(1, "%s(msg->len=%d)\n", __FUNCTION__, msg->len); + dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); /* Deal with i2c probe functions with zero payload */ if (msg->len == 0) { @@ -102,7 +102,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap, if (!i2c_slave_did_ack(i2c_adap)) return -EIO; - dprintk(1, "%s() returns 0\n", __FUNCTION__); + dprintk(1, "%s() returns 0\n", __func__); return 0; } @@ -177,7 +177,7 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, if (i2c_debug && !joined) - dprintk(1, "%s(msg->len=%d)\n", __FUNCTION__, msg->len); + dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); /* Deal with i2c probe functions with zero payload */ if (msg->len == 0) { @@ -189,7 +189,7 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap, return -EIO; - dprintk(1, "%s() returns 0\n", __FUNCTION__); + dprintk(1, "%s() returns 0\n", __func__); return 0; } @@ -239,11 +239,11 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap, struct cx23885_dev *dev = bus->dev; int i, retval = 0; - dprintk(1, "%s(num = %d)\n", __FUNCTION__, num); + dprintk(1, "%s(num = %d)\n", __func__, num); for (i = 0 ; i < num; i++) { dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n", - __FUNCTION__, num, msgs[i].addr, msgs[i].len); + __func__, num, msgs[i].addr, msgs[i].len); if (msgs[i].flags & I2C_M_RD) { /* read */ retval = i2c_readbytes(i2c_adap, &msgs[i], 0); @@ -374,6 +374,7 @@ static struct i2c_client cx23885_i2c_client_template = { }; static char *i2c_devs[128] = { + [0x10 >> 1] = "tda10048", [ 0x1c >> 1 ] = "lgdt3303", [ 0x86 >> 1 ] = "tda9887", [ 0x32 >> 1 ] = "cx24227", @@ -404,7 +405,7 @@ int cx23885_i2c_register(struct cx23885_i2c *bus) { struct cx23885_dev *dev = bus->dev; - dprintk(1, "%s(bus = %d)\n", __FUNCTION__, bus->nr); + dprintk(1, "%s(bus = %d)\n", __func__, bus->nr); memcpy(&bus->i2c_adap, &cx23885_i2c_adap_template, sizeof(bus->i2c_adap)); diff --git a/linux/drivers/media/video/cx23885/cx23885-video.c b/linux/drivers/media/video/cx23885/cx23885-video.c index 702d76493..a3bd7e8d8 100644 --- a/linux/drivers/media/video/cx23885/cx23885-video.c +++ b/linux/drivers/media/video/cx23885/cx23885-video.c @@ -188,7 +188,7 @@ static struct cx23885_fmt *format_by_fourcc(unsigned int fourcc) if (formats[i].fourcc == fourcc) return formats+i; - printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __FUNCTION__, fourcc); + printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc); return NULL; } @@ -342,13 +342,13 @@ void cx23885_video_wakeup(struct cx23885_dev *dev, } if (bc != 1) printk(KERN_ERR "%s: %d buffers handled (should be 1)\n", - __FUNCTION__, bc); + __func__, bc); } int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) { dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", - __FUNCTION__, + __func__, (unsigned int)norm, v4l2_norm_to_name(norm)); @@ -369,7 +369,7 @@ struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, char *type) { struct video_device *vfd; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); vfd = video_device_alloc(); if (NULL == vfd) @@ -410,7 +410,7 @@ EXPORT_SYMBOL(cx23885_ctrl_query); static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh, unsigned int bit) { - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); if (fh->resources & bit) /* have it already allocated */ return 1; @@ -444,7 +444,7 @@ static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh, unsigned int bits) { BUG_ON((fh->resources & bits) != bits); - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); mutex_lock(&dev->lock); fh->resources &= ~bits; @@ -459,7 +459,7 @@ int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) memset(&route, 0, sizeof(route)); dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n", - __FUNCTION__, + __func__, input, INPUT(input)->vmux, INPUT(input)->gpio0, INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3); @@ -484,7 +484,7 @@ EXPORT_SYMBOL(cx23885_video_mux); int cx23885_set_scale(struct cx23885_dev *dev, unsigned int width, unsigned int height, enum v4l2_field field) { - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); return 0; } @@ -492,7 +492,7 @@ static int cx23885_start_video_dma(struct cx23885_dev *dev, struct cx23885_dmaqueue *q, struct cx23885_buffer *buf) { - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); /* setup fifo + format */ cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01], @@ -518,7 +518,7 @@ static int cx23885_start_video_dma(struct cx23885_dev *dev, #ifdef CONFIG_PM static int cx23885_stop_video_dma(struct cx23885_dev *dev) { - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); /* stop dma */ cx_clear(VID_A_DMA_CTL, 0x11); @@ -536,7 +536,7 @@ static int cx23885_restart_video_queue(struct cx23885_dev *dev, { struct cx23885_buffer *buf, *prev; struct list_head *item; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); if (!list_empty(&q->active)) { buf = list_entry(q->active.next, struct cx23885_buffer, @@ -652,13 +652,13 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, if (dev->tvnorm & V4L2_STD_NTSC) { /* cx25840 transmits NTSC bottom field first */ dprintk(1, "%s() Creating NTSC risc\n", - __FUNCTION__); + __func__); line0_offset = buf->bpl; line1_offset = 0; } else { /* All other formats are top field first */ dprintk(1, "%s() Creating PAL/SECAM risc\n", - __FUNCTION__); + __func__); line0_offset = 0; line1_offset = buf->bpl; } @@ -979,7 +979,7 @@ static int video_mmap(struct file *file, struct vm_area_struct *vma) int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl) { - dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __FUNCTION__); + dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__); cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl); return 0; } @@ -988,7 +988,7 @@ EXPORT_SYMBOL(cx23885_get_control); int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl) { dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)" - " (disabled - no action)\n", __FUNCTION__); + " (disabled - no action)\n", __func__); #if 0 cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl); #endif @@ -1087,7 +1087,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; int err; - dprintk(2, "%s()\n", __FUNCTION__); + dprintk(2, "%s()\n", __func__); err = vidioc_try_fmt_cap(file, priv, f); if (0 != err) @@ -1096,7 +1096,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, fh->width = f->fmt.pix.width; fh->height = f->fmt.pix.height; fh->vidq.field = f->fmt.pix.field; - dprintk(2, "%s() width=%d height=%d field=%d\n", __FUNCTION__, + dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width, fh->height, fh->vidq.field); cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_FMT, f); return 0; @@ -1201,7 +1201,7 @@ static int vidioc_streamon(struct file *file, void *priv, { struct cx23885_fh *fh = priv; struct cx23885_dev *dev = fh->dev; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) return -EINVAL; @@ -1218,7 +1218,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) struct cx23885_fh *fh = priv; struct cx23885_dev *dev = fh->dev; int err, res; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1236,7 +1236,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms) { struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); mutex_lock(&dev->lock); cx23885_set_tvnorm(dev, *tvnorms); @@ -1259,7 +1259,7 @@ int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) [CX23885_VMUX_DEBUG] = "for debug only", }; unsigned int n; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); n = i->index; if (n >= 4) @@ -1284,7 +1284,7 @@ static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i) { struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); return cx23885_enum_input(dev, i); } @@ -1293,7 +1293,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; *i = dev->input; - dprintk(1, "%s() returns %d\n", __FUNCTION__, *i); + dprintk(1, "%s() returns %d\n", __func__, *i); return 0; } @@ -1301,10 +1301,10 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) { struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - dprintk(1, "%s(%d)\n", __FUNCTION__, i); + dprintk(1, "%s(%d)\n", __func__, i); if (i >= 4) { - dprintk(1, "%s() -EINVAL\n", __FUNCTION__); + dprintk(1, "%s() -EINVAL\n", __func__); return -EINVAL; } @@ -1594,7 +1594,7 @@ int cx23885_video_irq(struct cx23885_dev *dev, u32 status) return handled; cx_write(VID_A_INT_STAT, status); - dprintk(2, "%s() status = 0x%08x\n", __FUNCTION__, status); + dprintk(2, "%s() status = 0x%08x\n", __func__, status); /* risc op code error */ if (status & (1 << 16)) { printk(KERN_WARNING "%s/0: video risc op code error\n", @@ -1736,7 +1736,7 @@ static struct video_device cx23885_radio_template = { void cx23885_video_unregister(struct cx23885_dev *dev) { - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); cx_clear(PCI_INT_MSK, 1); #if 0 @@ -1771,7 +1771,7 @@ int cx23885_video_register(struct cx23885_dev *dev) { int err; - dprintk(1, "%s()\n", __FUNCTION__); + dprintk(1, "%s()\n", __func__); spin_lock_init(&dev->slock); /* Initialize VBI template */ diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h index d66fe2484..7eaadeab6 100644 --- a/linux/drivers/media/video/cx23885/cx23885.h +++ b/linux/drivers/media/video/cx23885/cx23885.h @@ -62,6 +62,8 @@ #define CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP 4 #define CX23885_BOARD_HAUPPAUGE_HVR1500Q 5 #define CX23885_BOARD_HAUPPAUGE_HVR1500 6 +#define CX23885_BOARD_HAUPPAUGE_HVR1200 7 +#define CX23885_BOARD_HAUPPAUGE_HVR1700 8 /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ #define CX23885_NORMS (\ diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c index 82e7fb267..7e21143e2 100644 --- a/linux/drivers/media/video/cx25840/cx25840-core.c +++ b/linux/drivers/media/video/cx25840/cx25840-core.c @@ -1297,6 +1297,12 @@ static int cx25840_probe(struct i2c_client *client) state->id = id; state->rev = device_id; + if (state->is_cx23885) { + /* Drive GPIO2 direction and values */ + cx25840_write(client, 0x160, 0x1d); + cx25840_write(client, 0x164, 0x00); + } + return 0; } diff --git a/linux/drivers/media/video/cx88/cx88-alsa.c b/linux/drivers/media/video/cx88/cx88-alsa.c index 56adb9c19..5bf2fd5bc 100644 --- a/linux/drivers/media/video/cx88/cx88-alsa.c +++ b/linux/drivers/media/video/cx88/cx88-alsa.c @@ -553,7 +553,7 @@ static snd_pcm_uframes_t snd_cx88_pointer(struct snd_pcm_substream *substream) #endif count = atomic_read(&chip->count); -// dprintk(2, "%s - count %d (+%u), period %d, frame %lu\n", __FUNCTION__, +// dprintk(2, "%s - count %d (+%u), period %d, frame %lu\n", __func__, // count, new, count & (runtime->periods-1), // runtime->period_size * (count & (runtime->periods-1))); return runtime->period_size * (count & (runtime->periods-1)); diff --git a/linux/drivers/media/video/cx88/cx88-blackbird.c b/linux/drivers/media/video/cx88/cx88-blackbird.c index ab409da51..a77616c3f 100644 --- a/linux/drivers/media/video/cx88/cx88-blackbird.c +++ b/linux/drivers/media/video/cx88/cx88-blackbird.c @@ -319,7 +319,7 @@ static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 dat u32 value, flag, retval; int i; - dprintk(1,"%s: 0x%X\n", __FUNCTION__, command); + dprintk(1,"%s: 0x%X\n", __func__, command); /* this may not be 100% safe if we can't read any memory location without side effects */ @@ -1081,7 +1081,7 @@ static int mpeg_open(struct inode *inode, struct file *file) dev = cx8802_get_device(inode); - dprintk( 1, "%s\n", __FUNCTION__); + dprintk( 1, "%s\n", __func__); if (dev == NULL) return -ENODEV; @@ -1091,7 +1091,7 @@ static int mpeg_open(struct inode *inode, struct file *file) if (drv) { err = drv->request_acquire(drv); if(err != 0) { - dprintk(1,"%s: Unable to acquire hardware, %d\n", __FUNCTION__, err); + dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err); return err; } } @@ -1313,7 +1313,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) struct cx8802_dev *dev = core->dvbdev; int err; - dprintk( 1, "%s\n", __FUNCTION__); + dprintk( 1, "%s\n", __func__); dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", core->boardnr, core->name, diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c index fcecfeed9..0809039a5 100644 --- a/linux/drivers/media/video/cx88/cx88-cards.c +++ b/linux/drivers/media/video/cx88/cx88-cards.c @@ -1410,6 +1410,10 @@ static const struct cx88_board cx88_boards[] = { }}, /* fixme: Add radio support */ .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD, + .radio = { + .type = CX88_RADIO, + .gpio0 = 0xe780, + }, }, [CX88_BOARD_ADSTECH_PTV_390] = { .name = "ADS Tech Instant Video PCI", diff --git a/linux/drivers/media/video/cx88/cx88-core.c b/linux/drivers/media/video/cx88/cx88-core.c index a580d3706..8655bb677 100644 --- a/linux/drivers/media/video/cx88/cx88-core.c +++ b/linux/drivers/media/video/cx88/cx88-core.c @@ -575,7 +575,7 @@ void cx88_wakeup(struct cx88_core *core, mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); } if (bc != 1) - printk("%s: %d buffers handled (should be 1)\n",__FUNCTION__,bc); + printk("%s: %d buffers handled (should be 1)\n",__func__,bc); } void cx88_shutdown(struct cx88_core *core) @@ -604,7 +604,7 @@ void cx88_shutdown(struct cx88_core *core) int cx88_reset(struct cx88_core *core) { - dprintk(1,"%s\n",__FUNCTION__); + dprintk(1,"%s\n",__func__); cx88_shutdown(core); /* clear irq status */ diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c index ab31fdc80..7d35590f9 100644 --- a/linux/drivers/media/video/cx88/cx88-dvb.c +++ b/linux/drivers/media/video/cx88/cx88-dvb.c @@ -46,7 +46,6 @@ #include "nxt200x.h" #include "cx24123.h" #include "isl6421.h" -#include "tuner-xc2028-types.h" #include "tuner-simple.h" #include "tda9887.h" @@ -59,6 +58,8 @@ static unsigned int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug,"enable debug messages [dvb]"); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + #define dprintk(level,fmt, arg...) if (debug >= level) \ printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg) @@ -283,7 +284,7 @@ static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) struct cx8802_dev *dev= fe->dvb->priv; struct cx88_core *core = dev->core; - dprintk(1, "%s: index = %d\n", __FUNCTION__, index); + dprintk(1, "%s: index = %d\n", __func__, index); if (index == 0) cx_clear(MO_GP0_IO, 8); else @@ -381,7 +382,7 @@ static int cx88_pci_nano_callback(void *ptr, int command, int arg) switch (command) { case XC2028_TUNER_RESET: /* Send the tuner in then out of reset */ - dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __FUNCTION__, arg); + dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __func__, arg); switch (core->boardnr) { case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: @@ -397,10 +398,10 @@ static int cx88_pci_nano_callback(void *ptr, int command, int arg) break; case XC2028_RESET_CLK: - dprintk(1, "%s: XC2028_RESET_CLK %d\n", __FUNCTION__, arg); + dprintk(1, "%s: XC2028_RESET_CLK %d\n", __func__, arg); break; default: - dprintk(1, "%s: unknown command %d, arg %d\n", __FUNCTION__, + dprintk(1, "%s: unknown command %d, arg %d\n", __func__, command, arg); return -EINVAL; } @@ -818,7 +819,7 @@ static int dvb_register(struct cx8802_dev *dev) static struct xc2028_ctrl ctl = { .fname = "xc3028-v27.fw", .max_len = 64, - .scode_table = OREN538, + .scode_table = XC3028_FE_OREN538, }; fe = dvb_attach(xc2028_attach, @@ -869,7 +870,8 @@ static int dvb_register(struct cx8802_dev *dev) cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); /* register everything */ - return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev); + return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, + &dev->pci->dev, adapter_nr); } /* ----------------------------------------------------------- */ @@ -879,7 +881,7 @@ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; - dprintk( 1, "%s\n", __FUNCTION__); + dprintk( 1, "%s\n", __func__); switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: @@ -902,7 +904,7 @@ static int cx8802_dvb_advise_release(struct cx8802_driver *drv) { struct cx88_core *core = drv->core; int err = 0; - dprintk( 1, "%s\n", __FUNCTION__); + dprintk( 1, "%s\n", __func__); switch (core->boardnr) { case CX88_BOARD_HAUPPAUGE_HVR1300: @@ -923,7 +925,7 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv) struct cx8802_dev *dev = drv->core->dvbdev; int err; - dprintk( 1, "%s\n", __FUNCTION__); + dprintk( 1, "%s\n", __func__); dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", core->boardnr, core->name, @@ -961,7 +963,8 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv) struct cx8802_dev *dev = drv->core->dvbdev; /* dvb */ - videobuf_dvb_unregister(&dev->dvb); + if (dev->dvb.frontend) + videobuf_dvb_unregister(&dev->dvb); vp3054_i2c_remove(dev); diff --git a/linux/drivers/media/video/cx88/cx88-mpeg.c b/linux/drivers/media/video/cx88/cx88-mpeg.c index 6ec40f79f..c8dba3dfa 100644 --- a/linux/drivers/media/video/cx88/cx88-mpeg.c +++ b/linux/drivers/media/video/cx88/cx88-mpeg.c @@ -175,7 +175,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev, cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */ udelay(100); } else { - printk( "%s() Failed. Unsupported value in .mpeg (0x%08x)\n", __FUNCTION__, + printk( "%s() Failed. Unsupported value in .mpeg (0x%08x)\n", __func__, core->board.mpeg ); return -EINVAL; } @@ -279,7 +279,7 @@ int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev, struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); int rc; - dprintk(1, "%s: %p\n", __FUNCTION__, buf); + dprintk(1, "%s: %p\n", __func__, buf); if (0 != buf->vb.baddr && buf->vb.bsize < size) return -EINVAL; @@ -321,7 +321,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) buf->count = cx88q->count++; mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT); dprintk(1,"[%p/%d] %s - first active\n", - buf, buf->vb.i, __FUNCTION__); + buf, buf->vb.i, __func__); #if 0 udelay(100); #endif @@ -334,7 +334,7 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) buf->count = cx88q->count++; prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); dprintk( 1, "[%p/%d] %s - append to active\n", - buf, buf->vb.i, __FUNCTION__); + buf, buf->vb.i, __func__); #if 0 udelay(100); #endif @@ -380,7 +380,7 @@ static void cx8802_timeout(unsigned long data) { struct cx8802_dev *dev = (struct cx8802_dev*)data; - dprintk(1, "%s\n",__FUNCTION__); + dprintk(1, "%s\n",__func__); if (debug) cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); @@ -683,7 +683,7 @@ static int cx8802_request_acquire(struct cx8802_driver *drv) } mutex_unlock(&drv->core->lock); - mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO)); + mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); } return 0; @@ -699,7 +699,7 @@ static int cx8802_request_release(struct cx8802_driver *drv) { drv->advise_release(drv); core->active_type_id = CX88_BOARD_NONE; - mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO)); + mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); } mutex_unlock(&drv->core->lock); @@ -873,7 +873,7 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev) dev = pci_get_drvdata(pci_dev); - dprintk( 1, "%s\n", __FUNCTION__); + dprintk( 1, "%s\n", __func__); if (!list_empty(&dev->drvlist)) { struct cx8802_driver *drv, *tmp; diff --git a/linux/drivers/media/video/cx88/cx88-tvaudio.c b/linux/drivers/media/video/cx88/cx88-tvaudio.c index d2e1fdb91..b4dab2647 100644 --- a/linux/drivers/media/video/cx88/cx88-tvaudio.c +++ b/linux/drivers/media/video/cx88/cx88-tvaudio.c @@ -271,12 +271,12 @@ static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap, mode |= EN_FMRADIO_EN_RDS; if (sap) { - dprintk("%s SAP (status: unknown)\n", __FUNCTION__); + dprintk("%s SAP (status: unknown)\n", __func__); set_audio_start(core, SEL_SAP); set_audio_registers(core, btsc_sap); set_audio_finish(core, mode); } else { - dprintk("%s (status: known-good)\n", __FUNCTION__); + dprintk("%s (status: known-good)\n", __func__); set_audio_start(core, SEL_BTSC); set_audio_registers(core, btsc); set_audio_finish(core, mode); @@ -357,16 +357,16 @@ static void set_audio_standard_NICAM(struct cx88_core *core, u32 mode) set_audio_start(core,SEL_NICAM); switch (core->tvaudio) { case WW_L: - dprintk("%s SECAM-L NICAM (status: devel)\n", __FUNCTION__); + dprintk("%s SECAM-L NICAM (status: devel)\n", __func__); set_audio_registers(core, nicam_l); break; case WW_I: - dprintk("%s PAL-I NICAM (status: known-good)\n", __FUNCTION__); + dprintk("%s PAL-I NICAM (status: known-good)\n", __func__); set_audio_registers(core, nicam_bgdki_common); set_audio_registers(core, nicam_i); break; default: - dprintk("%s PAL-BGDK NICAM (status: known-good)\n", __FUNCTION__); + dprintk("%s PAL-BGDK NICAM (status: known-good)\n", __func__); set_audio_registers(core, nicam_bgdki_common); set_audio_registers(core, nicam_default); break; @@ -606,28 +606,28 @@ static void set_audio_standard_A2(struct cx88_core *core, u32 mode) set_audio_start(core, SEL_A2); switch (core->tvaudio) { case WW_BG: - dprintk("%s PAL-BG A1/2 (status: known-good)\n", __FUNCTION__); + dprintk("%s PAL-BG A1/2 (status: known-good)\n", __func__); set_audio_registers(core, a2_bgdk_common); set_audio_registers(core, a2_bg); set_audio_registers(core, a2_deemph50); break; case WW_DK: - dprintk("%s PAL-DK A1/2 (status: known-good)\n", __FUNCTION__); + dprintk("%s PAL-DK A1/2 (status: known-good)\n", __func__); set_audio_registers(core, a2_bgdk_common); set_audio_registers(core, a2_dk); set_audio_registers(core, a2_deemph50); break; case WW_I: - dprintk("%s PAL-I A1 (status: known-good)\n", __FUNCTION__); + dprintk("%s PAL-I A1 (status: known-good)\n", __func__); set_audio_registers(core, a1_i); set_audio_registers(core, a2_deemph50); break; case WW_L: - dprintk("%s AM-L (status: devel)\n", __FUNCTION__); + dprintk("%s AM-L (status: devel)\n", __func__); set_audio_registers(core, am_l); break; default: - dprintk("%s Warning: wrong value\n", __FUNCTION__); + dprintk("%s Warning: wrong value\n", __func__); return; break; }; @@ -643,7 +643,7 @@ static void set_audio_standard_EIAJ(struct cx88_core *core) { /* end of list */ }, }; - dprintk("%s (status: unknown)\n", __FUNCTION__); + dprintk("%s (status: unknown)\n", __func__); set_audio_start(core, SEL_EIAJ); set_audio_registers(core, eiaj); @@ -697,7 +697,7 @@ static void set_audio_standard_FM(struct cx88_core *core, { /* end of list */ }, }; - dprintk("%s (status: unknown)\n", __FUNCTION__); + dprintk("%s (status: unknown)\n", __func__); set_audio_start(core, SEL_FMRADIO); switch (deemph) { diff --git a/linux/drivers/media/video/dpc7146.c b/linux/drivers/media/video/dpc7146.c index 258d46407..4bfb3076b 100644 --- a/linux/drivers/media/video/dpc7146.c +++ b/linux/drivers/media/video/dpc7146.c @@ -132,7 +132,7 @@ static int dpc_probe(struct saa7146_dev* dev) device_for_each_child(&dpc->i2c_adapter.dev, dpc, dpc_check_clients); /* check if all devices are present */ - if( 0 == dpc->saa7111a ) { + if (!dpc->saa7111a) { DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n")); i2c_del_adapter(&dpc->i2c_adapter); kfree(dpc); diff --git a/linux/drivers/media/video/em28xx/Kconfig b/linux/drivers/media/video/em28xx/Kconfig index 0f7a0bd86..3d9082fa6 100644 --- a/linux/drivers/media/video/em28xx/Kconfig +++ b/linux/drivers/media/video/em28xx/Kconfig @@ -1,11 +1,13 @@ config VIDEO_EM28XX - tristate "Empia EM2800/2820/2840 USB video capture support" + tristate "Empia EM28xx USB video capture support" depends on VIDEO_DEV && I2C && INPUT select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_IR + select VIDEOBUF_VMALLOC select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO ---help--- This is a video4linux driver for Empia 28xx based TV cards. @@ -27,3 +29,14 @@ config VIDEO_EM28XX_ALSA To compile this driver as a module, choose M here: the module will be called em28xx-alsa +config VIDEO_EM28XX_DVB + tristate "DVB/ATSC Support for em28xx based TV cards" + depends on VIDEO_EM28XX && DVB_CORE + select DVB_LGDT330X if !DVB_FE_CUSTOMISE + select DVB_ZL10353 if !DVB_FE_CUSTOMISE + select VIDEOBUF_DVB + select FW_LOADER + ---help--- + This adds support for DVB cards based on the + Empiatech em28xx chips. + diff --git a/linux/drivers/media/video/em28xx/Makefile b/linux/drivers/media/video/em28xx/Makefile index 092455099..3d1c3cc33 100644 --- a/linux/drivers/media/video/em28xx/Makefile +++ b/linux/drivers/media/video/em28xx/Makefile @@ -5,6 +5,7 @@ em28xx-alsa-objs := em28xx-audio.o obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o +obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o EXTRA_CFLAGS += -Idrivers/media/video EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core diff --git a/linux/drivers/media/video/em28xx/em28xx-audio.c b/linux/drivers/media/video/em28xx/em28xx-audio.c index 37e893455..609e28e77 100644 --- a/linux/drivers/media/video/em28xx/em28xx-audio.c +++ b/linux/drivers/media/video/em28xx/em28xx-audio.c @@ -52,7 +52,7 @@ MODULE_PARM_DESC(debug, "activates debug info"); #define dprintk(fmt, arg...) do { \ if (debug) \ printk(KERN_INFO "em28xx-audio %s: " fmt, \ - __FUNCTION__, ##arg); \ + __func__, ##arg); \ } while (0) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c index 06a4e4a2b..bdf64cd9c 100644 --- a/linux/drivers/media/video/em28xx/em28xx-cards.c +++ b/linux/drivers/media/video/em28xx/em28xx-cards.c @@ -37,7 +37,6 @@ #include <media/v4l2-common.h> #include "em28xx.h" -#include "tuner-xc2028.h" static int tuner = -1; module_param(tuner, int, 0444); @@ -53,26 +52,6 @@ struct em28xx_hash_table { unsigned int tuner; }; -/* Boards supported by driver */ - -#define EM2800_BOARD_UNKNOWN 0 -#define EM2820_BOARD_UNKNOWN 1 -#define EM2820_BOARD_TERRATEC_CINERGY_250 2 -#define EM2820_BOARD_PINNACLE_USB_2 3 -#define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4 -#define EM2820_BOARD_MSI_VOX_USB_2 5 -#define EM2800_BOARD_TERRATEC_CINERGY_200 6 -#define EM2800_BOARD_LEADTEK_WINFAST_USBII 7 -#define EM2800_BOARD_KWORLD_USB2800 8 -#define EM2820_BOARD_PINNACLE_DVC_90 9 -#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 10 -#define EM2880_BOARD_TERRATEC_HYBRID_XS 11 -#define EM2820_BOARD_KWORLD_PVRTV2800RF 12 -#define EM2880_BOARD_TERRATEC_PRODIGY_XS 13 -#define EM2820_BOARD_PROLINK_PLAYTV_USB2 14 -#define EM2800_BOARD_VGEAR_POCKETTV 15 -#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16 - struct em28xx_board em28xx_boards[] = { [EM2800_BOARD_UNKNOWN] = { .name = "Unknown EM2800 video grabber", @@ -201,6 +180,7 @@ struct em28xx_board em28xx_boards[] = { .tuner_type = TUNER_XC2028, .mts_firmware = 1, .has_12mhz_i2s = 1, + .has_dvb = 1, .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -215,9 +195,6 @@ struct em28xx_board em28xx_boards[] = { .vmux = TVP5150_SVIDEO, .amux = 1, } }, - - /* gpio's 4, 1, 0 */ - .analog_gpio = 0x003d2d, }, [EM2880_BOARD_TERRATEC_HYBRID_XS] = { .name = "Terratec Hybrid XS", @@ -454,7 +431,36 @@ struct usb_device_id em28xx_id_table [] = { }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); -/* EEPROM hash table for devices with generic USB IDs */ +/* + * Reset sequences for analog/digital modes + */ + +/* Board Hauppauge WinTV HVR 900 analog */ +static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { + {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10}, + {0x05, 0xff, 0x10, 10}, + { -1, -1, -1, -1}, +}; + +/* Board Hauppauge WinTV HVR 900 digital */ +static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { + {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10}, + {EM2880_R04_GPO, 0x04, 0x0f, 10}, + {EM2880_R04_GPO, 0x0c, 0x0f, 10}, + { -1, -1, -1, -1}, +}; + +/* Board Hauppauge WinTV HVR 900 tuner_callback */ +static struct em28xx_reg_seq hauppauge_wintv_hvr_900_tuner_callback[] = { + {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, + {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10}, + {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, + { -1, -1, -1, -1}, +}; + +/* + * EEPROM hash table for devices with generic USB IDs + */ static struct em28xx_hash_table em28xx_eeprom_hash [] = { /* P/N: SA 60002070465 Tuner: TVF7533-MF */ {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, @@ -466,79 +472,113 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = { {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, }; +int em28xx_tuner_callback(void *ptr, int command, int arg) +{ + int rc = 0; + struct em28xx *dev = ptr; + + if (dev->tuner_type != TUNER_XC2028) + return 0; + + if (command != XC2028_TUNER_RESET) + return 0; + + if (dev->mode == EM28XX_ANALOG_MODE) + rc = em28xx_gpio_set(dev, dev->tun_analog_gpio); + else + rc = em28xx_gpio_set(dev, dev->tun_digital_gpio); + + return rc; +} +EXPORT_SYMBOL_GPL(em28xx_tuner_callback); + +static void em28xx_set_model(struct em28xx *dev) +{ + dev->is_em2800 = em28xx_boards[dev->model].is_em2800; + dev->has_msp34xx = em28xx_boards[dev->model].has_msp34xx; + dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf; + dev->decoder = em28xx_boards[dev->model].decoder; + dev->video_inputs = em28xx_boards[dev->model].vchannels; + dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s; + dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480; + dev->has_dvb = em28xx_boards[dev->model].has_dvb; +} + /* Since em28xx_pre_card_setup() requires a proper dev->model, * this won't work for boards with generic PCI IDs */ void em28xx_pre_card_setup(struct em28xx *dev) { + int rc; + + rc = em28xx_read_reg(dev, EM2880_R04_GPO); + if (rc >= 0) + dev->reg_gpo = rc; + + dev->wait_after_write = 5; + rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); + if (rc > 0) { + switch (rc) { + case CHIP_ID_EM2883: + em28xx_info("chip ID is em2882/em2883\n"); + dev->wait_after_write = 0; + break; + default: + em28xx_info("em28xx chip ID = %d\n", rc); + } + } + em28xx_set_model(dev); + /* request some modules */ switch (dev->model) { case EM2880_BOARD_TERRATEC_PRODIGY_XS: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: - case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_TERRATEC_HYBRID_XS: - em28xx_write_regs(dev, XCLK_REG, "\x27", 1); - em28xx_write_regs(dev, I2C_CLK_REG, "\x40", 1); - em28xx_write_regs(dev, 0x08, "\xff", 1); - em28xx_write_regs(dev, 0x04, "\x00", 1); - msleep(100); - em28xx_write_regs(dev, 0x04, "\x08", 1); - msleep(100); - em28xx_write_regs(dev, 0x08, "\xff", 1); - msleep(50); - em28xx_write_regs(dev, 0x08, "\x2d", 1); + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); msleep(50); - em28xx_write_regs(dev, 0x08, "\x3d", 1); + + /* Sets GPO/GPIO sequences for this device */ + dev->analog_gpio = hauppauge_wintv_hvr_900_analog; + dev->digital_gpio = hauppauge_wintv_hvr_900_digital; + dev->tun_analog_gpio = hauppauge_wintv_hvr_900_tuner_callback; + dev->tun_digital_gpio = hauppauge_wintv_hvr_900_tuner_callback; + break; } + + em28xx_gpio_set(dev, dev->tun_analog_gpio); + em28xx_set_mode(dev, EM28XX_ANALOG_MODE); + + /* Unlock device */ + em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); } -static int em28xx_tuner_callback(void *ptr, int command, int arg) +static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) { - int rc = 0; - struct em28xx *dev = ptr; + memset(ctl, 0, sizeof(*ctl)); - if (dev->tuner_type != TUNER_XC2028) - return 0; - - switch (command) { - case XC2028_TUNER_RESET: - { - /* GPIO and initialization codes for analog TV and radio - This code should be complemented for DTV, since reset - codes are different. - */ - - dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); - dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1); - - if (dev->analog_gpio) { - char gpio0 = dev->analog_gpio & 0xff; - char gpio1 = (dev->analog_gpio >> 8) & 0xff; - char gpio4 = dev->analog_gpio >> 24; - - if (gpio4) { - dev->em28xx_write_regs(dev, 0x04, &gpio4, 1); - msleep(140); - } - - msleep(6); - dev->em28xx_write_regs(dev, 0x08, &gpio0, 1); - msleep(10); - dev->em28xx_write_regs(dev, 0x08, &gpio1, 1); - msleep(5); - } + ctl->fname = XC2028_DEFAULT_FIRMWARE; + ctl->max_len = 64; + ctl->mts = em28xx_boards[dev->model].mts_firmware; + switch (dev->model) { + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: + ctl->demod = XC3028_FE_ZARLINK456; break; + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + /* FIXME: Better to specify the needed IF */ + ctl->demod = XC3028_FE_DEFAULT; + break; + default: + ctl->demod = XC3028_FE_OREN538; } - } - return rc; } static void em28xx_config_tuner(struct em28xx *dev) { struct v4l2_priv_tun_config xc2028_cfg; - struct xc2028_ctrl ctl; struct tuner_setup tun_setup; struct v4l2_frequency f; @@ -553,11 +593,9 @@ static void em28xx_config_tuner(struct em28xx *dev) em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); if (dev->tuner_type == TUNER_XC2028) { - memset(&ctl, 0, sizeof(ctl)); + struct xc2028_ctrl ctl; - ctl.fname = XC2028_DEFAULT_FIRMWARE; - ctl.max_len = 64; - ctl.mts = em28xx_boards[dev->model].mts_firmware; + em28xx_setup_xc3028(dev, &ctl); xc2028_cfg.tuner = TUNER_XC2028; xc2028_cfg.priv = &ctl; @@ -655,19 +693,6 @@ static int em28xx_hint_board(struct em28xx *dev) return -1; } - -static void em28xx_set_model(struct em28xx *dev) -{ - dev->is_em2800 = em28xx_boards[dev->model].is_em2800; - dev->has_msp34xx = em28xx_boards[dev->model].has_msp34xx; - dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf; - dev->decoder = em28xx_boards[dev->model].decoder; - dev->video_inputs = em28xx_boards[dev->model].vchannels; - dev->analog_gpio = em28xx_boards[dev->model].analog_gpio; - dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s; - dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480; -} - /* ----------------------------------------------------------------------- */ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) { diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c index 1f6abc803..393425487 100644 --- a/linux/drivers/media/video/em28xx/em28xx-core.c +++ b/linux/drivers/media/video/em28xx/em28xx-core.c @@ -38,7 +38,7 @@ MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); #define em28xx_coredbg(fmt, arg...) do {\ if (core_debug) \ printk(KERN_INFO "%s %s :"fmt, \ - dev->name, __FUNCTION__ , ##arg); } while (0) + dev->name, __func__ , ##arg); } while (0) static unsigned int reg_debug; module_param(reg_debug,int,0644); @@ -47,139 +47,17 @@ MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); #define em28xx_regdbg(fmt, arg...) do {\ if (reg_debug) \ printk(KERN_INFO "%s %s :"fmt, \ - dev->name, __FUNCTION__ , ##arg); } while (0) - -static unsigned int isoc_debug; -module_param(isoc_debug,int,0644); -MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]"); - -#define em28xx_isocdbg(fmt, arg...) do {\ - if (isoc_debug) \ - printk(KERN_INFO "%s %s :"fmt, \ - dev->name, __FUNCTION__ , ##arg); } while (0) + dev->name, __func__ , ##arg); } while (0) static int alt = EM28XX_PINOUT; module_param(alt, int, 0644); MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) -#include <linux/mm.h> -static void *rvmalloc(size_t size) -{ - void *mem; - unsigned long adr; - - size = PAGE_ALIGN(size); - - mem = vmalloc_32((unsigned long)size); - if (!mem) - return NULL; - - adr = (unsigned long)mem; - while (size > 0) { - SetPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - return mem; -} - -static void rvfree(void *mem, size_t size) -{ - unsigned long adr; - - if (!mem) - return; - - size = PAGE_ALIGN(size); - - adr = (unsigned long)mem; - while (size > 0) { - ClearPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - vfree(mem); -} -#endif - -/* - * em28xx_request_buffers() - * allocate a number of buffers - */ -u32 em28xx_request_buffers(struct em28xx *dev, u32 count) -{ - const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */ - void *buff = NULL; - u32 i; - em28xx_coredbg("requested %i buffers with size %zi\n", - count, imagesize); - if (count > EM28XX_NUM_FRAMES) - count = EM28XX_NUM_FRAMES; - - dev->num_frames = count; - while (dev->num_frames > 0) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) - if ((buff = rvmalloc(dev->num_frames * imagesize))) { -#else - if ((buff = vmalloc_32(dev->num_frames * imagesize))) { -#endif - memset(buff, 0, dev->num_frames * imagesize); - break; - } - dev->num_frames--; - } - - for (i = 0; i < dev->num_frames; i++) { - dev->frame[i].bufmem = buff + i * imagesize; - dev->frame[i].buf.index = i; - dev->frame[i].buf.m.offset = i * imagesize; - dev->frame[i].buf.length = dev->frame_size; - dev->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - dev->frame[i].buf.sequence = 0; - dev->frame[i].buf.field = V4L2_FIELD_NONE; - dev->frame[i].buf.memory = V4L2_MEMORY_MMAP; - dev->frame[i].buf.flags = 0; - } - return dev->num_frames; -} - -/* - * em28xx_queue_unusedframes() - * add all frames that are not currently in use to the inbuffer queue - */ -void em28xx_queue_unusedframes(struct em28xx *dev) -{ - unsigned long lock_flags; - u32 i; - - for (i = 0; i < dev->num_frames; i++) - if (dev->frame[i].state == F_UNUSED) { - dev->frame[i].state = F_QUEUED; - spin_lock_irqsave(&dev->queue_lock, lock_flags); - list_add_tail(&dev->frame[i].frame, &dev->inqueue); - spin_unlock_irqrestore(&dev->queue_lock, lock_flags); - } -} - -/* - * em28xx_release_buffers() - * free frame buffers - */ -void em28xx_release_buffers(struct em28xx *dev) -{ - if (dev->num_frames) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) - rvfree(dev->frame[0].bufmem, - dev->num_frames * PAGE_ALIGN(dev->frame[0].buf.length)); -#else - vfree(dev->frame[0].bufmem); -#endif - dev->num_frames = 0; - } -} +/* FIXME */ +#define em28xx_isocdbg(fmt, arg...) do {\ + if (core_debug) \ + printk(KERN_INFO "%s %s :"fmt, \ + dev->name, __func__ , ##arg); } while (0) /* * em28xx_read_reg_req() @@ -199,11 +77,11 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x0000, reg, buf, len, HZ); - if (reg_debug){ + if (reg_debug) { printk(ret < 0 ? " failed!\n" : "%02x values: ", ret); - for (byte = 0; byte < len; byte++) { + for (byte = 0; byte < len; byte++) printk(" %02x", (unsigned char)buf[byte]); - } + printk("\n"); } @@ -256,7 +134,10 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, unsigned char *bufs; if (dev->state & DEV_DISCONNECTED) - return(-ENODEV); + return -ENODEV; + + if (len < 1) + return -EINVAL; bufs = kmalloc(len, GFP_KERNEL); @@ -265,8 +146,8 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, if (reg_debug) { int i; for (i = 0; i < len; ++i) - printk (" %02x", (unsigned char)buf[i]); - printk ("\n"); + printk(" %02x", (unsigned char)buf[i]); + printk("\n"); } if (!bufs) @@ -275,14 +156,32 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x0000, reg, bufs, len, HZ); - msleep(5); /* FIXME: magic number */ + if (dev->wait_after_write) + msleep(dev->wait_after_write); + kfree(bufs); return ret; } int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len) { - return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len); + int rc; + + rc = em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len); + + /* Stores GPO/GPIO values at the cache, if changed + Only write values should be stored, since input on a GPIO + register will return the input bits. + Not sure what happens on reading GPO register. + */ + if (rc >= 0) { + if (reg == EM2880_R04_GPO) + dev->reg_gpo = buf[0]; + else if (reg == EM28XX_R08_GPIO) + dev->reg_gpio = buf[0]; + } + + return rc; } /* @@ -295,9 +194,20 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, { int oldval; u8 newval; - if ((oldval = em28xx_read_reg(dev, reg)) < 0) + + /* Uses cache for gpo/gpio registers */ + if (reg == EM2880_R04_GPO) + oldval = dev->reg_gpo; + else if (reg == EM28XX_R08_GPIO) + oldval = dev->reg_gpio; + else + oldval = em28xx_read_reg(dev, reg); + + if (oldval < 0) return oldval; + newval = (((u8) oldval) & ~bitmask) | (val & bitmask); + return em28xx_write_regs(dev, reg, &newval, 1); } @@ -309,20 +219,26 @@ static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val) { int ret, i; u8 addr = reg & 0x7f; - if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0) + + ret = em28xx_write_regs(dev, EM28XX_R40_AC97LSB, val, 2); + if (ret < 0) return ret; - if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0) + + ret = em28xx_write_regs(dev, EM28XX_R42_AC97ADDR, &addr, 1); + if (ret < 0) return ret; /* Wait up to 50 ms for AC97 command to complete */ for (i = 0; i < 10; i++) { - if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0) + ret = em28xx_read_reg(dev, EM28XX_R43_AC97BUSY); + if (ret < 0) return ret; + if (!(ret & 0x01)) return 0; msleep(5); } - em28xx_warn ("AC97 command still being executed: not handled properly!\n"); + em28xx_warn("AC97 command still being executed: not handled properly!\n"); return 0; } @@ -340,7 +256,7 @@ static int em28xx_set_audio_source(struct em28xx *dev) else input = EM2800_AUDIO_SRC_TUNER; - ret = em28xx_write_regs(dev, EM2800_AUDIOSRC_REG, &input, 1); + ret = em28xx_write_regs(dev, EM2800_R08_AUDIOSRC, &input, 1); if (ret < 0) return ret; } @@ -366,7 +282,7 @@ static int em28xx_set_audio_source(struct em28xx *dev) } } - ret = em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0); + ret = em28xx_write_reg_bits(dev, EM28XX_R0E_AUDIOSRC, input, 0xc0); if (ret < 0) return ret; msleep(5); @@ -374,11 +290,11 @@ static int em28xx_set_audio_source(struct em28xx *dev) /* Sets AC97 mixer registers This is seems to be needed, even for non-ac97 configs */ - ret = em28xx_write_ac97(dev, VIDEO_AC97, video); + ret = em28xx_write_ac97(dev, EM28XX_R14_VIDEO_AC97, video); if (ret < 0) return ret; - ret = em28xx_write_ac97(dev, LINE_IN_AC97, line); + ret = em28xx_write_ac97(dev, EM28XX_R10_LINE_IN_AC97, line); return ret; } @@ -394,7 +310,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) /* Mute */ s[1] |= 0x80; - ret = em28xx_write_ac97(dev, MASTER_AC97, s); + ret = em28xx_write_ac97(dev, EM28XX_R02_MASTER_AC97, s); if (ret < 0) return ret; @@ -405,7 +321,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) if (!dev->mute) xclk |= 0x80; - ret = em28xx_write_reg_bits(dev, XCLK_REG, xclk, 0xa7); + ret = em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, xclk, 0xa7); if (ret < 0) return ret; msleep(10); @@ -416,7 +332,7 @@ int em28xx_audio_analog_set(struct em28xx *dev) /* Unmute device */ if (!dev->mute) s[1] &= ~0x80; - ret = em28xx_write_ac97(dev, MASTER_AC97, s); + ret = em28xx_write_ac97(dev, EM28XX_R02_MASTER_AC97, s); return ret; } @@ -424,50 +340,68 @@ EXPORT_SYMBOL_GPL(em28xx_audio_analog_set); int em28xx_colorlevels_set_default(struct em28xx *dev) { - em28xx_write_regs(dev, YGAIN_REG, "\x10", 1); /* contrast */ - em28xx_write_regs(dev, YOFFSET_REG, "\x00", 1); /* brightness */ - em28xx_write_regs(dev, UVGAIN_REG, "\x10", 1); /* saturation */ - em28xx_write_regs(dev, UOFFSET_REG, "\x00", 1); - em28xx_write_regs(dev, VOFFSET_REG, "\x00", 1); - em28xx_write_regs(dev, SHARPNESS_REG, "\x00", 1); - - em28xx_write_regs(dev, GAMMA_REG, "\x20", 1); - em28xx_write_regs(dev, RGAIN_REG, "\x20", 1); - em28xx_write_regs(dev, GGAIN_REG, "\x20", 1); - em28xx_write_regs(dev, BGAIN_REG, "\x20", 1); - em28xx_write_regs(dev, ROFFSET_REG, "\x00", 1); - em28xx_write_regs(dev, GOFFSET_REG, "\x00", 1); - return em28xx_write_regs(dev, BOFFSET_REG, "\x00", 1); + em28xx_write_regs(dev, EM28XX_R20_YGAIN, "\x10", 1); /* contrast */ + em28xx_write_regs(dev, EM28XX_R21_YOFFSET, "\x00", 1); /* brightness */ + em28xx_write_regs(dev, EM28XX_R22_UVGAIN, "\x10", 1); /* saturation */ + em28xx_write_regs(dev, EM28XX_R23_UOFFSET, "\x00", 1); + em28xx_write_regs(dev, EM28XX_R24_VOFFSET, "\x00", 1); + em28xx_write_regs(dev, EM28XX_R25_SHARPNESS, "\x00", 1); + + em28xx_write_regs(dev, EM28XX_R14_GAMMA, "\x20", 1); + em28xx_write_regs(dev, EM28XX_R15_RGAIN, "\x20", 1); + em28xx_write_regs(dev, EM28XX_R16_GGAIN, "\x20", 1); + em28xx_write_regs(dev, EM28XX_R17_BGAIN, "\x20", 1); + em28xx_write_regs(dev, EM28XX_R18_ROFFSET, "\x00", 1); + em28xx_write_regs(dev, EM28XX_R19_GOFFSET, "\x00", 1); + return em28xx_write_regs(dev, EM28XX_R1A_BOFFSET, "\x00", 1); } int em28xx_capture_start(struct em28xx *dev, int start) { - int ret; + int rc; /* FIXME: which is the best order? */ /* video registers are sampled by VREF */ - if ((ret = em28xx_write_reg_bits(dev, USBSUSP_REG, start ? 0x10 : 0x00, - 0x10)) < 0) - return ret; + rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP, + start ? 0x10 : 0x00, 0x10); + if (rc < 0) + return rc; + + if (!start) { + /* disable video capture */ + rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x27", 1); + return rc; + } + /* enable video capture */ - return em28xx_write_regs(dev, VINENABLE_REG, start ? "\x67" : "\x27", 1); + rc = em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); + + if (dev->mode == EM28XX_ANALOG_MODE) + rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x67", 1); + else + rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x37", 1); + + msleep(6); + + return rc; } int em28xx_outfmt_set_yuv422(struct em28xx *dev) { - em28xx_write_regs(dev, OUTFMT_REG, "\x34", 1); - em28xx_write_regs(dev, VINMODE_REG, "\x10", 1); - return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1); + em28xx_write_regs(dev, EM28XX_R27_OUTFMT, "\x34", 1); + em28xx_write_regs(dev, EM28XX_R10_VINMODE, "\x10", 1); + return em28xx_write_regs(dev, EM28XX_R11_VINCTRL, "\x11", 1); } static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin, u8 ymax) { - em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax); + em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", + xmin, ymin, xmax, ymax); - em28xx_write_regs(dev, XMIN_REG, &xmin, 1); - em28xx_write_regs(dev, XMAX_REG, &xmax, 1); - em28xx_write_regs(dev, YMIN_REG, &ymin, 1); - return em28xx_write_regs(dev, YMAX_REG, &ymax, 1); + em28xx_write_regs(dev, EM28XX_R28_XMIN, &xmin, 1); + em28xx_write_regs(dev, EM28XX_R29_XMAX, &xmax, 1); + em28xx_write_regs(dev, EM28XX_R2A_YMIN, &ymin, 1); + return em28xx_write_regs(dev, EM28XX_R2B_YMAX, &ymax, 1); } static int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, @@ -477,34 +411,36 @@ static int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, u8 cheight = height; u8 overflow = (height >> 7 & 0x02) | (width >> 8 & 0x01); - em28xx_coredbg("em28xx Area Set: (%d,%d)\n", (width | (overflow & 2) << 7), + em28xx_coredbg("em28xx Area Set: (%d,%d)\n", + (width | (overflow & 2) << 7), (height | (overflow & 1) << 8)); - em28xx_write_regs(dev, HSTART_REG, &hstart, 1); - em28xx_write_regs(dev, VSTART_REG, &vstart, 1); - em28xx_write_regs(dev, CWIDTH_REG, &cwidth, 1); - em28xx_write_regs(dev, CHEIGHT_REG, &cheight, 1); - return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1); + em28xx_write_regs(dev, EM28XX_R1C_HSTART, &hstart, 1); + em28xx_write_regs(dev, EM28XX_R1D_VSTART, &vstart, 1); + em28xx_write_regs(dev, EM28XX_R1E_CWIDTH, &cwidth, 1); + em28xx_write_regs(dev, EM28XX_R1F_CHEIGHT, &cheight, 1); + return em28xx_write_regs(dev, EM28XX_R1B_OFLOW, &overflow, 1); } static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) { u8 mode; /* the em2800 scaler only supports scaling down to 50% */ - if(dev->is_em2800) + if (dev->is_em2800) mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); else { u8 buf[2]; buf[0] = h; buf[1] = h >> 8; - em28xx_write_regs(dev, HSCALELOW_REG, (char *)buf, 2); + em28xx_write_regs(dev, EM28XX_R30_HSCALELOW, (char *)buf, 2); buf[0] = v; buf[1] = v >> 8; - em28xx_write_regs(dev, VSCALELOW_REG, (char *)buf, 2); - /* it seems that both H and V scalers must be active to work correctly */ + em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2); + /* it seems that both H and V scalers must be active + to work correctly */ mode = (h || v)? 0x30: 0x00; } - return em28xx_write_reg_bits(dev, COMPR_REG, mode, 0x30); + return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30); } /* FIXME: this only function read values from dev */ @@ -520,396 +456,280 @@ int em28xx_resolution_set(struct em28xx *dev) return em28xx_scaler_set(dev, dev->hscale, dev->vscale); } - -/******************* isoc transfer handling ****************************/ - -#ifdef ENABLE_DEBUG_ISOC_FRAMES -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -static void em28xx_isoc_dump(struct urb *urb, struct pt_regs *regs) -#else -static void em28xx_isoc_dump(struct urb *urb) -#endif +int em28xx_set_alternate(struct em28xx *dev) { - int len = 0; - int ntrans = 0; + int errCode, prev_alt = dev->alt; int i; + unsigned int min_pkt_size = dev->width * 2 + 4; - printk(KERN_DEBUG "isocIrq: sf=%d np=%d ec=%x\n", - urb->start_frame, urb->number_of_packets, - urb->error_count); - for (i = 0; i < urb->number_of_packets; i++) { - unsigned char *buf = - urb->transfer_buffer + - urb->iso_frame_desc[i].offset; - int alen = urb->iso_frame_desc[i].actual_length; - if (alen > 0) { - if (buf[0] == 0x88) { - ntrans++; - len += alen; - } else if (buf[0] == 0x22) { - printk(KERN_DEBUG - "= l=%d nt=%d bpp=%d\n", - len - 4 * ntrans, ntrans, - ntrans == 0 ? 0 : len / ntrans); - ntrans = 1; - len = alen; - } else - printk(KERN_DEBUG "!\n"); + /* When image size is bigger than a certain value, + the frame size should be increased, otherwise, only + green screen will be received. + */ + if (dev->width * 2 * dev->height > 720 * 240 * 2) + min_pkt_size *= 2; + + for (i = 0; i < dev->num_alt; i++) { + /* stop when the selected alt setting offers enough bandwidth */ + if (dev->alt_max_pkt_size[i] >= min_pkt_size) { + dev->alt = i; + break; + /* otherwise make sure that we end up with the maximum bandwidth + because the min_pkt_size equation might be wrong... + */ + } else if (dev->alt_max_pkt_size[i] > + dev->alt_max_pkt_size[dev->alt]) + dev->alt = i; + } + + if (dev->alt != prev_alt) { + em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", + min_pkt_size, dev->alt); + dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt]; + em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", + dev->alt, dev->max_pkt_size); + errCode = usb_set_interface(dev->udev, 0, dev->alt); + if (errCode < 0) { + em28xx_errdev("cannot change alternate number to %d (error=%i)\n", + dev->alt, errCode); + return errCode; } - printk(KERN_DEBUG " n=%d s=%d al=%d %x\n", i, - urb->iso_frame_desc[i].status, - urb->iso_frame_desc[i].actual_length, - (unsigned int) - *((unsigned char *)(urb->transfer_buffer + - urb->iso_frame_desc[i]. - offset))); } + return 0; } -#endif -static inline int em28xx_isoc_video(struct em28xx *dev,struct em28xx_frame_t **f, - unsigned long *lock_flags, unsigned char buf) +int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio) { - if (!(buf & 0x01)) { - if ((*f)->state == F_GRABBING) { - /*previous frame is incomplete */ - if ((*f)->fieldbytesused < dev->field_size) { - (*f)->state = F_ERROR; - em28xx_isocdbg ("dropping incomplete bottom field (%i missing bytes)", - dev->field_size-(*f)->fieldbytesused); - } else { - (*f)->state = F_DONE; - (*f)->buf.bytesused = dev->frame_size; - } - } - if ((*f)->state == F_DONE || (*f)->state == F_ERROR) { - /* move current frame to outqueue and get next free buffer from inqueue */ - spin_lock_irqsave(&dev-> queue_lock, *lock_flags); - list_move_tail(&(*f)->frame, &dev->outqueue); - if (!list_empty(&dev->inqueue)) - (*f) = list_entry(dev-> inqueue.next, - struct em28xx_frame_t,frame); - else - (*f) = NULL; - spin_unlock_irqrestore(&dev->queue_lock,*lock_flags); - } - if (!(*f)) { - em28xx_isocdbg ("new frame but no buffer is free"); - return -1; - } - do_gettimeofday(&(*f)->buf.timestamp); - (*f)->buf.sequence = ++dev->frame_count; - (*f)->buf.field = V4L2_FIELD_INTERLACED; - (*f)->state = F_GRABBING; - (*f)->buf.bytesused = 0; - (*f)->top_field = 1; - (*f)->fieldbytesused = 0; - } else { - /* acquiring bottom field */ - if ((*f)->state == F_GRABBING) { - if (!(*f)->top_field) { - (*f)->state = F_ERROR; - em28xx_isocdbg ("unexpected begin of bottom field; discarding it"); - } else if ((*f)-> fieldbytesused < dev->field_size - 172) { - (*f)->state = F_ERROR; - em28xx_isocdbg ("dropping incomplete top field (%i missing bytes)", - dev->field_size-(*f)->fieldbytesused); - } else { - (*f)->top_field = 0; - (*f)->fieldbytesused = 0; - } + int rc = 0; + + if (!gpio) + return rc; + + dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); + if (dev->mode == EM28XX_ANALOG_MODE) + dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1); + else + dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1); + msleep(6); + + /* Send GPIO reset sequences specified at board entry */ + while (gpio->sleep >= 0) { + if (gpio->reg >= 0) { + rc = em28xx_write_reg_bits(dev, + gpio->reg, + gpio->val, + gpio->mask); + if (rc < 0) + return rc; } + if (gpio->sleep > 0) + msleep(gpio->sleep); + + gpio++; } - return (0); + return rc; } -static inline void em28xx_isoc_video_copy(struct em28xx *dev, - struct em28xx_frame_t **f, unsigned char *buf, int len) +int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode) { - void *fieldstart, *startwrite, *startread; - int linesdone, currlinedone, offset, lencopy,remain; + if (dev->mode == set_mode) + return 0; - if(dev->frame_size != (*f)->buf.length){ - em28xx_err("frame_size %i and buf.length %i are different!!!\n",dev->frame_size,(*f)->buf.length); - return; + if (set_mode == EM28XX_MODE_UNDEFINED) { + dev->mode = set_mode; + return 0; } - if ((*f)->fieldbytesused + len > dev->field_size) - len =dev->field_size - (*f)->fieldbytesused; - - if (buf[0] != 0x88 && buf[0] != 0x22) { - em28xx_isocdbg("frame is not complete\n"); - startread = buf; - len+=4; - } else - startread = buf + 4; - - remain = len; +#if 0 + /* Resource is locked */ + if (dev->mode != EM28XX_MODE_UNDEFINED) + return -EINVAL; +#endif + dev->mode = set_mode; - if ((*f)->top_field) - fieldstart = (*f)->bufmem; + if (dev->mode == EM28XX_DIGITAL_MODE) + return em28xx_gpio_set(dev, dev->digital_gpio); else - fieldstart = (*f)->bufmem + dev->bytesperline; - - linesdone = (*f)->fieldbytesused / dev->bytesperline; - currlinedone = (*f)->fieldbytesused % dev->bytesperline; - offset = linesdone * dev->bytesperline * 2 + currlinedone; - startwrite = fieldstart + offset; - lencopy = dev->bytesperline - currlinedone; - lencopy = lencopy > remain ? remain : lencopy; - - memcpy(startwrite, startread, lencopy); - remain -= lencopy; - - while (remain > 0) { - startwrite += lencopy + dev->bytesperline; - startread += lencopy; - if (dev->bytesperline > remain) - lencopy = remain; - else - lencopy = dev->bytesperline; - - memcpy(startwrite, startread, lencopy); - remain -= lencopy; - } - - (*f)->fieldbytesused += len; + return em28xx_gpio_set(dev, dev->analog_gpio); } +EXPORT_SYMBOL_GPL(em28xx_set_mode); + +/* ------------------------------------------------------------------ + URB control + ------------------------------------------------------------------*/ /* - * em28xx_isoIrq() - * handles the incoming isoc urbs and fills the frames from our inqueue + * IRQ callback, called by URB callback */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -static void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void em28xx_irq_callback(struct urb *urb, struct pt_regs *regs) #else -static void em28xx_isocIrq(struct urb *urb) +static void em28xx_irq_callback(struct urb *urb) #endif { - struct em28xx *dev = urb->context; - int i, status; - struct em28xx_frame_t **f; - unsigned long lock_flags; - - if (!dev) - return; -#ifdef ENABLE_DEBUG_ISOC_FRAMES - if (isoc_debug>1) -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) - em28xx_isoc_dump(urb, regs); -#else - em28xx_isoc_dump(urb); -#endif -#endif - - if (urb->status == -ENOENT) - return; - - f = &dev->frame_current; - - if (dev->stream == STREAM_INTERRUPT) { - dev->stream = STREAM_OFF; - if ((*f)) - (*f)->state = F_QUEUED; - em28xx_isocdbg("stream interrupted"); - wake_up_interruptible(&dev->wait_stream); - } - - if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) - return; - - if (dev->stream == STREAM_ON && !list_empty(&dev->inqueue)) { - if (!(*f)) - (*f) = list_entry(dev->inqueue.next, - struct em28xx_frame_t, frame); - - for (i = 0; i < urb->number_of_packets; i++) { - unsigned char *buf = urb->transfer_buffer + - urb->iso_frame_desc[i].offset; - int len = urb->iso_frame_desc[i].actual_length - 4; - - if (urb->iso_frame_desc[i].status) { - em28xx_isocdbg("data error: [%d] len=%d, status=%d", i, - urb->iso_frame_desc[i].actual_length, - urb->iso_frame_desc[i].status); - if (urb->iso_frame_desc[i].status != -EPROTO) - continue; - } - if (urb->iso_frame_desc[i].actual_length <= 0) { - em28xx_isocdbg("packet %d is empty",i); - continue; - } - if (urb->iso_frame_desc[i].actual_length > - urb->iso_frame_desc[i].length) { - em28xx_isocdbg("packet bigger than packet size"); - continue; - } - /*new frame */ - if (buf[0] == 0x22 && buf[1] == 0x5a) { - em28xx_isocdbg("Video frame, length=%i!",len); - - if (em28xx_isoc_video(dev,f,&lock_flags,buf[2])) - break; - } else if (buf[0]==0x33 && buf[1]==0x95 && buf[2]==0x00) { - em28xx_isocdbg("VBI HEADER!!!"); - } + struct em28xx_dmaqueue *dma_q = urb->context; + struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); + int rc, i; - /* actual copying */ - if ((*f)->state == F_GRABBING) { - em28xx_isoc_video_copy(dev,f,buf, len); - } - } - } + /* Copy data from URB */ + spin_lock(&dev->slock); + rc = dev->isoc_ctl.isoc_copy(dev, urb); + spin_unlock(&dev->slock); + /* Reset urb buffers */ for (i = 0; i < urb->number_of_packets; i++) { urb->iso_frame_desc[i].status = 0; urb->iso_frame_desc[i].actual_length = 0; } - urb->status = 0; - if ((status = usb_submit_urb(urb, GFP_ATOMIC))) { - em28xx_errdev("resubmit of urb failed (error=%i)\n", status); - dev->state |= DEV_MISCONFIGURED; + + urb->status = usb_submit_urb(urb, GFP_ATOMIC); + if (urb->status) { + em28xx_isocdbg("urb resubmit failed (error=%i)\n", + urb->status); } - wake_up_interruptible(&dev->wait_frame); - return; } /* - * em28xx_uninit_isoc() - * deallocates the buffers and urbs allocated during em28xx_init_iosc() + * Stop and Deallocate URBs */ void em28xx_uninit_isoc(struct em28xx *dev) { + struct urb *urb; int i; - for (i = 0; i < EM28XX_NUM_BUFS; i++) { - if (dev->urb[i]) { - usb_kill_urb(dev->urb[i]); - if (dev->transfer_buffer[i]) { + em28xx_isocdbg("em28xx: called em28xx_uninit_isoc\n"); + + dev->isoc_ctl.nfields = -1; + for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { + urb = dev->isoc_ctl.urb[i]; + if (urb) { + usb_kill_urb(urb); + usb_unlink_urb(urb); + if (dev->isoc_ctl.transfer_buffer[i]) { usb_buffer_free(dev->udev, - dev->urb[i]->transfer_buffer_length, - dev->transfer_buffer[i], - dev->urb[i]->transfer_dma); + urb->transfer_buffer_length, + dev->isoc_ctl.transfer_buffer[i], + urb->transfer_dma); } - usb_free_urb(dev->urb[i]); + usb_free_urb(urb); + dev->isoc_ctl.urb[i] = NULL; } - dev->urb[i] = NULL; - dev->transfer_buffer[i] = NULL; + dev->isoc_ctl.transfer_buffer[i] = NULL; } + + kfree(dev->isoc_ctl.urb); + kfree(dev->isoc_ctl.transfer_buffer); + + dev->isoc_ctl.urb = NULL; + dev->isoc_ctl.transfer_buffer = NULL; + dev->isoc_ctl.num_bufs = 0; + em28xx_capture_start(dev, 0); } +EXPORT_SYMBOL_GPL(em28xx_uninit_isoc); /* - * em28xx_init_isoc() - * allocates transfer buffers and submits the urbs for isoc transfer + * Allocate URBs and start IRQ */ -int em28xx_init_isoc(struct em28xx *dev) +int em28xx_init_isoc(struct em28xx *dev, int max_packets, + int num_bufs, int max_pkt_size, + int (*isoc_copy) (struct em28xx *dev, struct urb *urb)) { - /* change interface to 3 which allows the biggest packet sizes */ - int i, errCode; - int sb_size; - - em28xx_set_alternate(dev); - sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size; - - /* reset streaming vars */ - dev->frame_current = NULL; - dev->frame_count = 0; - - /* allocate urbs */ - for (i = 0; i < EM28XX_NUM_BUFS; i++) { - struct urb *urb; - int j; - /* allocate transfer buffer */ - urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL); - if (!urb){ - em28xx_errdev("cannot alloc urb %i\n", i); + struct em28xx_dmaqueue *dma_q = &dev->vidq; + int i; + int sb_size, pipe; + struct urb *urb; + int j, k; + int rc; + + em28xx_isocdbg("em28xx: called em28xx_prepare_isoc\n"); + + /* De-allocates all pending stuff */ + em28xx_uninit_isoc(dev); + + dev->isoc_ctl.isoc_copy = isoc_copy; + dev->isoc_ctl.num_bufs = num_bufs; + + dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); + if (!dev->isoc_ctl.urb) { + em28xx_errdev("cannot alloc memory for usb buffers\n"); + return -ENOMEM; + } + + dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs, + GFP_KERNEL); + if (!dev->isoc_ctl.urb) { + em28xx_errdev("cannot allocate memory for usbtransfer\n"); + kfree(dev->isoc_ctl.urb); + return -ENOMEM; + } + + dev->isoc_ctl.max_pkt_size = max_pkt_size; + dev->isoc_ctl.buf = NULL; + + sb_size = max_packets * dev->isoc_ctl.max_pkt_size; + + /* allocate urbs and transfer buffers */ + for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { + urb = usb_alloc_urb(max_packets, GFP_KERNEL); + if (!urb) { + em28xx_err("cannot alloc isoc_ctl.urb %i\n", i); em28xx_uninit_isoc(dev); return -ENOMEM; } - dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, - GFP_KERNEL, - &urb->transfer_dma); - if (!dev->transfer_buffer[i]) { - em28xx_errdev - ("unable to allocate %i bytes for transfer buffer %i\n", - sb_size, i); + dev->isoc_ctl.urb[i] = urb; + + dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->udev, + sb_size, GFP_KERNEL, &urb->transfer_dma); + if (!dev->isoc_ctl.transfer_buffer[i]) { + em28xx_err("unable to allocate %i bytes for transfer" + " buffer %i%s\n", + sb_size, i, + in_interrupt()?" while in int":""); em28xx_uninit_isoc(dev); - usb_free_urb(urb); return -ENOMEM; } - memset(dev->transfer_buffer[i], 0, sb_size); - urb->dev = dev->udev; - urb->context = dev; - urb->pipe = usb_rcvisocpipe(dev->udev, 0x82); - urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; - urb->interval = 1; - urb->transfer_buffer = dev->transfer_buffer[i]; - urb->complete = em28xx_isocIrq; - urb->number_of_packets = EM28XX_NUM_PACKETS; - urb->transfer_buffer_length = sb_size; - for (j = 0; j < EM28XX_NUM_PACKETS; j++) { - urb->iso_frame_desc[j].offset = j * dev->max_pkt_size; - urb->iso_frame_desc[j].length = dev->max_pkt_size; + memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size); + + /* FIXME: this is a hack - should be + 'desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK' + should also be using 'desc.bInterval' + */ + pipe = usb_rcvisocpipe(dev->udev, + dev->mode == EM28XX_ANALOG_MODE ? 0x82 : 0x84); + + usb_fill_int_urb(urb, dev->udev, pipe, + dev->isoc_ctl.transfer_buffer[i], sb_size, + em28xx_irq_callback, dma_q, 1); + + urb->number_of_packets = max_packets; + urb->transfer_flags = URB_ISO_ASAP; + + k = 0; + for (j = 0; j < max_packets; j++) { + urb->iso_frame_desc[j].offset = k; + urb->iso_frame_desc[j].length = + dev->isoc_ctl.max_pkt_size; + k += dev->isoc_ctl.max_pkt_size; } - dev->urb[i] = urb; } - /* submit urbs */ - em28xx_coredbg("Submitting %d urbs of %d packets (%d each)\n", - EM28XX_NUM_BUFS, EM28XX_NUM_PACKETS, dev->max_pkt_size); - for (i = 0; i < EM28XX_NUM_BUFS; i++) { - errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL); - if (errCode) { - em28xx_errdev("submit of urb %i failed (error=%i)\n", i, - errCode); - em28xx_uninit_isoc(dev); - return errCode; - } - } + init_waitqueue_head(&dma_q->wq); - return 0; -} + em28xx_capture_start(dev, 1); -int em28xx_set_alternate(struct em28xx *dev) -{ - int errCode, prev_alt = dev->alt; - int i; - unsigned int min_pkt_size = dev->bytesperline + 4; - - /* When image size is bigger than a certain value, - the frame size should be increased, otherwise, only - green screen will be received. - */ - if (dev->frame_size > 720*240*2) - min_pkt_size *= 2; - - for (i = 0; i < dev->num_alt; i++) { - /* stop when the selected alt setting offers enough bandwidth */ - if (dev->alt_max_pkt_size[i] >= min_pkt_size) { - dev->alt = i; - break; - /* otherwise make sure that we end up with the maximum bandwidth - because the min_pkt_size equation might be wrong... - */ - } else if (dev->alt_max_pkt_size[i] > - dev->alt_max_pkt_size[dev->alt]) - dev->alt = i; - } - - if (dev->alt != prev_alt) { - em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", - min_pkt_size, dev->alt); - dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt]; - em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", - dev->alt, dev->max_pkt_size); - errCode = usb_set_interface(dev->udev, 0, dev->alt); - if (errCode < 0) { - em28xx_errdev ("cannot change alternate number to %d (error=%i)\n", - dev->alt, errCode); - return errCode; + /* submit urbs and enables IRQ */ + for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { + rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC); + if (rc) { + em28xx_err("submit of urb %i failed (error=%i)\n", i, + rc); + em28xx_uninit_isoc(dev); + return rc; } } + return 0; } +EXPORT_SYMBOL_GPL(em28xx_init_isoc); diff --git a/linux/drivers/media/video/em28xx/em28xx-dvb.c b/linux/drivers/media/video/em28xx/em28xx-dvb.c new file mode 100644 index 000000000..5c9941d92 --- /dev/null +++ b/linux/drivers/media/video/em28xx/em28xx-dvb.c @@ -0,0 +1,506 @@ +/* + DVB device driver for em28xx + + (c) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> + + (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> + - Fixes for the driver to properly work with HVR-950 + + (c) 2008 Aidan Thornton <makosoft@googlemail.com> + + Based on cx88-dvb, saa7134-dvb and videobuf-dvb originally written by: + (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> + (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] + + 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. + */ + +#include <linux/kernel.h> +#include <linux/usb.h> +#include "compat.h" + +#include "em28xx.h" +#include <media/v4l2-common.h> +#include <media/videobuf-vmalloc.h> + +#include "lgdt330x.h" +#include "zl10353.h" + +MODULE_DESCRIPTION("driver for em28xx based DVB cards"); +MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); +MODULE_LICENSE("GPL"); + +static unsigned int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "enable debug messages [dvb]"); + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +#define dprintk(level, fmt, arg...) do { \ +if (debug >= level) \ + printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \ +} while (0) + +#define EM28XX_DVB_NUM_BUFS 5 +#define EM28XX_DVB_MAX_PACKETSIZE 564 +#define EM28XX_DVB_MAX_PACKETS 64 + +struct em28xx_dvb { + struct dvb_frontend *frontend; + + /* feed count management */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 15) + struct mutex lock; +#else + struct semaphore lock; +#endif + int nfeeds; + + /* general boilerplate stuff */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) + struct dvb_adapter adapter; +#else + struct dvb_adapter *adapter; +#endif + struct dvb_demux demux; + struct dmxdev dmxdev; + struct dmx_frontend fe_hw; + struct dmx_frontend fe_mem; + struct dvb_net net; +}; + + +static inline void print_err_status(struct em28xx *dev, + int packet, int status) +{ + char *errmsg = "Unknown"; + + switch (status) { + case -ENOENT: + errmsg = "unlinked synchronuously"; + break; + case -ECONNRESET: + errmsg = "unlinked asynchronuously"; + break; + case -ENOSR: + errmsg = "Buffer error (overrun)"; + break; + case -EPIPE: + errmsg = "Stalled (device not responding)"; + break; + case -EOVERFLOW: + errmsg = "Babble (bad cable?)"; + break; + case -EPROTO: + errmsg = "Bit-stuff error (bad cable?)"; + break; + case -EILSEQ: + errmsg = "CRC/Timeout (could be anything)"; + break; + case -ETIME: + errmsg = "Device does not respond"; + break; + } + if (packet < 0) { + dprintk(1, "URB status %d [%s].\n", status, errmsg); + } else { + dprintk(1, "URB packet %d, status %d [%s].\n", + packet, status, errmsg); + } +} + +static inline int dvb_isoc_copy(struct em28xx *dev, struct urb *urb) +{ + int i; + + if (!dev) + return 0; + + if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) + return 0; + + if (urb->status < 0) { + print_err_status(dev, -1, urb->status); + if (urb->status == -ENOENT) + return 0; + } + + for (i = 0; i < urb->number_of_packets; i++) { + int status = urb->iso_frame_desc[i].status; + + if (status < 0) { + print_err_status(dev, i, status); + if (urb->iso_frame_desc[i].status != -EPROTO) + continue; + } + + dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer + + urb->iso_frame_desc[i].offset, + urb->iso_frame_desc[i].actual_length); + } + + return 0; +} + +static int start_streaming(struct em28xx_dvb *dvb) +{ + int rc; + struct em28xx *dev = dvb->adapter.priv; + + usb_set_interface(dev->udev, 0, 1); + rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); + if (rc < 0) + return rc; + + return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS, + EM28XX_DVB_NUM_BUFS, EM28XX_DVB_MAX_PACKETSIZE, + dvb_isoc_copy); +} + +static int stop_streaming(struct em28xx_dvb *dvb) +{ + struct em28xx *dev = dvb->adapter.priv; + + em28xx_uninit_isoc(dev); + + em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); + + return 0; +} + +static int start_feed(struct dvb_demux_feed *feed) +{ + struct dvb_demux *demux = feed->demux; + struct em28xx_dvb *dvb = demux->priv; + int rc, ret; + + if (!demux->dmx.frontend) + return -EINVAL; + + mutex_lock(&dvb->lock); + dvb->nfeeds++; + rc = dvb->nfeeds; + + if (dvb->nfeeds == 1) { + ret = start_streaming(dvb); + if (ret < 0) + rc = ret; + } + + mutex_unlock(&dvb->lock); + return rc; +} + +static int stop_feed(struct dvb_demux_feed *feed) +{ + struct dvb_demux *demux = feed->demux; + struct em28xx_dvb *dvb = demux->priv; + int err = 0; + + mutex_lock(&dvb->lock); + dvb->nfeeds--; + + if (0 == dvb->nfeeds) + err = stop_streaming(dvb); + + mutex_unlock(&dvb->lock); + return err; +} + + + +/* ------------------------------------------------------------------ */ +static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) +{ + struct em28xx *dev = fe->dvb->priv; + + if (acquire) + return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); + else + return em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); +} + +/* ------------------------------------------------------------------ */ + +static struct lgdt330x_config em2880_lgdt3303_dev = { + .demod_address = 0x0e, + .demod_chip = LGDT3303, +}; + +static struct zl10353_config em28xx_zl10353_with_xc3028 = { + .demod_address = (0x1e >> 1), + .no_tuner = 1, + .parallel_ts = 1, + .if2 = 45600, +}; + +/* ------------------------------------------------------------------ */ + +static int attach_xc3028(u8 addr, struct em28xx *dev) +{ + struct dvb_frontend *fe; + struct xc2028_config cfg; + + memset(&cfg, 0, sizeof(cfg)); + cfg.i2c_adap = &dev->i2c_adap; + cfg.i2c_addr = addr; + cfg.callback = em28xx_tuner_callback; + + if (!dev->dvb->frontend) { + printk(KERN_ERR "%s/2: dvb frontend not attached. " + "Can't attach xc3028\n", + dev->name); + return -EINVAL; + } + + fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg); + if (!fe) { + printk(KERN_ERR "%s/2: xc3028 attach failed\n", + dev->name); + dvb_frontend_detach(dev->dvb->frontend); + dvb_unregister_frontend(dev->dvb->frontend); + dev->dvb->frontend = NULL; + return -EINVAL; + } + + printk(KERN_INFO "%s/2: xc3028 attached\n", dev->name); + + return 0; +} + +/* ------------------------------------------------------------------ */ + +int register_dvb(struct em28xx_dvb *dvb, + struct module *module, + struct em28xx *dev, + struct device *device) +{ + int result; + + mutex_init(&dvb->lock); + + /* register adapter */ + result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, + adapter_nr); + if (result < 0) { + printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", + dev->name, result); + goto fail_adapter; + } + + /* Ensure all frontends negotiate bus access */ + dvb->frontend->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) + dvb->adapter.priv = dev; + + /* register frontend */ + result = dvb_register_frontend(&dvb->adapter, dvb->frontend); +#else + dvb->adapter->priv = dev; + + /* register frontend */ + result = dvb_register_frontend(dvb->adapter, dvb->frontend); +#endif + if (result < 0) { + printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", + dev->name, result); + goto fail_frontend; + } + + /* register demux stuff */ + dvb->demux.dmx.capabilities = + DMX_TS_FILTERING | DMX_SECTION_FILTERING | + DMX_MEMORY_BASED_FILTERING; + dvb->demux.priv = dvb; + dvb->demux.filternum = 256; + dvb->demux.feednum = 256; + dvb->demux.start_feed = start_feed; + dvb->demux.stop_feed = stop_feed; + + result = dvb_dmx_init(&dvb->demux); + if (result < 0) { + printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n", + dev->name, result); + goto fail_dmx; + } + + dvb->dmxdev.filternum = 256; + dvb->dmxdev.demux = &dvb->demux.dmx; + dvb->dmxdev.capabilities = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) + result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); +#else + result = dvb_dmxdev_init(&dvb->dmxdev, dvb->adapter); +#endif + if (result < 0) { + printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", + dev->name, result); + goto fail_dmxdev; + } + + dvb->fe_hw.source = DMX_FRONTEND_0; + result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); + if (result < 0) { + printk(KERN_WARNING "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", + dev->name, result); + goto fail_fe_hw; + } + + dvb->fe_mem.source = DMX_MEMORY_FE; + result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); + if (result < 0) { + printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", + dev->name, result); + goto fail_fe_mem; + } + + result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); + if (result < 0) { + printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n", + dev->name, result); + goto fail_fe_conn; + } + + /* register network adapter */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) + dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); +#else + dvb_net_init(dvb->adapter, &dvb->net, &dvb->demux.dmx); +#endif + return 0; + +fail_fe_conn: + dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); +fail_fe_mem: + dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); +fail_fe_hw: + dvb_dmxdev_release(&dvb->dmxdev); +fail_dmxdev: + dvb_dmx_release(&dvb->demux); +fail_dmx: + dvb_unregister_frontend(dvb->frontend); +fail_frontend: + dvb_frontend_detach(dvb->frontend); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) + dvb_unregister_adapter(&dvb->adapter); +#else + dvb_unregister_adapter(dvb->adapter); +#endif +fail_adapter: + return result; +} + +static void unregister_dvb(struct em28xx_dvb *dvb) +{ + dvb_net_release(&dvb->net); + dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); + dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); + dvb_dmxdev_release(&dvb->dmxdev); + dvb_dmx_release(&dvb->demux); + dvb_unregister_frontend(dvb->frontend); + dvb_frontend_detach(dvb->frontend); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)) + dvb_unregister_adapter(&dvb->adapter); +#else + dvb_unregister_adapter(dvb->adapter); +#endif +} + + +static int dvb_init(struct em28xx *dev) +{ + int result = 0; + struct em28xx_dvb *dvb; + + dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); + + if (dvb == NULL) { + printk(KERN_INFO "em28xx_dvb: memory allocation failed\n"); + return -ENOMEM; + } + dev->dvb = dvb; + + em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); + /* init frontend */ + switch (dev->model) { + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + dvb->frontend = dvb_attach(lgdt330x_attach, + &em2880_lgdt3303_dev, + &dev->i2c_adap); + if (attach_xc3028(0x61, dev) < 0) { + result = -EINVAL; + goto out_free; + } + break; + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: + dvb->frontend = dvb_attach(zl10353_attach, + &em28xx_zl10353_with_xc3028, + &dev->i2c_adap); + if (attach_xc3028(0x61, dev) < 0) { + result = -EINVAL; + goto out_free; + } + break; + default: + printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" + " isn't supported yet\n", + dev->name); + break; + } + if (NULL == dvb->frontend) { + printk(KERN_ERR + "%s/2: frontend initialization failed\n", + dev->name); + result = -EINVAL; + goto out_free; + } + + /* register everything */ + result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); + + if (result < 0) + goto out_free; + + em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); + printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); + return 0; + +out_free: + em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); + kfree(dvb); + dev->dvb = NULL; + return result; +} + +static int dvb_fini(struct em28xx *dev) +{ + if (dev->dvb) { + unregister_dvb(dev->dvb); + dev->dvb = NULL; + } + + return 0; +} + +static struct em28xx_ops dvb_ops = { + .id = EM28XX_DVB, + .name = "Em28xx dvb Extension", + .init = dvb_init, + .fini = dvb_fini, +}; + +static int __init em28xx_dvb_register(void) +{ + return em28xx_register_extension(&dvb_ops); +} + +static void __exit em28xx_dvb_unregister(void) +{ + em28xx_unregister_extension(&dvb_ops); +} + +module_init(em28xx_dvb_register); +module_exit(em28xx_dvb_unregister); diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c index e13743d67..c22e73019 100644 --- a/linux/drivers/media/video/em28xx/em28xx-i2c.c +++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c @@ -41,11 +41,21 @@ static unsigned int i2c_debug; module_param(i2c_debug, int, 0644); MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); -#define dprintk1(lvl,fmt, args...) if (i2c_debug>=lvl) do {\ - printk(fmt, ##args); } while (0) -#define dprintk2(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \ - printk(KERN_DEBUG "%s at %s: " fmt, \ - dev->name, __FUNCTION__ , ##args); } while (0) + +#define dprintk1(lvl, fmt, args...) \ +do { \ + if (i2c_debug >= lvl) { \ + printk(fmt, ##args); \ + } \ +} while (0) + +#define dprintk2(lvl, fmt, args...) \ +do { \ + if (i2c_debug >= lvl) { \ + printk(KERN_DEBUG "%s at %s: " fmt, \ + dev->name, __func__ , ##args); \ + } \ +} while (0) /* * em2800_i2c_send_max4() @@ -235,16 +245,16 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, return 0; for (i = 0; i < num; i++) { addr = msgs[i].addr << 1; - dprintk2(2,"%s %s addr=%x len=%d:", + dprintk2(2, "%s %s addr=%x len=%d:", (msgs[i].flags & I2C_M_RD) ? "read" : "write", i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); - if (!msgs[i].len) { /* no len: check only for device presence */ + if (!msgs[i].len) { /* no len: check only for device presence */ if (dev->is_em2800) rc = em2800_i2c_check_for_device(dev, addr); else rc = em28xx_i2c_check_for_device(dev, addr); if (rc < 0) { - dprintk2(2," no device\n"); + dprintk2(2, " no device\n"); return rc; } @@ -258,14 +268,13 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, rc = em28xx_i2c_recv_bytes(dev, addr, msgs[i].buf, msgs[i].len); - if (i2c_debug>=2) { - for (byte = 0; byte < msgs[i].len; byte++) { + if (i2c_debug >= 2) { + for (byte = 0; byte < msgs[i].len; byte++) printk(" %02x", msgs[i].buf[byte]); - } } } else { /* write bytes */ - if (i2c_debug>=2) { + if (i2c_debug >= 2) { for (byte = 0; byte < msgs[i].len; byte++) printk(" %02x", msgs[i].buf[byte]); } @@ -281,13 +290,13 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, } if (rc < 0) goto err; - if (i2c_debug>=2) + if (i2c_debug >= 2) printk("\n"); } return num; - err: - dprintk2(2," ERROR: %i\n", rc); +err: + dprintk2(2, " ERROR: %i\n", rc); return rc; } @@ -330,7 +339,9 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) return -1; buf = 0; - if (1 != (err = i2c_master_send(&dev->i2c_client, &buf, 1))) { + + err = i2c_master_send(&dev->i2c_client, &buf, 1); + if (err != 1) { printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", dev->name, err); return -1; @@ -403,8 +414,10 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) break; } printk(KERN_INFO "Table at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", - em_eeprom->string_idx_table,em_eeprom->string1, - em_eeprom->string2,em_eeprom->string3); + em_eeprom->string_idx_table, + em_eeprom->string1, + em_eeprom->string2, + em_eeprom->string3); return 0; } @@ -441,58 +454,61 @@ static int attach_inform(struct i2c_client *client) struct em28xx *dev = client->adapter->algo_data; switch (client->addr << 1) { - case 0x86: - case 0x84: - case 0x96: - case 0x94: - { - struct v4l2_priv_tun_config tda9887_cfg; - - struct tuner_setup tun_setup; - - tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; - tun_setup.type = TUNER_TDA9887; - tun_setup.addr = client->addr; - - em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup); - - tda9887_cfg.tuner = TUNER_TDA9887; - tda9887_cfg.priv = &dev->tda9887_conf; - em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG, - &tda9887_cfg); - break; - } - case 0x42: - dprintk1(1,"attach_inform: saa7114 detected.\n"); - break; - case 0x4a: - dprintk1(1,"attach_inform: saa7113 detected.\n"); - break; - case 0xa0: - dprintk1(1,"attach_inform: eeprom detected.\n"); - break; - case 0x60: - case 0x8e: - { - struct IR_i2c *ir = i2c_get_clientdata(client); - dprintk1(1,"attach_inform: IR detected (%s).\n",ir->phys); - em28xx_set_ir(dev,ir); - break; - } - case 0x80: - case 0x88: - dprintk1(1,"attach_inform: msp34xx detected.\n"); - break; - case 0xb8: - case 0xba: - dprintk1(1,"attach_inform: tvp5150 detected.\n"); - break; + case 0x86: + case 0x84: + case 0x96: + case 0x94: + { + struct v4l2_priv_tun_config tda9887_cfg; + + struct tuner_setup tun_setup; + + tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; + tun_setup.type = TUNER_TDA9887; + tun_setup.addr = client->addr; + + em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, + &tun_setup); + + tda9887_cfg.tuner = TUNER_TDA9887; + tda9887_cfg.priv = &dev->tda9887_conf; + em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG, + &tda9887_cfg); + break; + } + case 0x42: + dprintk1(1, "attach_inform: saa7114 detected.\n"); + break; + case 0x4a: + dprintk1(1, "attach_inform: saa7113 detected.\n"); + break; + case 0xa0: + dprintk1(1, "attach_inform: eeprom detected.\n"); + break; + case 0x60: + case 0x8e: + { + struct IR_i2c *ir = i2c_get_clientdata(client); + dprintk1(1, "attach_inform: IR detected (%s).\n", + ir->phys); + em28xx_set_ir(dev, ir); + break; + } + case 0x80: + case 0x88: + dprintk1(1, "attach_inform: msp34xx detected.\n"); + break; + case 0xb8: + case 0xba: + dprintk1(1, "attach_inform: tvp5150 detected.\n"); + break; - default: - if (!dev->tuner_addr) - dev->tuner_addr = client->addr; + default: + if (!dev->tuner_addr) + dev->tuner_addr = client->addr; - dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1); + dprintk1(1, "attach inform: detected I2C address %x\n", + client->addr << 1); } @@ -522,7 +538,7 @@ static struct i2c_adapter em28xx_adap_template = { static struct i2c_client em28xx_client_template = { .name = "em28xx internal", -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 15) .flags = I2C_CLIENT_ALLOW_USE, #endif }; diff --git a/linux/drivers/media/video/em28xx/em28xx-input.c b/linux/drivers/media/video/em28xx/em28xx-input.c index 5c78eceff..49c40f083 100644 --- a/linux/drivers/media/video/em28xx/em28xx-input.c +++ b/linux/drivers/media/video/em28xx/em28xx-input.c @@ -33,10 +33,12 @@ static unsigned int ir_debug; module_param(ir_debug, int, 0644); -MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]"); +MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); -#define dprintk(fmt, arg...) if (ir_debug) \ - printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg) +#define dprintk(fmt, arg...) \ + if (ir_debug) { \ + printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \ + } /* ----------------------------------------------------------------------- */ @@ -45,7 +47,7 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) unsigned char b; /* poll IR chip */ - if (1 != i2c_master_recv(&ir->c,&b,1)) { + if (1 != i2c_master_recv(&ir->c, &b, 1)) { dprintk("read error\n"); return -EIO; } @@ -75,29 +77,30 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) unsigned char code; /* poll IR chip */ - if (2 != i2c_master_recv(&ir->c,buf,2)) + if (2 != i2c_master_recv(&ir->c, buf, 2)) return -EIO; /* Does eliminate repeated parity code */ - if (buf[1]==0xff) + if (buf[1] == 0xff) return 0; #if 0 /* avoid reapeating keystrokes */ - if (buf[1]==ir->old) + if (buf[1] == ir->old) return 0; #endif - ir->old=buf[1]; + ir->old = buf[1]; /* Rearranges bits to the right order */ - code= ((buf[0]&0x01)<<5) | /* 0010 0000 */ + code = ((buf[0]&0x01)<<5) | /* 0010 0000 */ ((buf[0]&0x02)<<3) | /* 0001 0000 */ ((buf[0]&0x04)<<1) | /* 0000 1000 */ ((buf[0]&0x08)>>1) | /* 0000 0100 */ ((buf[0]&0x10)>>3) | /* 0000 0010 */ ((buf[0]&0x20)>>5); /* 0000 0001 */ - dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",code,buf[0]); + dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n", + code, buf[0]); /* return key */ *ir_key = code; @@ -112,15 +115,14 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, /* poll IR chip */ - if (3 != i2c_master_recv(&ir->c,buf,3)) { + if (3 != i2c_master_recv(&ir->c, buf, 3)) { dprintk("read error\n"); return -EIO; } dprintk("key %02x\n", buf[2]&0x3f); - if (buf[0]!=0x00){ + if (buf[0] != 0x00) return 0; - } *ir_key = buf[2]&0x3f; *ir_raw = buf[2]&0x3f; diff --git a/linux/drivers/media/video/em28xx/em28xx-reg.h b/linux/drivers/media/video/em28xx/em28xx-reg.h new file mode 100644 index 000000000..9058bed07 --- /dev/null +++ b/linux/drivers/media/video/em28xx/em28xx-reg.h @@ -0,0 +1,88 @@ +#define EM_GPIO_0 (1 << 0) +#define EM_GPIO_1 (1 << 1) +#define EM_GPIO_2 (1 << 2) +#define EM_GPIO_3 (1 << 3) +#define EM_GPIO_4 (1 << 4) +#define EM_GPIO_5 (1 << 5) +#define EM_GPIO_6 (1 << 6) +#define EM_GPIO_7 (1 << 7) + +#define EM_GPO_0 (1 << 0) +#define EM_GPO_1 (1 << 1) +#define EM_GPO_2 (1 << 2) +#define EM_GPO_3 (1 << 3) + +/* em2800 registers */ +#define EM2800_R08_AUDIOSRC 0x08 + +/* em28xx registers */ + + /* GPIO/GPO registers */ +#define EM2880_R04_GPO 0x04 /* em2880-em2883 only */ +#define EM28XX_R08_GPIO 0x08 /* em2820 or upper */ + +#define EM28XX_R06_I2C_CLK 0x06 +#define EM28XX_R0A_CHIPID 0x0a +#define EM28XX_R0C_USBSUSP 0x0c /* */ + +#define EM28XX_R0E_AUDIOSRC 0x0e +#define EM28XX_R0F_XCLK 0x0f + +#define EM28XX_R10_VINMODE 0x10 +#define EM28XX_R11_VINCTRL 0x11 +#define EM28XX_R12_VINENABLE 0x12 /* */ + +#define EM28XX_R14_GAMMA 0x14 +#define EM28XX_R15_RGAIN 0x15 +#define EM28XX_R16_GGAIN 0x16 +#define EM28XX_R17_BGAIN 0x17 +#define EM28XX_R18_ROFFSET 0x18 +#define EM28XX_R19_GOFFSET 0x19 +#define EM28XX_R1A_BOFFSET 0x1a + +#define EM28XX_R1B_OFLOW 0x1b +#define EM28XX_R1C_HSTART 0x1c +#define EM28XX_R1D_VSTART 0x1d +#define EM28XX_R1E_CWIDTH 0x1e +#define EM28XX_R1F_CHEIGHT 0x1f + +#define EM28XX_R20_YGAIN 0x20 +#define EM28XX_R21_YOFFSET 0x21 +#define EM28XX_R22_UVGAIN 0x22 +#define EM28XX_R23_UOFFSET 0x23 +#define EM28XX_R24_VOFFSET 0x24 +#define EM28XX_R25_SHARPNESS 0x25 + +#define EM28XX_R26_COMPR 0x26 +#define EM28XX_R27_OUTFMT 0x27 + +#define EM28XX_R28_XMIN 0x28 +#define EM28XX_R29_XMAX 0x29 +#define EM28XX_R2A_YMIN 0x2a +#define EM28XX_R2B_YMAX 0x2b + +#define EM28XX_R30_HSCALELOW 0x30 +#define EM28XX_R31_HSCALEHIGH 0x31 +#define EM28XX_R32_VSCALELOW 0x32 +#define EM28XX_R33_VSCALEHIGH 0x33 + +#define EM28XX_R40_AC97LSB 0x40 +#define EM28XX_R41_AC97MSB 0x41 +#define EM28XX_R42_AC97ADDR 0x42 +#define EM28XX_R43_AC97BUSY 0x43 + +/* em202 registers */ +#define EM28XX_R02_MASTER_AC97 0x02 +#define EM28XX_R10_LINE_IN_AC97 0x10 +#define EM28XX_R14_VIDEO_AC97 0x14 + +/* register settings */ +#define EM2800_AUDIO_SRC_TUNER 0x0d +#define EM2800_AUDIO_SRC_LINE 0x0c +#define EM28XX_AUDIO_SRC_TUNER 0xc0 +#define EM28XX_AUDIO_SRC_LINE 0x80 + +/* FIXME: Need to be populated with the other chip ID's */ +enum em28xx_chip_id { + CHIP_ID_EM2883 = 36, +}; diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c index 4999897ed..093fef4bb 100644 --- a/linux/drivers/media/video/em28xx/em28xx-video.c +++ b/linux/drivers/media/video/em28xx/em28xx-video.c @@ -1,5 +1,6 @@ /* - em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB video capture devices + em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB + video capture devices Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> Markus Rechberger <mrechberger@gmail.com> @@ -33,7 +34,7 @@ #include <linux/i2c.h> #include <linux/version.h> #include <linux/mm.h> -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 15) #include <linux/mutex.h> #endif @@ -41,7 +42,7 @@ #include <media/v4l2-common.h> #include <media/msp3400.h> #include <media/tuner.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) #include "i2c-compat.h" #endif @@ -57,7 +58,19 @@ #define em28xx_videodbg(fmt, arg...) do {\ if (video_debug) \ printk(KERN_INFO "%s %s :"fmt, \ - dev->name, __FUNCTION__ , ##arg); } while (0) + dev->name, __func__ , ##arg); } while (0) + +static unsigned int isoc_debug; +module_param(isoc_debug, int, 0644); +MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]"); + +#define em28xx_isocdbg(fmt, arg...) \ +do {\ + if (isoc_debug) { \ + printk(KERN_INFO "%s %s :"fmt, \ + dev->name, __func__ , ##arg); \ + } \ + } while (0) MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); @@ -70,13 +83,13 @@ static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) MODULE_PARM(card, "1-" __stringify(EM28XX_MAXBOARDS) "i"); MODULE_PARM(video_nr, "1-" __stringify(EM28XX_MAXBOARDS) "i"); MODULE_PARM(vbi_nr, "1-" __stringify(EM28XX_MAXBOARDS) "i"); MODULE_PARM(radio_nr, "1-" __stringify(EM28XX_MAXBOARDS) "i"); #else -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) static int dummy; module_param_array(card, int, dummy, 0444); module_param_array(video_nr, int, dummy, 0444); @@ -95,8 +108,8 @@ MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); MODULE_PARM_DESC(radio_nr, "radio device numbers"); static unsigned int video_debug; -module_param(video_debug,int,0644); -MODULE_PARM_DESC(video_debug,"enable debug messages [video]"); +module_param(video_debug, int, 0644); +MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ static unsigned long em28xx_devused; @@ -113,7 +126,7 @@ static struct v4l2_queryctrl em28xx_qctrl[] = { .step = 0x1, .default_value = 0x1f, .flags = 0, - },{ + }, { .id = V4L2_CID_AUDIO_MUTE, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Mute", @@ -127,8 +140,395 @@ static struct v4l2_queryctrl em28xx_qctrl[] = { static struct usb_driver em28xx_usb_driver; +/* ------------------------------------------------------------------ + DMA and thread functions + ------------------------------------------------------------------*/ + +/* + * Announces that a buffer were filled and request the next + */ +static inline void buffer_filled(struct em28xx *dev, + struct em28xx_dmaqueue *dma_q, + struct em28xx_buffer *buf) +{ + /* Advice that buffer was filled */ + em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i); + buf->vb.state = VIDEOBUF_DONE; + buf->vb.field_count++; + do_gettimeofday(&buf->vb.ts); + + dev->isoc_ctl.buf = NULL; + + list_del(&buf->vb.queue); + wake_up(&buf->vb.done); +} + +/* + * Identify the buffer header type and properly handles + */ +static void em28xx_copy_video(struct em28xx *dev, + struct em28xx_dmaqueue *dma_q, + struct em28xx_buffer *buf, + unsigned char *p, + unsigned char *outp, unsigned long len) +{ + void *fieldstart, *startwrite, *startread; + int linesdone, currlinedone, offset, lencopy, remain; + int bytesperline = dev->width << 1; + + if (dma_q->pos + len > buf->vb.size) + len = buf->vb.size - dma_q->pos; + + if (p[0] != 0x88 && p[0] != 0x22) { + em28xx_isocdbg("frame is not complete\n"); + len += 4; + } else + p += 4; + + startread = p; + remain = len; + + /* Interlaces frame */ + if (buf->top_field) + fieldstart = outp; + else + fieldstart = outp + bytesperline; + + linesdone = dma_q->pos / bytesperline; + currlinedone = dma_q->pos % bytesperline; + offset = linesdone * bytesperline * 2 + currlinedone; + startwrite = fieldstart + offset; + lencopy = bytesperline - currlinedone; + lencopy = lencopy > remain ? remain : lencopy; + + if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) { + em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n", + ((char *)startwrite + lencopy) - + ((char *)outp + buf->vb.size)); + lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite; + } + if (lencopy <= 0) + return; + memcpy(startwrite, startread, lencopy); + + remain -= lencopy; + + while (remain > 0) { + startwrite += lencopy + bytesperline; + startread += lencopy; + if (bytesperline > remain) + lencopy = remain; + else + lencopy = bytesperline; + + if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) { + em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n", + ((char *)startwrite + lencopy) - + ((char *)outp + buf->vb.size)); + lencopy = remain = (char *)outp + buf->vb.size - + (char *)startwrite; + } + if (lencopy <= 0) + break; + + memcpy(startwrite, startread, lencopy); + + remain -= lencopy; + } + + dma_q->pos += len; +} + +static inline void print_err_status(struct em28xx *dev, + int packet, int status) +{ + char *errmsg = "Unknown"; + + switch (status) { + case -ENOENT: + errmsg = "unlinked synchronuously"; + break; + case -ECONNRESET: + errmsg = "unlinked asynchronuously"; + break; + case -ENOSR: + errmsg = "Buffer error (overrun)"; + break; + case -EPIPE: + errmsg = "Stalled (device not responding)"; + break; + case -EOVERFLOW: + errmsg = "Babble (bad cable?)"; + break; + case -EPROTO: + errmsg = "Bit-stuff error (bad cable?)"; + break; + case -EILSEQ: + errmsg = "CRC/Timeout (could be anything)"; + break; + case -ETIME: + errmsg = "Device does not respond"; + break; + } + if (packet < 0) { + em28xx_isocdbg("URB status %d [%s].\n", status, errmsg); + } else { + em28xx_isocdbg("URB packet %d, status %d [%s].\n", + packet, status, errmsg); + } +} -/********************* v4l2 interface ******************************************/ +/* + * video-buf generic routine to get the next available buffer + */ +static inline void get_next_buf(struct em28xx_dmaqueue *dma_q, + struct em28xx_buffer **buf) +{ + struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); +#if 1 + char *outp; +#endif + + if (list_empty(&dma_q->active)) { + em28xx_isocdbg("No active queue to serve\n"); + dev->isoc_ctl.buf = NULL; + *buf = NULL; + return; + } + + /* Get the next buffer */ + *buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue); + +#if 1 + /* Cleans up buffer - Usefull for testing for frame/URB loss */ + outp = videobuf_to_vmalloc(&(*buf)->vb); + memset(outp, 0, (*buf)->vb.size); +#endif + + dev->isoc_ctl.buf = *buf; + + return; +} + +/* + * Controls the isoc copy of each urb packet + */ +static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb) +{ + struct em28xx_buffer *buf; + struct em28xx_dmaqueue *dma_q = urb->context; + unsigned char *outp = NULL; + int i, len = 0, rc = 1; + unsigned char *p; + + if (!dev) + return 0; + + if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) + return 0; + + if (urb->status < 0) { + print_err_status(dev, -1, urb->status); + if (urb->status == -ENOENT) + return 0; + } + + buf = dev->isoc_ctl.buf; + if (buf != NULL) + outp = videobuf_to_vmalloc(&buf->vb); + + for (i = 0; i < urb->number_of_packets; i++) { + int status = urb->iso_frame_desc[i].status; + + if (status < 0) { + print_err_status(dev, i, status); + if (urb->iso_frame_desc[i].status != -EPROTO) + continue; + } + + len = urb->iso_frame_desc[i].actual_length - 4; + + if (urb->iso_frame_desc[i].actual_length <= 0) { + /* em28xx_isocdbg("packet %d is empty",i); - spammy */ + continue; + } + if (urb->iso_frame_desc[i].actual_length > + dev->max_pkt_size) { + em28xx_isocdbg("packet bigger than packet size"); + continue; + } + + p = urb->transfer_buffer + urb->iso_frame_desc[i].offset; + + /* FIXME: incomplete buffer checks where removed to make + logic simpler. Impacts of those changes should be evaluated + */ + if (p[0] == 0x33 && p[1] == 0x95 && p[2] == 0x00) { + em28xx_isocdbg("VBI HEADER!!!\n"); + /* FIXME: Should add vbi copy */ + continue; + } + if (p[0] == 0x22 && p[1] == 0x5a) { + em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2], + len, (p[2] & 1)? "odd" : "even"); + + if (!(p[2] & 1)) { + if (buf != NULL) + buffer_filled(dev, dma_q, buf); + get_next_buf(dma_q, &buf); + if (buf == NULL) + outp = NULL; + else + outp = videobuf_to_vmalloc(&buf->vb); + } + + if (buf != NULL) { + if (p[2] & 1) + buf->top_field = 0; + else + buf->top_field = 1; + } + + dma_q->pos = 0; + } + if (buf != NULL) + em28xx_copy_video(dev, dma_q, buf, p, outp, len); + } + return rc; +} + +/* ------------------------------------------------------------------ + Videobuf operations + ------------------------------------------------------------------*/ + +static int +buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) +{ + struct em28xx_fh *fh = vq->priv_data; + struct em28xx *dev = fh->dev; + struct v4l2_frequency f; + + *size = 16 * fh->dev->width * fh->dev->height >> 3; + if (0 == *count) + *count = EM28XX_DEF_BUF; + + if (*count < EM28XX_MIN_BUF) + *count = EM28XX_MIN_BUF; + + /* Ask tuner to go to analog mode */ + memset(&f, 0, sizeof(f)); + f.frequency = dev->ctl_freq; + + em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f); + + return 0; +} + +/* This is called *without* dev->slock held; please keep it that way */ +static void free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf) +{ + struct em28xx_fh *fh = vq->priv_data; + struct em28xx *dev = fh->dev; + unsigned long flags = 0; + if (in_interrupt()) + BUG(); + + /* We used to wait for the buffer to finish here, but this didn't work + because, as we were keeping the state as VIDEOBUF_QUEUED, + videobuf_queue_cancel marked it as finished for us. + (Also, it could wedge forever if the hardware was misconfigured.) + + This should be safe; by the time we get here, the buffer isn't + queued anymore. If we ever start marking the buffers as + VIDEOBUF_ACTIVE, it won't be, though. + */ + spin_lock_irqsave(&dev->slock, flags); + if (dev->isoc_ctl.buf == buf) + dev->isoc_ctl.buf = NULL; + spin_unlock_irqrestore(&dev->slock, flags); + + videobuf_vmalloc_free(&buf->vb); + buf->vb.state = VIDEOBUF_NEEDS_INIT; +} + +static int +buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, + enum v4l2_field field) +{ + struct em28xx_fh *fh = vq->priv_data; + struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); + struct em28xx *dev = fh->dev; + int rc = 0, urb_init = 0; + + /* FIXME: It assumes depth = 16 */ + /* The only currently supported format is 16 bits/pixel */ + buf->vb.size = 16 * dev->width * dev->height >> 3; + + if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) + return -EINVAL; + + buf->vb.width = dev->width; + buf->vb.height = dev->height; + buf->vb.field = field; + + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { + rc = videobuf_iolock(vq, &buf->vb, NULL); + if (rc < 0) + goto fail; + } + + if (!dev->isoc_ctl.num_bufs) + urb_init = 1; + + if (urb_init) { + rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS, + EM28XX_NUM_BUFS, dev->max_pkt_size, + em28xx_isoc_copy); + if (rc < 0) + goto fail; + } + + buf->vb.state = VIDEOBUF_PREPARED; + return 0; + +fail: + free_buffer(vq, buf); + return rc; +} + +static void +buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) +{ + struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); + struct em28xx_fh *fh = vq->priv_data; + struct em28xx *dev = fh->dev; + struct em28xx_dmaqueue *vidq = &dev->vidq; + + buf->vb.state = VIDEOBUF_QUEUED; + list_add_tail(&buf->vb.queue, &vidq->active); + +} + +static void buffer_release(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); + struct em28xx_fh *fh = vq->priv_data; + struct em28xx *dev = (struct em28xx *)fh->dev; + + em28xx_isocdbg("em28xx: called buffer_release\n"); + + free_buffer(vq, buf); +} + +static struct videobuf_queue_ops em28xx_video_qops = { + .buf_setup = buffer_setup, + .buf_prepare = buffer_prepare, + .buf_queue = buffer_queue, + .buf_release = buffer_release, +}; + +/********************* v4l2 interface **************************************/ /* * em28xx_config() @@ -144,9 +544,9 @@ static int em28xx_config(struct em28xx *dev) #if 1 /* enable vbi capturing */ -/* em28xx_write_regs_req(dev,0x00,0x0e,"\xC0",1); audio register */ -/* em28xx_write_regs_req(dev,0x00,0x0f,"\x80",1); clk register */ - em28xx_write_regs_req(dev,0x00,0x11,"\x51",1); +/* em28xx_write_regs_req(dev, 0x00, 0x0e, "\xC0", 1); audio register */ +/* em28xx_write_regs_req(dev, 0x00, 0x0f, "\x80", 1); clk register */ + em28xx_write_regs_req(dev, 0x00, 0x11, "\x51", 1); #endif dev->mute = 1; /* maybe not the right place... */ @@ -174,23 +574,6 @@ static void em28xx_config_i2c(struct em28xx *dev) em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); } -/* - * em28xx_empty_framequeues() - * prepare queues for incoming and outgoing frames - */ -static void em28xx_empty_framequeues(struct em28xx *dev) -{ - u32 i; - - INIT_LIST_HEAD(&dev->inqueue); - INIT_LIST_HEAD(&dev->outqueue); - - for (i = 0; i < EM28XX_NUM_FRAMES; i++) { - dev->frame[i].state = F_UNUSED; - dev->frame[i].buf.bytesused = 0; - } -} - static void video_mux(struct em28xx *dev, int index) { struct v4l2_routing route; @@ -203,12 +586,15 @@ static void video_mux(struct em28xx *dev, int index) em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); if (dev->has_msp34xx) { - if (dev->i2s_speed) - em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed); + if (dev->i2s_speed) { + em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, + &dev->i2s_speed); + } route.input = dev->ctl_ainput; route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); /* Note: this is msp3400 specific */ - em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, &route); + em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING, + &route); } em28xx_audio_analog_set(dev); @@ -224,15 +610,12 @@ static int res_get(struct em28xx_fh *fh) if (fh->stream_on) return rc; - mutex_lock(&dev->lock); - if (dev->stream_on) - rc = -EINVAL; - else { - dev->stream_on = 1; - fh->stream_on = 1; - } + return -EINVAL; + mutex_lock(&dev->lock); + dev->stream_on = 1; + fh->stream_on = 1; mutex_unlock(&dev->lock); return rc; } @@ -253,33 +636,6 @@ static void res_free(struct em28xx_fh *fh) } /* - * em28xx_vm_open() - */ -static void em28xx_vm_open(struct vm_area_struct *vma) -{ - struct em28xx_frame_t *f = vma->vm_private_data; - f->vma_use_count++; -} - -/* - * em28xx_vm_close() - */ -static void em28xx_vm_close(struct vm_area_struct *vma) -{ - /* NOTE: buffers are not freed here */ - struct em28xx_frame_t *f = vma->vm_private_data; - - if (f->vma_use_count) - f->vma_use_count--; -} - -static struct vm_operations_struct em28xx_vm_ops = { - .open = em28xx_vm_open, - .close = em28xx_vm_close, -}; - - -/* * em28xx_get_ctrl() * return the current saturation, brightness or contrast, mute state */ @@ -318,34 +674,6 @@ static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) } } -/* - * em28xx_stream_interrupt() - * stops streaming - */ -static int em28xx_stream_interrupt(struct em28xx *dev) -{ - int rc = 0; - - /* stop reading from the device */ - - dev->stream = STREAM_INTERRUPT; - rc = wait_event_timeout(dev->wait_stream, - (dev->stream == STREAM_OFF) || - (dev->state & DEV_DISCONNECTED), - EM28XX_URB_TIMEOUT); - - if (rc) { - dev->state |= DEV_MISCONFIGURED; - em28xx_videodbg("device is misconfigured; close and " - "open /dev/video%d again\n", - dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN); - return rc; - } - - return 0; -} - - static int check_dev(struct em28xx *dev) { if (dev->state & DEV_DISCONNECTED) { @@ -392,8 +720,8 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv, f->fmt.pix.width = dev->width; f->fmt.pix.height = dev->height; f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; - f->fmt.pix.bytesperline = dev->bytesperline; - f->fmt.pix.sizeimage = dev->frame_size; + f->fmt.pix.bytesperline = dev->width * 2; + f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ @@ -469,7 +797,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - int rc, i; + int rc; rc = check_dev(dev); if (rc < 0) @@ -479,49 +807,34 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, mutex_lock(&dev->lock); - for (i = 0; i < dev->num_frames; i++) - if (dev->frame[i].vma_use_count) { - em28xx_videodbg("VIDIOC_S_FMT failed. " - "Unmap the buffers first.\n"); - rc = -EINVAL; - goto err; - } - - /* stop io in case it is already in progress */ - if (dev->stream == STREAM_ON) { - em28xx_videodbg("VIDIOC_SET_FMT: interrupting stream\n"); - rc = em28xx_stream_interrupt(dev); - if (rc < 0) - goto err; + if (videobuf_queue_is_busy(&fh->vb_vidq)) { + em28xx_errdev("%s queue busy\n", __func__); + rc = -EBUSY; + goto out; } - em28xx_release_buffers(dev); - dev->io = IO_NONE; + if (dev->stream_on && !fh->stream_on) { + em28xx_errdev("%s device in use by another fh\n", __func__); + rc = -EBUSY; + goto out; + } /* set new image size */ dev->width = f->fmt.pix.width; dev->height = f->fmt.pix.height; - dev->frame_size = dev->width * dev->height * 2; - dev->field_size = dev->frame_size >> 1; - dev->bytesperline = dev->width * 2; get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); - /* FIXME: This is really weird! Why capture is starting with - this ioctl ??? - */ - em28xx_uninit_isoc(dev); em28xx_set_alternate(dev); - em28xx_capture_start(dev, 1); em28xx_resolution_set(dev); - em28xx_init_isoc(dev); + rc = 0; -err: +out: mutex_unlock(&dev->lock); return rc; } -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm) { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; @@ -546,9 +859,6 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) /* set new image size */ dev->width = f.fmt.pix.width; dev->height = f.fmt.pix.height; - dev->frame_size = dev->width * dev->height * 2; - dev->field_size = dev->frame_size >> 1; - dev->bytesperline = dev->width * 2; get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); em28xx_resolution_set(dev); @@ -641,11 +951,11 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) index = dev->ctl_ainput; - if (index == 0) { + if (index == 0) strcpy(a->name, "Television"); - } else { + else strcpy(a->name, "Line In"); - } + a->capability = V4L2_AUDCAP_STEREO; a->index = index; @@ -856,9 +1166,9 @@ static int vidioc_s_frequency(struct file *file, void *priv, static int em28xx_reg_len(int reg) { switch (reg) { - case AC97LSB_REG: - case HSCALELOW_REG: - case VSCALELOW_REG: + case EM28XX_R40_AC97LSB: + case EM28XX_R30_HSCALELOW: + case EM28XX_R32_VSCALELOW: return 2; default: return 1; @@ -940,23 +1250,11 @@ static int vidioc_streamon(struct file *file, void *priv, if (rc < 0) return rc; - if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || dev->io != IO_MMAP) - return -EINVAL; - - if (list_empty(&dev->inqueue)) - return -EINVAL; - - mutex_lock(&dev->lock); - if (unlikely(res_get(fh) < 0)) { - mutex_unlock(&dev->lock); + if (unlikely(res_get(fh) < 0)) return -EBUSY; - } - dev->stream = STREAM_ON; /* FIXME: Start video capture here? */ - - mutex_unlock(&dev->lock); - return 0; + return (videobuf_streamon(&fh->vb_vidq)); } static int vidioc_streamoff(struct file *file, void *priv, @@ -970,23 +1268,14 @@ static int vidioc_streamoff(struct file *file, void *priv, if (rc < 0) return rc; - if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || dev->io != IO_MMAP) + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (type != fh->type) return -EINVAL; - mutex_lock(&dev->lock); - - if (dev->stream == STREAM_ON) { - em28xx_videodbg("VIDIOC_STREAMOFF: interrupting stream\n"); - rc = em28xx_stream_interrupt(dev); - if (rc < 0) { - mutex_unlock(&dev->lock); - return rc; - } - } - - em28xx_empty_framequeues(dev); + videobuf_streamoff(&fh->vb_vidq); + res_free(fh); - mutex_unlock(&dev->lock); return 0; } @@ -1117,53 +1406,13 @@ static int vidioc_reqbufs(struct file *file, void *priv, { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - u32 i; int rc; rc = check_dev(dev); if (rc < 0) return rc; - if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - rb->memory != V4L2_MEMORY_MMAP) - return -EINVAL; - - if (dev->io == IO_READ) { - em28xx_videodbg("method is set to read;" - " close and open the device again to" - " choose the mmap I/O method\n"); - return -EINVAL; - } - - for (i = 0; i < dev->num_frames; i++) - if (dev->frame[i].vma_use_count) { - em28xx_videodbg("VIDIOC_REQBUFS failed; " - "previous buffers are still mapped\n"); - return -EINVAL; - } - - mutex_lock(&dev->lock); - - if (dev->stream == STREAM_ON) { - em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n"); - rc = em28xx_stream_interrupt(dev); - if (rc < 0) { - mutex_unlock(&dev->lock); - return rc; - } - } - - em28xx_empty_framequeues(dev); - - em28xx_release_buffers(dev); - if (rb->count) - rb->count = em28xx_request_buffers(dev, rb->count); - - dev->frame_current = NULL; - dev->io = rb->count ? IO_MMAP : IO_NONE; - - mutex_unlock(&dev->lock); - return 0; + return (videobuf_reqbufs(&fh->vb_vidq, rb)); } static int vidioc_querybuf(struct file *file, void *priv, @@ -1177,52 +1426,20 @@ static int vidioc_querybuf(struct file *file, void *priv, if (rc < 0) return rc; - if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - b->index >= dev->num_frames || dev->io != IO_MMAP) - return -EINVAL; - - mutex_lock(&dev->lock); - - memcpy(b, &dev->frame[b->index].buf, sizeof(*b)); - - if (dev->frame[b->index].vma_use_count) - b->flags |= V4L2_BUF_FLAG_MAPPED; - - if (dev->frame[b->index].state == F_DONE) - b->flags |= V4L2_BUF_FLAG_DONE; - else if (dev->frame[b->index].state != F_UNUSED) - b->flags |= V4L2_BUF_FLAG_QUEUED; - - mutex_unlock(&dev->lock); - return 0; + return (videobuf_querybuf(&fh->vb_vidq, b)); } static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - unsigned long lock_flags; int rc; rc = check_dev(dev); if (rc < 0) return rc; - if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || dev->io != IO_MMAP || - b->index >= dev->num_frames) - return -EINVAL; - - if (dev->frame[b->index].state != F_UNUSED) - return -EAGAIN; - - dev->frame[b->index].state = F_QUEUED; - - /* add frame to fifo */ - spin_lock_irqsave(&dev->queue_lock, lock_flags); - list_add_tail(&dev->frame[b->index].frame, &dev->inqueue); - spin_unlock_irqrestore(&dev->queue_lock, lock_flags); - - return 0; + return (videobuf_qbuf(&fh->vb_vidq, b)); } static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) @@ -1230,46 +1447,24 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; int rc; - struct em28xx_frame_t *f; - unsigned long lock_flags; rc = check_dev(dev); if (rc < 0) return rc; - if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || dev->io != IO_MMAP) - return -EINVAL; - - if (list_empty(&dev->outqueue)) { - if (dev->stream == STREAM_OFF) - return -EINVAL; - - if (file->f_flags & O_NONBLOCK) - return -EAGAIN; - - rc = wait_event_interruptible(dev->wait_frame, - (!list_empty(&dev->outqueue)) || - (dev->state & DEV_DISCONNECTED)); - if (rc) - return rc; - - if (dev->state & DEV_DISCONNECTED) - return -ENODEV; - } - - spin_lock_irqsave(&dev->queue_lock, lock_flags); - f = list_entry(dev->outqueue.next, struct em28xx_frame_t, frame); - list_del(dev->outqueue.next); - spin_unlock_irqrestore(&dev->queue_lock, lock_flags); - - f->state = F_UNUSED; - memcpy(b, &f->buf, sizeof(*b)); + return (videobuf_dqbuf(&fh->vb_vidq, b, + file->f_flags & O_NONBLOCK)); +} - if (f->vma_use_count) - b->flags |= V4L2_BUF_FLAG_MAPPED; +#ifdef CONFIG_VIDEO_V4L1_COMPAT +static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) +{ + struct em28xx_fh *fh = priv; - return 0; + return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); } +#endif + /* ----------------------------------------------------------- */ /* RADIO ESPECIFIC IOCTLS */ @@ -1375,17 +1570,18 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) { int minor = iminor(inode); int errCode = 0, radio = 0; - struct em28xx *h,*dev = NULL; + struct em28xx *h, *dev = NULL; struct em28xx_fh *fh; + enum v4l2_buf_type fh_type = 0; list_for_each_entry(h, &em28xx_devlist, devlist) { if (h->vdev->minor == minor) { dev = h; - dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; } if (h->vbi_dev->minor == minor) { dev = h; - dev->type = V4L2_BUF_TYPE_VBI_CAPTURE; + fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; } if (h->radio_dev && h->radio_dev->minor == minor) { @@ -1397,10 +1593,17 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) return -ENODEV; em28xx_videodbg("open minor=%d type=%s users=%d\n", - minor,v4l2_type_names[dev->type],dev->users); + minor, v4l2_type_names[fh_type], dev->users); - fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); +#if 0 + errCode = em28xx_set_mode(dev, EM28XX_ANALOG_MODE); + if (errCode < 0) { + em28xx_errdev("Device locked on digital mode. Can't open analog\n"); + return -EBUSY; + } +#endif + fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); if (!fh) { em28xx_errdev("em28xx-video.c: Out of memory?!\n"); return -ENOMEM; @@ -1408,32 +1611,28 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) mutex_lock(&dev->lock); fh->dev = dev; fh->radio = radio; + fh->type = fh_type; filp->private_data = fh; - if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { dev->width = norm_maxw(dev); dev->height = norm_maxh(dev); - dev->frame_size = dev->width * dev->height * 2; - dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */ - dev->bytesperline = dev->width * 2; dev->hscale = 0; dev->vscale = 0; + em28xx_set_mode(dev, EM28XX_ANALOG_MODE); em28xx_set_alternate(dev); - em28xx_capture_start(dev, 1); em28xx_resolution_set(dev); + /* Needed, since GPIO might have disabled power of + some i2c device + */ + em28xx_config_i2c(dev); + #if 0 /* device needs to be initialized before isoc transfer */ video_mux(dev, 0); #endif - - /* start the transfer */ - errCode = em28xx_init_isoc(dev); - if (errCode) - goto err; - - em28xx_empty_framequeues(dev); } if (fh->radio) { em28xx_videodbg("video_open: setting radio device\n"); @@ -1445,8 +1644,12 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) dev->users++; -err: + videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops, + NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED, + sizeof(struct em28xx_buffer), fh); + mutex_unlock(&dev->lock); + return errCode; } @@ -1489,12 +1692,13 @@ static void em28xx_release_resources(struct em28xx *dev) usb_put_dev(dev->udev); /* Mark device as unused */ - em28xx_devused&=~(1<<dev->devno); + em28xx_devused &= ~(1<<dev->devno); } /* * em28xx_v4l2_close() - * stops streaming and deallocates all resources allocated by the v4l2 calls and ioctls + * stops streaming and deallocates all resources allocated by the v4l2 + * calls and ioctls */ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) { @@ -1511,9 +1715,8 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) mutex_lock(&dev->lock); if (dev->users == 1) { - em28xx_uninit_isoc(dev); - em28xx_release_buffers(dev); - dev->io = IO_NONE; + videobuf_stop(&fh->vb_vidq); + videobuf_mmap_free(&fh->vb_vidq); /* the device is already disconnect, free the remaining resources */ @@ -1524,6 +1727,10 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) return 0; } + /* do this before setting alternate! */ + em28xx_uninit_isoc(dev); + em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); + /* set alternate 0 */ dev->alt = 0; em28xx_videodbg("setting alternate 0\n"); @@ -1545,135 +1752,29 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) * will allocate buffers when called for the first time */ static ssize_t -em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count, - loff_t * f_pos) +em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count, + loff_t *pos) { - struct em28xx_frame_t *f, *i; - unsigned long lock_flags; - int ret = 0; struct em28xx_fh *fh = filp->private_data; struct em28xx *dev = fh->dev; + int rc; + + rc = check_dev(dev); + if (rc < 0) + return rc; /* FIXME: read() is not prepared to allow changing the video resolution while streaming. Seems a bug at em28xx_set_fmt */ - if (unlikely(res_get(fh) < 0)) - return -EBUSY; + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + if (unlikely(res_get(fh))) + return -EBUSY; - mutex_lock(&dev->lock); - - if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - em28xx_videodbg("V4l2_Buf_type_videocapture is set\n"); - - if (dev->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - em28xx_videodbg("V4L2_BUF_TYPE_VBI_CAPTURE is set\n"); - em28xx_videodbg("not supported yet! ...\n"); - if (copy_to_user(buf, "", 1)) { - mutex_unlock(&dev->lock); - return -EFAULT; - } - mutex_unlock(&dev->lock); - return (1); + return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, + filp->f_flags & O_NONBLOCK); } - if (dev->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { - em28xx_videodbg("V4L2_BUF_TYPE_SLICED_VBI_CAPTURE is set\n"); - em28xx_videodbg("not supported yet! ...\n"); - if (copy_to_user(buf, "", 1)) { - mutex_unlock(&dev->lock); - return -EFAULT; - } - mutex_unlock(&dev->lock); - return (1); - } - - if (dev->state & DEV_DISCONNECTED) { - em28xx_videodbg("device not present\n"); - mutex_unlock(&dev->lock); - return -ENODEV; - } - - if (dev->state & DEV_MISCONFIGURED) { - em28xx_videodbg("device misconfigured; close and open it again\n"); - mutex_unlock(&dev->lock); - return -EIO; - } - - if (dev->io == IO_MMAP) { - em28xx_videodbg ("IO method is set to mmap; close and open" - " the device again to choose the read method\n"); - mutex_unlock(&dev->lock); - return -EINVAL; - } - - if (dev->io == IO_NONE) { - if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) { - em28xx_errdev("read failed, not enough memory\n"); - mutex_unlock(&dev->lock); - return -ENOMEM; - } - dev->io = IO_READ; - dev->stream = STREAM_ON; - em28xx_queue_unusedframes(dev); - } - - if (!count) { - mutex_unlock(&dev->lock); - return 0; - } - - if (list_empty(&dev->outqueue)) { - if (filp->f_flags & O_NONBLOCK) { - mutex_unlock(&dev->lock); - return -EAGAIN; - } - ret = wait_event_interruptible - (dev->wait_frame, - (!list_empty(&dev->outqueue)) || - (dev->state & DEV_DISCONNECTED)); - if (ret) { - mutex_unlock(&dev->lock); - return ret; - } - if (dev->state & DEV_DISCONNECTED) { - mutex_unlock(&dev->lock); - return -ENODEV; - } - dev->video_bytesread = 0; - } - - f = list_entry(dev->outqueue.prev, struct em28xx_frame_t, frame); - - em28xx_queue_unusedframes(dev); - - if (count > f->buf.length) - count = f->buf.length; - - if ((dev->video_bytesread + count) > dev->frame_size) - count = dev->frame_size - dev->video_bytesread; - - if (copy_to_user(buf, f->bufmem+dev->video_bytesread, count)) { - em28xx_err("Error while copying to user\n"); - return -EFAULT; - } - dev->video_bytesread += count; - - if (dev->video_bytesread == dev->frame_size) { - spin_lock_irqsave(&dev->queue_lock, lock_flags); - list_for_each_entry(i, &dev->outqueue, frame) - i->state = F_UNUSED; - INIT_LIST_HEAD(&dev->outqueue); - spin_unlock_irqrestore(&dev->queue_lock, lock_flags); - - em28xx_queue_unusedframes(dev); - dev->video_bytesread = 0; - } - - *f_pos += count; - - mutex_unlock(&dev->lock); - - return count; + return 0; } /* @@ -1682,46 +1783,21 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count, */ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait) { - unsigned int mask = 0; struct em28xx_fh *fh = filp->private_data; struct em28xx *dev = fh->dev; + int rc; + + rc = check_dev(dev); + if (rc < 0) + return rc; if (unlikely(res_get(fh) < 0)) return POLLERR; - mutex_lock(&dev->lock); - - if (dev->state & DEV_DISCONNECTED) { - em28xx_videodbg("device not present\n"); - } else if (dev->state & DEV_MISCONFIGURED) { - em28xx_videodbg("device is misconfigured; close and open it again\n"); - } else { - if (dev->io == IO_NONE) { - if (!em28xx_request_buffers - (dev, EM28XX_NUM_READ_FRAMES)) { - em28xx_warn - ("poll() failed, not enough memory\n"); - } else { - dev->io = IO_READ; - dev->stream = STREAM_ON; - } - } - - if (dev->io == IO_READ) { - em28xx_queue_unusedframes(dev); - poll_wait(filp, &dev->wait_frame, wait); - - if (!list_empty(&dev->outqueue)) - mask |= POLLIN | POLLRDNORM; - - mutex_unlock(&dev->lock); - - return mask; - } - } + if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) + return POLLERR; - mutex_unlock(&dev->lock); - return POLLERR; + return videobuf_poll_stream(filp, &fh->vb_vidq, wait); } /* @@ -1731,69 +1807,23 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) { struct em28xx_fh *fh = filp->private_data; struct em28xx *dev = fh->dev; - unsigned long size = vma->vm_end - vma->vm_start; - unsigned long start = vma->vm_start; - void *pos; - u32 i; + int rc; if (unlikely(res_get(fh) < 0)) return -EBUSY; - mutex_lock(&dev->lock); - - if (dev->state & DEV_DISCONNECTED) { - em28xx_videodbg("mmap: device not present\n"); - mutex_unlock(&dev->lock); - return -ENODEV; - } - - if (dev->state & DEV_MISCONFIGURED) { - em28xx_videodbg ("mmap: Device is misconfigured; close and " - "open it again\n"); - mutex_unlock(&dev->lock); - return -EIO; - } - - if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE)) { - mutex_unlock(&dev->lock); - return -EINVAL; - } - - if (size > PAGE_ALIGN(dev->frame[0].buf.length)) - size = PAGE_ALIGN(dev->frame[0].buf.length); - - for (i = 0; i < dev->num_frames; i++) { - if ((dev->frame[i].buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) - break; - } - if (i == dev->num_frames) { - em28xx_videodbg("mmap: user supplied mapping address is out of range\n"); - mutex_unlock(&dev->lock); - return -EINVAL; - } - - /* VM_IO is eventually going to replace PageReserved altogether */ - vma->vm_flags |= VM_IO; - vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ + rc = check_dev(dev); + if (rc < 0) + return rc; - pos = dev->frame[i].bufmem; - while (size > 0) { /* size is page-aligned */ - if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { - em28xx_videodbg("mmap: vm_insert_page failed\n"); - mutex_unlock(&dev->lock); - return -EAGAIN; - } - start += PAGE_SIZE; - pos += PAGE_SIZE; - size -= PAGE_SIZE; - } + rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); - vma->vm_ops = &em28xx_vm_ops; - vma->vm_private_data = &dev->frame[i]; + em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n", + (unsigned long)vma->vm_start, + (unsigned long)vma->vm_end-(unsigned long)vma->vm_start, + rc); - em28xx_vm_open(vma); - mutex_unlock(&dev->lock); - return 0; + return rc; } static const struct file_operations em28xx_v4l_fops = { @@ -1865,6 +1895,9 @@ static const struct video_device em28xx_video_template = { .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, #endif +#ifdef CONFIG_VIDEO_V4L1_COMPAT + .vidiocgmbuf = vidiocgmbuf, +#endif .tvnorms = V4L2_STD_ALL, .current_norm = V4L2_STD_PAL, @@ -1893,7 +1926,7 @@ static struct video_device em28xx_radio_template = { #endif }; -/******************************** usb interface *****************************************/ +/******************************** usb interface ******************************/ static LIST_HEAD(em28xx_extension_devlist); @@ -1952,6 +1985,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, vfd->release = video_device_release; #endif vfd->type = type; + vfd->debug = video_debug; snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); @@ -1975,7 +2009,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, dev->udev = udev; mutex_init(&dev->lock); - spin_lock_init(&dev->queue_lock); + spin_lock_init(&dev->slock); init_waitqueue_head(&dev->open); init_waitqueue_head(&dev->wait_frame); init_waitqueue_head(&dev->wait_stream); @@ -1987,10 +2021,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, dev->em28xx_read_reg_req = em28xx_read_reg_req; dev->is_em2800 = em28xx_boards[dev->model].is_em2800; - errCode = em28xx_read_reg(dev, CHIPID_REG); - if (errCode >= 0) - em28xx_info("em28xx chip ID = %d\n", errCode); - em28xx_pre_card_setup(dev); errCode = em28xx_config(dev); @@ -2023,10 +2053,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, dev->width = maxw; dev->height = maxh; dev->interlaced = EM28XX_INTERLACED_DEFAULT; - dev->field_size = dev->width * dev->height; - dev->frame_size = - dev->interlaced ? dev->field_size << 1 : dev->field_size; - dev->bytesperline = dev->width * 2; dev->hscale = 0; dev->vscale = 0; dev->ctl_input = 2; @@ -2082,6 +2108,10 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, dev->radio_dev->minor & 0x1f); } + /* init video dma queues */ + INIT_LIST_HEAD(&dev->vidq.active); + INIT_LIST_HEAD(&dev->vidq.queued); + #if 0 video_set_drvdata(dev->vbi_dev, dev); #endif @@ -2134,6 +2164,9 @@ static void request_module_async(struct work_struct *work) request_module("snd-usb-audio"); else request_module("em28xx-alsa"); + + if (dev->has_dvb) + request_module("em28xx-dvb"); } #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) @@ -2172,22 +2205,24 @@ static int em28xx_usb_probe(struct usb_interface *interface, ifnum = interface->altsetting[0].desc.bInterfaceNumber; /* Check to see next free device and mark as used */ - nr=find_first_zero_bit(&em28xx_devused,EM28XX_MAXBOARDS); - em28xx_devused|=1<<nr; + nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS); + em28xx_devused |= 1<<nr; /* Don't register audio interfaces */ if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { em28xx_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n", - udev->descriptor.idVendor,udev->descriptor.idProduct, + udev->descriptor.idVendor, + udev->descriptor.idProduct, ifnum, interface->altsetting[0].desc.bInterfaceClass); - em28xx_devused&=~(1<<nr); + em28xx_devused &= ~(1<<nr); return -ENODEV; } em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n", - udev->descriptor.idVendor,udev->descriptor.idProduct, + udev->descriptor.idVendor, + udev->descriptor.idProduct, ifnum, interface->altsetting[0].desc.bInterfaceClass); @@ -2197,18 +2232,19 @@ static int em28xx_usb_probe(struct usb_interface *interface, if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC) { em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); - em28xx_devused&=~(1<<nr); + em28xx_devused &= ~(1<<nr); return -ENODEV; } if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); - em28xx_devused&=~(1<<nr); + em28xx_devused &= ~(1<<nr); return -ENODEV; } if (nr >= EM28XX_MAXBOARDS) { - printk (DRIVER_NAME ": Supports only %i em28xx boards.\n",EM28XX_MAXBOARDS); - em28xx_devused&=~(1<<nr); + printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", + EM28XX_MAXBOARDS); + em28xx_devused &= ~(1<<nr); return -ENOMEM; } @@ -2216,7 +2252,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { em28xx_err(DRIVER_NAME ": out of memory!\n"); - em28xx_devused&=~(1<<nr); + em28xx_devused &= ~(1<<nr); return -ENOMEM; } @@ -2240,14 +2276,14 @@ static int em28xx_usb_probe(struct usb_interface *interface, /* compute alternate max packet sizes */ uif = udev->actconfig->interface[0]; - dev->num_alt=uif->num_altsetting; - em28xx_info("Alternate settings: %i\n",dev->num_alt); -// dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)* - dev->alt_max_pkt_size = kmalloc(32* - dev->num_alt,GFP_KERNEL); + dev->num_alt = uif->num_altsetting; + em28xx_info("Alternate settings: %i\n", dev->num_alt); +/* dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)* */ + dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL); + if (dev->alt_max_pkt_size == NULL) { em28xx_errdev("out of memory!\n"); - em28xx_devused&=~(1<<nr); + em28xx_devused &= ~(1<<nr); kfree(dev); return -ENOMEM; } @@ -2257,11 +2293,11 @@ static int em28xx_usb_probe(struct usb_interface *interface, wMaxPacketSize); dev->alt_max_pkt_size[i] = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); - em28xx_info("Alternate setting %i, max size= %i\n",i, - dev->alt_max_pkt_size[i]); + em28xx_info("Alternate setting %i, max size= %i\n", i, + dev->alt_max_pkt_size[i]); } - if ((card[nr]>=0)&&(card[nr]<em28xx_bcount)) + if ((card[nr] >= 0) && (card[nr] < em28xx_bcount)) dev->model = card[nr]; /* allocate device struct */ @@ -2297,7 +2333,8 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) em28xx_info("disconnecting %s\n", dev->vdev->name); - /* wait until all current v4l2 io is finished then deallocate resources */ + /* wait until all current v4l2 io is finished then deallocate + resources */ mutex_lock(&dev->lock); wake_up_interruptible_all(&dev->open); @@ -2334,7 +2371,7 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) } static struct usb_driver em28xx_usb_driver = { -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 15) .owner = THIS_MODULE, #endif .name = "em28xx", diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h index 980989f11..d31d11a5e 100644 --- a/linux/drivers/media/video/em28xx/em28xx.h +++ b/linux/drivers/media/video/em28xx/em28xx.h @@ -27,13 +27,41 @@ #include "compat.h" #include <linux/videodev2.h> +#include <media/videobuf-vmalloc.h> + #include <linux/i2c.h> -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 15) #include <linux/mutex.h> #endif #include <media/ir-kbd-i2c.h> - -#define UNSET -1 +#if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE) +#include <media/videobuf-dvb.h> +#endif +#include "tuner-xc2028.h" +#include "em28xx-reg.h" + +/* Boards supported by driver */ +#define EM2800_BOARD_UNKNOWN 0 +#define EM2820_BOARD_UNKNOWN 1 +#define EM2820_BOARD_TERRATEC_CINERGY_250 2 +#define EM2820_BOARD_PINNACLE_USB_2 3 +#define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4 +#define EM2820_BOARD_MSI_VOX_USB_2 5 +#define EM2800_BOARD_TERRATEC_CINERGY_200 6 +#define EM2800_BOARD_LEADTEK_WINFAST_USBII 7 +#define EM2800_BOARD_KWORLD_USB2800 8 +#define EM2820_BOARD_PINNACLE_DVC_90 9 +#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 10 +#define EM2880_BOARD_TERRATEC_HYBRID_XS 11 +#define EM2820_BOARD_KWORLD_PVRTV2800RF 12 +#define EM2880_BOARD_TERRATEC_PRODIGY_XS 13 +#define EM2820_BOARD_PROLINK_PLAYTV_USB2 14 +#define EM2800_BOARD_VGEAR_POCKETTV 15 +#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16 + +/* Limits minimum and default number of buffers */ +#define EM28XX_MIN_BUF 4 +#define EM28XX_DEF_BUF 8 /* maximum number of em28xx boards */ #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ @@ -84,31 +112,78 @@ /* time in msecs to wait for i2c writes to finish */ #define EM2800_I2C_WRITE_TIMEOUT 20 -/* the various frame states */ -enum em28xx_frame_state { - F_UNUSED = 0, - F_QUEUED, - F_GRABBING, - F_DONE, - F_ERROR, +enum em28xx_mode { + EM28XX_MODE_UNDEFINED, + EM28XX_ANALOG_MODE, + EM28XX_DIGITAL_MODE, }; -/* stream states */ enum em28xx_stream_state { STREAM_OFF, STREAM_INTERRUPT, STREAM_ON, }; -/* frames */ -struct em28xx_frame_t { - void *bufmem; - struct v4l2_buffer buf; - enum em28xx_frame_state state; +struct em28xx; + +struct em28xx_usb_isoc_ctl { + /* max packet size of isoc transaction */ + int max_pkt_size; + + /* number of allocated urbs */ + int num_bufs; + + /* urb for isoc transfers */ + struct urb **urb; + + /* transfer buffers for isoc transfer */ + char **transfer_buffer; + + /* Last buffer command and region */ + u8 cmd; + int pos, size, pktsize; + + /* Last field: ODD or EVEN? */ + int field; + + /* Stores incomplete commands */ + u32 tmp_buf; + int tmp_buf_len; + + /* Stores already requested buffers */ + struct em28xx_buffer *buf; + + /* Stores the number of received fields */ + int nfields; + + /* isoc urb callback */ + int (*isoc_copy) (struct em28xx *dev, struct urb *urb); + +}; + +struct em28xx_fmt { + char *name; + u32 fourcc; /* v4l2 format id */ +}; + +/* buffer for one video frame */ +struct em28xx_buffer { + /* common v4l buffer stuff -- must be first */ + struct videobuf_buffer vb; + struct list_head frame; - unsigned long vma_use_count; int top_field; - int fieldbytesused; + int receiving; +}; + +struct em28xx_dmaqueue { + struct list_head active; + struct list_head queued; + + wait_queue_head_t wq; + + /* Counters to control buffer fill */ + int pos; }; /* io methods */ @@ -155,6 +230,12 @@ enum em28xx_decoder { EM28XX_SAA7114 }; +struct em28xx_reg_seq { + int reg; + unsigned char val, mask; + int sleep; +}; + struct em28xx_board { char *name; int vchannels; @@ -168,8 +249,7 @@ struct em28xx_board { unsigned int mts_firmware:1; unsigned int has_12mhz_i2s:1; unsigned int max_range_640_480:1; - - unsigned int analog_gpio; + unsigned int has_dvb:1; enum em28xx_decoder decoder; @@ -202,7 +282,10 @@ enum em28xx_dev_state { #define EM28XX_NUM_AUDIO_PACKETS 64 #define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */ #define EM28XX_CAPTURE_STREAM_EN 1 + +/* em28xx extensions */ #define EM28XX_AUDIO 0x10 +#define EM28XX_DVB 0x20 struct em28xx_audio { char name[50]; @@ -228,13 +311,24 @@ struct em28xx_audio { spinlock_t slock; }; +struct em28xx; + +struct em28xx_fh { + struct em28xx *dev; + unsigned int stream_on:1; /* Locks streams */ + int radio; + + struct videobuf_queue vb_vidq; + + enum v4l2_buf_type type; +}; + /* main device struct */ struct em28xx { /* generic device properties */ char name[30]; /* name (including minor) of the device */ int model; /* index in the device_data struct */ int devno; /* marks the number of this device */ - unsigned int analog_gpio; unsigned int is_em2800:1; unsigned int has_msp34xx:1; unsigned int has_tda9887:1; @@ -242,6 +336,16 @@ struct em28xx { unsigned int has_audio_class:1; unsigned int has_12mhz_i2s:1; unsigned int max_range_640_480:1; + unsigned int has_dvb:1; + + /* Some older em28xx chips needs a waiting time after writing */ + unsigned int wait_after_write; + + /* GPIO sequences for analog and digital mode */ + struct em28xx_reg_seq *analog_gpio, *digital_gpio; + + /* GPIO sequences for tuner callbacks */ + struct em28xx_reg_seq *tun_analog_gpio, *tun_digital_gpio; int video_inputs; /* number of video inputs */ struct list_head devlist; @@ -266,40 +370,32 @@ struct em28xx { int mute; int volume; /* frame properties */ - struct em28xx_frame_t frame[EM28XX_NUM_FRAMES]; /* list of frames */ - int num_frames; /* number of frames currently in use */ - unsigned int frame_count; /* total number of transfered frames */ - struct em28xx_frame_t *frame_current; /* the frame that is being filled */ int width; /* current frame width */ int height; /* current frame height */ - int frame_size; /* current frame size */ - int field_size; /* current field size */ - int bytesperline; int hscale; /* horizontal scale factor (see datasheet) */ int vscale; /* vertical scale factor (see datasheet) */ int interlaced; /* 1=interlace fileds, 0=just top fileds */ - int type; unsigned int video_bytesread; /* Number of bytes read */ unsigned long hash; /* eeprom hash - for boards with generic ID */ - unsigned long i2c_hash; /* i2c devicelist hash - for boards with generic ID */ + unsigned long i2c_hash; /* i2c devicelist hash - + for boards with generic ID */ struct em28xx_audio *adev; /* states */ enum em28xx_dev_state state; - enum em28xx_stream_state stream; enum em28xx_io_method io; struct work_struct request_module_wk; /* locks */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 15) struct mutex lock; #else struct semaphore lock, fileop_lock; #endif - spinlock_t queue_lock; + /* spinlock_t queue_lock; */ struct list_head inqueue, outqueue; wait_queue_head_t open, wait_frame, wait_stream; struct video_device *vbi_dev; @@ -307,6 +403,11 @@ struct em28xx { unsigned char eedata[256]; + /* Isoc control struct */ + struct em28xx_dmaqueue vidq; + struct em28xx_usb_isoc_ctl isoc_ctl; + spinlock_t slock; + /* usb transfer */ struct usb_device *udev; /* the usb device */ int alt; /* alternate */ @@ -316,20 +417,21 @@ struct em28xx { struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */ char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */ /* helper funcs that call usb_control_msg */ - int (*em28xx_write_regs) (struct em28xx * dev, u16 reg, char *buf, - int len); - int (*em28xx_read_reg) (struct em28xx * dev, u16 reg); - int (*em28xx_read_reg_req_len) (struct em28xx * dev, u8 req, u16 reg, + int (*em28xx_write_regs) (struct em28xx *dev, u16 reg, char *buf, int len); - int (*em28xx_write_regs_req) (struct em28xx * dev, u8 req, u16 reg, + int (*em28xx_read_reg) (struct em28xx *dev, u16 reg); + int (*em28xx_read_reg_req_len) (struct em28xx *dev, u8 req, u16 reg, + char *buf, int len); + int (*em28xx_write_regs_req) (struct em28xx *dev, u8 req, u16 reg, char *buf, int len); - int (*em28xx_read_reg_req) (struct em28xx * dev, u8 req, u16 reg); -}; + int (*em28xx_read_reg_req) (struct em28xx *dev, u8 req, u16 reg); -struct em28xx_fh { - struct em28xx *dev; - unsigned int stream_on:1; /* Locks streams */ - int radio; + enum em28xx_mode mode; + + /* Caches GPO and GPIO registers */ + unsigned char reg_gpo, reg_gpio; + + struct em28xx_dvb *dvb; }; struct em28xx_ops { @@ -366,22 +468,27 @@ int em28xx_colorlevels_set_default(struct em28xx *dev); int em28xx_capture_start(struct em28xx *dev, int start); int em28xx_outfmt_set_yuv422(struct em28xx *dev); int em28xx_resolution_set(struct em28xx *dev); -int em28xx_init_isoc(struct em28xx *dev); -void em28xx_uninit_isoc(struct em28xx *dev); int em28xx_set_alternate(struct em28xx *dev); +int em28xx_init_isoc(struct em28xx *dev, int max_packets, + int num_bufs, int max_pkt_size, + int (*isoc_copy) (struct em28xx *dev, struct urb *urb)); +void em28xx_uninit_isoc(struct em28xx *dev); +int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); +int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); /* Provided by em28xx-video.c */ int em28xx_register_extension(struct em28xx_ops *dev); void em28xx_unregister_extension(struct em28xx_ops *dev); /* Provided by em28xx-cards.c */ -extern int em2800_variant_detect(struct usb_device* udev,int model); +extern int em2800_variant_detect(struct usb_device *udev, int model); extern void em28xx_pre_card_setup(struct em28xx *dev); extern void em28xx_card_setup(struct em28xx *dev); extern struct em28xx_board em28xx_boards[]; extern struct usb_device_id em28xx_id_table[]; extern const unsigned int em28xx_bcount; void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir); +int em28xx_tuner_callback(void *ptr, int command, int arg); /* Provided by em28xx-input.c */ /* TODO: Check if the standard get_key handlers on ir-common can be used */ @@ -390,71 +497,6 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); -/* em2800 registers */ -#define EM2800_AUDIOSRC_REG 0x08 - -/* em28xx registers */ -#define I2C_CLK_REG 0x06 -#define CHIPID_REG 0x0a -#define USBSUSP_REG 0x0c /* */ - -#define AUDIOSRC_REG 0x0e -#define XCLK_REG 0x0f - -#define VINMODE_REG 0x10 -#define VINCTRL_REG 0x11 -#define VINENABLE_REG 0x12 /* */ - -#define GAMMA_REG 0x14 -#define RGAIN_REG 0x15 -#define GGAIN_REG 0x16 -#define BGAIN_REG 0x17 -#define ROFFSET_REG 0x18 -#define GOFFSET_REG 0x19 -#define BOFFSET_REG 0x1a - -#define OFLOW_REG 0x1b -#define HSTART_REG 0x1c -#define VSTART_REG 0x1d -#define CWIDTH_REG 0x1e -#define CHEIGHT_REG 0x1f - -#define YGAIN_REG 0x20 -#define YOFFSET_REG 0x21 -#define UVGAIN_REG 0x22 -#define UOFFSET_REG 0x23 -#define VOFFSET_REG 0x24 -#define SHARPNESS_REG 0x25 - -#define COMPR_REG 0x26 -#define OUTFMT_REG 0x27 - -#define XMIN_REG 0x28 -#define XMAX_REG 0x29 -#define YMIN_REG 0x2a -#define YMAX_REG 0x2b - -#define HSCALELOW_REG 0x30 -#define HSCALEHIGH_REG 0x31 -#define VSCALELOW_REG 0x32 -#define VSCALEHIGH_REG 0x33 - -#define AC97LSB_REG 0x40 -#define AC97MSB_REG 0x41 -#define AC97ADDR_REG 0x42 -#define AC97BUSY_REG 0x43 - -/* em202 registers */ -#define MASTER_AC97 0x02 -#define LINE_IN_AC97 0x10 -#define VIDEO_AC97 0x14 - -/* register settings */ -#define EM2800_AUDIO_SRC_TUNER 0x0d -#define EM2800_AUDIO_SRC_LINE 0x0c -#define EM28XX_AUDIO_SRC_TUNER 0xc0 -#define EM28XX_AUDIO_SRC_LINE 0x80 - /* printk macros */ #define em28xx_err(fmt, arg...) do {\ @@ -471,80 +513,80 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, printk(KERN_WARNING "%s: "fmt,\ dev->name , ##arg); } while (0) -inline static int em28xx_compression_disable(struct em28xx *dev) +static inline int em28xx_compression_disable(struct em28xx *dev) { /* side effect of disabling scaler and mixer */ - return em28xx_write_regs(dev, COMPR_REG, "\x00", 1); + return em28xx_write_regs(dev, EM28XX_R26_COMPR, "\x00", 1); } -inline static int em28xx_contrast_get(struct em28xx *dev) +static inline int em28xx_contrast_get(struct em28xx *dev) { - return em28xx_read_reg(dev, YGAIN_REG) & 0x1f; + return em28xx_read_reg(dev, EM28XX_R20_YGAIN) & 0x1f; } -inline static int em28xx_brightness_get(struct em28xx *dev) +static inline int em28xx_brightness_get(struct em28xx *dev) { - return em28xx_read_reg(dev, YOFFSET_REG); + return em28xx_read_reg(dev, EM28XX_R21_YOFFSET); } -inline static int em28xx_saturation_get(struct em28xx *dev) +static inline int em28xx_saturation_get(struct em28xx *dev) { - return em28xx_read_reg(dev, UVGAIN_REG) & 0x1f; + return em28xx_read_reg(dev, EM28XX_R22_UVGAIN) & 0x1f; } -inline static int em28xx_u_balance_get(struct em28xx *dev) +static inline int em28xx_u_balance_get(struct em28xx *dev) { - return em28xx_read_reg(dev, UOFFSET_REG); + return em28xx_read_reg(dev, EM28XX_R23_UOFFSET); } -inline static int em28xx_v_balance_get(struct em28xx *dev) +static inline int em28xx_v_balance_get(struct em28xx *dev) { - return em28xx_read_reg(dev, VOFFSET_REG); + return em28xx_read_reg(dev, EM28XX_R24_VOFFSET); } -inline static int em28xx_gamma_get(struct em28xx *dev) +static inline int em28xx_gamma_get(struct em28xx *dev) { - return em28xx_read_reg(dev, GAMMA_REG) & 0x3f; + return em28xx_read_reg(dev, EM28XX_R14_GAMMA) & 0x3f; } -inline static int em28xx_contrast_set(struct em28xx *dev, s32 val) +static inline int em28xx_contrast_set(struct em28xx *dev, s32 val) { u8 tmp = (u8) val; - return em28xx_write_regs(dev, YGAIN_REG, &tmp, 1); + return em28xx_write_regs(dev, EM28XX_R20_YGAIN, &tmp, 1); } -inline static int em28xx_brightness_set(struct em28xx *dev, s32 val) +static inline int em28xx_brightness_set(struct em28xx *dev, s32 val) { u8 tmp = (u8) val; - return em28xx_write_regs(dev, YOFFSET_REG, &tmp, 1); + return em28xx_write_regs(dev, EM28XX_R21_YOFFSET, &tmp, 1); } -inline static int em28xx_saturation_set(struct em28xx *dev, s32 val) +static inline int em28xx_saturation_set(struct em28xx *dev, s32 val) { u8 tmp = (u8) val; - return em28xx_write_regs(dev, UVGAIN_REG, &tmp, 1); + return em28xx_write_regs(dev, EM28XX_R22_UVGAIN, &tmp, 1); } -inline static int em28xx_u_balance_set(struct em28xx *dev, s32 val) +static inline int em28xx_u_balance_set(struct em28xx *dev, s32 val) { u8 tmp = (u8) val; - return em28xx_write_regs(dev, UOFFSET_REG, &tmp, 1); + return em28xx_write_regs(dev, EM28XX_R23_UOFFSET, &tmp, 1); } -inline static int em28xx_v_balance_set(struct em28xx *dev, s32 val) +static inline int em28xx_v_balance_set(struct em28xx *dev, s32 val) { u8 tmp = (u8) val; - return em28xx_write_regs(dev, VOFFSET_REG, &tmp, 1); + return em28xx_write_regs(dev, EM28XX_R24_VOFFSET, &tmp, 1); } -inline static int em28xx_gamma_set(struct em28xx *dev, s32 val) +static inline int em28xx_gamma_set(struct em28xx *dev, s32 val) { u8 tmp = (u8) val; - return em28xx_write_regs(dev, GAMMA_REG, &tmp, 1); + return em28xx_write_regs(dev, EM28XX_R14_GAMMA, &tmp, 1); } /*FIXME: maxw should be dependent of alt mode */ -inline static unsigned int norm_maxw(struct em28xx *dev) +static inline unsigned int norm_maxw(struct em28xx *dev) { if (dev->max_range_640_480) return 640; @@ -552,7 +594,7 @@ inline static unsigned int norm_maxw(struct em28xx *dev) return 720; } -inline static unsigned int norm_maxh(struct em28xx *dev) +static inline unsigned int norm_maxh(struct em28xx *dev) { if (dev->max_range_640_480) return 480; diff --git a/linux/drivers/media/video/et61x251/et61x251.h b/linux/drivers/media/video/et61x251/et61x251.h index d22fbd34a..64ff5de0d 100644 --- a/linux/drivers/media/video/et61x251/et61x251.h +++ b/linux/drivers/media/video/et61x251/et61x251.h @@ -206,7 +206,7 @@ do { \ dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ else if ((level) >= 3) \ dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", \ - __FILE__, __FUNCTION__, __LINE__ , ## args); \ + __FILE__, __func__, __LINE__ , ## args); \ } \ } while (0) # define KDBG(level, fmt, args...) \ @@ -216,7 +216,7 @@ do { \ pr_info("et61x251: " fmt "\n", ## args); \ else if ((level) == 3) \ pr_debug("sn9c102: [%s:%s:%d] " fmt "\n", __FILE__, \ - __FUNCTION__, __LINE__ , ## args); \ + __func__, __LINE__ , ## args); \ } \ } while (0) # define V4LDBG(level, name, cmd) \ @@ -232,7 +232,7 @@ do { \ #undef PDBG #define PDBG(fmt, args...) \ -dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __FUNCTION__, \ +dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __func__, \ __LINE__ , ## args) #undef PDBGG diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c index 198e0a18b..afe23f323 100644 --- a/linux/drivers/media/video/ir-kbd-i2c.c +++ b/linux/drivers/media/video/ir-kbd-i2c.c @@ -155,7 +155,7 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) } if(buf[0] !=0 || buf[1] !=0 || buf[2] !=0 || buf[3] != 0) - dprintk(2, "%s: 0x%2x 0x%2x 0x%2x 0x%2x\n", __FUNCTION__, + dprintk(2, "%s: 0x%2x 0x%2x 0x%2x 0x%2x\n", __func__, buf[0], buf[1], buf[2], buf[3]); /* no key pressed or signal from other ir remote */ diff --git a/linux/drivers/media/video/ivtv/Kconfig b/linux/drivers/media/video/ivtv/Kconfig index 270906fc3..b6171702c 100644 --- a/linux/drivers/media/video/ivtv/Kconfig +++ b/linux/drivers/media/video/ivtv/Kconfig @@ -10,6 +10,7 @@ config VIDEO_IVTV select VIDEO_CX25840 select VIDEO_MSP3400 select VIDEO_SAA711X + select VIDEO_SAA717X select VIDEO_SAA7127 select VIDEO_TVAUDIO select VIDEO_CS53L32A diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c index b8b0ac859..fdb2e5848 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.c +++ b/linux/drivers/media/video/ivtv/ivtv-driver.c @@ -887,7 +887,9 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) #ifndef CONFIG_VIDEO_SAA7127 hw = ivtv_request_module(itv, hw, "saa7127", IVTV_HW_SAA7127); #endif +#ifndef CONFIG_VIDEO_SAA717X hw = ivtv_request_module(itv, hw, "saa717x", IVTV_HW_SAA717X); +#endif #ifndef CONFIG_VIDEO_UPD64031A hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A); #endif diff --git a/linux/drivers/media/video/ivtv/ivtv-fileops.c b/linux/drivers/media/video/ivtv/ivtv-fileops.c index d949a8133..a7640c49f 100644 --- a/linux/drivers/media/video/ivtv/ivtv-fileops.c +++ b/linux/drivers/media/video/ivtv/ivtv-fileops.c @@ -219,7 +219,9 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, /* Process pending program info updates and pending VBI data */ ivtv_update_pgm_info(itv); - if (jiffies - itv->dualwatch_jiffies > msecs_to_jiffies(1000)) { + if (time_after(jiffies, + itv->dualwatch_jiffies + + msecs_to_jiffies(1000))) { itv->dualwatch_jiffies = jiffies; ivtv_dualwatch(itv); } diff --git a/linux/drivers/media/video/ivtv/ivtv-i2c.c b/linux/drivers/media/video/ivtv/ivtv-i2c.c index 1f421a574..77b4f960b 100644 --- a/linux/drivers/media/video/ivtv/ivtv-i2c.c +++ b/linux/drivers/media/video/ivtv/ivtv-i2c.c @@ -178,10 +178,16 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx) } if (id != I2C_DRIVERID_TUNER) { - c = i2c_new_device(&itv->i2c_adap, &info); - if (c->driver == NULL) + if (id == I2C_DRIVERID_UPD64031A || + id == I2C_DRIVERID_UPD64083) { + unsigned short addrs[2] = { info.addr, I2C_CLIENT_END }; + + c = i2c_new_probed_device(&itv->i2c_adap, &info, addrs); + } else + c = i2c_new_device(&itv->i2c_adap, &info); + if (c && c->driver == NULL) i2c_unregister_device(c); - else + else if (c) itv->i2c_clients[i] = c; return itv->i2c_clients[i] ? 0 : -ENODEV; } diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index 873296394..a5da513d6 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1644,6 +1644,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, if (ivtv_debug & IVTV_DBGFLG_IOCTL) { printk(KERN_INFO "ivtv%d ioctl: ", itv->num); v4l_printk_ioctl(cmd); + printk("\n"); } return ivtv_debug_ioctls(filp, cmd, arg); @@ -1687,6 +1688,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, if (ivtv_debug & IVTV_DBGFLG_IOCTL) { printk(KERN_INFO "ivtv%d ioctl: ", itv->num); v4l_printk_ioctl(cmd); + printk("\n"); } return ivtv_v4l2_ioctls(itv, filp, cmd, arg); @@ -1700,6 +1702,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, if (ivtv_debug & IVTV_DBGFLG_IOCTL) { printk(KERN_INFO "ivtv%d ioctl: ", itv->num); v4l_printk_ioctl(cmd); + printk("\n"); } return ivtv_control_ioctls(itv, cmd, arg); diff --git a/linux/drivers/media/video/ivtv/ivtv-mailbox.c b/linux/drivers/media/video/ivtv/ivtv-mailbox.c index 13a6c374d..1b5c0ac09 100644 --- a/linux/drivers/media/video/ivtv/ivtv-mailbox.c +++ b/linux/drivers/media/video/ivtv/ivtv-mailbox.c @@ -177,7 +177,8 @@ static int get_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int f /* Sleep before a retry, if not atomic */ if (!(flags & API_NO_WAIT_MB)) { - if (jiffies - then > msecs_to_jiffies(10*retries)) + if (time_after(jiffies, + then + msecs_to_jiffies(10*retries))) break; ivtv_msleep_timeout(10, 0); } @@ -244,7 +245,9 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) data, then just return 0 as there is no need to issue this command again. Just an optimization to prevent unnecessary use of mailboxes. */ if (itv->api_cache[cmd].last_jiffies && - jiffies - itv->api_cache[cmd].last_jiffies < msecs_to_jiffies(1800000) && + time_before(jiffies, + itv->api_cache[cmd].last_jiffies + + msecs_to_jiffies(1800000)) && !memcmp(data, itv->api_cache[cmd].data, sizeof(itv->api_cache[cmd].data))) { itv->api_cache[cmd].last_jiffies = jiffies; return 0; @@ -299,7 +302,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) } } while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) { - if (jiffies - then > api_timeout) { + if (time_after(jiffies, then + api_timeout)) { IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name); /* reset the mailbox, but it is likely too late already */ write_sync(0, &mbox->flags); @@ -311,7 +314,7 @@ static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[]) else ivtv_msleep_timeout(1, 0); } - if (jiffies - then > msecs_to_jiffies(100)) + if (time_after(jiffies, then + msecs_to_jiffies(100))) IVTV_DEBUG_WARN("%s took %u jiffies\n", api_info[cmd].name, jiffies_to_msecs(jiffies - then)); diff --git a/linux/drivers/media/video/ivtv/ivtv-streams.c b/linux/drivers/media/video/ivtv/ivtv-streams.c index 24d98ecf3..4ab8d3683 100644 --- a/linux/drivers/media/video/ivtv/ivtv-streams.c +++ b/linux/drivers/media/video/ivtv/ivtv-streams.c @@ -768,7 +768,8 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) /* wait 2s for EOS interrupt */ while (!test_bit(IVTV_F_I_EOS, &itv->i_flags) && - jiffies < then + msecs_to_jiffies (2000)) { + time_before(jiffies, + then + msecs_to_jiffies(2000))) { schedule_timeout(msecs_to_jiffies(10)); } diff --git a/linux/drivers/media/video/msp3400-driver.c b/linux/drivers/media/video/msp3400-driver.c index ef780ed60..716f30eb5 100644 --- a/linux/drivers/media/video/msp3400-driver.c +++ b/linux/drivers/media/video/msp3400-driver.c @@ -410,7 +410,7 @@ int msp_sleep(struct msp_state *state, int timeout) } /* ------------------------------------------------------------------------ */ -#ifdef CONFIG_VIDEO_V4L1 +#ifdef CONFIG_VIDEO_ALLOW_V4L1 static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode) { if (rxsubchans == V4L2_TUNER_SUB_MONO) @@ -558,7 +558,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) /* --- v4l ioctls --- */ /* take care: bttv does userspace copying, we'll get a kernel pointer here... */ -#ifdef CONFIG_VIDEO_V4L1 +#ifdef CONFIG_VIDEO_ALLOW_V4L1 case VIDIOCGAUDIO: { struct video_audio *va = arg; diff --git a/linux/drivers/media/video/mt20xx.h b/linux/drivers/media/video/mt20xx.h index 5e9c825d2..aa848e14c 100644 --- a/linux/drivers/media/video/mt20xx.h +++ b/linux/drivers/media/video/mt20xx.h @@ -29,7 +29,7 @@ static inline struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, struct i2c_adapter* i2c_adap, u8 i2c_addr) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif diff --git a/linux/drivers/media/video/mt9m001.c b/linux/drivers/media/video/mt9m001.c index 2ea133e8a..3fb5f63df 100644 --- a/linux/drivers/media/video/mt9m001.c +++ b/linux/drivers/media/video/mt9m001.c @@ -123,7 +123,7 @@ static int mt9m001_init(struct soc_camera_device *icd) int ret; /* Disable chip, synchronous option update */ - dev_dbg(icd->vdev->dev, "%s\n", __FUNCTION__); + dev_dbg(icd->vdev->dev, "%s\n", __func__); ret = reg_write(icd, MT9M001_RESET, 1); if (ret >= 0) diff --git a/linux/drivers/media/video/mxb.c b/linux/drivers/media/video/mxb.c index 97cc92c82..bf2462a58 100644 --- a/linux/drivers/media/video/mxb.c +++ b/linux/drivers/media/video/mxb.c @@ -222,9 +222,8 @@ static int mxb_probe(struct saa7146_dev* dev) device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients); /* check if all devices are present */ - if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c - || 0 == mxb->tda9840 || 0 == mxb->saa7111a || 0 == mxb->tuner ) { - + if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c || + !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) { printk("mxb: did not find all i2c devices. aborting\n"); i2c_del_adapter(&mxb->i2c_adapter); kfree(mxb); diff --git a/linux/drivers/media/video/ov511.c b/linux/drivers/media/video/ov511.c index cba851d18..4c8050667 100644 --- a/linux/drivers/media/video/ov511.c +++ b/linux/drivers/media/video/ov511.c @@ -5838,7 +5838,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) goto error; memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev)); - ov->vdev->dev = &dev->dev; + ov->vdev->dev = &intf->dev; video_set_drvdata(ov->vdev, ov); for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) { diff --git a/linux/drivers/media/video/ov511.h b/linux/drivers/media/video/ov511.h index 2fb0d992c..e797d3c9c 100644 --- a/linux/drivers/media/video/ov511.h +++ b/linux/drivers/media/video/ov511.h @@ -18,7 +18,7 @@ #ifdef OV511_DEBUG #define PDEBUG(level, fmt, args...) \ if (debug >= (level)) info("[%s:%d] " fmt, \ - __FUNCTION__, __LINE__ , ## args) + __func__, __LINE__ , ## args) #else #define PDEBUG(level, fmt, args...) do {} while(0) #endif diff --git a/linux/drivers/media/video/ovcamchip/ovcamchip_priv.h b/linux/drivers/media/video/ovcamchip/ovcamchip_priv.h index 50c7763d4..9afa4fe47 100644 --- a/linux/drivers/media/video/ovcamchip/ovcamchip_priv.h +++ b/linux/drivers/media/video/ovcamchip/ovcamchip_priv.h @@ -24,11 +24,11 @@ extern int ovcamchip_debug; #define PDEBUG(level, fmt, args...) \ if (ovcamchip_debug >= (level)) pr_debug("[%s:%d] " fmt "\n", \ - __FUNCTION__, __LINE__ , ## args) + __func__, __LINE__ , ## args) #define DDEBUG(level, dev, fmt, args...) \ if (ovcamchip_debug >= (level)) dev_dbg(dev, "[%s:%d] " fmt "\n", \ - __FUNCTION__, __LINE__ , ## args) + __func__, __LINE__ , ## args) /* Number of times to retry chip detection. Increase this if you are getting * "Failed to init camera chip" */ diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/linux/drivers/media/video/pvrusb2/pvrusb2-ctrl.c index 32e43e9d1..8b500528d 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-ctrl.c @@ -68,7 +68,7 @@ int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val) int ret = 0; if (!cptr) return -EINVAL; LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->set_value != 0) { + if (cptr->info->set_value) { if (cptr->info->type == pvr2_ctl_bitmask) { mask &= cptr->info->def.type_bitmask.valid_bits; } else if ((cptr->info->type == pvr2_ctl_int)|| @@ -269,7 +269,7 @@ unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr) int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr) { if (!cptr) return 0; - return cptr->info->set_value != 0; + return cptr->info->set_value != NULL; } diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 77edc72a2..8356bc0e4 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -2357,7 +2357,7 @@ static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw) for (idx = 0; idx < hdw->control_cnt; idx++) { cptr = hdw->controls + idx; - if (cptr->info->is_dirty == 0) continue; + if (!cptr->info->is_dirty) continue; if (!cptr->info->is_dirty(cptr)) continue; commit_flag = !0; @@ -2706,7 +2706,7 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, u16 address; unsigned int pipe; LOCK_TAKE(hdw->big_lock); do { - if ((hdw->fw_buffer == 0) == !enable_flag) break; + if ((hdw->fw_buffer == NULL) == !enable_flag) break; if (!enable_flag) { pvr2_trace(PVR2_TRACE_FIRMWARE, @@ -2775,7 +2775,7 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, /* Return true if we're in a mode for retrieval CPU firmware */ int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw) { - return hdw->fw_buffer != 0; + return hdw->fw_buffer != NULL; } diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-io.c b/linux/drivers/media/video/pvrusb2/pvrusb2-io.c index 7b3be67f5..e4aae2c97 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-io.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-io.c @@ -603,7 +603,7 @@ void pvr2_stream_kill(struct pvr2_stream *sp) struct pvr2_buffer *bp; mutex_lock(&sp->mutex); do { pvr2_stream_internal_flush(sp); - while ((bp = pvr2_stream_get_ready_buffer(sp)) != 0) { + while ((bp = pvr2_stream_get_ready_buffer(sp)) != NULL) { pvr2_buffer_set_idle(bp); } if (sp->buffer_total_count != sp->buffer_target_count) { diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/linux/drivers/media/video/pvrusb2/pvrusb2-ioread.c index aef12fecb..d7bbbe00f 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-ioread.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-ioread.c @@ -174,7 +174,7 @@ static int pvr2_ioread_start(struct pvr2_ioread *cp) if (!(cp->stream)) return 0; pvr2_trace(PVR2_TRACE_START_STOP, "/*---TRACE_READ---*/ pvr2_ioread_start id=%p",cp); - while ((bp = pvr2_stream_get_idle_buffer(cp->stream)) != 0) { + while ((bp = pvr2_stream_get_idle_buffer(cp->stream)) != NULL) { stat = pvr2_buffer_queue(bp); if (stat < 0) { pvr2_trace(PVR2_TRACE_DATA_FLOW, diff --git a/linux/drivers/media/video/pwc/pwc-if.c b/linux/drivers/media/video/pwc/pwc-if.c index a54d4ddfa..8236b2b2d 100644 --- a/linux/drivers/media/video/pwc/pwc-if.c +++ b/linux/drivers/media/video/pwc/pwc-if.c @@ -489,7 +489,7 @@ static void pwc_reset_buffers(struct pwc_device *pdev) int i; unsigned long flags; - PWC_DEBUG_MEMORY(">> %s __enter__\n", __FUNCTION__); + PWC_DEBUG_MEMORY(">> %s __enter__\n", __func__); spin_lock_irqsave(&pdev->ptrlock, flags); pdev->full_frames = NULL; @@ -511,7 +511,7 @@ static void pwc_reset_buffers(struct pwc_device *pdev) pdev->fill_image = 0; spin_unlock_irqrestore(&pdev->ptrlock, flags); - PWC_DEBUG_MEMORY("<< %s __leaving__\n", __FUNCTION__); + PWC_DEBUG_MEMORY("<< %s __leaving__\n", __func__); } @@ -929,7 +929,7 @@ static void pwc_iso_stop(struct pwc_device *pdev) struct urb *urb; urb = pdev->sbuf[i].urb; - if (urb != 0) { + if (urb) { PWC_DEBUG_MEMORY("Unlinking URB %p\n", urb); usb_kill_urb(urb); } @@ -945,7 +945,7 @@ static void pwc_iso_free(struct pwc_device *pdev) struct urb *urb; urb = pdev->sbuf[i].urb; - if (urb != 0) { + if (urb) { PWC_DEBUG_MEMORY("Freeing URB\n"); usb_free_urb(urb); pdev->sbuf[i].urb = NULL; @@ -1440,7 +1440,7 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) unsigned long page, pos = 0; int index; - PWC_DEBUG_MEMORY(">> %s\n", __FUNCTION__); + PWC_DEBUG_MEMORY(">> %s\n", __func__); pdev = vdev->priv; size = vma->vm_end - vma->vm_start; start = vma->vm_start; @@ -1784,8 +1784,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id /* Allocate video_device structure */ pdev->vdev = video_device_alloc(); - if (pdev->vdev == 0) - { + if (!pdev->vdev) { PWC_ERROR("Err, cannot allocate video_device struture. Failing probe."); kfree(pdev); return -ENOMEM; diff --git a/linux/drivers/media/video/pwc/pwc-v4l.c b/linux/drivers/media/video/pwc/pwc-v4l.c index 32fbe1ae6..174288987 100644 --- a/linux/drivers/media/video/pwc/pwc-v4l.c +++ b/linux/drivers/media/video/pwc/pwc-v4l.c @@ -351,8 +351,10 @@ int pwc_video_do_ioctl(struct inode *inode, struct file *file, return -EFAULT; #ifdef CONFIG_USB_PWC_DEBUG - if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace) + if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace) { v4l_printk_ioctl(cmd); + printk("\n"); + } #endif diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c index bef3c9c79..936db67a5 100644 --- a/linux/drivers/media/video/pxa_camera.c +++ b/linux/drivers/media/video/pxa_camera.c @@ -148,7 +148,7 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf) BUG_ON(in_interrupt()); - dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __FUNCTION__, + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, &buf->vb, buf->vb.baddr, buf->vb.bsize); /* This waits until this buffer is out of danger, i.e., until it is no @@ -175,7 +175,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq, struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); int i, ret; - dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __FUNCTION__, + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); /* Added list head initialization on alloc */ @@ -281,7 +281,7 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq, int nents = dma->sglen; unsigned long flags; - dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __FUNCTION__, + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); spin_lock_irqsave(&pcdev->lock, flags); @@ -354,21 +354,21 @@ static void pxa_videobuf_release(struct videobuf_queue *vq, #ifdef DEBUG struct soc_camera_device *icd = vq->priv_data; - dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __FUNCTION__, + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); switch (vb->state) { case VIDEOBUF_ACTIVE: - dev_dbg(&icd->dev, "%s (active)\n", __FUNCTION__); + dev_dbg(&icd->dev, "%s (active)\n", __func__); break; case VIDEOBUF_QUEUED: - dev_dbg(&icd->dev, "%s (queued)\n", __FUNCTION__); + dev_dbg(&icd->dev, "%s (queued)\n", __func__); break; case VIDEOBUF_PREPARED: - dev_dbg(&icd->dev, "%s (prepared)\n", __FUNCTION__); + dev_dbg(&icd->dev, "%s (prepared)\n", __func__); break; default: - dev_dbg(&icd->dev, "%s (unknown)\n", __FUNCTION__); + dev_dbg(&icd->dev, "%s (unknown)\n", __func__); break; } #endif @@ -408,7 +408,7 @@ static void pxa_camera_dma_irq_y(int channel, void *data) vb = &pcdev->active->vb; buf = container_of(vb, struct pxa_buffer, vb); WARN_ON(buf->inwork || list_empty(&vb->queue)); - dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __FUNCTION__, + dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, vb, vb->baddr, vb->bsize); /* _init is used to debug races, see comment in pxa_camera_reqbufs() */ @@ -466,18 +466,18 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev) pcdev, pdata); if (pdata && pdata->init) { - dev_dbg(pcdev->dev, "%s: Init gpios\n", __FUNCTION__); + dev_dbg(pcdev->dev, "%s: Init gpios\n", __func__); pdata->init(pcdev->dev); } if (pdata && pdata->power) { - dev_dbg(pcdev->dev, "%s: Power on camera\n", __FUNCTION__); + dev_dbg(pcdev->dev, "%s: Power on camera\n", __func__); pdata->power(pcdev->dev, 1); } if (pdata && pdata->reset) { dev_dbg(pcdev->dev, "%s: Releasing camera reset\n", - __FUNCTION__); + __func__); pdata->reset(pcdev->dev, 1); } @@ -507,12 +507,12 @@ static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev) if (board && board->reset) { dev_dbg(pcdev->dev, "%s: Asserting camera reset\n", - __FUNCTION__); + __func__); board->reset(pcdev->dev, 0); } if (board && board->power) { - dev_dbg(pcdev->dev, "%s: Power off camera\n", __FUNCTION__); + dev_dbg(pcdev->dev, "%s: Power off camera\n", __func__); board->power(pcdev->dev, 0); } } diff --git a/linux/drivers/media/video/saa7110.c b/linux/drivers/media/video/saa7110.c index eb561ce6c..0692e4bef 100644 --- a/linux/drivers/media/video/saa7110.c +++ b/linux/drivers/media/video/saa7110.c @@ -489,7 +489,7 @@ saa7110_detect_client (struct i2c_adapter *adapter, return 0; client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == 0) + if (!client) return -ENOMEM; client->addr = address; client->adapter = adapter; @@ -497,7 +497,7 @@ saa7110_detect_client (struct i2c_adapter *adapter, strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client))); decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL); - if (decoder == 0) { + if (!decoder) { kfree(client); return -ENOMEM; } diff --git a/linux/drivers/media/video/saa7111.c b/linux/drivers/media/video/saa7111.c index df44aed92..917fb2553 100644 --- a/linux/drivers/media/video/saa7111.c +++ b/linux/drivers/media/video/saa7111.c @@ -503,7 +503,7 @@ saa7111_detect_client (struct i2c_adapter *adapter, return 0; client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == 0) + if (!client) return -ENOMEM; client->addr = address; client->adapter = adapter; diff --git a/linux/drivers/media/video/saa7114.c b/linux/drivers/media/video/saa7114.c index ebf42cf9e..158bd123c 100644 --- a/linux/drivers/media/video/saa7114.c +++ b/linux/drivers/media/video/saa7114.c @@ -842,7 +842,7 @@ saa7114_detect_client (struct i2c_adapter *adapter, return 0; client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == 0) + if (!client) return -ENOMEM; client->addr = address; client->adapter = adapter; diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c index 165b4b850..fd92ef654 100644 --- a/linux/drivers/media/video/saa7134/saa7134-dvb.c +++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c @@ -65,6 +65,8 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off module debugging (default:off)."); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + #define dprintk(fmt, arg...) do { if (debug) \ printk(KERN_DEBUG "%s/dvb: " fmt, dev->name , ## arg); } while(0) @@ -852,6 +854,14 @@ static struct tda10086_config flydvbs = { .demod_address = 0x0e, .invert = 0, .diseqc_tone = 0, + .xtal_freq = TDA10086_XTAL_16M, +}; + +static struct tda10086_config sd1878_4m = { + .demod_address = 0x0e, + .invert = 0, + .diseqc_tone = 0, + .xtal_freq = TDA10086_XTAL_4M, }; /* ------------------------------------------------------------------ @@ -1211,7 +1221,7 @@ static int dvb_init(struct saa7134_dev *dev) break; case SAA7134_BOARD_MD7134_BRIDGE_2: dev->dvb.frontend = dvb_attach(tda10086_attach, - &flydvbs, &dev->i2c_adap); + &sd1878_4m, &dev->i2c_adap); if (dev->dvb.frontend) { struct dvb_frontend *fe; if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, @@ -1264,7 +1274,8 @@ static int dvb_init(struct saa7134_dev *dev) } /* register everything else */ - ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev); + ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev, + adapter_nr); /* this sequence is necessary to make the tda1004x load its firmware * and to enter analog mode of hybrid boards @@ -1309,7 +1320,8 @@ static int dvb_fini(struct saa7134_dev *dev) } } } - videobuf_dvb_unregister(&dev->dvb); + if (dev->dvb.frontend) + videobuf_dvb_unregister(&dev->dvb); return 0; } diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index b83e910c3..6688970cf 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -419,7 +419,7 @@ static int empress_init(struct saa7134_dev *dev) { int err; - dprintk("%s: %s\n",dev->name,__FUNCTION__); + dprintk("%s: %s\n",dev->name,__func__); dev->empress_dev = video_device_alloc(); if (NULL == dev->empress_dev) return -ENOMEM; @@ -467,7 +467,7 @@ static int empress_init(struct saa7134_dev *dev) static int empress_fini(struct saa7134_dev *dev) { - dprintk("%s: %s\n",dev->name,__FUNCTION__); + dprintk("%s: %s\n",dev->name,__func__); if (NULL == dev->empress_dev) return 0; diff --git a/linux/drivers/media/video/saa717x.c b/linux/drivers/media/video/saa717x.c new file mode 100644 index 000000000..bdae62189 --- /dev/null +++ b/linux/drivers/media/video/saa717x.c @@ -0,0 +1,1534 @@ +/* + * saa717x - Philips SAA717xHL video decoder driver + * + * Based on the saa7115 driver + * + * Changes by Ohta Kyuma <alpha292@bremen.or.jp> + * - Apply to SAA717x,NEC uPD64031,uPD64083. (1/31/2004) + * + * Changes by T.Adachi (tadachi@tadachi-net.com) + * - support audio, video scaler etc, and checked the initialize sequence. + * + * Cleaned up by Hans Verkuil <hverkuil@xs4all.nl> + * + * Note: this is a reversed engineered driver based on captures from + * the I2C bus under Windows. This chip is very similar to the saa7134, + * though. Unfortunately, this driver is currently only working for NTSC. + * + * 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. + */ + +#include <linux/version.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> + +#include <linux/videodev.h> +#include <linux/videodev2.h> +#include <linux/i2c.h> +#include <media/v4l2-common.h> +#include <media/v4l2-i2c-drv.h> +#include "compat.h" + +MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver"); +MODULE_AUTHOR("K. Ohta, T. Adachi, Hans Verkuil"); +MODULE_LICENSE("GPL"); + +static int debug; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +module_param(debug, int, 0644); +#else +MODULE_PARM(debug, "i"); +#endif +MODULE_PARM_DESC(debug, "Debug level (0-1)"); + +/* + * Generic i2c probe + * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22) +static unsigned short normal_i2c[] = { 0x42 >> 1, I2C_CLIENT_END }; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) +static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; +#endif + +I2C_CLIENT_INSMOD; +#endif + +struct saa717x_state { + v4l2_std_id std; + int input; + int enable; + int radio; + int bright; + int contrast; + int hue; + int sat; + int playback; + int audio; + int tuner_audio_mode; + int audio_main_mute; + int audio_main_vol_r; + int audio_main_vol_l; + u16 audio_main_bass; + u16 audio_main_treble; + u16 audio_main_volume; + u16 audio_main_balance; + int audio_input; +}; + +/* ----------------------------------------------------------------------- */ + +/* for audio mode */ +#define TUNER_AUDIO_MONO 0 /* LL */ +#define TUNER_AUDIO_STEREO 1 /* LR */ +#define TUNER_AUDIO_LANG1 2 /* LL */ +#define TUNER_AUDIO_LANG2 3 /* RR */ + +#define SAA717X_NTSC_WIDTH (704) +#define SAA717X_NTSC_HEIGHT (480) + +/* ----------------------------------------------------------------------- */ + +static int saa717x_write(struct i2c_client *client, u32 reg, u32 value) +{ + struct i2c_adapter *adap = client->adapter; + int fw_addr = reg == 0x454 || (reg >= 0x464 && reg <= 0x478) || reg == 0x480 || reg == 0x488; + unsigned char mm1[6]; + struct i2c_msg msg; + + msg.flags = 0; + msg.addr = client->addr; + mm1[0] = (reg >> 8) & 0xff; + mm1[1] = reg & 0xff; + + if (fw_addr) { + mm1[4] = (value >> 16) & 0xff; + mm1[3] = (value >> 8) & 0xff; + mm1[2] = value & 0xff; + } else { + mm1[2] = value & 0xff; + } + msg.len = fw_addr ? 5 : 3; /* Long Registers have *only* three bytes! */ + msg.buf = mm1; + v4l_dbg(2, debug, client, "wrote: reg 0x%03x=%08x\n", reg, value); + return i2c_transfer(adap, &msg, 1) == 1; +} + +static void saa717x_write_regs(struct i2c_client *client, u32 *data) +{ + while (data[0] || data[1]) { + saa717x_write(client, data[0], data[1]); + data += 2; + } +} + +static u32 saa717x_read(struct i2c_client *client, u32 reg) +{ + struct i2c_adapter *adap = client->adapter; + int fw_addr = (reg >= 0x404 && reg <= 0x4b8) || reg == 0x528; + unsigned char mm1[2]; + unsigned char mm2[4] = { 0, 0, 0, 0 }; + struct i2c_msg msgs[2]; + u32 value; + + msgs[0].flags = 0; + msgs[1].flags = I2C_M_RD; + msgs[0].addr = msgs[1].addr = client->addr; + mm1[0] = (reg >> 8) & 0xff; + mm1[1] = reg & 0xff; + msgs[0].len = 2; + msgs[0].buf = mm1; + msgs[1].len = fw_addr ? 3 : 1; /* Multibyte Registers contains *only* 3 bytes */ + msgs[1].buf = mm2; + i2c_transfer(adap, msgs, 2); + + if (fw_addr) + value = (mm2[2] & 0xff) | ((mm2[1] & 0xff) >> 8) | ((mm2[0] & 0xff) >> 16); + else + value = mm2[0] & 0xff; + + v4l_dbg(2, debug, client, "read: reg 0x%03x=0x%08x\n", reg, value); + return value; +} + +/* ----------------------------------------------------------------------- */ + +static u32 reg_init_initialize[] = +{ + /* from linux driver */ + 0x101, 0x008, /* Increment delay */ + + 0x103, 0x000, /* Analog input control 2 */ + 0x104, 0x090, /* Analog input control 3 */ + 0x105, 0x090, /* Analog input control 4 */ + 0x106, 0x0eb, /* Horizontal sync start */ + 0x107, 0x0e0, /* Horizontal sync stop */ + 0x109, 0x055, /* Luminance control */ + + 0x10f, 0x02a, /* Chroma gain control */ + 0x110, 0x000, /* Chroma control 2 */ + + 0x114, 0x045, /* analog/ADC */ + + 0x118, 0x040, /* RAW data gain */ + 0x119, 0x080, /* RAW data offset */ + + 0x044, 0x000, /* VBI horizontal input window start (L) TASK A */ + 0x045, 0x000, /* VBI horizontal input window start (H) TASK A */ + 0x046, 0x0cf, /* VBI horizontal input window stop (L) TASK A */ + 0x047, 0x002, /* VBI horizontal input window stop (H) TASK A */ + + 0x049, 0x000, /* VBI vertical input window start (H) TASK A */ + + 0x04c, 0x0d0, /* VBI horizontal output length (L) TASK A */ + 0x04d, 0x002, /* VBI horizontal output length (H) TASK A */ + + 0x064, 0x080, /* Lumina brightness TASK A */ + 0x065, 0x040, /* Luminance contrast TASK A */ + 0x066, 0x040, /* Chroma saturation TASK A */ + /* 067H: Reserved */ + 0x068, 0x000, /* VBI horizontal scaling increment (L) TASK A */ + 0x069, 0x004, /* VBI horizontal scaling increment (H) TASK A */ + 0x06a, 0x000, /* VBI phase offset TASK A */ + + 0x06e, 0x000, /* Horizontal phase offset Luma TASK A */ + 0x06f, 0x000, /* Horizontal phase offset Chroma TASK A */ + + 0x072, 0x000, /* Vertical filter mode TASK A */ + + 0x084, 0x000, /* VBI horizontal input window start (L) TAKS B */ + 0x085, 0x000, /* VBI horizontal input window start (H) TAKS B */ + 0x086, 0x0cf, /* VBI horizontal input window stop (L) TAKS B */ + 0x087, 0x002, /* VBI horizontal input window stop (H) TAKS B */ + + 0x089, 0x000, /* VBI vertical input window start (H) TAKS B */ + + 0x08c, 0x0d0, /* VBI horizontal output length (L) TASK B */ + 0x08d, 0x002, /* VBI horizontal output length (H) TASK B */ + + 0x0a4, 0x080, /* Lumina brightness TASK B */ + 0x0a5, 0x040, /* Luminance contrast TASK B */ + 0x0a6, 0x040, /* Chroma saturation TASK B */ + /* 0A7H reserved */ + 0x0a8, 0x000, /* VBI horizontal scaling increment (L) TASK B */ + 0x0a9, 0x004, /* VBI horizontal scaling increment (H) TASK B */ + 0x0aa, 0x000, /* VBI phase offset TASK B */ + + 0x0ae, 0x000, /* Horizontal phase offset Luma TASK B */ + 0x0af, 0x000, /*Horizontal phase offset Chroma TASK B */ + + 0x0b2, 0x000, /* Vertical filter mode TASK B */ + + 0x00c, 0x000, /* Start point GREEN path */ + 0x00d, 0x000, /* Start point BLUE path */ + 0x00e, 0x000, /* Start point RED path */ + + 0x010, 0x010, /* GREEN path gamma curve --- */ + 0x011, 0x020, + 0x012, 0x030, + 0x013, 0x040, + 0x014, 0x050, + 0x015, 0x060, + 0x016, 0x070, + 0x017, 0x080, + 0x018, 0x090, + 0x019, 0x0a0, + 0x01a, 0x0b0, + 0x01b, 0x0c0, + 0x01c, 0x0d0, + 0x01d, 0x0e0, + 0x01e, 0x0f0, + 0x01f, 0x0ff, /* --- GREEN path gamma curve */ + + 0x020, 0x010, /* BLUE path gamma curve --- */ + 0x021, 0x020, + 0x022, 0x030, + 0x023, 0x040, + 0x024, 0x050, + 0x025, 0x060, + 0x026, 0x070, + 0x027, 0x080, + 0x028, 0x090, + 0x029, 0x0a0, + 0x02a, 0x0b0, + 0x02b, 0x0c0, + 0x02c, 0x0d0, + 0x02d, 0x0e0, + 0x02e, 0x0f0, + 0x02f, 0x0ff, /* --- BLUE path gamma curve */ + + 0x030, 0x010, /* RED path gamma curve --- */ + 0x031, 0x020, + 0x032, 0x030, + 0x033, 0x040, + 0x034, 0x050, + 0x035, 0x060, + 0x036, 0x070, + 0x037, 0x080, + 0x038, 0x090, + 0x039, 0x0a0, + 0x03a, 0x0b0, + 0x03b, 0x0c0, + 0x03c, 0x0d0, + 0x03d, 0x0e0, + 0x03e, 0x0f0, + 0x03f, 0x0ff, /* --- RED path gamma curve */ + + 0x109, 0x085, /* Luminance control */ + + /**** from app start ****/ + 0x584, 0x000, /* AGC gain control */ + 0x585, 0x000, /* Program count */ + 0x586, 0x003, /* Status reset */ + 0x588, 0x0ff, /* Number of audio samples (L) */ + 0x589, 0x00f, /* Number of audio samples (M) */ + 0x58a, 0x000, /* Number of audio samples (H) */ + 0x58b, 0x000, /* Audio select */ + 0x58c, 0x010, /* Audio channel assign1 */ + 0x58d, 0x032, /* Audio channel assign2 */ + 0x58e, 0x054, /* Audio channel assign3 */ + 0x58f, 0x023, /* Audio format */ + 0x590, 0x000, /* SIF control */ + + 0x595, 0x000, /* ?? */ + 0x596, 0x000, /* ?? */ + 0x597, 0x000, /* ?? */ + + 0x464, 0x00, /* Digital input crossbar1 */ + + 0x46c, 0xbbbb10, /* Digital output selection1-3 */ + 0x470, 0x101010, /* Digital output selection4-6 */ + + 0x478, 0x00, /* Sound feature control */ + + 0x474, 0x18, /* Softmute control */ + + 0x454, 0x0425b9, /* Sound Easy programming(reset) */ + 0x454, 0x042539, /* Sound Easy programming(reset) */ + + + /**** common setting( of DVD play, including scaler commands) ****/ + 0x042, 0x003, /* Data path configuration for VBI (TASK A) */ + + 0x082, 0x003, /* Data path configuration for VBI (TASK B) */ + + 0x108, 0x0f8, /* Sync control */ + 0x2a9, 0x0fd, /* ??? */ + 0x102, 0x089, /* select video input "mode 9" */ + 0x111, 0x000, /* Mode/delay control */ + + 0x10e, 0x00a, /* Chroma control 1 */ + + 0x594, 0x002, /* SIF, analog I/O select */ + + 0x454, 0x0425b9, /* Sound */ + 0x454, 0x042539, + + 0x111, 0x000, + 0x10e, 0x00a, + 0x464, 0x000, + 0x300, 0x000, + 0x301, 0x006, + 0x302, 0x000, + 0x303, 0x006, + 0x308, 0x040, + 0x309, 0x000, + 0x30a, 0x000, + 0x30b, 0x000, + 0x000, 0x002, + 0x001, 0x000, + 0x002, 0x000, + 0x003, 0x000, + 0x004, 0x033, + 0x040, 0x01d, + 0x041, 0x001, + 0x042, 0x004, + 0x043, 0x000, + 0x080, 0x01e, + 0x081, 0x001, + 0x082, 0x004, + 0x083, 0x000, + 0x190, 0x018, + 0x115, 0x000, + 0x116, 0x012, + 0x117, 0x018, + 0x04a, 0x011, + 0x08a, 0x011, + 0x04b, 0x000, + 0x08b, 0x000, + 0x048, 0x000, + 0x088, 0x000, + 0x04e, 0x012, + 0x08e, 0x012, + 0x058, 0x012, + 0x098, 0x012, + 0x059, 0x000, + 0x099, 0x000, + 0x05a, 0x003, + 0x09a, 0x003, + 0x05b, 0x001, + 0x09b, 0x001, + 0x054, 0x008, + 0x094, 0x008, + 0x055, 0x000, + 0x095, 0x000, + 0x056, 0x0c7, + 0x096, 0x0c7, + 0x057, 0x002, + 0x097, 0x002, + 0x0ff, 0x0ff, + 0x060, 0x001, + 0x0a0, 0x001, + 0x061, 0x000, + 0x0a1, 0x000, + 0x062, 0x000, + 0x0a2, 0x000, + 0x063, 0x000, + 0x0a3, 0x000, + 0x070, 0x000, + 0x0b0, 0x000, + 0x071, 0x004, + 0x0b1, 0x004, + 0x06c, 0x0e9, + 0x0ac, 0x0e9, + 0x06d, 0x003, + 0x0ad, 0x003, + 0x05c, 0x0d0, + 0x09c, 0x0d0, + 0x05d, 0x002, + 0x09d, 0x002, + 0x05e, 0x0f2, + 0x09e, 0x0f2, + 0x05f, 0x000, + 0x09f, 0x000, + 0x074, 0x000, + 0x0b4, 0x000, + 0x075, 0x000, + 0x0b5, 0x000, + 0x076, 0x000, + 0x0b6, 0x000, + 0x077, 0x000, + 0x0b7, 0x000, + 0x195, 0x008, + 0x0ff, 0x0ff, + 0x108, 0x0f8, + 0x111, 0x000, + 0x10e, 0x00a, + 0x2a9, 0x0fd, + 0x464, 0x001, + 0x454, 0x042135, + 0x598, 0x0e7, + 0x599, 0x07d, + 0x59a, 0x018, + 0x59c, 0x066, + 0x59d, 0x090, + 0x59e, 0x001, + 0x584, 0x000, + 0x585, 0x000, + 0x586, 0x003, + 0x588, 0x0ff, + 0x589, 0x00f, + 0x58a, 0x000, + 0x58b, 0x000, + 0x58c, 0x010, + 0x58d, 0x032, + 0x58e, 0x054, + 0x58f, 0x023, + 0x590, 0x000, + 0x595, 0x000, + 0x596, 0x000, + 0x597, 0x000, + 0x464, 0x000, + 0x46c, 0xbbbb10, + 0x470, 0x101010, + + + 0x478, 0x000, + 0x474, 0x018, + 0x454, 0x042135, + 0x598, 0x0e7, + 0x599, 0x07d, + 0x59a, 0x018, + 0x59c, 0x066, + 0x59d, 0x090, + 0x59e, 0x001, + 0x584, 0x000, + 0x585, 0x000, + 0x586, 0x003, + 0x588, 0x0ff, + 0x589, 0x00f, + 0x58a, 0x000, + 0x58b, 0x000, + 0x58c, 0x010, + 0x58d, 0x032, + 0x58e, 0x054, + 0x58f, 0x023, + 0x590, 0x000, + 0x595, 0x000, + 0x596, 0x000, + 0x597, 0x000, + 0x464, 0x000, + 0x46c, 0xbbbb10, + 0x470, 0x101010, + + 0x478, 0x000, + 0x474, 0x018, + 0x454, 0x042135, + 0x598, 0x0e7, + 0x599, 0x07d, + 0x59a, 0x018, + 0x59c, 0x066, + 0x59d, 0x090, + 0x59e, 0x001, + 0x584, 0x000, + 0x585, 0x000, + 0x586, 0x003, + 0x588, 0x0ff, + 0x589, 0x00f, + 0x58a, 0x000, + 0x58b, 0x000, + 0x58c, 0x010, + 0x58d, 0x032, + 0x58e, 0x054, + 0x58f, 0x023, + 0x590, 0x000, + 0x595, 0x000, + 0x596, 0x000, + 0x597, 0x000, + 0x464, 0x000, + 0x46c, 0xbbbb10, + 0x470, 0x101010, + 0x478, 0x000, + 0x474, 0x018, + 0x454, 0x042135, + 0x193, 0x000, + 0x300, 0x000, + 0x301, 0x006, + 0x302, 0x000, + 0x303, 0x006, + 0x308, 0x040, + 0x309, 0x000, + 0x30a, 0x000, + 0x30b, 0x000, + 0x000, 0x002, + 0x001, 0x000, + 0x002, 0x000, + 0x003, 0x000, + 0x004, 0x033, + 0x040, 0x01d, + 0x041, 0x001, + 0x042, 0x004, + 0x043, 0x000, + 0x080, 0x01e, + 0x081, 0x001, + 0x082, 0x004, + 0x083, 0x000, + 0x190, 0x018, + 0x115, 0x000, + 0x116, 0x012, + 0x117, 0x018, + 0x04a, 0x011, + 0x08a, 0x011, + 0x04b, 0x000, + 0x08b, 0x000, + 0x048, 0x000, + 0x088, 0x000, + 0x04e, 0x012, + 0x08e, 0x012, + 0x058, 0x012, + 0x098, 0x012, + 0x059, 0x000, + 0x099, 0x000, + 0x05a, 0x003, + 0x09a, 0x003, + 0x05b, 0x001, + 0x09b, 0x001, + 0x054, 0x008, + 0x094, 0x008, + 0x055, 0x000, + 0x095, 0x000, + 0x056, 0x0c7, + 0x096, 0x0c7, + 0x057, 0x002, + 0x097, 0x002, + 0x060, 0x001, + 0x0a0, 0x001, + 0x061, 0x000, + 0x0a1, 0x000, + 0x062, 0x000, + 0x0a2, 0x000, + 0x063, 0x000, + 0x0a3, 0x000, + 0x070, 0x000, + 0x0b0, 0x000, + 0x071, 0x004, + 0x0b1, 0x004, + 0x06c, 0x0e9, + 0x0ac, 0x0e9, + 0x06d, 0x003, + 0x0ad, 0x003, + 0x05c, 0x0d0, + 0x09c, 0x0d0, + 0x05d, 0x002, + 0x09d, 0x002, + 0x05e, 0x0f2, + 0x09e, 0x0f2, + 0x05f, 0x000, + 0x09f, 0x000, + 0x074, 0x000, + 0x0b4, 0x000, + 0x075, 0x000, + 0x0b5, 0x000, + 0x076, 0x000, + 0x0b6, 0x000, + 0x077, 0x000, + 0x0b7, 0x000, + 0x195, 0x008, + 0x598, 0x0e7, + 0x599, 0x07d, + 0x59a, 0x018, + 0x59c, 0x066, + 0x59d, 0x090, + 0x59e, 0x001, + 0x584, 0x000, + 0x585, 0x000, + 0x586, 0x003, + 0x588, 0x0ff, + 0x589, 0x00f, + 0x58a, 0x000, + 0x58b, 0x000, + 0x58c, 0x010, + 0x58d, 0x032, + 0x58e, 0x054, + 0x58f, 0x023, + 0x590, 0x000, + 0x595, 0x000, + 0x596, 0x000, + 0x597, 0x000, + 0x464, 0x000, + 0x46c, 0xbbbb10, + 0x470, 0x101010, + 0x478, 0x000, + 0x474, 0x018, + 0x454, 0x042135, + 0x193, 0x0a6, + 0x108, 0x0f8, + 0x042, 0x003, + 0x082, 0x003, + 0x454, 0x0425b9, + 0x454, 0x042539, + 0x193, 0x000, + 0x193, 0x0a6, + 0x464, 0x000, + + 0, 0 +}; + +/* Tuner */ +static u32 reg_init_tuner_input[] = { + 0x108, 0x0f8, /* Sync control */ + 0x111, 0x000, /* Mode/delay control */ + 0x10e, 0x00a, /* Chroma control 1 */ + 0, 0 +}; + +/* Composite */ +static u32 reg_init_composite_input[] = { + 0x108, 0x0e8, /* Sync control */ + 0x111, 0x000, /* Mode/delay control */ + 0x10e, 0x04a, /* Chroma control 1 */ + 0, 0 +}; + +/* S-Video */ +static u32 reg_init_svideo_input[] = { + 0x108, 0x0e8, /* Sync control */ + 0x111, 0x000, /* Mode/delay control */ + 0x10e, 0x04a, /* Chroma control 1 */ + 0, 0 +}; + +static u32 reg_set_audio_template[4][2] = +{ + { /* for MONO + tadachi 6/29 DMA audio output select? + Register 0x46c + 7-4: DMA2, 3-0: DMA1 ch. DMA4, DMA3 DMA2, DMA1 + 0: MAIN left, 1: MAIN right + 2: AUX1 left, 3: AUX1 right + 4: AUX2 left, 5: AUX2 right + 6: DPL left, 7: DPL right + 8: DPL center, 9: DPL surround + A: monitor output, B: digital sense */ + 0xbbbb00, + + /* tadachi 6/29 DAC and I2S output select? + Register 0x470 + 7-4:DAC right ch. 3-0:DAC left ch. + I2S1 right,left I2S2 right,left */ + 0x00, + }, + { /* for STEREO */ + 0xbbbb10, 0x101010, + }, + { /* for LANG1 */ + 0xbbbb00, 0x00, + }, + { /* for LANG2/SAP */ + 0xbbbb11, 0x111111, + } +}; + + +/* Get detected audio flags (from saa7134 driver) */ +static void get_inf_dev_status(struct i2c_client *client, + int *dual_flag, int *stereo_flag) +{ + u32 reg_data3; + + static char *stdres[0x20] = { + [0x00] = "no standard detected", + [0x01] = "B/G (in progress)", + [0x02] = "D/K (in progress)", + [0x03] = "M (in progress)", + + [0x04] = "B/G A2", + [0x05] = "B/G NICAM", + [0x06] = "D/K A2 (1)", + [0x07] = "D/K A2 (2)", + [0x08] = "D/K A2 (3)", + [0x09] = "D/K NICAM", + [0x0a] = "L NICAM", + [0x0b] = "I NICAM", + + [0x0c] = "M Korea", + [0x0d] = "M BTSC ", + [0x0e] = "M EIAJ", + + [0x0f] = "FM radio / IF 10.7 / 50 deemp", + [0x10] = "FM radio / IF 10.7 / 75 deemp", + [0x11] = "FM radio / IF sel / 50 deemp", + [0x12] = "FM radio / IF sel / 75 deemp", + + [0x13 ... 0x1e] = "unknown", + [0x1f] = "??? [in progress]", + }; + + + *dual_flag = *stereo_flag = 0; + + /* (demdec status: 0x528) */ + + /* read current status */ + reg_data3 = saa717x_read(client, 0x0528); + + v4l_dbg(1, debug, client, "tvaudio thread status: 0x%x [%s%s%s]\n", + reg_data3, stdres[reg_data3 & 0x1f], + (reg_data3 & 0x000020) ? ",stereo" : "", + (reg_data3 & 0x000040) ? ",dual" : ""); + v4l_dbg(1, debug, client, "detailed status: " + "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n", + (reg_data3 & 0x000080) ? " A2/EIAJ pilot tone " : "", + (reg_data3 & 0x000100) ? " A2/EIAJ dual " : "", + (reg_data3 & 0x000200) ? " A2/EIAJ stereo " : "", + (reg_data3 & 0x000400) ? " A2/EIAJ noise mute " : "", + + (reg_data3 & 0x000800) ? " BTSC/FM radio pilot " : "", + (reg_data3 & 0x001000) ? " SAP carrier " : "", + (reg_data3 & 0x002000) ? " BTSC stereo noise mute " : "", + (reg_data3 & 0x004000) ? " SAP noise mute " : "", + (reg_data3 & 0x008000) ? " VDSP " : "", + + (reg_data3 & 0x010000) ? " NICST " : "", + (reg_data3 & 0x020000) ? " NICDU " : "", + (reg_data3 & 0x040000) ? " NICAM muted " : "", + (reg_data3 & 0x080000) ? " NICAM reserve sound " : "", + + (reg_data3 & 0x100000) ? " init done " : ""); + + if (reg_data3 & 0x000220) { + v4l_dbg(1, debug, client, "ST!!!\n"); + *stereo_flag = 1; + } + + if (reg_data3 & 0x000140) { + v4l_dbg(1, debug, client, "DUAL!!!\n"); + *dual_flag = 1; + } +} + +/* regs write to set audio mode */ +static void set_audio_mode(struct i2c_client *client, int audio_mode) +{ + v4l_dbg(1, debug, client, "writing registers to set audio mode by set %d\n", + audio_mode); + + saa717x_write(client, 0x46c, reg_set_audio_template[audio_mode][0]); + saa717x_write(client, 0x470, reg_set_audio_template[audio_mode][1]); +} + +/* write regs to video output level (bright,contrast,hue,sat) */ +static void set_video_output_level_regs(struct i2c_client *client, + struct saa717x_state *decoder) +{ + /* brightness ffh (bright) - 80h (ITU level) - 00h (dark) */ + saa717x_write(client, 0x10a, decoder->bright); + + /* contrast 7fh (max: 1.984) - 44h (ITU) - 40h (1.0) - + 0h (luminance off) 40: i2c dump + c0h (-1.0 inverse chrominance) + 80h (-2.0 inverse chrominance) */ + saa717x_write(client, 0x10b, decoder->contrast); + + /* saturation? 7fh(max)-40h(ITU)-0h(color off) + c0h (-1.0 inverse chrominance) + 80h (-2.0 inverse chrominance) */ + saa717x_write(client, 0x10c, decoder->sat); + + /* color hue (phase) control + 7fh (+178.6) - 0h (0 normal) - 80h (-180.0) */ + saa717x_write(client, 0x10d, decoder->hue); +} + +/* write regs to set audio volume, bass and treble */ +static int set_audio_regs(struct i2c_client *client, + struct saa717x_state *decoder) +{ + u8 mute = 0xac; /* -84 dB */ + u32 val; + unsigned int work_l, work_r; + + /* set SIF analog I/O select */ + saa717x_write(client, 0x0594, decoder->audio_input); + v4l_dbg(1, debug, client, "set audio input %d\n", + decoder->audio_input); + + /* normalize ( 65535 to 0 -> 24 to -40 (not -84)) */ + work_l = (min(65536 - decoder->audio_main_balance, 32768) * decoder->audio_main_volume) / 32768; + work_r = (min(decoder->audio_main_balance, (u16)32768) * decoder->audio_main_volume) / 32768; + decoder->audio_main_vol_l = (long)work_l * (24 - (-40)) / 65535 - 40; + decoder->audio_main_vol_r = (long)work_r * (24 - (-40)) / 65535 - 40; + + /* set main volume */ + /* main volume L[7-0],R[7-0],0x00 24=24dB,-83dB, -84(mute) */ + /* def:0dB->6dB(MPG600GR) */ + /* if mute is on, set mute */ + if (decoder->audio_main_mute) { + val = mute | (mute << 8); + } else { + val = (u8)decoder->audio_main_vol_l | + ((u8)decoder->audio_main_vol_r << 8); + } + + saa717x_write(client, 0x480, val); + + /* bass and treble; go to another function */ + /* set bass and treble */ + val = decoder->audio_main_bass | (decoder->audio_main_treble << 8); + saa717x_write(client, 0x488, val); + return 0; +} + +/********** scaling staff ***********/ +static void set_h_prescale(struct i2c_client *client, + int task, int prescale) +{ + static const struct { + int xpsc; + int xacl; + int xc2_1; + int xdcg; + int vpfy; + } vals[] = { + /* XPSC XACL XC2_1 XDCG VPFY */ + { 1, 0, 0, 0, 0 }, + { 2, 2, 1, 2, 2 }, + { 3, 4, 1, 3, 2 }, + { 4, 8, 1, 4, 2 }, + { 5, 8, 1, 4, 2 }, + { 6, 8, 1, 4, 3 }, + { 7, 8, 1, 4, 3 }, + { 8, 15, 0, 4, 3 }, + { 9, 15, 0, 4, 3 }, + { 10, 16, 1, 5, 3 }, + }; + static const int count = ARRAY_SIZE(vals); + int i, task_shift; + + task_shift = task * 0x40; + for (i = 0; i < count; i++) + if (vals[i].xpsc == prescale) + break; + if (i == count) + return; + + /* horizonal prescaling */ + saa717x_write(client, 0x60 + task_shift, vals[i].xpsc); + /* accumulation length */ + saa717x_write(client, 0x61 + task_shift, vals[i].xacl); + /* level control */ + saa717x_write(client, 0x62 + task_shift, + (vals[i].xc2_1 << 3) | vals[i].xdcg); + /*FIR prefilter control */ + saa717x_write(client, 0x63 + task_shift, + (vals[i].vpfy << 2) | vals[i].vpfy); +} + +/********** scaling staff ***********/ +static void set_v_scale(struct i2c_client *client, int task, int yscale) +{ + int task_shift; + + task_shift = task * 0x40; + /* Vertical scaling ratio (LOW) */ + saa717x_write(client, 0x70 + task_shift, yscale & 0xff); + /* Vertical scaling ratio (HI) */ + saa717x_write(client, 0x71 + task_shift, yscale >> 8); +} + +static int saa717x_set_audio_clock_freq(struct i2c_client *client, u32 freq) +{ + /* not yet implament, so saa717x_cfg_??hz_??_audio is not defined. */ + return 0; +} + +static int saa717x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) +{ + struct saa717x_state *state = i2c_get_clientdata(client); + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + if (ctrl->value < 0 || ctrl->value > 255) { + v4l_err(client, "invalid brightness setting %d\n", ctrl->value); + return -ERANGE; + } + + state->bright = ctrl->value; + v4l_dbg(1, debug, client, "bright:%d\n", state->bright); + saa717x_write(client, 0x10a, state->bright); + break; + + case V4L2_CID_CONTRAST: + if (ctrl->value < 0 || ctrl->value > 127) { + v4l_err(client, "invalid contrast setting %d\n", ctrl->value); + return -ERANGE; + } + + state->contrast = ctrl->value; + v4l_dbg(1, debug, client, "contrast:%d\n", state->contrast); + saa717x_write(client, 0x10b, state->contrast); + break; + + case V4L2_CID_SATURATION: + if (ctrl->value < 0 || ctrl->value > 127) { + v4l_err(client, "invalid saturation setting %d\n", ctrl->value); + return -ERANGE; + } + + state->sat = ctrl->value; + v4l_dbg(1, debug, client, "sat:%d\n", state->sat); + saa717x_write(client, 0x10c, state->sat); + break; + + case V4L2_CID_HUE: + if (ctrl->value < -127 || ctrl->value > 127) { + v4l_err(client, "invalid hue setting %d\n", ctrl->value); + return -ERANGE; + } + + state->hue = ctrl->value; + v4l_dbg(1, debug, client, "hue:%d\n", state->hue); + saa717x_write(client, 0x10d, state->hue); + break; + + case V4L2_CID_AUDIO_MUTE: + state->audio_main_mute = ctrl->value; + set_audio_regs(client, state); + break; + + case V4L2_CID_AUDIO_VOLUME: + state->audio_main_volume = ctrl->value; + set_audio_regs(client, state); + break; + + case V4L2_CID_AUDIO_BALANCE: + state->audio_main_balance = ctrl->value; + set_audio_regs(client, state); + break; + + case V4L2_CID_AUDIO_TREBLE: + state->audio_main_treble = ctrl->value; + set_audio_regs(client, state); + break; + + case V4L2_CID_AUDIO_BASS: + state->audio_main_bass = ctrl->value; + set_audio_regs(client, state); + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int saa717x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) +{ + struct saa717x_state *state = i2c_get_clientdata(client); + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = state->bright; + break; + + case V4L2_CID_CONTRAST: + ctrl->value = state->contrast; + break; + + case V4L2_CID_SATURATION: + ctrl->value = state->sat; + break; + + case V4L2_CID_HUE: + ctrl->value = state->hue; + break; + + case V4L2_CID_AUDIO_MUTE: + ctrl->value = state->audio_main_mute; + break; + + case V4L2_CID_AUDIO_VOLUME: + ctrl->value = state->audio_main_volume; + break; + + case V4L2_CID_AUDIO_BALANCE: + ctrl->value = state->audio_main_balance; + break; + + case V4L2_CID_AUDIO_TREBLE: + ctrl->value = state->audio_main_treble; + break; + + case V4L2_CID_AUDIO_BASS: + ctrl->value = state->audio_main_bass; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static struct v4l2_queryctrl saa717x_qctrl[] = { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 128, + .flags = 0, + }, { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 64, + .flags = 0, + }, { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 64, + .flags = 0, + }, { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = -128, + .maximum = 127, + .step = 1, + .default_value = 0, + .flags = 0, + }, { + .id = V4L2_CID_AUDIO_VOLUME, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Volume", + .minimum = 0, + .maximum = 65535, + .step = 65535 / 100, + .default_value = 58880, + .flags = 0, + }, { + .id = V4L2_CID_AUDIO_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Balance", + .minimum = 0, + .maximum = 65535, + .step = 65535 / 100, + .default_value = 32768, + .flags = 0, + }, { + .id = V4L2_CID_AUDIO_MUTE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + .flags = 0, + }, { + .id = V4L2_CID_AUDIO_BASS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Bass", + .minimum = 0, + .maximum = 65535, + .step = 65535 / 100, + .default_value = 32768, + }, { + .id = V4L2_CID_AUDIO_TREBLE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Treble", + .minimum = 0, + .maximum = 65535, + .step = 65535 / 100, + .default_value = 32768, + }, +}; + +static int saa717x_set_video_input(struct i2c_client *client, struct saa717x_state *decoder, int inp) +{ + int is_tuner = inp & 0x80; /* tuner input flag */ + + inp &= 0x7f; + + v4l_dbg(1, debug, client, "decoder set input (%d)\n", inp); + /* inputs from 0-9 are available*/ + /* saa717x have mode0-mode9 but mode5 is reserved. */ + if (inp < 0 || inp > 9 || inp == 5) + return -EINVAL; + + if (decoder->input != inp) { + int input_line = inp; + + decoder->input = input_line; + v4l_dbg(1, debug, client, "now setting %s input %d\n", + input_line >= 6 ? "S-Video" : "Composite", + input_line); + + /* select mode */ + saa717x_write(client, 0x102, + (saa717x_read(client, 0x102) & 0xf0) | + input_line); + + /* bypass chrominance trap for modes 6..9 */ + saa717x_write(client, 0x109, + (saa717x_read(client, 0x109) & 0x7f) | + (input_line < 6 ? 0x0 : 0x80)); + + /* change audio_mode */ + if (is_tuner) { + /* tuner */ + set_audio_mode(client, decoder->tuner_audio_mode); + } else { + /* Force to STEREO mode if Composite or + * S-Video were chosen */ + set_audio_mode(client, TUNER_AUDIO_STEREO); + } + /* change initialize procedure (Composite/S-Video) */ + if (is_tuner) + saa717x_write_regs(client, reg_init_tuner_input); + else if (input_line >= 6) + saa717x_write_regs(client, reg_init_svideo_input); + else + saa717x_write_regs(client, reg_init_composite_input); + } + + return 0; +} + +static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg) +{ + struct saa717x_state *decoder = i2c_get_clientdata(client); + + v4l_dbg(1, debug, client, "IOCTL: %08x\n", cmd); + + switch (cmd) { + case VIDIOC_INT_AUDIO_CLOCK_FREQ: + return saa717x_set_audio_clock_freq(client, *(u32 *)arg); + + case VIDIOC_G_CTRL: + return saa717x_get_v4lctrl(client, (struct v4l2_control *)arg); + + case VIDIOC_S_CTRL: + return saa717x_set_v4lctrl(client, (struct v4l2_control *)arg); + + case VIDIOC_QUERYCTRL: { + struct v4l2_queryctrl *qc = arg; + int i; + + for (i = 0; i < ARRAY_SIZE(saa717x_qctrl); i++) + if (qc->id && qc->id == saa717x_qctrl[i].id) { + memcpy(qc, &saa717x_qctrl[i], sizeof(*qc)); + return 0; + } + return -EINVAL; + } + +#ifdef CONFIG_VIDEO_ADV_DEBUG + case VIDIOC_DBG_G_REGISTER: { + struct v4l2_register *reg = arg; + + if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip)) + return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + reg->val = saa717x_read(client, reg->reg); + break; + } + + case VIDIOC_DBG_S_REGISTER: { + struct v4l2_register *reg = arg; + u16 addr = reg->reg & 0xffff; + u8 val = reg->val & 0xff; + + if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip)) + return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + saa717x_write(client, addr, val); + break; + } +#endif + + case VIDIOC_S_FMT: { + struct v4l2_format *fmt = (struct v4l2_format *)arg; + struct v4l2_pix_format *pix; + int prescale, h_scale, v_scale; + + pix = &fmt->fmt.pix; + v4l_dbg(1, debug, client, "decoder set size\n"); + + /* FIXME need better bounds checking here */ + if (pix->width < 1 || pix->width > 1440) + return -EINVAL; + if (pix->height < 1 || pix->height > 960) + return -EINVAL; + + /* scaling setting */ + /* NTSC and interlace only */ + prescale = SAA717X_NTSC_WIDTH / pix->width; + if (prescale == 0) + prescale = 1; + h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / pix->width; + /* interlace */ + v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / pix->height; + + /* Horizontal prescaling etc */ + set_h_prescale(client, 0, prescale); + set_h_prescale(client, 1, prescale); + + /* Horizontal scaling increment */ + /* TASK A */ + saa717x_write(client, 0x6C, (u8)(h_scale & 0xFF)); + saa717x_write(client, 0x6D, (u8)((h_scale >> 8) & 0xFF)); + /* TASK B */ + saa717x_write(client, 0xAC, (u8)(h_scale & 0xFF)); + saa717x_write(client, 0xAD, (u8)((h_scale >> 8) & 0xFF)); + + /* Vertical prescaling etc */ + set_v_scale(client, 0, v_scale); + set_v_scale(client, 1, v_scale); + + /* set video output size */ + /* video number of pixels at output */ + /* TASK A */ + saa717x_write(client, 0x5C, (u8)(pix->width & 0xFF)); + saa717x_write(client, 0x5D, (u8)((pix->width >> 8) & 0xFF)); + /* TASK B */ + saa717x_write(client, 0x9C, (u8)(pix->width & 0xFF)); + saa717x_write(client, 0x9D, (u8)((pix->width >> 8) & 0xFF)); + + /* video number of lines at output */ + /* TASK A */ + saa717x_write(client, 0x5E, (u8)(pix->height & 0xFF)); + saa717x_write(client, 0x5F, (u8)((pix->height >> 8) & 0xFF)); + /* TASK B */ + saa717x_write(client, 0x9E, (u8)(pix->height & 0xFF)); + saa717x_write(client, 0x9F, (u8)((pix->height >> 8) & 0xFF)); + break; + } + + case AUDC_SET_RADIO: + decoder->radio = 1; + break; + + case VIDIOC_S_STD: { + v4l2_std_id std = *(v4l2_std_id *) arg; + + v4l_dbg(1, debug, client, "decoder set norm "); + v4l_dbg(1, debug, client, "(not yet implementd)\n"); + + decoder->radio = 0; + decoder->std = std; + break; + } + + case VIDIOC_INT_G_AUDIO_ROUTING: { + struct v4l2_routing *route = arg; + + route->input = decoder->audio_input; + route->output = 0; + break; + } + + case VIDIOC_INT_S_AUDIO_ROUTING: { + struct v4l2_routing *route = arg; + + if (route->input < 3) { /* FIXME! --tadachi */ + decoder->audio_input = route->input; + v4l_dbg(1, debug, client, + "set decoder audio input to %d\n", + decoder->audio_input); + set_audio_regs(client, decoder); + break; + } + return -ERANGE; + } + + case VIDIOC_INT_S_VIDEO_ROUTING: { + struct v4l2_routing *route = arg; + int inp = route->input; + + return saa717x_set_video_input(client, decoder, inp); + } + + case VIDIOC_STREAMON: { + v4l_dbg(1, debug, client, "decoder enable output\n"); + decoder->enable = 1; + saa717x_write(client, 0x193, 0xa6); + break; + } + + case VIDIOC_STREAMOFF: { + v4l_dbg(1, debug, client, "decoder disable output\n"); + decoder->enable = 0; + saa717x_write(client, 0x193, 0x26); /* right? FIXME!--tadachi */ + break; + } + + /* change audio mode */ + case VIDIOC_S_TUNER: { + struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; + int audio_mode; + char *mes[4] = { + "MONO", "STEREO", "LANG1", "LANG2/SAP" + }; + + audio_mode = V4L2_TUNER_MODE_STEREO; + + switch (vt->audmode) { + case V4L2_TUNER_MODE_MONO: + audio_mode = TUNER_AUDIO_MONO; + break; + case V4L2_TUNER_MODE_STEREO: + audio_mode = TUNER_AUDIO_STEREO; + break; + case V4L2_TUNER_MODE_LANG2: + audio_mode = TUNER_AUDIO_LANG2; + break; + case V4L2_TUNER_MODE_LANG1: + audio_mode = TUNER_AUDIO_LANG1; + break; + } + + v4l_dbg(1, debug, client, "change audio mode to %s\n", + mes[audio_mode]); + decoder->tuner_audio_mode = audio_mode; + /* The registers are not changed here. */ + /* See DECODER_ENABLE_OUTPUT section. */ + set_audio_mode(client, decoder->tuner_audio_mode); + break; + } + + case VIDIOC_G_TUNER: { + struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; + int dual_f, stereo_f; + + if (decoder->radio) + break; + get_inf_dev_status(client, &dual_f, &stereo_f); + + v4l_dbg(1, debug, client, "DETECT==st:%d dual:%d\n", + stereo_f, dual_f); + + /* mono */ + if ((dual_f == 0) && (stereo_f == 0)) { + vt->rxsubchans = V4L2_TUNER_SUB_MONO; + v4l_dbg(1, debug, client, "DETECT==MONO\n"); + } + + /* stereo */ + if (stereo_f == 1) { + if (vt->audmode == V4L2_TUNER_MODE_STEREO || + vt->audmode == V4L2_TUNER_MODE_LANG1) { + vt->rxsubchans = V4L2_TUNER_SUB_STEREO; + v4l_dbg(1, debug, client, "DETECT==ST(ST)\n"); + } else { + vt->rxsubchans = V4L2_TUNER_SUB_MONO; + v4l_dbg(1, debug, client, "DETECT==ST(MONO)\n"); + } + } + + /* dual */ + if (dual_f == 1) { + if (vt->audmode == V4L2_TUNER_MODE_LANG2) { + vt->rxsubchans = V4L2_TUNER_SUB_LANG2 | V4L2_TUNER_SUB_MONO; + v4l_dbg(1, debug, client, "DETECT==DUAL1\n"); + } else { + vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_MONO; + v4l_dbg(1, debug, client, "DETECT==DUAL2\n"); + } + } + break; + } + + case VIDIOC_LOG_STATUS: + /* not yet implemented */ + break; + + default: + return -EINVAL; + } + + return 0; +} + +/* ----------------------------------------------------------------------- */ + + +/* i2c implementation */ + +/* ----------------------------------------------------------------------- */ +static int saa717x_probe(struct i2c_client *client) +{ + struct saa717x_state *decoder; + u8 id = 0; + char *p = ""; + + /* Check if the adapter supports the needed features */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -EIO; + + snprintf(client->name, sizeof(client->name) - 1, "saa717x"); + + if (saa717x_write(client, 0x5a4, 0xfe) && + saa717x_write(client, 0x5a5, 0x0f) && + saa717x_write(client, 0x5a6, 0x00) && + saa717x_write(client, 0x5a7, 0x01)) + id = saa717x_read(client, 0x5a0); + if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) { + v4l_dbg(1, debug, client, "saa717x not found (id=%02x)\n", id); + return -ENODEV; + } + if (id == 0xc2) + p = "saa7173"; + else if (id == 0x32) + p = "saa7174A"; + else if (id == 0x6c) + p = "saa7174HL"; + else + p = "saa7171"; + v4l_info(client, "%s found @ 0x%x (%s)\n", p, + client->addr << 1, client->adapter->name); + + decoder = kzalloc(sizeof(struct saa717x_state), GFP_KERNEL); + i2c_set_clientdata(client, decoder); + + if (decoder == NULL) + return -ENOMEM; + decoder->std = V4L2_STD_NTSC; + decoder->input = -1; + decoder->enable = 1; + + /* tune these parameters */ + decoder->bright = 0x80; + decoder->contrast = 0x44; + decoder->sat = 0x40; + decoder->hue = 0x00; + + /* FIXME!! */ + decoder->playback = 0; /* initially capture mode used */ + decoder->audio = 1; /* DECODER_AUDIO_48_KHZ */ + + decoder->audio_input = 2; /* FIXME!! */ + + decoder->tuner_audio_mode = TUNER_AUDIO_STEREO; + /* set volume, bass and treble */ + decoder->audio_main_vol_l = 6; + decoder->audio_main_vol_r = 6; + decoder->audio_main_bass = 0; + decoder->audio_main_treble = 0; + decoder->audio_main_mute = 0; + decoder->audio_main_balance = 32768; + /* normalize (24 to -40 (not -84) -> 65535 to 0) */ + decoder->audio_main_volume = + (decoder->audio_main_vol_r + 41) * 65535 / (24 - (-40)); + + v4l_dbg(1, debug, client, "writing init values\n"); + + /* FIXME!! */ + saa717x_write_regs(client, reg_init_initialize); + set_video_output_level_regs(client, decoder); + /* set bass,treble to 0db 20041101 K.Ohta */ + decoder->audio_main_bass = 0; + decoder->audio_main_treble = 0; + set_audio_regs(client, decoder); + + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(2*HZ); + return 0; +} + +static int saa717x_remove(struct i2c_client *client) +{ + kfree(i2c_get_clientdata(client)); + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static struct v4l2_i2c_driver_data v4l2_i2c_data = { + .name = "saa717x", + .driverid = I2C_DRIVERID_SAA717X, + .command = saa717x_command, + .probe = saa717x_probe, + .remove = saa717x_remove, +#ifdef I2C_CLASS_TV_ANALOG + .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, +#endif +}; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) +EXPORT_NO_SYMBOLS; +#endif diff --git a/linux/drivers/media/video/saa7185.c b/linux/drivers/media/video/saa7185.c index 2ac144d9a..7a6c9c1fb 100644 --- a/linux/drivers/media/video/saa7185.c +++ b/linux/drivers/media/video/saa7185.c @@ -404,7 +404,7 @@ saa7185_detect_client (struct i2c_adapter *adapter, return 0; client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == 0) + if (!client) return -ENOMEM; client->addr = address; client->adapter = adapter; diff --git a/linux/drivers/media/video/se401.c b/linux/drivers/media/video/se401.c index 1bc4b3a3f..c82bfddde 100644 --- a/linux/drivers/media/video/se401.c +++ b/linux/drivers/media/video/se401.c @@ -304,10 +304,10 @@ static void se401_button_irq(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); + dbg("%s - urb shutting down with status: %d", __func__, urb->status); return; default: - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); + dbg("%s - nonzero urb status received: %d", __func__, urb->status); goto exit; } @@ -319,7 +319,7 @@ exit: status = usb_submit_urb (urb, GFP_ATOMIC); if (status) err ("%s - usb_submit_urb failed with result %d", - __FUNCTION__, status); + __func__, status); } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) diff --git a/linux/drivers/media/video/sn9c102/sn9c102.h b/linux/drivers/media/video/sn9c102/sn9c102.h index e845e2dea..c6e41428d 100644 --- a/linux/drivers/media/video/sn9c102/sn9c102.h +++ b/linux/drivers/media/video/sn9c102/sn9c102.h @@ -183,7 +183,7 @@ do { \ dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ else if ((level) >= 3) \ dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ - __FUNCTION__, __LINE__ , ## args); \ + __func__, __LINE__ , ## args); \ } \ } while (0) # define V4LDBG(level, name, cmd) \ @@ -198,7 +198,7 @@ do { \ pr_info("sn9c102: " fmt "\n", ## args); \ else if ((level) == 3) \ pr_debug("sn9c102: [%s:%d] " fmt "\n", \ - __FUNCTION__, __LINE__ , ## args); \ + __func__, __LINE__ , ## args); \ } \ } while (0) #else @@ -209,7 +209,7 @@ do { \ #undef PDBG #define PDBG(fmt, args...) \ -dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __FUNCTION__, \ +dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __func__, \ __LINE__ , ## args) #undef PDBGG diff --git a/linux/drivers/media/video/soc_camera.c b/linux/drivers/media/video/soc_camera.c index 1e9215788..91a1251d9 100644 --- a/linux/drivers/media/video/soc_camera.c +++ b/linux/drivers/media/video/soc_camera.c @@ -137,7 +137,7 @@ static int soc_camera_reqbufs(struct file *file, void *priv, WARN_ON(priv != file->private_data); - dev_dbg(&icd->dev, "%s: %d\n", __FUNCTION__, p->memory); + dev_dbg(&icd->dev, "%s: %d\n", __func__, p->memory); ret = videobuf_reqbufs(&icf->vb_vidq, p); if (ret < 0) @@ -453,7 +453,7 @@ static int soc_camera_streamon(struct file *file, void *priv, WARN_ON(priv != file->private_data); - dev_dbg(&icd->dev, "%s\n", __FUNCTION__); + dev_dbg(&icd->dev, "%s\n", __func__); if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -472,7 +472,7 @@ static int soc_camera_streamoff(struct file *file, void *priv, WARN_ON(priv != file->private_data); - dev_dbg(&icd->dev, "%s\n", __FUNCTION__); + dev_dbg(&icd->dev, "%s\n", __func__); if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -985,7 +985,7 @@ void soc_camera_video_stop(struct soc_camera_device *icd) { struct video_device *vdev = icd->vdev; - dev_dbg(&icd->dev, "%s\n", __FUNCTION__); + dev_dbg(&icd->dev, "%s\n", __func__); if (!icd->dev.parent || !vdev) return; diff --git a/linux/drivers/media/video/stk-webcam.c b/linux/drivers/media/video/stk-webcam.c index 015f6a53f..7d8843c8e 100644 --- a/linux/drivers/media/video/stk-webcam.c +++ b/linux/drivers/media/video/stk-webcam.c @@ -1101,7 +1101,7 @@ static int stk_setup_format(struct stk_camera *dev) && i < ARRAY_SIZE(stk_sizes)) i++; if (i == ARRAY_SIZE(stk_sizes)) { - STK_ERROR("Something is broken in %s\n", __FUNCTION__); + STK_ERROR("Something is broken in %s\n", __func__); return -EFAULT; } /* This registers controls some timings, not sure of what. */ diff --git a/linux/drivers/media/video/stv680.c b/linux/drivers/media/video/stv680.c index dfbb63b93..8bc396533 100644 --- a/linux/drivers/media/video/stv680.c +++ b/linux/drivers/media/video/stv680.c @@ -86,7 +86,7 @@ static unsigned int debug; #define PDEBUG(level, fmt, args...) \ do { \ if (debug >= level) \ - info("[%s:%d] " fmt, __FUNCTION__, __LINE__ , ## args); \ + info("[%s:%d] " fmt, __func__, __LINE__ , ## args); \ } while (0) diff --git a/linux/drivers/media/video/tcm825x.c b/linux/drivers/media/video/tcm825x.c index fb895f668..6943b447a 100644 --- a/linux/drivers/media/video/tcm825x.c +++ b/linux/drivers/media/video/tcm825x.c @@ -906,7 +906,7 @@ static int __init tcm825x_init(void) rval = i2c_add_driver(&tcm825x_i2c_driver); if (rval) printk(KERN_INFO "%s: failed registering " TCM825X_NAME "\n", - __FUNCTION__); + __func__); return rval; } diff --git a/linux/drivers/media/video/tda8290.c b/linux/drivers/media/video/tda8290.c index 789548828..d57602d22 100644 --- a/linux/drivers/media/video/tda8290.c +++ b/linux/drivers/media/video/tda8290.c @@ -389,7 +389,7 @@ static void tda8295_set_params(struct dvb_frontend *fe, set_audio(fe, params); - tuner_dbg("%s: freq = %d\n", __FUNCTION__, params->frequency); + tuner_dbg("%s: freq = %d\n", __func__, params->frequency); tda8295_power(fe, 1); tda8295_agc1_out(fe, 1); @@ -639,7 +639,7 @@ static int tda8290_probe(struct tuner_i2c_props *i2c_props) if (tda8290_id[1] == TDA8290_ID) { if (debug) printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n", - __FUNCTION__, i2c_adapter_id(i2c_props->adap), + __func__, i2c_adapter_id(i2c_props->adap), i2c_props->addr); return 0; } @@ -659,7 +659,7 @@ static int tda8295_probe(struct tuner_i2c_props *i2c_props) if (tda8295_id[1] == TDA8295_ID) { if (debug) printk(KERN_DEBUG "%s: tda8295 detected @ %d-%04x\n", - __FUNCTION__, i2c_adapter_id(i2c_props->adap), + __func__, i2c_adapter_id(i2c_props->adap), i2c_props->addr); return 0; } diff --git a/linux/drivers/media/video/tda8290.h b/linux/drivers/media/video/tda8290.h index 9dd8b73eb..d3bbf276a 100644 --- a/linux/drivers/media/video/tda8290.h +++ b/linux/drivers/media/video/tda8290.h @@ -39,7 +39,7 @@ extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, #else static inline int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return -EINVAL; } @@ -49,7 +49,7 @@ static inline struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, struct tda829x_config *cfg) { printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", - __FUNCTION__); + __func__); return NULL; } #endif diff --git a/linux/drivers/media/video/tda9840.c b/linux/drivers/media/video/tda9840.c index 8218f466d..c41e50ba6 100644 --- a/linux/drivers/media/video/tda9840.c +++ b/linux/drivers/media/video/tda9840.c @@ -37,10 +37,10 @@ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) #define dprintk(args...) \ - do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0) + do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __func__, __LINE__); printk(args); } } while (0) #else #define dprintk(args...) \ - do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) + do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) #endif #define SWITCH 0x00 @@ -181,7 +181,7 @@ static int detect(struct i2c_adapter *adapter, int address, int kind) /* allocate memory for client structure */ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (0 == client) { + if (!client) { printk("not enough kernel memory\n"); return -ENOMEM; } diff --git a/linux/drivers/media/video/tda9887.h b/linux/drivers/media/video/tda9887.h index 8f873a8e6..be49dcbfc 100644 --- a/linux/drivers/media/video/tda9887.h +++ b/linux/drivers/media/video/tda9887.h @@ -30,7 +30,7 @@ static inline struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c_adap, u8 i2c_addr) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif diff --git a/linux/drivers/media/video/tea5761.h b/linux/drivers/media/video/tea5761.h index 73a03b427..8eb62722b 100644 --- a/linux/drivers/media/video/tea5761.h +++ b/linux/drivers/media/video/tea5761.h @@ -31,7 +31,7 @@ static inline int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) { printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", - __FUNCTION__); + __func__); return -EINVAL; } @@ -39,7 +39,7 @@ static inline struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, struct i2c_adapter* i2c_adap, u8 i2c_addr) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif diff --git a/linux/drivers/media/video/tea5767.h b/linux/drivers/media/video/tea5767.h index a44451f61..7b547c092 100644 --- a/linux/drivers/media/video/tea5767.h +++ b/linux/drivers/media/video/tea5767.h @@ -50,7 +50,7 @@ static inline int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) { printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", - __FUNCTION__); + __func__); return -EINVAL; } @@ -58,7 +58,7 @@ static inline struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe, struct i2c_adapter* i2c_adap, u8 i2c_addr) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif diff --git a/linux/drivers/media/video/tea6415c.c b/linux/drivers/media/video/tea6415c.c index 003fe1edb..16f369195 100644 --- a/linux/drivers/media/video/tea6415c.c +++ b/linux/drivers/media/video/tea6415c.c @@ -39,10 +39,10 @@ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) #define dprintk(args...) \ - do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0) + do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __func__, __LINE__); printk(args); } } while (0) #else #define dprintk(args...) \ - do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) + do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) #endif #define TEA6415C_NUM_INPUTS 8 @@ -73,7 +73,7 @@ static int detect(struct i2c_adapter *adapter, int address, int kind) /* allocate memory for client structure */ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (0 == client) { + if (!client) { return -ENOMEM; } diff --git a/linux/drivers/media/video/tea6420.c b/linux/drivers/media/video/tea6420.c index 261675012..7a8fec9cf 100644 --- a/linux/drivers/media/video/tea6420.c +++ b/linux/drivers/media/video/tea6420.c @@ -39,10 +39,10 @@ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) #define dprintk(args...) \ - do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0) + do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __func__, __LINE__); printk(args); } } while (0) #else #define dprintk(args...) \ - do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0) + do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) #endif /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ @@ -110,7 +110,7 @@ static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind) /* allocate memory for client structure */ client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (0 == client) { + if (!client) { return -ENOMEM; } diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c index 38a90afb6..fa218e910 100644 --- a/linux/drivers/media/video/tuner-core.c +++ b/linux/drivers/media/video/tuner-core.c @@ -802,7 +802,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) if (analog_ops->standby) analog_ops->standby(&t->fe); break; -#ifdef CONFIG_VIDEO_V4L1 +#ifdef CONFIG_VIDEO_ALLOW_V4L1 case VIDIOCSAUDIO: if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) return 0; diff --git a/linux/drivers/media/video/tuner-simple.c b/linux/drivers/media/video/tuner-simple.c index 772bfefbe..29c14a4c6 100644 --- a/linux/drivers/media/video/tuner-simple.c +++ b/linux/drivers/media/video/tuner-simple.c @@ -1034,7 +1034,7 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, if (type >= tuner_count) { printk(KERN_WARNING "%s: invalid tuner type: %d (max: %d)\n", - __FUNCTION__, type, tuner_count-1); + __func__, type, tuner_count-1); return NULL; } diff --git a/linux/drivers/media/video/tuner-simple.h b/linux/drivers/media/video/tuner-simple.h index bf425f325..e46cf0121 100644 --- a/linux/drivers/media/video/tuner-simple.h +++ b/linux/drivers/media/video/tuner-simple.h @@ -31,7 +31,7 @@ static inline struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, u8 i2c_addr, unsigned int type) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } #endif diff --git a/linux/drivers/media/video/tuner-xc2028-types.h b/linux/drivers/media/video/tuner-xc2028-types.h index d0057fbf0..e38970f1c 100644 --- a/linux/drivers/media/video/tuner-xc2028-types.h +++ b/linux/drivers/media/video/tuner-xc2028-types.h @@ -1,6 +1,9 @@ /* tuner-xc2028_types * - * Copyright (c) 2007 Mauro Carvalho Chehab (mchehab@infradead.org) + * This file includes internal tipes to be used inside tuner-xc2028. + * Shouldn't be included outside tuner-xc2028 + * + * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) * This code is placed under the terms of the GNU General Public License v2 */ @@ -85,11 +88,28 @@ /* This flag identifies that the scode table has a new format */ #define HAS_IF (1 << 30) -#define SCODE_TYPES (MTS|DTV6|QAM|DTV7|DTV78|DTV8|LCD|NOGD|MONO|ATSC|IF| \ +#if 0 +/* The current seek algorithm doesn'use those flags. Instead, this is + currently useful only for debug process, since this is a HINT table + associating an alias to an IF table that can be used by that digital + video standard (in the case of DTV6/7/78/8, QAM and ATSC), or to a + particular demod type + */ +#define SCODE_TYPES (DTV6|QAM|DTV7|DTV78|DTV8|LCD|NOGD|MONO|ATSC|IF| \ LG60|ATI638|OREN538|OREN36|TOYOTA388|TOYOTA794| \ DIBCOM52|ZARLINK456|CHINA|F6MHZ|SCODE) +#else +#define SCODE_TYPES SCODE +#endif -/* Newer types to be moved to videodev2.h */ + +/* Newer types not defined on videodev2.h. + The original idea were to move all those types to videodev2.h, but + it seemed overkill, since, with the exception of SECAM/K3, the other + types seem to be autodetected. + It is not clear where secam/k3 is used, nor we have a feedback of this + working or being autodetected by the standard secam firmware. + */ #define V4L2_STD_SECAM_K3 (0x04000000) diff --git a/linux/drivers/media/video/tuner-xc2028.c b/linux/drivers/media/video/tuner-xc2028.c index 0ab0cbeca..ce066dc97 100644 --- a/linux/drivers/media/video/tuner-xc2028.c +++ b/linux/drivers/media/video/tuner-xc2028.c @@ -1,6 +1,6 @@ /* tuner-xc2028 * - * Copyright (c) 2007 Mauro Carvalho Chehab (mchehab@infradead.org) + * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) * * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com) * - frontend interface @@ -145,12 +145,12 @@ struct xc2028_data { _rc; \ }) -static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val) +static int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val) { unsigned char buf[2]; unsigned char ibuf[2]; - tuner_dbg("%s %04x called\n", __FUNCTION__, reg); + tuner_dbg("%s %04x called\n", __func__, reg); buf[0] = reg >> 8; buf[1] = (unsigned char) reg; @@ -250,6 +250,7 @@ static v4l2_std_id parse_audio_std_option(void) static void free_firmware(struct xc2028_data *priv) { int i; + tuner_dbg("%s called\n", __func__); if (!priv->firm) return; @@ -275,7 +276,7 @@ static int load_all_firmwares(struct dvb_frontend *fe) char name[33]; char *fname; - tuner_dbg("%s called\n", __FUNCTION__); + tuner_dbg("%s called\n", __func__); if (!firmware_name[0]) fname = priv->ctrl.fname; @@ -418,9 +419,9 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, { struct xc2028_data *priv = fe->tuner_priv; int i, best_i = -1, best_nr_matches = 0; - unsigned int ign_firm_type_mask = 0; + unsigned int type_mask = 0; - tuner_dbg("%s called, want type=", __FUNCTION__); + tuner_dbg("%s called, want type=", __func__); if (debug) { dump_firm_type(type); printk("(%x), id %016llx.\n", type, (unsigned long long)*id); @@ -435,18 +436,23 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, *id = V4L2_STD_PAL; if (type & BASE) - type &= BASE_TYPES; + type_mask = BASE_TYPES; else if (type & SCODE) { type &= SCODE_TYPES; - ign_firm_type_mask = HAS_IF; + type_mask = SCODE_TYPES &~ HAS_IF; } else if (type & DTV_TYPES) - type &= DTV_TYPES; + type_mask = DTV_TYPES; else if (type & STD_SPECIFIC_TYPES) - type &= STD_SPECIFIC_TYPES; + type_mask = STD_SPECIFIC_TYPES; + + type &= type_mask; + + if (!type & SCODE) + type_mask = ~0; /* Seek for exact match */ for (i = 0; i < priv->firm_size; i++) { - if ((type == (priv->firm[i].type & ~ign_firm_type_mask)) && + if ((type == (priv->firm[i].type & type_mask)) && (*id == priv->firm[i].id)) goto found; } @@ -456,7 +462,7 @@ static int seek_firmware(struct dvb_frontend *fe, unsigned int type, v4l2_std_id match_mask; int nr_matches; - if (type != (priv->firm[i].type & ~ign_firm_type_mask)) + if (type != (priv->firm[i].type & type_mask)) continue; match_mask = *id & priv->firm[i].id; @@ -506,7 +512,7 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type, int pos, rc; unsigned char *p, *endp, buf[priv->ctrl.max_len]; - tuner_dbg("%s called\n", __FUNCTION__); + tuner_dbg("%s called\n", __func__); pos = seek_firmware(fe, type, id); if (pos < 0) @@ -609,7 +615,7 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type, int pos, rc; unsigned char *p; - tuner_dbg("%s called\n", __FUNCTION__); + tuner_dbg("%s called\n", __func__); if (!int_freq) { pos = seek_firmware(fe, type, id); @@ -673,7 +679,7 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type, u16 version, hwmodel; v4l2_std_id std0; - tuner_dbg("%s called\n", __FUNCTION__); + tuner_dbg("%s called\n", __func__); if (!priv->firm) { if (!priv->ctrl.fname) { @@ -793,10 +799,10 @@ check_device: goto fail; } - tuner_info("Device is Xceive %d version %d.%d, " - "firmware version %d.%d\n", - hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8, - (version & 0xf0) >> 4, version & 0xf); + tuner_dbg("Device is Xceive %d version %d.%d, " + "firmware version %d.%d\n", + hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8, + (version & 0xf0) >> 4, version & 0xf); /* Check firmware version against what we downloaded. */ if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) { @@ -847,7 +853,7 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength) u16 frq_lock, signal = 0; int rc; - tuner_dbg("%s called\n", __FUNCTION__); + tuner_dbg("%s called\n", __func__); mutex_lock(&priv->lock); @@ -884,7 +890,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, unsigned char buf[4]; u32 div, offset = 0; - tuner_dbg("%s called\n", __FUNCTION__); + tuner_dbg("%s called\n", __func__); mutex_lock(&priv->lock); @@ -967,7 +973,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe, struct xc2028_data *priv = fe->tuner_priv; unsigned int type=0; - tuner_dbg("%s called\n", __FUNCTION__); + tuner_dbg("%s called\n", __func__); if (p->mode == V4L2_TUNER_RADIO) { type |= FM; @@ -1000,7 +1006,7 @@ static int xc2028_set_params(struct dvb_frontend *fe, fe_bandwidth_t bw = BANDWIDTH_8_MHZ; u16 demod = 0; - tuner_dbg("%s called\n", __FUNCTION__); + tuner_dbg("%s called\n", __func__); if (priv->ctrl.d2633) type |= D2633; @@ -1065,12 +1071,16 @@ static int xc2028_set_params(struct dvb_frontend *fe, T_DIGITAL_TV, type, 0, demod); } +#if 0 +/* This is needed at sleep (S1/S3), but not at fe_standby. Otherwise, + firmware will be loaded on every open() + */ static int xc2028_sleep(struct dvb_frontend *fe) { struct xc2028_data *priv = fe->tuner_priv; int rc = 0; - tuner_dbg("%s called\n", __FUNCTION__); + tuner_dbg("%s called\n", __func__); mutex_lock(&priv->lock); @@ -1085,13 +1095,13 @@ static int xc2028_sleep(struct dvb_frontend *fe) return rc; } - +#endif static int xc2028_dvb_release(struct dvb_frontend *fe) { struct xc2028_data *priv = fe->tuner_priv; - tuner_dbg("%s called\n", __FUNCTION__); + tuner_dbg("%s called\n", __func__); mutex_lock(&xc2028_list_mutex); @@ -1116,7 +1126,7 @@ static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct xc2028_data *priv = fe->tuner_priv; - tuner_dbg("%s called\n", __FUNCTION__); + tuner_dbg("%s called\n", __func__); *frequency = priv->frequency; @@ -1129,25 +1139,25 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) struct xc2028_ctrl *p = priv_cfg; int rc = 0; - tuner_dbg("%s called\n", __FUNCTION__); + tuner_dbg("%s called\n", __func__); mutex_lock(&priv->lock); - kfree(priv->ctrl.fname); - free_firmware(priv); - memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); - priv->ctrl.fname = NULL; + if (priv->ctrl.max_len < 9) + priv->ctrl.max_len = 13; if (p->fname) { + if (priv->ctrl.fname && strcmp(p->fname, priv->ctrl.fname)) { + kfree(priv->ctrl.fname); + free_firmware(priv); + } + priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL); if (priv->ctrl.fname == NULL) rc = -ENOMEM; } - if (priv->ctrl.max_len < 9) - priv->ctrl.max_len = 13; - mutex_unlock(&priv->lock); return rc; @@ -1167,8 +1177,9 @@ static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = { .get_frequency = xc2028_get_frequency, .get_rf_strength = xc2028_signal, .set_params = xc2028_set_params, +#if 0 .sleep = xc2028_sleep, - +#endif #if 0 int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth); int (*get_status)(struct dvb_frontend *fe, u32 *status); diff --git a/linux/drivers/media/video/tuner-xc2028.h b/linux/drivers/media/video/tuner-xc2028.h index 3eb842037..fc2f132a5 100644 --- a/linux/drivers/media/video/tuner-xc2028.h +++ b/linux/drivers/media/video/tuner-xc2028.h @@ -1,6 +1,6 @@ /* tuner-xc2028 * - * Copyright (c) 2007 Mauro Carvalho Chehab (mchehab@infradead.org) + * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org) * This code is placed under the terms of the GNU General Public License v2 */ @@ -12,7 +12,7 @@ #define XC2028_DEFAULT_FIRMWARE "xc3028-v27.fw" /* Dmoduler IF (kHz) */ -#define XC3028_FE_DEFAULT 0 +#define XC3028_FE_DEFAULT 0 /* Don't load SCODE */ #define XC3028_FE_LG60 6000 #define XC3028_FE_ATI638 6380 #define XC3028_FE_OREN538 5380 @@ -55,7 +55,7 @@ static inline struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, struct xc2028_config *cfg) { printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n", - __FUNCTION__); + __func__); return NULL; } #endif diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c index e6907db8b..7dc6623cc 100644 --- a/linux/drivers/media/video/tvp5150.c +++ b/linux/drivers/media/video/tvp5150.c @@ -1175,12 +1175,12 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter, return 0; c = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (c == 0) + if (!c) return -ENOMEM; memcpy(c, &client_template, sizeof(struct i2c_client)); core = kzalloc(sizeof(struct tvp5150), GFP_KERNEL); - if (core == 0) { + if (!core) { kfree(c); return -ENOMEM; } diff --git a/linux/drivers/media/video/usbvideo/ibmcam.c b/linux/drivers/media/video/usbvideo/ibmcam.c index 1261593cf..1afbcc147 100644 --- a/linux/drivers/media/video/usbvideo/ibmcam.c +++ b/linux/drivers/media/video/usbvideo/ibmcam.c @@ -802,6 +802,21 @@ static enum ParseState ibmcam_model2_320x240_parse_lines( return scan_Continue; } +/* + * ibmcam_model3_parse_lines() + * + * | Even lines | Odd Lines | + * -----------------------------------| + * |YYY........Y|UYVYUYVY.........UYVY| + * |YYY........Y|UYVYUYVY.........UYVY| + * |............|.....................| + * |YYY........Y|UYVYUYVY.........UYVY| + * |------------+---------------------| + * + * There is one (U, V) chroma pair for every four luma (Y) values. This + * function reads a pair of lines at a time and obtains missing chroma values + * from adjacent pixels. + */ static enum ParseState ibmcam_model3_parse_lines( struct uvd *uvd, struct usbvideo_frame *frame, @@ -816,6 +831,7 @@ static enum ParseState ibmcam_model3_parse_lines( const int ccm = 128; /* Color correction median - see below */ int i, u, v, rw, data_w=0, data_h=0, color_corr; static unsigned char lineBuffer[640*3]; + int line; color_corr = (uvd->vpic.colour - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/ RESTRICT_TO_RANGE(color_corr, -ccm, ccm+1); @@ -869,15 +885,15 @@ static enum ParseState ibmcam_model3_parse_lines( return scan_NextFrame; } - /* Make sure there's enough data for the entire line */ - len = 3 * data_w; /* <y-data> <uv-data> */ + /* Make sure that lineBuffer can store two lines of data */ + len = 3 * data_w; /* <y-data> <uyvy-data> */ assert(len <= sizeof(lineBuffer)); - /* Make sure there's enough data for the entire line */ + /* Make sure there's enough data for two lines */ if (RingQueue_GetLength(&uvd->dp) < len) return scan_Out; - /* Suck one line out of the ring queue */ + /* Suck two lines of data out of the ring queue */ RingQueue_Dequeue(&uvd->dp, lineBuffer, len); data = lineBuffer; @@ -887,15 +903,23 @@ static enum ParseState ibmcam_model3_parse_lines( rw = (int)VIDEOSIZE_Y(frame->request) - (int)(frame->curline) - 1; RESTRICT_TO_RANGE(rw, 0, VIDEOSIZE_Y(frame->request)-1); - for (i = 0; i < VIDEOSIZE_X(frame->request); i++) { - int y, rv, gv, bv; /* RGB components */ + /* Iterate over two lines. */ + for (line = 0; line < 2; line++) { + for (i = 0; i < VIDEOSIZE_X(frame->request); i++) { + int y; + int rv, gv, bv; /* RGB components */ - if (i < data_w) { - y = data[i]; /* Luminosity is the first line */ + if (i >= data_w) { + RGB24_PUTPIXEL(frame, i, rw, 0, 0, 0); + continue; + } + + /* first line is YYY...Y; second is UYVY...UYVY */ + y = data[(line == 0) ? i : (i*2 + 1)]; /* Apply static color correction */ - u = color[i*2] + hue_corr; - v = color[i*2 + 1] + hue2_corr; + u = color[(i/2)*4] + hue_corr; + v = color[(i/2)*4 + 2] + hue2_corr; /* Apply color correction */ if (color_corr != 0) { @@ -903,13 +927,21 @@ static enum ParseState ibmcam_model3_parse_lines( u = 128 + ((ccm + color_corr) * (u - 128)) / ccm; v = 128 + ((ccm + color_corr) * (v - 128)) / ccm; } - } else - y = 0, u = v = 128; - YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv); - RGB24_PUTPIXEL(frame, i, rw, rv, gv, bv); /* Done by deinterlacing now */ + + YUV_TO_RGB_BY_THE_BOOK(y, u, v, rv, gv, bv); + RGB24_PUTPIXEL(frame, i, rw, rv, gv, bv); /* No deinterlacing */ + } + + /* Check for the end of requested data */ + if (rw == 0) + break; + + /* Prepare for the second line */ + rw--; + data = lineBuffer + data_w; } - frame->deinterlace = Deinterlace_FillEvenLines; + frame->deinterlace = Deinterlace_None; /* * Account for number of bytes that we wrote into output V4L frame. diff --git a/linux/drivers/media/video/usbvideo/konicawc.c b/linux/drivers/media/video/usbvideo/konicawc.c index 67f46c77f..7e2f04fb4 100644 --- a/linux/drivers/media/video/usbvideo/konicawc.c +++ b/linux/drivers/media/video/usbvideo/konicawc.c @@ -64,7 +64,7 @@ static struct usbvideo *cams; static int debug; #define DEBUG(n, format, arg...) \ if (n <= debug) { \ - printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \ + printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \ } #else #define DEBUG(n, arg...) diff --git a/linux/drivers/media/video/usbvideo/quickcam_messenger.c b/linux/drivers/media/video/usbvideo/quickcam_messenger.c index c6673bd58..8cab43ab7 100644 --- a/linux/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/linux/drivers/media/video/usbvideo/quickcam_messenger.c @@ -51,7 +51,7 @@ static int debug; #define DEBUG(n, format, arg...) \ if (n <= debug) { \ - printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \ + printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \ } #else #define DEBUG(n, arg...) diff --git a/linux/drivers/media/video/usbvideo/usbvideo.c b/linux/drivers/media/video/usbvideo/usbvideo.c index e9b305a77..f1aafd97d 100644 --- a/linux/drivers/media/video/usbvideo/usbvideo.c +++ b/linux/drivers/media/video/usbvideo/usbvideo.c @@ -525,11 +525,11 @@ void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode) static int num_pass; if (uvd == NULL) { - err("%s: uvd == NULL", __FUNCTION__); + err("%s: uvd == NULL", __func__); return; } if ((uvd->curframe < 0) || (uvd->curframe >= USBVIDEO_NUMFRAMES)) { - err("%s: uvd->curframe=%d.", __FUNCTION__, uvd->curframe); + err("%s: uvd->curframe=%d.", __func__, uvd->curframe); return; } @@ -630,15 +630,15 @@ EXPORT_SYMBOL(usbvideo_HexDump); static int usbvideo_ClientIncModCount(struct uvd *uvd) { if (uvd == NULL) { - err("%s: uvd == NULL", __FUNCTION__); + err("%s: uvd == NULL", __func__); return -EINVAL; } if (uvd->handle == NULL) { - err("%s: uvd->handle == NULL", __FUNCTION__); + err("%s: uvd->handle == NULL", __func__); return -EINVAL; } if (!try_module_get(uvd->handle->md_module)) { - err("%s: try_module_get() == 0", __FUNCTION__); + err("%s: try_module_get() == 0", __func__); return -ENODEV; } return 0; @@ -647,15 +647,15 @@ static int usbvideo_ClientIncModCount(struct uvd *uvd) static void usbvideo_ClientDecModCount(struct uvd *uvd) { if (uvd == NULL) { - err("%s: uvd == NULL", __FUNCTION__); + err("%s: uvd == NULL", __func__); return; } if (uvd->handle == NULL) { - err("%s: uvd->handle == NULL", __FUNCTION__); + err("%s: uvd->handle == NULL", __func__); return; } if (uvd->handle->md_module == NULL) { - err("%s: uvd->handle->md_module == NULL", __FUNCTION__); + err("%s: uvd->handle->md_module == NULL", __func__); return; } module_put(uvd->handle->md_module); @@ -675,13 +675,13 @@ int usbvideo_register( /* Check parameters for sanity */ if ((num_cams <= 0) || (pCams == NULL) || (cbTbl == NULL)) { - err("%s: Illegal call", __FUNCTION__); + err("%s: Illegal call", __func__); return -EINVAL; } /* Check registration callback - must be set! */ if (cbTbl->probe == NULL) { - err("%s: probe() is required!", __FUNCTION__); + err("%s: probe() is required!", __func__); return -EINVAL; } @@ -692,7 +692,7 @@ int usbvideo_register( return -ENOMEM; } dbg("%s: Allocated $%p (%d. bytes) for %d. cameras", - __FUNCTION__, cams, base_size, num_cams); + __func__, cams, base_size, num_cams); /* Copy callbacks, apply defaults for those that are not set */ memmove(&cams->cb, cbTbl, sizeof(cams->cb)); @@ -721,7 +721,7 @@ int usbvideo_register( up->user_data = kmalloc(up->user_size, GFP_KERNEL); if (up->user_data == NULL) { err("%s: Failed to allocate user_data (%d. bytes)", - __FUNCTION__, up->user_size); + __func__, up->user_size); while (i) { up = &cams->cam[--i]; kfree(up->user_data); @@ -730,7 +730,7 @@ int usbvideo_register( return -ENOMEM; } dbg("%s: Allocated cams[%d].user_data=$%p (%d. bytes)", - __FUNCTION__, i, up->user_data, up->user_size); + __func__, i, up->user_data, up->user_size); } } @@ -776,19 +776,19 @@ void usbvideo_Deregister(struct usbvideo **pCams) int i; if (pCams == NULL) { - err("%s: pCams == NULL", __FUNCTION__); + err("%s: pCams == NULL", __func__); return; } cams = *pCams; if (cams == NULL) { - err("%s: cams == NULL", __FUNCTION__); + err("%s: cams == NULL", __func__); return; } - dbg("%s: Deregistering %s driver.", __FUNCTION__, cams->drvName); + dbg("%s: Deregistering %s driver.", __func__, cams->drvName); usb_deregister(&cams->usbdrv); - dbg("%s: Deallocating cams=$%p (%d. cameras)", __FUNCTION__, cams, cams->num_cameras); + dbg("%s: Deallocating cams=$%p (%d. cameras)", __func__, cams, cams->num_cameras); for (i=0; i < cams->num_cameras; i++) { struct uvd *up = &cams->cam[i]; int warning = 0; @@ -802,16 +802,16 @@ void usbvideo_Deregister(struct usbvideo **pCams) } if (warning) { err("%s: Warning: user_data=$%p user_size=%d.", - __FUNCTION__, up->user_data, up->user_size); + __func__, up->user_data, up->user_size); } else { dbg("%s: Freeing %d. $%p->user_data=$%p", - __FUNCTION__, i, up, up->user_data); + __func__, i, up, up->user_data); kfree(up->user_data); } } /* Whole array was allocated in one chunk */ dbg("%s: Freed %d uvd structures", - __FUNCTION__, cams->num_cameras); + __func__, cams->num_cameras); kfree(cams); *pCams = NULL; } @@ -846,7 +846,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf) int i; if (uvd == NULL) { - err("%s($%p): Illegal call.", __FUNCTION__, intf); + err("%s($%p): Illegal call.", __func__, intf); return; } @@ -854,7 +854,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf) usbvideo_ClientIncModCount(uvd); if (uvd->debug > 0) - info("%s(%p.)", __FUNCTION__, intf); + info("%s(%p.)", __func__, intf); mutex_lock(&uvd->lock); uvd->remove_pending = 1; /* Now all ISO data will be ignored */ @@ -870,10 +870,10 @@ static void usbvideo_Disconnect(struct usb_interface *intf) video_unregister_device(&uvd->vdev); if (uvd->debug > 0) - info("%s: Video unregistered.", __FUNCTION__); + info("%s: Video unregistered.", __func__); if (uvd->user) - info("%s: In use, disconnect pending.", __FUNCTION__); + info("%s: In use, disconnect pending.", __func__); else usbvideo_CameraRelease(uvd); mutex_unlock(&uvd->lock); @@ -895,7 +895,7 @@ static void usbvideo_Disconnect(struct usb_interface *intf) static void usbvideo_CameraRelease(struct uvd *uvd) { if (uvd == NULL) { - err("%s: Illegal call", __FUNCTION__); + err("%s: Illegal call", __func__); return; } @@ -1013,18 +1013,18 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd) char tmp1[20], tmp2[20]; /* Buffers for printing */ if (uvd == NULL) { - err("%s: Illegal call.", __FUNCTION__); + err("%s: Illegal call.", __func__); return -EINVAL; } if (uvd->video_endp == 0) { - info("%s: No video endpoint specified; data pump disabled.", __FUNCTION__); + info("%s: No video endpoint specified; data pump disabled.", __func__); } if (uvd->paletteBits == 0) { - err("%s: No palettes specified!", __FUNCTION__); + err("%s: No palettes specified!", __func__); return -EINVAL; } if (uvd->defaultPalette == 0) { - info("%s: No default palette!", __FUNCTION__); + info("%s: No default palette!", __func__); } uvd->max_frame_size = VIDEOSIZE_X(uvd->canvas) * @@ -1034,7 +1034,7 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd) if (uvd->debug > 0) { info("%s: iface=%d. endpoint=$%02x paletteBits=$%08lx", - __FUNCTION__, uvd->iface, uvd->video_endp, uvd->paletteBits); + __func__, uvd->iface, uvd->video_endp, uvd->paletteBits); } if (uvd->dev == NULL) { err("%s: uvd->dev == NULL", __func__); @@ -1042,11 +1042,11 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd) } uvd->vdev.dev = &uvd->dev->dev; if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { - err("%s: video_register_device failed", __FUNCTION__); + err("%s: video_register_device failed", __func__); return -EPIPE; } if (uvd->debug > 1) { - info("%s: video_register_device() successful", __FUNCTION__); + info("%s: video_register_device() successful", __func__); } info("%s on /dev/video%d: canvas=%s videosize=%s", @@ -1113,14 +1113,14 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) int i, errCode = 0; if (uvd->debug > 1) - info("%s($%p)", __FUNCTION__, dev); + info("%s($%p)", __func__, dev); if (0 < usbvideo_ClientIncModCount(uvd)) return -ENODEV; mutex_lock(&uvd->lock); if (uvd->user) { - err("%s: Someone tried to open an already opened device!", __FUNCTION__); + err("%s: Someone tried to open an already opened device!", __func__); errCode = -EBUSY; } else { /* Clear statistics */ @@ -1136,7 +1136,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) RingQueue_Allocate(&uvd->dp, RING_QUEUE_SIZE); if ((uvd->fbuf == NULL) || (!RingQueue_IsAllocated(&uvd->dp))) { - err("%s: Failed to allocate fbuf or dp", __FUNCTION__); + err("%s: Failed to allocate fbuf or dp", __func__); errCode = -ENOMEM; } else { /* Allocate all buffers */ @@ -1180,19 +1180,19 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) if (errCode == 0) { if (VALID_CALLBACK(uvd, setupOnOpen)) { if (uvd->debug > 1) - info("%s: setupOnOpen callback", __FUNCTION__); + info("%s: setupOnOpen callback", __func__); errCode = GET_CALLBACK(uvd, setupOnOpen)(uvd); if (errCode < 0) { err("%s: setupOnOpen callback failed (%d.).", - __FUNCTION__, errCode); + __func__, errCode); } else if (uvd->debug > 1) { - info("%s: setupOnOpen callback successful", __FUNCTION__); + info("%s: setupOnOpen callback successful", __func__); } } if (errCode == 0) { uvd->settingsAdjusted = 0; if (uvd->debug > 1) - info("%s: Open succeeded.", __FUNCTION__); + info("%s: Open succeeded.", __func__); uvd->user++; file->private_data = uvd; } @@ -1202,7 +1202,7 @@ static int usbvideo_v4l_open(struct inode *inode, struct file *file) if (errCode != 0) usbvideo_ClientDecModCount(uvd); if (uvd->debug > 0) - info("%s: Returning %d.", __FUNCTION__, errCode); + info("%s: Returning %d.", __func__, errCode); return errCode; } @@ -1225,7 +1225,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file) int i; if (uvd->debug > 1) - info("%s($%p)", __FUNCTION__, dev); + info("%s($%p)", __func__, dev); mutex_lock(&uvd->lock); GET_CALLBACK(uvd, stopDataPump)(uvd); @@ -1252,7 +1252,7 @@ static int usbvideo_v4l_close(struct inode *inode, struct file *file) usbvideo_ClientDecModCount(uvd); if (uvd->debug > 1) - info("%s: Completed.", __FUNCTION__); + info("%s: Completed.", __func__); file->private_data = NULL; return 0; } @@ -1506,7 +1506,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, return -EFAULT; if (uvd->debug >= 1) - info("%s: %Zd. bytes, noblock=%d.", __FUNCTION__, count, noblock); + info("%s: %Zd. bytes, noblock=%d.", __func__, count, noblock); mutex_lock(&uvd->lock); @@ -1553,7 +1553,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, */ if (frmx == -1) { if (uvd->defaultPalette == 0) { - err("%s: No default palette; don't know what to do!", __FUNCTION__); + err("%s: No default palette; don't know what to do!", __func__); count = -EFAULT; goto read_done; } @@ -1625,7 +1625,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, frame->seqRead_Index += count; if (uvd->debug >= 1) { err("%s: {copy} count used=%Zd, new seqRead_Index=%ld", - __FUNCTION__, count, frame->seqRead_Index); + __func__, count, frame->seqRead_Index); } /* Finally check if the frame is done with and "release" it */ @@ -1636,7 +1636,7 @@ static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf, /* Mark it as available to be used again. */ uvd->frame[frmx].frameState = FrameState_Unused; if (usbvideo_NewFrame(uvd, (frmx + 1) % USBVIDEO_NUMFRAMES)) { - err("%s: usbvideo_NewFrame failed.", __FUNCTION__); + err("%s: usbvideo_NewFrame failed.", __func__); } } read_done: @@ -1747,10 +1747,10 @@ static int usbvideo_StartDataPump(struct uvd *uvd) int i, errFlag; if (uvd->debug > 1) - info("%s($%p)", __FUNCTION__, uvd); + info("%s($%p)", __func__, uvd); if (!CAMERA_IS_OPERATIONAL(uvd)) { - err("%s: Camera is not operational", __FUNCTION__); + err("%s: Camera is not operational", __func__); return -EFAULT; } uvd->curframe = -1; @@ -1758,14 +1758,14 @@ static int usbvideo_StartDataPump(struct uvd *uvd) /* Alternate interface 1 is is the biggest frame size */ i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive); if (i < 0) { - err("%s: usb_set_interface error", __FUNCTION__); + err("%s: usb_set_interface error", __func__); uvd->last_error = i; return -EBUSY; } if (VALID_CALLBACK(uvd, videoStart)) GET_CALLBACK(uvd, videoStart)(uvd); else - err("%s: videoStart not set", __FUNCTION__); + err("%s: videoStart not set", __func__); /* We double buffer the Iso lists */ for (i=0; i < USBVIDEO_NUMSBUF; i++) { @@ -1790,12 +1790,12 @@ static int usbvideo_StartDataPump(struct uvd *uvd) for (i=0; i < USBVIDEO_NUMSBUF; i++) { errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL); if (errFlag) - err("%s: usb_submit_isoc(%d) ret %d", __FUNCTION__, i, errFlag); + err("%s: usb_submit_isoc(%d) ret %d", __func__, i, errFlag); } uvd->streaming = 1; if (uvd->debug > 1) - info("%s: streaming=1 video_endp=$%02x", __FUNCTION__, uvd->video_endp); + info("%s: streaming=1 video_endp=$%02x", __func__, uvd->video_endp); return 0; } @@ -1817,14 +1817,14 @@ static void usbvideo_StopDataPump(struct uvd *uvd) return; if (uvd->debug > 1) - info("%s($%p)", __FUNCTION__, uvd); + info("%s($%p)", __func__, uvd); /* Unschedule all of the iso td's */ for (i=0; i < USBVIDEO_NUMSBUF; i++) { usb_kill_urb(uvd->sbuf[i].urb); } if (uvd->debug > 1) - info("%s: streaming=0", __FUNCTION__); + info("%s: streaming=0", __func__); uvd->streaming = 0; if (!uvd->remove_pending) { @@ -1832,12 +1832,12 @@ static void usbvideo_StopDataPump(struct uvd *uvd) if (VALID_CALLBACK(uvd, videoStop)) GET_CALLBACK(uvd, videoStop)(uvd); else - err("%s: videoStop not set", __FUNCTION__); + err("%s: videoStop not set", __func__); /* Set packet size to 0 */ j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive); if (j < 0) { - err("%s: usb_set_interface() error %d.", __FUNCTION__, j); + err("%s: usb_set_interface() error %d.", __func__, j); uvd->last_error = j; } } @@ -1961,12 +1961,12 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) struct usbvideo_frame *frame = &uvd->frame[frameNum]; if (uvd->debug >= 2) - info("%s($%p,%d.)", __FUNCTION__, uvd, frameNum); + info("%s($%p,%d.)", __func__, uvd, frameNum); switch (frame->frameState) { case FrameState_Unused: if (uvd->debug >= 2) - info("%s: FrameState_Unused", __FUNCTION__); + info("%s: FrameState_Unused", __func__); return -EINVAL; case FrameState_Ready: case FrameState_Grabbing: @@ -1976,7 +1976,7 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) redo: if (!CAMERA_IS_OPERATIONAL(uvd)) { if (uvd->debug >= 2) - info("%s: Camera is not operational (1)", __FUNCTION__); + info("%s: Camera is not operational (1)", __func__); return -EIO; } ntries = 0; @@ -1985,24 +1985,24 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) signalPending = signal_pending(current); if (!CAMERA_IS_OPERATIONAL(uvd)) { if (uvd->debug >= 2) - info("%s: Camera is not operational (2)", __FUNCTION__); + info("%s: Camera is not operational (2)", __func__); return -EIO; } assert(uvd->fbuf != NULL); if (signalPending) { if (uvd->debug >= 2) - info("%s: Signal=$%08x", __FUNCTION__, signalPending); + info("%s: Signal=$%08x", __func__, signalPending); if (uvd->flags & FLAGS_RETRY_VIDIOCSYNC) { usbvideo_TestPattern(uvd, 1, 0); uvd->curframe = -1; uvd->stats.frame_num++; if (uvd->debug >= 2) - info("%s: Forced test pattern screen", __FUNCTION__); + info("%s: Forced test pattern screen", __func__); return 0; } else { /* Standard answer: Interrupted! */ if (uvd->debug >= 2) - info("%s: Interrupted!", __FUNCTION__); + info("%s: Interrupted!", __func__); return -EINTR; } } else { @@ -2012,17 +2012,17 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) else if (VALID_CALLBACK(uvd, processData)) GET_CALLBACK(uvd, processData)(uvd, frame); else - err("%s: processData not set", __FUNCTION__); + err("%s: processData not set", __func__); } } while (frame->frameState == FrameState_Grabbing); if (uvd->debug >= 2) { info("%s: Grabbing done; state=%d. (%lu. bytes)", - __FUNCTION__, frame->frameState, frame->seqRead_Length); + __func__, frame->frameState, frame->seqRead_Length); } if (frame->frameState == FrameState_Error) { int ret = usbvideo_NewFrame(uvd, frameNum); if (ret < 0) { - err("%s: usbvideo_NewFrame() failed (%d.)", __FUNCTION__, ret); + err("%s: usbvideo_NewFrame() failed (%d.)", __func__, ret); return ret; } goto redo; @@ -2054,7 +2054,7 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) } frame->frameState = FrameState_Done_Hold; if (uvd->debug >= 2) - info("%s: Entered FrameState_Done_Hold state.", __FUNCTION__); + info("%s: Entered FrameState_Done_Hold state.", __func__); return 0; case FrameState_Done_Hold: @@ -2065,12 +2065,12 @@ static int usbvideo_GetFrame(struct uvd *uvd, int frameNum) * it will be released back into the wild to roam freely. */ if (uvd->debug >= 2) - info("%s: FrameState_Done_Hold state.", __FUNCTION__); + info("%s: FrameState_Done_Hold state.", __func__); return 0; } /* Catch-all for other cases. We shall not be here. */ - err("%s: Invalid state %d.", __FUNCTION__, frame->frameState); + err("%s: Invalid state %d.", __func__, frame->frameState); frame->frameState = FrameState_Unused; return 0; } @@ -2166,7 +2166,7 @@ static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd, const int ccm = 128; /* Color correction median - see below */ if ((uvd == NULL) || (frame == NULL)) { - err("%s: Illegal call.", __FUNCTION__); + err("%s: Illegal call.", __func__); return; } adj = (uvd->vpic.contrast - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/ diff --git a/linux/drivers/media/video/usbvideo/vicam.c b/linux/drivers/media/video/usbvideo/vicam.c index 984f4b756..5853563fa 100644 --- a/linux/drivers/media/video/usbvideo/vicam.c +++ b/linux/drivers/media/video/usbvideo/vicam.c @@ -50,7 +50,7 @@ // #define VICAM_DEBUG #ifdef VICAM_DEBUG -#define ADBG(lineno,fmt,args...) printk(fmt, jiffies, __FUNCTION__, lineno, ##args) +#define ADBG(lineno,fmt,args...) printk(fmt, jiffies, __func__, lineno, ##args) #define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt,##args) #else #define DBG(fmn,args...) do {} while(0) diff --git a/linux/drivers/media/video/videobuf-core.c b/linux/drivers/media/video/videobuf-core.c index 5220023c2..367f150a9 100644 --- a/linux/drivers/media/video/videobuf-core.c +++ b/linux/drivers/media/video/videobuf-core.c @@ -95,13 +95,14 @@ int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, return CALL(q, iolock, q, vb, fbuf); } -/* --------------------------------------------------------------------- */ - -static int videobuf_mmap_setup_default(struct videobuf_queue *q, - struct videobuf_buffer *vb) +void *videobuf_queue_to_vmalloc (struct videobuf_queue *q, + struct videobuf_buffer *buf) { - return 0; + return CALL(q, vmalloc, buf); } +EXPORT_SYMBOL_GPL(videobuf_queue_to_vmalloc); + +/* --------------------------------------------------------------------- */ void videobuf_queue_core_init(struct videobuf_queue *q, @@ -124,9 +125,6 @@ void videobuf_queue_core_init(struct videobuf_queue *q, q->priv_data = priv; q->int_ops = int_ops; - if (!q->int_ops->mmap_setup) - q->int_ops->mmap_setup = videobuf_mmap_setup_default; - /* All buffer operations are mandatory */ BUG_ON(!q->ops->buf_setup); BUG_ON(!q->ops->buf_prepare); @@ -136,6 +134,9 @@ void videobuf_queue_core_init(struct videobuf_queue *q, /* Having implementations for abstract methods are mandatory */ BUG_ON(!q->int_ops); + /* Having irqlock is mandatory */ + BUG_ON(!q->irqlock); + mutex_init(&q->vb_lock); init_waitqueue_head(&q->wait); INIT_LIST_HEAD(&q->stream); @@ -190,8 +191,7 @@ void videobuf_queue_cancel(struct videobuf_queue *q) wake_up_interruptible_sync(&q->wait); /* remove queued buffers from list */ - if (q->irqlock) - spin_lock_irqsave(q->irqlock, flags); + spin_lock_irqsave(q->irqlock, flags); for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) continue; @@ -201,8 +201,7 @@ void videobuf_queue_cancel(struct videobuf_queue *q) wake_up_all(&q->bufs[i]->done); } } - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock, flags); + spin_unlock_irqrestore(q->irqlock, flags); /* free all buffers + clear queue */ for (i = 0; i < VIDEO_MAX_FRAME; i++) { @@ -304,6 +303,8 @@ static int __videobuf_mmap_free(struct videobuf_queue *q) rc = CALL(q, mmap_free, q); + q->is_mmapped = 0; + if (rc < 0) return rc; @@ -355,9 +356,6 @@ static int __videobuf_mmap_setup(struct videobuf_queue *q, switch (memory) { case V4L2_MEMORY_MMAP: q->bufs[i]->boff = bsize * i; - err = q->int_ops->mmap_setup(q, q->bufs[i]); - if (err) - break; break; case V4L2_MEMORY_USERPTR: case V4L2_MEMORY_OVERLAY: @@ -559,11 +557,9 @@ int videobuf_qbuf(struct videobuf_queue *q, list_add_tail(&buf->stream, &q->stream); if (q->streaming) { - if (q->irqlock) - spin_lock_irqsave(q->irqlock, flags); + spin_lock_irqsave(q->irqlock, flags); q->ops->buf_queue(q, buf); - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock, flags); + spin_unlock_irqrestore(q->irqlock, flags); } dprintk(1, "qbuf: succeded\n"); retval = 0; @@ -700,13 +696,11 @@ int videobuf_streamon(struct videobuf_queue *q) if (q->streaming) goto done; q->streaming = 1; - if (q->irqlock) - spin_lock_irqsave(q->irqlock, flags); + spin_lock_irqsave(q->irqlock, flags); list_for_each_entry(buf, &q->stream, stream) if (buf->state == VIDEOBUF_PREPARED) q->ops->buf_queue(q, buf); - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock, flags); + spin_unlock_irqrestore(q->irqlock, flags); wake_up_interruptible_sync(&q->wait); done: @@ -762,11 +756,10 @@ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q, goto done; /* start capture & wait */ - if (q->irqlock) - spin_lock_irqsave(q->irqlock, flags); + spin_lock_irqsave(q->irqlock, flags); q->ops->buf_queue(q, q->read_buf); - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock, flags); + spin_unlock_irqrestore(q->irqlock, flags); + retval = videobuf_waiton(q->read_buf, 0, 0); if (0 == retval) { CALL(q, sync, q, q->read_buf); @@ -827,12 +820,10 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, q->read_buf = NULL; goto done; } - if (q->irqlock) - spin_lock_irqsave(q->irqlock, flags); - + spin_lock_irqsave(q->irqlock, flags); q->ops->buf_queue(q, q->read_buf); - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock, flags); + spin_unlock_irqrestore(q->irqlock, flags); + q->read_off = 0; } @@ -898,12 +889,12 @@ static int __videobuf_read_start(struct videobuf_queue *q) return err; list_add_tail(&q->bufs[i]->stream, &q->stream); } - if (q->irqlock) - spin_lock_irqsave(q->irqlock, flags); + + spin_lock_irqsave(q->irqlock, flags); for (i = 0; i < count; i++) q->ops->buf_queue(q, q->bufs[i]); - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock, flags); + spin_unlock_irqrestore(q->irqlock, flags); + q->reading = 1; return 0; } @@ -912,7 +903,6 @@ static void __videobuf_read_stop(struct videobuf_queue *q) { int i; - videobuf_queue_cancel(q); __videobuf_mmap_free(q); INIT_LIST_HEAD(&q->stream); @@ -967,7 +957,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); - dprintk(2, "%s\n", __FUNCTION__); + dprintk(2, "%s\n", __func__); mutex_lock(&q->vb_lock); retval = -EBUSY; if (q->streaming) @@ -1016,11 +1006,11 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q, if (q->read_off == q->read_buf->size) { list_add_tail(&q->read_buf->stream, &q->stream); - if (q->irqlock) - spin_lock_irqsave(q->irqlock, flags); + + spin_lock_irqsave(q->irqlock, flags); q->ops->buf_queue(q, q->read_buf); - if (q->irqlock) - spin_unlock_irqrestore(q->irqlock, flags); + spin_unlock_irqrestore(q->irqlock, flags); + q->read_buf = NULL; } if (retval < 0) @@ -1080,6 +1070,7 @@ int videobuf_mmap_mapper(struct videobuf_queue *q, mutex_lock(&q->vb_lock); retval = CALL(q, mmap_mapper, q, vma); + q->is_mmapped = 1; mutex_unlock(&q->vb_lock); return retval; diff --git a/linux/drivers/media/video/videobuf-dma-sg.c b/linux/drivers/media/video/videobuf-dma-sg.c index 06a219e0d..7d459ed6b 100644 --- a/linux/drivers/media/video/videobuf-dma-sg.c +++ b/linux/drivers/media/video/videobuf-dma-sg.c @@ -163,9 +163,6 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, dprintk(1,"init user [0x%lx+0x%lx => %d pages]\n", data,size,dma->nr_pages); - dma->varea = (void *) data; - - err = get_user_pages(current,current->mm, data & PAGE_MASK, dma->nr_pages, rw == READ, 1, /* force */ @@ -253,7 +250,7 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma) dma->nr_pages, dma->direction); if (0 == dma->sglen) { printk(KERN_WARNING - "%s: videobuf_map_sg failed\n",__FUNCTION__); + "%s: videobuf_map_sg failed\n",__func__); kfree(dma->sglist); dma->sglist = NULL; dma->sglen = 0; @@ -305,7 +302,6 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma) vfree(dma->vmalloc); dma->vmalloc = NULL; - dma->varea = NULL; if (dma->bus_addr) { dma->bus_addr = 0; @@ -476,12 +472,22 @@ static void *__videobuf_alloc(size_t size) videobuf_dma_init(&mem->dma); dprintk(1,"%s: allocated at %p(%ld+%ld) & %p(%ld)\n", - __FUNCTION__,vb,(long)sizeof(*vb),(long)size-sizeof(*vb), + __func__,vb,(long)sizeof(*vb),(long)size-sizeof(*vb), mem,(long)sizeof(*mem)); return vb; } +static void *__videobuf_to_vmalloc (struct videobuf_buffer *buf) +{ + struct videobuf_dma_sg_memory *mem = buf->priv; + BUG_ON(!mem); + + MAGIC_CHECK(mem->magic, MAGIC_SG_MEM); + + return mem->dma.vmalloc; +} + static int __videobuf_iolock (struct videobuf_queue* q, struct videobuf_buffer *vb, struct v4l2_framebuffer *fbuf) @@ -727,6 +733,7 @@ static struct videobuf_qtype_ops sg_ops = { .mmap_mapper = __videobuf_mmap_mapper, .video_copy_to_user = __videobuf_copy_to_user, .copy_stream = __videobuf_copy_stream, + .vmalloc = __videobuf_to_vmalloc, }; void *videobuf_sg_alloc(size_t size) diff --git a/linux/drivers/media/video/videobuf-dvb.c b/linux/drivers/media/video/videobuf-dvb.c index 8966a53db..9a821371a 100644 --- a/linux/drivers/media/video/videobuf-dvb.c +++ b/linux/drivers/media/video/videobuf-dvb.c @@ -21,13 +21,14 @@ #include <linux/fs.h> #include <linux/kthread.h> #include <linux/file.h> + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) #include <linux/suspend.h> #else #include <linux/freezer.h> #endif -#include <media/videobuf-dma-sg.h> +#include <media/videobuf-core.h> #include <media/videobuf-dvb.h> #include "compat.h" @@ -51,7 +52,7 @@ static int videobuf_dvb_thread(void *data) struct videobuf_buffer *buf; unsigned long flags; int err; - struct videobuf_dmabuf *dma; + void *outp; dprintk("dvb thread started\n"); set_freezable(); @@ -72,9 +73,10 @@ static int videobuf_dvb_thread(void *data) try_to_freeze(); /* feed buffer data to demux */ - dma=videobuf_to_dma(buf); + outp = videobuf_queue_to_vmalloc (&dvb->dvbq, buf); + if (buf->state == VIDEOBUF_DONE) - dvb_dmx_swfilter(&dvb->demux, dma->vmalloc, + dvb_dmx_swfilter(&dvb->demux, outp, buf->size); /* requeue buffer */ @@ -144,14 +146,16 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed) int videobuf_dvb_register(struct videobuf_dvb *dvb, struct module *module, void *adapter_priv, - struct device *device) + struct device *device, + short *adapter_nr) { int result; mutex_init(&dvb->lock); /* register adapter */ - result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device); + result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device, + adapter_nr); if (result < 0) { printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", dvb->name, result); diff --git a/linux/drivers/media/video/videobuf-vmalloc.c b/linux/drivers/media/video/videobuf-vmalloc.c index 3bc7308af..6f487b348 100644 --- a/linux/drivers/media/video/videobuf-vmalloc.c +++ b/linux/drivers/media/video/videobuf-vmalloc.c @@ -58,20 +58,26 @@ videobuf_vm_open(struct vm_area_struct *vma) map->count++; } -static void -videobuf_vm_close(struct vm_area_struct *vma) +static void videobuf_vm_close(struct vm_area_struct *vma) { struct videobuf_mapping *map = vma->vm_private_data; struct videobuf_queue *q = map->q; int i; - dprintk(2,"vm_close %p [count=%u,vma=%08lx-%08lx]\n",map, - map->count,vma->vm_start,vma->vm_end); + dprintk(2,"vm_close %p [count=%u,vma=%08lx-%08lx]\n", map, + map->count, vma->vm_start, vma->vm_end); map->count--; if (0 == map->count) { - dprintk(1,"munmap %p q=%p\n",map,q); + struct videobuf_vmalloc_memory *mem; + + dprintk(1, "munmap %p q=%p\n", map, q); mutex_lock(&q->vb_lock); + + /* We need first to cancel streams, before unmapping */ + if (q->streaming) + videobuf_queue_cancel(q); + for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) continue; @@ -79,12 +85,35 @@ videobuf_vm_close(struct vm_area_struct *vma) if (q->bufs[i]->map != map) continue; + mem = q->bufs[i]->priv; + if (mem) { + /* This callback is called only if kernel has + allocated memory and this memory is mmapped. + In this case, memory should be freed, + in order to do memory unmap. + */ + + MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); + + /* vfree is not atomic - can't be + called with IRQ's disabled + */ + dprintk(1, "%s: buf[%d] freeing (%p)\n", + __func__, i, mem->vmalloc); + + vfree(mem->vmalloc); + mem->vmalloc = NULL; + } + q->bufs[i]->map = NULL; q->bufs[i]->baddr = 0; } - mutex_unlock(&q->vb_lock); + kfree(map); + + mutex_unlock(&q->vb_lock); } + return; } @@ -115,7 +144,7 @@ static void *__videobuf_alloc(size_t size) mem->magic=MAGIC_VMAL_MEM; dprintk(1,"%s: allocated at %p(%ld+%ld) & %p(%ld)\n", - __FUNCTION__,vb,(long)sizeof(*vb),(long)size-sizeof(*vb), + __func__,vb,(long)sizeof(*vb),(long)size-sizeof(*vb), mem,(long)sizeof(*mem)); return vb; @@ -125,53 +154,77 @@ static int __videobuf_iolock (struct videobuf_queue* q, struct videobuf_buffer *vb, struct v4l2_framebuffer *fbuf) { + struct videobuf_vmalloc_memory *mem = vb->priv; int pages; - struct videobuf_vmalloc_memory *mem=vb->priv; BUG_ON(!mem); - MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); + MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); - pages = PAGE_ALIGN(vb->size) >> PAGE_SHIFT; + switch (vb->memory) { + case V4L2_MEMORY_MMAP: + dprintk(1, "%s memory method MMAP\n", __func__); - /* Currently, doesn't support V4L2_MEMORY_OVERLAY */ - if ((vb->memory != V4L2_MEMORY_MMAP) && - (vb->memory != V4L2_MEMORY_USERPTR) ) { - printk(KERN_ERR "Method currently unsupported.\n"); - return -EINVAL; - } + /* All handling should be done by __videobuf_mmap_mapper() */ + if (!mem->vmalloc) { + printk(KERN_ERR "memory is not alloced/mmapped.\n"); + return -EINVAL; + } + break; + case V4L2_MEMORY_USERPTR: + pages = PAGE_ALIGN(vb->size); - /* FIXME: should be tested with kernel mmap mem */ - mem->vmalloc=vmalloc_user (PAGE_ALIGN(vb->size)); - if (NULL == mem->vmalloc) { - printk(KERN_ERR "vmalloc (%d pages) failed\n",pages); - return -ENOMEM; - } + dprintk(1, "%s memory method USERPTR\n", __func__); - dprintk(1,"vmalloc is at addr 0x%08lx, size=%d\n", - (unsigned long)mem->vmalloc, - pages << PAGE_SHIFT); +#if 1 /* keep */ + if (vb->baddr) { + printk(KERN_ERR "USERPTR is currently not supported\n"); + return -EINVAL; + } +#endif - return 0; -} + /* The only USERPTR currently supported is the one needed for + read() method. + */ -static int __videobuf_mmap_setup(struct videobuf_queue *q, - struct videobuf_buffer *vb) -{ - int retval = 0; - BUG_ON(vb->memory != V4L2_MEMORY_MMAP); - if (vb->state == VIDEOBUF_NEEDS_INIT) { - /* bsize == size since the buffer needs to be large enough to - * hold an entire frame, not the case in the read case for - * example*/ - vb->size = vb->bsize; - retval = __videobuf_iolock(q, vb, NULL); - if (!retval) { - /* Don't IOLOCK later */ - vb->state = VIDEOBUF_IDLE; + mem->vmalloc = vmalloc_user(pages); + if (!mem->vmalloc) { + printk(KERN_ERR "vmalloc (%d pages) failed\n", pages); + return -ENOMEM; + } + dprintk(1, "vmalloc is at addr %p (%d pages)\n", + mem->vmalloc, pages); + +#if 0 /* keep */ + int rc; + /* Kernel userptr is used also by read() method. In this case, + there's no need to remap, since data will be copied to user + */ + if (!vb->baddr) + return 0; + + /* FIXME: to properly support USERPTR, remap should occur. + The code bellow won't work, since mem->vma = NULL + */ + /* Try to remap memory */ + rc = remap_vmalloc_range(mem->vma, (void *)vb->baddr, 0); + if (rc < 0) { + printk(KERN_ERR "mmap: remap failed with error %d. ", rc); + return -ENOMEM; } +#endif + + break; + case V4L2_MEMORY_OVERLAY: + default: + dprintk(1, "%s memory method OVERLAY/unknown\n", __func__); + + /* Currently, doesn't support V4L2_MEMORY_OVERLAY */ + printk(KERN_ERR "Memory method currently unsupported.\n"); + return -EINVAL; } - return retval; + + return 0; } static int __videobuf_sync(struct videobuf_queue *q, @@ -184,6 +237,7 @@ static int __videobuf_mmap_free(struct videobuf_queue *q) { unsigned int i; + dprintk(1, "%s\n", __func__); for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (q->bufs[i]) { if (q->bufs[i]->map) @@ -200,10 +254,11 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, struct videobuf_vmalloc_memory *mem; struct videobuf_mapping *map; unsigned int first; - int retval; + int retval, pages; unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; - if (! (vma->vm_flags & VM_WRITE) || ! (vma->vm_flags & VM_SHARED)) + dprintk(1, "%s\n", __func__); + if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) return -EINVAL; /* look for first buffer to map */ @@ -223,39 +278,55 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, } /* create mapping + update buffer list */ - map = q->bufs[first]->map = kzalloc(sizeof(struct videobuf_mapping),GFP_KERNEL); + map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL); if (NULL == map) return -ENOMEM; + q->bufs[first]->map = map; map->start = vma->vm_start; map->end = vma->vm_end; map->q = q; q->bufs[first]->baddr = vma->vm_start; - vma->vm_ops = &videobuf_vm_ops; - vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; - vma->vm_private_data = map; + mem = q->bufs[first]->priv; + BUG_ON(!mem); + MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); - mem=q->bufs[first]->priv; - BUG_ON (!mem); - MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); + pages = PAGE_ALIGN(vma->vm_end - vma->vm_start); + mem->vmalloc = vmalloc_user(pages); + if (!mem->vmalloc) { + printk(KERN_ERR "vmalloc (%d pages) failed\n", pages); + goto error; + } + dprintk(1, "vmalloc is at addr %p (%d pages)\n", + mem->vmalloc, pages); /* Try to remap memory */ - retval=remap_vmalloc_range(vma, mem->vmalloc,0); - if (retval<0) { - dprintk(1, "mmap: failed to remap_vmalloc_range\n"); - return -EINVAL; + retval = remap_vmalloc_range(vma, mem->vmalloc, 0); + if (retval < 0) { + printk(KERN_ERR "mmap: remap failed with error %d. ", retval); + vfree(mem->vmalloc); + goto error; } + vma->vm_ops = &videobuf_vm_ops; + vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; + vma->vm_private_data = map; + dprintk(1,"mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n", - map,q,vma->vm_start,vma->vm_end, + map, q, vma->vm_start, vma->vm_end, (long int) q->bufs[first]->bsize, - vma->vm_pgoff,first); + vma->vm_pgoff, first); videobuf_vm_open(vma); - return (0); + return 0; + +error: + mem = NULL; + kfree(map); + return -ENOMEM; } static int __videobuf_copy_to_user ( struct videobuf_queue *q, @@ -313,11 +384,11 @@ static struct videobuf_qtype_ops qops = { .alloc = __videobuf_alloc, .iolock = __videobuf_iolock, .sync = __videobuf_sync, - .mmap_setup = __videobuf_mmap_setup, .mmap_free = __videobuf_mmap_free, .mmap_mapper = __videobuf_mmap_mapper, .video_copy_to_user = __videobuf_copy_to_user, .copy_stream = __videobuf_copy_stream, + .vmalloc = videobuf_to_vmalloc, }; void videobuf_queue_vmalloc_init(struct videobuf_queue* q, @@ -347,13 +418,24 @@ EXPORT_SYMBOL_GPL(videobuf_to_vmalloc); void videobuf_vmalloc_free (struct videobuf_buffer *buf) { - struct videobuf_vmalloc_memory *mem=buf->priv; - BUG_ON (!mem); + struct videobuf_vmalloc_memory *mem = buf->priv; - MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); + /* mmapped memory can't be freed here, otherwise mmapped region + would be released, while still needed. In this case, the memory + release should happen inside videobuf_vm_close(). + So, it should free memory only if the memory were allocated for + read() operation. + */ + if ((buf->memory != V4L2_MEMORY_USERPTR) || (buf->baddr == 0)) + return; + + if (!mem) + return; + + MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM); vfree(mem->vmalloc); - mem->vmalloc=NULL; + mem->vmalloc = NULL; return; } diff --git a/linux/drivers/media/video/videocodec.c b/linux/drivers/media/video/videocodec.c index b30b6b2a9..cf24956f3 100644 --- a/linux/drivers/media/video/videocodec.c +++ b/linux/drivers/media/video/videocodec.c @@ -39,6 +39,7 @@ #ifdef CONFIG_PROC_FS #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <asm/uaccess.h> #endif @@ -320,56 +321,22 @@ videocodec_unregister (const struct videocodec *codec) } #ifdef CONFIG_PROC_FS -/* ============ */ -/* procfs stuff */ -/* ============ */ - -static char *videocodec_buf = NULL; -static int videocodec_bufsize; - -static int -videocodec_build_table (void) +static int proc_videocodecs_show(struct seq_file *m, void *v) { struct codec_list *h = codeclist_top; struct attached_list *a; - int i = 0, size; - - // sum up amount of slaves plus their attached masters - while (h) { - i += h->attached + 1; - h = h->next; - } -#define LINESIZE 100 - size = LINESIZE * (i + 1); - dprintk(3, "videocodec_build table: %d entries, %d bytes\n", i, - size); - - kfree(videocodec_buf); - videocodec_buf = kmalloc(size, GFP_KERNEL); - - if (!videocodec_buf) - return 0; - - i = 0; - i += scnprintf(videocodec_buf + i, size - 1, - "<S>lave or attached <M>aster name type flags magic "); - i += scnprintf(videocodec_buf + i, size -i - 1, "(connected as)\n"); + seq_printf(m, "<S>lave or attached <M>aster name type flags magic "); + seq_printf(m, "(connected as)\n"); h = codeclist_top; while (h) { - if (i > (size - LINESIZE)) - break; // security check - i += scnprintf(videocodec_buf + i, size -i -1, - "S %32s %04x %08lx %08lx (TEMPLATE)\n", + seq_printf(m, "S %32s %04x %08lx %08lx (TEMPLATE)\n", h->codec->name, h->codec->type, h->codec->flags, h->codec->magic); a = h->list; while (a) { - if (i > (size - LINESIZE)) - break; // security check - i += scnprintf(videocodec_buf + i, size -i -1, - "M %32s %04x %08lx %08lx (%s)\n", + seq_printf(m, "M %32s %04x %08lx %08lx (%s)\n", a->codec->master_data->name, a->codec->master_data->type, a->codec->master_data->flags, @@ -380,54 +347,21 @@ videocodec_build_table (void) h = h->next; } - return i; + return 0; } -//The definition: -//typedef int (read_proc_t)(char *page, char **start, off_t off, -// int count, int *eof, void *data); - -static int -videocodec_info (char *buffer, - char **buffer_location, - off_t offset, - int buffer_length, - int *eof, - void *data) +static int proc_videocodecs_open(struct inode *inode, struct file *file) { - int size; - - dprintk(3, "videocodec_info: offset: %ld, len %d / size %d\n", - offset, buffer_length, videocodec_bufsize); - - if (offset == 0) { - videocodec_bufsize = videocodec_build_table(); - } - if ((offset < 0) || (offset >= videocodec_bufsize)) { - dprintk(4, - "videocodec_info: call delivers no result, return 0\n"); - *eof = 1; - return 0; - } - - if (buffer_length < (videocodec_bufsize - offset)) { - dprintk(4, "videocodec_info: %ld needed, %d got\n", - videocodec_bufsize - offset, buffer_length); - size = buffer_length; - } else { - dprintk(4, "videocodec_info: last reading of %ld bytes\n", - videocodec_bufsize - offset); - size = videocodec_bufsize - offset; - *eof = 1; - } - - memcpy(buffer, videocodec_buf + offset, size); - /* doesn't work... */ - /* copy_to_user(buffer, videocodec_buf+offset, size); */ - /* *buffer_location = videocodec_buf+offset; */ - - return size; + return single_open(file, proc_videocodecs_show, NULL); } + +static const struct file_operations videocodecs_proc_fops = { + .owner = THIS_MODULE, + .open = proc_videocodecs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; #endif /* ===================== */ @@ -444,16 +378,8 @@ videocodec_init (void) VIDEOCODEC_VERSION); #ifdef CONFIG_PROC_FS - videocodec_buf = NULL; - videocodec_bufsize = 0; - - videocodec_proc_entry = create_proc_entry("videocodecs", 0, NULL); - if (videocodec_proc_entry) { - videocodec_proc_entry->read_proc = videocodec_info; - videocodec_proc_entry->write_proc = NULL; - videocodec_proc_entry->data = NULL; - videocodec_proc_entry->owner = THIS_MODULE; - } else { + videocodec_proc_entry = proc_create("videocodecs", 0, NULL, &videocodecs_proc_fops); + if (!videocodec_proc_entry) { dprintk(1, KERN_ERR "videocodec: can't init procfs.\n"); } #endif @@ -465,7 +391,6 @@ videocodec_exit (void) { #ifdef CONFIG_PROC_FS remove_proc_entry("videocodecs", NULL); - kfree(videocodec_buf); #endif } diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c index 9c38b6b2f..50c504bc0 100644 --- a/linux/drivers/media/video/videodev.c +++ b/linux/drivers/media/video/videodev.c @@ -18,14 +18,14 @@ #define dbgarg(cmd, fmt, arg...) \ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ - printk (KERN_DEBUG "%s: ", vfd->name); \ + printk(KERN_DEBUG "%s: ", vfd->name); \ v4l_printk_ioctl(cmd); \ - printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); \ + printk(" " fmt, ## arg); \ } #define dbgarg2(fmt, arg...) \ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ - printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); + printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg); #include <linux/module.h> #include <linux/types.h> @@ -382,38 +382,45 @@ static const char *v4l2_int_ioctls[] = { external ioctl messages as well as internal V4L ioctl */ void v4l_printk_ioctl(unsigned int cmd) { - char *dir; + char *dir, *type; - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: dir = "--"; break; - case _IOC_READ: dir = "r-"; break; - case _IOC_WRITE: dir = "-w"; break; - case _IOC_READ | _IOC_WRITE: dir = "rw"; break; - default: dir = "*ERR*"; break; - } switch (_IOC_TYPE(cmd)) { case 'd': - printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? - v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; + if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) { + type = "v4l2_int"; + break; + } + printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]); + return; #ifdef CONFIG_VIDEO_V4L1_COMPAT case 'v': - printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L1_IOCTLS) ? - v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; + if (_IOC_NR(cmd) >= V4L1_IOCTLS) { + type = "v4l1"; + break; + } + printk("%s", v4l1_ioctls[_IOC_NR(cmd)]); + return; #endif case 'V': - printk("v4l2 ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L2_IOCTLS) ? - v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; - + if (_IOC_NR(cmd) >= V4L2_IOCTLS) { + type = "v4l2"; + break; + } + printk("%s", v4l2_ioctls[_IOC_NR(cmd)]); + return; default: - printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n", - _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); + type = "unknown"; + } + + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: dir = "--"; break; + case _IOC_READ: dir = "r-"; break; + case _IOC_WRITE: dir = "-w"; break; + case _IOC_READ | _IOC_WRITE: dir = "rw"; break; + default: dir = "*ERR*"; break; } + printk("%s ioctl '%c', dir=%s, #%d (0x%08x)", + type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); } EXPORT_SYMBOL(v4l_printk_ioctl); @@ -811,6 +818,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if ( (vfd->debug & V4L2_DEBUG_IOCTL) && !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { v4l_print_ioctl(vfd->name, cmd); + printk("\n"); } #ifdef CONFIG_VIDEO_V4L1_COMPAT @@ -1901,8 +1909,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { if (ret<0) { - printk ("%s: err:\n", vfd->name); + printk("%s: err: on ", vfd->name); v4l_print_ioctl(vfd->name, cmd); + printk("\n"); } } @@ -2063,7 +2072,7 @@ int video_register_device(struct video_device *vfd, int type, int nr) break; default: printk(KERN_ERR "%s called with unknown type: %d\n", - __FUNCTION__, type); + __func__, type); return -1; } @@ -2112,7 +2121,7 @@ int video_register_device(struct video_device *vfd, int type, int nr) ret = device_register(&vfd->class_dev); if (ret < 0) { printk(KERN_ERR "%s: device_register failed\n", - __FUNCTION__); + __func__); goto fail_minor; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 6464c69f3..900a17404 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -439,7 +439,7 @@ static void vivi_sleep(struct vivi_fh *fh) int timeout; DECLARE_WAITQUEUE(wait, current); - dprintk(dev, 1, "%s dma_q=0x%08lx\n", __FUNCTION__, + dprintk(dev, 1, "%s dma_q=0x%08lx\n", __func__, (unsigned long)dma_q); add_wait_queue(&dma_q->wq, &wait); @@ -514,7 +514,7 @@ static int vivi_start_thread(struct vivi_fh *fh) dma_q->frame = 0; dma_q->ini_jiffies = jiffies; - dprintk(dev, 1, "%s\n", __FUNCTION__); + dprintk(dev, 1, "%s\n", __func__); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) dma_q->kthread = kthread_run(vivi_thread, fh, "vivi"); @@ -541,7 +541,7 @@ static int vivi_start_thread(struct vivi_fh *fh) /* Wakes thread */ wake_up_interruptible(&dma_q->wq); - dprintk(dev, 1, "returning from %s\n", __FUNCTION__); + dprintk(dev, 1, "returning from %s\n", __func__); return 0; } @@ -549,7 +549,7 @@ static void vivi_stop_thread(struct vivi_dmaqueue *dma_q) { struct vivi_dev *dev = container_of(dma_q, struct vivi_dev, vidq); - dprintk(dev, 1, "%s\n", __FUNCTION__); + dprintk(dev, 1, "%s\n", __func__); /* shutdown control thread */ if (dma_q->kthread) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) @@ -586,7 +586,7 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) while (*size * *count > vid_limit * 1024 * 1024) (*count)--; - dprintk(dev, 1, "%s, count=%d, size=%d\n", __FUNCTION__, + dprintk(dev, 1, "%s, count=%d, size=%d\n", __func__, *count, *size); return 0; @@ -597,13 +597,13 @@ static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) struct vivi_fh *fh = vq->priv_data; struct vivi_dev *dev = fh->dev; - dprintk(dev, 1, "%s, state: %i\n", __FUNCTION__, buf->vb.state); + dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state); if (in_interrupt()) BUG(); videobuf_vmalloc_free(&buf->vb); - dprintk(dev, 1, "free_buffer: freed"); + dprintk(dev, 1, "free_buffer: freed\n"); buf->vb.state = VIDEOBUF_NEEDS_INIT; } @@ -618,7 +618,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); int rc; - dprintk(dev, 1, "%s, field=%d\n", __FUNCTION__, field); + dprintk(dev, 1, "%s, field=%d\n", __func__, field); BUG_ON(NULL == fh->fmt); @@ -659,7 +659,7 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) struct vivi_dev *dev = fh->dev; struct vivi_dmaqueue *vidq = &dev->vidq; - dprintk(dev, 1, "%s\n", __FUNCTION__); + dprintk(dev, 1, "%s\n", __func__); buf->vb.state = VIDEOBUF_QUEUED; list_add_tail(&buf->vb.queue, &vidq->active); @@ -672,7 +672,7 @@ static void buffer_release(struct videobuf_queue *vq, struct vivi_fh *fh = vq->priv_data; struct vivi_dev *dev = (struct vivi_dev *)fh->dev; - dprintk(dev, 1, "%s\n", __FUNCTION__); + dprintk(dev, 1, "%s\n", __func__); free_buffer(vq, buf); } @@ -788,7 +788,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, mutex_lock(&q->vb_lock); if (videobuf_queue_is_busy(&fh->vb_vidq)) { - dprintk(fh->dev, 1, "%s queue busy\n", __FUNCTION__); + dprintk(fh->dev, 1, "%s queue busy\n", __func__); ret = -EBUSY; goto out; } @@ -1044,7 +1044,7 @@ vivi_poll(struct file *file, struct poll_table_struct *wait) struct vivi_dev *dev = fh->dev; struct videobuf_queue *q = &fh->vb_vidq; - dprintk(dev, 1, "%s\n", __FUNCTION__); + dprintk(dev, 1, "%s\n", __func__); if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) return POLLERR; @@ -1123,7 +1123,7 @@ static const struct file_operations vivi_fops = { .poll = vivi_poll, .ioctl = video_ioctl2, /* V4L2 ioctl handler */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) - .compat_ioctl = v4l_compat_ioctl32, + .compat_ioctl = v4l_compat_ioctl32, #endif .mmap = vivi_mmap, .llseek = no_llseek, diff --git a/linux/drivers/media/video/w9966.c b/linux/drivers/media/video/w9966.c index 595e32a87..9b77f268c 100644 --- a/linux/drivers/media/video/w9966.c +++ b/linux/drivers/media/video/w9966.c @@ -65,7 +65,7 @@ /*#define DEBUG*/ /* Undef me for production */ #ifdef DEBUG -#define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: %s(): "x, __FUNCTION__ , ##a) +#define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: %s(): "x, __func__ , ##a) #else #define DPRINTF(x...) #endif diff --git a/linux/drivers/media/video/w9968cf.h b/linux/drivers/media/video/w9968cf.h index c2e609bac..8e1742cb7 100644 --- a/linux/drivers/media/video/w9968cf.h +++ b/linux/drivers/media/video/w9968cf.h @@ -304,7 +304,7 @@ struct w9968cf_device { dev_warn(&cam->dev, fmt "\n", ## args); \ else if ((level) >= 5) \ dev_info(&cam->dev, "[%s:%d] " fmt "\n", \ - __FUNCTION__, __LINE__ , ## args); \ + __func__, __LINE__ , ## args); \ } \ } /* For generic kernel (not device specific) messages */ @@ -315,7 +315,7 @@ struct w9968cf_device { if ((level) >= 1 && (level) <= 4) \ pr_info("w9968cf: " fmt "\n", ## args); \ else if ((level) >= 5) \ - pr_debug("w9968cf: [%s:%d] " fmt "\n", __FUNCTION__, \ + pr_debug("w9968cf: [%s:%d] " fmt "\n", __func__, \ __LINE__ , ## args); \ } \ } @@ -327,7 +327,7 @@ struct w9968cf_device { #undef PDBG #define PDBG(fmt, args...) \ -dev_info(&cam->dev, "[%s:%d] " fmt "\n", __FUNCTION__, __LINE__ , ## args); +dev_info(&cam->dev, "[%s:%d] " fmt "\n", __func__, __LINE__ , ## args); #undef PDBGG #define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */ diff --git a/linux/drivers/media/video/zc0301/zc0301.h b/linux/drivers/media/video/zc0301/zc0301.h index 6a944c658..d0e258176 100644 --- a/linux/drivers/media/video/zc0301/zc0301.h +++ b/linux/drivers/media/video/zc0301/zc0301.h @@ -167,7 +167,7 @@ do { \ dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ else if ((level) >= 3) \ dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", \ - __FILE__, __FUNCTION__, __LINE__ , ## args); \ + __FILE__, __func__, __LINE__ , ## args); \ } \ } while (0) # define KDBG(level, fmt, args...) \ @@ -177,7 +177,7 @@ do { \ pr_info("zc0301: " fmt "\n", ## args); \ else if ((level) == 3) \ pr_debug("sn9c102: [%s:%s:%d] " fmt "\n", __FILE__, \ - __FUNCTION__, __LINE__ , ## args); \ + __func__, __LINE__ , ## args); \ } \ } while (0) # define V4LDBG(level, name, cmd) \ @@ -193,7 +193,7 @@ do { \ #undef PDBG #define PDBG(fmt, args...) \ -dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __FUNCTION__, \ +dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __func__, \ __LINE__ , ## args) #undef PDBGG diff --git a/linux/drivers/media/video/zoran.h b/linux/drivers/media/video/zoran.h index 848dbcf25..5f74688c1 100644 --- a/linux/drivers/media/video/zoran.h +++ b/linux/drivers/media/video/zoran.h @@ -243,10 +243,8 @@ struct zoran_format { #ifdef CONFIG_VIDEO_V4L1_COMPAT int palette; #endif -#ifdef CONFIG_VIDEO_V4L2 __u32 fourcc; int colorspace; -#endif int depth; __u32 flags; __u32 vfespfr; @@ -271,20 +269,6 @@ struct zoran_v4l_settings { const struct zoran_format *format; /* capture format */ }; -/* whoops, this one is undeclared if !v4l2 */ -#ifndef CONFIG_VIDEO_V4L2 -struct v4l2_jpegcompression { - int quality; - int APPn; - int APP_len; - char APP_data[60]; - int COM_len; - char COM_data[60]; - __u32 jpeg_markers; - __u8 reserved[116]; -}; -#endif - /* jpg-capture/-playback settings */ struct zoran_jpg_settings { int decimation; /* this bit is used to set everything to default */ diff --git a/linux/drivers/media/video/zoran_driver.c b/linux/drivers/media/video/zoran_driver.c index ceb5c1778..6b7a7c137 100644 --- a/linux/drivers/media/video/zoran_driver.c +++ b/linux/drivers/media/video/zoran_driver.c @@ -88,7 +88,6 @@ #include "zoran_device.h" #include "zoran_card.h" -#ifdef CONFIG_VIDEO_V4L2 /* we declare some card type definitions here, they mean * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */ #define ZORAN_V4L2_VID_FLAGS ( \ @@ -97,19 +96,15 @@ V4L2_CAP_VIDEO_OUTPUT |\ V4L2_CAP_VIDEO_OVERLAY \ ) -#endif #include <asm/byteorder.h> -#if defined(CONFIG_VIDEO_V4L2) && defined(CONFIG_VIDEO_V4L1_COMPAT) +#if defined(CONFIG_VIDEO_V4L1_COMPAT) #define ZFMT(pal, fcc, cs) \ .palette = (pal), .fourcc = (fcc), .colorspace = (cs) -#elif defined(CONFIG_VIDEO_V4L2) -#define ZFMT(pal, fcc, cs) \ - .fourcc = (fcc), .colorspace = (cs) #else #define ZFMT(pal, fcc, cs) \ - .palette = (pal) + .fourcc = (fcc), .colorspace = (cs) #endif const struct zoran_format zoran_formats[] = { @@ -219,7 +214,6 @@ static int lock_norm; /* 0 = default 1 = Don't change TV standard (norm) */ module_param(lock_norm, int, 0644); MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)"); -#ifdef CONFIG_VIDEO_V4L2 /* small helper function for calculating buffersizes for v4l2 * we calculate the nearest higher power-of-two, which * will be the recommended buffersize */ @@ -242,7 +236,6 @@ zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings) return 8192; return result; } -#endif /* forward references */ static void v4l_fbuffer_free(struct file *file); @@ -353,7 +346,7 @@ v4l_fbuffer_alloc (struct file *file) /* Use kmalloc */ mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL); - if (mem == 0) { + if (!mem) { dprintk(1, KERN_ERR "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n", @@ -1776,7 +1769,6 @@ setup_overlay (struct file *file, return wait_grab_pending(zr); } -#ifdef CONFIG_VIDEO_V4L2 /* get the status of a buffer in the clients buffer queue */ static int zoran_v4l2_buffer_status (struct file *file, @@ -1882,7 +1874,6 @@ zoran_v4l2_buffer_status (struct file *file, return 0; } -#endif static int zoran_set_norm (struct zoran *zr, @@ -2691,8 +2682,6 @@ zoran_do_ioctl (struct inode *inode, } break; -#ifdef CONFIG_VIDEO_V4L2 - /* The new video4linux2 capture interface - much nicer than video4linux1, since * it allows for integrating the JPEG capturing calls inside standard v4l2 */ @@ -4264,7 +4253,6 @@ zoran_do_ioctl (struct inode *inode, return 0; } break; -#endif default: dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n", @@ -4314,7 +4302,7 @@ zoran_poll (struct file *file, dprintk(3, KERN_DEBUG "%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n", - ZR_DEVNAME(zr), __FUNCTION__, + ZR_DEVNAME(zr), __func__, "FAL"[fh->v4l_buffers.active], zr->v4l_sync_tail, "UPMD"[zr->v4l_buffers.buffer[frame].state], zr->v4l_pend_tail, zr->v4l_pend_head); @@ -4336,7 +4324,7 @@ zoran_poll (struct file *file, dprintk(3, KERN_DEBUG "%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n", - ZR_DEVNAME(zr), __FUNCTION__, + ZR_DEVNAME(zr), __func__, "FAL"[fh->jpg_buffers.active], zr->jpg_que_tail, "UPMD"[zr->jpg_buffers.buffer[frame].state], zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head); @@ -4724,9 +4712,7 @@ static const struct file_operations zoran_fops = { struct video_device zoran_template __devinitdata = { .name = ZORAN_NAME, .type = ZORAN_VID_TYPE, -#ifdef CONFIG_VIDEO_V4L2 .type2 = ZORAN_V4L2_VID_FLAGS, -#endif .fops = &zoran_fops, .release = &zoran_vdev_release, .minor = -1 diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c index 0afd1c9c1..c2abb3af9 100644 --- a/linux/drivers/media/video/zr364xx.c +++ b/linux/drivers/media/video/zr364xx.c @@ -395,7 +395,7 @@ static int read_frame(struct zr364xx_camera *cam, int framenum) } -static ssize_t zr364xx_read(struct file *file, char *buf, size_t cnt, +static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t cnt, loff_t * ppos) { unsigned long count = cnt; |