summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2007-09-27 18:27:03 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-09-27 18:27:03 -0300
commit63c63d931c469cf4cbda715ad4bc4a92783ce84b (patch)
treee809c463c93bb588598efaacbff6a4aced7740d7 /linux
parent65de801c051f783e016e022cba03311ba64c524e (diff)
downloadmediapointer-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.c60
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);