aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Krufky <mkrufky@linuxtv.org>2007-08-21 00:25:48 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 21:07:35 -0400
commite18f9444bda60a67e6feef00c354f8de0cdaeba7 (patch)
tree249fdd5ffa57459f8e126987ccef51e7cb69f893
parentdb8a695658cda21eacfa2a5e3b15e8964bfb93ef (diff)
V4L/DVB (6128): hybrid tuner refactoring core changes, phase 1
Prepare tuner-core for conversion of tuner sub-drivers into dvb_frontend modules Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Acked-by: Hans Verkuil <hverkuil@xs4all.nl> Acked-by: Mike Isely <isely@pobox.com> Acked-by: Steven Toth <stoth@hauppauge.com> Acked-by: Patrick Boettcher <pb@linuxtv.org> Acked-by: Jarod Wilson <jwilson@redhat.com> Acked-by: Oliver Endriss <o.endriss@gmx.de> Acked-by: Trent Piepho <xyzzy@speakeasy.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h9
-rw-r--r--drivers/media/video/tuner-core.c129
-rw-r--r--drivers/media/video/tuner-driver.h3
3 files changed, 123 insertions, 18 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index f95de63d0e24..ffb83b0f68c3 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -62,6 +62,13 @@ struct dvb_tuner_info {
62 u32 bandwidth_step; 62 u32 bandwidth_step;
63}; 63};
64 64
65struct analog_parameters {
66 unsigned int frequency;
67 unsigned int mode;
68 unsigned int audmode;
69 u64 std;
70};
71
65struct dvb_tuner_ops { 72struct dvb_tuner_ops {
66 73
67 struct dvb_tuner_info info; 74 struct dvb_tuner_info info;
@@ -72,6 +79,7 @@ struct dvb_tuner_ops {
72 79
73 /** This is for simple PLLs - set all parameters in one go. */ 80 /** This is for simple PLLs - set all parameters in one go. */
74 int (*set_params)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); 81 int (*set_params)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
82 int (*set_analog_params)(struct dvb_frontend *fe, struct analog_parameters *p);
75 83
76 /** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */ 84 /** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */
77 int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len); 85 int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len);
@@ -80,6 +88,7 @@ struct dvb_tuner_ops {
80 int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth); 88 int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
81 89
82#define TUNER_STATUS_LOCKED 1 90#define TUNER_STATUS_LOCKED 1
91#define TUNER_STATUS_STEREO 2
83 int (*get_status)(struct dvb_frontend *fe, u32 *status); 92 int (*get_status)(struct dvb_frontend *fe, u32 *status);
84 93
85 /** These are provided seperately from set_params in order to facilitate silicon 94 /** These are provided seperately from set_params in order to facilitate silicon
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 0363eae800e7..183bbb9ba6ab 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -70,6 +70,40 @@ static struct i2c_client client_template;
70 70
71/* ---------------------------------------------------------------------- */ 71/* ---------------------------------------------------------------------- */
72 72
73static void fe_set_freq(struct tuner *t, unsigned int freq)
74{
75 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
76
77 struct analog_parameters params = {
78 .frequency = freq,
79 .mode = t->mode,
80 .audmode = t->audmode,
81 .std = t->std
82 };
83
84 if (NULL == fe_tuner_ops->set_analog_params) {
85 tuner_warn("Tuner frontend module has no way to set freq\n");
86 return;
87 }
88 fe_tuner_ops->set_analog_params(&t->fe, &params);
89}
90
91static void fe_release(struct tuner *t)
92{
93 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
94
95 if (fe_tuner_ops->release)
96 fe_tuner_ops->release(&t->fe);
97}
98
99static void fe_standby(struct tuner *t)
100{
101 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
102
103 if (fe_tuner_ops->sleep)
104 fe_tuner_ops->sleep(&t->fe);
105}
106
73/* Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz */ 107/* Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz */
74static void set_tv_freq(struct i2c_client *c, unsigned int freq) 108static void set_tv_freq(struct i2c_client *c, unsigned int freq)
75{ 109{
@@ -171,6 +205,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
171 int (*tuner_callback) (void *dev, int command,int arg)) 205 int (*tuner_callback) (void *dev, int command,int arg))
172{ 206{
173 struct tuner *t = i2c_get_clientdata(c); 207 struct tuner *t = i2c_get_clientdata(c);
208 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
174 unsigned char buffer[4]; 209 unsigned char buffer[4];
175 210
176 if (type == UNSET || type == TUNER_ABSENT) { 211 if (type == UNSET || type == TUNER_ABSENT) {
@@ -258,6 +293,17 @@ static void set_type(struct i2c_client *c, unsigned int type,
258 break; 293 break;
259 } 294 }
260 295
296 if (fe_tuner_ops->set_analog_params) {
297 strlcpy(t->i2c.name, fe_tuner_ops->info.name, sizeof(t->i2c.name));
298
299 t->ops.set_tv_freq = fe_set_freq;
300 t->ops.set_radio_freq = fe_set_freq;
301 t->ops.standby = fe_standby;
302 t->ops.release = fe_release;
303 }
304
305 tuner_info("type set to %s\n", t->i2c.name);
306
261 if (t->mode_mask == T_UNINITIALIZED) 307 if (t->mode_mask == T_UNINITIALIZED)
262 t->mode_mask = new_mode_mask; 308 t->mode_mask = new_mode_mask;
263 309
@@ -429,6 +475,7 @@ static int tuner_fixup_std(struct tuner *t)
429static void tuner_status(struct tuner *t) 475static void tuner_status(struct tuner *t)
430{ 476{
431 unsigned long freq, freq_fraction; 477 unsigned long freq, freq_fraction;
478 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
432 const char *p; 479 const char *p;
433 480
434 switch (t->mode) { 481 switch (t->mode) {
@@ -449,6 +496,15 @@ static void tuner_status(struct tuner *t)
449 tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std); 496 tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std);
450 if (t->mode != V4L2_TUNER_RADIO) 497 if (t->mode != V4L2_TUNER_RADIO)
451 return; 498 return;
499 if (fe_tuner_ops->get_status) {
500 u32 tuner_status;
501
502 fe_tuner_ops->get_status(&t->fe, &tuner_status);
503 if (tuner_status & TUNER_STATUS_LOCKED)
504 tuner_info("Tuner is locked.\n");
505 if (tuner_status & TUNER_STATUS_STEREO)
506 tuner_info("Stereo: yes\n");
507 }
452 if (t->ops.has_signal) { 508 if (t->ops.has_signal) {
453 tuner_info("Signal strength: %d\n", t->ops.has_signal(t)); 509 tuner_info("Signal strength: %d\n", t->ops.has_signal(t));
454 } 510 }
@@ -634,6 +690,7 @@ static inline int check_v4l2(struct tuner *t)
634static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) 690static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
635{ 691{
636 struct tuner *t = i2c_get_clientdata(client); 692 struct tuner *t = i2c_get_clientdata(client);
693 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
637 694
638 if (tuner_debug>1) 695 if (tuner_debug>1)
639 v4l_i2c_print_ioctl(&(t->i2c),cmd); 696 v4l_i2c_print_ioctl(&(t->i2c),cmd);
@@ -720,15 +777,27 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
720 return 0; 777 return 0;
721 778
722 if (V4L2_TUNER_RADIO == t->mode) { 779 if (V4L2_TUNER_RADIO == t->mode) {
723 if (t->ops.has_signal) 780 if (fe_tuner_ops->get_status) {
724 vt->signal = t->ops.has_signal(t); 781 u32 tuner_status;
725 if (t->ops.is_stereo) { 782
726 if (t->ops.is_stereo(t)) 783 fe_tuner_ops->get_status(&t->fe, &tuner_status);
727 vt->flags |= 784 if (tuner_status & TUNER_STATUS_STEREO)
728 VIDEO_TUNER_STEREO_ON; 785 vt->flags |= VIDEO_TUNER_STEREO_ON;
729 else 786 else
730 vt->flags &= 787 vt->flags &= ~VIDEO_TUNER_STEREO_ON;
731 ~VIDEO_TUNER_STEREO_ON; 788 vt->signal = tuner_status & TUNER_STATUS_LOCKED
789 ? 65535 : 0;
790 } else {
791 if (t->ops.is_stereo) {
792 if (t->ops.is_stereo(t))
793 vt->flags |=
794 VIDEO_TUNER_STEREO_ON;
795 else
796 vt->flags &=
797 ~VIDEO_TUNER_STEREO_ON;
798 }
799 if (t->ops.has_signal)
800 vt->signal = t->ops.has_signal(t);
732 } 801 }
733 vt->flags |= VIDEO_TUNER_LOW; /* Allow freqs at 62.5 Hz */ 802 vt->flags |= VIDEO_TUNER_LOW; /* Allow freqs at 62.5 Hz */
734 803
@@ -751,9 +820,17 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
751 if (check_v4l2(t) == EINVAL) 820 if (check_v4l2(t) == EINVAL)
752 return 0; 821 return 0;
753 822
754 if (V4L2_TUNER_RADIO == t->mode && t->ops.is_stereo) 823 if (V4L2_TUNER_RADIO == t->mode) {
755 va->mode = t->ops.is_stereo(t) 824 if (fe_tuner_ops->get_status) {
756 ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; 825 u32 tuner_status;
826
827 fe_tuner_ops->get_status(&t->fe, &tuner_status);
828 va->mode = (tuner_status & TUNER_STATUS_STEREO)
829 ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
830 } else if (t->ops.is_stereo)
831 va->mode = t->ops.is_stereo(t)
832 ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
833 }
757 return 0; 834 return 0;
758 } 835 }
759#endif 836#endif
@@ -804,6 +881,15 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
804 return 0; 881 return 0;
805 switch_v4l2(); 882 switch_v4l2();
806 f->type = t->mode; 883 f->type = t->mode;
884 if (fe_tuner_ops->get_frequency) {
885 u32 abs_freq;
886
887 fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
888 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
889 (abs_freq * 2 + 125/2) / 125 :
890 (abs_freq + 62500/2) / 62500;
891 break;
892 }
807 f->frequency = (V4L2_TUNER_RADIO == t->mode) ? 893 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
808 t->radio_freq : t->tv_freq; 894 t->radio_freq : t->tv_freq;
809 break; 895 break;
@@ -828,16 +914,23 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
828 } 914 }
829 915
830 /* radio mode */ 916 /* radio mode */
831 if (t->ops.has_signal)
832 tuner->signal = t->ops.has_signal(t);
833
834 tuner->rxsubchans = 917 tuner->rxsubchans =
835 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 918 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
836 if (t->ops.is_stereo) { 919 if (fe_tuner_ops->get_status) {
837 tuner->rxsubchans = t->ops.is_stereo(t) ? 920 u32 tuner_status;
921
922 fe_tuner_ops->get_status(&t->fe, &tuner_status);
923 tuner->rxsubchans = (tuner_status & TUNER_STATUS_STEREO) ?
838 V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; 924 V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
925 tuner->signal = tuner_status & TUNER_STATUS_LOCKED ? 65535 : 0;
926 } else {
927 if (t->ops.is_stereo) {
928 tuner->rxsubchans = t->ops.is_stereo(t) ?
929 V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
930 }
931 if (t->ops.has_signal)
932 tuner->signal = t->ops.has_signal(t);
839 } 933 }
840
841 tuner->capability |= 934 tuner->capability |=
842 V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; 935 V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
843 tuner->audmode = t->audmode; 936 tuner->audmode = t->audmode;
diff --git a/drivers/media/video/tuner-driver.h b/drivers/media/video/tuner-driver.h
index 3cd1d446f2f3..d4c02b4abe71 100644
--- a/drivers/media/video/tuner-driver.h
+++ b/drivers/media/video/tuner-driver.h
@@ -25,6 +25,7 @@
25#include <linux/videodev2.h> 25#include <linux/videodev2.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include "tuner-i2c.h" 27#include "tuner-i2c.h"
28#include "dvb_frontend.h"
28 29
29extern unsigned const int tuner_count; 30extern unsigned const int tuner_count;
30 31
@@ -58,6 +59,8 @@ struct tuner {
58 int using_v4l2; 59 int using_v4l2;
59 void *priv; 60 void *priv;
60 61
62 struct dvb_frontend fe;
63
61 /* used by tda9887 */ 64 /* used by tda9887 */
62 unsigned int tda9887_config; 65 unsigned int tda9887_config;
63 66