diff options
author | Michael Krufky <mkrufky@linuxtv.org> | 2007-08-21 00:25:48 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-09 21:07:35 -0400 |
commit | e18f9444bda60a67e6feef00c354f8de0cdaeba7 (patch) | |
tree | 249fdd5ffa57459f8e126987ccef51e7cb69f893 | |
parent | db8a695658cda21eacfa2a5e3b15e8964bfb93ef (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.h | 9 | ||||
-rw-r--r-- | drivers/media/video/tuner-core.c | 129 | ||||
-rw-r--r-- | drivers/media/video/tuner-driver.h | 3 |
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 | ||
65 | struct analog_parameters { | ||
66 | unsigned int frequency; | ||
67 | unsigned int mode; | ||
68 | unsigned int audmode; | ||
69 | u64 std; | ||
70 | }; | ||
71 | |||
65 | struct dvb_tuner_ops { | 72 | struct 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 | ||
73 | static 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, ¶ms); | ||
89 | } | ||
90 | |||
91 | static 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 | |||
99 | static 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 */ |
74 | static void set_tv_freq(struct i2c_client *c, unsigned int freq) | 108 | static 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) | |||
429 | static void tuner_status(struct tuner *t) | 475 | static 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) | |||
634 | static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | 690 | static 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 | ||
29 | extern unsigned const int tuner_count; | 30 | extern 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 | ||