diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-09-27 18:27:03 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-09-27 18:27:03 -0300 |
commit | 63c63d931c469cf4cbda715ad4bc4a92783ce84b (patch) | |
tree | e809c463c93bb588598efaacbff6a4aced7740d7 /linux | |
parent | 65de801c051f783e016e022cba03311ba64c524e (diff) | |
download | mediapointer-dvb-s2-63c63d931c469cf4cbda715ad4bc4a92783ce84b.tar.gz mediapointer-dvb-s2-63c63d931c469cf4cbda715ad4bc4a92783ce84b.tar.bz2 |
Avoid having two tuner commands happening at the same time
From: Mauro Carvalho Chehab <mchehab@infradead.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
---
linux/drivers/media/video/tuner-xc2028.c | 60 ++++++++++++++++++++++++-------
1 file changed, 47 insertions(+), 13 deletions(-)
Diffstat (limited to 'linux')
-rw-r--r-- | linux/drivers/media/video/tuner-xc2028.c | 60 |
1 files changed, 47 insertions, 13 deletions
diff --git a/linux/drivers/media/video/tuner-xc2028.c b/linux/drivers/media/video/tuner-xc2028.c index 153d023a5..e55fa5c25 100644 --- a/linux/drivers/media/video/tuner-xc2028.c +++ b/linux/drivers/media/video/tuner-xc2028.c @@ -9,10 +9,15 @@ #include <linux/i2c.h> #include <asm/div64.h> #include <linux/firmware.h> -#include "compat.h" #include <linux/videodev.h> #include <linux/delay.h> #include <media/tuner.h> +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) +#include <linux/mutex.h> +#else +#include <asm/semaphore.h> +#endif +#include "compat.h" #include "tuner-driver.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) #include "i2c-compat.h" @@ -51,6 +56,12 @@ struct xc2028_data { were loaded? */ enum tuner_mode mode; struct i2c_client *i2c_client; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) + struct mutex lock; +#else + struct semaphore lock; +#endif }; #define i2c_send(rc,c,buf,size) \ @@ -298,20 +309,28 @@ static int check_firmware(struct i2c_client *c, enum tuner_mode new_mode, static int xc2028_signal(struct i2c_client *c) { - int lock, signal; + struct tuner *t = i2c_get_clientdata(c); + struct xc2028_data *xc2028 = t->priv; + int frq_lock, signal=0; + + mutex_lock(&xc2028->lock); printk(KERN_INFO "xc2028: %s called\n", __FUNCTION__); - lock = xc2028_get_reg(c, 0x2); - if (lock<=0) - return lock; + frq_lock = xc2028_get_reg(c, 0x2); + if (frq_lock<=0) + goto ret; /* Frequency is locked. Return signal quality */ signal = xc2028_get_reg(c, 0x40); - if(signal<=0) - return lock; + if(signal<=0) { + signal=frq_lock; + } + +ret: + mutex_unlock(&xc2028->lock); return signal; } @@ -331,6 +350,8 @@ static void generic_set_tv_freq(struct i2c_client *c, u32 freq /* in Hz */, when freq is changed */ struct xc2028_data *xc2028 = t->priv; + mutex_lock(&xc2028->lock); + xc2028->firm_type=0; /* Reset GPIO 1 */ @@ -338,14 +359,14 @@ static void generic_set_tv_freq(struct i2c_client *c, u32 freq /* in Hz */, rc = t->tuner_callback( c->adapter->algo_data, XC2028_TUNER_RESET, 0); if (rc<0) - return; + goto ret; } msleep(10); #endif printk("xc3028: should set frequency %d kHz)\n", freq / 1000); if (check_firmware(c, new_mode, bandwidth)<0) - return; + goto ret; if(new_mode == T_DIGITAL_TV) offset = 2750000; @@ -358,7 +379,7 @@ static void generic_set_tv_freq(struct i2c_client *c, u32 freq /* in Hz */, rc = t->tuner_callback( c->adapter->algo_data, XC2028_RESET_CLK, 1); if (rc<0) - return; + goto ret; } msleep(10); @@ -371,23 +392,32 @@ static void generic_set_tv_freq(struct i2c_client *c, u32 freq /* in Hz */, i2c_send(rc, c, buf, sizeof(buf)); if (rc<0) - return; + goto ret; msleep(100); printk("divider= %02x %02x %02x %02x (freq=%d.%02d)\n", buf[1],buf[2],buf[3],buf[4], freq / 16, freq % 16 * 100 / 16); + +ret: + mutex_unlock(&xc2028->lock); } #if 0 static int xc2028_stereo(struct i2c_client *c) { unsigned char buffer[5]; - int rc; + int rc=0; struct tuner *t = i2c_get_clientdata(c); + struct xc2028_data *xc2028 = t->priv; + mutex_lock(&xc2028->lock); if (check_firmware(c)<0) - return 0; + goto ret; + +ret: + mutex_unlock(&xc2028->lock); + return ret; } #endif @@ -442,6 +472,8 @@ int xc2028_tuner_init(struct i2c_client *c) xc2028->need_load_generic=1; xc2028->mode = T_UNINITIALIZED; + mutex_init(&xc2028->lock); + /* FIXME: Check where t->priv will be freed */ if (version<0) @@ -524,5 +556,7 @@ int xc2028_attach(struct i2c_client *c, struct dvb_frontend *fe) return 0; } + + EXPORT_SYMBOL(xc2028_attach); |