aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/tda9840.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2008-09-06 14:40:25 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-12 07:37:00 -0400
commit707ecf4603a9439dcf409e13c5e9ed4e164ddfff (patch)
tree276b2ff411c90e42716f71be52bfa4e9d7ece382 /drivers/media/video/tda9840.c
parent6bd6dff6318397b1127dd256b65dde007306b8ea (diff)
V4L/DVB (8941): mxb/tda9840: cleanups, use module saa7115 instead of saa7111.
Cleanup tda9840 and use a v4l2 API to get the tuner subchannels. Do some cleanups in mxb and switch to saa7115 instead of the saa7111 module. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/tda9840.c')
-rw-r--r--drivers/media/video/tda9840.c112
1 files changed, 69 insertions, 43 deletions
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
index 57deeb893318..77bfd24ecfae 100644
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/video/tda9840.c
@@ -47,6 +47,15 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
47#define STEREO_ADJUST 0x03 47#define STEREO_ADJUST 0x03
48#define TEST 0x04 48#define TEST 0x04
49 49
50#define TDA9840_SET_MUTE 0x00
51#define TDA9840_SET_MONO 0x10
52#define TDA9840_SET_STEREO 0x2a
53#define TDA9840_SET_LANG1 0x12
54#define TDA9840_SET_LANG2 0x1e
55#define TDA9840_SET_BOTH 0x1a
56#define TDA9840_SET_BOTH_R 0x16
57#define TDA9840_SET_EXTERNAL 0x7a
58
50/* addresses to scan, found only at 0x42 (7-Bit) */ 59/* addresses to scan, found only at 0x42 (7-Bit) */
51static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END }; 60static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END };
52 61
@@ -62,26 +71,74 @@ static void tda9840_write(struct i2c_client *client, u8 reg, u8 val)
62 71
63static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg) 72static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg)
64{ 73{
65 int result; 74 int result = 0;
66 int byte = *(int *)arg; 75 int byte = *(int *)arg;
67 76
68 switch (cmd) { 77 switch (cmd) {
69 case TDA9840_SWITCH: 78 case VIDIOC_S_TUNER: {
79 struct v4l2_tuner *t = arg;
80 int byte;
81
82 if (t->index)
83 return -EINVAL;
84
85 switch (t->audmode) {
86 case V4L2_TUNER_MODE_STEREO:
87 byte = TDA9840_SET_STEREO;
88 break;
89 case V4L2_TUNER_MODE_LANG1_LANG2:
90 byte = TDA9840_SET_BOTH;
91 break;
92 case V4L2_TUNER_MODE_LANG1:
93 byte = TDA9840_SET_LANG1;
94 break;
95 case V4L2_TUNER_MODE_LANG2:
96 byte = TDA9840_SET_LANG2;
97 break;
98 default:
99 byte = TDA9840_SET_MONO;
100 break;
101 }
70 v4l_dbg(1, debug, client, "TDA9840_SWITCH: 0x%02x\n", byte); 102 v4l_dbg(1, debug, client, "TDA9840_SWITCH: 0x%02x\n", byte);
103 tda9840_write(client, SWITCH, byte);
104 break;
105 }
106
107 case VIDIOC_G_TUNER: {
108 struct v4l2_tuner *t = arg;
109 u8 byte;
71 110
72 if (byte != TDA9840_SET_MONO 111 t->rxsubchans = V4L2_TUNER_SUB_MONO;
73 && byte != TDA9840_SET_MUTE 112 if (1 != i2c_master_recv(client, &byte, 1)) {
74 && byte != TDA9840_SET_STEREO 113 v4l_dbg(1, debug, client,
75 && byte != TDA9840_SET_LANG1 114 "i2c_master_recv() failed\n");
76 && byte != TDA9840_SET_LANG2 115 return -EIO;
77 && byte != TDA9840_SET_BOTH 116 }
78 && byte != TDA9840_SET_BOTH_R 117
79 && byte != TDA9840_SET_EXTERNAL) { 118 if (byte & 0x80) {
119 v4l_dbg(1, debug, client,
120 "TDA9840_DETECT: register contents invalid\n");
80 return -EINVAL; 121 return -EINVAL;
81 } 122 }
82 123
83 tda9840_write(client, SWITCH, byte); 124 v4l_dbg(1, debug, client, "TDA9840_DETECT: byte: 0x%02x\n", byte);
125
126 switch (byte & 0x60) {
127 case 0x00:
128 t->rxsubchans = V4L2_TUNER_SUB_MONO;
129 break;
130 case 0x20:
131 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
132 break;
133 case 0x40:
134 t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
135 break;
136 default: /* Incorrect detect */
137 t->rxsubchans = V4L2_TUNER_MODE_MONO;
138 break;
139 }
84 break; 140 break;
141 }
85 142
86 case TDA9840_LEVEL_ADJUST: 143 case TDA9840_LEVEL_ADJUST:
87 v4l_dbg(1, debug, client, "TDA9840_LEVEL_ADJUST: %d\n", byte); 144 v4l_dbg(1, debug, client, "TDA9840_LEVEL_ADJUST: %d\n", byte);
@@ -115,36 +172,6 @@ static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg)
115 172
116 tda9840_write(client, STEREO_ADJUST, byte); 173 tda9840_write(client, STEREO_ADJUST, byte);
117 break; 174 break;
118
119 case TDA9840_DETECT: {
120 int *ret = (int *)arg;
121
122 byte = i2c_smbus_read_byte_data(client, STEREO_ADJUST);
123 if (byte == -1) {
124 v4l_dbg(1, debug, client,
125 "i2c_smbus_read_byte_data() failed\n");
126 return -EIO;
127 }
128
129 if (byte & 0x80) {
130 v4l_dbg(1, debug, client,
131 "TDA9840_DETECT: register contents invalid\n");
132 return -EINVAL;
133 }
134
135 v4l_dbg(1, debug, client, "TDA9840_DETECT: byte: 0x%02x\n", byte);
136 *ret = (byte & 0x60) >> 5;
137 result = 0;
138 break;
139 }
140 case TDA9840_TEST:
141 v4l_dbg(1, debug, client, "TDA9840_TEST: 0x%02x\n", byte);
142
143 /* mask out irrelevant bits */
144 byte &= 0x3;
145
146 tda9840_write(client, TEST, byte);
147 break;
148 default: 175 default:
149 return -ENOIOCTLCMD; 176 return -ENOIOCTLCMD;
150 } 177 }
@@ -174,8 +201,7 @@ static int tda9840_probe(struct i2c_client *client,
174 byte = 0; 201 byte = 0;
175 result = tda9840_command(client, TDA9840_LEVEL_ADJUST, &byte); 202 result = tda9840_command(client, TDA9840_LEVEL_ADJUST, &byte);
176 result += tda9840_command(client, TDA9840_STEREO_ADJUST, &byte); 203 result += tda9840_command(client, TDA9840_STEREO_ADJUST, &byte);
177 byte = TDA9840_SET_MONO; 204 tda9840_write(client, SWITCH, TDA9840_SET_STEREO);
178 result = tda9840_command(client, TDA9840_SWITCH, &byte);
179 if (result) { 205 if (result) {
180 v4l_dbg(1, debug, client, "could not initialize tda9840\n"); 206 v4l_dbg(1, debug, client, "could not initialize tda9840\n");
181 return -ENODEV; 207 return -ENODEV;