Commit 586a9edd authored by Michael Hunold's avatar Michael Hunold Committed by Linus Torvalds

[PATCH] dvb subsystem and saa7146 v4l fixes

This fixes some issues in the dvb subsystem and some nasty things in the
v4l saa7146 driver.

[DVB]
 - dvb-core: aquire -> acquire spelling fix
 - nxt600 frontend: don't send zero-byte messages when probing the PLL
   type
 - Kconfig: add a note that says that the CI of the budget-CI card is
   not actually supported by the budget-CI driver
 - ttusb-dec: Check for presence of crc32 function.  Make unknown types
   of packet less likely to cause packet loss.

[V4L]
 - saa7146: use kernel mint_t()/max_t() instead of homebrewn stuff
 - saa7146: disable video clipping before capturing for sure to prevent
   black pictures
 - saa7146: make sure to disable the right video dma upon device close
 - saa7146: don't free resources if disabling an already disabled video
   overlay
parent a71d72ce
#include <linux/kernel.h>
#include <media/saa7146_vv.h> #include <media/saa7146_vv.h>
#define my_min(type,x,y) \
({ type __x = (x), __y = (y); __x < __y ? __x: __y; })
#define my_max(type,x,y) \
({ type __x = (x), __y = (y); __x > __y ? __x: __y; })
static void calculate_output_format_register(struct saa7146_dev* saa, u32 palette, u32* clip_format) static void calculate_output_format_register(struct saa7146_dev* saa, u32 palette, u32* clip_format)
{ {
/* clear out the necessary bits */ /* clear out the necessary bits */
...@@ -398,11 +394,11 @@ static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct sa ...@@ -398,11 +394,11 @@ static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct sa
b = y[i]+h[i]; b = y[i]+h[i];
/* insert left/right coordinates */ /* insert left/right coordinates */
pixel_list[ 2*i ] = my_min(int, l, width); pixel_list[ 2*i ] = min_t(int, l, width);
pixel_list[(2*i)+1] = my_min(int, r, width); pixel_list[(2*i)+1] = min_t(int, r, width);
/* insert top/bottom coordinates */ /* insert top/bottom coordinates */
line_list[ 2*i ] = my_min(int, t, height); line_list[ 2*i ] = min_t(int, t, height);
line_list[(2*i)+1] = my_min(int, b, height); line_list[(2*i)+1] = min_t(int, b, height);
} }
/* sort and eliminate lists */ /* sort and eliminate lists */
...@@ -411,9 +407,9 @@ static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct sa ...@@ -411,9 +407,9 @@ static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct sa
sort_and_eliminate( &line_list[0], &cnt_line ); sort_and_eliminate( &line_list[0], &cnt_line );
/* calculate the number of used u32s */ /* calculate the number of used u32s */
numdwords = my_max(int, (cnt_line+1), (cnt_pixel+1))*2; numdwords = max_t(int, (cnt_line+1), (cnt_pixel+1))*2;
numdwords = my_max(int, 4, numdwords); numdwords = max_t(int, 4, numdwords);
numdwords = my_min(int, 64, numdwords); numdwords = min_t(int, 64, numdwords);
/* fill up cliptable */ /* fill up cliptable */
for(i = 0; i < cnt_pixel; i++) { for(i = 0; i < cnt_pixel; i++) {
...@@ -1022,6 +1018,7 @@ void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struc ...@@ -1022,6 +1018,7 @@ void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struc
saa7146_set_window(dev, buf->fmt->width, buf->fmt->height, buf->fmt->field); saa7146_set_window(dev, buf->fmt->width, buf->fmt->height, buf->fmt->field);
saa7146_set_output_format(dev, sfmt->trans); saa7146_set_output_format(dev, sfmt->trans);
saa7146_disable_clipping(dev);
if ( vv->last_field == V4L2_FIELD_INTERLACED ) { if ( vv->last_field == V4L2_FIELD_INTERLACED ) {
} else if ( vv->last_field == V4L2_FIELD_TOP ) { } else if ( vv->last_field == V4L2_FIELD_TOP ) {
......
...@@ -755,7 +755,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file) ...@@ -755,7 +755,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
dmas = MASK_22 | MASK_21 | MASK_20; dmas = MASK_22 | MASK_21 | MASK_20;
} else { } else {
resource = RESOURCE_DMA1_HPS; resource = RESOURCE_DMA1_HPS;
dmas = MASK_20; dmas = MASK_22;
} }
saa7146_res_free(fh, resource); saa7146_res_free(fh, resource);
...@@ -1110,6 +1110,9 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -1110,6 +1110,9 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
DEB_D(("overlay is active, but in another open\n")); DEB_D(("overlay is active, but in another open\n"));
return -EAGAIN; return -EAGAIN;
} }
} else {
DEB_D(("overlay is not active\n"));
return 0;
} }
spin_lock_irqsave(&dev->slock,flags); spin_lock_irqsave(&dev->slock,flags);
err = saa7146_stop_preview(fh); err = saa7146_stop_preview(fh);
......
...@@ -67,7 +67,7 @@ struct dvb_frontend_data { ...@@ -67,7 +67,7 @@ struct dvb_frontend_data {
pid_t thread_pid; pid_t thread_pid;
unsigned long release_jiffies; unsigned long release_jiffies;
unsigned long lost_sync_jiffies; unsigned long lost_sync_jiffies;
int aquire_signal; int acquire_signal;
int bending; int bending;
int lnb_drift; int lnb_drift;
int timeout_count; int timeout_count;
...@@ -306,7 +306,7 @@ static int dvb_frontend_set_parameters (struct dvb_frontend_data *fe, ...@@ -306,7 +306,7 @@ static int dvb_frontend_set_parameters (struct dvb_frontend_data *fe,
fe->lost_sync_count = 0; fe->lost_sync_count = 0;
fe->lost_sync_jiffies = jiffies; fe->lost_sync_jiffies = jiffies;
fe->lnb_drift = 0; fe->lnb_drift = 0;
fe->aquire_signal = 1; fe->acquire_signal = 1;
if (fe->status & ~FE_TIMEDOUT) if (fe->status & ~FE_TIMEDOUT)
dvb_frontend_add_event (fe, 0); dvb_frontend_add_event (fe, 0);
memcpy (&fe->parameters, param, memcpy (&fe->parameters, param,
...@@ -467,13 +467,13 @@ static int dvb_frontend_thread (void *data) ...@@ -467,13 +467,13 @@ static int dvb_frontend_thread (void *data)
if (s & FE_HAS_LOCK) { if (s & FE_HAS_LOCK) {
fe->timeout_count = 0; fe->timeout_count = 0;
fe->lost_sync_count = 0; fe->lost_sync_count = 0;
fe->aquire_signal = 0; fe->acquire_signal = 0;
} else { } else {
fe->lost_sync_count++; fe->lost_sync_count++;
if (!(fe->info->caps & FE_CAN_RECOVER)) { if (!(fe->info->caps & FE_CAN_RECOVER)) {
if (!(fe->info->caps & FE_CAN_CLEAN_SETUP)) { if (!(fe->info->caps & FE_CAN_CLEAN_SETUP)) {
if (fe->lost_sync_count < 10) { if (fe->lost_sync_count < 10) {
if (fe->aquire_signal) if (fe->acquire_signal)
dvb_frontend_internal_ioctl( dvb_frontend_internal_ioctl(
&fe->frontend, &fe->frontend,
FE_RESET, NULL); FE_RESET, NULL);
......
...@@ -374,7 +374,7 @@ static int tdmb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) ...@@ -374,7 +374,7 @@ static int tdmb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
cx22700_set_inversion (i2c, p->inversion); cx22700_set_inversion (i2c, p->inversion);
cx22700_set_tps (i2c, &p->u.ofdm); cx22700_set_tps (i2c, &p->u.ofdm);
cx22700_writereg (i2c, 0x37, 0x01); /* PAL loop filter off */ cx22700_writereg (i2c, 0x37, 0x01); /* PAL loop filter off */
cx22700_writereg (i2c, 0x00, 0x01); /* restart aquire */ cx22700_writereg (i2c, 0x00, 0x01); /* restart acquire */
break; break;
} }
......
...@@ -123,7 +123,19 @@ static u8 nxt6000_readreg(struct dvb_frontend *fe, u8 reg) ...@@ -123,7 +123,19 @@ static u8 nxt6000_readreg(struct dvb_frontend *fe, u8 reg)
struct nxt6000_config *nxt = FE2NXT(fe); struct nxt6000_config *nxt = FE2NXT(fe);
return nxt6000_read(fe->i2c, nxt->demod_addr, reg); return nxt6000_read(fe->i2c, nxt->demod_addr, reg);
}
static int pll_test(struct dvb_i2c_bus *i2c, u8 demod_addr, u8 tuner_addr)
{
u8 buf [1];
struct i2c_msg msg = {.addr = tuner_addr >> 1,.flags = I2C_M_RD,.buf = buf,.len = 1 };
int ret;
nxt6000_write(i2c, demod_addr, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */
ret = i2c->xfer(i2c, &msg, 1);
nxt6000_write(i2c, demod_addr, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */
return (ret != 1) ? -EFAULT : 0;
} }
static int pll_write(struct dvb_i2c_bus *i2c, u8 demod_addr, u8 tuner_addr, u8 *buf, u8 len) static int pll_write(struct dvb_i2c_bus *i2c, u8 demod_addr, u8 tuner_addr, u8 *buf, u8 len)
...@@ -833,21 +845,21 @@ static int nxt6000_attach(struct dvb_i2c_bus *i2c, void **data) ...@@ -833,21 +845,21 @@ static int nxt6000_attach(struct dvb_i2c_bus *i2c, void **data)
if (nxt6000_read(i2c, demod_addr_tbl[addr_nr], OFDM_MSC_REV) != NXT6000ASICDEVICE) if (nxt6000_read(i2c, demod_addr_tbl[addr_nr], OFDM_MSC_REV) != NXT6000ASICDEVICE)
continue; continue;
if (pll_write(i2c, demod_addr_tbl[addr_nr], 0xC0, NULL, 0) == 0) { if (pll_test(i2c, demod_addr_tbl[addr_nr], 0xC0) == 0) {
nxt->tuner_addr = 0xC0; nxt->tuner_addr = 0xC0;
nxt->tuner_type = TUNER_TYPE_ALP510; nxt->tuner_type = TUNER_TYPE_ALP510;
nxt->clock_inversion = 1; nxt->clock_inversion = 1;
dprintk("nxt6000: detected TI ALP510 tuner at 0x%02X\n", nxt->tuner_addr); dprintk("nxt6000: detected TI ALP510 tuner at 0x%02X\n", nxt->tuner_addr);
} else if (pll_write(i2c, demod_addr_tbl[addr_nr], 0xC2, NULL, 0) == 0) { } else if (pll_test(i2c, demod_addr_tbl[addr_nr], 0xC2) == 0) {
nxt->tuner_addr = 0xC2; nxt->tuner_addr = 0xC2;
nxt->tuner_type = TUNER_TYPE_SP5659; nxt->tuner_type = TUNER_TYPE_SP5659;
nxt->clock_inversion = 0; nxt->clock_inversion = 0;
dprintk("nxt6000: detected MITEL SP5659 tuner at 0x%02X\n", nxt->tuner_addr); dprintk("nxt6000: detected MITEL SP5659 tuner at 0x%02X\n", nxt->tuner_addr);
} else if (pll_write(i2c, demod_addr_tbl[addr_nr], 0xC0, NULL, 0) == 0) { } else if (pll_test(i2c, demod_addr_tbl[addr_nr], 0xC0) == 0) {
nxt->tuner_addr = 0xC0; nxt->tuner_addr = 0xC0;
nxt->tuner_type = TUNER_TYPE_SP5730; nxt->tuner_type = TUNER_TYPE_SP5730;
nxt->clock_inversion = 0; nxt->clock_inversion = 0;
......
...@@ -66,6 +66,9 @@ config DVB_BUDGET_CI ...@@ -66,6 +66,9 @@ config DVB_BUDGET_CI
(so called Budget- or Nova-PCI cards) without onboard (so called Budget- or Nova-PCI cards) without onboard
MPEG2 decoder, but with onboard Common Interface connector. MPEG2 decoder, but with onboard Common Interface connector.
Note: The Common Interface is not yet supported by this driver
due to lack of information from the vendor.
Say Y if you own such a card and want to use it. Say Y if you own such a card and want to use it.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
......
...@@ -2,6 +2,7 @@ config DVB_TTUSB_DEC ...@@ -2,6 +2,7 @@ config DVB_TTUSB_DEC
tristate "Technotrend/Hauppauge USB DEC devices" tristate "Technotrend/Hauppauge USB DEC devices"
depends on DVB_CORE && USB depends on DVB_CORE && USB
select FW_LOADER select FW_LOADER
select CRC32
help help
Support for external USB adapters designed by Technotrend and Support for external USB adapters designed by Technotrend and
produced by Hauppauge, shipped under the brand name 'DEC2000-t' produced by Hauppauge, shipped under the brand name 'DEC2000-t'
......
...@@ -552,13 +552,14 @@ static void ttusb_dec_process_urb_frame(struct ttusb_dec * dec, u8 * b, ...@@ -552,13 +552,14 @@ static void ttusb_dec_process_urb_frame(struct ttusb_dec * dec, u8 * b,
break; break;
case 3: case 3:
if (*b++ == 0x00) { if (*b == 0x00) {
dec->packet_state++; dec->packet_state++;
dec->packet_length = 0; dec->packet_length = 0;
} else { } else if (*b != 0xaa) {
dec->packet_state = 0; dec->packet_state = 0;
} }
b++;
length--; length--;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment