All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 03/14] [media] tuner-core: Remove V4L1/V4L2 API switch
       [not found] <cover.1297716906.git.mchehab@redhat.com>
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 04/14] [media] tuner-core: remove the legacy is_stereo() call Mauro Carvalho Chehab
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

V4L1 was removed. So, the code there is just dead code.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 1cec122..6041c7d 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -80,7 +80,6 @@ struct tuner {
 	struct i2c_client   *i2c;
 	struct v4l2_subdev  sd;
 	struct list_head    list;
-	unsigned int        using_v4l2:1;
 
 	/* keep track of the current settings */
 	v4l2_std_id         std;
@@ -717,19 +716,6 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode,
 	return 0;
 }
 
-#define switch_v4l2()	if (!t->using_v4l2) \
-			    tuner_dbg("switching to v4l2\n"); \
-			t->using_v4l2 = 1;
-
-static inline int check_v4l2(struct tuner *t)
-{
-	/* bttv still uses both v4l1 and v4l2 calls to the tuner (v4l2 for
-	   TV, v4l1 for radio), until that is fixed this code is disabled.
-	   Otherwise the radio (v4l1) wouldn't tune after using the TV (v4l2)
-	   first. */
-	return 0;
-}
-
 static int tuner_s_type_addr(struct v4l2_subdev *sd, struct tuner_setup *type)
 {
 	struct tuner *t = to_tuner(sd);
@@ -803,8 +789,6 @@ static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
 	if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "s_std") == -EINVAL)
 		return 0;
 
-	switch_v4l2();
-
 	t->std = std;
 	tuner_fixup_std(t);
 	if (t->tv_freq)
@@ -819,7 +803,6 @@ static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
 
 	if (set_mode(client, t, f->type, "s_frequency") == -EINVAL)
 		return 0;
-	switch_v4l2();
 	set_freq(client, f->frequency);
 
 	return 0;
@@ -832,7 +815,6 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
 
 	if (check_mode(t, "g_frequency") == -EINVAL)
 		return 0;
-	switch_v4l2();
 	f->type = t->mode;
 	if (fe_tuner_ops->get_frequency) {
 		u32 abs_freq;
@@ -856,7 +838,6 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 
 	if (check_mode(t, "g_tuner") == -EINVAL)
 		return 0;
-	switch_v4l2();
 
 	vt->type = t->mode;
 	if (analog_ops->get_afc)
@@ -906,8 +887,6 @@ static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 	if (check_mode(t, "s_tuner") == -EINVAL)
 		return 0;
 
-	switch_v4l2();
-
 	/* do nothing unless we're a radio tuner */
 	if (t->mode != V4L2_TUNER_RADIO)
 		return 0;
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 04/14] [media] tuner-core: remove the legacy is_stereo() call
       [not found] <cover.1297716906.git.mchehab@redhat.com>
  2011-02-14 21:03 ` [PATCH 03/14] [media] tuner-core: Remove V4L1/V4L2 API switch Mauro Carvalho Chehab
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 05/14] [media] tuner-core: move some messages to the proper place Mauro Carvalho Chehab
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

Nobody is using this legacy call. Just remove it.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index f9f19be..3b86050 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -239,7 +239,6 @@ struct analog_demod_ops {
 	void (*set_params)(struct dvb_frontend *fe,
 			   struct analog_parameters *params);
 	int  (*has_signal)(struct dvb_frontend *fe);
-	int  (*is_stereo)(struct dvb_frontend *fe);
 	int  (*get_afc)(struct dvb_frontend *fe);
 	void (*tuner_status)(struct dvb_frontend *fe);
 	void (*standby)(struct dvb_frontend *fe);
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 6041c7d..912d8e8 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -682,9 +682,6 @@ static void tuner_status(struct dvb_frontend *fe)
 	if (analog_ops->has_signal)
 		tuner_info("Signal strength: %d\n",
 			   analog_ops->has_signal(fe));
-	if (analog_ops->is_stereo)
-		tuner_info("Stereo:          %s\n",
-			   analog_ops->is_stereo(fe) ? "yes" : "no");
 }
 
 /* ---------------------------------------------------------------------- */
@@ -861,13 +858,6 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 			(tuner_status & TUNER_STATUS_STEREO) ?
 			V4L2_TUNER_SUB_STEREO :
 			V4L2_TUNER_SUB_MONO;
-	} else {
-		if (analog_ops->is_stereo) {
-			vt->rxsubchans =
-				analog_ops->is_stereo(&t->fe) ?
-				V4L2_TUNER_SUB_STEREO :
-				V4L2_TUNER_SUB_MONO;
-		}
 	}
 	if (analog_ops->has_signal)
 		vt->signal = analog_ops->has_signal(&t->fe);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 05/14] [media] tuner-core: move some messages to the proper place
       [not found] <cover.1297716906.git.mchehab@redhat.com>
  2011-02-14 21:03 ` [PATCH 03/14] [media] tuner-core: Remove V4L1/V4L2 API switch Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 04/14] [media] tuner-core: remove the legacy is_stereo() call Mauro Carvalho Chehab
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 06/14] [media] tuner-core: Reorganize the functions internally Mauro Carvalho Chehab
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

Move the frequency set debug printk's to the code that actually
are changing it.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 912d8e8..f497f52 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -246,6 +246,9 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
 			freq = tv_range[1] * 16;
 	}
 	params.frequency = freq;
+	tuner_dbg("tv freq set to %lu.%02lu\n",
+			freq / 16, freq % 16 * 100 / 16);
+	t->tv_freq = freq;
 
 	analog_ops->set_params(&t->fe, &params);
 }
@@ -281,6 +284,9 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
 			freq = radio_range[1] * 16000;
 	}
 	params.frequency = freq;
+	tuner_dbg("radio freq set to %lu.%02lu\n",
+			freq / 16000, freq % 16000 * 100 / 16000);
+	t->radio_freq = freq;
 
 	analog_ops->set_params(&t->fe, &params);
 }
@@ -291,17 +297,11 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
 
 	switch (t->mode) {
 	case V4L2_TUNER_RADIO:
-		tuner_dbg("radio freq set to %lu.%02lu\n",
-			  freq / 16000, freq % 16000 * 100 / 16000);
 		set_radio_freq(c, freq);
-		t->radio_freq = freq;
 		break;
 	case V4L2_TUNER_ANALOG_TV:
 	case V4L2_TUNER_DIGITAL_TV:
-		tuner_dbg("tv freq set to %lu.%02lu\n",
-			  freq / 16, freq % 16 * 100 / 16);
 		set_tv_freq(c, freq);
-		t->tv_freq = freq;
 		break;
 	default:
 		tuner_dbg("freq set: unknown mode: 0x%04x!\n",t->mode);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 06/14] [media] tuner-core: Reorganize the functions internally
       [not found] <cover.1297716906.git.mchehab@redhat.com>
                   ` (2 preceding siblings ...)
  2011-02-14 21:03 ` [PATCH 05/14] [media] tuner-core: move some messages to the proper place Mauro Carvalho Chehab
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 07/14] [media] tuner-core: Some cleanups at check_mode/set_mode Mauro Carvalho Chehab
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

This is a big patch with no functional changes. It just
rearranges everything inside the driver, and prepares to
break TV and Radio into two separate fops groups.

Currently, it has an heuristics logic to determine if the
call came from radio or video. However, the caller driver
knows for sure, so tuner-core shouldn't try to guess it.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index f497f52..5c3da21 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -34,6 +34,99 @@
 
 #define PREFIX t->i2c->driver->driver.name
 
+/*
+ * Driver modprobe parameters
+ */
+
+/* insmod options used at init time => read/only */
+static unsigned int addr;
+static unsigned int no_autodetect;
+static unsigned int show_i2c;
+
+module_param(addr, int, 0444);
+module_param(no_autodetect, int, 0444);
+module_param(show_i2c, int, 0444);
+
+/* insmod options used at runtime => read/write */
+static int tuner_debug;
+static unsigned int tv_range[2] = { 44, 958 };
+static unsigned int radio_range[2] = { 65, 108 };
+static char pal[] = "--";
+static char secam[] = "--";
+static char ntsc[] = "-";
+
+module_param_named(debug,tuner_debug, int, 0644);
+module_param_array(tv_range, int, NULL, 0644);
+module_param_array(radio_range, int, NULL, 0644);
+module_param_string(pal, pal, sizeof(pal), 0644);
+module_param_string(secam, secam, sizeof(secam), 0644);
+module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
+
+/*
+ * Static vars
+ */
+
+static struct xc5000_config xc5000_cfg;
+static LIST_HEAD(tuner_list);
+
+/*
+ * Debug macros
+ */
+
+#define tuner_warn(fmt, arg...) do {			\
+	printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \
+	       i2c_adapter_id(t->i2c->adapter),		\
+	       t->i2c->addr, ##arg);			\
+	 } while (0)
+
+#define tuner_info(fmt, arg...) do {			\
+	printk(KERN_INFO "%s %d-%04x: " fmt, PREFIX,	\
+	       i2c_adapter_id(t->i2c->adapter),		\
+	       t->i2c->addr, ##arg);			\
+	 } while (0)
+
+#define tuner_err(fmt, arg...) do {			\
+	printk(KERN_ERR "%s %d-%04x: " fmt, PREFIX,	\
+	       i2c_adapter_id(t->i2c->adapter),		\
+	       t->i2c->addr, ##arg);			\
+	 } while (0)
+
+#define tuner_dbg(fmt, arg...) do {				\
+	if (tuner_debug)					\
+		printk(KERN_DEBUG "%s %d-%04x: " fmt, PREFIX,	\
+		       i2c_adapter_id(t->i2c->adapter),		\
+		       t->i2c->addr, ##arg);			\
+	 } while (0)
+
+/*
+ * Internal struct used inside the driver
+ */
+
+struct tuner {
+	/* device */
+	struct dvb_frontend fe;
+	struct i2c_client   *i2c;
+	struct v4l2_subdev  sd;
+	struct list_head    list;
+
+	/* keep track of the current settings */
+	v4l2_std_id         std;
+	unsigned int        tv_freq;
+	unsigned int        radio_freq;
+	unsigned int        audmode;
+
+	unsigned int        mode;
+	unsigned int        mode_mask; /* Combination of allowable modes */
+
+	unsigned int        type; /* chip type id */
+	unsigned int        config;
+	const char          *name;
+};
+
+/*
+ * tuner attach/detach logic
+ */
+
 /** This macro allows us to probe dynamically, avoiding static links */
 #ifdef CONFIG_MEDIA_ATTACH
 #define tuner_symbol_probe(FUNCTION, ARGS...) ({ \
@@ -74,91 +167,15 @@ static void tuner_detach(struct dvb_frontend *fe)
 }
 #endif
 
-struct tuner {
-	/* device */
-	struct dvb_frontend fe;
-	struct i2c_client   *i2c;
-	struct v4l2_subdev  sd;
-	struct list_head    list;
-
-	/* keep track of the current settings */
-	v4l2_std_id         std;
-	unsigned int        tv_freq;
-	unsigned int        radio_freq;
-	unsigned int        audmode;
-
-	unsigned int        mode;
-	unsigned int        mode_mask; /* Combination of allowable modes */
-
-	unsigned int        type; /* chip type id */
-	unsigned int        config;
-	const char          *name;
-};
 
 static inline struct tuner *to_tuner(struct v4l2_subdev *sd)
 {
 	return container_of(sd, struct tuner, sd);
 }
 
-
-/* insmod options used at init time => read/only */
-static unsigned int addr;
-static unsigned int no_autodetect;
-static unsigned int show_i2c;
-
-/* insmod options used at runtime => read/write */
-static int tuner_debug;
-
-#define tuner_warn(fmt, arg...) do {			\
-	printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \
-	       i2c_adapter_id(t->i2c->adapter),		\
-	       t->i2c->addr, ##arg);			\
-	 } while (0)
-
-#define tuner_info(fmt, arg...) do {			\
-	printk(KERN_INFO "%s %d-%04x: " fmt, PREFIX,	\
-	       i2c_adapter_id(t->i2c->adapter),		\
-	       t->i2c->addr, ##arg);			\
-	 } while (0)
-
-#define tuner_err(fmt, arg...) do {			\
-	printk(KERN_ERR "%s %d-%04x: " fmt, PREFIX,	\
-	       i2c_adapter_id(t->i2c->adapter),		\
-	       t->i2c->addr, ##arg);			\
-	 } while (0)
-
-#define tuner_dbg(fmt, arg...) do {				\
-	if (tuner_debug)					\
-		printk(KERN_DEBUG "%s %d-%04x: " fmt, PREFIX,	\
-		       i2c_adapter_id(t->i2c->adapter),		\
-		       t->i2c->addr, ##arg);			\
-	 } while (0)
-
-/* ------------------------------------------------------------------------ */
-
-static unsigned int tv_range[2] = { 44, 958 };
-static unsigned int radio_range[2] = { 65, 108 };
-
-static char pal[] = "--";
-static char secam[] = "--";
-static char ntsc[] = "-";
-
-
-module_param(addr, int, 0444);
-module_param(no_autodetect, int, 0444);
-module_param(show_i2c, int, 0444);
-module_param_named(debug,tuner_debug, int, 0644);
-module_param_string(pal, pal, sizeof(pal), 0644);
-module_param_string(secam, secam, sizeof(secam), 0644);
-module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
-module_param_array(tv_range, int, NULL, 0644);
-module_param_array(radio_range, int, NULL, 0644);
-
-MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
-MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
-MODULE_LICENSE("GPL");
-
-/* ---------------------------------------------------------------------- */
+/*
+ * struct analog_demod_ops callbacks
+ */
 
 static void fe_set_params(struct dvb_frontend *fe,
 			  struct analog_parameters *params)
@@ -214,101 +231,13 @@ static struct analog_demod_ops tuner_analog_ops = {
 	.tuner_status   = tuner_status
 };
 
-/* Set tuner frequency,  freq in Units of 62.5kHz = 1/16MHz */
-static void set_tv_freq(struct i2c_client *c, unsigned int freq)
-{
-	struct tuner *t = to_tuner(i2c_get_clientdata(c));
-	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
+/*
+ * Functions that are common to both TV and radio
+ */
 
-	struct analog_parameters params = {
-		.mode      = t->mode,
-		.audmode   = t->audmode,
-		.std       = t->std
-	};
-
-	if (t->type == UNSET) {
-		tuner_warn ("tuner type not set\n");
-		return;
-	}
-	if (NULL == analog_ops->set_params) {
-		tuner_warn ("Tuner has no way to set tv freq\n");
-		return;
-	}
-	if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) {
-		tuner_dbg ("TV freq (%d.%02d) out of range (%d-%d)\n",
-			   freq / 16, freq % 16 * 100 / 16, tv_range[0],
-			   tv_range[1]);
-		/* V4L2 spec: if the freq is not possible then the closest
-		   possible value should be selected */
-		if (freq < tv_range[0] * 16)
-			freq = tv_range[0] * 16;
-		else
-			freq = tv_range[1] * 16;
-	}
-	params.frequency = freq;
-	tuner_dbg("tv freq set to %lu.%02lu\n",
-			freq / 16, freq % 16 * 100 / 16);
-	t->tv_freq = freq;
-
-	analog_ops->set_params(&t->fe, &params);
-}
-
-static void set_radio_freq(struct i2c_client *c, unsigned int freq)
-{
-	struct tuner *t = to_tuner(i2c_get_clientdata(c));
-	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
-
-	struct analog_parameters params = {
-		.mode      = t->mode,
-		.audmode   = t->audmode,
-		.std       = t->std
-	};
-
-	if (t->type == UNSET) {
-		tuner_warn ("tuner type not set\n");
-		return;
-	}
-	if (NULL == analog_ops->set_params) {
-		tuner_warn ("tuner has no way to set radio frequency\n");
-		return;
-	}
-	if (freq < radio_range[0] * 16000 || freq > radio_range[1] * 16000) {
-		tuner_dbg ("radio freq (%d.%02d) out of range (%d-%d)\n",
-			   freq / 16000, freq % 16000 * 100 / 16000,
-			   radio_range[0], radio_range[1]);
-		/* V4L2 spec: if the freq is not possible then the closest
-		   possible value should be selected */
-		if (freq < radio_range[0] * 16000)
-			freq = radio_range[0] * 16000;
-		else
-			freq = radio_range[1] * 16000;
-	}
-	params.frequency = freq;
-	tuner_dbg("radio freq set to %lu.%02lu\n",
-			freq / 16000, freq % 16000 * 100 / 16000);
-	t->radio_freq = freq;
-
-	analog_ops->set_params(&t->fe, &params);
-}
-
-static void set_freq(struct i2c_client *c, unsigned long freq)
-{
-	struct tuner *t = to_tuner(i2c_get_clientdata(c));
-
-	switch (t->mode) {
-	case V4L2_TUNER_RADIO:
-		set_radio_freq(c, freq);
-		break;
-	case V4L2_TUNER_ANALOG_TV:
-	case V4L2_TUNER_DIGITAL_TV:
-		set_tv_freq(c, freq);
-		break;
-	default:
-		tuner_dbg("freq set: unknown mode: 0x%04x!\n",t->mode);
-	}
-}
-
-static struct xc5000_config xc5000_cfg;
+static void set_tv_freq(struct i2c_client *c, unsigned int freq);
+static void set_radio_freq(struct i2c_client *c, unsigned int freq);
+static const struct v4l2_subdev_ops tuner_ops;
 
 static void set_type(struct i2c_client *c, unsigned int type,
 		     unsigned int new_mode_mask, unsigned int new_config,
@@ -467,9 +396,12 @@ static void set_type(struct i2c_client *c, unsigned int type,
 	   FIXME: better to move set_freq to the tuner code. This is needed
 	   on analog tuners for PLL to properly work
 	 */
-	if (tune_now)
-		set_freq(c, (V4L2_TUNER_RADIO == t->mode) ?
-			    t->radio_freq : t->tv_freq);
+	if (tune_now) {
+		if (V4L2_TUNER_RADIO == t->mode)
+			set_radio_freq(c, t->radio_freq);
+		else
+			set_tv_freq(c, t->tv_freq);
+	}
 
 	tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
 		  c->adapter->name, c->driver->driver.name, c->addr << 1, type,
@@ -508,26 +440,249 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
 			  tun_setup->addr, tun_setup->mode_mask);
 }
 
-static inline int check_mode(struct tuner *t, char *cmd)
+static int tuner_s_type_addr(struct v4l2_subdev *sd, struct tuner_setup *type)
 {
-	if ((1 << t->mode & t->mode_mask) == 0) {
-		return -EINVAL;
+	struct tuner *t = to_tuner(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	tuner_dbg("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=0x%02x\n",
+			type->type,
+			type->addr,
+			type->mode_mask,
+			type->config);
+
+	set_addr(client, type);
+	return 0;
+}
+
+static int tuner_s_config(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *cfg)
+{
+	struct tuner *t = to_tuner(sd);
+	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
+
+	if (t->type != cfg->tuner)
+		return 0;
+
+	if (analog_ops->set_config) {
+		analog_ops->set_config(&t->fe, cfg->priv);
+		return 0;
+	}
+
+	tuner_dbg("Tuner frontend module has no way to set config\n");
+	return 0;
+}
+
+/* Search for existing radio and/or TV tuners on the given I2C adapter.
+   Note that when this function is called from tuner_probe you can be
+   certain no other devices will be added/deleted at the same time, I2C
+   core protects against that. */
+static void tuner_lookup(struct i2c_adapter *adap,
+		struct tuner **radio, struct tuner **tv)
+{
+	struct tuner *pos;
+
+	*radio = NULL;
+	*tv = NULL;
+
+	list_for_each_entry(pos, &tuner_list, list) {
+		int mode_mask;
+
+		if (pos->i2c->adapter != adap ||
+		    strcmp(pos->i2c->driver->driver.name, "tuner"))
+			continue;
+
+		mode_mask = pos->mode_mask & ~T_STANDBY;
+		if (*radio == NULL && mode_mask == T_RADIO)
+			*radio = pos;
+		/* Note: currently TDA9887 is the only demod-only
+		   device. If other devices appear then we need to
+		   make this test more general. */
+		else if (*tv == NULL && pos->type != TUNER_TDA9887 &&
+			 (pos->mode_mask & (T_ANALOG_TV | T_DIGITAL_TV)))
+			*tv = pos;
 	}
+}
 
-	switch (t->mode) {
-	case V4L2_TUNER_RADIO:
-		tuner_dbg("Cmd %s accepted for radio\n", cmd);
-		break;
-	case V4L2_TUNER_ANALOG_TV:
-		tuner_dbg("Cmd %s accepted for analog TV\n", cmd);
-		break;
-	case V4L2_TUNER_DIGITAL_TV:
-		tuner_dbg("Cmd %s accepted for digital TV\n", cmd);
-		break;
+/* During client attach, set_type is called by adapter's attach_inform callback.
+   set_type must then be completed by tuner_probe.
+ */
+static int tuner_probe(struct i2c_client *client,
+		       const struct i2c_device_id *id)
+{
+	struct tuner *t;
+	struct tuner *radio;
+	struct tuner *tv;
+
+	t = kzalloc(sizeof(struct tuner), GFP_KERNEL);
+	if (NULL == t)
+		return -ENOMEM;
+	v4l2_i2c_subdev_init(&t->sd, client, &tuner_ops);
+	t->i2c = client;
+	t->name = "(tuner unset)";
+	t->type = UNSET;
+	t->audmode = V4L2_TUNER_MODE_STEREO;
+	t->mode_mask = T_UNINITIALIZED;
+
+	if (show_i2c) {
+		unsigned char buffer[16];
+		int i, rc;
+
+		memset(buffer, 0, sizeof(buffer));
+		rc = i2c_master_recv(client, buffer, sizeof(buffer));
+		tuner_info("I2C RECV = ");
+		for (i = 0; i < rc; i++)
+			printk(KERN_CONT "%02x ", buffer[i]);
+		printk("\n");
 	}
+
+	/* autodetection code based on the i2c addr */
+	if (!no_autodetect) {
+		switch (client->addr) {
+		case 0x10:
+			if (tuner_symbol_probe(tea5761_autodetection,
+					       t->i2c->adapter,
+					       t->i2c->addr) >= 0) {
+				t->type = TUNER_TEA5761;
+				t->mode_mask = T_RADIO;
+				t->mode = T_STANDBY;
+				/* Sets freq to FM range */
+				t->radio_freq = 87.5 * 16000;
+				tuner_lookup(t->i2c->adapter, &radio, &tv);
+				if (tv)
+					tv->mode_mask &= ~T_RADIO;
+
+				goto register_client;
+			}
+			kfree(t);
+			return -ENODEV;
+		case 0x42:
+		case 0x43:
+		case 0x4a:
+		case 0x4b:
+			/* If chip is not tda8290, don't register.
+			   since it can be tda9887*/
+			if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
+					       t->i2c->addr) >= 0) {
+				tuner_dbg("tda829x detected\n");
+			} else {
+				/* Default is being tda9887 */
+				t->type = TUNER_TDA9887;
+				t->mode_mask = T_RADIO | T_ANALOG_TV |
+					       T_DIGITAL_TV;
+				t->mode = T_STANDBY;
+				goto register_client;
+			}
+			break;
+		case 0x60:
+			if (tuner_symbol_probe(tea5767_autodetection,
+					       t->i2c->adapter, t->i2c->addr)
+					>= 0) {
+				t->type = TUNER_TEA5767;
+				t->mode_mask = T_RADIO;
+				t->mode = T_STANDBY;
+				/* Sets freq to FM range */
+				t->radio_freq = 87.5 * 16000;
+				tuner_lookup(t->i2c->adapter, &radio, &tv);
+				if (tv)
+					tv->mode_mask &= ~T_RADIO;
+
+				goto register_client;
+			}
+			break;
+		}
+	}
+
+	/* Initializes only the first TV tuner on this adapter. Why only the
+	   first? Because there are some devices (notably the ones with TI
+	   tuners) that have more than one i2c address for the *same* device.
+	   Experience shows that, except for just one case, the first
+	   address is the right one. The exception is a Russian tuner
+	   (ACORP_Y878F). So, the desired behavior is just to enable the
+	   first found TV tuner. */
+	tuner_lookup(t->i2c->adapter, &radio, &tv);
+	if (tv == NULL) {
+		t->mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
+		if (radio == NULL)
+			t->mode_mask |= T_RADIO;
+		tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask);
+		t->tv_freq = 400 * 16; /* Sets freq to VHF High */
+		t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */
+	}
+
+	/* Should be just before return */
+register_client:
+	tuner_info("chip found @ 0x%x (%s)\n", client->addr << 1,
+		       client->adapter->name);
+
+	/* Sets a default mode */
+	if (t->mode_mask & T_ANALOG_TV) {
+		t->mode = V4L2_TUNER_ANALOG_TV;
+	} else  if (t->mode_mask & T_RADIO) {
+		t->mode = V4L2_TUNER_RADIO;
+	} else {
+		t->mode = V4L2_TUNER_DIGITAL_TV;
+	}
+	set_type(client, t->type, t->mode_mask, t->config, t->fe.callback);
+	list_add_tail(&t->list, &tuner_list);
 	return 0;
 }
 
+static int tuner_remove(struct i2c_client *client)
+{
+	struct tuner *t = to_tuner(i2c_get_clientdata(client));
+
+	v4l2_device_unregister_subdev(&t->sd);
+	tuner_detach(&t->fe);
+	t->fe.analog_demod_priv = NULL;
+
+	list_del(&t->list);
+	kfree(t);
+	return 0;
+}
+
+/*
+ * Functions that are specific for TV mode
+ */
+
+/* Set tuner frequency,  freq in Units of 62.5kHz = 1/16MHz */
+static void set_tv_freq(struct i2c_client *c, unsigned int freq)
+{
+	struct tuner *t = to_tuner(i2c_get_clientdata(c));
+	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
+
+	struct analog_parameters params = {
+		.mode      = t->mode,
+		.audmode   = t->audmode,
+		.std       = t->std
+	};
+
+	if (t->type == UNSET) {
+		tuner_warn ("tuner type not set\n");
+		return;
+	}
+	if (NULL == analog_ops->set_params) {
+		tuner_warn ("Tuner has no way to set tv freq\n");
+		return;
+	}
+	if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) {
+		tuner_dbg ("TV freq (%d.%02d) out of range (%d-%d)\n",
+			   freq / 16, freq % 16 * 100 / 16, tv_range[0],
+			   tv_range[1]);
+		/* V4L2 spec: if the freq is not possible then the closest
+		   possible value should be selected */
+		if (freq < tv_range[0] * 16)
+			freq = tv_range[0] * 16;
+		else
+			freq = tv_range[1] * 16;
+	}
+	params.frequency = freq;
+	tuner_dbg("tv freq set to %d.%02d\n",
+			freq / 16, freq % 16 * 100 / 16);
+	t->tv_freq = freq;
+
+	analog_ops->set_params(&t->fe, &params);
+}
+
 /* get more precise norm info from insmod option */
 static int tuner_fixup_std(struct tuner *t)
 {
@@ -644,6 +799,116 @@ static int tuner_fixup_std(struct tuner *t)
 	return 0;
 }
 
+/*
+ * Functions that are specific for Radio mode
+ */
+
+static void set_radio_freq(struct i2c_client *c, unsigned int freq)
+{
+	struct tuner *t = to_tuner(i2c_get_clientdata(c));
+	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
+
+	struct analog_parameters params = {
+		.mode      = t->mode,
+		.audmode   = t->audmode,
+		.std       = t->std
+	};
+
+	if (t->type == UNSET) {
+		tuner_warn ("tuner type not set\n");
+		return;
+	}
+	if (NULL == analog_ops->set_params) {
+		tuner_warn ("tuner has no way to set radio frequency\n");
+		return;
+	}
+	if (freq < radio_range[0] * 16000 || freq > radio_range[1] * 16000) {
+		tuner_dbg ("radio freq (%d.%02d) out of range (%d-%d)\n",
+			   freq / 16000, freq % 16000 * 100 / 16000,
+			   radio_range[0], radio_range[1]);
+		/* V4L2 spec: if the freq is not possible then the closest
+		   possible value should be selected */
+		if (freq < radio_range[0] * 16000)
+			freq = radio_range[0] * 16000;
+		else
+			freq = radio_range[1] * 16000;
+	}
+	params.frequency = freq;
+	tuner_dbg("radio freq set to %d.%02d\n",
+			freq / 16000, freq % 16000 * 100 / 16000);
+	t->radio_freq = freq;
+
+	analog_ops->set_params(&t->fe, &params);
+}
+
+/*
+ * Functions that should be broken into separate radio/TV functions
+ */
+
+static inline int check_mode(struct tuner *t, char *cmd)
+{
+	if ((1 << t->mode & t->mode_mask) == 0) {
+		return -EINVAL;
+	}
+
+	switch (t->mode) {
+	case V4L2_TUNER_RADIO:
+		tuner_dbg("Cmd %s accepted for radio\n", cmd);
+		break;
+	case V4L2_TUNER_ANALOG_TV:
+		tuner_dbg("Cmd %s accepted for analog TV\n", cmd);
+		break;
+	case V4L2_TUNER_DIGITAL_TV:
+		tuner_dbg("Cmd %s accepted for digital TV\n", cmd);
+		break;
+	}
+	return 0;
+}
+
+/*
+ * Switch tuner to other mode. If tuner support both tv and radio,
+ * set another frequency to some value (This is needed for some pal
+ * tuners to avoid locking). Otherwise, just put second tuner in
+ * standby mode.
+ */
+
+static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
+{
+	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
+
+	if (mode == t->mode)
+		return 0;
+
+	t->mode = mode;
+
+	if (check_mode(t, cmd) == -EINVAL) {
+		tuner_dbg("Tuner doesn't support this mode. "
+			  "Putting tuner to sleep\n");
+		t->mode = T_STANDBY;
+		if (analog_ops->standby)
+			analog_ops->standby(&t->fe);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void set_freq(struct i2c_client *c, unsigned long freq)
+{
+	struct tuner *t = to_tuner(i2c_get_clientdata(c));
+
+	switch (t->mode) {
+	case V4L2_TUNER_RADIO:
+		set_radio_freq(c, freq);
+		break;
+	case V4L2_TUNER_ANALOG_TV:
+	case V4L2_TUNER_DIGITAL_TV:
+		set_tv_freq(c, freq);
+		break;
+	default:
+		tuner_dbg("freq set: unknown mode: 0x%04x!\n",t->mode);
+	}
+}
+
 static void tuner_status(struct dvb_frontend *fe)
 {
 	struct tuner *t = fe->analog_demod_priv;
@@ -684,62 +949,6 @@ static void tuner_status(struct dvb_frontend *fe)
 			   analog_ops->has_signal(fe));
 }
 
-/* ---------------------------------------------------------------------- */
-
-/*
- * Switch tuner to other mode. If tuner support both tv and radio,
- * set another frequency to some value (This is needed for some pal
- * tuners to avoid locking). Otherwise, just put second tuner in
- * standby mode.
- */
-
-static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
-{
-	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
-
-	if (mode == t->mode)
-		return 0;
-
-	t->mode = mode;
-
-	if (check_mode(t, cmd) == -EINVAL) {
-		tuner_dbg("Tuner doesn't support this mode. "
-			  "Putting tuner to sleep\n");
-		t->mode = T_STANDBY;
-		if (analog_ops->standby)
-			analog_ops->standby(&t->fe);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int tuner_s_type_addr(struct v4l2_subdev *sd, struct tuner_setup *type)
-{
-	struct tuner *t = to_tuner(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	tuner_dbg("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=0x%02x\n",
-			type->type,
-			type->addr,
-			type->mode_mask,
-			type->config);
-
-	set_addr(client, type);
-	return 0;
-}
-
-static int tuner_s_radio(struct v4l2_subdev *sd)
-{
-	struct tuner *t = to_tuner(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL)
-		return 0;
-	if (t->radio_freq)
-		set_freq(client, t->radio_freq);
-	return 0;
-}
-
 static int tuner_s_power(struct v4l2_subdev *sd, int on)
 {
 	struct tuner *t = to_tuner(sd);
@@ -758,20 +967,18 @@ static int tuner_s_power(struct v4l2_subdev *sd, int on)
 	return 0;
 }
 
-static int tuner_s_config(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *cfg)
+/* ---------------------------------------------------------------------- */
+
+
+static int tuner_s_radio(struct v4l2_subdev *sd)
 {
 	struct tuner *t = to_tuner(sd);
-	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (t->type != cfg->tuner)
+	if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL)
 		return 0;
-
-	if (analog_ops->set_config) {
-		analog_ops->set_config(&t->fe, cfg->priv);
-		return 0;
-	}
-
-	tuner_dbg("Tuner frontend module has no way to set config\n");
+	if (t->radio_freq)
+		set_freq(client, t->radio_freq);
 	return 0;
 }
 
@@ -956,178 +1163,6 @@ static const struct v4l2_subdev_ops tuner_ops = {
 	.tuner = &tuner_tuner_ops,
 };
 
-/* ---------------------------------------------------------------------- */
-
-static LIST_HEAD(tuner_list);
-
-/* Search for existing radio and/or TV tuners on the given I2C adapter.
-   Note that when this function is called from tuner_probe you can be
-   certain no other devices will be added/deleted at the same time, I2C
-   core protects against that. */
-static void tuner_lookup(struct i2c_adapter *adap,
-		struct tuner **radio, struct tuner **tv)
-{
-	struct tuner *pos;
-
-	*radio = NULL;
-	*tv = NULL;
-
-	list_for_each_entry(pos, &tuner_list, list) {
-		int mode_mask;
-
-		if (pos->i2c->adapter != adap ||
-		    strcmp(pos->i2c->driver->driver.name, "tuner"))
-			continue;
-
-		mode_mask = pos->mode_mask & ~T_STANDBY;
-		if (*radio == NULL && mode_mask == T_RADIO)
-			*radio = pos;
-		/* Note: currently TDA9887 is the only demod-only
-		   device. If other devices appear then we need to
-		   make this test more general. */
-		else if (*tv == NULL && pos->type != TUNER_TDA9887 &&
-			 (pos->mode_mask & (T_ANALOG_TV | T_DIGITAL_TV)))
-			*tv = pos;
-	}
-}
-
-/* During client attach, set_type is called by adapter's attach_inform callback.
-   set_type must then be completed by tuner_probe.
- */
-static int tuner_probe(struct i2c_client *client,
-		       const struct i2c_device_id *id)
-{
-	struct tuner *t;
-	struct tuner *radio;
-	struct tuner *tv;
-
-	t = kzalloc(sizeof(struct tuner), GFP_KERNEL);
-	if (NULL == t)
-		return -ENOMEM;
-	v4l2_i2c_subdev_init(&t->sd, client, &tuner_ops);
-	t->i2c = client;
-	t->name = "(tuner unset)";
-	t->type = UNSET;
-	t->audmode = V4L2_TUNER_MODE_STEREO;
-	t->mode_mask = T_UNINITIALIZED;
-
-	if (show_i2c) {
-		unsigned char buffer[16];
-		int i, rc;
-
-		memset(buffer, 0, sizeof(buffer));
-		rc = i2c_master_recv(client, buffer, sizeof(buffer));
-		tuner_info("I2C RECV = ");
-		for (i = 0; i < rc; i++)
-			printk(KERN_CONT "%02x ", buffer[i]);
-		printk("\n");
-	}
-
-	/* autodetection code based on the i2c addr */
-	if (!no_autodetect) {
-		switch (client->addr) {
-		case 0x10:
-			if (tuner_symbol_probe(tea5761_autodetection,
-					       t->i2c->adapter,
-					       t->i2c->addr) >= 0) {
-				t->type = TUNER_TEA5761;
-				t->mode_mask = T_RADIO;
-				t->mode = T_STANDBY;
-				/* Sets freq to FM range */
-				t->radio_freq = 87.5 * 16000;
-				tuner_lookup(t->i2c->adapter, &radio, &tv);
-				if (tv)
-					tv->mode_mask &= ~T_RADIO;
-
-				goto register_client;
-			}
-			kfree(t);
-			return -ENODEV;
-		case 0x42:
-		case 0x43:
-		case 0x4a:
-		case 0x4b:
-			/* If chip is not tda8290, don't register.
-			   since it can be tda9887*/
-			if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
-					       t->i2c->addr) >= 0) {
-				tuner_dbg("tda829x detected\n");
-			} else {
-				/* Default is being tda9887 */
-				t->type = TUNER_TDA9887;
-				t->mode_mask = T_RADIO | T_ANALOG_TV |
-					       T_DIGITAL_TV;
-				t->mode = T_STANDBY;
-				goto register_client;
-			}
-			break;
-		case 0x60:
-			if (tuner_symbol_probe(tea5767_autodetection,
-					       t->i2c->adapter, t->i2c->addr)
-					>= 0) {
-				t->type = TUNER_TEA5767;
-				t->mode_mask = T_RADIO;
-				t->mode = T_STANDBY;
-				/* Sets freq to FM range */
-				t->radio_freq = 87.5 * 16000;
-				tuner_lookup(t->i2c->adapter, &radio, &tv);
-				if (tv)
-					tv->mode_mask &= ~T_RADIO;
-
-				goto register_client;
-			}
-			break;
-		}
-	}
-
-	/* Initializes only the first TV tuner on this adapter. Why only the
-	   first? Because there are some devices (notably the ones with TI
-	   tuners) that have more than one i2c address for the *same* device.
-	   Experience shows that, except for just one case, the first
-	   address is the right one. The exception is a Russian tuner
-	   (ACORP_Y878F). So, the desired behavior is just to enable the
-	   first found TV tuner. */
-	tuner_lookup(t->i2c->adapter, &radio, &tv);
-	if (tv == NULL) {
-		t->mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
-		if (radio == NULL)
-			t->mode_mask |= T_RADIO;
-		tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask);
-		t->tv_freq = 400 * 16; /* Sets freq to VHF High */
-		t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */
-	}
-
-	/* Should be just before return */
-register_client:
-	tuner_info("chip found @ 0x%x (%s)\n", client->addr << 1,
-		       client->adapter->name);
-
-	/* Sets a default mode */
-	if (t->mode_mask & T_ANALOG_TV) {
-		t->mode = V4L2_TUNER_ANALOG_TV;
-	} else  if (t->mode_mask & T_RADIO) {
-		t->mode = V4L2_TUNER_RADIO;
-	} else {
-		t->mode = V4L2_TUNER_DIGITAL_TV;
-	}
-	set_type(client, t->type, t->mode_mask, t->config, t->fe.callback);
-	list_add_tail(&t->list, &tuner_list);
-	return 0;
-}
-
-static int tuner_remove(struct i2c_client *client)
-{
-	struct tuner *t = to_tuner(i2c_get_clientdata(client));
-
-	v4l2_device_unregister_subdev(&t->sd);
-	tuner_detach(&t->fe);
-	t->fe.analog_demod_priv = NULL;
-
-	list_del(&t->list);
-	kfree(t);
-	return 0;
-}
-
 /* ----------------------------------------------------------------------- */
 
 /* This driver supports many devices and the idea is to let the driver
@@ -1165,10 +1200,6 @@ static __exit void exit_tuner(void)
 module_init(init_tuner);
 module_exit(exit_tuner);
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
+MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
+MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
+MODULE_LICENSE("GPL");
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 07/14] [media] tuner-core: Some cleanups at check_mode/set_mode
       [not found] <cover.1297716906.git.mchehab@redhat.com>
                   ` (3 preceding siblings ...)
  2011-02-14 21:03 ` [PATCH 06/14] [media] tuner-core: Reorganize the functions internally Mauro Carvalho Chehab
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 09/14] [media] tuner-core: do the right thing for suspend/resume Mauro Carvalho Chehab
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

Properly document those functions and do some cleanups around that.
There's just one behavior change on this patchset: it will now restore
TV frequency when changing from radio to TV mode.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 5c3da21..7cdfe3a 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -841,38 +841,39 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
 	analog_ops->set_params(&t->fe, &params);
 }
 
-/*
- * Functions that should be broken into separate radio/TV functions
+/**
+ * check_mode - Verify if tuner supports the requested mode
+ * @t - a pointer to the module's internal struct_tuner
+ *
+ * This function checks if the tuner is capable of tuning analog TV,
+ * digital TV or radio, depending on what the caller wants. If the
+ * tuner can't support that mode, it returns -EINVAL. Otherwise, it
+ * returns 0.
+ * This function is needed for boards that have a separate tuner for
+ * radio (like devices with tea5767).
  */
-
-static inline int check_mode(struct tuner *t, char *cmd)
+static inline int check_mode(struct tuner *t)
 {
 	if ((1 << t->mode & t->mode_mask) == 0) {
 		return -EINVAL;
 	}
-
-	switch (t->mode) {
-	case V4L2_TUNER_RADIO:
-		tuner_dbg("Cmd %s accepted for radio\n", cmd);
-		break;
-	case V4L2_TUNER_ANALOG_TV:
-		tuner_dbg("Cmd %s accepted for analog TV\n", cmd);
-		break;
-	case V4L2_TUNER_DIGITAL_TV:
-		tuner_dbg("Cmd %s accepted for digital TV\n", cmd);
-		break;
-	}
 	return 0;
 }
 
-/*
- * Switch tuner to other mode. If tuner support both tv and radio,
- * set another frequency to some value (This is needed for some pal
- * tuners to avoid locking). Otherwise, just put second tuner in
- * standby mode.
+/**
+ * set_mode - Switch tuner to other mode.
+ * @client - struct i2c_client pointer
+ * @t - a pointer to the module's internal struct_tuner
+ * @mode - enum v4l2_type + T_STANDBY mode
+ * @cmd - string for the command to be executed (for debug messages)
+ *
+ * If tuner doesn't support the needed mode (radio or TV), prints a
+ * debug message and returns -EINVAL, changing internal state to T_STANDBY.
+ * Otherwise, changes the state and sets frequency to the last value, if
+ * the tuner can sleep or if it supports both Radio and TV.
  */
-
-static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
+static inline int set_mode(struct i2c_client *client, struct tuner *t,
+			   int mode, char *cmd)
 {
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 
@@ -881,7 +882,7 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode,
 
 	t->mode = mode;
 
-	if (check_mode(t, cmd) == -EINVAL) {
+	if (check_mode(t) == -EINVAL) {
 		tuner_dbg("Tuner doesn't support this mode. "
 			  "Putting tuner to sleep\n");
 		t->mode = T_STANDBY;
@@ -889,9 +890,22 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode,
 			analog_ops->standby(&t->fe);
 		return -EINVAL;
 	}
+
+	if (t->mode == V4L2_TUNER_RADIO) {
+		if (t->radio_freq)
+			set_radio_freq(client, t->radio_freq);
+	} else {
+		if (t->tv_freq)
+			set_tv_freq(client, t->tv_freq);
+	}
+
 	return 0;
 }
 
+/*
+ * Functions that should be broken into separate radio/TV functions
+ */
+
 static void set_freq(struct i2c_client *c, unsigned long freq)
 {
 	struct tuner *t = to_tuner(i2c_get_clientdata(c));
@@ -959,7 +973,7 @@ static int tuner_s_power(struct v4l2_subdev *sd, int on)
 
 	tuner_dbg("Putting tuner to sleep\n");
 
-	if (check_mode(t, "s_power") == -EINVAL)
+	if (check_mode(t) == -EINVAL)
 		return 0;
 	t->mode = T_STANDBY;
 	if (analog_ops->standby)
@@ -977,8 +991,6 @@ static int tuner_s_radio(struct v4l2_subdev *sd)
 
 	if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL)
 		return 0;
-	if (t->radio_freq)
-		set_freq(client, t->radio_freq);
 	return 0;
 }
 
@@ -1017,7 +1029,7 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
 	struct tuner *t = to_tuner(sd);
 	struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
 
-	if (check_mode(t, "g_frequency") == -EINVAL)
+	if (check_mode(t) == -EINVAL)
 		return 0;
 	f->type = t->mode;
 	if (fe_tuner_ops->get_frequency) {
@@ -1040,7 +1052,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 	struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
 
-	if (check_mode(t, "g_tuner") == -EINVAL)
+	if (check_mode(t) == -EINVAL)
 		return 0;
 
 	vt->type = t->mode;
@@ -1081,7 +1093,7 @@ static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 	struct tuner *t = to_tuner(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (check_mode(t, "s_tuner") == -EINVAL)
+	if (check_mode(t) == -EINVAL)
 		return 0;
 
 	/* do nothing unless we're a radio tuner */
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 08/14] [media] tuner-core: Better implement standby mode
       [not found] <cover.1297716906.git.mchehab@redhat.com>
                   ` (5 preceding siblings ...)
  2011-02-14 21:03 ` [PATCH 09/14] [media] tuner-core: do the right thing for suspend/resume Mauro Carvalho Chehab
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 10/14] [media] tuner-core: CodingStyle cleanups Mauro Carvalho Chehab
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

In the past, T_STANDBY were used on devices with a separate radio tuner to
mark a tuner that were disabled. With the time, it got newer meanings.

Also, due to a bug at the logic, the driver might incorrectly return
T_STANDBY to userspace.

So, instead of keeping the abuse, just use a boolean for storing
such information.

We can't remove T_STANDBY yet, as this is used on two other drivers. A
latter patch will address its usage outside tuner-core.

Thanks-to: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 7cdfe3a..e6855a4 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -115,9 +115,11 @@ struct tuner {
 	unsigned int        radio_freq;
 	unsigned int        audmode;
 
-	unsigned int        mode;
+	enum v4l2_tuner_type mode;
 	unsigned int        mode_mask; /* Combination of allowable modes */
 
+	bool                standby;	/* Standby mode */
+
 	unsigned int        type; /* chip type id */
 	unsigned int        config;
 	const char          *name;
@@ -262,12 +264,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
 		t->fe.callback = tuner_callback;
 	}
 
-	if (t->mode == T_UNINITIALIZED) {
-		tuner_dbg ("tuner 0x%02x: called during i2c_client register by adapter's attach_inform\n", c->addr);
-
-		return;
-	}
-
 	/* discard private data, in case set_type() was previously called */
 	tuner_detach(&t->fe);
 	t->fe.analog_demod_priv = NULL;
@@ -387,8 +383,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
 
 	tuner_dbg("type set to %s\n", t->name);
 
-	if (t->mode_mask == T_UNINITIALIZED)
-		t->mode_mask = new_mode_mask;
+	t->mode_mask = new_mode_mask;
 
 	/* Some tuners require more initialization setup before use,
 	   such as firmware download or device calibration.
@@ -411,7 +406,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
 attach_failed:
 	tuner_dbg("Tuner attach for type = %d failed.\n", t->type);
 	t->type = TUNER_ABSENT;
-	t->mode_mask = T_UNINITIALIZED;
 
 	return;
 }
@@ -429,10 +423,10 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
 	struct tuner *t = to_tuner(i2c_get_clientdata(c));
 
 	if ( (t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) &&
-		(t->mode_mask & tun_setup->mode_mask))) ||
-		(tun_setup->addr == c->addr)) {
-			set_type(c, tun_setup->type, tun_setup->mode_mask,
-				 tun_setup->config, tun_setup->tuner_callback);
+	     (t->mode_mask & tun_setup->mode_mask))) ||
+	     (tun_setup->addr == c->addr)) {
+		set_type(c, tun_setup->type, tun_setup->mode_mask,
+			 tun_setup->config, tun_setup->tuner_callback);
 	} else
 		tuner_dbg("set addr discarded for type %i, mask %x. "
 			  "Asked to change tuner at addr 0x%02x, with mask %x\n",
@@ -491,7 +485,8 @@ static void tuner_lookup(struct i2c_adapter *adap,
 		    strcmp(pos->i2c->driver->driver.name, "tuner"))
 			continue;
 
-		mode_mask = pos->mode_mask & ~T_STANDBY;
+		mode_mask = pos->mode_mask;
+		pos->standby = 1;
 		if (*radio == NULL && mode_mask == T_RADIO)
 			*radio = pos;
 		/* Note: currently TDA9887 is the only demod-only
@@ -521,7 +516,9 @@ static int tuner_probe(struct i2c_client *client,
 	t->name = "(tuner unset)";
 	t->type = UNSET;
 	t->audmode = V4L2_TUNER_MODE_STEREO;
-	t->mode_mask = T_UNINITIALIZED;
+	t->standby = 1;
+	t->radio_freq = 87.5 * 16000;	/* Initial freq range */
+	t->tv_freq = 400 * 16; /* Sets freq to VHF High - needed for some PLL's to properly start */
 
 	if (show_i2c) {
 		unsigned char buffer[16];
@@ -544,9 +541,6 @@ static int tuner_probe(struct i2c_client *client,
 					       t->i2c->addr) >= 0) {
 				t->type = TUNER_TEA5761;
 				t->mode_mask = T_RADIO;
-				t->mode = T_STANDBY;
-				/* Sets freq to FM range */
-				t->radio_freq = 87.5 * 16000;
 				tuner_lookup(t->i2c->adapter, &radio, &tv);
 				if (tv)
 					tv->mode_mask &= ~T_RADIO;
@@ -569,7 +563,6 @@ static int tuner_probe(struct i2c_client *client,
 				t->type = TUNER_TDA9887;
 				t->mode_mask = T_RADIO | T_ANALOG_TV |
 					       T_DIGITAL_TV;
-				t->mode = T_STANDBY;
 				goto register_client;
 			}
 			break;
@@ -579,9 +572,7 @@ static int tuner_probe(struct i2c_client *client,
 					>= 0) {
 				t->type = TUNER_TEA5767;
 				t->mode_mask = T_RADIO;
-				t->mode = T_STANDBY;
 				/* Sets freq to FM range */
-				t->radio_freq = 87.5 * 16000;
 				tuner_lookup(t->i2c->adapter, &radio, &tv);
 				if (tv)
 					tv->mode_mask &= ~T_RADIO;
@@ -605,15 +596,10 @@ static int tuner_probe(struct i2c_client *client,
 		if (radio == NULL)
 			t->mode_mask |= T_RADIO;
 		tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask);
-		t->tv_freq = 400 * 16; /* Sets freq to VHF High */
-		t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */
 	}
 
 	/* Should be just before return */
 register_client:
-	tuner_info("chip found @ 0x%x (%s)\n", client->addr << 1,
-		       client->adapter->name);
-
 	/* Sets a default mode */
 	if (t->mode_mask & T_ANALOG_TV) {
 		t->mode = V4L2_TUNER_ANALOG_TV;
@@ -624,6 +610,12 @@ register_client:
 	}
 	set_type(client, t->type, t->mode_mask, t->config, t->fe.callback);
 	list_add_tail(&t->list, &tuner_list);
+
+	tuner_info("Tuner %d found with type(s)%s%s%s.\n",
+		   t->type,
+		   t->mode_mask & T_RADIO ? " radio" : "",
+		   t->mode_mask & T_ANALOG_TV ? " TV" : "",
+		   t->mode_mask & T_ANALOG_TV ? " DTV" : "");
 	return 0;
 }
 
@@ -679,6 +671,7 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
 	tuner_dbg("tv freq set to %d.%02d\n",
 			freq / 16, freq % 16 * 100 / 16);
 	t->tv_freq = freq;
+	t->standby = false;
 
 	analog_ops->set_params(&t->fe, &params);
 }
@@ -837,13 +830,14 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
 	tuner_dbg("radio freq set to %d.%02d\n",
 			freq / 16000, freq % 16000 * 100 / 16000);
 	t->radio_freq = freq;
+	t->standby = false;
 
 	analog_ops->set_params(&t->fe, &params);
 }
 
 /**
  * check_mode - Verify if tuner supports the requested mode
- * @t - a pointer to the module's internal struct_tuner
+ * @t: a pointer to the module's internal struct_tuner
  *
  * This function checks if the tuner is capable of tuning analog TV,
  * digital TV or radio, depending on what the caller wants. If the
@@ -852,51 +846,51 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
  * This function is needed for boards that have a separate tuner for
  * radio (like devices with tea5767).
  */
-static inline int check_mode(struct tuner *t)
+static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode)
 {
-	if ((1 << t->mode & t->mode_mask) == 0) {
+	if ((1 << mode & t->mode_mask) == 0) {
 		return -EINVAL;
 	}
 	return 0;
 }
 
 /**
- * set_mode - Switch tuner to other mode.
- * @client - struct i2c_client pointer
- * @t - a pointer to the module's internal struct_tuner
- * @mode - enum v4l2_type + T_STANDBY mode
- * @cmd - string for the command to be executed (for debug messages)
+ * set_mode_freq - Switch tuner to other mode.
+ * @client:	struct i2c_client pointer
+ * @t:		a pointer to the module's internal struct_tuner
+ * @mode:	enum v4l2_type (radio or TV)
+ * @freq:	frequency to set (0 means to use the previous one)
  *
  * If tuner doesn't support the needed mode (radio or TV), prints a
  * debug message and returns -EINVAL, changing internal state to T_STANDBY.
  * Otherwise, changes the state and sets frequency to the last value, if
  * the tuner can sleep or if it supports both Radio and TV.
  */
-static inline int set_mode(struct i2c_client *client, struct tuner *t,
-			   int mode, char *cmd)
+static int set_mode_freq(struct i2c_client *client, struct tuner *t,
+		         enum v4l2_tuner_type mode, unsigned int freq)
 {
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 
-	if (mode == t->mode)
-		return 0;
-
-	t->mode = mode;
-
-	if (check_mode(t) == -EINVAL) {
-		tuner_dbg("Tuner doesn't support this mode. "
-			  "Putting tuner to sleep\n");
-		t->mode = T_STANDBY;
-		if (analog_ops->standby)
-			analog_ops->standby(&t->fe);
-		return -EINVAL;
+	if (mode != t->mode) {
+		if (check_mode(t, mode) == -EINVAL) {
+			tuner_dbg("Tuner doesn't support mode %d. "
+				  "Putting tuner to sleep\n", mode);
+			t->standby = true;
+			if (analog_ops->standby)
+				analog_ops->standby(&t->fe);
+			return -EINVAL;
+		}
+		t->mode = mode;
+		tuner_dbg("Changing to mode %d\n", mode);
 	}
-
 	if (t->mode == V4L2_TUNER_RADIO) {
-		if (t->radio_freq)
-			set_radio_freq(client, t->radio_freq);
+		if (freq)
+			t->radio_freq = freq;
+		set_radio_freq(client, t->radio_freq);
 	} else {
-		if (t->tv_freq)
-			set_tv_freq(client, t->tv_freq);
+		if (freq)
+			t->tv_freq = freq;
+		set_tv_freq(client, t->tv_freq);
 	}
 
 	return 0;
@@ -923,6 +917,13 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
 	}
 }
 
+/**
+ * tuner_status - Dumps the current tuner status at dmesg
+ * @fe: pointer to struct dvb_frontend
+ *
+ * This callback is used only for driver debug purposes, answering to
+ * VIDIOC_LOG_STATUS. No changes should happen on this call.
+ */
 static void tuner_status(struct dvb_frontend *fe)
 {
 	struct tuner *t = fe->analog_demod_priv;
@@ -932,10 +933,16 @@ static void tuner_status(struct dvb_frontend *fe)
 	const char *p;
 
 	switch (t->mode) {
-		case V4L2_TUNER_RADIO: 	    p = "radio"; break;
-		case V4L2_TUNER_ANALOG_TV:  p = "analog TV"; break;
-		case V4L2_TUNER_DIGITAL_TV: p = "digital TV"; break;
-		default: p = "undefined"; break;
+		case V4L2_TUNER_RADIO:
+			p = "radio";
+			break;
+		case V4L2_TUNER_DIGITAL_TV:
+			p = "digital TV";
+			break;
+		case V4L2_TUNER_ANALOG_TV:
+		default:
+			p = "analog TV";
+			break;
 	}
 	if (t->mode == V4L2_TUNER_RADIO) {
 		freq = t->radio_freq / 16000;
@@ -944,7 +951,8 @@ static void tuner_status(struct dvb_frontend *fe)
 		freq = t->tv_freq / 16;
 		freq_fraction = (t->tv_freq % 16) * 100 / 16;
 	}
-	tuner_info("Tuner mode:      %s\n", p);
+	tuner_info("Tuner mode:      %s%s\n", p,
+		   t->standby ? " on standby mode" : "");
 	tuner_info("Frequency:       %lu.%02lu MHz\n", freq, freq_fraction);
 	tuner_info("Standard:        0x%08lx\n", (unsigned long)t->std);
 	if (t->mode != V4L2_TUNER_RADIO)
@@ -963,19 +971,22 @@ static void tuner_status(struct dvb_frontend *fe)
 			   analog_ops->has_signal(fe));
 }
 
+/**
+ * tuner_s_power - controls the power state of the tuner
+ * @sd: pointer to struct v4l2_subdev
+ * @on: a zero value puts the tuner to sleep
+ */
 static int tuner_s_power(struct v4l2_subdev *sd, int on)
 {
 	struct tuner *t = to_tuner(sd);
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 
+	/* FIXME: Why this function don't wake the tuner if on != 0 ? */
 	if (on)
 		return 0;
 
 	tuner_dbg("Putting tuner to sleep\n");
-
-	if (check_mode(t) == -EINVAL)
-		return 0;
-	t->mode = T_STANDBY;
+	t->standby = true;
 	if (analog_ops->standby)
 		analog_ops->standby(&t->fe);
 	return 0;
@@ -983,13 +994,12 @@ static int tuner_s_power(struct v4l2_subdev *sd, int on)
 
 /* ---------------------------------------------------------------------- */
 
-
 static int tuner_s_radio(struct v4l2_subdev *sd)
 {
 	struct tuner *t = to_tuner(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL)
+	if (set_mode_freq(client, t, V4L2_TUNER_RADIO, 0) == -EINVAL)
 		return 0;
 	return 0;
 }
@@ -1002,13 +1012,12 @@ static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
 	struct tuner *t = to_tuner(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "s_std") == -EINVAL)
+	if (set_mode_freq(client, t, V4L2_TUNER_ANALOG_TV, 0) == -EINVAL)
 		return 0;
 
 	t->std = std;
 	tuner_fixup_std(t);
-	if (t->tv_freq)
-		set_freq(client, t->tv_freq);
+
 	return 0;
 }
 
@@ -1017,9 +1026,8 @@ static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
 	struct tuner *t = to_tuner(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (set_mode(client, t, f->type, "s_frequency") == -EINVAL)
+	if (set_mode_freq(client, t, f->type, f->frequency) == -EINVAL)
 		return 0;
-	set_freq(client, f->frequency);
 
 	return 0;
 }
@@ -1029,20 +1037,20 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
 	struct tuner *t = to_tuner(sd);
 	struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
 
-	if (check_mode(t) == -EINVAL)
+	if (check_mode(t, f->type) == -EINVAL)
 		return 0;
 	f->type = t->mode;
-	if (fe_tuner_ops->get_frequency) {
+	if (fe_tuner_ops->get_frequency && !t->standby) {
 		u32 abs_freq;
 
 		fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
 		f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
 			DIV_ROUND_CLOSEST(abs_freq * 2, 125) :
 			DIV_ROUND_CLOSEST(abs_freq, 62500);
-		return 0;
+	} else {
+		f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
+			t->radio_freq : t->tv_freq;
 	}
-	f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
-		t->radio_freq : t->tv_freq;
 	return 0;
 }
 
@@ -1052,9 +1060,8 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 	struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
 
-	if (check_mode(t) == -EINVAL)
+	if (check_mode(t, vt->type) == -EINVAL)
 		return 0;
-
 	vt->type = t->mode;
 	if (analog_ops->get_afc)
 		vt->afc = analog_ops->get_afc(&t->fe);
@@ -1067,8 +1074,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 	}
 
 	/* radio mode */
-	vt->rxsubchans =
-		V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+	vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
 	if (fe_tuner_ops->get_status) {
 		u32 tuner_status;
 
@@ -1080,11 +1086,11 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 	}
 	if (analog_ops->has_signal)
 		vt->signal = analog_ops->has_signal(&t->fe);
-	vt->capability |=
-		V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
+	vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
 	vt->audmode = t->audmode;
 	vt->rangelow = radio_range[0] * 16000;
 	vt->rangehigh = radio_range[1] * 16000;
+
 	return 0;
 }
 
@@ -1093,14 +1099,12 @@ static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 	struct tuner *t = to_tuner(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (check_mode(t) == -EINVAL)
+	if (set_mode_freq(client, t, vt->type, 0) == -EINVAL)
 		return 0;
 
-	/* do nothing unless we're a radio tuner */
-	if (t->mode != V4L2_TUNER_RADIO)
-		return 0;
-	t->audmode = vt->audmode;
-	set_radio_freq(client, t->radio_freq);
+	if (t->mode == V4L2_TUNER_RADIO)
+		t->audmode = vt->audmode;
+
 	return 0;
 }
 
@@ -1128,13 +1132,10 @@ static int tuner_resume(struct i2c_client *c)
 	struct tuner *t = to_tuner(i2c_get_clientdata(c));
 
 	tuner_dbg("resume\n");
-	if (V4L2_TUNER_RADIO == t->mode) {
-		if (t->radio_freq)
-			set_freq(c, t->radio_freq);
-	} else {
-		if (t->tv_freq)
-			set_freq(c, t->tv_freq);
-	}
+	if (V4L2_TUNER_RADIO == t->mode)
+		set_freq(c, t->radio_freq);
+	else
+		set_freq(c, t->tv_freq);
 	return 0;
 }
 
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 5eec529..1d59642 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -160,7 +160,6 @@
 #ifdef __KERNEL__
 
 enum tuner_mode {
-	T_UNINITIALIZED = 0,
 	T_RADIO		= 1 << V4L2_TUNER_RADIO,
 	T_ANALOG_TV     = 1 << V4L2_TUNER_ANALOG_TV,
 	T_DIGITAL_TV    = 1 << V4L2_TUNER_DIGITAL_TV,
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 09/14] [media] tuner-core: do the right thing for suspend/resume
       [not found] <cover.1297716906.git.mchehab@redhat.com>
                   ` (4 preceding siblings ...)
  2011-02-14 21:03 ` [PATCH 07/14] [media] tuner-core: Some cleanups at check_mode/set_mode Mauro Carvalho Chehab
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 08/14] [media] tuner-core: Better implement standby mode Mauro Carvalho Chehab
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

Power down tuners at suspend. At resume, if the tuner is in standby,
calls set_mode, that will turn it on and set the latest frequencies.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index e6855a4..e6b63e9 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1121,9 +1121,13 @@ static int tuner_log_status(struct v4l2_subdev *sd)
 static int tuner_suspend(struct i2c_client *c, pm_message_t state)
 {
 	struct tuner *t = to_tuner(i2c_get_clientdata(c));
+	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 
 	tuner_dbg("suspend\n");
-	/* FIXME: power down ??? */
+
+	if (!t->standby && analog_ops->standby)
+		analog_ops->standby(&t->fe);
+
 	return 0;
 }
 
@@ -1132,10 +1136,10 @@ static int tuner_resume(struct i2c_client *c)
 	struct tuner *t = to_tuner(i2c_get_clientdata(c));
 
 	tuner_dbg("resume\n");
-	if (V4L2_TUNER_RADIO == t->mode)
-		set_freq(c, t->radio_freq);
-	else
-		set_freq(c, t->tv_freq);
+
+	if (!t->standby)
+		set_mode_freq(c, t, t->type, 0);
+
 	return 0;
 }
 
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 10/14] [media] tuner-core: CodingStyle cleanups
       [not found] <cover.1297716906.git.mchehab@redhat.com>
                   ` (6 preceding siblings ...)
  2011-02-14 21:03 ` [PATCH 08/14] [media] tuner-core: Better implement standby mode Mauro Carvalho Chehab
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 11/14] [media] tuner-core: Don't use a static var for xc5000_cfg Mauro Carvalho Chehab
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index e6b63e9..70ff416 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -32,7 +32,7 @@
 
 #define UNSET (-1U)
 
-#define PREFIX t->i2c->driver->driver.name
+#define PREFIX (t->i2c->driver->driver.name)
 
 /*
  * Driver modprobe parameters
@@ -55,7 +55,7 @@ static char pal[] = "--";
 static char secam[] = "--";
 static char ntsc[] = "-";
 
-module_param_named(debug,tuner_debug, int, 0644);
+module_param_named(debug, tuner_debug, int, 0644);
 module_param_array(tv_range, int, NULL, 0644);
 module_param_array(radio_range, int, NULL, 0644);
 module_param_string(pal, pal, sizeof(pal), 0644);
@@ -252,7 +252,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
 	int tune_now = 1;
 
 	if (type == UNSET || type == TUNER_ABSENT) {
-		tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr);
+		tuner_dbg("tuner 0x%02x: Tuner type absent\n", c->addr);
 		return;
 	}
 
@@ -422,9 +422,9 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
 {
 	struct tuner *t = to_tuner(i2c_get_clientdata(c));
 
-	if ( (t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) &&
-	     (t->mode_mask & tun_setup->mode_mask))) ||
-	     (tun_setup->addr == c->addr)) {
+	if ((t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) &&
+	    (t->mode_mask & tun_setup->mode_mask))) ||
+	    (tun_setup->addr == c->addr)) {
 		set_type(c, tun_setup->type, tun_setup->mode_mask,
 			 tun_setup->config, tun_setup->tuner_callback);
 	} else
@@ -449,7 +449,8 @@ static int tuner_s_type_addr(struct v4l2_subdev *sd, struct tuner_setup *type)
 	return 0;
 }
 
-static int tuner_s_config(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *cfg)
+static int tuner_s_config(struct v4l2_subdev *sd,
+			  const struct v4l2_priv_tun_config *cfg)
 {
 	struct tuner *t = to_tuner(sd);
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
@@ -601,13 +602,12 @@ static int tuner_probe(struct i2c_client *client,
 	/* Should be just before return */
 register_client:
 	/* Sets a default mode */
-	if (t->mode_mask & T_ANALOG_TV) {
+	if (t->mode_mask & T_ANALOG_TV)
 		t->mode = V4L2_TUNER_ANALOG_TV;
-	} else  if (t->mode_mask & T_RADIO) {
+	else if (t->mode_mask & T_RADIO)
 		t->mode = V4L2_TUNER_RADIO;
-	} else {
+	else
 		t->mode = V4L2_TUNER_DIGITAL_TV;
-	}
 	set_type(client, t->type, t->mode_mask, t->config, t->fe.callback);
 	list_add_tail(&t->list, &tuner_list);
 
@@ -649,15 +649,15 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
 	};
 
 	if (t->type == UNSET) {
-		tuner_warn ("tuner type not set\n");
+		tuner_warn("tuner type not set\n");
 		return;
 	}
 	if (NULL == analog_ops->set_params) {
-		tuner_warn ("Tuner has no way to set tv freq\n");
+		tuner_warn("Tuner has no way to set tv freq\n");
 		return;
 	}
 	if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) {
-		tuner_dbg ("TV freq (%d.%02d) out of range (%d-%d)\n",
+		tuner_dbg("TV freq (%d.%02d) out of range (%d-%d)\n",
 			   freq / 16, freq % 16 * 100 / 16, tv_range[0],
 			   tv_range[1]);
 		/* V4L2 spec: if the freq is not possible then the closest
@@ -682,31 +682,31 @@ static int tuner_fixup_std(struct tuner *t)
 	if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
 		switch (pal[0]) {
 		case '6':
-			tuner_dbg ("insmod fixup: PAL => PAL-60\n");
+			tuner_dbg("insmod fixup: PAL => PAL-60\n");
 			t->std = V4L2_STD_PAL_60;
 			break;
 		case 'b':
 		case 'B':
 		case 'g':
 		case 'G':
-			tuner_dbg ("insmod fixup: PAL => PAL-BG\n");
+			tuner_dbg("insmod fixup: PAL => PAL-BG\n");
 			t->std = V4L2_STD_PAL_BG;
 			break;
 		case 'i':
 		case 'I':
-			tuner_dbg ("insmod fixup: PAL => PAL-I\n");
+			tuner_dbg("insmod fixup: PAL => PAL-I\n");
 			t->std = V4L2_STD_PAL_I;
 			break;
 		case 'd':
 		case 'D':
 		case 'k':
 		case 'K':
-			tuner_dbg ("insmod fixup: PAL => PAL-DK\n");
+			tuner_dbg("insmod fixup: PAL => PAL-DK\n");
 			t->std = V4L2_STD_PAL_DK;
 			break;
 		case 'M':
 		case 'm':
-			tuner_dbg ("insmod fixup: PAL => PAL-M\n");
+			tuner_dbg("insmod fixup: PAL => PAL-M\n");
 			t->std = V4L2_STD_PAL_M;
 			break;
 		case 'N':
@@ -715,7 +715,7 @@ static int tuner_fixup_std(struct tuner *t)
 				tuner_dbg("insmod fixup: PAL => PAL-Nc\n");
 				t->std = V4L2_STD_PAL_Nc;
 			} else {
-				tuner_dbg ("insmod fixup: PAL => PAL-N\n");
+				tuner_dbg("insmod fixup: PAL => PAL-N\n");
 				t->std = V4L2_STD_PAL_N;
 			}
 			break;
@@ -723,7 +723,7 @@ static int tuner_fixup_std(struct tuner *t)
 			/* default parameter, do nothing */
 			break;
 		default:
-			tuner_warn ("pal= argument not recognised\n");
+			tuner_warn("pal= argument not recognised\n");
 			break;
 		}
 	}
@@ -736,22 +736,24 @@ static int tuner_fixup_std(struct tuner *t)
 		case 'h':
 		case 'H':
 			tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n");
-			t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
+			t->std = V4L2_STD_SECAM_B |
+				 V4L2_STD_SECAM_G |
+				 V4L2_STD_SECAM_H;
 			break;
 		case 'd':
 		case 'D':
 		case 'k':
 		case 'K':
-			tuner_dbg ("insmod fixup: SECAM => SECAM-DK\n");
+			tuner_dbg("insmod fixup: SECAM => SECAM-DK\n");
 			t->std = V4L2_STD_SECAM_DK;
 			break;
 		case 'l':
 		case 'L':
-			if ((secam[1]=='C')||(secam[1]=='c')) {
-				tuner_dbg ("insmod fixup: SECAM => SECAM-L'\n");
+			if ((secam[1] == 'C') || (secam[1] == 'c')) {
+				tuner_dbg("insmod fixup: SECAM => SECAM-L'\n");
 				t->std = V4L2_STD_SECAM_LC;
 			} else {
-				tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
+				tuner_dbg("insmod fixup: SECAM => SECAM-L\n");
 				t->std = V4L2_STD_SECAM_L;
 			}
 			break;
@@ -759,7 +761,7 @@ static int tuner_fixup_std(struct tuner *t)
 			/* default parameter, do nothing */
 			break;
 		default:
-			tuner_warn ("secam= argument not recognised\n");
+			tuner_warn("secam= argument not recognised\n");
 			break;
 		}
 	}
@@ -808,15 +810,15 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
 	};
 
 	if (t->type == UNSET) {
-		tuner_warn ("tuner type not set\n");
+		tuner_warn("tuner type not set\n");
 		return;
 	}
 	if (NULL == analog_ops->set_params) {
-		tuner_warn ("tuner has no way to set radio frequency\n");
+		tuner_warn("tuner has no way to set radio frequency\n");
 		return;
 	}
 	if (freq < radio_range[0] * 16000 || freq > radio_range[1] * 16000) {
-		tuner_dbg ("radio freq (%d.%02d) out of range (%d-%d)\n",
+		tuner_dbg("radio freq (%d.%02d) out of range (%d-%d)\n",
 			   freq / 16000, freq % 16000 * 100 / 16000,
 			   radio_range[0], radio_range[1]);
 		/* V4L2 spec: if the freq is not possible then the closest
@@ -848,9 +850,9 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
  */
 static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode)
 {
-	if ((1 << mode & t->mode_mask) == 0) {
+	if ((1 << mode & t->mode_mask) == 0)
 		return -EINVAL;
-	}
+
 	return 0;
 }
 
@@ -867,7 +869,7 @@ static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode)
  * the tuner can sleep or if it supports both Radio and TV.
  */
 static int set_mode_freq(struct i2c_client *client, struct tuner *t,
-		         enum v4l2_tuner_type mode, unsigned int freq)
+			 enum v4l2_tuner_type mode, unsigned int freq)
 {
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 
@@ -913,7 +915,7 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
 		set_tv_freq(c, freq);
 		break;
 	default:
-		tuner_dbg("freq set: unknown mode: 0x%04x!\n",t->mode);
+		tuner_dbg("freq set: unknown mode: 0x%04x!\n", t->mode);
 	}
 }
 
@@ -933,16 +935,16 @@ static void tuner_status(struct dvb_frontend *fe)
 	const char *p;
 
 	switch (t->mode) {
-		case V4L2_TUNER_RADIO:
-			p = "radio";
-			break;
-		case V4L2_TUNER_DIGITAL_TV:
-			p = "digital TV";
-			break;
-		case V4L2_TUNER_ANALOG_TV:
-		default:
-			p = "analog TV";
-			break;
+	case V4L2_TUNER_RADIO:
+		p = "radio";
+		break;
+	case V4L2_TUNER_DIGITAL_TV:
+		p = "digital TV";
+		break;
+	case V4L2_TUNER_ANALOG_TV:
+	default:
+		p = "analog TV";
+		break;
 	}
 	if (t->mode == V4L2_TUNER_RADIO) {
 		freq = t->radio_freq / 16000;
@@ -956,7 +958,7 @@ static void tuner_status(struct dvb_frontend *fe)
 	tuner_info("Frequency:       %lu.%02lu MHz\n", freq, freq_fraction);
 	tuner_info("Standard:        0x%08lx\n", (unsigned long)t->std);
 	if (t->mode != V4L2_TUNER_RADIO)
-	       return;
+		return;
 	if (fe_tuner_ops->get_status) {
 		u32 tuner_status;
 
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 11/14] [media] tuner-core: Don't use a static var for xc5000_cfg
       [not found] <cover.1297716906.git.mchehab@redhat.com>
                   ` (7 preceding siblings ...)
  2011-02-14 21:03 ` [PATCH 10/14] [media] tuner-core: CodingStyle cleanups Mauro Carvalho Chehab
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 01/14] [media] cx88: use unlocked_ioctl for cx88-video Mauro Carvalho Chehab
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

A static var is evil, especially if a device has two boards with
xc5000. Instead, just like the other drivers, use stack to store
its config during setup.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 70ff416..16939ca 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -66,7 +66,6 @@ module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
  * Static vars
  */
 
-static struct xc5000_config xc5000_cfg;
 static LIST_HEAD(tuner_list);
 
 /*
@@ -338,9 +337,12 @@ static void set_type(struct i2c_client *c, unsigned int type,
 		break;
 	case TUNER_XC5000:
 	{
-		xc5000_cfg.i2c_address	  = t->i2c->addr;
-		/* if_khz will be set when the digital dvb_attach() occurs */
-		xc5000_cfg.if_khz	  = 0;
+		struct xc5000_config xc5000_cfg = {
+			.i2c_address = t->i2c->addr,
+			/* if_khz will be set at dvb_attach() */
+			.if_khz	  = 0,
+		};
+
 		if (!dvb_attach(xc5000_attach,
 				&t->fe, t->i2c->adapter, &xc5000_cfg))
 			goto attach_failed;
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 01/14] [media] cx88: use unlocked_ioctl for cx88-video.
       [not found] <cover.1297716906.git.mchehab@redhat.com>
                   ` (8 preceding siblings ...)
  2011-02-14 21:03 ` [PATCH 11/14] [media] tuner-core: Don't use a static var for xc5000_cfg Mauro Carvalho Chehab
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 02/14] [media] cx88: Don't allow opening a device while it is not ready Mauro Carvalho Chehab
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

cx88-video has locks. don't use the locked ioctl version, as
it is not needed.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 508dabb..e2fc455 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1672,7 +1672,7 @@ static const struct v4l2_file_operations video_fops =
 	.read	       = video_read,
 	.poll          = video_poll,
 	.mmap	       = video_mmap,
-	.ioctl	       = video_ioctl2,
+	.unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops video_ioctl_ops = {
@@ -1722,7 +1722,7 @@ static const struct v4l2_file_operations radio_fops =
 	.owner         = THIS_MODULE,
 	.open          = video_open,
 	.release       = video_release,
-	.ioctl         = video_ioctl2,
+	.unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops radio_ioctl_ops = {
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 02/14] [media] cx88: Don't allow opening a device while it is not ready
       [not found] <cover.1297716906.git.mchehab@redhat.com>
                   ` (9 preceding siblings ...)
  2011-02-14 21:03 ` [PATCH 01/14] [media] cx88: use unlocked_ioctl for cx88-video Mauro Carvalho Chehab
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 14/14] [media] Remove the remaining usages for T_STANDBY Mauro Carvalho Chehab
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

After registering the cdev, it would be possible do have an open on it.
In a matter of fact, some versions of udev do this. So, move registration
to the end and protect it with a mutex.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index e2fc455..f814886 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1882,6 +1882,15 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
 		request_module("ir-kbd-i2c");
 	}
 
+	/* Sets device info at pci_dev */
+	pci_set_drvdata(pci_dev, dev);
+
+	/* initial device configuration */
+	mutex_lock(&core->lock);
+	cx88_set_tvnorm(core, core->tvnorm);
+	init_controls(core);
+	cx88_video_mux(core, 0);
+
 	/* register v4l devices */
 	dev->video_dev = cx88_vdev_init(core,dev->pci,
 					&cx8800_video_template,"video");
@@ -1923,16 +1932,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
 		       core->name, video_device_node_name(dev->radio_dev));
 	}
 
-	/* everything worked */
-	pci_set_drvdata(pci_dev,dev);
-
-	/* initial device configuration */
-	mutex_lock(&core->lock);
-	cx88_set_tvnorm(core,core->tvnorm);
-	init_controls(core);
-	cx88_video_mux(core,0);
-	mutex_unlock(&core->lock);
-
 	/* start tvaudio thread */
 	if (core->board.tuner_type != TUNER_ABSENT) {
 		core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio");
@@ -1942,11 +1941,14 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
 			       core->name, err);
 		}
 	}
+	mutex_unlock(&core->lock);
+
 	return 0;
 
 fail_unreg:
 	cx8800_unregister_video(dev);
 	free_irq(pci_dev->irq, dev);
+	mutex_unlock(&core->lock);
 fail_core:
 	cx88_core_put(core,dev->pci);
 fail_free:
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 14/14] [media] Remove the remaining usages for T_STANDBY
       [not found] <cover.1297716906.git.mchehab@redhat.com>
                   ` (10 preceding siblings ...)
  2011-02-14 21:03 ` [PATCH 02/14] [media] cx88: Don't allow opening a device while it is not ready Mauro Carvalho Chehab
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 12/14] [media] tuner-core: dead code removal Mauro Carvalho Chehab
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

tda9887 used to use the T_STANDBY type internally, while tea5761
used it to put the device to sleep. Fix the code for it to work
properly with the tuner core changes and remove this flag from
tuner.h.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c
index bf14bd7..cdb645d 100644
--- a/drivers/media/common/tuners/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
@@ -36,6 +36,8 @@ struct tda9887_priv {
 	unsigned int       mode;
 	unsigned int       audmode;
 	v4l2_std_id        std;
+
+	bool               standby;
 };
 
 /* ---------------------------------------------------------------------- */
@@ -568,7 +570,7 @@ static void tda9887_configure(struct dvb_frontend *fe)
 	tda9887_do_config(fe);
 	tda9887_set_insmod(fe);
 
-	if (priv->mode == T_STANDBY)
+	if (priv->standby)
 		priv->data[1] |= cForcedMuteAudioON;
 
 	tuner_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
@@ -616,7 +618,7 @@ static void tda9887_standby(struct dvb_frontend *fe)
 {
 	struct tda9887_priv *priv = fe->analog_demod_priv;
 
-	priv->mode = T_STANDBY;
+	priv->standby = true;
 
 	tda9887_configure(fe);
 }
@@ -626,6 +628,7 @@ static void tda9887_set_params(struct dvb_frontend *fe,
 {
 	struct tda9887_priv *priv = fe->analog_demod_priv;
 
+	priv->standby = false;
 	priv->mode    = params->mode;
 	priv->audmode = params->audmode;
 	priv->std     = params->std;
@@ -686,7 +689,7 @@ struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
 		return NULL;
 	case 1:
 		fe->analog_demod_priv = priv;
-		priv->mode = T_STANDBY;
+		priv->standby = true;
 		tuner_info("tda988[5/6/7] found\n");
 		break;
 	default:
diff --git a/drivers/media/common/tuners/tea5761.c b/drivers/media/common/tuners/tea5761.c
index 925399d..bf78cb9 100644
--- a/drivers/media/common/tuners/tea5761.c
+++ b/drivers/media/common/tuners/tea5761.c
@@ -23,6 +23,7 @@ struct tea5761_priv {
 	struct tuner_i2c_props i2c_props;
 
 	u32 frequency;
+	bool standby;
 };
 
 /*****************************************************************************/
@@ -135,18 +136,19 @@ static void tea5761_status_dump(unsigned char *buffer)
 }
 
 /* Freq should be specifyed at 62.5 Hz */
-static int set_radio_freq(struct dvb_frontend *fe,
-			  struct analog_parameters *params)
+static int __set_radio_freq(struct dvb_frontend *fe,
+			    unsigned int freq,
+			    bool mono)
 {
 	struct tea5761_priv *priv = fe->tuner_priv;
-	unsigned int frq = params->frequency;
+	unsigned int frq = freq;
 	unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 };
 	unsigned div;
 	int rc;
 
 	tuner_dbg("radio freq counter %d\n", frq);
 
-	if (params->mode == T_STANDBY) {
+	if (priv->standby) {
 		tuner_dbg("TEA5761 set to standby mode\n");
 		buffer[5] |= TEA5761_TNCTRL_MU;
 	} else {
@@ -154,7 +156,7 @@ static int set_radio_freq(struct dvb_frontend *fe,
 	}
 
 
-	if (params->audmode == V4L2_TUNER_MODE_MONO) {
+	if (mono) {
 		tuner_dbg("TEA5761 set to mono\n");
 		buffer[5] |= TEA5761_TNCTRL_MST;
 	} else {
@@ -176,6 +178,26 @@ static int set_radio_freq(struct dvb_frontend *fe,
 	return 0;
 }
 
+static int set_radio_freq(struct dvb_frontend *fe,
+			  struct analog_parameters *params)
+{
+	struct tea5761_priv *priv = fe->analog_demod_priv;
+
+	priv->standby = false;
+
+	return __set_radio_freq(fe, params->frequency,
+				params->audmode == V4L2_TUNER_MODE_MONO);
+}
+
+static int set_radio_sleep(struct dvb_frontend *fe)
+{
+	struct tea5761_priv *priv = fe->analog_demod_priv;
+
+	priv->standby = true;
+
+	return __set_radio_freq(fe, priv->frequency, false);
+}
+
 static int tea5761_read_status(struct dvb_frontend *fe, char *buffer)
 {
 	struct tea5761_priv *priv = fe->tuner_priv;
@@ -284,6 +306,7 @@ static struct dvb_tuner_ops tea5761_tuner_ops = {
 		.name           = "tea5761", // Philips TEA5761HN FM Radio
 	},
 	.set_analog_params = set_radio_freq,
+	.sleep		   = set_radio_sleep,
 	.release           = tea5761_release,
 	.get_frequency     = tea5761_get_frequency,
 	.get_status        = tea5761_get_status,
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 1d59642..32dfd5f 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -21,6 +21,7 @@
 
 #ifndef _TUNER_H
 #define _TUNER_H
+#ifdef __KERNEL__
 
 #include <linux/videodev2.h>
 
@@ -157,13 +158,10 @@
 #define TDA9887_GAIN_NORMAL		(1<<20)
 #define TDA9887_RIF_41_3		(1<<21)  /* radio IF1 41.3 vs 33.3 */
 
-#ifdef __KERNEL__
-
 enum tuner_mode {
 	T_RADIO		= 1 << V4L2_TUNER_RADIO,
 	T_ANALOG_TV     = 1 << V4L2_TUNER_ANALOG_TV,
 	T_DIGITAL_TV    = 1 << V4L2_TUNER_DIGITAL_TV,
-	T_STANDBY	= 1 << 31
 };
 
 /* Older boards only had a single tuner device. Nowadays multiple tuner
@@ -193,11 +191,3 @@ struct tuner_setup {
 #endif /* __KERNEL__ */
 
 #endif /* _TUNER_H */
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 12/14] [media] tuner-core: dead code removal
       [not found] <cover.1297716906.git.mchehab@redhat.com>
                   ` (11 preceding siblings ...)
  2011-02-14 21:03 ` [PATCH 14/14] [media] Remove the remaining usages for T_STANDBY Mauro Carvalho Chehab
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:03 ` [PATCH 13/14] [media] tuner-core: Fix a few comments on it Mauro Carvalho Chehab
  2011-02-14 21:49 ` [PATCH 01/14] [media] cx88: use unlocked_ioctl for cx88-video Mauro Carvalho Chehab
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

Remove the now obsolete set_freq. Also merge set_addr and set_type_addr.

In the past, it used to have two different setup calls, one to set just
the tuner type to any tuner found, and another to set the type only if
the address matches. Those two internal calls were grouped together,
but the functions weren't merged, making the code uglier.

No functional changes are done in this patch.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 16939ca..2a0bea1 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -419,10 +419,17 @@ attach_failed:
  * it's applied. Otherwise status and type are applied only to
  * tuner with exactly the same addr.
 */
-
-static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
+static int tuner_s_type_addr(struct v4l2_subdev *sd,
+			     struct tuner_setup *tun_setup)
 {
-	struct tuner *t = to_tuner(i2c_get_clientdata(c));
+	struct tuner *t = to_tuner(sd);
+	struct i2c_client *c = v4l2_get_subdevdata(sd);
+
+	tuner_dbg("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=0x%02x\n",
+			tun_setup->type,
+			tun_setup->addr,
+			tun_setup->mode_mask,
+			tun_setup->config);
 
 	if ((t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) &&
 	    (t->mode_mask & tun_setup->mode_mask))) ||
@@ -434,20 +441,7 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
 			  "Asked to change tuner at addr 0x%02x, with mask %x\n",
 			  t->type, t->mode_mask,
 			  tun_setup->addr, tun_setup->mode_mask);
-}
 
-static int tuner_s_type_addr(struct v4l2_subdev *sd, struct tuner_setup *type)
-{
-	struct tuner *t = to_tuner(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	tuner_dbg("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=0x%02x\n",
-			type->type,
-			type->addr,
-			type->mode_mask,
-			type->config);
-
-	set_addr(client, type);
 	return 0;
 }
 
@@ -900,27 +894,6 @@ static int set_mode_freq(struct i2c_client *client, struct tuner *t,
 	return 0;
 }
 
-/*
- * Functions that should be broken into separate radio/TV functions
- */
-
-static void set_freq(struct i2c_client *c, unsigned long freq)
-{
-	struct tuner *t = to_tuner(i2c_get_clientdata(c));
-
-	switch (t->mode) {
-	case V4L2_TUNER_RADIO:
-		set_radio_freq(c, freq);
-		break;
-	case V4L2_TUNER_ANALOG_TV:
-	case V4L2_TUNER_DIGITAL_TV:
-		set_tv_freq(c, freq);
-		break;
-	default:
-		tuner_dbg("freq set: unknown mode: 0x%04x!\n", t->mode);
-	}
-}
-
 /**
  * tuner_status - Dumps the current tuner status at dmesg
  * @fe: pointer to struct dvb_frontend
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 13/14] [media] tuner-core: Fix a few comments on it
       [not found] <cover.1297716906.git.mchehab@redhat.com>
                   ` (12 preceding siblings ...)
  2011-02-14 21:03 ` [PATCH 12/14] [media] tuner-core: dead code removal Mauro Carvalho Chehab
@ 2011-02-14 21:03 ` Mauro Carvalho Chehab
  2011-02-14 21:49 ` [PATCH 01/14] [media] cx88: use unlocked_ioctl for cx88-video Mauro Carvalho Chehab
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:03 UTC (permalink / raw)
  Cc: Linux Media Mailing List

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 2a0bea1..dcf03fa 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -128,7 +128,7 @@ struct tuner {
  * tuner attach/detach logic
  */
 
-/** This macro allows us to probe dynamically, avoiding static links */
+/* This macro allows us to probe dynamically, avoiding static links */
 #ifdef CONFIG_MEDIA_ATTACH
 #define tuner_symbol_probe(FUNCTION, ARGS...) ({ \
 	int __r = -EINVAL; \
@@ -412,13 +412,20 @@ attach_failed:
 	return;
 }
 
-/*
- * This function apply tuner config to tuner specified
- * by tun_setup structure. I addr is unset, then admin status
- * and tun addr status is more precise then current status,
- * it's applied. Otherwise status and type are applied only to
- * tuner with exactly the same addr.
-*/
+/**
+ * tuner_s_type_addr - Sets the tuner type for a device
+ *
+ * @sd:		subdev descriptor
+ * @tun_setup:	type to be associated to a given tuner i2c address
+ *
+ * This function applys the tuner config to tuner specified
+ * by tun_setup structure.
+ * If tuner I2C address is UNSET, then it will only set the device
+ * if the tuner supports the mode specified in the call.
+ * If the address is specified, the change will be applied only if
+ * tuner I2C address matches.
+ * The call can change the tuner number and the tuner mode.
+ */
 static int tuner_s_type_addr(struct v4l2_subdev *sd,
 			     struct tuner_setup *tun_setup)
 {
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 01/14] [media] cx88: use unlocked_ioctl for cx88-video
       [not found] <cover.1297716906.git.mchehab@redhat.com>
                   ` (13 preceding siblings ...)
  2011-02-14 21:03 ` [PATCH 13/14] [media] tuner-core: Fix a few comments on it Mauro Carvalho Chehab
@ 2011-02-14 21:49 ` Mauro Carvalho Chehab
  14 siblings, 0 replies; 15+ messages in thread
From: Mauro Carvalho Chehab @ 2011-02-14 21:49 UTC (permalink / raw)
  Cc: Linux Media Mailing List

cx88-video has locks. don't use the locked ioctl version, as
it is not needed.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 508dabb..e2fc455 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1672,7 +1672,7 @@ static const struct v4l2_file_operations video_fops =
 	.read	       = video_read,
 	.poll          = video_poll,
 	.mmap	       = video_mmap,
-	.ioctl	       = video_ioctl2,
+	.unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops video_ioctl_ops = {
@@ -1722,7 +1722,7 @@ static const struct v4l2_file_operations radio_fops =
 	.owner         = THIS_MODULE,
 	.open          = video_open,
 	.release       = video_release,
-	.ioctl         = video_ioctl2,
+	.unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops radio_ioctl_ops = {
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2011-02-14 21:55 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <cover.1297716906.git.mchehab@redhat.com>
2011-02-14 21:03 ` [PATCH 03/14] [media] tuner-core: Remove V4L1/V4L2 API switch Mauro Carvalho Chehab
2011-02-14 21:03 ` [PATCH 04/14] [media] tuner-core: remove the legacy is_stereo() call Mauro Carvalho Chehab
2011-02-14 21:03 ` [PATCH 05/14] [media] tuner-core: move some messages to the proper place Mauro Carvalho Chehab
2011-02-14 21:03 ` [PATCH 06/14] [media] tuner-core: Reorganize the functions internally Mauro Carvalho Chehab
2011-02-14 21:03 ` [PATCH 07/14] [media] tuner-core: Some cleanups at check_mode/set_mode Mauro Carvalho Chehab
2011-02-14 21:03 ` [PATCH 09/14] [media] tuner-core: do the right thing for suspend/resume Mauro Carvalho Chehab
2011-02-14 21:03 ` [PATCH 08/14] [media] tuner-core: Better implement standby mode Mauro Carvalho Chehab
2011-02-14 21:03 ` [PATCH 10/14] [media] tuner-core: CodingStyle cleanups Mauro Carvalho Chehab
2011-02-14 21:03 ` [PATCH 11/14] [media] tuner-core: Don't use a static var for xc5000_cfg Mauro Carvalho Chehab
2011-02-14 21:03 ` [PATCH 01/14] [media] cx88: use unlocked_ioctl for cx88-video Mauro Carvalho Chehab
2011-02-14 21:03 ` [PATCH 02/14] [media] cx88: Don't allow opening a device while it is not ready Mauro Carvalho Chehab
2011-02-14 21:03 ` [PATCH 14/14] [media] Remove the remaining usages for T_STANDBY Mauro Carvalho Chehab
2011-02-14 21:03 ` [PATCH 12/14] [media] tuner-core: dead code removal Mauro Carvalho Chehab
2011-02-14 21:03 ` [PATCH 13/14] [media] tuner-core: Fix a few comments on it Mauro Carvalho Chehab
2011-02-14 21:49 ` [PATCH 01/14] [media] cx88: use unlocked_ioctl for cx88-video Mauro Carvalho Chehab

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.