diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-02-04 08:09:07 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:32:01 -0400 |
commit | e2d25a2474a8c0178bac4919729ab092783bd916 (patch) | |
tree | 1bad31779e31d6b310a42cdb5a43bd494636852b /drivers/media/video | |
parent | 9f3f71ef6d9a6179a16f82287f062cbf3f112ec6 (diff) |
[media] tuner-core: Some cleanups at check_mode/set_mode
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>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/tuner-core.c | 72 |
1 files changed, 42 insertions, 30 deletions
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 5c3da21d188e..7cdfe3af6e74 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) | |||
841 | analog_ops->set_params(&t->fe, ¶ms); | 841 | analog_ops->set_params(&t->fe, ¶ms); |
842 | } | 842 | } |
843 | 843 | ||
844 | /* | 844 | /** |
845 | * Functions that should be broken into separate radio/TV functions | 845 | * check_mode - Verify if tuner supports the requested mode |
846 | * @t - a pointer to the module's internal struct_tuner | ||
847 | * | ||
848 | * This function checks if the tuner is capable of tuning analog TV, | ||
849 | * digital TV or radio, depending on what the caller wants. If the | ||
850 | * tuner can't support that mode, it returns -EINVAL. Otherwise, it | ||
851 | * returns 0. | ||
852 | * This function is needed for boards that have a separate tuner for | ||
853 | * radio (like devices with tea5767). | ||
846 | */ | 854 | */ |
847 | 855 | static inline int check_mode(struct tuner *t) | |
848 | static inline int check_mode(struct tuner *t, char *cmd) | ||
849 | { | 856 | { |
850 | if ((1 << t->mode & t->mode_mask) == 0) { | 857 | if ((1 << t->mode & t->mode_mask) == 0) { |
851 | return -EINVAL; | 858 | return -EINVAL; |
852 | } | 859 | } |
853 | |||
854 | switch (t->mode) { | ||
855 | case V4L2_TUNER_RADIO: | ||
856 | tuner_dbg("Cmd %s accepted for radio\n", cmd); | ||
857 | break; | ||
858 | case V4L2_TUNER_ANALOG_TV: | ||
859 | tuner_dbg("Cmd %s accepted for analog TV\n", cmd); | ||
860 | break; | ||
861 | case V4L2_TUNER_DIGITAL_TV: | ||
862 | tuner_dbg("Cmd %s accepted for digital TV\n", cmd); | ||
863 | break; | ||
864 | } | ||
865 | return 0; | 860 | return 0; |
866 | } | 861 | } |
867 | 862 | ||
868 | /* | 863 | /** |
869 | * Switch tuner to other mode. If tuner support both tv and radio, | 864 | * set_mode - Switch tuner to other mode. |
870 | * set another frequency to some value (This is needed for some pal | 865 | * @client - struct i2c_client pointer |
871 | * tuners to avoid locking). Otherwise, just put second tuner in | 866 | * @t - a pointer to the module's internal struct_tuner |
872 | * standby mode. | 867 | * @mode - enum v4l2_type + T_STANDBY mode |
868 | * @cmd - string for the command to be executed (for debug messages) | ||
869 | * | ||
870 | * If tuner doesn't support the needed mode (radio or TV), prints a | ||
871 | * debug message and returns -EINVAL, changing internal state to T_STANDBY. | ||
872 | * Otherwise, changes the state and sets frequency to the last value, if | ||
873 | * the tuner can sleep or if it supports both Radio and TV. | ||
873 | */ | 874 | */ |
874 | 875 | static inline int set_mode(struct i2c_client *client, struct tuner *t, | |
875 | static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd) | 876 | int mode, char *cmd) |
876 | { | 877 | { |
877 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; | 878 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; |
878 | 879 | ||
@@ -881,7 +882,7 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, | |||
881 | 882 | ||
882 | t->mode = mode; | 883 | t->mode = mode; |
883 | 884 | ||
884 | if (check_mode(t, cmd) == -EINVAL) { | 885 | if (check_mode(t) == -EINVAL) { |
885 | tuner_dbg("Tuner doesn't support this mode. " | 886 | tuner_dbg("Tuner doesn't support this mode. " |
886 | "Putting tuner to sleep\n"); | 887 | "Putting tuner to sleep\n"); |
887 | t->mode = T_STANDBY; | 888 | t->mode = T_STANDBY; |
@@ -889,9 +890,22 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, | |||
889 | analog_ops->standby(&t->fe); | 890 | analog_ops->standby(&t->fe); |
890 | return -EINVAL; | 891 | return -EINVAL; |
891 | } | 892 | } |
893 | |||
894 | if (t->mode == V4L2_TUNER_RADIO) { | ||
895 | if (t->radio_freq) | ||
896 | set_radio_freq(client, t->radio_freq); | ||
897 | } else { | ||
898 | if (t->tv_freq) | ||
899 | set_tv_freq(client, t->tv_freq); | ||
900 | } | ||
901 | |||
892 | return 0; | 902 | return 0; |
893 | } | 903 | } |
894 | 904 | ||
905 | /* | ||
906 | * Functions that should be broken into separate radio/TV functions | ||
907 | */ | ||
908 | |||
895 | static void set_freq(struct i2c_client *c, unsigned long freq) | 909 | static void set_freq(struct i2c_client *c, unsigned long freq) |
896 | { | 910 | { |
897 | struct tuner *t = to_tuner(i2c_get_clientdata(c)); | 911 | struct tuner *t = to_tuner(i2c_get_clientdata(c)); |
@@ -959,7 +973,7 @@ static int tuner_s_power(struct v4l2_subdev *sd, int on) | |||
959 | 973 | ||
960 | tuner_dbg("Putting tuner to sleep\n"); | 974 | tuner_dbg("Putting tuner to sleep\n"); |
961 | 975 | ||
962 | if (check_mode(t, "s_power") == -EINVAL) | 976 | if (check_mode(t) == -EINVAL) |
963 | return 0; | 977 | return 0; |
964 | t->mode = T_STANDBY; | 978 | t->mode = T_STANDBY; |
965 | if (analog_ops->standby) | 979 | if (analog_ops->standby) |
@@ -977,8 +991,6 @@ static int tuner_s_radio(struct v4l2_subdev *sd) | |||
977 | 991 | ||
978 | if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL) | 992 | if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL) |
979 | return 0; | 993 | return 0; |
980 | if (t->radio_freq) | ||
981 | set_freq(client, t->radio_freq); | ||
982 | return 0; | 994 | return 0; |
983 | } | 995 | } |
984 | 996 | ||
@@ -1017,7 +1029,7 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) | |||
1017 | struct tuner *t = to_tuner(sd); | 1029 | struct tuner *t = to_tuner(sd); |
1018 | struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; | 1030 | struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; |
1019 | 1031 | ||
1020 | if (check_mode(t, "g_frequency") == -EINVAL) | 1032 | if (check_mode(t) == -EINVAL) |
1021 | return 0; | 1033 | return 0; |
1022 | f->type = t->mode; | 1034 | f->type = t->mode; |
1023 | if (fe_tuner_ops->get_frequency) { | 1035 | if (fe_tuner_ops->get_frequency) { |
@@ -1040,7 +1052,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | |||
1040 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; | 1052 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; |
1041 | struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; | 1053 | struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; |
1042 | 1054 | ||
1043 | if (check_mode(t, "g_tuner") == -EINVAL) | 1055 | if (check_mode(t) == -EINVAL) |
1044 | return 0; | 1056 | return 0; |
1045 | 1057 | ||
1046 | vt->type = t->mode; | 1058 | vt->type = t->mode; |
@@ -1081,7 +1093,7 @@ static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | |||
1081 | struct tuner *t = to_tuner(sd); | 1093 | struct tuner *t = to_tuner(sd); |
1082 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1094 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1083 | 1095 | ||
1084 | if (check_mode(t, "s_tuner") == -EINVAL) | 1096 | if (check_mode(t) == -EINVAL) |
1085 | return 0; | 1097 | return 0; |
1086 | 1098 | ||
1087 | /* do nothing unless we're a radio tuner */ | 1099 | /* do nothing unless we're a radio tuner */ |