aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2011-02-04 08:09:07 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:32:01 -0400
commite2d25a2474a8c0178bac4919729ab092783bd916 (patch)
tree1bad31779e31d6b310a42cdb5a43bd494636852b /drivers/media/video
parent9f3f71ef6d9a6179a16f82287f062cbf3f112ec6 (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.c72
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, &params); 841 analog_ops->set_params(&t->fe, &params);
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 855static inline int check_mode(struct tuner *t)
848static 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 875static inline int set_mode(struct i2c_client *client, struct tuner *t,
875static 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
895static void set_freq(struct i2c_client *c, unsigned long freq) 909static 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 */