diff options
Diffstat (limited to 'drivers/media/video/msp3400.c')
-rw-r--r-- | drivers/media/video/msp3400.c | 962 |
1 files changed, 662 insertions, 300 deletions
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index e75e7948fd9d..a23fb0338986 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c | |||
@@ -54,9 +54,41 @@ | |||
54 | #include <asm/pgtable.h> | 54 | #include <asm/pgtable.h> |
55 | 55 | ||
56 | #include <media/audiochip.h> | 56 | #include <media/audiochip.h> |
57 | #include <media/id.h> | ||
58 | #include "msp3400.h" | 57 | #include "msp3400.h" |
59 | 58 | ||
59 | #define msp3400_dbg(fmt, arg...) \ | ||
60 | do { \ | ||
61 | if (debug) \ | ||
62 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | ||
63 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
64 | } while (0) | ||
65 | |||
66 | /* Medium volume debug. */ | ||
67 | #define msp3400_dbg_mediumvol(fmt, arg...) \ | ||
68 | do { \ | ||
69 | if (debug >= 2) \ | ||
70 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | ||
71 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
72 | } while (0) | ||
73 | |||
74 | /* High volume debug. Use with care. */ | ||
75 | #define msp3400_dbg_highvol(fmt, arg...) \ | ||
76 | do { \ | ||
77 | if (debug >= 16) \ | ||
78 | printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \ | ||
79 | i2c_adapter_id(client->adapter), client->addr , ## arg); \ | ||
80 | } while (0) | ||
81 | |||
82 | #define msp3400_err(fmt, arg...) do { \ | ||
83 | printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \ | ||
84 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
85 | #define msp3400_warn(fmt, arg...) do { \ | ||
86 | printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->name, \ | ||
87 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
88 | #define msp3400_info(fmt, arg...) do { \ | ||
89 | printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \ | ||
90 | i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) | ||
91 | |||
60 | #define OPMODE_AUTO -1 | 92 | #define OPMODE_AUTO -1 |
61 | #define OPMODE_MANUAL 0 | 93 | #define OPMODE_MANUAL 0 |
62 | #define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */ | 94 | #define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */ |
@@ -73,15 +105,26 @@ static int dolby = 0; | |||
73 | 105 | ||
74 | static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual | 106 | static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual |
75 | (msp34xxg only) 0x00a0-0x03c0 */ | 107 | (msp34xxg only) 0x00a0-0x03c0 */ |
108 | #define DFP_COUNT 0x41 | ||
109 | static const int bl_dfp[] = { | ||
110 | 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a, | ||
111 | 0x0b, 0x0d, 0x0e, 0x10 | ||
112 | }; | ||
113 | |||
114 | #define IS_MSP34XX_G(msp) ((msp)->opmode==2) | ||
76 | 115 | ||
77 | struct msp3400c { | 116 | struct msp3400c { |
78 | int rev1,rev2; | 117 | int rev1,rev2; |
79 | 118 | ||
80 | int opmode; | 119 | int opmode; |
120 | int nicam; | ||
81 | int mode; | 121 | int mode; |
82 | int norm; | 122 | int norm; |
123 | int stereo; | ||
83 | int nicam_on; | 124 | int nicam_on; |
84 | int acb; | 125 | int acb; |
126 | int in_scart; | ||
127 | int i2s_mode; | ||
85 | int main, second; /* sound carrier */ | 128 | int main, second; /* sound carrier */ |
86 | int input; | 129 | int input; |
87 | int source; /* see msp34xxg_set_source */ | 130 | int source; /* see msp34xxg_set_source */ |
@@ -91,9 +134,12 @@ struct msp3400c { | |||
91 | int rxsubchans; | 134 | int rxsubchans; |
92 | 135 | ||
93 | int muted; | 136 | int muted; |
94 | int volume, balance; | 137 | int left, right; /* volume */ |
95 | int bass, treble; | 138 | int bass, treble; |
96 | 139 | ||
140 | /* shadow register set */ | ||
141 | int dfp_regs[DFP_COUNT]; | ||
142 | |||
97 | /* thread */ | 143 | /* thread */ |
98 | struct task_struct *kthread; | 144 | struct task_struct *kthread; |
99 | wait_queue_head_t wq; | 145 | wait_queue_head_t wq; |
@@ -101,6 +147,8 @@ struct msp3400c { | |||
101 | int watch_stereo:1; | 147 | int watch_stereo:1; |
102 | }; | 148 | }; |
103 | 149 | ||
150 | #define MIN(a,b) (((a)>(b))?(b):(a)) | ||
151 | #define MAX(a,b) (((a)>(b))?(a):(b)) | ||
104 | #define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00) | 152 | #define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00) |
105 | #define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@') | 153 | #define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@') |
106 | #define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@') | 154 | #define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@') |
@@ -110,9 +158,6 @@ struct msp3400c { | |||
110 | 158 | ||
111 | /* ---------------------------------------------------------------------- */ | 159 | /* ---------------------------------------------------------------------- */ |
112 | 160 | ||
113 | #define dprintk if (debug >= 1) printk | ||
114 | #define d2printk if (debug >= 2) printk | ||
115 | |||
116 | /* read-only */ | 161 | /* read-only */ |
117 | module_param(opmode, int, 0444); | 162 | module_param(opmode, int, 0444); |
118 | 163 | ||
@@ -132,11 +177,6 @@ MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Defau | |||
132 | MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); | 177 | MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); |
133 | MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); | 178 | MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); |
134 | 179 | ||
135 | |||
136 | MODULE_DESCRIPTION("device driver for msp34xx TV sound processor"); | ||
137 | MODULE_AUTHOR("Gerd Knorr"); | ||
138 | MODULE_LICENSE("Dual BSD/GPL"); /* FreeBSD uses this too */ | ||
139 | |||
140 | /* ---------------------------------------------------------------------- */ | 180 | /* ---------------------------------------------------------------------- */ |
141 | 181 | ||
142 | #define I2C_MSP3400C 0x80 | 182 | #define I2C_MSP3400C 0x80 |
@@ -153,6 +193,10 @@ static unsigned short normal_i2c[] = { | |||
153 | }; | 193 | }; |
154 | I2C_CLIENT_INSMOD; | 194 | I2C_CLIENT_INSMOD; |
155 | 195 | ||
196 | MODULE_DESCRIPTION("device driver for msp34xx TV sound processor"); | ||
197 | MODULE_AUTHOR("Gerd Knorr"); | ||
198 | MODULE_LICENSE("GPL"); | ||
199 | |||
156 | /* ----------------------------------------------------------------------- */ | 200 | /* ----------------------------------------------------------------------- */ |
157 | /* functions for talking to the MSP3400C Sound processor */ | 201 | /* functions for talking to the MSP3400C Sound processor */ |
158 | 202 | ||
@@ -172,68 +216,73 @@ static int msp3400c_reset(struct i2c_client *client) | |||
172 | { client->addr, I2C_M_RD, 2, read }, | 216 | { client->addr, I2C_M_RD, 2, read }, |
173 | }; | 217 | }; |
174 | 218 | ||
219 | msp3400_dbg_highvol("msp3400c_reset\n"); | ||
175 | if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) || | 220 | if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) || |
176 | (1 != i2c_transfer(client->adapter,&reset[1],1)) || | 221 | (1 != i2c_transfer(client->adapter,&reset[1],1)) || |
177 | (2 != i2c_transfer(client->adapter,test,2)) ) { | 222 | (2 != i2c_transfer(client->adapter,test,2)) ) { |
178 | printk(KERN_ERR "msp3400: chip reset failed\n"); | 223 | msp3400_err("chip reset failed\n"); |
179 | return -1; | 224 | return -1; |
180 | } | 225 | } |
181 | return 0; | 226 | return 0; |
182 | } | 227 | } |
183 | 228 | ||
184 | static int | 229 | static int msp3400c_read(struct i2c_client *client, int dev, int addr) |
185 | msp3400c_read(struct i2c_client *client, int dev, int addr) | ||
186 | { | 230 | { |
187 | int err; | 231 | int err,retval; |
232 | |||
233 | unsigned char write[3]; | ||
234 | unsigned char read[2]; | ||
235 | struct i2c_msg msgs[2] = { | ||
236 | { client->addr, 0, 3, write }, | ||
237 | { client->addr, I2C_M_RD, 2, read } | ||
238 | }; | ||
188 | 239 | ||
189 | unsigned char write[3]; | 240 | write[0] = dev+1; |
190 | unsigned char read[2]; | 241 | write[1] = addr >> 8; |
191 | struct i2c_msg msgs[2] = { | 242 | write[2] = addr & 0xff; |
192 | { client->addr, 0, 3, write }, | ||
193 | { client->addr, I2C_M_RD, 2, read } | ||
194 | }; | ||
195 | write[0] = dev+1; | ||
196 | write[1] = addr >> 8; | ||
197 | write[2] = addr & 0xff; | ||
198 | 243 | ||
199 | for (err = 0; err < 3;) { | 244 | for (err = 0; err < 3;) { |
200 | if (2 == i2c_transfer(client->adapter,msgs,2)) | 245 | if (2 == i2c_transfer(client->adapter,msgs,2)) |
201 | break; | 246 | break; |
202 | err++; | 247 | err++; |
203 | printk(KERN_WARNING "msp34xx: I/O error #%d (read 0x%02x/0x%02x)\n", | 248 | msp3400_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err, |
204 | err, dev, addr); | 249 | dev, addr); |
205 | msleep(10); | 250 | current->state = TASK_INTERRUPTIBLE; |
251 | schedule_timeout(msecs_to_jiffies(10)); | ||
206 | } | 252 | } |
207 | if (3 == err) { | 253 | if (3 == err) { |
208 | printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n"); | 254 | msp3400_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n"); |
209 | msp3400c_reset(client); | 255 | msp3400c_reset(client); |
210 | return -1; | 256 | return -1; |
211 | } | 257 | } |
212 | return read[0] << 8 | read[1]; | 258 | retval = read[0] << 8 | read[1]; |
259 | msp3400_dbg_highvol("msp3400c_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval); | ||
260 | return retval; | ||
213 | } | 261 | } |
214 | 262 | ||
215 | static int | 263 | static int msp3400c_write(struct i2c_client *client, int dev, int addr, int val) |
216 | msp3400c_write(struct i2c_client *client, int dev, int addr, int val) | ||
217 | { | 264 | { |
218 | int err; | 265 | int err; |
219 | unsigned char buffer[5]; | 266 | unsigned char buffer[5]; |
220 | 267 | ||
221 | buffer[0] = dev; | 268 | buffer[0] = dev; |
222 | buffer[1] = addr >> 8; | 269 | buffer[1] = addr >> 8; |
223 | buffer[2] = addr & 0xff; | 270 | buffer[2] = addr & 0xff; |
224 | buffer[3] = val >> 8; | 271 | buffer[3] = val >> 8; |
225 | buffer[4] = val & 0xff; | 272 | buffer[4] = val & 0xff; |
226 | 273 | ||
274 | msp3400_dbg_highvol("msp3400c_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val); | ||
227 | for (err = 0; err < 3;) { | 275 | for (err = 0; err < 3;) { |
228 | if (5 == i2c_master_send(client, buffer, 5)) | 276 | if (5 == i2c_master_send(client, buffer, 5)) |
229 | break; | 277 | break; |
230 | err++; | 278 | err++; |
231 | printk(KERN_WARNING "msp34xx: I/O error #%d (write 0x%02x/0x%02x)\n", | 279 | msp3400_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err, |
232 | err, dev, addr); | 280 | dev, addr); |
233 | msleep(10); | 281 | current->state = TASK_INTERRUPTIBLE; |
282 | schedule_timeout(msecs_to_jiffies(10)); | ||
234 | } | 283 | } |
235 | if (3 == err) { | 284 | if (3 == err) { |
236 | printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n"); | 285 | msp3400_warn("giving up, reseting chip. Sound will go off, sorry folks :-|\n"); |
237 | msp3400c_reset(client); | 286 | msp3400c_reset(client); |
238 | return -1; | 287 | return -1; |
239 | } | 288 | } |
@@ -266,45 +315,47 @@ static struct MSP_INIT_DATA_DEM { | |||
266 | int dfp_src; | 315 | int dfp_src; |
267 | int dfp_matrix; | 316 | int dfp_matrix; |
268 | } msp_init_data[] = { | 317 | } msp_init_data[] = { |
269 | /* AM (for carrier detect / msp3400) */ | 318 | { /* AM (for carrier detect / msp3400) */ |
270 | { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 }, | 319 | {75, 19, 36, 35, 39, 40}, |
271 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | 320 | {75, 19, 36, 35, 39, 40}, |
272 | 0x00d0, 0x0500, 0x0020, 0x3000}, | 321 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), |
273 | 322 | 0x00d0, 0x0500, 0x0020, 0x3000 | |
274 | /* AM (for carrier detect / msp3410) */ | 323 | },{ /* AM (for carrier detect / msp3410) */ |
275 | { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 }, | 324 | {-1, -1, -8, 2, 59, 126}, |
276 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | 325 | {-1, -1, -8, 2, 59, 126}, |
277 | 0x00d0, 0x0100, 0x0020, 0x3000}, | 326 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), |
278 | 327 | 0x00d0, 0x0100, 0x0020, 0x3000 | |
279 | /* FM Radio */ | 328 | },{ /* FM Radio */ |
280 | { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 }, | 329 | {-8, -8, 4, 6, 78, 107}, |
281 | MSP_CARRIER(10.7), MSP_CARRIER(10.7), | 330 | {-8, -8, 4, 6, 78, 107}, |
282 | 0x00d0, 0x0480, 0x0020, 0x3000 }, | 331 | MSP_CARRIER(10.7), MSP_CARRIER(10.7), |
283 | 332 | 0x00d0, 0x0480, 0x0020, 0x3000 | |
284 | /* Terrestial FM-mono + FM-stereo */ | 333 | },{ /* Terrestial FM-mono + FM-stereo */ |
285 | { { 3, 18, 27, 48, 66, 72 }, { 3, 18, 27, 48, 66, 72 }, | 334 | {3, 18, 27, 48, 66, 72}, |
286 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | 335 | {3, 18, 27, 48, 66, 72}, |
287 | 0x00d0, 0x0480, 0x0030, 0x3000}, | 336 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), |
288 | 337 | 0x00d0, 0x0480, 0x0030, 0x3000 | |
289 | /* Sat FM-mono */ | 338 | },{ /* Sat FM-mono */ |
290 | { { 1, 9, 14, 24, 33, 37 }, { 3, 18, 27, 48, 66, 72 }, | 339 | { 1, 9, 14, 24, 33, 37}, |
291 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), | 340 | { 3, 18, 27, 48, 66, 72}, |
292 | 0x00c6, 0x0480, 0x0000, 0x3000}, | 341 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), |
293 | 342 | 0x00c6, 0x0480, 0x0000, 0x3000 | |
294 | /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */ | 343 | },{ /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */ |
295 | { { -2, -8, -10, 10, 50, 86 }, { 3, 18, 27, 48, 66, 72 }, | 344 | {-2, -8, -10, 10, 50, 86}, |
296 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), | 345 | {3, 18, 27, 48, 66, 72}, |
297 | 0x00d0, 0x0040, 0x0120, 0x3000}, | 346 | MSP_CARRIER(5.5), MSP_CARRIER(5.5), |
298 | 347 | 0x00d0, 0x0040, 0x0120, 0x3000 | |
299 | /* NICAM/FM -- I (6.0/6.552) */ | 348 | },{ /* NICAM/FM -- I (6.0/6.552) */ |
300 | { { 2, 4, -6, -4, 40, 94 }, { 3, 18, 27, 48, 66, 72 }, | 349 | {2, 4, -6, -4, 40, 94}, |
301 | MSP_CARRIER(6.0), MSP_CARRIER(6.0), | 350 | {3, 18, 27, 48, 66, 72}, |
302 | 0x00d0, 0x0040, 0x0120, 0x3000}, | 351 | MSP_CARRIER(6.0), MSP_CARRIER(6.0), |
303 | 352 | 0x00d0, 0x0040, 0x0120, 0x3000 | |
304 | /* NICAM/AM -- L (6.5/5.85) */ | 353 | },{ /* NICAM/AM -- L (6.5/5.85) */ |
305 | { { -2, -8, -10, 10, 50, 86 }, { -4, -12, -9, 23, 79, 126 }, | 354 | {-2, -8, -10, 10, 50, 86}, |
306 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), | 355 | {-4, -12, -9, 23, 79, 126}, |
307 | 0x00c6, 0x0140, 0x0120, 0x7c03}, | 356 | MSP_CARRIER(6.5), MSP_CARRIER(6.5), |
357 | 0x00c6, 0x0140, 0x0120, 0x7c03 | ||
358 | }, | ||
308 | }; | 359 | }; |
309 | 360 | ||
310 | struct CARRIER_DETECT { | 361 | struct CARRIER_DETECT { |
@@ -338,32 +389,68 @@ static struct CARRIER_DETECT carrier_detect_65[] = { | |||
338 | 389 | ||
339 | #define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT)) | 390 | #define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT)) |
340 | 391 | ||
341 | /* ----------------------------------------------------------------------- */ | 392 | /* ----------------------------------------------------------------------- * |
393 | * bits 9 8 5 - SCART DSP input Select: | ||
394 | * 0 0 0 - SCART 1 to DSP input (reset position) | ||
395 | * 0 1 0 - MONO to DSP input | ||
396 | * 1 0 0 - SCART 2 to DSP input | ||
397 | * 1 1 1 - Mute DSP input | ||
398 | * | ||
399 | * bits 11 10 6 - SCART 1 Output Select: | ||
400 | * 0 0 0 - undefined (reset position) | ||
401 | * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS) | ||
402 | * 1 0 0 - MONO input to SCART 1 Output | ||
403 | * 1 1 0 - SCART 1 DA to SCART 1 Output | ||
404 | * 0 0 1 - SCART 2 DA to SCART 1 Output | ||
405 | * 0 1 1 - SCART 1 Input to SCART 1 Output | ||
406 | * 1 1 1 - Mute SCART 1 Output | ||
407 | * | ||
408 | * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART): | ||
409 | * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position) | ||
410 | * 0 1 0 - SCART 1 Input to SCART 2 Output | ||
411 | * 1 0 0 - MONO input to SCART 2 Output | ||
412 | * 0 0 1 - SCART 2 DA to SCART 2 Output | ||
413 | * 0 1 1 - SCART 2 Input to SCART 2 Output | ||
414 | * 1 1 0 - Mute SCART 2 Output | ||
415 | * | ||
416 | * Bits 4 to 0 should be zero. | ||
417 | * ----------------------------------------------------------------------- */ | ||
342 | 418 | ||
343 | static int scarts[3][9] = { | 419 | static int scarts[3][9] = { |
344 | /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ | 420 | /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ |
345 | { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, | 421 | /* SCART DSP Input select */ |
346 | { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, | 422 | { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, |
347 | { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, | 423 | /* SCART1 Output select */ |
424 | { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, | ||
425 | /* SCART2 Output select */ | ||
426 | { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, | ||
348 | }; | 427 | }; |
349 | 428 | ||
350 | static char *scart_names[] = { | 429 | static char *scart_names[] = { |
351 | "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" | 430 | "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" |
352 | }; | 431 | }; |
353 | 432 | ||
354 | static void | 433 | static void msp3400c_set_scart(struct i2c_client *client, int in, int out) |
355 | msp3400c_set_scart(struct i2c_client *client, int in, int out) | ||
356 | { | 434 | { |
357 | struct msp3400c *msp = i2c_get_clientdata(client); | 435 | struct msp3400c *msp = i2c_get_clientdata(client); |
358 | 436 | ||
359 | if (-1 == scarts[out][in]) | 437 | msp->in_scart=in; |
360 | return; | 438 | |
439 | if (in >= 1 && in <= 8 && out >= 0 && out <= 2) { | ||
440 | if (-1 == scarts[out][in]) | ||
441 | return; | ||
361 | 442 | ||
362 | dprintk(KERN_DEBUG | 443 | msp->acb &= ~scarts[out][SCART_MASK]; |
363 | "msp34xx: scart switch: %s => %d\n",scart_names[in],out); | 444 | msp->acb |= scarts[out][in]; |
364 | msp->acb &= ~scarts[out][SCART_MASK]; | 445 | } else |
365 | msp->acb |= scarts[out][in]; | 446 | msp->acb = 0xf60; /* Mute Input and SCART 1 Output */ |
366 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb); | 447 | |
448 | msp3400_dbg("scart switch: %s => %d (ACB=0x%04x)\n", | ||
449 | scart_names[in], out, msp->acb); | ||
450 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb); | ||
451 | |||
452 | /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */ | ||
453 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); | ||
367 | } | 454 | } |
368 | 455 | ||
369 | /* ------------------------------------------------------------------------ */ | 456 | /* ------------------------------------------------------------------------ */ |
@@ -378,33 +465,34 @@ static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2) | |||
378 | } | 465 | } |
379 | 466 | ||
380 | static void msp3400c_setvolume(struct i2c_client *client, | 467 | static void msp3400c_setvolume(struct i2c_client *client, |
381 | int muted, int volume, int balance) | 468 | int muted, int left, int right) |
382 | { | 469 | { |
383 | int val = 0, bal = 0; | 470 | int vol = 0, val = 0, balance = 0; |
384 | 471 | ||
385 | if (!muted) { | 472 | if (!muted) { |
386 | /* 0x7f instead if 0x73 here has sound quality issues, | 473 | /* 0x7f instead if 0x73 here has sound quality issues, |
387 | * probably due to overmodulation + clipping ... */ | 474 | * probably due to overmodulation + clipping ... */ |
388 | val = (volume * 0x73 / 65535) << 8; | 475 | vol = (left > right) ? left : right; |
476 | val = (vol * 0x73 / 65535) << 8; | ||
389 | } | 477 | } |
390 | if (val) { | 478 | if (vol > 0) { |
391 | bal = (balance / 256) - 128; | 479 | balance = ((right - left) * 127) / vol; |
392 | } | 480 | } |
393 | dprintk(KERN_DEBUG | 481 | |
394 | "msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", | 482 | msp3400_dbg("setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", |
395 | muted ? "on" : "off", volume, balance, val>>8, bal); | 483 | muted ? "on" : "off", left, right, val >> 8, balance); |
396 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ | 484 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ |
397 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ | 485 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ |
398 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, | 486 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, |
399 | muted ? 0x01 : (val | 0x01)); | 487 | muted ? 0x1 : (val | 0x1)); |
400 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, bal << 8); | 488 | msp3400c_write(client, I2C_MSP3400C_DFP, 0x0001, balance << 8); |
401 | } | 489 | } |
402 | 490 | ||
403 | static void msp3400c_setbass(struct i2c_client *client, int bass) | 491 | static void msp3400c_setbass(struct i2c_client *client, int bass) |
404 | { | 492 | { |
405 | int val = ((bass-32768) * 0x60 / 65535) << 8; | 493 | int val = ((bass-32768) * 0x60 / 65535) << 8; |
406 | 494 | ||
407 | dprintk(KERN_DEBUG "msp34xx: setbass: %d 0x%02x\n",bass, val>>8); | 495 | msp3400_dbg("setbass: %d 0x%02x\n", bass, val >> 8); |
408 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ | 496 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ |
409 | } | 497 | } |
410 | 498 | ||
@@ -412,7 +500,7 @@ static void msp3400c_settreble(struct i2c_client *client, int treble) | |||
412 | { | 500 | { |
413 | int val = ((treble-32768) * 0x60 / 65535) << 8; | 501 | int val = ((treble-32768) * 0x60 / 65535) << 8; |
414 | 502 | ||
415 | dprintk(KERN_DEBUG "msp34xx: settreble: %d 0x%02x\n",treble, val>>8); | 503 | msp3400_dbg("settreble: %d 0x%02x\n",treble, val>>8); |
416 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ | 504 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ |
417 | } | 505 | } |
418 | 506 | ||
@@ -421,7 +509,7 @@ static void msp3400c_setmode(struct i2c_client *client, int type) | |||
421 | struct msp3400c *msp = i2c_get_clientdata(client); | 509 | struct msp3400c *msp = i2c_get_clientdata(client); |
422 | int i; | 510 | int i; |
423 | 511 | ||
424 | dprintk(KERN_DEBUG "msp3400: setmode: %d\n",type); | 512 | msp3400_dbg("setmode: %d\n",type); |
425 | msp->mode = type; | 513 | msp->mode = type; |
426 | msp->audmode = V4L2_TUNER_MODE_MONO; | 514 | msp->audmode = V4L2_TUNER_MODE_MONO; |
427 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; | 515 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; |
@@ -474,7 +562,8 @@ static void msp3400c_setmode(struct i2c_client *client, int type) | |||
474 | } | 562 | } |
475 | } | 563 | } |
476 | 564 | ||
477 | static int best_audio_mode(int rxsubchans) | 565 | /* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */ |
566 | static int best_video_sound(int rxsubchans) | ||
478 | { | 567 | { |
479 | if (rxsubchans & V4L2_TUNER_SUB_STEREO) | 568 | if (rxsubchans & V4L2_TUNER_SUB_STEREO) |
480 | return V4L2_TUNER_MODE_STEREO; | 569 | return V4L2_TUNER_MODE_STEREO; |
@@ -486,31 +575,31 @@ static int best_audio_mode(int rxsubchans) | |||
486 | } | 575 | } |
487 | 576 | ||
488 | /* turn on/off nicam + stereo */ | 577 | /* turn on/off nicam + stereo */ |
489 | static void msp3400c_set_audmode(struct i2c_client *client, int audmode) | 578 | static void msp3400c_setstereo(struct i2c_client *client, int mode) |
490 | { | 579 | { |
491 | static char *strmode[16] = { | 580 | static char *strmode[] = { "0", "mono", "stereo", "3", |
492 | #if __GNUC__ >= 3 | 581 | "lang1", "5", "6", "7", "lang2" |
493 | [ 0 ... 15 ] = "invalid", | ||
494 | #endif | ||
495 | [ V4L2_TUNER_MODE_MONO ] = "mono", | ||
496 | [ V4L2_TUNER_MODE_STEREO ] = "stereo", | ||
497 | [ V4L2_TUNER_MODE_LANG1 ] = "lang1", | ||
498 | [ V4L2_TUNER_MODE_LANG2 ] = "lang2", | ||
499 | }; | 582 | }; |
500 | struct msp3400c *msp = i2c_get_clientdata(client); | 583 | struct msp3400c *msp = i2c_get_clientdata(client); |
501 | int nicam=0; /* channel source: FM/AM or nicam */ | 584 | int nicam = 0; /* channel source: FM/AM or nicam */ |
502 | int src=0; | 585 | int src = 0; |
503 | 586 | ||
504 | BUG_ON(msp->opmode == OPMODE_SIMPLER); | 587 | if (IS_MSP34XX_G(msp)) { |
505 | msp->audmode = audmode; | 588 | /* this method would break everything, let's make sure |
589 | * it's never called | ||
590 | */ | ||
591 | msp3400_dbg | ||
592 | ("DEBUG WARNING setstereo called with mode=%d instead of set_source (ignored)\n", | ||
593 | mode); | ||
594 | return; | ||
595 | } | ||
506 | 596 | ||
507 | /* switch demodulator */ | 597 | /* switch demodulator */ |
508 | switch (msp->mode) { | 598 | switch (msp->mode) { |
509 | case MSP_MODE_FM_TERRA: | 599 | case MSP_MODE_FM_TERRA: |
510 | dprintk(KERN_DEBUG "msp3400: FM setstereo: %s\n", | 600 | msp3400_dbg("FM setstereo: %s\n", strmode[mode]); |
511 | strmode[audmode]); | ||
512 | msp3400c_setcarrier(client,msp->second,msp->main); | 601 | msp3400c_setcarrier(client,msp->second,msp->main); |
513 | switch (audmode) { | 602 | switch (mode) { |
514 | case V4L2_TUNER_MODE_STEREO: | 603 | case V4L2_TUNER_MODE_STEREO: |
515 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001); | 604 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001); |
516 | break; | 605 | break; |
@@ -522,9 +611,8 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode) | |||
522 | } | 611 | } |
523 | break; | 612 | break; |
524 | case MSP_MODE_FM_SAT: | 613 | case MSP_MODE_FM_SAT: |
525 | dprintk(KERN_DEBUG "msp3400: SAT setstereo: %s\n", | 614 | msp3400_dbg("SAT setstereo: %s\n", strmode[mode]); |
526 | strmode[audmode]); | 615 | switch (mode) { |
527 | switch (audmode) { | ||
528 | case V4L2_TUNER_MODE_MONO: | 616 | case V4L2_TUNER_MODE_MONO: |
529 | msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); | 617 | msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); |
530 | break; | 618 | break; |
@@ -542,39 +630,35 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode) | |||
542 | case MSP_MODE_FM_NICAM1: | 630 | case MSP_MODE_FM_NICAM1: |
543 | case MSP_MODE_FM_NICAM2: | 631 | case MSP_MODE_FM_NICAM2: |
544 | case MSP_MODE_AM_NICAM: | 632 | case MSP_MODE_AM_NICAM: |
545 | dprintk(KERN_DEBUG "msp3400: NICAM setstereo: %s\n", | 633 | msp3400_dbg("NICAM setstereo: %s\n",strmode[mode]); |
546 | strmode[audmode]); | ||
547 | msp3400c_setcarrier(client,msp->second,msp->main); | 634 | msp3400c_setcarrier(client,msp->second,msp->main); |
548 | if (msp->nicam_on) | 635 | if (msp->nicam_on) |
549 | nicam=0x0100; | 636 | nicam=0x0100; |
550 | break; | 637 | break; |
551 | case MSP_MODE_BTSC: | 638 | case MSP_MODE_BTSC: |
552 | dprintk(KERN_DEBUG "msp3400: BTSC setstereo: %s\n", | 639 | msp3400_dbg("BTSC setstereo: %s\n",strmode[mode]); |
553 | strmode[audmode]); | ||
554 | nicam=0x0300; | 640 | nicam=0x0300; |
555 | break; | 641 | break; |
556 | case MSP_MODE_EXTERN: | 642 | case MSP_MODE_EXTERN: |
557 | dprintk(KERN_DEBUG "msp3400: extern setstereo: %s\n", | 643 | msp3400_dbg("extern setstereo: %s\n",strmode[mode]); |
558 | strmode[audmode]); | ||
559 | nicam = 0x0200; | 644 | nicam = 0x0200; |
560 | break; | 645 | break; |
561 | case MSP_MODE_FM_RADIO: | 646 | case MSP_MODE_FM_RADIO: |
562 | dprintk(KERN_DEBUG "msp3400: FM-Radio setstereo: %s\n", | 647 | msp3400_dbg("FM-Radio setstereo: %s\n",strmode[mode]); |
563 | strmode[audmode]); | ||
564 | break; | 648 | break; |
565 | default: | 649 | default: |
566 | dprintk(KERN_DEBUG "msp3400: mono setstereo\n"); | 650 | msp3400_dbg("mono setstereo\n"); |
567 | return; | 651 | return; |
568 | } | 652 | } |
569 | 653 | ||
570 | /* switch audio */ | 654 | /* switch audio */ |
571 | switch (audmode) { | 655 | switch (best_video_sound(mode)) { |
572 | case V4L2_TUNER_MODE_STEREO: | 656 | case V4L2_TUNER_MODE_STEREO: |
573 | src = 0x0020 | nicam; | 657 | src = 0x0020 | nicam; |
574 | break; | 658 | break; |
575 | case V4L2_TUNER_MODE_MONO: | 659 | case V4L2_TUNER_MODE_MONO: |
576 | if (msp->mode == MSP_MODE_AM_NICAM) { | 660 | if (msp->mode == MSP_MODE_AM_NICAM) { |
577 | dprintk("msp3400: switching to AM mono\n"); | 661 | msp3400_dbg("switching to AM mono\n"); |
578 | /* AM mono decoding is handled by tuner, not MSP chip */ | 662 | /* AM mono decoding is handled by tuner, not MSP chip */ |
579 | /* SCART switching control register */ | 663 | /* SCART switching control register */ |
580 | msp3400c_set_scart(client,SCART_MONO,0); | 664 | msp3400c_set_scart(client,SCART_MONO,0); |
@@ -588,8 +672,7 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode) | |||
588 | src = 0x0010 | nicam; | 672 | src = 0x0010 | nicam; |
589 | break; | 673 | break; |
590 | } | 674 | } |
591 | dprintk(KERN_DEBUG | 675 | msp3400_dbg("setstereo final source/matrix = 0x%x\n", src); |
592 | "msp3400: setstereo final source/matrix = 0x%x\n", src); | ||
593 | 676 | ||
594 | if (dolby) { | 677 | if (dolby) { |
595 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); | 678 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); |
@@ -605,29 +688,55 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode) | |||
605 | } | 688 | } |
606 | 689 | ||
607 | static void | 690 | static void |
608 | msp3400c_print_mode(struct msp3400c *msp) | 691 | msp3400c_print_mode(struct i2c_client *client) |
609 | { | 692 | { |
693 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
694 | |||
610 | if (msp->main == msp->second) { | 695 | if (msp->main == msp->second) { |
611 | printk(KERN_DEBUG "msp3400: mono sound carrier: %d.%03d MHz\n", | 696 | msp3400_dbg("mono sound carrier: %d.%03d MHz\n", |
612 | msp->main/910000,(msp->main/910)%1000); | 697 | msp->main/910000,(msp->main/910)%1000); |
613 | } else { | 698 | } else { |
614 | printk(KERN_DEBUG "msp3400: main sound carrier: %d.%03d MHz\n", | 699 | msp3400_dbg("main sound carrier: %d.%03d MHz\n", |
615 | msp->main/910000,(msp->main/910)%1000); | 700 | msp->main/910000,(msp->main/910)%1000); |
616 | } | 701 | } |
617 | if (msp->mode == MSP_MODE_FM_NICAM1 || | 702 | if (msp->mode == MSP_MODE_FM_NICAM1 || msp->mode == MSP_MODE_FM_NICAM2) |
618 | msp->mode == MSP_MODE_FM_NICAM2) | 703 | msp3400_dbg("NICAM/FM carrier : %d.%03d MHz\n", |
619 | printk(KERN_DEBUG "msp3400: NICAM/FM carrier : %d.%03d MHz\n", | ||
620 | msp->second/910000,(msp->second/910)%1000); | 704 | msp->second/910000,(msp->second/910)%1000); |
621 | if (msp->mode == MSP_MODE_AM_NICAM) | 705 | if (msp->mode == MSP_MODE_AM_NICAM) |
622 | printk(KERN_DEBUG "msp3400: NICAM/AM carrier : %d.%03d MHz\n", | 706 | msp3400_dbg("NICAM/AM carrier : %d.%03d MHz\n", |
623 | msp->second/910000,(msp->second/910)%1000); | 707 | msp->second/910000,(msp->second/910)%1000); |
624 | if (msp->mode == MSP_MODE_FM_TERRA && | 708 | if (msp->mode == MSP_MODE_FM_TERRA && |
625 | msp->main != msp->second) { | 709 | msp->main != msp->second) { |
626 | printk(KERN_DEBUG "msp3400: FM-stereo carrier : %d.%03d MHz\n", | 710 | msp3400_dbg("FM-stereo carrier : %d.%03d MHz\n", |
627 | msp->second/910000,(msp->second/910)%1000); | 711 | msp->second/910000,(msp->second/910)%1000); |
628 | } | 712 | } |
629 | } | 713 | } |
630 | 714 | ||
715 | #define MSP3400_MAX 4 | ||
716 | static struct i2c_client *msps[MSP3400_MAX]; | ||
717 | static void msp3400c_restore_dfp(struct i2c_client *client) | ||
718 | { | ||
719 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
720 | int i; | ||
721 | |||
722 | for (i = 0; i < DFP_COUNT; i++) { | ||
723 | if (-1 == msp->dfp_regs[i]) | ||
724 | continue; | ||
725 | msp3400c_write(client, I2C_MSP3400C_DFP, i, msp->dfp_regs[i]); | ||
726 | } | ||
727 | } | ||
728 | |||
729 | /* if the dfp_regs is set, set what's in there. Otherwise, set the default value */ | ||
730 | static int msp3400c_write_dfp_with_default(struct i2c_client *client, | ||
731 | int addr, int default_value) | ||
732 | { | ||
733 | struct msp3400c *msp = i2c_get_clientdata(client); | ||
734 | int value = default_value; | ||
735 | if (addr < DFP_COUNT && -1 != msp->dfp_regs[addr]) | ||
736 | value = msp->dfp_regs[addr]; | ||
737 | return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value); | ||
738 | } | ||
739 | |||
631 | /* ----------------------------------------------------------------------- */ | 740 | /* ----------------------------------------------------------------------- */ |
632 | 741 | ||
633 | struct REGISTER_DUMP { | 742 | struct REGISTER_DUMP { |
@@ -635,8 +744,15 @@ struct REGISTER_DUMP { | |||
635 | char *name; | 744 | char *name; |
636 | }; | 745 | }; |
637 | 746 | ||
638 | static int | 747 | struct REGISTER_DUMP d1[] = { |
639 | autodetect_stereo(struct i2c_client *client) | 748 | {0x007e, "autodetect"}, |
749 | {0x0023, "C_AD_BITS "}, | ||
750 | {0x0038, "ADD_BITS "}, | ||
751 | {0x003e, "CIB_BITS "}, | ||
752 | {0x0057, "ERROR_RATE"}, | ||
753 | }; | ||
754 | |||
755 | static int autodetect_stereo(struct i2c_client *client) | ||
640 | { | 756 | { |
641 | struct msp3400c *msp = i2c_get_clientdata(client); | 757 | struct msp3400c *msp = i2c_get_clientdata(client); |
642 | int val; | 758 | int val; |
@@ -649,8 +765,7 @@ autodetect_stereo(struct i2c_client *client) | |||
649 | val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18); | 765 | val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18); |
650 | if (val > 32767) | 766 | if (val > 32767) |
651 | val -= 65536; | 767 | val -= 65536; |
652 | dprintk(KERN_DEBUG | 768 | msp3400_dbg("stereo detect register: %d\n",val); |
653 | "msp34xx: stereo detect register: %d\n",val); | ||
654 | if (val > 4096) { | 769 | if (val > 4096) { |
655 | rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; | 770 | rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; |
656 | } else if (val < -4096) { | 771 | } else if (val < -4096) { |
@@ -664,8 +779,7 @@ autodetect_stereo(struct i2c_client *client) | |||
664 | case MSP_MODE_FM_NICAM2: | 779 | case MSP_MODE_FM_NICAM2: |
665 | case MSP_MODE_AM_NICAM: | 780 | case MSP_MODE_AM_NICAM: |
666 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23); | 781 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23); |
667 | dprintk(KERN_DEBUG | 782 | msp3400_dbg("nicam sync=%d, mode=%d\n", |
668 | "msp34xx: nicam sync=%d, mode=%d\n", | ||
669 | val & 1, (val & 0x1e) >> 1); | 783 | val & 1, (val & 0x1e) >> 1); |
670 | 784 | ||
671 | if (val & 1) { | 785 | if (val & 1) { |
@@ -698,8 +812,7 @@ autodetect_stereo(struct i2c_client *client) | |||
698 | break; | 812 | break; |
699 | case MSP_MODE_BTSC: | 813 | case MSP_MODE_BTSC: |
700 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200); | 814 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200); |
701 | dprintk(KERN_DEBUG | 815 | msp3400_dbg("status=0x%x (pri=%s, sec=%s, %s%s%s)\n", |
702 | "msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n", | ||
703 | val, | 816 | val, |
704 | (val & 0x0002) ? "no" : "yes", | 817 | (val & 0x0002) ? "no" : "yes", |
705 | (val & 0x0004) ? "no" : "yes", | 818 | (val & 0x0004) ? "no" : "yes", |
@@ -713,13 +826,13 @@ autodetect_stereo(struct i2c_client *client) | |||
713 | } | 826 | } |
714 | if (rxsubchans != msp->rxsubchans) { | 827 | if (rxsubchans != msp->rxsubchans) { |
715 | update = 1; | 828 | update = 1; |
716 | dprintk(KERN_DEBUG "msp34xx: watch: rxsubchans %d => %d\n", | 829 | msp3400_dbg("watch: rxsubchans %d => %d\n", |
717 | msp->rxsubchans,rxsubchans); | 830 | msp->rxsubchans,rxsubchans); |
718 | msp->rxsubchans = rxsubchans; | 831 | msp->rxsubchans = rxsubchans; |
719 | } | 832 | } |
720 | if (newnicam != msp->nicam_on) { | 833 | if (newnicam != msp->nicam_on) { |
721 | update = 1; | 834 | update = 1; |
722 | dprintk(KERN_DEBUG "msp34xx: watch: nicam %d => %d\n", | 835 | msp3400_dbg("watch: nicam %d => %d\n", |
723 | msp->nicam_on,newnicam); | 836 | msp->nicam_on,newnicam); |
724 | msp->nicam_on = newnicam; | 837 | msp->nicam_on = newnicam; |
725 | } | 838 | } |
@@ -756,8 +869,15 @@ static void watch_stereo(struct i2c_client *client) | |||
756 | { | 869 | { |
757 | struct msp3400c *msp = i2c_get_clientdata(client); | 870 | struct msp3400c *msp = i2c_get_clientdata(client); |
758 | 871 | ||
759 | if (autodetect_stereo(client)) | 872 | if (autodetect_stereo(client)) { |
760 | msp3400c_set_audmode(client,best_audio_mode(msp->rxsubchans)); | 873 | if (msp->stereo & V4L2_TUNER_MODE_STEREO) |
874 | msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO); | ||
875 | else if (msp->stereo & VIDEO_SOUND_LANG1) | ||
876 | msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1); | ||
877 | else | ||
878 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); | ||
879 | } | ||
880 | |||
761 | if (once) | 881 | if (once) |
762 | msp->watch_stereo = 0; | 882 | msp->watch_stereo = 0; |
763 | } | 883 | } |
@@ -769,14 +889,14 @@ static int msp3400c_thread(void *data) | |||
769 | struct CARRIER_DETECT *cd; | 889 | struct CARRIER_DETECT *cd; |
770 | int count, max1,max2,val1,val2, val,this; | 890 | int count, max1,max2,val1,val2, val,this; |
771 | 891 | ||
772 | printk("msp3400: kthread started\n"); | 892 | msp3400_info("msp3400 daemon started\n"); |
773 | for (;;) { | 893 | for (;;) { |
774 | d2printk("msp3400: thread: sleep\n"); | 894 | msp3400_dbg_mediumvol("msp3400 thread: sleep\n"); |
775 | msp34xx_sleep(msp,-1); | 895 | msp34xx_sleep(msp,-1); |
776 | d2printk("msp3400: thread: wakeup\n"); | 896 | msp3400_dbg_mediumvol("msp3400 thread: wakeup\n"); |
777 | 897 | ||
778 | restart: | 898 | restart: |
779 | dprintk("msp3410: thread: restart scan\n"); | 899 | msp3400_dbg("thread: restart scan\n"); |
780 | msp->restart = 0; | 900 | msp->restart = 0; |
781 | if (kthread_should_stop()) | 901 | if (kthread_should_stop()) |
782 | break; | 902 | break; |
@@ -784,9 +904,8 @@ static int msp3400c_thread(void *data) | |||
784 | if (VIDEO_MODE_RADIO == msp->norm || | 904 | if (VIDEO_MODE_RADIO == msp->norm || |
785 | MSP_MODE_EXTERN == msp->mode) { | 905 | MSP_MODE_EXTERN == msp->mode) { |
786 | /* no carrier scan, just unmute */ | 906 | /* no carrier scan, just unmute */ |
787 | printk("msp3400: thread: no carrier scan\n"); | 907 | msp3400_info("thread: no carrier scan\n"); |
788 | msp3400c_setvolume(client, msp->muted, | 908 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
789 | msp->volume, msp->balance); | ||
790 | continue; | 909 | continue; |
791 | } | 910 | } |
792 | 911 | ||
@@ -802,13 +921,14 @@ static int msp3400c_thread(void *data) | |||
802 | goto restart; | 921 | goto restart; |
803 | 922 | ||
804 | /* carrier detect pass #1 -- main carrier */ | 923 | /* carrier detect pass #1 -- main carrier */ |
805 | cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main); | 924 | cd = carrier_detect_main; |
925 | count = CARRIER_COUNT(carrier_detect_main); | ||
806 | 926 | ||
807 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { | 927 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { |
808 | /* autodetect doesn't work well with AM ... */ | 928 | /* autodetect doesn't work well with AM ... */ |
809 | max1 = 3; | 929 | max1 = 3; |
810 | count = 0; | 930 | count = 0; |
811 | dprintk("msp3400: AM sound override\n"); | 931 | msp3400_dbg("AM sound override\n"); |
812 | } | 932 | } |
813 | 933 | ||
814 | for (this = 0; this < count; this++) { | 934 | for (this = 0; this < count; this++) { |
@@ -820,7 +940,7 @@ static int msp3400c_thread(void *data) | |||
820 | val -= 65536; | 940 | val -= 65536; |
821 | if (val1 < val) | 941 | if (val1 < val) |
822 | val1 = val, max1 = this; | 942 | val1 = val, max1 = this; |
823 | dprintk("msp3400: carrier1 val: %5d / %s\n", val,cd[this].name); | 943 | msp3400_dbg("carrier1 val: %5d / %s\n", val,cd[this].name); |
824 | } | 944 | } |
825 | 945 | ||
826 | /* carrier detect pass #2 -- second (stereo) carrier */ | 946 | /* carrier detect pass #2 -- second (stereo) carrier */ |
@@ -836,13 +956,16 @@ static int msp3400c_thread(void *data) | |||
836 | case 0: /* 4.5 */ | 956 | case 0: /* 4.5 */ |
837 | case 2: /* 6.0 */ | 957 | case 2: /* 6.0 */ |
838 | default: | 958 | default: |
839 | cd = NULL; count = 0; | 959 | cd = NULL; |
960 | count = 0; | ||
840 | break; | 961 | break; |
841 | } | 962 | } |
842 | 963 | ||
843 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { | 964 | if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { |
844 | /* autodetect doesn't work well with AM ... */ | 965 | /* autodetect doesn't work well with AM ... */ |
845 | cd = NULL; count = 0; max2 = 0; | 966 | cd = NULL; |
967 | count = 0; | ||
968 | max2 = 0; | ||
846 | } | 969 | } |
847 | for (this = 0; this < count; this++) { | 970 | for (this = 0; this < count; this++) { |
848 | msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); | 971 | msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); |
@@ -853,7 +976,7 @@ static int msp3400c_thread(void *data) | |||
853 | val -= 65536; | 976 | val -= 65536; |
854 | if (val2 < val) | 977 | if (val2 < val) |
855 | val2 = val, max2 = this; | 978 | val2 = val, max2 = this; |
856 | dprintk("msp3400: carrier2 val: %5d / %s\n", val,cd[this].name); | 979 | msp3400_dbg("carrier2 val: %5d / %s\n", val,cd[this].name); |
857 | } | 980 | } |
858 | 981 | ||
859 | /* programm the msp3400 according to the results */ | 982 | /* programm the msp3400 according to the results */ |
@@ -865,7 +988,7 @@ static int msp3400c_thread(void *data) | |||
865 | msp->second = carrier_detect_55[max2].cdo; | 988 | msp->second = carrier_detect_55[max2].cdo; |
866 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | 989 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); |
867 | msp->nicam_on = 0; | 990 | msp->nicam_on = 0; |
868 | msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); | 991 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); |
869 | msp->watch_stereo = 1; | 992 | msp->watch_stereo = 1; |
870 | } else if (max2 == 1 && HAVE_NICAM(msp)) { | 993 | } else if (max2 == 1 && HAVE_NICAM(msp)) { |
871 | /* B/G NICAM */ | 994 | /* B/G NICAM */ |
@@ -892,7 +1015,7 @@ static int msp3400c_thread(void *data) | |||
892 | msp->second = carrier_detect_65[max2].cdo; | 1015 | msp->second = carrier_detect_65[max2].cdo; |
893 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); | 1016 | msp3400c_setmode(client, MSP_MODE_FM_TERRA); |
894 | msp->nicam_on = 0; | 1017 | msp->nicam_on = 0; |
895 | msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); | 1018 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); |
896 | msp->watch_stereo = 1; | 1019 | msp->watch_stereo = 1; |
897 | } else if (max2 == 0 && | 1020 | } else if (max2 == 0 && |
898 | msp->norm == VIDEO_MODE_SECAM) { | 1021 | msp->norm == VIDEO_MODE_SECAM) { |
@@ -900,7 +1023,7 @@ static int msp3400c_thread(void *data) | |||
900 | msp->second = carrier_detect_65[max2].cdo; | 1023 | msp->second = carrier_detect_65[max2].cdo; |
901 | msp3400c_setmode(client, MSP_MODE_AM_NICAM); | 1024 | msp3400c_setmode(client, MSP_MODE_AM_NICAM); |
902 | msp->nicam_on = 0; | 1025 | msp->nicam_on = 0; |
903 | msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); | 1026 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); |
904 | msp3400c_setcarrier(client, msp->second, msp->main); | 1027 | msp3400c_setcarrier(client, msp->second, msp->main); |
905 | /* volume prescale for SCART (AM mono input) */ | 1028 | /* volume prescale for SCART (AM mono input) */ |
906 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900); | 1029 | msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900); |
@@ -924,15 +1047,16 @@ static int msp3400c_thread(void *data) | |||
924 | msp->nicam_on = 0; | 1047 | msp->nicam_on = 0; |
925 | msp3400c_setcarrier(client, msp->second, msp->main); | 1048 | msp3400c_setcarrier(client, msp->second, msp->main); |
926 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; | 1049 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; |
927 | msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); | 1050 | msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); |
928 | break; | 1051 | break; |
929 | } | 1052 | } |
930 | 1053 | ||
931 | /* unmute */ | 1054 | /* unmute */ |
932 | msp3400c_setvolume(client, msp->muted, | 1055 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
933 | msp->volume, msp->balance); | 1056 | msp3400c_restore_dfp(client); |
1057 | |||
934 | if (debug) | 1058 | if (debug) |
935 | msp3400c_print_mode(msp); | 1059 | msp3400c_print_mode(client); |
936 | 1060 | ||
937 | /* monitor tv audio mode */ | 1061 | /* monitor tv audio mode */ |
938 | while (msp->watch_stereo) { | 1062 | while (msp->watch_stereo) { |
@@ -941,7 +1065,7 @@ static int msp3400c_thread(void *data) | |||
941 | watch_stereo(client); | 1065 | watch_stereo(client); |
942 | } | 1066 | } |
943 | } | 1067 | } |
944 | dprintk(KERN_DEBUG "msp3400: thread: exit\n"); | 1068 | msp3400_dbg("thread: exit\n"); |
945 | return 0; | 1069 | return 0; |
946 | } | 1070 | } |
947 | 1071 | ||
@@ -985,10 +1109,12 @@ static inline const char *msp34xx_standard_mode_name(int mode) | |||
985 | return "unknown"; | 1109 | return "unknown"; |
986 | } | 1110 | } |
987 | 1111 | ||
988 | static int msp34xx_modus(int norm) | 1112 | static int msp34xx_modus(struct i2c_client *client, int norm) |
989 | { | 1113 | { |
990 | switch (norm) { | 1114 | switch (norm) { |
991 | case VIDEO_MODE_PAL: | 1115 | case VIDEO_MODE_PAL: |
1116 | msp3400_dbg("video mode selected to PAL\n"); | ||
1117 | |||
992 | #if 1 | 1118 | #if 1 |
993 | /* experimental: not sure this works with all chip versions */ | 1119 | /* experimental: not sure this works with all chip versions */ |
994 | return 0x7003; | 1120 | return 0x7003; |
@@ -997,12 +1123,16 @@ static int msp34xx_modus(int norm) | |||
997 | return 0x1003; | 1123 | return 0x1003; |
998 | #endif | 1124 | #endif |
999 | case VIDEO_MODE_NTSC: /* BTSC */ | 1125 | case VIDEO_MODE_NTSC: /* BTSC */ |
1126 | msp3400_dbg("video mode selected to NTSC\n"); | ||
1000 | return 0x2003; | 1127 | return 0x2003; |
1001 | case VIDEO_MODE_SECAM: | 1128 | case VIDEO_MODE_SECAM: |
1129 | msp3400_dbg("video mode selected to SECAM\n"); | ||
1002 | return 0x0003; | 1130 | return 0x0003; |
1003 | case VIDEO_MODE_RADIO: | 1131 | case VIDEO_MODE_RADIO: |
1132 | msp3400_dbg("video mode selected to Radio\n"); | ||
1004 | return 0x0003; | 1133 | return 0x0003; |
1005 | case VIDEO_MODE_AUTO: | 1134 | case VIDEO_MODE_AUTO: |
1135 | msp3400_dbg("video mode selected to Auto\n"); | ||
1006 | return 0x2003; | 1136 | return 0x2003; |
1007 | default: | 1137 | default: |
1008 | return 0x0003; | 1138 | return 0x0003; |
@@ -1031,23 +1161,22 @@ static int msp3410d_thread(void *data) | |||
1031 | struct msp3400c *msp = i2c_get_clientdata(client); | 1161 | struct msp3400c *msp = i2c_get_clientdata(client); |
1032 | int mode,val,i,std; | 1162 | int mode,val,i,std; |
1033 | 1163 | ||
1034 | printk("msp3410: daemon started\n"); | 1164 | msp3400_info("msp3410 daemon started\n"); |
1035 | for (;;) { | 1165 | for (;;) { |
1036 | d2printk(KERN_DEBUG "msp3410: thread: sleep\n"); | 1166 | msp3400_dbg_mediumvol("msp3410 thread: sleep\n"); |
1037 | msp34xx_sleep(msp,-1); | 1167 | msp34xx_sleep(msp,-1); |
1038 | d2printk(KERN_DEBUG "msp3410: thread: wakeup\n"); | 1168 | msp3400_dbg_mediumvol("msp3410 thread: wakeup\n"); |
1039 | 1169 | ||
1040 | restart: | 1170 | restart: |
1041 | dprintk("msp3410: thread: restart scan\n"); | 1171 | msp3400_dbg("thread: restart scan\n"); |
1042 | msp->restart = 0; | 1172 | msp->restart = 0; |
1043 | if (kthread_should_stop()) | 1173 | if (kthread_should_stop()) |
1044 | break; | 1174 | break; |
1045 | 1175 | ||
1046 | if (msp->mode == MSP_MODE_EXTERN) { | 1176 | if (msp->mode == MSP_MODE_EXTERN) { |
1047 | /* no carrier scan needed, just unmute */ | 1177 | /* no carrier scan needed, just unmute */ |
1048 | dprintk(KERN_DEBUG "msp3410: thread: no carrier scan\n"); | 1178 | msp3400_dbg("thread: no carrier scan\n"); |
1049 | msp3400c_setvolume(client, msp->muted, | 1179 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
1050 | msp->volume, msp->balance); | ||
1051 | continue; | 1180 | continue; |
1052 | } | 1181 | } |
1053 | 1182 | ||
@@ -1059,14 +1188,14 @@ static int msp3410d_thread(void *data) | |||
1059 | goto restart; | 1188 | goto restart; |
1060 | 1189 | ||
1061 | /* start autodetect */ | 1190 | /* start autodetect */ |
1062 | mode = msp34xx_modus(msp->norm); | 1191 | mode = msp34xx_modus(client, msp->norm); |
1063 | std = msp34xx_standard(msp->norm); | 1192 | std = msp34xx_standard(msp->norm); |
1064 | msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode); | 1193 | msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode); |
1065 | msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std); | 1194 | msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std); |
1066 | msp->watch_stereo = 0; | 1195 | msp->watch_stereo = 0; |
1067 | 1196 | ||
1068 | if (debug) | 1197 | if (debug) |
1069 | printk(KERN_DEBUG "msp3410: setting mode: %s (0x%04x)\n", | 1198 | msp3400_dbg("setting mode: %s (0x%04x)\n", |
1070 | msp34xx_standard_mode_name(std) ,std); | 1199 | msp34xx_standard_mode_name(std) ,std); |
1071 | 1200 | ||
1072 | if (std != 1) { | 1201 | if (std != 1) { |
@@ -1082,13 +1211,13 @@ static int msp3410d_thread(void *data) | |||
1082 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); | 1211 | val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); |
1083 | if (val < 0x07ff) | 1212 | if (val < 0x07ff) |
1084 | break; | 1213 | break; |
1085 | dprintk(KERN_DEBUG "msp3410: detection still in progress\n"); | 1214 | msp3400_dbg("detection still in progress\n"); |
1086 | } | 1215 | } |
1087 | } | 1216 | } |
1088 | for (i = 0; modelist[i].name != NULL; i++) | 1217 | for (i = 0; modelist[i].name != NULL; i++) |
1089 | if (modelist[i].retval == val) | 1218 | if (modelist[i].retval == val) |
1090 | break; | 1219 | break; |
1091 | dprintk(KERN_DEBUG "msp3410: current mode: %s (0x%04x)\n", | 1220 | msp3400_dbg("current mode: %s (0x%04x)\n", |
1092 | modelist[i].name ? modelist[i].name : "unknown", | 1221 | modelist[i].name ? modelist[i].name : "unknown", |
1093 | val); | 1222 | val); |
1094 | msp->main = modelist[i].main; | 1223 | msp->main = modelist[i].main; |
@@ -1096,7 +1225,7 @@ static int msp3410d_thread(void *data) | |||
1096 | 1225 | ||
1097 | if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) { | 1226 | if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) { |
1098 | /* autodetection has failed, let backup */ | 1227 | /* autodetection has failed, let backup */ |
1099 | dprintk(KERN_DEBUG "msp3410: autodetection failed," | 1228 | msp3400_dbg("autodetection failed," |
1100 | " switching to backup mode: %s (0x%04x)\n", | 1229 | " switching to backup mode: %s (0x%04x)\n", |
1101 | modelist[8].name ? modelist[8].name : "unknown",val); | 1230 | modelist[8].name ? modelist[8].name : "unknown",val); |
1102 | val = 0x0009; | 1231 | val = 0x0009; |
@@ -1120,13 +1249,13 @@ static int msp3410d_thread(void *data) | |||
1120 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; | 1249 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; |
1121 | msp->nicam_on = 1; | 1250 | msp->nicam_on = 1; |
1122 | msp->watch_stereo = 1; | 1251 | msp->watch_stereo = 1; |
1123 | msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO); | 1252 | msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); |
1124 | break; | 1253 | break; |
1125 | case 0x0009: | 1254 | case 0x0009: |
1126 | msp->mode = MSP_MODE_AM_NICAM; | 1255 | msp->mode = MSP_MODE_AM_NICAM; |
1127 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; | 1256 | msp->rxsubchans = V4L2_TUNER_SUB_MONO; |
1128 | msp->nicam_on = 1; | 1257 | msp->nicam_on = 1; |
1129 | msp3400c_set_audmode(client,V4L2_TUNER_MODE_MONO); | 1258 | msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO); |
1130 | msp->watch_stereo = 1; | 1259 | msp->watch_stereo = 1; |
1131 | break; | 1260 | break; |
1132 | case 0x0020: /* BTSC */ | 1261 | case 0x0020: /* BTSC */ |
@@ -1135,7 +1264,7 @@ static int msp3410d_thread(void *data) | |||
1135 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; | 1264 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; |
1136 | msp->nicam_on = 0; | 1265 | msp->nicam_on = 0; |
1137 | msp->watch_stereo = 1; | 1266 | msp->watch_stereo = 1; |
1138 | msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO); | 1267 | msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); |
1139 | break; | 1268 | break; |
1140 | case 0x0040: /* FM radio */ | 1269 | case 0x0040: /* FM radio */ |
1141 | msp->mode = MSP_MODE_FM_RADIO; | 1270 | msp->mode = MSP_MODE_FM_RADIO; |
@@ -1169,9 +1298,10 @@ static int msp3410d_thread(void *data) | |||
1169 | /* unmute, restore misc registers */ | 1298 | /* unmute, restore misc registers */ |
1170 | msp3400c_setbass(client, msp->bass); | 1299 | msp3400c_setbass(client, msp->bass); |
1171 | msp3400c_settreble(client, msp->treble); | 1300 | msp3400c_settreble(client, msp->treble); |
1172 | msp3400c_setvolume(client, msp->muted, | 1301 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
1173 | msp->volume, msp->balance); | 1302 | msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb); |
1174 | msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb); | 1303 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); |
1304 | msp3400c_restore_dfp(client); | ||
1175 | 1305 | ||
1176 | /* monitor tv audio mode */ | 1306 | /* monitor tv audio mode */ |
1177 | while (msp->watch_stereo) { | 1307 | while (msp->watch_stereo) { |
@@ -1180,7 +1310,7 @@ static int msp3410d_thread(void *data) | |||
1180 | watch_stereo(client); | 1310 | watch_stereo(client); |
1181 | } | 1311 | } |
1182 | } | 1312 | } |
1183 | dprintk(KERN_DEBUG "msp3410: thread: exit\n"); | 1313 | msp3400_dbg("thread: exit\n"); |
1184 | return 0; | 1314 | return 0; |
1185 | } | 1315 | } |
1186 | 1316 | ||
@@ -1195,7 +1325,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source); | |||
1195 | /* (re-)initialize the msp34xxg, according to the current norm in msp->norm | 1325 | /* (re-)initialize the msp34xxg, according to the current norm in msp->norm |
1196 | * return 0 if it worked, -1 if it failed | 1326 | * return 0 if it worked, -1 if it failed |
1197 | */ | 1327 | */ |
1198 | static int msp34xxg_init(struct i2c_client *client) | 1328 | static int msp34xxg_reset(struct i2c_client *client) |
1199 | { | 1329 | { |
1200 | struct msp3400c *msp = i2c_get_clientdata(client); | 1330 | struct msp3400c *msp = i2c_get_clientdata(client); |
1201 | int modus,std; | 1331 | int modus,std; |
@@ -1210,8 +1340,10 @@ static int msp34xxg_init(struct i2c_client *client) | |||
1210 | 0x0f20 /* mute DSP input, mute SCART 1 */)) | 1340 | 0x0f20 /* mute DSP input, mute SCART 1 */)) |
1211 | return -1; | 1341 | return -1; |
1212 | 1342 | ||
1343 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); | ||
1344 | |||
1213 | /* step-by-step initialisation, as described in the manual */ | 1345 | /* step-by-step initialisation, as described in the manual */ |
1214 | modus = msp34xx_modus(msp->norm); | 1346 | modus = msp34xx_modus(client, msp->norm); |
1215 | std = msp34xx_standard(msp->norm); | 1347 | std = msp34xx_standard(msp->norm); |
1216 | modus &= ~0x03; /* STATUS_CHANGE=0 */ | 1348 | modus &= ~0x03; /* STATUS_CHANGE=0 */ |
1217 | modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */ | 1349 | modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */ |
@@ -1222,7 +1354,7 @@ static int msp34xxg_init(struct i2c_client *client) | |||
1222 | return -1; | 1354 | return -1; |
1223 | if (msp3400c_write(client, | 1355 | if (msp3400c_write(client, |
1224 | I2C_MSP3400C_DEM, | 1356 | I2C_MSP3400C_DEM, |
1225 | 0x20/*stanard*/, | 1357 | 0x20/*standard*/, |
1226 | std)) | 1358 | std)) |
1227 | return -1; | 1359 | return -1; |
1228 | 1360 | ||
@@ -1230,21 +1362,18 @@ static int msp34xxg_init(struct i2c_client *client) | |||
1230 | standard/audio autodetection right now */ | 1362 | standard/audio autodetection right now */ |
1231 | msp34xxg_set_source(client, msp->source); | 1363 | msp34xxg_set_source(client, msp->source); |
1232 | 1364 | ||
1233 | if (msp3400c_write(client, I2C_MSP3400C_DFP, | 1365 | if (msp3400c_write_dfp_with_default(client, 0x0e, /* AM/FM Prescale */ |
1234 | 0x0e, /* AM/FM Prescale */ | 1366 | 0x3000 |
1235 | 0x3000 /* default: [15:8] 75khz deviation */)) | 1367 | /* default: [15:8] 75khz deviation */ |
1368 | )) | ||
1236 | return -1; | 1369 | return -1; |
1237 | 1370 | ||
1238 | if (msp3400c_write(client, I2C_MSP3400C_DFP, | 1371 | if (msp3400c_write_dfp_with_default(client, 0x10, /* NICAM Prescale */ |
1239 | 0x10, /* NICAM Prescale */ | 1372 | 0x5a00 |
1240 | 0x5a00 /* default: 9db gain (as recommended) */)) | 1373 | /* default: 9db gain (as recommended) */ |
1374 | )) | ||
1241 | return -1; | 1375 | return -1; |
1242 | 1376 | ||
1243 | if (msp3400c_write(client, | ||
1244 | I2C_MSP3400C_DEM, | ||
1245 | 0x20, /* STANDARD SELECT */ | ||
1246 | standard /* default: 0x01 for automatic standard select*/)) | ||
1247 | return -1; | ||
1248 | return 0; | 1377 | return 0; |
1249 | } | 1378 | } |
1250 | 1379 | ||
@@ -1254,27 +1383,27 @@ static int msp34xxg_thread(void *data) | |||
1254 | struct msp3400c *msp = i2c_get_clientdata(client); | 1383 | struct msp3400c *msp = i2c_get_clientdata(client); |
1255 | int val, std, i; | 1384 | int val, std, i; |
1256 | 1385 | ||
1257 | printk("msp34xxg: daemon started\n"); | 1386 | msp3400_info("msp34xxg daemon started\n"); |
1258 | msp->source = 1; /* default */ | 1387 | msp->source = 1; /* default */ |
1259 | for (;;) { | 1388 | for (;;) { |
1260 | d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n"); | 1389 | msp3400_dbg_mediumvol("msp34xxg thread: sleep\n"); |
1261 | msp34xx_sleep(msp,-1); | 1390 | msp34xx_sleep(msp,-1); |
1262 | d2printk(KERN_DEBUG "msp34xxg: thread: wakeup\n"); | 1391 | msp3400_dbg_mediumvol("msp34xxg thread: wakeup\n"); |
1263 | 1392 | ||
1264 | restart: | 1393 | restart: |
1265 | dprintk("msp34xxg: thread: restart scan\n"); | 1394 | msp3400_dbg("thread: restart scan\n"); |
1266 | msp->restart = 0; | 1395 | msp->restart = 0; |
1267 | if (kthread_should_stop()) | 1396 | if (kthread_should_stop()) |
1268 | break; | 1397 | break; |
1269 | 1398 | ||
1270 | /* setup the chip*/ | 1399 | /* setup the chip*/ |
1271 | msp34xxg_init(client); | 1400 | msp34xxg_reset(client); |
1272 | std = standard; | 1401 | std = standard; |
1273 | if (std != 0x01) | 1402 | if (std != 0x01) |
1274 | goto unmute; | 1403 | goto unmute; |
1275 | 1404 | ||
1276 | /* watch autodetect */ | 1405 | /* watch autodetect */ |
1277 | dprintk("msp34xxg: triggered autodetect, waiting for result\n"); | 1406 | msp3400_dbg("triggered autodetect, waiting for result\n"); |
1278 | for (i = 0; i < 10; i++) { | 1407 | for (i = 0; i < 10; i++) { |
1279 | if (msp34xx_sleep(msp,100)) | 1408 | if (msp34xx_sleep(msp,100)) |
1280 | goto restart; | 1409 | goto restart; |
@@ -1285,23 +1414,23 @@ static int msp34xxg_thread(void *data) | |||
1285 | std = val; | 1414 | std = val; |
1286 | break; | 1415 | break; |
1287 | } | 1416 | } |
1288 | dprintk("msp34xxg: detection still in progress\n"); | 1417 | msp3400_dbg("detection still in progress\n"); |
1289 | } | 1418 | } |
1290 | if (0x01 == std) { | 1419 | if (0x01 == std) { |
1291 | dprintk("msp34xxg: detection still in progress after 10 tries. giving up.\n"); | 1420 | msp3400_dbg("detection still in progress after 10 tries. giving up.\n"); |
1292 | continue; | 1421 | continue; |
1293 | } | 1422 | } |
1294 | 1423 | ||
1295 | unmute: | 1424 | unmute: |
1296 | dprintk("msp34xxg: current mode: %s (0x%04x)\n", | 1425 | msp3400_dbg("current mode: %s (0x%04x)\n", |
1297 | msp34xx_standard_mode_name(std), std); | 1426 | msp34xx_standard_mode_name(std), std); |
1298 | 1427 | ||
1299 | /* unmute: dispatch sound to scart output, set scart volume */ | 1428 | /* unmute: dispatch sound to scart output, set scart volume */ |
1300 | dprintk("msp34xxg: unmute\n"); | 1429 | msp3400_dbg("unmute\n"); |
1301 | 1430 | ||
1302 | msp3400c_setbass(client, msp->bass); | 1431 | msp3400c_setbass(client, msp->bass); |
1303 | msp3400c_settreble(client, msp->treble); | 1432 | msp3400c_settreble(client, msp->treble); |
1304 | msp3400c_setvolume(client, msp->muted, msp->volume, msp->balance); | 1433 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
1305 | 1434 | ||
1306 | /* restore ACB */ | 1435 | /* restore ACB */ |
1307 | if (msp3400c_write(client, | 1436 | if (msp3400c_write(client, |
@@ -1309,8 +1438,10 @@ static int msp34xxg_thread(void *data) | |||
1309 | 0x13, /* ACB */ | 1438 | 0x13, /* ACB */ |
1310 | msp->acb)) | 1439 | msp->acb)) |
1311 | return -1; | 1440 | return -1; |
1441 | |||
1442 | msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); | ||
1312 | } | 1443 | } |
1313 | dprintk(KERN_DEBUG "msp34xxg: thread: exit\n"); | 1444 | msp3400_dbg("thread: exit\n"); |
1314 | return 0; | 1445 | return 0; |
1315 | } | 1446 | } |
1316 | 1447 | ||
@@ -1329,7 +1460,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source) | |||
1329 | * for MONO (source==0) downmixing set bit[7:0] to 0x30 | 1460 | * for MONO (source==0) downmixing set bit[7:0] to 0x30 |
1330 | */ | 1461 | */ |
1331 | int value = (source&0x07)<<8|(source==0 ? 0x30:0x20); | 1462 | int value = (source&0x07)<<8|(source==0 ? 0x30:0x20); |
1332 | dprintk("msp34xxg: set source to %d (0x%x)\n", source, value); | 1463 | msp3400_dbg("set source to %d (0x%x)\n", source, value); |
1333 | msp3400c_write(client, | 1464 | msp3400c_write(client, |
1334 | I2C_MSP3400C_DFP, | 1465 | I2C_MSP3400C_DFP, |
1335 | 0x08, /* Loudspeaker Output */ | 1466 | 0x08, /* Loudspeaker Output */ |
@@ -1380,7 +1511,7 @@ static void msp34xxg_detect_stereo(struct i2c_client *client) | |||
1380 | * this is a problem, I'll handle SAP just like lang1/lang2. | 1511 | * this is a problem, I'll handle SAP just like lang1/lang2. |
1381 | */ | 1512 | */ |
1382 | } | 1513 | } |
1383 | dprintk("msp34xxg: status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", | 1514 | msp3400_dbg("status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", |
1384 | status, is_stereo, is_bilingual, msp->rxsubchans); | 1515 | status, is_stereo, is_bilingual, msp->rxsubchans); |
1385 | } | 1516 | } |
1386 | 1517 | ||
@@ -1427,7 +1558,7 @@ static void msp_wake_thread(struct i2c_client *client); | |||
1427 | 1558 | ||
1428 | static struct i2c_driver driver = { | 1559 | static struct i2c_driver driver = { |
1429 | .owner = THIS_MODULE, | 1560 | .owner = THIS_MODULE, |
1430 | .name = "i2c msp3400 driver", | 1561 | .name = "msp3400", |
1431 | .id = I2C_DRIVERID_MSP3400, | 1562 | .id = I2C_DRIVERID_MSP3400, |
1432 | .flags = I2C_DF_NOTIFY, | 1563 | .flags = I2C_DF_NOTIFY, |
1433 | .attach_adapter = msp_probe, | 1564 | .attach_adapter = msp_probe, |
@@ -1449,57 +1580,64 @@ static struct i2c_client client_template = | |||
1449 | static int msp_attach(struct i2c_adapter *adap, int addr, int kind) | 1580 | static int msp_attach(struct i2c_adapter *adap, int addr, int kind) |
1450 | { | 1581 | { |
1451 | struct msp3400c *msp; | 1582 | struct msp3400c *msp; |
1452 | struct i2c_client *c; | 1583 | struct i2c_client *client = &client_template; |
1453 | int (*thread_func)(void *data) = NULL; | 1584 | int (*thread_func)(void *data) = NULL; |
1585 | int i; | ||
1454 | 1586 | ||
1455 | client_template.adapter = adap; | 1587 | client_template.adapter = adap; |
1456 | client_template.addr = addr; | 1588 | client_template.addr = addr; |
1457 | 1589 | ||
1458 | if (-1 == msp3400c_reset(&client_template)) { | 1590 | if (-1 == msp3400c_reset(&client_template)) { |
1459 | dprintk("msp34xx: no chip found\n"); | 1591 | msp3400_dbg("no chip found\n"); |
1460 | return -1; | 1592 | return -1; |
1461 | } | 1593 | } |
1462 | 1594 | ||
1463 | if (NULL == (c = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) | 1595 | if (NULL == (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) |
1464 | return -ENOMEM; | 1596 | return -ENOMEM; |
1465 | memcpy(c,&client_template,sizeof(struct i2c_client)); | 1597 | memcpy(client,&client_template,sizeof(struct i2c_client)); |
1466 | if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) { | 1598 | if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) { |
1467 | kfree(c); | 1599 | kfree(client); |
1468 | return -ENOMEM; | 1600 | return -ENOMEM; |
1469 | } | 1601 | } |
1470 | 1602 | ||
1471 | memset(msp,0,sizeof(struct msp3400c)); | 1603 | memset(msp,0,sizeof(struct msp3400c)); |
1472 | msp->volume = 58880; /* 0db gain */ | 1604 | msp->norm = VIDEO_MODE_NTSC; |
1473 | msp->balance = 32768; | 1605 | msp->left = 58880; /* 0db gain */ |
1474 | msp->bass = 32768; | 1606 | msp->right = 58880; /* 0db gain */ |
1475 | msp->treble = 32768; | 1607 | msp->bass = 32768; |
1476 | msp->input = -1; | 1608 | msp->treble = 32768; |
1477 | msp->muted = 1; | 1609 | msp->input = -1; |
1478 | 1610 | msp->muted = 0; | |
1479 | i2c_set_clientdata(c, msp); | 1611 | msp->i2s_mode = 0; |
1612 | for (i = 0; i < DFP_COUNT; i++) | ||
1613 | msp->dfp_regs[i] = -1; | ||
1614 | |||
1615 | i2c_set_clientdata(client, msp); | ||
1480 | init_waitqueue_head(&msp->wq); | 1616 | init_waitqueue_head(&msp->wq); |
1481 | 1617 | ||
1482 | if (-1 == msp3400c_reset(c)) { | 1618 | if (-1 == msp3400c_reset(client)) { |
1483 | kfree(msp); | 1619 | kfree(msp); |
1484 | kfree(c); | 1620 | kfree(client); |
1485 | dprintk("msp34xx: no chip found\n"); | 1621 | msp3400_dbg("no chip found\n"); |
1486 | return -1; | 1622 | return -1; |
1487 | } | 1623 | } |
1488 | 1624 | ||
1489 | msp->rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e); | 1625 | msp->rev1 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1e); |
1490 | if (-1 != msp->rev1) | 1626 | if (-1 != msp->rev1) |
1491 | msp->rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f); | 1627 | msp->rev2 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1f); |
1492 | if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) { | 1628 | if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) { |
1493 | kfree(msp); | 1629 | kfree(msp); |
1494 | kfree(c); | 1630 | kfree(client); |
1495 | dprintk("msp34xx: error while reading chip version\n"); | 1631 | msp3400_dbg("error while reading chip version\n"); |
1496 | return -1; | 1632 | return -1; |
1497 | } | 1633 | } |
1634 | msp3400_dbg("rev1=0x%04x, rev2=0x%04x\n", msp->rev1, msp->rev2); | ||
1498 | 1635 | ||
1499 | msp3400c_setvolume(c, msp->muted, msp->volume, msp->balance); | 1636 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
1500 | 1637 | ||
1501 | snprintf(c->name, sizeof(c->name), "MSP34%02d%c-%c%d", | 1638 | snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d", |
1502 | (msp->rev2>>8)&0xff, (msp->rev1&0xff)+'@', | 1639 | ((msp->rev1>>4)&0x0f) + '3', |
1640 | (msp->rev2>>8)&0xff, (msp->rev1&0x0f)+'@', | ||
1503 | ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f); | 1641 | ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f); |
1504 | 1642 | ||
1505 | msp->opmode = opmode; | 1643 | msp->opmode = opmode; |
@@ -1513,7 +1651,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1513 | } | 1651 | } |
1514 | 1652 | ||
1515 | /* hello world :-) */ | 1653 | /* hello world :-) */ |
1516 | printk(KERN_INFO "msp34xx: init: chip=%s", c->name); | 1654 | msp3400_info("chip=%s", client->name); |
1517 | if (HAVE_NICAM(msp)) | 1655 | if (HAVE_NICAM(msp)) |
1518 | printk(" +nicam"); | 1656 | printk(" +nicam"); |
1519 | if (HAVE_SIMPLE(msp)) | 1657 | if (HAVE_SIMPLE(msp)) |
@@ -1542,29 +1680,49 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) | |||
1542 | 1680 | ||
1543 | /* startup control thread if needed */ | 1681 | /* startup control thread if needed */ |
1544 | if (thread_func) { | 1682 | if (thread_func) { |
1545 | msp->kthread = kthread_run(thread_func, c, "msp34xx"); | 1683 | msp->kthread = kthread_run(thread_func, client, "msp34xx"); |
1684 | |||
1546 | if (NULL == msp->kthread) | 1685 | if (NULL == msp->kthread) |
1547 | printk(KERN_WARNING "msp34xx: kernel_thread() failed\n"); | 1686 | msp3400_warn("kernel_thread() failed\n"); |
1548 | msp_wake_thread(c); | 1687 | msp_wake_thread(client); |
1549 | } | 1688 | } |
1550 | 1689 | ||
1551 | /* done */ | 1690 | /* done */ |
1552 | i2c_attach_client(c); | 1691 | i2c_attach_client(client); |
1692 | |||
1693 | /* update our own array */ | ||
1694 | for (i = 0; i < MSP3400_MAX; i++) { | ||
1695 | if (NULL == msps[i]) { | ||
1696 | msps[i] = client; | ||
1697 | break; | ||
1698 | } | ||
1699 | } | ||
1700 | |||
1553 | return 0; | 1701 | return 0; |
1554 | } | 1702 | } |
1555 | 1703 | ||
1556 | static int msp_detach(struct i2c_client *client) | 1704 | static int msp_detach(struct i2c_client *client) |
1557 | { | 1705 | { |
1558 | struct msp3400c *msp = i2c_get_clientdata(client); | 1706 | struct msp3400c *msp = i2c_get_clientdata(client); |
1707 | int i; | ||
1559 | 1708 | ||
1560 | /* shutdown control thread */ | 1709 | /* shutdown control thread */ |
1561 | if (msp->kthread >= 0) { | 1710 | if (msp->kthread) { |
1562 | msp->restart = 1; | 1711 | msp->restart = 1; |
1563 | kthread_stop(msp->kthread); | 1712 | kthread_stop(msp->kthread); |
1564 | } | 1713 | } |
1565 | msp3400c_reset(client); | 1714 | msp3400c_reset(client); |
1715 | |||
1716 | /* update our own array */ | ||
1717 | for (i = 0; i < MSP3400_MAX; i++) { | ||
1718 | if (client == msps[i]) { | ||
1719 | msps[i] = NULL; | ||
1720 | break; | ||
1721 | } | ||
1722 | } | ||
1566 | 1723 | ||
1567 | i2c_detach_client(client); | 1724 | i2c_detach_client(client); |
1725 | |||
1568 | kfree(msp); | 1726 | kfree(msp); |
1569 | kfree(client); | 1727 | kfree(client); |
1570 | return 0; | 1728 | return 0; |
@@ -1640,7 +1798,7 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode) | |||
1640 | case OPMODE_MANUAL: | 1798 | case OPMODE_MANUAL: |
1641 | case OPMODE_SIMPLE: | 1799 | case OPMODE_SIMPLE: |
1642 | msp->watch_stereo = 0; | 1800 | msp->watch_stereo = 0; |
1643 | msp3400c_set_audmode(client, audmode); | 1801 | msp3400c_setstereo(client, audmode); |
1644 | break; | 1802 | break; |
1645 | case OPMODE_SIMPLER: | 1803 | case OPMODE_SIMPLER: |
1646 | msp34xxg_set_audmode(client, audmode); | 1804 | msp34xxg_set_audmode(client, audmode); |
@@ -1648,16 +1806,18 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode) | |||
1648 | } | 1806 | } |
1649 | } | 1807 | } |
1650 | 1808 | ||
1809 | |||
1651 | static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | 1810 | static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) |
1652 | { | 1811 | { |
1653 | struct msp3400c *msp = i2c_get_clientdata(client); | 1812 | struct msp3400c *msp = i2c_get_clientdata(client); |
1654 | __u16 *sarg = arg; | 1813 | __u16 *sarg = arg; |
1655 | int scart = 0; | 1814 | int scart = 0; |
1656 | 1815 | ||
1657 | switch (cmd) { | 1816 | switch (cmd) { |
1658 | 1817 | ||
1659 | case AUDC_SET_INPUT: | 1818 | case AUDC_SET_INPUT: |
1660 | dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)\n",*sarg); | 1819 | msp3400_dbg("AUDC_SET_INPUT(%d)\n",*sarg); |
1820 | |||
1661 | if (*sarg == msp->input) | 1821 | if (*sarg == msp->input) |
1662 | break; | 1822 | break; |
1663 | msp->input = *sarg; | 1823 | msp->input = *sarg; |
@@ -1691,15 +1851,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1691 | msp3400c_set_scart(client,scart,0); | 1851 | msp3400c_set_scart(client,scart,0); |
1692 | msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); | 1852 | msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); |
1693 | if (msp->opmode != OPMODE_SIMPLER) | 1853 | if (msp->opmode != OPMODE_SIMPLER) |
1694 | msp3400c_set_audmode(client, msp->audmode); | 1854 | msp3400c_setstereo(client, msp->audmode); |
1695 | } | 1855 | } |
1696 | msp_wake_thread(client); | 1856 | msp_wake_thread(client); |
1697 | break; | 1857 | break; |
1698 | 1858 | ||
1699 | case AUDC_SET_RADIO: | 1859 | case AUDC_SET_RADIO: |
1700 | dprintk(KERN_DEBUG "msp34xx: AUDC_SET_RADIO\n"); | 1860 | msp3400_dbg("AUDC_SET_RADIO\n"); |
1701 | msp->norm = VIDEO_MODE_RADIO; | 1861 | msp->norm = VIDEO_MODE_RADIO; |
1702 | dprintk(KERN_DEBUG "msp34xx: switching to radio mode\n"); | 1862 | msp3400_dbg("switching to radio mode\n"); |
1703 | msp->watch_stereo = 0; | 1863 | msp->watch_stereo = 0; |
1704 | switch (msp->opmode) { | 1864 | switch (msp->opmode) { |
1705 | case OPMODE_MANUAL: | 1865 | case OPMODE_MANUAL: |
@@ -1707,8 +1867,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1707 | msp3400c_setmode(client,MSP_MODE_FM_RADIO); | 1867 | msp3400c_setmode(client,MSP_MODE_FM_RADIO); |
1708 | msp3400c_setcarrier(client, MSP_CARRIER(10.7), | 1868 | msp3400c_setcarrier(client, MSP_CARRIER(10.7), |
1709 | MSP_CARRIER(10.7)); | 1869 | MSP_CARRIER(10.7)); |
1710 | msp3400c_setvolume(client, msp->muted, | 1870 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); |
1711 | msp->volume, msp->balance); | ||
1712 | break; | 1871 | break; |
1713 | case OPMODE_SIMPLE: | 1872 | case OPMODE_SIMPLE: |
1714 | case OPMODE_SIMPLER: | 1873 | case OPMODE_SIMPLER: |
@@ -1717,6 +1876,30 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1717 | break; | 1876 | break; |
1718 | } | 1877 | } |
1719 | break; | 1878 | break; |
1879 | /* work-in-progress: hook to control the DFP registers */ | ||
1880 | case MSP_SET_DFPREG: | ||
1881 | { | ||
1882 | struct msp_dfpreg *r = arg; | ||
1883 | int i; | ||
1884 | |||
1885 | if (r->reg < 0 || r->reg >= DFP_COUNT) | ||
1886 | return -EINVAL; | ||
1887 | for (i = 0; i < sizeof(bl_dfp) / sizeof(int); i++) | ||
1888 | if (r->reg == bl_dfp[i]) | ||
1889 | return -EINVAL; | ||
1890 | msp->dfp_regs[r->reg] = r->value; | ||
1891 | msp3400c_write(client, I2C_MSP3400C_DFP, r->reg, r->value); | ||
1892 | return 0; | ||
1893 | } | ||
1894 | case MSP_GET_DFPREG: | ||
1895 | { | ||
1896 | struct msp_dfpreg *r = arg; | ||
1897 | |||
1898 | if (r->reg < 0 || r->reg >= DFP_COUNT) | ||
1899 | return -EINVAL; | ||
1900 | r->value = msp3400c_read(client, I2C_MSP3400C_DFP, r->reg); | ||
1901 | return 0; | ||
1902 | } | ||
1720 | 1903 | ||
1721 | /* --- v4l ioctls --- */ | 1904 | /* --- v4l ioctls --- */ |
1722 | /* take care: bttv does userspace copying, we'll get a | 1905 | /* take care: bttv does userspace copying, we'll get a |
@@ -1725,7 +1908,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1725 | { | 1908 | { |
1726 | struct video_audio *va = arg; | 1909 | struct video_audio *va = arg; |
1727 | 1910 | ||
1728 | dprintk(KERN_DEBUG "msp34xx: VIDIOCGAUDIO\n"); | 1911 | msp3400_dbg("VIDIOCGAUDIO\n"); |
1729 | va->flags |= VIDEO_AUDIO_VOLUME | | 1912 | va->flags |= VIDEO_AUDIO_VOLUME | |
1730 | VIDEO_AUDIO_BASS | | 1913 | VIDEO_AUDIO_BASS | |
1731 | VIDEO_AUDIO_TREBLE | | 1914 | VIDEO_AUDIO_TREBLE | |
@@ -1733,8 +1916,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1733 | if (msp->muted) | 1916 | if (msp->muted) |
1734 | va->flags |= VIDEO_AUDIO_MUTE; | 1917 | va->flags |= VIDEO_AUDIO_MUTE; |
1735 | 1918 | ||
1736 | va->volume = msp->volume; | 1919 | if (msp->muted) |
1737 | va->balance = (va->volume) ? msp->balance : 32768; | 1920 | va->flags |= VIDEO_AUDIO_MUTE; |
1921 | va->volume = MAX(msp->left, msp->right); | ||
1922 | va->balance = (32768 * MIN(msp->left, msp->right)) / | ||
1923 | (va->volume ? va->volume : 1); | ||
1924 | va->balance = (msp->left < msp->right) ? | ||
1925 | (65535 - va->balance) : va->balance; | ||
1926 | if (0 == va->volume) | ||
1927 | va->balance = 32768; | ||
1738 | va->bass = msp->bass; | 1928 | va->bass = msp->bass; |
1739 | va->treble = msp->treble; | 1929 | va->treble = msp->treble; |
1740 | 1930 | ||
@@ -1746,27 +1936,43 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1746 | { | 1936 | { |
1747 | struct video_audio *va = arg; | 1937 | struct video_audio *va = arg; |
1748 | 1938 | ||
1749 | dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n"); | 1939 | msp3400_dbg("VIDIOCSAUDIO\n"); |
1750 | msp->muted = (va->flags & VIDEO_AUDIO_MUTE); | 1940 | msp->muted = (va->flags & VIDEO_AUDIO_MUTE); |
1751 | msp->volume = va->volume; | 1941 | msp->left = (MIN(65536 - va->balance, 32768) * |
1752 | msp->balance = va->balance; | 1942 | va->volume) / 32768; |
1943 | msp->right = (MIN(va->balance, 32768) * va->volume) / 32768; | ||
1753 | msp->bass = va->bass; | 1944 | msp->bass = va->bass; |
1754 | msp->treble = va->treble; | 1945 | msp->treble = va->treble; |
1755 | 1946 | msp3400_dbg("VIDIOCSAUDIO setting va->volume to %d\n", | |
1756 | msp3400c_setvolume(client, msp->muted, | 1947 | va->volume); |
1757 | msp->volume, msp->balance); | 1948 | msp3400_dbg("VIDIOCSAUDIO setting va->balance to %d\n", |
1758 | msp3400c_setbass(client,msp->bass); | 1949 | va->balance); |
1759 | msp3400c_settreble(client,msp->treble); | 1950 | msp3400_dbg("VIDIOCSAUDIO setting va->flags to %d\n", |
1951 | va->flags); | ||
1952 | msp3400_dbg("VIDIOCSAUDIO setting msp->left to %d\n", | ||
1953 | msp->left); | ||
1954 | msp3400_dbg("VIDIOCSAUDIO setting msp->right to %d\n", | ||
1955 | msp->right); | ||
1956 | msp3400_dbg("VIDIOCSAUDIO setting msp->bass to %d\n", | ||
1957 | msp->bass); | ||
1958 | msp3400_dbg("VIDIOCSAUDIO setting msp->treble to %d\n", | ||
1959 | msp->treble); | ||
1960 | msp3400_dbg("VIDIOCSAUDIO setting msp->mode to %d\n", | ||
1961 | msp->mode); | ||
1962 | msp3400c_setvolume(client, msp->muted, msp->left, msp->right); | ||
1963 | msp3400c_setbass(client, msp->bass); | ||
1964 | msp3400c_settreble(client, msp->treble); | ||
1760 | 1965 | ||
1761 | if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO) | 1966 | if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO) |
1762 | msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode)); | 1967 | msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode)); |
1763 | break; | 1968 | break; |
1764 | } | 1969 | } |
1970 | |||
1765 | case VIDIOCSCHAN: | 1971 | case VIDIOCSCHAN: |
1766 | { | 1972 | { |
1767 | struct video_channel *vc = arg; | 1973 | struct video_channel *vc = arg; |
1768 | 1974 | ||
1769 | dprintk(KERN_DEBUG "msp34xx: VIDIOCSCHAN (norm=%d)\n",vc->norm); | 1975 | msp3400_dbg("VIDIOCSCHAN (norm=%d)\n",vc->norm); |
1770 | msp->norm = vc->norm; | 1976 | msp->norm = vc->norm; |
1771 | msp_wake_thread(client); | 1977 | msp_wake_thread(client); |
1772 | break; | 1978 | break; |
@@ -1776,12 +1982,135 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1776 | case VIDIOC_S_FREQUENCY: | 1982 | case VIDIOC_S_FREQUENCY: |
1777 | { | 1983 | { |
1778 | /* new channel -- kick audio carrier scan */ | 1984 | /* new channel -- kick audio carrier scan */ |
1779 | dprintk(KERN_DEBUG "msp34xx: VIDIOCSFREQ\n"); | 1985 | msp3400_dbg("VIDIOCSFREQ\n"); |
1780 | msp_wake_thread(client); | 1986 | msp_wake_thread(client); |
1781 | break; | 1987 | break; |
1782 | } | 1988 | } |
1783 | 1989 | ||
1990 | /* msp34xx specific */ | ||
1991 | case MSP_SET_MATRIX: | ||
1992 | { | ||
1993 | struct msp_matrix *mspm = arg; | ||
1994 | |||
1995 | msp3400_dbg("MSP_SET_MATRIX\n"); | ||
1996 | msp3400c_set_scart(client, mspm->input, mspm->output); | ||
1997 | break; | ||
1998 | } | ||
1999 | |||
1784 | /* --- v4l2 ioctls --- */ | 2000 | /* --- v4l2 ioctls --- */ |
2001 | case VIDIOC_S_STD: | ||
2002 | { | ||
2003 | v4l2_std_id *id = arg; | ||
2004 | |||
2005 | /*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/ | ||
2006 | if (*id & V4L2_STD_PAL) { | ||
2007 | msp->norm=VIDEO_MODE_PAL; | ||
2008 | } else if (*id & V4L2_STD_SECAM) { | ||
2009 | msp->norm=VIDEO_MODE_SECAM; | ||
2010 | } else { | ||
2011 | msp->norm=VIDEO_MODE_NTSC; | ||
2012 | } | ||
2013 | |||
2014 | msp_wake_thread(client); | ||
2015 | return 0; | ||
2016 | } | ||
2017 | |||
2018 | case VIDIOC_ENUMINPUT: | ||
2019 | { | ||
2020 | struct v4l2_input *i = arg; | ||
2021 | |||
2022 | if (i->index != 0) | ||
2023 | return -EINVAL; | ||
2024 | |||
2025 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
2026 | switch (i->index) { | ||
2027 | case AUDIO_RADIO: | ||
2028 | strcpy(i->name,"Radio"); | ||
2029 | break; | ||
2030 | case AUDIO_EXTERN_1: | ||
2031 | strcpy(i->name,"Extern 1"); | ||
2032 | break; | ||
2033 | case AUDIO_EXTERN_2: | ||
2034 | strcpy(i->name,"Extern 2"); | ||
2035 | break; | ||
2036 | case AUDIO_TUNER: | ||
2037 | strcpy(i->name,"Television"); | ||
2038 | break; | ||
2039 | default: | ||
2040 | return -EINVAL; | ||
2041 | } | ||
2042 | return 0; | ||
2043 | } | ||
2044 | |||
2045 | case VIDIOC_G_AUDIO: | ||
2046 | { | ||
2047 | struct v4l2_audio *a = arg; | ||
2048 | |||
2049 | memset(a,0,sizeof(*a)); | ||
2050 | |||
2051 | switch (a->index) { | ||
2052 | case AUDIO_RADIO: | ||
2053 | strcpy(a->name,"Radio"); | ||
2054 | break; | ||
2055 | case AUDIO_EXTERN_1: | ||
2056 | strcpy(a->name,"Extern 1"); | ||
2057 | break; | ||
2058 | case AUDIO_EXTERN_2: | ||
2059 | strcpy(a->name,"Extern 2"); | ||
2060 | break; | ||
2061 | case AUDIO_TUNER: | ||
2062 | strcpy(a->name,"Television"); | ||
2063 | break; | ||
2064 | default: | ||
2065 | return -EINVAL; | ||
2066 | } | ||
2067 | |||
2068 | msp_any_detect_stereo(client); | ||
2069 | if (msp->audmode == V4L2_TUNER_MODE_STEREO) { | ||
2070 | a->capability=V4L2_AUDCAP_STEREO; | ||
2071 | } | ||
2072 | |||
2073 | break; | ||
2074 | } | ||
2075 | case VIDIOC_S_AUDIO: | ||
2076 | { | ||
2077 | struct v4l2_audio *sarg = arg; | ||
2078 | |||
2079 | switch (sarg->index) { | ||
2080 | case AUDIO_RADIO: | ||
2081 | /* Hauppauge uses IN2 for the radio */ | ||
2082 | msp->mode = MSP_MODE_FM_RADIO; | ||
2083 | scart = SCART_IN2; | ||
2084 | break; | ||
2085 | case AUDIO_EXTERN_1: | ||
2086 | /* IN1 is often used for external input ... */ | ||
2087 | msp->mode = MSP_MODE_EXTERN; | ||
2088 | scart = SCART_IN1; | ||
2089 | break; | ||
2090 | case AUDIO_EXTERN_2: | ||
2091 | /* ... sometimes it is IN2 through ;) */ | ||
2092 | msp->mode = MSP_MODE_EXTERN; | ||
2093 | scart = SCART_IN2; | ||
2094 | break; | ||
2095 | case AUDIO_TUNER: | ||
2096 | msp->mode = -1; | ||
2097 | break; | ||
2098 | } | ||
2099 | if (scart) { | ||
2100 | msp->rxsubchans = V4L2_TUNER_SUB_STEREO; | ||
2101 | msp->audmode = V4L2_TUNER_MODE_STEREO; | ||
2102 | msp3400c_set_scart(client,scart,0); | ||
2103 | msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); | ||
2104 | } | ||
2105 | if (sarg->capability==V4L2_AUDCAP_STEREO) { | ||
2106 | msp->audmode = V4L2_TUNER_MODE_STEREO; | ||
2107 | } else { | ||
2108 | msp->audmode &= ~V4L2_TUNER_MODE_STEREO; | ||
2109 | } | ||
2110 | msp_any_set_audmode(client, msp->audmode); | ||
2111 | msp_wake_thread(client); | ||
2112 | break; | ||
2113 | } | ||
1785 | case VIDIOC_G_TUNER: | 2114 | case VIDIOC_G_TUNER: |
1786 | { | 2115 | { |
1787 | struct v4l2_tuner *vt = arg; | 2116 | struct v4l2_tuner *vt = arg; |
@@ -1804,13 +2133,46 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1804 | break; | 2133 | break; |
1805 | } | 2134 | } |
1806 | 2135 | ||
1807 | /* msp34xx specific */ | 2136 | case VIDIOC_G_AUDOUT: |
1808 | case MSP_SET_MATRIX: | ||
1809 | { | 2137 | { |
1810 | struct msp_matrix *mspm = arg; | 2138 | struct v4l2_audioout *a=(struct v4l2_audioout *)arg; |
2139 | int idx=a->index; | ||
2140 | |||
2141 | memset(a,0,sizeof(*a)); | ||
2142 | |||
2143 | switch (idx) { | ||
2144 | case 0: | ||
2145 | strcpy(a->name,"Scart1 Out"); | ||
2146 | break; | ||
2147 | case 1: | ||
2148 | strcpy(a->name,"Scart2 Out"); | ||
2149 | break; | ||
2150 | case 2: | ||
2151 | strcpy(a->name,"I2S Out"); | ||
2152 | break; | ||
2153 | default: | ||
2154 | return -EINVAL; | ||
2155 | } | ||
2156 | break; | ||
2157 | |||
2158 | } | ||
2159 | case VIDIOC_S_AUDOUT: | ||
2160 | { | ||
2161 | struct v4l2_audioout *a=(struct v4l2_audioout *)arg; | ||
2162 | |||
2163 | if (a->index<0||a->index>2) | ||
2164 | return -EINVAL; | ||
2165 | |||
2166 | if (a->index==2) { | ||
2167 | if (a->mode == V4L2_AUDMODE_32BITS) | ||
2168 | msp->i2s_mode=1; | ||
2169 | else | ||
2170 | msp->i2s_mode=0; | ||
2171 | } | ||
2172 | msp3400_dbg("Setting audio out on msp34xx to input %i, mode %i\n", | ||
2173 | a->index,msp->i2s_mode); | ||
2174 | msp3400c_set_scart(client,msp->in_scart,a->index+1); | ||
1811 | 2175 | ||
1812 | dprintk(KERN_DEBUG "msp34xx: MSP_SET_MATRIX\n"); | ||
1813 | msp3400c_set_scart(client, mspm->input, mspm->output); | ||
1814 | break; | 2176 | break; |
1815 | } | 2177 | } |
1816 | 2178 | ||
@@ -1823,19 +2185,19 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
1823 | 2185 | ||
1824 | static int msp_suspend(struct device * dev, pm_message_t state) | 2186 | static int msp_suspend(struct device * dev, pm_message_t state) |
1825 | { | 2187 | { |
1826 | struct i2c_client *c = container_of(dev, struct i2c_client, dev); | 2188 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); |
1827 | 2189 | ||
1828 | dprintk("msp34xx: suspend\n"); | 2190 | msp3400_dbg("msp34xx: suspend\n"); |
1829 | msp3400c_reset(c); | 2191 | msp3400c_reset(client); |
1830 | return 0; | 2192 | return 0; |
1831 | } | 2193 | } |
1832 | 2194 | ||
1833 | static int msp_resume(struct device * dev) | 2195 | static int msp_resume(struct device * dev) |
1834 | { | 2196 | { |
1835 | struct i2c_client *c = container_of(dev, struct i2c_client, dev); | 2197 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); |
1836 | 2198 | ||
1837 | dprintk("msp34xx: resume\n"); | 2199 | msp3400_dbg("msp34xx: resume\n"); |
1838 | msp_wake_thread(c); | 2200 | msp_wake_thread(client); |
1839 | return 0; | 2201 | return 0; |
1840 | } | 2202 | } |
1841 | 2203 | ||