aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2011-02-04 08:42:09 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:32:01 -0400
commitcbde689823776d187ba1b307a171625dbc02dd4f (patch)
tree6bb5aa1245d405fd42b81344738971356ee38d93
parente2d25a2474a8c0178bac4919729ab092783bd916 (diff)
[media] tuner-core: Better implement standby mode
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>
-rw-r--r--drivers/media/video/tuner-core.c189
-rw-r--r--include/media/tuner.h1
2 files changed, 95 insertions, 95 deletions
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 7cdfe3af6e74..e6855a46f433 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -115,9 +115,11 @@ struct tuner {
115 unsigned int radio_freq; 115 unsigned int radio_freq;
116 unsigned int audmode; 116 unsigned int audmode;
117 117
118 unsigned int mode; 118 enum v4l2_tuner_type mode;
119 unsigned int mode_mask; /* Combination of allowable modes */ 119 unsigned int mode_mask; /* Combination of allowable modes */
120 120
121 bool standby; /* Standby mode */
122
121 unsigned int type; /* chip type id */ 123 unsigned int type; /* chip type id */
122 unsigned int config; 124 unsigned int config;
123 const char *name; 125 const char *name;
@@ -262,12 +264,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
262 t->fe.callback = tuner_callback; 264 t->fe.callback = tuner_callback;
263 } 265 }
264 266
265 if (t->mode == T_UNINITIALIZED) {
266 tuner_dbg ("tuner 0x%02x: called during i2c_client register by adapter's attach_inform\n", c->addr);
267
268 return;
269 }
270
271 /* discard private data, in case set_type() was previously called */ 267 /* discard private data, in case set_type() was previously called */
272 tuner_detach(&t->fe); 268 tuner_detach(&t->fe);
273 t->fe.analog_demod_priv = NULL; 269 t->fe.analog_demod_priv = NULL;
@@ -387,8 +383,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
387 383
388 tuner_dbg("type set to %s\n", t->name); 384 tuner_dbg("type set to %s\n", t->name);
389 385
390 if (t->mode_mask == T_UNINITIALIZED) 386 t->mode_mask = new_mode_mask;
391 t->mode_mask = new_mode_mask;
392 387
393 /* Some tuners require more initialization setup before use, 388 /* Some tuners require more initialization setup before use,
394 such as firmware download or device calibration. 389 such as firmware download or device calibration.
@@ -411,7 +406,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
411attach_failed: 406attach_failed:
412 tuner_dbg("Tuner attach for type = %d failed.\n", t->type); 407 tuner_dbg("Tuner attach for type = %d failed.\n", t->type);
413 t->type = TUNER_ABSENT; 408 t->type = TUNER_ABSENT;
414 t->mode_mask = T_UNINITIALIZED;
415 409
416 return; 410 return;
417} 411}
@@ -429,10 +423,10 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
429 struct tuner *t = to_tuner(i2c_get_clientdata(c)); 423 struct tuner *t = to_tuner(i2c_get_clientdata(c));
430 424
431 if ( (t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) && 425 if ( (t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) &&
432 (t->mode_mask & tun_setup->mode_mask))) || 426 (t->mode_mask & tun_setup->mode_mask))) ||
433 (tun_setup->addr == c->addr)) { 427 (tun_setup->addr == c->addr)) {
434 set_type(c, tun_setup->type, tun_setup->mode_mask, 428 set_type(c, tun_setup->type, tun_setup->mode_mask,
435 tun_setup->config, tun_setup->tuner_callback); 429 tun_setup->config, tun_setup->tuner_callback);
436 } else 430 } else
437 tuner_dbg("set addr discarded for type %i, mask %x. " 431 tuner_dbg("set addr discarded for type %i, mask %x. "
438 "Asked to change tuner at addr 0x%02x, with mask %x\n", 432 "Asked to change tuner at addr 0x%02x, with mask %x\n",
@@ -491,7 +485,8 @@ static void tuner_lookup(struct i2c_adapter *adap,
491 strcmp(pos->i2c->driver->driver.name, "tuner")) 485 strcmp(pos->i2c->driver->driver.name, "tuner"))
492 continue; 486 continue;
493 487
494 mode_mask = pos->mode_mask & ~T_STANDBY; 488 mode_mask = pos->mode_mask;
489 pos->standby = 1;
495 if (*radio == NULL && mode_mask == T_RADIO) 490 if (*radio == NULL && mode_mask == T_RADIO)
496 *radio = pos; 491 *radio = pos;
497 /* Note: currently TDA9887 is the only demod-only 492 /* Note: currently TDA9887 is the only demod-only
@@ -521,7 +516,9 @@ static int tuner_probe(struct i2c_client *client,
521 t->name = "(tuner unset)"; 516 t->name = "(tuner unset)";
522 t->type = UNSET; 517 t->type = UNSET;
523 t->audmode = V4L2_TUNER_MODE_STEREO; 518 t->audmode = V4L2_TUNER_MODE_STEREO;
524 t->mode_mask = T_UNINITIALIZED; 519 t->standby = 1;
520 t->radio_freq = 87.5 * 16000; /* Initial freq range */
521 t->tv_freq = 400 * 16; /* Sets freq to VHF High - needed for some PLL's to properly start */
525 522
526 if (show_i2c) { 523 if (show_i2c) {
527 unsigned char buffer[16]; 524 unsigned char buffer[16];
@@ -544,9 +541,6 @@ static int tuner_probe(struct i2c_client *client,
544 t->i2c->addr) >= 0) { 541 t->i2c->addr) >= 0) {
545 t->type = TUNER_TEA5761; 542 t->type = TUNER_TEA5761;
546 t->mode_mask = T_RADIO; 543 t->mode_mask = T_RADIO;
547 t->mode = T_STANDBY;
548 /* Sets freq to FM range */
549 t->radio_freq = 87.5 * 16000;
550 tuner_lookup(t->i2c->adapter, &radio, &tv); 544 tuner_lookup(t->i2c->adapter, &radio, &tv);
551 if (tv) 545 if (tv)
552 tv->mode_mask &= ~T_RADIO; 546 tv->mode_mask &= ~T_RADIO;
@@ -569,7 +563,6 @@ static int tuner_probe(struct i2c_client *client,
569 t->type = TUNER_TDA9887; 563 t->type = TUNER_TDA9887;
570 t->mode_mask = T_RADIO | T_ANALOG_TV | 564 t->mode_mask = T_RADIO | T_ANALOG_TV |
571 T_DIGITAL_TV; 565 T_DIGITAL_TV;
572 t->mode = T_STANDBY;
573 goto register_client; 566 goto register_client;
574 } 567 }
575 break; 568 break;
@@ -579,9 +572,7 @@ static int tuner_probe(struct i2c_client *client,
579 >= 0) { 572 >= 0) {
580 t->type = TUNER_TEA5767; 573 t->type = TUNER_TEA5767;
581 t->mode_mask = T_RADIO; 574 t->mode_mask = T_RADIO;
582 t->mode = T_STANDBY;
583 /* Sets freq to FM range */ 575 /* Sets freq to FM range */
584 t->radio_freq = 87.5 * 16000;
585 tuner_lookup(t->i2c->adapter, &radio, &tv); 576 tuner_lookup(t->i2c->adapter, &radio, &tv);
586 if (tv) 577 if (tv)
587 tv->mode_mask &= ~T_RADIO; 578 tv->mode_mask &= ~T_RADIO;
@@ -605,15 +596,10 @@ static int tuner_probe(struct i2c_client *client,
605 if (radio == NULL) 596 if (radio == NULL)
606 t->mode_mask |= T_RADIO; 597 t->mode_mask |= T_RADIO;
607 tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask); 598 tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask);
608 t->tv_freq = 400 * 16; /* Sets freq to VHF High */
609 t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */
610 } 599 }
611 600
612 /* Should be just before return */ 601 /* Should be just before return */
613register_client: 602register_client:
614 tuner_info("chip found @ 0x%x (%s)\n", client->addr << 1,
615 client->adapter->name);
616
617 /* Sets a default mode */ 603 /* Sets a default mode */
618 if (t->mode_mask & T_ANALOG_TV) { 604 if (t->mode_mask & T_ANALOG_TV) {
619 t->mode = V4L2_TUNER_ANALOG_TV; 605 t->mode = V4L2_TUNER_ANALOG_TV;
@@ -624,6 +610,12 @@ register_client:
624 } 610 }
625 set_type(client, t->type, t->mode_mask, t->config, t->fe.callback); 611 set_type(client, t->type, t->mode_mask, t->config, t->fe.callback);
626 list_add_tail(&t->list, &tuner_list); 612 list_add_tail(&t->list, &tuner_list);
613
614 tuner_info("Tuner %d found with type(s)%s%s%s.\n",
615 t->type,
616 t->mode_mask & T_RADIO ? " radio" : "",
617 t->mode_mask & T_ANALOG_TV ? " TV" : "",
618 t->mode_mask & T_ANALOG_TV ? " DTV" : "");
627 return 0; 619 return 0;
628} 620}
629 621
@@ -679,6 +671,7 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
679 tuner_dbg("tv freq set to %d.%02d\n", 671 tuner_dbg("tv freq set to %d.%02d\n",
680 freq / 16, freq % 16 * 100 / 16); 672 freq / 16, freq % 16 * 100 / 16);
681 t->tv_freq = freq; 673 t->tv_freq = freq;
674 t->standby = false;
682 675
683 analog_ops->set_params(&t->fe, &params); 676 analog_ops->set_params(&t->fe, &params);
684} 677}
@@ -837,13 +830,14 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
837 tuner_dbg("radio freq set to %d.%02d\n", 830 tuner_dbg("radio freq set to %d.%02d\n",
838 freq / 16000, freq % 16000 * 100 / 16000); 831 freq / 16000, freq % 16000 * 100 / 16000);
839 t->radio_freq = freq; 832 t->radio_freq = freq;
833 t->standby = false;
840 834
841 analog_ops->set_params(&t->fe, &params); 835 analog_ops->set_params(&t->fe, &params);
842} 836}
843 837
844/** 838/**
845 * check_mode - Verify if tuner supports the requested mode 839 * check_mode - Verify if tuner supports the requested mode
846 * @t - a pointer to the module's internal struct_tuner 840 * @t: a pointer to the module's internal struct_tuner
847 * 841 *
848 * This function checks if the tuner is capable of tuning analog TV, 842 * 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 843 * 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)
852 * This function is needed for boards that have a separate tuner for 846 * This function is needed for boards that have a separate tuner for
853 * radio (like devices with tea5767). 847 * radio (like devices with tea5767).
854 */ 848 */
855static inline int check_mode(struct tuner *t) 849static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode)
856{ 850{
857 if ((1 << t->mode & t->mode_mask) == 0) { 851 if ((1 << mode & t->mode_mask) == 0) {
858 return -EINVAL; 852 return -EINVAL;
859 } 853 }
860 return 0; 854 return 0;
861} 855}
862 856
863/** 857/**
864 * set_mode - Switch tuner to other mode. 858 * set_mode_freq - Switch tuner to other mode.
865 * @client - struct i2c_client pointer 859 * @client: struct i2c_client pointer
866 * @t - a pointer to the module's internal struct_tuner 860 * @t: a pointer to the module's internal struct_tuner
867 * @mode - enum v4l2_type + T_STANDBY mode 861 * @mode: enum v4l2_type (radio or TV)
868 * @cmd - string for the command to be executed (for debug messages) 862 * @freq: frequency to set (0 means to use the previous one)
869 * 863 *
870 * If tuner doesn't support the needed mode (radio or TV), prints a 864 * 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. 865 * debug message and returns -EINVAL, changing internal state to T_STANDBY.
872 * Otherwise, changes the state and sets frequency to the last value, if 866 * 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. 867 * the tuner can sleep or if it supports both Radio and TV.
874 */ 868 */
875static inline int set_mode(struct i2c_client *client, struct tuner *t, 869static int set_mode_freq(struct i2c_client *client, struct tuner *t,
876 int mode, char *cmd) 870 enum v4l2_tuner_type mode, unsigned int freq)
877{ 871{
878 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 872 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
879 873
880 if (mode == t->mode) 874 if (mode != t->mode) {
881 return 0; 875 if (check_mode(t, mode) == -EINVAL) {
882 876 tuner_dbg("Tuner doesn't support mode %d. "
883 t->mode = mode; 877 "Putting tuner to sleep\n", mode);
884 878 t->standby = true;
885 if (check_mode(t) == -EINVAL) { 879 if (analog_ops->standby)
886 tuner_dbg("Tuner doesn't support this mode. " 880 analog_ops->standby(&t->fe);
887 "Putting tuner to sleep\n"); 881 return -EINVAL;
888 t->mode = T_STANDBY; 882 }
889 if (analog_ops->standby) 883 t->mode = mode;
890 analog_ops->standby(&t->fe); 884 tuner_dbg("Changing to mode %d\n", mode);
891 return -EINVAL;
892 } 885 }
893
894 if (t->mode == V4L2_TUNER_RADIO) { 886 if (t->mode == V4L2_TUNER_RADIO) {
895 if (t->radio_freq) 887 if (freq)
896 set_radio_freq(client, t->radio_freq); 888 t->radio_freq = freq;
889 set_radio_freq(client, t->radio_freq);
897 } else { 890 } else {
898 if (t->tv_freq) 891 if (freq)
899 set_tv_freq(client, t->tv_freq); 892 t->tv_freq = freq;
893 set_tv_freq(client, t->tv_freq);
900 } 894 }
901 895
902 return 0; 896 return 0;
@@ -923,6 +917,13 @@ static void set_freq(struct i2c_client *c, unsigned long freq)
923 } 917 }
924} 918}
925 919
920/**
921 * tuner_status - Dumps the current tuner status at dmesg
922 * @fe: pointer to struct dvb_frontend
923 *
924 * This callback is used only for driver debug purposes, answering to
925 * VIDIOC_LOG_STATUS. No changes should happen on this call.
926 */
926static void tuner_status(struct dvb_frontend *fe) 927static void tuner_status(struct dvb_frontend *fe)
927{ 928{
928 struct tuner *t = fe->analog_demod_priv; 929 struct tuner *t = fe->analog_demod_priv;
@@ -932,10 +933,16 @@ static void tuner_status(struct dvb_frontend *fe)
932 const char *p; 933 const char *p;
933 934
934 switch (t->mode) { 935 switch (t->mode) {
935 case V4L2_TUNER_RADIO: p = "radio"; break; 936 case V4L2_TUNER_RADIO:
936 case V4L2_TUNER_ANALOG_TV: p = "analog TV"; break; 937 p = "radio";
937 case V4L2_TUNER_DIGITAL_TV: p = "digital TV"; break; 938 break;
938 default: p = "undefined"; break; 939 case V4L2_TUNER_DIGITAL_TV:
940 p = "digital TV";
941 break;
942 case V4L2_TUNER_ANALOG_TV:
943 default:
944 p = "analog TV";
945 break;
939 } 946 }
940 if (t->mode == V4L2_TUNER_RADIO) { 947 if (t->mode == V4L2_TUNER_RADIO) {
941 freq = t->radio_freq / 16000; 948 freq = t->radio_freq / 16000;
@@ -944,7 +951,8 @@ static void tuner_status(struct dvb_frontend *fe)
944 freq = t->tv_freq / 16; 951 freq = t->tv_freq / 16;
945 freq_fraction = (t->tv_freq % 16) * 100 / 16; 952 freq_fraction = (t->tv_freq % 16) * 100 / 16;
946 } 953 }
947 tuner_info("Tuner mode: %s\n", p); 954 tuner_info("Tuner mode: %s%s\n", p,
955 t->standby ? " on standby mode" : "");
948 tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction); 956 tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction);
949 tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std); 957 tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std);
950 if (t->mode != V4L2_TUNER_RADIO) 958 if (t->mode != V4L2_TUNER_RADIO)
@@ -963,19 +971,22 @@ static void tuner_status(struct dvb_frontend *fe)
963 analog_ops->has_signal(fe)); 971 analog_ops->has_signal(fe));
964} 972}
965 973
974/**
975 * tuner_s_power - controls the power state of the tuner
976 * @sd: pointer to struct v4l2_subdev
977 * @on: a zero value puts the tuner to sleep
978 */
966static int tuner_s_power(struct v4l2_subdev *sd, int on) 979static int tuner_s_power(struct v4l2_subdev *sd, int on)
967{ 980{
968 struct tuner *t = to_tuner(sd); 981 struct tuner *t = to_tuner(sd);
969 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 982 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
970 983
984 /* FIXME: Why this function don't wake the tuner if on != 0 ? */
971 if (on) 985 if (on)
972 return 0; 986 return 0;
973 987
974 tuner_dbg("Putting tuner to sleep\n"); 988 tuner_dbg("Putting tuner to sleep\n");
975 989 t->standby = true;
976 if (check_mode(t) == -EINVAL)
977 return 0;
978 t->mode = T_STANDBY;
979 if (analog_ops->standby) 990 if (analog_ops->standby)
980 analog_ops->standby(&t->fe); 991 analog_ops->standby(&t->fe);
981 return 0; 992 return 0;
@@ -983,13 +994,12 @@ static int tuner_s_power(struct v4l2_subdev *sd, int on)
983 994
984/* ---------------------------------------------------------------------- */ 995/* ---------------------------------------------------------------------- */
985 996
986
987static int tuner_s_radio(struct v4l2_subdev *sd) 997static int tuner_s_radio(struct v4l2_subdev *sd)
988{ 998{
989 struct tuner *t = to_tuner(sd); 999 struct tuner *t = to_tuner(sd);
990 struct i2c_client *client = v4l2_get_subdevdata(sd); 1000 struct i2c_client *client = v4l2_get_subdevdata(sd);
991 1001
992 if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL) 1002 if (set_mode_freq(client, t, V4L2_TUNER_RADIO, 0) == -EINVAL)
993 return 0; 1003 return 0;
994 return 0; 1004 return 0;
995} 1005}
@@ -1002,13 +1012,12 @@ static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1002 struct tuner *t = to_tuner(sd); 1012 struct tuner *t = to_tuner(sd);
1003 struct i2c_client *client = v4l2_get_subdevdata(sd); 1013 struct i2c_client *client = v4l2_get_subdevdata(sd);
1004 1014
1005 if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "s_std") == -EINVAL) 1015 if (set_mode_freq(client, t, V4L2_TUNER_ANALOG_TV, 0) == -EINVAL)
1006 return 0; 1016 return 0;
1007 1017
1008 t->std = std; 1018 t->std = std;
1009 tuner_fixup_std(t); 1019 tuner_fixup_std(t);
1010 if (t->tv_freq) 1020
1011 set_freq(client, t->tv_freq);
1012 return 0; 1021 return 0;
1013} 1022}
1014 1023
@@ -1017,9 +1026,8 @@ static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
1017 struct tuner *t = to_tuner(sd); 1026 struct tuner *t = to_tuner(sd);
1018 struct i2c_client *client = v4l2_get_subdevdata(sd); 1027 struct i2c_client *client = v4l2_get_subdevdata(sd);
1019 1028
1020 if (set_mode(client, t, f->type, "s_frequency") == -EINVAL) 1029 if (set_mode_freq(client, t, f->type, f->frequency) == -EINVAL)
1021 return 0; 1030 return 0;
1022 set_freq(client, f->frequency);
1023 1031
1024 return 0; 1032 return 0;
1025} 1033}
@@ -1029,20 +1037,20 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
1029 struct tuner *t = to_tuner(sd); 1037 struct tuner *t = to_tuner(sd);
1030 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 1038 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
1031 1039
1032 if (check_mode(t) == -EINVAL) 1040 if (check_mode(t, f->type) == -EINVAL)
1033 return 0; 1041 return 0;
1034 f->type = t->mode; 1042 f->type = t->mode;
1035 if (fe_tuner_ops->get_frequency) { 1043 if (fe_tuner_ops->get_frequency && !t->standby) {
1036 u32 abs_freq; 1044 u32 abs_freq;
1037 1045
1038 fe_tuner_ops->get_frequency(&t->fe, &abs_freq); 1046 fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
1039 f->frequency = (V4L2_TUNER_RADIO == t->mode) ? 1047 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
1040 DIV_ROUND_CLOSEST(abs_freq * 2, 125) : 1048 DIV_ROUND_CLOSEST(abs_freq * 2, 125) :
1041 DIV_ROUND_CLOSEST(abs_freq, 62500); 1049 DIV_ROUND_CLOSEST(abs_freq, 62500);
1042 return 0; 1050 } else {
1051 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
1052 t->radio_freq : t->tv_freq;
1043 } 1053 }
1044 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
1045 t->radio_freq : t->tv_freq;
1046 return 0; 1054 return 0;
1047} 1055}
1048 1056
@@ -1052,9 +1060,8 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1052 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 1060 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
1053 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 1061 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
1054 1062
1055 if (check_mode(t) == -EINVAL) 1063 if (check_mode(t, vt->type) == -EINVAL)
1056 return 0; 1064 return 0;
1057
1058 vt->type = t->mode; 1065 vt->type = t->mode;
1059 if (analog_ops->get_afc) 1066 if (analog_ops->get_afc)
1060 vt->afc = analog_ops->get_afc(&t->fe); 1067 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)
1067 } 1074 }
1068 1075
1069 /* radio mode */ 1076 /* radio mode */
1070 vt->rxsubchans = 1077 vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
1071 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
1072 if (fe_tuner_ops->get_status) { 1078 if (fe_tuner_ops->get_status) {
1073 u32 tuner_status; 1079 u32 tuner_status;
1074 1080
@@ -1080,11 +1086,11 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1080 } 1086 }
1081 if (analog_ops->has_signal) 1087 if (analog_ops->has_signal)
1082 vt->signal = analog_ops->has_signal(&t->fe); 1088 vt->signal = analog_ops->has_signal(&t->fe);
1083 vt->capability |= 1089 vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
1084 V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
1085 vt->audmode = t->audmode; 1090 vt->audmode = t->audmode;
1086 vt->rangelow = radio_range[0] * 16000; 1091 vt->rangelow = radio_range[0] * 16000;
1087 vt->rangehigh = radio_range[1] * 16000; 1092 vt->rangehigh = radio_range[1] * 16000;
1093
1088 return 0; 1094 return 0;
1089} 1095}
1090 1096
@@ -1093,14 +1099,12 @@ static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1093 struct tuner *t = to_tuner(sd); 1099 struct tuner *t = to_tuner(sd);
1094 struct i2c_client *client = v4l2_get_subdevdata(sd); 1100 struct i2c_client *client = v4l2_get_subdevdata(sd);
1095 1101
1096 if (check_mode(t) == -EINVAL) 1102 if (set_mode_freq(client, t, vt->type, 0) == -EINVAL)
1097 return 0; 1103 return 0;
1098 1104
1099 /* do nothing unless we're a radio tuner */ 1105 if (t->mode == V4L2_TUNER_RADIO)
1100 if (t->mode != V4L2_TUNER_RADIO) 1106 t->audmode = vt->audmode;
1101 return 0; 1107
1102 t->audmode = vt->audmode;
1103 set_radio_freq(client, t->radio_freq);
1104 return 0; 1108 return 0;
1105} 1109}
1106 1110
@@ -1128,13 +1132,10 @@ static int tuner_resume(struct i2c_client *c)
1128 struct tuner *t = to_tuner(i2c_get_clientdata(c)); 1132 struct tuner *t = to_tuner(i2c_get_clientdata(c));
1129 1133
1130 tuner_dbg("resume\n"); 1134 tuner_dbg("resume\n");
1131 if (V4L2_TUNER_RADIO == t->mode) { 1135 if (V4L2_TUNER_RADIO == t->mode)
1132 if (t->radio_freq) 1136 set_freq(c, t->radio_freq);
1133 set_freq(c, t->radio_freq); 1137 else
1134 } else { 1138 set_freq(c, t->tv_freq);
1135 if (t->tv_freq)
1136 set_freq(c, t->tv_freq);
1137 }
1138 return 0; 1139 return 0;
1139} 1140}
1140 1141
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 5eec5292d01e..1d596427d124 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -160,7 +160,6 @@
160#ifdef __KERNEL__ 160#ifdef __KERNEL__
161 161
162enum tuner_mode { 162enum tuner_mode {
163 T_UNINITIALIZED = 0,
164 T_RADIO = 1 << V4L2_TUNER_RADIO, 163 T_RADIO = 1 << V4L2_TUNER_RADIO,
165 T_ANALOG_TV = 1 << V4L2_TUNER_ANALOG_TV, 164 T_ANALOG_TV = 1 << V4L2_TUNER_ANALOG_TV,
166 T_DIGITAL_TV = 1 << V4L2_TUNER_DIGITAL_TV, 165 T_DIGITAL_TV = 1 << V4L2_TUNER_DIGITAL_TV,