aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/tda9840.c75
1 files changed, 44 insertions, 31 deletions
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
index 465d7086babf..3d7ddd93282d 100644
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/video/tda9840.c
@@ -66,29 +66,53 @@ static void tda9840_write(struct v4l2_subdev *sd, u8 reg, u8 val)
66 val, reg); 66 val, reg);
67} 67}
68 68
69static int tda9840_status(struct v4l2_subdev *sd)
70{
71 struct i2c_client *client = v4l2_get_subdevdata(sd);
72 u8 byte;
73
74 if (1 != i2c_master_recv(client, &byte, 1)) {
75 v4l2_dbg(1, debug, sd,
76 "i2c_master_recv() failed\n");
77 return -EIO;
78 }
79
80 if (byte & 0x80) {
81 v4l2_dbg(1, debug, sd,
82 "TDA9840_DETECT: register contents invalid\n");
83 return -EINVAL;
84 }
85
86 v4l2_dbg(1, debug, sd, "TDA9840_DETECT: byte: 0x%02x\n", byte);
87 return byte & 0x60;
88}
89
69static int tda9840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t) 90static int tda9840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
70{ 91{
92 int stat = tda9840_status(sd);
71 int byte; 93 int byte;
72 94
73 if (t->index) 95 if (t->index)
74 return -EINVAL; 96 return -EINVAL;
75 97
76 switch (t->audmode) { 98 stat = stat < 0 ? 0 : stat;
77 case V4L2_TUNER_MODE_STEREO: 99 if (stat == 0 || stat == 0x60) /* mono input */
78 byte = TDA9840_SET_STEREO;
79 break;
80 case V4L2_TUNER_MODE_LANG1_LANG2:
81 byte = TDA9840_SET_BOTH;
82 break;
83 case V4L2_TUNER_MODE_LANG1:
84 byte = TDA9840_SET_LANG1;
85 break;
86 case V4L2_TUNER_MODE_LANG2:
87 byte = TDA9840_SET_LANG2;
88 break;
89 default:
90 byte = TDA9840_SET_MONO; 100 byte = TDA9840_SET_MONO;
91 break; 101 else if (stat == 0x40) /* stereo input */
102 byte = (t->audmode == V4L2_TUNER_MODE_MONO) ?
103 TDA9840_SET_MONO : TDA9840_SET_STEREO;
104 else { /* bilingual */
105 switch (t->audmode) {
106 case V4L2_TUNER_MODE_LANG1_LANG2:
107 byte = TDA9840_SET_BOTH;
108 break;
109 case V4L2_TUNER_MODE_LANG2:
110 byte = TDA9840_SET_LANG2;
111 break;
112 default:
113 byte = TDA9840_SET_LANG1;
114 break;
115 }
92 } 116 }
93 v4l2_dbg(1, debug, sd, "TDA9840_SWITCH: 0x%02x\n", byte); 117 v4l2_dbg(1, debug, sd, "TDA9840_SWITCH: 0x%02x\n", byte);
94 tda9840_write(sd, SWITCH, byte); 118 tda9840_write(sd, SWITCH, byte);
@@ -97,25 +121,14 @@ static int tda9840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
97 121
98static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t) 122static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
99{ 123{
100 struct i2c_client *client = v4l2_get_subdevdata(sd); 124 int stat = tda9840_status(sd);
101 u8 byte;
102
103 t->rxsubchans = V4L2_TUNER_SUB_MONO;
104 if (1 != i2c_master_recv(client, &byte, 1)) {
105 v4l2_dbg(1, debug, sd,
106 "i2c_master_recv() failed\n");
107 return -EIO;
108 }
109 125
110 if (byte & 0x80) { 126 if (stat < 0)
111 v4l2_dbg(1, debug, sd, 127 return stat;
112 "TDA9840_DETECT: register contents invalid\n");
113 return -EINVAL;
114 }
115 128
116 v4l2_dbg(1, debug, sd, "TDA9840_DETECT: byte: 0x%02x\n", byte); 129 t->rxsubchans = V4L2_TUNER_SUB_MONO;
117 130
118 switch (byte & 0x60) { 131 switch (stat & 0x60) {
119 case 0x00: 132 case 0x00:
120 t->rxsubchans = V4L2_TUNER_SUB_MONO; 133 t->rxsubchans = V4L2_TUNER_SUB_MONO;
121 break; 134 break;